genfstab,common: use named reference instead of globals
This commit is contained in:
parent
f40fc1f2b0
commit
0e14a1a13b
130
common
130
common
@ -89,10 +89,12 @@ ignore_error() {
|
|||||||
|
|
||||||
in_array() {
|
in_array() {
|
||||||
local i
|
local i
|
||||||
|
local -n _arr="$1"
|
||||||
|
|
||||||
for i in "${@:2}"; do
|
for i in "${_arr[@]}"; do
|
||||||
[[ "$1" = "$i" ]] && return 0
|
[[ "$i" = "$1" ]] && return 0
|
||||||
done
|
done
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,83 +351,99 @@ unmangle() {
|
|||||||
printf '%s' "$out${1:i}"
|
printf '%s' "$out${1:i}"
|
||||||
}
|
}
|
||||||
|
|
||||||
optstring_match_option() {
|
optstring_match_one_option() {
|
||||||
local candidate pat patterns
|
local options=() target="$2"
|
||||||
|
local -n _optstring_match="$1"
|
||||||
|
|
||||||
IFS=, read -ra patterns <<<"$1"
|
IFS=, read -ra options <<<"$_optstring_match"
|
||||||
for pat in "${patterns[@]}"; do
|
if [[ "$target" != *'='* ]]; then
|
||||||
if [[ $pat = *'='* ]]; then
|
options=("${options[@]%%=*}")
|
||||||
# "key=val" will only ever match "key=val"
|
|
||||||
candidate="$2"
|
|
||||||
else
|
|
||||||
# "key" will match "key", but also "key=anyval"
|
|
||||||
candidate="${2%%=*}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ "$pat" = "$candidate" ]] && return 0
|
in_array options "$target"
|
||||||
done
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
optstring_remove_option() {
|
optstring_get_options() {
|
||||||
local o _options remove="$2"
|
local i options=()
|
||||||
|
local -n _ret="$1" _optstring_get="$2"
|
||||||
|
local -i got=0
|
||||||
|
|
||||||
IFS=, read -ra _options <<<"${!1}"
|
IFS=, read -ra options <<<"$_optstring_get"
|
||||||
for o in "${!_options[@]}"; do
|
|
||||||
optstring_match_option "$remove" "${_options[o]}" && unset '_options[o]'
|
shift 2
|
||||||
|
for i in "${!options[@]}"; do
|
||||||
|
if optstring_match_one_option 'options[i]' "$1"; then
|
||||||
|
_ret+=(["${options[i]%%=*}"]="${options[i]//*=}")
|
||||||
|
got=1
|
||||||
|
fi
|
||||||
|
shift || break
|
||||||
done
|
done
|
||||||
|
|
||||||
declare -g "$1=${_options[*]}"
|
(( got ))
|
||||||
|
}
|
||||||
|
|
||||||
|
optstring_from_array() {
|
||||||
|
local optstring
|
||||||
|
local -n _optarray="$1"
|
||||||
|
|
||||||
|
optstring="$(printf ',%s' "${_optarray[@]}")"
|
||||||
|
optstring="${optstring:1}" # Remove the leading comma
|
||||||
|
|
||||||
|
printf '%s' "$optstring"
|
||||||
}
|
}
|
||||||
|
|
||||||
optstring_normalize() {
|
optstring_normalize() {
|
||||||
local o _options norm
|
local i options=()
|
||||||
|
local -n _optstring_norm="$1"
|
||||||
|
|
||||||
|
IFS=, read -ra options <<<"$_optstring_norm"
|
||||||
|
|
||||||
IFS=, read -ra _options <<<"${!1}"
|
|
||||||
# remove empty fields
|
# remove empty fields
|
||||||
for o in "${_options[@]}"; do
|
for i in "${!options[@]}"; do
|
||||||
[[ $o ]] && norm+=("$o")
|
[[ ${options[i]} ]] || unset 'options[i]'
|
||||||
done
|
done
|
||||||
|
|
||||||
# avoid empty strings, reset to "defaults"
|
# avoid empty strings, reset to "defaults"
|
||||||
declare -g "$1=${norm[*]:-defaults}"
|
if (( ! ${#options[@]} )); then
|
||||||
}
|
_optstring_norm="defaults"
|
||||||
|
else
|
||||||
optstring_has_option() {
|
_optstring_norm="$(optstring_from_array options)"
|
||||||
local o="${2%%=*}"
|
|
||||||
|
|
||||||
optstring_get_option "$1" "$o"
|
|
||||||
}
|
|
||||||
|
|
||||||
optstring_append_option() {
|
|
||||||
if ! optstring_has_option "$1" "$2"; then
|
|
||||||
declare -g "$1=${!1},$2"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
optstring_normalize "$1"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
optstring_prepend_option() {
|
optstring_remove_options() {
|
||||||
if ! optstring_has_option "$1" "$2"; then
|
local i options=() target="$2"
|
||||||
declare -g "$1=$2,${!1}"
|
local -n _optstring_remove="$1"
|
||||||
fi
|
|
||||||
|
|
||||||
optstring_normalize "$1"
|
IFS=, read -ra options <<<"$_optstring_remove"
|
||||||
}
|
|
||||||
|
|
||||||
optstring_get_option() {
|
for i in "${!options[@]}"; do
|
||||||
local _opts o
|
optstring_match_one_option 'options[i]' "$target" && unset 'options[i]'
|
||||||
|
|
||||||
IFS=, read -ra _opts <<<"${!1}"
|
|
||||||
for o in "${_opts[@]}"; do
|
|
||||||
if optstring_match_option "$2" "$o"; then
|
|
||||||
declare -g "$o"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
return 1
|
_optstring_remove="$(optstring_from_array options)"
|
||||||
|
}
|
||||||
|
|
||||||
|
optstring_append_one_option() {
|
||||||
|
local option="$2"
|
||||||
|
local -n _optstring_append="$1"
|
||||||
|
|
||||||
|
if ! optstring_match_one_option _optstring_append "$option"; then
|
||||||
|
_optstring_append+=",$option"
|
||||||
|
fi
|
||||||
|
|
||||||
|
optstring_normalize _optstring_append
|
||||||
|
}
|
||||||
|
|
||||||
|
optstring_prepend_one_option() {
|
||||||
|
local option="$2"
|
||||||
|
local -n _optstring_prepend="$1"
|
||||||
|
|
||||||
|
if ! optstring_match_one_option _optstring_prepend "$option"; then
|
||||||
|
_optstring_prepend="$option,$_optstring_prepend"
|
||||||
|
fi
|
||||||
|
|
||||||
|
optstring_normalize _optstring_prepend
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_name_for_devnode() {
|
dm_name_for_devnode() {
|
||||||
|
14
genfstab.in
14
genfstab.in
@ -1,5 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# shellcheck disable=SC2154 # optstring_*_option may export variables in runtime
|
|
||||||
|
|
||||||
shopt -s extglob
|
shopt -s extglob
|
||||||
|
|
||||||
@ -43,18 +42,19 @@ write_source() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
optstring_apply_quirks() {
|
optstring_apply_quirks() {
|
||||||
local varname="$1" fstype="$2"
|
local fstype="$2"
|
||||||
|
local -n _optstring="$1"
|
||||||
|
|
||||||
# SELinux displays a 'seclabel' option in /proc/self/mountinfo. We can't know
|
# 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
|
# 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.
|
# one might install Arch from a Fedora environment), so let's remove it.
|
||||||
optstring_remove_option "$varname" seclabel
|
optstring_remove_options _optstring seclabel
|
||||||
|
|
||||||
# Prune 'relatime' option for any pseudofs. This seems to be a rampant
|
# Prune 'relatime' option for any pseudofs. This seems to be a rampant
|
||||||
# default which the kernel often exports even if the underlying filesystem
|
# default which the kernel often exports even if the underlying filesystem
|
||||||
# doesn't support it. Example: https://bugs.archlinux.org/task/54554.
|
# doesn't support it. Example: https://bugs.archlinux.org/task/54554.
|
||||||
if fstype_is_pseudofs "$fstype"; then
|
if fstype_is_pseudofs "$fstype"; then
|
||||||
optstring_remove_option "$varname" relatime
|
optstring_remove_options _optstring relatime
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case $fstype in
|
case $fstype in
|
||||||
@ -62,15 +62,15 @@ optstring_apply_quirks() {
|
|||||||
# Having only one of subvol= and subvolid= is enough for mounting a btrfs subvolume
|
# Having only one of subvol= and subvolid= is enough for mounting a btrfs subvolume
|
||||||
# And having subvolid= set prevents things like 'snapper rollback' to work, as it
|
# And having subvolid= set prevents things like 'snapper rollback' to work, as it
|
||||||
# updates the subvolume in-place, leaving subvol= unchanged with a different subvolid.
|
# updates the subvolume in-place, leaving subvol= unchanged with a different subvolid.
|
||||||
if optstring_has_option "$varname" subvol; then
|
if optstring_match_one_option _optstring subvol; then
|
||||||
optstring_remove_option "$varname" subvolid
|
optstring_remove_options _optstring subvolid
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
f2fs)
|
f2fs)
|
||||||
# These are Kconfig options for f2fs. Kernels supporting the options will
|
# These are Kconfig options for f2fs. Kernels supporting the options will
|
||||||
# only provide the negative versions of these (e.g. noacl), and vice versa
|
# only provide the negative versions of these (e.g. noacl), and vice versa
|
||||||
# for kernels without support.
|
# for kernels without support.
|
||||||
optstring_remove_option "$varname" noacl,acl,nouser_xattr,user_xattr
|
optstring_remove_options _optstring noacl,acl,nouser_xattr,user_xattr
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user