Whamcloud - gitweb
e2fsck: update mmp block in one thread
[tools/e2fsprogs.git] / contrib / populate-extfs.sh
1 #!/bin/sh
2 #
3 # This script uses debugfs command to populate the ext2/3/4 filesystem
4 # from a given directory.
5 #
6
7 do_usage () {
8         cat << _EOF
9 Usage: populate-extfs.sh <source> <device>
10 Create 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
21 SRCDIR=${1%%/}
22 DEVICE=$2
23
24 # Find where is the debugfs command if not found in the env.
25 if [ -z "$DEBUGFS" ]; then
26         CONTRIB_DIR=$(dirname $(readlink -f $0))
27         DEBUGFS="$CONTRIB_DIR/../debugfs/debugfs"
28 fi
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