Here are some more thoughts. 11/15/2011 06:51 PM, anonym: > > We make home-{rw,sn} obsolete, and use live-{rw,sn} as the only way to > tell that "this is a live-boot compatible overlay/snapshot". When a > persistent media (i.e. with the right label/filename) is found by > live-boot, it looks for a file called .live-persistence.list (but I'll > continue calling it just ".list" for brevity) in its root.
Intrigeri made a good point about that .list doesn't have to be a hidden dot-file, and suggested the names "live.persist" or "live.persistent", both which I think are better. From now on I'll call the list of persistent directories "live.persist". > If it's not there, then it mounts the media on / just like it does > for live-rw currently. Perhaps it's better to have different labels for full persistence and custom mounts, e.g. live-{rw,sn} and custom-{rw,sn}? If one where to name live.persist incorrectly, one could potentially screw up (i.e. overwrite files in) one's custom mounts media, and we really want to avoid that. > But if .list is present, then it doesn't mount anything on /, it > instead bind-mounts the directories listed in .list to their > specified destinations. Instead of bind-mounting we could use union mounting, and the "diff"-part would be what we save on the persistent media. As it is now, live-rw is union mounted on the filesystem root exactly like that, but home-rw is mounted directly on /home, so whatever is in /home in the live system is hidden. Union mounts has the obvious benefits that they can save (potentially a lot of) space on the persistent media, and unions don't hide stuff (unless it's whited out) so we don't have to copy stuff from the live system's filesystem to the persistent media (more about this below). I don't thing unionmount supports making unions of directories, though, but OTOH it's not even listed as a supported union filesystem in the man page. Is unionmount only there for historical reasons? Can we deprecate it? That would allow to refactor union mounting quite nicely. Any way, I think I'm in favour of union-mounting instead of bind-mounting. Thoughts? > [...] > > In-depth example > ---------------- > > We want to have home-rw style persistence, but we also want the apt > cache in case of security upgrades and the occasional program we need > but are not installed on the image. So, inside our persistent media > $dev (either a file called live-rw.$EXT or a partition with label > live-rw), we put a .list containing: > > /home/user > /var/cache/apt > > When live-boot is supposed to mount $dev, it does so on some $mnt. It > checks for the existence of $mnt/.list, and since it's there it does: > > mount -o bind ${mnt}/home/user ${root}/home/user Or with e.g. aufs union-mounting, something like: mount -t aufs -o dirs=${mnt}/home/user=rw:${root}/home/user=ro \ ${root}/home/user > mount -o bind ${mnt}/var/cache/apt ${root}/var/cache/apt > > where $root is what will become the filesystem root after > initramfs. An interesting issue is what to do if the source on the persistent media (e.g. ${mnt}/home/user) and/or the destination in the live system (e.g. ${root}/home/user) don't exist. The particular examples I gave within parentheses is especially troubling since users are set up in live-config, i.e. after live-boot, so we lack user and group information for setting correct ownership. Missing mount destination in live system ---------------------------------------- If the destination doesn't exist, it obviously has to be auto-created by live-boot so we can mount on it. The only issue I can think of is ownership. Sure, since we will mount something on the destination, it will get the source's ownership, so that will be no problem (unless both source and destination are missing, see below). But what if the destination is ${root}/home/${USER}/a/b? First of all ${USER} hasn't been set up yet (it'll be done in live-config) so ${root}/home/${USER} doesn't exist, and we don't have access to ${USER}'s uid and guid to set ownership correctly. Even if $USER was setup ${root}/home/${USER}/a doesn't exist, so we must create it and give it a sane ownership. I guess the following will work except in very complex ownership situations: Case: The desination is /$A/$B/$DIR, where all directories in /$A exist in the live system's filesystem, but none in /$A/$B/$DIR exist. What we do in live-boot: We simply "mkdir -p /$A/$B/$DIR" and give the newly create directories ownership as the last directory in $A. In other words, non-existing directories inherit the parent's ownership. Actually we don't care about $DIR's ownership as it will be a mount point. What we do in live-config: When we set up a $USER, if /home/$USER exists *and* has another owner than $USER, we do "chown -R $USER:$USER /home/$USER", then we continue as usual. (Note that checking the ownership makes it possible to run the chown command (which can be slow if there's a lot of files) *only* if the source has the wrong ownership -- this will be the case when the source is missing, as you can read about in the next section). AFAICT this will handle persistence anywhere gracefully as long as the ownership situation is like in a normal Debian install. The live-config stuff is only necessary for home directories since users are set up in live-config, but other directories with non-root owner's are usually (more like "always" I believe) set up when some package is installed, and thus that ownership info will be available in the live systems's filesystem, so it can be handled in live-boot. If a user needs more flexibility than this, s/he has to use either full persistence or make /$A persistent, and then create all of $B within the persistent media and manually set the complex ownership settings. Missing mount source on live media ---------------------------------- If the source doesn't exist, we should create it so users don't have to do that part as well, which could be error prone. But just creating the directories isn't enough; we need to make sure the source somehow contains the files that the destination contains in the live system, and that ownership is correct. E.g. if someone wants /etc to be persistent, then the live system's /etc has to be "contained" in the source somehow, otherwise the system won't boot. Fix: * If we use bind-mount we should bootstrap the source with the contents of the destination by copying it. Then we set ownership of the source to the same as the destination. * If we use union-mounting we just create the source and give it the same ownership as the destination. Missing both source and destination ----------------------------------- I think we can't handle this case w.r.t. ownership in any more or less bulletproof way. Either we skip such custom mounts and log a warning to the user, or we create both of them with root as owner. I think the latter is better, as the user then has the opportunity to manually fix the ownerships after the very first boot and then all will be well from then on since the changes are saved back to the persistent media. This has to be clearly documented, though. > Say that we also have another persistent media that contains the > following .list: > > /etc > /var > /home/user > > * /etc would be mounted as above without any second thoughts since > there's no possible mount hiding. > * /var would have to be mounted before /var/cache/apt in order to > avoid getting one mount hiding the other. Note: if the same list > would include both, we'd only bind /var, i.e we'd just ignore the > children. > * /home/user is problematic, since hiding is unavoidable. Hence we'd > only use the one appearing on the device we scanned first, and > reject all consecutive ones. For simplicity, let's just say that identical destinations/mount points (like the /home/user case) cause undefined behaviour. A single device will be selected and mounted on it, but we don't give any guarantees to which. Cheers!
signature.asc
Description: OpenPGP digital signature