xref: /aosp_15_r20/external/e2fsprogs/contrib/populate-extfs.sh (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
1*6a54128fSAndroid Build Coastguard Worker#!/bin/sh
2*6a54128fSAndroid Build Coastguard Worker#
3*6a54128fSAndroid Build Coastguard Worker# This script uses debugfs command to populate the ext2/3/4 filesystem
4*6a54128fSAndroid Build Coastguard Worker# from a given directory.
5*6a54128fSAndroid Build Coastguard Worker#
6*6a54128fSAndroid Build Coastguard Worker
7*6a54128fSAndroid Build Coastguard Workerdo_usage () {
8*6a54128fSAndroid Build Coastguard Worker	cat << _EOF
9*6a54128fSAndroid Build Coastguard WorkerUsage: populate-extfs.sh <source> <device>
10*6a54128fSAndroid Build Coastguard WorkerCreate an ext2/ext3/ext4 filesystem from a directory or file
11*6a54128fSAndroid Build Coastguard Worker
12*6a54128fSAndroid Build Coastguard Worker  source: The source directory or file
13*6a54128fSAndroid Build Coastguard Worker  device: The target device
14*6a54128fSAndroid Build Coastguard Worker
15*6a54128fSAndroid Build Coastguard Worker_EOF
16*6a54128fSAndroid Build Coastguard Worker	exit 1
17*6a54128fSAndroid Build Coastguard Worker}
18*6a54128fSAndroid Build Coastguard Worker
19*6a54128fSAndroid Build Coastguard Worker[ $# -ne 2 ] && do_usage
20*6a54128fSAndroid Build Coastguard Worker
21*6a54128fSAndroid Build Coastguard WorkerSRCDIR=${1%%/}
22*6a54128fSAndroid Build Coastguard WorkerDEVICE=$2
23*6a54128fSAndroid Build Coastguard Worker
24*6a54128fSAndroid Build Coastguard Worker# Find where is the debugfs command if not found in the env.
25*6a54128fSAndroid Build Coastguard Workerif [ -z "$DEBUGFS" ]; then
26*6a54128fSAndroid Build Coastguard Worker	CONTRIB_DIR=$(dirname $(readlink -f $0))
27*6a54128fSAndroid Build Coastguard Worker	DEBUGFS="$CONTRIB_DIR/../debugfs/debugfs"
28*6a54128fSAndroid Build Coastguard Workerfi
29*6a54128fSAndroid Build Coastguard Worker
30*6a54128fSAndroid Build Coastguard Worker{
31*6a54128fSAndroid Build Coastguard Worker	CWD="/"
32*6a54128fSAndroid Build Coastguard Worker	find $SRCDIR | while read FILE; do
33*6a54128fSAndroid Build Coastguard Worker                TGT="${FILE##*/}"
34*6a54128fSAndroid Build Coastguard Worker                DIR="${FILE#$SRCDIR}"
35*6a54128fSAndroid Build Coastguard Worker                DIR="${DIR%$TGT}"
36*6a54128fSAndroid Build Coastguard Worker
37*6a54128fSAndroid Build Coastguard Worker		# Skip the root dir
38*6a54128fSAndroid Build Coastguard Worker		[ ! -z "$DIR" ] || continue
39*6a54128fSAndroid Build Coastguard Worker		[ ! -z "$TGT" ] || continue
40*6a54128fSAndroid Build Coastguard Worker
41*6a54128fSAndroid Build Coastguard Worker		if [ "$DIR" != "$CWD" ]; then
42*6a54128fSAndroid Build Coastguard Worker			echo "cd $DIR"
43*6a54128fSAndroid Build Coastguard Worker			CWD="$DIR"
44*6a54128fSAndroid Build Coastguard Worker		fi
45*6a54128fSAndroid Build Coastguard Worker
46*6a54128fSAndroid Build Coastguard Worker		# Only stat once since stat is a time consuming command
47*6a54128fSAndroid Build Coastguard Worker		STAT=$(stat -c "TYPE=\"%F\";DEVNO=\"0x%t 0x%T\";MODE=\"%f\";U=\"%u\";G=\"%g\"" $FILE)
48*6a54128fSAndroid Build Coastguard Worker		eval $STAT
49*6a54128fSAndroid Build Coastguard Worker
50*6a54128fSAndroid Build Coastguard Worker		case $TYPE in
51*6a54128fSAndroid Build Coastguard Worker		"directory")
52*6a54128fSAndroid Build Coastguard Worker			echo "mkdir $TGT"
53*6a54128fSAndroid Build Coastguard Worker			;;
54*6a54128fSAndroid Build Coastguard Worker		"regular file" | "regular empty file")
55*6a54128fSAndroid Build Coastguard Worker			echo "write $FILE $TGT"
56*6a54128fSAndroid Build Coastguard Worker			;;
57*6a54128fSAndroid Build Coastguard Worker		"symbolic link")
58*6a54128fSAndroid Build Coastguard Worker			LINK_TGT=$(readlink $FILE)
59*6a54128fSAndroid Build Coastguard Worker			echo "symlink $TGT $LINK_TGT"
60*6a54128fSAndroid Build Coastguard Worker			;;
61*6a54128fSAndroid Build Coastguard Worker		"block special file")
62*6a54128fSAndroid Build Coastguard Worker			echo "mknod $TGT b $DEVNO"
63*6a54128fSAndroid Build Coastguard Worker			;;
64*6a54128fSAndroid Build Coastguard Worker		"character special file")
65*6a54128fSAndroid Build Coastguard Worker			echo "mknod $TGT c $DEVNO"
66*6a54128fSAndroid Build Coastguard Worker			;;
67*6a54128fSAndroid Build Coastguard Worker		"fifo")
68*6a54128fSAndroid Build Coastguard Worker			echo "mknod $TGT p"
69*6a54128fSAndroid Build Coastguard Worker			;;
70*6a54128fSAndroid Build Coastguard Worker		*)
71*6a54128fSAndroid Build Coastguard Worker			echo "Unknown/unhandled file type '$TYPE' file: $FILE" 1>&2
72*6a54128fSAndroid Build Coastguard Worker			;;
73*6a54128fSAndroid Build Coastguard Worker		esac
74*6a54128fSAndroid Build Coastguard Worker
75*6a54128fSAndroid Build Coastguard Worker		# Set the file mode
76*6a54128fSAndroid Build Coastguard Worker		echo "sif $TGT mode 0x$MODE"
77*6a54128fSAndroid Build Coastguard Worker
78*6a54128fSAndroid Build Coastguard Worker		# Set uid and gid
79*6a54128fSAndroid Build Coastguard Worker		echo "sif $TGT uid $U"
80*6a54128fSAndroid Build Coastguard Worker		echo "sif $TGT gid $G"
81*6a54128fSAndroid Build Coastguard Worker	done
82*6a54128fSAndroid Build Coastguard Worker
83*6a54128fSAndroid Build Coastguard Worker	# Handle the hard links.
84*6a54128fSAndroid Build Coastguard Worker	# Save the hard links to a file, use the inode number as the filename, for example:
85*6a54128fSAndroid Build Coastguard Worker	# If a and b's inode number is 6775928, save a and b to /tmp/tmp.VrCwHh5gdt/6775928.
86*6a54128fSAndroid Build Coastguard Worker	INODE_DIR=`mktemp -d` || exit 1
87*6a54128fSAndroid Build Coastguard Worker	for i in `find $SRCDIR -type f -links +1 -printf 'INODE=%i###FN=%p\n'`; do
88*6a54128fSAndroid Build Coastguard Worker		eval `echo $i | sed 's$###$ $'`
89*6a54128fSAndroid Build Coastguard Worker		echo ${FN#$SRCDIR} >>$INODE_DIR/$INODE
90*6a54128fSAndroid Build Coastguard Worker	done
91*6a54128fSAndroid Build Coastguard Worker	# Use the debugfs' ln and "sif links_count" to handle them.
92*6a54128fSAndroid Build Coastguard Worker	for i in `ls $INODE_DIR`; do
93*6a54128fSAndroid Build Coastguard Worker		# The link source
94*6a54128fSAndroid Build Coastguard Worker		SRC=`head -1 $INODE_DIR/$i`
95*6a54128fSAndroid Build Coastguard Worker		# Remove the files and link them again except the first one
96*6a54128fSAndroid Build Coastguard Worker		for TGT in `sed -n -e '1!p' $INODE_DIR/$i`; do
97*6a54128fSAndroid Build Coastguard Worker			echo "rm $TGT"
98*6a54128fSAndroid Build Coastguard Worker			echo "ln $SRC $TGT"
99*6a54128fSAndroid Build Coastguard Worker		done
100*6a54128fSAndroid Build Coastguard Worker		LN_CNT=`cat $INODE_DIR/$i | wc -l`
101*6a54128fSAndroid Build Coastguard Worker		# Set the links count
102*6a54128fSAndroid Build Coastguard Worker		echo "sif $SRC links_count $LN_CNT"
103*6a54128fSAndroid Build Coastguard Worker	done
104*6a54128fSAndroid Build Coastguard Worker	rm -fr $INODE_DIR
105*6a54128fSAndroid Build Coastguard Worker} | $DEBUGFS -w -f - $DEVICE
106