Adding --symlink to fix bug 98716
[genkernel.git] / genkernel
1 #!/bin/bash
2 # Genkernel v3
3
4 PATH="/bin:/usr/bin:/sbin:/usr/sbin"
5 GK_V='3.2.2'
6
7 TEMP='/var/tmp/genkernel'
8 TODEBUGCACHE=1 # Until an error occurs or DEBUGFILE is fully qualified.
9
10 small_die() {
11   echo $1
12   exit 1
13 }
14
15 source /etc/genkernel.conf || small_die "Could not read /etc/genkernel.conf"
16 source ${GK_BIN}/gen_funcs.sh || small_die "Could not read ${GK_BIN}/gen_funcs.sh"
17 source ${GK_BIN}/gen_cmdline.sh || gen_die "Could not read ${GK_BIN}/gen_cmdline.sh"
18 source ${GK_BIN}/gen_arch.sh || gen_die "Could not read ${GK_BIN}/gen_arch.sh"
19 source ${GK_BIN}/gen_determineargs.sh || gen_die "Could not read ${GK_BIN}/gen_determineargs.sh"
20 source ${GK_BIN}/gen_compile.sh || gen_die "Could not read ${GK_BIN}/gen_compile.sh"
21 source ${GK_BIN}/gen_configkernel.sh || gen_die "Could not read ${GK_BIN}/gen_configkernel.sh"
22 source ${GK_BIN}/gen_initrd.sh || gen_die "Could not read ${GK_BIN}/gen_initrd.sh"
23 source ${GK_BIN}/gen_initramfs.sh || gen_die "Could not read ${GK_BIN}/gen_initramfs.sh"
24 source ${GK_BIN}/gen_moddeps.sh || gen_die "Could not read ${GK_BIN}/gen_moddeps.sh"
25 source ${GK_BIN}/gen_package.sh || gen_die "Could not read ${GK_BIN}/gen_package.sh"
26 source ${GK_BIN}/gen_bootloader.sh || gen_die "Could not read ${GK_BIN}/gen_bootloader.sh"
27
28 tmp=${TMPDIR-/tmp}
29 tmp=${tmp}/genkernel.$RANDOM.$RANDOM.$RANDOM.$$
30
31 cleanup(){
32     if [ -n "$tmp" -a -d "$tmp" ]; then
33         echo "Removing $tmp"
34         rm -rf "$tmp"
35     fi
36     exit 1
37 }
38 trap cleanup SIGHUP SIGQUIT SIGINT SIGTERM SIGKILL
39 BUILD_KERNEL=0
40 BUILD_INITRD=0
41 BUILD_MODULES=0
42
43 # Parse all command line options...
44 Options=$* # Save for later
45 while [ $# -gt 0 ]
46 do
47         Option=$1; shift
48         parse_cmdline $Option
49 done
50
51 # Check if no action is specified...
52 if [ "${BUILD_KERNEL}" -eq 0 -a "${BUILD_INITRD}" -eq 0 ]
53 then
54         usage
55         exit 1
56 fi
57
58 clear_log
59 NORMAL=${GOOD} print_info 1 "Gentoo Linux Genkernel; Version ${GK_V}${NORMAL}"
60 print_info 1 "Running with options: ${Options}"
61 echo
62
63 # Set ${ARCH}
64 get_official_arch
65
66 # Read arch-specific config
67 source ${ARCH_CONFIG} || gen_die "Could not read ${ARCH_CONFIG}"
68 source ${GK_SHARE}/${ARCH}/modules_load || gen_die "Could not read ${GK_SHARE}/${ARCH}/modules_load"
69
70 # Merge modules_load from config
71 for group_modules in ${!AMODULES_*}; do
72         group="$(echo $group_modules | cut -d_ -f2)"
73         eval cmodules="\$$group_modules"
74         eval MODULES_${group}=\"\${MODULES_${group}} ${cmodules}\"
75         print_info 1 "<config> Merged AMODULES_${group}:'${cmodules}' into MODULES_${group}"
76 done
77
78 [ ! -f "${TEMP}" ] && mkdir -p "${TEMP}"
79 [ ! -f "${CACHE_DIR}" ] && mkdir -p "${CACHE_DIR}"
80
81 # Based on genkernel.conf, arch-specific configs, and commandline options,
82 # get the real arguments for usage...
83
84 determine_real_args
85 dump_debugcache
86
87 NORMAL=${BOLD} print_info 1 "Linux Kernel ${BOLD}${KV}${NORMAL} for ${BOLD}${ARCH}${NORMAL}..."
88
89 if [ "${BUILD_INITRD}" -ne '0' ]
90 then
91         if ! has_loop
92         then
93                 modprobe loop 2>/dev/null
94                 sleep 3
95                 if ! has_loop
96                 then
97                         print_error 1 'The build-host kernel does not appear to have loop device support.'
98                         print_error 1 'Please load loop support before running genkernel!'
99                         gen_die 'Load loop support!'
100                 else
101                         print_info 1 'loop: "loop" module loaded successfully...'
102                 fi
103         fi
104 fi
105
106 # Check /boot is mounted
107 if isTrue ${CMD_NOINSTALL}
108 then
109         isTrue ${MOUNTBOOT} && print_info 2 'Skipping automatic mount of boot'
110 else
111         if ! egrep -q ' /boot ' /proc/mounts
112         then
113                 if egrep -q '^[^#].+    /boot   ' /etc/fstab
114                 then
115                         if isTrue ${MOUNTBOOT}
116                         then
117                                 if ! mount /boot
118                                 then
119                                         print_warning 1 "${BOLD}WARNING${NORMAL}: Failed to mount /boot!"
120                                         echo
121                                 else
122                                         print_info 1 'mount: /boot mounted successfully!'
123                                 fi
124                         else
125                                 print_warning 1 "${BOLD}WARNING${NORMAL}: No mounted /boot partition detected!"
126                                 print_warning 1 '         Run ``mount /boot`` to mount it!'
127                                 echo
128                         fi
129                 fi
130         elif isBootRO
131         then
132                 if isTrue ${MOUNTBOOT}
133                 then
134                         if ! mount -o remount,rw /boot
135                         then
136                                 print_warning 1 "${BOLD}WARNING${NORMAL}: Failed to remount /boot RW!"
137                                 echo
138                         else
139                                 print_info 1 "mount: /boot remounted read/write successfully!"
140                                 BOOTRW=1
141                         fi
142                 fi
143         fi
144 fi
145
146 # Check whether another Genkernel is running
147 GENPIDS="`ps -C genkernel --no-headers -o pid | wc -l`"
148 if [ "${GENPIDS}" -gt '3' ]
149 then
150         [ "${GENPIDS}" -gt '4' ] && EX='s'
151         print_warning 1 "${BOLD}WARNING${NORMAL}: Another Genkernel instance is running under"
152         print_warning 1 "         process ID${EX} " 0
153         GENPIDS=`ps -C genkernel --no-headers -o pid`
154         echo -n "${GENPIDS}" | sed -e "s/$$//; s/ /, /g"
155         echo 'halting...'
156         echo
157         print_warning 1 'Running multiple genkernels on the same source tree will cause data loss!'
158         print_info 1 "Press ^C to halt; ^D to continue [ ${BOLD}if${NORMAL} you know what you're doing! ]"
159         cat
160         echo
161         CTEMP="${TEMP}"
162         TEMP=${TMPDIR-/tmp}
163         TEMP=${TEMP}/genkernel.$RANDOM.$RANDOM.$RANDOM.$$
164         print_info 1 'thread: Running multiple genkernels may cause problems!'
165         print_info 1 "thread: Temporary files reallocated to ${TEMP}..."
166         echo
167 fi
168
169
170 KERNCACHE_IS_VALID=0
171 if [ "${KERNCACHE}" != "" ] 
172 then
173     gen_kerncache_is_valid
174 fi
175
176 if [ ${BUILD_KERNEL} -eq 1 -a "${KERNCACHE_IS_VALID}" == "0" ]
177 then
178         # Configure kernel
179         config_kernel
180         
181         # KV may have changed due to the configuration
182         get_KV
183
184         # Make deps
185         compile_dep
186
187         # Make prepare [2.6]
188         if [ "${ARCH_HAVENOPREPARE}" = '' ]
189         then
190                 [ "${VER}" -gt '2' ] || [ "${VER}" -eq '2' -a "${PAT}" -ge '6' ] && compile_generic prepare kernel
191         fi
192
193         # Compile kernel
194         [ "${GENERATE_Z_IMAGE}" = '' ] && compile_kernel
195
196         # Compile modules
197         if [ ${BUILD_MODULES} -eq 1 ]
198         then
199                 compile_modules
200         fi
201
202         if [ ${SAVE_CONFIG} -eq 1 ]
203         then
204                 print_info 1 "Copying config for successful build to /etc/kernels/kernel-config-${ARCH}-${KV}"
205                 [ ! -e '/etc/kernels' ] && mkdir -p /etc/kernels
206                 cp "${KERNEL_DIR}/.config" "/etc/kernels/kernel-config-${ARCH}-${KV}"
207         fi
208         [ "${KERNCACHE}" != "" ] && gen_kerncache
209 fi
210
211 if ! isTrue "${CMD_NOINSTALL}"
212 then
213         if [ "${KERNCACHE}" != "" -a "${KERNCACHE_IS_VALID}" != "0" ] 
214         then
215                 gen_kerncache_extract_kernel
216         fi
217 fi
218
219 if [ "${KERNCACHE}" != "" -a "${KERNCACHE_IS_VALID}" != "0" ] 
220 then
221         gen_kerncache_extract_modules
222 fi
223
224 # Run callback
225 if [ "${CMD_CALLBACK}" != "" ]
226 then
227         print_info 1 "" 1 0
228         print_info 1 "Preparing to run callback: \"${CMD_CALLBACK}\"" 0
229
230         CALLBACK_ESCAPE=0
231         CALLBACK_COUNT=0
232
233         trap "CALLBACK_ESCAPE=1" TERM KILL INT QUIT ABRT
234         while [[ ${CALLBACK_ESCAPE} -eq 0 && ${CALLBACK_COUNT} -lt 5 ]]
235         do
236                 sleep 1; echo -n '.';
237                 let CALLBACK_COUNT=${CALLBACK_COUNT}+1
238         done
239
240         if [ "${CALLBACK_ESCAPE}" -eq 0 ]
241         then
242                 echo
243                 echo
244                 eval ${CMD_CALLBACK} | tee -a ${DEBUGFILE}
245                 CMD_STATUS="${PIPESTATUS[0]}"
246                 echo
247                 print_info 1 "<<< Callback exit status: ${CMD_STATUS}"
248                 [ "${CMD_STATUS}" -ne 0 ] && gen_die '--callback failed!'
249         else
250                 echo
251                 print_info 1 ">>> Callback cancelled..."
252         fi
253         trap - TERM KILL INT QUIT ABRT
254         print_info 1 "" 1 0
255 fi
256
257 if [ "${BUILD_INITRD}" -eq '1' ]
258 then
259         # Only compile insmod if we're installing modules onto the initrd
260         if [ "${NOINITRDMODULES}" = '' ]
261         then
262                 if [ "${PAT}" -gt '4' ]
263                 then
264                         # Compile module-init-tools
265                         compile_module_init_tools
266                 else
267                         compile_modutils
268                 fi
269         fi
270         
271         [ "${DISKLABEL}" -eq '1' ] && compile_e2fsprogs
272
273         if [ "${PAT}" -gt '4' -a "${UDEV}" -eq '1' ] 
274         then
275                 compile_udev 
276         else
277                 DEVFS=1
278                 UDEV=0
279                 compile_devfsd
280         fi
281
282         if [ "${PAT}" -gt '4' -a  "${CMD_BOOTSPLASH}" != '1' ]
283         then
284             if [ "${BUSYBOX}" -eq '1' ]
285             then
286                 # Compile Busybox
287                 compile_busybox
288             fi
289             
290             # Compile initramfs
291             create_initramfs
292         else
293             # Create initrd
294             compile_busybox
295             create_initrd
296         fi
297 else
298         print_info 1 'initrd: Not building since only the kernel was requested...'
299 fi
300
301 # Pegasos fix
302 if [ "${GENERATE_Z_IMAGE}" != '' ]
303 then
304         # Compile kernel, intergrating the initrd into it for Pegasos
305         compile_kernel
306 fi
307
308 [ "${MINKERNPACKAGE}" != '' ] && gen_minkernpackage
309 [ "${MODULESPACKAGE}" != '' ] && gen_modulespackage
310
311 # Clean up...
312 [ -n "${CTEMP}" ] && rm -rf "${TEMP}"
313
314 if [ "${BUILD_KERNEL}" -eq '1' ]
315 then
316         set_bootloader
317         print_info 1 ''
318         print_info 1 "Kernel compiled successfully!"
319         print_info 1 ''
320         print_info 1 'Required Kernel Parameters:'
321         if [ "${BUILD_INITRD}" -eq '0' ]
322         then
323                 print_info 1 '    root=/dev/$ROOT'
324                 print_info 1 '    [ And "vga=0x317 splash=verbose" if you use a framebuffer ]'
325                 print_info 1 ''
326                 print_info 1 '    Where $ROOT is the device node for your root partition as the'
327                 print_info 1 '    one specified in /etc/fstab'
328         elif [ "${PAT}" -gt '4' -a  "${CMD_BOOTSPLASH}" != '1' ]
329         then
330                 print_info 1 '    real_root=/dev/$ROOT'
331                 print_info 1 '    [ And "vga=0x317 splash=verbose" if you use a framebuffer ]'
332                 print_info 1 ''
333                 print_info 1 '    Where $ROOT is the device node for your root partition as the'
334                 print_info 1 '    one specified in /etc/fstab'
335                 print_info 1 ''
336                 print_info 1 "If you require Genkernel's hardware detection features; you MUST"
337                 print_info 1 'tell your bootloader to use the provided initrd file. Otherwise;'
338                 print_info 1 'substitute the root argument for the real_root argument if you are'
339                 print_info 1 'not planning to use the initrd...'
340         else    
341                 print_info 1 '    root=/dev/ram0 real_root=/dev/$ROOT init=/linuxrc'
342                 [ "${INITRD_SIZE}" -ge 4096 ] && print_info 1 "    ramdisk_size=8192"
343                 [ "${LVM2}" -eq '1' ] && print_info 1 'add "dolvm2" for lvm2 support at boot time'
344                 [ "${EVMS2}" -eq '1' ] && print_info 1 'add "doevms" for evms support at boot time'
345                 [ "${DMRAID}" -eq '1' ] && print_info 1 'add "dodmraid" for dmraid support at boot time'
346                 [ "${DMRAID}" -eq '1' ] && print_info 1 'or "dodmraid=<additional options>"'
347                 print_info 1 '    [ And "vga=0x317 splash=verbose" if you use a framebuffer ]'
348                 print_info 1 ''
349                 print_info 1 '    Where $ROOT is the device node for your root partition as the'
350                 print_info 1 '    one specified in /etc/fstab'
351                 print_info 1 ''
352                 print_info 1 "If you require Genkernel's hardware detection features; you MUST"
353                 print_info 1 'tell your bootloader to use the provided initrd file. Otherwise;'
354                 print_info 1 'substitute the root argument for the real_root argument if you are'
355                 print_info 1 'not planning to use the initrd...'
356         fi
357 else
358         print_info 1 ''
359         if [ "${PAT}" -gt '4' -a  "${CMD_BOOTSPLASH}" != '1' ]
360         then
361             print_info 1 'initramfs compiled successfully!'
362         else
363             print_info 1 'initrd compiled successfully!'
364         fi
365 fi
366
367 if [ "${CMD_NOINSTALL}" != '1' -a "${SYMLINK}" = '1' ]
368 then 
369     print_info 1 ''
370     print_info 1 'Creating symlinks'
371     
372     
373     print_info 1 '          creating kernel name symlink!'
374     if [ -e /boot/kernel-${KNAME}-${ARCH}-${KV} ]
375     then
376         /bin/rm /boot/kernel
377         ln -s /boot/kernel-${KNAME}-${ARCH}-${KV} /boot/kernel
378         ret=$?
379         [ ${ret} = '1' ] && print_error 1 'kernel link failed'
380     fi
381     
382     if [ "${PAT}" -gt '4' -a  "${CMD_BOOTSPLASH}" != '1' ]
383     then
384         print_info 1 '      creating initramfs name symlink!'
385         if [ -e /boot/initramfs-${KNAME}-${ARCH}-${KV} ]
386         then
387             /bin/rm /boot/initramfs
388             ln -s /boot/initramfs-${KNAME}-${ARCH}-${KV} /boot/initramfs
389             ret=$?
390             [ ${ret} = '1' ] && print_error 1 'initramfs link failed'
391         fi
392     else
393         print_info 1 '      creating initrd name symlink!'
394         if [ -e /boot/initrd-${KNAME}-${ARCH}-${KV} ]
395         then
396             /bin/rm /boot/initrd
397             ln -s /boot/initrd-${KNAME}-${ARCH}-${KV} /boot/initrd
398             ret=$?
399             [ ${ret} = '1' ] && print_error 1 'initrd link failed'
400         fi
401     fi
402 fi
403
404
405 [ "${BOOTRW}" != '' ] && mount -o remount,ro /boot
406
407 print_info 1 ''
408 print_info 1 'Do NOT report kernel bugs as genkernel bugs unless your bug'
409 print_info 1 'is about the default genkernel configuration...'
410 print_info 1 ''
411 print_info 1 'Make sure you have the latest genkernel before reporting bugs.'