Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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
rwmjones committed Aug 31, 2012
1 parent 22d69a8 commit 170b4bf
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 15 deletions.
7 changes: 7 additions & 0 deletions helper/febootstrap-supermin-helper.pod
Expand Up @@ -77,6 +77,13 @@ host_cpu and the UID of the current user are included in the checksum.

=back

=item B<--copy-kernel>

Copy the kernel instead of symlinking to the kernel in C</boot>.

This is fractionally slower, but is necessary if you want to change
the permissions or SELinux label on the kernel.

=item B<-k file>

=item B<--kmods file>
Expand Down
1 change: 1 addition & 0 deletions helper/helper.h
Expand Up @@ -50,6 +50,7 @@ struct writer {
/* main.c */
extern struct timeval start_t;
extern int verbose;
extern int copy_kernel;

/* appliance.c */
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);
Expand Down
64 changes: 50 additions & 14 deletions helper/kernel.c
Expand Up @@ -21,16 +21,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <unistd.h>
#include <errno.h>
#include <sys/utsname.h>

#include "error.h"
#include "xvasprintf.h"
#include "full-write.h"

#include "helper.h"

#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif

/* Directory containing candidate kernels. We could make this
* configurable at some point.
*/
Expand All @@ -39,6 +45,7 @@

static char* get_kernel_version (char* filename);
static const char *create_kernel_from_env (const char *hostcpu, const char *kernel, const char *kernel_env, const char *modpath_env);
static void copy_or_symlink_kernel (const char *from, const char *to);

static char *
get_modpath (const char *kernel_name)
Expand Down Expand Up @@ -104,7 +111,7 @@ has_modpath (const char *kernel_name)
}

/* Create the kernel. This chooses an appropriate kernel and makes a
* symlink to it.
* symlink to it (or copies it if --copy-kernel was passed).
*
* Look for the most recent kernel named vmlinuz-*.<arch>* which has a
* corresponding directory in /lib/modules/. If the architecture is
Expand Down Expand Up @@ -157,13 +164,7 @@ create_kernel (const char *hostcpu, const char *kernel)
if (kernel) {
/* Choose the first candidate. */
char *tmp = xasprintf (KERNELDIR "/%s", candidates[0]);

if (verbose >= 2)
fprintf (stderr, "creating symlink %s -> %s\n", kernel, tmp);

if (symlink (tmp, kernel) == -1)
error (EXIT_FAILURE, errno, "symlink kernel");

copy_or_symlink_kernel (tmp, kernel);
free (tmp);
}

Expand Down Expand Up @@ -231,15 +232,50 @@ create_kernel_from_env (const char *hostcpu, const char *kernel,
}

/* Create the symlink. */
if (kernel) {
if (verbose >= 2)
fprintf (stderr, "creating symlink %s -> %s\n", kernel_env, kernel);
if (kernel)
copy_or_symlink_kernel (kernel_env, kernel);

return modpath_env;
}

static void
copy_or_symlink_kernel (const char *from, const char *to)
{
int fd1, fd2;
char buf[BUFSIZ];
ssize_t r;

if (symlink (kernel_env, kernel) == -1)
error (EXIT_FAILURE, errno, "symlink kernel");
if (verbose >= 2)
fprintf (stderr, "%s kernel %s -> %s\n",
!copy_kernel ? "symlink" : "copy", from, to);

if (!copy_kernel) {
if (symlink (from, to) == -1)
error (EXIT_FAILURE, errno, "creating kernel symlink %s %s", from, to);
}
else {
fd1 = open (from, O_RDONLY | O_CLOEXEC);
if (fd1 == -1)
error (EXIT_FAILURE, errno, "open: %s", from);

return modpath_env;
fd2 = open (to, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0644);
if (fd2 == -1)
error (EXIT_FAILURE, errno, "open: %s", to);

while ((r = read (fd1, buf, sizeof buf)) > 0) {
if (full_write (fd2, buf, r) != r)
error (EXIT_FAILURE, errno, "write: %s", to);
}

if (r == -1)
error (EXIT_FAILURE, errno, "read: %s", from);

if (close (fd1) == -1)
error (EXIT_FAILURE, errno, "close: %s", from);

if (close (fd2) == -1)
error (EXIT_FAILURE, errno, "close: %s", to);
}
}

/* Read an unsigned little endian short at a specified offset in a file.
Expand Down
17 changes: 16 additions & 1 deletion helper/main.c
Expand Up @@ -38,12 +38,14 @@

struct timeval start_t;
int verbose = 0;
int copy_kernel = 0;

enum { HELP_OPTION = CHAR_MAX + 1 };

static const char *options = "f:g:k:u:vV";
static const struct option long_options[] = {
{ "help", 0, 0, HELP_OPTION },
{ "copy-kernel", 0, 0, 0 },
{ "format", required_argument, 0, 'f' },
{ "group", 0, 0, 'g' },
{ "kmods", required_argument, 0, 'k' },
Expand Down Expand Up @@ -79,6 +81,8 @@ usage (FILE *f, const char *progname)
" Display this help text and exit.\n"
" -f cpio|ext2|checksum | --format cpio|ext2|checksum\n"
" Specify output format (default: cpio).\n"
" --copy-kernel\n"
" Copy the kernel instead of symlinking to it.\n"
" -u user\n"
" The user name or uid the appliance will run as. Use of this\n"
" option requires root privileges.\n"
Expand Down Expand Up @@ -164,14 +168,25 @@ main (int argc, char *argv[])

/* Command line arguments. */
for (;;) {
int c = getopt_long (argc, argv, options, long_options, NULL);
int option_index;
int c = getopt_long (argc, argv, options, long_options, &option_index);
if (c == -1) break;

switch (c) {
case HELP_OPTION:
usage (stdout, argv[0]);
exit (EXIT_SUCCESS);

case 0: /* options which are long only */
if (strcmp (long_options[option_index].name, "copy-kernel") == 0) {
copy_kernel = 1;
} else {
fprintf (stderr, "%s: unknown long option: %s (%d)\n",
argv[0], long_options[option_index].name, option_index);
exit (EXIT_FAILURE);
}
break;

case 'f':
format = optarg;
break;
Expand Down

0 comments on commit 170b4bf

Please sign in to comment.