• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2#
3# This script uses debugfs command to populate the ext2/3/4 filesystem
4# from a given directory.
5#
6# Added mode, uid and gid config function by OpenHarmony team.
7export LANG=en_US.UTF-8
8export LANGUAGE=en_US:en
9
10do_usage () {
11	cat << _EOF
12Usage: populate-extfs.sh <source> <device> <cfgfile>
13Create an ext2/ext3/ext4 filesystem from a directory or file
14
15  source: The source directory or file
16  device: The target device
17
18_EOF
19	exit 1
20}
21
22CFGFILE_CNT=5
23FILEMODE_IDX=2
24FILEU_IDX=3
25FILEG_IDX=4
26_NEW_FILEMODE=0
27_NEW_FILEUID=0
28_NEW_FILEGID=0
29
30declare -a CONFIG_ARRAY
31
32do_parsecfgfile () {
33	i=0
34	while read _BINFILE_ _FILETYPE_ _FILEMODE_ _FILEUID_ _FILEGID_
35	do
36		CONFIG_ARRAY[${i}]=${_BINFILE_}
37		i=$[$i+1]
38		CONFIG_ARRAY[${i}]=${_FILETYPE_}
39		i=$[$i+1]
40		CONFIG_ARRAY[${i}]=${_FILEMODE_}
41		i=$[$i+1]
42		CONFIG_ARRAY[${i}]=${_FILEUID_}
43		i=$[$i+1]
44		CONFIG_ARRAY[${i}]=${_FILEGID_}
45		i=$[$i+1]
46	done < ${CFGFILE}
47}
48
49do_getfilecfgmode () {
50	i=0
51	_NEW_FILEMODE_=$2
52	_NEW_FILEUID_=0
53	_NEW_FILEGID_=0
54	while [ $i -lt ${#CONFIG_ARRAY[@]} ]
55	do
56		if [ "$1" == "${CONFIG_ARRAY[$i]}" ]; then
57			# Change file mode from OCT to HEX.
58			_NEW_FILEMODE_=$(echo "obase=16;$((0x$MODE & (~07777) | 0${CONFIG_ARRAY[$i+${FILEMODE_IDX}]}))"|bc)
59			_NEW_FILEUID_=${CONFIG_ARRAY[$i+${FILEU_IDX}]}
60			_NEW_FILLEGID_=${CONFIG_ARRAY[$i+${FILEG_IDX}]}
61			return 0
62		fi
63		i=$[$i+${CFGFILE_CNT}]
64	done
65}
66
67[ $# -ne 3 ] && do_usage
68
69SRCDIR=${1%%/}
70DEVICE=$2
71CFGFILE=$3
72
73# parse config file
74do_parsecfgfile
75
76# Find where is the debugfs command if not found in the env.
77if [ -z "$DEBUGFS" ]; then
78	CONTRIB_DIR=$(dirname $(readlink -f $0))
79	DEBUGFS="$CONTRIB_DIR/../debugfs/debugfs"
80	DEBUGFS=debugfs
81fi
82
83# "debugfs" command check.
84command -v debugfs >/dev/null 2>&1 || \
85{ echo >&2 "debugfs is required, please install by \"apt-get install e2fsprogs\". Aborting."; exit 1; }
86
87{
88	CWD="/"
89	find $SRCDIR | while read FILE; do
90                TGT="${FILE##*/}"
91                DIR="${FILE#$SRCDIR}"
92                DIR="${DIR%$TGT}"
93
94		# Skip the root dir
95		[ ! -z "$DIR" ] || continue
96		[ ! -z "$TGT" ] || continue
97
98		if [ "$DIR" != "$CWD" ]; then
99			echo "cd $DIR"
100			CWD="$DIR"
101		fi
102
103		# Only stat once since stat is a time consuming command
104		STAT=$(stat -c "TYPE=\"%F\";DEVNO=\"0x%t 0x%T\";MODE=\"%f\";U=\"%u\";G=\"%g\"" $FILE)
105		eval $STAT
106
107		case $TYPE in
108		"directory")
109			echo "mkdir $TGT"
110			;;
111		"regular file" | "regular empty file")
112			echo "write $FILE $TGT"
113			;;
114		"symbolic link")
115			LINK_TGT=$(readlink $FILE)
116			echo "symlink $TGT $LINK_TGT"
117			;;
118		"block special file")
119			echo "mknod $TGT b $DEVNO"
120			;;
121		"character special file")
122			echo "mknod $TGT c $DEVNO"
123			;;
124		"fifo")
125			echo "mknod $TGT p"
126			;;
127		*)
128			echo "Unknown/unhandled file type '$TYPE' file: $FILE" 1>&2
129			;;
130		esac
131
132		do_getfilecfgmode ${FILE#$SRCDIR} $MODE $U $G
133		MODE=${_NEW_FILEMODE_}
134		U=${_NEW_FILEUID_}
135		G=${_NEW_FILEGID_}
136		# Set the file mode
137		echo "sif $TGT mode 0x$MODE"
138
139		# Set uid and gid
140		echo "sif $TGT uid $U"
141		echo "sif $TGT gid $G"
142	done
143
144	# Handle the hard links.
145	# Save the hard links to a file, use the inode number as the filename, for example:
146	# If a and b's inode number is 6775928, save a and b to /tmp/tmp.VrCwHh5gdt/6775928.
147	INODE_DIR=`mktemp -d` || exit 1
148	for i in `find $SRCDIR -type f -links +1 -printf 'INODE=%i###FN=%p\n'`; do
149		eval `echo $i | sed 's$###$ $'`
150		echo ${FN#$SRCDIR} >>$INODE_DIR/$INODE
151	done
152	# Use the debugfs' ln and "sif links_count" to handle them.
153	for i in `ls $INODE_DIR`; do
154		# The link source
155		SRC=`head -1 $INODE_DIR/$i`
156		# Remove the files and link them again except the first one
157		for TGT in `sed -n -e '1!p' $INODE_DIR/$i`; do
158			echo "rm $TGT"
159			echo "ln $SRC $TGT"
160		done
161		LN_CNT=`cat $INODE_DIR/$i | wc -l`
162		# Set the links count
163		echo "sif $SRC links_count $LN_CNT"
164	done
165	rm -fr $INODE_DIR
166} | $DEBUGFS -w -f - $DEVICE
167