Blob Blame History Raw
From d580636e97bffdd17124961e2f9db0aa2a645060 Mon Sep 17 00:00:00 2001
From: Mike Gorse <mgorse@suse.com>
Date: Thu, 26 Jul 2012 09:17:18 -0500
Subject: [PATCH] Added cifs

---
 dracut.cmdline.7.asc               | 15 +++++++++++
 modules.d/95cifs/cifs-lib.sh       | 36 ++++++++++++++++++++++++++
 modules.d/95cifs/cifsroot.sh       | 26 +++++++++++++++++++
 modules.d/95cifs/module-setup.sh   | 46 +++++++++++++++++++++++++++++++++
 modules.d/95cifs/parse-cifsroot.sh | 52 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 175 insertions(+)
 create mode 100755 modules.d/95cifs/cifs-lib.sh
 create mode 100755 modules.d/95cifs/cifsroot.sh
 create mode 100755 modules.d/95cifs/module-setup.sh
 create mode 100755 modules.d/95cifs/parse-cifsroot.sh

diff --git a/dracut.cmdline.7.asc b/dracut.cmdline.7.asc
index 8f642f3..0b1b8a2 100644
--- a/dracut.cmdline.7.asc
+++ b/dracut.cmdline.7.asc
@@ -398,6 +398,21 @@ NFS
 **rd.nfs.domain=**_<NFSv4 domain name>_::
     Set the NFSv4 domain name. Will overwrite the settings in _/etc/idmap.conf_.
 
+CIFS
+~~~
+**root=**cifs://[_<username>_[:_<password>_]@]_<server-ip>_:_<root-dir>_::
+    mount cifs share from <server-ip>:/<root-dir>, if no server-ip is given, use
+    dhcp next_server. if server-ip is an IPv6 address it has to be put in
+    brackets, e.g. [2001:DB8::1]. If a username or password are not specified
+as part of the root, then they must be passed on the command line through
+cifsuser/cifspass.
+
+**cifsuser=_<username>_::
+    Set the cifs username, if not specified as part of the root.
+
+**cifspass=_<password>_::
+    Set the cifs password, if not specified as part of the root.
+
 iSCSI
 ~~~~~
 **root=**iscsi:[_<username>_:_<password>_[:_<reverse>_:_<password>_]@][_<servername>_]:[_<protocol>_]:[_<port>_][:[_<iscsi_iface_name>_]:[_<netdev_name>_]]:[_<LUN>_]:_<targetname>_::
diff --git a/modules.d/95cifs/cifs-lib.sh b/modules.d/95cifs/cifs-lib.sh
new file mode 100755
index 0000000..3cbe6dc
--- /dev/null
+++ b/modules.d/95cifs/cifs-lib.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=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
+
+    path=${server#*/}
+    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
+    options="user=$cifsuser,pass=$cifspass"
+}
diff --git a/modules.d/95cifs/cifsroot.sh b/modules.d/95cifs/cifsroot.sh
new file mode 100755
index 0000000..7956d6f
--- /dev/null
+++ b/modules.d/95cifs/cifsroot.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=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
+echo server: $server
+echo path: $path
+echo options: $options
+
+mount.cifs //$server/$path $NEWROOT -o $options && { [ -e /dev/root ] || >/dev/root ; }
+
+# inject new exit_if_exists
+echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm "$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..2f2e78d
--- /dev/null
+++ b/modules.d/95cifs/module-setup.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+
+check() {
+    # If our prerequisites are not met, fail anyways.
+    type -P mount.cifs >/dev/null || return 1
+
+    [[ $hostonly ]] || [[ $mount_needs ]] && {
+        for fs in ${host_fs_types[@]}; do
+            strstr "$fs" "\|cifs"  && return 0
+        done
+        return 255
+    }
+
+    return 0
+}
+
+depends() {
+    # We depend on network modules being loaded
+    echo network
+}
+
+installkernel() {
+    instmods cifs ipv6
+}
+
+install() {
+    local _i
+    local _nsslibs
+    dracut_install -o mount.cifs
+    dracut_install /etc/services /etc/nsswitch.conf /etc/protocols
+
+    inst_libdir_file 'libcap-ng.so*'
+
+    _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*'
+
+    inst_hook cmdline 90 "$moddir/parse-cifsroot.sh"
+    inst "$moddir/cifsroot.sh" "/sbin/cifsroot"
+    inst "$moddir/cifs-lib.sh" "/lib/cifs-lib.sh"
+}
diff --git a/modules.d/95cifs/parse-cifsroot.sh b/modules.d/95cifs/parse-cifsroot.sh
new file mode 100755
index 0000000..d5adb98
--- /dev/null
+++ b/modules.d/95cifs/parse-cifsroot.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=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
+
+#Don't continue if root is ok
+[ -n "$rootok" ] && return
+
+# This script is sourced, so root should be set. But let's be paranoid
+[ -z "$root" ] && root=$(getarg root=)
+[ -z "$netroot" ] && netroot=$(getarg netroot=)
+
+# netroot= cmdline argument must be ignored, but must be used if
+# we're inside netroot to parse dhcp root-path
+if [ -n "$netroot" ] ; then
+    if [ "$netroot" = "$(getarg netroot=)" ] ; then
+        warn "Ignoring netroot argument for CIFS"
+        netroot=$root
+    fi
+else
+    netroot=$root;
+fi
+
+# Continue if cifs
+case "${netroot%%:*}" in
+    cifs);;
+    *) unset netroot; return;;
+esac
+
+# Check required arguments
+cifs_to_var $netroot
+
+# If we don't have a server, we need dhcp
+if [ -z "$server" ] ; then
+    DHCPORSERVER="1"
+fi;
+
+# Done, all good!
+rootok=1
+
+echo '[ -e $NEWROOT/proc ]' > $hookdir/initqueue/finished/cifsroot.sh