This is basically the same as #234, except it turns out that a couple of the pre-requisite commits either never made it to RHEL7 or got dropped in the rebase. So I've added bd99015 and 8e5b65d, and now CDROM-swapping with `inst.ks=cdrom` should work in RHEL7. Yaaayyyyyyyyy~~~
From: Will Woods wwoods@redhat.com
Add a couple of utility functions:
* tell_user() sends a message to the log and the screen via plymouth; if plymouth isn't running we send it to the console instead.
* dev_is_cdrom() tells you whether the given device is a CDROM (according to udev).
(cherry picked from commit abfa908d089d18ce8d72ac818b62b33a1a12647a) --- dracut/anaconda-lib.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/dracut/anaconda-lib.sh b/dracut/anaconda-lib.sh index 9e74e3d..7a46058 100755 --- a/dracut/anaconda-lib.sh +++ b/dracut/anaconda-lib.sh @@ -165,6 +165,26 @@ when_any_cdrom_appears() { >> $rulesfile }
+plymouth_running() { + type plymouth >/dev/null 2>&1 && plymouth --ping 2>/dev/null +} + +# print something to the display (and put it in the log so we know what's up) +tell_user() { + if plymouth_running; then + # NOTE: if we're doing graphical splash but we don't have all the + # font-rendering libraries, no message will appear. + plymouth display-message --text="$*" + echo "$*" # this goes to journal only + else + echo "$*" >&2 # this goes to journal+console + fi +} + +dev_is_cdrom() { + udevadm info --query=property --name=$1 | grep -q 'ID_CDROM=1' +} + # dracut doesn't bring up the network unless: # a) $netroot is set (i.e. you have a network root device), or # b) /tmp/net.ifaces exists.
Added label: rhel7-branch.
From: Will Woods wwoods@redhat.com
Apparently this is a thing: some people do installs in secure environments where they have no network and aren't allowed to use USB devices; all they can use is optical media. So they have the install disc, and another cdrom that contains their kickstart.
So: the user boots the install DVD with "inst.ks=cdrom[:/path/ks.cfg]", and once udev notices the disc we run both fetch-kickstart-disk and anaconda-diskroot¹.
Normally, anaconda-diskroot would mount the installer DVD here, but we need to be able to eject it, so anaconda-diskroot instead ignores it and quietly exits.
Meanwhile, fetch-kickstart-disk tries to grab the kickstart and fails (because we're looking at the install DVD!), so it asks the user to insert the CDROM containing the kickstart.
So: when the user ejects the DVD and inserts their kickstart CD, fetch-kickstart-disk will fetch the kickstart and ask for the install media back.
Finally, the user re-inserts the DVD, anaconda-diskroot mounts it, and off we go!
¹I'm assuming the ordering is undefined. It might be predictable in reality but it's probably better if we don't rely on that.
Resolves: rhbz#1122104 (cherry picked from commit 5d016ef9451247ef569784a18600a83b92ea5d53) --- dracut/anaconda-diskroot | 11 +++++++++++ dracut/fetch-kickstart-disk | 15 +++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/dracut/anaconda-diskroot b/dracut/anaconda-diskroot index 2df6248..36fd49e 100755 --- a/dracut/anaconda-diskroot +++ b/dracut/anaconda-diskroot @@ -35,6 +35,17 @@ path="$2" # optional, could be empty
[ -e "/dev/root" ] && exit 1 # we already have a root device!
+# If we're waiting for a cdrom kickstart, the user might need to swap discs. +# So if this is a CDROM drive, make a note of it, but don't mount it (yet). +# Once we get the kickstart either the udev trigger or disk-reinsertion will +# retrigger this script, and we'll mount the disk as normal. +if str_starts "$kickstart" "cdrom" && [ ! -e /tmp/ks.cfg.done ]; then + if dev_is_cdrom "$dev"; then + > /tmp/anaconda-on-cdrom + exit 0 + fi +fi + info "anaconda using disk root at $dev" mount $dev $repodir || warn "Couldn't mount $dev" anaconda_live_root_dir $repodir $path diff --git a/dracut/fetch-kickstart-disk b/dracut/fetch-kickstart-disk index d9ead33..37a1050 100755 --- a/dracut/fetch-kickstart-disk +++ b/dracut/fetch-kickstart-disk @@ -14,16 +14,27 @@ info "anaconda: fetching kickstart from $dev:$path" mnt="$(find_mount $dev)"
if [ -n "$mnt" ]; then - cp $mnt$path /tmp/ks.cfg + cp $mnt$path /tmp/ks.cfg 2>&1 else tmpmnt="$(mkuniqdir /run/install tmpmnt)" if mount -o ro $dev $tmpmnt; then - cp $tmpmnt/$path /tmp/ks.cfg + cp $tmpmnt/$path /tmp/ks.cfg 2>&1 umount $tmpmnt rmdir $tmpmnt fi fi
+ +# if we're waiting for a cdrom kickstart, tell the user so they can swap discs +if str_starts "$kickstart" "cdrom"; then + if [ ! -f /tmp/ks.cfg ]; then + tell_user "Please insert CDROM containing '$path'..." + exit 0 + elif [ -f /tmp/anaconda-on-cdrom ]; then + tell_user "Kickstart loaded. Please re-insert installation media." + fi +fi + if [ -f /tmp/ks.cfg ]; then parse_kickstart /tmp/ks.cfg run_kickstart
From: Will Woods wwoods@redhat.com
Commit 5d016ef added support for doing cdrom-swapping while doing "inst.ks=cdrom[:...]". But it turns out that if you're slow to swap the discs, we'll hit dracut's retry timeout and it'll drop to the emergency shell.
So, in response to User Requests, we now disable the timeout entirely when using "inst.ks=cdrom[:...]"; dracut will wait forever for the kickstart and/or installer media, and if anything goes wrong you're just stuck and you'll need to reset.
Resolves: rhbz#1168902 (cherry picked from commit bc6378b2fed442e2f5a5d723ada9f87baed1e835) --- dracut/kickstart-genrules.sh | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dracut/kickstart-genrules.sh b/dracut/kickstart-genrules.sh index 3b83d6c1..7edfacd 100755 --- a/dracut/kickstart-genrules.sh +++ b/dracut/kickstart-genrules.sh @@ -19,6 +19,12 @@ case "${kickstart%%:*}" in when_diskdev_appears "$ksdev" \ fetch-kickstart-disk $env{DEVNAME} "$kspath" fi + # "cdrom:" also means "wait forever for kickstart" because rhbz#1168902 + if [ "$kstype" = "cdrom" ]; then + # if we reset main_loop to 0 every loop, we never hit the timeout. + # (see dracut's dracut-initqueue.sh for details on the mainloop) + echo "main_loop=0" > "$hookdir/initqueue/ks-cdrom-wait-forever.sh" + fi wait_for_kickstart ;; bd) # bd:<dev>:<path> - biospart (TODO... if anyone uses this anymore)
From: Will Woods wwoods@redhat.com
fetch-kickstart-disk and anaconda-diskroot are *executed*, not sourced, so they don't get the default dracut environment, so "$kickstart" isn't set, so "str_starts $kickstart cdrom" is always false, so the user never gets any of the "Please insert CDROM containing '$path'..." messages.
Set "$kickstart" from the boot args, and then this all works as expected.
Related: rhbz#1168902 (cherry picked from commit 672ee4fe918a54ef94c62e86bc71e0993b6f1dd1) --- dracut/anaconda-diskroot | 1 + dracut/fetch-kickstart-disk | 1 + 2 files changed, 2 insertions(+)
diff --git a/dracut/anaconda-diskroot b/dracut/anaconda-diskroot index 36fd49e..4ae7112 100755 --- a/dracut/anaconda-diskroot +++ b/dracut/anaconda-diskroot @@ -32,6 +32,7 @@ run_checkisomd5() {
dev="$1" path="$2" # optional, could be empty +kickstart="$(getarg ks= inst.ks=)"
[ -e "/dev/root" ] && exit 1 # we already have a root device!
diff --git a/dracut/fetch-kickstart-disk b/dracut/fetch-kickstart-disk index 37a1050..7eb769e 100755 --- a/dracut/fetch-kickstart-disk +++ b/dracut/fetch-kickstart-disk @@ -6,6 +6,7 @@ command -v getarg >/dev/null || . /lib/dracut-lib.sh
dev="$1" path="${2:-/ks.cfg}" +kickstart="$(getarg ks= inst.ks=)"
[ -e /tmp/ks.cfg.done ] && exit 1 [ -b "$dev" ] || exit 1
From: Will Woods wwoods@redhat.com
anaconda-lib has the `when_any_cdrom_appears` function for this exact purpose, so use that instead of handcrafting the udev rule.
(cherry picked from commit fdee9c29ff58b60f799d93565db8f9a0d6cec45f) --- dracut/repo-genrules.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dracut/repo-genrules.sh b/dracut/repo-genrules.sh index 55abd32..9f1d40e 100755 --- a/dracut/repo-genrules.sh +++ b/dracut/repo-genrules.sh @@ -14,9 +14,8 @@ case "$root" in ;; anaconda-auto-cd) # special catch-all rule for CDROMs - echo 'ENV{ID_CDROM}=="1",' \ - 'RUN+="/sbin/initqueue --settled --onetime' \ - '/sbin/anaconda-diskroot $env{DEVNAME}"' >> $rulesfile + when_any_cdrom_appears \ + anaconda-diskroot $env{DEVNAME} # HACK: anaconda demands that CDROMs be mounted at /mnt/install/source ln -s repo /run/install/source ;;
anaconda-patches@lists.fedorahosted.org