genfstab

simple implementation of genfstab
git clone git://git.ckyln.com/~cem/genfstab.git
Log | Files | Refs | README | LICENSE

commit c0507cea20b8d3a6d23f84938f18ac237a428be0
Author: Cem Keylan <cem@ckyln.com>
Date:   Mon, 15 Jun 2020 16:49:00 +0300

initial commit

Diffstat:
ALICENSE | 21+++++++++++++++++++++
AREADME | 14++++++++++++++
Agenfstab | 145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agenfstab.8 | 45+++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 225 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (C) 2020 Cem Keylan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README b/README @@ -0,0 +1,14 @@ +GENFSTAB +-------------------------------------------------------------------------------- + +Simplified POSIX sh implementation of the Arch Linux tool[1] with the same name. +This implementation (with the exception of a single function) is pure shell, +the only dependency is 'readlink' which can be found in most base utility +implementations. + +Pseudo-filesystem identification is better on this implementation for complex +environments. Other than this, syntax and output is identical. If you are +using a simple PC, you will not notice any difference. + + +[1]: https://github.com/archlinux/arch-install-scripts diff --git a/genfstab b/genfstab @@ -0,0 +1,145 @@ +#!/bin/sh +# fstab generator similar in function to the Arch Linux tool that can be found +# on arch-install-scripts. +# +# Copyright (C) 2020 Cem Keylan <cem@ckyln.com> + +out() { printf '%s\n' "$@" ;} +msg() { out "$@" >&2 ;} +die() { [ "$1" ] && msg "$@"; exit 1 ;} + +find_tag() { + # Function to find the tag of the given device. This eliminates the + # requirement for programs such as lsblk/blkid. + # + # usage: find_tag /dev/sdx1 + + # If no identifiers are given, return with the plain partition name. + [ "$ident" ] || { out "$1"; return 0 ;} + + [ -d "${tagdir:=/dev/disk/by-$(printf "$ident" | tr '[:upper:]' '[:lower:]')}" ] || + die "Directory '$dir' doesn't exist" + + for file in "$tagdir/"*; do + [ "$(readlink -f "$file")" = "$1" ] || continue + tag="$ident=${file##*/}" + break + done + + # If the tag couldn't be found for some reason, fallback to the default + # name instead of printing empty. + out "${tag:-$1}" +} + +readlink_sh() ( + # This function changes directory to the given path in order to find the + # real location of the given directory. We are doing this in a subshell + # so that we return to our previous location. Sadly, we cannot use this + # function on 'find_tag()' as this only works for resolving directory paths. + cd -P "$1" || return 1 + printf '%s\n' "$PWD" +) + +ispseudo() { + # This function checks for pseudo-filesystems and returns 0 if it is. + # There is no definitive way to know every single pseudo-filesystems, + # there might be some issues with this function. + # + # If the filesystem is not a directory or a tag, we will assume that + # it is a pseudofs. The only exception I have noticed so far are loop + # devices. + case "$fs" in /dev/loop*) return 0 ;; /*|*=*) ;; *) return 0; esac + + # These are the most common types of pseudo filesystems. + case "$type" in squashfs|proc|sysfs|tmpfs|devtmpfs|devpts|debugfs) return 0; esac + + # As for the last check, we will look up /proc/filesystems which are + # filesystems known by the running kernel. + while read -r ps filesystem; do + [ "$filesystem" = "$type" ] || continue + [ "$ps" ] && return 0 + return 1 + done < /proc/filesystems + + # If we still haven't come up with an answer, let's assume that this is NOT + # a pseudo-filesystem. + return 1 +} + +usage() { + out "usage: ${0##*/} [-f filter] [-t tag] [-LpPU] [root]" "" \ + " Options:" \ + " -f <filter> Restrict output to mountpoints matching the prefix FILTER" \ + " -L Use labels for source identifiers (Shortcut for -t LABEL)" \ + " -p Exclude pseudofs mounts (default behaviour)" \ + " -P Include pseudofs mounts" \ + " -t <tag> Use tag for source identifiers (should be one of: LABEL," \ + " UUID, PARTLABEL, PARTUUID)" \ + " -U Use UUIDs for source identifiers (Shortcut for -t UUID)" "" \ + " -h Print this help message" "" \ + "${0##*/} generates output suitable for addition to an fstab file based on the" \ + "devices mounted under the mountpoint specified by the given root." "" \ + "This implementation of genfstab is from <https://git.ckyln.com/genfstab>" + exit 0 +} + + +# Print help information +case " $* " in *' --help '*|*' -h '*) usage; esac + +ident='' filter='' pseudo=0 +while getopts PpLUf:t: flag; do + case $flag in + h) usage ;; + P) pseudo=1 ;; + p) pseudo=0 ;; + L) ident=LABEL ;; + U) ident=UUID ;; + f) [ -d "$OPTARG" ] || die "Not a directory '$OPTARG'" + filter=$(readlink_sh "$OPTARG") ;; + t) case "$OPTARG" in + LABEL|UUID|PARTLABEL|PARTUUID) ident=$OPTARG ;; + *) die "Unknown identifier '$OPTARG'"; esac + ;; + ?) die + esac +done +shift $(( OPTIND - 1 )) + +[ "$1" ] && { + [ -d "$1" ] || die "Not a directory '$1'" + root="$(readlink_sh "$1")" +} + +# It's a good thing that /proc/mounts and fstab share the same syntax. We will +# always be defining dump and pass ourselves since they will always be '0 0' on +# /proc/mounts. +while read -r fs dir type options _; do + if ispseudo; then + pass=0 + [ "$pseudo" != 1 ] && continue + [ "$ident" ] && out "# $fs" + else + case "$dir" in "${root:-/}"*) ;; *) continue; esac + [ "$ident" ] && out "# $fs" + fs="$(find_tag "$fs")" + [ "$root" ] && dir=/${dir#$root} + + case "$dir" in /) pass=1 ;; *) pass=2; esac + fi + [ "$filter" ] && case "$dir" in ${filter%/}*) ;; *) continue; esac + + printf '%-23s %-15s %-15s %-15s %s %s\n\n' "$fs" "${dir:-/}" "$type" "$options" "${dump:=0}" "$pass" +done < /proc/mounts + +# Now print out mounted swaps. I am really not quite sure how swaps work as I +# don't personally use them. If you have a better approach to this, please let +# me know. +while read -r file _; do + [ -f "/$file" ] || continue + [ "$root" ] && { + case "$file" in "$root/"*) ;; *) continue; esac + file=/${file#$root} + } + printf '%-23s %-15s %-15s %-15s %s %s\n\n' "$file" none swap sw 0 0 +done < /proc/swaps diff --git a/genfstab.8 b/genfstab.8 @@ -0,0 +1,45 @@ +.TH GENFSTAB 8 "2020-06-15" "Cem Keylan" "System Administration" +.SH NAME +genfstab - generate fstab-compatible output +.SH SYNOPSIS +genfstab [-f filter] [-t tag] [-LpPU] [root] +.SH DESCRIPTION +genfstab is a utility that detects mounted filesystems and swaps, and outputs +information that can be parsed by fstab(5). This is a POSIX sh implementation +of the Arch Linux tool with the same name. +.SH OPTIONS +.PP +\fB-f\fR <filter> +.RS 4 +Restrict output to mountpoints matching the prefix FILTER +.RE +.PP +\fB-L\fR +.RS 4 +Use labels for source identifiers (shortcut for -t LABEL) +.RE +.PP +\fB-p\fR +.RS 4 +Exclude pseudofs mounts (default behaviour) +.RE +.PP +\fB-P\fR +.RS 4 +Include pseudofs mounts +.RE +.PP +\fB-t\fR <tag> +.RS 4 +Use tag for source identifiers (should be one of: LABEL, UUID, PARTLABEL, PARTUUID) +.RE +.PP +\fB-U\fR +.RS 4 +Use UUIDs for source identifiers (shortcut for \fI-t UUID\fR) +.RE +.SH AUTHOR +Cem Keylan <cem@ckyln\&.com> +.SH SEE ALSO +.sp +\fBfstab\fR(5)