[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH 6 of 6] HACK: xenguest updates for Xen 4.0/4.1



# HG changeset patch
# User root@xxxxxxxxxxxxxxxxxxxxx
# Date 1291305009 18000
# Node ID 45271ebfd9022c7b0a2f962360c4c7a663706865
# Parent  15700c869b5445ce6d239513c54d6f69f9d62808
HACK: xenguest updates for Xen 4.0/4.1

Totally incomplete but enough to start a PV guest.

Not-signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

diff -r 15700c869b54 -r 45271ebfd902 ocaml/xenguest/save_helpers.c
--- a/ocaml/xenguest/save_helpers.c     Thu Dec 02 10:50:03 2010 -0500
+++ b/ocaml/xenguest/save_helpers.c     Thu Dec 02 10:50:09 2010 -0500
@@ -22,150 +22,19 @@
  * Modifications (c) Citrix Systems Inc
  */
 
-#include <err.h>
 #include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <grp.h>
 
 #include <xs.h>
 #include <xenctrl.h>
 #include <xenguest.h>
 
-static char *qemu_active_path;
-static char *qemu_next_active_path;
-static int qemu_shmid = -1;
-static struct xs_handle *xs;
-
-
-/* Mark the shared-memory segment for destruction */
-static void qemu_destroy_buffer(void)
-{
-    if (qemu_shmid != -1)
-        shmctl(qemu_shmid, IPC_RMID, NULL);
-    qemu_shmid = -1;
+int switch_qemu_logdirty(int domid, unsigned enable, void *data)
+{      
+       return 1; /* XXX actually do something! */
 }
 
-/* Get qemu to change buffers. */
-void qemu_flip_buffer(int domid, int next_active)
+int do_domain_suspend(void* data)
 {
-    char digit = '0' + next_active;
-    unsigned int len;
-    char *active_str, **watch;
-    struct timeval tv;
-    fd_set fdset;
-    int rc;
-
-    /* Tell qemu that we want it to start writing log-dirty bits to the
-     * other buffer */
-    if (!xs_write(xs, XBT_NULL, qemu_next_active_path, &digit, 1)) {
-        errx(1, "can't write next-active to store path (%s)\n",
-              qemu_next_active_path);
-        exit(1);
-    }
-
-    /* Wait a while for qemu to signal that it has switched to the new
-     * active buffer */
- read_again:
-    tv.tv_sec = 60;
-    tv.tv_usec = 0;
-    FD_ZERO(&fdset);
-    FD_SET(xs_fileno(xs), &fdset);
-    rc = select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv);
-    if (rc == 0)
-        errx(1, "timed out waiting for qemu to switch buffers\n");
-    else if (rc < 0) {
-        if (errno == EINTR) 
-            goto read_again;
-        err(1, "error waiting for qemu to switch buffers");
-    }
-    watch = xs_read_watch(xs, &len);
-    free(watch);
-
-    active_str = xs_read(xs, XBT_NULL, qemu_active_path, &len);
-    if (active_str == NULL || active_str[0] - '0' != next_active)
-        /* Watch fired but value is not yet right */
-        goto read_again;
+       return 1; /* XXX actually do something! */
 }
 
-void * init_qemu_maps(int domid, unsigned int bitmap_size)
-{
-    key_t key;
-    char key_ascii[17] = {0,};
-    void *seg;
-    char *path, *p;
-    struct shmid_ds ds_buf;
-    struct group *gr;
-
-    /* Make a shared-memory segment */
-    do {
-        key = rand(); /* No security, just a sequence of numbers */
-        qemu_shmid = shmget(key, 2 * bitmap_size, 
-                       IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
-        if (qemu_shmid == -1 && errno != EEXIST)
-            errx(1, "can't get shmem to talk to qemu-dm");
-    } while (qemu_shmid == -1);
-
-    /* Remember to tidy up after ourselves */
-    atexit(qemu_destroy_buffer);
-
-    /* Change owner so that qemu can map it. */
-    gr = getgrnam("qemu_base");
-    if (!gr)
-        err(1, "can't get qemu gid");
-    if (shmctl(qemu_shmid, IPC_STAT, &ds_buf) < 0)
-        err(1, "can't get status of shm area");
-    ds_buf.shm_perm.gid = gr->gr_gid + (unsigned short)domid;
-    if (shmctl(qemu_shmid, IPC_SET, &ds_buf) < 0)
-        err(1, "can't change gid of shm area");
-
-    /* Map it into our address space */
-    seg = shmat(qemu_shmid, NULL, 0);
-    if (seg == (void *) -1)
-        errx(1, "can't map shmem to talk to qemu-dm");
-    memset(seg, 0, 2 * bitmap_size);
-
-    /* Write the size of it into the first 32 bits */
-    *(uint32_t *)seg = bitmap_size;
-
-    /* Tell qemu about it */
-    if ((xs = xs_daemon_open()) == NULL)
-        errx(1, "Couldn't contact xenstore");
-    if (!(path = xs_get_domain_path(xs, domid)))
-        errx(1, "can't get domain path in store");
-    if (!(path = realloc(path, strlen(path)
-                         + strlen("/logdirty/next-active") + 1)))
-        errx(1, "no memory for constructing xenstore path");
-    strcat(path, "/logdirty/");
-    p = path + strlen(path);
-
-    strcpy(p, "key");
-    snprintf(key_ascii, 17, "%16.16llx", (unsigned long long) key);
-    if (!xs_write(xs, XBT_NULL, path, key_ascii, 16))
-        errx(1, "can't write key (%s) to store path (%s)\n", key_ascii, path);
-
-    /* Watch for qemu's indication of the active buffer, and request it
-     * to start writing to buffer 0 */
-    strcpy(p, "active");
-    if (!xs_watch(xs, path, "qemu-active-buffer"))
-        errx(1, "can't set watch in store (%s)\n", path);
-    if (!(qemu_active_path = strdup(path)))
-        errx(1, "no memory for copying xenstore path");
-
-    strcpy(p, "next-active");
-    if (!(qemu_next_active_path = strdup(path)))
-        errx(1, "no memory for copying xenstore path");
-
-    qemu_flip_buffer(domid, 0);
-
-    free(path);
-    return seg;
-}
-
-/***********************************************************************/
diff -r 15700c869b54 -r 45271ebfd902 ocaml/xenguest/xenguest_stubs.c
--- a/ocaml/xenguest/xenguest_stubs.c   Thu Dec 02 10:50:03 2010 -0500
+++ b/ocaml/xenguest/xenguest_stubs.c   Thu Dec 02 10:50:09 2010 -0500
@@ -34,7 +34,7 @@
 #include <caml/signals.h>
 #include <caml/fail.h>
 
-#define _H(__h) (Int_val(__h))
+#define _H(__h) ((xc_interface *)(__h))
 #define _D(__d) ((uint32_t)Int_val(__d))
 
 #define None_val (Val_int(0))
@@ -138,17 +138,17 @@ get_flags(struct flags *f, int domid)
 }
 
 
-static void failwith_oss_xc(char *fct)
+static void failwith_oss_xc(xc_interface *xch, char *fct)
 {
        char buf[80];
        const xc_error *error;
 
-       error = xc_get_last_error();
+       error = xc_get_last_error(xch);
        if (error->code == XC_ERROR_NONE)
                snprintf(buf, 80, "%s: [%d] %s", fct, errno, strerror(errno));
        else
                snprintf(buf, 80, "%s: [%d] %s", fct, error->code, 
error->message);
-       xc_clear_last_error();
+       xc_clear_last_error(xch);
        caml_failwith(buf);
 }
 
@@ -172,41 +172,55 @@ static int suspend_flag_list[] = {
 
 CAMLprim value stub_xenguest_init()
 {
-       int handle;
+       xc_interface *xch;
 
-       handle = xc_interface_open();
-       if (handle == -1)
-               failwith_oss_xc("xc_interface_open");
-       return Val_int(handle);
+       xch = xc_interface_open(NULL, NULL, 0);
+       if (xch == NULL)
+               failwith_oss_xc(NULL, "xc_interface_open");
+       return (value)xch;
 }
 
 CAMLprim value stub_xenguest_close(value xenguest_handle)
 {
        CAMLparam1(xenguest_handle);
-       xc_interface_close(Int_val(xenguest_handle));
+       xc_interface_close(_H(xenguest_handle));
        CAMLreturn(Val_unit);
 }
 
-extern struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char 
*features);
+extern struct xc_dom_image *xc_dom_allocate(xc_interface *xch, const char 
*cmdline, const char *features);
 
-static void configure_vcpus(int handle, int domid, struct flags f){
+static void configure_vcpus(xc_interface *xch, int domid, struct flags f){
   struct xen_domctl_sched_credit sdom;
   int i, r;
   if (f.vcpu_affinity != 0L){ /* 0L means unset */
+    xc_cpumap_t cpumap = xc_cpumap_alloc(xch);
+    if (cpumap == NULL)
+      failwith_oss_xc(xch, "xc_cpumap_alloc");
+
+    for (i=0; i<64; i++) {
+      if (f.vcpu_affinity & 1<<i)
+        cpumap[i/8] |= i << (i&7);
+    }
+
     for (i=0; i<f.vcpus; i++){
-      r = xc_vcpu_setaffinity(handle, domid, i, f.vcpu_affinity);
-      if (r)
-       failwith_oss_xc("xc_vcpu_setaffinity");
+      r = xc_vcpu_setaffinity(xch, domid, i, cpumap);
+      if (r) {
+        free(cpumap);
+       failwith_oss_xc(xch, "xc_vcpu_setaffinity");
+      }
     }
-  };
-  r = xc_sched_credit_domain_get(handle, domid, &sdom);
+
+    free(cpumap);
+  }
+
+  r = xc_sched_credit_domain_get(xch, domid, &sdom);
   if (r)
-    failwith_oss_xc("xc_sched_credit_domain_get");
+    failwith_oss_xc(xch, "xc_sched_credit_domain_get");
   if (f.vcpu_weight != 0L) sdom.weight = f.vcpu_weight;
   if (f.vcpu_cap != 0L) sdom.cap = f.vcpu_cap;
-  r = xc_sched_credit_domain_set(handle, domid, &sdom);
+  r = xc_sched_credit_domain_set(xch, domid, &sdom);
   if (r)
-    failwith_oss_xc("xc_sched_credit_domain_set");
+    failwith_oss_xc(xch, "xc_sched_credit_domain_set");
 }
 
 CAMLprim value stub_xc_linux_build_native(value xc_handle, value domid,
@@ -228,7 +242,7 @@ CAMLprim value stub_xc_linux_build_nativ
        char c_protocol[64];
 
        /* Copy the ocaml values into c-land before dropping the mutex */
-       int c_xc_handle = _H(xc_handle);
+       xc_interface *xch = _H(xc_handle);
        unsigned int c_mem_start_mib = Int_val(mem_start_mib);
        uint32_t c_domid = _D(domid);
        char *c_image_name = strdup(String_val(image_name));
@@ -241,14 +255,14 @@ CAMLprim value stub_xc_linux_build_nativ
        get_flags(&f,c_domid);
 
        xc_dom_loginit();
-       dom = xc_dom_allocate(String_val(cmdline), String_val(features));
+       dom = xc_dom_allocate(xch, String_val(cmdline), String_val(features));
        if (!dom)
-               failwith_oss_xc("xc_dom_allocate");
+               failwith_oss_xc(xch, "xc_dom_allocate");
 
-       configure_vcpus(c_xc_handle, c_domid, f);
+       configure_vcpus(xch, c_domid, f);
 
        caml_enter_blocking_section();
-       r = xc_dom_linux_build(c_xc_handle, dom, c_domid, c_mem_start_mib,
+       r = xc_dom_linux_build(xch, dom, c_domid, c_mem_start_mib,
                               c_image_name, c_ramdisk_name, c_flags,
                               c_store_evtchn, &store_mfn,
                               c_console_evtchn, &console_mfn);
@@ -264,7 +278,7 @@ CAMLprim value stub_xc_linux_build_nativ
        xc_dom_release(dom);
 
        if (r != 0)
-               failwith_oss_xc("xc_dom_linux_build");
+               failwith_oss_xc(xch, "xc_dom_linux_build");
 
        result = caml_alloc_tuple(3);
        Store_field(result, 0, caml_copy_nativeint(store_mfn));
@@ -282,7 +296,7 @@ CAMLprim value stub_xc_linux_build_bytec
                                          argv[8], argv[9], argv[10]);
 }
 
-static int hvm_build_set_params(int handle, int domid,
+static int hvm_build_set_params(xc_interface *xch, int domid,
                                 int store_evtchn, unsigned long *store_mfn,
                                struct flags f)
 {
@@ -290,7 +304,7 @@ static int hvm_build_set_params(int hand
        uint8_t *va_map, sum;
        int i;
 
-       va_map = xc_map_foreign_range(handle, domid,
+       va_map = xc_map_foreign_range(xch, domid,
                            XC_PAGE_SIZE, PROT_READ | PROT_WRITE,
                            HVM_INFO_PFN);
        if (va_map == NULL)
@@ -300,22 +314,24 @@ static int hvm_build_set_params(int hand
        va_hvm->acpi_enabled = f.acpi;
        va_hvm->apic_mode = f.apic;
        va_hvm->nr_vcpus = f.vcpus;
+#if 0
         va_hvm->s4_enabled = f.acpi_s4;
         va_hvm->s3_enabled = f.acpi_s3;
+#endif
        va_hvm->checksum = 0;
        for (i = 0, sum = 0; i < va_hvm->length; i++)
                sum += ((uint8_t *) va_hvm)[i];
        va_hvm->checksum = -sum;
        munmap(va_map, XC_PAGE_SIZE);
 
-       xc_get_hvm_param(handle, domid, HVM_PARAM_STORE_PFN, store_mfn);
-       xc_set_hvm_param(handle, domid, HVM_PARAM_PAE_ENABLED, f.pae);
+       xc_get_hvm_param(xch, domid, HVM_PARAM_STORE_PFN, store_mfn);
+       xc_set_hvm_param(xch, domid, HVM_PARAM_PAE_ENABLED, f.pae);
 #ifdef HVM_PARAM_VIRIDIAN
-       xc_set_hvm_param(handle, domid, HVM_PARAM_VIRIDIAN, f.viridian);
+       xc_set_hvm_param(xch, domid, HVM_PARAM_VIRIDIAN, f.viridian);
 #endif
-       xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn);
+       xc_set_hvm_param(xch, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn);
 #ifndef XEN_UNSTABLE
-       xc_set_hvm_param(handle, domid, HVM_PARAM_NX_ENABLED, f.nx);
+       xc_set_hvm_param(xch, domid, HVM_PARAM_NX_ENABLED, f.nx);
 #endif
        return 0;
 }
@@ -330,16 +346,18 @@ CAMLprim value stub_xc_hvm_build_native(
        CAMLlocal1(ret);
        char *image_name_c = strdup(String_val(image_name));
        char *error[256];
+       xc_interface *xch;
 
        unsigned long store_mfn=0;
        int r;
        struct flags f;
        get_flags(&f, _D(domid));
 
-       configure_vcpus(_H(xc_handle), _D(domid), f);
+       xch = _H(xc_handle);
+       configure_vcpus(xch, _D(domid), f);
 
        caml_enter_blocking_section ();
-       r = xc_hvm_build_target_mem(_H(xc_handle), _D(domid),
+       r = xc_hvm_build_target_mem(xch, _D(domid),
                                    Int_val(mem_max_mib),
                                    Int_val(mem_start_mib),
                                    image_name_c);
@@ -348,13 +366,13 @@ CAMLprim value stub_xc_hvm_build_native(
        free(image_name_c);
 
        if (r)
-               failwith_oss_xc("hvm_build");
+               failwith_oss_xc(xch, "hvm_build");
 
 
-       r = hvm_build_set_params(_H(xc_handle), _D(domid),
+       r = hvm_build_set_params(xch, _D(domid),
                                 Int_val(store_evtchn), &store_mfn, f);
        if (r)
-               failwith_oss_xc("hvm_build_params");
+               failwith_oss_xc(xch, "hvm_build_params");
 
        ret = caml_copy_nativeint(store_mfn);
        CAMLreturn(ret);
@@ -366,8 +384,8 @@ CAMLprim value stub_xc_hvm_build_bytecod
                                        argv[4], argv[5]);
 }
 
-extern void qemu_flip_buffer(int domid, int next_active);
-extern void * init_qemu_maps(int domid, unsigned int bitmap_size);
+extern int switch_qemu_logdirty(int domid, unsigned enable, void *data);
+extern int do_domain_suspend(void* data);
 
 CAMLprim value stub_xc_domain_save(value handle, value fd, value domid,
                                    value max_iters, value max_factors,
@@ -375,24 +393,23 @@ CAMLprim value stub_xc_domain_save(value
 {
        CAMLparam5(handle, fd, domid, max_iters, max_factors);
        CAMLxparam2(flags, hvm);
-       void *(*init_maps)(int, unsigned);
-       void (*flip_buffer)(int, int);
+       struct save_callbacks callbacks;
        uint32_t c_flags;
        int r;
 
-       init_maps = (Bool_val(hvm)) ? init_qemu_maps : NULL;
-       flip_buffer = (Bool_val(hvm)) ? qemu_flip_buffer : NULL;
+       c_flags = caml_convert_flag_list(flags, suspend_flag_list);
 
-       c_flags = caml_convert_flag_list(flags, suspend_flag_list);
+       memset(&callbacks, 0, sizeof(callbacks));
+       callbacks.suspend = &do_domain_suspend; 
+       callbacks.switch_qemu_logdirty = &switch_qemu_logdirty;
 
        caml_enter_blocking_section();
        r = xc_domain_save(_H(handle), Int_val(fd), _D(domid),
                           Int_val(max_iters), Int_val(max_factors),
-                          c_flags, dispatch_suspend,
-                          Bool_val(hvm), init_maps, flip_buffer);
+                          c_flags, &callbacks, Bool_val(hvm));
        caml_leave_blocking_section();
        if (r)
-               failwith_oss_xc("xc_domain_save");
+               failwith_oss_xc(_H(handle), "xc_domain_save");
 
        CAMLreturn(Val_unit);
 }
@@ -413,7 +430,7 @@ CAMLprim value stub_xc_domain_resume_slo
        /* hard code fast to 0, we only want to expose the slow version here */
        r = xc_domain_resume(_H(handle), _D(domid), 0);
        if (r)
-               failwith_oss_xc("xc_domain_resume");
+               failwith_oss_xc(_H(handle), "xc_domain_resume");
        CAMLreturn(Val_unit);
 }
 
@@ -444,10 +461,10 @@ CAMLprim value stub_xc_domain_restore(va
        r = xc_domain_restore(_H(handle), Int_val(fd), _D(domid),
                              c_store_evtchn, &store_mfn,
                              c_console_evtchn, &console_mfn,
-                             Bool_val(hvm), f.pae);
+                             Bool_val(hvm), f.pae, 0 /*superpages*/);
        caml_leave_blocking_section();
        if (r)
-               failwith_oss_xc("xc_domain_restore");
+               failwith_oss_xc(_H(handle), "xc_domain_restore");
 
        result = caml_alloc_tuple(2);
        Store_field(result, 0, caml_copy_nativeint(store_mfn));
@@ -469,6 +486,6 @@ CAMLprim value stub_xc_domain_dumpcore(v
 
        r = xc_domain_dumpcore(_H(handle), _D(domid), String_val(file));
        if (r)
-               failwith_oss_xc("xc_domain_dumpcore");
+               failwith_oss_xc(_H(handle), "xc_domain_dumpcore");
        CAMLreturn(Val_unit);
 }
diff -r 15700c869b54 -r 45271ebfd902 ocaml/xenops/xenops.ml
--- a/ocaml/xenops/xenops.ml    Thu Dec 02 10:50:03 2010 -0500
+++ b/ocaml/xenops/xenops.ml    Thu Dec 02 10:50:09 2010 -0500
@@ -29,8 +29,8 @@ let print_xen_physinfo ~xc =
        printf "nr_cpus = %d\n" physinfo.Xc.nr_cpus;
        printf "threads_per_core = %d\n" physinfo.Xc.threads_per_core;
        printf "cores_per_socket = %d\n" physinfo.Xc.cores_per_socket;
-       printf "sockets_per_node = %d\n" physinfo.Xc.sockets_per_node;
-       printf "nr_nodes = %d\n" physinfo.Xc.nr_nodes;
+       (*printf "sockets_per_node = %d\n" physinfo.Xc.sockets_per_node;*)
+       (*printf "nr_nodes = %d\n" physinfo.Xc.nr_nodes;*)
        printf "cpu_khz = %d\n" physinfo.Xc.cpu_khz;
        printf "total_pages = %s (%Ld Mb)\n" (Nativeint.to_string 
physinfo.Xc.total_pages) totalmib;
        printf "free_pages = %s (%Ld Mb)\n" (Nativeint.to_string 
physinfo.Xc.free_pages) freemib;

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.