ia64/xen-unstable

changeset 934:7c889292df89

bitkeeper revision 1.594 (3fb210e1h9kxCYdiaHlo-5FLn1jxLg)

xi_build.c, Makefile:
xi_build will now accept a gzipped kernel image.
author kaf24@scramble.cl.cam.ac.uk
date Wed Nov 12 10:52:17 2003 +0000 (2003-11-12)
parents baade9a49791
children 87d895822ab8
files tools/internal/Makefile tools/internal/xi_build.c
line diff
     1.1 --- a/tools/internal/Makefile	Tue Nov 11 12:10:54 2003 +0000
     1.2 +++ b/tools/internal/Makefile	Wed Nov 12 10:52:17 2003 +0000
     1.3 @@ -40,7 +40,7 @@ rpm: all
     1.4  	mv staging/i386/*.rpm .
     1.5  	rm -rf staging
     1.6  
     1.7 -xi_save_linux xi_restore_linux: %: %.c $(HDRS) Makefile
     1.8 +xi_build xi_save_linux xi_restore_linux: %: %.c $(HDRS) Makefile
     1.9  	$(CC) $(CFLAGS) -lz -o $@ $<
    1.10  
    1.11  %: %.c $(HDRS) Makefile
     2.1 --- a/tools/internal/xi_build.c	Tue Nov 11 12:10:54 2003 +0000
     2.2 +++ b/tools/internal/xi_build.c	Wed Nov 12 10:52:17 2003 +0000
     2.3 @@ -2,6 +2,8 @@
     2.4  #include "dom0_defs.h"
     2.5  #include "mem_defs.h"
     2.6  
     2.7 +#include <zlib.h>
     2.8 +
     2.9  /* This string is written to the head of every guest kernel image. */
    2.10  #define GUEST_SIG   "XenoGues"
    2.11  #define SIG_LEN    8
    2.12 @@ -69,29 +71,12 @@ static int send_pgupdates(mmu_update_t *
    2.13  }
    2.14  
    2.15  /* Read the kernel header, extracting the image size and load address. */
    2.16 -static int read_kernel_header(int fd, long dom_size, 
    2.17 -                              unsigned long * load_addr, size_t * ksize)
    2.18 +static int read_kernel_header(gzFile gfd, long dom_size, 
    2.19 +                              unsigned long *load_addr)
    2.20  {
    2.21 -    char signature[8];
    2.22 -    char status[1024];
    2.23 -    struct stat stat;
    2.24 -    
    2.25 -    if ( fstat(fd, &stat) < 0 )
    2.26 -    {
    2.27 -        PERROR("Cannot stat the kernel image");
    2.28 -        return -1;
    2.29 -    }
    2.30 +    char signature[SIG_LEN];
    2.31  
    2.32 -    /* Double the kernel image size to account for dynamic memory usage etc. */
    2.33 -    if ( (stat.st_size * 2) > (dom_size << 10) )
    2.34 -    {
    2.35 -        sprintf(status, "Kernel image size %ld larger than requested "
    2.36 -                "domain size %ld\n Terminated.\n", stat.st_size, dom_size);
    2.37 -        ERROR(status);
    2.38 -        return -1;
    2.39 -    }
    2.40 -    
    2.41 -    read(fd, signature, SIG_LEN);
    2.42 +    gzread(gfd, signature, SIG_LEN);
    2.43      if ( strncmp(signature, GUEST_SIG, SIG_LEN) )
    2.44      {
    2.45          ERROR("Kernel image does not contain required signature.\n"
    2.46 @@ -100,21 +85,7 @@ static int read_kernel_header(int fd, lo
    2.47      }
    2.48  
    2.49      /* Read the load address which immediately follows the Xeno signature. */
    2.50 -    read(fd, load_addr, sizeof(unsigned long));
    2.51 -
    2.52 -    if ( (*load_addr & (PAGE_SIZE-1)) != 0 )
    2.53 -    {
    2.54 -        ERROR("We can only deal with page-aligned load addresses");
    2.55 -        return -1;
    2.56 -    }
    2.57 -
    2.58 -    if ( (*load_addr + (dom_size << 10)) > HYPERVISOR_VIRT_START )
    2.59 -    {
    2.60 -        ERROR("Cannot map all domain memory without hitting Xen space");
    2.61 -        return -1;
    2.62 -    }
    2.63 -
    2.64 -    *ksize = stat.st_size - SIG_LEN - sizeof(unsigned long);
    2.65 +    gzread(gfd, load_addr, sizeof(unsigned long));
    2.66  
    2.67      return 0;
    2.68  }
    2.69 @@ -159,8 +130,8 @@ static int copy_to_domain_page(unsigned 
    2.70  }
    2.71  
    2.72  static int setup_guestos(
    2.73 -    int dom, int kernel_fd, int initrd_fd, unsigned long tot_pages,
    2.74 -    unsigned long virt_load_addr, size_t ksize, 
    2.75 +    int dom, gzFile kernel_gfd, int initrd_fd, unsigned long tot_pages,
    2.76 +    unsigned long virt_load_addr, 
    2.77      dom0_builddomain_t *builddomain, int argc, char **argv, int args_start,
    2.78      unsigned long shared_info_frame)
    2.79  {
    2.80 @@ -177,6 +148,7 @@ static int setup_guestos(
    2.81      start_info_t *start_info;
    2.82      shared_info_t *shared_info;
    2.83      int cmd_len;
    2.84 +    unsigned long ksize;
    2.85  
    2.86      memset(builddomain, 0, sizeof(*builddomain));
    2.87  
    2.88 @@ -198,19 +170,27 @@ static int setup_guestos(
    2.89          goto error_out;
    2.90      }
    2.91  
    2.92 -    /* Load the guest OS image. */
    2.93 -    for ( i = 0; i < ksize; i += PAGE_SIZE )
    2.94 +    /* Load the guest OS image. Let it take no more than 1/2 memory.*/
    2.95 +    for ( i = 0; i < ((tot_pages/2)*PAGE_SIZE); i += PAGE_SIZE )
    2.96      {
    2.97          char page[PAGE_SIZE];
    2.98 -        int size = ((ksize-i) < PAGE_SIZE) ? (ksize-i) : PAGE_SIZE;
    2.99 -        if ( read(kernel_fd, page, size) != size )
   2.100 +        int size;
   2.101 +        if ( (size = gzread(kernel_gfd, page, PAGE_SIZE)) == -1 )
   2.102          {
   2.103              PERROR("Error reading kernel image, could not"
   2.104                     " read the whole image.");
   2.105              goto error_out;
   2.106 -        } 
   2.107 +        }
   2.108 +        if ( size == 0 )
   2.109 +            goto kernel_copied;
   2.110          copy_to_domain_page(page_array[i>>PAGE_SHIFT], page);
   2.111      }
   2.112 +    ERROR("Kernel too big to safely fit in domain memory");
   2.113 +    goto error_out;
   2.114 +
   2.115 + kernel_copied:
   2.116 +    /* ksize is kernel-image size rounded up to a page boundary. */
   2.117 +    ksize = i;
   2.118  
   2.119      /* Load the initial ramdisk image. */
   2.120      if ( initrd_fd >= 0 )
   2.121 @@ -224,17 +204,16 @@ static int setup_guestos(
   2.122              goto error_out;
   2.123          }
   2.124          isize = stat.st_size;
   2.125 -        if ( ((isize + ksize) * 2) > (tot_pages << PAGE_SHIFT) )
   2.126 +        if ( (isize + ksize) > ((tot_pages/2) * PAGE_SIZE) )
   2.127          {
   2.128              ERROR("Kernel + initrd too big to safely fit in domain memory");
   2.129              goto error_out;
   2.130          }
   2.131  
   2.132 -        /* 'i' is 'ksize' rounded up to a page boundary. */
   2.133 -        initrd_addr = virt_load_addr + i;
   2.134 +        initrd_addr = virt_load_addr + ksize;
   2.135          initrd_len  = isize;
   2.136  
   2.137 -        for ( j = 0; j < isize; j += PAGE_SIZE, i += PAGE_SIZE )
   2.138 +        for ( j = 0, i = ksize; j < isize; j += PAGE_SIZE, i += PAGE_SIZE )
   2.139          {
   2.140              char page[PAGE_SIZE];
   2.141              int size = ((isize-j) < PAGE_SIZE) ? (isize-j) : PAGE_SIZE;
   2.142 @@ -376,15 +355,11 @@ static int setup_guestos(
   2.143  
   2.144  int main(int argc, char **argv)
   2.145  {
   2.146 -    /*
   2.147 -     * NB. 'ksize' is the size in bytes of the main kernel image. It excludes
   2.148 -     * the 8-byte signature and 4-byte load address.
   2.149 -     */
   2.150 -    size_t ksize;
   2.151      dom0_op_t launch_op, op;
   2.152      unsigned long load_addr;
   2.153      long tot_pages;
   2.154      int kernel_fd, initrd_fd = -1;
   2.155 +    gzFile kernel_gfd;
   2.156      int args_start = 4;
   2.157      char initrd_name[1024];
   2.158      int domain_id;
   2.159 @@ -421,12 +396,30 @@ int main(int argc, char **argv)
   2.160          return 1;
   2.161      }
   2.162  
   2.163 -    rc = read_kernel_header(kernel_fd,
   2.164 +    if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
   2.165 +    {
   2.166 +        PERROR("Could not allocate decompression state for state file");
   2.167 +        return 1;
   2.168 +    }
   2.169 +
   2.170 +    rc = read_kernel_header(kernel_gfd,
   2.171                              tot_pages << (PAGE_SHIFT - 10), 
   2.172 -                            &load_addr, &ksize);
   2.173 +                            &load_addr);
   2.174      if ( rc < 0 )
   2.175          return 1;
   2.176      
   2.177 +    if ( (load_addr & (PAGE_SIZE-1)) != 0 )
   2.178 +    {
   2.179 +        ERROR("We can only deal with page-aligned load addresses");
   2.180 +        return -1;
   2.181 +    }
   2.182 +
   2.183 +    if ( (load_addr + (tot_pages << PAGE_SHIFT)) > HYPERVISOR_VIRT_START )
   2.184 +    {
   2.185 +        ERROR("Cannot map all domain memory without hitting Xen space");
   2.186 +        return -1;
   2.187 +    }
   2.188 +
   2.189      if( (argc > args_start) && 
   2.190          (strncmp("initrd=", argv[args_start], 7) == 0) )
   2.191      {
   2.192 @@ -457,8 +450,8 @@ int main(int argc, char **argv)
   2.193          return 1;
   2.194      }
   2.195  
   2.196 -    if ( setup_guestos(domain_id, kernel_fd, initrd_fd, tot_pages,
   2.197 -                       load_addr, ksize, &launch_op.u.builddomain,
   2.198 +    if ( setup_guestos(domain_id, kernel_gfd, initrd_fd, tot_pages,
   2.199 +                       load_addr, &launch_op.u.builddomain,
   2.200                         argc, argv, args_start, 
   2.201                         op.u.getdomaininfo.shared_info_frame) < 0 )
   2.202      {
   2.203 @@ -468,7 +461,7 @@ int main(int argc, char **argv)
   2.204  
   2.205      if ( initrd_fd >= 0 )
   2.206          close(initrd_fd);
   2.207 -    close(kernel_fd);
   2.208 +    gzclose(kernel_gfd);
   2.209  
   2.210      ctxt = &launch_op.u.builddomain.ctxt;
   2.211