mount{,_ufs}(8): Remove unnecessary code to prevent warnings.
[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 check_dirs()
44 {
45         for _dir; do
46                 [ -d "${_dir}" ] || {
47                         echo "Directory '${_dir}' does not exist"
48                         return 1
49                 }
50         done
51         return 0
52 }
53
54 # Calculate the total size of the given directory, taking care of the
55 # hard links.
56 calc_size()
57 {
58         find "$1" -ls | \
59             awk '{ print $7,$1 }' | \
60             sort -n -k 2 | \
61             uniq -f 1 | \
62             awk '{ sum+=$1 } END { print sum }'  # byte
63 }
64
65 calc_initrd_size()
66 {
67         echo "Contents directories:" >&2
68         isize=0
69         for dir in ${CONTENT_DIRS}; do
70                 csize=$(calc_size ${dir})
71                 echo "* ${dir}: ${csize} bytes" >&2
72                 isize=$((${isize} + ${csize}))
73         done
74         # Round initrd size up by MB
75         isize_mb=$(echo "${isize}" | awk '
76             function ceil(x) {
77                 y = int(x);
78                 return (x>y ? y+1 : y);
79             }
80             {
81                 mb = $1/1024/1024;
82                 print ceil(mb);
83             }')
84         # Add additional 1 MB
85         echo $((${isize_mb} + 1))
86 }
87
88 create_vn()
89 {
90         local _vndev
91         _vndev=${TMP_DIR}/vndev.$$
92
93         if [ ! -d "$BUILD_DIR" ]; then
94                 mkdir -p $BUILD_DIR
95                 echo "Created build directory $BUILD_DIR"
96         fi
97         vnconfig -c -S ${INITRD_SIZE}m -Z -T vn ${TMP_DIR}/initrd.img \
98             > ${_vndev} || {
99                 echo "Failed to configure vn device"
100                 exit 1
101         }
102
103         VN_DEV=`cat ${_vndev} | cut -f 2 -d ' '`
104         rm ${_vndev}
105
106         echo "Configured $VN_DEV"
107         newfs -i 131072 -m 0 /dev/${VN_DEV}s0
108         echo "Formatted initrd image with UFS"
109         mount -t ufs /dev/${VN_DEV}s0 $BUILD_DIR
110         echo "Mounted initrd image on ${BUILD_DIR}"
111 }
112
113 destroy_vn()
114 {
115         umount /dev/${VN_DEV}s0
116         echo "Unmounted initrd image"
117         vnconfig -u $VN_DEV
118         echo "Unconfigured $VN_DEV"
119         rmdir ${BUILD_DIR}
120 }
121
122 make_hier()
123 {
124         for dir in ${INITRD_DIRS}; do
125                 mkdir -p ${BUILD_DIR}/${dir}
126         done
127         echo "Created directory structure"
128 }
129
130 copy_content()
131 {
132         for dir in ${CONTENT_DIRS}; do
133                 cpdup -o -u ${dir}/ ${BUILD_DIR}/ || {
134                         echo "Failed to copy ${dir} to ${BUILD_DIR}"
135                         exit 1
136                 }
137         done
138 }
139
140 print_info()
141 {
142         lt ${BUILD_DIR}
143         df -h ${BUILD_DIR}
144 }
145
146 usage()
147 {
148         echo "usage: ${0##*/} [-b bootdir] [-c contentsdir] [-t tmpdir]" \
149              "[-s size] [-S max_size]"
150         exit 2
151 }
152
153 args=`getopt b:c:s:S:t: $*`
154 test $? -ne 0 && usage
155
156 set -- $args
157 for i; do
158         case "$i" in
159         -b)     BOOT_DIR="$2"; shift; shift;;
160         -c)     CONTENT_DIRS="$2"; shift; shift;;
161         -s)     INITRD_SIZE="$2"; shift; shift;;
162         -S)     INITRD_SIZE_MAX="$2"; shift; shift;;
163         -t)     TMP_DIR="$2"; shift; shift;;
164         --)     shift; break;
165         esac
166 done
167
168 test ! -z "$1" && usage
169 check_dirs ${BOOT_DIR} ${CONTENT_DIRS} ${TMP_DIR} || usage
170
171 BUILD_DIR="${TMP_DIR}/initrd.$$"
172 INITRD_SIZE=${INITRD_SIZE%[mM]}  # MB
173 INITRD_SIZE_MAX=${INITRD_SIZE_MAX%[mM]}  # MB
174
175 CSIZE=$(calc_initrd_size)
176 echo "Required initrd image size: ${CSIZE} MB"
177 if [ -n "${INITRD_SIZE}" -a "${INITRD_SIZE}" != "0" ]; then
178         if [ ${CSIZE} -gt ${INITRD_SIZE} ]; then
179                 echo "Specified initrd size (${INITRD_SIZE} MB) too small"
180                 exit 1
181         fi
182 else
183         INITRD_SIZE=${CSIZE}
184 fi
185 echo "Initrd size: ${INITRD_SIZE} MB"
186
187 if [ -n "${INITRD_SIZE_MAX}" -a "${INITRD_SIZE_MAX}" != "0" ] && \
188    [ ${INITRD_SIZE} -gt ${INITRD_SIZE_MAX} ]; then
189         echo "Exceeded the specified maximum size (${INITRD_SIZE_MAX} MB)"
190         exit 1
191 fi
192
193 create_vn
194 copy_content
195 make_hier
196 print_info
197 destroy_vn
198
199 echo -n "Compressing ${TMP_DIR}/initrd.img ..."
200 gzip -9 ${TMP_DIR}/initrd.img
201 echo " OK"
202
203 DEST="${BOOT_DIR}/kernel/initrd.img.gz"
204 if [ -f "${DEST}" ]; then
205         echo -n "Backup ${DEST} ..."
206         mv ${DEST} ${DEST}.old
207         echo " OK (${DEST}.old)"
208 fi
209
210 echo -n "Copying ${TMP_DIR}/initrd.img.gz to ${DEST} ..."
211 mv ${TMP_DIR}/initrd.img.gz ${DEST}
212 echo " OK"