Skip to content

Commit

Permalink
initrd-ls, initrd-export: Add Extra Boot Config support
Browse files Browse the repository at this point in the history
The presence of bootconfig must be properly handled. Before that, the
presence of bootconfig in the archive led to an error.

As addition an option has been added to the initrd-ls to display brief
information about parts of the archive.

Signed-off-by: Alexey Gladkov <[email protected]>
  • Loading branch information
legionus committed Sep 20, 2021
1 parent 39ab824 commit d833773
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 6 deletions.
7 changes: 7 additions & 0 deletions utils/initrd-cpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@

#include "initrd-common.h"

enum cpio_type {
CPIO_UNKNOWN = 0,
CPIO_ARCHIVE,
CPIO_BOOTCONFIG,
};

struct cpio {
enum cpio_type type;
const char *compress;

unsigned char *raw;
Expand Down
5 changes: 5 additions & 0 deletions utils/initrd-extract/initrd-extract.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ main(int argc, char **argv)
c = 1;
l = res.cpios;
while (l) {
if (((struct cpio *) l->data)->type != CPIO_ARCHIVE) {
l = l->next;
c++;
continue;
}
if (!n_archive || c == n_archive) {
h = ((struct cpio *) l->data)->headers;
while (h) {
Expand Down
55 changes: 49 additions & 6 deletions utils/initrd-ls/initrd-ls.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@

int opts = 0;

static const char cmdopts_s[] = "nCVh";
static const char cmdopts_s[] = "bnCVh";
static const struct option cmdopts[] = {
{ "brief", no_argument, 0, 'b' },
{ "name", no_argument, 0, 'n' },
{ "no-mtime", no_argument, 0, 3 },
{ "compression", no_argument, 0, 'C' },
Expand All @@ -42,6 +43,7 @@ print_help(const char *progname)
"\n"
"Options:\n"
" --no-mtime Hide modification time;\n"
" -b, --brief Show only brief information about archive parts;\n"
" -n, --name Show only filenames;\n"
" -C, --compression Show compression method for each archive;\n"
" -V, --version Show version of program and exit;\n"
Expand All @@ -57,7 +59,7 @@ print_version(const char *progname)
printf("%s version " PACKAGE_VERSION "\n"
"Written by Alexey Gladkov <[email protected]>\n"
"\n"
"Copyright (C) 2016 Alexey Gladkov <[email protected]>\n"
"Copyright (C) 2016-2021 Alexey Gladkov <[email protected]>\n"
"This is free software; see the source for copying conditions. There is NO\n"
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n",
Expand All @@ -76,6 +78,9 @@ main(int argc, char **argv)
case 3:
opts ^= SHOW_NO_MTIME;
break;
case 'b':
opts ^= SHOW_BRIEF;
break;
case 'n':
opts ^= SHOW_NAME_ONLY;
break;
Expand Down Expand Up @@ -131,15 +136,23 @@ main(int argc, char **argv)
int bytes;
int max_compress_name = 3;
char *fmt = NULL;
struct cpio *part = NULL;

l = res.cpios;
while (l) {
part = (struct cpio *) l->data;

if ((opts & SHOW_BRIEF) || part->type != CPIO_ARCHIVE) {
l = l->next;
n_cpio++;
continue;
}
if (opts & SHOW_COMPRESSION) {
bytes = snprintf(NULL, 0, "%s", ((struct cpio *) l->data)->compress);
bytes = snprintf(NULL, 0, "%s", part->compress);
if (bytes > max_compress_name)
max_compress_name = bytes;
}
h = ((struct cpio *) l->data)->headers;
h = part->headers;
while (h) {
preformat(h->data);
h = h->next;
Expand All @@ -160,10 +173,40 @@ main(int argc, char **argv)
c = 1;
l = res.cpios;
while (l) {
h = ((struct cpio *) l->data)->headers;
part = (struct cpio *) l->data;

if (opts & SHOW_BRIEF) {
fprintf(stdout, "%d\t", c);

switch (part->type) {
case CPIO_ARCHIVE:
if (strcmp("raw", part->compress))
fprintf(stdout, "%s compressed ", part->compress);
fprintf(stdout, "cpio archive");
break;
case CPIO_BOOTCONFIG:
fprintf(stdout, "bootconfig");
break;
case CPIO_UNKNOWN:
fprintf(stdout, "unknown");
break;
}

fprintf(stdout, ", size %ld bytes\n", part->size);

l = l->next;
c++;
continue;
}
if (part->type != CPIO_ARCHIVE) {
l = l->next;
n_cpio++;
continue;
}
h = part->headers;
while (h) {
(opts & SHOW_COMPRESSION)
? fprintf(stdout, fmt, c, ((struct cpio *) l->data)->compress)
? fprintf(stdout, fmt, c, part->compress)
: fprintf(stdout, fmt, c);
(opts & SHOW_NAME_ONLY)
? fprintf(stdout, "%s\n", ((struct cpio_header *) h->data)->name)
Expand Down
1 change: 1 addition & 0 deletions utils/initrd-ls/initrd-ls.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ enum flags {
SHOW_COMPRESSION = (1 << 1),
SHOW_NAME_ONLY = (1 << 2),
SHOW_NO_MTIME = (1 << 3),
SHOW_BRIEF = (1 << 4),
};

int preformat(struct cpio_header *header);
Expand Down
65 changes: 65 additions & 0 deletions utils/initrd-parse.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
#include <endian.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <err.h>

#include "initrd-common.h"
#include "initrd-cpio.h"
#include "initrd-decompress.h"
#include "initrd-parse.h"

#define BOOTCONFIG_MAGIC "#BOOTCONFIG\n"
#define BOOTCONFIG_MAGIC_LEN 12

static int stream_level = 0;

void
read_stream(const char *compress, struct stream *arv, struct result *res)
{
Expand All @@ -14,9 +22,33 @@ read_stream(const char *compress, struct stream *arv, struct result *res)
struct cpio *cpio;
const char *compress_name;
decompress_fn decompress;
unsigned char *data = NULL;
uint32_t *hdr;
uint32_t size = 0; //csum;

unsigned long offset = 0;

stream_level++;

if (stream_level == 1) {
/*
* Check bootconfig first.
*/
data = arv->addr + arv->size - BOOTCONFIG_MAGIC_LEN;

/*
* Since Grub may align the size of initrd to 4, we must
* check the preceding 3 bytes as well.
*/
for (int i = 0; i < 4; i++) {
if (!memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN))
goto bootconfig;
data--;
}

data = NULL;
}
stream:
while (offset < arv->size) {
decompress = decompress_method(arv->addr + offset, arv->size - offset, &compress_name);
if (decompress) {
Expand Down Expand Up @@ -48,13 +80,46 @@ read_stream(const char *compress, struct stream *arv, struct result *res)
err(EXIT_FAILURE, "ERROR: %s: %d: unable to add element to list", __FILE__, __LINE__);
cpio = l->data;

cpio->type = CPIO_ARCHIVE;
cpio->compress = compress;
cpio->raw = arv->addr + offset;
cpio->size = arv->size - offset;
cpio->headers = NULL;

offset += read_cpio(cpio);
}

if (data) {
l = list_append(&res->cpios, sizeof(struct cpio));
if (l == NULL)
err(EXIT_FAILURE, "ERROR: %s: %d: unable to add element to list", __FILE__, __LINE__);

cpio = l->data;

cpio->type = CPIO_BOOTCONFIG;
cpio->compress = NULL;
cpio->raw = data;
cpio->size = size;
cpio->headers = NULL;
}

stream_level--;
return;

bootconfig:
hdr = (uint32_t *)(data - 8);
size = le32toh(hdr[0]);
//csum = le32toh(hdr[1]);

data = ((void *)hdr) - size;

if (size > arv->size)
err(EXIT_FAILURE, "bootconfig size %d is greater than initrd size %ld", size, arv->size);

/* Remove bootconfig from initramfs/initrd */
arv->size = (unsigned long) (data - arv->addr);

goto stream;
}

void
Expand Down

0 comments on commit d833773

Please sign in to comment.