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