1 /* febootstrap-supermin-helper reimplementation in C.
2 * Copyright (C) 2009-2010 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include "xvasprintf.h"
32 /* Directory containing candidate kernels. We could make this
33 * configurable at some point.
35 #define KERNELDIR "/boot"
36 #define MODULESDIR "/lib/modules"
39 get_modpath (const char *kernel_name)
41 /* Ignore "vmlinuz-" at the beginning of the kernel name. */
42 const char *version = &kernel_name[8];
44 /* /lib/modules/<version> */
45 char *modpath = xasprintf (MODULESDIR "/%s", version);
54 /* kernel_name is "vmlinuz-*". Check if there is a corresponding
55 * module path in /lib/modules.
58 has_modpath (const char *kernel_name)
60 char *modpath = get_modpath (kernel_name);
63 fprintf (stderr, "checking modpath %s is a directory\n", modpath);
65 int r = isdir (modpath);
69 fprintf (stderr, "picked %s because modpath %s exists\n",
70 kernel_name, modpath);
80 /* Create the kernel. This chooses an appropriate kernel and makes a
83 * Look for the most recent kernel named vmlinuz-*.<arch>* which has a
84 * corresponding directory in /lib/modules/. If the architecture is
85 * x86, look for any x86 kernel.
87 * RHEL 5 didn't append the arch to the kernel name, so look for
88 * kernels without arch second.
90 * If no suitable kernel can be found, exit with an error.
92 * This function returns the module path (ie. /lib/modules/<version>).
95 create_kernel (const char *hostcpu, const char *kernel)
97 char **all_files = read_dir (KERNELDIR);
99 /* In original: ls -1dvr /boot/vmlinuz-*.$arch* 2>/dev/null | grep -v xen */
101 if (hostcpu[0] == 'i' && hostcpu[2] == '8' && hostcpu[3] == '6' &&
103 patt = "vmlinuz-*.i?86*";
105 patt = xasprintf ("vmlinuz-*.%s*", hostcpu);
108 candidates = filter_fnmatch (all_files, patt, FNM_NOESCAPE);
109 candidates = filter_notmatching_substring (candidates, "xen");
110 candidates = filter (candidates, has_modpath);
112 if (candidates[0] == NULL) {
113 /* In original: ls -1dvr /boot/vmlinuz-* 2>/dev/null | grep -v xen */
115 candidates = filter_fnmatch (all_files, patt, FNM_NOESCAPE);
116 candidates = filter_notmatching_substring (candidates, "xen");
117 candidates = filter (candidates, has_modpath);
119 if (candidates[0] == NULL)
123 sort (candidates, reverse_filevercmp);
126 /* Choose the first candidate. */
127 char *tmp = xasprintf (KERNELDIR "/%s", candidates[0]);
130 fprintf (stderr, "creating symlink %s -> %s\n", kernel, tmp);
132 if (symlink (tmp, kernel) == -1)
133 error (EXIT_FAILURE, errno, "symlink kernel");
138 return get_modpath (candidates[0]);
140 /* Print more diagnostics here than the old script did. */
143 "febootstrap-supermin-helper: failed to find a suitable kernel.\n"
144 "I looked for kernels in " KERNELDIR " and modules in " MODULESDIR
146 "If this is a Xen guest, and you only have Xen domU kernels\n"
147 "installed, try installing a fullvirt kernel (only for\n"
148 "febootstrap use, you shouldn't boot the Xen guest with it).\n");