From d929c8cbc09732337fb4805accbf3564e9cca0bb Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Tue, 20 Mar 2018 22:56:16 -0400 Subject: Import Upstream version 18 --- genfstab.in | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 genfstab.in (limited to 'genfstab.in') diff --git a/genfstab.in b/genfstab.in new file mode 100644 index 0000000..1e8a2c8 --- /dev/null +++ b/genfstab.in @@ -0,0 +1,230 @@ +#!/bin/bash + +shopt -s extglob + +m4_include(common) + +write_source() { + local src=$1 spec= label= uuid= comment=() + + label=$(lsblk -rno LABEL "$1" 2>/dev/null) + uuid=$(lsblk -rno UUID "$1" 2>/dev/null) + + # bind mounts do not have a UUID! + + case $bytag in + '') + [[ $uuid ]] && comment=("UUID=$uuid") + [[ $label ]] && comment+=("LABEL=$(mangle "$label")") + ;; + LABEL) + spec=$label + [[ $uuid ]] && comment=("$src" "UUID=$uuid") + ;; + UUID) + spec=$uuid + comment=("$src") + [[ $label ]] && comment+=("LABEL=$(mangle "$label")") + ;; + *) + [[ $uuid ]] && comment=("$1" "UUID=$uuid") + [[ $label ]] && comment+=("LABEL=$(mangle "$label")") + [[ $bytag ]] && spec=$(lsblk -rno "$bytag" "$1" 2>/dev/null) + ;; + esac + + [[ $comment ]] && printf '# %s\n' "${comment[*]}" + + if [[ $spec ]]; then + printf '%-20s' "$bytag=$(mangle "$spec")" + else + printf '%-20s' "$(mangle "$src")" + fi +} + +optstring_apply_quirks() { + local varname=$1 fstype=$2 + + # SELinux displays a 'seclabel' option in /proc/self/mountinfo. We can't know + # if the system we're generating the fstab for has any support for SELinux (as + # one might install Arch from a Fedora environment), so let's remove it. + optstring_remove_option "$varname" seclabel + + # Prune 'relatime' option for any pseudofs. This seems to be a rampant + # default which the kernel often exports even if the underlying filesystem + # doesn't support it. Example: https://bugs.archlinux.org/task/54554. + if awk -v fstype="$fstype" '$1 == fstype { exit 1 }' /proc/filesystems; then + optstring_remove_option "$varname" relatime + fi + + case $fstype in + f2fs) + # These are Kconfig options for f2fs. Kernels supporting the options will + # only provide the negative versions of these (e.g. noacl), and vice versa + # for kernels without support. + optstring_remove_option "$varname" noacl,acl,nouser_xattr,user_xattr + ;; + vfat) + # Before Linux v3.8, "cp" is prepended to the value of the codepage. + if optstring_get_option "$varname" codepage && [[ $codepage = cp* ]]; then + optstring_remove_option "$varname" codepage + optstring_append_option "$varname" "codepage=${codepage#cp}" + fi + ;; + esac +} + +usage() { + cat </dev/null; then + # this is root. we can't possibly have more than one... + pass=1 foundroot=1 + fi + + # if there's no fsck tool available, then only pass=0 makes sense. + if ! fstype_has_fsck "$fstype"; then + pass=0 + fi + + if [[ $fsroot != / ]]; then + if [[ $fstype = btrfs ]]; then + opts+=,subvol=${fsroot#/} + else + # it's a bind mount + src=$(findmnt -funcevo TARGET "$src")$fsroot + if [[ $src -ef $target ]]; then + # hrmm, this is weird. we're probably looking at a file or directory + # that was bound into a chroot from the host machine. Ignore it, + # because this won't actually be a valid mount. Worst case, the user + # just re-adds it. + continue + fi + fstype=none + opts+=,bind + pass=0 + fi + fi + + # filesystem quirks + case $fstype in + fuseblk) + # well-behaved FUSE filesystems will report themselves as fuse.$fstype. + # this is probably NTFS-3g, but let's just make sure. + if ! newtype=$(lsblk -no FSTYPE "$src") || [[ -z $newtype ]]; then + # avoid blanking out fstype, leading to an invalid fstab + error 'Failed to derive real filesystem type for FUSE device on %s' "$target" + else + fstype=$newtype + fi + ;; + esac + + optstring_apply_quirks "opts" "$fstype" + + # write one line + write_source "$src" + printf '\t%-10s' "/$(mangle "${target#/}")" "$fstype" "$opts" + printf '\t%s %s' "$dump" "$pass" + printf '\n\n' +done + +# handle swaps devices +{ + # ignore header + read + + while read -r device type _ _ prio; do + options=defaults + if [[ $prio != -1 ]]; then + options+=,pri=$prio + fi + + # skip files marked deleted by the kernel + [[ $device = *'\040(deleted)' ]] && continue + + if [[ $type = file ]]; then + printf '%-20s' "$device" + elif [[ $device = /dev/dm-+([0-9]) ]]; then + # device mapper doesn't allow characters we need to worry + # about being mangled, and it does the escaping of dashes + # for us in sysfs. + write_source "$(dm_name_for_devnode "$device")" + else + write_source "$(unmangle "$device")" + fi + + printf '\t%-10s\t%-10s\t%-10s\t0 0\n\n' 'none' 'swap' "$options" + done +}