Blame contrib/populate-extfs.sh

Packit a62e42
#!/bin/sh
Packit a62e42
#
Packit a62e42
# This script uses debugfs command to populate the ext2/3/4 filesystem
Packit a62e42
# from a given directory.
Packit a62e42
#
Packit a62e42
Packit a62e42
do_usage () {
Packit a62e42
	cat << _EOF
Packit a62e42
Usage: populate-extfs.sh <source> <device>
Packit a62e42
Create an ext2/ext3/ext4 filesystem from a directory or file
Packit a62e42
Packit a62e42
  source: The source directory or file
Packit a62e42
  device: The target device
Packit a62e42
Packit a62e42
_EOF
Packit a62e42
	exit 1
Packit a62e42
}
Packit a62e42
Packit a62e42
[ $# -ne 2 ] && do_usage
Packit a62e42
Packit a62e42
SRCDIR=${1%%/}
Packit a62e42
DEVICE=$2
Packit a62e42
Packit a62e42
# Find where is the debugfs command if not found in the env.
Packit a62e42
if [ -z "$DEBUGFS" ]; then
Packit a62e42
	CONTRIB_DIR=$(dirname $(readlink -f $0))
Packit a62e42
	DEBUGFS="$CONTRIB_DIR/../debugfs/debugfs"
Packit a62e42
fi
Packit a62e42
Packit a62e42
{
Packit a62e42
	CWD="/"
Packit a62e42
	find $SRCDIR | while read FILE; do
Packit a62e42
                TGT="${FILE##*/}"
Packit a62e42
                DIR="${FILE#$SRCDIR}"
Packit a62e42
                DIR="${DIR%$TGT}"
Packit a62e42
Packit a62e42
		# Skip the root dir
Packit a62e42
		[ ! -z "$DIR" ] || continue
Packit a62e42
		[ ! -z "$TGT" ] || continue
Packit a62e42
Packit a62e42
		if [ "$DIR" != "$CWD" ]; then
Packit a62e42
			echo "cd $DIR"
Packit a62e42
			CWD="$DIR"
Packit a62e42
		fi
Packit a62e42
Packit a62e42
		# Only stat once since stat is a time consuming command
Packit a62e42
		STAT=$(stat -c "TYPE=\"%F\";DEVNO=\"0x%t 0x%T\";MODE=\"%f\";U=\"%u\";G=\"%g\"" $FILE)
Packit a62e42
		eval $STAT
Packit a62e42
Packit a62e42
		case $TYPE in
Packit a62e42
		"directory")
Packit a62e42
			echo "mkdir $TGT"
Packit a62e42
			;;
Packit a62e42
		"regular file" | "regular empty file")
Packit a62e42
			echo "write $FILE $TGT"
Packit a62e42
			;;
Packit a62e42
		"symbolic link")
Packit a62e42
			LINK_TGT=$(readlink $FILE)
Packit a62e42
			echo "symlink $TGT $LINK_TGT"
Packit a62e42
			;;
Packit a62e42
		"block special file")
Packit a62e42
			echo "mknod $TGT b $DEVNO"
Packit a62e42
			;;
Packit a62e42
		"character special file")
Packit a62e42
			echo "mknod $TGT c $DEVNO"
Packit a62e42
			;;
Packit a62e42
		"fifo")
Packit a62e42
			echo "mknod $TGT p"
Packit a62e42
			;;
Packit a62e42
		*)
Packit a62e42
			echo "Unknown/unhandled file type '$TYPE' file: $FILE" 1>&2
Packit a62e42
			;;
Packit a62e42
		esac
Packit a62e42
Packit a62e42
		# Set the file mode
Packit a62e42
		echo "sif $TGT mode 0x$MODE"
Packit a62e42
Packit a62e42
		# Set uid and gid
Packit a62e42
		echo "sif $TGT uid $U"
Packit a62e42
		echo "sif $TGT gid $G"
Packit a62e42
	done
Packit a62e42
Packit a62e42
	# Handle the hard links.
Packit a62e42
	# Save the hard links to a file, use the inode number as the filename, for example:
Packit a62e42
	# If a and b's inode number is 6775928, save a and b to /tmp/tmp.VrCwHh5gdt/6775928.
Packit a62e42
	INODE_DIR=`mktemp -d` || exit 1
Packit a62e42
	for i in `find $SRCDIR -type f -links +1 -printf 'INODE=%i###FN=%p\n'`; do
Packit a62e42
		eval `echo $i | sed 's$###$ $'`
Packit a62e42
		echo ${FN#$SRCDIR} >>$INODE_DIR/$INODE
Packit a62e42
	done
Packit a62e42
	# Use the debugfs' ln and "sif links_count" to handle them.
Packit a62e42
	for i in `ls $INODE_DIR`; do
Packit a62e42
		# The link source
Packit a62e42
		SRC=`head -1 $INODE_DIR/$i`
Packit a62e42
		# Remove the files and link them again except the first one
Packit a62e42
		for TGT in `sed -n -e '1!p' $INODE_DIR/$i`; do
Packit a62e42
			echo "rm $TGT"
Packit a62e42
			echo "ln $SRC $TGT"
Packit a62e42
		done
Packit a62e42
		LN_CNT=`cat $INODE_DIR/$i | wc -l`
Packit a62e42
		# Set the links count
Packit a62e42
		echo "sif $SRC links_count $LN_CNT"
Packit a62e42
	done
Packit a62e42
	rm -fr $INODE_DIR
Packit a62e42
} | $DEBUGFS -w -f - $DEVICE