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