diff options
-rw-r--r-- | helper/Makefile.am | 1 | ||||
-rw-r--r-- | helper/appliance.c | 274 | ||||
-rw-r--r-- | helper/cpio.c | 278 | ||||
-rw-r--r-- | helper/helper.h | 26 | ||||
-rw-r--r-- | helper/main.c | 3 |
5 files changed, 333 insertions, 249 deletions
diff --git a/helper/Makefile.am b/helper/Makefile.am index 1033837..9702bbe 100644 --- a/helper/Makefile.am +++ b/helper/Makefile.am @@ -23,6 +23,7 @@ bin_PROGRAMS = \ febootstrap_supermin_helper_SOURCES = \ helper.h \ appliance.c \ + cpio.c \ kernel.c \ main.c \ utils.c diff --git a/helper/appliance.c b/helper/appliance.c index c6defc0..b7a46c0 100644 --- a/helper/appliance.c +++ b/helper/appliance.c @@ -22,7 +22,6 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <limits.h> #include <fcntl.h> #include <errno.h> #include <dirent.h> @@ -32,32 +31,15 @@ #include "error.h" #include "fts_.h" -#include "full-write.h" #include "xalloc.h" #include "xvasprintf.h" #include "helper.h" -/* Buffer size used in copy operations throughout. Large for - * greatest efficiency. - */ -#define BUFFER_SIZE 65536 - -static void iterate_inputs (char **inputs, int nr_inputs); -static void iterate_input_directory (const char *dirname, int dirfd); -static void write_kernel_modules (const char *whitelist, const char *modpath); -static void write_hostfiles (const char *hostfiles_file); -static void write_to_fd (const void *buffer, size_t len); -static void write_file_to_fd (const char *filename); -static void write_file_len_to_fd (const char *filename, size_t len); -static void write_padding (size_t len); -static void cpio_append_fts_entry (FTSENT *entry); -static void cpio_append_stat (const char *filename, struct stat *); -static void cpio_append (const char *filename); -static void cpio_append_trailer (void); - -static int out_fd = -1; -static off_t out_offset = 0; +static void iterate_inputs (char **inputs, int nr_inputs, struct writer *); +static void iterate_input_directory (const char *dirname, int dirfd, struct writer *); +static void add_kernel_modules (const char *whitelist, const char *modpath, struct writer *); +static void add_hostfiles (const char *hostfiles_file, struct writer *); /* Create the appliance. * @@ -86,30 +68,24 @@ void create_appliance (char **inputs, int nr_inputs, const char *whitelist, const char *modpath, - const char *appliance) + const char *appliance, + struct writer *writer) { - out_fd = open (appliance, O_WRONLY | O_CREAT | O_TRUNC | O_NOCTTY, 0644); - if (out_fd == -1) - error (EXIT_FAILURE, errno, "open: %s", appliance); - out_offset = 0; + writer->wr_start (appliance); - iterate_inputs (inputs, nr_inputs); + iterate_inputs (inputs, nr_inputs, writer); /* Kernel modules (3). */ - write_kernel_modules (whitelist, modpath); - - cpio_append_trailer (); + add_kernel_modules (whitelist, modpath, writer); - /* Finish off and close output file. */ - if (close (out_fd) == -1) - error (EXIT_FAILURE, errno, "close: %s", appliance); + writer->wr_end (); } /* Iterate over the inputs to find out what they are, visiting * directories if specified. */ static void -iterate_inputs (char **inputs, int nr_inputs) +iterate_inputs (char **inputs, int nr_inputs, struct writer *writer) { int i; for (i = 0; i < nr_inputs; ++i) { @@ -126,16 +102,16 @@ iterate_inputs (char **inputs, int nr_inputs) /* Directory? */ if (S_ISDIR (statbuf.st_mode)) - iterate_input_directory (inputs[i], fd); + iterate_input_directory (inputs[i], fd, writer); else if (S_ISREG (statbuf.st_mode)) { /* Is it a cpio file? */ char buf[6]; if (read (fd, buf, 6) == 6 && memcmp (buf, "070701", 6) == 0) /* Yes, a cpio file. This is a skeleton appliance, case (1). */ - write_file_to_fd (inputs[i]); + writer->wr_cpio_file (inputs[i]); else /* No, must be hostfiles, case (2). */ - write_hostfiles (inputs[i]); + add_hostfiles (inputs[i], writer); } else error (EXIT_FAILURE, 0, "%s: input is not a regular file or directory", @@ -146,7 +122,7 @@ iterate_inputs (char **inputs, int nr_inputs) } static void -iterate_input_directory (const char *dirname, int dirfd) +iterate_input_directory (const char *dirname, int dirfd, struct writer *writer) { char path[PATH_MAX]; strcpy (path, dirname); @@ -165,7 +141,7 @@ iterate_input_directory (const char *dirname, int dirfd) continue; strcpy (&path[len], d->d_name); - iterate_inputs (inputs, 1); + iterate_inputs (inputs, 1, writer); } if (errno != 0) @@ -188,7 +164,8 @@ iterate_input_directory (const char *dirname, int dirfd) * whitelist_file may be NULL, to include ALL kernel modules. */ static void -write_kernel_modules (const char *whitelist_file, const char *modpath) +add_kernel_modules (const char *whitelist_file, const char *modpath, + struct writer *writer) { char **whitelist = NULL; if (whitelist_file != NULL) @@ -197,13 +174,13 @@ write_kernel_modules (const char *whitelist_file, const char *modpath) char *paths[2] = { (char *) modpath, NULL }; FTS *fts = fts_open (paths, FTS_COMFOLLOW|FTS_PHYSICAL, NULL); if (fts == NULL) - error (EXIT_FAILURE, errno, "write_kernel_modules: fts_open: %s", modpath); + error (EXIT_FAILURE, errno, "add_kernel_modules: fts_open: %s", modpath); for (;;) { errno = 0; FTSENT *entry = fts_read (fts); if (entry == NULL && errno != 0) - error (EXIT_FAILURE, errno, "write_kernel_modules: fts_read: %s", modpath); + error (EXIT_FAILURE, errno, "add_kernel_modules: fts_read: %s", modpath); if (entry == NULL) break; @@ -227,7 +204,7 @@ write_kernel_modules (const char *whitelist_file, const char *modpath) if (verbose >= 2) fprintf (stderr, "including kernel module %s (matches whitelist entry %s)\n", entry->fts_name, whitelist[j]); - cpio_append_fts_entry (entry); + writer->wr_fts_entry (entry); break; } else if (r != FNM_NOMATCH) error (EXIT_FAILURE, 0, "internal error: fnmatch ('%s', '%s', %d) returned unexpected non-zero value %d\n", @@ -236,15 +213,15 @@ write_kernel_modules (const char *whitelist_file, const char *modpath) } else { /* whitelist == NULL, always include */ if (verbose >= 2) fprintf (stderr, "including kernel module %s\n", entry->fts_name); - cpio_append_fts_entry (entry); + writer->wr_fts_entry (entry); } } else /* It's some other sort of file, or a directory, always include. */ - cpio_append_fts_entry (entry); + writer->wr_fts_entry (entry); } if (fts_close (fts) == -1) - error (EXIT_FAILURE, errno, "write_kernel_modules: fts_close: %s", modpath); + error (EXIT_FAILURE, errno, "add_kernel_modules: fts_close: %s", modpath); } /* Copy the host files. @@ -254,7 +231,7 @@ write_kernel_modules (const char *whitelist_file, const char *modpath) * that exist. Ignore any files that don't exist or are not readable. */ static void -write_hostfiles (const char *hostfiles_file) +add_hostfiles (const char *hostfiles_file, struct writer *writer) { char **hostfiles = load_file (hostfiles_file); @@ -287,7 +264,7 @@ write_hostfiles (const char *hostfiles_file) if (verbose >= 2) fprintf (stderr, "including host file %s (matches %s)\n", tmp, patt); - cpio_append (tmp); + writer->wr_file (tmp); free (tmp); } @@ -298,204 +275,7 @@ write_hostfiles (const char *hostfiles_file) fprintf (stderr, "including host file %s (directly referenced)\n", hostfile); - cpio_append_stat (hostfile, &statbuf); + writer->wr_file_stat (hostfile, &statbuf); } /* Ignore files that don't exist. */ } } - -/* Copy contents of buffer to out_fd and keep out_offset correct. */ -static void -write_to_fd (const void *buffer, size_t len) -{ - if (full_write (out_fd, buffer, len) != len) - error (EXIT_FAILURE, errno, "write"); - out_offset += len; -} - -/* Copy contents of file to out_fd. */ -static void -write_file_to_fd (const char *filename) -{ - char buffer[BUFFER_SIZE]; - int fd2; - ssize_t r; - - if (verbose >= 2) - fprintf (stderr, "write_file_to_fd %s -> %d\n", filename, out_fd); - - fd2 = open (filename, O_RDONLY); - if (fd2 == -1) - error (EXIT_FAILURE, errno, "open: %s", filename); - for (;;) { - r = read (fd2, buffer, sizeof buffer); - if (r == 0) - break; - if (r == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) - continue; - error (EXIT_FAILURE, errno, "read: %s", filename); - } - write_to_fd (buffer, r); - } - - if (close (fd2) == -1) - error (EXIT_FAILURE, errno, "close: %s", filename); -} - -/* Copy file of given length to output, and fail if the file has - * changed size. - */ -static void -write_file_len_to_fd (const char *filename, size_t len) -{ - char buffer[BUFFER_SIZE]; - size_t count = 0; - - if (verbose >= 2) - fprintf (stderr, "write_file_to_fd %s -> %d\n", filename, out_fd); - - int fd2 = open (filename, O_RDONLY); - if (fd2 == -1) - error (EXIT_FAILURE, errno, "open: %s", filename); - for (;;) { - ssize_t r = read (fd2, buffer, sizeof buffer); - if (r == 0) - break; - if (r == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) - continue; - error (EXIT_FAILURE, errno, "read: %s", filename); - } - write_to_fd (buffer, r); - count += r; - if (count > len) - error (EXIT_FAILURE, 0, "write_file_len_to_fd: %s: file has increased in size\n", filename); - } - - if (close (fd2) == -1) - error (EXIT_FAILURE, errno, "close: %s", filename); - - if (count != len) - error (EXIT_FAILURE, 0, "febootstrap-supermin-helper: write_file_len_to_fd: %s: file has changed size\n", filename); -} - -/* Append the file pointed to by FTSENT to the cpio output. */ -static void -cpio_append_fts_entry (FTSENT *entry) -{ - if (entry->fts_info & FTS_NS || entry->fts_info & FTS_NSOK) - cpio_append (entry->fts_path); - else - cpio_append_stat (entry->fts_path, entry->fts_statp); -} - -/* Append the file named 'filename' to the cpio output. */ -static void -cpio_append (const char *filename) -{ - struct stat statbuf; - - if (lstat (filename, &statbuf) == -1) - error (EXIT_FAILURE, errno, "lstat: %s", filename); - cpio_append_stat (filename, &statbuf); -} - -/* Append the file to the cpio output. */ -#define PADDING(len) ((((len) + 3) & ~3) - (len)) - -#define CPIO_HEADER_LEN (6 + 13*8) - -static void -cpio_append_stat (const char *filename, struct stat *statbuf) -{ - const char *orig_filename = filename; - - if (*filename == '/') - filename++; - if (*filename == '\0') - filename = "."; - - if (verbose >= 2) - fprintf (stderr, "cpio_append_stat %s 0%o -> %d\n", - orig_filename, statbuf->st_mode, out_fd); - - /* Regular files and symlinks are the only ones that have a "body" - * in this cpio entry. - */ - int has_body = S_ISREG (statbuf->st_mode) || S_ISLNK (statbuf->st_mode); - - size_t len = strlen (filename) + 1; - - char header[CPIO_HEADER_LEN + 1]; - snprintf (header, sizeof header, - "070701" /* magic */ - "%08X" /* inode */ - "%08X" /* mode */ - "%08X" "%08X" /* uid, gid */ - "%08X" /* nlink */ - "%08X" /* mtime */ - "%08X" /* file length */ - "%08X" "%08X" /* device holding file major, minor */ - "%08X" "%08X" /* for specials, device major, minor */ - "%08X" /* name length (including \0 byte) */ - "%08X", /* checksum (not used by the kernel) */ - (unsigned) statbuf->st_ino, statbuf->st_mode, - statbuf->st_uid, statbuf->st_gid, - (unsigned) statbuf->st_nlink, (unsigned) statbuf->st_mtime, - has_body ? (unsigned) statbuf->st_size : 0, - major (statbuf->st_dev), minor (statbuf->st_dev), - major (statbuf->st_rdev), minor (statbuf->st_rdev), - (unsigned) len, 0); - - /* Write the header. */ - write_to_fd (header, CPIO_HEADER_LEN); - - /* Follow with the filename, and pad it. */ - write_to_fd (filename, len); - size_t padding_len = PADDING (CPIO_HEADER_LEN + len); - write_padding (padding_len); - - /* Follow with the file or symlink content, and pad it. */ - if (has_body) { - if (S_ISREG (statbuf->st_mode)) - write_file_len_to_fd (orig_filename, statbuf->st_size); - else if (S_ISLNK (statbuf->st_mode)) { - char tmp[PATH_MAX]; - if (readlink (orig_filename, tmp, sizeof tmp) == -1) - error (EXIT_FAILURE, errno, "readlink: %s", orig_filename); - write_to_fd (tmp, statbuf->st_size); - } - - padding_len = PADDING (statbuf->st_size); - write_padding (padding_len); - } -} - -/* CPIO voodoo. */ -static void -cpio_append_trailer (void) -{ - struct stat statbuf; - memset (&statbuf, 0, sizeof statbuf); - statbuf.st_nlink = 1; - cpio_append_stat ("TRAILER!!!", &statbuf); - - /* CPIO seems to pad up to the next block boundary, ie. up to - * the next 512 bytes. - */ - write_padding (((out_offset + 511) & ~511) - out_offset); - assert ((out_offset & 511) == 0); -} - -/* Write 'len' bytes of zeroes out. */ -static void -write_padding (size_t len) -{ - static const char buffer[512] = { 0 }; - - while (len > 0) { - size_t n = len < sizeof buffer ? len : sizeof buffer; - write_to_fd (buffer, n); - len -= n; - } -} diff --git a/helper/cpio.c b/helper/cpio.c new file mode 100644 index 0000000..f9ffc3f --- /dev/null +++ b/helper/cpio.c @@ -0,0 +1,278 @@ +/* febootstrap-supermin-helper reimplementation in C. + * Copyright (C) 2009-2010 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h> +#include <assert.h> + +#include "error.h" +#include "fts_.h" +#include "full-write.h" +#include "xalloc.h" +#include "xvasprintf.h" + +#include "helper.h" + +/* Buffer size used in copy operations throughout. Large for + * greatest efficiency. + */ +#define BUFFER_SIZE 65536 + +static int out_fd = -1; +static off_t out_offset = 0; + +static void write_file_to_fd (const char *filename); +static void write_file_len_to_fd (const char *filename, size_t len); +static void write_padding (size_t len); +static void cpio_append_fts_entry (FTSENT *entry); +static void cpio_append_stat (const char *filename, const struct stat *); +static void cpio_append (const char *filename); +static void cpio_append_trailer (void); + +/* Copy contents of buffer to out_fd and keep out_offset correct. */ +static void +write_to_fd (const void *buffer, size_t len) +{ + if (full_write (out_fd, buffer, len) != len) + error (EXIT_FAILURE, errno, "write"); + out_offset += len; +} + +/* Copy contents of file to out_fd. */ +static void +write_file_to_fd (const char *filename) +{ + char buffer[BUFFER_SIZE]; + int fd2; + ssize_t r; + + if (verbose >= 2) + fprintf (stderr, "write_file_to_fd %s -> %d\n", filename, out_fd); + + fd2 = open (filename, O_RDONLY); + if (fd2 == -1) + error (EXIT_FAILURE, errno, "open: %s", filename); + for (;;) { + r = read (fd2, buffer, sizeof buffer); + if (r == 0) + break; + if (r == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + continue; + error (EXIT_FAILURE, errno, "read: %s", filename); + } + write_to_fd (buffer, r); + } + + if (close (fd2) == -1) + error (EXIT_FAILURE, errno, "close: %s", filename); +} + +/* Copy file of given length to output, and fail if the file has + * changed size. + */ +static void +write_file_len_to_fd (const char *filename, size_t len) +{ + char buffer[BUFFER_SIZE]; + size_t count = 0; + + if (verbose >= 2) + fprintf (stderr, "write_file_to_fd %s -> %d\n", filename, out_fd); + + int fd2 = open (filename, O_RDONLY); + if (fd2 == -1) + error (EXIT_FAILURE, errno, "open: %s", filename); + for (;;) { + ssize_t r = read (fd2, buffer, sizeof buffer); + if (r == 0) + break; + if (r == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + continue; + error (EXIT_FAILURE, errno, "read: %s", filename); + } + write_to_fd (buffer, r); + count += r; + if (count > len) + error (EXIT_FAILURE, 0, "write_file_len_to_fd: %s: file has increased in size\n", filename); + } + + if (close (fd2) == -1) + error (EXIT_FAILURE, errno, "close: %s", filename); + + if (count != len) + error (EXIT_FAILURE, 0, "febootstrap-supermin-helper: write_file_len_to_fd: %s: file has changed size\n", filename); +} + +/* Append the file pointed to by FTSENT to the cpio output. */ +static void +cpio_append_fts_entry (FTSENT *entry) +{ + if (entry->fts_info & FTS_NS || entry->fts_info & FTS_NSOK) + cpio_append (entry->fts_path); + else + cpio_append_stat (entry->fts_path, entry->fts_statp); +} + +/* Append the file named 'filename' to the cpio output. */ +static void +cpio_append (const char *filename) +{ + struct stat statbuf; + + if (lstat (filename, &statbuf) == -1) + error (EXIT_FAILURE, errno, "lstat: %s", filename); + cpio_append_stat (filename, &statbuf); +} + +/* Append the file to the cpio output. */ +#define PADDING(len) ((((len) + 3) & ~3) - (len)) + +#define CPIO_HEADER_LEN (6 + 13*8) + +static void +cpio_append_stat (const char *filename, const struct stat *statbuf) +{ + const char *orig_filename = filename; + + if (*filename == '/') + filename++; + if (*filename == '\0') + filename = "."; + + if (verbose >= 2) + fprintf (stderr, "cpio_append_stat %s 0%o -> %d\n", + orig_filename, statbuf->st_mode, out_fd); + + /* Regular files and symlinks are the only ones that have a "body" + * in this cpio entry. + */ + int has_body = S_ISREG (statbuf->st_mode) || S_ISLNK (statbuf->st_mode); + + size_t len = strlen (filename) + 1; + + char header[CPIO_HEADER_LEN + 1]; + snprintf (header, sizeof header, + "070701" /* magic */ + "%08X" /* inode */ + "%08X" /* mode */ + "%08X" "%08X" /* uid, gid */ + "%08X" /* nlink */ + "%08X" /* mtime */ + "%08X" /* file length */ + "%08X" "%08X" /* device holding file major, minor */ + "%08X" "%08X" /* for specials, device major, minor */ + "%08X" /* name length (including \0 byte) */ + "%08X", /* checksum (not used by the kernel) */ + (unsigned) statbuf->st_ino, statbuf->st_mode, + statbuf->st_uid, statbuf->st_gid, + (unsigned) statbuf->st_nlink, (unsigned) statbuf->st_mtime, + has_body ? (unsigned) statbuf->st_size : 0, + major (statbuf->st_dev), minor (statbuf->st_dev), + major (statbuf->st_rdev), minor (statbuf->st_rdev), + (unsigned) len, 0); + + /* Write the header. */ + write_to_fd (header, CPIO_HEADER_LEN); + + /* Follow with the filename, and pad it. */ + write_to_fd (filename, len); + size_t padding_len = PADDING (CPIO_HEADER_LEN + len); + write_padding (padding_len); + + /* Follow with the file or symlink content, and pad it. */ + if (has_body) { + if (S_ISREG (statbuf->st_mode)) + write_file_len_to_fd (orig_filename, statbuf->st_size); + else if (S_ISLNK (statbuf->st_mode)) { + char tmp[PATH_MAX]; + if (readlink (orig_filename, tmp, sizeof tmp) == -1) + error (EXIT_FAILURE, errno, "readlink: %s", orig_filename); + write_to_fd (tmp, statbuf->st_size); + } + + padding_len = PADDING (statbuf->st_size); + write_padding (padding_len); + } +} + +/* CPIO voodoo. */ +static void +cpio_append_trailer (void) +{ + struct stat statbuf; + memset (&statbuf, 0, sizeof statbuf); + statbuf.st_nlink = 1; + cpio_append_stat ("TRAILER!!!", &statbuf); + + /* CPIO seems to pad up to the next block boundary, ie. up to + * the next 512 bytes. + */ + write_padding (((out_offset + 511) & ~511) - out_offset); + assert ((out_offset & 511) == 0); +} + +/* Write 'len' bytes of zeroes out. */ +static void +write_padding (size_t len) +{ + static const char buffer[512] = { 0 }; + + while (len > 0) { + size_t n = len < sizeof buffer ? len : sizeof buffer; + write_to_fd (buffer, n); + len -= n; + } +} + +static void +cpio_start (const char *appliance) +{ + out_fd = open (appliance, O_WRONLY | O_CREAT | O_TRUNC | O_NOCTTY, 0644); + if (out_fd == -1) + error (EXIT_FAILURE, errno, "open: %s", appliance); + out_offset = 0; +} + +static void +cpio_end (void) +{ + cpio_append_trailer (); + + /* Finish off and close output file. */ + if (close (out_fd) == -1) + error (EXIT_FAILURE, errno, "close"); +} + +struct writer cpio_writer = { + .wr_start = cpio_start, + .wr_end = cpio_end, + .wr_file = cpio_append, + .wr_file_stat = cpio_append_stat, + .wr_fts_entry = cpio_append_fts_entry, + .wr_cpio_file = write_file_to_fd, +}; diff --git a/helper/helper.h b/helper/helper.h index 50d4f33..9bb637a 100644 --- a/helper/helper.h +++ b/helper/helper.h @@ -19,12 +19,36 @@ #ifndef FEBOOTSTRAP_SUPERMIN_HELPER_H #define FEBOOTSTRAP_SUPERMIN_HELPER_H +#include <sys/stat.h> +#include "fts_.h" + +struct writer { + /* Start a new appliance, finish one off. */ + void (*wr_start) (const char *appliance); + void (*wr_end) (void); + + /* Append the named host file to the appliance being built. The + * wr_file_stat form is used where we have already stat'd this file, + * to avoid having to stat it a second time. The wr_fts_entry form + * is used where the caller has an FTSENT. + */ + void (*wr_file) (const char *filename); + void (*wr_file_stat) (const char *filename, const struct stat *); + void (*wr_fts_entry) (FTSENT *entry); + + /* Append the contents of cpio file to the appliance being built. */ + void (*wr_cpio_file) (const char *cpio_file); +}; + /* main.c */ extern struct timeval start_t; extern int verbose; /* appliance.c */ -extern void create_appliance (char **inputs, int nr_inputs, const char *whitelist, const char *modpath, const char *appliance); +extern void create_appliance (char **inputs, int nr_inputs, const char *whitelist, const char *modpath, const char *appliance, struct writer *writer); + +/* cpio.c */ +extern struct writer cpio_writer; /* kernel.c */ extern const char *create_kernel (const char *hostcpu, const char *kernel); diff --git a/helper/main.c b/helper/main.c index d350b4e..a448b9e 100644 --- a/helper/main.c +++ b/helper/main.c @@ -152,7 +152,8 @@ main (int argc, char *argv[]) print_timestamped_message ("finished creating kernel"); /* Create the appliance. */ - create_appliance (inputs, nr_inputs, whitelist, modpath, appliance); + create_appliance (inputs, nr_inputs, whitelist, modpath, appliance, + &cpio_writer); if (verbose) print_timestamped_message ("finished creating appliance"); |