WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [TOOLS] Uncompress and allocate memory fo

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [TOOLS] Uncompress and allocate memory for gzipped kernel and initrd images on
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 26 Oct 2006 20:50:12 +0000
Delivery-date: Thu, 26 Oct 2006 13:50:16 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Node ID 4a320d26fc24bc49ae24f31dec2bf006a9ddc7a8
# Parent  2041122e0c4a6df3cfce2691bf83d443dc2f698d
[TOOLS] Uncompress and allocate memory for gzipped kernel and initrd images on
the fly. We cannot rely on the length contained in the gzip trailer to determine
the length of the decompressed data because images have been observed which have
trailing junk.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
---
 tools/libxc/xc_linux_build.c |  105 ++++++++++++++++++++++++-------------------
 tools/libxc/xc_private.c     |   22 ---------
 tools/libxc/xg_private.c     |   65 ++++++++++++++++++--------
 tools/libxc/xg_private.h     |    2 
 4 files changed, 106 insertions(+), 88 deletions(-)

diff -r 2041122e0c4a -r 4a320d26fc24 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Thu Oct 26 15:08:20 2006 +0100
+++ b/tools/libxc/xc_linux_build.c      Thu Oct 26 16:56:16 2006 +0100
@@ -36,6 +36,11 @@
 
 struct initrd_info {
     enum { INITRD_none, INITRD_file, INITRD_mem } type;
+    /*
+     * .len must be filled in by the user for type==INITRD_mem. It is
+     * filled in by load_initrd() for INITRD_file and unused for
+     * INITRD_none.
+     */
     unsigned long len;
     union {
         gzFile file_handle;
@@ -134,30 +139,42 @@ static int load_initrd(int xc_handle, do
                 xen_pfn_t *phys_to_mach)
 {
     char page[PAGE_SIZE];
-    unsigned long pfn_start, pfn, nr_pages;
+    unsigned long pfn_start, pfn;
 
     if ( initrd->type == INITRD_none )
         return 0;
 
     pfn_start = physbase >> PAGE_SHIFT;
-    nr_pages  = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
-    for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
-    {
-        if ( initrd->type == INITRD_mem )
+
+    if ( initrd->type == INITRD_mem )
+    {
+        unsigned long nr_pages  = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+        for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
         {
             xc_copy_to_domain_page(
                 xc_handle, dom, phys_to_mach[pfn],
                 &initrd->u.mem_addr[(pfn - pfn_start) << PAGE_SHIFT]);
         }
-        else
-        {
-            if ( gzread(initrd->u.file_handle, page, PAGE_SIZE) == -1 )
+    }
+    else
+    {
+        int readlen;
+
+        pfn = pfn_start;
+        initrd->len = 0;
+
+        /* gzread returns 0 on EOF */
+        while ( (readlen = gzread(initrd->u.file_handle, page, PAGE_SIZE)) )
+        {
+            if ( readlen < 0 )
             {
                 PERROR("Error reading initrd image, could not");
                 return -EINVAL;
             }
-            xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn], page);
+
+            initrd->len += readlen;
+            xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn++], page);
         }
     }
 
@@ -485,10 +502,17 @@ static int setup_guest(int xc_handle,
     if ( rc != 0 )
         goto error_out;
 
-    dsi.v_start      = round_pgdown(dsi.v_start);
-    vinitrd_start    = round_pgup(dsi.v_end);
-    vinitrd_end      = vinitrd_start + initrd->len;
-    v_end            = round_pgup(vinitrd_end);
+    dsi.v_start = round_pgdown(dsi.v_start);
+    (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
+                           &dsi);
+
+    vinitrd_start = round_pgup(dsi.v_end);
+    if ( load_initrd(xc_handle, dom, initrd,
+                     vinitrd_start - dsi.v_start, page_array) )
+        goto error_out;
+
+    vinitrd_end    = vinitrd_start + initrd->len;
+    v_end          = round_pgup(vinitrd_end);
     start_info_mpa = (nr_pages - 3) << PAGE_SHIFT;
 
     /* Build firmware.  */
@@ -524,13 +548,6 @@ static int setup_guest(int xc_handle,
            _p(vinitrd_start),   _p(vinitrd_end),
            _p(dsi.v_start),     _p(v_end));
     IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
-
-    (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
-                           &dsi);
-
-    if ( load_initrd(xc_handle, dom, initrd,
-                     vinitrd_start - dsi.v_start, page_array) )
-        goto error_out;
 
     *pvke = dsi.v_kernentry;
 
@@ -728,6 +745,24 @@ static int setup_guest(int xc_handle,
     shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
                                            required_features);
 
+    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
+    {
+        PERROR("Could not allocate memory");
+        goto error_out;
+    }
+
+    if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
+    {
+        PERROR("Could not get the page frame list");
+        goto error_out;
+    }
+
+    rc = (load_funcs.loadimage)(image, image_size,
+                           xc_handle, dom, page_array,
+                           &dsi);
+    if ( rc != 0 )
+        goto error_out;
+
     /*
      * Why do we need this? The number of page-table frames depends on the
      * size of the bootstrap address space. But the size of the address space
@@ -741,9 +776,14 @@ static int setup_guest(int xc_handle,
         ERROR("End of mapped kernel image too close to end of memory");
         goto error_out;
     }
+
     vinitrd_start = v_end;
+    if ( load_initrd(xc_handle, dom, initrd,
+                     vinitrd_start - dsi.v_start, page_array) )
+        goto error_out;
     if ( !increment_ulong(&v_end, round_pgup(initrd->len)) )
         goto error_out;
+
     vphysmap_start = v_end;
     if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) )
         goto error_out;
@@ -844,28 +884,6 @@ static int setup_guest(int xc_handle,
                _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT));
         goto error_out;
     }
-
-    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
-    {
-        PERROR("Could not allocate memory");
-        goto error_out;
-    }
-
-    if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
-    {
-        PERROR("Could not get the page frame list");
-        goto error_out;
-    }
-
-    rc = (load_funcs.loadimage)(image, image_size,
-                           xc_handle, dom, page_array,
-                           &dsi);
-    if ( rc != 0 )
-        goto error_out;
-
-    if ( load_initrd(xc_handle, dom, initrd,
-                     vinitrd_start - dsi.v_start, page_array) )
-        goto error_out;
 
     /* setup page tables */
 #if defined(__i386__)
@@ -1350,7 +1368,6 @@ int xc_linux_build(int xc_handle,
             goto error_out;
         }
 
-        initrd_info.len = xc_get_filesz(fd);
         if ( (initrd_info.u.file_handle = gzdopen(fd, "rb")) == NULL )
         {
             PERROR("Could not allocate decompression state for initrd");
diff -r 2041122e0c4a -r 4a320d26fc24 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Thu Oct 26 15:08:20 2006 +0100
+++ b/tools/libxc/xc_private.c  Thu Oct 26 16:56:16 2006 +0100
@@ -344,28 +344,6 @@ int xc_clear_domain_page(int xc_handle,
     return 0;
 }
 
-unsigned long xc_get_filesz(int fd)
-{
-    uint16_t sig;
-    uint32_t _sz = 0;
-    unsigned long sz;
-
-    lseek(fd, 0, SEEK_SET);
-    if ( read(fd, &sig, sizeof(sig)) != sizeof(sig) )
-        return 0;
-    sz = lseek(fd, 0, SEEK_END);
-    if ( sig == 0x8b1f ) /* GZIP signature? */
-    {
-        lseek(fd, -4, SEEK_END);
-        if ( read(fd, &_sz, 4) != 4 )
-            return 0;
-        sz = _sz;
-    }
-    lseek(fd, 0, SEEK_SET);
-
-    return sz;
-}
-
 void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
                    int xch, uint32_t dom, xen_pfn_t *parray,
                    unsigned long vstart)
diff -r 2041122e0c4a -r 4a320d26fc24 tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c  Thu Oct 26 15:08:20 2006 +0100
+++ b/tools/libxc/xg_private.c  Thu Oct 26 16:56:16 2006 +0100
@@ -31,7 +31,7 @@ char *xc_read_image(const char *filename
 {
     int kernel_fd = -1;
     gzFile kernel_gfd = NULL;
-    char *image = NULL;
+    char *image = NULL, *tmp;
     unsigned int bytes;
 
     if ( (filename == NULL) || (size == NULL) )
@@ -43,33 +43,58 @@ char *xc_read_image(const char *filename
         goto out;
     }
 
-    if ( (*size = xc_get_filesz(kernel_fd)) == 0 )
-    {
-        PERROR("Could not read kernel image");
-        goto out;
-    }
-
     if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
     {
         PERROR("Could not allocate decompression state for state file");
         goto out;
     }
 
-    if ( (image = malloc(*size)) == NULL )
-    {
-        PERROR("Could not allocate memory for kernel image");
-        goto out;
-    }
-
-    if ( (bytes = gzread(kernel_gfd, image, *size)) != *size )
-    {
-        PERROR("Error reading kernel image, could not"
-               " read the whole image (%d != %ld).", bytes, *size);
-        free(image);
-        image = NULL;
-    }
+    *size = 0;
+
+#define CHUNK 1*1024*1024
+    while(1)
+    {
+           if ( (tmp = realloc(image, *size + CHUNK)) == NULL )
+           {
+                   PERROR("Could not allocate memory for kernel image");
+                   free(image);
+                   image = NULL;
+                   goto out;
+           }
+           image = tmp;
+
+           bytes = gzread(kernel_gfd, image + *size, CHUNK);
+           switch (bytes)
+           {
+           case -1:
+                   PERROR("Error reading kernel image");
+                   free(image);
+                   image = NULL;
+                   goto out;
+           case 0: /* EOF */
+                   goto out;
+           default:
+                   *size += bytes;
+                   break;
+           }
+    }
+#undef CHUNK
 
  out:
+    if ( *size == 0 )
+    {
+           PERROR("Could not read kernel image");
+           free(image);
+           image = NULL;
+    }
+    else if ( image )
+    {
+           /* Shrink allocation to fit image. */
+           tmp = realloc(image, *size);
+           if ( tmp )
+                   image = tmp;
+    }
+
     if ( kernel_gfd != NULL )
         gzclose(kernel_gfd);
     else if ( kernel_fd >= 0 )
diff -r 2041122e0c4a -r 4a320d26fc24 tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Thu Oct 26 15:08:20 2006 +0100
+++ b/tools/libxc/xg_private.h  Thu Oct 26 16:56:16 2006 +0100
@@ -193,8 +193,6 @@ int xc_copy_to_domain_page(int xc_handle
 int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
                             unsigned long dst_pfn, const char *src_page);
 
-unsigned long xc_get_filesz(int fd);
-
 void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
                    int xch, uint32_t dom, xen_pfn_t *parray,
                    unsigned long vstart);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [TOOLS] Uncompress and allocate memory for gzipped kernel and initrd images on, Xen patchbot-unstable <=