ia64/xen-unstable

changeset 9204:899532500ada

Add a parallel set of APIs to the domain builders to allow images and
ramdisks to be passed via buffer, rather than via file. This allows
usage of the underlying domain building routines in "file-challenged"
enviroments.

Specifically, xc_linux_build_mem is the buffer oriented version of the
file-oriented xc_linux_build. Likewise, xc_hvm_build_mem is the
buffer oriented analog of the file based xc_hvm_build.

Signed-off-by: Ben Thomas (bthomas@virtualiron.com)
author kaf24@firebug.cl.cam.ac.uk
date Thu Mar 09 13:00:38 2006 +0100 (2006-03-09)
parents 5ea87acc07dc
children a1fcee3b2abe
files tools/libxc/xc_hvm_build.c tools/libxc/xc_ia64_stubs.c tools/libxc/xc_linux_build.c tools/libxc/xenguest.h tools/libxc/xg_private.c tools/libxc/xg_private.h
line diff
     1.1 --- a/tools/libxc/xc_hvm_build.c	Thu Mar 09 11:20:31 2006 +0100
     1.2 +++ b/tools/libxc/xc_hvm_build.c	Thu Mar 09 13:00:38 2006 +0100
     1.3 @@ -338,25 +338,30 @@ static int setup_guest(int xc_handle,
     1.4      return -1;
     1.5  }
     1.6  
     1.7 -int xc_hvm_build(int xc_handle,
     1.8 -                 uint32_t domid,
     1.9 -                 int memsize,
    1.10 -                 const char *image_name,
    1.11 -                 unsigned int vcpus,
    1.12 -                 unsigned int pae,
    1.13 -                 unsigned int acpi,
    1.14 -                 unsigned int apic,
    1.15 -                 unsigned int store_evtchn,
    1.16 -                 unsigned long *store_mfn)
    1.17 +static int xc_hvm_build_internal(int xc_handle,
    1.18 +                                 uint32_t domid,
    1.19 +                                 int memsize,
    1.20 +                                 char *image,
    1.21 +                                 unsigned long image_size,
    1.22 +                                 unsigned int vcpus,
    1.23 +                                 unsigned int pae,
    1.24 +                                 unsigned int acpi,
    1.25 +                                 unsigned int apic,
    1.26 +                                 unsigned int store_evtchn,
    1.27 +                                 unsigned long *store_mfn)
    1.28  {
    1.29      dom0_op_t launch_op, op;
    1.30      int rc, i;
    1.31      vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
    1.32      unsigned long nr_pages;
    1.33 -    char         *image = NULL;
    1.34 -    unsigned long image_size;
    1.35      xen_capabilities_info_t xen_caps;
    1.36  
    1.37 +    if ( (image == NULL) || (image_size == 0) )
    1.38 +    {
    1.39 +        ERROR("Image required");
    1.40 +        goto error_out;
    1.41 +    }
    1.42 +
    1.43      if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 )
    1.44      {
    1.45          PERROR("Failed to get xen version info");
    1.46 @@ -376,9 +381,6 @@ int xc_hvm_build(int xc_handle,
    1.47          goto error_out;
    1.48      }
    1.49  
    1.50 -    if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL )
    1.51 -        goto error_out;
    1.52 -
    1.53      if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
    1.54      {
    1.55          PERROR("%s: ctxt mlock failed", __func__);
    1.56 @@ -405,8 +407,6 @@ int xc_hvm_build(int xc_handle,
    1.57          goto error_out;
    1.58      }
    1.59  
    1.60 -    free(image);
    1.61 -
    1.62      /* FPU is set up to default initial state. */
    1.63      memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
    1.64  
    1.65 @@ -450,7 +450,6 @@ int xc_hvm_build(int xc_handle,
    1.66      return rc;
    1.67  
    1.68   error_out:
    1.69 -    free(image);
    1.70      return -1;
    1.71  }
    1.72  
    1.73 @@ -580,6 +579,92 @@ loadelfimage(
    1.74      return 0;
    1.75  }
    1.76  
    1.77 +/* xc_hvm_build
    1.78 + *
    1.79 + * Create a domain for a virtualized Linux, using files/filenames
    1.80 + *
    1.81 + */
    1.82 +
    1.83 +int xc_hvm_build(int xc_handle,
    1.84 +                 uint32_t domid,
    1.85 +                 int memsize,
    1.86 +                 const char *image_name,
    1.87 +                 unsigned int vcpus,
    1.88 +                 unsigned int pae,
    1.89 +                 unsigned int acpi,
    1.90 +                 unsigned int apic,
    1.91 +                 unsigned int store_evtchn,
    1.92 +                 unsigned long *store_mfn)
    1.93 +{
    1.94 +    char *image;
    1.95 +    int  sts;
    1.96 +    unsigned long image_size;
    1.97 +
    1.98 +    if ( (image_name == NULL) ||
    1.99 +         ((image = xc_read_image(image_name, &image_size)) == NULL) )
   1.100 +        return -1;
   1.101 +
   1.102 +    sts = xc_hvm_build_internal(xc_handle, domid, memsize,
   1.103 +                                image, image_size,
   1.104 +                                vcpus, pae, acpi, apic,
   1.105 +                                store_evtchn, store_mfn);
   1.106 +
   1.107 +    free(image);
   1.108 +
   1.109 +    return sts;
   1.110 +}
   1.111 +
   1.112 +/* xc_hvm_build_mem
   1.113 + *
   1.114 + * Create a domain for a virtualized Linux, using buffers
   1.115 + *
   1.116 + */
   1.117 +
   1.118 +int xc_hvm_build_mem(int xc_handle,
   1.119 +                     uint32_t domid,
   1.120 +                     int memsize,
   1.121 +                     char *image_buffer,
   1.122 +                     unsigned long image_size,
   1.123 +                     unsigned int vcpus,
   1.124 +                     unsigned int pae,
   1.125 +                     unsigned int acpi,
   1.126 +                     unsigned int apic,
   1.127 +                     unsigned int store_evtchn,
   1.128 +                     unsigned long *store_mfn)
   1.129 +{
   1.130 +    int           sts;
   1.131 +    unsigned long img_len;
   1.132 +    char         *img;
   1.133 +
   1.134 +    /* Validate that there is a kernel buffer */
   1.135 +
   1.136 +    if ( (image_buffer == NULL) || (image_size == 0) )
   1.137 +    {
   1.138 +        ERROR("kernel image buffer not present");
   1.139 +        return -EINVAL;
   1.140 +    }
   1.141 +
   1.142 +    img = xc_inflate_buffer(image_buffer, image_size, &img_len);
   1.143 +    if (img == NULL)
   1.144 +    {
   1.145 +        ERROR("unable to inflate ram disk buffer");
   1.146 +        return -1;
   1.147 +    }
   1.148 +
   1.149 +    sts = xc_hvm_build_internal(xc_handle, domid, memsize,
   1.150 +                                img, img_len,
   1.151 +                                vcpus, pae, acpi, apic,
   1.152 +                                store_evtchn, store_mfn);
   1.153 +
   1.154 +    /* xc_inflate_buffer may return the original buffer pointer (for
   1.155 +       for already inflated buffers), so exercise some care in freeing */
   1.156 +
   1.157 +    if ( (img != NULL) && (img != image_buffer) )
   1.158 +        free(img);
   1.159 +
   1.160 +    return sts;
   1.161 +}
   1.162 +
   1.163  /*
   1.164   * Local variables:
   1.165   * mode: C
     2.1 --- a/tools/libxc/xc_ia64_stubs.c	Thu Mar 09 11:20:31 2006 +0100
     2.2 +++ b/tools/libxc/xc_ia64_stubs.c	Thu Mar 09 13:00:38 2006 +0100
     2.3 @@ -658,7 +658,7 @@ int xc_hvm_build(int xc_handle,
     2.4          goto error_out;
     2.5      }
     2.6  
     2.7 -    if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL ){
     2.8 +    if ( (image = xc_read_image(image_name, &image_size)) == NULL ){
     2.9          PERROR("Could not read guest firmware image %s",image_name);
    2.10          goto error_out;
    2.11      }
     3.1 --- a/tools/libxc/xc_linux_build.c	Thu Mar 09 11:20:31 2006 +0100
     3.2 +++ b/tools/libxc/xc_linux_build.c	Thu Mar 09 13:00:38 2006 +0100
     3.3 @@ -406,8 +406,8 @@ extern unsigned long xc_ia64_fpsr_defaul
     3.4  
     3.5  static int setup_guest(int xc_handle,
     3.6                         uint32_t dom,
     3.7 -                       char *image, unsigned long image_size,
     3.8 -                       gzFile initrd_gfd, unsigned long initrd_len,
     3.9 +                       const char *image, unsigned long image_size,
    3.10 +                       char *initrd, unsigned long initrd_len,
    3.11                         unsigned long nr_pages,
    3.12                         unsigned long *pvsi, unsigned long *pvke,
    3.13                         unsigned long *pvss, vcpu_guest_context_t *ctxt,
    3.14 @@ -472,24 +472,18 @@ static int setup_guest(int xc_handle,
    3.15      (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
    3.16                             &dsi);
    3.17  
    3.18 -    /* Load the initial ramdisk image. */
    3.19 +    /* Load the initial ramdisk image, if present */
    3.20      if ( initrd_len != 0 )
    3.21      {
    3.22 -        for ( i = (vinitrd_start - dsi.v_start);
    3.23 -              i < (vinitrd_end - dsi.v_start); i += PAGE_SIZE )
    3.24 -        {
    3.25 -            char page[PAGE_SIZE];
    3.26 -            if ( gzread(initrd_gfd, page, PAGE_SIZE) == -1 )
    3.27 -            {
    3.28 -                PERROR("Error reading initrd image, could not");
    3.29 -                goto error_out;
    3.30 -            }
    3.31 +        /* Pages are not contiguous, so do the copy one page at a time */
    3.32 +        for ( i = (vinitrd_start - dsi.v_start), offset = 0; 
    3.33 +              i < (vinitrd_end - dsi.v_start);
    3.34 +              i += PAGE_SIZE, offset += PAGE_SIZE )
    3.35              xc_copy_to_domain_page(xc_handle, dom,
    3.36 -                                   page_array[i>>PAGE_SHIFT], page);
    3.37 -        }
    3.38 +                                   page_array[i>>PAGE_SHIFT],
    3.39 +                                   &initrd[offset]);
    3.40      }
    3.41  
    3.42 -
    3.43      *pvke = dsi.v_kernentry;
    3.44  
    3.45      /* Now need to retrieve machine pfn for system pages:
    3.46 @@ -518,7 +512,7 @@ static int setup_guest(int xc_handle,
    3.47      start_info->store_evtchn = store_evtchn;
    3.48      start_info->console_mfn   = nr_pages - 1;
    3.49      start_info->console_evtchn = console_evtchn;
    3.50 -    start_info->nr_pages       = nr_pages;	// FIXME?: nr_pages - 2 ????
    3.51 +    start_info->nr_pages       = nr_pages; // FIXME?: nr_pages - 2 ????
    3.52      if ( initrd_len != 0 )
    3.53      {
    3.54          ctxt->initrd.start    = vinitrd_start;
    3.55 @@ -546,8 +540,8 @@ static int setup_guest(int xc_handle,
    3.56  #else /* x86 */
    3.57  static int setup_guest(int xc_handle,
    3.58                         uint32_t dom,
    3.59 -                       char *image, unsigned long image_size,
    3.60 -                       gzFile initrd_gfd, unsigned long initrd_len,
    3.61 +                       const char *image, unsigned long image_size,
    3.62 +                       char *initrd, unsigned long initrd_len,
    3.63                         unsigned long nr_pages,
    3.64                         unsigned long *pvsi, unsigned long *pvke,
    3.65                         unsigned long *pvss, vcpu_guest_context_t *ctxt,
    3.66 @@ -592,13 +586,13 @@ static int setup_guest(int xc_handle,
    3.67      unsigned long shadow_mode_enabled;
    3.68      uint32_t supported_features[XENFEAT_NR_SUBMAPS] = { 0, };
    3.69  
    3.70 -    rc = probeimageformat(image, image_size, &load_funcs);
    3.71 +    rc = probeimageformat((char *)image, (unsigned long)image_size, &load_funcs);
    3.72      if ( rc != 0 )
    3.73          goto error_out;
    3.74  
    3.75      memset(&dsi, 0, sizeof(struct domain_setup_info));
    3.76  
    3.77 -    rc = (load_funcs.parseimage)(image, image_size, &dsi);
    3.78 +    rc = (load_funcs.parseimage)((char *)image, (unsigned long)image_size, &dsi);
    3.79      if ( rc != 0 )
    3.80          goto error_out;
    3.81  
    3.82 @@ -706,7 +700,8 @@ static int setup_guest(int xc_handle,
    3.83          goto error_out;
    3.84      }
    3.85  
    3.86 -    (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
    3.87 +    (load_funcs.loadimage)((char *)image, image_size,
    3.88 +                           xc_handle, dom, page_array,
    3.89                             &dsi);
    3.90  
    3.91      /* Parse and validate kernel features. */
    3.92 @@ -738,21 +733,17 @@ static int setup_guest(int xc_handle,
    3.93  
    3.94      shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap, required_features);
    3.95  
    3.96 -    /* Load the initial ramdisk image. */
    3.97 +    /* Load the initial ramdisk image, if present. */
    3.98      if ( initrd_len != 0 )
    3.99      {
   3.100 -        for ( i = (vinitrd_start - dsi.v_start); 
   3.101 -              i < (vinitrd_end - dsi.v_start); i += PAGE_SIZE )
   3.102 -        {
   3.103 -            char page[PAGE_SIZE];
   3.104 -            if ( gzread(initrd_gfd, page, PAGE_SIZE) == -1 )
   3.105 -            {
   3.106 -                PERROR("Error reading initrd image, could not");
   3.107 -                goto error_out;
   3.108 -            }
   3.109 +        int offset;
   3.110 +        /* Pages are not contiguous, so do the inflation a page at a time. */
   3.111 +        for ( i = (vinitrd_start - dsi.v_start), offset = 0;
   3.112 +              i < (vinitrd_end - dsi.v_start);
   3.113 +              i += PAGE_SIZE, offset += PAGE_SIZE )
   3.114              xc_copy_to_domain_page(xc_handle, dom,
   3.115 -                                   page_array[i>>PAGE_SHIFT], page);
   3.116 -        }
   3.117 +                                   page_array[i>>PAGE_SHIFT],
   3.118 +                                   &initrd[offset]);
   3.119      }
   3.120  
   3.121      /* setup page tables */
   3.122 @@ -966,27 +957,25 @@ static int setup_guest(int xc_handle,
   3.123  }
   3.124  #endif
   3.125  
   3.126 -int xc_linux_build(int xc_handle,
   3.127 -                   uint32_t domid,
   3.128 -                   const char *image_name,
   3.129 -                   const char *ramdisk_name,
   3.130 -                   const char *cmdline,
   3.131 -                   const char *features,
   3.132 -                   unsigned long flags,
   3.133 -                   unsigned int store_evtchn,
   3.134 -                   unsigned long *store_mfn,
   3.135 -                   unsigned int console_evtchn,
   3.136 -                   unsigned long *console_mfn)
   3.137 +static int xc_linux_build_internal(int xc_handle,
   3.138 +                                   uint32_t domid,
   3.139 +                                   const char *image,
   3.140 +                                   unsigned long image_size,
   3.141 +                                   char *initrd,
   3.142 +                                   unsigned long initrd_len,
   3.143 +                                   const char *cmdline,
   3.144 +                                   const char *features,
   3.145 +                                   unsigned long flags,
   3.146 +                                   unsigned int store_evtchn,
   3.147 +                                   unsigned long *store_mfn,
   3.148 +                                   unsigned int console_evtchn,
   3.149 +                                   unsigned long *console_mfn)
   3.150  {
   3.151      dom0_op_t launch_op;
   3.152      DECLARE_DOM0_OP;
   3.153 -    int initrd_fd = -1;
   3.154 -    gzFile initrd_gfd = NULL;
   3.155      int rc, i;
   3.156      vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
   3.157      unsigned long nr_pages;
   3.158 -    char         *image = NULL;
   3.159 -    unsigned long image_size, initrd_size=0;
   3.160      unsigned long vstartinfo_start, vkern_entry, vstack_start;
   3.161      uint32_t      features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
   3.162  
   3.163 @@ -1005,26 +994,6 @@ int xc_linux_build(int xc_handle,
   3.164          goto error_out;
   3.165      }
   3.166  
   3.167 -    if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL )
   3.168 -        goto error_out;
   3.169 -
   3.170 -    if ( (ramdisk_name != NULL) && (strlen(ramdisk_name) != 0) )
   3.171 -    {
   3.172 -        if ( (initrd_fd = open(ramdisk_name, O_RDONLY)) < 0 )
   3.173 -        {
   3.174 -            PERROR("Could not open the initial ramdisk image");
   3.175 -            goto error_out;
   3.176 -        }
   3.177 -
   3.178 -        initrd_size = xc_get_filesz(initrd_fd);
   3.179 -
   3.180 -        if ( (initrd_gfd = gzdopen(initrd_fd, "rb")) == NULL )
   3.181 -        {
   3.182 -            PERROR("Could not allocate decompression state for initrd");
   3.183 -            goto error_out;
   3.184 -        }
   3.185 -    }
   3.186 -
   3.187  #ifdef VALGRIND
   3.188      memset(&st_ctxt, 0, sizeof(st_ctxt));
   3.189  #endif
   3.190 @@ -1047,7 +1016,8 @@ int xc_linux_build(int xc_handle,
   3.191      memset(ctxt, 0, sizeof(*ctxt));
   3.192  
   3.193      if ( setup_guest(xc_handle, domid, image, image_size, 
   3.194 -                     initrd_gfd, initrd_size, nr_pages, 
   3.195 +                     initrd, initrd_len,
   3.196 +                     nr_pages, 
   3.197                       &vstartinfo_start, &vkern_entry,
   3.198                       &vstack_start, ctxt, cmdline,
   3.199                       op.u.getdomaininfo.shared_info_frame,
   3.200 @@ -1059,12 +1029,6 @@ int xc_linux_build(int xc_handle,
   3.201          goto error_out;
   3.202      }
   3.203  
   3.204 -    if ( initrd_fd >= 0 )
   3.205 -        close(initrd_fd);
   3.206 -    if ( initrd_gfd )
   3.207 -        gzclose(initrd_gfd);
   3.208 -    free(image);
   3.209 -
   3.210  #ifdef __ia64__
   3.211      /* based on new_thread in xen/arch/ia64/domain.c */
   3.212      ctxt->flags = 0;
   3.213 @@ -1150,12 +1114,114 @@ int xc_linux_build(int xc_handle,
   3.214      return rc;
   3.215  
   3.216   error_out:
   3.217 -    if ( initrd_gfd != NULL )
   3.218 -        gzclose(initrd_gfd);
   3.219 -    else if ( initrd_fd >= 0 )
   3.220 -        close(initrd_fd);
   3.221 +    return -1;
   3.222 +}
   3.223 +
   3.224 +int xc_linux_build_mem(int xc_handle,
   3.225 +                       uint32_t domid,
   3.226 +                       char *image_buffer,
   3.227 +                       unsigned long image_size,
   3.228 +                       char *initrd,
   3.229 +                       unsigned long initrd_len,
   3.230 +                       const char *cmdline,
   3.231 +                       const char *features,
   3.232 +                       unsigned long flags,
   3.233 +                       unsigned int store_evtchn,
   3.234 +                       unsigned long *store_mfn,
   3.235 +                       unsigned int console_evtchn,
   3.236 +                       unsigned long *console_mfn)
   3.237 +{
   3.238 +    int            sts;
   3.239 +    char          *img_buf, *ram_buf;
   3.240 +    unsigned long  img_len, ram_len;
   3.241 +
   3.242 +    /* A kernel buffer is required */
   3.243 +    if ( (image_buffer == NULL) || (image_size == 0) )
   3.244 +    {
   3.245 +        ERROR("kernel image buffer not present");
   3.246 +        return EINVAL;
   3.247 +    }
   3.248 +
   3.249 +    /* If it's gzipped, inflate it;  otherwise, use as is */
   3.250 +    /* xc_inflate_buffer may return the same buffer pointer if */
   3.251 +    /* the buffer is already inflated */
   3.252 +    img_buf = xc_inflate_buffer(image_buffer, image_size, &img_len);
   3.253 +    if ( img_buf == NULL )
   3.254 +    {
   3.255 +        ERROR("unable to inflate kernel image buffer");
   3.256 +        return EFAULT;
   3.257 +    }
   3.258 +
   3.259 +    /* RAM disks are optional; if we get one, inflate it */
   3.260 +    if ( initrd != NULL )
   3.261 +    {
   3.262 +        ram_buf = xc_inflate_buffer(initrd, initrd_len, &ram_len);
   3.263 +        if ( ram_buf == NULL )
   3.264 +        {
   3.265 +            ERROR("unable to inflate ram disk buffer");
   3.266 +            sts = -1;
   3.267 +            goto out;
   3.268 +        }
   3.269 +    }
   3.270 +    else
   3.271 +    {
   3.272 +        ram_buf = initrd;
   3.273 +        ram_len = initrd_len;
   3.274 +    }
   3.275 +
   3.276 +    sts = xc_linux_build_internal(xc_handle, domid, img_buf, img_len,
   3.277 +                                  ram_buf, ram_len, cmdline, features, flags,
   3.278 +                                  store_evtchn, store_mfn,
   3.279 +                                  console_evtchn, console_mfn);
   3.280 +
   3.281 + out:
   3.282 +    /* The inflation routines may pass back the same buffer so be */
   3.283 +    /* sure that we have a buffer and that it's not the one passed in. */
   3.284 +    /* Don't unnecessarily annoy/surprise/confound the caller */
   3.285 +    if ( (img_buf != NULL) && (img_buf != image_buffer) )
   3.286 +        free(img_buf);
   3.287 +    if ( (ram_buf != NULL) && (ram_buf != initrd) )
   3.288 +        free(ram_buf);
   3.289 +
   3.290 +    return sts;
   3.291 +}
   3.292 +
   3.293 +int xc_linux_build(int xc_handle,
   3.294 +                   uint32_t domid,
   3.295 +                   const char *image_name,
   3.296 +                   const char *initrd_name,
   3.297 +                   const char *cmdline,
   3.298 +                   const char *features,
   3.299 +                   unsigned long flags,
   3.300 +                   unsigned int store_evtchn,
   3.301 +                   unsigned long *store_mfn,
   3.302 +                   unsigned int console_evtchn,
   3.303 +                   unsigned long *console_mfn)
   3.304 +{
   3.305 +    char *image, *ram = NULL;
   3.306 +    unsigned long image_size, ram_size = 0;
   3.307 +    int  sts;
   3.308 +
   3.309 +    if ( (image_name == NULL) ||
   3.310 +         ((image = xc_read_image(image_name, &image_size)) == NULL ))
   3.311 +        return -1;
   3.312 +
   3.313 +    if ( (initrd_name != NULL) && (strlen(initrd_name) != 0) &&
   3.314 +         ((ram = xc_read_image(initrd_name, &ram_size)) == NULL) )
   3.315 +    {
   3.316 +        free(image);
   3.317 +        return -1;
   3.318 +    }
   3.319 +
   3.320 +    sts = xc_linux_build_internal(xc_handle, domid, image, image_size,
   3.321 +                                  ram, ram_size, cmdline, features, flags,
   3.322 +                                  store_evtchn, store_mfn,
   3.323 +                                  console_evtchn, console_mfn);
   3.324 +
   3.325      free(image);
   3.326 -    return -1;
   3.327 +    free(ram);
   3.328 +
   3.329 +    return sts;
   3.330  }
   3.331  
   3.332  /*
     4.1 --- a/tools/libxc/xenguest.h	Thu Mar 09 11:20:31 2006 +0100
     4.2 +++ b/tools/libxc/xenguest.h	Thu Mar 09 13:00:38 2006 +0100
     4.3 @@ -42,6 +42,22 @@ int xc_linux_restore(int xc_handle, int 
     4.4                       unsigned long *store_mfn, unsigned int console_evtchn,
     4.5                       unsigned long *console_mfn);
     4.6  
     4.7 +/**
     4.8 + * This function will create a domain for a paravirtualized Linux
     4.9 + * using file names pointing to kernel and ramdisk
    4.10 + *
    4.11 + * @parm xc_handle a handle to an open hypervisor interface
    4.12 + * @parm domid the id of the domain
    4.13 + * @param image_name name of the kernel image file
    4.14 + * @param ramdisk_name name of the ramdisk image file
    4.15 + * @parm cmdline command line string
    4.16 + * @parm flags domain creation flags
    4.17 + * @parm store_evtchn the store event channel for this domain to use
    4.18 + * @parm store_mfn returned with the mfn of the store page
    4.19 + * @parm console_evtchn the console event channel for this domain to use
    4.20 + * @parm conole_mfn returned with the mfn of the console page
    4.21 + * @return 0 on success, -1 on failure
    4.22 + */
    4.23  int xc_linux_build(int xc_handle,
    4.24                     uint32_t domid,
    4.25                     const char *image_name,
    4.26 @@ -54,6 +70,38 @@ int xc_linux_build(int xc_handle,
    4.27                     unsigned int console_evtchn,
    4.28                     unsigned long *console_mfn);
    4.29  
    4.30 +/**
    4.31 + * This function will create a domain for a paravirtualized Linux
    4.32 + * using buffers for kernel and initrd
    4.33 + *
    4.34 + * @param xc_handle a handle to an open hypervisor interface
    4.35 + * @param domid the id of the domain
    4.36 + * @param image_buffer buffer containing kernel image
    4.37 + * @param image_size size of the kernel image buffer
    4.38 + * @param initrd_buffer name of the ramdisk image file
    4.39 + * @param initrd_size size of the ramdisk buffer
    4.40 + * @param cmdline command line string
    4.41 + * @param flags domain creation flags
    4.42 + * @param store_evtchn the store event channel for this domain to use
    4.43 + * @param store_mfn returned with the mfn of the store page
    4.44 + * @param console_evtchn the console event channel for this domain to use
    4.45 + * @param conole_mfn returned with the mfn of the console page
    4.46 + * @return 0 on success, -1 on failure
    4.47 + */
    4.48 +int xc_linux_build_mem(int xc_handle,
    4.49 +                       uint32_t domid,
    4.50 +                       char *image_buffer,
    4.51 +                       unsigned long image_size,
    4.52 +                       char *initrd_buffer,
    4.53 +                       unsigned long initrd_size,
    4.54 +                       const char *cmdline,
    4.55 +                       const char *features,
    4.56 +                       unsigned long flags,
    4.57 +                       unsigned int store_evtchn,
    4.58 +                       unsigned long *store_mfn,
    4.59 +                       unsigned int console_evtchn,
    4.60 +                       unsigned long *console_mfn);
    4.61 +
    4.62  int xc_hvm_build(int xc_handle,
    4.63                   uint32_t domid,
    4.64                   int memsize,
    4.65 @@ -65,4 +113,16 @@ int xc_hvm_build(int xc_handle,
    4.66                   unsigned int store_evtchn,
    4.67                   unsigned long *store_mfn);
    4.68  
    4.69 -#endif // XENGUEST_H
    4.70 +int xc_hvm_build_mem(int xc_handle,
    4.71 +                     uint32_t domid,
    4.72 +                     int memsize,
    4.73 +                     char *image_buffer,
    4.74 +                     unsigned long image_size,
    4.75 +                     unsigned int vcpus,
    4.76 +                     unsigned int pae,
    4.77 +                     unsigned int acpi,
    4.78 +                     unsigned int apic,
    4.79 +                     unsigned int store_evtchn,
    4.80 +                     unsigned long *store_mfn);
    4.81 +
    4.82 +#endif /* XENGUEST_H */
     5.1 --- a/tools/libxc/xg_private.c	Thu Mar 09 11:20:31 2006 +0100
     5.2 +++ b/tools/libxc/xg_private.c	Thu Mar 09 13:00:38 2006 +0100
     5.3 @@ -10,15 +10,15 @@
     5.4  
     5.5  #include "xg_private.h"
     5.6  
     5.7 -char *xc_read_kernel_image(const char *filename, unsigned long *size)
     5.8 +char *xc_read_image(const char *filename, unsigned long *size)
     5.9  {
    5.10      int kernel_fd = -1;
    5.11      gzFile kernel_gfd = NULL;
    5.12      char *image = NULL;
    5.13      unsigned int bytes;
    5.14  
    5.15 -    if ( filename == NULL )
    5.16 -        goto out;
    5.17 +    if ( (filename == NULL) || (size == NULL) )
    5.18 +        return NULL;
    5.19  
    5.20      if ( (kernel_fd = open(filename, O_RDONLY)) < 0 )
    5.21      {
    5.22 @@ -60,6 +60,62 @@ char *xc_read_kernel_image(const char *f
    5.23      return image;
    5.24  }
    5.25  
    5.26 +char *xc_inflate_buffer(char *in_buf, unsigned long in_size,
    5.27 +                        unsigned long *out_size)
    5.28 +{
    5.29 +    int           sts;
    5.30 +    z_stream      zStream;
    5.31 +    unsigned long out_len;
    5.32 +    char         *out_buf;
    5.33 +
    5.34 +    /* Not compressed? Then return the original buffer. */
    5.35 +    if ( ((unsigned char)in_buf[0] != 0x1F) ||
    5.36 +         ((unsigned char)in_buf[1] != 0x8B) )
    5.37 +    {
    5.38 +        if ( out_size != NULL )
    5.39 +            *out_size = in_size;
    5.40 +        return in_buf;
    5.41 +    }
    5.42 +
    5.43 +    out_len = in_buf[in_size-4] +
    5.44 +        (256 * (in_buf[in_size-3] +
    5.45 +                (256 * (in_buf[in_size-2] +
    5.46 +                        (256 * in_buf[in_size-1])))));
    5.47 +    bzero(&zStream, sizeof(zStream));
    5.48 +    out_buf = malloc(out_len + 16);        /* Leave a little extra space */
    5.49 +    if ( out_buf == NULL )
    5.50 +    {
    5.51 +        ERROR("Error mallocing buffer\n");
    5.52 +        return NULL;
    5.53 +    }
    5.54 +
    5.55 +    zStream.next_in = (unsigned char *)in_buf;
    5.56 +    zStream.avail_in = in_size;
    5.57 +    zStream.next_out = (unsigned char *)out_buf;
    5.58 +    zStream.avail_out = out_len+16;
    5.59 +    sts = inflateInit2(&zStream, (MAX_WBITS+32)); /* +32 means "handle gzip" */
    5.60 +    if ( sts != Z_OK )
    5.61 +    {
    5.62 +        ERROR("inflateInit failed, sts %d\n", sts);
    5.63 +        free(out_buf);
    5.64 +        return NULL;
    5.65 +    }
    5.66 +
    5.67 +    /* Inflate in one pass/call */
    5.68 +    sts = inflate(&zStream, Z_FINISH);
    5.69 +    if ( sts != Z_STREAM_END )
    5.70 +    {
    5.71 +        ERROR("inflate failed, sts %d\n", sts);
    5.72 +        free(out_buf);
    5.73 +        return NULL;
    5.74 +    }
    5.75 +
    5.76 +    if ( out_size != NULL )
    5.77 +        *out_size = out_len;
    5.78 +
    5.79 +    return out_buf;
    5.80 +}
    5.81 +
    5.82  /*******************/
    5.83  
    5.84  int pin_table(
    5.85 @@ -77,7 +133,7 @@ int pin_table(
    5.86  }
    5.87  
    5.88  /* This is shared between save and restore, and may generally be useful. */
    5.89 -unsigned long csum_page (void * page)
    5.90 +unsigned long csum_page(void *page)
    5.91  {
    5.92      int i;
    5.93      unsigned long *p = page;
     6.1 --- a/tools/libxc/xg_private.h	Thu Mar 09 11:20:31 2006 +0100
     6.2 +++ b/tools/libxc/xg_private.h	Thu Mar 09 13:00:38 2006 +0100
     6.3 @@ -26,7 +26,11 @@
     6.4  #endif
     6.5  
     6.6  
     6.7 -char *xc_read_kernel_image(const char *filename, unsigned long *size);
     6.8 +char *xc_read_image(const char *filename, unsigned long *size);
     6.9 +char *xc_inflate_buffer(char *in_buf,
    6.10 +                        unsigned long in_size,
    6.11 +                        unsigned long *out_size);
    6.12 +
    6.13  unsigned long csum_page (void * page);
    6.14  
    6.15  #define _PAGE_PRESENT   0x001
    6.16 @@ -89,7 +93,7 @@ typedef unsigned long l4_pgentry_t;
    6.17  #define l2_table_offset_pae(_a) \
    6.18    (((_a) >> L2_PAGETABLE_SHIFT_PAE) & (L2_PAGETABLE_ENTRIES_PAE - 1))
    6.19  #define l3_table_offset_pae(_a) \
    6.20 -	(((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
    6.21 +  (((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
    6.22  
    6.23  #if defined(__i386__)
    6.24  #define l1_table_offset(_a) \
    6.25 @@ -102,9 +106,9 @@ typedef unsigned long l4_pgentry_t;
    6.26  #define l2_table_offset(_a) \
    6.27    (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
    6.28  #define l3_table_offset(_a) \
    6.29 -	(((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
    6.30 +  (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
    6.31  #define l4_table_offset(_a) \
    6.32 -	(((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
    6.33 +  (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
    6.34  #endif
    6.35  
    6.36  #define ERROR(_m, _a...)                                \
    6.37 @@ -142,10 +146,10 @@ struct domain_setup_info
    6.38  };
    6.39  
    6.40  typedef int (*parseimagefunc)(char *image, unsigned long image_size,
    6.41 -			      struct domain_setup_info *dsi);
    6.42 +                              struct domain_setup_info *dsi);
    6.43  typedef int (*loadimagefunc)(char *image, unsigned long image_size, int xch,
    6.44 -			     uint32_t dom, unsigned long *parray,
    6.45 -			     struct domain_setup_info *dsi);
    6.46 +                             uint32_t dom, unsigned long *parray,
    6.47 +                             struct domain_setup_info *dsi);
    6.48  
    6.49  struct load_funcs
    6.50  {
    6.51 @@ -176,7 +180,7 @@ void xc_map_memcpy(unsigned long dst, ch
    6.52                     unsigned long vstart);
    6.53  
    6.54  int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
    6.55 -	      domid_t dom);
    6.56 +              domid_t dom);
    6.57  
    6.58  /* image loading */
    6.59  int probe_elf(char *image, unsigned long image_size, struct load_funcs *funcs);