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

[PATCH 1/2] add support to boot directly from Ceph RBD images



add a new command line option rbdroot which works analogous to nfsroot
syntax:
rbdroot=<mons>:<user>:<key>:<pool>:<image>[@<snapshot>]:[<part>]:[<mntopts>]

Signed-off-by: Paul Emmerich <p.emmerich@first-colo.net>

diff --git a/hook-functions b/hook-functions
index ee1c205..43f86b4 100644
--- a/hook-functions
+++ b/hook-functions
@@ -513,7 +513,7 @@ auto_add_modules()
 	local modules=
 
 	if [ "$#" -eq 0 ] ; then
-		set -- base net ide scsi block ata i2o dasd ieee1394 firewire mmc usb_storage
+		set -- base net ide scsi block ata i2o dasd ieee1394 firewire mmc usb_storage rbd
 	fi
 
 	for arg in "$@" ; do
@@ -594,6 +594,8 @@ auto_add_modules()
 		usb_storage)
 			copy_modules_dir kernel/drivers/usb/storage
 		;;
+		rbd)
+			modules="$modules rbd aes cbc"
 		esac
 	done
 
diff --git a/init b/init
index abf7f25..15d4ab3 100755
--- a/init
+++ b/init
@@ -101,6 +101,9 @@ for x in $(cat /proc/cmdline); do
 	nfsroot=*)
 		NFSROOT="${x#nfsroot=}"
 		;;
+	rbdroot=*)
+		RBDROOT="${x#rbdroot=}"
+		;;
 	ip=*)
 		IP="${x#ip=}"
 		;;
diff --git a/scripts/rbd b/scripts/rbd
new file mode 100644
index 0000000..3be56f3
--- /dev/null
+++ b/scripts/rbd
@@ -0,0 +1,178 @@
+# RBD root mounting			-*- shell-script -*-
+# based on the nfs script
+
+
+rbd_top()
+{
+	if [ "${rbd_top_used}" != "yes" ]; then
+		[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/rbd-top"
+		run_scripts /scripts/rbd-top
+		[ "$quiet" != "y" ] && log_end_msg
+	fi
+	rbd_top_used=yes
+}
+
+rbd_premount()
+{
+	if [ "${rbd_premount_used}" != "yes" ]; then
+		[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/rbd-premount"
+		run_scripts /scripts/rbd-premount
+		[ "$quiet" != "y" ] && log_end_msg
+	fi
+	rbd_premount_used=yes
+}
+
+rbd_bottom()
+{
+	if [ "${rbd_premount_used}" = "yes" ] || [ "${rbd_top_used}" = "yes" ]; then
+		[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/rbd-bottom"
+		run_scripts /scripts/rbd-bottom
+		[ "$quiet" != "y" ] && log_end_msg
+	fi
+	rbd_premount_used=no
+	rbd_top_used=no
+}
+
+# parse rbd bootargs and mount rbd
+rbd_mount_root_impl()
+{
+	configure_networking
+
+	# get rbd root from dhcp
+	if [ "x${RBDROOT}" = "xauto" ]; then
+		RBDROOT=${ROOTPATH}
+	fi
+	
+	local mons user key pool image snap partition opts
+	
+	# rbdroot=<mons>:<user>:<key>:<pool>:<image>[@<snapshot>]:[<partition>]:[<mountopts>]
+	if [ -n "${RBDROOT}" ]; then
+		local i=1
+		local OLD_IFS=${IFS}
+		IFS=":"
+		for arg in ${RBDROOT} ; do
+			case ${i} in
+				1)
+					mons=$(echo ${arg} | tr ";" ":")
+					;;
+				2)
+					user=${arg}
+					;;
+				3)
+					key=${arg}
+					;;
+				4)
+					pool=${arg}
+					;;
+				5)
+					# image contains an @, i.e. a snapshot
+					if [ ${arg#*@*} != ${arg} ] ; then
+						image=${arg%%@*}
+						snap=${arg##*@}
+					else
+						image=${arg}
+						snap=""
+					fi
+					;;
+				6)
+					partition=${arg}
+					;;
+				7)
+					opts=${arg}
+					;;
+			esac
+			i=$((${i} + 1))
+		done
+		IFS=${OLD_IFS}
+	fi
+
+	if [ ${readonly} = y ]; then
+		roflag="-o ro"
+	else
+		roflag="-o rw"
+	fi
+	
+	# the kernel will reject writes to add if add_single_major exists
+	local rbd_bus
+	if [ -e /sys/bus/rbd/add_single_major ]; then
+		rbd_bus=/sys/bus/rbd/add_single_major
+	elif [ -e /sys/bus/rbd/add ]; then
+		rbd_bus=/sys/bus/rbd/add
+	else
+		echo "ERROR: /sys/bus/rbd/add does not exist"
+		return 1
+	fi
+	
+	# tell the kernel rbd client to map the block device
+	echo "${mons} name=${user},secret=${key} ${pool} ${image} ${snap}" > ${rbd_bus}
+	# figure out where the block device appeared
+	local dev=$(ls /dev/rbd* | grep '/dev/rbd[0-9]*$' | tail -n 1)
+	# add partition if set
+	if [ ${partition} ]; then
+		dev=${dev}p${partition}
+	fi
+	# get the root filesystem type if not set
+	if [ -z "${ROOTFSTYPE}" ]; then
+		FSTYPE=$(get_fstype "${dev}")
+	else
+		FSTYPE=${ROOTFSTYPE}
+	fi
+
+	rbd_premount
+
+	# mount the fs
+	modprobe ${FSTYPE}
+	mount -t ${FSTYPE} $dev ${rootmnt} ${roflag},${opts}
+}
+
+# RBD root mounting
+rbd_mount_root()
+{
+	rbd_top
+
+	modprobe rbd
+	# For DHCP
+	modprobe af_packet
+
+	wait_for_udev 10
+
+	# Default delay is around 180s
+	delay=${ROOTDELAY:-180}
+
+	# loop until rbd mount succeeds
+	rbd_mount_root_impl
+	rbd_retry_count=0
+	while [ ${rbd_retry_count} -lt ${delay} ] \
+		&& ! chroot "${rootmnt}" test -x "${init}" ; do
+		[ "$quiet" != "y" ] && log_begin_msg "Retrying rbd mount"
+		/bin/sleep 1
+		rbd_mount_root_impl
+		rbd_retry_count=$(( ${rbd_retry_count} + 1 ))
+		[ "$quiet" != "y" ] && log_end_msg
+	done
+}
+
+mountroot()
+{
+	rbd_mount_root
+}
+
+mount_top()
+{
+	# Note, also called directly in case it's overridden.
+	rbd_top
+}
+
+mount_premount()
+{
+	# Note, also called directly in case it's overridden.
+	rbd_premount
+}
+
+mount_bottom()
+{
+	# Note, also called directly in case it's overridden.
+	rbd_bottom
+}
+
+
-- 
2.2.1


Reply to: