看板 Linux 關於我們 聯絡資訊
新增ubuntu版 於文末 =========== 作者: czm (czm) 看板: Linux 標題: Re: [心得] 閒聊+雙系統另種選擇 loopdevice 時間: Fri Jul 21 07:57:04 2017 已經成功像一般的distro 可以從 iso file boot 了 其中第2部份必須改寫 又將共同的功能寫成function 放在最前面 成為第0部份 而第1部份參數有重新命名 從 iso file boot 是目前最複雜的使用情況 主要動作有 1. 掛載iso 2. 掛載iso 裡面的loopfile 到 lower 3. 掛載另一個可寫的device ( tmpfs, loopfile 或 block device), 給 upper 和 work 4. mount 好整個 OverlayFS 然後boot. 完全參數化 會有10多個參數 如此才夠應付多數情況 以下為 initrd.d/linuxrc的新增4部份 ===================================== # zm 0 # $1: device name # $2: mount point (full path) # $3: caller's var for storing the results is_mounted() { local _FOUND eval _FOUND='$( [ -n "$( mount | grep "${1} on ${2} " )" ] && echo '1' || echo '0' )' if [ -n "${3}" ]; then eval $"${3}"='"$_FOUND"' else echo "$_FOUND" # > /dev/null fi } # $1: device name # $2: mount point # $3: options mount_device() { if [ -e "${1}" -a -d "${2}" ] && [ "$( is_mounted "${1}" "${2}" )" -eq '0' ]; then if [ -n "${3}" ]; then echo mount -o "${3}" "${1}" "${2}" mount -o "${3}" "${1}" "${2}" else echo mount "${1}" "${2}" mount "${1}" "${2}" fi fi } # $1: file name # $2: mount point # $3: options mount_loopfile() { if [ -f "${1}" -a -d "${2}" ]; then local DEV=$( losetup -f ) # local DEV=`losetup -f` echo losetup "$DEV" "${1}" losetup "$DEV" "${1}" if [ -n "${3}" ]; then echo mount -o "${3}" "$DEV" "${2}" mount -o "${3}" "$DEV" "${2}" else echo mount "$DEV" "${2}" mount "$DEV" "${2}" fi fi } # $1: name real_device() { local DEVICE="${1}" case "${DEVICE}" in UUID\=*|LABEL\=*) local REAL_DEVICE="" local retval=1 if [ "${retval}" -ne 0 ]; then REAL_DEVICE=$( findfs "${DEVICE}" 2>/dev/null) retval=$? fi if [ "$retval" -ne 0 ]; then REAL_DEVICE=$( busybox findfs "${DEVICE}" 2>/dev/null) retval=$? fi if [ "${retval}" -ne 0 ]; then REAL_DEVICE=$( blkid -o device -l -t "${DEVICE}") retval=$? fi if [ "${retval}" -eq 0 ] && [ -n "${REAL_DEVICE}" ]; then DEVICE="${REAL_DEVICE}" fi ;; esac echo -n "${DEVICE}" } # $1: dev name # $2: mount point # $3: loopfile # $4: loopfile mount point # $5: loopfile mount options setup_loop_device() { REAL_LOOPS_DEV=$( real_device "${1}" ) # echo mount_device "$REAL_LOOPS_DEV" "${2}" mount_device "$REAL_LOOPS_DEV" "${2}" local DEV=$( losetup -f) # local DEV=`losetup -f` if [ -e "${3}" ]; then echo losetup "$DEV" "${3}" losetup "$DEV" "${3}" if [ -n "${4}" ]; then mkdir -p "${4}" # echo mount_device "$DEV" "${4}" "${5}" mount_device "$DEV" "${4}" "${5}" fi fi } # $1: lower dir # $2: upper dir # $3: work dir # $4: merged dir setup_overlay_fs() { mount -t overlay -o lowerdir="${1}",upperdir="${2}",workdir="${3}" overlay "${4}" } # zm ====================================== # zm 1: get parameters for boot from loop file or overlayfs loops_dev=*) LOOPS_DEV=${x#*=} ;; loops_dev_mnt=*) LOOPS_DEV_MNT=${x#*=} ;; loop_file=*) LOOP_FILE=${x#*=} ;; loop_file_mnt=*) LOOP_FILE_MNT=${x#*=} ;; loop_file_mnt_opt=*) LOOP_FILE_MNT_OPT=${x#*=} ;; ovl_dev0=*) OVL_DEV0=${x#*=} ;; ovl_mnt0=*) OVL_MNT0=${x#*=} ;; ovl_loopfile0=*) OVL_LOOPFILE0=${x#*=} ;; ovl_mnt0_sub=*) OVL_MNT0_SUB=${x#*=} ;; ovl_dev1=*) OVL_DEV1=${x#*=} ;; ovl_mnt1=*) OVL_MNT1=${x#*=} ;; ovl_mnt1_opt=*) OVL_MNT1_OPT=${x#*=} ;; ovl_loopfile1=*) OVL_LOOPFILE1=${x#*=} ;; ovl_mnt1_sub=*) OVL_MNT1_SUB=${x#*=} ;; mount_move) MOUNT_MOVE=1 ;; # zm ================================================ # zm 2: find the device which contains loop files, mount and losetup. if [ -n "${LOOPS_DEV}" ]; then if [ -z "${LOOPS_DEV_MNT}" ]; then LOOPS_DEV_MNT='/loops' fi mkdir -p $LOOPS_DEV_MNT good_msg setup_loop_device "${LOOPS_DEV}" "${LOOPS_DEV_MNT}" "${LOOP_FILE}" "${LOOP_FILE_MNT}" "${LOOP_FILE_MNT_OPT}" setup_loop_device "${LOOPS_DEV}" "${LOOPS_DEV_MNT}" "${LOOP_FILE}" "${LOOP_FILE_MNT}" "${LOOP_FILE_MNT_OPT}" fi # zm 2-1: find the devices, loopfiles, dirs for overlay fs. if [ "${ROOTFSTYPE}" = 'overlay' ]; then OVL_MNT_DEV0="" if [ -n "${OVL_DEV0}" ]; then OVL_MNT_DEV0=$( real_device "${OVL_DEV0}" ) fi if [ -n "${OVL_MNT_DEV0}" ] && [ -n "${OVL_MNT0}" ]; then mkdir -p ${OVL_MNT0} good_msg mount_device echo "${OVL_MNT_DEV0}" "${OVL_MNT0}" mount_device "${OVL_MNT_DEV0}" "${OVL_MNT0}" if [ "$?" = '0' ]; then OVL_DEV0_MOUNTED=1 else OVL_DEV0_MOUNTED=0 fi fi if [ "${OVL_DEV0_MOUNTED}" = '1' ]; then if [ -n "${OVL_LOOPFILE0}" ]; then if [ -z "${OVL_MNT0_SUB}" ]; then OVL_MNT0_SUB="/lower" fi mkdir -p "${OVL_MNT0_SUB}" good_msg mount_loopfile echo "${OVL_LOOPFILE0}" "${OVL_MNT0_SUB}" mount_loopfile "${OVL_LOOPFILE0}" "${OVL_MNT0_SUB}" LOWER="${OVL_MNT0_SUB}" else if [ -n "${OVL_MNT0_SUB}" ]; then LOWER="${OVL_MNT0_SUB}" else LOWER="${OVL_MNT0}" fi fi fi if [ -n "${OVL_DEV1}" ]; then if [ "${OVL_DEV1}" = 'tmpfs' ]; then if [ -z "${OVL_MNT1_OPT}" ]; then OVL_MNT1_OPT='size=3072m' fi mkdir -p "${OVL_MNT1}" good_msg "mount -t tmpfs -o ${OVL_MNT1_OPT} ${OVL_DEV1} ${OVL_MNT1}" mount -t tmpfs -o "${OVL_MNT1_OPT}" "${OVL_DEV1}" "${OVL_MNT1}" UPPER="${OVL_MNT1}/upper" mkdir -p "${OVL_MNT1}/upper" WORK="${OVL_MNT1}/work" mkdir -p "${OVL_MNT1}/work" else # [ "${OVL_DEV1}" = 'tmpfs' ] OVL_MNT_DEV1="" if [ -n "${OVL_DEV1}" ]; then OVL_MNT_DEV1=$( real_device "${OVL_DEV1}" ) fi if [ -n "${OVL_MNT_DEV1}" ] && [ -n "${OVL_MNT1}" ]; then mkdir -p ${OVL_MNT1} echo mount ${OVL_MNT_DEV1} ${OVL_MNT1} mount ${OVL_MNT_DEV1} ${OVL_MNT1} if [ -z "${OVL_LOOPFILE1}" ]; then UPPER="${OVL_MNT1}/upper" mkdir -p "${OVL_MNT1}/upper" WORK="${OVL_MNT1}/work" mkdir -p "${OVL_MNT1}/work" fi fi if [ -n "${OVL_LOOPFILE1}" ]; then if [ -z "${OVL_MNT1_SUB}" ]; then OVL_MNT1_SUB="${OVL_MNT1}/rw" fi mkdir -p "${OVL_MNT1_SUB}" good_msg mount_loopfile echo "${OVL_LOOPFILE1}" "${OVL_MNT1_SUB}" mount_loopfile "${OVL_LOOPFILE1}" "${OVL_MNT1_SUB}" mkdir -p "${OVL_MNT1_SUB}/upper" mkdir -p "${OVL_MNT1_SUB}/work" UPPER="${OVL_MNT1_SUB}/upper" WORK="${OVL_MNT1_SUB}/work" else if [ -n "${OVL_MNT1_SUB}" ]; then mkdir -p "${OVL_MNT1_SUB}/upper" mkdir -p "${OVL_MNT1_SUB}/work" UPPER="${OVL_MNT1_SUB}/upper" WORK="${OVL_MNT1_SUB}/work" fi fi fi # [ "${OVL_DEV1}" = 'tmpfs' ] else # [ -n "${OVL_DEV1}" ] if [ -n "${OVL_LOOPFILE1}" ]; then if [ -z "${OVL_MNT1_SUB}" ]; then OVL_MNT1_SUB="${OVL_MNT0}/rw" fi mkdir -p "${OVL_MNT1_SUB}" good_msg mount_loopfile echo "${OVL_LOOPFILE1}" "${OVL_MNT1_SUB}" mount_loopfile "${OVL_LOOPFILE1}" "${OVL_MNT1_SUB}" mkdir -p "${OVL_MNT1_SUB}/upper" mkdir -p "${OVL_MNT1_SUB}/work" UPPER="${OVL_MNT1_SUB}/upper" WORK="${OVL_MNT1_SUB}/work" else #[ -n "${OVL_LOOPFILE1}" ] if [ -n "${OVL_MNT1_SUB}" ]; then mkdir -p "${OVL_MNT1_SUB}/upper" mkdir -p "${OVL_MNT1_SUB}/work" UPPER="${OVL_MNT1_SUB}/upper" WORK="${OVL_MNT1_SUB}/work" else if [ -z "${UPPER}" ]; then UPPER="${OVL_MNT0}/upper" mkdir -p "${OVL_MNT0}/upper" fi if [ -z "${WORK}" ]; then WORK="${OVL_MNT0}/work" mkdir -p "${OVL_MNT0}/work" fi fi #[ -n "${OVL_MNT1_SUB}" ] fi #[ -n "${OVL_LOOPFILE1}" ] fi # [ -n "${OVL_DEV1}" ] good_msg "OverlayFS: lowerdir=${LOWER},upperdir=${UPPER},workdir=${WORK} ..." REAL_ROOTFLAGS="lowerdir=${LOWER},upperdir=${UPPER},workdir=${WORK}" got_good_root=1 fi # zm [ "${ROOTFSTYPE}" = 'overlay' ] ========================================================= # zm 3: move LOOPS_DEV_MNT or OVL_MNTs from initramfs to real root if [ "${MOUNT_MOVE}" = '1' ]; then if [ -n "${LOOPS_DEV_MNT}" ]; then if [ ! -e "${CHROOT}${LOOPS_DEV_MNT}" ]; then mkdir -p "${CHROOT}${LOOPS_DEV_MNT}" fi good_msg "Remounting device=${LOOPS_DEV} to ${CHROOT}${LOOPS_DEV_MNT}" mount --move "${LOOPS_DEV_MNT}" "${CHROOT}${LOOPS_DEV_MNT}" fi if [ -n "${OVL_MNT0}" ]; then if [ ! -e "${CHROOT}${OVL_MNT0}" ]; then mkdir -p "${CHROOT}${OVL_MNT0}" fi good_msg "Remounting device=${OVL_DEV0} to ${CHROOT}${OVL_MNT0}" mount --move "${OVL_MNT0}" "${CHROOT}${OVL_MNT0}" fi if [ -n "${OVL_MNT1}" ]; then if [ ! -e "${CHROOT}${OVL_MNT1}" ]; then mkdir -p "${CHROOT}${OVL_MNT1}" fi good_msg "Remounting device=${OVL_DEV1} to ${CHROOT}${OVL_MNT1}" mount --move "${OVL_MNT1}" "${CHROOT}${OVL_MNT1}" fi fi # zm ========================================= -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 1.163.143.52 ※ 文章網址: https://www.ptt.cc/bbs/Linux/M.1500595026.A.51D.html ubuntu版 把共用部份放在 /etc/initramfs-tools/scripts/ 下 mount部份放在 /etc/initramfs-tools/scripts/init-premount/ 下 mount_move部份放在 /etc/initramfs-tools/scripts/init-bottom/ 下 (引用共用部份要記得先source) 然後執行 update-initramfs -c -k $(uname -r) 就可以得到新版的initrd了 ※ 編輯: czm (1.163.162.22), 08/14/2017 10:36:06