[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Linux image packages going to depend on python



On Sun, 2009-11-29 at 13:56 +0100, Marco d'Itri wrote:
> On Nov 28, Bastian Blank <waldi@debian.org> wrote:
> 
> > The Linux image packages needs to do some modifications to core
> > configuration files like fstab in the future to allow newer kernels to
> > work. To do this and the planned further extension I intend to make all
> > linux image packages depend on python.
> This is not justified.
> I will be happy to rewrite in perl whatever you need.

Find attached an initial attempt to use shell only. Let me know if you
are interested.

The script is configurable, so a sysadmin can decide to re-rewrite fstab
using DM/LVM names rather than UUID, or volume LABEL, or legacy /dev/hd*
names.

Known bugs/limitation:
 * Should accept command line arguments
 * Some devices may need to be blacklisted
 * What about removable media? (UUID of media in CDROM? ouch)
 * Should actually write fstab ;)

I have hesitated to probe the current /dev or to use blkid... I can
change that easily.

I think this script should have a companion, to insert/update a comments
line above each fstab entry (à-la Debian-Installer)

Franklin
#!/bin/sh
set -e
# update-fstab-persistent-names - Rewrite current fstab
# (Using your prefered device naming).
#
# Copyright 2009, Frank Lin PIAT <fpiat@klabs.be>
# Licensed under GPLv2 or later
#
# Known bugs/limitation
#  * Should actually _write_ fstab ;)
#  * Doesn't accept command line arguments
#  * Some devices may need to be blacklisted
#  * What about removable media?


# ====== User configurable variables ====== #

# Prefered device naming scheme to use in fstab. **Order matters**.
#    dm 	: use /dev/grpname/logvolname for LVM volumes
#               : or /dev/mapper/dmname for CRYPT and other.
#    uuid	: use UUID=cafecafe (based on the FS's volume UUID)
#    label	: use LABEL=foo (based on the FS's volume name)
#    plaindev	: use legacy /dev/ devices.
PREFERED_NAME='dm uuid label plaindev'

# Rewrite existing LABEL=foo lines in fstab
REWRITE_LABELS=1

# Rewrite existing UUID=foo lines in fstab
REWRITE_UUIDS=1

# ====== End of user configurable variables ====== #

# Let's declare some functions...

# Initialise a sed file to rewrite fstab, based on device major/minor IDs.
# (this temporary sed file search and replace all possible names for the
# local devices, with a fake unique ID "#DEVICE=X.Y" where X and Y are 
# the device's major and minor numbers)
generate_simple_fstab_sed() {

	# Sed rule to rewrite /dev/* entry as #DEVICE=X:Y
	find /dev/ \( -type b -o -type l \)  \
			\! -path '/dev/.udev/*' \! -path '/dev/.static/*' \
			-iregex '^[a-z0-9./_-]*$' -printf '%Y\t%p\n' \
		| sed -n -e 's/^b\t\(.*\)/\1/p' \
		| while read s ; do
			printf 's\t^%s\>\t#DEVICE=%d:%d\t\n' \
				"$s" \
				"$(stat -L -c '0x%t' "$s")" \
				"$(stat -L -c '0x%T' "$s")"
		done

	# Sed rule to rewrite existing LABELS=* entry as #DEVICE=X:Y
	if [ "$REWRITE_LABELS" = "1" -a -d /dev/disk/by-label ]; then
		find /dev/disk/by-label/ -type l -iregex '^[a-z0-9./_-]*$' \
			| while read s ; do \
				printf 's\t^%s\>\t#DEVICE=%d:%d\t\n' \
					"LABEL=$(basename $s)" \
					"$(stat -L -c '0x%t' "$s")" \
					"$(stat -L -c '0x%T' "$s")"
			done
	fi

	# Sed rule to rewrite existing UUID=* entry as #DEVICE=X:Y
	if [ "$REWRITE_UUIDS" = "1" -a -d /dev/disk/by-uuid ]; then
		find /dev/disk/by-uuid/ -type l -iregex '^[a-z0-9./_-]*$' \
			| while read s ; do \
				printf 's\t^%s\>\t#DEVICE=%d:%d\tg\n' \
					"UUID=$(basename $s)" \
					"$(stat -L -c '0x%t' "$s")" \
					"$(stat -L -c '0x%T' "$s")"
			done
	fi
}



# create a list of device-major-minor -> /dev/vg/lv for LVM.
use_dm_legacy() {
	which vgs 2>&1 > /dev/null || return 0

	LVM_VGS="$(vgs --all -o vg_name --noheadings | sed -e 's#^\s*#/dev/#')"
	[ ! "$LVM_VGS" ] && return 0

	find $LVM_VGS -maxdepth 1 -type l -iregex '^[a-z0-9./_-]*$' \
		| while read s ; do \
			printf 's\t#DEVICE=%d:%d\t%s\t\n' \
				"$(stat -L -c '0x%t' "$s")" \
				"$(stat -L -c '0x%T' "$s")" \
				"$s"
		done
}

# create a list of device-major-minor -> /dev/vg/lv
# or -> /dev/mapper/name for dmsetup (LVM/DM/CRYPT...)
use_dm_new() {
	which dmsetup 2>&1 > /dev/null || return 0

	dmsetup info -c --noheadings --separator="$(printf "\t")" \
			-o major,minor,name,vg_name,lv_name \
		| while read maj min name vg lv ; do
			if [ "$vg" -a "$lv" -a -b /dev/$vg/$lv ] ; then
			       	DEV=/dev/$vg/$lv
			else
				DEV=/dev/mapper/$name
			fi

			if [ -b $DEV ]; then
			       printf "s\t#DEVICE=%d:%d\t%s\t\n" $maj $min $DEV
			fi
	       done
}

# Disaptcher to create a list of device-major-minor -> /dev/vg/lv
# or -> /dev/mapper/diskmappername, depending on dmsetup version.
use_dm() {
	which dmsetup 2>&1 > /dev/null || return 0

	# Lenny's dmsetup don't provide "lv_name"
	if dmsetup --noheadings info -c -o lv_name >/dev/null 2>&1; then
		use_dm_new
	else
		use_dm_legacy
	fi
}

# create a list of device-major-minor -> uuid
use_uuid() {
	[ ! -d /dev/disk/by-uuid ] && return 0

	find /dev/disk/by-uuid/ -type l -iregex '^[a-z0-9./_-]*$' \
		| while read s ; do \
			printf 's\t#DEVICE=%d:%d\t%s\t\n' \
				"$(stat -L -c '0x%t' "$s")" \
				"$(stat -L -c '0x%T' "$s")" \
				"UUID=$(basename $s)"
		done
}

# create a list of device-major-minor -> label
use_label() {
	[ ! -d /dev/disk/by-label ] && return 0

	find /dev/disk/by-label/ -type l -iregex '^[a-z0-9./_-]*$' \
		| while read s ; do \
			printf 's\t#DEVICE=%d:%d\t%s\t\n' \
				"$(stat -L -c '0x%t' "$s")" \
				"$(stat -L -c '0x%T' "$s")" \
				"LABEL=$(basename $s)"
		done
}

# create a list of device-major-minor -> /dev
use_plaindev() {
	find /dev/ -maxdepth 1 -type b '!' -path '/dev/.udev/*' \
		| grep -v '/dev/dm-' \
		| while read s ; do \
			printf 's\t#DEVICE=%d:%d\t%s\t\n' \
				"$(stat -L -c '0x%t' "$s")" \
				"$(stat -L -c '0x%T' "$s")" \
				"$s"
		done
}

# Drop remaining entries which have no sane equivalement.
use_dropunknown() {
	echo '/#DEVICE=/d'
}

# Drop null rules
use_dropnullrules() {
	echo '/^s\t^\([^\t]\+\)\\>\t\1\t/d'
}

# ====== End of Function declaration ====== #


WDIR="$(mktemp -d -t $(basename $0).XXX)"
trap 'if [ "$WDIR" ]; then rm -f $WDIR/* ; rmdir $WDIR ; fi' EXIT
#Don't purge to debug#WDIR="/tmp/this-is-a-test"


# Initialise a sed file to rewrite fstab
generate_simple_fstab_sed > $WDIR/fstab.sed

# Now, let's poke the sed file to use sensible devices names
# instead of the fake "#DEVICE=X.Y".
i=1
last_tweak=".0.orig"
for p in $PREFERED_NAME dropunknown dropnullrules ; do
	case $p in
		dm|uuid|label|plaindev|dropunknown|dropnullrules)
			sedtweak=$WDIR/tweak_${i}_Use_$p.sed
			use_$p > $sedtweak
			sed -i$last_tweak -f $sedtweak $WDIR/fstab.sed
			last_tweak=".$i.$p"
			;;
		*)
			echo "Error: Invalid preference value \"$p\" for option PREFFERED_NAME" 1>&2
			;;
	esac
	i=$((i + 1))
done

# And Finaly...
sed -f $WDIR/fstab.sed /etc/fstab


Reply to: