Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add febootstrap-supermin-helper --copy-kernel option.

Because libvirt wants to set an SELinux label on the kernel, we can't
just symlink to it (because we don't want to change the SELinux label
on the kernel in /boot, and in any case it's owned by root so we
cannot).

Add the --copy-kernel option so that libguestfs can indicate that it
wants to copy the kernel instead of symlinking it.
  • Loading branch information...
commit 170b4bff109db3b1b41411bbd2be97259470452a 1 parent 22d69a8
rwmjones rwmjones authored
7 helper/febootstrap-supermin-helper.pod
Source Rendered
@@ -77,6 +77,13 @@ host_cpu and the UID of the current user are included in the checksum.
77 77
78 78 =back
79 79
  80 +=item B<--copy-kernel>
  81 +
  82 +Copy the kernel instead of symlinking to the kernel in C</boot>.
  83 +
  84 +This is fractionally slower, but is necessary if you want to change
  85 +the permissions or SELinux label on the kernel.
  86 +
80 87 =item B<-k file>
81 88
82 89 =item B<--kmods file>
1  helper/helper.h
@@ -50,6 +50,7 @@ struct writer {
50 50 /* main.c */
51 51 extern struct timeval start_t;
52 52 extern int verbose;
  53 +extern int copy_kernel;
53 54
54 55 /* appliance.c */
55 56 extern void create_appliance (const char *hostcpu, char **inputs, int nr_inputs, const char *whitelist, const char *modpath, const char *initrd, const char *appliance, struct writer *writer);
64 helper/kernel.c
@@ -21,6 +21,7 @@
21 21 #include <stdio.h>
22 22 #include <stdlib.h>
23 23 #include <string.h>
  24 +#include <fcntl.h>
24 25 #include <fnmatch.h>
25 26 #include <unistd.h>
26 27 #include <errno.h>
@@ -28,9 +29,14 @@
28 29
29 30 #include "error.h"
30 31 #include "xvasprintf.h"
  32 +#include "full-write.h"
31 33
32 34 #include "helper.h"
33 35
  36 +#ifndef O_CLOEXEC
  37 +#define O_CLOEXEC 0
  38 +#endif
  39 +
34 40 /* Directory containing candidate kernels. We could make this
35 41 * configurable at some point.
36 42 */
@@ -39,6 +45,7 @@
39 45
40 46 static char* get_kernel_version (char* filename);
41 47 static const char *create_kernel_from_env (const char *hostcpu, const char *kernel, const char *kernel_env, const char *modpath_env);
  48 +static void copy_or_symlink_kernel (const char *from, const char *to);
42 49
43 50 static char *
44 51 get_modpath (const char *kernel_name)
@@ -104,7 +111,7 @@ has_modpath (const char *kernel_name)
104 111 }
105 112
106 113 /* Create the kernel. This chooses an appropriate kernel and makes a
107   - * symlink to it.
  114 + * symlink to it (or copies it if --copy-kernel was passed).
108 115 *
109 116 * Look for the most recent kernel named vmlinuz-*.<arch>* which has a
110 117 * corresponding directory in /lib/modules/. If the architecture is
@@ -157,13 +164,7 @@ create_kernel (const char *hostcpu, const char *kernel)
157 164 if (kernel) {
158 165 /* Choose the first candidate. */
159 166 char *tmp = xasprintf (KERNELDIR "/%s", candidates[0]);
160   -
161   - if (verbose >= 2)
162   - fprintf (stderr, "creating symlink %s -> %s\n", kernel, tmp);
163   -
164   - if (symlink (tmp, kernel) == -1)
165   - error (EXIT_FAILURE, errno, "symlink kernel");
166   -
  167 + copy_or_symlink_kernel (tmp, kernel);
167 168 free (tmp);
168 169 }
169 170
@@ -231,15 +232,50 @@ create_kernel_from_env (const char *hostcpu, const char *kernel,
231 232 }
232 233
233 234 /* Create the symlink. */
234   - if (kernel) {
235   - if (verbose >= 2)
236   - fprintf (stderr, "creating symlink %s -> %s\n", kernel_env, kernel);
  235 + if (kernel)
  236 + copy_or_symlink_kernel (kernel_env, kernel);
  237 +
  238 + return modpath_env;
  239 +}
  240 +
  241 +static void
  242 +copy_or_symlink_kernel (const char *from, const char *to)
  243 +{
  244 + int fd1, fd2;
  245 + char buf[BUFSIZ];
  246 + ssize_t r;
237 247
238   - if (symlink (kernel_env, kernel) == -1)
239   - error (EXIT_FAILURE, errno, "symlink kernel");
  248 + if (verbose >= 2)
  249 + fprintf (stderr, "%s kernel %s -> %s\n",
  250 + !copy_kernel ? "symlink" : "copy", from, to);
  251 +
  252 + if (!copy_kernel) {
  253 + if (symlink (from, to) == -1)
  254 + error (EXIT_FAILURE, errno, "creating kernel symlink %s %s", from, to);
240 255 }
  256 + else {
  257 + fd1 = open (from, O_RDONLY | O_CLOEXEC);
  258 + if (fd1 == -1)
  259 + error (EXIT_FAILURE, errno, "open: %s", from);
241 260
242   - return modpath_env;
  261 + fd2 = open (to, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0644);
  262 + if (fd2 == -1)
  263 + error (EXIT_FAILURE, errno, "open: %s", to);
  264 +
  265 + while ((r = read (fd1, buf, sizeof buf)) > 0) {
  266 + if (full_write (fd2, buf, r) != r)
  267 + error (EXIT_FAILURE, errno, "write: %s", to);
  268 + }
  269 +
  270 + if (r == -1)
  271 + error (EXIT_FAILURE, errno, "read: %s", from);
  272 +
  273 + if (close (fd1) == -1)
  274 + error (EXIT_FAILURE, errno, "close: %s", from);
  275 +
  276 + if (close (fd2) == -1)
  277 + error (EXIT_FAILURE, errno, "close: %s", to);
  278 + }
243 279 }
244 280
245 281 /* Read an unsigned little endian short at a specified offset in a file.
17 helper/main.c
@@ -38,12 +38,14 @@
38 38
39 39 struct timeval start_t;
40 40 int verbose = 0;
  41 +int copy_kernel = 0;
41 42
42 43 enum { HELP_OPTION = CHAR_MAX + 1 };
43 44
44 45 static const char *options = "f:g:k:u:vV";
45 46 static const struct option long_options[] = {
46 47 { "help", 0, 0, HELP_OPTION },
  48 + { "copy-kernel", 0, 0, 0 },
47 49 { "format", required_argument, 0, 'f' },
48 50 { "group", 0, 0, 'g' },
49 51 { "kmods", required_argument, 0, 'k' },
@@ -79,6 +81,8 @@ usage (FILE *f, const char *progname)
79 81 " Display this help text and exit.\n"
80 82 " -f cpio|ext2|checksum | --format cpio|ext2|checksum\n"
81 83 " Specify output format (default: cpio).\n"
  84 + " --copy-kernel\n"
  85 + " Copy the kernel instead of symlinking to it.\n"
82 86 " -u user\n"
83 87 " The user name or uid the appliance will run as. Use of this\n"
84 88 " option requires root privileges.\n"
@@ -164,7 +168,8 @@ main (int argc, char *argv[])
164 168
165 169 /* Command line arguments. */
166 170 for (;;) {
167   - int c = getopt_long (argc, argv, options, long_options, NULL);
  171 + int option_index;
  172 + int c = getopt_long (argc, argv, options, long_options, &option_index);
168 173 if (c == -1) break;
169 174
170 175 switch (c) {
@@ -172,6 +177,16 @@ main (int argc, char *argv[])
172 177 usage (stdout, argv[0]);
173 178 exit (EXIT_SUCCESS);
174 179
  180 + case 0: /* options which are long only */
  181 + if (strcmp (long_options[option_index].name, "copy-kernel") == 0) {
  182 + copy_kernel = 1;
  183 + } else {
  184 + fprintf (stderr, "%s: unknown long option: %s (%d)\n",
  185 + argv[0], long_options[option_index].name, option_index);
  186 + exit (EXIT_FAILURE);
  187 + }
  188 + break;
  189 +
175 190 case 'f':
176 191 format = optarg;
177 192 break;

0 comments on commit 170b4bf

Please sign in to comment.
Something went wrong with that request. Please try again.