aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRick Farina (Zero_Chaos) <zerochaos@gentoo.org>2013-05-08 22:24:51 -0400
committerRick Farina (Zero_Chaos) <zerochaos@gentoo.org>2015-04-29 13:31:44 -0400
commit7149888e45e8ef7471ebb1461f3edb568bdd8b94 (patch)
tree673b63a9a787750f0181e13081ed66120db94087
parentset DEFAULT_MAKEOPTS to what portage uses (diff)
downloadgenkernel-7149888e45e8ef7471ebb1461f3edb568bdd8b94.tar.gz
genkernel-7149888e45e8ef7471ebb1461f3edb568bdd8b94.tar.bz2
genkernel-7149888e45e8ef7471ebb1461f3edb568bdd8b94.zip
Proper AUFS support
This patch is what we have been using for the Pentoo LiveCDs for about 5 years with the changes suggested by lxnay merged in. As much as possible has been addressed (with the exception of the man page documentation). Please review this code as the next version will likely be suggested for inclusion (once I write the documentation for the new features). Signed-off-by: Rick Farina (Zero_Chaos) <zerochaos@gentoo.org>
-rwxr-xr-xdefaults/initrd.defaults1
-rw-r--r--defaults/initrd.scripts180
-rw-r--r--defaults/linuxrc194
3 files changed, 321 insertions, 54 deletions
diff --git a/defaults/initrd.defaults b/defaults/initrd.defaults
index 69be516..a017642 100755
--- a/defaults/initrd.defaults
+++ b/defaults/initrd.defaults
@@ -65,6 +65,7 @@ CDROOT_PATH='/mnt/cdrom'
# This is the file that the cdroot will be checked for as a
# marker. It must exist RELATIVE to the cdroot.
CDROOT_MARKER='/livecd'
+AUFS_CHANGESFILE=livecd.aufs
LOOPS='/livecd.loop /zisofs /livecd.squashfs /image.squashfs /livecd.gcloop'
diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts
index 153c379..1bae276 100644
--- a/defaults/initrd.scripts
+++ b/defaults/initrd.scripts
@@ -234,6 +234,186 @@ mount_sysfs() {
[ ${ret} -eq 0 ] || bad_msg "Failed to mount /sys!"
}
+# Insert a directory tree ${2} to an union specified by ${1}
+# Top-level read-write branch is specified by it's index 0
+# ${1} = union absolute path (starting with /)
+# ${2} = path to data directory
+#
+union_insert_dir() {
+ # Always mount it over the precedent (add:1:)
+ mount -n -o remount,add:1:${2}=rr aufs ${1}
+ if [ $? = '0' ]
+ then
+ good_msg "Addition of ${2} to ${1} successful"
+ fi
+}
+
+# Insert all modules found in $1, usually ${CDROOT_PATH}
+# added to allow users to add their own apps.
+union_insert_modules() {
+ for module in $(ls ${NEW_ROOT}/${1}/modules/*.mo 2>/dev/null| sort)
+ do
+ mkdir -p ${MEMORY}/modules/$(basename ${module} .mo)
+ union_insert_dir $UNION ${MEMORY}/modules/$(basename ${module} .mo)
+ done
+ for module in $(ls ${NEW_ROOT}/${1}/modules/*.lzm 2>/dev/null| sort)
+ do
+ mkdir -p ${MEMORY}/modules/$(basename ${module} .lzm)
+ mount -o loop,ro ${module} ${MEMORY}/modules/$(basename ${module} .lzm)
+ union_insert_dir $UNION ${MEMORY}/modules/$(basename ${module} .lzm)
+ done
+}
+
+# Function to create an ext2 fs on $CHANGESDEV, $CHANGESMNT mountpoint
+create_changefs() {
+ local size
+ while [ 1 ]
+ do
+ read -p '<< Size of file (Enter for default 256 Mb): ' size
+ if [ -z "${size}" ]; then
+ let size=256
+ fi
+ let size="${size}"
+ if [ ${size} -lt 16 ]
+ then
+ bad_msg "Please give a size of at least 16 Mb"
+ else
+ dd if=/dev/zero of=${CHANGESMNT}/${AUFS_CHANGESFILE} bs=1M count=${size}
+ if [ $? = '0' ]
+ then
+ good_msg "Creation of ${AUFS_CHANGESFILE}, ${size} Mb on ${CHANGESDEV} successful, formatting it ext2"
+ mke2fs -F ${CHANGESMNT}/${AUFS_CHANGESFILE}
+ break
+ else
+ rm -f ${CHANGESMNT}/${AUFS_CHANGESFILE}
+ bad_msg "Unable to create ${AUFS_CHANGESFILE} on ${CHANGESDEV} of ${size} Mb"
+ bad_msg "Please give a size of at least 16 Mb"
+ bad_msg "Also check if your disk is full or read-only ?"
+ read -p '<< Type "a" to abort, anything else to continue : ' doabort
+ if [ "${doabort}" = "a" ]; then
+ return 1
+ fi
+ fi
+ fi
+ done
+ return 0
+}
+
+setup_aufs() {
+ if [ "${USE_AUFS_NORMAL}" -eq '1' ]
+ then
+ # Directory used for rw changes in union mount filesystem
+ UNION=/union
+ MEMORY=/memory
+ # Mountpoint for the changesdev
+ CHANGESMNT=${NEW_ROOT}/mnt/changesdev
+ if [ -z "$UID" ]
+ then
+ CHANGES=${MEMORY}/aufs_changes/default
+ else
+ CHANGES=${MEMORY}/aufs_changes/${UID}
+ fi
+
+ mkdir -p ${MEMORY}
+ mkdir -p ${UNION}
+ mkdir -p ${CHANGESMNT}
+ for i in dev mnt ${CDROOT_PATH} mnt/livecd mnt/key tmp tmp/.initrd mnt/gentoo sys
+ do
+ mkdir -p "${NEW_ROOT}/${i}"
+ chmod 755 "${NEW_ROOT}/${i}"
+ done
+ [ ! -e "${NEW_ROOT}/dev/null" ] && mknod "${NEW_ROOT}"/dev/null c 1 3
+ [ ! -e "${NEW_ROOT}/dev/console" ] && mknod "${NEW_ROOT}"/dev/console c 5 1
+
+ bootstrapCD
+ if [ -n "${AUFS}" ]
+ then
+ if [ "${AUFS}" = "detect" ]
+ then
+ CHANGESMNT="${NEW_ROOT}${CDROOT_PATH}"
+ CHANGESDEV=${REAL_ROOT}
+ else
+ CHANGESDEV=${AUFS}
+ good_msg "mounting ${CHANGESDEV} to ${MEMORY} for aufs support"
+ mount -t auto ${CHANGESDEV} ${CHANGESMNT}
+ ret=$?
+ if [ "${ret}" -ne 0 ]
+ then
+ bad_msg "mount of ${CHANGESDEV} failed, falling back to ramdisk based aufs"
+ unset AUFS
+ fi
+ fi
+ # Check and attempt to create the changesfile
+ if [ ! -e ${CHANGESMNT}/${AUFS_CHANGESFILE} ] && [ -n "${AUFS}" ]
+ then
+ create_changefs
+ mount -t auto ${CHANGESMNT}/${AUFS_CHANGESFILE} ${MEMORY}
+ elif [ -n "${AUFS}" ]
+ then
+ local nbpass=0
+ while [ 1 ]
+ do
+ mount -t auto ${CHANGESMNT}/${AUFS_CHANGESFILE} ${MEMORY}
+ ret=$?
+ if [ "${ret}" -ne 0 ]
+ then
+ if [ ${nbpass} -eq 0 ]
+ then
+ bad_msg "mounting of changes file failed, Running e2fsck"
+ e2fsck ${CHANGESMNT}/${AUFS_CHANGESFILE}
+ nbpass=$((${nbpass} + 1))
+ else
+ bad_msg "mount of ${CHANGESDEV} failed, falling back to ramdisk based aufs"
+ bad_msg "your ${AUFS_CHANGESFILE} might be messed up, and I couldn't fix it"
+ bad_msg "moving ${AUFS_CHANGESFILE} to ${AUFS_CHANGESFILE}.bad"
+ mv ${CHANGESMNT}/${AUFS_CHANGESFILE} ${CHANGESMNT}/${AUFS_CHANGESFILE}.bad
+ bad_msg "try to fix it yourself with e2fsck later on, sorry for disturbing"
+ break
+ fi
+ else
+ if [ ${nbpass} -eq 1 ]
+ then
+ good_msg "e2fsck ran successfully. Please check your files after bootup"
+ fi
+ break
+ fi
+ done
+ fi
+ # mount tmpfs only in the case when changes= boot parameter was
+ # empty or we were not able to mount the storage device
+ if [ "${CDROOT}" -eq '1' -a ! -f ${CHANGESMNT}/${AUFS_CHANGESFILE} ]
+ then
+ umount ${MEMORY}
+ bad_msg "failed to find ${AUFS_CHANGESFILE} file on ${CHANGESDEV}"
+ bad_msg "create an ext2 ${AUFS_CHANGESFILE} file on this device if you wish to use it for aufs"
+ bad_msg "falling back to ramdisk based aufs for safety"
+ mount -t tmpfs tmpfs ${MEMORY}
+ XINO=${MEMORY}
+ else
+ XINO=${MEMORY}/xino
+ mkdir -p ${XINO}
+ mount -t tmpfs tmpfs ${XINO}
+ fi
+ else
+ good_msg "Mounting ramdisk to $MEMORY for aufs support..."
+ mount -t tmpfs tmpfs ${MEMORY}
+ XINO=${MEMORY}
+ fi
+
+ mkdir -p ${CHANGES}
+ mount -t aufs -n -o nowarn_perm,udba=none,xino=${XINO}/.aufs.xino,br:${CHANGES}=rw aufs ${UNION}
+ ret=$?
+ if [ "${ret}" -ne 0 ]
+ then
+ bad_msg "Can't setup union ${UNION} in directory!"
+ USE_AUFS_NORMAL=0
+ fi
+ else
+ USE_AUFS_NORMAL=0
+ fi
+}
+
+
findnfsmount() {
if [ "${IP}" != '' ] || busybox udhcpc -n -T 15 -q
then
diff --git a/defaults/linuxrc b/defaults/linuxrc
index 6401614..e2e1b6f 100644
--- a/defaults/linuxrc
+++ b/defaults/linuxrc
@@ -253,6 +253,38 @@ do
aufs)
USE_AUFS_NORMAL=1
;;
+ aufs\=*)
+ USE_AUFS_NORMAL=1
+ CMD_AUFS=$(parse_opt "${x}")
+ echo ${CMD_AUFS}|grep , >/dev/null 2>&1
+ if [ "$?" -eq '0' ]
+ then
+ UID=$(echo ${CMD_AUFS#*,})
+ AUFS=$(echo ${CMD_AUFS%,*})
+ else
+ AUFS=${CMD_AUFS}
+ fi
+ ;;
+ aufs.changes\=*)
+ USE_AUFS_NORMAL=1
+ CMD_AUFS=$(parse_opt "${x}")
+ echo ${CMD_AUFS}|grep , >/dev/null 2>&1
+ if [ "$?" -eq '0' ]
+ then
+ UID=$(echo ${CMD_AUFS#*,})
+ AUFS=$(echo ${CMD_AUFS%,*})
+ else
+ AUFS=${CMD_AUFS}
+ fi
+ ;;
+ aufs.persistent)
+ USE_AUFS_NORMAL=1
+ AUFS="detect"
+ ;;
+ # Allow user to specify the modules location
+ aufs.modules\=*)
+ MODULESD=$(parse_opt "${x}")
+ ;;
unionfs)
if [ ! -x /sbin/unionfs ]
then
@@ -425,19 +457,26 @@ rundebugshell "before setting up the root filesystem"
if [ "${CDROOT}" = '1' ]
then
- good_msg "Making tmpfs for ${NEW_ROOT}"
- mount -n -t tmpfs tmpfs "${NEW_ROOT}"
+ setup_aufs
+ if [ "${USE_AUFS_NORMAL}" -eq '1' ]
+ then
+ CHROOT=${UNION}
+ else
+ CHROOT=${NEW_ROOT}
+ good_msg "Making tmpfs for ${NEW_ROOT}"
+ mount -n -t tmpfs tmpfs ${NEW_ROOT}
- for i in dev mnt proc run sys tmp mnt/livecd mnt/key tmp/.initrd mnt/gentoo
- do
- mkdir -p "${NEW_ROOT}/${i}"
- chmod 755 "${NEW_ROOT}/${i}"
- done
- [ ! -d "${CDROOT_PATH}" ] && mkdir -p "${CDROOT_PATH}"
- [ ! -e "${NEW_ROOT}/dev/null" ] && mknod -m 660 "${NEW_ROOT}"/dev/null c 1 3
- [ ! -e "${NEW_ROOT}/dev/zero" ] && mknod -m 660 "${NEW_ROOT}"/dev/zero c 1 5
- [ ! -e "${NEW_ROOT}/dev/console" ] && mknod -m 660 "${NEW_ROOT}"/dev/console c 5 1
- [ ! -e "${NEW_ROOT}/dev/ttyS0" ] && mknod -m 600 "${NEW_ROOT}"/dev/ttyS0 c 4 64
+ for i in dev mnt ${CDROOT_PATH} proc run mnt/livecd mnt/key tmp tmp/.initrd mnt/gentoo sys
+ do
+ mkdir -p "${NEW_ROOT}/${i}"
+ chmod 755 "${NEW_ROOT}/${i}"
+ done
+ [ ! -d "${CDROOT_PATH}" ] && mkdir -p "${CDROOT_PATH}"
+ [ ! -e "${NEW_ROOT}/dev/null" ] && mknod -m 666 "${NEW_ROOT}"/dev/null c 1 3
+ [ ! -e "${NEW_ROOT}/dev/zero" ] && mknod -m 666 "${NEW_ROOT}"/dev/zero c 1 5
+ [ ! -e "${NEW_ROOT}/dev/console" ] && mknod -m 600 "${NEW_ROOT}"/dev/console c 5 1
+ [ ! -e "${NEW_ROOT}/dev/ttyS0" ] && mknod -m 660 "${NEW_ROOT}"/dev/ttyS0 c 4 64
+ fi
# For SGI LiveCDs ...
if [ "${LOOPTYPE}" = "sgimips" ]
@@ -452,7 +491,7 @@ then
[ ! -e "${NEW_ROOT}/dev/$minor" ] && mknod -m 600 "${NEW_ROOT}/dev/tty$minor" c 4 $minor
done
- if [ "${REAL_ROOT}" != "/dev/nfs" ] && [ "${LOOPTYPE}" != "sgimips" ]
+ if [ "${REAL_ROOT}" != "/dev/nfs" ] && [ "${LOOPTYPE}" != "sgimips" ] && [ "${USE_AUFS_NORMAL}" != '1' ]
then
bootstrapCD
fi
@@ -764,7 +803,23 @@ then
fi
fi
+ if [ "${USE_AUFS_NORMAL}" -eq '1' ]
+ then
+ union_insert_dir ${UNION} ${NEW_ROOT}/${FS_LOCATION}
+ # Make sure fstab notes livecd is mounted ro. Makes system skip remount which fails on aufs dirs.
+ sed -e 's|\(.*\s/\s*tmpfs\s*\)defaults\(.*\)|\1defaults,ro\2|' /${UNION}/etc/fstab > /${UNION}/etc/fstab.new
+ mv /${UNION}/etc/fstab.new /${UNION}/etc/fstab
+ warn_msg "Adding all modules in $MODULESD/modules/"
+ if [ -z "${MODULESD}" ]
+ then
+ union_insert_modules ${CDROOT_PATH}
+ else
+ mkdir ${NEW_ROOT}/mnt/modulesd
+ mount "${MODULESD}" ${NEW_ROOT}/mnt/modulesd
+ union_insert_modules ${NEW_ROOT}/mnt/modulesd
+ fi
+ fi
# Unpacking additional packages from NFS mount
# This is useful for adding kernel modules to /lib
@@ -787,56 +842,60 @@ then
then
setup_unionfs ${NEW_ROOT} /${FS_LOCATION}
CHROOT=/union
- elif [ "${USE_AUFS_NORMAL}" != '1' ]; then
-
- good_msg "Copying read-write image contents to tmpfs"
- # Copy over stuff that should be writable
- (cd "${NEW_ROOT}/${FS_LOCATION}"; cp -a ${ROOT_TREES} "${NEW_ROOT}") || {
- bad_msg "Copying failed, dropping into a shell."
- do_rundebugshell
- }
-
- # Now we do the links.
- for x in ${ROOT_LINKS}
- do
- if [ -L "${NEW_ROOT}/${FS_LOCATION}/${x}" ]
+ else
+ #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
+ if [ ! "${USE_AUFS_NORMAL}" -eq '1' ]
then
- ln -s "$(readlink ${NEW_ROOT}/${FS_LOCATION}/${x})" "${x}" 2>/dev/null
- else
- # List all subdirectories of x
- find "${NEW_ROOT}/${FS_LOCATION}/${x}" -type d 2>/dev/null | while read directory
+ good_msg "Copying read-write image contents to tmpfs"
+ # Copy over stuff that should be writable
+ (cd "${NEW_ROOT}/${FS_LOCATION}"; cp -a ${ROOT_TREES} "${NEW_ROOT}") || {
+ bad_msg "Copying failed, dropping into a shell."
+ do_rundebugshell
+ }
+
+ # Now we do the links.
+ for x in ${ROOT_LINKS}
do
- # Strip the prefix of the FS_LOCATION
- directory="${directory#${NEW_ROOT}/${FS_LOCATION}/}"
-
- # Skip this directory if we already linked a parent directory
- if [ "${current_parent}" != '' ]; then
- var=$(echo "${directory}" | grep "^${current_parent}")
- if [ "${var}" != '' ]; then
- continue
- fi
- fi
- # Test if the directory exists already
- if [ -e "/${NEW_ROOT}/${directory}" ]
+ if [ -L "${NEW_ROOT}/${FS_LOCATION}/${x}" ]
then
- # It does exist, link all the individual files
- for file in $(ls /${NEW_ROOT}/${FS_LOCATION}/${directory})
+ ln -s "$(readlink ${NEW_ROOT}/${FS_LOCATION}/${x})" "${x}" 2>/dev/null
+ else
+ # List all subdirectories of x
+ find "${NEW_ROOT}/${FS_LOCATION}/${x}" -type d 2>/dev/null | while read directory
do
- if [ ! -d "/${NEW_ROOT}/${FS_LOCATION}/${directory}/${file}" ] && [ ! -e "${NEW_ROOT}/${directory}/${file}" ]; then
- ln -s "/${FS_LOCATION}/${directory}/${file}" "${directory}/${file}" 2> /dev/null
+ # Strip the prefix of the FS_LOCATION
+ directory="${directory#${NEW_ROOT}/${FS_LOCATION}/}"
+
+ # Skip this directory if we already linked a parent directory
+ if [ "${current_parent}" != '' ]; then
+ var=$(echo "${directory}" | grep "^${current_parent}")
+ if [ "${var}" != '' ]; then
+ continue
+ fi
+ fi
+ # Test if the directory exists already
+ if [ -e "/${NEW_ROOT}/${directory}" ]
+ then
+ # It does exist, link all the individual files
+ for file in $(ls /${NEW_ROOT}/${FS_LOCATION}/${directory})
+ do
+ if [ ! -d "/${NEW_ROOT}/${FS_LOCATION}/${directory}/${file}" ] && [ ! -e "${NEW_ROOT}/${directory}/${file}" ]; then
+ ln -s "/${FS_LOCATION}/${directory}/${file}" "${directory}/${file}" 2> /dev/null
+ fi
+ done
+ else
+ # It does not exist, make a link to the livecd
+ ln -s "/${FS_LOCATION}/${directory}" "${directory}" 2>/dev/null
+ current_parent="${directory}"
fi
done
- else
- # It does not exist, make a link to the livecd
- ln -s "/${FS_LOCATION}/${directory}" "${directory}" 2>/dev/null
- current_parent="${directory}"
fi
done
- fi
- done
+ mkdir initramfs proc tmp sys 2>/dev/null
+ chmod 1777 tmp
- mkdir initramfs proc tmp sys run 2>/dev/null
- chmod 1777 tmp
+ fi
+ #XXX: end extremely confusing hunk
# have handy /mnt/cdrom (CDROOT_PATH) as well
_new_cdroot="${NEW_ROOT}${CDROOT_PATH}"
@@ -863,6 +922,12 @@ else
setup_unionfs /union_changes ${NEW_ROOT}
mkdir -p ${UNION}/tmp/.initrd
fi
+ if [ "${USE_AUFS_NORMAL}" -eq '1' ]
+ then
+ union_insert_dir ${UNION} ${NEW_ROOT}
+ mkdir -p ${UNION}/tmp/.initrd
+ fi
+
fi
# Mount the additional things as required by udev & systemd
@@ -907,6 +972,27 @@ fi
verbose_kmsg
+if [ "${USE_AUFS_NORMAL}" -eq '1' ]
+then
+ mkdir -p /${CHROOT}/.unions/memory 2>/dev/null
+ mount -o move /memory /${CHROOT}/.unions/memory || echo '*: Failed to move aufs /memory into the system root!'
+ for i in tmp var/tmp mnt/gentoo mnt/livecd
+ do
+ mkdir -p ${CHROOT}/$i
+ chmod 755 ${CHROOT}/$i
+ done
+ # This will prevent from putting junk on the CHANGESDEV
+ mkdir -p ${CHROOT}/usr/portage/distfiles
+ mount -t tmpfs tmpfs ${CHROOT}/var/tmp
+ mount -t tmpfs tmpfs ${CHROOT}/tmp
+ mount -t tmpfs tmpfs ${CHROOT}/usr/portage/distfiles
+ warn_msg "/tmp /var/tmp /usr/portage/distfiles are mounted in ram"
+ warn_msg "consider saving important files elsewhere..."
+ read -t 3 UNUSEDVAL
+ mount --bind ${NEW_ROOT}${CDROOT_PATH} ${CHROOT}${CDROOT_PATH}
+ mount --bind ${NEW_ROOT}/mnt/livecd ${CHROOT}/mnt/livecd
+fi
+
good_msg "Booting (initramfs)"
cd "${CHROOT}"