0xV3NOMx
Linux ip-172-26-7-228 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64



Your IP : 3.146.178.241


Current Path : /snap/core/16928/usr/share/initramfs-tools/scripts/
Upload File :
Current File : //snap/core/16928/usr/share/initramfs-tools/scripts/ubuntu-core-rootfs

# -*- shell-script -*- vim:ft=sh:
#---------------------------------------------------------------------
# Description: Mount appropriate Ubuntu Core root filesystem read-only
#   and writable partition writable.
# Entry point: mountroot().
#---------------------------------------------------------------------

# shellcheck disable=SC2034
. ${scriptsroot:-/scripts}/ubuntu-core-functions

sync_dirs()
{
	base="$1"
	source="$2"
	target="$3"

	OLD_PWD="$PWD"
	cd "$base"

	for file in "$source"/*
	do
		# Skip empty directories
		[ ! -e "$base/$file" -a ! -L "$base/$file" ] && continue

		# If the target already exists as a file or link, there's nothing we can do
		[ -e "$target/$file" -o -L "$target/$file" ] && [ ! -d "$target/$file" ] && continue

		# If the target doesn't exist, just copy it over
		if [ ! -e "$target/$file" -a ! -L "$target/$file" ]; then
			cp -Ra "$base/$file" "$target/$file"
			continue
		fi

		# That leaves us with directories and a recursive call
		[ -d "$file" ] && sync_dirs "$base" "$file" "$target"
	done

	cd "$OLD_PWD"
}

# Process the list of bind-mounts (but don't mount them - systemd will handle that)
# File format is documented in writable-paths(5).
handle_writable_paths()
{
	writable_paths="$1"
	fstab="$2"

	[ -n "$writable_paths" ] || panic "need writeable paths"
	[ -e "$writable_paths" ] || panic "writeable paths does not exist"
	[ -n "$fstab" ] || panic "need fstab"

	cat "$writable_paths" | while read line; do
		# tokenise
		set -- $line

		# skip invalid/commented entries
		([ -z "$1" ] || \
		 [ -z "$2" ] || \
		 [ -z "$3" ] || \
		 [ -z "$4" ] || \
		 [ -z "$5" ]) && continue

		# ignore anything that isn't an absolute path (including comments)
		case "$1" in
			/*) ;;
			*) continue ;;
		esac

		# skip invalid mount points
		dstpath="${rootmnt}$1"
		[ ! -e "$dstpath" ] && continue

		if [ "$3" = "temporary" ]; then
			# Temporary entries are simple, just mount a tmpfs
			echo "tmpfs $1 tmpfs $5 0 0" >> "$fstab"
		elif [ "$3" = "persistent" ] || \
		     [ "$3" = "synced" ]; then
			# Figure out the source path
			if [ "$2" = "auto" ]; then
				srcpath="${rootmnt}/writable/system-data${1}"
				path="/writable/system-data${1}"
			else
				srcpath="${rootmnt}/writable/$2"
				path="/writable/$2"
			fi

			if [ ! -e "$srcpath" ]; then
				# Process new persistent or synced paths
				dstown=$(stat -c "%u:%g" "$dstpath")
				dstmode=$(stat -c "%a" "$dstpath")
				mkdir -p ${srcpath%/*}
				if [ ! -d "$dstpath" ]; then
					# Deal with redirected files
					if [ "$4" = "transition" ]; then
						cp -a "$dstpath" "$srcpath"
					else
						touch "$srcpath"
						chown "$dstown" "$srcpath"
						chmod "$dstmode" "$srcpath"
					fi
				else
					# Deal with redirected directories
					if [ "$4" = "transition" ] || [ "$3" = "synced" ]; then
						cp -aR "$dstpath" "$srcpath"
					else
						mkdir "$srcpath"
						chown "$dstown" "$srcpath"
						chmod "$dstmode" "$srcpath"
					fi
				fi
			elif [ "$3" = "synced" ]; then
				# Process existing synced paths
				sync_dirs "$dstpath" . "$srcpath"
			fi

                        # mount all /etc dirs right now, not later when fstab is
                        # processed, as it will cause races.
                        case $1 in
                            /etc*)
                                [ -e "${rootmnt}/writable/system-data/$1" ] || mkdir -p "${rootmnt}/writable/system-data/$1"
                                mount -o bind "${rootmnt}/writable/system-data/$1" "${rootmnt}/$1"
                                ;;
                            *)
                                # Write the fstab entry
                                if [ "$5" = "none" ]; then
                                        echo "$path $1 none bind 0 0" >> "$fstab"
                                else
                                        echo "$path $1 none bind,$5 0 0" >> "$fstab"
                                fi
                                ;;
                        esac
		else
			continue
		fi
	done

        # now apply the defaults on top
        handle_writable_defaults
}

# handle_writable_default will apply system defaults *once* after
# the handle_writable_path got populated
handle_writable_defaults()
{
        srcpath="${rootmnt}/writable/system-data/_writable_defaults"
        if [ ! -d "$srcpath" ] || [ -e "${srcpath}/.done" ]; then
                return
        fi

        dstpath="${rootmnt}/writable/system-data"
        for fileordir in "$srcpath"/* ; do
            # skip empty $srcpath/
            [ ! -e "$fileordir" ] && [ ! -L "$fileordir" ] &&  continue

            # copy
            cp -a "$fileordir" "$dstpath"
        done
        touch "$srcpath/.done"
}

fsck_writable()
{
	local writable_label="$1"
        local writable_mnt="$2"

	path=$(get_partition_from_label "$writable_label")

	[ -n "$path" ] || panic "cannot find '$writable_label' partition"

	# Mount the writable partition to a temporary mount point
	# (to allow it to be move-mounted on top of the read-only root).
	logfile="/run/initramfs/fsck-${writable_label}"

	echo "initrd: checking filesystem for ${writable_label} partition" >/dev/kmsg || true

	echo "$(date '+%s'): start" >> "$logfile" || true

	# XXX: The following commands must not fail (to ensure the system boots!)

	# Mount and umount first to let the kernel handle
	# the journal and orphaned inodes (much faster than e2fsck).
	mount -o errors=remount-ro "$path" "$writable_mnt" || true
	umount "$writable_mnt" || true

	# Automatically fix errors
	/sbin/e2fsck -va "$path" >> "$logfile" 2>&1 || true

	echo "$(date '+%s'): end" >> "$logfile" || true

}

# Mount core and kernel snaps
mount_snaps()
{
        # mount OS snap
        mount -o ro "${writable_mnt}/system-data/var/lib/snapd/snaps/${snap_core}" "$rootmnt"

        # now add a kernel bind mounts to it
        local kernel_mnt="/tmpmnt_kernel"
        mkdir -p "$kernel_mnt"
        mount -o ro "${writable_mnt}/system-data/var/lib/snapd/snaps/${snap_kernel}" "$kernel_mnt"
        for d in modules firmware; do
            if [ -d "${kernel_mnt}/$d" ]; then
                mount -o bind "${kernel_mnt}/$d" "$rootmnt/lib/$d"
            fi
        done

        # now we can umount the kernel and the bind mounts are still intact
        # (magic!)
        umount "$kernel_mnt"
}

#---------------------------------------------------------------------
# XXX: Entry point - called by the initramfs "/init" script.
#---------------------------------------------------------------------
mountroot()
{
        pre_mountroot

	[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-premount"
	run_scripts /scripts/local-premount
	[ "$quiet" != "y" ] && log_end_msg
        
        # find what snappy-os version to use
        for x in $(cat /proc/cmdline); do
	    case "${x}" in
                # new kernel/os snap vars
		snap_core=*)
			snap_core="${x#*=}"
			;;
		snap_kernel=*)
			snap_kernel="${x#*=}"
			;;
		esac
	done

        # basic validation
        if [ -z "$snap_core" ]; then
            panic "the requried kernel commandline snap_core is not set"
        fi
        if [ -z "$snap_kernel" ]; then
            panic "the requried kernel commandline snap_kernel is not set"
        fi

        # always ensure writable is in a good state
        writable_label="writable"
        writable_mnt="/tmpmnt_${writable_label}"
	mkdir -p "$writable_mnt"
        fsck_writable "$writable_label" "$writable_mnt"

        # mount the root fs
        do_root_mounting
        # mount core and kernel snaps
        mount_snaps
        
        # mount /run
	echo "initrd: mounting /run" >/dev/kmsg || true
	mount -o rw,nosuid,noexec,relatime,mode=755 -t tmpfs tmpfs "${rootmnt}/run"

        # move /writable to its final destination
	mount --move "$writable_mnt" "${rootmnt}/writable"

	# Prepare the fstab
	fstab="${rootmnt}/etc/fstab"
	writable_paths="${rootmnt}/etc/system-image/writable-paths"

	# Add writable overlays
	if [ -e "$writable_paths" ]; then
		touch "${rootmnt}/run/image.fstab"
		mount -o bind "${rootmnt}/run/image.fstab" "$fstab" || panic "Cannot bind mount fstab"
		echo "# Auto-generated by $0" >> "$fstab"
		echo "# DO NOT EDIT THIS FILE BY HAND - YOUR CHANGES WILL BE OVERWRITTEN" >> "$fstab"
		echo "# (See writable-paths(5) for details)" >> "$fstab"
		echo "/dev/root / rootfs defaults,ro 0 0" >> "$fstab"
                # FIXME: ideally we would mount /writable RO here and
                #        let systemd do a "remount,rw" for us. unfortunately
                #        this is not supported by systemd so we need to do
                #        the RW mount and fsck dance etc here :/
                echo "LABEL=writable /writable auto defaults 0 0" >> "$fstab"
		handle_writable_paths "$writable_paths" "$fstab"
	fi

        # IMPORTANT: ensure we synced everything back to disk
        sync

	# Request bootloader partition be mounted
	boot_partition=$(findfs LABEL="system-boot" 2>/dev/null || :)

	if [ -n "$boot_partition" ]; then
	        # determine bootloader type, we need to inspect the boot
                # partition for this
		grubdir="/boot/grub"
		ubootdir="/boot/uboot"

                tmpboot_mnt="/tmpmnt_system-boot"
                mkdir -p $tmpboot_mnt
                mount -o ro "$boot_partition" "$tmpboot_mnt"

		# Since the boot partition is not required to actually boot
		# the image, request the init system handle it (fsck+mount).
		if [ -f "${tmpboot_mnt}/EFI/ubuntu/grub/grub.cfg" ]; then
                        # OLD style (ubuntu-device-flash) base dir
			efidir="/boot/efi"
			efibinddir="${efidir}/EFI/ubuntu/grub"
			if [ -d "${rootmnt}/${efidir}" ]; then
				echo "$boot_partition $efidir auto defaults 0 2" >> "$fstab"
				echo "$efibinddir $grubdir none bind 0 0" >> "$fstab"
			fi
                elif [ -f "${tmpboot_mnt}/EFI/ubuntu/grub.cfg" ]; then
                        # NEW style (u-i base dir)
			efidir="/boot/efi"
			efibinddir="${efidir}/EFI/ubuntu/"
			if [ -d "${rootmnt}/${efidir}" ]; then
				echo "$boot_partition $efidir auto defaults 0 2" >> "$fstab"
				echo "$efibinddir $grubdir none bind 0 0" >> "$fstab"
			fi
		else
			echo "$boot_partition $ubootdir auto defaults 0 2" >> "$fstab"
		fi

                # let systemd do the actual mounting
                umount "$tmpboot_mnt"
        elif abootimg -i "$(findfs PARTLABEL=recovery)" >/dev/null 2>&1; then
                echo "android style bootloader detected" >/dev/kmsg || true
                androiddir="writable/androidboot"
                mkdir -p "${rootmnt}/${androiddir}"
                if [ ! -e "${rootmnt}/${androiddir}/androidboot.env" ]; then
                        echo -e "snap_mode=\nsnap_core=$snap_core\nsnap_kernel=$snap_kernel\nsnap_try_core=\nsnap_try_kernel=" > \
                             "${rootmnt}/${androiddir}/androidboot.env"
                fi
                mount -o bind "${rootmnt}/${androiddir}" "${rootmnt}/boot/androidboot"
	fi

	# Mount the systemd overlay so that we have a complete root partition during boot
	mkdir -p "${rootmnt}/writable/system-data/etc/systemd/system"
	mount -o bind "${rootmnt}/writable/system-data/etc/systemd/system" "${rootmnt}/etc/systemd/system"

	# create "machine-id" if it does not exist and bind mount it (LP: #1619721)
	if [ ! -e ${rootmnt}/writable/system-data/etc/machine-id ]; then
		cat /proc/sys/kernel/random/uuid|tr -d - >${rootmnt}/writable/system-data/etc/machine-id
	fi
	mount -o bind "${rootmnt}/writable/system-data/etc/machine-id" "${rootmnt}/etc/machine-id"

	# Apply customized content
	for user in "${rootmnt}"/writable/user-data/*
	do
		if [ -d "${rootmnt}/custom/home" ] && [ ! -e "$user/.customized" ]; then
			echo "initrd: copying custom content tp " >/dev/kmsg || true
			cp -Rap "${rootmnt}"/custom/home/* "$user/"
			cp -Rap "${rootmnt}"/custom/home/.[a-zA-Z0-9]* "$user/"
			touch "$user/.customized"
			dstown=$(stat -c "%u:%g" "$user")
			chown -R "$dstown" "$user/"
		fi
	done

	[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom"
	run_scripts /scripts/local-bottom
	[ "$quiet" != "y" ] && log_end_msg
}