summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2010-12-12 10:40:57 +0000
committerRichard W.M. Jones <rjones@redhat.com>2010-12-12 20:27:56 +0000
commit85db2a664c820e01a02ddc3b33b3da26fe05dc5b (patch)
treec9a6aadef662dc5e4b0ccb8d0b95dbe6461086a5
parent5989c6746ae10b1da2a15dbefc3cf360a02e7a08 (diff)
downloadfebootstrap-85db2a664c820e01a02ddc3b33b3da26fe05dc5b.tar.gz
febootstrap-85db2a664c820e01a02ddc3b33b3da26fe05dc5b.tar.xz
febootstrap-85db2a664c820e01a02ddc3b33b3da26fe05dc5b.zip
helper: Add support for ArchLinux kernels.
ArchLinux doesn't use the ordinary Linux kernel naming scheme. (Thanks Thomas S Hatch for helping to diagnose the issue)
-rw-r--r--helper/kernel.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/helper/kernel.c b/helper/kernel.c
index 0903805..adee8c2 100644
--- a/helper/kernel.c
+++ b/helper/kernel.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <fnmatch.h>
#include <unistd.h>
#include <errno.h>
@@ -77,6 +78,8 @@ has_modpath (const char *kernel_name)
}
}
+static char *create_kernel_archlinux (const char *hostcpu, const char *kernel);
+
/* Create the kernel. This chooses an appropriate kernel and makes a
* symlink to it.
*
@@ -96,6 +99,10 @@ create_kernel (const char *hostcpu, const char *kernel)
{
char **all_files = read_dir (KERNELDIR);
+ /* In ArchLinux, kernel is always named /boot/vmlinuz26. */
+ if (access ("/boot/vmlinuz26", F_OK) == 0)
+ return create_kernel_archlinux (hostcpu, kernel);
+
/* In original: ls -1dvr /boot/vmlinuz-*.$arch* 2>/dev/null | grep -v xen */
const char *patt;
if (hostcpu[0] == 'i' && hostcpu[2] == '8' && hostcpu[3] == '6' &&
@@ -148,3 +155,56 @@ create_kernel (const char *hostcpu, const char *kernel)
"febootstrap use, you shouldn't boot the Xen guest with it).\n");
exit (EXIT_FAILURE);
}
+
+/* In ArchLinux, kernel is always named /boot/vmlinuz26, and we have
+ * to use the 'file' command to work out what version it is.
+ */
+static char *
+create_kernel_archlinux (const char *hostcpu, const char *kernel)
+{
+ const char *file_cmd = "file /boot/vmlinuz26 | awk '{print $9}'";
+ FILE *pp;
+ char modversion[256];
+ char *modpath;
+ size_t len;
+
+ pp = popen (file_cmd, "r");
+ if (pp == NULL) {
+ error:
+ fprintf (stderr, "febootstrap-supermin-helper: %s: command failed\n",
+ file_cmd);
+ exit (EXIT_FAILURE);
+ }
+
+ if (fgets (modversion, sizeof modversion, pp) == NULL)
+ goto error;
+
+ if (pclose (pp) == -1)
+ goto error;
+
+ /* Chomp final \n */
+ len = strlen (modversion);
+ if (len > 0 && modversion[len-1] == '\n') {
+ modversion[len-1] = '\0';
+ len--;
+ }
+
+ /* Generate module path. */
+ modpath = xasprintf (MODULESDIR "/%s", modversion);
+
+ /* Check module path is a directory. */
+ if (!isdir (modpath)) {
+ fprintf (stderr, "febootstrap-supermin-helper: /boot/vmlinuz26 kernel exists but %s is not a valid module path\n",
+ modpath);
+ exit (EXIT_FAILURE);
+ }
+
+ if (kernel) {
+ /* Symlink from kernel to /boot/vmlinuz26. */
+ if (symlink ("/boot/vmlinuz26", kernel) == -1)
+ error (EXIT_FAILURE, errno, "symlink kernel");
+ }
+
+ /* Return module path. */
+ return modpath;
+}