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-devel

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

To: xen-devel@xxxxxxxxxxxxxxxxxxx, xen-api@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-API] [PATCH 6 of 6] HACK: xenguest updates for Xen 4.0/4.1
From: Ian Campbell <ian.campbell@xxxxxxxxxx>
Date: Tue, 07 Dec 2010 14:33:14 +0000
Cc: Ian Campbell <ian.campbell@xxxxxxxxxx>
Delivery-date: Tue, 07 Dec 2010 07:15:26 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1291732388@xxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-api-request@lists.xensource.com?subject=help>
List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>
List-post: <mailto:xen-api@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1291732388@xxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-api-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.5.2
# 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