dmsquash-live-root.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. #!/bin/sh
  2. type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
  3. command -v unpack_archive >/dev/null || . /lib/img-lib.sh
  4. PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin
  5. if getargbool 0 rd.live.debug -n -y rdlivedebug; then
  6. exec > /tmp/liveroot.$$.out
  7. exec 2>> /tmp/liveroot.$$.out
  8. set -x
  9. fi
  10. [ -z "$1" ] && exit 1
  11. livedev="$1"
  12. # parse various live image specific options that make sense to be
  13. # specified as their own things
  14. live_dir=$(getarg rd.live.dir -d live_dir)
  15. [ -z "$live_dir" ] && live_dir="LiveOS"
  16. squash_image=$(getarg rd.live.squashimg)
  17. [ -z "$squash_image" ] && squash_image="squashfs.img"
  18. getargbool 0 rd.live.ram -d -y live_ram && live_ram="yes"
  19. getargbool 0 rd.live.overlay.reset -d -y reset_overlay && reset_overlay="yes"
  20. getargbool 0 rd.live.overlay.readonly -d -y readonly_overlay && readonly_overlay="--readonly" || readonly_overlay=""
  21. overlay=$(getarg rd.live.overlay -d overlay)
  22. getargbool 0 rd.writable.fsimg -d -y writable_fsimg && writable_fsimg="yes"
  23. overlay_size=$(getarg rd.live.overlay.size=)
  24. [ -z "$overlay_size" ] && overlay_size=512
  25. getargbool 0 rd.live.overlay.thin && thin_snapshot="yes"
  26. # CD/DVD media check
  27. [ -b $livedev ] && fs=$(blkid -s TYPE -o value $livedev)
  28. if [ "$fs" = "iso9660" -o "$fs" = "udf" ]; then
  29. check="yes"
  30. fi
  31. getarg rd.live.check -d check || check=""
  32. if [ -n "$check" ]; then
  33. type plymouth >/dev/null 2>&1 && plymouth --hide-splash
  34. if [ -n "$DRACUT_SYSTEMD" ]; then
  35. p=$(dev_unit_name "$livedev")
  36. systemctl start checkisomd5@${p}.service
  37. else
  38. checkisomd5 --verbose $livedev
  39. fi
  40. if [ $? -eq 1 ]; then
  41. die "CD check failed!"
  42. exit 1
  43. fi
  44. type plymouth >/dev/null 2>&1 && plymouth --show-splash
  45. fi
  46. ln -s $livedev /run/initramfs/livedev
  47. # determine filesystem type for a filesystem image
  48. det_img_fs() {
  49. udevadm settle
  50. blkid -s TYPE -u noraid -o value "$1"
  51. }
  52. modprobe squashfs
  53. CMDLINE=$(getcmdline)
  54. for arg in $CMDLINE; do case $arg in ro|rw) liverw=$arg ;; esac; done
  55. # mount the backing of the live image first
  56. mkdir -m 0755 -p /run/initramfs/live
  57. if [ -f $livedev ]; then
  58. # no mount needed - we've already got the LiveOS image in initramfs
  59. # check filesystem type and handle accordingly
  60. fstype=$(det_img_fs $livedev)
  61. case $fstype in
  62. squashfs) SQUASHED=$livedev;;
  63. auto) die "cannot mount live image (unknown filesystem type)" ;;
  64. *) FSIMG=$livedev ;;
  65. esac
  66. [ -e /sys/fs/$fstype ] || modprobe $fstype
  67. else
  68. mount -n -t $fstype -o ${liverw:-ro} $livedev /run/initramfs/live
  69. if [ "$?" != "0" ]; then
  70. die "Failed to mount block device of live image"
  71. exit 1
  72. fi
  73. fi
  74. # overlay setup helper function
  75. do_live_overlay() {
  76. # create a sparse file for the overlay
  77. # overlay: if non-ram overlay searching is desired, do it,
  78. # otherwise, create traditional overlay in ram
  79. OVERLAY_LOOPDEV=$( losetup -f )
  80. l=$(blkid -s LABEL -o value $livedev) || l=""
  81. u=$(blkid -s UUID -o value $livedev) || u=""
  82. if [ -z "$overlay" ]; then
  83. pathspec="/${live_dir}/overlay-$l-$u"
  84. elif ( echo $overlay | grep -q ":" ); then
  85. # pathspec specified, extract
  86. pathspec=$( echo $overlay | sed -e 's/^.*://' )
  87. fi
  88. if [ -z "$pathspec" -o "$pathspec" = "auto" ]; then
  89. pathspec="/${live_dir}/overlay-$l-$u"
  90. fi
  91. devspec=$( echo $overlay | sed -e 's/:.*$//' )
  92. # need to know where to look for the overlay
  93. setup=""
  94. if [ -n "$devspec" -a -n "$pathspec" -a -n "$overlay" ]; then
  95. mkdir -m 0755 /run/initramfs/overlayfs
  96. mount -n -t auto $devspec /run/initramfs/overlayfs || :
  97. if [ -f /run/initramfs/overlayfs$pathspec -a -w /run/initramfs/overlayfs$pathspec ]; then
  98. losetup $OVERLAY_LOOPDEV /run/initramfs/overlayfs$pathspec
  99. if [ -n "$reset_overlay" ]; then
  100. dd if=/dev/zero of=$OVERLAY_LOOPDEV bs=64k count=1 conv=fsync 2>/dev/null
  101. fi
  102. setup="yes"
  103. fi
  104. umount -l /run/initramfs/overlayfs || :
  105. fi
  106. if [ -z "$setup" -o -n "$readonly_overlay" ]; then
  107. if [ -n "$setup" ]; then
  108. warn "Using temporary overlay."
  109. elif [ -n "$devspec" -a -n "$pathspec" ]; then
  110. warn "Unable to find persistent overlay; using temporary"
  111. sleep 5
  112. fi
  113. dd if=/dev/null of=/overlay bs=1024 count=1 seek=$((overlay_size*1024)) 2> /dev/null
  114. if [ -n "$setup" -a -n "$readonly_overlay" ]; then
  115. RO_OVERLAY_LOOPDEV=$( losetup -f )
  116. losetup $RO_OVERLAY_LOOPDEV /overlay
  117. else
  118. losetup $OVERLAY_LOOPDEV /overlay
  119. fi
  120. fi
  121. # set up the snapshot
  122. sz=$(blockdev --getsz $BASE_LOOPDEV)
  123. if [ -n "$readonly_overlay" ]; then
  124. echo 0 $sz snapshot $BASE_LOOPDEV $OVERLAY_LOOPDEV N 8 | dmsetup create --readonly live-ro
  125. base="/dev/mapper/live-ro"
  126. over=$RO_OVERLAY_LOOPDEV
  127. else
  128. base=$BASE_LOOPDEV
  129. over=$OVERLAY_LOOPDEV
  130. fi
  131. if [ -n "$thin_snapshot" ]; then
  132. modprobe dm_thin_pool
  133. mkdir /run/initramfs/thin-overlay
  134. # In block units (512b)
  135. thin_data_sz=$(( $overlay_size * 1024 * 1024 / 512 ))
  136. thin_meta_sz=$(( $thin_data_sz / 10 ))
  137. # It is important to have the backing file on a tmpfs
  138. # this is needed to let the loopdevice support TRIM
  139. dd if=/dev/null of=/run/initramfs/thin-overlay/meta bs=1b count=1 seek=$((thin_meta_sz)) 2> /dev/null
  140. dd if=/dev/null of=/run/initramfs/thin-overlay/data bs=1b count=1 seek=$((thin_data_sz)) 2> /dev/null
  141. THIN_META_LOOPDEV=$( losetup --show -f /run/initramfs/thin-overlay/meta )
  142. THIN_DATA_LOOPDEV=$( losetup --show -f /run/initramfs/thin-overlay/data )
  143. echo 0 $thin_data_sz thin-pool $THIN_META_LOOPDEV $THIN_DATA_LOOPDEV 1024 1024 | dmsetup create live-overlay-pool
  144. dmsetup message /dev/mapper/live-overlay-pool 0 "create_thin 0"
  145. # Create a snapshot of the base image
  146. echo 0 $sz thin /dev/mapper/live-overlay-pool 0 $base | dmsetup create live-rw
  147. else
  148. #emergency_shell
  149. loadkeys trq
  150. ln -s /usr/sbin/dmsetup /sbin/
  151. modprobe dm_mod
  152. modprobe dm_multipath
  153. echo "ornek:echo 0 7273437 snapshot /dev/loop1 /dev/loop2 PO 8"
  154. echo 0 $sz snapshot $base $over PO 8 | dmsetup create live-rw &
  155. fi
  156. # Create a device that always points to a ro base image
  157. echo 0 $sz linear $BASE_LOOPDEV 0 | dmsetup create --readonly live-base &
  158. ln -s /dev/dm-0 /dev/mapper/live-base
  159. ln -s /dev/dm-1 /dev/mapper/live-rw
  160. #emergency_shell
  161. }
  162. # live cd helper function
  163. do_live_from_base_loop() {
  164. do_live_overlay
  165. }
  166. # we might have a genMinInstDelta delta file for anaconda to take advantage of
  167. if [ -e /run/initramfs/live/${live_dir}/osmin.img ]; then
  168. OSMINSQFS=/run/initramfs/live/${live_dir}/osmin.img
  169. fi
  170. if [ -n "$OSMINSQFS" ]; then
  171. # decompress the delta data
  172. dd if=$OSMINSQFS of=/run/initramfs/osmin.img 2> /dev/null
  173. OSMIN_SQUASHED_LOOPDEV=$( losetup -f )
  174. losetup -r $OSMIN_SQUASHED_LOOPDEV /run/initramfs/osmin.img
  175. mkdir -m 0755 -p /run/initramfs/squashfs.osmin
  176. mount -n -t squashfs -o ro $OSMIN_SQUASHED_LOOPDEV /run/initramfs/squashfs.osmin
  177. OSMIN_LOOPDEV=$( losetup -f )
  178. losetup -r $OSMIN_LOOPDEV /run/initramfs/squashfs.osmin/osmin
  179. umount -l /run/initramfs/squashfs.osmin
  180. fi
  181. # we might have an embedded fs image on squashfs (compressed live)
  182. if [ -e /run/initramfs/live/${live_dir}/${squash_image} ]; then
  183. SQUASHED="/run/initramfs/live/${live_dir}/${squash_image}"
  184. if [ -n "$live_ram" ]; then
  185. echo "Copying live image to RAM..."
  186. echo "(this may take a few minutes)"
  187. dd if=$SQUASHED of=/run/initramfs/squashed.img bs=512 2> /dev/null
  188. echo "Done copying live image to RAM."
  189. SQUASHED="/run/initramfs/squashed.img"
  190. fi
  191. SQUASHED_LOOPDEV=$( losetup -f )
  192. losetup -r $SQUASHED_LOOPDEV $SQUASHED
  193. mkdir -m 0755 -p /run/initramfs/squashfs
  194. mount -n -t squashfs -o ro $SQUASHED_LOOPDEV /run/initramfs/squashfs
  195. if [ -f /run/initramfs/squashfs/LiveOS/ext3fs.img ]; then
  196. FSIMG="/run/initramfs/squashfs/LiveOS/ext3fs.img"
  197. elif [ -f /run/initramfs/squashfs/LiveOS/rootfs.img ]; then
  198. FSIMG="/run/initramfs/squashfs/LiveOS/rootfs.img"
  199. fi
  200. else
  201. # we might have an embedded fs image to use as rootfs (uncompressed live)
  202. if [ -e /run/initramfs/live/${live_dir}/ext3fs.img ]; then
  203. FSIMG="/run/initramfs/live/${live_dir}/ext3fs.img"
  204. elif [ -e /run/initramfs/live/${live_dir}/rootfs.img ]; then
  205. FSIMG="/run/initramfs/live/${live_dir}/rootfs.img"
  206. fi
  207. if [ -n "$live_ram" ]; then
  208. echo 'Copying live image to RAM...'
  209. echo '(this may take a few minutes)'
  210. dd if=$FSIMG of=/run/initramfs/rootfs.img bs=512 2> /dev/null
  211. echo 'Done copying live image to RAM.'
  212. FSIMG='/run/initramfs/rootfs.img'
  213. fi
  214. fi
  215. if [ -n "$FSIMG" ] ; then
  216. BASE_LOOPDEV=$( losetup -f )
  217. if [ -n "$writable_fsimg" ] ; then
  218. # mount the provided filesystem read/write
  219. echo "Unpacking live filesystem (may take some time)"
  220. mkdir /run/initramfs/fsimg/
  221. if [ -n "$SQUASHED" ]; then
  222. cp -v $FSIMG /run/initramfs/fsimg/rootfs.img
  223. else
  224. unpack_archive $FSIMG /run/initramfs/fsimg/
  225. fi
  226. FSIMG=/run/initramfs/fsimg/rootfs.img
  227. fi
  228. if [ -n "$writable_fsimg" ] || [ -z "$SQUASHED" -a -n "$live_ram" ] ||
  229. [ "$overlay" = none -o "$overlay" = None -o "$overlay" = NONE ]; then
  230. losetup $BASE_LOOPDEV $FSIMG
  231. sz=$(blockdev --getsz $BASE_LOOPDEV)
  232. echo 0 $sz linear $BASE_LOOPDEV 0 | dmsetup create live-rw
  233. else
  234. # mount the filesystem read-only and add a dm snapshot for writes
  235. losetup -r $BASE_LOOPDEV $FSIMG
  236. do_live_from_base_loop
  237. fi
  238. fi
  239. [ -e "$SQUASHED" ] && umount -l /run/initramfs/squashfs
  240. if [ -b "$OSMIN_LOOPDEV" ]; then
  241. # set up the devicemapper snapshot device, which will merge
  242. # the normal live fs image, and the delta, into a minimzied fs image
  243. echo "0 $( blockdev --getsz $BASE_LOOPDEV ) snapshot $BASE_LOOPDEV $OSMIN_LOOPDEV N 8" | dmsetup create --readonly live-osimg-min
  244. fi
  245. ROOTFLAGS="$(getarg rootflags)"
  246. if [ -n "$ROOTFLAGS" ]; then
  247. ROOTFLAGS="-o $ROOTFLAGS"
  248. fi
  249. ln -s /dev/mapper/live-rw /dev/root
  250. if [ -z "$DRACUT_SYSTEMD" ]; then
  251. printf 'mount %s /dev/mapper/live-rw %s\n' "$ROOTFLAGS" "$NEWROOT" > $hookdir/mount/01-$$-live.sh
  252. fi
  253. need_shutdown
  254. exit 0