* [PATCH] gen_init_cpio uses external file list
@ 2004-09-16 22:11 Thayne Harbaugh
2004-09-16 23:06 ` Jeff Garzik
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Thayne Harbaugh @ 2004-09-16 22:11 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, klibc
[-- Attachment #1: Type: text/plain, Size: 1183 bytes --]
(Apologies to klibc@zytor.com for the re-send)
This patch makes gen_init_cpio generate the initramfs_data.cpio from a
file which contains a list of entries: file, dir, nod. I swapped the
order of filename/location for the file arguments so that it would be
more uniform with the dir and nod tyes.
[thayne@torch linux-2.6.8]$ usr/gen_init_cpio --help
ERROR: unable to open '--help': No such file or directory
Usage:
usr/gen_init_cpio <cpio_list>
<cpio_list> is a file containing newline separated entries that
describe the files to be included in the initramfs archive:
file <name> <location> <mode> <uid> <gid>
dir <name> <mode> <uid> <gid>
nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>
<name> name of the file/dir/nod in the archive
<location> location of the file in the current filesystem
<mode> mode/permissions of the file
<uid> user id (0=root)
<gid> group id (0=root)
<dev_type> device type (b=block, c=character)
<maj> major number of nod
<min> minor number of nod
example:
dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1
dir /root 0700 0 0
dir /sbin 0755 0 0
file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0
[-- Attachment #2: Type: text/x-patch, Size: 8770 bytes --]
diff -uNr linux-2.6.8/usr/gen_init_cpio.c linux-2.6.8-cpio_list/usr/gen_init_cpio.c
--- linux-2.6.8/usr/gen_init_cpio.c 2004-09-13 12:35:11.148116792 -0600
+++ linux-2.6.8-cpio_list/usr/gen_init_cpio.c 2004-09-16 15:36:37.634729800 -0600
@@ -1,3 +1,4 @@
+#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -6,10 +7,21 @@
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+
+#define xstr(s) #s
+#define str(s) xstr(s)
static unsigned int offset;
static unsigned int ino = 721;
+struct file_type {
+ const char *type;
+ int (*handler)(const char *line);
+};
+
static void push_string(const char *name)
{
unsigned int name_len = strlen(name) + 1;
@@ -80,7 +92,7 @@
}
}
-static void cpio_mkdir(const char *name, unsigned int mode,
+static int cpio_mkdir(const char *name, unsigned int mode,
uid_t uid, gid_t gid)
{
char s[256];
@@ -104,10 +116,28 @@
0); /* chksum */
push_hdr(s);
push_rest(name);
+ return 0;
}
-static void cpio_mknod(const char *name, unsigned int mode,
- uid_t uid, gid_t gid, int dev_type,
+static int cpio_mkdir_line(const char *line)
+{
+ char name[PATH_MAX + 1];
+ unsigned int mode;
+ uid_t uid;
+ gid_t gid;
+ int rc = -1;
+
+ if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) {
+ fprintf(stderr, "Unrecognized dir format '%s'", line);
+ goto fail;
+ }
+ rc = cpio_mkdir(name, mode, uid, gid);
+ fail:
+ return rc;
+}
+
+static int cpio_mknod(const char *name, unsigned int mode,
+ uid_t uid, gid_t gid, char dev_type,
unsigned int maj, unsigned int min)
{
char s[256];
@@ -136,43 +166,66 @@
0); /* chksum */
push_hdr(s);
push_rest(name);
+ return 0;
+}
+
+static int cpio_mknod_line(const char *line)
+{
+ char name[PATH_MAX + 1];
+ unsigned int mode;
+ uid_t uid;
+ gid_t gid;
+ char dev_type;
+ unsigned int maj;
+ unsigned int min;
+ int rc = -1;
+
+ if (7 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d %c %u %u",
+ name, &mode, &uid, &gid, &dev_type, &maj, &min)) {
+ fprintf(stderr, "Unrecognized nod format '%s'", line);
+ goto fail;
+ }
+ rc = cpio_mknod(name, mode, uid, gid, dev_type, maj, min);
+ fail:
+ return rc;
}
/* Not marked static to keep the compiler quiet, as no one uses this yet... */
-void cpio_mkfile(const char *filename, const char *location,
+static int cpio_mkfile(const char *name, const char *location,
unsigned int mode, uid_t uid, gid_t gid)
{
char s[256];
- char *filebuf;
+ char *filebuf = NULL;
struct stat buf;
- int file;
+ int file = -1;
int retval;
int i;
+ int rc = -1;
mode |= S_IFREG;
- retval = stat (filename, &buf);
+ retval = stat (location, &buf);
if (retval) {
- fprintf (stderr, "Filename %s could not be located\n", filename);
+ fprintf (stderr, "File %s could not be located\n", location);
goto error;
}
- file = open (filename, O_RDONLY);
+ file = open (location, O_RDONLY);
if (file < 0) {
- fprintf (stderr, "Filename %s could not be opened for reading\n", filename);
+ fprintf (stderr, "File %s could not be opened for reading\n", location);
goto error;
}
filebuf = malloc(buf.st_size);
if (!filebuf) {
fprintf (stderr, "out of memory\n");
- goto error_close;
+ goto error;
}
retval = read (file, filebuf, buf.st_size);
if (retval < 0) {
- fprintf (stderr, "Can not read %s file\n", filename);
- goto error_free;
+ fprintf (stderr, "Can not read %s file\n", location);
+ goto error;
}
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
@@ -189,40 +242,146 @@
1, /* minor */
0, /* rmajor */
0, /* rminor */
- (unsigned)strlen(location) + 1,/* namesize */
+ (unsigned)strlen(name) + 1,/* namesize */
0); /* chksum */
push_hdr(s);
- push_string(location);
+ push_string(name);
push_pad();
for (i = 0; i < buf.st_size; ++i)
fputc(filebuf[i], stdout);
offset += buf.st_size;
- close(file);
- free(filebuf);
push_pad();
- return;
+ rc = 0;
-error_free:
- free(filebuf);
-error_close:
- close(file);
error:
- exit(-1);
+ if (filebuf) free(filebuf);
+ if (file >= 0) close(file);
+ return rc;
}
+static int cpio_mkfile_line(const char *line)
+{
+ char name[PATH_MAX + 1];
+ char location[PATH_MAX + 1];
+ unsigned int mode;
+ uid_t uid;
+ gid_t gid;
+ int rc = -1;
+
+ if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, location, &mode, &uid, &gid)) {
+ fprintf(stderr, "Unrecognized file format '%s'", line);
+ goto fail;
+ }
+ rc = cpio_mkfile(name, location, mode, uid, gid);
+ fail:
+ return rc;
+}
+
+void usage(const char *prog)
+{
+ fprintf(stderr, "Usage:\n"
+ "\t%s <cpio_list>\n"
+ "\n"
+ "<cpio_list> is a file containing newline separated entries that\n"
+ "describe the files to be included in the initramfs archive:\n"
+ "\n"
+ "file <name> <location> <mode> <uid> <gid> \n"
+ "dir <name> <mode> <uid> <gid>\n"
+ "nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n"
+ "\n"
+ "<name> name of the file/dir/nod in the archive\n"
+ "<location> location of the file in the current filesystem\n"
+ "<mode> mode/permissions of the file\n"
+ "<uid> user id (0=root)\n"
+ "<gid> group id (0=root)\n"
+ "<dev_type> device type (b=block, c=character)\n"
+ "<maj> major number of nod\n"
+ "<min> minor number of nod\n"
+ "\n"
+ "example:\n"
+ "dir /dev 0755 0 0\n"
+ "nod /dev/console 0600 0 0 c 5 1\n"
+ "dir /root 0700 0 0\n"
+ "dir /sbin 0755 0 0\n"
+ "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n",
+ prog);
+}
+
+struct file_type file_type_table[] = {
+ {
+ .type = "file",
+ .handler = cpio_mkfile_line,
+ }, {
+ .type = "nod",
+ .handler = cpio_mknod_line,
+ }, {
+ .type = "dir",
+ .handler = cpio_mkdir_line,
+ }, {
+ .type = NULL,
+ .handler = NULL,
+ }
+};
+
int main (int argc, char *argv[])
{
- cpio_mkdir("/dev", 0755, 0, 0);
- cpio_mknod("/dev/console", 0600, 0, 0, 'c', 5, 1);
- cpio_mkdir("/root", 0700, 0, 0);
- cpio_trailer();
+ FILE *cpio_list;
+ char *line = NULL, *args, *type;
+ size_t line_sz = 0;
+ int ec = 0;
+ int line_nr = 0;
+
+ if (2 != argc) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (! (cpio_list = fopen(argv[1], "r"))) {
+ fprintf(stderr, "ERROR: unable to open '%s': %s\n\n",
+ argv[1], strerror(errno));
+ usage(argv[0]);
+ exit(1);
+ }
- exit(0);
+ while (-1 != getline(&line, &line_sz, cpio_list)) {
+ int type_idx;
- /* silence compiler warnings */
- return 0;
- (void) argc;
- (void) argv;
+ line_nr++;
+
+ if (! (type = strtok(line, " \t"))) {
+ fprintf(stderr,
+ "ERROR: incorrect format, could not locate file type line %d: '%s'\n",
+ line_nr, line);
+ ec = -1;
+ }
+
+ if (! (args = strtok(NULL, "\n"))) {
+ fprintf(stderr,
+ "ERROR: incorrect format, newline required line %d: '%s'\n",
+ line_nr, line);
+ ec = -1;
+ }
+
+ for (type_idx = 0; file_type_table[type_idx].type; type_idx++) {
+ int rc;
+ if (! strcmp(line, file_type_table[type_idx].type)) {
+ if ((rc = file_type_table[type_idx].handler(args))) {
+ ec = rc;
+ fprintf(stderr, " line %d\n", line_nr);
+ }
+ break;
+ }
+ }
+
+ if (NULL == file_type_table[type_idx].type) {
+ fprintf(stderr, "unknown file type line %d: '%s'\n",
+ line_nr, line);
+ }
+ }
+ cpio_trailer();
+
+ if (line) free(line);
+ exit(ec);
}
diff -uNr linux-2.6.8/usr/initramfs_list linux-2.6.8-cpio_list/usr/initramfs_list
--- linux-2.6.8/usr/initramfs_list 1969-12-31 17:00:00.000000000 -0700
+++ linux-2.6.8-cpio_list/usr/initramfs_list 2004-09-16 15:36:37.686721896 -0600
@@ -0,0 +1,3 @@
+dir /dev 0755 0 0
+nod /dev/console 0600 0 0 c 5 1
+dir /root 0700 0 0
diff -uNr linux-2.6.8/usr/Makefile linux-2.6.8-cpio_list/usr/Makefile
--- linux-2.6.8/usr/Makefile 2004-09-16 15:03:35.535054752 -0600
+++ linux-2.6.8-cpio_list/usr/Makefile 2004-09-16 15:36:37.686721896 -0600
@@ -5,6 +5,11 @@
clean-files := initramfs_data.cpio.gz
+# If you want a different list of files in the initramfs_data.cpio
+# then you can either overwrite the cpio_list in this directory
+# or set INITRAMFS_LIST to another filename.
+INITRAMFS_LIST ?= $(obj)/initramfs_list
+
# initramfs_data.o contains the initramfs_data.cpio.gz image.
# The image is included using .incbin, a dependency which is not
# tracked automatically.
@@ -19,9 +24,9 @@
# initramfs-y := $(obj)/root/hello
quiet_cmd_cpio = CPIO $@
- cmd_cpio = ./$< > $@
+ cmd_cpio = ./$< $(INITRAMFS_LIST) > $@
-$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio $(initramfs-y) FORCE
+$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio $(initramfs-y) $(INITRAMFS_LIST) FORCE
$(call if_changed,cpio)
targets += initramfs_data.cpio
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] gen_init_cpio uses external file list
2004-09-16 22:11 [PATCH] gen_init_cpio uses external file list Thayne Harbaugh
@ 2004-09-16 23:06 ` Jeff Garzik
2004-09-16 22:53 ` Thayne Harbaugh
2004-09-17 4:49 ` Sam Ravnborg
2004-09-23 22:40 ` gen_initramfs_list.sh (was: Re: [PATCH] gen_init_cpio uses external file list) [u] Martin Schlemmer [c]
2 siblings, 1 reply; 8+ messages in thread
From: Jeff Garzik @ 2004-09-16 23:06 UTC (permalink / raw)
To: tharbaugh; +Cc: akpm, linux-kernel, klibc
Seems OK to me...
Jeff, the original gen_init_cpio author
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] gen_init_cpio uses external file list
2004-09-16 23:06 ` Jeff Garzik
@ 2004-09-16 22:53 ` Thayne Harbaugh
2004-09-17 0:16 ` Jeff Garzik
0 siblings, 1 reply; 8+ messages in thread
From: Thayne Harbaugh @ 2004-09-16 22:53 UTC (permalink / raw)
To: Jeff Garzik; +Cc: akpm, linux-kernel, klibc
On Thu, 2004-09-16 at 19:06 -0400, Jeff Garzik wrote:
> Seems OK to me...
>
> Jeff, the original gen_init_cpio author
There's been some minor discussion about the use of _GNU_SOURCE (needed
for getline()). Comments? I can rework the getline() if anyone can
make a case - otherwise I'm a bit lazy.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] gen_init_cpio uses external file list
2004-09-16 22:53 ` Thayne Harbaugh
@ 2004-09-17 0:16 ` Jeff Garzik
2004-09-17 1:36 ` [klibc] " H. Peter Anvin
0 siblings, 1 reply; 8+ messages in thread
From: Jeff Garzik @ 2004-09-17 0:16 UTC (permalink / raw)
To: tharbaugh; +Cc: akpm, linux-kernel, klibc
Thayne Harbaugh wrote:
> On Thu, 2004-09-16 at 19:06 -0400, Jeff Garzik wrote:
>
>>Seems OK to me...
>>
>> Jeff, the original gen_init_cpio author
>
>
> There's been some minor discussion about the use of _GNU_SOURCE (needed
> for getline()). Comments? I can rework the getline() if anyone can
> make a case - otherwise I'm a bit lazy.
I am a bit leery of _GNU_SOURCE but whatever :)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [klibc] Re: [PATCH] gen_init_cpio uses external file list
2004-09-17 0:16 ` Jeff Garzik
@ 2004-09-17 1:36 ` H. Peter Anvin
0 siblings, 0 replies; 8+ messages in thread
From: H. Peter Anvin @ 2004-09-17 1:36 UTC (permalink / raw)
To: Jeff Garzik; +Cc: tharbaugh, klibc, linux-kernel, akpm
Jeff Garzik wrote:
> Thayne Harbaugh wrote:
>
>> On Thu, 2004-09-16 at 19:06 -0400, Jeff Garzik wrote:
>>
>>> Seems OK to me...
>>>
>>> Jeff, the original gen_init_cpio author
>>
>> There's been some minor discussion about the use of _GNU_SOURCE (needed
>> for getline()). Comments? I can rework the getline() if anyone can
>> make a case - otherwise I'm a bit lazy.
>
> I am a bit leery of _GNU_SOURCE but whatever :)
>
_GNU_SOURCE just means enable all features. Perhaps it should be
something more restrictive, like _XOPEN_SOURCE or _POSIX_SOURCE; both of
those need to be set to specific values.
-hpa
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] gen_init_cpio uses external file list
2004-09-16 22:11 [PATCH] gen_init_cpio uses external file list Thayne Harbaugh
2004-09-16 23:06 ` Jeff Garzik
@ 2004-09-17 4:49 ` Sam Ravnborg
2004-09-17 22:38 ` Thayne Harbaugh
2004-09-23 22:40 ` gen_initramfs_list.sh (was: Re: [PATCH] gen_init_cpio uses external file list) [u] Martin Schlemmer [c]
2 siblings, 1 reply; 8+ messages in thread
From: Sam Ravnborg @ 2004-09-17 4:49 UTC (permalink / raw)
To: Thayne Harbaugh; +Cc: akpm, linux-kernel, klibc
On Thu, Sep 16, 2004 at 04:11:12PM -0600, Thayne Harbaugh wrote:
>
> This patch makes gen_init_cpio generate the initramfs_data.cpio from a
> file which contains a list of entries: file, dir, nod. I swapped the
> order of filename/location for the file arguments so that it would be
> more uniform with the dir and nod tyes.
Comments already given on klibc list by others, but repeated for lkml readers.
Helper programs like this shall be compatible with at least solaris & cygwin.
Therefore the linux only stuff needs to be avoided.
+ char name[PATH_MAX + 1];
> + unsigned int mode;
> + uid_t uid;
> + gid_t gid;
> + int rc = -1;
> +
> + if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) {
> + fprintf(stderr, "Unrecognized dir format '%s'", line);
> + goto fail;
Do we know that uid_t and gid_t equals an int here?
Use an int in the sscanf and do explicit type conversion later.
> + while (-1 != getline(&line, &line_sz, cpio_list)) {
> + int type_idx;
fgets() please.
Sam
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] gen_init_cpio uses external file list
2004-09-17 4:49 ` Sam Ravnborg
@ 2004-09-17 22:38 ` Thayne Harbaugh
0 siblings, 0 replies; 8+ messages in thread
From: Thayne Harbaugh @ 2004-09-17 22:38 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: akpm, linux-kernel, klibc, jgarzik
[-- Attachment #1: Type: text/plain, Size: 1017 bytes --]
On Fri, 2004-09-17 at 06:49 +0200, Sam Ravnborg wrote:
> On Thu, Sep 16, 2004 at 04:11:12PM -0600, Thayne Harbaugh wrote:
> >
> > This patch makes gen_init_cpio generate the initramfs_data.cpio from a
> > file which contains a list of entries: file, dir, nod. I swapped the
> > order of filename/location for the file arguments so that it would be
> > more uniform with the dir and nod tyes.
>
> Comments already given on klibc list by others, but repeated for lkml readers.
>
> Helper programs like this shall be compatible with at least solaris & cygwin.
> Therefore the linux only stuff needs to be avoided.
More correctly is GNU only stuff - but point taken. _GNU_SOURCE
removed.
> Do we know that uid_t and gid_t equals an int here?
> Use an int in the sscanf and do explicit type conversion later.
fixed.
> fgets() please.
fixed - although it's not as clean and flexible as what was there
(although more portable).
This newer patch also adds skipping of comments (initiated with #) and
blank lines.
[-- Attachment #2: cpio_list.3.patch --]
[-- Type: text/x-patch, Size: 9015 bytes --]
diff -uNr linux-2.6.8.orig/usr/gen_init_cpio.c linux-2.6.8/usr/gen_init_cpio.c
--- linux-2.6.8.orig/usr/gen_init_cpio.c 2004-08-14 04:55:34.000000000 -0600
+++ linux-2.6.8/usr/gen_init_cpio.c 2004-09-17 16:58:14.419508872 -0600
@@ -6,10 +6,21 @@
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+
+#define xstr(s) #s
+#define str(s) xstr(s)
static unsigned int offset;
static unsigned int ino = 721;
+struct file_type {
+ const char *type;
+ int (*handler)(const char *line);
+};
+
static void push_string(const char *name)
{
unsigned int name_len = strlen(name) + 1;
@@ -80,7 +91,7 @@
}
}
-static void cpio_mkdir(const char *name, unsigned int mode,
+static int cpio_mkdir(const char *name, unsigned int mode,
uid_t uid, gid_t gid)
{
char s[256];
@@ -104,10 +115,28 @@
0); /* chksum */
push_hdr(s);
push_rest(name);
+ return 0;
}
-static void cpio_mknod(const char *name, unsigned int mode,
- uid_t uid, gid_t gid, int dev_type,
+static int cpio_mkdir_line(const char *line)
+{
+ char name[PATH_MAX + 1];
+ unsigned int mode;
+ int uid;
+ int gid;
+ int rc = -1;
+
+ if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) {
+ fprintf(stderr, "Unrecognized dir format '%s'", line);
+ goto fail;
+ }
+ rc = cpio_mkdir(name, mode, uid, gid);
+ fail:
+ return rc;
+}
+
+static int cpio_mknod(const char *name, unsigned int mode,
+ uid_t uid, gid_t gid, char dev_type,
unsigned int maj, unsigned int min)
{
char s[256];
@@ -136,43 +165,66 @@
0); /* chksum */
push_hdr(s);
push_rest(name);
+ return 0;
+}
+
+static int cpio_mknod_line(const char *line)
+{
+ char name[PATH_MAX + 1];
+ unsigned int mode;
+ int uid;
+ int gid;
+ char dev_type;
+ unsigned int maj;
+ unsigned int min;
+ int rc = -1;
+
+ if (7 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d %c %u %u",
+ name, &mode, &uid, &gid, &dev_type, &maj, &min)) {
+ fprintf(stderr, "Unrecognized nod format '%s'", line);
+ goto fail;
+ }
+ rc = cpio_mknod(name, mode, uid, gid, dev_type, maj, min);
+ fail:
+ return rc;
}
/* Not marked static to keep the compiler quiet, as no one uses this yet... */
-void cpio_mkfile(const char *filename, const char *location,
+static int cpio_mkfile(const char *name, const char *location,
unsigned int mode, uid_t uid, gid_t gid)
{
char s[256];
- char *filebuf;
+ char *filebuf = NULL;
struct stat buf;
- int file;
+ int file = -1;
int retval;
int i;
+ int rc = -1;
mode |= S_IFREG;
- retval = stat (filename, &buf);
+ retval = stat (location, &buf);
if (retval) {
- fprintf (stderr, "Filename %s could not be located\n", filename);
+ fprintf (stderr, "File %s could not be located\n", location);
goto error;
}
- file = open (filename, O_RDONLY);
+ file = open (location, O_RDONLY);
if (file < 0) {
- fprintf (stderr, "Filename %s could not be opened for reading\n", filename);
+ fprintf (stderr, "File %s could not be opened for reading\n", location);
goto error;
}
filebuf = malloc(buf.st_size);
if (!filebuf) {
fprintf (stderr, "out of memory\n");
- goto error_close;
+ goto error;
}
retval = read (file, filebuf, buf.st_size);
if (retval < 0) {
- fprintf (stderr, "Can not read %s file\n", filename);
- goto error_free;
+ fprintf (stderr, "Can not read %s file\n", location);
+ goto error;
}
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
@@ -189,40 +241,164 @@
1, /* minor */
0, /* rmajor */
0, /* rminor */
- (unsigned)strlen(location) + 1,/* namesize */
+ (unsigned)strlen(name) + 1,/* namesize */
0); /* chksum */
push_hdr(s);
- push_string(location);
+ push_string(name);
push_pad();
for (i = 0; i < buf.st_size; ++i)
fputc(filebuf[i], stdout);
offset += buf.st_size;
- close(file);
- free(filebuf);
push_pad();
- return;
+ rc = 0;
-error_free:
- free(filebuf);
-error_close:
- close(file);
error:
- exit(-1);
+ if (filebuf) free(filebuf);
+ if (file >= 0) close(file);
+ return rc;
}
+static int cpio_mkfile_line(const char *line)
+{
+ char name[PATH_MAX + 1];
+ char location[PATH_MAX + 1];
+ unsigned int mode;
+ int uid;
+ int gid;
+ int rc = -1;
+
+ if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, location, &mode, &uid, &gid)) {
+ fprintf(stderr, "Unrecognized file format '%s'", line);
+ goto fail;
+ }
+ rc = cpio_mkfile(name, location, mode, uid, gid);
+ fail:
+ return rc;
+}
+
+void usage(const char *prog)
+{
+ fprintf(stderr, "Usage:\n"
+ "\t%s <cpio_list>\n"
+ "\n"
+ "<cpio_list> is a file containing newline separated entries that\n"
+ "describe the files to be included in the initramfs archive:\n"
+ "\n"
+ "# a comment\n"
+ "file <name> <location> <mode> <uid> <gid> \n"
+ "dir <name> <mode> <uid> <gid>\n"
+ "nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n"
+ "\n"
+ "<name> name of the file/dir/nod in the archive\n"
+ "<location> location of the file in the current filesystem\n"
+ "<mode> mode/permissions of the file\n"
+ "<uid> user id (0=root)\n"
+ "<gid> group id (0=root)\n"
+ "<dev_type> device type (b=block, c=character)\n"
+ "<maj> major number of nod\n"
+ "<min> minor number of nod\n"
+ "\n"
+ "example:\n"
+ "# A simple initramfs\n"
+ "dir /dev 0755 0 0\n"
+ "nod /dev/console 0600 0 0 c 5 1\n"
+ "dir /root 0700 0 0\n"
+ "dir /sbin 0755 0 0\n"
+ "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n",
+ prog);
+}
+
+struct file_type file_type_table[] = {
+ {
+ .type = "file",
+ .handler = cpio_mkfile_line,
+ }, {
+ .type = "nod",
+ .handler = cpio_mknod_line,
+ }, {
+ .type = "dir",
+ .handler = cpio_mkdir_line,
+ }, {
+ .type = NULL,
+ .handler = NULL,
+ }
+};
+
+#define LINE_SIZE (2 * PATH_MAX + 50)
+
int main (int argc, char *argv[])
{
- cpio_mkdir("/dev", 0755, 0, 0);
- cpio_mknod("/dev/console", 0600, 0, 0, 'c', 5, 1);
- cpio_mkdir("/root", 0700, 0, 0);
- cpio_trailer();
+ FILE *cpio_list;
+ char line[LINE_SIZE];
+ char *args, *type;
+ int ec = 0;
+ int line_nr = 0;
+
+ if (2 != argc) {
+ usage(argv[0]);
+ exit(1);
+ }
- exit(0);
+ if (! (cpio_list = fopen(argv[1], "r"))) {
+ fprintf(stderr, "ERROR: unable to open '%s': %s\n\n",
+ argv[1], strerror(errno));
+ usage(argv[0]);
+ exit(1);
+ }
- /* silence compiler warnings */
- return 0;
- (void) argc;
- (void) argv;
-}
+ while (fgets(line, LINE_SIZE, cpio_list)) {
+ int type_idx;
+ size_t slen = strlen(line);
+
+ line_nr++;
+
+ if ('#' == *line) {
+ /* comment - skip to next line */
+ continue;
+ }
+
+ if (! (type = strtok(line, " \t"))) {
+ fprintf(stderr,
+ "ERROR: incorrect format, could not locate file type line %d: '%s'\n",
+ line_nr, line);
+ ec = -1;
+ }
+
+ if ('\n' == *type) {
+ /* a blank line */
+ continue;
+ }
+
+ if (slen == strlen(type)) {
+ /* must be an empty line */
+ continue;
+ }
+
+ if (! (args = strtok(NULL, "\n"))) {
+ fprintf(stderr,
+ "ERROR: incorrect format, newline required line %d: '%s'\n",
+ line_nr, line);
+ ec = -1;
+ }
+
+ for (type_idx = 0; file_type_table[type_idx].type; type_idx++) {
+ int rc;
+ if (! strcmp(line, file_type_table[type_idx].type)) {
+ if ((rc = file_type_table[type_idx].handler(args))) {
+ ec = rc;
+ fprintf(stderr, " line %d\n", line_nr);
+ }
+ break;
+ }
+ }
+
+ if (NULL == file_type_table[type_idx].type) {
+ fprintf(stderr, "unknown file type line %d: '%s'\n",
+ line_nr, line);
+ }
+ }
+ cpio_trailer();
+ exit(ec);
+}
diff -uNr linux-2.6.8.orig/usr/initramfs_list linux-2.6.8/usr/initramfs_list
--- linux-2.6.8.orig/usr/initramfs_list 1969-12-31 17:00:00.000000000 -0700
+++ linux-2.6.8/usr/initramfs_list 2004-09-17 15:50:11.392223368 -0600
@@ -0,0 +1,5 @@
+# This is a very simple initramfs - mostly preliminary for future expansion
+
+dir /dev 0755 0 0
+nod /dev/console 0600 0 0 c 5 1
+dir /root 0700 0 0
diff -uNr linux-2.6.8.orig/usr/Makefile linux-2.6.8/usr/Makefile
--- linux-2.6.8.orig/usr/Makefile 2004-08-14 04:55:33.000000000 -0600
+++ linux-2.6.8/usr/Makefile 2004-09-16 15:45:24.343657872 -0600
@@ -5,6 +5,11 @@
clean-files := initramfs_data.cpio.gz
+# If you want a different list of files in the initramfs_data.cpio
+# then you can either overwrite the cpio_list in this directory
+# or set INITRAMFS_LIST to another filename.
+INITRAMFS_LIST ?= $(obj)/initramfs_list
+
# initramfs_data.o contains the initramfs_data.cpio.gz image.
# The image is included using .incbin, a dependency which is not
# tracked automatically.
@@ -19,9 +24,9 @@
# initramfs-y := $(obj)/root/hello
quiet_cmd_cpio = CPIO $@
- cmd_cpio = ./$< > $@
+ cmd_cpio = ./$< $(INITRAMFS_LIST) > $@
-$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio $(initramfs-y) FORCE
+$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio $(initramfs-y) $(INITRAMFS_LIST) FORCE
$(call if_changed,cpio)
targets += initramfs_data.cpio
^ permalink raw reply [flat|nested] 8+ messages in thread
* gen_initramfs_list.sh (was: Re: [PATCH] gen_init_cpio uses external file list) [u]
2004-09-16 22:11 [PATCH] gen_init_cpio uses external file list Thayne Harbaugh
2004-09-16 23:06 ` Jeff Garzik
2004-09-17 4:49 ` Sam Ravnborg
@ 2004-09-23 22:40 ` Martin Schlemmer [c]
2 siblings, 0 replies; 8+ messages in thread
From: Martin Schlemmer [c] @ 2004-09-23 22:40 UTC (permalink / raw)
To: Linux Kernel Mailing Lists; +Cc: akpm, tharbaugh, klibc
[-- Attachment #1.1: Type: text/plain, Size: 2890 bytes --]
On Thu, 2004-09-16 at 16:11 -0600, Thayne Harbaugh wrote:
Hi
>
> This patch makes gen_init_cpio generate the initramfs_data.cpio from a
> file which contains a list of entries: file, dir, nod. I swapped the
> order of filename/location for the file arguments so that it would be
> more uniform with the dir and nod tyes.
>
Attached is a simple script to generate a suitable initramfs_list for
use with gen_init_cpio from an external initramfs source directory, that
could be added to scripts/ if anybody thinks its useful and without
issues. Note the the description at the top of the file might need
some work from somebody more 'literate' than me.
Sample run:
-----
nosferatu linux-2.6.9-rc2-bk7 # ../scripts/gen_initramfs_list.sh /usr/src/initramfs/src/
dir /bin 755 0 0
file /bin/umount /usr/src/initramfs/src/bin/umount 755 0 0
file /bin/sleep /usr/src/initramfs/src/bin/sleep 755 0 0
file /bin/fstype /usr/src/initramfs/src/bin/fstype 755 0 0
file /bin/chroot /usr/src/initramfs/src/bin/chroot 755 0 0
file /bin/dd /usr/src/initramfs/src/bin/dd 755 0 0
file /bin/minips /usr/src/initramfs/src/bin/minips 755 0 0
file /bin/mkdir /usr/src/initramfs/src/bin/mkdir 755 0 0
file /bin/mount /usr/src/initramfs/src/bin/mount 755 0 0
file /bin/ln /usr/src/initramfs/src/bin/ln 755 0 0
file /bin/true /usr/src/initramfs/src/bin/true 755 0 0
file /bin/sh /usr/src/initramfs/src/bin/sh 755 0 0
file /bin/nuke /usr/src/initramfs/src/bin/nuke 755 0 0
file /bin/mkfifo /usr/src/initramfs/src/bin/mkfifo 755 0 0
file /bin/false /usr/src/initramfs/src/bin/false 755 0 0
file /bin/printf /usr/src/initramfs/src/bin/printf 755 0 0
dir /proc 755 0 0
dir /dev 755 0 0
nod /dev/console 600 0 5 c 5 1
dir /etc 755 0 0
file /etc/dmtab /usr/src/initramfs/src/etc/dmtab 644 0 0
dir /etc/udev 755 0 0
file /etc/udev/udev.conf /usr/src/initramfs/src/etc/udev/udev.conf 644 0 0
dir /etc/udev/rules.d 755 0 0
file /etc/udev/rules.d/30-sda.rules /usr/src/initramfs/src/etc/udev/rules.d/30-sda.rules 644 0 0
file /etc/udev/rules.d/40-dm.rules /usr/src/initramfs/src/etc/udev/rules.d/40-dm.rules 644 0 0
file /init /usr/src/initramfs/src/init 755 0 0
dir /sbin 755 0 0
file /sbin/run-init /usr/src/initramfs/src/sbin/run-init 755 0 0
file /sbin/dmsetup /usr/src/initramfs/src/sbin/dmsetup 755 0 0
file /sbin/pivot_root /usr/src/initramfs/src/sbin/pivot_root 755 0 0
file /sbin/kpartx /usr/src/initramfs/src/sbin/kpartx 755 0 0
file /sbin/udev /usr/src/initramfs/src/sbin/udev 755 0 0
file /sbin/udevstart /usr/src/initramfs/src/sbin/udevstart 755 0 0
file /sbin/devmap_name /usr/src/initramfs/src/sbin/devmap_name 755 0 0
dir /sys 755 0 0
dir /rootfs 755 0 0
nosferatu linux-2.6.9-rc2-bk7 # ../scripts/gen_initramfs_list.sh /usr/src/initramfs/src/ > usr/initramfs_list
nosferatu linux-2.6.9-rc2-bk7 #
-----
Regards,
--
Martin Schlemmer
[-- Attachment #1.2: gen_initramfs_list.sh --]
[-- Type: application/x-shellscript, Size: 1642 bytes --]
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2004-09-23 22:47 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-16 22:11 [PATCH] gen_init_cpio uses external file list Thayne Harbaugh
2004-09-16 23:06 ` Jeff Garzik
2004-09-16 22:53 ` Thayne Harbaugh
2004-09-17 0:16 ` Jeff Garzik
2004-09-17 1:36 ` [klibc] " H. Peter Anvin
2004-09-17 4:49 ` Sam Ravnborg
2004-09-17 22:38 ` Thayne Harbaugh
2004-09-23 22:40 ` gen_initramfs_list.sh (was: Re: [PATCH] gen_init_cpio uses external file list) [u] Martin Schlemmer [c]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox