diff mbox

Using directory as initrd

Message ID 20160117210413.GA30122@colin.search.kasperd.net (mailing list archive)
State New, archived
Headers show

Commit Message

Kasper Dupont Jan. 17, 2016, 9:04 p.m. UTC
I would like to use a directory as initrd file without
having to write it to an initrd file each time I have
changed anything in that directory.

I have written code to pipe an initrd directly from cpio
to qemu. Do you have any feedback on the attached patch?

Comments

KONRAD Frédéric Jan. 18, 2016, 9:45 a.m. UTC | #1
Hi Kasper,

The normal approach is to use git send email to send your patch on the list
instead of attaching the patch to the email so people can do inline comment.

You can use scripts/checkpatch.pl to check the coding style before sending.
(eg: you miss the signed off line and the description in the patch).

And better use the qemu master branch (you seems to be using qemu-2.0?)

Fred



Le 17/01/2016 22:04, Kasper Dupont a écrit :
> I would like to use a directory as initrd file without
> having to write it to an initrd file each time I have
> changed anything in that directory.
>
> I have written code to pipe an initrd directly from cpio
> to qemu. Do you have any feedback on the attached patch?
>
Kasper Dupont Feb. 7, 2016, 8:06 p.m. UTC | #2
On 18/01/16 10.45, KONRAD Frederic wrote:
> Hi Kasper,
> 
> The normal approach is to use git send email to send your patch on the list
> instead of attaching the patch to the email so people can do inline comment.
> 
> You can use scripts/checkpatch.pl to check the coding style before sending.
> (eg: you miss the signed off line and the description in the patch).
> 
> And better use the qemu master branch (you seems to be using qemu-2.0?)

Thank you for the feedback. I checked out the master branch
and updated a couple of lines to make the change work on
the master branch.

Now I have a commit of this change on the master branch,
but I cannot figure out which command it is you are
suggesting I should be using to mail the change.
diff mbox

Patch

diff -up qemu-2.0.0+dfsg/hw/core/loader.c.orig qemu-2.0.0+dfsg/hw/core/loader.c
--- qemu-2.0.0+dfsg/hw/core/loader.c.orig	2014-04-17 15:30:59.000000000 +0200
+++ qemu-2.0.0+dfsg/hw/core/loader.c	2016-01-17 19:38:01.505138214 +0100
@@ -137,6 +137,70 @@  void pstrcpy_targphys(const char *name,
     }
 }
 
+/* return the size or -1 if error */
+int load_initrd(const char *filename, uint8_t **addr)
+{
+    pid_t child = 0;
+    int fd, size = 0, buffer_size = 4096;
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return -1;
+
+    *addr = malloc(buffer_size);
+
+    while(*addr) {
+        int bytes_read = read(fd, (*addr) + size, buffer_size - size);
+
+        if (bytes_read == 0) {
+            close(fd);
+            if (child) {
+                waitpid(child, NULL, 0);
+            }
+            return size;
+        }
+
+        if (bytes_read > 0) {
+            size += bytes_read;
+        } else {
+            int pipefd[2];
+
+            if (errno != EISDIR)
+                return -1;
+
+            assert(!child);
+
+            if (pipe(pipefd))
+                return -1;
+
+            child = fork();
+            if (child == -1)
+                return -1;
+
+            if (!child) {
+                if(fchdir(fd))
+                    error(1, errno, "fchdir failed");
+                if(dup2(pipefd[1], 1) == -1)
+                    error(1, errno, "dup2 failed");
+                execlp("/bin/sh", "/bin/sh", "-c",
+                       "find . | cpio --quiet -R 0:0 -o -H newc",
+                       NULL);
+                error(1, errno, "/bin/sh");
+            }
+
+            close(fd);
+            close(pipefd[1]);
+            fd = pipefd[0];
+        }
+
+        if (size == buffer_size) {
+            buffer_size <<= 1;
+            *addr = realloc(*addr, buffer_size);
+        }
+    }
+
+    return -1;
+}
+
 /* A.OUT loader */
 
 struct exec
diff -up qemu-2.0.0+dfsg/hw/i386/pc.c.orig qemu-2.0.0+dfsg/hw/i386/pc.c
--- qemu-2.0.0+dfsg/hw/i386/pc.c.orig	2014-04-17 15:30:59.000000000 +0200
+++ qemu-2.0.0+dfsg/hw/i386/pc.c	2016-01-17 19:16:04.704258817 +0100
@@ -829,12 +829,13 @@  static void load_linux(FWCfgState *fw_cf
 
     /* load initrd */
     if (initrd_filename) {
+        uint8_t *initrd_load_buffer;
         if (protocol < 0x200) {
             fprintf(stderr, "qemu: linux kernel too old to load a ram disk\n");
             exit(1);
         }
 
-        initrd_size = get_image_size(initrd_filename);
+        initrd_size = load_initrd(initrd_filename, &initrd_load_buffer);
         if (initrd_size < 0) {
             fprintf(stderr, "qemu: error reading initrd %s: %s\n",
                     initrd_filename, strerror(errno));
@@ -844,7 +845,8 @@  static void load_linux(FWCfgState *fw_cf
         initrd_addr = (initrd_max-initrd_size) & ~4095;
 
         initrd_data = g_malloc(initrd_size);
-        load_image(initrd_filename, initrd_data);
+        memcpy(initrd_data, initrd_load_buffer, initrd_size);
+        free(initrd_load_buffer);
 
         fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
         fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
diff -up qemu-2.0.0+dfsg/include/hw/loader.h.orig qemu-2.0.0+dfsg/include/hw/loader.h
--- qemu-2.0.0+dfsg/include/hw/loader.h.orig	2014-04-17 15:30:59.000000000 +0200
+++ qemu-2.0.0+dfsg/include/hw/loader.h	2016-01-17 19:15:30.688236909 +0100
@@ -13,6 +13,7 @@ 
  */
 int get_image_size(const char *filename);
 int load_image(const char *filename, uint8_t *addr); /* deprecated */
+int load_initrd(const char *filename, uint8_t **addr);
 int load_image_targphys(const char *filename, hwaddr,
                         uint64_t max_sz);