[PATCH 13/10] features: RUNDIR, imgdir, ... [update 2]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- don't use cp -t (due to busybox's cp)
- add intermediate link to image's tree, to simplify life in init;
  this allows us to switch whole image tree with single 'ln' manipulation,
  instead of going in loop through all /bin, /sbin, ... symlinks;
  we employ that early (see the next point) and before /run move (to not
  lose access to binaries)
- create $prefix (and $prefix_mnt) early, so everything is de-facto
  started from /run/$prefix
- keep /tmp and /var/tmp inside image tree
- simplify det_lib_paths() - make it essentially the same as before
  an earlier patch, but keep it as a separate function
- add a few comments and corner cases fixups

---
 dracut                           |   31 ++++++++++--------
 dracut-functions                 |   29 ++++++----------
 modules.d/99base/init            |   64 ++++++++++++++++++++++---------------
 modules.d/99base/module-setup.sh |    2 +-
 4 files changed, 67 insertions(+), 59 deletions(-)

diff --git a/dracut b/dracut
index 72af2c0..e26e0c3 100755
--- a/dracut
+++ b/dracut
@@ -502,7 +502,7 @@ readonly initdir=$(mktemp --tmpdir=/var/tmp/ -d -t initramfs.XXXXXX)
     dfatal "mktemp failed."
     exit 1
 }
-readonly imgdir=/_img newroot=/sysroot
+readonly imgdir=/_img imglnk=/__img newroot=/sysroot
 
 # clean up after ourselves no matter how we die.
 trap 'ret=$?;[[ $keep ]] && echo "Not removing $initdir." >&2 || rm -rf "$initdir";exit $ret;' EXIT
@@ -517,34 +517,38 @@ export initdir dracutbasedir dracutmodules drivers \
     add_drivers mdadmconf lvmconf filesystems \
     use_fstab libdir usrlibdir fscks nofscks cttyhack \
     stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
-    debug imgdir prefix prefix_mnt newroot
+    debug imgdir imglnk prefix prefix_mnt newroot
 
 # initial directory layout + host safe symlinks
 if [[ $kernel_only != yes ]]; then
-    for d in /{bin,sbin,etc,lib{,64},var,usr{,/{bin,sbin,lib{,64}}}}; do
+    # directories inside ${initdir}${imgdir}
+    for d in /{bin,sbin,etc,lib{64,},var{,/tmp},usr{,/{bin,sbin,lib{64,}}},tmp}; do
         if [[ -h $d ]]; then inst_symlink $d
         elif [[ -d $d ]]; then inst_dir $d; fi
     done
 
+    # directories inside ${initdir}
     mkdir -m 0755 -p \
-        "${initdir}"/{dev,proc,sys,${newroot#/},root,run{,/{lock,initramfs}},tmp}
+        "${initdir}"/{dev,proc,sys,run{,/{lock,initramfs}},root,${newroot#/}}
 
     # host safe symlinks (will be adjusted later), needed during inst*() calls
-    ln -sfn "${initdir}"/tmp      "${initdir}${imgdir}"/tmp
-    ln -sfn "${initdir}"/tmp      "${initdir}${imgdir}"/var/tmp
     ln -sfn "${initdir}"/run      "${initdir}${imgdir}"/run
     ln -sfn "${initdir}"/run      "${initdir}${imgdir}"/var/run
     ln -sfn "${initdir}"/run/lock "${initdir}${imgdir}"/var/lock
 else
-    for d in /lib{,64}; do
+    for d in /lib{64,}; do
         if [[ -h $d ]]; then inst_symlink $d
         elif [[ -d $d ]]; then inst_dir $d; fi
     done
 fi
+
 # initial sewing pass
+# go through intermediate symlink (${imglnk}) - this greatly simplifies our life
+# inside init
+ln -sfn "${imgdir#/}" "${initdir}${imglnk}"
 for d in "${initdir}${imgdir}"/*; do
     if [[ ! -e "${initdir}/${d##*/}" ]]; then
-        ln -sfn "${imgdir#/}/${d##*/}" "${initdir}/${d##*/}"
+        ln -sfn "${imglnk#/}/${d##*/}" "${initdir}/${d##*/}"
     fi
 done
 
@@ -669,11 +673,10 @@ if strstr "$modules_loaded" " fips " && command -v prelink >/dev/null; then
 fi
 
 # final sewing pass
-# remove helper /run & /tmp links, set symlinks to match initramfs's root, link
+# remove helper /run link, set symlinks to match initramfs's root, link
 # remaining directories (if any)
 if [[ $kernel_only != yes ]]; then
-    rm -f             "${initdir}${imgdir}"/{run,tmp}
-    ln -sfn /tmp      "${initdir}${imgdir}"/var/tmp
+    rm -f             "${initdir}${imgdir}"/run
     ln -sfn /run      "${initdir}${imgdir}"/var/run
     ln -sfn /run/lock "${initdir}${imgdir}"/var/lock
 fi
@@ -682,12 +685,12 @@ for d in "${initdir}${imgdir}"/*; do
     if [[ -h ${s} ]]; then
         # verify if everything is fine
         t=$(readlink "${s}")
-        if [[ $t != ${d#${initdir}/} ]]; then
-            dfatal "dracut: symlink mismatch ${d##*/} -/-> ${d#${initdir}/}"
+        if [[ $t != ${imglnk#/}/${d##*/} ]]; then
+            dfatal "dracut: symlink mismatch ${d##*/} -/-> ${imglnk#/}/${d##*/}"
             exit 1
         fi
     elif [[ ! -e ${s} ]]; then
-        ln -sfn "${d#${initdir}/}" "${s}"
+        ln -sfn "${imglnk#/}/${d##*/}" "${s}"
     fi
 done
 
diff --git a/dracut-functions b/dracut-functions
index 7b6aa5a..0298585 100755
--- a/dracut-functions
+++ b/dracut-functions
@@ -959,23 +959,16 @@ instmods() {
     return $?
 }
 
-# determine lib paths in specified prefix
-# if they point to the same, ignore the one that is a symlink
-# prefer lib64 over lib
+# determine lib paths in specified prefix ($1)
+# order of preference: lib64, lib, lib32
 function det_lib_paths() {
-    local _lib _d _d64
-    _d=$(readlink -e "$1/lib")
-    _d64=$(readlink -e "$1/lib64")
-    if [[ $_d = $_d64 ]]; then
-        [[ -h $1/lib ]] && unset _d
-        [[ -h $1/lib64 ]] && unset _d64
-    fi
-    if [[ -n $_d64 ]]; then
-        _lib=$1/lib64
-    elif [[ -n $_d ]]; then
-        _lib=$1/lib
-    else
-        return 1
-    fi
-    echo "$_lib"
+    local _lib
+
+    for _lib in "$1"/lib{64,}; do
+        if [[ -d $_lib ]]; then
+            echo "$_lib"
+            return 0
+        fi
+    done
+    return 1
 }
diff --git a/modules.d/99base/init b/modules.d/99base/init
index 0397e36..00fcc27 100755
--- a/modules.d/99base/init
+++ b/modules.d/99base/init
@@ -81,20 +81,44 @@ mount $_fs $_opt tmpfs /dev/shm >/dev/null 2>&1
 # Prepare proper tmpfs mount for /run:
 # - /run is just a symlink to real staging area. This allows us to be
 #   independent from any mount place, with trivial symlink manipulation
-# - checking if /run is premounted, is pretty crazy in initramfs ...
-
+# - it handles both: if /run is present with content and/or if it's mounted
 _opt="-o mode=0755,nosuid,nodev,exec"; _fs="-t tmpfs"
 RUNDIR=/_run
 ismounted /run && { _opt="$_opt,remount"; unset _fs; }
-mkdir -m 0755 -p $RUNDIR
+mkdir -m 0755 -p "$RUNDIR"
 # move + remount or mount
-[ -z "$_fs" ] && mount --move /run $RUNDIR
-mount $_fs $_opt tmpfs $RUNDIR >/dev/null 2>&1
+[ -z "$_fs" ] && mount --move /run "$RUNDIR"
+mount $_fs $_opt tmpfs "$RUNDIR" >/dev/null 2>&1
 # copy if mount
-[ -z "$_fs" ] || { cd /run; cp -a -t $RUNDIR .; cd /; }
+[ -n "$_fs" ] && { cd /run; cp -a . "$RUNDIR"; cd /; }
 # set symlink
 rm -rf /run
-ln -sfn ${RUNDIR#/} /run
+ln -sfn "${RUNDIR#/}" /run
+
+# Prepare (if applicable) image tree inside $PREFIX under /run; we do it
+# here, as we want to run everything de-facto from /run/$PREFIX/...
+if [ -n "$PREFIX" ]; then
+    mkdir -p -m 0755 "/run/.prefix"
+    cd "$IMGLNK"
+    cp -a . "/run/.prefix"
+    if [ -d "/run/$PREFIX" ]; then
+        cd "/run/$PREFIX"; cp -a . "/run/.prefix"; cd /
+        umount "/run/$PREFIX" >/dev/null 2>&1
+        rm -rf "/run/$PREFIX"
+    fi
+    if [ -n "$PREFIX_MNT" ]; then
+        mkdir -p -m 0755 "/run/$PREFIX"
+        mount -t tmpfs -o mode=0755,nosuid,nodev,exec tmpfs "/run/$PREFIX"
+        cd "/run/.prefix"; cp -a . "/run/$PREFIX"; cd /
+        rm -rf "/run/.prefix"
+    else
+        _tgt="/run/$PREFIX"
+        mkdir -p -m 0755 "${_tgt%/*}"
+        mv "/run/.prefix" "$_tgt"
+    fi
+    # switch intermediary link to the image tree we actually want to use
+    ln -sfn "run/$PREFIX" "$IMGLNK"
+fi
 
 UDEVVERSION=$(udevadm --version)
 if [ $UDEVVERSION -gt 166 ]; then
@@ -374,7 +398,7 @@ else
 fi
 [ "$RD_DEBUG" = "yes" ] && set -x
 
-# /run move, udev adjustment (if applicable), prefix handling
+# /run move, udev adjustment (if applicable)
 if [ -d "$NEWROOT/run" ]; then
     NEWRUN="$NEWROOT/run"
 else
@@ -388,30 +412,18 @@ else
     if [ -d /run/udev/data -o -d /run/udev/db ]; then
         mkdir -p -m 0755 /dev/.udev
         cd /run/udev
-        cp -a -t /dev/.udev .
+        cp -a . /dev/.udev
         cd /
         rm -rf /run/udev
     fi
 fi
 
-mount --move "$RUNDIR" "$NEWRUN"
+# if we earlier moved away from IMGDIR, go back to it - or we lose access to
+# binaries briefly
+[ -n "$PREFIX" ] && ln -sfn "${IMGDIR#/}" "$IMGLNK"
 ln -sfn "${NEWRUN#/}" /run
-
-if [ -n "$PREFIX" ]; then
-    if [ -d "$NEWRUN/$PREFIX" ]; then
-        [ -n "$PREFIX_MNT" ] &&
-            warn "'$NEWRUN/$PREFIX' already exists, dracut files will be copied directly to this directory"
-        unset PREFIX_MNT
-    else
-        mkdir -p -m 0755 "$NEWRUN/$PREFIX"
-    fi
-    if [ -n "$PREFIX_MNT" ]; then
-        mount -t tmpfs -o mode=0755,nosuid,nodev,exec tmpfs "$NEWRUN/$PREFIX"
-    fi
-    cd "$IMGDIR"
-    cp -a -t "$NEWRUN/$PREFIX" .
-    cd /
-fi
+mount --move "$RUNDIR" "$NEWRUN"
+[ -n "$PREFIX" ] && ln -sfn "${NEWRUN#/}/$PREFIX" "$IMGLNK"
 
 wait_for_loginit
 
diff --git a/modules.d/99base/module-setup.sh b/modules.d/99base/module-setup.sh
index 4c64bca..2a59699 100755
--- a/modules.d/99base/module-setup.sh
+++ b/modules.d/99base/module-setup.sh
@@ -41,7 +41,7 @@ install() {
     [ -x /lib/systemd/systemd-timestamp ] && inst /lib/systemd/systemd-timestamp
 
     # export certain settings to init
-    for _d in newroot imgdir prefix prefix_mnt; do
+    for _d in newroot imgdir imglnk prefix prefix_mnt; do
         _x=$(echo $_d | tr "a-z" "A-Z")
         [ -n "$_d" ] && echo "${_x}=${!_d}" >>${initdir}/etc/dracut-init.conf
     done
-- 
1.7.7.1

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux