summaryrefslogtreecommitdiffstats
path: root/modules.d/95cifs
diff options
context:
space:
mode:
Diffstat (limited to 'modules.d/95cifs')
-rwxr-xr-xmodules.d/95cifs/cifs-lib.sh38
-rwxr-xr-xmodules.d/95cifs/cifsroot.sh22
-rwxr-xr-xmodules.d/95cifs/module-setup.sh58
-rwxr-xr-xmodules.d/95cifs/parse-cifsroot.sh51
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