JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3RbrJFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3RbrPK!Z1#modules.d/03modsign/module-setup.shnuȯ#!/bin/bash # # Licensed under the GPLv2 # # Copyright 2013 Red Hat, Inc. # Peter Jones # called by dracut check() { require_binaries keyctl || return 1 # do not include module in hostonly mode, # if no keys are present if [[ $hostonly ]]; then x=$(echo /lib/modules/keys/*) [[ "${x}" = "/lib/modules/keys/*" ]] && return 255 fi return 0 } # called by dracut depends() { return 0 } # called by dracut install() { inst_dir /lib/modules/keys inst_binary keyctl inst_hook pre-trigger 01 "$moddir/load-modsign-keys.sh" for x in /lib/modules/keys/* ; do [[ "${x}" = "/lib/modules/keys/*" ]] && break inst_simple "${x}" done } PK!`~(modules.d/03modsign/load-modsign-keys.shnuȯ#!/bin/sh # # Licensed under the GPLv2 # # Copyright 2013 Red Hat, Inc. # Peter Jones for x in /lib/modules/keys/* ; do [ "${x}" = "/lib/modules/keys/*" ] && break keyctl padd asymmetric "" @s < ${x} done PK!/modules.d/95nvmf/parse-nvmf-boot-connections.shnuȯ#!/bin/sh # # Supported formats: # nvmf.hostnqn= # nvmf.hostid= # nvmf.discover=::: # # Examples: # nvmf.hostnqn=nqn.2014-08.org.nvmexpress:uuid:37303738-3034-584d-5137-333230423843 # nvmf.discover=rdma:192.168.1.3::4420 # nvme.discover=tcp:192.168.1.3::4420 # nvme.discover=tcp:192.168.1.3 # nvmf.discover=fc:auto # # Note: FC does autodiscovery, so typically there is no need to # specify any discover parameters for FC. # type is_ip >/dev/null 2>&1 || . /lib/net-lib.sh if getargbool 0 rd.nonvmf ; then warn "rd.nonvmf=0: skipping nvmf" return 0 fi initqueue --onetime modprobe --all -b -q nvme nvme_tcp nvme_core nvme_fabrics traddr="none" trtype="none" hosttraddr="none" trsvcid=4420 validate_ip_conn() { if ! getargbool 0 rd.neednet ; then warn "$trtype transport requires rd.neednet=1" return 1 fi local_address=$(ip -o route get to $traddr | sed -n 's/.*src \([0-9a-f.:]*\).*/\1/p') # confirm we got a local IP address if ! is_ip "$local_address" ; then warn "$traddr is an invalid address"; return 1 fi ifname=$(ip -o route get to $local_address | sed -n 's/.*dev \([^ ]*\).*/\1/p') if ip l show "$ifname" >/dev/null 2>&1 ; then warn "invalid network interface $ifname" return 1 fi # confirm there's a route to destination if ip route get "$traddr" >/dev/null 2>&1 ; then warn "no route to $traddr" return 1 fi } parse_nvmf_discover() { OLDIFS="$IFS" IFS=: set $1 IFS="$OLDIFS" case $# in 2) [ -n "$1" ] && trtype=$1 [ -n "$2" ] && traddr=$2 ;; 3) [ -n "$1" ] && trtype=$1 [ -n "$2" ] && traddr=$2 [ -n "$3" ] && hosttraddr=$3 ;; 4) [ -n "$1" ] && trtype=$1 [ -n "$2" ] && traddr=$2 [ -n "$3" ] && hosttraddr=$3 [ -n "$4" ] && trsvcid=$4 ;; *) warn "Invalid arguments for nvmf.discover=$1" return 1 ;; esac if [ "$traddr" = "none" ] ; then warn "traddr is mandatory for $trtype" return 1; fi if [ "$trtype" = "fc" ] ; then if [ "$hosttraddr" = "none" ] ; then warn "host traddr is mandatory for fc" return 1 fi elif [ "$trtype" != "rdma" ] && [ "$trtype" != "tcp" ] ; then warn "unsupported transport $trtype" return 1 fi if [ "$trtype" = "tcp" ]; then validate_ip_conn fi echo "--transport=$trtype --traddr=$traddr --host-traddr=$hosttraddr --trsvcid=$trsvcid" >> /etc/nvme/discovery.conf } nvmf_hostnqn=$(getarg nvmf.hostnqn=) if [ -n "$nvmf_hostnqn" ] ; then echo "$nvmf_hostnqn" > /etc/nvme/hostnqn fi nvmf_hostid=$(getarg nvmf.hostid=) if [ -n "$nvmf_hostid" ] ; then echo "$nvmf_hostid" > /etc/nvme/hostid fi for d in $(getargs nvmf.discover=); do parse_nvmf_discover "$d" done # Host NQN and host id are mandatory for NVMe-oF [ -f "/etc/nvme/hostnqn" ] || exit 0 [ -f "/etc/nvme/hostid" ] || exit 0 if [ -f "/etc/nvme/discovery.conf" ] ; then if [ "$trtype" = "tcp" ] ; then /sbin/initqueue --settled --onetime --unique --name nvme-discover /usr/sbin/nvme connect-all > /tmp/net.$ifname.did-setup else /sbin/initqueue --onetime --unique --name nvme-discover /usr/sbin/nvme connect-all fi else if [ "$trtype" = "tcp" ] ; then /sbin/initqueue --settled --onetime --unique /usr/sbin/nvme connect-all -t tcp -a $traddr -s $trsvcid > /tmp/net.$ifname.did-setup else /sbin/initqueue --finished --onetime --unique --name nvme-fc-autoconnect /sbin/nvmf-autoconnect.sh fi fi PK!o$modules.d/95nvmf/nvmf-autoconnect.shnu[#!/bin/bash [ -f /sys/class/fc/fc_udev_device/nvme_discovery ] || exit 1 echo add > /sys/class/fc/fc_udev_device/nvme_discovery exit 0 PK!m> modules.d/95nvmf/module-setup.shnuȯ#!/bin/bash # called by dracut check() { require_binaries nvme || return 1 [ -f /etc/nvme/hostnqn ] || return 255 [ -f /etc/nvme/hostid ] || return 255 is_nvmf() { local _dev=$1 local trtype [[ -L "/sys/dev/block/$_dev" ]] || return 0 cd -P "/sys/dev/block/$_dev" || return 0 if [ -f partition ] ; then cd .. fi for d in device/nvme* ; do [ -L "$d" ] || continue if readlink "$d" | grep -q nvme-fabrics ; then trtype=$(cat "$d"/transport) break fi done [[ "$trtype" == "fc" ]] || [[ "$trtype" == "tcp" ]] || [[ "$trtype" == "rdma" ]] } [[ $hostonly ]] || [[ $mount_needs ]] && { pushd . >/dev/null for_each_host_dev_and_slaves is_nvmf local _is_nvmf=$? popd >/dev/null [[ $_is_nvmf == 0 ]] || return 255 if [ ! -f /sys/class/fc/fc_udev_device/nvme_discovery ] ; then if [ ! -f /etc/nvme/discovery.conf ] ; then echo "No discovery arguments present" return 255 fi fi } return 0 } # called by dracut depends() { echo bash rootfs-block network return 0 } # called by dracut installkernel() { instmods nvme_fc lpfc qla2xxx hostonly="" instmods nvme_tcp nvme_fabrics } # called by dracut cmdline() { local _hostnqn local _hostid if [ -f /etc/nvme/hostnqn ] ; then _hostnqn=$(cat /etc/nvme/hostnqn) echo -n " nvmf.hostnqn=${_hostnqn}" fi if [ -f /etc/nvme/hostid ] ; then _hostid=$(cat /etc/nvme/hostid) echo -n " nvmf.hostid=${_hostid}" fi echo "" } # called by dracut install() { if [[ $hostonly_cmdline == "yes" ]]; then local _nvmf_args=$(cmdline) [[ "$_nvmf_args" ]] && printf "%s" "$_nvmf_args" >> "${initdir}/etc/cmdline.d/95nvmf-args.conf" fi inst_simple "/etc/nvme/hostnqn" inst_simple "/etc/nvme/hostid" inst_multiple ip sed inst_script "${moddir}/nvmf-autoconnect.sh" /sbin/nvmf-autoconnect.sh inst_multiple nvme inst_multiple -o \ "$systemdsystemunitdir/nvm*-connect@.service" \ "$systemdsystemunitdir/nvm*-connect.target" inst_hook cmdline 99 "$moddir/parse-nvmf-boot-connections.sh" inst_simple "/etc/nvme/discovery.conf" inst_rules /usr/lib/udev/rules.d/70-nvm*-autoconnect.rules inst_rules /usr/lib/udev/rules.d/71-nvmf-iopolicy-netapp.rules dracut_need_initqueue } PK!"55,modules.d/97biosdevname/parse-biosdevname.shnuȯ#!/bin/sh if ! getargbool 1 biosdevname; then info "biosdevname=0: removing biosdevname network renaming" udevproperty UDEV_BIOSDEVNAME= rm -f -- /etc/udev/rules.d/71-biosdevname.rules else info "biosdevname=1: activating biosdevname network renaming" udevproperty UDEV_BIOSDEVNAME=1 fi PK!S'modules.d/97biosdevname/module-setup.shnuȯ#!/bin/bash # called by dracut check() { [[ "$mount_needs" ]] && return 1 require_binaries biosdevname || return 1 return 0 } # called by dracut depends() { return 0 } # called by dracut install() { inst_multiple biosdevname inst_rules 71-biosdevname.rules } PK! H&modules.d/95ssh-client/module-setup.shnuȯ#!/bin/bash # fixme: assume user is root # called by dracut check() { [[ $mount_needs ]] && return 1 # If our prerequisites are not met, fail. require_binaries ssh scp || return 1 if [[ $sshkey ]]; then [ ! -f $sshkey ] && { derror "ssh key: $sshkey is not found!" return 1 } fi return 255 } # called by dracut depends() { # We depend on network modules being loaded echo network } inst_sshenv() { if [ -d /root/.ssh ]; then inst_dir /root/.ssh chmod 700 ${initdir}/root/.ssh fi # Copy over ssh key and knowhosts if needed [[ $sshkey ]] && { inst_simple $sshkey [[ -f /root/.ssh/known_hosts ]] && inst_simple /root/.ssh/known_hosts [[ -f /etc/ssh/ssh_known_hosts ]] && inst_simple /etc/ssh/ssh_known_hosts } # Copy over root and system-wide ssh configs. [[ -f /root/.ssh/config ]] && inst_simple /root/.ssh/config if [[ -f /etc/ssh/ssh_config ]]; then inst_simple /etc/ssh/ssh_config sed -i -e 's/\(^[[:space:]]*\)ProxyCommand/\1# ProxyCommand/' ${initdir}/etc/ssh/ssh_config while read key val || [ -n "$key" ]; do if [[ $key == "GlobalKnownHostsFile" ]]; then inst_simple "$val" # Copy customized UserKnowHostsFile elif [[ $key == "UserKnownHostsFile" ]]; then # Make sure that ~/foo will be copied as /root/foo in kdump's initramfs if str_starts "$val" "~/"; then val="/root/${val#"~/"}" fi inst_simple "$val" fi done < /etc/ssh/ssh_config fi return 0 } # called by dracut install() { local _nsslibs inst_multiple ssh scp inst_sshenv _nsslibs=$(sed -e '/^#/d' -e 's/^.*://' -e 's/\[NOTFOUND=return\]//' /etc/nsswitch.conf \ | tr -s '[:space:]' '\n' | sort -u | tr -s '[:space:]' '|') _nsslibs=${_nsslibs#|} _nsslibs=${_nsslibs%|} inst_libdir_file -n "$_nsslibs" 'libnss_*.so*' } PK!imodules.d/99base/initqueue.shnuȯ#!/bin/sh # # Licensed under the GPLv2+ # # Copyright 2008-2010, Red Hat, Inc. # Harald Hoyer PATH=/usr/sbin:/usr/bin:/sbin:/bin type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh while [ $# -gt 0 ]; do case "$1" in --onetime) onetime="yes";; --online) qname="/online";; --settled) qname="/settled";; --finished) qname="/finished";; --timeout) qname="/timeout";; --unique) unique="yes";; --name) name="$2";shift;; --env) env="$2"; shift;; *) break;; esac shift done if [ -z "$unique" ]; then job="${name}$$" else job="${name:-$1}" job=${job##*/} fi exe=$1 shift [ -x "$exe" ] || exe=$(command -v $exe) if [ -z "$exe" ] ; then echo "Invalid command" exit 1 fi { [ -n "$onetime" ] && echo '[ -e "$job" ] && rm -f -- "$job"' [ -n "$env" ] && echo "$env" echo "$exe" "$@" } > "/tmp/$$-${job}.sh" mv -f "/tmp/$$-${job}.sh" "$hookdir/initqueue${qname}/${job}.sh" [ -z "$qname" ] && >> $hookdir/initqueue/work exit 0 PK!@..modules.d/99base/init.shnuȯ#!/bin/sh # # Licensed under the GPLv2 # # Copyright 2008-2010, Red Hat, Inc. # Harald Hoyer # Jeremy Katz export -p > /tmp/export.orig NEWROOT="/sysroot" [ -d $NEWROOT ] || mkdir -p -m 0755 $NEWROOT OLDPATH=$PATH PATH=/usr/sbin:/usr/bin:/sbin:/bin export PATH # mount some important things [ ! -d /proc/self ] && \ mount -t proc -o nosuid,noexec,nodev proc /proc >/dev/null if [ "$?" != "0" ]; then echo "Cannot mount proc on /proc! Compile the kernel with CONFIG_PROC_FS!" exit 1 fi [ ! -d /sys/kernel ] && \ mount -t sysfs -o nosuid,noexec,nodev sysfs /sys >/dev/null if [ "$?" != "0" ]; then echo "Cannot mount sysfs on /sys! Compile the kernel with CONFIG_SYSFS!" exit 1 fi RD_DEBUG="" . /lib/dracut-lib.sh setdebug if ! ismounted /dev; then mount -t devtmpfs -o mode=0755,noexec,nosuid,strictatime devtmpfs /dev >/dev/null fi if ! ismounted /dev; then echo "Cannot mount devtmpfs on /dev! Compile the kernel with CONFIG_DEVTMPFS!" exit 1 fi # prepare the /dev directory [ ! -h /dev/fd ] && ln -s /proc/self/fd /dev/fd >/dev/null 2>&1 [ ! -h /dev/stdin ] && ln -s /proc/self/fd/0 /dev/stdin >/dev/null 2>&1 [ ! -h /dev/stdout ] && ln -s /proc/self/fd/1 /dev/stdout >/dev/null 2>&1 [ ! -h /dev/stderr ] && ln -s /proc/self/fd/2 /dev/stderr >/dev/null 2>&1 if ! ismounted /dev/pts; then mkdir -m 0755 /dev/pts mount -t devpts -o gid=5,mode=620,noexec,nosuid devpts /dev/pts >/dev/null fi if ! ismounted /dev/shm; then mkdir -m 0755 /dev/shm mount -t tmpfs -o mode=1777,noexec,nosuid,nodev,strictatime tmpfs /dev/shm >/dev/null fi if ! ismounted /run; then mkdir -m 0755 /newrun if ! str_starts "$(readlink -f /bin/sh)" "/run/"; then mount -t tmpfs -o mode=0755,noexec,nosuid,nodev,strictatime tmpfs /newrun >/dev/null else # the initramfs binaries are located in /run, so don't mount it with noexec mount -t tmpfs -o mode=0755,nosuid,nodev,strictatime tmpfs /newrun >/dev/null fi cp -a /run/* /newrun >/dev/null 2>&1 mount --move /newrun /run rm -fr -- /newrun fi if command -v kmod >/dev/null 2>/dev/null; then kmod static-nodes --format=tmpfiles 2>/dev/null | \ while read type file mode a a a majmin || [ -n "$type" ]; do type=${type%\!} case $type in d) mkdir -m $mode -p $file ;; c) mknod -m $mode $file $type ${majmin%:*} ${majmin#*:} ;; esac done fi trap "emergency_shell Signal caught!" 0 export UDEVVERSION=$(udevadm --version | { read v _ ; echo $v ; }) if [ $UDEVVERSION -gt 166 ]; then # newer versions of udev use /run/udev/rules.d export UDEVRULESD=/run/udev/rules.d [ -d /run/udev ] || mkdir -p -m 0755 /run/udev [ -d $UDEVRULESD ] || mkdir -p -m 0755 $UDEVRULESD else mkdir -m 0755 /dev/.udev /dev/.udev/rules.d export UDEVRULESD=/dev/.udev/rules.d fi if [ "$RD_DEBUG" = "yes" ]; then mkfifo /run/initramfs/loginit.pipe loginit $DRACUT_QUIET /dev/console 2>&1 & exec >/run/initramfs/loginit.pipe 2>&1 else exec 0<>/dev/console 1<>/dev/console 2<>/dev/console fi [ -f /usr/lib/initrd-release ] && . /usr/lib/initrd-release [ -n "$VERSION_ID" ] && info "$NAME-$VERSION_ID" source_conf /etc/conf.d if getarg "rd.cmdline=ask"; then echo "Enter additional kernel command line parameter (end with ctrl-d or .)" while read -p "> " line || [ -n "$line" ]; do [ "$line" = "." ] && break echo "$line" >> /etc/cmdline.d/99-cmdline-ask.conf done fi if ! getargbool 1 'rd.hostonly'; then [ -f /etc/cmdline.d/99-cmdline-ask.conf ] && mv /etc/cmdline.d/99-cmdline-ask.conf /tmp/99-cmdline-ask.conf remove_hostonly_files [ -f /tmp/99-cmdline-ask.conf ] && mv /tmp/99-cmdline-ask.conf /etc/cmdline.d/99-cmdline-ask.conf fi # run scriptlets to parse the command line make_trace_mem "hook cmdline" '1+:mem' '1+:iomem' '3+:slab' getarg 'rd.break=cmdline' -d 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline" source_hook cmdline [ -z "$root" ] && die "No or empty root= argument" [ -z "$rootok" ] && die "Don't know how to handle 'root=$root'" export root rflags fstype netroot NEWROOT # pre-udev scripts run before udev starts, and are run only once. make_trace_mem "hook pre-udev" '1:shortmem' '2+:mem' '3+:slab' getarg 'rd.break=pre-udev' -d 'rdbreak=pre-udev' && emergency_shell -n pre-udev "Break before pre-udev" source_hook pre-udev UDEV_LOG=err getargbool 0 rd.udev.info -d -y rdudevinfo && UDEV_LOG=info getargbool 0 rd.udev.debug -d -y rdudevdebug && UDEV_LOG=debug # start up udev and trigger cold plugs UDEV_LOG=$UDEV_LOG $systemdutildir/systemd-udevd --daemon --resolve-names=never UDEV_QUEUE_EMPTY="udevadm settle --timeout=0" if [ $UDEVVERSION -lt 140 ]; then UDEV_QUEUE_EMPTY="udevadm settle --timeout=1" fi udevproperty "hookdir=$hookdir" make_trace_mem "hook pre-trigger" '1:shortmem' '2+:mem' '3+:slab' getarg 'rd.break=pre-trigger' -d 'rdbreak=pre-trigger' && emergency_shell -n pre-trigger "Break before pre-trigger" source_hook pre-trigger udevadm control --reload >/dev/null 2>&1 || : # then the rest udevadm trigger --type=subsystems --action=add >/dev/null 2>&1 udevadm trigger --type=devices --action=add >/dev/null 2>&1 make_trace_mem "hook initqueue" '1:shortmem' '2+:mem' '3+:slab' getarg 'rd.break=initqueue' -d 'rdbreak=initqueue' && emergency_shell -n initqueue "Break before initqueue" RDRETRY=$(getarg rd.retry -d 'rd_retry=') RDRETRY=${RDRETRY:-180} RDRETRY=$(($RDRETRY*2)) export RDRETRY main_loop=0 export main_loop while :; do check_finished && break udevsettle check_finished && break if [ -f $hookdir/initqueue/work ]; then rm -f -- $hookdir/initqueue/work fi for job in $hookdir/initqueue/*.sh; do [ -e "$job" ] || break job=$job . $job check_finished && break 2 done $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue for job in $hookdir/initqueue/settled/*.sh; do [ -e "$job" ] || break job=$job . $job check_finished && break 2 done $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue # no more udev jobs and queues empty. sleep 0.5 if [ $main_loop -gt $((2*$RDRETRY/3)) ]; then for job in $hookdir/initqueue/timeout/*.sh; do [ -e "$job" ] || break job=$job . $job udevadm settle --timeout=0 >/dev/null 2>&1 || main_loop=0 [ -f $hookdir/initqueue/work ] && main_loop=0 done fi main_loop=$(($main_loop+1)) [ $main_loop -gt $RDRETRY ] \ && { flock -s 9 ; emergency_shell "Could not boot."; } 9>/.console_lock done unset job unset queuetriggered unset main_loop unset RDRETRY # pre-mount happens before we try to mount the root filesystem, # and happens once. make_trace_mem "hook pre-mount" '1:shortmem' '2+:mem' '3+:slab' getarg 'rd.break=pre-mount' -d 'rdbreak=pre-mount' && emergency_shell -n pre-mount "Break pre-mount" source_hook pre-mount getarg 'rd.break=mount' -d 'rdbreak=mount' && emergency_shell -n mount "Break mount" # mount scripts actually try to mount the root filesystem, and may # be sourced any number of times. As soon as one suceeds, no more are sourced. _i_mount=0 while :; do if ismounted "$NEWROOT"; then usable_root "$NEWROOT" && break; umount "$NEWROOT" fi for f in $hookdir/mount/*.sh; do [ -f "$f" ] && . "$f" if ismounted "$NEWROOT"; then usable_root "$NEWROOT" && break; warn "$NEWROOT has no proper rootfs layout, ignoring and removing offending mount hook" umount "$NEWROOT" rm -f -- "$f" fi done _i_mount=$(($_i_mount+1)) [ $_i_mount -gt 20 ] \ && { flock -s 9 ; emergency_shell "Can't mount root filesystem"; } 9>/.console_lock done { printf "Mounted root filesystem " while read dev mp rest || [ -n "$dev" ]; do [ "$mp" = "$NEWROOT" ] && echo $dev; done < /proc/mounts } | vinfo # pre pivot scripts are sourced just before we doing cleanup and switch over # to the new root. make_trace_mem "hook pre-pivot" '1:shortmem' '2+:mem' '3+:slab' getarg 'rd.break=pre-pivot' -d 'rdbreak=pre-pivot' && emergency_shell -n pre-pivot "Break pre-pivot" source_hook pre-pivot make_trace_mem "hook cleanup" '1:shortmem' '2+:mem' '3+:slab' # pre pivot cleanup scripts are sourced just before we switch over to the new root. getarg 'rd.break=cleanup' -d 'rdbreak=cleanup' && emergency_shell -n cleanup "Break cleanup" source_hook cleanup # By the time we get here, the root filesystem should be mounted. # Try to find init. for i in "$(getarg real_init=)" "$(getarg init=)" $(getargs rd.distroinit=) /sbin/init; do [ -n "$i" ] || continue __p=$(readlink -f "${NEWROOT}/${i}") if [ -x "$__p" -o -x "${NEWROOT}/${__p}" ]; then INIT="$i" break fi done [ "$INIT" ] || { echo "Cannot find init!" echo "Please check to make sure you passed a valid root filesystem!" emergency_shell } if [ $UDEVVERSION -lt 168 ]; then # stop udev queue before killing it udevadm control --stop-exec-queue HARD="" while pidof udevd >/dev/null 2>&1; do for pid in $(pidof udevd); do kill $HARD $pid >/dev/null 2>&1 done HARD="-9" done else udevadm control --exit udevadm info --cleanup-db fi debug_off # Turn off debugging for this section # unexport some vars export_n root rflags fstype netroot NEWROOT export RD_TIMESTAMP # Clean up the environment for i in $(export -p); do i=${i#declare -x} i=${i#export} strstr "$i" "=" || continue i=${i%%=*} [ -z "$i" ] && continue case $i in root|PATH|HOME|TERM|PS4|RD_*) :;; *) unset "$i";; esac done . /tmp/export.orig 2>/dev/null || : rm -f -- /tmp/export.orig initargs="" read CLINE /dev/null ; then ignoreargs="console BOOT_IMAGE" # only pass arguments after init= to the init CLINE=${CLINE#*init=} set -- $CLINE shift # clear out the rest of the "init=" arg for x in "$@"; do for s in $ignoreargs; do [ "${x%%=*}" = $s ] && continue 2 done initargs="$initargs $x" done unset CLINE else debug_off # Turn off debugging for this section set -- $CLINE for x in "$@"; do case "$x" in [0-9]|s|S|single|emergency|auto ) \ initargs="$initargs $x" ;; esac done fi debug_on if ! [ -d "$NEWROOT"/run ]; then NEWRUN=/dev/.initramfs mkdir -m 0755 "$NEWRUN" mount --rbind /run/initramfs "$NEWRUN" fi wait_for_loginit # remove helper symlink [ -h /dev/root ] && rm -f -- /dev/root bv=$(getarg rd.break -d rdbreak) && [ -z "$bv" ] && emergency_shell -n switch_root "Break before switch_root" unset bv info "Switching root" unset PS4 CAPSH=$(command -v capsh) SWITCH_ROOT=$(command -v switch_root) PATH=$OLDPATH export PATH if [ -f /etc/capsdrop ]; then . /etc/capsdrop info "Calling $INIT with capabilities $CAPS_INIT_DROP dropped." unset RD_DEBUG exec $CAPSH --drop="$CAPS_INIT_DROP" -- \ -c "exec switch_root \"$NEWROOT\" \"$INIT\" $initargs" || \ { warn "Command:" warn capsh --drop=$CAPS_INIT_DROP -- -c exec switch_root "$NEWROOT" "$INIT" $initargs warn "failed." emergency_shell } else unset RD_DEBUG exec $SWITCH_ROOT "$NEWROOT" "$INIT" $initargs || { warn "Something went very badly wrong in the initramfs. Please " warn "file a bug against dracut." emergency_shell } fi PK!Tmodules.d/99base/loginit.shnuȯ#!/bin/sh # turn off debugging set +x QUIET=$1 printf -- "$$" > /run/initramfs/loginit.pid [ -e /dev/kmsg ] && exec 5>/dev/kmsg || exec 5>/dev/null exec 6>/run/initramfs/init.log while read line || [ -n "$line" ]; do if [ "$line" = "DRACUT_LOG_END" ]; then rm -f -- /run/initramfs/loginit.pipe exit 0 fi echo "<31>dracut: $line" >&5 # if "quiet" is specified we output to /dev/console [ -n "$QUIET" ] || echo "dracut: $line" echo "$line" >&6 done PK!-6bBBmodules.d/99base/rdsosreport.shnuȯ#!/bin/sh echo 'Generating "/run/initramfs/rdsosreport.txt"' [ -d /run/initramfs ] || mkdir -p /run/initramfs exec >/run/initramfs/rdsosreport.txt 2>&1 PWFILTER='s/\(ftp:\/\/.*\):.*@/\1:*******@/g;s/\(cifs:\/\/.*\):.*@/\1:*******@/g;s/cifspass=[^ ]*/cifspass=*******/g;s/iscsi:.*@/iscsi:******@/g;s/rd.iscsi.password=[^ ]*/rd.iscsi.password=******/g;s/rd.iscsi.in.password=[^ ]*/rd.iscsi.in.password=******/g' set -x cat /lib/dracut/dracut-* cat /proc/cmdline | sed -e "$PWFILTER" [ -f /etc/cmdline ] && cat /etc/cmdline | sed -e "$PWFILTER" for _i in /etc/cmdline.d/*.conf; do [ -f "$_i" ] || break echo $_i cat $_i | sed -e "$PWFILTER" done cat /proc/self/mountinfo cat /proc/mounts blkid blkid -o udev ls -l /dev/disk/by* for _i in /etc/conf.d/*.conf; do [ -f "$_i" ] || break echo $_i cat $_i | sed -e "$PWFILTER" done if command -v lvm >/dev/null 2>/dev/null; then lvm pvdisplay lvm vgdisplay lvm lvdisplay fi command -v dmsetup >/dev/null 2>/dev/null && dmsetup ls --tree cat /proc/mdstat command -v ip >/dev/null 2>/dev/null && ip addr if command -v journalctl >/dev/null 2>/dev/null; then journalctl -ab --no-pager -o short-monotonic | sed -e "$PWFILTER" else dmesg | sed -e "$PWFILTER" [ -f /run/initramfs/init.log ] && cat /run/initramfs/init.log | sed -e "$PWFILTER" fi PK!`J#modules.d/99base/parse-root-opts.shnuȯ#!/bin/sh root=$(getarg root=) rflags="$(getarg rootflags=)" getargbool 0 ro && rflags="${rflags},ro" getargbool 0 rw && rflags="${rflags},rw" rflags="${rflags#,}" fstype="$(getarg rootfstype=)" if [ -z "$fstype" ]; then fstype="auto" fi PK!tg   modules.d/99base/module-setup.shnuȯ#!/bin/bash # called by dracut check() { return 0 } # called by dracut depends() { echo udev-rules return 0 } # called by dracut install() { local _d inst_multiple mount mknod mkdir sleep chroot chown \ sed ls flock cp mv dmesg rm ln rmmod mkfifo umount readlink setsid inst $(command -v modprobe) /sbin/modprobe inst_multiple -o findmnt less kmod if [ ! -e "${initdir}/bin/sh" ]; then inst_multiple bash (ln -s bash "${initdir}/bin/sh" || :) fi #add common users in /etc/passwd, it will be used by nfs/ssh currently grep '^root:' "$initdir/etc/passwd" 2>/dev/null || echo 'root:x:0:0::/root:/bin/sh' >> "$initdir/etc/passwd" grep '^nobody:' /etc/passwd >> "$initdir/etc/passwd" # install our scripts and hooks inst_script "$moddir/init.sh" "/init" inst_script "$moddir/initqueue.sh" "/sbin/initqueue" inst_script "$moddir/loginit.sh" "/sbin/loginit" inst_script "$moddir/rdsosreport.sh" "/sbin/rdsosreport" [ -e "${initdir}/lib" ] || mkdir -m 0755 -p ${initdir}/lib mkdir -m 0755 -p ${initdir}/lib/dracut mkdir -m 0755 -p ${initdir}/lib/dracut/hooks mkdir -p ${initdir}/tmp inst_simple "$moddir/dracut-lib.sh" "/lib/dracut-lib.sh" mkdir -p "${initdir}/var" if ! dracut_module_included "systemd"; then inst_multiple switch_root || dfatal "Failed to install switch_root" inst_hook cmdline 10 "$moddir/parse-root-opts.sh" inst_multiple -o $systemdutildir/systemd-timestamp fi if [[ $realinitpath ]]; then for i in $realinitpath; do echo "rd.distroinit=$i" done > "${initdir}/etc/cmdline.d/distroinit.conf" fi ln -fs /proc/self/mounts "$initdir/etc/mtab" if [[ $ro_mnt = yes ]]; then echo ro >> "${initdir}/etc/cmdline.d/base.conf" fi local VERSION="" local PRETTY_NAME="" if [ -e /etc/os-release ]; then . /etc/os-release [[ -n ${VERSION} ]] && VERSION+=" " [[ -n ${PRETTY_NAME} ]] && PRETTY_NAME+=" " fi NAME=dracut ID=dracut VERSION+="dracut-$DRACUT_VERSION" PRETTY_NAME+="dracut-$DRACUT_VERSION (Initramfs)" VERSION_ID=$DRACUT_VERSION ANSI_COLOR="0;31" [ -e "${initdir}/usr/lib" ] || mkdir -m 0755 -p ${initdir}/usr/lib { echo NAME=\"$NAME\" echo VERSION=\"$VERSION\" echo ID=$ID echo VERSION_ID=$VERSION_ID echo PRETTY_NAME=\"$PRETTY_NAME\" echo ANSI_COLOR=\"$ANSI_COLOR\" } > $initdir/usr/lib/initrd-release echo dracut-$DRACUT_VERSION > $initdir/lib/dracut/dracut-$DRACUT_VERSION ln -sf ../usr/lib/initrd-release $initdir/etc/initrd-release ln -sf initrd-release $initdir/usr/lib/os-release ln -sf initrd-release $initdir/etc/os-release ## save host_devs which we need bring up if [[ $hostonly_cmdline == "yes" ]]; then if [[ -n "${host_devs[@]}" ]]; then dracut_need_initqueue fi if [[ -f "$initdir/lib/dracut/need-initqueue" ]] || ! dracut_module_included "systemd"; then ( if dracut_module_included "systemd"; then DRACUT_SYSTEMD=1 fi PREFIX="$initdir" . "$moddir/dracut-lib.sh" for _dev in "${host_devs[@]}"; do for _dev2 in "${root_devs[@]}"; do [[ "$_dev" == "$_dev2" ]] && continue 2 done # We only actually wait for real devs - swap is only needed # for resume and udev rules generated when parsing resume= # argument take care of the waiting for us for _dev2 in "${swap_devs[@]}"; do [[ "$_dev" == "$_dev2" ]] && continue 2 done _pdev=$(get_persistent_dev $_dev) case "$_pdev" in /dev/?*) wait_for_dev $_pdev;; *) ;; esac done ) fi fi } PK!8P؃؃modules.d/99base/dracut-lib.shnuȯ#!/bin/sh export DRACUT_SYSTEMD export NEWROOT if [ -n "$NEWROOT" ]; then [ -d $NEWROOT ] || mkdir -p -m 0755 $NEWROOT fi if ! [ -d /run/initramfs ]; then mkdir -p -m 0755 /run/initramfs/log ln -sfn /run/initramfs/log /var/log fi [ -d /run/lock ] || mkdir -p -m 0755 /run/lock [ -d /run/log ] || mkdir -p -m 0755 /run/log debug_off() { set +x } debug_on() { [ "$RD_DEBUG" = "yes" ] && set -x } # returns OK if $1 contains literal string $2 (and isn't empty) strstr() { [ "${1##*"$2"*}" != "$1" ] } # returns OK if $1 matches (completely) glob pattern $2 # An empty $1 will not be considered matched, even if $2 is * which technically # matches; as it would match anything, it's not an interesting case. strglob() { [ -n "$1" -a -z "${1##$2}" ] } # returns OK if $1 contains (anywhere) a match of glob pattern $2 # An empty $1 will not be considered matched, even if $2 is * which technically # matches; as it would match anything, it's not an interesting case. strglobin() { [ -n "$1" -a -z "${1##*$2*}" ] } # returns OK if $1 contains literal string $2 at the beginning, and isn't empty str_starts() { [ "${1#"$2"*}" != "$1" ] } # returns OK if $1 contains literal string $2 at the end, and isn't empty str_ends() { [ "${1%*"$2"}" != "$1" ] } trim() { local var="$*" var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters printf "%s" "$var" } if [ -z "$DRACUT_SYSTEMD" ]; then warn() { check_quiet echo "<28>dracut Warning: $*" > /dev/kmsg echo "dracut Warning: $*" >&2 } info() { check_quiet echo "<30>dracut: $*" > /dev/kmsg [ "$DRACUT_QUIET" != "yes" ] && \ echo "dracut: $*" >&2 } else warn() { echo "Warning: $*" >&2 } info() { echo "$*" } fi vwarn() { while read line || [ -n "$line" ]; do warn $line; done } vinfo() { while read line || [ -n "$line" ]; do info $line; done } # replaces all occurrences of 'search' in 'str' with 'replacement' # # str_replace str search replacement # # example: # str_replace ' one two three ' ' ' '_' str_replace() { local in="$1"; local s="$2"; local r="$3" local out='' while strstr "${in}" "$s"; do chop="${in%%"$s"*}" out="${out}${chop}$r" in="${in#*"$s"}" done echo "${out}${in}" } killall_proc_mountpoint() { local _pid local _t local _killed=0 for _pid in /proc/*; do _pid=${_pid##/proc/} case $_pid in *[!0-9]*) continue;; esac [ -e "/proc/$_pid/exe" ] || continue [ -e "/proc/$_pid/root" ] || continue if strstr "$(ls -l -- "/proc/$_pid" "/proc/$_pid/fd" 2>/dev/null)" "$1" ; then kill -9 "$_pid" _killed=1 fi done return $_killed } getcmdline() { local _line local _i local CMDLINE_ETC_D local CMDLINE_ETC local CMDLINE_PROC unset _line if [ -e /etc/cmdline ]; then while read -r _line || [ -n "$_line" ]; do CMDLINE_ETC="$CMDLINE_ETC $_line"; done ", we want the exact match if [ "$_o" = "$1" ]; then _val="1"; unset _doecho fi continue fi if [ "${_o#*=}" = "$_o" ]; then # if cmdline argument has no "=", we assume "=1" _val="1"; unset _doecho continue fi _val="${_o#*=}" _doecho=1 fi done if [ -n "$_val" ]; then [ "x$_doecho" != "x" ] && echo "$_val"; return 0; fi return 1; } getarg() { debug_off local _deprecated _newoption while [ $# -gt 0 ]; do case $1 in -d) _deprecated=1; shift;; -y) if _dogetarg $2 >/dev/null; then if [ "$_deprecated" = "1" ]; then [ -n "$_newoption" ] && warn "Kernel command line option '$2' is deprecated, use '$_newoption' instead." || warn "Option '$2' is deprecated." fi echo 1 debug_on return 0 fi _deprecated=0 shift 2;; -n) if _dogetarg $2 >/dev/null; then echo 0; if [ "$_deprecated" = "1" ]; then [ -n "$_newoption" ] && warn "Kernel command line option '$2' is deprecated, use '$_newoption=0' instead." || warn "Option '$2' is deprecated." fi debug_on return 1 fi _deprecated=0 shift 2;; *) if [ -z "$_newoption" ]; then _newoption="$1" fi if _dogetarg $1; then if [ "$_deprecated" = "1" ]; then [ -n "$_newoption" ] && warn "Kernel command line option '$1' is deprecated, use '$_newoption' instead." || warn "Option '$1' is deprecated." fi debug_on return 0; fi _deprecated=0 shift;; esac done debug_on return 1 } # getargbool # False if "getarg " returns "0", "no", or "off". # True if getarg returns any other non-empty string. # If not found, assumes - usually 0 for false, 1 for true. # example: getargbool 0 rd.info # true: rd.info, rd.info=1, rd.info=xxx # false: rd.info=0, rd.info=off, rd.info not present (default val is 0) getargbool() { local _b unset _b local _default _default="$1"; shift _b=$(getarg "$@") [ $? -ne 0 -a -z "$_b" ] && _b="$_default" if [ -n "$_b" ]; then [ $_b = "0" ] && return 1 [ $_b = "no" ] && return 1 [ $_b = "off" ] && return 1 fi return 0 } isdigit() { case "$1" in *[!0-9]*|"") return 1;; esac return 0 } # getargnum # Will echo the arg if it's in range [minval - maxval]. # If it's not set or it's not valid, will set it . # Note all values are required to be >= 0 here. # should be with [minval -maxval]. getargnum() { local _b unset _b local _default _min _max _default="$1"; shift _min="$1"; shift _max="$1"; shift _b=$(getarg "$1") [ $? -ne 0 -a -z "$_b" ] && _b=$_default if [ -n "$_b" ]; then isdigit "$_b" && _b=$(($_b)) && \ [ $_b -ge $_min ] && [ $_b -le $_max ] && echo $_b && return fi echo $_default } _dogetargs() { debug_off local _o _found _key unset _o unset _found CMDLINE=$(getcmdline) _key="$1" set -- for _o in $CMDLINE; do if [ "$_o" = "$_key" ]; then _found=1; elif [ "${_o%%=*}" = "${_key%=}" ]; then [ -n "${_o%%=*}" ] && set -- "$@" "${_o#*=}"; _found=1; fi done if [ -n "$_found" ]; then [ $# -gt 0 ] && printf '%s' "$*" return 0 fi return 1; } getargs() { debug_off local _val _i _args _gfound _deprecated unset _val unset _gfound _newoption="$1" _args="$@" set -- for _i in $_args; do if [ "$_i" = "-d" ]; then _deprecated=1 continue fi _val="$(_dogetargs $_i)" if [ $? -eq 0 ]; then if [ "$_deprecated" = "1" ]; then [ -n "$_newoption" ] && warn "Option '$_i' is deprecated, use '$_newoption' instead." || warn "Option $_i is deprecated!" fi _gfound=1 fi [ -n "$_val" ] && set -- "$@" "$_val" _deprecated=0 done if [ -n "$_gfound" ]; then if [ $# -gt 0 ]; then printf '%s' "$*" fi debug_on return 0 fi debug_on return 1; } # Prints value of given option. If option is a flag and it's present, # it just returns 0. Otherwise 1 is returned. # $1 = options separated by commas # $2 = option we are interested in # # Example: # $1 = cipher=aes-cbc-essiv:sha256,hash=sha256,verify # $2 = hash # Output: # sha256 getoptcomma() { local line=",$1,"; local opt="$2"; local tmp case "${line}" in *,${opt}=*,*) tmp="${line#*,${opt}=}" echo "${tmp%%,*}" return 0 ;; *,${opt},*) return 0;; esac return 1 } # Splits given string 'str' with separator 'sep' into variables 'var1', 'var2', # 'varN'. If number of fields is less than number of variables, remaining are # not set. If number of fields is greater than number of variables, the last # variable takes remaining fields. In short - it acts similary to 'read'. # # splitsep sep str var1 var2 varN # # example: # splitsep ':' 'foo:bar:baz' v1 v2 # in result: # v1='foo', v2='bar:baz' # # TODO: ':' inside fields. splitsep() { debug_off local sep="$1"; local str="$2"; shift 2 local tmp while [ -n "$str" -a "$#" -gt 1 ]; do tmp="${str%%$sep*}" eval "$1='${tmp}'" str="${str#"$tmp"}" str="${str#$sep}" shift done [ -n "$str" -a -n "$1" ] && eval "$1='$str'" debug_on return 0 } setdebug() { [ -f /usr/lib/initrd-release ] || return if [ -z "$RD_DEBUG" ]; then if [ -e /proc/cmdline ]; then RD_DEBUG=no if getargbool 0 rd.debug -d -y rdinitdebug -d -y rdnetdebug; then RD_DEBUG=yes [ -n "$BASH" ] && \ export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): '; fi fi export RD_DEBUG fi debug_on } setdebug source_all() { local f local _dir _dir=$1; shift [ "$_dir" ] && [ -d "/$_dir" ] || return for f in "/$_dir"/*.sh; do [ -e "$f" ] && . "$f" "$@"; done } hookdir=/lib/dracut/hooks export hookdir source_hook() { local _dir _dir=$1; shift source_all "/lib/dracut/hooks/$_dir" "$@" } check_finished() { local f for f in $hookdir/initqueue/finished/*.sh; do [ "$f" = "$hookdir/initqueue/finished/*.sh" ] && return 0 { [ -e "$f" ] && ( . "$f" ) ; } || return 1 done return 0 } source_conf() { local f [ "$1" ] && [ -d "/$1" ] || return for f in "/$1"/*.conf; do [ -e "$f" ] && . "$f"; done } die() { { echo "<24>dracut: FATAL: $*"; echo "<24>dracut: Refusing to continue"; } > /dev/kmsg { echo "warn dracut: FATAL: \"$*\""; echo "warn dracut: Refusing to continue"; } >> $hookdir/emergency/01-die.sh [ -d /run/initramfs ] || mkdir -p -- /run/initramfs > /run/initramfs/.die if getargbool 0 "rd.shell"; then emergency_shell else source_hook "shutdown-emergency" fi if [ -n "$DRACUT_SYSTEMD" ]; then systemctl --no-block --force halt fi exit 1 } check_quiet() { if [ -z "$DRACUT_QUIET" ]; then DRACUT_QUIET="yes" getargbool 0 rd.info -d -y rdinfo && DRACUT_QUIET="no" getargbool 0 rd.debug -d -y rdinitdebug && DRACUT_QUIET="no" getarg quiet || DRACUT_QUIET="yes" a=$(getarg loglevel=) [ -n "$a" ] && [ $a -ge 28 ] && DRACUT_QUIET="yes" export DRACUT_QUIET fi } check_occurances() { # Count the number of times the character $ch occurs in $str # Return 0 if the count matches the expected number, 1 otherwise local str="$1" local ch="$2" local expected="$3" local count=0 while [ "${str#*$ch}" != "${str}" ]; do str="${str#*$ch}" count=$(( $count + 1 )) done [ $count -eq $expected ] } incol2() { debug_off local dummy check; local file="$1"; local str="$2"; [ -z "$file" ] && return 1; [ -z "$str" ] && return 1; while read dummy check restofline || [ -n "$check" ]; do if [ "$check" = "$str" ]; then debug_on return 0 fi done < $file debug_on return 1 } udevsettle() { [ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version | { read v _ ; echo $v ; }) if [ $UDEVVERSION -ge 143 ]; then udevadm settle --exit-if-exists=$hookdir/initqueue/work $settle_exit_if_exists else udevadm settle --timeout=30 fi } udevproperty() { [ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version | { read v _ ; echo $v ; }) if [ $UDEVVERSION -ge 143 ]; then for i in "$@"; do udevadm control --property=$i; done else for i in "$@"; do udevadm control --env=$i; done fi } find_mount() { local dev mnt etc wanted_dev wanted_dev="$(readlink -e -q $1)" while read dev mnt etc || [ -n "$dev" ]; do [ "$dev" = "$wanted_dev" ] && echo "$dev" && return 0 done < /proc/mounts return 1 } # usage: ismounted # usage: ismounted /dev/ if command -v findmnt >/dev/null; then ismounted() { findmnt "$1" > /dev/null 2>&1 } else ismounted() { if [ -b "$1" ]; then find_mount "$1" > /dev/null && return 0 return 1 fi while read a m a || [ -n "$m" ]; do [ "$m" = "$1" ] && return 0 done < /proc/mounts return 1 } fi # root=nfs:[:][:] # root=nfs4:[:][:] nfsroot_to_var() { # strip nfs[4]: local arg="$@:" nfs="${arg%%:*}" arg="${arg##$nfs:}" # check if we have a server if strstr "$arg" ':/' ; then server="${arg%%:/*}" arg="/${arg##*:/}" fi path="${arg%%:*}" # rest are options options="${arg##$path}" # strip leading ":" options="${options##:}" # strip ":" options="${options%%:}" # Does it really start with '/'? [ -n "${path%%/*}" ] && path="error"; #Fix kernel legacy style separating path and options with ',' if [ "$path" != "${path#*,}" ] ; then options=${path#*,} path=${path%%,*} fi } # Create udev rule match for a device with its device name, or the udev property # ID_FS_UUID or ID_FS_LABEL # # example: # udevmatch LABEL=boot # prints: # ENV{ID_FS_LABEL}="boot" # # TODO: symlinks udevmatch() { case "$1" in UUID=????????-????-????-????-????????????|LABEL=*|PARTLABEL=*|PARTUUID=????????-????-????-????-????????????) printf 'ENV{ID_FS_%s}=="%s"' "${1%%=*}" "${1#*=}" ;; UUID=*) printf 'ENV{ID_FS_UUID}=="%s*"' "${1#*=}" ;; PARTUUID=*) printf 'ENV{ID_FS_PARTUUID}=="%s*"' "${1#*=}" ;; /dev/?*) printf -- 'KERNEL=="%s"' "${1#/dev/}" ;; *) return 255 ;; esac } # Prints unique path for potential file inside specified directory. It consists # of specified directory, prefix and number at the end which is incremented # until non-existing file is found. # # funiq dir prefix # # example: # # ls /mnt # cdrom0 cdrom1 # # # funiq /mnt cdrom # /mnt/cdrom2 funiq() { local dir="$1"; local prefix="$2" local i=0 [ -d "${dir}" ] || return 1 while [ -e "${dir}/${prefix}$i" ]; do i=$(($i+1)) || return 1 done echo "${dir}/${prefix}$i" } # Creates unique directory and prints its path. It's using funiq to generate # path. # # mkuniqdir subdir new_dir_name mkuniqdir() { local dir="$1"; local prefix="$2" local retdir; local retdir_new [ -d "${dir}" ] || mkdir -m 0755 -p "${dir}" || return 1 retdir=$(funiq "${dir}" "${prefix}") || return 1 until mkdir -m 0755 "${retdir}" 2>/dev/null; do retdir_new=$(funiq "${dir}" "${prefix}") || return 1 [ "$retdir_new" = "$retdir" ] && return 1 retdir="$retdir_new" done echo "${retdir}" } # Copy the contents of SRC into DEST, merging the contents of existing # directories (kinda like rsync, or cpio -p). # Creates DEST if it doesn't exist. Overwrites files with the same names. # # copytree SRC DEST copytree() { local src="$1" dest="$2" mkdir -p "$dest"; dest=$(readlink -e -q "$dest") ( cd "$src"; cp -af . -t "$dest" ) } # Evaluates command for UUIDs either given as arguments for this function or all # listed in /dev/disk/by-uuid. UUIDs doesn't have to be fully specified. If # beginning is given it is expanded to all matching UUIDs. To pass full UUID to # your command use '$___' as a place holder. Remember to escape '$'! # # foreach_uuid_until [ -p prefix ] command UUIDs # # prefix - string to put just before $___ # command - command to be evaluated # UUIDs - list of UUIDs separated by space # # The function returns after *first successful evaluation* of the given command # with status 0. If evaluation fails for every UUID function returns with # status 1. # # Example: # foreach_uuid_until "mount -U \$___ /mnt; echo OK; umount /mnt" \ # "01234 f512 a235567f-12a3-c123-a1b1-01234567abcb" foreach_uuid_until() ( cd /dev/disk/by-uuid [ "$1" = -p ] && local prefix="$2" && shift 2 local cmd="$1"; shift; local uuids_list="$*" local uuid; local full_uuid; local ___ [ -n "${cmd}" ] || return 1 for uuid in ${uuids_list:-*}; do for full_uuid in ${uuid}*; do [ -e "${full_uuid}" ] || continue ___="${prefix}${full_uuid}" eval ${cmd} && return 0 done done return 1 ) # Get kernel name for given device. Device may be the name too (then the same # is returned), a symlink (full path), UUID (prefixed with "UUID=") or label # (prefixed with "LABEL="). If just a beginning of the UUID is specified or # even an empty, function prints all device names which UUIDs match - every in # single line. # # NOTICE: The name starts with "/dev/". # # Example: # devnames UUID=123 # May print: # /dev/dm-1 # /dev/sdb1 # /dev/sdf3 devnames() { local dev="$1"; local d; local names case "$dev" in UUID=*) dev="$(foreach_uuid_until '! blkid -U $___' "${dev#UUID=}")" \ && return 255 [ -z "$dev" ] && return 255 ;; LABEL=*) dev="$(blkid -L "${dev#LABEL=}")" || return 255 ;; /dev/?*) ;; *) return 255 ;; esac for d in $dev; do names="$names $(readlink -e -q "$d")" || return 255 done echo "${names# }" } usable_root() { local _i [ -d "$1" ] || return 1 for _i in "$1"/usr/lib*/ld-*.so "$1"/lib*/ld-*.so; do [ -e "$_i" ] && return 0 done for _i in proc sys dev; do [ -e "$1"/$_i ] || return 1 done return 0 } inst_hook() { local _hookname _unique _name _job _exe while [ $# -gt 0 ]; do case "$1" in --hook) _hookname="/$2";shift;; --unique) _unique="yes";; --name) _name="$2";shift;; *) break;; esac shift done if [ -z "$_unique" ]; then _job="${_name}$$" else _job="${_name:-$1}" _job=${_job##*/} fi _exe=$1 shift [ -x "$_exe" ] || _exe=$(command -v $_exe) if [ -n "$onetime" ]; then { echo '[ -e "$_job" ] && rm -f -- "$_job"' echo "$_exe $@" } > "/tmp/$$-${_job}.sh" else echo "$_exe $@" > "/tmp/$$-${_job}.sh" fi mv -f "/tmp/$$-${_job}.sh" "$hookdir/${_hookname}/${_job}.sh" } # inst_mount_hook