# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID ef9591d03fdd96c4d290280fd3620e00f8a5ff2b
# Parent eaedc6b4ec0fdbb5b14ac62f0854477f50fa55b2
# Parent 811559fb02ab1e1c5a7731895bd57ca7f9d6dbfe
Merge latest xen-unstable into xen-ia64-unstable
diff -r eaedc6b4ec0f -r ef9591d03fdd Makefile
--- a/Makefile Fri Sep 23 21:41:28 2005
+++ b/Makefile Mon Sep 26 17:07:49 2005
@@ -164,7 +164,7 @@
uninstall: DESTDIR=
uninstall: D=$(DESTDIR)
uninstall:
- [ -d $(D)/etc/xen ] && mv -f $(D)/etc/xen $(D)/etc/xen.old-`date +%s`
+ [ -d $(D)/etc/xen ] && mv -f $(D)/etc/xen $(D)/etc/xen.old-`date +%s`
|| true
rm -rf $(D)/etc/init.d/xend*
rm -rf $(D)/etc/hotplug/xen-backend.agent
rm -rf $(D)/var/run/xen* $(D)/var/lib/xen*
diff -r eaedc6b4ec0f -r ef9591d03fdd docs/src/user/installation.tex
--- a/docs/src/user/installation.tex Fri Sep 23 21:41:28 2005
+++ b/docs/src/user/installation.tex Mon Sep 26 17:07:49 2005
@@ -21,6 +21,9 @@
\item [$\dag$] The \path{iproute2} package.
\item [$\dag$] The Linux bridge-utils\footnote{Available from {\tt
http://bridge.sourceforge.net}} (e.g., \path{/sbin/brctl})
+\item [$\dag$] The Linux hotplug system\footnote{Available from {\tt
+ http://linux-hotplug.sourceforge.net/}} (e.g., \path{/sbin/hotplug}
+ and related scripts)
\item [$\dag$] An installation of Twisted~v1.3 or
above\footnote{Available from {\tt http://www.twistedmatrix.com}}.
There may be a binary package available for your distribution;
diff -r eaedc6b4ec0f -r ef9591d03fdd
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Fri Sep 23
21:41:28 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Mon Sep 26
17:07:49 2005
@@ -1394,9 +1394,7 @@
return;
/* get the state value */
- xenbus_transaction_start("cpu");
err = xenbus_scanf(dir, "availability", "%s", state);
- xenbus_transaction_end(0);
if (err != 1) {
printk(KERN_ERR
diff -r eaedc6b4ec0f -r ef9591d03fdd
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Fri Sep 23 21:41:28 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Mon Sep 26 17:07:49 2005
@@ -324,7 +324,7 @@
int err;
again:
- err = xenbus_transaction_start("control");
+ err = xenbus_transaction_start();
if (err)
return;
str = (char *)xenbus_read("control", "shutdown", NULL);
@@ -337,7 +337,7 @@
xenbus_write("control", "shutdown", "");
err = xenbus_transaction_end(0);
- if (err == -ETIMEDOUT) {
+ if (err == -EAGAIN) {
kfree(str);
goto again;
}
@@ -366,7 +366,7 @@
int err;
again:
- err = xenbus_transaction_start("control");
+ err = xenbus_transaction_start();
if (err)
return;
if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) {
@@ -379,7 +379,7 @@
xenbus_printf("control", "sysrq", "%c", '\0');
err = xenbus_transaction_end(0);
- if (err == -ETIMEDOUT)
+ if (err == -EAGAIN)
goto again;
if (sysrq_key != '\0') {
diff -r eaedc6b4ec0f -r ef9591d03fdd
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Sep 23 21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Mon Sep 26 17:07:49 2005
@@ -80,8 +80,9 @@
return;
}
+again:
/* Supply the information about the device the frontend needs */
- err = xenbus_transaction_start(be->dev->nodename);
+ err = xenbus_transaction_start();
if (err) {
xenbus_dev_error(be->dev, err, "starting transaction");
return;
@@ -119,7 +120,15 @@
goto abort;
}
- xenbus_transaction_end(0);
+ err = xenbus_transaction_end(0);
+ if (err == -EAGAIN)
+ goto again;
+ if (err) {
+ xenbus_dev_error(be->dev, err, "ending transaction",
+ ring_ref, evtchn);
+ goto abort;
+ }
+
xenbus_dev_ok(be->dev);
return;
diff -r eaedc6b4ec0f -r ef9591d03fdd
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Fri Sep 23
21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon Sep 26
17:07:49 2005
@@ -572,7 +572,8 @@
goto out;
}
- err = xenbus_transaction_start(dev->nodename);
+again:
+ err = xenbus_transaction_start();
if (err) {
xenbus_dev_error(dev, err, "starting transaction");
goto destroy_blkring;
@@ -603,6 +604,8 @@
err = xenbus_transaction_end(0);
if (err) {
+ if (err == -EAGAIN)
+ goto again;
xenbus_dev_error(dev, err, "completing transaction");
goto destroy_blkring;
}
diff -r eaedc6b4ec0f -r ef9591d03fdd
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Sep 23
21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon Sep 26
17:07:49 2005
@@ -1122,7 +1122,8 @@
goto out;
}
- err = xenbus_transaction_start(dev->nodename);
+again:
+ err = xenbus_transaction_start();
if (err) {
xenbus_dev_error(dev, err, "starting transaction");
goto destroy_ring;
@@ -1160,6 +1161,8 @@
err = xenbus_transaction_end(0);
if (err) {
+ if (err == -EAGAIN)
+ goto again;
xenbus_dev_error(dev, err, "completing transaction");
goto destroy_ring;
}
diff -r eaedc6b4ec0f -r ef9591d03fdd
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Fri Sep 23 21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Mon Sep 26 17:07:49 2005
@@ -93,7 +93,8 @@
* Tell the front-end that we are ready to go -
* unless something bad happens
*/
- err = xenbus_transaction_start(be->dev->nodename);
+again:
+ err = xenbus_transaction_start();
if (err) {
xenbus_dev_error(be->dev, err, "starting transaction");
return;
@@ -127,7 +128,14 @@
goto abort;
}
- xenbus_transaction_end(0);
+ err = xenbus_transaction_end(0);
+ if (err == -EAGAIN)
+ goto again;
+ if (err) {
+ xenbus_dev_error(be->dev, err, "end of transaction");
+ goto abort;
+ }
+
xenbus_dev_ok(be->dev);
return;
abort:
diff -r eaedc6b4ec0f -r ef9591d03fdd
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Fri Sep 23
21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Mon Sep 26
17:07:49 2005
@@ -331,7 +331,8 @@
goto out;
}
- err = xenbus_transaction_start(dev->nodename);
+again:
+ err = xenbus_transaction_start();
if (err) {
xenbus_dev_error(dev, err, "starting transaction");
goto destroy_tpmring;
@@ -363,6 +364,8 @@
}
err = xenbus_transaction_end(0);
+ if (err == -EAGAIN)
+ goto again;
if (err) {
xenbus_dev_error(dev, err, "completing transaction");
goto destroy_tpmring;
diff -r eaedc6b4ec0f -r ef9591d03fdd
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Fri Sep 23
21:41:28 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon Sep 26
17:07:49 2005
@@ -287,12 +287,11 @@
/* Start a transaction: changes by others will not be seen during this
* transaction, and changes will not be visible to others until end.
- * Transaction only applies to the given subtree.
* You can only have one transaction at any time.
*/
-int xenbus_transaction_start(const char *subtree)
-{
- return xs_error(xs_single(XS_TRANSACTION_START, subtree, NULL));
+int xenbus_transaction_start(void)
+{
+ return xs_error(xs_single(XS_TRANSACTION_START, "", NULL));
}
EXPORT_SYMBOL(xenbus_transaction_start);
diff -r eaedc6b4ec0f -r ef9591d03fdd
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Fri Sep 23 21:41:28 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Mon Sep 26 17:07:49 2005
@@ -87,7 +87,7 @@
int xenbus_mkdir(const char *dir, const char *node);
int xenbus_exists(const char *dir, const char *node);
int xenbus_rm(const char *dir, const char *node);
-int xenbus_transaction_start(const char *subtree);
+int xenbus_transaction_start(void);
int xenbus_transaction_end(int abort);
/* Single read and scanf: returns -errno or num scanned if > 0. */
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/examples/Makefile
--- a/tools/examples/Makefile Fri Sep 23 21:41:28 2005
+++ b/tools/examples/Makefile Mon Sep 26 17:07:49 2005
@@ -25,19 +25,13 @@
XEN_SCRIPTS += block-file
XEN_SCRIPTS += block-enbd
-# no 64-bit specifics in mem-map.sxp
-# so place in /usr/lib, not /usr/lib64
-XEN_BOOT_DIR = /usr/lib/xen/boot
-XEN_BOOT = mem-map.sxp
-
XEN_HOTPLUG_DIR = /etc/hotplug
XEN_HOTPLUG_SCRIPTS = xen-backend.agent
all:
build:
-install: all install-initd install-configs install-scripts install-boot \
- install-hotplug
+install: all install-initd install-configs install-scripts install-hotplug
install-initd:
[ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
@@ -62,14 +56,6 @@
$(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
done
-install-boot:
- [ -d $(DESTDIR)$(XEN_BOOT_DIR) ] || \
- $(INSTALL_DIR) $(DESTDIR)$(XEN_BOOT_DIR)
- for i in $(XEN_BOOT); \
- do [ -a $(DESTDIR)$(XEN_BOOT_DIR)/$$i ] || \
- $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_BOOT_DIR); \
- done
-
install-hotplug:
[ -d $(DESTDIR)$(XEN_HOTPLUG_DIR) ] || \
$(INSTALL_DIR) $(DESTDIR)$(XEN_HOTPLUG_DIR)
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/examples/xmexample.vmx
--- a/tools/examples/xmexample.vmx Fri Sep 23 21:41:28 2005
+++ b/tools/examples/xmexample.vmx Mon Sep 26 17:07:49 2005
@@ -60,9 +60,6 @@
# New stuff
device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
-# Advanced users only. Don't touch if you don't know what you're doing
-memmap = '/usr/lib/xen/boot/mem-map.sxp'
-
#-----------------------------------------------------------------------------
# Disk image for
#cdrom=
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/firmware/vmxassist/Makefile
--- a/tools/firmware/vmxassist/Makefile Fri Sep 23 21:41:28 2005
+++ b/tools/firmware/vmxassist/Makefile Mon Sep 26 17:07:49 2005
@@ -44,7 +44,7 @@
vmxloader: roms.h vmxloader.c acpi.h acpi_madt.c
${CC} ${CFLAGS} ${DEFINES} -c vmxloader.c -c acpi_madt.c
$(CC) -o vmxloader.tmp -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,0x100000
vmxloader.o acpi_madt.o
- objcopy --change-addresses=0xC0000000 vmxloader.tmp vmxloader
+ objcopy vmxloader.tmp vmxloader
rm -f vmxloader.tmp
vmxassist.bin: vmxassist.ld ${OBJECTS}
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/firmware/vmxassist/vmxloader.c
--- a/tools/firmware/vmxassist/vmxloader.c Fri Sep 23 21:41:28 2005
+++ b/tools/firmware/vmxassist/vmxloader.c Mon Sep 26 17:07:49 2005
@@ -34,28 +34,39 @@
/*
* C runtime start off
*/
-asm(" \n\
- .text \n\
- .globl _start \n\
-_start: \n\
- cli \n\
- movl $stack_top, %esp \n\
- movl %esp, %ebp \n\
- call main \n\
- jmp halt \n\
- \n\
- .globl halt \n\
-halt: \n\
- sti \n\
- jmp . \n\
- \n\
- .bss \n\
- .align 8 \n\
- .globl stack, stack_top \n\
-stack: \n\
- .skip 0x4000 \n\
-stack_top: \n\
-");
+asm(
+" .text \n"
+" .globl _start \n"
+"_start: \n"
+" cld \n"
+" cli \n"
+" lgdt gdt_desr \n"
+" movl $stack_top, %esp \n"
+" movl %esp, %ebp \n"
+" call main \n"
+" jmp halt \n"
+" \n"
+"gdt_desr: \n"
+" .word gdt_end - gdt - 1 \n"
+" .long gdt \n"
+" \n"
+" .align 8 \n"
+"gdt: \n"
+" .quad 0x0000000000000000 \n"
+" .quad 0x00CF92000000FFFF \n"
+" .quad 0x00CF9A000000FFFF \n"
+"gdt_end: \n"
+" \n"
+"halt: \n"
+" sti \n"
+" jmp . \n"
+" \n"
+" .bss \n"
+" .align 8 \n"
+"stack: \n"
+" .skip 0x4000 \n"
+"stack_top: \n"
+);
void *
memcpy(void *dest, const void *src, unsigned n)
@@ -95,7 +106,7 @@
}
int
-main()
+main(void)
{
puts("VMXAssist Loader\n");
puts("Loading ROMBIOS ...\n");
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/hw/cirrus_vga.c Mon Sep 26 17:07:49 2005
@@ -231,6 +231,8 @@
int cirrus_linear_io_addr;
int cirrus_linear_bitblt_io_addr;
int cirrus_mmio_io_addr;
+ unsigned long cirrus_lfb_addr;
+ unsigned long cirrus_lfb_end;
uint32_t cirrus_addr_mask;
uint32_t linear_mmio_mask;
uint8_t cirrus_shadow_gr0;
@@ -2447,6 +2449,10 @@
{
unsigned mode;
+ extern void unset_vram_mapping(unsigned long addr, unsigned long end);
+ extern void set_vram_mapping(unsigned long addr, unsigned long end);
+ extern int vga_accelerate;
+
if ((s->sr[0x17] & 0x44) == 0x44) {
goto generic_io;
} else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
@@ -2454,17 +2460,21 @@
} else {
if ((s->gr[0x0B] & 0x14) == 0x14) {
goto generic_io;
- } else if (s->gr[0x0B] & 0x02) {
- goto generic_io;
- }
-
- mode = s->gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
+ } else if (s->gr[0x0B] & 0x02) {
+ goto generic_io;
+ }
+
+ mode = s->gr[0x05] & 0x7;
+ if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
+ if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end)
+ set_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end);
s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
} else {
generic_io:
+ if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end)
+ unset_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end);
s->cirrus_linear_write[0] = cirrus_linear_writeb;
s->cirrus_linear_write[1] = cirrus_linear_writew;
s->cirrus_linear_write[2] = cirrus_linear_writel;
@@ -3058,6 +3068,8 @@
/* XXX: add byte swapping apertures */
cpu_register_physical_memory(addr, s->vram_size,
s->cirrus_linear_io_addr);
+ s->cirrus_lfb_addr = addr;
+ s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
cpu_register_physical_memory(addr + 0x1000000, 0x400000,
s->cirrus_linear_bitblt_io_addr);
}
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/hw/pc.c Mon Sep 26 17:07:49 2005
@@ -385,6 +385,7 @@
unsigned long bios_offset, vga_bios_offset;
int bios_size, isa_bios_size;
PCIBus *pci_bus;
+ extern void * shared_vram;
linux_boot = (kernel_filename != NULL);
@@ -511,14 +512,14 @@
if (cirrus_vga_enabled) {
if (pci_enabled) {
pci_cirrus_vga_init(pci_bus,
- ds, phys_ram_base + ram_size, ram_size,
+ ds, shared_vram, ram_size,
vga_ram_size);
} else {
- isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size,
+ isa_cirrus_vga_init(ds, shared_vram, ram_size,
vga_ram_size);
}
} else {
- vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size,
+ vga_initialize(pci_bus, ds, shared_vram, ram_size,
vga_ram_size);
}
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/hw/vga.c Mon Sep 26 17:07:49 2005
@@ -1568,6 +1568,8 @@
s->graphic_mode = graphic_mode;
full_update = 1;
}
+
+ full_update = 1;
switch(graphic_mode) {
case GMODE_TEXT:
vga_draw_text(s, full_update);
@@ -1848,6 +1850,7 @@
unsigned long vga_ram_offset, int vga_ram_size)
{
int i, j, v, b;
+ extern void* shared_vram;
for(i = 0;i < 256; i++) {
v = 0;
@@ -1876,7 +1879,7 @@
/* qemu's vga mem is not detached from phys_ram_base and can cause DM abort
* when guest write vga mem, so allocate a new one */
- s->vram_ptr = qemu_mallocz(vga_ram_size);
+ s->vram_ptr = shared_vram;
s->vram_offset = vga_ram_offset;
s->vram_size = vga_ram_size;
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c Mon Sep 26 17:07:49 2005
@@ -54,6 +54,8 @@
#include "exec-all.h"
#include "vl.h"
+void *shared_vram;
+
shared_iopage_t *shared_page = NULL;
extern int reset_requested;
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Fri Sep 23 21:41:28 2005
+++ b/tools/ioemu/vl.c Mon Sep 26 17:07:49 2005
@@ -134,6 +134,7 @@
int prep_enabled = 0;
int rtc_utc = 1;
int cirrus_vga_enabled = 1;
+int vga_accelerate = 1;
int graphic_width = 800;
int graphic_height = 600;
int graphic_depth = 15;
@@ -141,6 +142,12 @@
TextConsole *vga_console;
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
int xc_handle;
+unsigned long *vgapage_array;
+unsigned long *freepage_array;
+unsigned long free_pages;
+void *vtop_table;
+unsigned long toptab;
+unsigned long vgaram_pages;
/***********************************************************/
/* x86 ISA bus support */
@@ -2162,6 +2169,7 @@
"-isa simulate an ISA-only system (default is PCI
system)\n"
"-std-vga simulate a standard VGA card with VESA Bochs
Extensions\n"
" (default is CL-GD5446 PCI VGA)\n"
+ "-vgaacc [0|1] 1 to accelerate CL-GD5446 speed, default is 1\n"
#endif
"-loadvm file start right away with a saved state (loadvm in
monitor)\n"
"\n"
@@ -2251,6 +2259,7 @@
QEMU_OPTION_serial,
QEMU_OPTION_loadvm,
QEMU_OPTION_full_screen,
+ QEMU_OPTION_vgaacc,
};
typedef struct QEMUOption {
@@ -2327,6 +2336,7 @@
{ "pci", 0, QEMU_OPTION_pci },
{ "nic-pcnet", 0, QEMU_OPTION_nic_pcnet },
{ "cirrusvga", 0, QEMU_OPTION_cirrusvga },
+ { "vgaacc", HAS_ARG, QEMU_OPTION_vgaacc },
{ NULL },
};
@@ -2342,6 +2352,177 @@
#define NET_IF_TUN 0
#define NET_IF_USER 1
#define NET_IF_DUMMY 2
+
+#include <xg_private.h>
+
+#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
+#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
+
+#ifdef __i386__
+#define _LEVEL_3_ 0
+#else
+#define _LEVEL_3_ 1
+#endif
+
+#if _LEVEL_3_
+#define L3_PROT (_PAGE_PRESENT)
+#define L1_PAGETABLE_ENTRIES 512
+#else
+#define L1_PAGETABLE_ENTRIES 1024
+#endif
+
+inline int
+get_vl2_table(unsigned long count, unsigned long start)
+{
+#if _LEVEL_3_
+ return ((start + (count << PAGE_SHIFT)) >> L3_PAGETABLE_SHIFT) & 0x3;
+#else
+ return 0;
+#endif
+}
+
+int
+setup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long
*mem_page_array, unsigned long *page_table_array, unsigned long v_start,
unsigned long v_end)
+{
+ l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
+ l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
+ unsigned long l1tab;
+ unsigned long ppt_alloc = 0;
+ unsigned long count;
+ int i = 0;
+#if _LEVEL_3_
+ l3_pgentry_t *vl3tab = NULL;
+ unsigned long l2tab;
+ if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ toptab >> PAGE_SHIFT)) == NULL )
+ goto error_out;
+ for (i = 0; i < 4 ; i++) {
+ l2tab = vl3tab[i] & PAGE_MASK;
+ vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ l2tab >> PAGE_SHIFT);
+ if(vl2tab[i] == NULL)
+ goto error_out;
+ }
+ munmap(vl3tab, PAGE_SIZE);
+ vl3tab = NULL;
+#else
+ if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ toptab >> PAGE_SHIFT)) == NULL )
+ goto error_out;
+#endif
+
+ for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ )
+ {
+ if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
+ {
+ vl2_table = vl2tab[get_vl2_table(count, v_start)];
+ vl2e = &vl2_table[l2_table_offset(
+ v_start + (count << PAGE_SHIFT))];
+
+ l1tab = page_table_array[ppt_alloc++] << PAGE_SHIFT;
+ if ( vl1tab != NULL )
+ munmap(vl1tab, PAGE_SIZE);
+
+ if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ l1tab >> PAGE_SHIFT)) == NULL )
+ {
+ goto error_out;
+ }
+ memset(vl1tab, 0, PAGE_SIZE);
+ vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))];
+ *vl2e = l1tab | L2_PROT;
+ }
+
+ *vl1e = (mem_page_array[count] << PAGE_SHIFT) | L1_PROT;
+ vl1e++;
+ }
+error_out:
+ if(vl1tab) munmap(vl1tab, PAGE_SIZE);
+ for(i = 0; i < 4; i++)
+ if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
+ return ppt_alloc;
+}
+
+void
+unsetup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long
v_start, unsigned long v_end)
+{
+ l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
+ l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
+ unsigned long l1tab;
+ unsigned long count;
+ int i = 0;
+#if _LEVEL_3_
+ l3_pgentry_t *vl3tab = NULL;
+ unsigned long l2tab;
+ if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ toptab >> PAGE_SHIFT)) == NULL )
+ goto error_out;
+ for (i = 0; i < 4 ; i ++){
+ l2tab = vl3tab[i] & PAGE_MASK;
+ vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ l2tab >> PAGE_SHIFT);
+ if(vl2tab[i] == NULL)
+ goto error_out;
+ }
+ munmap(vl3tab, PAGE_SIZE);
+ vl3tab = NULL;
+#else
+ if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ toptab >> PAGE_SHIFT)) == NULL )
+ goto error_out;
+#endif
+
+ for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ){
+ if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
+ {
+ vl2_table = vl2tab[get_vl2_table(count, v_start)];
+ vl2e = &vl2_table[l2_table_offset(v_start + (count <<
PAGE_SHIFT))];
+ l1tab = *vl2e & PAGE_MASK;
+
+ if(l1tab == 0)
+ continue;
+ if ( vl1tab != NULL )
+ munmap(vl1tab, PAGE_SIZE);
+
+ if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ l1tab >> PAGE_SHIFT)) == NULL )
+ {
+ goto error_out;
+ }
+ vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))];
+ *vl2e = 0;
+ }
+
+ *vl1e = 0;
+ vl1e++;
+ }
+error_out:
+ if(vl1tab) munmap(vl1tab, PAGE_SIZE);
+ for(i = 0; i < 4; i++)
+ if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
+}
+
+void set_vram_mapping(unsigned long addr, unsigned long end)
+{
+ end = addr + VGA_RAM_SIZE;
+ setup_mapping(xc_handle, domid, toptab,
+ vgapage_array, freepage_array, addr, end);
+}
+
+void unset_vram_mapping(unsigned long addr, unsigned long end)
+{
+ end = addr + VGA_RAM_SIZE;
+ /* FIXME Flush the shadow page */
+ unsetup_mapping(xc_handle, domid, toptab, addr, end);
+}
int main(int argc, char **argv)
{
@@ -2366,8 +2547,9 @@
char serial_devices[MAX_SERIAL_PORTS][128];
int serial_device_index;
const char *loadvm = NULL;
- unsigned long nr_pages, *page_array;
+ unsigned long nr_pages, extra_pages, ram_pages, *page_array;
extern void *shared_page;
+ extern void *shared_vram;
/* change the qemu-dm to daemon, just like bochs dm */
// daemon(0, 0);
@@ -2674,6 +2856,17 @@
case QEMU_OPTION_cirrusvga:
cirrus_vga_enabled = 1;
break;
+ case QEMU_OPTION_vgaacc:
+ {
+ const char *p;
+ p = optarg;
+ vga_accelerate = strtol(p, (char **)&p, 0);
+ if (*p != '\0') {
+ fprintf(stderr, "qemu: invalid vgaacc option\n");
+ exit(1);
+ }
+ break;
+ }
case QEMU_OPTION_std_vga:
cirrus_vga_enabled = 0;
break;
@@ -2803,12 +2996,25 @@
/* init the memory */
phys_ram_size = ram_size + vga_ram_size + bios_size;
- #define PAGE_SHIFT 12
- #define PAGE_SIZE (1 << PAGE_SHIFT)
-
- nr_pages = ram_size/PAGE_SIZE;
+ ram_pages = ram_size/PAGE_SIZE;
+ vgaram_pages = (vga_ram_size -1)/PAGE_SIZE + 1;
+ free_pages = vgaram_pages / L1_PAGETABLE_ENTRIES;
+ extra_pages = vgaram_pages + free_pages;
+
xc_handle = xc_interface_open();
-
+
+ xc_dominfo_t info;
+ xc_domain_getinfo(xc_handle, domid, 1, &info);
+
+ nr_pages = info.nr_pages + extra_pages;
+
+ if ( xc_domain_setmaxmem(xc_handle, domid,
+ (nr_pages) * PAGE_SIZE/1024 ) != 0)
+ {
+ perror("set maxmem");
+ exit(-1);
+ }
+
if ( (page_array = (unsigned long *)
malloc(nr_pages * sizeof(unsigned long))) == NULL)
{
@@ -2816,6 +3022,12 @@
exit(-1);
}
+ if (xc_domain_memory_increase_reservation(xc_handle, domid,
+ extra_pages , 0, 0, NULL) != 0) {
+ perror("increase reservation");
+ exit(-1);
+ }
+
if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
{
perror("xc_get_pfn_list");
@@ -2825,15 +3037,36 @@
if ((phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
PROT_READ|PROT_WRITE,
page_array,
- nr_pages - 1)) == 0) {
+ ram_pages - 1)) == 0) {
perror("xc_map_foreign_batch");
exit(-1);
}
shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
PROT_READ|PROT_WRITE,
- page_array[nr_pages - 1]);
-
+ page_array[ram_pages - 1]);
+
+ vgapage_array = &page_array[nr_pages - vgaram_pages];
+
+ if ((shared_vram = xc_map_foreign_batch(xc_handle, domid,
+ PROT_READ|PROT_WRITE,
+ vgapage_array,
+ vgaram_pages)) == 0) {
+ perror("xc_map_foreign_batch vgaram ");
+ exit(-1);
+ }
+
+
+
+ memset(shared_vram, 0, vgaram_pages * PAGE_SIZE);
+ toptab = page_array[ram_pages] << PAGE_SHIFT;
+
+ vtop_table = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ page_array[ram_pages]);
+
+ freepage_array = &page_array[nr_pages - extra_pages];
+
fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1),
(page_array[nr_pages - 1]));
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c Fri Sep 23 21:41:28 2005
+++ b/tools/libxc/xc_vmx_build.c Mon Sep 26 17:07:49 2005
@@ -10,7 +10,8 @@
#include <unistd.h>
#include <zlib.h>
#include <xen/io/ioreq.h>
-#include "linux_boot_params.h"
+
+#define VMX_LOADER_ENTR_ADDR 0x00100000
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
@@ -18,12 +19,28 @@
#define L3_PROT (_PAGE_PRESENT)
#endif
+#define E820MAX 128
+
+#define E820_RAM 1
+#define E820_RESERVED 2
+#define E820_ACPI 3
+#define E820_NVS 4
+#define E820_IO 16
+#define E820_SHARED_PAGE 17
+#define E820_XENSTORE 18
+
+#define E820_MAP_PAGE 0x00090000
+#define E820_MAP_NR_OFFSET 0x000001E8
+#define E820_MAP_OFFSET 0x000002D0
+
+struct e820entry {
+ u64 addr;
+ u64 size;
+ u32 type;
+} __attribute__((packed));
+
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
#define round_pgdown(_p) ((_p)&PAGE_MASK)
-
-#define LINUX_BOOT_PARAMS_ADDR 0x00090000
-#define LINUX_KERNEL_ENTR_ADDR 0x00100000
-#define LINUX_PAGE_OFFSET 0xC0000000
static int
parseelfimage(
@@ -33,78 +50,70 @@
char *elfbase, int xch, u32 dom, unsigned long *parray,
struct domain_setup_info *dsi);
-static void build_e820map(struct mem_map *mem_mapp, unsigned long mem_size)
-{
- int nr_map = 0;
+static unsigned char build_e820map(void *e820_page, unsigned long mem_size)
+{
+ struct e820entry *e820entry =
+ (struct e820entry *)(((unsigned char *)e820_page) + E820_MAP_OFFSET);
+ unsigned char nr_map = 0;
/* XXX: Doesn't work for > 4GB yet */
- mem_mapp->map[nr_map].addr = 0x0;
- mem_mapp->map[nr_map].size = 0x9F800;
- mem_mapp->map[nr_map].type = E820_RAM;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
- nr_map++;
-
- mem_mapp->map[nr_map].addr = 0x9F800;
- mem_mapp->map[nr_map].size = 0x800;
- mem_mapp->map[nr_map].type = E820_RESERVED;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
- nr_map++;
-
- mem_mapp->map[nr_map].addr = 0xA0000;
- mem_mapp->map[nr_map].size = 0x20000;
- mem_mapp->map[nr_map].type = E820_IO;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
- nr_map++;
-
- mem_mapp->map[nr_map].addr = 0xF0000;
- mem_mapp->map[nr_map].size = 0x10000;
- mem_mapp->map[nr_map].type = E820_RESERVED;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
+ e820entry[nr_map].addr = 0x0;
+ e820entry[nr_map].size = 0x9F800;
+ e820entry[nr_map].type = E820_RAM;
+ nr_map++;
+
+ e820entry[nr_map].addr = 0x9F800;
+ e820entry[nr_map].size = 0x800;
+ e820entry[nr_map].type = E820_RESERVED;
+ nr_map++;
+
+ e820entry[nr_map].addr = 0xA0000;
+ e820entry[nr_map].size = 0x20000;
+ e820entry[nr_map].type = E820_IO;
+ nr_map++;
+
+ e820entry[nr_map].addr = 0xF0000;
+ e820entry[nr_map].size = 0x10000;
+ e820entry[nr_map].type = E820_RESERVED;
nr_map++;
#define STATIC_PAGES 2 /* for ioreq_t and store_mfn */
/* Most of the ram goes here */
- mem_mapp->map[nr_map].addr = 0x100000;
- mem_mapp->map[nr_map].size = mem_size - 0x100000 - STATIC_PAGES*PAGE_SIZE;
- mem_mapp->map[nr_map].type = E820_RAM;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
+ e820entry[nr_map].addr = 0x100000;
+ e820entry[nr_map].size = mem_size - 0x100000 - STATIC_PAGES*PAGE_SIZE;
+ e820entry[nr_map].type = E820_RAM;
nr_map++;
/* Statically allocated special pages */
/* Shared ioreq_t page */
- mem_mapp->map[nr_map].addr = mem_size - PAGE_SIZE;
- mem_mapp->map[nr_map].size = PAGE_SIZE;
- mem_mapp->map[nr_map].type = E820_SHARED;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
+ e820entry[nr_map].addr = mem_size - PAGE_SIZE;
+ e820entry[nr_map].size = PAGE_SIZE;
+ e820entry[nr_map].type = E820_SHARED_PAGE;
nr_map++;
/* For xenstore */
- mem_mapp->map[nr_map].addr = mem_size - 2*PAGE_SIZE;
- mem_mapp->map[nr_map].size = PAGE_SIZE;
- mem_mapp->map[nr_map].type = E820_XENSTORE;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
- nr_map++;
-
- mem_mapp->map[nr_map].addr = mem_size;
- mem_mapp->map[nr_map].size = 0x3 * PAGE_SIZE;
- mem_mapp->map[nr_map].type = E820_NVS;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
- nr_map++;
-
- mem_mapp->map[nr_map].addr = mem_size + 0x3 * PAGE_SIZE;
- mem_mapp->map[nr_map].size = 0xA * PAGE_SIZE;
- mem_mapp->map[nr_map].type = E820_ACPI;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_WB;
- nr_map++;
-
- mem_mapp->map[nr_map].addr = 0xFEC00000;
- mem_mapp->map[nr_map].size = 0x1400000;
- mem_mapp->map[nr_map].type = E820_IO;
- mem_mapp->map[nr_map].caching_attr = MEMMAP_UC;
- nr_map++;
-
- mem_mapp->nr_map = nr_map;
+ e820entry[nr_map].addr = mem_size - 2*PAGE_SIZE;
+ e820entry[nr_map].size = PAGE_SIZE;
+ e820entry[nr_map].type = E820_XENSTORE;
+ nr_map++;
+
+ e820entry[nr_map].addr = mem_size;
+ e820entry[nr_map].size = 0x3 * PAGE_SIZE;
+ e820entry[nr_map].type = E820_NVS;
+ nr_map++;
+
+ e820entry[nr_map].addr = mem_size + 0x3 * PAGE_SIZE;
+ e820entry[nr_map].size = 0xA * PAGE_SIZE;
+ e820entry[nr_map].type = E820_ACPI;
+ nr_map++;
+
+ e820entry[nr_map].addr = 0xFEC00000;
+ e820entry[nr_map].size = 0x1400000;
+ e820entry[nr_map].type = E820_IO;
+ nr_map++;
+
+ return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
}
/*
@@ -112,19 +121,19 @@
* vmxloader will use it to config ACPI MADT table
*/
#define VCPU_MAGIC 0x76637075 /* "vcpu" */
-static int
-set_nr_vcpus(int xc_handle, u32 dom, unsigned long *pfn_list,
+static int
+set_nr_vcpus(int xc_handle, u32 dom, unsigned long *pfn_list,
struct domain_setup_info *dsi, unsigned long vcpus)
{
char *va_map;
unsigned long *va_vcpus;
-
+
va_map = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
- pfn_list[(0x9F000 - dsi->v_start) >> PAGE_SHIFT]);
+ pfn_list[(0x9F000 - dsi->v_start) >> PAGE_SHIFT]);
if ( va_map == NULL )
return -1;
-
+
va_vcpus = (unsigned long *)(va_map + 0x800);
*va_vcpus++ = VCPU_MAGIC;
*va_vcpus++ = vcpus;
@@ -164,24 +173,23 @@
return 0;
}
-static int zap_mmio_ranges(int xc_handle, u32 dom,
- unsigned long l2tab,
- struct mem_map *mem_mapp)
-{
- int i;
+static int zap_mmio_ranges(int xc_handle, u32 dom, unsigned long l2tab,
+ unsigned char e820_map_nr, unsigned char *e820map)
+{
+ unsigned int i;
+ struct e820entry *e820entry = (struct e820entry *)e820map;
+
l2_pgentry_32_t *vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE,
l2tab >> PAGE_SHIFT);
if ( vl2tab == 0 )
return -1;
- for ( i = 0; i < mem_mapp->nr_map; i++ )
- {
- if ( (mem_mapp->map[i].type == E820_IO) &&
- (mem_mapp->map[i].caching_attr == MEMMAP_UC) &&
+ for ( i = 0; i < e820_map_nr; i++ )
+ {
+ if ( (e820entry[i].type == E820_IO) &&
(zap_mmio_range(xc_handle, dom, vl2tab,
- mem_mapp->map[i].addr,
- mem_mapp->map[i].size) == -1) )
+ e820entry[i].addr, e820entry[i].size) == -1))
return -1;
}
@@ -200,7 +208,7 @@
unsigned long vl3e;
l1_pgentry_t *vl1tab;
l2_pgentry_t *vl2tab;
-
+
mmio_addr = mmio_range_start & PAGE_MASK;
for ( ; mmio_addr < mmio_range_end; mmio_addr += PAGE_SIZE )
{
@@ -239,22 +247,22 @@
return 0;
}
-static int zap_mmio_ranges(int xc_handle, u32 dom,
- unsigned long l3tab,
- struct mem_map *mem_mapp)
-{
- int i;
+static int zap_mmio_ranges(int xc_handle, u32 dom, unsigned long l3tab,
+ unsigned char e820_map_nr, unsigned char *e820map)
+{
+ unsigned int i;
+ struct e820entry *e820entry = (struct e820entry *)e820map;
+
l3_pgentry_t *vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE,
l3tab >> PAGE_SHIFT);
if (vl3tab == 0)
return -1;
- for (i = 0; i < mem_mapp->nr_map; i++) {
- if ((mem_mapp->map[i].type == E820_IO)
- && (mem_mapp->map[i].caching_attr == MEMMAP_UC))
- if (zap_mmio_range(xc_handle, dom, vl3tab,
- mem_mapp->map[i].addr, mem_mapp->map[i].size)
== -1)
- return -1;
+ for ( i = 0; i < e820_map_nr; i++ ) {
+ if ( (e820entry[i].type == E820_IO) &&
+ (zap_mmio_range(xc_handle, dom, vl3tab,
+ e820entry[i].addr, e820entry[i].size) == -1) )
+ return -1;
}
munmap(vl3tab, PAGE_SIZE);
return 0;
@@ -265,18 +273,14 @@
static int setup_guest(int xc_handle,
u32 dom, int memsize,
char *image, unsigned long image_size,
- gzFile initrd_gfd, unsigned long initrd_len,
unsigned long nr_pages,
vcpu_guest_context_t *ctxt,
- const char *cmdline,
unsigned long shared_info_frame,
unsigned int control_evtchn,
unsigned long flags,
unsigned int vcpus,
unsigned int store_evtchn,
- unsigned long *store_mfn,
- struct mem_map *mem_mapp
- )
+ unsigned long *store_mfn)
{
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
@@ -289,8 +293,8 @@
unsigned long l1tab;
unsigned long count, i;
shared_info_t *shared_info;
- struct linux_boot_params * boot_paramsp;
- __u16 * boot_gdtp;
+ void *e820_page;
+ unsigned char e820_map_nr;
xc_mmu_t *mmu = NULL;
int rc;
@@ -298,12 +302,6 @@
unsigned long ppt_alloc;
struct domain_setup_info dsi;
- unsigned long vinitrd_start;
- unsigned long vinitrd_end;
- unsigned long vboot_params_start;
- unsigned long vboot_params_end;
- unsigned long vboot_gdt_start;
- unsigned long vboot_gdt_end;
unsigned long vpt_start;
unsigned long vpt_end;
unsigned long v_end;
@@ -322,27 +320,8 @@
goto error_out;
}
- /*
- * Why do we need this? The number of page-table frames depends on the
- * size of the bootstrap address space. But the size of the address space
- * depends on the number of page-table frames (since each one is mapped
- * read-only). We have a pair of simultaneous equations in two unknowns,
- * which we solve by exhaustive search.
- */
- vboot_params_start = LINUX_BOOT_PARAMS_ADDR;
- vboot_params_end = vboot_params_start + PAGE_SIZE;
- vboot_gdt_start = vboot_params_end;
- vboot_gdt_end = vboot_gdt_start + PAGE_SIZE;
-
/* memsize is in megabytes */
v_end = memsize << 20;
- /* leaving the top 4k untouched for IO requests page use */
- vinitrd_end = v_end - PAGE_SIZE;
- vinitrd_start = vinitrd_end - initrd_len;
- vinitrd_start = vinitrd_start & (~(PAGE_SIZE - 1));
-
- if(initrd_len == 0)
- vinitrd_start = vinitrd_end = 0;
#ifdef __i386__
nr_pt_pages = 1 + ((memsize + 3) >> 2);
@@ -353,24 +332,17 @@
vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE);
printf("VIRTUAL MEMORY ARRANGEMENT:\n"
- " Boot_params: %08lx->%08lx\n"
- " boot_gdt: %08lx->%08lx\n"
- " Loaded kernel: %08lx->%08lx\n"
- " Init. ramdisk: %08lx->%08lx\n"
+ " Loaded VMX loader: %08lx->%08lx\n"
" Page tables: %08lx->%08lx\n"
" TOTAL: %08lx->%08lx\n",
- vboot_params_start, vboot_params_end,
- vboot_gdt_start, vboot_gdt_end,
- dsi.v_kernstart, dsi.v_kernend,
- vinitrd_start, vinitrd_end,
+ dsi.v_kernstart, dsi.v_kernend,
vpt_start, vpt_end,
dsi.v_start, v_end);
printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
- printf(" INITRD LENGTH: %08lx\n", initrd_len);
if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
{
- printf("Initial guest OS requires too much space\n"
+ ERROR("Initial guest OS requires too much space\n"
"(%luMB is greater than %luMB limit)\n",
(v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
goto error_out;
@@ -389,23 +361,6 @@
}
loadelfimage(image, xc_handle, dom, page_array, &dsi);
-
- /* Load the initial ramdisk image. */
- if ( initrd_len != 0 )
- {
- for ( i = (vinitrd_start - dsi.v_start);
- i < (vinitrd_end - dsi.v_start); i += PAGE_SIZE )
- {
- char page[PAGE_SIZE];
- if ( gzread(initrd_gfd, page, PAGE_SIZE) == -1 )
- {
- PERROR("Error reading initrd image, could not");
- goto error_out;
- }
- xc_copy_to_domain_page(xc_handle, dom,
- page_array[i>>PAGE_SHIFT], page);
- }
- }
if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
goto error_out;
@@ -428,15 +383,14 @@
l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
ctxt->ctrlreg[3] = l2tab;
- /* Initialise the page tables. */
- if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
- PROT_READ|PROT_WRITE,
+ if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
l2tab >> PAGE_SHIFT)) == NULL )
goto error_out;
memset(vl2tab, 0, PAGE_SIZE);
vl2e = &vl2tab[l2_table_offset(dsi.v_start)];
for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
- {
+ {
if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
{
l1tab = page_array[ppt_alloc++] << PAGE_SHIFT;
@@ -460,23 +414,35 @@
munmap(vl1tab, PAGE_SIZE);
munmap(vl2tab, PAGE_SIZE);
#else
- /* here l3tab means pdpt, only 4 entry is used */
l3tab = page_array[ppt_alloc++] << PAGE_SHIFT;
ctxt->ctrlreg[3] = l3tab;
- /* Initialise the page tables. */
- if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
- PROT_READ|PROT_WRITE,
+ if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
l3tab >> PAGE_SHIFT)) == NULL )
goto error_out;
memset(vl3tab, 0, PAGE_SIZE);
+ /* Fill in every PDPT entry. */
+ for ( i = 0; i < L3_PAGETABLE_ENTRIES_PAE; i++ )
+ {
+ l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
+ if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ l2tab >> PAGE_SHIFT)) == NULL )
+ goto error_out;
+ memset(vl2tab, 0, PAGE_SIZE);
+ munmap(vl2tab, PAGE_SIZE);
+ vl3tab[i] = l2tab | L3_PROT;
+ }
+
vl3e = &vl3tab[l3_table_offset(dsi.v_start)];
for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
{
- if (!(count % (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
- l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
+ if (!(count & (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
+ l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]
+ & PAGE_MASK;
if (vl2tab != NULL)
munmap(vl2tab, PAGE_SIZE);
@@ -486,8 +452,6 @@
l2tab >> PAGE_SHIFT)) == NULL )
goto error_out;
- memset(vl2tab, 0, PAGE_SIZE);
- *vl3e++ = l2tab | L3_PROT;
vl2e = &vl2tab[l2_table_offset(dsi.v_start + (count <<
PAGE_SHIFT))];
}
if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
@@ -519,103 +483,31 @@
for ( count = 0; count < nr_pages; count++ )
{
if ( xc_add_mmu_update(xc_handle, mmu,
- (page_array[count] << PAGE_SHIFT) |
+ (page_array[count] << PAGE_SHIFT) |
MMU_MACHPHYS_UPDATE, count) )
goto error_out;
}
set_nr_vcpus(xc_handle, dom, page_array, &dsi, vcpus);
- if ((boot_paramsp = xc_map_foreign_range(
+ *store_mfn = page_array[(v_end-2) >> PAGE_SHIFT];
+ shared_page_frame = (v_end - PAGE_SIZE) >> PAGE_SHIFT;
+
+ if ((e820_page = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
- page_array[(vboot_params_start-dsi.v_start)>>PAGE_SHIFT])) == 0)
- goto error_out;
-
- memset(boot_paramsp, 0, sizeof(*boot_paramsp));
-
- strncpy((char *)boot_paramsp->cmd_line, cmdline, 0x800);
- boot_paramsp->cmd_line[0x800-1] = '\0';
- boot_paramsp->cmd_line_ptr = ((unsigned long) vboot_params_start) +
offsetof(struct linux_boot_params, cmd_line);
-
- boot_paramsp->setup_sects = 0;
- boot_paramsp->mount_root_rdonly = 1;
- boot_paramsp->swapdev = 0x0;
- boot_paramsp->ramdisk_flags = 0x0;
- boot_paramsp->root_dev = 0x0; /* We must tell kernel root dev by kernel
command line. */
-
- /* we don't have a ps/2 mouse now.
- * 0xAA means a aux mouse is there.
- * See detect_auxiliary_port() in pc_keyb.c.
- */
- boot_paramsp->aux_device_info = 0x0;
-
- boot_paramsp->header_magic[0] = 0x48; /* "H" */
- boot_paramsp->header_magic[1] = 0x64; /* "d" */
- boot_paramsp->header_magic[2] = 0x72; /* "r" */
- boot_paramsp->header_magic[3] = 0x53; /* "S" */
-
- boot_paramsp->protocol_version = 0x0203; /* 2.03 */
- boot_paramsp->loader_type = 0x71; /* GRUB */
- boot_paramsp->loader_flags = 0x1; /* loaded high */
- boot_paramsp->code32_start = LINUX_KERNEL_ENTR_ADDR; /* 1MB */
- boot_paramsp->initrd_start = vinitrd_start;
- boot_paramsp->initrd_size = initrd_len;
-
- i = ((memsize - 1) << 10) - 4;
- boot_paramsp->alt_mem_k = i; /* alt_mem_k */
- boot_paramsp->screen.overlap.ext_mem_k = i & 0xFFFF; /* ext_mem_k */
-
- /*
- * Stuff SCREAN_INFO
- */
- boot_paramsp->screen.info.orig_x = 0;
- boot_paramsp->screen.info.orig_y = 0;
- boot_paramsp->screen.info.orig_video_page = 8;
- boot_paramsp->screen.info.orig_video_mode = 3;
- boot_paramsp->screen.info.orig_video_cols = 80;
- boot_paramsp->screen.info.orig_video_ega_bx = 0;
- boot_paramsp->screen.info.orig_video_lines = 25;
- boot_paramsp->screen.info.orig_video_isVGA = 1;
- boot_paramsp->screen.info.orig_video_points = 0x0010;
-
- /* seems we may NOT stuff boot_paramsp->apm_bios_info */
- /* seems we may NOT stuff boot_paramsp->drive_info */
- /* seems we may NOT stuff boot_paramsp->sys_desc_table */
- *((unsigned short *) &boot_paramsp->drive_info.dummy[0]) = 800;
- boot_paramsp->drive_info.dummy[2] = 4;
- boot_paramsp->drive_info.dummy[14] = 32;
-
- /* memsize is in megabytes */
- /* If you need to create a special e820map, comment this line
- and use mem-map.sxp */
- build_e820map(mem_mapp, memsize << 20);
- *store_mfn = page_array[(v_end-2) >> PAGE_SHIFT];
+ page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0)
+ goto error_out;
+ memset(e820_page, 0, PAGE_SIZE);
+ e820_map_nr = build_e820map(e820_page, v_end);
#if defined (__i386__)
- if (zap_mmio_ranges(xc_handle, dom, l2tab, mem_mapp) == -1)
+ if (zap_mmio_ranges(xc_handle, dom, l2tab, e820_map_nr,
+ ((unsigned char *)e820_page) + E820_MAP_OFFSET) == -1)
#else
- if (zap_mmio_ranges(xc_handle, dom, l3tab, mem_mapp) == -1)
+ if (zap_mmio_ranges(xc_handle, dom, l3tab, e820_map_nr,
+ ((unsigned char *)e820_page) + E820_MAP_OFFSET) == -1)
#endif
- goto error_out;
- boot_paramsp->e820_map_nr = mem_mapp->nr_map;
- for (i=0; i<mem_mapp->nr_map; i++) {
- boot_paramsp->e820_map[i].addr = mem_mapp->map[i].addr;
- boot_paramsp->e820_map[i].size = mem_mapp->map[i].size;
- boot_paramsp->e820_map[i].type = mem_mapp->map[i].type;
- if (mem_mapp->map[i].type == E820_SHARED)
- shared_page_frame = (mem_mapp->map[i].addr >> PAGE_SHIFT);
- }
- munmap(boot_paramsp, PAGE_SIZE);
-
- if ((boot_gdtp = xc_map_foreign_range(
- xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
- page_array[(vboot_gdt_start-dsi.v_start)>>PAGE_SHIFT])) == 0)
- goto error_out;
- memset(boot_gdtp, 0, PAGE_SIZE);
- boot_gdtp[12*4 + 0] = boot_gdtp[13*4 + 0] = 0xffff; /* limit */
- boot_gdtp[12*4 + 1] = boot_gdtp[13*4 + 1] = 0x0000; /* base */
- boot_gdtp[12*4 + 2] = 0x9a00; boot_gdtp[13*4 + 2] = 0x9200; /* perms */
- boot_gdtp[12*4 + 3] = boot_gdtp[13*4 + 3] = 0x00cf; /* granu + top of
limit */
- munmap(boot_gdtp, PAGE_SIZE);
+ goto error_out;
+ munmap(e820_page, PAGE_SIZE);
/* shared_info page starts its life empty. */
if ((shared_info = xc_map_foreign_range(
@@ -651,20 +543,21 @@
/*
* Initial register values:
*/
- ctxt->user_regs.ds = 0x68;
- ctxt->user_regs.es = 0x0;
- ctxt->user_regs.fs = 0x0;
- ctxt->user_regs.gs = 0x0;
- ctxt->user_regs.ss = 0x68;
- ctxt->user_regs.cs = 0x60;
+ ctxt->user_regs.ds = 0;
+ ctxt->user_regs.es = 0;
+ ctxt->user_regs.fs = 0;
+ ctxt->user_regs.gs = 0;
+ ctxt->user_regs.ss = 0;
+ ctxt->user_regs.cs = 0;
ctxt->user_regs.eip = dsi.v_kernentry;
- ctxt->user_regs.edx = vboot_gdt_start;
- ctxt->user_regs.eax = 0x800;
- ctxt->user_regs.esp = vboot_gdt_end;
+ ctxt->user_regs.edx = 0;
+ ctxt->user_regs.eax = 0;
+ ctxt->user_regs.esp = 0;
ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot
cpu */
- ctxt->user_regs.ecx = mem_mapp->nr_map;
- ctxt->user_regs.esi = vboot_params_start;
- ctxt->user_regs.edi = vboot_params_start + 0x2d0;
+ ctxt->user_regs.ecx = 0;
+ ctxt->user_regs.esi = 0;
+ ctxt->user_regs.edi = 0;
+ ctxt->user_regs.ebp = 0;
ctxt->user_regs.eflags = 0;
@@ -684,9 +577,9 @@
int eax, ecx;
#ifdef __i386__
- __asm__ __volatile__ ("pushl %%ebx; cpuid; popl %%ebx"
- : "=a" (eax), "=c" (ecx)
- : "0" (1)
+ __asm__ __volatile__ ("pushl %%ebx; cpuid; popl %%ebx"
+ : "=a" (eax), "=c" (ecx)
+ : "0" (1)
: "dx");
#elif defined __x86_64__
__asm__ __volatile__ ("pushq %%rbx; cpuid; popq %%rbx"
@@ -705,9 +598,6 @@
u32 domid,
int memsize,
const char *image_name,
- struct mem_map *mem_mapp,
- const char *ramdisk_name,
- const char *cmdline,
unsigned int control_evtchn,
unsigned long flags,
unsigned int vcpus,
@@ -715,20 +605,18 @@
unsigned long *store_mfn)
{
dom0_op_t launch_op, op;
- int initrd_fd = -1;
- gzFile initrd_gfd = NULL;
int rc, i;
vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
unsigned long nr_pages;
char *image = NULL;
- unsigned long image_size, initrd_size=0;
+ unsigned long image_size;
if ( vmx_identify() < 0 )
{
PERROR("CPU doesn't support VMX Extensions");
goto error_out;
}
-
+
if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 )
{
PERROR("Could not find total pages for domain");
@@ -738,32 +626,15 @@
if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL )
goto error_out;
- if ( (ramdisk_name != NULL) && (strlen(ramdisk_name) != 0) )
- {
- if ( (initrd_fd = open(ramdisk_name, O_RDONLY)) < 0 )
- {
- PERROR("Could not open the initial ramdisk image");
- goto error_out;
- }
-
- initrd_size = xc_get_filesz(initrd_fd);
-
- if ( (initrd_gfd = gzdopen(initrd_fd, "rb")) == NULL )
- {
- PERROR("Could not allocate decompression state for initrd");
- goto error_out;
- }
- }
-
if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
- {
+ {
PERROR("xc_vmx_build: ctxt mlock failed");
return 1;
}
op.cmd = DOM0_GETDOMAININFO;
op.u.getdomaininfo.domain = (domid_t)domid;
- if ( (xc_dom0_op(xc_handle, &op) < 0) ||
+ if ( (xc_dom0_op(xc_handle, &op) < 0) ||
((u16)op.u.getdomaininfo.domain != domid) )
{
PERROR("Could not get info on domain");
@@ -783,21 +654,14 @@
goto error_out;
}
- if ( setup_guest(xc_handle, domid, memsize, image, image_size,
- initrd_gfd, initrd_size, nr_pages,
- ctxt, cmdline,
- op.u.getdomaininfo.shared_info_frame,
- control_evtchn, flags, vcpus, store_evtchn, store_mfn,
- mem_mapp) < 0 )
+ if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
+ ctxt, op.u.getdomaininfo.shared_info_frame,
control_evtchn,
+ flags, vcpus, store_evtchn, store_mfn) < 0)
{
ERROR("Error constructing guest OS");
goto error_out;
}
- if ( initrd_fd >= 0 )
- close(initrd_fd);
- if ( initrd_gfd )
- gzclose(initrd_gfd);
free(image);
ctxt->flags = VGCF_VMX_GUEST;
@@ -813,15 +677,10 @@
/* No LDT. */
ctxt->ldt_ents = 0;
-
+
/* Use the default Xen-provided GDT. */
ctxt->gdt_ents = 0;
- /* Ring 1 stack is the initial stack. */
-/*
- ctxt->kernel_ss = FLAT_KERNEL_DS;
- ctxt->kernel_sp = vstartinfo_start;
-*/
/* No debugging. */
memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
@@ -845,14 +704,10 @@
launch_op.cmd = DOM0_SETDOMAININFO;
rc = xc_dom0_op(xc_handle, &launch_op);
-
+
return rc;
error_out:
- if ( initrd_gfd != NULL )
- gzclose(initrd_gfd);
- else if ( initrd_fd >= 0 )
- close(initrd_fd);
free(image);
return -1;
@@ -864,7 +719,7 @@
((phdr->p_flags & (PF_W|PF_X)) != 0));
}
-static int parseelfimage(char *elfbase,
+static int parseelfimage(char *elfbase,
unsigned long elfsize,
struct domain_setup_info *dsi)
{
@@ -899,11 +754,11 @@
ERROR("ELF image has no section-header strings table (shstrtab).");
return -EINVAL;
}
- shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
+ shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
(ehdr->e_shstrndx*ehdr->e_shentsize));
shstrtab = elfbase + shdr->sh_offset;
-
- for ( h = 0; h < ehdr->e_phnum; h++ )
+
+ for ( h = 0; h < ehdr->e_phnum; h++ )
{
phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
if ( !is_loadable_phdr(phdr) )
@@ -914,8 +769,8 @@
kernend = phdr->p_paddr + phdr->p_memsz;
}
- if ( (kernstart > kernend) ||
- (ehdr->e_entry < kernstart) ||
+ if ( (kernstart > kernend) ||
+ (ehdr->e_entry < kernstart) ||
(ehdr->e_entry > kernend) )
{
ERROR("Malformed ELF image.");
@@ -924,9 +779,9 @@
dsi->v_start = 0x00000000;
- dsi->v_kernstart = kernstart - LINUX_PAGE_OFFSET;
- dsi->v_kernend = kernend - LINUX_PAGE_OFFSET;
- dsi->v_kernentry = LINUX_KERNEL_ENTR_ADDR;
+ dsi->v_kernstart = kernstart;
+ dsi->v_kernend = kernend;
+ dsi->v_kernentry = VMX_LOADER_ENTR_ADDR;
dsi->v_end = dsi->v_kernend;
@@ -945,18 +800,18 @@
char *va;
unsigned long pa, done, chunksz;
- for ( h = 0; h < ehdr->e_phnum; h++ )
+ for ( h = 0; h < ehdr->e_phnum; h++ )
{
phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
if ( !is_loadable_phdr(phdr) )
continue;
-
+
for ( done = 0; done < phdr->p_filesz; done += chunksz )
{
- pa = (phdr->p_paddr + done) - dsi->v_start - LINUX_PAGE_OFFSET;
+ pa = (phdr->p_paddr + done) - dsi->v_start;
if ((va = xc_map_foreign_range(
xch, dom, PAGE_SIZE, PROT_WRITE,
- parray[pa>>PAGE_SHIFT])) == 0)
+ parray[pa >> PAGE_SHIFT])) == 0)
return -1;
chunksz = phdr->p_filesz - done;
if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
@@ -968,10 +823,10 @@
for ( ; done < phdr->p_memsz; done += chunksz )
{
- pa = (phdr->p_paddr + done) - dsi->v_start - LINUX_PAGE_OFFSET;
+ pa = (phdr->p_paddr + done) - dsi->v_start;
if ((va = xc_map_foreign_range(
xch, dom, PAGE_SIZE, PROT_WRITE,
- parray[pa>>PAGE_SHIFT])) == 0)
+ parray[pa >> PAGE_SHIFT])) == 0)
return -1;
chunksz = phdr->p_memsz - done;
if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h Fri Sep 23 21:41:28 2005
+++ b/tools/libxc/xenguest.h Mon Sep 26 17:07:49 2005
@@ -57,9 +57,6 @@
uint32_t domid,
int memsize,
const char *image_name,
- struct mem_map *memmap,
- const char *ramdisk_name,
- const char *cmdline,
unsigned int control_evtchn,
unsigned long flags,
unsigned int vcpus,
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h Fri Sep 23 21:41:28 2005
+++ b/tools/libxc/xg_private.h Mon Sep 26 17:07:49 2005
@@ -28,25 +28,27 @@
#define _PAGE_PSE 0x080
#define _PAGE_GLOBAL 0x100
+#define L1_PAGETABLE_SHIFT_PAE 12
+#define L2_PAGETABLE_SHIFT_PAE 21
+#define L3_PAGETABLE_SHIFT_PAE 30
+
#if defined(__i386__)
#define L1_PAGETABLE_SHIFT 12
#define L2_PAGETABLE_SHIFT 22
-#define L1_PAGETABLE_SHIFT_PAE 12
-#define L2_PAGETABLE_SHIFT_PAE 21
-#define L3_PAGETABLE_SHIFT_PAE 30
#elif defined(__x86_64__)
-#define L1_PAGETABLE_SHIFT 12
-#define L2_PAGETABLE_SHIFT 21
-#define L3_PAGETABLE_SHIFT 30
-#define L4_PAGETABLE_SHIFT 39
+#define L1_PAGETABLE_SHIFT 12
+#define L2_PAGETABLE_SHIFT 21
+#define L3_PAGETABLE_SHIFT 30
+#define L4_PAGETABLE_SHIFT 39
#endif
-#if defined(__i386__)
-#define ENTRIES_PER_L1_PAGETABLE 1024
-#define ENTRIES_PER_L2_PAGETABLE 1024
#define L1_PAGETABLE_ENTRIES_PAE 512
#define L2_PAGETABLE_ENTRIES_PAE 512
#define L3_PAGETABLE_ENTRIES_PAE 4
+
+#if defined(__i386__)
+#define L1_PAGETABLE_ENTRIES 1024
+#define L2_PAGETABLE_ENTRIES 1024
#elif defined(__x86_64__)
#define L1_PAGETABLE_ENTRIES 512
#define L2_PAGETABLE_ENTRIES 512
@@ -70,17 +72,18 @@
typedef unsigned long l4_pgentry_t;
#endif
-#if defined(__i386__)
-#define l1_table_offset(_a) \
- (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1))
-#define l2_table_offset(_a) \
- ((_a) >> L2_PAGETABLE_SHIFT)
#define l1_table_offset_pae(_a) \
(((_a) >> L1_PAGETABLE_SHIFT_PAE) & (L1_PAGETABLE_ENTRIES_PAE - 1))
#define l2_table_offset_pae(_a) \
(((_a) >> L2_PAGETABLE_SHIFT_PAE) & (L2_PAGETABLE_ENTRIES_PAE - 1))
#define l3_table_offset_pae(_a) \
(((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
+
+#if defined(__i386__)
+#define l1_table_offset(_a) \
+ (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
+#define l2_table_offset(_a) \
+ ((_a) >> L2_PAGETABLE_SHIFT)
#elif defined(__x86_64__)
#define l1_table_offset(_a) \
(((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Sep 26 17:07:49 2005
@@ -17,7 +17,6 @@
#include <arpa/inet.h>
#include "xc_private.h"
-#include "linux_boot_params.h"
/* Needed for Python versions earlier than 2.3. */
#ifndef PyMODINIT_FUNC
@@ -310,80 +309,24 @@
XcObject *xc = (XcObject *)self;
u32 dom;
- char *image, *ramdisk = NULL, *cmdline = "";
- PyObject *memmap;
+ char *image;
int control_evtchn, store_evtchn;
int flags = 0, vcpus = 1;
- int numItems, i;
int memsize;
- struct mem_map mem_map;
unsigned long store_mfn = 0;
static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
- "memsize", "image", "memmap",
- "ramdisk", "cmdline", "flags",
- "vcpus", NULL };
-
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisO!|ssii", kwd_list,
+ "memsize", "image", "flags", "vcpus", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list,
&dom, &control_evtchn, &store_evtchn,
- &memsize,
- &image, &PyList_Type, &memmap,
- &ramdisk, &cmdline, &flags, &vcpus) )
- return NULL;
-
- memset(&mem_map, 0, sizeof(mem_map));
- /* Parse memmap */
-
- /* get the number of lines passed to us */
- numItems = PyList_Size(memmap) - 1; /* removing the line
- containing "memmap" */
- mem_map.nr_map = numItems;
-
- /* should raise an error here. */
- if (numItems < 0) return NULL; /* Not a list */
-
- /* iterate over items of the list, grabbing ranges and parsing them */
- for (i = 1; i <= numItems; i++) { // skip over "memmap"
- PyObject *item, *f1, *f2, *f3, *f4;
- int numFields;
- unsigned long lf1, lf2, lf3, lf4;
- char *sf1, *sf2;
-
- /* grab the string object from the next element of the list */
- item = PyList_GetItem(memmap, i); /* Can't fail */
-
- /* get the number of lines passed to us */
- numFields = PyList_Size(item);
-
- if (numFields != 4)
- return NULL;
-
- f1 = PyList_GetItem(item, 0);
- f2 = PyList_GetItem(item, 1);
- f3 = PyList_GetItem(item, 2);
- f4 = PyList_GetItem(item, 3);
-
- /* Convert objects to strings/longs */
- sf1 = PyString_AsString(f1);
- sf2 = PyString_AsString(f2);
- lf3 = PyLong_AsLong(f3);
- lf4 = PyLong_AsLong(f4);
- if ( sscanf(sf1, "%lx", &lf1) != 1 )
- return NULL;
- if ( sscanf(sf2, "%lx", &lf2) != 1 )
- return NULL;
-
- mem_map.map[i-1].addr = lf1;
- mem_map.map[i-1].size = lf2 - lf1;
- mem_map.map[i-1].type = lf3;
- mem_map.map[i-1].caching_attr = lf4;
- }
-
- if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, &mem_map,
- ramdisk, cmdline, control_evtchn, flags,
- vcpus, store_evtchn, &store_mfn) != 0 )
- return PyErr_SetFromErrno(xc_error);
-
+ &memsize, &image, &flags, &vcpus) )
+ return NULL;
+
+ if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn,
+ flags, vcpus, store_evtchn, &store_mfn) != 0 )
+ return PyErr_SetFromErrno(xc_error);
+
return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
}
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/lowlevel/xs/xs.c Mon Sep 26 17:07:49 2005
@@ -582,9 +582,8 @@
}
#define xspy_transaction_start_doc "\n" \
- "Start a transaction on a path.\n" \
+ "Start a transaction.\n" \
"Only one transaction can be active at a time.\n" \
- " path [string]: xenstore path.\n" \
"\n" \
"Returns None on success.\n" \
"Raises RuntimeError on error.\n" \
@@ -593,8 +592,8 @@
static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
PyObject *kwds)
{
- static char *kwd_spec[] = { "path", NULL };
- static char *arg_spec = "s|";
+ static char *kwd_spec[] = { NULL };
+ static char *arg_spec = "";
char *path = NULL;
struct xs_handle *xh = xshandle(self);
@@ -606,7 +605,7 @@
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
goto exit;
Py_BEGIN_ALLOW_THREADS
- xsval = xs_transaction_start(xh, path);
+ xsval = xs_transaction_start(xh);
Py_END_ALLOW_THREADS
if (!xsval) {
PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -623,7 +622,7 @@
"Attempts to commit the transaction unless abort is true.\n" \
" abort [int]: abort flag (default 0).\n" \
"\n" \
- "Returns None on success.\n" \
+ "Returns True on success, False if you need to try again.\n" \
"Raises RuntimeError on error.\n" \
"\n"
@@ -646,11 +645,16 @@
xsval = xs_transaction_end(xh, abort);
Py_END_ALLOW_THREADS
if (!xsval) {
- PyErr_SetFromErrno(PyExc_RuntimeError);
- goto exit;
- }
- Py_INCREF(Py_None);
- val = Py_None;
+ if (errno == EAGAIN) {
+ Py_INCREF(Py_False);
+ val = Py_False;
+ goto exit;
+ }
+ PyErr_SetFromErrno(PyExc_RuntimeError);
+ goto exit;
+ }
+ Py_INCREF(Py_True);
+ val = Py_True;
exit:
return val;
}
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/PrettyPrint.py
--- a/tools/python/xen/xend/PrettyPrint.py Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/PrettyPrint.py Mon Sep 26 17:07:49 2005
@@ -252,7 +252,7 @@
self.block = self.block.parent
def prettyprint(self, out=sys.stdout):
- self.top.prettyprint(Line(out, self.width))
+ self.top.prettyprint(Line(out, self.width), self.width)
class SXPPrettyPrinter(PrettyPrinter):
"""An SXP prettyprinter.
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/XendDomain.py Mon Sep 26 17:07:49 2005
@@ -433,12 +433,11 @@
self.domain_shutdowns()
return val
+
def domain_sysrq(self, id, key):
- """Send a SysRq to a domain
- """
- dominfo = self.domain_lookup(id)
- val = dominfo.send_sysrq(key)
- return val
+ """Send a SysRq to the specified domain."""
+ return self.callInfo(id, XendDomainInfo.send_sysrq, key)
+
def domain_shutdowns(self):
"""Process pending domain shutdowns.
@@ -630,73 +629,45 @@
except Exception, ex:
raise XendError(str(ex))
- def domain_device_create(self, id, devconfig):
- """Create a new device for a domain.
-
- @param id: domain id
- @param devconfig: device configuration
- """
- dominfo = self.domain_lookup(id)
- val = dominfo.device_create(devconfig)
- dominfo.exportToDB()
- return val
-
- def domain_device_configure(self, id, devconfig, devid):
- """Configure an existing device for a domain.
-
- @param id: domain id
- @param devconfig: device configuration
- @param devid: device id
+
+ def domain_device_create(self, domid, devconfig):
+ """Create a new device for the specified domain.
+ """
+ return self.callInfo(domid, XendDomainInfo.device_create, devconfig)
+
+
+ def domain_device_configure(self, domid, devconfig, devid):
+ """Configure an existing device in the specified domain.
@return: updated device configuration
"""
- dominfo = self.domain_lookup(id)
- val = dominfo.device_configure(devconfig, devid)
- dominfo.exportToDB()
- return val
+ return self.callInfo(domid, XendDomainInfo.device_configure,
+ devconfig, devid)
+
- def domain_device_refresh(self, id, type, devid):
- """Refresh a device.
-
- @param id: domain id
- @param devid: device id
- @param type: device type
- """
- dominfo = self.domain_lookup(id)
- val = dominfo.device_refresh(type, devid)
- dominfo.exportToDB()
- return val
-
- def domain_device_destroy(self, id, type, devid):
- """Destroy a device.
-
- @param id: domain id
- @param devid: device id
- @param type: device type
- """
- dominfo = self.domain_lookup(id)
- return dominfo.destroyDevice(type, devid)
-
-
- def domain_devtype_ls(self, id, type):
- """Get list of device sxprs for a domain.
-
- @param id: domain
- @param type: device type
- @return: device sxprs
- """
- dominfo = self.domain_lookup(id)
- return dominfo.getDeviceSxprs(type)
-
- def domain_devtype_get(self, id, type, devid):
+ def domain_device_refresh(self, domid, devtype, devid):
+ """Refresh a device."""
+ return self.callInfo(domid, XendDomainInfo.device_refresh, devtype,
+ devid)
+
+
+ def domain_device_destroy(self, domid, devtype, devid):
+ """Destroy a device."""
+ return self.callInfo(domid, XendDomainInfo.destroyDevice, devtype,
+ devid)
+
+
+ def domain_devtype_ls(self, domid, devtype):
+ """Get list of device sxprs for the specified domain."""
+ return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
+
+
+ def domain_devtype_get(self, domid, devtype, devid):
"""Get a device from a domain.
- @param id: domain
- @param type: device type
- @param devid: device id
@return: device object (or None)
"""
- dominfo = self.domain_lookup(id)
- return dominfo.getDevice(type, devid)
+ return self.callInfo(domid, XendDomainInfo.getDevice, devtype, devid)
+
def domain_vif_limit_set(self, id, vif, credit, period):
"""Limit the vif's transmission rate
@@ -723,7 +694,7 @@
"""Set the memory limit for a domain.
@param id: domain
- @param mem: memory limit (in MB)
+ @param mem: memory limit (in MiB)
@return: 0 on success, -1 on error
"""
dominfo = self.domain_lookup(id)
@@ -734,42 +705,37 @@
except Exception, ex:
raise XendError(str(ex))
- def domain_mem_target_set(self, id, mem):
+ def domain_mem_target_set(self, domid, mem):
"""Set the memory target for a domain.
- @param id: domain
- @param mem: memory target (in MB)
- @return: 0 on success, -1 on error
- """
- dominfo = self.domain_lookup(id)
- return dominfo.setMemoryTarget(mem << 10)
-
- def domain_vcpu_hotplug(self, id, vcpu, state):
- """Enable or disable VCPU vcpu in DOM id
-
- @param id: domain
+ @param mem: memory target (in MiB)
+ """
+ self.callInfo(domid, XendDomainInfo.setMemoryTarget, mem << 10)
+
+
+ def domain_vcpu_hotplug(self, domid, vcpu, state):
+ """Enable or disable specified VCPU in specified domain
+
@param vcpu: target VCPU in domain
@param state: which state VCPU will become
- @return: 0 on success, -1 on error
- """
-
- dominfo = self.domain_lookup(id)
- return dominfo.vcpu_hotplug(vcpu, state)
-
- def domain_dumpcore(self, id):
- """Save a core dump for a crashed domain.
-
- @param id: domain
- """
- dominfo = self.domain_lookup(id)
- corefile = "/var/xen/dump/%s.%s.core" % (dominfo.getName(),
- dominfo.getDomid())
- try:
- xc.domain_dumpcore(dom=dominfo.getDomid(), corefile=corefile)
- except Exception, ex:
- log.warning("Dumpcore failed, id=%s name=%s: %s",
- dominfo.getDomid(), dominfo.getName(), ex)
-
+ """
+ self.callInfo(domid, XendDomainInfo.vcpu_hotplug, vcpu, state)
+
+
+ def domain_dumpcore(self, domid):
+ """Save a core dump for a crashed domain."""
+ self.callInfo(domid, XendDomainInfo.dumpCore)
+
+
+ ## private:
+
+ def callInfo(self, domid, fn, *args, **kwargs):
+ self.refresh()
+ dominfo = self.domains.get(domid)
+ if dominfo:
+ return fn(dominfo, *args, **kwargs)
+
+
def instance():
"""Singleton constructor. Use this instead of the class constructor.
"""
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon Sep 26 17:07:49 2005
@@ -34,6 +34,7 @@
from xen.xend.server.channel import EventChannel
+from xen.xend import image
from xen.xend import sxp
from xen.xend.XendBootloader import bootloader
from xen.xend.XendLogging import log
@@ -319,6 +320,7 @@
try:
defaultInfo('name', lambda: "Domain-%d" % self.domid)
+ defaultInfo('ssidref', lambda: 0)
defaultInfo('restart_mode', lambda: RESTART_ONREBOOT)
defaultInfo('cpu_weight', lambda: 1.0)
defaultInfo('bootloader', lambda: None)
@@ -511,6 +513,19 @@
self.info['backend'], 0)
+ def dumpCore(self):
+ """Create a core dump for this domain. Nothrow guarantee."""
+
+ try:
+ corefile = "/var/xen/dump/%s.%s.core" % (self.info['name'],
+ self.domid)
+ xc.domain_dumpcore(dom = self.domid, corefile = corefile)
+
+ except Exception, exn:
+ log.error("XendDomainInfo.dumpCore failed: id = %s name = %s: %s",
+ self.domid, self.info['name'], str(exn))
+
+
def closeStoreChannel(self):
"""Close the store channel, if any. Nothrow guarantee."""
@@ -614,7 +629,7 @@
sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024])
if self.infoIsSet('device'):
- for (n, c) in self.info['device']:
+ for (_, c) in self.info['device']:
sxpr.append(['device', c])
def stateChar(name):
@@ -706,13 +721,6 @@
"""
# todo - add support for scheduling params?
try:
- if 'image' not in self.info:
- raise VmError('Missing image in configuration')
-
- self.image = ImageHandler.create(self,
- self.info['image'],
- self.info['device'])
-
self.initDomain()
# Create domain devices.
@@ -737,6 +745,14 @@
self.domid = xc.domain_create(dom = self.domid or 0,
ssidref = self.info['ssidref'])
+
+ if 'image' not in self.info:
+ raise VmError('Missing image in configuration')
+
+ self.image = image.create(self,
+ self.info['image'],
+ self.info['device'])
+
if self.domid <= 0:
raise VmError('Creating domain failed: name=%s' %
self.info['name'])
@@ -839,20 +855,20 @@
"""Release all vm devices.
"""
- t = xstransact("%s/device" % self.path)
-
- for n in controllerClasses.keys():
- for d in t.list(n):
- try:
- t.remove(d)
- except ex:
- # Log and swallow any exceptions in removal -- there's
- # nothing more we can do.
- log.exception(
- "Device release failed: %s; %s; %s; %s" %
- (self.info['name'], n, d, str(ex)))
- t.commit()
-
+ while True:
+ t = xstransact("%s/device" % self.path)
+ for n in controllerClasses.keys():
+ for d in t.list(n):
+ try:
+ t.remove(d)
+ except ex:
+ # Log and swallow any exceptions in removal --
+ # there's nothing more we can do.
+ log.exception(
+ "Device release failed: %s; %s; %s; %s" %
+ (self.info['name'], n, d, str(ex)))
+ if t.commit():
+ break
def eventChannel(self, path=None):
"""Create an event channel to the domain.
@@ -1085,19 +1101,6 @@
#============================================================================
-# Register image handlers.
-
-from image import \
- addImageHandlerClass, \
- ImageHandler, \
- LinuxImageHandler, \
- VmxImageHandler
-
-addImageHandlerClass(LinuxImageHandler)
-addImageHandlerClass(VmxImageHandler)
-
-
-#============================================================================
# Register device controllers and their device config types.
"""A map from device-class names to the subclass of DevController that
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/image.py Mon Sep 26 17:07:49 2005
@@ -33,6 +33,15 @@
MAX_GUEST_CMDLINE = 1024
+
+def create(vm, imageConfig, deviceConfig):
+ """Create an image handler for a vm.
+
+ @return ImageHandler instance
+ """
+ return findImageHandlerClass(imageConfig)(vm, imageConfig, deviceConfig)
+
+
class ImageHandler:
"""Abstract base class for image handlers.
@@ -48,81 +57,39 @@
The method destroy() is called when the domain is destroyed.
The default is to do nothing.
-
"""
- #======================================================================
- # Class vars and methods.
-
- """Table of image handler classes for virtual machine images.
- Indexed by image type.
- """
- imageHandlerClasses = {}
-
- def addImageHandlerClass(cls, h):
- """Add a handler class for an image type
- @param h: handler: ImageHandler subclass
- """
- cls.imageHandlerClasses[h.ostype] = h
-
- addImageHandlerClass = classmethod(addImageHandlerClass)
-
- def findImageHandlerClass(cls, image):
- """Find the image handler class for an image config.
-
- @param image config
- @return ImageHandler subclass or None
- """
- ty = sxp.name(image)
- if ty is None:
- raise VmError('missing image type')
- imageClass = cls.imageHandlerClasses.get(ty)
- if imageClass is None:
- raise VmError('unknown image type: ' + ty)
- return imageClass
-
- findImageHandlerClass = classmethod(findImageHandlerClass)
-
- def create(cls, vm, imageConfig, deviceConfig):
- """Create an image handler for a vm.
-
- @return ImageHandler instance
- """
- imageClass = cls.findImageHandlerClass(imageConfig)
- return imageClass(vm, imageConfig, deviceConfig)
-
- create = classmethod(create)
-
- #======================================================================
- # Instance vars and methods.
-
ostype = None
- kernel = None
- ramdisk = None
- cmdline = None
-
- flags = 0
def __init__(self, vm, imageConfig, deviceConfig):
self.vm = vm
+
+ self.kernel = None
+ self.ramdisk = None
+ self.cmdline = None
+ self.flags = 0
+
self.configure(imageConfig, deviceConfig)
def configure(self, imageConfig, _):
"""Config actions common to all unix-like domains."""
- self.kernel = sxp.child_value(imageConfig, "kernel")
+ def get_cfg(name, default = None):
+ return sxp.child_value(imageConfig, name, default)
+
+ self.kernel = get_cfg("kernel")
self.cmdline = ""
- ip = sxp.child_value(imageConfig, "ip", None)
+ ip = get_cfg("ip")
if ip:
self.cmdline += " ip=" + ip
- root = sxp.child_value(imageConfig, "root")
+ root = get_cfg("root")
if root:
self.cmdline += " root=" + root
- args = sxp.child_value(imageConfig, "args")
+ args = get_cfg("args")
if args:
self.cmdline += " " + args
- self.ramdisk = sxp.child_value(imageConfig, "ramdisk", '')
+ self.ramdisk = get_cfg("ramdisk", '')
self.vm.storeVm(("image/ostype", self.ostype),
("image/kernel", self.kernel),
@@ -130,7 +97,7 @@
("image/ramdisk", self.ramdisk))
- def handleBootloading():
+ def handleBootloading(self):
self.unlink(self.kernel)
self.unlink(self.ramdisk)
@@ -194,7 +161,6 @@
if d.has_key('console_mfn'):
self.vm.setConsoleRef(d.get('console_mfn'))
-addImageHandlerClass = ImageHandler.addImageHandlerClass
class LinuxImageHandler(ImageHandler):
@@ -238,22 +204,19 @@
def configure(self, imageConfig, deviceConfig):
ImageHandler.configure(self, imageConfig, deviceConfig)
-
- self.memmap = sxp.child_value(imageConfig, 'memmap')
+
self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
self.device_model = sxp.child_value(imageConfig, 'device_model')
if not self.device_model:
raise VmError("vmx: missing device model")
self.display = sxp.child_value(imageConfig, 'display')
- self.vm.storeVm(("image/memmap", self.memmap),
- ("image/dmargs", " ".join(self.dmargs)),
+ self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
("image/device-model", self.device_model),
("image/display", self.display))
self.device_channel = None
self.pid = 0
- self.memmap_value = []
self.dmargs += self.configVNC(imageConfig)
@@ -261,7 +224,6 @@
def createImage(self):
"""Create a VM for the VMX environment.
"""
- self.parseMemmap()
self.createDomain()
def buildDomain(self):
@@ -278,9 +240,6 @@
log.debug("control_evtchn = %d", self.device_channel.port2)
log.debug("store_evtchn = %d", store_evtchn)
log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024)
- log.debug("memmap = %s", self.memmap_value)
- log.debug("cmdline = %s", self.cmdline)
- log.debug("ramdisk = %s", self.ramdisk)
log.debug("flags = %d", self.flags)
log.debug("vcpus = %d", self.vm.getVCpuCount())
@@ -289,9 +248,6 @@
control_evtchn = self.device_channel.port2,
store_evtchn = store_evtchn,
memsize = self.vm.getMemoryTarget() / 1024,
- memmap = self.memmap_value,
- cmdline = self.cmdline,
- ramdisk = self.ramdisk,
flags = self.flags,
vcpus = self.vm.getVCpuCount())
if isinstance(ret, dict):
@@ -299,18 +255,11 @@
return 0
return ret
- def parseMemmap(self):
- if self.memmap is None:
- return
- memmap = sxp.parse(open(self.memmap))[0]
- from xen.util.memmap import memmap_parse
- self.memmap_value = memmap_parse(memmap)
-
# Return a list of cmd line args to the device models based on the
# xm config file
def parseDeviceModelArgs(self, imageConfig, deviceConfig):
dmargs = [ 'cdrom', 'boot', 'fda', 'fdb',
- 'localtime', 'serial', 'stdvga', 'isa', 'vcpus' ]
+ 'localtime', 'serial', 'stdvga', 'isa', 'vcpus' ]
ret = []
for a in dmargs:
v = sxp.child_value(imageConfig, a)
@@ -439,3 +388,28 @@
return 16 * 1024
else:
return (1 + ((mem_mb + 3) >> 2)) * 4
+
+
+"""Table of image handler classes for virtual machine images. Indexed by
+image type.
+"""
+imageHandlerClasses = {}
+
+
+for h in LinuxImageHandler, VmxImageHandler:
+ imageHandlerClasses[h.ostype] = h
+
+
+def findImageHandlerClass(image):
+ """Find the image handler class for an image config.
+
+ @param image config
+ @return ImageHandler subclass or None
+ """
+ ty = sxp.name(image)
+ if ty is None:
+ raise VmError('missing image type')
+ imageClass = imageHandlerClasses.get(ty)
+ if imageClass is None:
+ raise VmError('unknown image type: ' + ty)
+ return imageClass
diff -r eaedc6b4ec0f -r ef9591d03fdd
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/server/DevController.py Mon Sep 26 17:07:49 2005
@@ -126,20 +126,21 @@
compulsory to use it; subclasses may prefer to allocate IDs based upon
the device configuration instead.
"""
- path = self.frontendMiscPath()
- t = xstransact(path)
- try:
- result = t.read("nextDeviceID")
- if result:
- result = int(result)
- else:
- result = 1
- t.write("nextDeviceID", str(result + 1))
- t.commit()
- return result
- except:
- t.abort()
- raise
+ while True:
+ path = self.frontendMiscPath()
+ t = xstransact(path)
+ try:
+ result = t.read("nextDeviceID")
+ if result:
+ result = int(result)
+ else:
+ result = 1
+ t.write("nextDeviceID", str(result + 1))
+ if t.commit():
+ return result
+ except:
+ t.abort()
+ raise
## private:
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xend/xenstore/xsnode.py
--- a/tools/python/xen/xend/xenstore/xsnode.py Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/xenstore/xsnode.py Mon Sep 26 17:07:49 2005
@@ -280,8 +280,8 @@
(', while writing %s : %s' % (str(path),
str(data))))
- def begin(self, path):
- self.getxs().transaction_start(path)
+ def begin(self):
+ self.getxs().transaction_start()
def commit(self, abandon=False):
self.getxs().transaction_end(abort=abandon)
diff -r eaedc6b4ec0f -r ef9591d03fdd
tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xend/xenstore/xstransact.py Mon Sep 26 17:07:49 2005
@@ -14,16 +14,8 @@
def __init__(self, path):
self.in_transaction = False
self.path = path.rstrip("/")
- while True:
- try:
- xshandle().transaction_start(path)
- self.in_transaction = True
- return
- except RuntimeError, ex:
- if ex.args[0] == errno.ENOENT and path != "/":
- path = "/".join(path.split("/")[0:-1]) or "/"
- else:
- raise
+ xshandle().transaction_start()
+ self.in_transaction = True
def __del__(self):
if self.in_transaction:
@@ -175,14 +167,8 @@
t = cls(path)
try:
v = t.read(*args)
- t.commit()
+ t.abort()
return v
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
except:
t.abort()
raise
@@ -194,14 +180,8 @@
t = cls(path)
try:
t.write(*args, **opts)
- t.commit()
- return
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return
except:
t.abort()
raise
@@ -217,14 +197,8 @@
t = cls(path)
try:
t.remove(*args)
- t.commit()
- return
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return
except:
t.abort()
raise
@@ -236,14 +210,8 @@
t = cls(path)
try:
v = t.list(*args)
- t.commit()
- return v
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return v
except:
t.abort()
raise
@@ -255,14 +223,8 @@
t = cls(path)
try:
v = t.gather(*args)
- t.commit()
- return v
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return v
except:
t.abort()
raise
@@ -274,14 +236,8 @@
t = cls(path)
try:
v = t.store(*args)
- t.commit()
- return v
- except RuntimeError, ex:
- t.abort()
- if ex.args[0] == errno.ETIMEDOUT:
- pass
- else:
- raise
+ if t.commit():
+ return v
except:
t.abort()
raise
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Fri Sep 23 21:41:28 2005
+++ b/tools/python/xen/xm/main.py Mon Sep 26 17:07:49 2005
@@ -1,5 +1,6 @@
# (C) Copyright IBM Corp. 2005
# Copyright (C) 2004 Mike Wray
+# Copyright (c) 2005 XenSource Ltd
#
# Authors:
# Sean Dague <sean at dague dot net>
@@ -169,12 +170,6 @@
#
#########################################################################
-def xm_create(args):
- from xen.xm import create
- # ugly hack because the opt parser apparently wants
- # the subcommand name just to throw it away!
- create.main(["bogus"] + args)
-
def xm_save(args):
arg_check(args,2,"save")
@@ -195,13 +190,6 @@
id = sxp.child_value(info, 'domid')
if id is not None:
server.xend_domain_unpause(domid)
-
-def xm_migrate(args):
- # TODO: arg_check
- from xen.xm import migrate
- # ugly hack because the opt parser apparently wants
- # the subcommand name just to throw it away!
- migrate.main(["bogus"] + args)
def xm_list(args):
use_long = 0
@@ -290,14 +278,6 @@
def xm_vcpu_list(args):
xm_list(["-v"] + args)
-def xm_destroy(args):
- arg_check(args,1,"destroy")
-
- from xen.xm import destroy
- # ugly hack because the opt parser apparently wants
- # the subcommand name just to throw it away!
- destroy.main(["bogus"] + args)
-
def xm_reboot(args):
arg_check(args,1,"reboot")
from xen.xm import shutdown
@@ -305,20 +285,6 @@
# the subcommand name just to throw it away!
shutdown.main(["bogus", "-R"] + args)
-def xm_shutdown(args):
- arg_check(args,1,"shutdown")
-
- from xen.xm import shutdown
- # ugly hack because the opt parser apparently wants
- # the subcommand name just to throw it away!
- shutdown.main(["bogus"] + args)
-
-def xm_sysrq(args):
- from xen.xm import sysrq
- # ugly hack because the opt parser apparently wants
- # the subcommand name just to throw it away!
- sysrq.main(["bogus"] + args)
-
def xm_pause(args):
arg_check(args, 1, "pause")
dom = args[0]
@@ -332,6 +298,11 @@
from xen.xend.XendClient import server
server.xend_domain_unpause(dom)
+
+def xm_subcommand(command, args):
+ cmd = __import__(command, globals(), locals(), 'xen.xm')
+ cmd.main(["bogus"] + args)
+
#############################################################
@@ -506,14 +477,6 @@
sxp.show(x)
print
-def xm_network_attach(args):
-
- print "Not implemented"
-
-def xm_network_detach(args):
-
- print "Not implemented"
-
def xm_block_list(args):
arg_check(args,1,"block-list")
dom = args[0]
@@ -609,11 +572,8 @@
# domain commands
"domid": xm_domid,
"domname": xm_domname,
- "create": xm_create,
- "destroy": xm_destroy,
"restore": xm_restore,
"save": xm_save,
- "shutdown": xm_shutdown,
"reboot": xm_reboot,
"list": xm_list,
# memory commands
@@ -625,10 +585,7 @@
"vcpu-enable": xm_vcpu_enable,
"vcpu-disable": xm_vcpu_disable,
"vcpu-list": xm_vcpu_list,
- # migration
- "migrate": xm_migrate,
# special
- "sysrq": xm_sysrq,
"pause": xm_pause,
"unpause": xm_unpause,
# host commands
@@ -647,13 +604,23 @@
# network
"network-limit": xm_network_limit,
"network-list": xm_network_list,
- "network-attach": xm_network_attach,
- "network-detach": xm_network_detach,
# vnet
"vnet-list": xm_vnet_list,
"vnet-create": xm_vnet_create,
"vnet-delete": xm_vnet_delete,
}
+
+## The commands supported by a separate argument parser in xend.xm.
+subcommands = [
+ 'create',
+ 'destroy',
+ 'migrate',
+ 'sysrq',
+ 'shutdown'
+ ]
+
+for c in subcommands:
+ commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c)
aliases = {
"balloon": "mem-set",
@@ -669,6 +636,7 @@
"--long": longhelp
}
+
def xm_lookup_cmd(cmd):
if commands.has_key(cmd):
return commands[cmd]
@@ -688,9 +656,7 @@
err('Option %s is the new replacement, see "xm help %s" for more info' %
(new, new))
def usage(cmd=None):
- if cmd == "full":
- print fullhelp
- elif help.has_key(cmd):
+ if help.has_key(cmd):
print help[cmd]
else:
print shorthelp
@@ -701,7 +667,7 @@
usage()
if re.compile('-*help').match(argv[1]):
- if len(argv) > 2 and help.has_key(argv[2]):
+ if len(argv) > 2:
usage(argv[2])
else:
usage()
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/Makefile
--- a/tools/xenstore/Makefile Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/Makefile Mon Sep 26 17:07:49 2005
@@ -28,11 +28,11 @@
CLIENTS += xenstore-write
CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))
-all: libxenstore.so xenstored $(CLIENTS)
+all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump
testcode: xs_test xenstored_test xs_random xs_dom0_test
-xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o
xenstored_transaction.o xs_lib.o talloc.o utils.o
+xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o
xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@
$(CLIENTS): libxenstore.so
@@ -42,13 +42,21 @@
$(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c
$(COMPILE.c) -DCLIENT_$(*F) -o $@ $<
-xenstored_test: xenstored_core_test.o xenstored_watch_test.o
xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o
fake_libxc.o utils.o
+xenstored_test: xenstored_core_test.o xenstored_watch_test.o
xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o
fake_libxc.o utils.o tdb.o
+ $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
+
+xs_tdb_dump: xs_tdb_dump.o utils.o tdb.o talloc.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
xs_test: xs_test.o xs_lib.o utils.o
xs_random: xs_random.o xs_test_lib.o xs_lib.o talloc.o utils.o
xs_stress: xs_stress.o xs_test_lib.o xs_lib.o talloc.o utils.o
xs_crashme: xs_crashme.o xs_lib.o talloc.o utils.o
+
+speedtest: speedtest.o xs.o xs_lib.o utils.o talloc.o
+
+check-speed: speedtest xenstored_test $(TESTDIR)
+ $(TESTENV) time ./speedtest 100
xs_test.o xs_stress.o xenstored_core_test.o xenstored_watch_test.o
xenstored_transaction_test.o xenstored_domain_test.o xs_random.o xs_test_lib.o
talloc_test.o fake_libxc.o xs_crashme.o: CFLAGS=$(BASECFLAGS) $(TESTFLAGS)
@@ -98,7 +106,7 @@
randomcheck: xs_random xenstored_test $(TESTDIR)
$(TESTENV) ./xs_random --simple --fast /tmp/xs_random 200000
$(RANDSEED) && echo
$(TESTENV) ./xs_random --fast /tmp/xs_random 100000 $(RANDSEED) && echo
- $(TESTENV) ./xs_random --fail /tmp/xs_random 10000 $(RANDSEED)
+# $(TESTENV) ./xs_random --fail /tmp/xs_random 10000 $(RANDSEED)
crashme: xs_crashme xenstored_test $(TESTDIR)
rm -rf $(TESTDIR)/store $(TESTDIR)/transactions /tmp/xs_crashme.vglog*
/tmp/trace
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/testsuite/04rm.test
--- a/tools/xenstore/testsuite/04rm.test Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/04rm.test Mon Sep 26 17:07:49 2005
@@ -6,6 +6,8 @@
# Create file and remove it
write /test contents
rm /test
+expect tool
+dir /
# Create directory and remove it.
mkdir /dir
@@ -15,3 +17,4 @@
mkdir /dir
write /dir/test contents
rm /dir
+
diff -r eaedc6b4ec0f -r ef9591d03fdd
tools/xenstore/testsuite/08transaction.slowtest
--- a/tools/xenstore/testsuite/08transaction.slowtest Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/08transaction.slowtest Mon Sep 26 17:07:49 2005
@@ -1,21 +1,43 @@
-# Test transaction timeouts. Take a second each.
+# Test transaction clashes.
mkdir /test
write /test/entry1 contents
-# Transactions can take as long as the want...
-start /test
-sleep 1100
-rm /test/entry1
+# Start transaction, do read-only op, transaction succeeds
+1 start
+1 write /test/entry1 contents2
+expect contents
+read /test/entry1
+1 commit
+expect contents2
+read /test/entry1
+
+# Start transaction, abort other transaction, transaction succeeds.
+1 start
+1 write /test/entry1 contents3
+start
+write /test/entry1 contents
+abort
+1 commit
+expect contents3
+read /test/entry1
+
+# Start transaction, do write op, transaction fails
+1 start
+1 write /test/entry1 contents4
+write /test/entry1 contents
+expect 1: commit failed: Resource temporarily unavailable
+1 commit
+expect contents
+read /test/entry1
+
+# Start transaction, do other transaction, transaction fails
+1 start
+1 write /test/entry1 contents4
+start
+write /test/entry1 contents5
commit
-dir /test
-
-# ... as long as noone is waiting.
-1 start /test
-notimeout
-2 mkdir /test/dir
-1 mkdir /test/dir
-expect 1:dir
-1 dir /test
-expect 1: commit failed: Connection timed out
+expect 1: commit failed: Resource temporarily unavailable
1 commit
+expect contents5
+read /test/entry1
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/testsuite/08transaction.test
--- a/tools/xenstore/testsuite/08transaction.test Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/08transaction.test Mon Sep 26 17:07:49 2005
@@ -3,7 +3,7 @@
mkdir /test
# Simple transaction: create a file inside transaction.
-1 start /test
+1 start
1 write /test/entry1 contents
2 dir /test
expect 1:entry1
@@ -15,7 +15,7 @@
rm /test/entry1
# Create a file and abort transaction.
-1 start /test
+1 start
1 write /test/entry1 contents
2 dir /test
expect 1:entry1
@@ -25,7 +25,7 @@
write /test/entry1 contents
# Delete in transaction, commit
-1 start /test
+1 start
1 rm /test/entry1
expect 2:entry1
2 dir /test
@@ -35,7 +35,7 @@
# Delete in transaction, abort.
write /test/entry1 contents
-1 start /test
+1 start
1 rm /test/entry1
expect 2:entry1
2 dir /test
@@ -47,7 +47,7 @@
# Events inside transactions don't trigger watches until (successful) commit.
mkdir /test/dir
1 watch /test token
-2 start /test
+2 start
2 mkdir /test/dir/sub
expect 1: waitwatch failed: Connection timed out
1 waitwatch
@@ -55,7 +55,7 @@
1 close
1 watch /test token
-2 start /test
+2 start
2 mkdir /test/dir/sub
2 abort
expect 1: waitwatch failed: Connection timed out
@@ -63,7 +63,7 @@
1 close
1 watch /test token
-2 start /test
+2 start
2 mkdir /test/dir/sub
2 commit
expect 1:/test/dir/sub:token
@@ -73,7 +73,7 @@
# Rm inside transaction works like rm outside: children get notified.
1 watch /test/dir/sub token
-2 start /test
+2 start
2 rm /test/dir
2 commit
expect 1:/test/dir/sub:token
@@ -83,7 +83,7 @@
# Multiple events from single transaction don't trigger assert
1 watch /test token
-2 start /test
+2 start
2 write /test/1 contents
2 write /test/2 contents
2 commit
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/testsuite/12readonly.test
--- a/tools/xenstore/testsuite/12readonly.test Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/12readonly.test Mon Sep 26 17:07:49 2005
@@ -13,23 +13,23 @@
getperm /test
watch /test token
unwatch /test token
-start /
+start
commit
-start /
+start
abort
# These don't work
-expect write failed: Read-only file system
+expect write failed: Permission denied
write /test2 contents
-expect write failed: Read-only file system
+expect write failed: Permission denied
write /test contents
-expect setperm failed: Read-only file system
+expect setperm failed: Permission denied
setperm /test 100 NONE
-expect setperm failed: Read-only file system
+expect setperm failed: Permission denied
setperm /test 100 NONE
-expect shutdown failed: Read-only file system
+expect shutdown failed: Permission denied
shutdown
-expect introduce failed: Read-only file system
+expect introduce failed: Permission denied
introduce 1 100 7 /home
# Check that watches work like normal.
diff -r eaedc6b4ec0f -r ef9591d03fdd
tools/xenstore/testsuite/14complexperms.test
--- a/tools/xenstore/testsuite/14complexperms.test Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/14complexperms.test Mon Sep 26 17:07:49 2005
@@ -33,14 +33,6 @@
expect *No such file or directory
unwatch /dir/file token
expect *Permission denied
-start /dir/file
-expect *No such file or directory
-abort
-expect *Permission denied
-start /dir/file
-expect *No such file or directory
-commit
-expect *Permission denied
introduce 2 100 7 /dir/file
# Now it exists
@@ -73,12 +65,4 @@
expect *No such file or directory
unwatch /dir/file token
expect *Permission denied
-start /dir/file
-expect *No such file or directory
-abort
-expect *Permission denied
-start /dir/file
-expect *No such file or directory
-commit
-expect *Permission denied
introduce 2 100 7 /dir/file
diff -r eaedc6b4ec0f -r ef9591d03fdd
tools/xenstore/testsuite/16block-watch-crash.test
--- a/tools/xenstore/testsuite/16block-watch-crash.test Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/testsuite/16block-watch-crash.test Mon Sep 26 17:07:49 2005
@@ -1,13 +1,14 @@
# Test case where blocked connection gets sent watch.
-mkdir /test
-watch /test token
-1 start /test
-# This will block on above
-noackwrite /test/entry contents
-1 write /test/entry2 contents
-1 commit
-readack
-expect /test/entry2:token
-waitwatch
-ackwatch token
+# FIXME: We no longer block connections
+# mkdir /test
+# watch /test token
+# 1 start
+# # This will block on above
+# noackwrite /test/entry contents
+# 1 write /test/entry2 contents
+# 1 commit
+# readack
+# expect /test/entry2:token
+# waitwatch
+# ackwatch token
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/xenstore_client.c Mon Sep 26 17:07:49 2005
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
#include <xs.h>
+#include <errno.h>
static void
usage(const char *progname)
@@ -82,8 +83,8 @@
}
#endif
- /* XXX maybe find longest common prefix */
- success = xs_transaction_start(xsh, "/");
+ again:
+ success = xs_transaction_start(xsh);
if (!success)
errx(1, "couldn't start transaction");
@@ -145,8 +146,10 @@
out:
success = xs_transaction_end(xsh, ret ? true : false);
- if (!success)
+ if (!success) {
+ if (ret == 0 && errno == EAGAIN)
+ goto again;
errx(1, "couldn't end transaction");
-
+ }
return ret;
}
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/xenstored.h
--- a/tools/xenstore/xenstored.h Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/xenstored.h Mon Sep 26 17:07:49 2005
@@ -75,7 +75,7 @@
XSD_ERROR(ENOSYS),
XSD_ERROR(EROFS),
XSD_ERROR(EBUSY),
- XSD_ERROR(ETIMEDOUT),
+ XSD_ERROR(EAGAIN),
XSD_ERROR(EISCONN),
};
struct xsd_sockmsg
diff -r eaedc6b4ec0f -r ef9591d03fdd tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c Fri Sep 23 21:41:28 2005
+++ b/tools/xenstore/xenstored_core.c Mon Sep 26 17:07:49 2005
@@ -50,10 +50,12 @@
#include "xenstored_transaction.h"
#include "xenstored_domain.h"
#include "xenctrl.h"
+#include "tdb.h"
static bool verbose;
LIST_HEAD(connections);
static int tracefd = -1;
+static TDB_CONTEXT *tdb_ctx;
#ifdef TESTING
static bool failtest = false;
@@ -124,6 +126,23 @@
"xenstored corruption: connection id %i: err %s: %s",
conn ? (int)conn->id : -1, strerror(saved_errno), str);
_exit(2);
+}
+
+TDB_CONTEXT *tdb_context(struct connection *conn)
+{
+ /* conn = NULL used in manual_node at setup. */
+ if (!conn || !conn->transaction)
+ return tdb_ctx;
+ return tdb_transaction_context(conn->transaction);
+}
+
+bool replace_tdb(const char *newname, TDB_CONTEXT *newtdb)
+{
+ if (rename(newname, xs_daemon_tdb()) != 0)
+ return false;
+ tdb_close(tdb_ctx);
+ tdb_ctx = talloc_steal(talloc_autofree_context(), newtdb);
+ return true;
}
static char *sockmsg_string(enum xsd_sockmsg_type type)
@@ -202,37 +221,6 @@
write(tracefd, string, strlen(string));
}
-void trace_watch_timeout(const struct connection *conn, const char *node,
const char *token)
-{
- char string[64];
- if (tracefd < 0)
- return;
- write(tracefd, "WATCH_TIMEOUT ", strlen("WATCH_TIMEOUT "));
- sprintf(string, " %p ", conn);
- write(tracefd, string, strlen(string));
- write(tracefd, " (", 2);
- write(tracefd, node, strlen(node));
- write(tracefd, " ", 1);
- write(tracefd, token, strlen(token));
- write(tracefd, ")\n", 2);
-}
-
-static void trace_blocked(const struct connection *conn,
- const struct buffered_data *data)
-{
- char string[64];
-
- if (tracefd < 0)
- return;
-
- write(tracefd, "BLOCKED", strlen("BLOCKED"));
- sprintf(string, " %p (", conn);
- write(tracefd, string, strlen(string));
- write(tracefd, sockmsg_string(data->hdr.msg.type),
- strlen(sockmsg_string(data->hdr.msg.type)));
- write(tracefd, ")\n", 2);
-}
-
void trace(const char *fmt, ...)
{
va_list arglist;
@@ -253,7 +241,6 @@
int ret;
struct buffered_data *out = conn->out;
- assert(conn->state != BLOCKED);
if (out->inhdr) {
if (verbose)
xprintf("Writing msg %s (%s) out to %p\n",
@@ -351,24 +338,6 @@
return max;
}
-/* Read everything from a talloc_open'ed fd. */
-void *read_all(int *fd, unsigned int *size)
-{
- unsigned int max = 4;
- int ret;
- void *buffer = talloc_size(fd, max);
-
- *size = 0;
- while ((ret = read(*fd, buffer + *size, max - *size)) > 0) {
- *size += ret;
- if (*size == max)
- buffer = talloc_realloc_size(fd, buffer, max *= 2);
- }
- if (ret < 0)
- return NULL;
- return buffer;
-}
-
static int destroy_fd(void *_fd)
{
int *fd = _fd;
@@ -409,42 +378,167 @@
return child[len] == '/' || child[len] == '\0';
}
-/* Answer never ends in /. */
-char *node_dir_outside_transaction(const char *node)
-{
- if (streq(node, "/"))
- return talloc_strdup(node, xs_daemon_store());
- return talloc_asprintf(node, "%s%s", xs_daemon_store(), node);
-}
-
-static char *node_dir(struct transaction *trans, const char *node)
-{
- if (!trans || !within_transaction(trans, node))
- return node_dir_outside_transaction(node);
- return node_dir_inside_transaction(trans, node);
-}
-
-static char *datafile(const char *dir)
-{
- return talloc_asprintf(dir, "%s/.data", dir);
-}
-
-static char *node_datafile(struct transaction *trans, const char *node)
-{
- return datafile(node_dir(trans, node));
-}
-
-static char *permfile(const char *dir)
-{
- return talloc_asprintf(dir, "%s/.perms", dir);
-}
-
-static char *node_permfile(struct transaction *trans, const char *node)
-{
- return permfile(node_dir(trans, node));
-}
-
-struct buffered_data *new_buffer(void *ctx)
+/* If it fails, returns NULL and sets errno. */
+static struct node *read_node(struct connection *conn, const char *name)
+{
+ TDB_DATA key, data;
+ u32 *p;
+ struct node *node;
+
+ key.dptr = (void *)name;
+ key.dsize = strlen(name);
+ data = tdb_fetch(tdb_context(conn), key);
+
+ if (data.dptr == NULL) {
+ if (tdb_error(tdb_context(conn)) == TDB_ERR_NOEXIST)
+ errno = ENOENT;
+ else
+ errno = EIO;
+ return NULL;
+ }
+
+ node = talloc(name, struct node);
+ node->name = talloc_strdup(node, name);
+ node->parent = NULL;
+ node->tdb = tdb_context(conn);
+ talloc_steal(node, data.dptr);
+
+ /* Datalen, childlen, number of permissions */
+ p = (u32 *)data.dptr;
+ node->num_perms = p[0];
+ node->datalen = p[1];
+ node->childlen = p[2];
+
+ /* Permissions are struct xs_permissions. */
+ node->perms = (void *)&p[3];
+ /* Data is binary blob (usually ascii, no nul). */
+ node->data = node->perms + node->num_perms;
+ /* Children is strings, nul separated. */
+ node->children = node->data + node->datalen;
+
+ return node;
+}
+
+static bool write_node(struct connection *conn, const struct node *node)
+{
+ TDB_DATA key, data;
+ void *p;
+ |