Gentoo Archives: gentoo-commits

From: Richard Farina <zerochaos@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/genkernel:aufs commit in: defaults/
Date: Thu, 22 May 2014 20:28:54
Message-Id: 1400789026.6df308a1f51e423d7378147610562459538249ec.zerochaos@gentoo
1 commit: 6df308a1f51e423d7378147610562459538249ec
2 Author: Rick Farina (Zero_Chaos) <zerochaos <AT> gentoo <DOT> org>
3 AuthorDate: Thu May 9 02:24:51 2013 +0000
4 Commit: Richard Farina <zerochaos <AT> gentoo <DOT> org>
5 CommitDate: Thu May 22 20:03:46 2014 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/genkernel.git;a=commit;h=6df308a1
7
8 Proper AUFS support
9
10 This patch is what we have been using for the Pentoo LiveCDs for about 5
11 years with the changes suggested by lxnay merged in. As much as
12 possible has been addressed (with the exception of the man page
13 documentation). Please review this code as the next version will likely
14 be suggested for inclusion (once I write the documentation for the new
15 features).
16
17 Signed-off-by: Rick Farina (Zero_Chaos) <zerochaos <AT> gentoo.org>
18
19 ---
20 defaults/initrd.defaults | 1 +
21 defaults/initrd.scripts | 180 +++++++++++++++++++++++++++++++++++++++++++
22 defaults/linuxrc | 194 ++++++++++++++++++++++++++++++++++-------------
23 3 files changed, 321 insertions(+), 54 deletions(-)
24
25 diff --git a/defaults/initrd.defaults b/defaults/initrd.defaults
26 index cbf18f3..3d6fe7e 100755
27 --- a/defaults/initrd.defaults
28 +++ b/defaults/initrd.defaults
29 @@ -65,6 +65,7 @@ CDROOT_PATH='/mnt/cdrom'
30 # This is the file that the cdroot will be checked for as a
31 # marker. It must exist RELATIVE to the cdroot.
32 CDROOT_MARKER='/livecd'
33 +AUFS_CHANGESFILE=livecd.aufs
34
35 LOOPS='/livecd.loop /zisofs /livecd.squashfs /image.squashfs /livecd.gcloop'
36
37
38 diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts
39 index 5ef5d0b..6b31095 100644
40 --- a/defaults/initrd.scripts
41 +++ b/defaults/initrd.scripts
42 @@ -234,6 +234,186 @@ mount_sysfs() {
43 [ ${ret} -eq 0 ] || bad_msg "Failed to mount /sys!"
44 }
45
46 +# Insert a directory tree ${2} to an union specified by ${1}
47 +# Top-level read-write branch is specified by it's index 0
48 +# ${1} = union absolute path (starting with /)
49 +# ${2} = path to data directory
50 +#
51 +union_insert_dir() {
52 + # Always mount it over the precedent (add:1:)
53 + mount -n -o remount,add:1:${2}=rr aufs ${1}
54 + if [ $? = '0' ]
55 + then
56 + good_msg "Addition of ${2} to ${1} successful"
57 + fi
58 +}
59 +
60 +# Insert all modules found in $1, usually ${CDROOT_PATH}
61 +# added to allow users to add their own apps.
62 +union_insert_modules() {
63 + for module in $(ls ${NEW_ROOT}/${1}/modules/*.mo 2>/dev/null| sort)
64 + do
65 + mkdir -p ${MEMORY}/modules/$(basename ${module} .mo)
66 + union_insert_dir $UNION ${MEMORY}/modules/$(basename ${module} .mo)
67 + done
68 + for module in $(ls ${NEW_ROOT}/${1}/modules/*.lzm 2>/dev/null| sort)
69 + do
70 + mkdir -p ${MEMORY}/modules/$(basename ${module} .lzm)
71 + mount -o loop,ro ${module} ${MEMORY}/modules/$(basename ${module} .lzm)
72 + union_insert_dir $UNION ${MEMORY}/modules/$(basename ${module} .lzm)
73 + done
74 +}
75 +
76 +# Function to create an ext2 fs on $CHANGESDEV, $CHANGESMNT mountpoint
77 +create_changefs() {
78 + local size
79 + while [ 1 ]
80 + do
81 + read -p '<< Size of file (Enter for default 256 Mb): ' size
82 + if [ -z "${size}" ]; then
83 + let size=256
84 + fi
85 + let size="${size}"
86 + if [ ${size} -lt 16 ]
87 + then
88 + bad_msg "Please give a size of at least 16 Mb"
89 + else
90 + dd if=/dev/zero of=${CHANGESMNT}/${AUFS_CHANGESFILE} bs=1M count=${size}
91 + if [ $? = '0' ]
92 + then
93 + good_msg "Creation of ${AUFS_CHANGESFILE}, ${size} Mb on ${CHANGESDEV} successful, formatting it ext2"
94 + mke2fs -F ${CHANGESMNT}/${AUFS_CHANGESFILE}
95 + break
96 + else
97 + rm -f ${CHANGESMNT}/${AUFS_CHANGESFILE}
98 + bad_msg "Unable to create ${AUFS_CHANGESFILE} on ${CHANGESDEV} of ${size} Mb"
99 + bad_msg "Please give a size of at least 16 Mb"
100 + bad_msg "Also check if your disk is full or read-only ?"
101 + read -p '<< Type "a" to abort, anything else to continue : ' doabort
102 + if [ "${doabort}" = "a" ]; then
103 + return 1
104 + fi
105 + fi
106 + fi
107 + done
108 + return 0
109 +}
110 +
111 +setup_aufs() {
112 + if [ "${USE_AUFS_NORMAL}" -eq '1' ]
113 + then
114 + # Directory used for rw changes in union mount filesystem
115 + UNION=/union
116 + MEMORY=/memory
117 + # Mountpoint for the changesdev
118 + CHANGESMNT=${NEW_ROOT}/mnt/changesdev
119 + if [ -z "$UID" ]
120 + then
121 + CHANGES=${MEMORY}/aufs_changes/default
122 + else
123 + CHANGES=${MEMORY}/aufs_changes/${UID}
124 + fi
125 +
126 + mkdir -p ${MEMORY}
127 + mkdir -p ${UNION}
128 + mkdir -p ${CHANGESMNT}
129 + for i in dev mnt ${CDROOT_PATH} mnt/livecd mnt/key tmp tmp/.initrd mnt/gentoo sys
130 + do
131 + mkdir -p "${NEW_ROOT}/${i}"
132 + chmod 755 "${NEW_ROOT}/${i}"
133 + done
134 + [ ! -e "${NEW_ROOT}/dev/null" ] && mknod "${NEW_ROOT}"/dev/null c 1 3
135 + [ ! -e "${NEW_ROOT}/dev/console" ] && mknod "${NEW_ROOT}"/dev/console c 5 1
136 +
137 + bootstrapCD
138 + if [ -n "${AUFS}" ]
139 + then
140 + if [ "${AUFS}" = "detect" ]
141 + then
142 + CHANGESMNT="${NEW_ROOT}${CDROOT_PATH}"
143 + CHANGESDEV=${REAL_ROOT}
144 + else
145 + CHANGESDEV=${AUFS}
146 + good_msg "mounting ${CHANGESDEV} to ${MEMORY} for aufs support"
147 + mount -t auto ${CHANGESDEV} ${CHANGESMNT}
148 + ret=$?
149 + if [ "${ret}" -ne 0 ]
150 + then
151 + bad_msg "mount of ${CHANGESDEV} failed, falling back to ramdisk based aufs"
152 + unset AUFS
153 + fi
154 + fi
155 + # Check and attempt to create the changesfile
156 + if [ ! -e ${CHANGESMNT}/${AUFS_CHANGESFILE} ] && [ -n "${AUFS}" ]
157 + then
158 + create_changefs
159 + mount -t auto ${CHANGESMNT}/${AUFS_CHANGESFILE} ${MEMORY}
160 + elif [ -n "${AUFS}" ]
161 + then
162 + local nbpass=0
163 + while [ 1 ]
164 + do
165 + mount -t auto ${CHANGESMNT}/${AUFS_CHANGESFILE} ${MEMORY}
166 + ret=$?
167 + if [ "${ret}" -ne 0 ]
168 + then
169 + if [ ${nbpass} -eq 0 ]
170 + then
171 + bad_msg "mounting of changes file failed, Running e2fsck"
172 + e2fsck ${CHANGESMNT}/${AUFS_CHANGESFILE}
173 + nbpass=$((${nbpass} + 1))
174 + else
175 + bad_msg "mount of ${CHANGESDEV} failed, falling back to ramdisk based aufs"
176 + bad_msg "your ${AUFS_CHANGESFILE} might be messed up, and I couldn't fix it"
177 + bad_msg "moving ${AUFS_CHANGESFILE} to ${AUFS_CHANGESFILE}.bad"
178 + mv ${CHANGESMNT}/${AUFS_CHANGESFILE} ${CHANGESMNT}/${AUFS_CHANGESFILE}.bad
179 + bad_msg "try to fix it yourself with e2fsck later on, sorry for disturbing"
180 + break
181 + fi
182 + else
183 + if [ ${nbpass} -eq 1 ]
184 + then
185 + good_msg "e2fsck ran successfully. Please check your files after bootup"
186 + fi
187 + break
188 + fi
189 + done
190 + fi
191 + # mount tmpfs only in the case when changes= boot parameter was
192 + # empty or we were not able to mount the storage device
193 + if [ "${CDROOT}" -eq '1' -a ! -f ${CHANGESMNT}/${AUFS_CHANGESFILE} ]
194 + then
195 + umount ${MEMORY}
196 + bad_msg "failed to find ${AUFS_CHANGESFILE} file on ${CHANGESDEV}"
197 + bad_msg "create an ext2 ${AUFS_CHANGESFILE} file on this device if you wish to use it for aufs"
198 + bad_msg "falling back to ramdisk based aufs for safety"
199 + mount -t tmpfs tmpfs ${MEMORY}
200 + XINO=${MEMORY}
201 + else
202 + XINO=${MEMORY}/xino
203 + mkdir -p ${XINO}
204 + mount -t tmpfs tmpfs ${XINO}
205 + fi
206 + else
207 + good_msg "Mounting ramdisk to $MEMORY for aufs support..."
208 + mount -t tmpfs tmpfs ${MEMORY}
209 + XINO=${MEMORY}
210 + fi
211 +
212 + mkdir -p ${CHANGES}
213 + mount -t aufs -n -o nowarn_perm,udba=none,xino=${XINO}/.aufs.xino,br:${CHANGES}=rw aufs ${UNION}
214 + ret=$?
215 + if [ "${ret}" -ne 0 ]
216 + then
217 + bad_msg "Can't setup union ${UNION} in directory!"
218 + USE_AUFS_NORMAL=0
219 + fi
220 + else
221 + USE_AUFS_NORMAL=0
222 + fi
223 +}
224 +
225 +
226 findnfsmount() {
227 if [ "${IP}" != '' ] || busybox udhcpc -n -T 15 -q
228 then
229
230 diff --git a/defaults/linuxrc b/defaults/linuxrc
231 index 6401614..e2e1b6f 100644
232 --- a/defaults/linuxrc
233 +++ b/defaults/linuxrc
234 @@ -253,6 +253,38 @@ do
235 aufs)
236 USE_AUFS_NORMAL=1
237 ;;
238 + aufs\=*)
239 + USE_AUFS_NORMAL=1
240 + CMD_AUFS=$(parse_opt "${x}")
241 + echo ${CMD_AUFS}|grep , >/dev/null 2>&1
242 + if [ "$?" -eq '0' ]
243 + then
244 + UID=$(echo ${CMD_AUFS#*,})
245 + AUFS=$(echo ${CMD_AUFS%,*})
246 + else
247 + AUFS=${CMD_AUFS}
248 + fi
249 + ;;
250 + aufs.changes\=*)
251 + USE_AUFS_NORMAL=1
252 + CMD_AUFS=$(parse_opt "${x}")
253 + echo ${CMD_AUFS}|grep , >/dev/null 2>&1
254 + if [ "$?" -eq '0' ]
255 + then
256 + UID=$(echo ${CMD_AUFS#*,})
257 + AUFS=$(echo ${CMD_AUFS%,*})
258 + else
259 + AUFS=${CMD_AUFS}
260 + fi
261 + ;;
262 + aufs.persistent)
263 + USE_AUFS_NORMAL=1
264 + AUFS="detect"
265 + ;;
266 + # Allow user to specify the modules location
267 + aufs.modules\=*)
268 + MODULESD=$(parse_opt "${x}")
269 + ;;
270 unionfs)
271 if [ ! -x /sbin/unionfs ]
272 then
273 @@ -425,19 +457,26 @@ rundebugshell "before setting up the root filesystem"
274
275 if [ "${CDROOT}" = '1' ]
276 then
277 - good_msg "Making tmpfs for ${NEW_ROOT}"
278 - mount -n -t tmpfs tmpfs "${NEW_ROOT}"
279 + setup_aufs
280 + if [ "${USE_AUFS_NORMAL}" -eq '1' ]
281 + then
282 + CHROOT=${UNION}
283 + else
284 + CHROOT=${NEW_ROOT}
285 + good_msg "Making tmpfs for ${NEW_ROOT}"
286 + mount -n -t tmpfs tmpfs ${NEW_ROOT}
287
288 - for i in dev mnt proc run sys tmp mnt/livecd mnt/key tmp/.initrd mnt/gentoo
289 - do
290 - mkdir -p "${NEW_ROOT}/${i}"
291 - chmod 755 "${NEW_ROOT}/${i}"
292 - done
293 - [ ! -d "${CDROOT_PATH}" ] && mkdir -p "${CDROOT_PATH}"
294 - [ ! -e "${NEW_ROOT}/dev/null" ] && mknod -m 660 "${NEW_ROOT}"/dev/null c 1 3
295 - [ ! -e "${NEW_ROOT}/dev/zero" ] && mknod -m 660 "${NEW_ROOT}"/dev/zero c 1 5
296 - [ ! -e "${NEW_ROOT}/dev/console" ] && mknod -m 660 "${NEW_ROOT}"/dev/console c 5 1
297 - [ ! -e "${NEW_ROOT}/dev/ttyS0" ] && mknod -m 600 "${NEW_ROOT}"/dev/ttyS0 c 4 64
298 + for i in dev mnt ${CDROOT_PATH} proc run mnt/livecd mnt/key tmp tmp/.initrd mnt/gentoo sys
299 + do
300 + mkdir -p "${NEW_ROOT}/${i}"
301 + chmod 755 "${NEW_ROOT}/${i}"
302 + done
303 + [ ! -d "${CDROOT_PATH}" ] && mkdir -p "${CDROOT_PATH}"
304 + [ ! -e "${NEW_ROOT}/dev/null" ] && mknod -m 666 "${NEW_ROOT}"/dev/null c 1 3
305 + [ ! -e "${NEW_ROOT}/dev/zero" ] && mknod -m 666 "${NEW_ROOT}"/dev/zero c 1 5
306 + [ ! -e "${NEW_ROOT}/dev/console" ] && mknod -m 600 "${NEW_ROOT}"/dev/console c 5 1
307 + [ ! -e "${NEW_ROOT}/dev/ttyS0" ] && mknod -m 660 "${NEW_ROOT}"/dev/ttyS0 c 4 64
308 + fi
309
310 # For SGI LiveCDs ...
311 if [ "${LOOPTYPE}" = "sgimips" ]
312 @@ -452,7 +491,7 @@ then
313 [ ! -e "${NEW_ROOT}/dev/$minor" ] && mknod -m 600 "${NEW_ROOT}/dev/tty$minor" c 4 $minor
314 done
315
316 - if [ "${REAL_ROOT}" != "/dev/nfs" ] && [ "${LOOPTYPE}" != "sgimips" ]
317 + if [ "${REAL_ROOT}" != "/dev/nfs" ] && [ "${LOOPTYPE}" != "sgimips" ] && [ "${USE_AUFS_NORMAL}" != '1' ]
318 then
319 bootstrapCD
320 fi
321 @@ -764,7 +803,23 @@ then
322 fi
323 fi
324
325 + if [ "${USE_AUFS_NORMAL}" -eq '1' ]
326 + then
327 + union_insert_dir ${UNION} ${NEW_ROOT}/${FS_LOCATION}
328
329 + # Make sure fstab notes livecd is mounted ro. Makes system skip remount which fails on aufs dirs.
330 + sed -e 's|\(.*\s/\s*tmpfs\s*\)defaults\(.*\)|\1defaults,ro\2|' /${UNION}/etc/fstab > /${UNION}/etc/fstab.new
331 + mv /${UNION}/etc/fstab.new /${UNION}/etc/fstab
332 + warn_msg "Adding all modules in $MODULESD/modules/"
333 + if [ -z "${MODULESD}" ]
334 + then
335 + union_insert_modules ${CDROOT_PATH}
336 + else
337 + mkdir ${NEW_ROOT}/mnt/modulesd
338 + mount "${MODULESD}" ${NEW_ROOT}/mnt/modulesd
339 + union_insert_modules ${NEW_ROOT}/mnt/modulesd
340 + fi
341 + fi
342
343 # Unpacking additional packages from NFS mount
344 # This is useful for adding kernel modules to /lib
345 @@ -787,56 +842,60 @@ then
346 then
347 setup_unionfs ${NEW_ROOT} /${FS_LOCATION}
348 CHROOT=/union
349 - elif [ "${USE_AUFS_NORMAL}" != '1' ]; then
350 -
351 - good_msg "Copying read-write image contents to tmpfs"
352 - # Copy over stuff that should be writable
353 - (cd "${NEW_ROOT}/${FS_LOCATION}"; cp -a ${ROOT_TREES} "${NEW_ROOT}") || {
354 - bad_msg "Copying failed, dropping into a shell."
355 - do_rundebugshell
356 - }
357 -
358 - # Now we do the links.
359 - for x in ${ROOT_LINKS}
360 - do
361 - if [ -L "${NEW_ROOT}/${FS_LOCATION}/${x}" ]
362 + else
363 + #XXX Note to potential reviewers. diff formats this section very very oddly. Be sure to review this hunk after applied, do NOT simply read the diff
364 + if [ ! "${USE_AUFS_NORMAL}" -eq '1' ]
365 then
366 - ln -s "$(readlink ${NEW_ROOT}/${FS_LOCATION}/${x})" "${x}" 2>/dev/null
367 - else
368 - # List all subdirectories of x
369 - find "${NEW_ROOT}/${FS_LOCATION}/${x}" -type d 2>/dev/null | while read directory
370 + good_msg "Copying read-write image contents to tmpfs"
371 + # Copy over stuff that should be writable
372 + (cd "${NEW_ROOT}/${FS_LOCATION}"; cp -a ${ROOT_TREES} "${NEW_ROOT}") || {
373 + bad_msg "Copying failed, dropping into a shell."
374 + do_rundebugshell
375 + }
376 +
377 + # Now we do the links.
378 + for x in ${ROOT_LINKS}
379 do
380 - # Strip the prefix of the FS_LOCATION
381 - directory="${directory#${NEW_ROOT}/${FS_LOCATION}/}"
382 -
383 - # Skip this directory if we already linked a parent directory
384 - if [ "${current_parent}" != '' ]; then
385 - var=$(echo "${directory}" | grep "^${current_parent}")
386 - if [ "${var}" != '' ]; then
387 - continue
388 - fi
389 - fi
390 - # Test if the directory exists already
391 - if [ -e "/${NEW_ROOT}/${directory}" ]
392 + if [ -L "${NEW_ROOT}/${FS_LOCATION}/${x}" ]
393 then
394 - # It does exist, link all the individual files
395 - for file in $(ls /${NEW_ROOT}/${FS_LOCATION}/${directory})
396 + ln -s "$(readlink ${NEW_ROOT}/${FS_LOCATION}/${x})" "${x}" 2>/dev/null
397 + else
398 + # List all subdirectories of x
399 + find "${NEW_ROOT}/${FS_LOCATION}/${x}" -type d 2>/dev/null | while read directory
400 do
401 - if [ ! -d "/${NEW_ROOT}/${FS_LOCATION}/${directory}/${file}" ] && [ ! -e "${NEW_ROOT}/${directory}/${file}" ]; then
402 - ln -s "/${FS_LOCATION}/${directory}/${file}" "${directory}/${file}" 2> /dev/null
403 + # Strip the prefix of the FS_LOCATION
404 + directory="${directory#${NEW_ROOT}/${FS_LOCATION}/}"
405 +
406 + # Skip this directory if we already linked a parent directory
407 + if [ "${current_parent}" != '' ]; then
408 + var=$(echo "${directory}" | grep "^${current_parent}")
409 + if [ "${var}" != '' ]; then
410 + continue
411 + fi
412 + fi
413 + # Test if the directory exists already
414 + if [ -e "/${NEW_ROOT}/${directory}" ]
415 + then
416 + # It does exist, link all the individual files
417 + for file in $(ls /${NEW_ROOT}/${FS_LOCATION}/${directory})
418 + do
419 + if [ ! -d "/${NEW_ROOT}/${FS_LOCATION}/${directory}/${file}" ] && [ ! -e "${NEW_ROOT}/${directory}/${file}" ]; then
420 + ln -s "/${FS_LOCATION}/${directory}/${file}" "${directory}/${file}" 2> /dev/null
421 + fi
422 + done
423 + else
424 + # It does not exist, make a link to the livecd
425 + ln -s "/${FS_LOCATION}/${directory}" "${directory}" 2>/dev/null
426 + current_parent="${directory}"
427 fi
428 done
429 - else
430 - # It does not exist, make a link to the livecd
431 - ln -s "/${FS_LOCATION}/${directory}" "${directory}" 2>/dev/null
432 - current_parent="${directory}"
433 fi
434 done
435 - fi
436 - done
437 + mkdir initramfs proc tmp sys 2>/dev/null
438 + chmod 1777 tmp
439
440 - mkdir initramfs proc tmp sys run 2>/dev/null
441 - chmod 1777 tmp
442 + fi
443 + #XXX: end extremely confusing hunk
444
445 # have handy /mnt/cdrom (CDROOT_PATH) as well
446 _new_cdroot="${NEW_ROOT}${CDROOT_PATH}"
447 @@ -863,6 +922,12 @@ else
448 setup_unionfs /union_changes ${NEW_ROOT}
449 mkdir -p ${UNION}/tmp/.initrd
450 fi
451 + if [ "${USE_AUFS_NORMAL}" -eq '1' ]
452 + then
453 + union_insert_dir ${UNION} ${NEW_ROOT}
454 + mkdir -p ${UNION}/tmp/.initrd
455 + fi
456 +
457 fi
458
459 # Mount the additional things as required by udev & systemd
460 @@ -907,6 +972,27 @@ fi
461
462 verbose_kmsg
463
464 +if [ "${USE_AUFS_NORMAL}" -eq '1' ]
465 +then
466 + mkdir -p /${CHROOT}/.unions/memory 2>/dev/null
467 + mount -o move /memory /${CHROOT}/.unions/memory || echo '*: Failed to move aufs /memory into the system root!'
468 + for i in tmp var/tmp mnt/gentoo mnt/livecd
469 + do
470 + mkdir -p ${CHROOT}/$i
471 + chmod 755 ${CHROOT}/$i
472 + done
473 + # This will prevent from putting junk on the CHANGESDEV
474 + mkdir -p ${CHROOT}/usr/portage/distfiles
475 + mount -t tmpfs tmpfs ${CHROOT}/var/tmp
476 + mount -t tmpfs tmpfs ${CHROOT}/tmp
477 + mount -t tmpfs tmpfs ${CHROOT}/usr/portage/distfiles
478 + warn_msg "/tmp /var/tmp /usr/portage/distfiles are mounted in ram"
479 + warn_msg "consider saving important files elsewhere..."
480 + read -t 3 UNUSEDVAL
481 + mount --bind ${NEW_ROOT}${CDROOT_PATH} ${CHROOT}${CDROOT_PATH}
482 + mount --bind ${NEW_ROOT}/mnt/livecd ${CHROOT}/mnt/livecd
483 +fi
484 +
485 good_msg "Booting (initramfs)"
486
487 cd "${CHROOT}"