per-process namespaces for Linux
PATCH 1/1 per-process namespaces for Linux
Quoted 2 lines
* large cleanup of boot process (ramdisk handling, etc.)
Have you thought about supporting .tar.gz into ramfs? Creating custom boot images would be simpler.
--
Manfred
Quoted 5 lines · Manfred Spraul
Quoted 2 lines
* large cleanup of boot process (ramdisk handling, etc.)
Have you thought about supporting .tar.gz into ramfs? Creating custom boot images would be simpler.
*uh*. It's definitely easier to do than it used to be, but I'm seriously sceptical about adding more cruft into the thing. Let's sort it out and then see what can be added to the sequences. At least now it's in one place and doesn't have to pull the tricks it used to need for dealing with IO...
(I presume that you mean "unpacking tar.gz into initrd/floppy-loaded ramdisk" and not "adding into ramfs a loader of tarballs" - the latter is out of question, as far as I'm concerned; such code belongs to do_mounts.c if it belongs anywhere at all)
IOW, look into init/do_mounts.c - that's the right place to do that stuff.
Cheers,
Al
Quoted 9 lines · Alexander Viro
Quoted 2 lines
Have you thought about supporting .tar.gz into ramfs? Creating custom boot images would be simpler.
*uh*. It's definitely easier to do than it used to be, but I'm seriously sceptical about adding more cruft into the thing. ...
(I presume that you mean "unpacking tar.gz into initrd/floppy-loaded ramdisk" and not "adding into ramfs a loader of tarballs" - the latter is out of question, as far as I'm concerned;
Yes, indeed.
Quoted 4 lines
such code belongs to
do_mounts.cif it belongs anywhere at all)IOW, look into
init/do_mounts.c- that's the right place to do that stuff.
Methinks there are at least two possibilities that could do everything we might need here without unnecessary complications.
One is just mount a ramdisk and extract a tarball into its root. Yes, this has some problems -- how do you load tar when you haven't set up your root? -- but I suspect they can be solved. At worst, this would involve some strictly limited kluge to do that.
A better approach might be to find or invent a generic compressed file system. Given that, you just build a compressed root, copy an image of it into ramdisk and let the compressed FS driver handle it from there. I suspect such a driver might be useful elsewhere as well. Does one exist?
Quoted 4 lines · Sandy Harris
One is just mount a ramdisk and extract a tarball into its root. Yes, this has some problems -- how do you load tar when you haven't set up your root? -- but I suspect they can be solved. At worst, this would involve some strictly limited kluge to do that.
No kludges actually needed. "Simplified boot sequence" _is_ simplified - we overmount the "final" root over ramfs. Initially empty. So you have the normal environment when you load ramdisk, etc.
IOW, with the namespaces patch you can have root (empty, writable) as soon as you've registered ramfs driver. I.e. _very_ early - before device initialization, for one thing. Actual mounting of the "final" root happen very late, along with all initrd games, etc. That stuff (in do_mounts.c) could be executed as userland process, actually - see the comments in init/do_mounts.c and actual code there.
Cheers,
Al
Quoted 3 lines · Alexander Viro
No kludges actually needed. "Simplified boot sequence" _is_ simplified - we overmount the "final" root over ramfs. Initially empty. So you have the normal environment when you load ramdisk, etc.
So is this the Holy Grail, err, union mount we've discussed about one year ago ? I.e.
stat foo # output A
mount /dev/whatever /
stat foo # output B
with A != B ?
If yes, is there also a way to destroy/empty ramfs after this ?
- Werner
Signature · 3 lines
_________________________________________________________________________ / Werner Almesberger, ICA, EPFL, CH [email protected] / /_IN_N_032__Tel_+41_21_693_6621__Fax_+41_21_693_6610_____________________/
Quoted 7 lines · Werner Almesberger
Quoted 3 lines · Alexander Viro
No kludges actually needed. "Simplified boot sequence" _is_ simplified - we overmount the "final" root over ramfs. Initially empty. So you have the normal environment when you load ramdisk, etc.
So is this the Holy Grail, err, union mount we've discussed about one year ago ? I.e.
No. Just an overmount. Final root ends up mounted atop of absolute root - see comments in fs/super.c:mount_root() and in init/do_mounts.c
Quoted 5 lines
stat foo # output A
mount/dev/whatever/
stat foo # output Bwith A != B ?
We end with forced chroot to covering one. Due to details of path_walk() it's unbreakable even for root (well, barring the direct access to kernel data structures via /dev/kmem ;-)
So yes, you'll see the covering fs. Chech do_chroot() in init/do_mounts.c
Quoted 1 line
If yes, is there also a way to destroy/empty ramfs after this ?
At the end of boot process we are left with (at most) 8 dentries, 8 inodes and no data pages on ramfs. Is it worth emptying? I can do that (reduce to 1 dentry/1 inode), just add sys_rmdir() and sys_unlink() calls in the end of init/do_mounts.c:prepare_namespace(), but I don't really see the point of it.
Fs _is_ covered - you don't get its objects after mouting the final root.
BTW, Werner - could you take a look at the prepare_namespace()/handle_initrd()? That's our late boot process taken into one place. I'm really not happy about the following:
a) initrd with /linuxrc exec'ing init leaves init with PID > 1.
Is it a good idea? I've reproduced the behaviour we have in the main tree, but I have a bad feeling about it. For one thing, init is killable that way. Not good...
b) can we _please_ kill the real_root_dev sysctl?
c) you had plans for mandating non-exiting /linuxrc. What's the status
of these plans? I'd be glad if we could pull that one off... More than half of handle_initrd() implements the behaviour for the case when /linuxrc does exit and I would be only happy to remove that cruft. AFAICS both RH and Debian have /linuxrc that _does_ exit, though...
Again, current patch reproduces the behaviour of the main tree. Every boot setup that used to work should stay working - that was the design goal. I want to, erm, concentrate the existing logics in one place and make it readable before even thinking of changing behaviour.
I've tested it with all combinations that end up with root on local fs (initrd or not, ramdisks from floppies, devfs mounted or not and their combinations, with different variants of /linuxrc in cases that did initrd). I didn't do exhaustive testing for NFS-root. If someone can find a setup that works with official tree and doesn't work with the patched one - yell. I consider that as a bug.
BTW, people with rootfs=... patches may find that in this variant their patches would become _much_ simpler - they can actually call sys_mount() to mount the final root.
Don't get me wrong - I would be glad to see both rootfs=... and tar patches done atop of that namespace/s_lock (and archive them, keep up-to-date, put on FTP, etc). Just don't expect me to _merge_ them until their counterparts get merged into the Linus' tree (or this patch ends up these, but that won't happen until 2.5).
IOW, I consider the boot-process part of the patch as cleanup of existing code. If it makes some experiments easier - great, but in _that_ respect namespace patch is in permanent feature freeze. Unless behaviour is accepted by Linus - it won't get merged.
Cheers,
Al
Quoted 1 line · Alexander Viro
No. Just an overmount.
Ah, too bad. Union mounts would have been really elegant (allowing the operation to be repeated without residues, and also allowing umounting of the covered FS as a sanity check). But I guess there's no way to implement them without performance penalty ...
Quoted 1 line
Is it worth emptying?
Probably not ... the only interesting case would be if you could completely umount it.
Quoted 2 lines
BTW, Werner - could you take a look at the
prepare_namespace()/handle_initrd()?
Okay, I'll have a look.
Quoted 2 lines
That's our late boot process taken into one place. I'm really not happy about the following:
Agreed on all three counts. Also, change_root might just die by evolution, just like most of NFS-root-from-initrd (using change_root) died.
What we need is a migration plan. Right now, it seems that most people still use change_root. Hopefully they read the little message I left them in linux/Documentation/initrd.txt:
Current kernels still support it, but you should _not_ rely on its continued availability.
So with some luck, distributors will switch to pivot_root sometime soon, when deploying 2.4. So if we drop all the old junk in 2.5, the amount of letter bombs should be small ;-)
Quoted 1 line
Again, current patch reproduces the behaviour of the main tree.
Since you've already done all the work ... ;-) It's good if we can make one change at a time.
- Werner
Signature · 3 lines
_________________________________________________________________________ / Werner Almesberger, ICA, EPFL, CH [email protected] / /_IN_N_032__Tel_+41_21_693_6621__Fax_+41_21_693_6610_____________________/
Quoted 7 lines · Werner Almesberger
Quoted 1 line · Alexander Viro
No. Just an overmount.
Ah, too bad. Union mounts would have been really elegant (allowing the operation to be repeated without residues, and also allowing umounting of the covered FS as a sanity check). But I guess there's no way to implement them without performance penalty ...
There is no way to implement them without credentials' cache. Which needs to be done for many other reasons, but that's a separate patch and separate story. If it's done - no serious penalty involved. However, I doubt that we want a union on / itself. /dev - sure, /bin and /lib - maybe, but /... What for?
Quoted 4 lines
Quoted 1 line
Is it worth emptying?
Probably not ... the only interesting case would be if you could completely umount it.
What's the point in unmounting it? Let the root of the mount tree be fixed - it actually simplifies the things big way. Not that we had any performance penalty for having the thing in place - after this forced chroot we never touch it in lookups. BTW, pivot_root() is simpler that way.
BTW, we probably want to add mount --move <old> <new> - atomically moving a subtree from one place to another. Code is there, we just need to decide on API. Andries?
Quoted 3 lines
So with some luck, distributors will switch to
pivot_rootsometime soon, when deploying 2.4. So if we drop all the old junk in 2.5, the amount of letter bombs should be small ;-)
Tomorrow I'll try to catch Erik and talk with him about that. I'm not sure that I know anyone in Debian Install System Team (oh, boy... somebody sure loved capital letters). And I've absolutely no idea who is doing that stuff in other distributions...
Cheers,
Al
Quoted 5 lines · Alexander Viro
There is no way to implement them without credentials' cache. Which needs to be done for many other reasons, but that's a separate patch and separate story. If it's done - no serious penalty involved. However, I doubt that we want a union on / itself. /dev - sure, /bin and /lib - maybe, but /... What for?
What I'd really like to do is remount / somewhere with mount --bind, mount over it another skeleton file system which hides setuid programs and some directories and then run a chrooted sshd in the new root. If I'm not missing something, this would make creation of secure chroot environments very easy.
Quoted 2 lines
Tomorrow I'll try to catch Erik and talk with him about that. I'm not sure that I know anyone in Debian Install System Team (oh, boy... somebody sure
Just write to [email protected].
Signature · 2 lines
ciao, Marco
Quoted 7 lines · Marco d'Itri
Quoted 5 lines · Alexander Viro
There is no way to implement them without credentials' cache. Which needs to be done for many other reasons, but that's a separate patch and separate story. If it's done - no serious penalty involved. However, I doubt that we want a union on / itself. /dev - sure, /bin and /lib - maybe, but /... What for?
Quoted 5 lines
What I'd really like to do is remount / somewhere with mount --bind, mount over it another skeleton file system which hides setuid programs and some directories and then run a chrooted sshd in the new root. If I'm not missing something, this would make creation of secure chroot environments very easy.
I'm making NOSUID per-mountpoint. So
pid = clone(CLONE_NEWNS,0);
if (!pid) {
...
remount everything with nosuid
exec sshd
}should be OK
As for hiding the directories - also easy, mount --bind an empty immutable directory over each of them.
NODEV is also easy to make per-mountpoint, but readonly may be trickier; we need permission() to take vfsmount+dentry instead of inode for that. Doable, but will touch quite a few places.
New version uploaded on ftp.math.psu.edu/pub/viro/namespaces-a-S2.gz
Changes:
* nosuid, nodev and noexec are per-mountpoint now.
* new flag for mount() - MS_MOVE (move a subtree, probable syntax
for mount(8) - mount --move old new; old must be a mountpoint)
* Fixes for "lazy" umount.
* CLONE_NEWNS is made root-only (CAP_SYS_ADMIN, actually)
Folks, please help with testing. Again, It Works Here(tm).
Cheers,
Al
New version uploaded on ftp.math.psu.edu/pub/viro/namespaces-d-S2.gz
Changes:
* fixed an idiotic bug in get_filesystem_info() that din't
unfortunately) show up on UP.
* nosuid/nodev/noexec work in any combinations (had been b0rken in
previous version).
* fixed multiple-mount (had been b0rken; --bind worked, but attempt
to mount the device you've already had mounted did bad things).
* sanity checks for mount --move were missing. Fixed.
* Assorted cleanups.
Folks, please help with testing.
Cheers,
Al
Quoted 1 line · Alexander Viro
*
CLONE_NEWNSis made root-only (CAP_SYS_ADMIN, actually)
Would an unprivileged version that killed setuid be OK to have?
Evil idea of the day: non-directory (even non-existant) mount points and non-directory mounts. So then "mount --bind /etc/foo /dev/bar" works.
Quoted 5 lines · Albert D. Cahalan
Quoted 1 line · Alexander Viro
*
CLONE_NEWNSis made root-only (CAP_SYS_ADMIN, actually)Would an unprivileged version that killed setuid be OK to have?
Not until we get decent resource accounting here.
Quoted 2 lines
Evil idea of the day: non-directory (even non-existant) mount points and non-directory mounts. So then "mount --bind
/etc/foo/dev/bar" works.
Try it. It _does_ work.
Quoted 4 lines · Alexander Viro
Quoted 2 lines
Evil idea of the day: non-directory (even non-existant) mount points and non-directory mounts. So then "mount --bind
/etc/foo/dev/bar" works.Try it. It _does_ work.
Yeah, mount --bind is cool, I've been using it on one of my projects today. But - maybe I'm just not thinking creatively enough - what are the advantages of mount --bind versus just symlinking?
Also, I tried mount --bind fileone filetwo, and it fails if filetwo doesn't exist. ('mount point filetwo doesn't exist'). Is that supposed to work? (using mount from latest redhat beta)
BTW, pivot_root is nifty, too. ;-)
regards,
David
Signature · 3 lines
David L. Parsley Network Administrator Roanoke College
Quoted 9 lines · David L. Parsley
Quoted 4 lines · Alexander Viro
Quoted 2 lines
Evil idea of the day: non-directory (even non-existant) mount points and non-directory mounts. So then "mount --bind
/etc/foo/dev/bar" works.Try it. It _does_ work.
Yeah, mount --bind is cool, I've been using it on one of my projects today. But - maybe I'm just not thinking creatively enough - what are the advantages of mount --bind versus just symlinking?
1) Correctly working ".." (obviously relevant only for directories)
2) Try to create symlinks on read-only NFS mount. For bonus points, try to do that one one client without disturbing everybody else.
3) Try to make it different for different users, for that matter.
Quoted 3 lines
Also, I tried mount --bind fileone filetwo, and it fails if filetwo doesn't exist. ('mount point filetwo doesn't exist'). Is that supposed to work? (using mount from latest redhat beta)
Nope. It does exactly what it should - changing that is a too large can of worms I simply don't want to touch.
Quoted 1 line
BTW,
pivot_rootis nifty, too. ;-)
Thank Werner for that ;-)
Quoted 10 lines · Alexander Viro
Quoted 3 lines · David L. Parsley
Yeah, mount --bind is cool, I've been using it on one of my projects today. But - maybe I'm just not thinking creatively enough - what are the advantages of mount --bind versus just symlinking?
1) Correctly working ".." (obviously relevant only for directories)
2) Try to create symlinks on read-only NFS mount. For bonus points, try to do that one one client without disturbing everybody else.
3) Try to make it different for different users, for that matter.
And disadvantages: you can't have broken symlinks.
This actually turns out to be quite a bit of a problem when one tries to use bind mounts with autofs. For one thing, it's perfectly legal to have /autofs/foo as a symlink to /autofs/bar/foo, where /autofs/bar is not yet mounted -- but a bind mount can't handle that...
Ion
Signature · 2 lines
It is better to keep your mouth shut and be thought a fool,
than to open it and remove all doubt.Quoted 13 lines · Ion Badulescu
Quoted 10 lines · Alexander Viro
Quoted 3 lines · David L. Parsley
Yeah, mount --bind is cool, I've been using it on one of my projects today. But - maybe I'm just not thinking creatively enough - what are the advantages of mount --bind versus just symlinking?
1) Correctly working ".." (obviously relevant only for directories)
2) Try to create symlinks on read-only NFS mount. For bonus points, try to do that one one client without disturbing everybody else.
3) Try to make it different for different users, for that matter.
Quoted 6 lines
And disadvantages: you can't have broken symlinks.
This actually turns out to be quite a bit of a problem when one tries to use bind mounts with autofs. For one thing, it's perfectly legal to have /autofs/foo as a symlink to /autofs/bar/foo, where /autofs/bar is not yet mounted -- but a bind mount can't handle that...
First of all, you still have symlinks. What's more, the right solution is to use local objects at the mountpoints. And forget about having a small tree full of links to real mountpoints. Think of autofs-with-one-node.
Quoted 8 lines · Alexander Viro
Quoted 6 lines
And disadvantages: you can't have broken symlinks.
This actually turns out to be quite a bit of a problem when one tries to use bind mounts with autofs. For one thing, it's perfectly legal to have /autofs/foo as a symlink to /autofs/bar/foo, where /autofs/bar is not yet mounted -- but a bind mount can't handle that...
First of all, you still have symlinks.
Oh yeah, of course. :-)
Quoted 3 lines
What's more, the right solution is to use local objects at the mountpoints. And forget about having a small tree full of links to real mountpoints. Think of autofs-with-one-node.
That's what Sun's autofs and am-utils call 'direct mounts', which are not yet supported by our autofs (unless I missed something recently). Direct mounts are good for some things, but not for everything. In particular, they are useless for cascading auto-triggered mounts (think /usr/local/src, /usr/local, and /usr, all automounted).
[and, btw, Linux _still_ doesn't properly support am-utils' direct mounts, although all that's needed is to remove LOOKUP_FOLLOW from path_init in sys_umount...]
As for bind mounts, I'll probably revisit them after I'm done with the Solaris autofs support in am-utils -- which will probably be a while. If I can get the thing to chain-trigger all the necessary mounts, we might be able to do something useful with it..
Thanks,
Ion
Signature · 2 lines
It is better to keep your mouth shut and be thought a fool,
than to open it and remove all doubt.Quoted 8 lines · Albert D. Cahalan
Quoted 1 line · Alexander Viro
*
CLONE_NEWNSis made root-only (CAP_SYS_ADMIN, actually)Would an unprivileged version that killed setuid be OK to have?
Evil idea of the day: non-directory (even non-existant) mount points and non-directory mounts. So then "mount --bind
/etc/foo/dev/bar" works.
BTW, out of curiosity: what's that evil about non-directory mounts? You obviously shouldn't mix directories with non-directories in that context (userland will not take that lightly, same as with rename(), etc.), but binding a non-directory over non-directory... Why not? Me, I'm playing with
% mount -t devloop /tmp/image /dev/loop0 -o offset=4096
Yes, in that order. /dev/loop0 is the mountpoint here. ioctls? We don't need on stinkin' ioctls. Now, _that_ I would call evil... Pretty simple, actually - filesystem with ->read_super() making ->s_root not a directory but a block device. And setting it up (lo_set_fd() with small modifications). Still alpha, requires namespace patch (or at least s_lock one), but seems to be working. Simpler than loop.c in official tree, BTW - no ioctls, no handling pending requests since we unset device only upon umount, when we have nobody keeping it open. losetup? What losetup? Shell script, if somebody would bother to write it (going through losetup options and turning them into mount ones).
Quoted 4 lines · In article <[email protected]> you wrote:
A better approach might be to find or invent a generic compressed file system. Given that, you just build a compressed root, copy an image of it into ramdisk and let the compressed FS driver handle it from there. I suspect such a driver might be useful elsewhere as well. Does one exist?
cramfs is compressed but read-only, jffs has the potential to do compressed writes as well....
Greetings,
Arjan van de Ven
Quoted 5 lines · [email protected] said:
Quoted 2 lines
Have you thought about supporting .tar.gz into ramfs? Creating custom boot images would be simpler.
*uh*. It's definitely easier to do than it used to be, but I'm seriously sceptical about adding more cruft into the thing.
The really neat part of untarring into a ramfs-root is that it allows you to remove a whole pile of other unnecessary cruft - ll_rw_blk and all the other crap for dealing with block devices and buffer_heads.
CONFIG_BLK_DEV=n
--
dwmw2