[cap-talk] Announce: Plash 1.18

Mark Seaborn mrs at mythic-beasts.com
Thu Jun 7 18:51:34 EDT 2007


Toby Murray wrote:

> On Wed, 2007-06-06 at 19:10 +0100, Mark Seaborn wrote:

> > The major new feature is the packaging system, for running programs
> > from Debian packages in sandboxes.  This is able to run a number of
> > programs such as Firefox and Evince.  See
> > <http://plash.beasts.org/wiki/PackageTools>.
> 
> Looking at that link and at http://plash.beasts.org/wiki/Story2 I'm
> trying to figure out the mechanics of what's going on with the sandbox
> construction.
> 
> Can you comment on the following guesses?
> 
> When a new package is installed (e.g. firefox) you pull down and install
> all dependencies somewhere -- eg. /path/to/plash-sandboxes/firefox
> 
> This allows any (sandboxed) firefox instance to have all needed
> dependencies available to it directly in its sandbox.

Right.  Suppose you do:
  plash-pkg-install ~/pets/firefox -c firefox.pkg
Then the dependencies will be unpacked into ~/pets/firefox/unpacked.

The individual packages are first unpacked into
~/.cache/plash-pkg/unpack-cache, and the files are then hardlinked
into ~/pets/firefox/unpacked, merging the packages' directory trees
together.  The file inodes therefore get shared between apps.


> When launched, (sandboxed) firefox instance X is given copy-on-write
> access to /path/to/sandbox/firefox so any changes it makes there do not
> effect other (sandboxed) firefox instances

The launcher combines ~/pets/firefox/unpacked (the read-only portion)
and ~/pets/firefox/write_layer using FsObjCopyOnWrite so that any
writes go into the write_layer directory.  Changes *are* saved across
instances of firefox that are launched from the same ~/pets/firefox
directory.  But you can of course create another directory
~/pets/another-firefox which is separate.

The relevant part of the code is this:

    root_dir = ns.make_cow_dir(my_root.get_obj(
                                 os.path.join(app_dir, "write_layer")),
                               my_root.get_obj(
                                 os.path.join(app_dir, "unpacked")))
    ns.attach_at_path(proc.root_node, "/", root_dir)

in http://svn.gna.org/viewcvs/plash/trunk/python/plash_pkg/launch.py


> grants by the powerbox allow (sandboxed) firefox instance X to edit
> files and have the changes appear in-place in the global filesystem

Right.

> other grants -- e.g. copy-on-write grants to other parts of the
> filesystem -- are not possible, so if (sandboxed) firefox instance X
> tries to write to $HOME/somewhere and the user hasn't granted access via
> the powerbox, the write will fail.

It is possible to map other objects into the process's file namespace
by passing more arguments to plash-pkg-launch, which takes the same
arguments as pola-run.  That doesn't provide a way to set up further
copy-on-write directories though (pola-run doesn't have an argument
syntax for that) -- you'd need to do that in Python.

If the firefox instance tries to write to a file named $HOME/somewhere
(and no file or slot of this name has been mapped in, e.g. via the
powerbox), you will see the file
~/pets/firefox/write_layer/$HOME/somewhere appear.  This means it can
write into $HOME/.mozilla and we don't have to configure granting a
".mozilla" directory specially.

There are two proxy directory objects involved in this:
 * FsObjMountTable: This provides functionality similar to Linux's mount
   tables and allows files/directories to be attached at points in the
   file namespace.  The powerbox grants files by attaching them into the
   mount table.
 * FsObjCopyOnWrite: similar to a union directory but will direct writes
   into one branch.
plash-pkg-launch sets things up so the FsObjCopyOnWrite directory is
bound at "/" in the mount table.

Mark


More information about the cap-talk mailing list