[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: