diff options
Diffstat (limited to 'modules.d/95cifs')
-rwxr-xr-x | modules.d/95cifs/cifs-lib.sh | 38 | ||||
-rwxr-xr-x | modules.d/95cifs/cifsroot.sh | 22 | ||||
-rwxr-xr-x | modules.d/95cifs/module-setup.sh | 58 | ||||
-rwxr-xr-x | modules.d/95cifs/parse-cifsroot.sh | 51 |
4 files changed, 169 insertions, 0 deletions
diff --git a/modules.d/95cifs/cifs-lib.sh b/modules.d/95cifs/cifs-lib.sh new file mode 100755 index 0000000..b996b41 --- /dev/null +++ b/modules.d/95cifs/cifs-lib.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +# cifs_to_var CIFSROOT +# use CIFSROOT to set $server, $path, and $options. +# CIFSROOT is something like: cifs://[<username>[:<password>]]@<host>/<path> +# NETIF is used to get information from DHCP options, if needed. + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +cifs_to_var() { + local cifsuser + local cifspass + # Check required arguments + server=${1##cifs://} + cifsuser=${server%@*} + cifspass=${cifsuser#*:} + if [ "$cifspass" != "$cifsuser" ]; then + cifsuser=${cifsuser%:*} + else + cifspass=$(getarg cifspass) + fi + if [ "$cifsuser" != "$server" ]; then + server="${server#*@}" + else + cifsuser=$(getarg cifsuser) + fi + + # shellcheck disable=SC2034 + path=${server#*/} + # shellcheck disable=SC2034 + server=${server%/*} + + if [ ! "$cifsuser" -o ! "$cifspass" ]; then + die "For CIFS support you need to specify a cifsuser and cifspass either in the cifsuser and cifspass commandline parameters or in the root= CIFS URL." + fi + # shellcheck disable=SC2034 + options="user=$cifsuser,pass=$cifspass,$(getarg rootflags=)" +} diff --git a/modules.d/95cifs/cifsroot.sh b/modules.d/95cifs/cifsroot.sh new file mode 100755 index 0000000..83539d4 --- /dev/null +++ b/modules.d/95cifs/cifsroot.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh +. /lib/cifs-lib.sh + +[ "$#" = 3 ] || exit 1 + +# root is in the form root=cifs://user:pass@[server]/[folder] either from +# cmdline or dhcp root-path +#netif="$1" +root="$2" +NEWROOT="$3" + +cifs_to_var "$root" + +mount.cifs "//$server/$path" "$NEWROOT" -o "$options" && { [ -e /dev/root ] || ln -s null /dev/root; } + +# inject new exit_if_exists +# shellcheck disable=SC2016 +echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm -f -- "$job"' > "$hookdir"/initqueue/cifs.sh +# force udevsettle to break +: > "$hookdir"/initqueue/work diff --git a/modules.d/95cifs/module-setup.sh b/modules.d/95cifs/module-setup.sh new file mode 100755 index 0000000..6abc475 --- /dev/null +++ b/modules.d/95cifs/module-setup.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# called by dracut +check() { + # If our prerequisites are not met, fail anyways. + require_binaries mount.cifs || return 1 + + [[ $hostonly ]] || [[ $mount_needs ]] && { + for fs in "${host_fs_types[@]}"; do + [[ $fs == "cifs" ]] && return 0 + done + return 255 + } + + return 0 +} + +# called by dracut +depends() { + # We depend on network modules being loaded + echo network +} + +# called by dracut +installkernel() { + instmods cifs ipv6 + # hash algos + instmods md4 md5 sha256 sha512 + # ciphers + instmods aes arc4 des ecb gcm aead2 + # macs + instmods hmac cmac ccm +} + +# called by dracut +install() { + local _nsslibs + inst_multiple -o mount.cifs + inst_multiple -o /etc/services /etc/nsswitch.conf /etc/protocols + inst_multiple -o /usr/etc/services /usr/etc/nsswitch.conf /usr/etc/protocols + + inst_libdir_file 'libcap-ng.so*' + + _nsslibs=$( + cat "$dracutsysrootdir"/{,usr/}etc/nsswitch.conf 2> /dev/null \ + | sed -e '/^#/d' -e 's/^.*://' -e 's/\[NOTFOUND=return\]//' \ + | tr -s '[:space:]' '\n' | sort -u | tr -s '[:space:]' '|' + ) + _nsslibs=${_nsslibs#|} + _nsslibs=${_nsslibs%|} + + inst_libdir_file -n "$_nsslibs" 'libnss_*.so*' + + inst_hook cmdline 90 "$moddir/parse-cifsroot.sh" + inst "$moddir/cifsroot.sh" "/sbin/cifsroot" + inst "$moddir/cifs-lib.sh" "/lib/cifs-lib.sh" + dracut_need_initqueue +} diff --git a/modules.d/95cifs/parse-cifsroot.sh b/modules.d/95cifs/parse-cifsroot.sh new file mode 100755 index 0000000..b88bef4 --- /dev/null +++ b/modules.d/95cifs/parse-cifsroot.sh @@ -0,0 +1,51 @@ +#!/bin/sh +# +# root=cifs://[user:pass@]<server>/<folder> +# +# This syntax can come from DHCP root-path as well. +# +# If a username or password are not specified as part of the root, then they +# will be pulled from cifsuser and cifspass on the kernel command line, +# respectively. +# + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh +. /lib/cifs-lib.sh + +# This script is sourced, so root should be set. But let's be paranoid +[ -z "$root" ] && root=$(getarg root=) + +if [ -z "$netroot" ]; then + for netroot in $(getargs netroot=); do + [ "${netroot%%:*}" = "cifs" ] && break + done + [ "${netroot%%:*}" = "cifs" ] || unset netroot +fi + +# Root takes precedence over netroot +if [ "${root%%:*}" = "cifs" ]; then + if [ -n "$netroot" ]; then + warn "root takes precedence over netroot. Ignoring netroot" + fi + netroot=$root + unset root +fi + +# If it's not cifs we don't continue +[ "${netroot%%:*}" = "cifs" ] || return + +# Check required arguments +cifs_to_var "$netroot" + +# If we don't have a server, we need dhcp +if [ -z "$server" ]; then + # shellcheck disable=SC2034 + DHCPORSERVER="1" +fi + +# Done, all good! +# shellcheck disable=SC2034 +rootok=1 + +# shellcheck disable=SC2016 +echo '[ -e $NEWROOT/proc ]' > "$hookdir"/initqueue/finished/cifsroot.sh |