# HG changeset patch
# User root@xxxxxxxxxxxxxxxxxxxxx
# Date 1290076616 18000
# Node ID 1b166fb9629c50be802c5cfc9c2722db80ec8a0e
# Parent 13460a457762df182fec2b1f4860d640934f73ad
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 13460a457762 -r 1b166fb9629c ocaml/xenguest/save_helpers.c
--- a/ocaml/xenguest/save_helpers.c Thu Nov 18 05:36:56 2010 -0500
+++ b/ocaml/xenguest/save_helpers.c Thu Nov 18 05:36:56 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 13460a457762 -r 1b166fb9629c ocaml/xenguest/xenguest_stubs.c
--- a/ocaml/xenguest/xenguest_stubs.c Thu Nov 18 05:36:56 2010 -0500
+++ b/ocaml/xenguest/xenguest_stubs.c Thu Nov 18 05:36:56 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 13460a457762 -r 1b166fb9629c ocaml/xenops/xenops.ml
--- a/ocaml/xenops/xenops.ml Thu Nov 18 05:36:56 2010 -0500
+++ b/ocaml/xenops/xenops.ml Thu Nov 18 05:36:56 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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|