FS#30526 - mkinitcpio gives zero opportunity for any hook to see the resolved root path

Attached to Project: Arch Linux
Opened by C Anthony Risinger (extofme) - Wednesday, 04 July 2012, 01:59 GMT
Last edited by Dave Reisner (falconindy) - Wednesday, 04 July 2012, 12:32 GMT
Task Type Bug Report
Category Arch Projects
Status Closed
Assigned To Dave Reisner (falconindy)
Architecture All
Severity Medium
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

DEFECT:

mkinitcpio used to (IIRC) resolve the root device before calling hooks, thereby allowing hooks to know the canonical name for / (if it exists). this no longer seems to be true; thus mount hooks can no longer easily use:

root=UUID=XXXX
root=LABEL=XXXX

... or other non-path directives mkinitcpio is capable of handling. currently, mkinitcpio call hooks, resolves the root, mounts root, calls late hooks ... this gives zero opportunity for any hook to see the resolved path.

RESOLUTION:

resolve / before calling hooks.

ADDITIONAL:

https://aur.archlinux.org/packages.php?ID=33376
(Comment by: WorMzy on Tue, 26 Jun 2012 23:04:42 +0000)
This task depends upon

Closed by  Dave Reisner (falconindy)
Wednesday, 04 July 2012, 12:32 GMT
Reason for closing:  Not a bug
Additional comments about closing:  Working as intended.
Comment by Dave Reisner (falconindy) - Wednesday, 04 July 2012, 02:43 GMT
We've not changed when root is resolved -- it's still done in the same place as it has been for years, right after the normal hook run.

I'm not really sure what you're proposing as far as resolving root earlier. How is it possible to, for example, resolve an encrypted root device before running the encrypt hook?
Comment by Dave Reisner (falconindy) - Wednesday, 04 July 2012, 03:06 GMT
I'm looking at your hook and the order of operations makes no sense to me. Your error handling is intolerant of all the wrong things.

Here's my advice:

run_hook: this function needs to do very few things. run "modprobe btrfs", run "btrfs device scan", and then figure out what mount handler to use (you really should get rid of the deprecated one by now). In the world of devtmpfs, /dev/btrfs_control *will* show up. Have you checked to see how long that busy wait loop actually runs for? If you desperately want to know what root is, you can call resolve_device() yourself, but I really think you should avoid it.

btrfs_mount_handler: get rid of the explicit '-t btrfs' option for mount. We use util-linux's mount these days, which is smart enough to figure this out on its own. If this mount call fails (likely due to the subvol option being misunderstood), then fall back on the same mount call WITHOUT the subvol option. Additional note: PLEASE respect the user's choice of rw versus ro. You're defaulting to 'rw' here which I think is somewhat odd. AFTER mounting (assuming that it worked), feel free to check what filesystem type you actually mounted and continue on if its btrfs. This makes your hook far more resilient and willing to work with non-btrfs devices in case a foolish user includes this hook by accident.

The theme of early userspace is to do whatever it takes to mount root and get out. You can't possibly bail so early on something that can't be determined and consider it sane behavior on your part. I've attached an untested version of your hook with the changes I've described above. There's probably more improvements to be made, but this should get you moving on the right track.
Comment by C Anthony Risinger (extofme) - Wednesday, 04 July 2012, 04:59 GMT
hmm, fair enough; i hadn't thought about the encryption scenario, and i suppose even udev and whatnot are started via hook. i wasn't sure if this had even changed, and considering your response, i can only assume mounting via UUID/LABEL was always broken, and no one noticed and/or cared.

i'm not sure what you are referencing RE:intolerance and order-of-operations, but in all fairness, this hook has seen next to zero updates (or issues) since circa 2.6.32 or earlier, and was my first swing at anything in initramfs -- can't be too bad ;-)

regarding devtmpfs, the loop was added because /dev/btrfs_control was not showing up in a timely manner prior to calling `mount`, not because it may not show at all. in the past, things blew up if mount was called before it was there. yes, in my testing a full second could elapse after modprobe (again, ~3 years ago) -- 10 sec default was more-or-less arbitrary -- usually it was very fast.

i try to silently fail in the event the use switches root devices for whatever reason (eg. temporarily/briefly) but the initramfs is not updated and/or the hook skipped -- i see no reason to pointlessly install a new mount_handler, fail, and block the boot if it can otherwise be prevented. i do sort of like the idea of blindly mounting, inspecting the mount afterwards, and returning success if NOT btrfs ... if this is enough to replace the activities of the default handler, it seems reasonable. if anything, i will defer more checks to the actual handler instead of run_hook.

`-t btrfs` can be dropped, but the system is installed into a subvolume ... it MUST mount correctly or it might as well fail. the root subvol is for management only, has nothing to do with the standard directory hierarchy, and has no /sbin/init. `rw` exists because features were planned requiring a writable FS, such as auto-snap on boot, but are not yet implemented and thus `rw` is indeed unnecessary.

at any rate, i will evaluate your modifications and go from there -- thanks -- feel free to nuke this ticket.

Loading...