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

Bug#968325: src:initramfs-tools: root=/dev/cifs support



Source: initramfs-tools
Version: 0.137
Severity: wishlist
Tags: patch

Hi!

I've used this i-t patch to successfully (I think? I can log in and the
system is usable, but I get an endless stream of 
> CIFS VFS: SMB signature verification returned error = -13
on the console, though I think that's unrelated to anything in this
patch) boot an otherwise clean+cifs-utils+systemd sid i686 chroot
off samba, mostly mirroring the NFS code.

Note that Debian kernels don't set CONFIG_CIFS_ROOT, so "rootfs" is
ignored [1], but AFAICT that's only used to change some socket
parameters and error handling [2,3], so shouldn't affect much.

Best,
наб

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/cifs/connect.c?id=a0a3036b81f1f66fa3333559ecfe18f5bbfa5076#n1787
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/cifs/connect.c?id=a0a3036b81f1f66fa3333559ecfe18f5bbfa5076#n2754
[3]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/cifs/connect.c?id=a0a3036b81f1f66fa3333559ecfe18f5bbfa5076#n3950

-- >8 --
Subject: Allow booting with root=/dev/cifs

---
 hook-functions |   1 +
 hooks/cifs     |   7 +++
 init           |  15 ++++-
 scripts/cifs   | 161 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 181 insertions(+), 3 deletions(-)
 create mode 100755 hooks/cifs
 create mode 100644 scripts/cifs

diff --git a/hook-functions b/hook-functions
index 7a82b9c..c932d46 100644
--- a/hook-functions
+++ b/hook-functions
@@ -566,6 +566,7 @@ auto_add_modules()
 			modules="$modules btrfs ext2 ext3 ext4 f2fs"
 			modules="$modules isofs jfs reiserfs udf xfs"
 			modules="$modules nfs nfsv2 nfsv3 nfsv4"
+			modules="$modules cifs md4 cmac aes sha512"
 			modules="$modules af_packet atkbd i8042 psmouse"
 			modules="$modules virtio_pci virtio_mmio"
 
diff --git a/hooks/cifs b/hooks/cifs
new file mode 100755
index 0000000..5b0f8da
--- /dev/null
+++ b/hooks/cifs
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. /usr/share/initramfs-tools/hook-functions
+
+if [ -x /sbin/mount.cifs ]; then
+	copy_exec /sbin/mount.cifs
+fi
diff --git a/init b/init
index 43f6828..3438121 100755
--- a/init
+++ b/init
@@ -87,8 +87,11 @@ for x in $(cat /proc/cmdline); do
 		;;
 	root=*)
 		ROOT=${x#root=}
-		if [ -z "${BOOT}" ] && [ "$ROOT" = "/dev/nfs" ]; then
-			BOOT=nfs
+		if [ -z "${BOOT}" ]; then
+			case "$ROOT" in
+			  "/dev/nfs")  BOOT=nfs  ;;
+			  "/dev/cifs") BOOT=cifs ;;
+			esac
 		fi
 		;;
 	rootflags=*)
@@ -109,6 +112,10 @@ for x in $(cat /proc/cmdline); do
 		# shellcheck disable=SC2034
 		NFSROOT="${x#nfsroot=}"
 		;;
+	cifsroot=*)
+		# shellcheck disable=SC2034
+		CIFSROOT="${x#cifsroot=}"
+		;;
 	initramfs.runsize=*)
 		RUNSIZE="${x#initramfs.runsize=}"
 		;;
@@ -234,10 +241,11 @@ run_scripts /scripts/init-premount
 
 maybe_break mount
 log_begin_msg "Mounting root file system"
-# Always load local and nfs (since these might be needed for /etc or
+# Always load local, nfs, and cifs (since these might be needed for /etc or
 # /usr, irrespective of the boot script used to mount the rootfs).
 . /scripts/local
 . /scripts/nfs
+. /scripts/cifs
 . /scripts/${BOOT}
 parse_numeric "${ROOT}"
 maybe_break mountroot
@@ -255,6 +263,7 @@ fi
 # Mount cleanup
 mount_bottom
 nfs_bottom
+cifs_bottom
 local_bottom
 
 maybe_break bottom
diff --git a/scripts/cifs b/scripts/cifs
new file mode 100644
index 0000000..6f0ebe6
--- /dev/null
+++ b/scripts/cifs
@@ -0,0 +1,161 @@
+# CIFS filesystem mounting			-*- shell-script -*-
+
+# FIXME This needs error checking
+
+cifs_top()
+{
+	if [ "${cifs_top_used}" != "yes" ]; then
+		[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/cifs-top"
+		run_scripts /scripts/cifs-top
+		[ "$quiet" != "y" ] && log_end_msg
+	fi
+	cifs_top_used=yes
+}
+
+cifs_premount()
+{
+	if [ "${cifs_premount_used}" != "yes" ]; then
+		[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/cifs-premount"
+		run_scripts /scripts/cifs-premount
+		[ "$quiet" != "y" ] && log_end_msg
+	fi
+	cifs_premount_used=yes
+}
+
+cifs_bottom()
+{
+	if [ "${cifs_premount_used}" = "yes" ] || [ "${cifs_top_used}" = "yes" ]; then
+		[ "${quiet?}" != "y" ] && log_begin_msg "Running /scripts/cifs-bottom"
+		run_scripts /scripts/cifs-bottom
+		[ "$quiet" != "y" ] && log_end_msg
+	fi
+	cifs_premount_used=no
+	cifs_top_used=no
+}
+
+# parse cifs bootargs and mount cifs
+cifs_mount_root_impl()
+{
+	configure_networking
+
+	# get cifs root from dhcp
+	if [ "x${CIFSROOT}" = "xauto" ]; then
+		# check if server ip is part of dhcp root-path
+		if [ "${ROOTPATH#*//*/}" = "${ROOTPATH}" ]; then
+			CIFSROOT=//${ROOTSERVER}/${ROOTPATH#*/}
+		else
+			CIFSROOT=${ROOTPATH}
+		fi
+
+	# cifsroot=//<server-ip>/<share>[,options]
+	elif [ -n "${CIFSROOT}" ]; then
+		# cifs options are an optional arg
+		if [ "${CIFSROOT#*,}" != "${CIFSROOT}" ]; then
+			CIFSOPTS="${CIFSROOT#*,}"
+		fi
+		CIFSROOT=${CIFSROOT%%,*}
+		if [ "${CIFSROOT#*//*/}" = "$CIFSROOT" ]; then
+			CIFSROOT=//${ROOTSERVER}/${CIFSROOT}
+		fi
+	fi
+
+	cifs_premount
+
+	if [ "${readonly?}" = y ]; then
+		roflag="-o ro"
+	else
+		roflag="-o rw"
+	fi
+
+	# The redirexion displays the password prompt, if any, instead of just blocking
+	# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/cifs/cifsroot.c?id=a0a3036b81f1f66fa3333559ecfe18f5bbfa5076#n18
+	# shellcheck disable=SC2086
+	mount.cifs ${roflag} -o "vers=1.0,cifsacl,mfsymlinks,rsize=1048576,wsize=65536,uid=0,gid=0,hard,rootfs,${CIFSOPTS}" "${CIFSROOT}" "${rootmnt?}" >/dev/console 2>&1
+}
+
+# CIFS root mounting
+cifs_mount_root()
+{
+	cifs_top
+
+	# For DHCP
+	modprobe af_packet
+
+	wait_for_udev 10
+
+	# Default delay is around 180s
+	delay=${ROOTDELAY:-180}
+
+	# loop until mount.cifs succeeds
+	cifs_mount_root_impl
+	ret=$?
+	cifs_retry_count=0
+	while [ ${cifs_retry_count} -lt "${delay}" ] \
+		&& [ $ret -ne 0 ] ; do
+		[ "$quiet" != "y" ] && log_begin_msg "Retrying cifs mount"
+		sleep 1
+		cifs_mount_root_impl
+		ret=$?
+		cifs_retry_count=$(( cifs_retry_count + 1 ))
+		[ "$quiet" != "y" ] && log_end_msg
+	done
+}
+
+cifs_mount_fs_impl()
+{
+	configure_networking
+
+	cifs_premount
+
+	if [ "${readonly}" = y ]; then
+		roflag="-o ro"
+	else
+		roflag="-o rw"
+	fi
+
+	read_fstab_entry "$1"
+
+	# The redirexion displays the password prompt, if any, instead of just blocking
+	# shellcheck disable=SC2086
+	mount.cifs ${roflag} -o "${CIFSOPTS}" -o "${MNT_OPTS}" "$MNT_FSNAME" "${rootmnt}${MNT_DIR}" >/dev/console 2>&1
+}
+
+cifs_mount_fs()
+{
+	cifs_top
+
+	# For DHCP
+	modprobe af_packet
+
+	wait_for_udev 10
+
+	# Default delay is around 180s
+	delay=${ROOTDELAY:-180}
+
+	# Don't loop here; we can't sanely check if it worked like for
+	# the rootfs or /etc.
+	cifs_mount_fs_impl "$1"
+}
+
+mountroot()
+{
+	cifs_mount_root
+}
+
+mount_top()
+{
+	# Note, also called directly in case it's overridden.
+	cifs_top
+}
+
+mount_premount()
+{
+	# Note, also called directly in case it's overridden.
+	cifs_premount
+}
+
+mount_bottom()
+{
+	# Note, also called directly in case it's overridden.
+	cifs_bottom
+}
-- 
2.20.1

Attachment: signature.asc
Description: PGP signature


Reply to: