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