mkinitrd(8): improve the man page and styles
[dragonfly.git] / sbin / mkinitrd / mkinitrd.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2010, 2018
4 #       The DragonFly Project.  All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in
14 #    the documentation and/or other materials provided with the
15 #    distribution.
16 # 3. Neither the name of The DragonFly Project nor the names of its
17 #    contributors may be used to endorse or promote products derived
18 #    from this software without specific, prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
24 # COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 # SUCH DAMAGE.
32 #
33
34 . /etc/defaults/mkinitrd.conf
35
36 if [ -r /etc/mkinitrd.conf ]; then
37         . /etc/mkinitrd.conf
38         echo "Loaded configuration from /etc/mkinitrd.conf"
39 fi
40
41 VN_DEV=""
42
43 # Calculate the total size of the given directory, taking care of the
44 # hard links.
45 calc_size()
46 {
47         find "$1" -ls | \
48             awk '{ print $7,$1 }' | \
49             sort -n -k 2 | \
50             uniq -f 1 | \
51             awk '{ sum+=$1 } END { print sum }'  # byte
52 }
53
54 calc_initrd_size()
55 {
56         echo "Contents directories:" >&2
57         isize=0
58         for dir in ${CONTENT_DIRS}; do
59                 csize=$(calc_size ${dir})
60                 echo "* ${dir}: ${csize} bytes" >&2
61                 isize=$((${isize} + ${csize}))
62         done
63         # Round initrd size up by MB
64         isize_mb=$(echo "${isize}" | awk '
65             function ceil(x) {
66                 y = int(x);
67                 return (x>y ? y+1 : y);
68             }
69             {
70                 mb = $1/1024/1024;
71                 print ceil(mb);
72             }')
73         # Add additional 1 MB
74         echo $((${isize_mb} + 1))
75 }
76
77 create_vn()
78 {
79         if [ ! -d "$BUILD_DIR" ]; then
80                 mkdir -p $BUILD_DIR
81                 echo "Created build directory $BUILD_DIR"
82         fi
83         vnconfig -c -S ${INITRD_SIZE}m -Z -T vn ${TMP_DIR}/initrd.img \
84             > ${TMP_DIR}/vndev.mkinitrd || {
85                 echo "Failed to configure vn device"
86                 exit 1
87         }
88
89         VN_DEV=`cat ${TMP_DIR}/vndev.mkinitrd | cut -f 2 -d ' '`
90         rm ${TMP_DIR}/vndev.mkinitrd
91
92         echo "Configured $VN_DEV"
93         newfs -i 131072 -m 0 /dev/${VN_DEV}s0
94         echo "Formatted initrd image with UFS"
95         mount -t ufs /dev/${VN_DEV}s0 $BUILD_DIR
96         echo "Mounted initrd image on ${BUILD_DIR}"
97 }
98
99 destroy_vn()
100 {
101         umount /dev/${VN_DEV}s0
102         echo "Unmounted initrd image"
103         vnconfig -u $VN_DEV
104         echo "Unconfigured $VN_DEV"
105 }
106
107 make_hier()
108 {
109         for dir in ${INITRD_DIRS}; do
110                 mkdir -p ${BUILD_DIR}/${dir}
111         done
112
113         echo "Created directory structure"
114 }
115
116 copy_content()
117 {
118         for dir in ${CONTENT_DIRS}; do
119                 cpdup -o -u ${dir}/ ${BUILD_DIR}/ || {
120                         echo "Failed to copy ${dir} to ${BUILD_DIR}"
121                         exit 1
122                 }
123         done
124 }
125
126 print_info()
127 {
128         lt ${BUILD_DIR}
129         df -h ${BUILD_DIR}
130 }
131
132 usage()
133 {
134         echo "usage: ${0##*/} [-b bootdir] [-c contentsdir] [-t tmpdir]" \
135              "[-s size] [-S max_size]"
136         exit 2
137 }
138
139 args=`getopt b:c:s:S:t: $*`
140 test $? -ne 0 && usage
141
142 set -- $args
143 for i; do
144         case "$i" in
145         -b)     BOOT_DIR="$2"; shift; shift;;
146         -c)     CONTENT_DIR="$2"; shift; shift;;
147         -s)     INITRD_SIZE="$2"; shift; shift;;
148         -S)     INITRD_SIZE_MAX="$2"; shift; shift;;
149         -t)     TMP_DIR="$2"; shift; shift;;
150         --)     shift; break;
151         esac
152 done
153 test ! -d ${BOOT_DIR}    && usage
154 test ! -d ${CONTENT_DIR} && usage
155 test ! -d ${TMP_DIR}     && usage
156 test ! -z "$1"           && usage
157
158 BUILD_DIR="${TMP_DIR}/initrd"
159 INITRD_SIZE=${INITRD_SIZE%[mM]}  # MB
160 INITRD_SIZE_MAX=${INITRD_SIZE_MAX%[mM]}  # MB
161
162 CSIZE=$(calc_initrd_size)
163 echo "Required initrd image size: ${CSIZE} MB"
164 if [ -n "${INITRD_SIZE}" -a "${INITRD_SIZE}" != "0" ]; then
165         if [ ${CSIZE} -gt ${INITRD_SIZE} ]; then
166                 echo "Specified initrd size (${INITRD_SIZE} MB) too small"
167                 exit 1
168         fi
169 else
170         INITRD_SIZE=${CSIZE}
171 fi
172 echo "Initrd size: ${INITRD_SIZE} MB"
173
174 if [ -n "${INITRD_SIZE_MAX}" -a "${INITRD_SIZE_MAX}" != "0" ] && \
175    [ ${INITRD_SIZE} -gt ${INITRD_SIZE_MAX} ]; then
176         echo "Exceeded the specified maximum size (${INITRD_SIZE_MAX} MB)"
177         exit 1
178 fi
179
180 create_vn
181 copy_content
182 make_hier
183 print_info
184 destroy_vn
185 echo -n "Compressing ${TMP_DIR}/initrd.img ..."
186 gzip -9 ${TMP_DIR}/initrd.img
187 echo " OK"
188 echo -n "Copying ${TMP_DIR}/initrd.img.gz to ${BOOT_DIR}/kernel/initrd.img.gz ..."
189 mv ${TMP_DIR}/initrd.img.gz ${BOOT_DIR}/kernel/initrd.img.gz
190 echo " OK"