# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID ebed727182630279e605f32f35a5364924cbd433
# Parent 11b718eb22c996868bed5b18dcc08081ad27d0be
# Parent d19deb173503962cc42c235cdeda84d3b4a6a52c
merge with xen-unstable.hg
---
tools/firmware/acpi/Makefile
| 68
tools/firmware/acpi/README
| 22
tools/firmware/acpi/acpi2_0.h
| 331
tools/firmware/acpi/acpi_build.c
| 232
tools/firmware/acpi/acpi_dsdt.asl
| 521
tools/firmware/acpi/acpi_dsdt.c
| 300
tools/firmware/acpi/acpi_facs.c
| 72
tools/firmware/acpi/acpi_facs.h
| 32
tools/firmware/acpi/acpi_fadt.c
| 193
tools/firmware/acpi/acpi_fadt.h
| 166
tools/firmware/acpi/acpi_gen.c
| 53
tools/firmware/acpi/acpi_madt.c
| 68
tools/firmware/acpi/acpi_madt.h
| 44
tools/firmware/acpi/acpi_rsdt.c
| 68
tools/pygrub/src/fsys/__init__.py
| 64
tools/pygrub/src/fsys/ext2/__init__.py
| 38
tools/pygrub/src/fsys/ext2/ext2module.c
| 387
tools/pygrub/src/fsys/ext2/test.py
| 15
tools/pygrub/src/fsys/reiser/__init__.py
| 40
tools/pygrub/src/fsys/reiser/reisermodule.c
| 345
.hgignore
| 3
buildconfigs/linux-defconfig_xen0_ia64
| 2
buildconfigs/linux-defconfig_xen_ia64
| 2
config/SunOS.mk
| 2
docs/src/user.tex
| 26
docs/xen-api/Makefile
| 23
docs/xen-api/coversheet.tex
| 50
docs/xen-api/fdl.tex
| 488
docs/xen-api/presentation.tex
| 149
docs/xen-api/todo.tex
| 140
docs/xen-api/vm-lifecycle.tex
| 24
docs/xen-api/vm_lifecycle.dot
| 15
docs/xen-api/wire-protocol.tex
| 287
docs/xen-api/xen.eps
| 49
docs/xen-api/xenapi-coversheet.tex
| 40
docs/xen-api/xenapi-datamodel-graph.dot
| 17
docs/xen-api/xenapi-datamodel.tex
| 9648 ++++++++++
docs/xen-api/xenapi.tex
| 56
linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c
| 2
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
| 4
linux-2.6-xen-sparse/arch/i386/mm/init-xen.c
| 4
linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c
| 5
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
| 4
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
| 1
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
| 42
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
| 5
linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
| 3
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
| 21
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
| 30
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
| 2
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
| 75
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
| 215
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
| 6
linux-2.6-xen-sparse/drivers/xen/core/Makefile
| 2
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
| 185
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
| 212
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
| 3
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
| 9
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
| 14
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
| 48
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
| 18
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
| 7
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h
| 1
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
| 10
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
| 8
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
| 15
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
| 3
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
| 16
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h
| 1
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
| 10
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
| 17
linux-2.6-xen-sparse/include/xen/gnttab.h
| 5
patches/linux-2.6.16.29/series
| 1
patches/linux-2.6.16.29/xenoprof-generic.patch
| 53
tools/Makefile
| 1
tools/blktap/drivers/blktapctrl.c
| 4
tools/blktap/drivers/tapdisk.c
| 5
tools/blktap/drivers/tapdisk.h
| 1
tools/blktap/lib/blktaplib.h
| 7
tools/console/Makefile
| 2
tools/examples/blktap
| 18
tools/examples/block
| 30
tools/examples/external-device-migrate
| 56
tools/examples/vif-bridge
| 2
tools/examples/vif-nat
| 4
tools/examples/vif-route
| 2
tools/examples/xend-config.sxp
| 2
tools/examples/xmexample.hvm
| 3
tools/firmware/Makefile
| 1
tools/firmware/hvmloader/Makefile
| 11
tools/firmware/hvmloader/acpi/Makefile
| 63
tools/firmware/hvmloader/acpi/README
| 24
tools/firmware/hvmloader/acpi/acpi2_0.h
| 324
tools/firmware/hvmloader/acpi/build.c
| 241
tools/firmware/hvmloader/acpi/dsdt.asl
| 521
tools/firmware/hvmloader/acpi/dsdt.c
| 300
tools/firmware/hvmloader/acpi/gen.c
| 53
tools/firmware/hvmloader/acpi/static_tables.c
| 184
tools/firmware/hvmloader/acpi_madt.c
| 176
tools/firmware/hvmloader/acpi_ssdt_tpm.asl
| 29
tools/firmware/hvmloader/acpi_ssdt_tpm.h
| 25
tools/firmware/hvmloader/acpi_utils.c
| 207
tools/firmware/hvmloader/acpi_utils.h
| 36
tools/firmware/hvmloader/hvmloader.c
| 16
tools/firmware/hvmloader/util.c
| 5
tools/firmware/vmxassist/setup.c
| 3
tools/firmware/vmxassist/vm86.c
| 87
tools/ioemu/Makefile.target
| 1
tools/ioemu/hw/ne2000.c
| 35
tools/ioemu/hw/pc.c
| 3
tools/ioemu/hw/serial.c
| 44
tools/ioemu/hw/tpm_tis.c
| 1114 +
tools/ioemu/keymaps/ja
| 3
tools/ioemu/target-i386-dm/cpu.h
| 2
tools/ioemu/target-i386-dm/exec-dm.c
| 50
tools/ioemu/target-i386-dm/helper2.c
| 131
tools/ioemu/target-i386-dm/i8259-dm.c
| 42
tools/ioemu/target-i386-dm/qemu-dm.debug
| 7
tools/ioemu/vl.c
| 25
tools/ioemu/vl.h
| 23
tools/ioemu/vnc_keysym.h
| 10
tools/ioemu/xenstore.c
| 137
tools/libfsimage/Makefile
| 13
tools/libfsimage/Rules.mk
| 32
tools/libfsimage/check-libext2fs
| 21
tools/libfsimage/common/Makefile
| 46
tools/libfsimage/common/fsimage.c
| 142
tools/libfsimage/common/fsimage.h
| 52
tools/libfsimage/common/fsimage_grub.c
| 276
tools/libfsimage/common/fsimage_grub.h
| 92
tools/libfsimage/common/fsimage_plugin.c
| 214
tools/libfsimage/common/fsimage_plugin.h
| 65
tools/libfsimage/common/fsimage_priv.h
| 62
tools/libfsimage/common/mapfile-GNU
| 37
tools/libfsimage/common/mapfile-SunOS
| 35
tools/libfsimage/ext2fs-lib/Makefile
| 15
tools/libfsimage/ext2fs-lib/ext2fs-lib.c
| 172
tools/libfsimage/ext2fs/Makefile
| 13
tools/libfsimage/ext2fs/fsys_ext2fs.c
| 804
tools/libfsimage/reiserfs/Makefile
| 13
tools/libfsimage/reiserfs/fsys_reiserfs.c
| 1254 +
tools/libfsimage/ufs/Makefile
| 13
tools/libfsimage/ufs/fsys_ufs.c
| 276
tools/libfsimage/ufs/ufs.h
| 228
tools/libxc/ia64/xc_ia64_hvm_build.c
| 2
tools/libxc/xc_core.c
| 2
tools/libxc/xc_domain.c
| 28
tools/libxc/xc_hvm_build.c
| 297
tools/libxc/xc_linux_build.c
| 195
tools/libxc/xc_linux_save.c
| 24
tools/libxc/xc_misc.c
| 28
tools/libxc/xc_private.c
| 22
tools/libxc/xc_private.h
| 5
tools/libxc/xc_ptrace.c
| 29
tools/libxc/xc_ptrace_core.c
| 24
tools/libxc/xenctrl.h
| 31
tools/libxc/xenguest.h
| 34
tools/libxc/xg_private.c
| 66
tools/libxc/xg_private.h
| 2
tools/libxen/COPYING
| 510
tools/libxen/Makefile
| 37
tools/libxen/README
| 54
tools/libxen/include/xen_boot_type.h
| 87
tools/libxen/include/xen_boot_type_internal.h
| 37
tools/libxen/include/xen_common.h
| 145
tools/libxen/include/xen_cpu_feature.h
| 387
tools/libxen/include/xen_cpu_feature_internal.h
| 37
tools/libxen/include/xen_driver_type.h
| 77
tools/libxen/include/xen_driver_type_internal.h
| 37
tools/libxen/include/xen_host.h
| 292
tools/libxen/include/xen_host_cpu.h
| 239
tools/libxen/include/xen_host_cpu_decl.h
| 30
tools/libxen/include/xen_host_decl.h
| 30
tools/libxen/include/xen_int_float_map.h
| 53
tools/libxen/include/xen_internal.h
| 193
tools/libxen/include/xen_network.h
| 273
tools/libxen/include/xen_network_decl.h
| 30
tools/libxen/include/xen_on_crash_behaviour.h
| 97
tools/libxen/include/xen_on_crash_behaviour_internal.h
| 38
tools/libxen/include/xen_on_normal_exit.h
| 77
tools/libxen/include/xen_on_normal_exit_internal.h
| 37
tools/libxen/include/xen_pif.h
| 290
tools/libxen/include/xen_pif_decl.h
| 30
tools/libxen/include/xen_sr.h
| 282
tools/libxen/include/xen_sr_decl.h
| 30
tools/libxen/include/xen_string_string_map.h
| 53
tools/libxen/include/xen_user.h
| 204
tools/libxen/include/xen_user_decl.h
| 30
tools/libxen/include/xen_vbd.h
| 285
tools/libxen/include/xen_vbd_decl.h
| 30
tools/libxen/include/xen_vbd_mode.h
| 77
tools/libxen/include/xen_vbd_mode_internal.h
| 37
tools/libxen/include/xen_vdi.h
| 344
tools/libxen/include/xen_vdi_decl.h
| 30
tools/libxen/include/xen_vdi_type.h
| 82
tools/libxen/include/xen_vdi_type_internal.h
| 37
tools/libxen/include/xen_vif.h
| 305
tools/libxen/include/xen_vif_decl.h
| 30
tools/libxen/include/xen_vm.h
| 819
tools/libxen/include/xen_vm_decl.h
| 30
tools/libxen/include/xen_vm_power_state.h
| 97
tools/libxen/include/xen_vm_power_state_internal.h
| 37
tools/libxen/include/xen_vtpm.h
| 216
tools/libxen/include/xen_vtpm_decl.h
| 31
tools/libxen/src/xen_boot_type.c
| 83
tools/libxen/src/xen_common.c
| 1363 +
tools/libxen/src/xen_cpu_feature.c
| 143
tools/libxen/src/xen_driver_type.c
| 81
tools/libxen/src/xen_host.c
| 390
tools/libxen/src/xen_host_cpu.c
| 287
tools/libxen/src/xen_int_float_map.c
| 37
tools/libxen/src/xen_network.c
| 364
tools/libxen/src/xen_on_crash_behaviour.c
| 85
tools/libxen/src/xen_on_normal_exit.c
| 81
tools/libxen/src/xen_pif.c
| 403
tools/libxen/src/xen_sr.c
| 388
tools/libxen/src/xen_string_string_map.c
| 49
tools/libxen/src/xen_user.c
| 201
tools/libxen/src/xen_vbd.c
| 387
tools/libxen/src/xen_vbd_mode.c
| 81
tools/libxen/src/xen_vdi.c
| 533
tools/libxen/src/xen_vdi_type.c
| 82
tools/libxen/src/xen_vif.c
| 440
tools/libxen/src/xen_vm.c
| 1596 +
tools/libxen/src/xen_vm_power_state.c
| 85
tools/libxen/src/xen_vtpm.c
| 227
tools/libxen/test/test_bindings.c
| 424
tools/pygrub/setup.py
| 43
tools/pygrub/src/fsimage/fsimage.c
| 299
tools/pygrub/src/pygrub
| 35
tools/python/README.XendConfig
| 159
tools/python/README.sxpcfg
| 116
tools/python/scripts/README
| 49
tools/python/scripts/README.lifecycle
| 136
tools/python/scripts/xapi.domcfg.py
| 37
tools/python/scripts/xapi.py
| 537
tools/python/scripts/xapi.vbdcfg.py
| 12
tools/python/scripts/xapi.vdicfg.py
| 7
tools/python/scripts/xapi.vifcfg.py
| 10
tools/python/scripts/xapi.vtpmcfg.py
| 3
tools/python/setup.py
| 3
tools/python/xen/lowlevel/xc/xc.c
| 90
tools/python/xen/util/blkif.py
| 14
tools/python/xen/util/xmlrpclib2.py
| 36
tools/python/xen/xend/Args.py
| 2
tools/python/xen/xend/PrettyPrint.py
| 2
tools/python/xen/xend/XendAPI.py
| 1531 +
tools/python/xen/xend/XendAPIConstants.py
| 75
tools/python/xen/xend/XendAuthSessions.py
| 137
tools/python/xen/xend/XendBootloader.py
| 6
tools/python/xen/xend/XendCheckpoint.py
| 29
tools/python/xen/xend/XendConfig.py
| 872
tools/python/xen/xend/XendConstants.py
| 96
tools/python/xen/xend/XendDevices.py
| 68
tools/python/xen/xend/XendDomain.py
| 1313 +
tools/python/xen/xend/XendDomainInfo.py
| 2490 +-
tools/python/xen/xend/XendError.py
| 16
tools/python/xen/xend/XendNode.py
| 131
tools/python/xen/xend/XendProtocol.py
| 2
tools/python/xen/xend/XendRoot.py
| 28
tools/python/xen/xend/XendStorageRepository.py
| 381
tools/python/xen/xend/XendVDI.py
| 155
tools/python/xen/xend/image.py
| 84
tools/python/xen/xend/server/DevController.py
| 79
tools/python/xen/xend/server/SrvDaemon.py
| 10
tools/python/xen/xend/server/SrvDomainDir.py
| 2
tools/python/xen/xend/server/SrvServer.py
| 30
tools/python/xen/xend/server/XMLRPCServer.py
| 103
tools/python/xen/xend/server/blkif.py
| 56
tools/python/xen/xend/server/iopif.py
| 4
tools/python/xen/xend/server/irqif.py
| 2
tools/python/xen/xend/server/netif.py
| 38
tools/python/xen/xend/server/pciif.py
| 61
tools/python/xen/xend/server/tpmif.py
| 32
tools/python/xen/xend/sxp.py
| 24
tools/python/xen/xend/uuid.py
| 10
tools/python/xen/xm/create.py
| 84
tools/python/xen/xm/main.py
| 108
tools/python/xen/xm/new.py
| 68
tools/xenmon/Makefile
| 2
tools/xenmon/xenmon.py
| 4
tools/xenstat/libxenstat/src/xenstat.c
| 20
tools/xenstore/Makefile
| 2
tools/xenstore/xsls.c
| 19
tools/xentrace/formats
| 2
tools/xm-test/configure.ac
| 9
tools/xm-test/lib/XmTestLib/arch.py
| 1
tools/xm-test/lib/XmTestReport/arch.py
| 4
tools/xm-test/ramdisk/Makefile.am
| 6
tools/xm-test/ramdisk/README-XenSource-initrd-1.0-img
| 3
tools/xm-test/ramdisk/README-XenSource-initrd-1.1-img
| 45
tools/xm-test/ramdisk/make-release.sh
| 47
tools/xm-test/ramdisk/patches/buildroot/add_xvd_devices.patch
| 5
tools/xm-test/runtest.sh
| 27
tools/xm-test/tests/block-create/01_block_attach_device_pos.py
| 10
tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py
| 8
tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py
| 16
tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py
| 18
tools/xm-test/tests/block-create/06_block_attach_baddomain_neg.py
| 8
tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py
| 14
tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py
| 16
tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py
| 44
tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py
| 30
tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py
| 2
tools/xm-test/tests/block-create/12_block_attach_shared_domU.py
| 2
tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py
| 8
tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py
| 8
tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py
| 2
tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py
| 8
tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py
| 10
tools/xm-test/tests/block-integrity/01_block_device_read_verify.py
| 4
tools/xm-test/tests/block-integrity/02_block_device_write_verify.py
| 4
tools/xm-test/tests/block-list/01_block-list_pos.py
| 6
tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py
| 6
tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py
| 10
tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py
| 24
tools/xm-test/tests/create/07_create_mem64_pos.py
| 2
tools/xm-test/tests/create/08_create_mem128_pos.py
| 2
tools/xm-test/tests/create/09_create_mem256_pos.py
| 2
tools/xm-test/tests/create/14_create_blockroot_pos.py
| 11
tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py
| 6
unmodified_drivers/linux-2.6/Makefile
| 1
unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h
| 1
unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h
| 15
unmodified_drivers/linux-2.6/mkbuildtree
| 3
unmodified_drivers/linux-2.6/platform-pci/evtchn.c
| 8
unmodified_drivers/linux-2.6/util/Kbuild
| 3
unmodified_drivers/linux-2.6/util/Makefile
| 3
xen/COPYING
| 20
xen/arch/ia64/vmx/mmio.c
| 16
xen/arch/ia64/vmx/vlsapic.c
| 61
xen/arch/ia64/vmx/vmx_hypercall.c
| 2
xen/arch/ia64/vmx/vmx_init.c
| 11
xen/arch/ia64/vmx/vmx_process.c
| 4
xen/arch/ia64/vmx/vmx_support.c
| 25
xen/arch/ia64/xen/dom0_ops.c
| 3
xen/arch/ia64/xen/domain.c
| 110
xen/arch/ia64/xen/irq.c
| 14
xen/arch/ia64/xen/mm.c
| 77
xen/arch/ia64/xen/tlb_track.c
| 5
xen/arch/ia64/xen/vcpu.c
| 7
xen/arch/ia64/xen/xencomm.c
| 7
xen/arch/ia64/xen/xensetup.c
| 6
xen/arch/powerpc/domain.c
| 23
xen/arch/powerpc/domain_build.c
| 2
xen/arch/powerpc/mm.c
| 8
xen/arch/powerpc/papr/xlate.c
| 2
xen/arch/powerpc/setup.c
| 9
xen/arch/powerpc/shadow.c
| 4
xen/arch/powerpc/usercopy.c
| 7
xen/arch/x86/domain.c
| 129
xen/arch/x86/domain_build.c
| 100
xen/arch/x86/domctl.c
| 57
xen/arch/x86/e820.c
| 2
xen/arch/x86/extable.c
| 2
xen/arch/x86/hvm/hvm.c
| 508
xen/arch/x86/hvm/i8254.c
| 16
xen/arch/x86/hvm/i8259.c
| 295
xen/arch/x86/hvm/instrlen.c
| 5
xen/arch/x86/hvm/intercept.c
| 93
xen/arch/x86/hvm/io.c
| 139
xen/arch/x86/hvm/platform.c
| 85
xen/arch/x86/hvm/pmtimer.c
| 6
xen/arch/x86/hvm/rtc.c
| 30
xen/arch/x86/hvm/svm/intr.c
| 80
xen/arch/x86/hvm/svm/svm.c
| 245
xen/arch/x86/hvm/svm/vmcb.c
| 412
xen/arch/x86/hvm/svm/x86_32/exits.S
| 7
xen/arch/x86/hvm/svm/x86_64/exits.S
| 11
xen/arch/x86/hvm/vioapic.c
| 988 -
xen/arch/x86/hvm/vlapic.c
| 737
xen/arch/x86/hvm/vmx/io.c
| 48
xen/arch/x86/hvm/vmx/vmcs.c
| 479
xen/arch/x86/hvm/vmx/vmx.c
| 829
xen/arch/x86/hvm/vmx/x86_32/exits.S
| 3
xen/arch/x86/hvm/vmx/x86_64/exits.S
| 3
xen/arch/x86/io_apic.c
| 3
xen/arch/x86/irq.c
| 13
xen/arch/x86/mm.c
| 33
xen/arch/x86/mm/shadow/common.c
| 152
xen/arch/x86/mm/shadow/multi.c
| 717
xen/arch/x86/mm/shadow/private.h
| 117
xen/arch/x86/mm/shadow/types.h
| 96
xen/arch/x86/oprofile/xenoprof.c
| 2
xen/arch/x86/platform_hypercall.c
| 2
xen/arch/x86/setup.c
| 11
xen/arch/x86/traps.c
| 114
xen/arch/x86/x86_32/asm-offsets.c
| 1
xen/arch/x86/x86_32/domain_page.c
| 2
xen/arch/x86/x86_32/seg_fixup.c
| 50
xen/arch/x86/x86_32/traps.c
| 16
xen/arch/x86/x86_64/asm-offsets.c
| 1
xen/arch/x86/x86_64/traps.c
| 24
xen/arch/x86/x86_emulate.c
| 12
xen/common/domain.c
| 99
xen/common/domctl.c
| 44
xen/common/event_channel.c
| 3
xen/common/grant_table.c
| 93
xen/common/keyhandler.c
| 4
xen/common/lib.c
| 17
xen/common/memory.c
| 303
xen/common/multicall.c
| 2
xen/common/page_alloc.c
| 7
xen/common/perfc.c
| 13
xen/common/sched_credit.c
| 520
xen/common/sched_sedf.c
| 44
xen/common/schedule.c
| 27
xen/common/trace.c
| 2
xen/common/xmalloc.c
| 90
xen/drivers/char/console.c
| 260
xen/include/asm-ia64/config.h
| 7
xen/include/asm-ia64/debugger.h
| 1
xen/include/asm-ia64/mm.h
| 2
xen/include/asm-ia64/vlsapic.h
| 1
xen/include/asm-ia64/vmx.h
| 2
xen/include/asm-ia64/vmx_platform.h
| 6
xen/include/asm-ia64/vmx_vpd.h
| 1
xen/include/asm-powerpc/powerpc64/config.h
| 6
xen/include/asm-x86/bitops.h
| 58
xen/include/asm-x86/config.h
| 7
xen/include/asm-x86/grant_table.h
| 4
xen/include/asm-x86/hvm/domain.h
| 12
xen/include/asm-x86/hvm/hvm.h
| 31
xen/include/asm-x86/hvm/io.h
| 18
xen/include/asm-x86/hvm/support.h
| 17
xen/include/asm-x86/hvm/svm/vmcb.h
| 24
xen/include/asm-x86/hvm/vcpu.h
| 5
xen/include/asm-x86/hvm/vioapic.h
| 113
xen/include/asm-x86/hvm/vlapic.h
| 116
xen/include/asm-x86/hvm/vmx/vmcs.h
| 6
xen/include/asm-x86/hvm/vmx/vmx.h
| 178
xen/include/asm-x86/hvm/vpic.h
| 39
xen/include/asm-x86/hvm/vpt.h
| 1
xen/include/asm-x86/mm.h
| 9
xen/include/asm-x86/page.h
| 12
xen/include/asm-x86/perfc_defn.h
| 3
xen/include/asm-x86/processor.h
| 2
xen/include/asm-x86/regs.h
| 2
xen/include/asm-x86/shadow.h
| 70
xen/include/asm-x86/x86_32/page-2level.h
| 3
xen/include/asm-x86/x86_32/page-3level.h
| 11
xen/include/asm-x86/x86_64/page.h
| 3
xen/include/public/COPYING
| 16
xen/include/public/acm.h
| 18
xen/include/public/acm_ops.h
| 18
xen/include/public/arch-ia64.h
| 19
xen/include/public/arch-x86_32.h
| 21
xen/include/public/arch-x86_64.h
| 27
xen/include/public/callback.h
| 18
xen/include/public/dom0_ops.h
| 18
xen/include/public/domctl.h
| 63
xen/include/public/elfnote.h
| 18
xen/include/public/event_channel.h
| 18
xen/include/public/features.h
| 18
xen/include/public/grant_table.h
| 18
xen/include/public/hvm/e820.h
| 27
xen/include/public/hvm/hvm_info_table.h
| 18
xen/include/public/hvm/hvm_op.h
| 25
xen/include/public/hvm/ioreq.h
| 48
xen/include/public/hvm/params.h
| 42
xen/include/public/hvm/vmx_assist.h
| 18
xen/include/public/io/blkif.h
| 47
xen/include/public/io/console.h
| 18
xen/include/public/io/netif.h
| 18
xen/include/public/io/pciif.h
| 18
xen/include/public/io/ring.h
| 18
xen/include/public/io/tpmif.h
| 18
xen/include/public/io/xenbus.h
| 18
xen/include/public/io/xs_wire.h
| 19
xen/include/public/memory.h
| 18
xen/include/public/nmi.h
| 18
xen/include/public/physdev.h
| 20
xen/include/public/platform.h
| 18
xen/include/public/sched.h
| 18
xen/include/public/sysctl.h
| 18
xen/include/public/trace.h
| 18
xen/include/public/vcpu.h
| 18
xen/include/public/version.h
| 18
xen/include/public/xen-compat.h
| 18
xen/include/public/xen.h
| 18
xen/include/public/xenoprof.h
| 18
xen/include/xen/config.h
| 74
xen/include/xen/console.h
| 3
xen/include/xen/domain.h
| 14
xen/include/xen/lib.h
| 4
xen/include/xen/sched-if.h
| 6
xen/include/xen/sched.h
| 61
xen/include/xen/softirq.h
| 5
488 files changed, 47189 insertions(+), 11341 deletions(-), 3 modifications(!)
diff -r 11b718eb22c9 -r ebed72718263 .hgignore
--- a/.hgignore Thu Nov 02 12:43:04 2006 -0700
+++ b/.hgignore Fri Nov 10 11:11:04 2006 -0700
@@ -98,7 +98,7 @@
^tools/firmware/.*\.bin$
^tools/firmware/.*\.sym$
^tools/firmware/.*bios/.*bios.*\.txt$
-^tools/firmware/acpi/acpigen$
+^tools/firmware/hvmloader/acpi/acpigen$
^tools/firmware/hvmloader/hvmloader$
^tools/firmware/hvmloader/roms\.h$
^tools/firmware/rombios/BIOS-bochs-[^/]*$
@@ -123,6 +123,7 @@
^tools/ioemu/qemu\.1$
^tools/ioemu/qemu\.pod$
^tools/libxc/xen/.*$
+^tools/libxen/test/test_bindings$
^tools/libaio/src/.*\.ol$
^tools/libaio/src/.*\.os$
^tools/misc/cpuperf/cpuperf-perfcntr$
diff -r 11b718eb22c9 -r ebed72718263 buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64 Thu Nov 02 12:43:04 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen0_ia64 Fri Nov 10 11:11:04 2006 -0700
@@ -1529,7 +1529,7 @@ CONFIG_XEN_XENBUS_DEV=y
CONFIG_XEN_XENBUS_DEV=y
CONFIG_XEN_BACKEND=y
CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
+CONFIG_XEN_BLKDEV_TAP=y
CONFIG_XEN_NETDEV_BACKEND=y
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=y
diff -r 11b718eb22c9 -r ebed72718263 buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64 Thu Nov 02 12:43:04 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen_ia64 Fri Nov 10 11:11:04 2006 -0700
@@ -1535,7 +1535,7 @@ CONFIG_XEN_XENBUS_DEV=y
CONFIG_XEN_XENBUS_DEV=y
CONFIG_XEN_BACKEND=y
CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
+CONFIG_XEN_BLKDEV_TAP=y
CONFIG_XEN_NETDEV_BACKEND=y
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=y
diff -r 11b718eb22c9 -r ebed72718263 config/SunOS.mk
--- a/config/SunOS.mk Thu Nov 02 12:43:04 2006 -0700
+++ b/config/SunOS.mk Fri Nov 10 11:11:04 2006 -0700
@@ -21,7 +21,7 @@ SOCKET_LIBS = -lsocket
SOCKET_LIBS = -lsocket
CURSES_LIBS = -lcurses
SONAME_LDFLAG = -h
-SHLIB_CFLAGS = -static-libgcc -shared
+SHLIB_CFLAGS = -R /usr/sfw/$(LIBDIR) -shared
ifneq ($(debug),y)
# Optimisation flags are overridable
diff -r 11b718eb22c9 -r ebed72718263 docs/src/user.tex
--- a/docs/src/user.tex Thu Nov 02 12:43:04 2006 -0700
+++ b/docs/src/user.tex Fri Nov 10 11:11:04 2006 -0700
@@ -3192,6 +3192,15 @@ editing \path{grub.conf}.
input to DOM0 when it boots --- if it is `x' then auto-switching is
disabled. Any other value, or omitting the character, enables
auto-switching. [NB. Default switch-char is `a'.]
+\item [ loglvl=$<$level$>/<$level$>$ ]
+ Specify logging level. Messages of the specified severity level (and
+ higher) will be printed to the Xen console. Valid levels are `none',
+ `error', `warning', `info', `debug', and `all'. The second level
+ specifier is optional: it is used to specify message severities
+ which are to be rate limited. Default is `loglvl=warning'.
+\item [ guest\_loglvl=$<$level$>/<$level$>$ ] As for loglvl, but
+ applies to messages relating to guests. Default is
+ `guest\_loglvl=none/warning'.
\item [ nmi=xxx ]
Specify what to do with an NMI parity or I/O error. \\
`nmi=fatal': Xen prints a diagnostic and then hangs. \\
@@ -3202,12 +3211,21 @@ editing \path{grub.conf}.
ignored. This parameter may be specified with a B, K, M or G suffix,
representing bytes, kilobytes, megabytes and gigabytes respectively.
The default unit, if no suffix is specified, is kilobytes.
-\item [ dom0\_mem=xxx ] Set the amount of memory to be allocated to
- domain0. In Xen 3.x the parameter may be specified with a B, K, M or
+\item [ dom0\_mem=$<$specifier list$>$ ] Set the amount of memory to
+ be allocated to domain 0. This is a comma-separated list containing
+ the following optional components:
+ \begin{description}
+ \item[ min:$<$min\_amt$>$ ] Minimum amount to allocate to domain 0
+ \item[ max:$<$min\_amt$>$ ] Maximum amount to allocate to domain 0
+ \item[ $<$amt$>$ ] Precise amount to allocate to domain 0
+ \end{description}
+ Each numeric parameter may be specified with a B, K, M or
G suffix, representing bytes, kilobytes, megabytes and gigabytes
respectively; if no suffix is specified, the parameter defaults to
- kilobytes. In previous versions of Xen, suffixes were not supported
- and the value is always interpreted as kilobytes.
+ kilobytes. Negative values are subtracted from total available
+ memory. If $<$amt$>$ is not specified, it defaults to all available
+ memory less a small amount (clamped to 128MB) for uses such as DMA
+ buffers.
\item [ dom0\_vcpus\_pin ] Pins domain 0 VCPUs on their respective
physical CPUS (default=false).
\item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c Fri Nov 10 11:11:04
2006 -0700
@@ -60,7 +60,7 @@ int __init sysenter_setup(void)
#ifdef CONFIG_XEN
if (boot_cpu_has(X86_FEATURE_SEP)) {
- struct callback_register sysenter = {
+ static struct callback_register __initdata sysenter = {
.type = CALLBACKTYPE_sysenter,
.address = { __KERNEL_CS, (unsigned long)sysenter_entry
},
};
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Fri Nov 10 11:11:04
2006 -0700
@@ -325,6 +325,7 @@ int xen_create_contiguous_region(
success = (exchange.nr_exchanged == (1UL << order));
BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
BUG_ON(success && (rc != 0));
+#ifdef CONFIG_XEN_COMPAT_030002
if (unlikely(rc == -ENOSYS)) {
/* Compatibility when XENMEM_exchange is unsupported. */
if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
@@ -341,6 +342,7 @@ int xen_create_contiguous_region(
BUG();
}
}
+#endif
/* 3. Map the new extent in place of old pages. */
for (i = 0; i < (1UL<<order); i++) {
@@ -419,6 +421,7 @@ void xen_destroy_contiguous_region(unsig
success = (exchange.nr_exchanged == 1);
BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
BUG_ON(success && (rc != 0));
+#ifdef CONFIG_XEN_COMPAT_030002
if (unlikely(rc == -ENOSYS)) {
/* Compatibility when XENMEM_exchange is unsupported. */
if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
@@ -429,6 +432,7 @@ void xen_destroy_contiguous_region(unsig
BUG();
success = 1;
}
+#endif
/* 4. Map new pages in place of old pages. */
for (i = 0; i < (1UL<<order); i++) {
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/arch/i386/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Fri Nov 10 11:11:04
2006 -0700
@@ -663,8 +663,8 @@ void __init mem_init(void)
totalram_pages += free_all_bootmem();
/* XEN: init and count low-mem pages outside initial allocation. */
for (pfn = xen_start_info->nr_pages; pfn < max_low_pfn; pfn++) {
- ClearPageReserved(&mem_map[pfn]);
- set_page_count(&mem_map[pfn], 1);
+ ClearPageReserved(pfn_to_page(pfn));
+ set_page_count(pfn_to_page(pfn), 1);
totalram_pages++;
}
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c Fri Nov 10 11:11:04
2006 -0700
@@ -20,6 +20,11 @@
#include <linux/mm.h>
#include <xen/interface/xen.h>
#include <asm/page.h>
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
#include <asm/xen/xencomm.h>
static int xencomm_debug = 0;
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Fri Nov 10 11:11:04
2006 -0700
@@ -913,8 +913,8 @@ void __init mem_init(void)
#endif
/* XEN: init and count pages outside initial allocation. */
for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
- ClearPageReserved(&mem_map[pfn]);
- set_page_count(&mem_map[pfn], 1);
+ ClearPageReserved(pfn_to_page(pfn));
+ set_page_count(pfn_to_page(pfn), 1);
totalram_pages++;
}
reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn);
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Fri Nov 10 11:11:04
2006 -0700
@@ -41,6 +41,7 @@
#include <xen/evtchn.h>
#include <xen/interface/grant_table.h>
#include <xen/interface/io/tpmif.h>
+#include <xen/gnttab.h>
#include <xen/xenbus.h>
#include "tpm.h"
#include "tpm_vtpm.h"
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu Nov 02
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Fri Nov 10
11:11:04 2006 -0700
@@ -189,9 +189,9 @@ static void fast_flush_area(pending_req_
static void print_stats(blkif_t *blkif)
{
- printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d\n",
+ printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d | br %4d\n",
current->comm, blkif->st_oo_req,
- blkif->st_rd_req, blkif->st_wr_req);
+ blkif->st_rd_req, blkif->st_wr_req, blkif->st_br_req);
blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
blkif->st_rd_req = 0;
blkif->st_wr_req = 0;
@@ -241,11 +241,17 @@ int blkif_schedule(void *arg)
* COMPLETION CALLBACK -- Called as bh->b_end_io()
*/
-static void __end_block_io_op(pending_req_t *pending_req, int uptodate)
+static void __end_block_io_op(pending_req_t *pending_req, int error)
{
/* An error fails the entire request. */
- if (!uptodate) {
- DPRINTK("Buffer not up-to-date at end of operation\n");
+ if ((pending_req->operation == BLKIF_OP_WRITE_BARRIER) &&
+ (error == -EOPNOTSUPP)) {
+ DPRINTK("blkback: write barrier op failed, not supported\n");
+ blkback_barrier(XBT_NIL, pending_req->blkif->be, 0);
+ pending_req->status = BLKIF_RSP_EOPNOTSUPP;
+ } else if (error) {
+ DPRINTK("Buffer not up-to-date at end of operation, "
+ "error=%d\n", error);
pending_req->status = BLKIF_RSP_ERROR;
}
@@ -262,7 +268,7 @@ static int end_block_io_op(struct bio *b
{
if (bio->bi_size != 0)
return 1;
- __end_block_io_op(bio->bi_private, !error);
+ __end_block_io_op(bio->bi_private, error);
bio_put(bio);
return error;
}
@@ -319,6 +325,9 @@ static int do_block_io_op(blkif_t *blkif
blkif->st_rd_req++;
dispatch_rw_block_io(blkif, &req, pending_req);
break;
+ case BLKIF_OP_WRITE_BARRIER:
+ blkif->st_br_req++;
+ /* fall through */
case BLKIF_OP_WRITE:
blkif->st_wr_req++;
dispatch_rw_block_io(blkif, &req, pending_req);
@@ -340,7 +349,6 @@ static void dispatch_rw_block_io(blkif_t
pending_req_t *pending_req)
{
extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
- int operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST];
struct phys_req preq;
struct {
@@ -349,6 +357,22 @@ static void dispatch_rw_block_io(blkif_t
unsigned int nseg;
struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
int ret, i, nbio = 0;
+ int operation;
+
+ switch (req->operation) {
+ case BLKIF_OP_READ:
+ operation = READ;
+ break;
+ case BLKIF_OP_WRITE:
+ operation = WRITE;
+ break;
+ case BLKIF_OP_WRITE_BARRIER:
+ operation = WRITE_BARRIER;
+ break;
+ default:
+ operation = 0; /* make gcc happy */
+ BUG();
+ }
/* Check that number of segments is sane. */
nseg = req->nr_segments;
@@ -364,7 +388,7 @@ static void dispatch_rw_block_io(blkif_t
pending_req->blkif = blkif;
pending_req->id = req->id;
- pending_req->operation = operation;
+ pending_req->operation = req->operation;
pending_req->status = BLKIF_RSP_OKAY;
pending_req->nr_pages = nseg;
@@ -380,7 +404,7 @@ static void dispatch_rw_block_io(blkif_t
preq.nr_sects += seg[i].nsec;
flags = GNTMAP_host_map;
- if ( operation == WRITE )
+ if (operation != READ)
flags |= GNTMAP_readonly;
gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags,
req->seg[i].gref, blkif->domid);
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Fri Nov 10 11:11:04
2006 -0700
@@ -44,6 +44,7 @@
#include <xen/interface/io/ring.h>
#include <xen/gnttab.h>
#include <xen/driver_util.h>
+#include <xen/xenbus.h>
#define DPRINTK(_f, _a...) \
pr_debug("(file=%s, line=%d) " _f, \
@@ -87,6 +88,7 @@ typedef struct blkif_st {
int st_rd_req;
int st_wr_req;
int st_oo_req;
+ int st_br_req;
wait_queue_head_t waiting_to_free;
@@ -131,4 +133,7 @@ irqreturn_t blkif_be_int(int irq, void *
irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
int blkif_schedule(void *arg);
+int blkback_barrier(struct xenbus_transaction xbt,
+ struct backend_info *be, int state);
+
#endif /* __BLKIF__BACKEND__COMMON_H__ */
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c Fri Nov 10 11:11:04
2006 -0700
@@ -31,7 +31,6 @@
*/
#include "common.h"
-#include <xen/xenbus.h>
#define vbd_sz(_v) ((_v)->bdev->bd_part ? \
(_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
@@ -104,7 +103,7 @@ int vbd_translate(struct phys_req *req,
struct vbd *vbd = &blkif->vbd;
int rc = -EACCES;
- if ((operation == WRITE) && vbd->readonly)
+ if ((operation != READ) && vbd->readonly)
goto out;
if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)))
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Nov 10 11:11:04
2006 -0700
@@ -20,7 +20,6 @@
#include <stdarg.h>
#include <linux/module.h>
#include <linux/kthread.h>
-#include <xen/xenbus.h>
#include "common.h"
#undef DPRINTK
@@ -91,11 +90,13 @@ VBD_SHOW(oo_req, "%d\n", be->blkif->st_o
VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
+VBD_SHOW(br_req, "%d\n", be->blkif->st_br_req);
static struct attribute *vbdstat_attrs[] = {
&dev_attr_oo_req.attr,
&dev_attr_rd_req.attr,
&dev_attr_wr_req.attr,
+ &dev_attr_br_req.attr,
NULL
};
@@ -165,6 +166,19 @@ static int blkback_remove(struct xenbus_
return 0;
}
+int blkback_barrier(struct xenbus_transaction xbt,
+ struct backend_info *be, int state)
+{
+ struct xenbus_device *dev = be->dev;
+ int err;
+
+ err = xenbus_printf(xbt, dev->nodename, "feature-barrier",
+ "%d", state);
+ if (err)
+ xenbus_dev_fatal(dev, err, "writing feature-barrier");
+
+ return err;
+}
/**
* Entry point to this code when a new device is created. Allocate the basic
@@ -366,11 +380,14 @@ static void connect(struct backend_info
/* Supply the information about the device the frontend needs */
again:
err = xenbus_transaction_start(&xbt);
-
if (err) {
xenbus_dev_fatal(dev, err, "starting transaction");
return;
}
+
+ err = blkback_barrier(xbt, be, 1);
+ if (err)
+ goto abort;
err = xenbus_printf(xbt, dev->nodename, "sectors", "%lu",
vbd_size(&be->blkif->vbd));
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Thu Nov 02
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Fri Nov 10
11:11:04 2006 -0700
@@ -320,6 +320,12 @@ static void connect(struct blkfront_info
return;
}
+ err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+ "feature-barrier", "%lu", &info->feature_barrier,
+ NULL);
+ if (err)
+ info->feature_barrier = 0;
+
err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
if (err) {
xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
@@ -569,10 +575,13 @@ static int blkif_queue_request(struct re
info->shadow[id].request = (unsigned long)req;
ring_req->id = id;
+ ring_req->sector_number = (blkif_sector_t)req->sector;
+ ring_req->handle = info->handle;
+
ring_req->operation = rq_data_dir(req) ?
BLKIF_OP_WRITE : BLKIF_OP_READ;
- ring_req->sector_number = (blkif_sector_t)req->sector;
- ring_req->handle = info->handle;
+ if (blk_barrier_rq(req))
+ ring_req->operation = BLKIF_OP_WRITE_BARRIER;
ring_req->nr_segments = 0;
rq_for_each_bio (bio, req) {
@@ -670,6 +679,7 @@ static irqreturn_t blkif_int(int irq, vo
RING_IDX i, rp;
unsigned long flags;
struct blkfront_info *info = (struct blkfront_info *)dev_id;
+ int uptodate;
spin_lock_irqsave(&blkif_io_lock, flags);
@@ -694,19 +704,27 @@ static irqreturn_t blkif_int(int irq, vo
ADD_ID_TO_FREELIST(info, id);
+ uptodate = (bret->status == BLKIF_RSP_OKAY);
switch (bret->operation) {
+ case BLKIF_OP_WRITE_BARRIER:
+ if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
+ printk("blkfront: %s: write barrier op
failed\n",
+ info->gd->disk_name);
+ uptodate = -EOPNOTSUPP;
+ info->feature_barrier = 0;
+ xlvbd_barrier(info);
+ }
+ /* fall through */
case BLKIF_OP_READ:
case BLKIF_OP_WRITE:
if (unlikely(bret->status != BLKIF_RSP_OKAY))
DPRINTK("Bad return from blkdev data "
"request: %x\n", bret->status);
- ret = end_that_request_first(
- req, (bret->status == BLKIF_RSP_OKAY),
+ ret = end_that_request_first(req, uptodate,
req->hard_nr_sectors);
BUG_ON(ret);
- end_that_request_last(
- req, (bret->status == BLKIF_RSP_OKAY));
+ end_that_request_last(req, uptodate);
break;
default:
BUG();
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Fri Nov 10 11:11:04
2006 -0700
@@ -126,6 +126,7 @@ struct blkfront_info
struct gnttab_free_callback callback;
struct blk_shadow shadow[BLK_RING_SIZE];
unsigned long shadow_free;
+ int feature_barrier;
/**
* The number of people holding this device open. We won't allow a
@@ -152,5 +153,6 @@ int xlvbd_add(blkif_sector_t capacity, i
int xlvbd_add(blkif_sector_t capacity, int device,
u16 vdisk_info, u16 sector_size, struct blkfront_info *info);
void xlvbd_del(struct blkfront_info *info);
+int xlvbd_barrier(struct blkfront_info *info);
#endif /* __XEN_DRIVERS_BLOCK_H__ */
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Fri Nov 10 11:11:04
2006 -0700
@@ -50,7 +50,7 @@
*/
#define NUM_IDE_MAJORS 10
-#define NUM_SCSI_MAJORS 9
+#define NUM_SCSI_MAJORS 17
#define NUM_VBD_MAJORS 1
static struct xlbd_type_info xlbd_ide_type = {
@@ -165,8 +165,11 @@ xlbd_get_major_info(int vdevice)
case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
index = 11 + major - SCSI_DISK1_MAJOR;
break;
- case SCSI_CDROM_MAJOR: index = 18; break;
- default: index = 19; break;
+ case SCSI_DISK8_MAJOR ... SCSI_DISK15_MAJOR:
+ index = 18 + major - SCSI_DISK8_MAJOR;
+ break;
+ case SCSI_CDROM_MAJOR: index = 26; break;
+ default: index = 27; break;
}
mi = ((major_info[index] != NULL) ? major_info[index] :
@@ -227,6 +230,7 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
struct xlbd_major_info *mi;
int nr_minors = 1;
int err = -ENODEV;
+ unsigned int offset;
BUG_ON(info->gd != NULL);
BUG_ON(info->mi != NULL);
@@ -244,15 +248,33 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
if (gd == NULL)
goto out;
- if (nr_minors > 1)
- sprintf(gd->disk_name, "%s%c", mi->type->diskname,
- 'a' + mi->index * mi->type->disks_per_major +
- (minor >> mi->type->partn_shift));
- else
- sprintf(gd->disk_name, "%s%c%d", mi->type->diskname,
- 'a' + mi->index * mi->type->disks_per_major +
- (minor >> mi->type->partn_shift),
- minor & ((1 << mi->type->partn_shift) - 1));
+ offset = mi->index * mi->type->disks_per_major +
+ (minor >> mi->type->partn_shift);
+ if (nr_minors > 1) {
+ if (offset < 26) {
+ sprintf(gd->disk_name, "%s%c",
+ mi->type->diskname, 'a' + offset );
+ }
+ else {
+ sprintf(gd->disk_name, "%s%c%c",
+ mi->type->diskname,
+ 'a' + ((offset/26)-1), 'a' + (offset%26) );
+ }
+ }
+ else {
+ if (offset < 26) {
+ sprintf(gd->disk_name, "%s%c%d",
+ mi->type->diskname,
+ 'a' + offset,
+ minor & ((1 << mi->type->partn_shift) - 1));
+ }
+ else {
+ sprintf(gd->disk_name, "%s%c%c%d",
+ mi->type->diskname,
+ 'a' + ((offset/26)-1), 'a' + (offset%26),
+ minor & ((1 << mi->type->partn_shift) - 1));
+ }
+ }
gd->major = mi->major;
gd->first_minor = minor;
@@ -267,6 +289,10 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
}
info->rq = gd->queue;
+ info->gd = gd;
+
+ if (info->feature_barrier)
+ xlvbd_barrier(info);
if (vdisk_info & VDISK_READONLY)
set_disk_ro(gd, 1);
@@ -276,8 +302,6 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
if (vdisk_info & VDISK_CDROM)
gd->flags |= GENHD_FL_CD;
-
- info->gd = gd;
return 0;
@@ -326,3 +350,26 @@ xlvbd_del(struct blkfront_info *info)
blk_cleanup_queue(info->rq);
info->rq = NULL;
}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
+int
+xlvbd_barrier(struct blkfront_info *info)
+{
+ int err;
+
+ err = blk_queue_ordered(info->rq,
+ info->feature_barrier ? QUEUE_ORDERED_DRAIN :
QUEUE_ORDERED_NONE, NULL);
+ if (err)
+ return err;
+ printk("blkfront: %s: barriers %s\n",
+ info->gd->disk_name, info->feature_barrier ? "enabled" :
"disabled");
+ return 0;
+}
+#else
+int
+xlvbd_barrier(struct blkfront_info *info)
+{
+ printk("blkfront: %s: barriers disabled\n", info->gd->disk_name);
+ return -ENOSYS;
+}
+#endif
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Fri Nov 10 11:11:04
2006 -0700
@@ -93,8 +93,9 @@ int setup_xen_class(void)
* mmap_alloc is initialised to 2 and should be adjustable on the fly via
* sysfs.
*/
-#define MAX_DYNAMIC_MEM 64
-#define MAX_PENDING_REQS 64
+#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
+#define MAX_DYNAMIC_MEM BLK_RING_SIZE
+#define MAX_PENDING_REQS BLK_RING_SIZE
#define MMAP_PAGES (MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
#define MMAP_VADDR(_start, _req,_seg) \
(_start + \
@@ -215,6 +216,7 @@ struct grant_handle_pair
grant_handle_t kernel;
grant_handle_t user;
};
+#define INVALID_GRANT_HANDLE 0xFFFF
static struct grant_handle_pair
pending_grant_handles[MAX_DYNAMIC_MEM][MMAP_PAGES];
@@ -293,10 +295,11 @@ static inline int GET_NEXT_REQ(unsigned
#define BLKTAP_INVALID_HANDLE(_g) \
- (((_g->kernel) == 0xFFFF) && ((_g->user) == 0xFFFF))
+ (((_g->kernel) == INVALID_GRANT_HANDLE) && \
+ ((_g->user) == INVALID_GRANT_HANDLE))
#define BLKTAP_INVALIDATE_HANDLE(_g) do { \
- (_g)->kernel = 0xFFFF; (_g)->user = 0xFFFF; \
+ (_g)->kernel = INVALID_GRANT_HANDLE; (_g)->user = INVALID_GRANT_HANDLE; \
} while(0)
@@ -535,8 +538,10 @@ static int blktap_release(struct inode *
}
if ( (info->status != CLEANSHUTDOWN) && (info->blkif != NULL) ) {
- kthread_stop(info->blkif->xenblkd);
- info->blkif->xenblkd = NULL;
+ if (info->blkif->xenblkd != NULL) {
+ kthread_stop(info->blkif->xenblkd);
+ info->blkif->xenblkd = NULL;
+ }
info->status = CLEANSHUTDOWN;
}
return 0;
@@ -588,8 +593,6 @@ static int blktap_mmap(struct file *filp
info->user_vstart = info->rings_vstart + (RING_PAGES << PAGE_SHIFT);
/* Map the ring pages to the start of the region and reserve it. */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
if (remap_pfn_range(vma, vma->vm_start,
__pa(info->ufe_ring.sring) >> PAGE_SHIFT,
PAGE_SIZE, vma->vm_page_prot)) {
@@ -884,6 +887,15 @@ static void fast_flush_area(pending_req_
return;
}
+ if (info->vma != NULL &&
+ xen_feature(XENFEAT_auto_translated_physmap)) {
+ down_write(&info->vma->vm_mm->mmap_sem);
+ zap_page_range(info->vma,
+ MMAP_VADDR(info->user_vstart, u_idx, 0),
+ req->nr_pages << PAGE_SHIFT, NULL);
+ up_write(&info->vma->vm_mm->mmap_sem);
+ }
+
mmap_idx = req->mem_idx;
for (i = 0; i < req->nr_pages; i++) {
@@ -892,14 +904,15 @@ static void fast_flush_area(pending_req_
khandle = &pending_handle(mmap_idx, k_idx, i);
- if (khandle->kernel != 0xFFFF) {
+ if (khandle->kernel != INVALID_GRANT_HANDLE) {
gnttab_set_unmap_op(&unmap[invcount],
idx_to_kaddr(mmap_idx, k_idx, i),
GNTMAP_host_map, khandle->kernel);
invcount++;
}
- if (khandle->user != 0xFFFF) {
+ if (khandle->user != INVALID_GRANT_HANDLE) {
+ BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
if (create_lookup_pte_addr(
info->vma->vm_mm,
MMAP_VADDR(info->user_vstart, u_idx, i),
@@ -908,8 +921,10 @@ static void fast_flush_area(pending_req_
return;
}
- gnttab_set_unmap_op(&unmap[invcount],
- ptep, GNTMAP_host_map,
+ gnttab_set_unmap_op(&unmap[invcount], ptep,
+ GNTMAP_host_map
+ | GNTMAP_application_map
+ | GNTMAP_contains_pte,
khandle->user);
invcount++;
}
@@ -920,7 +935,7 @@ static void fast_flush_area(pending_req_
GNTTABOP_unmap_grant_ref, unmap, invcount);
BUG_ON(ret);
- if (info->vma != NULL)
+ if (info->vma != NULL && !xen_feature(XENFEAT_auto_translated_physmap))
zap_page_range(info->vma,
MMAP_VADDR(info->user_vstart, u_idx, 0),
req->nr_pages << PAGE_SHIFT, NULL);
@@ -1004,11 +1019,14 @@ static int blktap_read_ufe_ring(tap_blki
rmb();
for (i = info->ufe_ring.rsp_cons; i != rp; i++) {
+ blkif_response_t res;
resp = RING_GET_RESPONSE(&info->ufe_ring, i);
+ memcpy(&res, resp, sizeof(res));
+ mb(); /* rsp_cons read by RING_FULL() in do_block_io_op(). */
++info->ufe_ring.rsp_cons;
/*retrieve [usr_idx] to [mmap_idx,pending_idx] mapping*/
- usr_idx = (int)resp->id;
+ usr_idx = (int)res.id;
pending_idx = MASK_PEND_IDX(ID_TO_IDX(info->idx_map[usr_idx]));
mmap_idx = ID_TO_MIDX(info->idx_map[usr_idx]);
@@ -1041,8 +1059,8 @@ static int blktap_read_ufe_ring(tap_blki
map[offset] = NULL;
}
fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
- make_response(blkif, pending_req->id, resp->operation,
- resp->status);
+ make_response(blkif, pending_req->id, res.operation,
+ res.status);
info->idx_map[usr_idx] = INVALID_REQ;
blkif_put(pending_req->blkif);
free_req(pending_req);
@@ -1184,8 +1202,10 @@ static void dispatch_rw_block_io(blkif_t
/* Check we have space on user ring - should never fail. */
usr_idx = GET_NEXT_REQ(info->idx_map);
- if (usr_idx == INVALID_REQ)
+ if (usr_idx == INVALID_REQ) {
+ BUG();
goto fail_response;
+ }
/* Check that number of segments is sane. */
nseg = req->nr_segments;
@@ -1219,14 +1239,12 @@ static void dispatch_rw_block_io(blkif_t
unsigned long uvaddr;
unsigned long kvaddr;
uint64_t ptep;
- struct page *page;
uint32_t flags;
uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
- page = virt_to_page(kvaddr);
-
- sector = req->sector_number + (8*i);
+
+ sector = req->sector_number + ((PAGE_SIZE / 512) * i);
if( (blkif->sectors > 0) && (sector >= blkif->sectors) ) {
WPRINTK("BLKTAP: Sector request greater"
"than size\n");
@@ -1236,7 +1254,7 @@ static void dispatch_rw_block_io(blkif_t
BLKIF_OP_WRITE ? "WRITE" : "READ"),
(long long unsigned) sector,
(long long unsigned) sector>>9,
- blkif->sectors);
+ (long long unsigned) blkif->sectors);
}
flags = GNTMAP_host_map;
@@ -1246,68 +1264,103 @@ static void dispatch_rw_block_io(blkif_t
req->seg[i].gref, blkif->domid);
op++;
- /* Now map it to user. */
- ret = create_lookup_pte_addr(info->vma->vm_mm,
- uvaddr, &ptep);
- if (ret) {
- WPRINTK("Couldn't get a pte addr!\n");
- goto fail_flush;
- }
-
- flags = GNTMAP_host_map | GNTMAP_application_map
- | GNTMAP_contains_pte;
- if (operation == WRITE)
- flags |= GNTMAP_readonly;
- gnttab_set_map_op(&map[op], ptep, flags,
- req->seg[i].gref, blkif->domid);
- op++;
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ /* Now map it to user. */
+ ret = create_lookup_pte_addr(info->vma->vm_mm,
+ uvaddr, &ptep);
+ if (ret) {
+ WPRINTK("Couldn't get a pte addr!\n");
+ goto fail_flush;
+ }
+
+ flags = GNTMAP_host_map | GNTMAP_application_map
+ | GNTMAP_contains_pte;
+ if (operation == WRITE)
+ flags |= GNTMAP_readonly;
+ gnttab_set_map_op(&map[op], ptep, flags,
+ req->seg[i].gref, blkif->domid);
+ op++;
+ }
}
ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op);
BUG_ON(ret);
- for (i = 0; i < (nseg*2); i+=2) {
- unsigned long uvaddr;
- unsigned long kvaddr;
- unsigned long offset;
- struct page *pg;
-
- uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2);
- kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i/2);
-
- if (unlikely(map[i].status != 0)) {
- WPRINTK("invalid kernel buffer -- "
- "could not remap it\n");
- ret |= 1;
- map[i].handle = 0xFFFF;
- }
-
- if (unlikely(map[i+1].status != 0)) {
- WPRINTK("invalid user buffer -- "
- "could not remap it\n");
- ret |= 1;
- map[i+1].handle = 0xFFFF;
- }
-
- pending_handle(mmap_idx, pending_idx, i/2).kernel
- = map[i].handle;
- pending_handle(mmap_idx, pending_idx, i/2).user
- = map[i+1].handle;
-
- if (ret)
- continue;
-
- set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
- FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
- offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
- pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
- ((struct page **)info->vma->vm_private_data)[offset] =
- pg;
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ for (i = 0; i < (nseg*2); i+=2) {
+ unsigned long uvaddr;
+ unsigned long kvaddr;
+ unsigned long offset;
+ struct page *pg;
+
+ uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2);
+ kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i/2);
+
+ if (unlikely(map[i].status != 0)) {
+ WPRINTK("invalid kernel buffer -- "
+ "could not remap it\n");
+ ret |= 1;
+ map[i].handle = INVALID_GRANT_HANDLE;
+ }
+
+ if (unlikely(map[i+1].status != 0)) {
+ WPRINTK("invalid user buffer -- "
+ "could not remap it\n");
+ ret |= 1;
+ map[i+1].handle = INVALID_GRANT_HANDLE;
+ }
+
+ pending_handle(mmap_idx, pending_idx, i/2).kernel
+ = map[i].handle;
+ pending_handle(mmap_idx, pending_idx, i/2).user
+ = map[i+1].handle;
+
+ if (ret)
+ continue;
+
+ set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
+ FOREIGN_FRAME(map[i].dev_bus_addr
+ >> PAGE_SHIFT));
+ offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
+ pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
+ ((struct page **)info->vma->vm_private_data)[offset] =
+ pg;
+ }
+ } else {
+ for (i = 0; i < nseg; i++) {
+ unsigned long uvaddr;
+ unsigned long kvaddr;
+ unsigned long offset;
+ struct page *pg;
+
+ uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
+ kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
+
+ if (unlikely(map[i].status != 0)) {
+ WPRINTK("invalid kernel buffer -- "
+ "could not remap it\n");
+ ret |= 1;
+ map[i].handle = INVALID_GRANT_HANDLE;
+ }
+
+ pending_handle(mmap_idx, pending_idx, i).kernel
+ = map[i].handle;
+
+ if (ret)
+ continue;
+
+ offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
+ pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
+ ((struct page **)info->vma->vm_private_data)[offset] =
+ pg;
+ }
}
if (ret)
goto fail_flush;
+ if (xen_feature(XENFEAT_auto_translated_physmap))
+ down_write(&info->vma->vm_mm->mmap_sem);
/* Mark mapped pages as reserved: */
for (i = 0; i < req->nr_segments; i++) {
unsigned long kvaddr;
@@ -1316,7 +1369,18 @@ static void dispatch_rw_block_io(blkif_t
kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
SetPageReserved(pg);
- }
+ if (xen_feature(XENFEAT_auto_translated_physmap)) {
+ ret = vm_insert_page(info->vma,
+ MMAP_VADDR(info->user_vstart,
+ usr_idx, i), pg);
+ if (ret) {
+ up_write(&info->vma->vm_mm->mmap_sem);
+ goto fail_flush;
+ }
+ }
+ }
+ if (xen_feature(XENFEAT_auto_translated_physmap))
+ up_write(&info->vma->vm_mm->mmap_sem);
/*record [mmap_idx,pending_idx] to [usr_idx] mapping*/
info->idx_map[usr_idx] = MAKE_ID(mmap_idx, pending_idx);
@@ -1327,6 +1391,7 @@ static void dispatch_rw_block_io(blkif_t
info->ufe_ring.req_prod_pvt);
memcpy(target, req, sizeof(*req));
target->id = usr_idx;
+ wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */
info->ufe_ring.req_prod_pvt++;
return;
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Fri Nov 10 11:11:04
2006 -0700
@@ -189,7 +189,7 @@ static int blktap_probe(struct xenbus_de
return 0;
fail:
- DPRINTK("blktap probe failed");
+ DPRINTK("blktap probe failed\n");
blktap_remove(dev);
return err;
}
@@ -243,7 +243,7 @@ static void tap_frontend_changed(struct
struct backend_info *be = dev->dev.driver_data;
int err;
- DPRINTK("");
+ DPRINTK("\n");
switch (frontend_state) {
case XenbusStateInitialising:
@@ -318,7 +318,7 @@ static int connect_ring(struct backend_i
unsigned int evtchn;
int err;
- DPRINTK("%s", dev->otherend);
+ DPRINTK("%s\n", dev->otherend);
err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu",
&ring_ref, "event-channel", "%u", &evtchn, NULL);
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/core/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile Fri Nov 10 11:11:04
2006 -0700
@@ -9,5 +9,5 @@ obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug
obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o
obj-$(CONFIG_XEN_SKBUFF) += skbuff.o
-obj-$(CONFIG_XEN_REBOOT) += reboot.o
+obj-$(CONFIG_XEN_REBOOT) += reboot.o machine_reboot.o
obj-$(CONFIG_XEN_SMPBOOT) += smpboot.o
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Fri Nov 10 11:11:04
2006 -0700
@@ -1,25 +1,15 @@
#define __KERNEL_SYSCALLS__
#include <linux/version.h>
#include <linux/kernel.h>
-#include <linux/mm.h>
#include <linux/unistd.h>
#include <linux/module.h>
#include <linux/reboot.h>
#include <linux/sysrq.h>
-#include <linux/stringify.h>
-#include <asm/irq.h>
-#include <asm/mmu_context.h>
-#include <xen/evtchn.h>
#include <asm/hypervisor.h>
-#include <xen/interface/dom0_ops.h>
#include <xen/xenbus.h>
-#include <linux/cpu.h>
#include <linux/kthread.h>
-#include <xen/gnttab.h>
-#include <xen/xencons.h>
-#include <xen/cpu_hotplug.h>
-
-extern void ctrl_alt_del(void);
+
+MODULE_LICENSE("Dual BSD/GPL");
#define SHUTDOWN_INVALID -1
#define SHUTDOWN_POWEROFF 0
@@ -31,185 +21,17 @@ extern void ctrl_alt_del(void);
*/
#define SHUTDOWN_HALT 4
-#if defined(__i386__) || defined(__x86_64__)
-
-/*
- * Power off function, if any
- */
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
-void machine_emergency_restart(void)
-{
- /* We really want to get pending console data out before we die. */
- xencons_force_flush();
- HYPERVISOR_shutdown(SHUTDOWN_reboot);
-}
-
-void machine_restart(char * __unused)
-{
- machine_emergency_restart();
-}
-
-void machine_halt(void)
-{
- machine_power_off();
-}
-
-void machine_power_off(void)
-{
- /* We really want to get pending console data out before we die. */
- xencons_force_flush();
- if (pm_power_off)
- pm_power_off();
- HYPERVISOR_shutdown(SHUTDOWN_poweroff);
-}
-
-int reboot_thru_bios = 0; /* for dmi_scan.c */
-EXPORT_SYMBOL(machine_restart);
-EXPORT_SYMBOL(machine_halt);
-EXPORT_SYMBOL(machine_power_off);
-
-#endif /* defined(__i386__) || defined(__x86_64__) */
-
-/******************************************************************************
- * Stop/pickle callback handling.
- */
-
/* Ignore multiple shutdown requests. */
static int shutting_down = SHUTDOWN_INVALID;
+
static void __shutdown_handler(void *unused);
static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
-#if defined(__i386__) || defined(__x86_64__)
-
-/* Ensure we run on the idle task page tables so that we will
- switch page tables before running user space. This is needed
- on architectures with separate kernel and user page tables
- because the user page table pointer is not saved/restored. */
-static void switch_idle_mm(void)
-{
- struct mm_struct *mm = current->active_mm;
-
- if (mm == &init_mm)
- return;
-
- atomic_inc(&init_mm.mm_count);
- switch_mm(mm, &init_mm, current);
- current->active_mm = &init_mm;
- mmdrop(mm);
-}
-
-static void pre_suspend(void)
-{
- HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
- clear_fixmap(FIX_SHARED_INFO);
-
- xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
- xen_start_info->console.domU.mfn =
- mfn_to_pfn(xen_start_info->console.domU.mfn);
-}
-
-static void post_suspend(void)
-{
- int i, j, k, fpp;
- extern unsigned long max_pfn;
- extern unsigned long *pfn_to_mfn_frame_list_list;
- extern unsigned long *pfn_to_mfn_frame_list[];
-
- set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-
- HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-
- memset(empty_zero_page, 0, PAGE_SIZE);
-
- HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
- virt_to_mfn(pfn_to_mfn_frame_list_list);
-
- fpp = PAGE_SIZE/sizeof(unsigned long);
- for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
- if ((j % fpp) == 0) {
- k++;
- pfn_to_mfn_frame_list_list[k] =
- virt_to_mfn(pfn_to_mfn_frame_list[k]);
- j = 0;
- }
- pfn_to_mfn_frame_list[k][j] =
- virt_to_mfn(&phys_to_machine_mapping[i]);
- }
- HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-}
-
-#else /* !(defined(__i386__) || defined(__x86_64__)) */
-
-#define switch_idle_mm() ((void)0)
-#define mm_pin_all() ((void)0)
-#define pre_suspend() ((void)0)
-#define post_suspend() ((void)0)
-
+#ifdef CONFIG_XEN
+int __xen_suspend(void);
+#else
+#define __xen_suspend() (void)0
#endif
-
-static int __do_suspend(void *ignore)
-{
- int err;
-
- extern void time_resume(void);
-
- BUG_ON(smp_processor_id() != 0);
- BUG_ON(in_interrupt());
-
-#if defined(__i386__) || defined(__x86_64__)
- if (xen_feature(XENFEAT_auto_translated_physmap)) {
- printk(KERN_WARNING "Cannot suspend in "
- "auto_translated_physmap mode.\n");
- return -EOPNOTSUPP;
- }
-#endif
-
- err = smp_suspend();
- if (err)
- return err;
-
- xenbus_suspend();
-
- preempt_disable();
-
- mm_pin_all();
- local_irq_disable();
- preempt_enable();
-
- gnttab_suspend();
-
- pre_suspend();
-
- /*
- * We'll stop somewhere inside this hypercall. When it returns,
- * we'll start resuming after the restore.
- */
- HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
-
- shutting_down = SHUTDOWN_INVALID;
-
- post_suspend();
-
- gnttab_resume();
-
- irq_resume();
-
- time_resume();
-
- switch_idle_mm();
-
- local_irq_enable();
-
- xencons_resume();
-
- xenbus_resume();
-
- smp_resume();
-
- return err;
-}
static int shutdown_process(void *__unused)
{
@@ -222,16 +44,25 @@ static int shutdown_process(void *__unus
if ((shutting_down == SHUTDOWN_POWEROFF) ||
(shutting_down == SHUTDOWN_HALT)) {
- if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) {
+ if (call_usermodehelper("/sbin/poweroff", poweroff_argv, envp,
0) < 0) {
+#ifdef CONFIG_XEN
sys_reboot(LINUX_REBOOT_MAGIC1,
LINUX_REBOOT_MAGIC2,
LINUX_REBOOT_CMD_POWER_OFF,
NULL);
+#endif /* CONFIG_XEN */
}
}
shutting_down = SHUTDOWN_INVALID; /* could try again */
+ return 0;
+}
+
+static int xen_suspend(void *__unused)
+{
+ __xen_suspend();
+ shutting_down = SHUTDOWN_INVALID;
return 0;
}
@@ -257,7 +88,7 @@ static void __shutdown_handler(void *unu
err = kernel_thread(shutdown_process, NULL,
CLONE_FS | CLONE_FILES);
else
- err = kthread_create_on_cpu(__do_suspend, NULL, "suspend", 0);
+ err = kthread_create_on_cpu(xen_suspend, NULL, "suspend", 0);
if (err < 0) {
printk(KERN_WARNING "Error creating shutdown process (%d): "
@@ -298,7 +129,7 @@ static void shutdown_handler(struct xenb
if (strcmp(str, "poweroff") == 0)
shutting_down = SHUTDOWN_POWEROFF;
else if (strcmp(str, "reboot") == 0)
- ctrl_alt_del();
+ kill_proc(1, SIGINT, 1); /* interrupt init */
else if (strcmp(str, "suspend") == 0)
shutting_down = SHUTDOWN_SUSPEND;
else if (strcmp(str, "halt") == 0)
@@ -364,10 +195,14 @@ static int setup_shutdown_watcher(struct
err = register_xenbus_watch(&shutdown_watch);
if (err)
printk(KERN_ERR "Failed to set shutdown watcher\n");
+ else
+ xenbus_write(XBT_NIL, "control", "feature-reboot", "1");
err = register_xenbus_watch(&sysrq_watch);
if (err)
printk(KERN_ERR "Failed to set sysrq watcher\n");
+ else
+ xenbus_write(XBT_NIL, "control", "feature-sysrq", "1");
return NOTIFY_DONE;
}
@@ -378,6 +213,7 @@ static int __init setup_shutdown_event(v
.notifier_call = setup_shutdown_watcher
};
register_xenstore_notifier(&xenstore_notifier);
+
return 0;
}
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Thu Nov 02
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Fri Nov 10
11:11:04 2006 -0700
@@ -166,9 +166,6 @@ netif_t *netif_alloc(domid_t domid, unsi
SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
dev->tx_queue_len = netbk_queue_length;
- if (dev->tx_queue_len != 0)
- printk(KERN_WARNING "netbk: WARNING: device '%s' has non-zero "
- "queue length (%lu)!\n", dev->name, dev->tx_queue_len);
/*
* Initialise a dummy MAC address. We choose the numerically
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Nov 02
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri Nov 10
11:11:04 2006 -0700
@@ -814,7 +814,7 @@ void netif_deschedule_work(netif_t *neti
static void tx_add_credit(netif_t *netif)
{
- unsigned long max_burst;
+ unsigned long max_burst, max_credit;
/*
* Allow a burst big enough to transmit a jumbo packet of up to 128kB.
@@ -824,9 +824,10 @@ static void tx_add_credit(netif_t *netif
max_burst = min(max_burst, 131072UL);
max_burst = max(max_burst, netif->credit_bytes);
- netif->remaining_credit = min(netif->remaining_credit +
- netif->credit_bytes,
- max_burst);
+ /* Take care that adding a new chunk of credit doesn't wrap to zero. */
+ max_credit = max(netif->remaining_credit + netif->credit_bytes, ~0UL);
+
+ netif->remaining_credit = min(max_credit, max_burst);
}
static void tx_credit_callback(unsigned long data)
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Nov 10 11:11:04
2006 -0700
@@ -93,10 +93,22 @@ static int netback_probe(struct xenbus_d
goto abort_transaction;
}
+ /* We support rx-copy path. */
err = xenbus_printf(xbt, dev->nodename,
"feature-rx-copy", "%d", 1);
if (err) {
- message = "writing feature-copying";
+ message = "writing feature-rx-copy";
+ goto abort_transaction;
+ }
+
+ /*
+ * We don't support rx-flip path (except old guests who don't
+ * grok this feature flag).
+ */
+ err = xenbus_printf(xbt, dev->nodename,
+ "feature-rx-flip", "%d", 0);
+ if (err) {
+ message = "writing feature-rx-flip";
goto abort_transaction;
}
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Thu Nov 02
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Nov 10
11:11:04 2006 -0700
@@ -101,6 +101,14 @@ static inline void dev_disable_gso_featu
}
#elif defined(NETIF_F_TSO)
#define HAVE_TSO 1
+
+/* Some older kernels cannot cope with incorrect checksums,
+ * particularly in netfilter. I'm not sure there is 100% correlation
+ * with the presence of NETIF_F_TSO but it appears to be a good first
+ * approximiation.
+ */
+#define HAVE_NO_CSUM_OFFLOAD 1
+
#define gso_size tso_size
#define gso_segs tso_segs
static inline void dev_disable_gso_features(struct net_device *dev)
@@ -242,7 +250,6 @@ static void netif_disconnect_backend(str
static void netif_disconnect_backend(struct netfront_info *);
static int open_netdev(struct netfront_info *);
static void close_netdev(struct netfront_info *);
-static void netif_free(struct netfront_info *);
static int network_connect(struct net_device *);
static void network_tx_buf_gc(struct net_device *);
@@ -395,6 +402,14 @@ again:
goto abort_transaction;
}
+#ifdef HAVE_NO_CSUM_OFFLOAD
+ err = xenbus_printf(xbt, dev->nodename, "feature-no-csum-offload",
"%d", 1);
+ if (err) {
+ message = "writing feature-no-csum-offload";
+ goto abort_transaction;
+ }
+#endif
+
err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
if (err) {
message = "writing feature-sg";
@@ -427,7 +442,6 @@ again:
out:
return err;
}
-
static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
{
@@ -488,10 +502,8 @@ static int setup_device(struct xenbus_de
return 0;
fail:
- netif_free(info);
return err;
}
-
/**
* Callback received when the backend's state changes.
@@ -513,10 +525,8 @@ static void backend_changed(struct xenbu
break;
case XenbusStateInitWait:
- if (network_connect(netdev) != 0) {
- netif_free(np);
+ if (network_connect(netdev) != 0)
break;
- }
xenbus_switch_state(dev, XenbusStateConnected);
(void)send_fake_arp(netdev);
break;
@@ -526,7 +536,6 @@ static void backend_changed(struct xenbu
break;
}
}
-
/** Send a packet on a net device to encourage switches to learn the
* MAC. We send a fake ARP request.
@@ -555,7 +564,6 @@ static int send_fake_arp(struct net_devi
return dev_queue_xmit(skb);
}
-
static int network_open(struct net_device *dev)
{
@@ -648,13 +656,11 @@ static void network_tx_buf_gc(struct net
network_maybe_wake_tx(dev);
}
-
static void rx_refill_timeout(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
netif_rx_schedule(dev);
}
-
static void network_alloc_rx_buffers(struct net_device *dev)
{
@@ -1617,8 +1623,16 @@ static void xennet_set_features(struct n
if (!(dev->features & NETIF_F_IP_CSUM))
return;
- if (!xennet_set_sg(dev, 1))
- xennet_set_tso(dev, 1);
+ if (xennet_set_sg(dev, 1))
+ return;
+
+ /* Before 2.6.9 TSO seems to be unreliable so do not enable it
+ * on older kernels.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
+ xennet_set_tso(dev, 1);
+#endif
+
}
static int network_connect(struct net_device *dev)
@@ -2063,14 +2077,6 @@ static void netif_disconnect_backend(str
}
-static void netif_free(struct netfront_info *info)
-{
- close_netdev(info);
- netif_disconnect_backend(info);
- free_netdev(info->netdev);
-}
-
-
static void end_access(int ref, void *page)
{
if (ref != GRANT_INVALID_REF)
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Thu Nov 02
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Fri Nov 10
11:11:04 2006 -0700
@@ -53,6 +53,8 @@ static int privcmd_ioctl(struct inode *i
return -EFAULT;
#if defined(__i386__)
+ if (hypercall.op >= (PAGE_SIZE >> 5))
+ break;
__asm__ __volatile__ (
"pushl %%ebx; pushl %%ecx; pushl %%edx; "
"pushl %%esi; pushl %%edi; "
@@ -69,21 +71,21 @@ static int privcmd_ioctl(struct inode *i
"popl %%ecx; popl %%ebx"
: "=a" (ret) : "0" (&hypercall) : "memory" );
#elif defined (__x86_64__)
- {
+ if (hypercall.op < (PAGE_SIZE >> 5)) {
long ign1, ign2, ign3;
__asm__ __volatile__ (
"movq %8,%%r10; movq %9,%%r8;"
- "shlq $5,%%rax ;"
+ "shll $5,%%eax ;"
"addq $hypercall_page,%%rax ;"
"call *%%rax"
: "=a" (ret), "=D" (ign1),
"=S" (ign2), "=d" (ign3)
- : "0" ((unsigned long)hypercall.op),
- "1" ((unsigned long)hypercall.arg[0]),
- "2" ((unsigned long)hypercall.arg[1]),
- "3" ((unsigned long)hypercall.arg[2]),
- "g" ((unsigned long)hypercall.arg[3]),
- "g" ((unsigned long)hypercall.arg[4])
+ : "0" ((unsigned int)hypercall.op),
+ "1" (hypercall.arg[0]),
+ "2" (hypercall.arg[1]),
+ "3" (hypercall.arg[2]),
+ "g" (hypercall.arg[3]),
+ "g" (hypercall.arg[4])
: "r8", "r10", "memory" );
}
#elif defined (__ia64__)
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Thu Nov 02
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Fri Nov 10
11:11:04 2006 -0700
@@ -30,13 +30,16 @@
* IN THE SOFTWARE.
*/
-#include <asm/hypervisor.h>
-#include <xen/evtchn.h>
#include <linux/wait.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/err.h>
+#include <linux/ptrace.h>
+#include <xen/evtchn.h>
#include <xen/xenbus.h>
+
+#include <asm/hypervisor.h>
+
#include "xenbus_comms.h"
#ifdef HAVE_XEN_PLATFORM_COMPAT_H
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h Thu Nov
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h Fri Nov
10 11:11:04 2006 -0700
@@ -27,7 +27,6 @@ extern unsigned long __FIXADDR_TOP;
#include <asm/acpi.h>
#include <asm/apicdef.h>
#include <asm/page.h>
-#include <xen/gnttab.h>
#ifdef CONFIG_HIGHMEM
#include <linux/threads.h>
#include <asm/kmap_types.h>
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Thu Nov
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Fri Nov
10 11:11:04 2006 -0700
@@ -260,6 +260,8 @@ HYPERVISOR_event_channel_op(
int cmd, void *arg)
{
int rc = _hypercall2(int, event_channel_op, cmd, arg);
+
+#ifdef CONFIG_XEN_COMPAT_030002
if (unlikely(rc == -ENOSYS)) {
struct evtchn_op op;
op.cmd = cmd;
@@ -267,6 +269,8 @@ HYPERVISOR_event_channel_op(
rc = _hypercall1(int, event_channel_op_compat, &op);
memcpy(arg, &op.u, sizeof(op.u));
}
+#endif
+
return rc;
}
@@ -296,6 +300,8 @@ HYPERVISOR_physdev_op(
int cmd, void *arg)
{
int rc = _hypercall2(int, physdev_op, cmd, arg);
+
+#ifdef CONFIG_XEN_COMPAT_030002
if (unlikely(rc == -ENOSYS)) {
struct physdev_op op;
op.cmd = cmd;
@@ -303,6 +309,8 @@ HYPERVISOR_physdev_op(
rc = _hypercall1(int, physdev_op_compat, &op);
memcpy(arg, &op.u, sizeof(op.u));
}
+#endif
+
return rc;
}
@@ -350,9 +358,11 @@ HYPERVISOR_suspend(
int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
&sched_shutdown, srec);
+#ifdef CONFIG_XEN_COMPAT_030002
if (rc == -ENOSYS)
rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
+#endif
return rc;
}
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Thu Nov
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Fri Nov
10 11:11:04 2006 -0700
@@ -131,8 +131,10 @@ HYPERVISOR_yield(
{
int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
+#ifdef CONFIG_XEN_COMPAT_030002
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
+#endif
return rc;
}
@@ -143,8 +145,10 @@ HYPERVISOR_block(
{
int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
+#ifdef CONFIG_XEN_COMPAT_030002
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
+#endif
return rc;
}
@@ -159,8 +163,10 @@ HYPERVISOR_shutdown(
int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
+#ifdef CONFIG_XEN_COMPAT_030002
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
+#endif
return rc;
}
@@ -177,8 +183,10 @@ HYPERVISOR_poll(
set_xen_guest_handle(sched_poll.ports, ports);
rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
+#ifdef CONFIG_XEN_COMPAT_030002
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
+#endif
return rc;
}
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Thu Nov
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Fri Nov
10 11:11:04 2006 -0700
@@ -56,15 +56,15 @@ static void __init machine_specific_arch
struct xen_machphys_mapping mapping;
unsigned long machine_to_phys_nr_ents;
struct xen_platform_parameters pp;
- struct callback_register event = {
+ static struct callback_register __initdata event = {
.type = CALLBACKTYPE_event,
.address = { __KERNEL_CS, (unsigned long)hypervisor_callback },
};
- struct callback_register failsafe = {
+ static struct callback_register __initdata failsafe = {
.type = CALLBACKTYPE_failsafe,
.address = { __KERNEL_CS, (unsigned long)failsafe_callback },
};
- struct callback_register nmi_cb = {
+ static struct callback_register __initdata nmi_cb = {
.type = CALLBACKTYPE_nmi,
.address = { __KERNEL_CS, (unsigned long)nmi },
};
@@ -72,19 +72,24 @@ static void __init machine_specific_arch
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
if (ret == 0)
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
+#ifdef CONFIG_XEN_COMPAT_030002
if (ret == -ENOSYS)
ret = HYPERVISOR_set_callbacks(
event.address.cs, event.address.eip,
failsafe.address.cs, failsafe.address.eip);
+#endif
BUG_ON(ret);
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
+#ifdef CONFIG_XEN_COMPAT_030002
if (ret == -ENOSYS) {
- struct xennmi_callback cb;
+ static struct xennmi_callback __initdata cb = {
+ .handler_address = (unsigned long)nmi
+ };
- cb.handler_address = nmi_cb.address.eip;
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
}
+#endif
if (HYPERVISOR_xen_version(XENVER_platform_parameters,
&pp) == 0)
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Thu Nov 02 12:43:04
2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Fri Nov 10 11:11:04
2006 -0700
@@ -283,6 +283,9 @@ static inline void exit_idle(void) {}
#ifdef CONFIG_XEN
#include <asm/xen/privop.h>
#endif /* CONFIG_XEN */
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
static inline unsigned long
__HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Thu Nov 02
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Fri Nov 10
11:11:04 2006 -0700
@@ -191,6 +191,22 @@ MULTI_grant_table_op(multicall_entry_t *
mcl->args[2] = count;
}
+/*
+ * for blktap.c
+ * int create_lookup_pte_addr(struct mm_struct *mm,
+ * unsigned long address,
+ * uint64_t *ptep);
+ */
+#define create_lookup_pte_addr(mm, address, ptep) \
+ ({ \
+ printk(KERN_EMERG \
+ "%s:%d " \
+ "create_lookup_pte_addr() isn't supported.\n", \
+ __func__, __LINE__); \
+ BUG(); \
+ (-ENOSYS); \
+ })
+
// for debug
asmlinkage int xprintk(const char *fmt, ...);
#define xprintd(fmt, ...) xprintk("%s:%d " fmt, __func__, __LINE__, \
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h Thu Nov
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h Fri Nov
10 11:11:04 2006 -0700
@@ -14,7 +14,6 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <asm/apicdef.h>
-#include <xen/gnttab.h>
#include <asm/page.h>
#include <asm/vsyscall.h>
#include <asm/vsyscall32.h>
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Thu Nov
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Fri Nov
10 11:11:04 2006 -0700
@@ -258,6 +258,8 @@ HYPERVISOR_event_channel_op(
int cmd, void *arg)
{
int rc = _hypercall2(int, event_channel_op, cmd, arg);
+
+#ifdef CONFIG_XEN_COMPAT_030002
if (unlikely(rc == -ENOSYS)) {
struct evtchn_op op;
op.cmd = cmd;
@@ -265,6 +267,8 @@ HYPERVISOR_event_channel_op(
rc = _hypercall1(int, event_channel_op_compat, &op);
memcpy(arg, &op.u, sizeof(op.u));
}
+#endif
+
return rc;
}
@@ -294,6 +298,8 @@ HYPERVISOR_physdev_op(
int cmd, void *arg)
{
int rc = _hypercall2(int, physdev_op, cmd, arg);
+
+#ifdef CONFIG_XEN_COMPAT_030002
if (unlikely(rc == -ENOSYS)) {
struct physdev_op op;
op.cmd = cmd;
@@ -301,6 +307,8 @@ HYPERVISOR_physdev_op(
rc = _hypercall1(int, physdev_op_compat, &op);
memcpy(arg, &op.u, sizeof(op.u));
}
+#endif
+
return rc;
}
@@ -351,9 +359,11 @@ HYPERVISOR_suspend(
int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
&sched_shutdown, srec);
+#ifdef CONFIG_XEN_COMPAT_030002
if (rc == -ENOSYS)
rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
+#endif
return rc;
}
diff -r 11b718eb22c9 -r ebed72718263
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
Thu Nov 02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
Fri Nov 10 11:11:04 2006 -0700
@@ -15,20 +15,20 @@ static void __init machine_specific_arch
static void __init machine_specific_arch_setup(void)
{
int ret;
- struct callback_register event = {
+ static struct callback_register __initdata event = {
.type = CALLBACKTYPE_event,
.address = (unsigned long) hypervisor_callback,
};
- struct callback_register failsafe = {
+ static struct callback_register __initdata failsafe = {
.type = CALLBACKTYPE_failsafe,
.address = (unsigned long)failsafe_callback,
};
- struct callback_register syscall = {
+ static struct callback_register __initdata syscall = {
.type = CALLBACKTYPE_syscall,
.address = (unsigned long)system_call,
};
#ifdef CONFIG_X86_LOCAL_APIC
- struct callback_register nmi_cb = {
+ static struct callback_register __initdata nmi_cb = {
.type = CALLBACKTYPE_nmi,
.address = (unsigned long)nmi,
};
@@ -39,20 +39,25 @@ static void __init machine_specific_arch
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
if (ret == 0)
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &syscall);
+#ifdef CONFIG_XEN_COMPAT_030002
if (ret == -ENOSYS)
ret = HYPERVISOR_set_callbacks(
event.address,
failsafe.address,
syscall.address);
+#endif
BUG_ON(ret);
#ifdef CONFIG_X86_LOCAL_APIC
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
+#ifdef CONFIG_XEN_COMPAT_030002
if (ret == -ENOSYS) {
- struct xennmi_callback cb;
+ static struct xennmi_callback __initdata cb = {
+ .handler_address = (unsigned long)nmi
+ };
- cb.handler_address = nmi_cb.address;
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
}
#endif
+#endif
}
diff -r 11b718eb22c9 -r ebed72718263 linux-2.6-xen-sparse/include/xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/xen/gnttab.h Thu Nov 02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/xen/gnttab.h Fri Nov 10 11:11:04 2006 -0700
@@ -39,6 +39,7 @@
#include <linux/config.h>
#include <asm/hypervisor.h>
+#include <asm/maddr.h> /* maddr_t */
#include <xen/interface/grant_table.h>
#include <xen/features.h>
@@ -118,7 +119,7 @@ int gnttab_resume(void);
int gnttab_resume(void);
static inline void
-gnttab_set_map_op(struct gnttab_map_grant_ref *map, unsigned long addr,
+gnttab_set_map_op(struct gnttab_map_grant_ref *map, maddr_t addr,
uint32_t flags, grant_ref_t ref, domid_t domid)
{
if (flags & GNTMAP_contains_pte)
@@ -134,7 +135,7 @@ gnttab_set_map_op(struct gnttab_map_gran
}
static inline void
-gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, unsigned long addr,
+gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, maddr_t addr,
uint32_t flags, grant_handle_t handle)
{
if (flags & GNTMAP_contains_pte)
diff -r 11b718eb22c9 -r ebed72718263 patches/linux-2.6.16.29/series
--- a/patches/linux-2.6.16.29/series Thu Nov 02 12:43:04 2006 -0700
+++ b/patches/linux-2.6.16.29/series Fri Nov 10 11:11:04 2006 -0700
@@ -10,6 +10,7 @@ net-gso-2-checksum-fix.patch
net-gso-2-checksum-fix.patch
net-gso-3-fix-errorcheck.patch
net-gso-4-kill-warnon.patch
+net-gso-5-rcv-mss.patch
pci-mmconfig-fix-from-2.6.17.patch
pmd-shared.patch
rcu_needs_cpu.patch
diff -r 11b718eb22c9 -r ebed72718263
patches/linux-2.6.16.29/xenoprof-generic.patch
--- a/patches/linux-2.6.16.29/xenoprof-generic.patch Thu Nov 02 12:43:04
2006 -0700
+++ b/patches/linux-2.6.16.29/xenoprof-generic.patch Fri Nov 10 11:11:04
2006 -0700
@@ -1,6 +1,6 @@ diff -pruN ../orig-linux-2.6.16.29/drive
diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c
./drivers/oprofile/buffer_sync.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c 2006-09-12
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/buffer_sync.c 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c 2006-11-06
14:46:52.000000000 -0800
++++ ./drivers/oprofile/buffer_sync.c 2006-11-06 15:16:52.000000000 -0800
@@ -6,6 +6,10 @@
*
* @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -12,7 +12,27 @@ diff -pruN ../orig-linux-2.6.16.29/drive
* This is the core of the buffer management. Each
* CPU buffer is processed and entered into the
* global event buffer. Such processing is necessary
-@@ -275,15 +279,31 @@ static void add_cpu_switch(int i)
+@@ -38,6 +42,7 @@ static cpumask_t marked_cpus = CPU_MASK_
+ static DEFINE_SPINLOCK(task_mortuary);
+ static void process_task_mortuary(void);
+
++static int cpu_current_domain[NR_CPUS];
+
+ /* Take ownership of the task struct and place it on the
+ * list for processing. Only after two full buffer syncs
+@@ -146,6 +151,11 @@ static void end_sync(void)
+ int sync_start(void)
+ {
+ int err;
++ int i;
++
++ for (i = 0; i < NR_CPUS; i++) {
++ cpu_current_domain[i] = COORDINATOR_DOMAIN;
++ }
+
+ start_cpu_work();
+
+@@ -275,15 +285,31 @@ static void add_cpu_switch(int i)
last_cookie = INVALID_COOKIE;
}
@@ -50,7 +70,7 @@ diff -pruN ../orig-linux-2.6.16.29/drive
static void
add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
{
-@@ -348,9 +368,9 @@ static int add_us_sample(struct mm_struc
+@@ -348,9 +374,9 @@ static int add_us_sample(struct mm_struc
* for later lookup from userspace.
*/
static int
@@ -62,7 +82,7 @@ diff -pruN ../orig-linux-2.6.16.29/drive
add_sample_entry(s->eip, s->event);
return 1;
} else if (mm) {
-@@ -496,10 +516,11 @@ void sync_buffer(int cpu)
+@@ -496,15 +522,21 @@ void sync_buffer(int cpu)
struct mm_struct *mm = NULL;
struct task_struct * new;
unsigned long cookie = 0;
@@ -75,7 +95,17 @@ diff -pruN ../orig-linux-2.6.16.29/drive
down(&buffer_sem);
-@@ -512,16 +533,18 @@ void sync_buffer(int cpu)
+ add_cpu_switch(cpu);
+
++ /* We need to assign the first samples in this CPU buffer to the
++ same domain that we were processing at the last sync_buffer */
++ if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
++ add_domain_switch(cpu_current_domain[cpu]);
++ }
+ /* Remember, only we can modify tail_pos */
+
+ available = get_slots(cpu_buf);
+@@ -512,16 +544,18 @@ void sync_buffer(int cpu)
for (i = 0; i < available; ++i) {
struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
@@ -99,7 +129,7 @@ diff -pruN ../orig-linux-2.6.16.29/drive
} else {
struct mm_struct * oldmm = mm;
-@@ -535,11 +558,16 @@ void sync_buffer(int cpu)
+@@ -535,11 +569,21 @@ void sync_buffer(int cpu)
add_user_ctx_switch(new, cookie);
}
} else {
@@ -109,10 +139,15 @@ diff -pruN ../orig-linux-2.6.16.29/drive
- state = sb_bt_ignore;
-
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
+ if (domain_switch) {
++ cpu_current_domain[cpu] = s->eip;
+ add_domain_switch(s->eip);
+ domain_switch = 0;
+ } else {
-+ if (state >= sb_bt_start &&
++ if (cpu_current_domain[cpu] !=
++ COORDINATOR_DOMAIN) {
++ add_sample_entry(s->eip, s->event);
++ }
++ else if (state >= sb_bt_start &&
+ !add_sample(mm, s, cpu_mode)) {
+ if (state == sb_bt_start) {
+ state = sb_bt_ignore;
@@ -121,9 +156,21 @@ diff -pruN ../orig-linux-2.6.16.29/drive
}
}
}
+@@ -548,6 +592,11 @@ void sync_buffer(int cpu)
+ }
+ release_mm(mm);
+
++ /* We reset domain to COORDINATOR at each CPU switch */
++ if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
++ add_domain_switch(COORDINATOR_DOMAIN);
++ }
++
+ mark_done(cpu);
+
+ up(&buffer_sem);
diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c
./drivers/oprofile/cpu_buffer.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c 2006-09-12
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.c 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c 2006-11-06
14:46:52.000000000 -0800
++++ ./drivers/oprofile/cpu_buffer.c 2006-11-06 14:47:55.000000000 -0800
@@ -6,6 +6,10 @@
*
* @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -233,8 +280,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
* This serves to avoid cpu buffer overflow, and makes sure
* the task mortuary progresses
diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h
./drivers/oprofile/cpu_buffer.h
---- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h 2006-09-12
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.h 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h 2006-11-06
14:46:52.000000000 -0800
++++ ./drivers/oprofile/cpu_buffer.h 2006-11-06 14:47:55.000000000 -0800
@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
volatile unsigned long tail_pos;
unsigned long buffer_size;
@@ -258,8 +305,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
#endif /* OPROFILE_CPU_BUFFER_H */
diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h
./drivers/oprofile/event_buffer.h
---- ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h 2006-09-12
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/event_buffer.h 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h 2006-11-06
14:46:52.000000000 -0800
++++ ./drivers/oprofile/event_buffer.h 2006-11-06 14:47:55.000000000 -0800
@@ -29,15 +29,20 @@ void wake_up_buffer_waiter(void);
#define CPU_SWITCH_CODE 2
#define COOKIE_SWITCH_CODE 3
@@ -283,8 +330,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
void add_event_entry(unsigned long data);
diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c
./drivers/oprofile/oprof.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c 2006-09-12
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/oprof.c 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c 2006-11-06
14:46:52.000000000 -0800
++++ ./drivers/oprofile/oprof.c 2006-11-06 14:47:55.000000000 -0800
@@ -5,6 +5,10 @@
* @remark Read the file COPYING
*
@@ -339,8 +386,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
{
int err;
diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h
./drivers/oprofile/oprof.h
---- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h 2006-09-12
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/oprof.h 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h 2006-11-06
14:46:52.000000000 -0800
++++ ./drivers/oprofile/oprof.h 2006-11-06 14:47:55.000000000 -0800
@@ -35,5 +35,8 @@ void oprofile_create_files(struct super_
void oprofile_timer_init(struct oprofile_operations * ops);
@@ -351,8 +398,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
#endif /* OPROF_H */
diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c
./drivers/oprofile/oprofile_files.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c 2006-09-12
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/oprofile_files.c 2006-09-19 14:06:05.000000000
+0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c 2006-11-06
14:46:52.000000000 -0800
++++ ./drivers/oprofile/oprofile_files.c 2006-11-06 14:47:55.000000000
-0800
@@ -5,15 +5,21 @@
* @remark Read the file COPYING
*
@@ -581,8 +628,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
oprofilefs_create_ulong(sb, root, "buffer_watershed",
&fs_buffer_watershed);
diff -pruN ../orig-linux-2.6.16.29/include/linux/oprofile.h
./include/linux/oprofile.h
---- ../orig-linux-2.6.16.29/include/linux/oprofile.h 2006-09-12
19:02:10.000000000 +0100
-+++ ./include/linux/oprofile.h 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/include/linux/oprofile.h 2006-11-06
14:46:42.000000000 -0800
++++ ./include/linux/oprofile.h 2006-11-06 14:47:55.000000000 -0800
@@ -16,6 +16,8 @@
#include <linux/types.h>
#include <linux/spinlock.h>
diff -r 11b718eb22c9 -r ebed72718263 tools/Makefile
--- a/tools/Makefile Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/Makefile Fri Nov 10 11:11:04 2006 -0700
@@ -18,6 +18,7 @@ SUBDIRS-y += xenstat
SUBDIRS-y += xenstat
SUBDIRS-y += libaio
SUBDIRS-y += blktap
+SUBDIRS-y += libfsimage
# These don't cross-compile
ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
diff -r 11b718eb22c9 -r ebed72718263 tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/blktap/drivers/blktapctrl.c Fri Nov 10 11:11:04 2006 -0700
@@ -607,9 +607,11 @@ int main(int argc, char *argv[])
struct xs_handle *h;
struct pollfd pfd[NUM_POLL_FDS];
pid_t process;
+ char buf[128];
__init_blkif();
- openlog("BLKTAPCTRL", LOG_CONS|LOG_ODELAY, LOG_DAEMON);
+ snprintf(buf, sizeof(buf), "BLKTAPCTRL[%d]", getpid());
+ openlog(buf, LOG_CONS|LOG_ODELAY, LOG_DAEMON);
daemon(0,0);
print_drivers();
diff -r 11b718eb22c9 -r ebed72718263 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/blktap/drivers/tapdisk.c Fri Nov 10 11:11:04 2006 -0700
@@ -381,7 +381,6 @@ static inline int write_rsp_to_ring(stru
rsp_d = RING_GET_RESPONSE(&info->fe_ring, info->fe_ring.rsp_prod_pvt);
memcpy(rsp_d, rsp, sizeof(blkif_response_t));
- wmb();
info->fe_ring.rsp_prod_pvt++;
return 0;
@@ -562,12 +561,14 @@ int main(int argc, char *argv[])
fd_list_entry_t *ptr;
struct tap_disk *drv;
struct td_state *s;
+ char openlogbuf[128];
if (argc != 3) usage();
daemonize();
- openlog("TAPDISK", LOG_CONS|LOG_ODELAY, LOG_DAEMON);
+ snprintf(openlogbuf, sizeof(openlogbuf), "TAPDISK[%d]", getpid());
+ openlog(openlogbuf, LOG_CONS|LOG_ODELAY, LOG_DAEMON);
/*Setup signal handlers*/
signal (SIGBUS, sig_handler);
signal (SIGINT, sig_handler);
diff -r 11b718eb22c9 -r ebed72718263 tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/blktap/drivers/tapdisk.h Fri Nov 10 11:11:04 2006 -0700
@@ -61,7 +61,6 @@
/* Things disks need to know about, these should probably be in a higher-level
* header. */
-#define MAX_REQUESTS 64
#define MAX_SEGMENTS_PER_REQ 11
#define SECTOR_SHIFT 9
#define DEFAULT_SECTOR_SIZE 512
diff -r 11b718eb22c9 -r ebed72718263 tools/blktap/lib/blktaplib.h
--- a/tools/blktap/lib/blktaplib.h Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/blktap/lib/blktaplib.h Fri Nov 10 11:11:04 2006 -0700
@@ -41,7 +41,7 @@
#include <sys/types.h>
#include <unistd.h>
-#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, getpagesize())
+#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, XC_PAGE_SIZE)
/* size of the extra VMA area to map in attached pages. */
#define BLKTAP_VMA_PAGES BLK_RING_SIZE
@@ -74,10 +74,10 @@ static inline int BLKTAP_MODE_VALID(unsi
( arg == BLKTAP_MODE_INTERPOSE ) );
}
-#define MAX_REQUESTS 64
+#define MAX_REQUESTS BLK_RING_SIZE
#define BLKTAP_IOCTL_KICK 1
-#define MAX_PENDING_REQS 64
+#define MAX_PENDING_REQS BLK_RING_SIZE
#define BLKTAP_DEV_DIR "/dev/xen"
#define BLKTAP_DEV_NAME "blktap"
#define BLKTAP_DEV_MINOR 0
@@ -199,7 +199,6 @@ int xs_fire_next_watch(struct xs_handle
/* Abitrary values, must match the underlying driver... */
-#define MAX_PENDING_REQS 64
#define MAX_TAP_DEV 100
/* Accessing attached data page mappings */
diff -r 11b718eb22c9 -r ebed72718263 tools/console/Makefile
--- a/tools/console/Makefile Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/console/Makefile Fri Nov 10 11:11:04 2006 -0700
@@ -5,7 +5,7 @@ DAEMON_INSTALL_DIR = /usr/sbin
DAEMON_INSTALL_DIR = /usr/sbin
CLIENT_INSTALL_DIR = /usr/$(LIBDIR)/xen/bin
-CFLAGS += -Werror -g
+CFLAGS += -Werror
CFLAGS += -I $(XEN_LIBXC)
CFLAGS += -I $(XEN_XENSTORE)
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/blktap
--- a/tools/examples/blktap Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/blktap Fri Nov 10 11:11:04 2006 -0700
@@ -4,12 +4,26 @@
dir=$(dirname "$0")
. "$dir/xen-hotplug-common.sh"
+. "$dir/block-common.sh"
findCommand "$@"
-if [ "$command" == 'add' ]
+t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING')
+if [ -n "$t" ]
then
- success
+ p=$(xenstore_read "$XENBUS_PATH/params")
+ # if we have a ':', chew from head including :
+ if echo $p | grep -q \:
+ then
+ p=${p#*:}
+ fi
+fi
+file=$(readlink -f "$p") || ebusy "$p does not exist."
+
+if [ "$command" = 'add' ]
+then
+ [ -e "$file" ] || { ebusy $file does not exist; }
+ success
fi
exit 0
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/block
--- a/tools/examples/block Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/block Fri Nov 10 11:11:04 2006 -0700
@@ -68,7 +68,7 @@ check_sharing()
local devmm=$(device_major_minor "$dev")
local file
- if [ "$mode" == 'w' ]
+ if [ "$mode" = 'w' ]
then
toskip="^$"
else
@@ -81,7 +81,7 @@ check_sharing()
then
local d=$(device_major_minor "$file")
- if [ "$d" == "$devmm" ]
+ if [ "$d" = "$devmm" ]
then
echo 'local'
return
@@ -96,9 +96,9 @@ check_sharing()
do
d=$(xenstore_read_default "$base_path/$dom/$dev/physical-device" "")
- if [ "$d" == "$devmm" ]
+ if [ "$d" = "$devmm" ]
then
- if [ "$mode" == 'w' ]
+ if [ "$mode" = 'w' ]
then
if ! same_vm $dom
then
@@ -109,7 +109,7 @@ check_sharing()
local m=$(xenstore_read "$base_path/$dom/$dev/mode")
m=$(canonicalise_mode "$m")
- if [ "$m" == 'w' ]
+ if [ "$m" = 'w' ]
then
if ! same_vm $dom
then
@@ -138,7 +138,7 @@ same_vm()
local othervm=$(xenstore_read_default "/local/domain/$otherdom/vm" \
"$FRONTEND_UUID")
- [ "$FRONTEND_UUID" == "$othervm" ]
+ [ "$FRONTEND_UUID" = "$othervm" ]
}
@@ -153,7 +153,7 @@ check_device_sharing()
local mode=$(canonicalise_mode "$2")
local result
- if [ "$mode" == '!' ]
+ if [ "x$mode" = 'x!' ]
then
return 0
fi
@@ -202,7 +202,7 @@ do_ebusy()
local mode="$2"
local result="$3"
- if [ "$result" == 'guest' ]
+ if [ "$result" = 'guest' ]
then
dom='a guest '
when='now'
@@ -211,7 +211,7 @@ do_ebusy()
when='by a guest'
fi
- if [ "$mode" == 'w' ]
+ if [ "$mode" = 'w' ]
then
m1=''
m2=''
@@ -266,7 +266,7 @@ case "$command" in
claim_lock "block"
- if [ "$mode" == 'w' ] && ! stat "$file" -c %A | grep -q w
+ if [ "$mode" = 'w' ] && ! stat "$file" -c %A | grep -q w
then
release_lock "block"
ebusy \
@@ -287,7 +287,7 @@ mount it read-write in a guest domain."
if [ "$f" ]
then
# $dev is in use. Check sharing.
- if [ "$mode" == '!' ]
+ if [ "x$mode" = 'x!' ]
then
continue
fi
@@ -307,7 +307,7 @@ mount it read-write in a guest domain."
do
d=$(xenstore_read_default \
"$XENBUS_BASE_PATH/$dom/$domdev/node" "")
- if [ "$d" == "$dev" ]
+ if [ "$d" = "$dev" ]
then
f=$(xenstore_read "$XENBUS_BASE_PATH/$dom/$domdev/params")
found=1
@@ -347,7 +347,7 @@ mount it read-write in a guest domain."
f=$(readlink -f "$f" || echo $(dirname "$file")/$(basename "$f"))
- if [ "$f" == "$file" ]
+ if [ "$f" = "$file" ]
then
check_file_sharing "$file" "$dev" "$mode"
fi
@@ -355,14 +355,14 @@ mount it read-write in a guest domain."
# $dev is not in use, so we'll remember it for use later; we want
# to finish the sharing check first.
- if [ "$loopdev" == '' ]
+ if [ "$loopdev" = '' ]
then
loopdev="$dev"
fi
fi
done
- if [ "$loopdev" == '' ]
+ if [ "$loopdev" = '' ]
then
fatal 'Failed to find an unused loop device'
fi
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/external-device-migrate
--- a/tools/examples/external-device-migrate Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/external-device-migrate Fri Nov 10 11:11:04 2006 -0700
@@ -55,41 +55,27 @@ function evaluate_params()
{
local step host domname typ recover filename func stype
stype=""
- while [ 1 ]; do
- if [ "$1" == "-step" ]; then
- shift
- step=$1
- elif [ "$1" == "-host" ]; then
- shift
- host=$1
- elif [ "$1" == "-domname" ]; then
- shift
- domname=$1
- elif [ "$1" == "-type" ]; then
- shift
- typ=$1
- elif [ "$1" == "-subtype" ]; then
- shift
- stype="_$1"
- elif [ "$1" == "-recover" ]; then
- recover=1
- elif [ "$1" == "-help" ]; then
- ext_dev_migrate_usage
- exit
- else
- break
- fi
- shift
+ while [ $# -ge 1 ]; do
+ case "$1" in
+ -step) step=$2; shift 2;;
+ -host) host=$2; shift 2;;
+ -domname) domname=$2; shift 2;;
+ -type) type=$2; shift 2;;
+ -subtype) subtype=$2; shift 2;;
+ -recover) recover=1; shift;;
+ -help) ext_dev_migrate_usage; exit 0;;
+ *) break;;
+ esac
done
- if [ "$step" == "" -o \
- "$host" == "" -o \
- "$typ" == "" -o \
- "$domname" == "" ]; then
- echo "Error: Parameter(s) missing (-step/-host/-type/-domname)"
- echo ""
- echo "$0 -help for usage."
- exit
+ if [ "$step" = "" -o \
+ "$host" = "" -o \
+ "$typ" = "" -o \
+ "$domname" = "" ]; then
+ echo "Error: Parameter(s) missing (-step/-host/-type/-domname)"
1>&2
+ echo "" 1>&2
+ echo "$0 -help for usage." 1>&2
+ exit 1
fi
filename="$dir/$typ$stype-migration.sh"
@@ -99,7 +85,7 @@ function evaluate_params()
fi
. "$filename"
- if [ "$recover" == "1" ]; then
+ if [ "$recover" = "1" ]; then
func="$typ"_recover
eval $func $host $domname $step $*
else
@@ -108,4 +94,4 @@ function evaluate_params()
fi
}
-evaluate_params $*
+evaluate_params "$@"
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/vif-bridge
--- a/tools/examples/vif-bridge Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/vif-bridge Fri Nov 10 11:11:04 2006 -0700
@@ -61,7 +61,7 @@ handle_iptable
handle_iptable
log debug "Successful vif-bridge $command for $vif, bridge $bridge."
-if [ "$command" == "online" ]
+if [ "$command" = "online" ]
then
success
fi
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/vif-nat
--- a/tools/examples/vif-nat Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/vif-nat Fri Nov 10 11:11:04 2006 -0700
@@ -72,7 +72,7 @@ dotted_quad()
}
-if [ "$ip" == "" ]
+if [ "$ip" = "" ]
then
ip=$(ip_from_dom)
fi
@@ -152,7 +152,7 @@ handle_iptable
handle_iptable
log debug "Successful vif-nat $command for $vif."
-if [ "$command" == "online" ]
+if [ "$command" = "online" ]
then
success
fi
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/vif-route
--- a/tools/examples/vif-route Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/vif-route Fri Nov 10 11:11:04 2006 -0700
@@ -50,7 +50,7 @@ handle_iptable
handle_iptable
log debug "Successful vif-route $command for $vif."
-if [ "$command" == "online" ]
+if [ "$command" = "online" ]
then
success
fi
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/xend-config.sxp Fri Nov 10 11:11:04 2006 -0700
@@ -51,7 +51,7 @@
# regular expressions will be accepted.
#
# For example:
-# (xend-relocation-hosts-allow '^localhost$ ^.*\.example\.org$')
+# (xend-relocation-hosts-allow '^localhost$ ^.*\\.example\\.org$')
#
#(xend-relocation-hosts-allow '')
(xend-relocation-hosts-allow '^localhost$ ^localhost\\.localdomain$')
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/xmexample.hvm Fri Nov 10 11:11:04 2006 -0700
@@ -47,9 +47,6 @@ name = "ExampleHVMDomain"
# enable/disable HVM guest ACPI, default=0 (disabled)
#acpi=0
-
-# enable/disable HVM guest APIC, default=0 (disabled)
-#apic=0
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/Makefile
--- a/tools/firmware/Makefile Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/Makefile Fri Nov 10 11:11:04 2006 -0700
@@ -9,7 +9,6 @@ SUBDIRS :=
SUBDIRS :=
SUBDIRS += rombios
SUBDIRS += vgabios
-SUBDIRS += acpi
SUBDIRS += vmxassist
SUBDIRS += hvmloader
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/hvmloader/Makefile Fri Nov 10 11:11:04 2006 -0700
@@ -40,11 +40,14 @@ CFLAGS += $(DEFINES) -I. $(XENINC) -fno
CFLAGS += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float
LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR)
-SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c smbios.c
+SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c smbios.c acpi_utils.c
OBJS = $(patsubst %.c,%.o,$(SRCS))
.PHONY: all
all: hvmloader
+
+acpi/acpi.bin:
+ $(MAKE) -C acpi
hvmloader: roms.h $(SRCS)
$(CC) $(CFLAGS) -c $(SRCS)
@@ -52,15 +55,15 @@ hvmloader: roms.h $(SRCS)
$(OBJCOPY) hvmloader.tmp hvmloader
rm -f hvmloader.tmp
-roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
../acpi/acpi.bin
+roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
acpi/acpi.bin
sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin
>> roms.h
sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
- sh ./mkhex acpi ../acpi/acpi.bin >> roms.h
+ sh ./mkhex acpi acpi/acpi.bin >> roms.h
.PHONY: clean
clean:
rm -f roms.h acpi.h
rm -f hvmloader hvmloader.tmp hvmloader.o $(OBJS)
-
+ $(MAKE) -C acpi clean
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/hvmloader/acpi_madt.c
--- a/tools/firmware/hvmloader/acpi_madt.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/hvmloader/acpi_madt.c Fri Nov 10 11:11:04 2006 -0700
@@ -18,9 +18,9 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "../acpi/acpi2_0.h"
-#include "../acpi/acpi_madt.h"
+#include "acpi/acpi2_0.h"
#include "util.h"
+#include "acpi_utils.h"
#include <xen/hvm/hvm_info_table.h>
#define NULL ((void*)0)
@@ -29,160 +29,134 @@ static struct hvm_info_table *table = NU
static int validate_hvm_info(struct hvm_info_table *t)
{
- char signature[] = "HVM INFO";
- uint8_t *ptr = (uint8_t *)t;
- uint8_t sum = 0;
- int i;
+ char signature[] = "HVM INFO";
+ uint8_t *ptr = (uint8_t *)t;
+ uint8_t sum = 0;
+ int i;
- /* strncmp(t->signature, "HVM INFO", 8) */
- for (i = 0; i < 8; i++) {
- if (signature[i] != t->signature[i]) {
- puts("Bad hvm info signature\n");
- return 0;
- }
- }
+ /* strncmp(t->signature, "HVM INFO", 8) */
+ for (i = 0; i < 8; i++) {
+ if (signature[i] != t->signature[i]) {
+ puts("Bad hvm info signature\n");
+ return 0;
+ }
+ }
- for (i = 0; i < t->length; i++)
- sum += ptr[i];
+ for (i = 0; i < t->length; i++)
+ sum += ptr[i];
- return (sum == 0);
+ return (sum == 0);
}
/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
struct hvm_info_table *
get_hvm_info_table(void)
{
- struct hvm_info_table *t;
+ struct hvm_info_table *t;
- if (table != NULL)
- return table;
+ if (table != NULL)
+ return table;
- t = (struct hvm_info_table *)HVM_INFO_PADDR;
+ t = (struct hvm_info_table *)HVM_INFO_PADDR;
- if (!validate_hvm_info(t)) {
- puts("Bad hvm info table\n");
- return NULL;
- }
+ if (!validate_hvm_info(t)) {
+ puts("Bad hvm info table\n");
+ return NULL;
+ }
- table = t;
+ table = t;
- return table;
+ return table;
}
int
get_vcpu_nr(void)
{
- struct hvm_info_table *t = get_hvm_info_table();
- return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
+ struct hvm_info_table *t = get_hvm_info_table();
+ return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
}
int
get_acpi_enabled(void)
{
- struct hvm_info_table *t = get_hvm_info_table();
- return (t ? t->acpi_enabled : 0); /* default no acpi */
+ struct hvm_info_table *t = get_hvm_info_table();
+ return (t ? t->acpi_enabled : 0); /* default no acpi */
}
static void *
acpi_madt_get_madt(unsigned char *acpi_start)
{
- ACPI_2_0_RSDP *rsdp=NULL;
- ACPI_2_0_RSDT *rsdt=NULL;
- ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
+ struct acpi_20_rsdt *rsdt;
+ struct acpi_20_madt *madt;
- rsdp = (ACPI_2_0_RSDP *)(acpi_start + sizeof(ACPI_2_0_FACS));
- if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE) {
- puts("Bad RSDP signature\n");
- return NULL;
- }
+ rsdt = acpi_rsdt_get(acpi_start);
+ if (rsdt == NULL)
+ return NULL;
- rsdt= (ACPI_2_0_RSDT *)
- (acpi_start + rsdp->RsdtAddress - ACPI_PHYSICAL_ADDRESS);
- if (rsdt->Header.Signature != ACPI_2_0_RSDT_SIGNATURE) {
- puts("Bad RSDT signature\n");
- return NULL;
- }
+ madt = (struct acpi_20_madt *)(acpi_start + rsdt->entry[1] -
+ ACPI_PHYSICAL_ADDRESS);
+ if (madt->header.header.signature != ACPI_2_0_MADT_SIGNATURE) {
+ puts("Bad MADT signature \n");
+ return NULL;
+ }
- madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *)
- ( acpi_start+ rsdt->Entry[1] - ACPI_PHYSICAL_ADDRESS);
- if (madt->Header.Header.Signature !=
- ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
- puts("Bad MADT signature \n");
- return NULL;
- }
-
- return madt;
-}
-
-static void
-set_checksum(void *start, int checksum_offset, int len)
-{
- unsigned char sum = 0;
- unsigned char *ptr;
-
- ptr = start;
- ptr[checksum_offset] = 0;
- while (len--)
- sum += *ptr++;
-
- ptr = start;
- ptr[checksum_offset] = -sum;
+ return madt;
}
static int
acpi_madt_set_local_apics(
- int nr_vcpu,
- ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
+ int nr_vcpu,
+ struct acpi_20_madt *madt)
{
- int i;
+ int i;
- if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
- return -1;
+ if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
+ return -1;
- for (i = 0; i < nr_vcpu; i++) {
- madt->LocalApic[i].Type = ACPI_PROCESSOR_LOCAL_APIC;
- madt->LocalApic[i].Length = sizeof
(ACPI_LOCAL_APIC_STRUCTURE);
- madt->LocalApic[i].AcpiProcessorId = i;
- madt->LocalApic[i].ApicId = i;
- madt->LocalApic[i].Flags = 1;
- }
+ for (i = 0; i < nr_vcpu; i++) {
+ madt->lapic[i].type = ACPI_PROCESSOR_LOCAL_APIC;
+ madt->lapic[i].length = sizeof(struct acpi_20_madt_lapic);
+ madt->lapic[i].acpi_processor_id = i;
+ madt->lapic[i].apic_id = i;
+ madt->lapic[i].flags = 1;
+ }
- madt->Header.Header.Length =
- sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
- (MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
+ madt->header.header.length =
+ sizeof(struct acpi_20_madt) -
+ (MAX_VIRT_CPUS - nr_vcpu) * sizeof(struct acpi_20_madt_lapic);
- return 0;
+ return 0;
}
#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
int acpi_madt_update(unsigned char *acpi_start)
{
- int rc;
- ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
+ int rc;
+ struct acpi_20_madt *madt;
- madt = acpi_madt_get_madt(acpi_start);
- if (!madt)
- return -1;
+ madt = acpi_madt_get_madt(acpi_start);
+ if (!madt)
+ return -1;
- rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
- if (rc != 0)
- return rc;
+ rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
+ if (rc != 0)
+ return rc;
- set_checksum(
- madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
- madt->Header.Header.Length);
+ set_checksum(
+ madt, FIELD_OFFSET(struct acpi_header, checksum),
+ madt->header.header.length);
- return 0;
+ return 0;
}
/*
* Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
* End:
*/
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/hvmloader/hvmloader.c Fri Nov 10 11:11:04 2006 -0700
@@ -22,9 +22,10 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
#include "roms.h"
-#include "../acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */
+#include "acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */
#include "hypercall.h"
#include "util.h"
+#include "acpi_utils.h"
#include "smbios.h"
#include <xen/version.h>
#include <xen/hvm/params.h>
@@ -164,8 +165,6 @@ int
int
main(void)
{
- struct xen_hvm_param hvm_param;
-
puts("HVM Loader\n");
init_hypercalls();
@@ -176,10 +175,7 @@ main(void)
puts("Loading ROMBIOS ...\n");
memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
- hvm_param.domid = DOMID_SELF;
- hvm_param.index = HVM_PARAM_APIC_ENABLED;
- if (!hypercall_hvm_op(HVMOP_get_param, &hvm_param) && hvm_param.value)
- create_mp_tables();
+ create_mp_tables();
if (cirrus_check()) {
puts("Loading Cirrus VGABIOS ...\n");
@@ -195,12 +191,18 @@ main(void)
puts("Loading ACPI ...\n");
acpi_madt_update((unsigned char *) acpi);
if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
+ unsigned char *freemem = (unsigned char *)
+ (ACPI_PHYSICAL_ADDRESS + sizeof(acpi));
/*
* Make sure acpi table does not overlap rombios
* currently acpi less than 8K will be OK.
*/
memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi,
sizeof(acpi));
+ acpi_update((unsigned char *)ACPI_PHYSICAL_ADDRESS,
+ sizeof(acpi),
+ (unsigned char *)0xF0000,
+ &freemem);
}
}
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/hvmloader/util.c Fri Nov 10 11:11:04 2006 -0700
@@ -18,7 +18,7 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "../acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */
+#include "acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */
#include "util.h"
#include <stdint.h>
@@ -227,4 +227,5 @@ uuid_to_string(char *dest, uint8_t *uuid
byte_to_hex(p, uuid[i]);
p += 2;
}
-}
+ *p = 0;
+}
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/vmxassist/setup.c Fri Nov 10 11:11:04 2006 -0700
@@ -53,13 +53,10 @@ struct e820entry e820map[] = {
struct e820entry e820map[] = {
{ 0x0000000000000000ULL, 0x000000000009F800ULL, E820_RAM },
{ 0x000000000009F800ULL, 0x0000000000000800ULL, E820_RESERVED },
- { 0x00000000000A0000ULL, 0x0000000000020000ULL, E820_IO },
{ 0x00000000000C0000ULL, 0x0000000000040000ULL, E820_RESERVED },
{ 0x0000000000100000ULL, 0x0000000000000000ULL, E820_RAM },
- { 0x0000000000000000ULL, 0x0000000000001000ULL, E820_SHARED_PAGE },
{ 0x0000000000000000ULL, 0x0000000000003000ULL, E820_NVS },
{ 0x0000000000003000ULL, 0x000000000000A000ULL, E820_ACPI },
- { 0x00000000FEC00000ULL, 0x0000000001400000ULL, E820_IO },
};
#endif /* TEST */
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/vmxassist/vm86.c Fri Nov 10 11:11:04 2006 -0700
@@ -867,6 +867,18 @@ load_seg(unsigned long sel, uint32_t *ba
}
/*
+ * Emulate a protected mode segment load, falling back to clearing it if
+ * the descriptor was invalid.
+ */
+static void
+load_or_clear_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union
vmcs_arbytes *arbytes)
+{
+ if (!load_seg(sel, base, limit, arbytes))
+ load_seg(0, base, limit, arbytes);
+}
+
+
+/*
* Transition to protected mode
*/
static void
@@ -877,8 +889,6 @@ protected_mode(struct regs *regs)
oldctx.eip = regs->eip;
oldctx.esp = regs->uesp;
oldctx.eflags = regs->eflags;
-
- memset(&saved_rm_regs, 0, sizeof(struct regs));
/* reload all segment registers */
if (!load_seg(regs->cs, &oldctx.cs_base,
@@ -886,55 +896,16 @@ protected_mode(struct regs *regs)
panic("Invalid %%cs=0x%x for protected mode\n", regs->cs);
oldctx.cs_sel = regs->cs;
- if (load_seg(regs->ves, &oldctx.es_base,
- &oldctx.es_limit, &oldctx.es_arbytes))
- oldctx.es_sel = regs->ves;
- else {
- load_seg(0, &oldctx.es_base,
- &oldctx.es_limit, &oldctx.es_arbytes);
- oldctx.es_sel = 0;
- saved_rm_regs.ves = regs->ves;
- }
-
- if (load_seg(regs->uss, &oldctx.ss_base,
- &oldctx.ss_limit, &oldctx.ss_arbytes))
- oldctx.ss_sel = regs->uss;
- else {
- load_seg(0, &oldctx.ss_base,
- &oldctx.ss_limit, &oldctx.ss_arbytes);
- oldctx.ss_sel = 0;
- saved_rm_regs.uss = regs->uss;
- }
-
- if (load_seg(regs->vds, &oldctx.ds_base,
- &oldctx.ds_limit, &oldctx.ds_arbytes))
- oldctx.ds_sel = regs->vds;
- else {
- load_seg(0, &oldctx.ds_base,
- &oldctx.ds_limit, &oldctx.ds_arbytes);
- oldctx.ds_sel = 0;
- saved_rm_regs.vds = regs->vds;
- }
-
- if (load_seg(regs->vfs, &oldctx.fs_base,
- &oldctx.fs_limit, &oldctx.fs_arbytes))
- oldctx.fs_sel = regs->vfs;
- else {
- load_seg(0, &oldctx.fs_base,
- &oldctx.fs_limit, &oldctx.fs_arbytes);
- oldctx.fs_sel = 0;
- saved_rm_regs.vfs = regs->vfs;
- }
-
- if (load_seg(regs->vgs, &oldctx.gs_base,
- &oldctx.gs_limit, &oldctx.gs_arbytes))
- oldctx.gs_sel = regs->vgs;
- else {
- load_seg(0, &oldctx.gs_base,
- &oldctx.gs_limit, &oldctx.gs_arbytes);
- oldctx.gs_sel = 0;
- saved_rm_regs.vgs = regs->vgs;
- }
+ load_or_clear_seg(oldctx.es_sel, &oldctx.es_base,
+ &oldctx.es_limit, &oldctx.es_arbytes);
+ load_or_clear_seg(oldctx.ss_sel, &oldctx.ss_base,
+ &oldctx.ss_limit, &oldctx.ss_arbytes);
+ load_or_clear_seg(oldctx.ds_sel, &oldctx.ds_base,
+ &oldctx.ds_limit, &oldctx.ds_arbytes);
+ load_or_clear_seg(oldctx.fs_sel, &oldctx.fs_base,
+ &oldctx.fs_limit, &oldctx.fs_arbytes);
+ load_or_clear_seg(oldctx.gs_sel, &oldctx.gs_base,
+ &oldctx.gs_limit, &oldctx.gs_arbytes);
/* initialize jump environment to warp back to protected mode */
regs->cs = CODE_SELECTOR;
@@ -1022,6 +993,16 @@ set_mode(struct regs *regs, enum vm86_mo
case VM86_REAL_TO_PROTECTED:
if (mode == VM86_REAL) {
regs->eflags |= EFLAGS_TF;
+ saved_rm_regs.vds = regs->vds;
+ saved_rm_regs.ves = regs->ves;
+ saved_rm_regs.vfs = regs->vfs;
+ saved_rm_regs.vgs = regs->vgs;
+ saved_rm_regs.uss = regs->uss;
+ oldctx.ds_sel = 0;
+ oldctx.es_sel = 0;
+ oldctx.fs_sel = 0;
+ oldctx.gs_sel = 0;
+ oldctx.ss_sel = 0;
break;
} else if (mode == VM86_REAL_TO_PROTECTED) {
break;
@@ -1282,6 +1263,10 @@ opcode(struct regs *regs)
else
regs->ves = pop16(regs);
TRACE((regs, regs->eip - eip, "pop %%es"));
+ if (mode == VM86_REAL_TO_PROTECTED) {
+ saved_rm_regs.ves = 0;
+ oldctx.es_sel = regs->ves;
+ }
return OPC_EMULATED;
case 0x0F: /* two byte opcode */
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/Makefile.target Fri Nov 10 11:11:04 2006 -0700
@@ -368,6 +368,7 @@ VL_OBJS+= piix4acpi.o
VL_OBJS+= piix4acpi.o
VL_OBJS+= xenstore.o
VL_OBJS+= xen_platform.o
+VL_OBJS+= tpm_tis.o
DEFINES += -DHAS_AUDIO
endif
ifeq ($(TARGET_BASE_ARCH), ppc)
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/hw/ne2000.c
--- a/tools/ioemu/hw/ne2000.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/hw/ne2000.c Fri Nov 10 11:11:04 2006 -0700
@@ -137,6 +137,7 @@ typedef struct NE2000State {
uint8_t curpag;
uint8_t mult[8]; /* multicast mask array */
int irq;
+ int tainted;
PCIDevice *pci_dev;
VLANClientState *vc;
uint8_t macaddr[6];
@@ -226,6 +227,27 @@ static int ne2000_can_receive(void *opaq
#define MIN_BUF_SIZE 60
+static inline int ne2000_valid_ring_addr(NE2000State *s, unsigned int addr)
+{
+ addr <<= 8;
+ return addr < s->stop && addr >= s->start;
+}
+
+static inline int ne2000_check_state(NE2000State *s)
+{
+ if (!s->tainted)
+ return 0;
+
+ if (s->start >= s->stop || s->stop > NE2000_MEM_SIZE)
+ return -EINVAL;
+
+ if (!ne2000_valid_ring_addr(s, s->curpag))
+ return -EINVAL;
+
+ s->tainted = 0;
+ return 0;
+}
+
static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
{
NE2000State *s = opaque;
@@ -238,6 +260,12 @@ static void ne2000_receive(void *opaque,
#if defined(DEBUG_NE2000)
printf("NE2000: received len=%d\n", size);
#endif
+
+ if (ne2000_check_state(s))
+ return;
+
+ if (!ne2000_valid_ring_addr(s, s->boundary))
+ return;
if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
return;
@@ -359,9 +387,11 @@ static void ne2000_ioport_write(void *op
switch(offset) {
case EN0_STARTPG:
s->start = val << 8;
+ s->tainted = 1;
break;
case EN0_STOPPG:
s->stop = val << 8;
+ s->tainted = 1;
break;
case EN0_BOUNDARY:
s->boundary = val;
@@ -406,6 +436,7 @@ static void ne2000_ioport_write(void *op
break;
case EN1_CURPAG:
s->curpag = val;
+ s->tainted = 1;
break;
case EN1_MULT ... EN1_MULT + 7:
s->mult[offset - EN1_MULT] = val;
@@ -509,7 +540,7 @@ static inline void ne2000_mem_writel(NE2
{
addr &= ~1; /* XXX: check exact behaviour if not even */
if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+ (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
}
}
@@ -539,7 +570,7 @@ static inline uint32_t ne2000_mem_readl(
{
addr &= ~1; /* XXX: check exact behaviour if not even */
if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+ (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
return le32_to_cpupu((uint32_t *)(s->mem + addr));
} else {
return 0xffffffff;
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/hw/pc.c Fri Nov 10 11:11:04 2006 -0700
@@ -875,6 +875,9 @@ static void pc_init1(uint64_t ram_size,
}
}
+ if (has_tpm_device())
+ tpm_tis_init(&pic_set_irq_new, isa_pic, 11);
+
kbd_init();
DMA_init(0);
#ifdef HAS_AUDIO
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/hw/serial.c
--- a/tools/ioemu/hw/serial.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/hw/serial.c Fri Nov 10 11:11:04 2006 -0700
@@ -93,6 +93,15 @@ struct SerialState {
int last_break_enable;
target_ulong base;
int it_shift;
+
+ /*
+ * If a character transmitted via UART cannot be written to its
+ * destination immediately we remember it here and retry a few times via
+ * a polling timer.
+ */
+ int write_retries;
+ char write_chr;
+ QEMUTimer *write_retry_timer;
};
static void serial_update_irq(SerialState *s)
@@ -204,10 +213,32 @@ static void serial_get_token(void)
tokens_avail--;
}
+static void serial_chr_write(void *opaque)
+{
+ SerialState *s = opaque;
+
+ qemu_del_timer(s->write_retry_timer);
+
+ /* Retry every 100ms for 300ms total. */
+ if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {
+ if (s->write_retries++ >= 3)
+ printf("serial: write error\n");
+ else
+ qemu_mod_timer(s->write_retry_timer,
+ qemu_get_clock(vm_clock) + ticks_per_sec / 10);
+ return;
+ }
+
+ /* Success: Notify guest that THR is empty. */
+ s->thr_ipending = 1;
+ s->lsr |= UART_LSR_THRE;
+ s->lsr |= UART_LSR_TEMT;
+ serial_update_irq(s);
+}
+
static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
SerialState *s = opaque;
- unsigned char ch;
addr &= 7;
#ifdef DEBUG_SERIAL
@@ -223,12 +254,9 @@ static void serial_ioport_write(void *op
s->thr_ipending = 0;
s->lsr &= ~UART_LSR_THRE;
serial_update_irq(s);
- ch = val;
- qemu_chr_write(s->chr, &ch, 1);
- s->thr_ipending = 1;
- s->lsr |= UART_LSR_THRE;
- s->lsr |= UART_LSR_TEMT;
- serial_update_irq(s);
+ s->write_chr = val;
+ s->write_retries = 0;
+ serial_chr_write(s);
}
break;
case 1:
@@ -424,6 +452,7 @@ SerialState *serial_init(SetIRQFunc *set
s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
s->iir = UART_IIR_NO_INT;
s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
+ s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
register_savevm("serial", base, 1, serial_save, serial_load, s);
@@ -511,6 +540,7 @@ SerialState *serial_mm_init (SetIRQFunc
s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
s->base = base;
s->it_shift = it_shift;
+ s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
register_savevm("serial", base, 1, serial_save, serial_load, s);
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/keymaps/ja
--- a/tools/ioemu/keymaps/ja Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/keymaps/ja Fri Nov 10 11:11:04 2006 -0700
@@ -102,3 +102,6 @@ Henkan_Mode 0x79
Henkan_Mode 0x79
Katakana 0x70
Muhenkan 0x7b
+Henkan_Mode_Real 0x79
+Henkan_Mode_Ultra 0x79
+backslash_ja 0x73
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/cpu.h
--- a/tools/ioemu/target-i386-dm/cpu.h Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/cpu.h Fri Nov 10 11:11:04 2006 -0700
@@ -55,8 +55,6 @@ typedef struct CPUX86State {
int interrupt_request;
CPU_COMMON
-
- int send_event;
} CPUX86State;
CPUX86State *cpu_x86_init(void);
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/exec-dm.c
--- a/tools/ioemu/target-i386-dm/exec-dm.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/exec-dm.c Fri Nov 10 11:11:04 2006 -0700
@@ -32,6 +32,8 @@
#include <unistd.h>
#include <inttypes.h>
+#include <xen/hvm/e820.h>
+
#include "cpu.h"
#include "exec-all.h"
@@ -407,22 +409,36 @@ int iomem_index(target_phys_addr_t addr)
return 0;
}
+static inline int paddr_is_ram(target_phys_addr_t addr)
+{
+ /* Is this guest physical address RAM-backed? */
+#if defined(CONFIG_DM) && (defined(__i386__) || defined(__x86_64__))
+ if (ram_size <= HVM_BELOW_4G_RAM_END)
+ /* RAM is contiguous */
+ return (addr < ram_size);
+ else
+ /* There is RAM below and above the MMIO hole */
+ return ((addr < HVM_BELOW_4G_MMIO_START) ||
+ ((addr >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH)
+ && (addr < ram_size + HVM_BELOW_4G_MMIO_LENGTH)));
+#else
+ return (addr < ram_size);
+#endif
+}
+
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write)
{
int l, io_index;
uint8_t *ptr;
uint32_t val;
- target_phys_addr_t page;
- unsigned long pd;
while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
+ /* How much can we copy before the next page boundary? */
+ l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);
if (l > len)
l = len;
- pd = page;
io_index = iomem_index(addr);
if (is_write) {
if (io_index) {
@@ -442,15 +458,11 @@ void cpu_physical_memory_rw(target_phys_
io_mem_write[io_index][0](io_mem_opaque[io_index], addr,
val);
l = 1;
}
- } else {
- unsigned long addr1;
-
- addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
- /* RAM case */
- ptr = phys_ram_base + addr1;
- memcpy(ptr, buf, l);
+ } else if (paddr_is_ram(addr)) {
+ /* Reading from RAM */
+ memcpy(phys_ram_base + addr, buf, l);
#ifdef __ia64__
- sync_icache((unsigned long)ptr, l);
+ sync_icache((unsigned long)(phys_ram_base + addr), l);
#endif
}
} else {
@@ -471,14 +483,12 @@ void cpu_physical_memory_rw(target_phys_
stb_raw(buf, val);
l = 1;
}
- } else if (addr < ram_size) {
- /* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- memcpy(buf, ptr, l);
+ } else if (paddr_is_ram(addr)) {
+ /* Reading from RAM */
+ memcpy(buf, phys_ram_base + addr, l);
} else {
- /* unreported MMIO space */
- memset(buf, 0xff, len);
+ /* Neither RAM nor known MMIO space */
+ memset(buf, 0xff, len);
}
}
len -= l;
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/helper2.c Fri Nov 10 11:11:04 2006 -0700
@@ -193,10 +193,10 @@ void sp_info()
for (i = 0; i < vcpus; i++) {
req = &(shared_page->vcpu_iodata[i].vp_ioreq);
term_printf("vcpu %d: event port %d\n", i, ioreq_local_port[i]);
- term_printf(" req state: %x, pvalid: %x, addr: %"PRIx64", "
+ term_printf(" req state: %x, ptr: %x, addr: %"PRIx64", "
"data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
- req->state, req->pdata_valid, req->addr,
- req->u.data, req->count, req->size);
+ req->state, req->data_is_ptr, req->addr,
+ req->data, req->count, req->size);
term_printf(" IO totally occurred on this vcpu: %"PRIx64"\n",
req->io_count);
}
@@ -209,18 +209,19 @@ static ioreq_t *__cpu_get_ioreq(int vcpu
req = &(shared_page->vcpu_iodata[vcpu].vp_ioreq);
- if (req->state == STATE_IOREQ_READY) {
- req->state = STATE_IOREQ_INPROCESS;
- rmb();
- return req;
- }
-
- fprintf(logfile, "False I/O request ... in-service already: "
- "%x, pvalid: %x, port: %"PRIx64", "
- "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
- req->state, req->pdata_valid, req->addr,
- req->u.data, req->count, req->size);
- return NULL;
+ if (req->state != STATE_IOREQ_READY) {
+ fprintf(logfile, "I/O request not ready: "
+ "%x, ptr: %x, port: %"PRIx64", "
+ "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
+ req->state, req->data_is_ptr, req->addr,
+ req->data, req->count, req->size);
+ return NULL;
+ }
+
+ rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
+
+ req->state = STATE_IOREQ_INPROCESS;
+ return req;
}
//use poll to get the port notification
@@ -305,26 +306,26 @@ void cpu_ioreq_pio(CPUState *env, ioreq_
sign = req->df ? -1 : 1;
if (req->dir == IOREQ_READ) {
- if (!req->pdata_valid) {
- req->u.data = do_inp(env, req->addr, req->size);
+ if (!req->data_is_ptr) {
+ req->data = do_inp(env, req->addr, req->size);
} else {
unsigned long tmp;
for (i = 0; i < req->count; i++) {
tmp = do_inp(env, req->addr, req->size);
- write_physical((target_phys_addr_t) req->u.pdata
+ write_physical((target_phys_addr_t) req->data
+ (sign * i * req->size),
req->size, &tmp);
}
}
} else if (req->dir == IOREQ_WRITE) {
- if (!req->pdata_valid) {
- do_outp(env, req->addr, req->size, req->u.data);
+ if (!req->data_is_ptr) {
+ do_outp(env, req->addr, req->size, req->data);
} else {
for (i = 0; i < req->count; i++) {
unsigned long tmp;
- read_physical((target_phys_addr_t) req->u.pdata
+ read_physical((target_phys_addr_t) req->data
+ (sign * i * req->size),
req->size, &tmp);
do_outp(env, req->addr, req->size, tmp);
@@ -339,18 +340,18 @@ void cpu_ioreq_move(CPUState *env, ioreq
sign = req->df ? -1 : 1;
- if (!req->pdata_valid) {
+ if (!req->data_is_ptr) {
if (req->dir == IOREQ_READ) {
for (i = 0; i < req->count; i++) {
read_physical(req->addr
+ (sign * i * req->size),
- req->size, &req->u.data);
+ req->size, &req->data);
}
} else if (req->dir == IOREQ_WRITE) {
for (i = 0; i < req->count; i++) {
write_physical(req->addr
+ (sign * i * req->size),
- req->size, &req->u.data);
+ req->size, &req->data);
}
}
} else {
@@ -361,13 +362,13 @@ void cpu_ioreq_move(CPUState *env, ioreq
read_physical(req->addr
+ (sign * i * req->size),
req->size, &tmp);
- write_physical((target_phys_addr_t )req->u.pdata
+ write_physical((target_phys_addr_t )req->data
+ (sign * i * req->size),
req->size, &tmp);
}
} else if (req->dir == IOREQ_WRITE) {
for (i = 0; i < req->count; i++) {
- read_physical((target_phys_addr_t) req->u.pdata
+ read_physical((target_phys_addr_t) req->data
+ (sign * i * req->size),
req->size, &tmp);
write_physical(req->addr
@@ -382,51 +383,66 @@ void cpu_ioreq_and(CPUState *env, ioreq_
{
unsigned long tmp1, tmp2;
- if (req->pdata_valid != 0)
+ if (req->data_is_ptr != 0)
hw_error("expected scalar value");
read_physical(req->addr, req->size, &tmp1);
if (req->dir == IOREQ_WRITE) {
- tmp2 = tmp1 & (unsigned long) req->u.data;
+ tmp2 = tmp1 & (unsigned long) req->data;
write_physical(req->addr, req->size, &tmp2);
}
- req->u.data = tmp1;
-}
-
-void cpu_ioreq_or(CPUState *env, ioreq_t *req)
+ req->data = tmp1;
+}
+
+void cpu_ioreq_add(CPUState *env, ioreq_t *req)
{
unsigned long tmp1, tmp2;
- if (req->pdata_valid != 0)
+ if (req->data_is_ptr != 0)
hw_error("expected scalar value");
read_physical(req->addr, req->size, &tmp1);
if (req->dir == IOREQ_WRITE) {
- tmp2 = tmp1 | (unsigned long) req->u.data;
+ tmp2 = tmp1 + (unsigned long) req->data;
write_physical(req->addr, req->size, &tmp2);
}
- req->u.data = tmp1;
-}
-
-void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
+ req->data = tmp1;
+}
+
+void cpu_ioreq_or(CPUState *env, ioreq_t *req)
{
unsigned long tmp1, tmp2;
- if (req->pdata_valid != 0)
+ if (req->data_is_ptr != 0)
hw_error("expected scalar value");
read_physical(req->addr, req->size, &tmp1);
if (req->dir == IOREQ_WRITE) {
- tmp2 = tmp1 ^ (unsigned long) req->u.data;
+ tmp2 = tmp1 | (unsigned long) req->data;
write_physical(req->addr, req->size, &tmp2);
}
- req->u.data = tmp1;
+ req->data = tmp1;
+}
+
+void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
+{
+ unsigned long tmp1, tmp2;
+
+ if (req->data_is_ptr != 0)
+ hw_error("expected scalar value");
+
+ read_physical(req->addr, req->size, &tmp1);
+ if (req->dir == IOREQ_WRITE) {
+ tmp2 = tmp1 ^ (unsigned long) req->data;
+ write_physical(req->addr, req->size, &tmp2);
+ }
+ req->data = tmp1;
}
void __handle_ioreq(CPUState *env, ioreq_t *req)
{
- if (!req->pdata_valid && req->dir == IOREQ_WRITE && req->size != 4)
- req->u.data &= (1UL << (8 * req->size)) - 1;
+ if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4)
+ req->data &= (1UL << (8 * req->size)) - 1;
switch (req->type) {
case IOREQ_TYPE_PIO:
@@ -437,6 +453,9 @@ void __handle_ioreq(CPUState *env, ioreq
break;
case IOREQ_TYPE_AND:
cpu_ioreq_and(env, req);
+ break;
+ case IOREQ_TYPE_ADD:
+ cpu_ioreq_add(env, req);
break;
case IOREQ_TYPE_OR:
cpu_ioreq_or(env, req);
@@ -486,12 +505,19 @@ void cpu_handle_ioreq(void *opaque)
if (req) {
__handle_ioreq(env, req);
- /* No state change if state = STATE_IORESP_HOOK */
- if (req->state == STATE_IOREQ_INPROCESS) {
- mb();
- req->state = STATE_IORESP_READY;
- }
- env->send_event = 1;
+ if (req->state != STATE_IOREQ_INPROCESS) {
+ fprintf(logfile, "Badness in I/O request ... not in service?!: "
+ "%x, ptr: %x, port: %"PRIx64", "
+ "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
+ req->state, req->data_is_ptr, req->addr,
+ req->data, req->count, req->size);
+ destroy_hvm_domain();
+ return;
+ }
+
+ wmb(); /* Update ioreq contents /then/ update state. */
+ req->state = STATE_IORESP_READY;
+ xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
}
}
@@ -507,8 +533,6 @@ int main_loop(void)
qemu_mod_timer(buffered_io_timer, qemu_get_clock(rt_clock));
qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
-
- env->send_event = 0;
while (1) {
if (vm_running) {
@@ -522,11 +546,6 @@ int main_loop(void)
/* Wait up to 10 msec. */
main_loop_wait(10);
-
- if (env->send_event) {
- env->send_event = 0;
- xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
- }
}
destroy_hvm_domain();
return 0;
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/i8259-dm.c
--- a/tools/ioemu/target-i386-dm/i8259-dm.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/i8259-dm.c Fri Nov 10 11:11:04 2006 -0700
@@ -22,58 +22,18 @@
* THE SOFTWARE.
*/
#include "vl.h"
-
-/* debug PIC */
-//#define DEBUG_PIC
-
-//#define DEBUG_IRQ_LATENCY
-//#define DEBUG_IRQ_COUNT
-
#include "xenctrl.h"
#include <xen/hvm/ioreq.h>
#include <stdio.h>
#include "cpu.h"
#include "cpu-all.h"
-extern shared_iopage_t *shared_page;
-
struct PicState2 {
};
void pic_set_irq_new(void *opaque, int irq, int level)
{
- /* PicState2 *s = opaque; */
- global_iodata_t *gio;
- int mask;
-
- gio = &shared_page->sp_global;
- mask = 1 << irq;
- if ( gio->pic_elcr & mask ) {
- /* level */
- if ( level ) {
- atomic_clear_bit(irq, &gio->pic_clear_irr);
- atomic_set_bit(irq, &gio->pic_irr);
- cpu_single_env->send_event = 1;
- }
- else {
- atomic_clear_bit(irq, &gio->pic_irr);
- atomic_set_bit(irq, &gio->pic_clear_irr);
- cpu_single_env->send_event = 1;
- }
- }
- else {
- /* edge */
- if ( level ) {
- if ( (mask & gio->pic_last_irr) == 0 ) {
- atomic_set_bit(irq, &gio->pic_irr);
- atomic_set_bit(irq, &gio->pic_last_irr);
- cpu_single_env->send_event = 1;
- }
- }
- else {
- atomic_clear_bit(irq, &gio->pic_last_irr);
- }
- }
+ xc_hvm_set_irq_level(xc_handle, domid, irq, level);
}
/* obsolete function */
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/qemu-dm.debug
--- a/tools/ioemu/target-i386-dm/qemu-dm.debug Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/qemu-dm.debug Fri Nov 10 11:11:04 2006 -0700
@@ -1,5 +1,10 @@
#!/bin/sh
+if [ "`arch`" = "x86_64" ]; then
+ LIBDIR="lib64"
+else
+ LIBDIR="lib"
+fi
echo $* > /tmp/args
echo $DISPLAY >> /tmp/args
-exec /usr/lib/xen/bin/qemu-dm $*
+exec /usr/$LIBDIR/xen/bin/qemu-dm $*
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/vl.c Fri Nov 10 11:11:04 2006 -0700
@@ -1684,7 +1684,7 @@ static void tty_serial_init(int fd, int
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag |= OPOST;
+ tty.c_oflag &= ~OPOST; /* no output mangling of raw serial stream */
tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS);
switch(data_bits) {
@@ -6390,17 +6390,17 @@ int main(int argc, char **argv)
exit(1);
}
- /* init the memory */
- phys_ram_size = ram_size + vga_ram_size + bios_size;
-
-#ifdef CONFIG_DM
-
- xc_handle = xc_interface_open();
-
#if defined (__ia64__)
if (ram_size > MMIO_START)
ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */
#endif
+
+ /* init the memory */
+ phys_ram_size = ram_size + vga_ram_size + bios_size;
+
+#ifdef CONFIG_DM
+
+ xc_handle = xc_interface_open();
nr_pages = ram_size/PAGE_SIZE;
tmp_nr_pages = nr_pages;
@@ -6420,14 +6420,13 @@ int main(int argc, char **argv)
}
#if defined(__i386__) || defined(__x86_64__)
- if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
+ for ( i = 0; i < tmp_nr_pages; i++)
+ page_array[i] = i;
+ if (xc_domain_translate_gpfn_list(xc_handle, domid, tmp_nr_pages,
+ page_array, page_array)) {
fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
exit(-1);
}
-
- if (ram_size > HVM_BELOW_4G_RAM_END)
- for (i = 0; i < nr_pages - (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT); i++)
- page_array[tmp_nr_pages - 1 - i] = page_array[nr_pages - 1 - i];
phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
PROT_READ|PROT_WRITE, page_array,
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/vl.h Fri Nov 10 11:11:04 2006 -0700
@@ -929,6 +929,10 @@ void piix4_pm_init(PCIBus *bus, int devf
void piix4_pm_init(PCIBus *bus, int devfn);
void acpi_bios_init(void);
+/* tpm_tis.c */
+int has_tpm_device(void);
+void tpm_tis_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);
+
/* piix4acpi.c */
extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
@@ -1213,6 +1217,25 @@ void xenstore_write_vncport(int vnc_disp
void xenstore_write_vncport(int vnc_display);
int xenstore_read_vncpasswd(int domid);
+int xenstore_domain_has_devtype(struct xs_handle *handle,
+ const char *devtype);
+char **xenstore_domain_get_devices(struct xs_handle *handle,
+ const char *devtype, unsigned int *num);
+char *xenstore_read_hotplug_status(struct xs_handle *handle,
+ const char *devtype, const char *inst);
+char *xenstore_backend_read_variable(struct xs_handle *,
+ const char *devtype, const char *inst,
+ const char *var);
+int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
+ const char *devtype,
+ const char *inst,
+ const char *token);
+int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
+ const char *devtype,
+ const char *inst,
+ const char *token);
+
+
/* xen_platform.c */
void pci_xen_platform_init(PCIBus *bus);
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/vnc_keysym.h
--- a/tools/ioemu/vnc_keysym.h Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/vnc_keysym.h Fri Nov 10 11:11:04 2006 -0700
@@ -271,5 +271,15 @@ static name2keysym_t name2keysym[]={
{"Num_Lock", 0xff7f}, /* XK_Num_Lock */
{"Pause", 0xff13}, /* XK_Pause */
{"Escape", 0xff1b}, /* XK_Escape */
+
+ /* localized keys */
+{"BackApostrophe", 0xff21},
+{"Muhenkan", 0xff22},
+{"Katakana", 0xff25},
+{"Zenkaku_Hankaku", 0xff29},
+{"Henkan_Mode_Real", 0xff23},
+{"Henkan_Mode_Ultra", 0xff3e},
+{"backslash_ja", 0xffa5},
+
{0,0},
};
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/xenstore.c Fri Nov 10 11:11:04 2006 -0700
@@ -264,3 +264,140 @@ int xenstore_read_vncpasswd(int domid)
return rc;
}
+
+
+/*
+ * get all device instances of a certain type
+ */
+char **xenstore_domain_get_devices(struct xs_handle *handle,
+ const char *devtype, unsigned int *num)
+{
+ char *path;
+ char *buf = NULL;
+ char **e = NULL;
+
+ path = xs_get_domain_path(handle, domid);
+ if (path == NULL)
+ goto out;
+
+ if (pasprintf(&buf, "%s/device/%s", path,devtype) == -1)
+ goto out;
+
+ e = xs_directory(handle, XBT_NULL, buf, num);
+
+ out:
+ free(path);
+ free(buf);
+ return e;
+}
+
+/*
+ * Check whether a domain has devices of the given type
+ */
+int xenstore_domain_has_devtype(struct xs_handle *handle, const char *devtype)
+{
+ int rc = 0;
+ unsigned int num;
+ char **e = xenstore_domain_get_devices(handle, devtype, &num);
+ if (e)
+ rc = 1;
+ free(e);
+ return rc;
+}
+
+/*
+ * Function that creates a path to a variable of an instance of a
+ * certain device
+ */
+static char *get_device_variable_path(const char *devtype, const char *inst,
+ const char *var)
+{
+ char *buf = NULL;
+ if (pasprintf(&buf, "/local/domain/0/backend/%s/%d/%s/%s",
+ devtype,
+ domid,
+ inst,
+ var) == -1) {
+ free(buf);
+ buf = NULL;
+ }
+ return buf;
+}
+
+char *xenstore_backend_read_variable(struct xs_handle *handle,
+ const char *devtype, const char *inst,
+ const char *var)
+{
+ char *value = NULL;
+ char *buf = NULL;
+ unsigned int len;
+
+ buf = get_device_variable_path(devtype, inst, var);
+ if (NULL == buf)
+ goto out;
+
+ value = xs_read(handle, XBT_NULL, buf, &len);
+
+ free(buf);
+
+out:
+ return value;
+}
+
+/*
+ Read the hotplug status variable from the backend given the type
+ of device and its instance.
+*/
+char *xenstore_read_hotplug_status(struct xs_handle *handle,
+ const char *devtype, const char *inst)
+{
+ return xenstore_backend_read_variable(handle, devtype, inst,
+ "hotplug-status");
+}
+
+/*
+ Subscribe to the hotplug status of a device given the type of device and
+ its instance.
+ In case an error occurrs, a negative number is returned.
+ */
+int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
+ const char *devtype,
+ const char *inst,
+ const char *token)
+{
+ int rc = 0;
+ char *path = get_device_variable_path(devtype, inst, "hotplug-status");
+
+ if (path == NULL)
+ return -1;
+
+ if (0 == xs_watch(handle, path, token))
+ rc = -2;
+
+ free(path);
+
+ return rc;
+}
+
+/*
+ * Unsubscribe from a subscription to the status of a hotplug variable of
+ * a device.
+ */
+int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
+ const char *devtype,
+ const char *inst,
+ const char *token)
+{
+ int rc = 0;
+ char *path;
+ path = get_device_variable_path(devtype, inst, "hotplug-status");
+ if (path == NULL)
+ return -1;
+
+ if (0 == xs_unwatch(handle, path, token))
+ rc = -2;
+
+ free(path);
+
+ return rc;
+}
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/ia64/xc_ia64_hvm_build.c
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Fri Nov 10 11:11:04 2006 -0700
@@ -618,7 +618,7 @@ int
int
xc_hvm_build(int xc_handle, uint32_t domid, int memsize,
const char *image_name, unsigned int vcpus, unsigned int pae,
- unsigned int acpi, unsigned int apic, unsigned int store_evtchn,
+ unsigned int acpi, unsigned int store_evtchn,
unsigned long *store_mfn)
{
struct xen_domctl launch_domctl, domctl;
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_core.c Fri Nov 10 11:11:04 2006 -0700
@@ -62,7 +62,7 @@ xc_domain_dumpcore_via_callback(int xc_h
nr_pages = info.nr_pages;
- header.xch_magic = XC_CORE_MAGIC;
+ header.xch_magic = info.hvm ? XC_CORE_MAGIC_HVM : XC_CORE_MAGIC;
header.xch_nr_vcpus = nr_vcpus;
header.xch_nr_pages = nr_pages;
header.xch_ctxt_offset = sizeof(struct xc_core_header);
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_domain.c Fri Nov 10 11:11:04 2006 -0700
@@ -12,6 +12,7 @@ int xc_domain_create(int xc_handle,
int xc_domain_create(int xc_handle,
uint32_t ssidref,
xen_domain_handle_t handle,
+ uint32_t flags,
uint32_t *pdomid)
{
int err;
@@ -20,6 +21,7 @@ int xc_domain_create(int xc_handle,
domctl.cmd = XEN_DOMCTL_createdomain;
domctl.domain = (domid_t)*pdomid;
domctl.u.createdomain.ssidref = ssidref;
+ domctl.u.createdomain.flags = flags;
memcpy(domctl.u.createdomain.handle, handle, sizeof(xen_domain_handle_t));
if ( (err = do_domctl(xc_handle, &domctl)) != 0 )
return err;
@@ -169,15 +171,16 @@ int xc_domain_getinfo(int xc_handle,
break;
info->domid = (uint16_t)domctl.domain;
- info->dying = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_DYING);
- info->shutdown = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_SHUTDOWN);
- info->paused = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_PAUSED);
- info->blocked = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_BLOCKED);
- info->running = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_RUNNING);
+ info->dying = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_dying);
+ info->shutdown = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_shutdown);
+ info->paused = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_paused);
+ info->blocked = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_blocked);
+ info->running = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_running);
+ info->hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest);
info->shutdown_reason =
- (domctl.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) &
- DOMFLAGS_SHUTDOWNMASK;
+ (domctl.u.getdomaininfo.flags>>XEN_DOMINF_shutdownshift) &
+ XEN_DOMINF_shutdownmask;
if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
{
@@ -200,7 +203,8 @@ int xc_domain_getinfo(int xc_handle,
info++;
}
- if( !nr_doms ) return rc;
+ if ( nr_doms == 0 )
+ return rc;
return nr_doms;
}
@@ -345,7 +349,7 @@ int xc_domain_memory_increase_reservatio
if ( err == nr_extents )
return 0;
- if ( err > 0 )
+ if ( err >= 0 )
{
DPRINTF("Failed allocation for dom %d: "
"%ld pages order %d addr_bits %d\n",
@@ -384,11 +388,11 @@ int xc_domain_memory_decrease_reservatio
if ( err == nr_extents )
return 0;
- if ( err > 0 )
+ if ( err >= 0 )
{
DPRINTF("Failed deallocation for dom %d: %ld pages order %d\n",
domid, nr_extents, extent_order);
- errno = EBUSY;
+ errno = EINVAL;
err = -1;
}
@@ -415,7 +419,7 @@ int xc_domain_memory_populate_physmap(in
if ( err == nr_extents )
return 0;
- if ( err > 0 )
+ if ( err >= 0 )
{
DPRINTF("Failed allocation for dom %d: %ld pages order %d\n",
domid, nr_extents, extent_order);
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_hvm_build.c Fri Nov 10 11:11:04 2006 -0700
@@ -12,7 +12,6 @@
#include <unistd.h>
#include <zlib.h>
#include <xen/hvm/hvm_info_table.h>
-#include <xen/hvm/ioreq.h>
#include <xen/hvm/params.h>
#include <xen/hvm/e820.h>
@@ -57,88 +56,67 @@ static void build_e820map(void *e820_pag
unsigned char nr_map = 0;
/*
- * physical address space from HVM_BELOW_4G_RAM_END to 4G is reserved
+ * Physical address space from HVM_BELOW_4G_RAM_END to 4G is reserved
* for PCI devices MMIO. So if HVM has more than HVM_BELOW_4G_RAM_END
* RAM, memory beyond HVM_BELOW_4G_RAM_END will go to 4G above.
*/
- if ( mem_size > HVM_BELOW_4G_RAM_END ) {
+ if ( mem_size > HVM_BELOW_4G_RAM_END )
+ {
extra_mem_size = mem_size - HVM_BELOW_4G_RAM_END;
mem_size = HVM_BELOW_4G_RAM_END;
}
+ /* 0x0-0x9F000: Ordinary RAM. */
e820entry[nr_map].addr = 0x0;
e820entry[nr_map].size = 0x9F000;
e820entry[nr_map].type = E820_RAM;
nr_map++;
+ /*
+ * 0x9F000-0x9F800: SMBIOS tables.
+ * 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA).
+ * TODO: SMBIOS tables should be moved higher (>=0xE0000).
+ * They are unusually low in our memory map: could cause problems?
+ */
e820entry[nr_map].addr = 0x9F000;
e820entry[nr_map].size = 0x1000;
e820entry[nr_map].type = E820_RESERVED;
nr_map++;
- e820entry[nr_map].addr = 0xA0000;
+ /*
+ * Following regions are standard regions of the PC memory map.
+ * They are not covered by e820 regions. OSes will not use as RAM.
+ * 0xA0000-0xC0000: VGA memory-mapped I/O. Not covered by E820.
+ * 0xC0000-0xE0000: 16-bit devices, expansion ROMs (inc. vgabios).
+ * TODO: hvmloader should free pages which turn out to be unused.
+ */
+
+ /*
+ * 0xE0000-0x0F0000: PC-specific area. We place ACPI tables here.
+ * We *cannot* mark as E820_ACPI, for two reasons:
+ * 1. ACPI spec. says that E820_ACPI regions below
+ * 16MB must clip INT15h 0x88 and 0xe801 queries.
+ * Our rombios doesn't do this.
+ * 2. The OS is allowed to reclaim ACPI memory after
+ * parsing the tables. But our FACS is in this
+ * region and it must not be reclaimed (it contains
+ * the ACPI global lock!).
+ * 0xF0000-0x100000: System BIOS.
+ * TODO: hvmloader should free pages which turn out to be unused.
+ */
+ e820entry[nr_map].addr = 0xE0000;
e820entry[nr_map].size = 0x20000;
- e820entry[nr_map].type = E820_IO;
- nr_map++;
-
- e820entry[nr_map].addr = 0xEA000;
- e820entry[nr_map].size = 0x01000;
- e820entry[nr_map].type = E820_ACPI;
- nr_map++;
-
- e820entry[nr_map].addr = 0xF0000;
- e820entry[nr_map].size = 0x10000;
e820entry[nr_map].type = E820_RESERVED;
nr_map++;
-/* buffered io page. */
-#define BUFFERED_IO_PAGES 1
-/* xenstore page. */
-#define XENSTORE_PAGES 1
-/* shared io page. */
-#define SHARED_IO_PAGES 1
-/* totally 16 static pages are reserved in E820 table */
-
- /* Most of the ram goes here */
+ /* Low RAM goes here. Remove 3 pages for ioreq, bufioreq, and xenstore. */
e820entry[nr_map].addr = 0x100000;
- e820entry[nr_map].size = mem_size - 0x100000 - PAGE_SIZE *
- (BUFFERED_IO_PAGES +
- XENSTORE_PAGES +
- SHARED_IO_PAGES);
+ e820entry[nr_map].size = mem_size - 0x100000 - PAGE_SIZE * 3;
e820entry[nr_map].type = E820_RAM;
nr_map++;
- /* Statically allocated special pages */
-
- /* For buffered IO requests */
- e820entry[nr_map].addr = mem_size - PAGE_SIZE *
- (BUFFERED_IO_PAGES +
- XENSTORE_PAGES +
- SHARED_IO_PAGES);
- e820entry[nr_map].size = PAGE_SIZE * BUFFERED_IO_PAGES;
- e820entry[nr_map].type = E820_BUFFERED_IO;
- nr_map++;
-
- /* For xenstore */
- e820entry[nr_map].addr = mem_size - PAGE_SIZE *
- (XENSTORE_PAGES +
- SHARED_IO_PAGES);
- e820entry[nr_map].size = PAGE_SIZE * XENSTORE_PAGES;
- e820entry[nr_map].type = E820_XENSTORE;
- nr_map++;
-
- /* Shared ioreq_t page */
- e820entry[nr_map].addr = mem_size - PAGE_SIZE * SHARED_IO_PAGES;
- e820entry[nr_map].size = PAGE_SIZE * SHARED_IO_PAGES;
- e820entry[nr_map].type = E820_SHARED_PAGE;
- nr_map++;
-
- e820entry[nr_map].addr = 0xFEC00000;
- e820entry[nr_map].size = 0x1400000;
- e820entry[nr_map].type = E820_IO;
- nr_map++;
-
- if ( extra_mem_size ) {
+ if ( extra_mem_size )
+ {
e820entry[nr_map].addr = (1ULL << 32);
e820entry[nr_map].size = extra_mem_size;
e820entry[nr_map].type = E820_RAM;
@@ -197,28 +175,22 @@ static int setup_guest(int xc_handle,
static int setup_guest(int xc_handle,
uint32_t dom, int memsize,
char *image, unsigned long image_size,
- unsigned long nr_pages,
vcpu_guest_context_t *ctxt,
unsigned long shared_info_frame,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
- unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn)
{
xen_pfn_t *page_array = NULL;
- unsigned long count, i;
- unsigned long long ptr;
- xc_mmu_t *mmu = NULL;
-
+ unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
+ unsigned long shared_page_nr;
shared_info_t *shared_info;
void *e820_page;
-
struct domain_setup_info dsi;
uint64_t v_end;
-
- unsigned long shared_page_nr;
+ int rc;
memset(&dsi, 0, sizeof(struct domain_setup_info));
@@ -231,7 +203,6 @@ static int setup_guest(int xc_handle,
goto error_out;
}
- /* memsize is in megabytes */
v_end = (unsigned long long)memsize << 20;
IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
@@ -256,40 +227,33 @@ static int setup_guest(int xc_handle,
goto error_out;
}
- if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
- {
- PERROR("Could not get the page frame list.\n");
+ for ( i = 0; i < nr_pages; i++ )
+ page_array[i] = i;
+ for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < nr_pages; i++ )
+ page_array[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
+
+ /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */
+ rc = xc_domain_memory_populate_physmap(
+ xc_handle, dom, (nr_pages > 0xa0) ? 0xa0 : nr_pages,
+ 0, 0, &page_array[0x00]);
+ if ( (rc == 0) && (nr_pages > 0xc0) )
+ rc = xc_domain_memory_populate_physmap(
+ xc_handle, dom, nr_pages - 0xc0, 0, 0, &page_array[0xc0]);
+ if ( rc != 0 )
+ {
+ PERROR("Could not allocate memory for HVM guest.\n");
+ goto error_out;
+ }
+
+ if ( xc_domain_translate_gpfn_list(xc_handle, dom, nr_pages,
+ page_array, page_array) )
+ {
+ PERROR("Could not translate addresses of HVM guest.\n");
goto error_out;
}
loadelfimage(image, xc_handle, dom, page_array, &dsi);
- if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
- goto error_out;
-
- /* Write the machine->phys table entries. */
- for ( count = 0; count < nr_pages; count++ )
- {
- unsigned long gpfn_count_skip;
-
- ptr = (unsigned long long)page_array[count] << PAGE_SHIFT;
-
- gpfn_count_skip = 0;
-
- /*
- * physical address space from HVM_BELOW_4G_RAM_END to 4G is reserved
- * for PCI devices MMIO. So if HVM has more than HVM_BELOW_4G_RAM_END
- * RAM, memory beyond HVM_BELOW_4G_RAM_END will go to 4G above.
- */
- if ( count >= (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT) )
- gpfn_count_skip = HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
-
- if ( xc_add_mmu_update(xc_handle, mmu,
- ptr | MMU_MACHPHYS_UPDATE,
- count + gpfn_count_skip) )
- goto error_out;
- }
-
if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi) )
{
ERROR("Couldn't set hvm info for HVM guest.\n");
@@ -297,7 +261,6 @@ static int setup_guest(int xc_handle,
}
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
- xc_set_hvm_param(xc_handle, dom, HVM_PARAM_APIC_ENABLED, apic);
if ( (e820_page = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
@@ -316,6 +279,8 @@ static int setup_guest(int xc_handle,
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
+ memset(&shared_info->evtchn_mask[0], 0xff,
+ sizeof(shared_info->evtchn_mask));
munmap(shared_info, PAGE_SIZE);
if ( v_end > HVM_BELOW_4G_RAM_END )
@@ -323,39 +288,25 @@ static int setup_guest(int xc_handle,
else
shared_page_nr = (v_end >> PAGE_SHIFT) - 1;
+ /* Paranoia: clean pages. */
+ if ( xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr]) ||
+ xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr-1]) ||
+ xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr-2]) )
+ goto error_out;
+
*store_mfn = page_array[shared_page_nr - 1];
-
- xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr - 1);
+ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
-
- /* Paranoia */
- /* clean the shared IO requests page */
- if ( xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr]) )
- goto error_out;
-
- /* clean the buffered IO requests page */
- if ( xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr - 2]) )
- goto error_out;
-
- if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
- goto error_out;
-
- /* Send the page update requests down to the hypervisor. */
- if ( xc_finish_mmu_updates(xc_handle, mmu) )
- goto error_out;
-
- free(mmu);
+ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
+ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
+
free(page_array);
- /*
- * Initial register values:
- */
ctxt->user_regs.eip = dsi.v_kernentry;
return 0;
error_out:
- free(mmu);
free(page_array);
return -1;
}
@@ -368,45 +319,17 @@ static int xc_hvm_build_internal(int xc_
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
- unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn)
{
struct xen_domctl launch_domctl, domctl;
- int rc, i;
- vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
- unsigned long nr_pages;
- xen_capabilities_info_t xen_caps;
+ vcpu_guest_context_t ctxt;
+ int rc;
if ( (image == NULL) || (image_size == 0) )
{
ERROR("Image required");
goto error_out;
- }
-
- if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 )
- {
- PERROR("Failed to get xen version info");
- goto error_out;
- }
-
- if ( !strstr(xen_caps, "hvm") )
- {
- PERROR("CPU doesn't support HVM extensions or "
- "the extensions are not enabled");
- goto error_out;
- }
-
- if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 )
- {
- PERROR("Could not find total pages for domain");
- goto error_out;
- }
-
- if ( lock_pages(&st_ctxt, sizeof(st_ctxt) ) )
- {
- PERROR("%s: ctxt mlock failed", __func__);
- return 1;
}
domctl.cmd = XEN_DOMCTL_getdomaininfo;
@@ -418,68 +341,30 @@ static int xc_hvm_build_internal(int xc_
goto error_out;
}
- /* HVM domains must be put into shadow mode at the start of day */
- if ( xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_ENABLE,
- NULL, 0, NULL,
- XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT |
- XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE |
- XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL,
- NULL) )
- {
- PERROR("Could not enable shadow paging for domain.\n");
- goto error_out;
- }
-
- memset(ctxt, 0, sizeof(*ctxt));
-
- ctxt->flags = VGCF_HVM_GUEST;
- if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
- ctxt, domctl.u.getdomaininfo.shared_info_frame,
- vcpus, pae, acpi, apic, store_evtchn, store_mfn) < 0)
+ memset(&ctxt, 0, sizeof(ctxt));
+
+ if ( setup_guest(xc_handle, domid, memsize, image, image_size,
+ &ctxt, domctl.u.getdomaininfo.shared_info_frame,
+ vcpus, pae, acpi, store_evtchn, store_mfn) < 0)
{
ERROR("Error constructing guest OS");
goto error_out;
}
- /* FPU is set up to default initial state. */
- memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
-
- /* Virtual IDT is empty at start-of-day. */
- for ( i = 0; i < 256; i++ )
- {
- ctxt->trap_ctxt[i].vector = i;
- ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS;
- }
-
- /* No LDT. */
- ctxt->ldt_ents = 0;
-
- /* Use the default Xen-provided GDT. */
- ctxt->gdt_ents = 0;
-
- /* No debugging. */
- memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
-
- /* No callback handlers. */
-#if defined(__i386__)
- ctxt->event_callback_cs = FLAT_KERNEL_CS;
- ctxt->event_callback_eip = 0;
- ctxt->failsafe_callback_cs = FLAT_KERNEL_CS;
- ctxt->failsafe_callback_eip = 0;
-#elif defined(__x86_64__)
- ctxt->event_callback_eip = 0;
- ctxt->failsafe_callback_eip = 0;
- ctxt->syscall_callback_eip = 0;
-#endif
+ if ( lock_pages(&ctxt, sizeof(ctxt) ) )
+ {
+ PERROR("%s: ctxt mlock failed", __func__);
+ goto error_out;
+ }
memset(&launch_domctl, 0, sizeof(launch_domctl));
-
launch_domctl.domain = (domid_t)domid;
launch_domctl.u.vcpucontext.vcpu = 0;
- set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt);
-
+ set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, &ctxt);
launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
rc = xc_domctl(xc_handle, &launch_domctl);
+
+ unlock_pages(&ctxt, sizeof(ctxt));
return rc;
@@ -626,7 +511,6 @@ int xc_hvm_build(int xc_handle,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
- unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn)
{
@@ -640,7 +524,7 @@ int xc_hvm_build(int xc_handle,
sts = xc_hvm_build_internal(xc_handle, domid, memsize,
image, image_size,
- vcpus, pae, acpi, apic,
+ vcpus, pae, acpi,
store_evtchn, store_mfn);
free(image);
@@ -662,7 +546,6 @@ int xc_hvm_build_mem(int xc_handle,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
- unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn)
{
@@ -687,7 +570,7 @@ int xc_hvm_build_mem(int xc_handle,
sts = xc_hvm_build_internal(xc_handle, domid, memsize,
img, img_len,
- vcpus, pae, acpi, apic,
+ vcpus, pae, acpi,
store_evtchn, store_mfn);
/* xc_inflate_buffer may return the original buffer pointer (for
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_linux_build.c Fri Nov 10 11:11:04 2006 -0700
@@ -25,17 +25,16 @@
#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#endif
-#ifdef __ia64__
-#define get_tot_pages xc_get_max_pages
-#else
-#define get_tot_pages xc_get_tot_pages
-#endif
-
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
#define round_pgdown(_p) ((_p)&PAGE_MASK)
struct initrd_info {
enum { INITRD_none, INITRD_file, INITRD_mem } type;
+ /*
+ * .len must be filled in by the user for type==INITRD_mem. It is
+ * filled in by load_initrd() for INITRD_file and unused for
+ * INITRD_none.
+ */
unsigned long len;
union {
gzFile file_handle;
@@ -134,30 +133,42 @@ static int load_initrd(int xc_handle, do
xen_pfn_t *phys_to_mach)
{
char page[PAGE_SIZE];
- unsigned long pfn_start, pfn, nr_pages;
+ unsigned long pfn_start, pfn;
if ( initrd->type == INITRD_none )
return 0;
pfn_start = physbase >> PAGE_SHIFT;
- nr_pages = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
- for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
- {
- if ( initrd->type == INITRD_mem )
+
+ if ( initrd->type == INITRD_mem )
+ {
+ unsigned long nr_pages = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
{
xc_copy_to_domain_page(
xc_handle, dom, phys_to_mach[pfn],
&initrd->u.mem_addr[(pfn - pfn_start) << PAGE_SHIFT]);
}
- else
- {
- if ( gzread(initrd->u.file_handle, page, PAGE_SIZE) == -1 )
+ }
+ else
+ {
+ int readlen;
+
+ pfn = pfn_start;
+ initrd->len = 0;
+
+ /* gzread returns 0 on EOF */
+ while ( (readlen = gzread(initrd->u.file_handle, page, PAGE_SIZE)) )
+ {
+ if ( readlen < 0 )
{
PERROR("Error reading initrd image, could not");
return -EINVAL;
}
- xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn], page);
+
+ initrd->len += readlen;
+ xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn++], page);
}
}
@@ -485,10 +496,17 @@ static int setup_guest(int xc_handle,
if ( rc != 0 )
goto error_out;
- dsi.v_start = round_pgdown(dsi.v_start);
- vinitrd_start = round_pgup(dsi.v_end);
- vinitrd_end = vinitrd_start + initrd->len;
- v_end = round_pgup(vinitrd_end);
+ dsi.v_start = round_pgdown(dsi.v_start);
+ (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
+ &dsi);
+
+ vinitrd_start = round_pgup(dsi.v_end);
+ if ( load_initrd(xc_handle, dom, initrd,
+ vinitrd_start - dsi.v_start, page_array) )
+ goto error_out;
+
+ vinitrd_end = vinitrd_start + initrd->len;
+ v_end = round_pgup(vinitrd_end);
start_info_mpa = (nr_pages - 3) << PAGE_SHIFT;
/* Build firmware. */
@@ -524,13 +542,6 @@ static int setup_guest(int xc_handle,
_p(vinitrd_start), _p(vinitrd_end),
_p(dsi.v_start), _p(v_end));
IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
-
- (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
- &dsi);
-
- if ( load_initrd(xc_handle, dom, initrd,
- vinitrd_start - dsi.v_start, page_array) )
- goto error_out;
*pvke = dsi.v_kernentry;
@@ -657,7 +668,6 @@ static int setup_guest(int xc_handle,
int hypercall_page_defined;
start_info_t *start_info;
shared_info_t *shared_info;
- xc_mmu_t *mmu = NULL;
const char *p;
DECLARE_DOMCTL;
int rc;
@@ -699,7 +709,7 @@ static int setup_guest(int xc_handle,
goto error_out;
}
- if (!compat_check(xc_handle, &dsi))
+ if ( !compat_check(xc_handle, &dsi) )
goto error_out;
/* Parse and validate kernel features. */
@@ -727,6 +737,28 @@ static int setup_guest(int xc_handle,
shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
required_features);
+
+ if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
+ {
+ PERROR("Could not allocate memory");
+ goto error_out;
+ }
+
+ for ( i = 0; i < nr_pages; i++ )
+ page_array[i] = i;
+
+ if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
+ 0, 0, page_array) )
+ {
+ PERROR("Could not allocate memory for PV guest.\n");
+ goto error_out;
+ }
+
+ rc = (load_funcs.loadimage)(image, image_size,
+ xc_handle, dom, page_array,
+ &dsi);
+ if ( rc != 0 )
+ goto error_out;
/*
* Why do we need this? The number of page-table frames depends on the
@@ -741,9 +773,14 @@ static int setup_guest(int xc_handle,
ERROR("End of mapped kernel image too close to end of memory");
goto error_out;
}
+
vinitrd_start = v_end;
+ if ( load_initrd(xc_handle, dom, initrd,
+ vinitrd_start - dsi.v_start, page_array) )
+ goto error_out;
if ( !increment_ulong(&v_end, round_pgup(initrd->len)) )
goto error_out;
+
vphysmap_start = v_end;
if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) )
goto error_out;
@@ -845,31 +882,8 @@ static int setup_guest(int xc_handle,
goto error_out;
}
- if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
- {
- PERROR("Could not allocate memory");
- goto error_out;
- }
-
- if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
- {
- PERROR("Could not get the page frame list");
- goto error_out;
- }
-
- rc = (load_funcs.loadimage)(image, image_size,
- xc_handle, dom, page_array,
- &dsi);
- if ( rc != 0 )
- goto error_out;
-
- if ( load_initrd(xc_handle, dom, initrd,
- vinitrd_start - dsi.v_start, page_array) )
- goto error_out;
-
- /* setup page tables */
#if defined(__i386__)
- if (dsi.pae_kernel != PAEKERN_no)
+ if ( dsi.pae_kernel != PAEKERN_no )
rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
dsi.v_start, v_end,
page_array, vpt_start, vpt_end,
@@ -886,16 +900,16 @@ static int setup_guest(int xc_handle,
page_array, vpt_start, vpt_end,
shadow_mode_enabled);
#endif
- if (0 != rc)
- goto error_out;
-
-#if defined(__i386__)
+ if ( rc != 0 )
+ goto error_out;
+
/*
* Pin down l2tab addr as page dir page - causes hypervisor to provide
* correct protection for the page
*/
if ( !shadow_mode_enabled )
{
+#if defined(__i386__)
if ( dsi.pae_kernel != PAEKERN_no )
{
if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
@@ -908,40 +922,24 @@ static int setup_guest(int xc_handle,
xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
goto error_out;
}
- }
+#elif defined(__x86_64__)
+ /*
+ * Pin down l4tab addr as page dir page - causes hypervisor to provide
+ * correct protection for the page
+ */
+ if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
+ xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
+ goto error_out;
#endif
-
-#if defined(__x86_64__)
- /*
- * Pin down l4tab addr as page dir page - causes hypervisor to provide
- * correct protection for the page
- */
- if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
- xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
- goto error_out;
-#endif
-
- if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
- goto error_out;
-
- /* Write the phys->machine and machine->phys table entries. */
+ }
+
+ /* Write the phys->machine table entries (machine->phys already done). */
physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
physmap = physmap_e = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[physmap_pfn++]);
-
for ( count = 0; count < nr_pages; count++ )
{
- if ( xc_add_mmu_update(
- xc_handle, mmu,
- ((uint64_t)page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
- count) )
- {
- DPRINTF("m2p update failure p=%lx m=%"PRIx64"\n",
- count, (uint64_t)page_array[count]);
- munmap(physmap, PAGE_SIZE);
- goto error_out;
- }
*physmap_e++ = page_array[count];
if ( ((unsigned long)physmap_e & (PAGE_SIZE-1)) == 0 )
{
@@ -952,10 +950,6 @@ static int setup_guest(int xc_handle,
}
}
munmap(physmap, PAGE_SIZE);
-
- /* Send the page update requests down to the hypervisor. */
- if ( xc_finish_mmu_updates(xc_handle, mmu) )
- goto error_out;
if ( shadow_mode_enabled )
{
@@ -1063,10 +1057,6 @@ static int setup_guest(int xc_handle,
munmap(shared_info, PAGE_SIZE);
- /* Send the page update requests down to the hypervisor. */
- if ( xc_finish_mmu_updates(xc_handle, mmu) )
- goto error_out;
-
hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE,
&hypercall_page_defined);
if ( hypercall_page_defined )
@@ -1082,7 +1072,6 @@ static int setup_guest(int xc_handle,
goto error_out;
}
- free(mmu);
free(page_array);
*pvsi = vstartinfo_start;
@@ -1092,7 +1081,6 @@ static int setup_guest(int xc_handle,
return 0;
error_out:
- free(mmu);
free(page_array);
return -1;
}
@@ -1100,6 +1088,7 @@ static int setup_guest(int xc_handle,
static int xc_linux_build_internal(int xc_handle,
uint32_t domid,
+ unsigned int mem_mb,
char *image,
unsigned long image_size,
struct initrd_info *initrd,
@@ -1114,8 +1103,7 @@ static int xc_linux_build_internal(int x
struct xen_domctl launch_domctl;
DECLARE_DOMCTL;
int rc, i;
- vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
- unsigned long nr_pages;
+ struct vcpu_guest_context st_ctxt, *ctxt = &st_ctxt;
unsigned long vstartinfo_start, vkern_entry, vstack_start;
uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
@@ -1126,12 +1114,6 @@ static int xc_linux_build_internal(int x
PERROR("Failed to parse configured features\n");
goto error_out;
}
- }
-
- if ( (nr_pages = get_tot_pages(xc_handle, domid)) < 0 )
- {
- PERROR("Could not find total pages for domain");
- goto error_out;
}
#ifdef VALGRIND
@@ -1157,7 +1139,7 @@ static int xc_linux_build_internal(int x
if ( setup_guest(xc_handle, domid, image, image_size,
initrd,
- nr_pages,
+ mem_mb << (20 - PAGE_SHIFT),
&vstartinfo_start, &vkern_entry,
&vstack_start, ctxt, cmdline,
domctl.u.getdomaininfo.shared_info_frame,
@@ -1253,6 +1235,7 @@ static int xc_linux_build_internal(int x
int xc_linux_build_mem(int xc_handle,
uint32_t domid,
+ unsigned int mem_mb,
const char *image_buffer,
unsigned long image_size,
const char *initrd,
@@ -1301,7 +1284,7 @@ int xc_linux_build_mem(int xc_handle,
}
}
- sts = xc_linux_build_internal(xc_handle, domid, img_buf, img_len,
+ sts = xc_linux_build_internal(xc_handle, domid, mem_mb, img_buf, img_len,
&initrd_info, cmdline, features, flags,
store_evtchn, store_mfn,
console_evtchn, console_mfn);
@@ -1321,6 +1304,7 @@ int xc_linux_build_mem(int xc_handle,
int xc_linux_build(int xc_handle,
uint32_t domid,
+ unsigned int mem_mb,
const char *image_name,
const char *initrd_name,
const char *cmdline,
@@ -1350,7 +1334,6 @@ int xc_linux_build(int xc_handle,
goto error_out;
}
- initrd_info.len = xc_get_filesz(fd);
if ( (initrd_info.u.file_handle = gzdopen(fd, "rb")) == NULL )
{
PERROR("Could not allocate decompression state for initrd");
@@ -1358,7 +1341,7 @@ int xc_linux_build(int xc_handle,
}
}
- sts = xc_linux_build_internal(xc_handle, domid, image, image_size,
+ sts = xc_linux_build_internal(xc_handle, domid, mem_mb, image, image_size,
&initrd_info, cmdline, features, flags,
store_evtchn, store_mfn,
console_evtchn, console_mfn);
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_linux_save.c Fri Nov 10 11:11:04 2006 -0700
@@ -978,12 +978,14 @@ int xc_linux_save(int xc_handle, int io_
}
if(!write_exact(io_fd, &batch, sizeof(unsigned int))) {
- ERROR("Error when writing to state file (2)");
+ ERROR("Error when writing to state file (2) (errno %d)",
+ errno);
goto out;
}
if(!write_exact(io_fd, pfn_type, sizeof(unsigned long)*j)) {
- ERROR("Error when writing to state file (3)");
+ ERROR("Error when writing to state file (3) (errno %d)",
+ errno);
goto out;
}
@@ -1013,7 +1015,8 @@ int xc_linux_save(int xc_handle, int io_
goto out;
if (ratewrite(io_fd, page, PAGE_SIZE) != PAGE_SIZE) {
- ERROR("Error when writing to state file (4)");
+ ERROR("Error when writing to state file (4)"
+ " (errno %d)", errno);
goto out;
}
@@ -1021,7 +1024,8 @@ int xc_linux_save(int xc_handle, int io_
/* We have a normal page: just write it directly. */
if (ratewrite(io_fd, spage, PAGE_SIZE) != PAGE_SIZE) {
- ERROR("Error when writing to state file (5)");
+ ERROR("Error when writing to state file (5)"
+ " (errno %d)", errno);
goto out;
}
}
@@ -1056,7 +1060,8 @@ int xc_linux_save(int xc_handle, int io_
/* send "-1" to put receiver into debug mode */
if(!write_exact(io_fd, &minusone, sizeof(int))) {
- ERROR("Error when writing to state file (6)");
+ ERROR("Error when writing to state file (6) (errno %d)",
+ errno);
goto out;
}
@@ -1110,7 +1115,7 @@ int xc_linux_save(int xc_handle, int io_
/* Zero terminate */
i = 0;
if (!write_exact(io_fd, &i, sizeof(int))) {
- ERROR("Error when writing to state file (6)");
+ ERROR("Error when writing to state file (6') (errno %d)", errno);
goto out;
}
@@ -1125,7 +1130,7 @@ int xc_linux_save(int xc_handle, int io_
}
if(!write_exact(io_fd, &j, sizeof(unsigned int))) {
- ERROR("Error when writing to state file (6a)");
+ ERROR("Error when writing to state file (6a) (errno %d)", errno);
goto out;
}
@@ -1137,7 +1142,8 @@ int xc_linux_save(int xc_handle, int io_
i++;
if (j == 1024 || i == max_pfn) {
if(!write_exact(io_fd, &pfntab, sizeof(unsigned long)*j)) {
- ERROR("Error when writing to state file (6b)");
+ ERROR("Error when writing to state file (6b) (errno %d)",
+ errno);
goto out;
}
j = 0;
@@ -1170,7 +1176,7 @@ int xc_linux_save(int xc_handle, int io_
if (!write_exact(io_fd, &ctxt, sizeof(ctxt)) ||
!write_exact(io_fd, live_shinfo, PAGE_SIZE)) {
- ERROR("Error when writing to state file (1)");
+ ERROR("Error when writing to state file (1) (errno %d)", errno);
goto out;
}
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_misc.c
--- a/tools/libxc/xc_misc.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_misc.c Fri Nov 10 11:11:04 2006 -0700
@@ -5,6 +5,7 @@
*/
#include "xc_private.h"
+#include <xen/hvm/hvm_op.h>
int xc_readconsolering(int xc_handle,
char **pbuffer,
@@ -89,6 +90,33 @@ int xc_perfc_control(int xc_handle,
return rc;
}
+int xc_hvm_set_irq_level(int xc_handle, domid_t dom, int irq, int level)
+{
+ DECLARE_HYPERCALL;
+ struct xen_hvm_set_irq_level arg;
+ int rc;
+
+ hypercall.op = __HYPERVISOR_hvm_op;
+ hypercall.arg[0] = HVMOP_set_irq_level;
+ hypercall.arg[1] = (unsigned long)&arg;
+
+ arg.domid = dom;
+ arg.irq = irq;
+ arg.level = level;
+
+ if ( mlock(&arg, sizeof(arg)) != 0 )
+ {
+ PERROR("Could not lock memory");
+ return -1;
+ }
+
+ rc = do_xen_hypercall(xc_handle, &hypercall);
+
+ safe_munlock(&arg, sizeof(arg));
+
+ return rc;
+}
+
/*
* Local variables:
* mode: C
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_private.c Fri Nov 10 11:11:04 2006 -0700
@@ -344,28 +344,6 @@ int xc_clear_domain_page(int xc_handle,
return 0;
}
-unsigned long xc_get_filesz(int fd)
-{
- uint16_t sig;
- uint32_t _sz = 0;
- unsigned long sz;
-
- lseek(fd, 0, SEEK_SET);
- if ( read(fd, &sig, sizeof(sig)) != sizeof(sig) )
- return 0;
- sz = lseek(fd, 0, SEEK_END);
- if ( sig == 0x8b1f ) /* GZIP signature? */
- {
- lseek(fd, -4, SEEK_END);
- if ( read(fd, &_sz, 4) != 4 )
- return 0;
- sz = _sz;
- }
- lseek(fd, 0, SEEK_SET);
-
- return sz;
-}
-
void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
int xch, uint32_t dom, xen_pfn_t *parray,
unsigned long vstart)
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_private.h Fri Nov 10 11:11:04 2006 -0700
@@ -158,4 +158,9 @@ int xc_map_foreign_ranges(int xc_handle,
int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
privcmd_mmap_entry_t *entries, int nr);
+void *map_domain_va_core(unsigned long domfd, int cpu, void *guest_va,
+ vcpu_guest_context_t *ctxt);
+int xc_waitdomain_core(int xc_handle, int domain, int *status,
+ int options, vcpu_guest_context_t *ctxt);
+
#endif /* __XC_PRIVATE_H__ */
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_ptrace.c Fri Nov 10 11:11:04 2006 -0700
@@ -36,8 +36,9 @@ static char *ptrace_names[] = {
};
#endif
-static int current_domid = -1;
-static int current_isfile;
+static int current_domid = -1;
+static int current_isfile;
+static int current_is_hvm;
static uint64_t online_cpumap;
static uint64_t regs_valid;
@@ -45,7 +46,6 @@ static vcpu_guest_context_t ctxt[MAX
extern int ffsll(long long int);
#define FOREACH_CPU(cpumap, i) for ( cpumap = online_cpumap; (i =
ffsll(cpumap)); cpumap &= ~(1 << (index - 1)) )
-
static int
fetch_regs(int xc_handle, int cpu, int *online)
@@ -172,7 +172,7 @@ to_ma(int cpu,
{
unsigned long maddr = in_addr;
- if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
+ if ( current_is_hvm && paging_enabled(&ctxt[cpu]) )
maddr = page_array[maddr >> PAGE_SHIFT] << PAGE_SHIFT;
return maddr;
}
@@ -443,7 +443,7 @@ __xc_waitdomain(
goto done;
}
- if ( !(domctl.u.getdomaininfo.flags & DOMFLAGS_PAUSED) )
+ if ( !(domctl.u.getdomaininfo.flags & XEN_DOMINF_paused) )
{
nanosleep(&ts,NULL);
goto retry;
@@ -482,11 +482,11 @@ xc_ptrace(
case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA:
if (current_isfile)
- guest_va = (unsigned long *)map_domain_va_core(current_domid,
- cpu, addr, ctxt);
+ guest_va = (unsigned long *)map_domain_va_core(
+ current_domid, cpu, addr, ctxt);
else
- guest_va = (unsigned long *)map_domain_va(xc_handle,
- cpu, addr, PROT_READ);
+ guest_va = (unsigned long *)map_domain_va(
+ xc_handle, cpu, addr, PROT_READ);
if ( guest_va == NULL )
goto out_error;
retval = *guest_va;
@@ -496,11 +496,11 @@ xc_ptrace(
case PTRACE_POKEDATA:
/* XXX assume that all CPUs have the same address space */
if (current_isfile)
- guest_va = (unsigned long *)map_domain_va_core(current_domid,
- cpu, addr, ctxt);
+ guest_va = (unsigned long *)map_domain_va_core(
+ current_domid, cpu, addr, ctxt);
else
- guest_va = (unsigned long *)map_domain_va(xc_handle,
- cpu, addr, PROT_READ|PROT_WRITE);
+ guest_va = (unsigned long *)map_domain_va(
+ xc_handle, cpu, addr, PROT_READ|PROT_WRITE);
if ( guest_va == NULL )
goto out_error;
*guest_va = (unsigned long)data;
@@ -590,10 +590,11 @@ xc_ptrace(
retval = do_domctl(xc_handle, &domctl);
if ( retval || (domctl.domain != current_domid) )
goto out_error_domctl;
- if ( domctl.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
+ if ( domctl.u.getdomaininfo.flags & XEN_DOMINF_paused )
IPRINTF("domain currently paused\n");
else if ((retval = xc_domain_pause(xc_handle, current_domid)))
goto out_error_domctl;
+ current_is_hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest);
domctl.cmd = XEN_DOMCTL_setdebugging;
domctl.domain = current_domid;
domctl.u.setdebugging.enable = 1;
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_ptrace_core.c
--- a/tools/libxc/xc_ptrace_core.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_ptrace_core.c Fri Nov 10 11:11:04 2006 -0700
@@ -7,6 +7,7 @@
/* XXX application state */
+static int current_is_hvm = 0;
static long nr_pages = 0;
static unsigned long *p2m_array = NULL;
static unsigned long *m2p_array = NULL;
@@ -24,8 +25,8 @@ map_mtop_offset(unsigned long ma)
void *
-map_domain_va_core(unsigned long domfd, int cpu, void * guest_va,
- vcpu_guest_context_t *ctxt)
+map_domain_va_core(unsigned long domfd, int cpu, void *guest_va,
+ vcpu_guest_context_t *ctxt)
{
unsigned long pde, page;
unsigned long va = (unsigned long)guest_va;
@@ -55,7 +56,7 @@ map_domain_va_core(unsigned long domfd,
}
if ((pde = cr3_virt[cpu][l2_table_offset_i386(va)]) == 0) /* logical
address */
return NULL;
- if (ctxt[cpu].flags & VGCF_HVM_GUEST)
+ if (current_is_hvm)
pde = p2m_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
if (pde != pde_phys[cpu])
{
@@ -71,7 +72,7 @@ map_domain_va_core(unsigned long domfd,
}
if ((page = pde_virt[cpu][l1_table_offset_i386(va)]) == 0) /* logical
address */
return NULL;
- if (ctxt[cpu].flags & VGCF_HVM_GUEST)
+ if (current_is_hvm)
page = p2m_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
if (page != page_phys[cpu])
{
@@ -104,17 +105,18 @@ xc_waitdomain_core(
int i;
xc_core_header_t header;
- if (nr_pages == 0)
+ if ( nr_pages == 0 )
{
-
if (read(domfd, &header, sizeof(header)) != sizeof(header))
return -1;
- if (header.xch_magic != XC_CORE_MAGIC) {
- IPRINTF("Magic number missmatch: 0x%08x (file) != "
- " 0x%08x (code)\n", header.xch_magic,
- XC_CORE_MAGIC);
- return -1;
+ current_is_hvm = (header.xch_magic == XC_CORE_MAGIC_HVM);
+ if ( !current_is_hvm && (header.xch_magic != XC_CORE_MAGIC) )
+ {
+ IPRINTF("Magic number missmatch: 0x%08x (file) != "
+ " 0x%08x (code)\n", header.xch_magic,
+ XC_CORE_MAGIC);
+ return -1;
}
nr_pages = header.xch_nr_pages;
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xenctrl.h Fri Nov 10 11:11:04 2006 -0700
@@ -47,10 +47,9 @@
#define rmb() __asm__ __volatile__ ( "lfence" : : : "memory")
#define wmb() __asm__ __volatile__ ( "" : : : "memory")
#elif defined(__ia64__)
-/* FIXME */
-#define mb()
-#define rmb()
-#define wmb()
+#define mb() __asm__ __volatile__ ("mf" ::: "memory")
+#define rmb() __asm__ __volatile__ ("mf" ::: "memory")
+#define wmb() __asm__ __volatile__ ("mf" ::: "memory")
#elif defined(__powerpc__)
/* XXX loosen these up later */
#define mb() __asm__ __volatile__ ("sync" : : : "memory")
@@ -113,25 +112,13 @@ typedef struct xc_core_header {
unsigned int xch_pages_offset;
} xc_core_header_t;
-#define XC_CORE_MAGIC 0xF00FEBED
+#define XC_CORE_MAGIC 0xF00FEBED
+#define XC_CORE_MAGIC_HVM 0xF00FEBEE
#ifdef __linux__
#include <sys/ptrace.h>
#include <thread_db.h>
-
-void * map_domain_va_core(
- unsigned long domfd,
- int cpu,
- void *guest_va,
- vcpu_guest_context_t *ctxt);
-
-int xc_waitdomain_core(
- int xc_handle,
- int domain,
- int *status,
- int options,
- vcpu_guest_context_t *ctxt);
typedef void (*thr_ev_handler_t)(long);
@@ -158,11 +145,12 @@ int xc_waitdomain(
* DOMAIN MANAGEMENT FUNCTIONS
*/
-typedef struct {
+typedef struct xc_dominfo {
uint32_t domid;
uint32_t ssidref;
unsigned int dying:1, crashed:1, shutdown:1,
- paused:1, blocked:1, running:1;
+ paused:1, blocked:1, running:1,
+ hvm:1;
unsigned int shutdown_reason; /* only meaningful if shutdown==1 */
unsigned long nr_pages;
unsigned long shared_info_frame;
@@ -177,6 +165,7 @@ int xc_domain_create(int xc_handle,
int xc_domain_create(int xc_handle,
uint32_t ssidref,
xen_domain_handle_t handle,
+ uint32_t flags,
uint32_t *pdomid);
@@ -677,4 +666,6 @@ evtchn_port_t xc_evtchn_pending(int xce_
*/
int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
+int xc_hvm_set_irq_level(int xce_handle, domid_t dom, int irq, int level);
+
#endif
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xenguest.h Fri Nov 10 11:11:04 2006 -0700
@@ -48,8 +48,9 @@ int xc_linux_restore(int xc_handle, int
*
* @parm xc_handle a handle to an open hypervisor interface
* @parm domid the id of the domain
- * @param image_name name of the kernel image file
- * @param ramdisk_name name of the ramdisk image file
+ * @parm mem_mb memory size in megabytes
+ * @parm image_name name of the kernel image file
+ * @parm ramdisk_name name of the ramdisk image file
* @parm cmdline command line string
* @parm flags domain creation flags
* @parm store_evtchn the store event channel for this domain to use
@@ -60,6 +61,7 @@ int xc_linux_restore(int xc_handle, int
*/
int xc_linux_build(int xc_handle,
uint32_t domid,
+ unsigned int mem_mb,
const char *image_name,
const char *ramdisk_name,
const char *cmdline,
@@ -74,22 +76,24 @@ int xc_linux_build(int xc_handle,
* This function will create a domain for a paravirtualized Linux
* using buffers for kernel and initrd
*
- * @param xc_handle a handle to an open hypervisor interface
- * @param domid the id of the domain
- * @param image_buffer buffer containing kernel image
- * @param image_size size of the kernel image buffer
- * @param initrd_buffer name of the ramdisk image file
- * @param initrd_size size of the ramdisk buffer
- * @param cmdline command line string
- * @param flags domain creation flags
- * @param store_evtchn the store event channel for this domain to use
- * @param store_mfn returned with the mfn of the store page
- * @param console_evtchn the console event channel for this domain to use
- * @param conole_mfn returned with the mfn of the console page
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the id of the domain
+ * @parm mem_mb memory size in megabytes
+ * @parm image_buffer buffer containing kernel image
+ * @parm image_size size of the kernel image buffer
+ * @parm initrd_buffer name of the ramdisk image file
+ * @parm initrd_size size of the ramdisk buffer
+ * @parm cmdline command line string
+ * @parm flags domain creation flags
+ * @parm store_evtchn the store event channel for this domain to use
+ * @parm store_mfn returned with the mfn of the store page
+ * @parm console_evtchn the console event channel for this domain to use
+ * @parm conole_mfn returned with the mfn of the console page
* @return 0 on success, -1 on failure
*/
int xc_linux_build_mem(int xc_handle,
uint32_t domid,
+ unsigned int mem_mb,
const char *image_buffer,
unsigned long image_size,
const char *initrd_buffer,
@@ -109,7 +113,6 @@ int xc_hvm_build(int xc_handle,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
- unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn);
@@ -121,7 +124,6 @@ int xc_hvm_build_mem(int xc_handle,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
- unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn);
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xg_private.c Fri Nov 10 11:11:04 2006 -0700
@@ -31,7 +31,7 @@ char *xc_read_image(const char *filename
{
int kernel_fd = -1;
gzFile kernel_gfd = NULL;
- char *image = NULL;
+ char *image = NULL, *tmp;
unsigned int bytes;
if ( (filename == NULL) || (size == NULL) )
@@ -43,33 +43,58 @@ char *xc_read_image(const char *filename
goto out;
}
- if ( (*size = xc_get_filesz(kernel_fd)) == 0 )
- {
- PERROR("Could not read kernel image");
- goto out;
- }
-
if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
{
PERROR("Could not allocate decompression state for state file");
goto out;
}
- if ( (image = malloc(*size)) == NULL )
- {
- PERROR("Could not allocate memory for kernel image");
- goto out;
- }
-
- if ( (bytes = gzread(kernel_gfd, image, *size)) != *size )
- {
- PERROR("Error reading kernel image, could not"
- " read the whole image (%d != %ld).", bytes, *size);
- free(image);
- image = NULL;
- }
+ *size = 0;
+
+#define CHUNK 1*1024*1024
+ while(1)
+ {
+ if ( (tmp = realloc(image, *size + CHUNK)) == NULL )
+ {
+ PERROR("Could not allocate memory for kernel image");
+ free(image);
+ image = NULL;
+ goto out;
+ }
+ image = tmp;
+
+ bytes = gzread(kernel_gfd, image + *size, CHUNK);
+ switch (bytes)
+ {
+ case -1:
+ PERROR("Error reading kernel image");
+ free(image);
+ image = NULL;
+ goto out;
+ case 0: /* EOF */
+ goto out;
+ default:
+ *size += bytes;
+ break;
+ }
+ }
+#undef CHUNK
out:
+ if ( *size == 0 )
+ {
+ PERROR("Could not read kernel image");
+ free(image);
+ image = NULL;
+ }
+ else if ( image )
+ {
+ /* Shrink allocation to fit image. */
+ tmp = realloc(image, *size);
+ if ( tmp )
+ image = tmp;
+ }
+
if ( kernel_gfd != NULL )
gzclose(kernel_gfd);
else if ( kernel_fd >= 0 )
@@ -171,7 +196,6 @@ __attribute__((weak)) int xc_hvm_build(
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
- unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn)
{
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xg_private.h Fri Nov 10 11:11:04 2006 -0700
@@ -193,8 +193,6 @@ int xc_copy_to_domain_page(int xc_handle
int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
unsigned long dst_pfn, const char *src_page);
-unsigned long xc_get_filesz(int fd);
-
void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
int xch, uint32_t dom, xen_pfn_t *parray,
unsigned long vstart);
diff -r 11b718eb22c9 -r ebed72718263 tools/pygrub/setup.py
--- a/tools/pygrub/setup.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/pygrub/setup.py Fri Nov 10 11:11:04 2006 -0700
@@ -3,48 +3,27 @@ import os
import os
import sys
-extra_compile_args = [ "-fno-strict-aliasing", "-Wall", "-Werror" ]
+extra_compile_args = [ "-fno-strict-aliasing", "-Werror" ]
-fsys_mods = []
-fsys_pkgs = []
+XEN_ROOT = "../.."
-if os.path.exists("/usr/include/ext2fs/ext2_fs.h"):
- ext2defines = []
- cc = new_compiler()
- cc.add_library("ext2fs")
- if hasattr(cc, "has_function") and cc.has_function("ext2fs_open2"):
- ext2defines.append( ("HAVE_EXT2FS_OPEN2", None) )
- else:
- sys.stderr.write("WARNING: older version of e2fsprogs installed, not
building full\n")
- sys.stderr.write(" disk support for ext2.\n")
-
- ext2 = Extension("grub.fsys.ext2._pyext2",
- extra_compile_args = extra_compile_args,
- libraries = ["ext2fs"],
- define_macros = ext2defines,
- sources = ["src/fsys/ext2/ext2module.c"])
- fsys_mods.append(ext2)
- fsys_pkgs.append("grub.fsys.ext2")
+fsimage = Extension("fsimage",
+ extra_compile_args = extra_compile_args,
+ include_dirs = [ XEN_ROOT + "/tools/libfsimage/common/" ],
+ library_dirs = [ XEN_ROOT + "/tools/libfsimage/common/" ],
+ libraries = ["fsimage"],
+ sources = ["src/fsimage/fsimage.c"])
-if os.path.exists("/usr/include/reiserfs/reiserfs.h"):
- reiser = Extension("grub.fsys.reiser._pyreiser",
- extra_compile_args = extra_compile_args,
- libraries = ["reiserfs"],
- sources = ["src/fsys/reiser/reisermodule.c"])
- fsys_mods.append(reiser)
- fsys_pkgs.append("grub.fsys.reiser")
+pkgs = [ 'grub' ]
-pkgs = ['grub', 'grub.fsys']
-pkgs.extend(fsys_pkgs)
setup(name='pygrub',
version='0.3',
description='Boot loader that looks a lot like grub for Xen',
author='Jeremy Katz',
author_email='katzj@xxxxxxxxxx',
license='GPL',
- package_dir={'grub': 'src'},
+ package_dir={'grub': 'src', 'fsimage': 'src'},
scripts = ["src/pygrub"],
packages=pkgs,
- ext_modules = fsys_mods
+ ext_modules = [ fsimage ]
)
-
diff -r 11b718eb22c9 -r ebed72718263 tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/pygrub/src/pygrub Fri Nov 10 11:11:04 2006 -0700
@@ -22,8 +22,8 @@ import getopt
sys.path = [ '/usr/lib/python' ] + sys.path
+import fsimage
import grub.GrubConf
-import grub.fsys
PYGRUB_VER = 0.5
@@ -113,17 +113,21 @@ class GrubLineEditor(curses.textpad.Text
elif ch == curses.ascii.SOH: # ^a
self.pos = 0
elif ch in (curses.ascii.STX,curses.KEY_LEFT):
- self.pos -= 1
+ if self.pos > 0:
+ self.pos -= 1
elif ch in (curses.ascii.BS,curses.KEY_BACKSPACE):
if self.pos > 0:
self.pos -= 1
+ if self.pos < len(self.line):
+ self.line.pop(self.pos)
+ elif ch == curses.ascii.EOT: # ^d
+ if self.pos < len(self.line):
self.line.pop(self.pos)
- elif ch == curses.ascii.EOT: # ^d
- self.line.pop(self.pos)
elif ch == curses.ascii.ENQ: # ^e
self.pos = len(self.line)
elif ch in (curses.ascii.ACK, curses.KEY_RIGHT):
- self.pos +=1
+ if self.pos < len(self.line):
+ self.pos +=1
elif ch == curses.ascii.VT: # ^k
self.line = self.line[:self.pos]
else:
@@ -313,25 +317,21 @@ class Grub:
raise RuntimeError, "Unable to find active partition on disk"
# open the image and read the grub config
- fs = None
- for fstype in grub.fsys.fstypes.values():
- if fstype.sniff_magic(fn, offset):
- fs = fstype.open_fs(fn, offset)
- break
+ fs = fsimage.open(fn, offset)
if fs is not None:
grubfile = None
for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
"/grub/menu.lst", "/grub/grub.conf"):
- if fs.file_exist(f):
+ if fs.file_exists(f):
grubfile = f
break
if grubfile is None:
raise RuntimeError, "we couldn't find grub config file in the
image provided."
f = fs.open_file(grubfile)
buf = f.read()
- f.close()
- fs.close()
+ del f
+ del fs
# then parse the grub config
self.cf.parse(buf)
else:
@@ -511,14 +511,7 @@ if __name__ == "__main__":
raise RuntimeError, "Unable to find active partition on disk"
# read the kernel and initrd onto the hostfs
- fs = None
- for fstype in grub.fsys.fstypes.values():
- if fstype.sniff_magic(file, offset):
- fs = fstype.open_fs(file, offset)
- break
-
- if fs is None:
- raise RuntimeError, "Unable to open filesystem"
+ fs = fsimage.open(file, offset)
kernel = fs.open_file(img.kernel[1],).read()
(tfd, fn) = tempfile.mkstemp(prefix="vmlinuz.", dir="/var/lib/xen")
diff -r 11b718eb22c9 -r ebed72718263 tools/python/setup.py
--- a/tools/python/setup.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/setup.py Fri Nov 10 11:11:04 2006 -0700
@@ -4,8 +4,7 @@ import os
XEN_ROOT = "../.."
-extra_compile_args = [ "-fno-strict-aliasing", "-Wall", "-Werror" ]
-
+extra_compile_args = [ "-fno-strict-aliasing", "-Werror" ]
include_dirs = [ XEN_ROOT + "/tools/libxc",
XEN_ROOT + "/tools/xenstore",
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Nov 10 11:11:04 2006 -0700
@@ -65,18 +65,17 @@ static PyObject *pyxc_domain_create(XcOb
PyObject *args,
PyObject *kwds)
{
- uint32_t dom = 0;
- int ret, i;
- uint32_t ssidref = 0;
+ uint32_t dom = 0, ssidref = 0, flags = 0;
+ int ret, i, hvm = 0;
PyObject *pyhandle = NULL;
xen_domain_handle_t handle = {
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
- static char *kwd_list[] = { "dom", "ssidref", "handle", NULL };
-
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiO", kwd_list,
- &dom, &ssidref, &pyhandle))
+ static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
+ &dom, &ssidref, &pyhandle, &hvm))
return NULL;
if ( pyhandle != NULL )
@@ -94,7 +93,11 @@ static PyObject *pyxc_domain_create(XcOb
}
}
- if ( (ret = xc_domain_create(self->xc_handle, ssidref, handle, &dom)) < 0 )
+ if ( hvm )
+ flags |= XEN_DOMCTL_CDF_hvm_guest;
+
+ if ( (ret = xc_domain_create(self->xc_handle, ssidref,
+ handle, flags, &dom)) < 0 )
return PyErr_SetFromErrno(xc_error);
return PyInt_FromLong(dom);
@@ -144,7 +147,7 @@ static PyObject *pyxc_vcpu_setaffinity(X
uint64_t cpumap = ~0ULL;
PyObject *cpulist = NULL;
- static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL };
+ static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list,
&dom, &vcpu, &cpulist) )
@@ -171,7 +174,7 @@ static PyObject *pyxc_domain_setcpuweigh
uint32_t dom;
float cpuweight = 1;
- static char *kwd_list[] = { "dom", "cpuweight", NULL };
+ static char *kwd_list[] = { "domid", "cpuweight", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
&dom, &cpuweight) )
@@ -254,11 +257,12 @@ static PyObject *pyxc_domain_getinfo(XcO
PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
- info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
+ info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
",s:l,s:L,s:l,s:i,s:i}",
- "dom", info[i].domid,
+ "domid", info[i].domid,
"online_vcpus", info[i].nr_online_vcpus,
"max_vcpu_id", info[i].max_vcpu_id,
+ "hvm", info[i].hvm,
"dying", info[i].dying,
"crashed", info[i].crashed,
"shutdown", info[i].shutdown,
@@ -291,7 +295,7 @@ static PyObject *pyxc_vcpu_getinfo(XcObj
int rc, i;
uint64_t cpumap;
- static char *kwd_list[] = { "dom", "vcpu", NULL };
+ static char *kwd_list[] = { "domid", "vcpu", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
&dom, &vcpu) )
@@ -331,24 +335,25 @@ static PyObject *pyxc_linux_build(XcObje
char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
int flags = 0;
int store_evtchn, console_evtchn;
+ unsigned int mem_mb;
unsigned long store_mfn = 0;
unsigned long console_mfn = 0;
- static char *kwd_list[] = { "dom", "store_evtchn",
+ static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
"console_evtchn", "image",
/* optional */
"ramdisk", "cmdline", "flags",
"features", NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssis", kwd_list,
- &dom, &store_evtchn,
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list,
+ &dom, &store_evtchn, &mem_mb,
&console_evtchn, &image,
/* optional */
&ramdisk, &cmdline, &flags,
&features) )
return NULL;
- if ( xc_linux_build(self->xc_handle, dom, image,
+ if ( xc_linux_build(self->xc_handle, dom, mem_mb, image,
ramdisk, cmdline, features, flags,
store_evtchn, &store_mfn,
console_evtchn, &console_mfn) != 0 ) {
@@ -372,19 +377,18 @@ static PyObject *pyxc_hvm_build(XcObject
int vcpus = 1;
int pae = 0;
int acpi = 0;
- int apic = 0;
unsigned long store_mfn = 0;
- static char *kwd_list[] = { "dom", "store_evtchn", "memsize", "image",
- "vcpus", "pae", "acpi", "apic",
- NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisiiii", kwd_list,
+ static char *kwd_list[] = { "domid", "store_evtchn",
+ "memsize", "image", "vcpus", "pae", "acpi",
+ NULL };
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisiii", kwd_list,
&dom, &store_evtchn, &memsize,
- &image, &vcpus, &pae, &acpi, &apic) )
+ &image, &vcpus, &pae, &acpi) )
return NULL;
if ( xc_hvm_build(self->xc_handle, dom, memsize, image,
- vcpus, pae, acpi, apic, store_evtchn, &store_mfn) != 0 )
+ vcpus, pae, acpi, store_evtchn, &store_mfn) != 0 )
return PyErr_SetFromErrno(xc_error);
return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
@@ -397,7 +401,7 @@ static PyObject *pyxc_evtchn_alloc_unbou
uint32_t dom, remote_dom;
int port;
- static char *kwd_list[] = { "dom", "remote_dom", NULL };
+ static char *kwd_list[] = { "domid", "remote_dom", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
&dom, &remote_dom) )
@@ -416,7 +420,7 @@ static PyObject *pyxc_physdev_pci_access
uint32_t dom;
int bus, dev, func, enable, ret;
- static char *kwd_list[] = { "dom", "bus", "dev", "func", "enable", NULL };
+ static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL
};
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
&dom, &bus, &dev, &func, &enable) )
@@ -557,7 +561,7 @@ static PyObject *pyxc_sedf_domain_set(Xc
uint32_t domid;
uint64_t period, slice, latency;
uint16_t extratime, weight;
- static char *kwd_list[] = { "dom", "period", "slice",
+ static char *kwd_list[] = { "domid", "period", "slice",
"latency", "extratime", "weight",NULL };
if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
@@ -586,7 +590,7 @@ static PyObject *pyxc_sedf_domain_get(Xc
return PyErr_SetFromErrno(xc_error);
return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
- "domain", domid,
+ "domid", domid,
"period", period,
"slice", slice,
"latency", latency,
@@ -647,6 +651,15 @@ static PyObject *pyxc_shadow_mem_control
return Py_BuildValue("i", mbarg);
}
+static PyObject *pyxc_sched_id_get(XcObject *self) {
+
+ int sched_id;
+ if (xc_sched_id(self->xc_handle, &sched_id) != 0)
+ return PyErr_SetFromErrno(xc_error);
+
+ return Py_BuildValue("i", sched_id);
+}
+
static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
PyObject *args,
PyObject *kwds)
@@ -654,7 +667,7 @@ static PyObject *pyxc_sched_credit_domai
uint32_t domid;
uint16_t weight;
uint16_t cap;
- static char *kwd_list[] = { "dom", "weight", "cap", NULL };
+ static char *kwd_list[] = { "domid", "weight", "cap", NULL };
static char kwd_type[] = "I|HH";
struct xen_domctl_sched_credit sdom;
@@ -714,7 +727,7 @@ static PyObject *pyxc_domain_memory_incr
unsigned int extent_order = 0 , address_bits = 0;
unsigned long nr_extents;
- static char *kwd_list[] = { "dom", "mem_kb", "extent_order",
"address_bits", NULL };
+ static char *kwd_list[] = { "domid", "mem_kb", "extent_order",
"address_bits", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list,
&dom, &mem_kb, &extent_order,
&address_bits) )
@@ -739,7 +752,7 @@ static PyObject *pyxc_domain_ioport_perm
uint32_t dom;
int first_port, nr_ports, allow_access, ret;
- static char *kwd_list[] = { "dom", "first_port", "nr_ports",
"allow_access", NULL };
+ static char *kwd_list[] = { "domid", "first_port", "nr_ports",
"allow_access", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
&dom, &first_port, &nr_ports,
&allow_access) )
@@ -762,7 +775,7 @@ static PyObject *pyxc_domain_irq_permiss
uint32_t dom;
int pirq, allow_access, ret;
- static char *kwd_list[] = { "dom", "pirq", "allow_access", NULL };
+ static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
&dom, &pirq, &allow_access) )
@@ -785,7 +798,7 @@ static PyObject *pyxc_domain_iomem_permi
uint32_t dom;
unsigned long first_pfn, nr_pfns, allow_access, ret;
- static char *kwd_list[] = { "dom", "first_pfn", "nr_pfns", "allow_access",
NULL };
+ static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns",
"allow_access", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
&dom, &first_pfn, &nr_pfns,
&allow_access) )
@@ -975,6 +988,12 @@ static PyMethodDef pyxc_methods[] = {
" image [str]: Name of HVM loader image file.\n"
" vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
+
+ { "sched_id_get",
+ (PyCFunction)pyxc_sched_id_get,
+ METH_NOARGS, "\n"
+ "Get the current scheduler type in use.\n"
+ "Returns: [int] sched_id.\n" },
{ "sedf_domain_set",
(PyCFunction)pyxc_sedf_domain_set,
@@ -1242,6 +1261,11 @@ PyMODINIT_FUNC initxc(void)
Py_INCREF(xc_error);
PyModule_AddObject(m, "Error", xc_error);
+
+ /* Expose some libxc constants to Python */
+ PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
+ PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
+
}
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/util/blkif.py
--- a/tools/python/xen/util/blkif.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/util/blkif.py Fri Nov 10 11:11:04 2006 -0700
@@ -21,11 +21,17 @@ def blkdev_name_to_number(name):
try:
return os.stat(n).st_rdev
except Exception, ex:
- log.debug("exception looking up device number for %s: %s", name, ex)
pass
- if re.match( '/dev/sd[a-p]([1-9]|1[0-5])?', n):
- return 8 * 256 + 16 * (ord(n[7:8]) - ord('a')) + int(n[8:] or 0)
+ scsi_major = [ 8, 65, 66, 67, 68, 69, 70, 71, 128, 129, 130, 131, 132,
133, 134, 135 ]
+ if re.match( '/dev/sd[a-z]([1-9]|1[0-5])?$', n):
+ major = scsi_major[(ord(n[7:8]) - ord('a')) / 16]
+ minor = ((ord(n[7:8]) - ord('a')) % 16) * 16 + int(n[8:] or 0)
+ return major * 256 + minor
+ if re.match( '/dev/sd[a-i][a-z]([1-9]|1[0-5])?$', n):
+ major = scsi_major[((ord(n[7:8]) - ord('a') + 1) * 26 + (ord(n[8:9]) -
ord('a'))) / 16 ]
+ minor = (((ord(n[7:8]) - ord('a') + 1 ) * 26 + (ord(n[8:9]) -
ord('a'))) % 16) * 16 + int(n[9:] or 0)
+ return major * 256 + minor
if re.match( '/dev/hd[a-t]([1-9]|[1-5][0-9]|6[0-3])?', n):
ide_majors = [ 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 ]
@@ -53,7 +59,7 @@ def blkdev_segment(name):
"""
val = None
n = blkdev_name_to_number(name)
- if n:
+ if not n is None:
val = { 'device' : n,
'start_sector' : long(0),
'nr_sectors' : long(1L<<63),
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/util/xmlrpclib2.py Fri Nov 10 11:11:04 2006 -0700
@@ -21,11 +21,11 @@ An enhanced XML-RPC client/server interf
"""
import string
-import types
import fcntl
+from types import *
+
from httplib import HTTPConnection, HTTP
-from xmlrpclib import Transport
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import SocketServer
import xmlrpclib, socket, os, stat
@@ -39,6 +39,23 @@ except ImportError:
# SSHTransport is disabled on Python <2.4, because it uses the subprocess
# package.
ssh_enabled = False
+
+#
+# Convert all integers to strings as described in the Xen API
+#
+
+
+def stringify(value):
+ if isinstance(value, IntType) and not isinstance(value, BooleanType):
+ return str(value)
+ elif isinstance(value, DictType):
+ for k, v in value.items():
+ value[k] = stringify(v)
+ return value
+ elif isinstance(value, (TupleType, ListType)):
+ return [stringify(v) for v in value]
+ else:
+ return value
# A new ServerProxy that also supports httpu urls. An http URL comes in the
@@ -81,18 +98,18 @@ class HTTPUnix(HTTP):
class HTTPUnix(HTTP):
_connection_class = HTTPUnixConnection
-class UnixTransport(Transport):
+class UnixTransport(xmlrpclib.Transport):
def request(self, host, handler, request_body, verbose=0):
self.__handler = handler
- return Transport.request(self, host, '/RPC2', request_body, verbose)
+ return xmlrpclib.Transport.request(self, host, '/RPC2',
+ request_body, verbose)
def make_connection(self, host):
return HTTPUnix(self.__handler)
# See _marshalled_dispatch below.
def conv_string(x):
- if (isinstance(x, types.StringType) or
- isinstance(x, unicode)):
+ if isinstance(x, StringTypes):
s = string.replace(x, "'", r"\047")
exec "s = '" + s + "'"
return s
@@ -134,7 +151,7 @@ class TCPXMLRPCServer(SocketServer.Threa
allow_reuse_address = True
def __init__(self, addr, requestHandler=XMLRPCRequestHandler,
- logRequests=1):
+ logRequests = 1):
SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests)
flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
@@ -169,8 +186,7 @@ class TCPXMLRPCServer(SocketServer.Threa
# to transmit the string using Python encoding.
# Thanks to David Mertz <mertz@xxxxxxxxx> for the trick (buried
# in xml_pickle.py).
- if (isinstance(response, types.StringType) or
- isinstance(response, unicode)):
+ if isinstance(response, StringTypes):
response = repr(response)[1:-1]
response = (response,)
@@ -201,7 +217,7 @@ class UnixXMLRPCServer(TCPXMLRPCServer):
class UnixXMLRPCServer(TCPXMLRPCServer):
address_family = socket.AF_UNIX
- def __init__(self, addr, logRequests):
+ def __init__(self, addr, logRequests = 1):
parent = os.path.dirname(addr)
if os.path.exists(parent):
os.chown(parent, os.geteuid(), os.getegid())
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/Args.py
--- a/tools/python/xen/xend/Args.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/Args.py Fri Nov 10 11:11:04 2006 -0700
@@ -18,7 +18,7 @@ import types
import types
import StringIO
-import sxp
+from xen.xend import sxp
class ArgError(StandardError):
pass
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/PrettyPrint.py
--- a/tools/python/xen/xend/PrettyPrint.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/PrettyPrint.py Fri Nov 10 11:11:04 2006 -0700
@@ -22,7 +22,7 @@ import sys
import sys
import types
import StringIO
-import sxp
+from xen.xend import sxp
class PrettyItem:
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/XendBootloader.py Fri Nov 10 11:11:04 2006 -0700
@@ -14,8 +14,8 @@
import os, select, errno
import random
-import sxp
import shlex
+from xen.xend import sxp
from XendLogging import log
from XendError import VmError
@@ -38,7 +38,7 @@ def bootloader(blexec, disk, quiet = 0,
raise VmError(msg)
while True:
- fifo = "/var/lib/xen/xenbl.%s" %(random.randint(0, 32000),)
+ fifo = "/var/lib/xen/xenbl.%s" % random.randint(0, 32000)
if not os.path.exists(fifo):
break
os.mkfifo(fifo, 0600)
@@ -48,7 +48,7 @@ def bootloader(blexec, disk, quiet = 0,
args = [ blexec ]
if quiet:
args.append("-q")
- args.append("--output=%s" %(fifo,))
+ args.append("--output=%s" % fifo)
if blargs is not None:
args.extend(shlex.split(blargs))
args.append(disk)
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/XendCheckpoint.py Fri Nov 10 11:11:04 2006 -0700
@@ -8,21 +8,18 @@ import os
import os
import re
import string
-import sxp
import threading
from struct import pack, unpack, calcsize
from xen.util.xpopen import xPopen3
-
import xen.util.auxbin
-
import xen.lowlevel.xc
-import balloon
-from XendError import XendError
-from XendLogging import log
-from XendDomainInfo import DEV_MIGRATE_STEP1, DEV_MIGRATE_STEP2
-from XendDomainInfo import DEV_MIGRATE_STEP3
+from xen.xend import balloon, sxp
+from xen.xend.XendError import XendError
+from xen.xend.XendLogging import log
+from xen.xend.XendConstants import *
+from xen.xend.XendConfig import XendConfig
SIGNATURE = "LinuxGuestRecord"
XC_SAVE = "xc_save"
@@ -43,13 +40,13 @@ def read_exact(fd, size, errmsg):
def read_exact(fd, size, errmsg):
buf = ''
while size != 0:
- str = os.read(fd, size)
- if not len(str):
+ readstr = os.read(fd, size)
+ if not len(readstr):
log.error("read_exact: EOF trying to read %d (buf='%s')" % \
(size, buf))
raise XendError(errmsg)
- size = size - len(str)
- buf = buf + str
+ size = size - len(readstr)
+ buf = buf + readstr
return buf
@@ -111,7 +108,7 @@ def save(fd, dominfo, network, live, dst
raise Exception, exn
-def restore(xd, fd):
+def restore(xd, fd, dominfo = None):
signature = read_exact(fd, len(SIGNATURE),
"not a valid guest state file: signature read")
if signature != SIGNATURE:
@@ -131,7 +128,11 @@ def restore(xd, fd):
vmconfig = p.get_val()
- dominfo = xd.restore_(vmconfig)
+ if dominfo:
+ dominfo.update(XendConfig(sxp = vmconfig), refresh = False)
+ dominfo.resume()
+ else:
+ dominfo = xd.restore_(vmconfig)
store_port = dominfo.getStorePort()
console_port = dominfo.getConsolePort()
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/XendDomain.py Fri Nov 10 11:11:04 2006 -0700
@@ -22,45 +22,60 @@
Needs to be persistent for one uptime.
"""
-import logging
import os
+import shutil
import socket
-import sys
import threading
import xen.lowlevel.xc
-import XendDomainInfo
-
-from xen.xend import XendRoot
-from xen.xend import XendCheckpoint
+
+from xen.xend import XendRoot, XendCheckpoint, XendDomainInfo
+from xen.xend.PrettyPrint import prettyprint
+from xen.xend.XendConfig import XendConfig
from xen.xend.XendError import XendError, XendInvalidDomain
from xen.xend.XendLogging import log
+from xen.xend.XendConstants import XS_VMROOT
+from xen.xend.XendConstants import DOM_STATE_HALTED, DOM_STATE_RUNNING
+
from xen.xend.xenstore.xstransact import xstransact
from xen.xend.xenstore.xswatch import xswatch
from xen.util import security
-
+from xen.xend import uuid
xc = xen.lowlevel.xc.xc()
-xroot = XendRoot.instance()
-
+xroot = XendRoot.instance()
__all__ = [ "XendDomain" ]
-PRIV_DOMAIN = 0
-VMROOT = '/vm/'
-
+CACHED_CONFIG_FILE = 'config.sxp'
+CHECK_POINT_FILE = 'checkpoint.chk'
+DOM0_UUID = "00000000-0000-0000-0000-000000000000"
+DOM0_NAME = "Domain-0"
+DOM0_ID = 0
class XendDomain:
"""Index of all domains. Singleton.
+
+ @ivar domains: map of domains indexed by domid
+ @type domains: dict of XendDomainInfo
+ @ivar managed_domains: domains that are not running and managed by Xend
+ @type managed_domains: dict of XendDomainInfo indexed by uuid
+ @ivar domains_lock: lock that must be held when manipulating self.domains
+ @type domains_lock: threaading.RLock
+ @ivar _allow_new_domains: Flag to set that allows creating of new domains.
+ @type _allow_new_domains: boolean
+
"""
- ## public:
-
def __init__(self):
self.domains = {}
+ self.managed_domains = {}
self.domains_lock = threading.RLock()
+ # xen api instance vars
+ # TODO: nothing uses this at the moment
+ self._allow_new_domains = True
# This must be called only the once, by instance() below. It is separate
# from the constructor because XendDomainInfo calls back into this class
@@ -68,85 +83,277 @@ class XendDomain:
# instance() must be able to return a valid instance of this class even
# during this initialisation.
def init(self):
- xstransact.Mkdir(VMROOT)
- xstransact.SetPermissions(VMROOT, { 'dom' : PRIV_DOMAIN })
-
- self.domains_lock.acquire()
- try:
- self._add_domain(
- XendDomainInfo.recreate(self.xen_domains()[PRIV_DOMAIN],
- True))
- self.dom0_setup()
+ """Singleton initialisation function."""
+
+ dom_path = self._managed_path()
+ try:
+ os.stat(dom_path)
+ except OSError:
+ log.info("Making %s", dom_path)
+ os.makedirs(dom_path, 0755)
+
+ xstransact.Mkdir(XS_VMROOT)
+ xstransact.SetPermissions(XS_VMROOT, {'dom': DOM0_ID})
+
+ self.domains_lock.acquire()
+ try:
+ try:
+ dom0info = [d for d in self._running_domains() \
+ if d.get('domid') == DOM0_ID][0]
+
+ dom0info['name'] = DOM0_NAME
+ dom0 = XendDomainInfo.recreate(dom0info, True)
+ self._add_domain(dom0)
+ except IndexError:
+ raise XendError('Unable to find Domain 0')
+
+ self._setDom0CPUCount()
# This watch registration needs to be before the refresh call, so
# that we're sure that we haven't missed any releases, but inside
# the domains_lock, as we don't want the watch to fire until after
# the refresh call has completed.
- xswatch("@introduceDomain", self.onChangeDomain)
- xswatch("@releaseDomain", self.onChangeDomain)
+ xswatch("@introduceDomain", self._on_domains_changed)
+ xswatch("@releaseDomain", self._on_domains_changed)
+
+ self._init_domains()
+ finally:
+ self.domains_lock.release()
+
+
+ def _on_domains_changed(self, _):
+ """ Callback method when xenstore changes.
+
+ Calls refresh which will keep the local cache of domains
+ in sync.
+
+ @rtype: int
+ @return: 1
+ """
+ self.domains_lock.acquire()
+ try:
+ self._refresh()
+ finally:
+ self.domains_lock.release()
+ return 1
+
+ def _init_domains(self):
+ """Does the initial scan of managed and active domains to
+ populate self.domains.
+
+ Note: L{XendDomainInfo._checkName} will call back into XendDomain
+ to make sure domain name is not a duplicate.
+
+ """
+ self.domains_lock.acquire()
+ try:
+ running = self._running_domains()
+ managed = self._managed_domains()
+
+ # add all active domains
+ for dom in running:
+ if dom['dying'] == 1:
+ log.warn('Ignoring dying domain %d from now on' %
+ dom['domid'])
+ continue
+
+ if dom['domid'] != DOM0_ID:
+ try:
+ new_dom = XendDomainInfo.recreate(dom, False)
+ self._add_domain(new_dom)
+ except Exception:
+ log.exception("Failed to create reference to running "
+ "domain id: %d" % dom['domid'])
+
+ # add all managed domains as dormant domains.
+ for dom in managed:
+ dom_uuid = dom.get('uuid')
+ if not dom_uuid:
+ continue
+
+ dom_name = dom.get('name', 'Domain-%s' % dom_uuid)
+ try:
+ running_dom = self.domain_lookup_nr(dom_name)
+ if not running_dom:
+ # instantiate domain if not started.
+ new_dom = XendDomainInfo.createDormant(dom)
+ self._managed_domain_register(new_dom)
+ else:
+ self._managed_domain_register(running_dom)
+ except Exception:
+ log.exception("Failed to create reference to managed "
+ "domain: %s" % dom_name)
+
+ finally:
+ self.domains_lock.release()
+
+
+ # -----------------------------------------------------------------
+ # Getting managed domains storage path names
+
+ def _managed_path(self, domuuid = None):
+ """Returns the path of the directory where managed domain
+ information is stored.
+
+ @keyword domuuid: If not None, will return the path to the domain
+ otherwise, will return the path containing
+ the directories which represent each domain.
+ @type: None or String.
+ @rtype: String
+ @return: Path.
+ """
+ dom_path = xroot.get_xend_domains_path()
+ if domuuid:
+ dom_path = os.path.join(dom_path, domuuid)
+ return dom_path
+
+ def _managed_config_path(self, domuuid):
+ """Returns the path to the configuration file of a managed domain.
+
+ @param domname: Domain uuid
+ @type domname: String
+ @rtype: String
+ @return: path to config file.
+ """
+ return os.path.join(self._managed_path(domuuid), CACHED_CONFIG_FILE)
+
+ def _managed_check_point_path(self, domuuid):
+ """Returns absolute path to check point file for managed domain.
+
+ @param domuuid: Name of managed domain
+ @type domname: String
+ @rtype: String
+ @return: Path
+ """
+ return os.path.join(self._managed_path(domuuid), CHECK_POINT_FILE)
+
+ def _managed_config_remove(self, domuuid):
+ """Removes a domain configuration from managed list
+
+ @param domuuid: Name of managed domain
+ @type domname: String
+ @raise XendError: fails to remove the domain.
+ """
+ config_path = self._managed_path(domuuid)
+ try:
+ if os.path.exists(config_path) and os.path.isdir(config_path):
+ shutil.rmtree(config_path)
+ except IOError:
+ log.exception('managed_config_remove failed removing conf')
+ raise XendError("Unable to remove managed configuration"
+ " for domain: %s" % domuuid)
+
+ def managed_config_save(self, dominfo):
+ """Save a domain's configuration to disk
+
+ @param domninfo: Managed domain to save.
+ @type dominfo: XendDomainInfo
+ @raise XendError: fails to save configuration.
+ @rtype: None
+ """
+ if not self.is_domain_managed(dominfo):
+ return # refuse to save configuration this domain isn't managed
+
+ if dominfo:
+ domains_dir = self._managed_path()
+ dom_uuid = dominfo.get_uuid()
+ domain_config_dir = self._managed_path(dom_uuid)
+
+ # make sure the domain dir exists
+ if not os.path.exists(domains_dir):
+ os.makedirs(domains_dir, 0755)
+ elif not os.path.isdir(domains_dir):
+ log.error("xend_domain_dir is not a directory.")
+ raise XendError("Unable to save managed configuration "
+ "because %s is not a directory." %
+ domains_dir)
- self.refresh(True)
- finally:
- self.domains_lock.release()
-
-
- def list(self):
- """Get list of domain objects.
-
- @return: domain objects
- """
- self.domains_lock.acquire()
- try:
- self.refresh()
- return self.domains.values()
- finally:
- self.domains_lock.release()
-
-
- def list_sorted(self):
- """Get list of domain objects, sorted by name.
-
- @return: domain objects
- """
- doms = self.list()
- doms.sort(lambda x, y: cmp(x.getName(), y.getName()))
+ if not os.path.exists(domain_config_dir):
+ try:
+ os.makedirs(domain_config_dir, 0755)
+ except IOError:
+ log.exception("Failed to create directory: %s" %
+ domain_config_dir)
+ raise XendError("Failed to create directory: %s" %
+ domain_config_dir)
+
+ try:
+ sxp_cache_file = open(self._managed_config_path(dom_uuid),'w')
+ prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78)
+ sxp_cache_file.close()
+ except IOError:
+ log.error("Error occurred saving configuration file to %s" %
+ domain_config_dir)
+ raise XendError("Failed to save configuration file to: %s" %
+ domain_config_dir)
+ else:
+ log.warn("Trying to save configuration for invalid domain")
+
+
+ def _managed_domains(self):
+ """ Returns list of domains that are managed.
+
+ Expects to be protected by domains_lock.
+
+ @rtype: list of XendConfig
+ @return: List of domain configurations that are managed.
+ """
+ dom_path = self._managed_path()
+ dom_uuids = os.listdir(dom_path)
+ doms = []
+ for dom_uuid in dom_uuids:
+ try:
+ cfg_file = self._managed_config_path(dom_uuid)
+ cfg = XendConfig(filename = cfg_file)
+ if cfg.get('uuid') != dom_uuid:
+ # something is wrong with the SXP
+ log.error("UUID mismatch in stored configuration: %s" %
+ cfg_file)
+ continue
+ doms.append(cfg)
+ except Exception:
+ log.exception('Unable to open or parse config.sxp: %s' % \
+ cfg_file)
return doms
- def list_names(self):
- """Get list of domain names.
-
- @return: domain names
- """
- doms = self.list_sorted()
- return map(lambda x: x.getName(), doms)
-
-
- ## private:
-
- def onChangeDomain(self, _):
- self.domains_lock.acquire()
- try:
- self.refresh()
- finally:
- self.domains_lock.release()
- return 1
-
-
- def xen_domains(self):
- """Get table of domains indexed by id from xc. Expects to be
- protected by the domains_lock.
- """
- domlist = xc.domain_getinfo()
- doms = {}
- for d in domlist:
- domid = d['dom']
- doms[domid] = d
- return doms
-
-
- def dom0_setup(self):
- """Expects to be protected by the domains_lock."""
- dom0 = self.domains[PRIV_DOMAIN]
+ def _managed_domain_unregister(self, dom):
+ try:
+ if self.is_domain_managed(dom):
+ self._managed_config_remove(dom.get_uuid())
+ del self.managed_domains[dom.get_uuid()]
+ except ValueError:
+ log.warn("Domain is not registered: %s" % dom.get_uuid())
+
+ def _managed_domain_register(self, dom):
+ self.managed_domains[dom.get_uuid()] = dom
+
+ def is_domain_managed(self, dom = None):
+ return (dom.get_uuid() in self.managed_domains)
+
+ # End of Managed Domain Access
+ # --------------------------------------------------------------------
+
+ def _running_domains(self):
+ """Get table of domains indexed by id from xc.
+
+ @requires: Expects to be protected by domains_lock.
+ @rtype: list of dicts
+ @return: A list of dicts representing the running domains.
+ """
+ try:
+ return xc.domain_getinfo()
+ except RuntimeError, e:
+ log.exception("Unable to get domain information.")
+ return {}
+
+ def _setDom0CPUCount(self):
+ """Sets the number of VCPUs dom0 has. Retreived from the
+ Xend configuration, L{XendRoot}.
+
+ @requires: Expects to be protected by domains_lock.
+ @rtype: None
+ """
+ dom0 = self.privilegedDomain()
# get max number of vcpus to use for dom0 from config
target = int(xroot.get_dom0_vcpus())
@@ -157,74 +364,441 @@ class XendDomain:
dom0.setVCpuCount(target)
+ def _refresh(self):
+ """Refresh the domain list. Needs to be called when
+ either xenstore has changed or when a method requires
+ up to date information (like uptime, cputime stats).
+
+ Expects to be protected by the domains_lock.
+
+ @rtype: None
+ """
+
+ # update information for all running domains
+ # - like cpu_time, status, dying, etc.
+ running = self._running_domains()
+ for dom in running:
+ domid = dom['domid']
+ if domid in self.domains and dom['dying'] != 1:
+ self.domains[domid].update(dom)
+
+ # remove domains that are not running from active domain list.
+ # The list might have changed by now, because the update call may
+ # cause new domains to be added, if the domain has rebooted. We get
+ # the list again.
+ running_domids = [d['domid'] for d in running if d['dying'] != 1]
+ for domid, dom in self.domains.items():
+ if domid not in running_domids and domid != DOM0_ID:
+ self._remove_domain(dom, domid)
+
+
def _add_domain(self, info):
- """Add the given domain entry to this instance's internal cache.
- Expects to be protected by the domains_lock.
- """
+ """Add a domain to the list of running domains
+
+ @requires: Expects to be protected by the domains_lock.
+ @param info: XendDomainInfo of a domain to be added.
+ @type info: XendDomainInfo
+ """
+ log.debug("Adding Domain: %s" % info.getDomid())
self.domains[info.getDomid()] = info
-
- def _delete_domain(self, domid):
- """Remove the given domain from this instance's internal cache.
- Expects to be protected by the domains_lock.
- """
- info = self.domains.get(domid)
+ def _remove_domain(self, info, domid = None):
+ """Remove the domain from the list of running domains
+
+ @requires: Expects to be protected by the domains_lock.
+ @param info: XendDomainInfo of a domain to be removed.
+ @type info: XendDomainInfo
+ """
+
if info:
- del self.domains[domid]
- info.cleanupDomain()
-
-
- def refresh(self, initialising = False):
- """Refresh domain list from Xen. Expects to be protected by the
- domains_lock.
-
- @param initialising True if this is the first refresh after starting
- Xend. This does not change this method's behaviour, except for
- logging.
- """
- doms = self.xen_domains()
- for d in self.domains.values():
- info = doms.get(d.getDomid())
- if info:
- d.update(info)
- else:
- self._delete_domain(d.getDomid())
- for d in doms:
- if d not in self.domains:
- if doms[d]['dying']:
- log.log(initialising and logging.ERROR or logging.DEBUG,
- 'Cannot recreate information for dying domain %d.'
- ' Xend will ignore this domain from now on.',
- doms[d]['dom'])
- elif d == PRIV_DOMAIN:
- log.fatal(
- "No record of privileged domain %d! Terminating.", d)
- sys.exit(1)
- else:
- try:
- self._add_domain(
- XendDomainInfo.recreate(doms[d], False))
- except:
- log.exception(
- "Failed to recreate information for domain "
- "%d. Destroying it in the hope of "
- "recovery.", d)
- try:
- xc.domain_destroy(d)
- except:
- log.exception('Destruction of %d failed.', d)
-
-
- ## public:
+ if domid == None:
+ domid = info.getDomid()
+
+ if info.state != DOM_STATE_HALTED:
+ info.cleanupDomain()
+
+ if domid in self.domains:
+ del self.domains[domid]
+ else:
+ log.warning("Attempted to remove non-existent domain.")
+
+ def restore_(self, config):
+ """Create a domain as part of the restore process. This is called
+ only from L{XendCheckpoint}.
+
+ A restore request comes into XendDomain through L{domain_restore}
+ or L{domain_restore_fd}. That request is
+ forwarded immediately to XendCheckpoint which, when it is ready, will
+ call this method. It is necessary to come through here rather than go
+ directly to L{XendDomainInfo.restore} because we need to
+ serialise the domain creation process, but cannot lock
+ domain_restore_fd as a whole, otherwise we will deadlock waiting for
+ the old domain to die.
+
+ @param config: Configuration of domain to restore
+ @type config: SXP Object (eg. list of lists)
+ """
+ self.domains_lock.acquire()
+ try:
+ security.refresh_ssidref(config)
+ dominfo = XendDomainInfo.restore(config)
+ self._add_domain(dominfo)
+ return dominfo
+ finally:
+ self.domains_lock.release()
+
+
+ def domain_lookup(self, domid):
+ """Look up given I{domid} in the list of managed and running
+ domains.
+
+ @note: Will cause a refresh before lookup up domains, for
+ a version that does not need to re-read xenstore
+ use L{domain_lookup_nr}.
+
+ @param domid: Domain ID or Domain Name.
+ @type domid: int or string
+ @return: Found domain.
+ @rtype: XendDomainInfo
+ @raise XendError: If domain is not found.
+ """
+ self.domains_lock.acquire()
+ try:
+ self._refresh()
+ dom = self.domain_lookup_nr(domid)
+ if not dom:
+ raise XendError("No domain named '%s'." % str(domid))
+ return dom
+ finally:
+ self.domains_lock.release()
+
+
+ def domain_lookup_nr(self, domid):
+ """Look up given I{domid} in the list of managed and running
+ domains.
+
+ @param domid: Domain ID or Domain Name.
+ @type domid: int or string
+ @return: Found domain.
+ @rtype: XendDomainInfo or None
+ """
+ self.domains_lock.acquire()
+ try:
+ # lookup by name
+ match = [dom for dom in self.domains.values() \
+ if dom.getName() == domid]
+ if match:
+ return match[0]
+
+ match = [dom for dom in self.managed_domains.values() \
+ if dom.getName() == domid]
+ if match:
+ return match[0]
+
+ # lookup by id
+ try:
+ if int(domid) in self.domains:
+ return self.domains[int(domid)]
+ except ValueError:
+ pass
+
+ # lookup by uuid for running domains
+ match = [dom for dom in self.domains.values() \
+ if dom.get_uuid() == domid]
+ if match:
+ return match[0]
+
+ # lookup by uuid for inactive managed domains
+ if domid in self.managed_domains:
+ return self.managed_domains[domid]
+
+ return None
+ finally:
+ self.domains_lock.release()
+
+ def privilegedDomain(self):
+ """ Get the XendDomainInfo of a dom0
+
+ @rtype: XendDomainInfo
+ """
+ self.domains_lock.acquire()
+ try:
+ return self.domains[DOM0_ID]
+ finally:
+ self.domains_lock.release()
+
+ def cleanup_domains(self):
+ """Clean up domains that are marked as autostop.
+ Should be called when Xend goes down. This is currently
+ called from L{xen.xend.servers.XMLRPCServer}.
+
+ """
+ log.debug('cleanup_domains')
+ self.domains_lock.acquire()
+ try:
+ for dom in self.domains.values():
+ if dom.getName() == DOM0_NAME:
+ continue
+
+ if dom.state == DOM_STATE_RUNNING:
+ shutdownAction = dom.info.get('on_xend_stop', 'ignore')
+ if shutdownAction == 'shutdown':
+ log.debug('Shutting down domain: %s' % dom.getName())
+ dom.shutdown("poweroff")
+ elif shutdownAction == 'suspend':
+ chkfile = self._managed_check_point_path(dom.getName())
+ self.domain_save(dom.domid, chkfile)
+ finally:
+ self.domains_lock.release()
+
+
+
+ # ----------------------------------------------------------------
+ # Xen API
+
+
+ def set_allow_new_domains(self, allow_new_domains):
+ self._allow_new_domains = allow_new_domains
+
+ def allow_new_domains(self):
+ return self._allow_new_domains
+
+ def get_domain_refs(self):
+ result = []
+ try:
+ self.domains_lock.acquire()
+ result = [d.get_uuid() for d in self.domains.values()]
+ result += self.managed_domains.keys()
+ return result
+ finally:
+ self.domains_lock.release()
+
+ def get_vm_by_uuid(self, vm_uuid):
+ self.domains_lock.acquire()
+ try:
+ for dom in self.domains.values():
+ if dom.get_uuid() == vm_uuid:
+ return dom
+
+ if vm_uuid in self.managed_domains:
+ return self.managed_domains[vm_uuid]
+
+ return None
+ finally:
+ self.domains_lock.release()
+
+ def get_vm_with_dev_uuid(self, klass, dev_uuid):
+ self.domains_lock.acquire()
+ try:
+ for dom in self.domains.values() + self.managed_domains.values():
+ if dom.has_device(klass, dev_uuid):
+ return dom
+ return None
+ finally:
+ self.domains_lock.release()
+
+ def get_dev_property_by_uuid(self, klass, dev_uuid, field):
+ self.domains_lock.acquire()
+ try:
+ dom = self.get_vm_with_dev_uuid(klass, dev_uuid)
+ if not dom:
+ return None
+
+ value = dom.get_device_property(klass, dev_uuid, field)
+ return value
+ except ValueError, e:
+ pass
+
+ return None
+
+ def is_valid_vm(self, vm_ref):
+ return (self.get_vm_by_uuid(vm_ref) != None)
+
+ def is_valid_dev(self, klass, dev_uuid):
+ return (self.get_vm_with_dev_uuid(klass, dev_uuid) != None)
+
+ def do_legacy_api_with_uuid(self, fn, vm_uuid, *args):
+ self.domains_lock.acquire()
+ try:
+ for domid, dom in self.domains.items():
+ if dom.get_uuid == vm_uuid:
+ return fn(domid, *args)
+
+ if vm_uuid in self.managed_domains:
+ domid = self.managed_domains[vm_uuid].getDomid()
+ if domid == None:
+ domid = self.managed_domains[vm_uuid].getName()
+ return fn(domid, *args)
+
+ raise XendInvalidDomain("Domain does not exist")
+ finally:
+ self.domains_lock.release()
+
+
+ def create_domain(self, xenapi_vm):
+ self.domains_lock.acquire()
+ try:
+ try:
+ xeninfo = XendConfig(xenapi_vm = xenapi_vm)
+ dominfo = XendDomainInfo.createDormant(xeninfo)
+ log.debug("Creating new managed domain: %s: %s" %
+ (dominfo.getName(), dominfo.get_uuid()))
+ self._managed_domain_register(dominfo)
+ self.managed_config_save(dominfo)
+ return dominfo.get_uuid()
+ except XendError, e:
+ raise
+ except Exception, e:
+ raise XendError(str(e))
+ finally:
+ self.domains_lock.release()
+
+ def rename_domain(self, dom, new_name):
+ self.domains_lock.acquire()
+ try:
+ old_name = dom.getName()
+ dom.setName(new_name)
+
+ finally:
+ self.domains_lock.release()
+
+
+ #
+ # End of Xen API
+ # ----------------------------------------------------------------
+
+ # ------------------------------------------------------------
+ # Xen Legacy API
+
+ def list(self):
+ """Get list of domain objects.
+
+ @return: domains
+ @rtype: list of XendDomainInfo
+ """
+ self.domains_lock.acquire()
+ try:
+ self._refresh()
+
+ # active domains
+ active_domains = self.domains.values()
+ active_uuids = [d.get_uuid() for d in active_domains]
+
+ # inactive domains
+ inactive_domains = []
+ for dom_uuid, dom in self.managed_domains.items():
+ if dom_uuid not in active_uuids:
+ inactive_domains.append(dom)
+
+ return active_domains + inactive_domains
+ finally:
+ self.domains_lock.release()
+
+
+ def list_sorted(self):
+ """Get list of domain objects, sorted by name.
+
+ @return: domain objects
+ @rtype: list of XendDomainInfo
+ """
+ doms = self.list()
+ doms.sort(lambda x, y: cmp(x.getName(), y.getName()))
+ return doms
+
+ def list_names(self):
+ """Get list of domain names.
+
+ @return: domain names
+ @rtype: list of strings.
+ """
+ return [d.getName() for d in self.list_sorted()]
+
+ def domain_suspend(self, domname):
+ """Suspends a domain that is persistently managed by Xend
+
+ @param domname: Domain Name
+ @type domname: string
+ @rtype: None
+ @raise XendError: Failure during checkpointing.
+ """
+
+ try:
+ dominfo = self.domain_lookup_nr(domname)
+ if not dominfo:
+ raise XendInvalidDomain(domname)
+
+ if dominfo.getDomid() == DOM0_ID:
+ raise XendError("Cannot save privileged domain %s" % domname)
+
+ if dominfo.state != DOM_STATE_RUNNING:
+ raise XendError("Cannot suspend domain that is not running.")
+
+ if not os.path.exists(self._managed_config_path(domname)):
+ raise XendError("Domain is not managed by Xend lifecycle " +
+ "support.")
+
+ path = self._managed_check_point_path(domname)
+ fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
+ try:
+ # For now we don't support 'live checkpoint'
+ XendCheckpoint.save(fd, dominfo, False, False, path)
+ finally:
+ os.close(fd)
+ except OSError, ex:
+ raise XendError("can't write guest state file %s: %s" %
+ (path, ex[1]))
+
+ def domain_resume(self, domname):
+ """Resumes a domain that is persistently managed by Xend.
+
+ @param domname: Domain Name
+ @type domname: string
+ @rtype: None
+ @raise XendError: If failed to restore.
+ """
+ try:
+ dominfo = self.domain_lookup_nr(domname)
+
+ if not dominfo:
+ raise XendInvalidDomain(domname)
+
+ if dominfo.getDomid() == DOM0_ID:
+ raise XendError("Cannot save privileged domain %s" % domname)
+
+ if dominfo.state != DOM_STATE_HALTED:
+ raise XendError("Cannot suspend domain that is not running.")
+
+ chkpath = self._managed_check_point_path(domname)
+ if not os.path.exists(chkpath):
+ raise XendError("Domain was not suspended by Xend")
+
+ # Restore that replaces the existing XendDomainInfo
+ try:
+ log.debug('Current DomainInfo state: %d' % dominfo.state)
+ XendCheckpoint.restore(self,
+ os.open(chkpath, os.O_RDONLY),
+ dominfo)
+ os.unlink(chkpath)
+ except OSError, ex:
+ raise XendError("Failed to read stored checkpoint file")
+ except IOError, ex:
+ raise XendError("Failed to delete checkpoint file")
+ except Exception, ex:
+ log.exception("Exception occurred when resuming")
+ raise XendError("Error occurred when resuming: %s" % str(ex))
+
def domain_create(self, config):
"""Create a domain from a configuration.
@param config: configuration
- @return: domain
- """
- self.domains_lock.acquire()
- try:
+ @type config: SXP Object (list of lists)
+ @rtype: XendDomainInfo
+ """
+ self.domains_lock.acquire()
+ try:
+ self._refresh()
+
dominfo = XendDomainInfo.create(config)
self._add_domain(dominfo)
self.domain_sched_credit_set(dominfo.getDomid(),
@@ -235,10 +809,91 @@ class XendDomain:
self.domains_lock.release()
+ def domain_new(self, config):
+ """Create a domain from a configuration but do not start it.
+
+ @param config: configuration
+ @type config: SXP Object (list of lists)
+ @rtype: XendDomainInfo
+ """
+ self.domains_lock.acquire()
+ try:
+ try:
+ xeninfo = XendConfig(sxp = config)
+ dominfo = XendDomainInfo.createDormant(xeninfo)
+ log.debug("Creating new managed domain: %s" %
+ dominfo.getName())
+ self._managed_domain_register(dominfo)
+ self.managed_config_save(dominfo)
+ # no return value because it isn't meaningful for client
+ except XendError, e:
+ raise
+ except Exception, e:
+ raise XendError(str(e))
+ finally:
+ self.domains_lock.release()
+
+ def domain_start(self, domid):
+ """Start a managed domain
+
+ @require: Domain must not be running.
+ @param domid: Domain name or domain ID.
+ @type domid: string or int
+ @rtype: None
+ @raise XendError: If domain is still running
+ @rtype: None
+ """
+ self.domains_lock.acquire()
+ try:
+ self._refresh()
+
+ dominfo = self.domain_lookup_nr(domid)
+ if not dominfo:
+ raise XendInvalidDomain(str(domid))
+
+ if dominfo.state != DOM_STATE_HALTED:
+ raise XendError("Domain is already running")
+
+ dominfo.start(is_managed = True)
+ self._add_domain(dominfo)
+ finally:
+ self.domains_lock.release()
+
+
+ def domain_delete(self, domid):
+ """Remove a managed domain from database
+
+ @require: Domain must not be running.
+ @param domid: Domain name or domain ID.
+ @type domid: string or int
+ @rtype: None
+ @raise XendError: If domain is still running
+ """
+ self.domains_lock.acquire()
+ try:
+ try:
+ dominfo = self.domain_lookup_nr(domid)
+ if not dominfo:
+ raise XendInvalidDomain(str(domid))
+
+ if dominfo.state != DOM_STATE_HALTED:
+ raise XendError("Domain is still running")
+
+ self._managed_domain_unregister(dominfo)
+ self._remove_domain(dominfo)
+
+ except Exception, ex:
+ raise XendError(str(ex))
+ finally:
+ self.domains_lock.release()
+
+
def domain_configure(self, config):
"""Configure an existing domain.
@param vmconfig: vm configuration
+ @type vmconfig: SXP Object (list of lists)
+ @todo: Not implemented
"""
# !!!
raise XendError("Unsupported")
@@ -246,9 +901,12 @@ class XendDomain:
def domain_restore(self, src):
"""Restore a domain from file.
- @param src: source file
- """
-
+ @param src: filename of checkpoint file to restore from
+ @type src: string
+ @return: Restored domain
+ @rtype: XendDomainInfo
+ @raise XendError: Failure to restore domain
+ """
try:
fd = os.open(src, os.O_RDONLY)
try:
@@ -260,7 +918,13 @@ class XendDomain:
(src, ex[1]))
def domain_restore_fd(self, fd):
- """Restore a domain from the given file descriptor."""
+ """Restore a domain from the given file descriptor.
+
+ @param fd: file descriptor of the checkpoint file
+ @type fd: File object
+ @rtype: XendDomainInfo
+ @raise XendError: if failed to restore
+ """
try:
return XendCheckpoint.restore(self, fd)
@@ -270,151 +934,85 @@ class XendDomain:
# poor, so we need to log this for debugging.
log.exception("Restore failed")
raise XendError("Restore failed")
-
-
- def restore_(self, config):
- """Create a domain as part of the restore process. This is called
- only from {@link XendCheckpoint}.
-
- A restore request comes into XendDomain through {@link
- #domain_restore} or {@link #domain_restore_fd}. That request is
- forwarded immediately to XendCheckpoint which, when it is ready, will
- call this method. It is necessary to come through here rather than go
- directly to {@link XendDomainInfo.restore} because we need to
- serialise the domain creation process, but cannot lock
- domain_restore_fd as a whole, otherwise we will deadlock waiting for
- the old domain to die.
- """
- self.domains_lock.acquire()
- try:
- security.refresh_ssidref(config)
- dominfo = XendDomainInfo.restore(config)
- self._add_domain(dominfo)
- return dominfo
- finally:
- self.domains_lock.release()
-
-
- def domain_lookup(self, domid):
- self.domains_lock.acquire()
- try:
- self.refresh()
- return self.domains.get(domid)
- finally:
- self.domains_lock.release()
-
-
- def domain_lookup_nr(self, domid):
- self.domains_lock.acquire()
- try:
- return self.domains.get(domid)
- finally:
- self.domains_lock.release()
-
-
- def domain_lookup_by_name_or_id(self, name):
- self.domains_lock.acquire()
- try:
- self.refresh()
- return self.domain_lookup_by_name_or_id_nr(name)
- finally:
- self.domains_lock.release()
-
-
- def domain_lookup_by_name_or_id_nr(self, name):
- self.domains_lock.acquire()
- try:
- dominfo = self.domain_lookup_by_name_nr(name)
-
- if dominfo:
- return dominfo
- else:
- try:
- return self.domains.get(int(name))
- except ValueError:
- return None
- finally:
- self.domains_lock.release()
-
-
- def domain_lookup_by_name_nr(self, name):
- self.domains_lock.acquire()
- try:
- matching = filter(lambda d: d.getName() == name,
- self.domains.values())
- n = len(matching)
- if n == 1:
- return matching[0]
- return None
- finally:
- self.domains_lock.release()
-
-
- def privilegedDomain(self):
- self.domains_lock.acquire()
- try:
- return self.domains[PRIV_DOMAIN]
- finally:
- self.domains_lock.release()
-
def domain_unpause(self, domid):
- """Unpause domain execution."""
-
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ """Unpause domain execution.
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @rtype: None
+ @raise XendError: Failed to unpause
+ @raise XendInvalidDomain: Domain is not valid
+ """
+ try:
+ dominfo = self.domain_lookup_nr(domid)
+ if not dominfo:
+ raise XendInvalidDomain(str(domid))
+
+ log.info("Domain %s (%d) unpaused.", dominfo.getName(),
+ int(dominfo.getDomid()))
+
+ dominfo.unpause()
+ except XendInvalidDomain:
+ log.exception("domain_unpause")
+ raise
+ except Exception, ex:
+ log.exception("domain_unpause")
+ raise XendError(str(ex))
+
+ def domain_pause(self, domid):
+ """Pause domain execution.
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @rtype: None
+ @raise XendError: Failed to pause
+ @raise XendInvalidDomain: Domain is not valid
+ """
+ try:
+ dominfo = self.domain_lookup_nr(domid)
+ if not dominfo:
+ raise XendInvalidDomain(str(domid))
+ log.info("Domain %s (%d) paused.", dominfo.getName(),
+ int(dominfo.getDomid()))
+ dominfo.pause()
+ except XendInvalidDomain:
+ log.exception("domain_pause")
+ raise
+ except Exception, ex:
+ log.exception("domain_pause")
+ raise XendError(str(ex))
+
+ def domain_dump(self, domid, filename, live, crash):
+ """Dump domain core."""
+
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
- if dominfo.getDomid() == PRIV_DOMAIN:
- raise XendError("Cannot unpause privileged domain %s" % domid)
-
- try:
- log.info("Domain %s (%d) unpaused.", dominfo.getName(),
- dominfo.getDomid())
- return dominfo.unpause()
- except Exception, ex:
- raise XendError(str(ex))
-
-
- def domain_pause(self, domid):
- """Pause domain execution."""
-
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
- if not dominfo:
- raise XendInvalidDomain(str(domid))
-
- if dominfo.getDomid() == PRIV_DOMAIN:
- raise XendError("Cannot pause privileged domain %s" % domid)
-
- try:
- log.info("Domain %s (%d) paused.", dominfo.getName(),
- dominfo.getDomid())
- return dominfo.pause()
- except Exception, ex:
- raise XendError(str(ex))
-
- def domain_dump(self, domid, filename, live, crash):
- """Dump domain core."""
-
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
- if not dominfo:
- raise XendInvalidDomain(str(domid))
-
- if dominfo.getDomid() == PRIV_DOMAIN:
+ if dominfo.getDomid() == DOM0_ID:
raise XendError("Cannot dump core for privileged domain %s" %
domid)
try:
- log.info("Domain core dump requested for domain %s (%d) live=%d
crash=%d.",
+ log.info("Domain core dump requested for domain %s (%d) "
+ "live=%d crash=%d.",
dominfo.getName(), dominfo.getDomid(), live, crash)
return dominfo.dumpCore(filename)
except Exception, ex:
raise XendError(str(ex))
def domain_destroy(self, domid):
- """Terminate domain immediately."""
-
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
- if dominfo and dominfo.getDomid() == PRIV_DOMAIN:
+ """Terminate domain immediately.
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @rtype: None
+ @raise XendError: Failed to destroy
+ @raise XendInvalidDomain: Domain is not valid
+ """
+
+ dominfo = self.domain_lookup_nr(domid)
+ if dominfo and dominfo.getDomid() == DOM0_ID:
raise XendError("Cannot destroy privileged domain %s" % domid)
if dominfo:
@@ -422,19 +1020,36 @@ class XendDomain:
else:
try:
val = xc.domain_destroy(int(domid))
- except Exception, ex:
- raise XendInvalidDomain(str(domid))
+ except ValueError:
+ raise XendInvalidDomain(domid)
+ except Exception, e:
+ raise XendError(str(e))
+
return val
def domain_migrate(self, domid, dst, live=False, resource=0, port=0):
- """Start domain migration."""
-
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ """Start domain migration.
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @param dst: Destination IP address
+ @type dst: string
+ @keyword port: relocation port on destination
+ @type port: int
+ @keyword live: Live migration
+ @type live: bool
+ @keyword resource: not used??
+ @rtype: None
+ @raise XendError: Failed to migrate
+ @raise XendInvalidDomain: Domain is not valid
+ """
+
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
- if dominfo.getDomid() == PRIV_DOMAIN:
- raise XendError("Cannot migrate privileged domain %s" % domid)
+ if dominfo.getDomid() == DOM0_ID:
+ raise XendError("Cannot migrate privileged domain %i" % domid)
""" The following call may raise a XendError exception """
dominfo.testMigrateDevices(True, dst)
@@ -460,21 +1075,26 @@ class XendDomain:
def domain_save(self, domid, dst):
"""Start saving a domain to file.
- @param dst: destination file
- """
-
- try:
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @param dst: Destination filename
+ @type dst: string
+ @rtype: None
+ @raise XendError: Failed to save domain
+ @raise XendInvalidDomain: Domain is not valid
+ """
+ try:
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
- if dominfo.getDomid() == PRIV_DOMAIN:
- raise XendError("Cannot save privileged domain %s" % domid)
+ if dominfo.getDomid() == DOM0_ID:
+ raise XendError("Cannot save privileged domain %i" % domid)
fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
try:
# For now we don't support 'live checkpoint'
- return XendCheckpoint.save(fd, dominfo, False, False, dst)
+ XendCheckpoint.save(fd, dominfo, False, False, dst)
finally:
os.close(fd)
except OSError, ex:
@@ -484,9 +1104,15 @@ class XendDomain:
def domain_pincpu(self, domid, vcpu, cpumap):
"""Set which cpus vcpu can use
- @param cpumap: string repr of list of usable cpus
- """
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @param vcpu: vcpu to pin to
+ @type vcpu: int
+ @param cpumap: string repr of usable cpus
+ @type cpumap: string
+ @rtype: 0
+ """
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
@@ -507,8 +1133,12 @@ class XendDomain:
def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
weight):
"""Set Simple EDF scheduler parameters for a domain.
- """
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @rtype: 0
+ """
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
try:
@@ -519,15 +1149,20 @@ class XendDomain:
def domain_cpu_sedf_get(self, domid):
"""Get Simple EDF scheduler parameters for a domain.
- """
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @rtype: SXP object
+ @return: The parameters for Simple EDF schedule for a domain.
+ """
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
try:
sedf_info = xc.sedf_domain_get(dominfo.getDomid())
# return sxpr
return ['sedf',
- ['domain', sedf_info['domain']],
+ ['domid', sedf_info['domid']],
['period', sedf_info['period']],
['slice', sedf_info['slice']],
['latency', sedf_info['latency']],
@@ -538,7 +1173,14 @@ class XendDomain:
raise XendError(str(ex))
def domain_shadow_control(self, domid, op):
- """Shadow page control."""
+ """Shadow page control.
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @param op: operation
+ @type op: int
+ @rtype: 0
+ """
dominfo = self.domain_lookup(domid)
try:
return xc.shadow_control(dominfo.getDomid(), op)
@@ -546,7 +1188,13 @@ class XendDomain:
raise XendError(str(ex))
def domain_shadow_mem_get(self, domid):
- """Get shadow pagetable memory allocation."""
+ """Get shadow pagetable memory allocation.
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @rtype: int
+ @return: shadow memory in MB
+ """
dominfo = self.domain_lookup(domid)
try:
return xc.shadow_mem_control(dominfo.getDomid())
@@ -554,7 +1202,15 @@ class XendDomain:
raise XendError(str(ex))
def domain_shadow_mem_set(self, domid, mb):
- """Set shadow pagetable memory allocation."""
+ """Set shadow pagetable memory allocation.
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @param mb: shadow memory to set in MB
+ @type: mb: int
+ @rtype: int
+ @return: shadow memory in MB
+ """
dominfo = self.domain_lookup(domid)
try:
return xc.shadow_mem_control(dominfo.getDomid(), mb=mb)
@@ -563,8 +1219,13 @@ class XendDomain:
def domain_sched_credit_get(self, domid):
"""Get credit scheduler parameters for a domain.
- """
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @rtype: dict with keys 'weight' and 'cap'
+ @return: credit scheduler parameters
+ """
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
try:
@@ -574,8 +1235,14 @@ class XendDomain:
def domain_sched_credit_set(self, domid, weight = None, cap = None):
"""Set credit scheduler parameters for a domain.
- """
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @type weight: int
+ @type cap: int
+ @rtype: 0
+ """
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
try:
@@ -589,17 +1256,25 @@ class XendDomain:
elif cap < 0 or cap > dominfo.getVCpuCount() * 100:
raise XendError("cap is out of range")
+ assert type(weight) == int
+ assert type(cap) == int
+
return xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap)
except Exception, ex:
+ log.exception(ex)
raise XendError(str(ex))
def domain_maxmem_set(self, domid, mem):
"""Set the memory limit for a domain.
+ @param domid: Domain ID or Name
+ @type domid: int or string.
@param mem: memory limit (in MiB)
- @return: 0 on success, -1 on error
- """
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ @type mem: int
+ @raise XendError: fail to set memory
+ @rtype: 0
+ """
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
maxmem = int(mem) * 1024
@@ -613,9 +1288,10 @@ class XendDomain:
@param first: first IO port
@param last: last IO port
- @return: 0 on success, -1 on error
- """
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ @raise XendError: failed to set range
+ @rtype: 0
+ """
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
nr_ports = last - first + 1
@@ -632,9 +1308,10 @@ class XendDomain:
@param first: first IO port
@param last: last IO port
- @return: 0 on success, -1 on error
- """
- dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ @raise XendError: failed to set range
+ @rtype: 0
+ """
+ dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
nr_ports = last - first + 1
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py Fri Nov 10 11:11:04 2006 -0700
@@ -24,90 +24,39 @@ Author: Mike Wray <mike.wray@xxxxxx>
"""
-import errno
import logging
-import string
import time
import threading
+import re
+import copy
import os
+from types import StringTypes
import xen.lowlevel.xc
from xen.util import asserts
from xen.util.blkif import blkdev_uname_to_file
from xen.util import security
-import balloon
-import image
-import sxp
-import uuid
-import XendDomain
-import XendRoot
+
+from xen.xend import balloon, sxp, uuid, image, arch
+from xen.xend import XendRoot, XendNode
from xen.xend.XendBootloader import bootloader
+from xen.xend.XendConfig import XendConfig
from xen.xend.XendError import XendError, VmError
-
+from xen.xend.XendDevices import XendDevices
from xen.xend.xenstore.xstransact import xstransact, complete
from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
from xen.xend.xenstore.xswatch import xswatch
-
-from xen.xend import arch
-
-"""Shutdown code for poweroff."""
-DOMAIN_POWEROFF = 0
-
-"""Shutdown code for reboot."""
-DOMAIN_REBOOT = 1
-
-"""Shutdown code for suspend."""
-DOMAIN_SUSPEND = 2
-
-"""Shutdown code for crash."""
-DOMAIN_CRASH = 3
-
-"""Shutdown code for halt."""
-DOMAIN_HALT = 4
-
-"""Map shutdown codes to strings."""
-shutdown_reasons = {
- DOMAIN_POWEROFF: "poweroff",
- DOMAIN_REBOOT : "reboot",
- DOMAIN_SUSPEND : "suspend",
- DOMAIN_CRASH : "crash",
- DOMAIN_HALT : "halt"
- }
-
-restart_modes = [
- "restart",
- "destroy",
- "preserve",
- "rename-restart"
- ]
-
-STATE_DOM_OK = 1
-STATE_DOM_SHUTDOWN = 2
-
-SHUTDOWN_TIMEOUT = 30.0
+from xen.xend.XendConstants import *
+from xen.xend.XendAPIConstants import *
+
MIGRATE_TIMEOUT = 30.0
-
-ZOMBIE_PREFIX = 'Zombie-'
-
-"""Constants for the different stages of ext. device migration """
-DEV_MIGRATE_TEST = 0
-DEV_MIGRATE_STEP1 = 1
-DEV_MIGRATE_STEP2 = 2
-DEV_MIGRATE_STEP3 = 3
-
-"""Minimum time between domain restarts in seconds."""
-MINIMUM_RESTART_TIME = 20
-
-RESTART_IN_PROGRESS = 'xend/restart_in_progress'
-
xc = xen.lowlevel.xc.xc()
xroot = XendRoot.instance()
log = logging.getLogger("xend.XendDomainInfo")
#log.setLevel(logging.TRACE)
-
##
# All parameters of VMs that may be configured on-the-fly, or at start-up.
@@ -157,6 +106,8 @@ VM_STORE_ENTRIES = [
('shadow_memory', int),
('maxmem', int),
('start_time', float),
+ ('on_xend_start', str),
+ ('on_xend_stop', str),
]
VM_STORE_ENTRIES += VM_CONFIG_PARAMS
@@ -182,77 +133,102 @@ VM_STORE_ENTRIES += VM_CONFIG_PARAMS
def create(config):
- """Create a VM from a configuration.
-
- @param config configuration
- @raise: VmError for invalid configuration
+ """Creates and start a VM using the supplied configuration.
+ (called from XMLRPCServer directly)
+
+ @param config: A configuration object involving lists of tuples.
+ @type config: list of lists, eg ['vm', ['image', 'xen.gz']]
+
+ @rtype: XendDomainInfo
+ @return: A up and running XendDomainInfo instance
+ @raise VmError: Invalid configuration or failure to start.
"""
log.debug("XendDomainInfo.create(%s)", config)
-
- vm = XendDomainInfo(parseConfig(config))
+ vm = XendDomainInfo(XendConfig(sxp = config))
try:
- vm.construct()
- vm.initDomain()
- vm.storeVmDetails()
- vm.storeDomDetails()
- vm.registerWatches()
- vm.refreshShutdown()
- return vm
+ vm.start()
except:
log.exception('Domain construction failed')
vm.destroy()
raise
-
-def recreate(xeninfo, priv):
+ return vm
+
+def recreate(info, priv):
"""Create the VM object for an existing domain. The domain must not
be dying, as the paths in the store should already have been removed,
- and asking us to recreate them causes problems."""
-
- log.debug("XendDomainInfo.recreate(%s)", xeninfo)
-
- assert not xeninfo['dying']
-
- domid = xeninfo['dom']
+ and asking us to recreate them causes problems.
+
+ @param xeninfo: Parsed configuration
+ @type xeninfo: Dictionary
+ @param priv: TODO, unknown, something to do with memory
+ @type priv: bool
+
+ @rtype: XendDomainInfo
+ @return: A up and running XendDomainInfo instance
+ @raise VmError: Invalid configuration.
+ @raise XendError: Errors with configuration.
+ """
+
+ log.debug("XendDomainInfo.recreate(%s)", info)
+
+ assert not info['dying']
+
+ xeninfo = XendConfig(cfg = info)
+ domid = xeninfo['domid']
uuid1 = xeninfo['handle']
xeninfo['uuid'] = uuid.toString(uuid1)
+ needs_reinitialising = False
+
dompath = GetDomainPath(domid)
if not dompath:
- raise XendError(
- 'No domain path in store for existing domain %d' % domid)
-
- log.info("Recreating domain %d, UUID %s.", domid, xeninfo['uuid'])
+ raise XendError('No domain path in store for existing '
+ 'domain %d' % domid)
+
+ log.info("Recreating domain %d, UUID %s. at %s" %
+ (domid, xeninfo['uuid'], dompath))
+
+ # need to verify the path and uuid if not Domain-0
+ # if the required uuid and vm aren't set, then that means
+ # we need to recreate the dom with our own values
+ #
+ # NOTE: this is probably not desirable, really we should just
+ # abort or ignore, but there may be cases where xenstore's
+ # entry disappears (eg. xenstore-rm /)
+ #
try:
vmpath = xstransact.Read(dompath, "vm")
if not vmpath:
- raise XendError(
- 'No vm path in store for existing domain %d' % domid)
+ log.warn('/local/domain/%d/vm is missing. recreate is '
+ 'confused, trying our best to recover' % domid)
+ needs_reinitialising = True
+ raise XendError('reinit')
+
uuid2_str = xstransact.Read(vmpath, "uuid")
if not uuid2_str:
- raise XendError(
- 'No vm/uuid path in store for existing domain %d' % domid)
-
+ log.warn('%s/uuid/ is missing. recreate is confused, '
+ 'trying our best to recover' % vmpath)
+ needs_reinitialising = True
+ raise XendError('reinit')
+
uuid2 = uuid.fromString(uuid2_str)
-
if uuid1 != uuid2:
- raise XendError(
- 'Uuid in store does not match uuid for existing domain %d: '
- '%s != %s' % (domid, uuid2_str, xeninfo['uuid']))
-
- vm = XendDomainInfo(xeninfo, domid, dompath, True, priv)
-
- except Exception, exn:
- if priv:
- log.warn(str(exn))
-
- vm = XendDomainInfo(xeninfo, domid, dompath, True, priv)
- vm.recreateDom()
- vm.removeVm()
- vm.storeVmDetails()
- vm.storeDomDetails()
-
- vm.registerWatches()
+ log.warn('UUID in /vm does not match the UUID in /dom/%d.'
+ 'Trying out best to recover' % domid)
+ needs_reinitialising = True
+ except XendError:
+ pass # our best shot at 'goto' in python :)
+
+ vm = XendDomainInfo(xeninfo, domid, dompath, augment = True, priv = priv)
+
+ if needs_reinitialising:
+ vm._recreateDom()
+ vm._removeVm()
+ vm._storeVmDetails()
+ vm._storeDomDetails()
+
+ vm._registerWatches()
vm.refreshShutdown(xeninfo)
return vm
@@ -260,146 +236,52 @@ def restore(config):
def restore(config):
"""Create a domain and a VM object to do a restore.
- @param config: domain configuration
+ @param config: Domain configuration object
+ @type config: list of lists. (see C{create})
+
+ @rtype: XendDomainInfo
+ @return: A up and running XendDomainInfo instance
+ @raise VmError: Invalid configuration or failure to start.
+ @raise XendError: Errors with configuration.
"""
log.debug("XendDomainInfo.restore(%s)", config)
-
- vm = XendDomainInfo(parseConfig(config), None, None, False, False, True)
+ vm = XendDomainInfo(XendConfig(sxp = config), resume = True)
try:
- vm.construct()
- vm.storeVmDetails()
- vm.createDevices()
- vm.createChannels()
- vm.storeDomDetails()
- vm.endRestore()
+ vm.resume()
return vm
except:
vm.destroy()
raise
-
-def parseConfig(config):
- def get_cfg(name, conv = None):
- val = sxp.child_value(config, name)
-
- if conv and not val is None:
- try:
- return conv(val)
- except TypeError, exn:
- raise VmError(
- 'Invalid setting %s = %s in configuration: %s' %
- (name, val, str(exn)))
- else:
- return val
-
-
- log.debug("parseConfig: config is %s", config)
-
- result = {}
-
- for e in ROUNDTRIPPING_CONFIG_ENTRIES:
- result[e[0]] = get_cfg(e[0], e[1])
-
- result['cpu'] = get_cfg('cpu', int)
- result['cpus'] = get_cfg('cpus', str)
- result['image'] = get_cfg('image')
- tmp_security = get_cfg('security')
- if tmp_security:
- result['security'] = tmp_security
-
- try:
- if result['image']:
- v = sxp.child_value(result['image'], 'vcpus')
- if result['vcpus'] is None and v is not None:
- result['vcpus'] = int(v)
- elif v is not None and int(v) != result['vcpus']:
- log.warn(('Image VCPUs setting overrides vcpus=%d elsewhere.'
- ' Using %s VCPUs for VM %s.') %
- (result['vcpus'], v, result['uuid']))
- result['vcpus'] = int(v)
- except TypeError, exn:
- raise VmError(
- 'Invalid configuration setting: vcpus = %s: %s' %
- (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
-
- try:
- # support legacy config files with 'cpu' parameter
- # NB: prepending to list to support previous behavior
- # where 'cpu' parameter pinned VCPU0.
- if result['cpu']:
- if result['cpus']:
- result['cpus'] = "%s,%s" % (str(result['cpu']), result['cpus'])
- else:
- result['cpus'] = str(result['cpu'])
-
- # convert 'cpus' string to list of ints
- # 'cpus' supports a list of ranges (0-3), seperated by
- # commas, and negation, (^1).
- # Precedence is settled by order of the string:
- # "0-3,^1" -> [0,2,3]
- # "0-3,^1,1" -> [0,1,2,3]
- if result['cpus']:
- cpus = []
- for c in result['cpus'].split(','):
- if c.find('-') != -1:
- (x,y) = c.split('-')
- for i in range(int(x),int(y)+1):
- cpus.append(int(i))
- else:
- # remove this element from the list
- if c[0] == '^':
- cpus = [x for x in cpus if x != int(c[1:])]
- else:
- cpus.append(int(c))
-
- result['cpus'] = cpus
-
- except ValueError, exn:
- raise VmError(
- 'Invalid configuration setting: cpus = %s: %s' %
- (result['cpus'], exn))
-
- result['backend'] = []
- for c in sxp.children(config, 'backend'):
- result['backend'].append(sxp.name(sxp.child0(c)))
-
- result['device'] = []
- for d in sxp.children(config, 'device'):
- c = sxp.child0(d)
- result['device'].append((sxp.name(c), c))
-
- # Configuration option "restart" is deprecated. Parse it, but
- # let on_xyz override it if they are present.
- restart = get_cfg('restart')
- if restart:
- def handle_restart(event, val):
- if result[event] is None:
- result[event] = val
-
- if restart == "onreboot":
- handle_restart('on_poweroff', 'destroy')
- handle_restart('on_reboot', 'restart')
- handle_restart('on_crash', 'destroy')
- elif restart == "always":
- handle_restart('on_poweroff', 'restart')
- handle_restart('on_reboot', 'restart')
- handle_restart('on_crash', 'restart')
- elif restart == "never":
- handle_restart('on_poweroff', 'destroy')
- handle_restart('on_reboot', 'destroy')
- handle_restart('on_crash', 'destroy')
- else:
- log.warn("Ignoring malformed and deprecated config option "
- "restart = %s", restart)
-
- result['start_time'] = get_cfg('start_time', float)
-
- log.debug("parseConfig: result is %s", result)
- return result
-
+def createDormant(xeninfo):
+ """Create a dormant/inactive XenDomainInfo without creating VM.
+ This is for creating instances of persistent domains that are not
+ yet start.
+
+ @param xeninfo: Parsed configuration
+ @type xeninfo: dictionary
+
+ @rtype: XendDomainInfo
+ @return: A up and running XendDomainInfo instance
+ @raise XendError: Errors with configuration.
+ """
+
+ log.debug("XendDomainInfo.createDormant(%s)", xeninfo)
+
+ # domid does not make sense for non-running domains.
+ xeninfo.pop('domid', None)
+ vm = XendDomainInfo(XendConfig(cfg = xeninfo))
+ return vm
def domain_by_name(name):
+ """Get domain by name
+
+ @params name: Name of the domain
+ @type name: string
+ @return: XendDomainInfo or None
+ """
+ from xen.xend import XendDomain
return XendDomain.instance().domain_lookup_by_name_nr(name)
@@ -411,17 +293,19 @@ def shutdown_reason(code):
@return: shutdown reason
@rtype: string
"""
- return shutdown_reasons.get(code, "?")
+ return DOMAIN_SHUTDOWN_REASONS.get(code, "?")
def dom_get(dom):
"""Get info from xen for an existing domain.
@param dom: domain id
+ @type dom: int
@return: info or None
+ @rtype: dictionary
"""
try:
domlist = xc.domain_getinfo(dom, 1)
- if domlist and dom == domlist[0]['dom']:
+ if domlist and dom == domlist[0]['domid']:
return domlist[0]
except Exception, err:
# ignore missing domain
@@ -430,32 +314,87 @@ def dom_get(dom):
class XendDomainInfo:
-
+ """An object represents a domain.
+
+ @TODO: try to unify dom and domid, they mean the same thing, but
+ xc refers to it as dom, and everywhere else, including
+ xenstore it is domid. The best way is to change xc's
+ python interface.
+
+ @ivar info: Parsed configuration
+ @type info: dictionary
+ @ivar domid: Domain ID (if VM has started)
+ @type domid: int or None
+ @ivar vmpath: XenStore path to this VM.
+ @type vmpath: string
+ @ivar dompath: XenStore path to this Domain.
+ @type dompath: string
+ @ivar image: Reference to the VM Image.
+ @type image: xen.xend.image.ImageHandler
+ @ivar store_port: event channel to xenstored
+ @type store_port: int
+ @ivar console_port: event channel to xenconsoled
+ @type console_port: int
+ @ivar store_mfn: xenstored mfn
+ @type store_mfn: int
+ @ivar console_mfn: xenconsoled mfn
+ @type console_mfn: int
+ @ivar vmWatch: reference to a watch on the xenstored vmpath
+ @type vmWatch: xen.xend.xenstore.xswatch
+ @ivar shutdownWatch: reference to watch on the xenstored domain shutdown
+ @type shutdownWatch: xen.xend.xenstore.xswatch
+ @ivar shutdownStartTime: UNIX Time when domain started shutting down.
+ @type shutdownStartTime: float or None
+ @ivar state: Domain state
+ @type state: enum(DOM_STATE_HALTED, DOM_STATE_RUNNING, ...)
+ @ivar state_updated: lock for self.state
+ @type state_updated: threading.Condition
+ @ivar refresh_shutdown_lock: lock for polling shutdown state
+ @type refresh_shutdown_lock: threading.Condition
+ @ivar _deviceControllers: device controller cache for this domain
+ @type _deviceControllers: dict 'string' to DevControllers
+ """
+
def __init__(self, info, domid = None, dompath = None, augment = False,
priv = False, resume = False):
+ """Constructor for a domain
+
+ @param info: parsed configuration
+ @type info: dictionary
+ @keyword domid: Set initial domain id (if any)
+ @type domid: int
+ @keyword dompath: Set initial dompath (if any)
+ @type dompath: string
+ @keyword augment: Augment given info with xenstored VM info
+ @type augment: bool
+ @keyword priv: Is a privledged domain (Dom 0) (TODO: really?)
+ @type priv: bool
+ @keyword resume: Is this domain being resumed?
+ @type resume: bool
+ """
self.info = info
-
- if not self.infoIsSet('uuid'):
- self.info['uuid'] = uuid.toString(uuid.create())
-
- if domid is not None:
+ if domid == None:
+ self.domid = self.info.get('domid')
+ else:
self.domid = domid
- elif 'dom' in info:
- self.domid = int(info['dom'])
- else:
- self.domid = None
-
- self.vmpath = XendDomain.VMROOT + self.info['uuid']
+
+ #REMOVE: uuid is now generated in XendConfig
+ #if not self._infoIsSet('uuid'):
+ # self.info['uuid'] = uuid.toString(uuid.create())
+
+ #REMOVE: domid logic can be shortened
+ #if domid is not None:
+ # self.domid = domid
+ #elif info.has_key('dom'):
+ # self.domid = int(info['dom'])
+ #else:
+ # self.domid = None
+
+ self.vmpath = XS_VMROOT + self.info['uuid']
self.dompath = dompath
- if augment:
- self.augmentInfo(priv)
-
- self.validateInfo()
-
self.image = None
- self.security = None
self.store_port = None
self.store_mfn = None
self.console_port = None
@@ -463,67 +402,215 @@ class XendDomainInfo:
self.vmWatch = None
self.shutdownWatch = None
-
self.shutdownStartTime = None
- self.state = STATE_DOM_OK
+ self.state = DOM_STATE_HALTED
self.state_updated = threading.Condition()
self.refresh_shutdown_lock = threading.Condition()
+ self._deviceControllers = {}
+
+ for state in DOM_STATES_OLD:
+ self.info[state] = 0
+
+ if augment:
+ self._augmentInfo(priv)
+
+ self._checkName(self.info['name'])
self.setResume(resume)
-
- ## private:
-
- def readVMDetails(self, params):
- """Read the specified parameters from the store.
+
+
+ #
+ # Public functions available through XMLRPC
+ #
+
+
+ def start(self, is_managed = False):
+ """Attempts to start the VM by do the appropriate
+ initialisation if it not started.
+ """
+ from xen.xend import XendDomain
+
+ if self.state == DOM_STATE_HALTED:
+ try:
+ self._constructDomain()
+ self._initDomain()
+ self._storeVmDetails()
+ self._storeDomDetails()
+ self._registerWatches()
+ self.refreshShutdown()
+ self.unpause()
+
+ # save running configuration if XendDomains believe domain is
+ # persistent
+ #
+ if is_managed:
+ xendomains = XendDomain.instance()
+ xendomains.managed_config_save(self)
+ except:
+ log.exception('VM start failed')
+ self.destroy()
+ raise
+ else:
+ raise XendError('VM already running')
+
+ def resume(self):
+ """Resumes a domain that has come back from suspension."""
+ if self.state in (DOM_STATE_HALTED, DOM_STATE_SUSPENDED):
+ try:
+ self._constructDomain()
+ self._storeVmDetails()
+ self._createDevices()
+ self._createChannels()
+ self._storeDomDetails()
+ self._endRestore()
+ except:
+ log.exception('VM resume failed')
+ raise
+ else:
+ raise XendError('VM already running')
+
+ def shutdown(self, reason):
+ """Shutdown a domain by signalling this via xenstored."""
+ log.debug('XendDomainInfo.shutdown')
+ if self.state in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,):
+ raise XendError('Domain cannot be shutdown')
+
+ if not reason in DOMAIN_SHUTDOWN_REASONS.values():
+ raise XendError('Invalid reason: %s' % reason)
+ self._storeDom("control/shutdown", reason)
+
+ def pause(self):
+ """Pause domain
+
+ @raise XendError: Failed pausing a domain
"""
try:
- return self.gatherVm(*params)
+ xc.domain_pause(self.domid)
+ self._stateSet(DOM_STATE_PAUSED)
+ except Exception, ex:
+ raise XendError("Domain unable to be paused: %s" % str(ex))
+
+ def unpause(self):
+ """Unpause domain
+
+ @raise XendError: Failed unpausing a domain
+ """
+ try:
+ xc.domain_unpause(self.domid)
+ self._stateSet(DOM_STATE_RUNNING)
+ except Exception, ex:
+ raise XendError("Domain unable to be unpaused: %s" % str(ex))
+
+ def send_sysrq(self, key):
+ """ Send a Sysrq equivalent key via xenstored."""
+ asserts.isCharConvertible(key)
+ self._storeDom("control/sysrq", '%c' % key)
+
+ def device_create(self, dev_config):
+ """Create a new device.
+
+ @param dev_config: device configuration
+ @type dev_config: dictionary (parsed config)
+ """
+ log.debug("XendDomainInfo.device_create: %s" % dev_config)
+ dev_type = sxp.name(dev_config)
+ devid = self._createDevice(dev_type, dev_config)
+ self.info.device_add(dev_type, cfg_sxp = dev_config)
+ self._waitForDevice(dev_type, devid)
+ return self.getDeviceController(dev_type).sxpr(devid)
+
+ def device_configure(self, dev_config, devid):
+ """Configure an existing device.
+
+ @param dev_config: device configuration
+ @type dev_config: dictionary (parsed config)
+ @param devid: device id
+ @type devid: int
+ """
+ deviceClass = sxp.name(dev_config)
+ self._reconfigureDevice(deviceClass, devid, dev_config)
+
+ def waitForDevices(self):
+ """Wait for this domain's configured devices to connect.
+
+ @raise VmError: if any device fails to initialise.
+ """
+ for devclass in XendDevices.valid_devices():
+ self.getDeviceController(devclass).waitForDevices()
+
+ def destroyDevice(self, deviceClass, devid):
+ try:
+ devid = int(devid)
except ValueError:
- # One of the int/float entries in params has a corresponding store
- # entry that is invalid. We recover, because older versions of
- # Xend may have put the entry there (memory/target, for example),
- # but this is in general a bad situation to have reached.
- log.exception(
- "Store corrupted at %s! Domain %d's configuration may be "
- "affected.", self.vmpath, self.domid)
- return []
-
-
- def storeChanged(self, _):
- log.trace("XendDomainInfo.storeChanged");
-
- changed = False
-
- def f(x, y):
- if y is not None and self.info[x[0]] != y:
- self.info[x[0]] = y
- changed = True
-
- map(f, VM_CONFIG_PARAMS, self.readVMDetails(VM_CONFIG_PARAMS))
-
- im = self.readVm('image')
- current_im = self.info['image']
- if (im is not None and
- (current_im is None or sxp.to_string(current_im) != im)):
- self.info['image'] = sxp.from_string(im)
- changed = True
-
- if changed:
- # Update the domain section of the store, as this contains some
- # parameters derived from the VM configuration.
- self.storeDomDetails()
-
- return 1
-
-
- def augmentInfo(self, priv):
- """Augment self.info, as given to us through {@link #recreate}, with
- values taken from the store. This recovers those values known to xend
- but not to the hypervisor.
+ # devid is not a number, let's search for it in xenstore.
+ devicePath = '%s/device/%s' % (self.dompath, deviceClass)
+ for entry in xstransact.List(devicePath):
+ backend = xstransact.Read('%s/%s' % (devicePath, entry),
+ "backend")
+ devName = xstransact.Read(backend, "dev")
+ if devName == devid:
+ # We found the integer matching our devid, use it instead
+ devid = entry
+ break
+
+ return self.getDeviceController(deviceClass).destroyDevice(devid)
+
+
+ def getDeviceSxprs(self, deviceClass):
+ return self.getDeviceController(deviceClass).sxprs()
+
+
+ def setMemoryTarget(self, target):
+ """Set the memory target of this domain.
+ @param target: In MiB.
+ """
+ log.debug("Setting memory target of domain %s (%d) to %d MiB.",
+ self.info['name'], self.domid, target)
+
+ if target <= 0:
+ raise XendError('Invalid memory size')
+
+ self.info['memory'] = target
+ self.storeVm("memory", target)
+ self._storeDom("memory/target", target << 10)
+
+ def getVCPUInfo(self):
+ try:
+ # We include the domain name and ID, to help xm.
+ sxpr = ['domain',
+ ['domid', self.domid],
+ ['name', self.info['name']],
+ ['vcpu_count', self.info['online_vcpus']]]
+
+ for i in range(0, self.info['max_vcpu_id']+1):
+ info = xc.vcpu_getinfo(self.domid, i)
+
+ sxpr.append(['vcpu',
+ ['number', i],
+ ['online', info['online']],
+ ['blocked', info['blocked']],
+ ['running', info['running']],
+ ['cpu_time', info['cpu_time'] / 1e9],
+ ['cpu', info['cpu']],
+ ['cpumap', info['cpumap']]])
+
+ return sxpr
+
+ except RuntimeError, exn:
+ raise XendError(str(exn))
+
+ #
+ # internal functions ... TODO: re-categorised
+ #
+
+ def _augmentInfo(self, priv):
+ """Augment self.info, as given to us through L{recreate}, with
+ values taken from the store. This recovers those values known
+ to xend but not to the hypervisor.
"""
def useIfNeeded(name, val):
- if not self.infoIsSet(name) and val is not None:
+ if not self._infoIsSet(name) and val is not None:
self.info[name] = val
if priv:
@@ -536,199 +623,64 @@ class XendDomainInfo:
entries.append(('security', str))
map(lambda x, y: useIfNeeded(x[0], y), entries,
- self.readVMDetails(entries))
-
- device = []
- for c in controllerClasses:
- devconfig = self.getDeviceConfigurations(c)
+ self._readVMDetails(entries))
+
+ devices = []
+
+ for devclass in XendDevices.valid_devices():
+ devconfig = self.getDeviceController(devclass).configurations()
if devconfig:
- device.extend(map(lambda x: (c, x), devconfig))
- useIfNeeded('device', device)
-
-
- def validateInfo(self):
- """Validate and normalise the info block. This has either been parsed
- by parseConfig, or received from xc through recreate and augmented by
- the current store contents.
- """
- def defaultInfo(name, val):
- if not self.infoIsSet(name):
- self.info[name] = val()
-
- try:
- defaultInfo('name', lambda: "Domain-%d" % self.domid)
- defaultInfo('on_poweroff', lambda: "destroy")
- defaultInfo('on_reboot', lambda: "restart")
- defaultInfo('on_crash', lambda: "restart")
- defaultInfo('features', lambda: "")
- defaultInfo('cpu', lambda: None)
- defaultInfo('cpus', lambda: [])
- defaultInfo('cpu_cap', lambda: 0)
- defaultInfo('cpu_weight', lambda: 256)
-
- # some domains don't have a config file (e.g. dom0 )
- # to set number of vcpus so we derive available cpus
- # from max_vcpu_id which is present for running domains.
- if not self.infoIsSet('vcpus') and self.infoIsSet('max_vcpu_id'):
- avail = int(self.info['max_vcpu_id'])+1
- else:
- avail = int(1)
-
- defaultInfo('vcpus', lambda: avail)
- defaultInfo('online_vcpus', lambda: self.info['vcpus'])
- defaultInfo('max_vcpu_id', lambda: self.info['vcpus']-1)
- defaultInfo('vcpu_avail', lambda: (1 << self.info['vcpus']) - 1)
-
- defaultInfo('memory', lambda: 0)
- defaultInfo('shadow_memory', lambda: 0)
- defaultInfo('maxmem', lambda: 0)
- defaultInfo('bootloader', lambda: None)
- defaultInfo('bootloader_args', lambda: None)
- defaultInfo('backend', lambda: [])
- defaultInfo('device', lambda: [])
- defaultInfo('image', lambda: None)
- defaultInfo('security', lambda: None)
-
- self.check_name(self.info['name'])
-
- if isinstance(self.info['image'], str):
- self.info['image'] = sxp.from_string(self.info['image'])
-
- if isinstance(self.info['security'], str):
- self.info['security'] = sxp.from_string(self.info['security'])
-
- if self.info['memory'] == 0:
- if self.infoIsSet('mem_kb'):
- self.info['memory'] = (self.info['mem_kb'] + 1023) / 1024
- if self.info['memory'] <= 0:
- raise VmError('Invalid memory size')
-
- if self.info['maxmem'] < self.info['memory']:
- self.info['maxmem'] = self.info['memory']
-
- for (n, c) in self.info['device']:
- if not n or not c or n not in controllerClasses:
- raise VmError('invalid device (%s, %s)' %
- (str(n), str(c)))
-
- for event in ['on_poweroff', 'on_reboot', 'on_crash']:
- if self.info[event] not in restart_modes:
- raise VmError('invalid restart event: %s = %s' %
- (event, str(self.info[event])))
-
- except KeyError, exn:
- log.exception(exn)
- raise VmError('Unspecified domain detail: %s' % exn)
-
-
- def readVm(self, *args):
+ devices.extend(map(lambda conf: (devclass, conf), devconfig))
+
+ if not self.info['device'] and devices is not None:
+ for device in devices:
+ self.info.device_add(device[0], cfg_sxp = device)
+
+ #
+ # Function to update xenstore /vm/*
+ #
+
+ def _readVm(self, *args):
return xstransact.Read(self.vmpath, *args)
- def writeVm(self, *args):
+ def _writeVm(self, *args):
return xstransact.Write(self.vmpath, *args)
- def removeVm(self, *args):
+ def _removeVm(self, *args):
return xstransact.Remove(self.vmpath, *args)
- def gatherVm(self, *args):
+ def _gatherVm(self, *args):
return xstransact.Gather(self.vmpath, *args)
-
-
- ## public:
def storeVm(self, *args):
return xstransact.Store(self.vmpath, *args)
-
- ## private:
-
- def readDom(self, *args):
+ #
+ # Function to update xenstore /dom/*
+ #
+
+ def _readDom(self, *args):
return xstransact.Read(self.dompath, *args)
- def writeDom(self, *args):
+ def _writeDom(self, *args):
return xstransact.Write(self.dompath, *args)
-
- ## public:
-
- def removeDom(self, *args):
+ def _removeDom(self, *args):
return xstransact.Remove(self.dompath, *args)
- def recreateDom(self):
- complete(self.dompath, lambda t: self._recreateDom(t))
-
- def _recreateDom(self, t):
+ def _storeDom(self, *args):
+ return xstransact.Store(self.dompath, *args)
+
+ def _recreateDom(self):
+ complete(self.dompath, lambda t: self._recreateDomFunc(t))
+
+ def _recreateDomFunc(self, t):
t.remove()
t.mkdir()
t.set_permissions({ 'dom' : self.domid })
-
-
- ## private:
-
- def storeDom(self, *args):
- return xstransact.Store(self.dompath, *args)
-
-
- ## public:
-
- def completeRestore(self, store_mfn, console_mfn):
-
- log.debug("XendDomainInfo.completeRestore")
-
- self.store_mfn = store_mfn
- self.console_mfn = console_mfn
-
- self.introduceDomain()
- self.storeDomDetails()
- self.registerWatches()
- self.refreshShutdown()
-
- log.debug("XendDomainInfo.completeRestore done")
-
-
- def storeVmDetails(self):
- to_store = {}
-
- for k in VM_STORE_ENTRIES:
- if self.infoIsSet(k[0]):
- to_store[k[0]] = str(self.info[k[0]])
-
- if self.infoIsSet('image'):
- to_store['image'] = sxp.to_string(self.info['image'])
-
- if self.infoIsSet('security'):
- security = self.info['security']
- to_store['security'] = sxp.to_string(security)
- for idx in range(0, len(security)):
- if security[idx][0] == 'access_control':
- to_store['security/access_control'] = sxp.to_string([
security[idx][1] , security[idx][2] ])
- for aidx in range(1, len(security[idx])):
- if security[idx][aidx][0] == 'label':
- to_store['security/access_control/label'] =
security[idx][aidx][1]
- if security[idx][aidx][0] == 'policy':
- to_store['security/access_control/policy'] =
security[idx][aidx][1]
- if security[idx][0] == 'ssidref':
- to_store['security/ssidref'] = str(security[idx][1])
-
- if not self.readVm('xend/restart_count'):
- to_store['xend/restart_count'] = str(0)
-
- log.debug("Storing VM details: %s", to_store)
-
- self.writeVm(to_store)
- self.setVmPermissions()
-
-
- def setVmPermissions(self):
- """Allow the guest domain to read its UUID. We don't allow it to
- access any other entry, for security."""
- xstransact.SetPermissions('%s/uuid' % self.vmpath,
- { 'dom' : self.domid,
- 'read' : True,
- 'write' : False })
-
-
- def storeDomDetails(self):
+ t.write('vm', self.vmpath)
+
+ def _storeDomDetails(self):
to_store = {
'domid': str(self.domid),
'vm': self.vmpath,
@@ -746,16 +698,13 @@ class XendDomainInfo:
f('store/port', self.store_port)
f('store/ring-ref', self.store_mfn)
- to_store.update(self.vcpuDomDetails())
+ to_store.update(self._vcpuDomDetails())
log.debug("Storing domain details: %s", to_store)
- self.writeDom(to_store)
-
-
- ## private:
-
- def vcpuDomDetails(self):
+ self._writeDom(to_store)
+
+ def _vcpuDomDetails(self):
def availability(n):
if self.info['vcpu_avail'] & (1 << n):
return 'online'
@@ -767,25 +716,80 @@ class XendDomainInfo:
result["cpu/%d/availability" % v] = availability(v)
return result
-
- ## public:
-
- def registerWatches(self):
+ #
+ # xenstore watches
+ #
+
+ def _registerWatches(self):
"""Register a watch on this VM's entries in the store, and the
domain's control/shutdown node, so that when they are changed
externally, we keep up to date. This should only be called by {@link
#create}, {@link #recreate}, or {@link #restore}, once the domain's
details have been written, but before the new instance is returned."""
- self.vmWatch = xswatch(self.vmpath, self.storeChanged)
+ self.vmWatch = xswatch(self.vmpath, self._storeChanged)
self.shutdownWatch = xswatch(self.dompath + '/control/shutdown',
- self.handleShutdownWatch)
+ self._handleShutdownWatch)
+
+ def _storeChanged(self, _):
+ log.trace("XendDomainInfo.storeChanged");
+
+ changed = False
+
+ def f(x, y):
+ if y is not None and self.info[x[0]] != y:
+ self.info[x[0]] = y
+ changed = True
+
+ map(f, VM_CONFIG_PARAMS, self._readVMDetails(VM_CONFIG_PARAMS))
+
+ im = self._readVm('image')
+ current_im = self.info['image']
+ if (im is not None and
+ (current_im is None or sxp.to_string(current_im) != im)):
+ self.info['image'] = sxp.from_string(im)
+ changed = True
+
+ if changed:
+ # Update the domain section of the store, as this contains some
+ # parameters derived from the VM configuration.
+ self._storeDomDetails()
+
+ return 1
+
+ def _handleShutdownWatch(self, _):
+ log.debug('XendDomainInfo.handleShutdownWatch')
+
+ reason = self._readDom('control/shutdown')
+
+ if reason and reason != 'suspend':
+ sst = self._readDom('xend/shutdown_start_time')
+ now = time.time()
+ if sst:
+ self.shutdownStartTime = float(sst)
+ timeout = float(sst) + SHUTDOWN_TIMEOUT - now
+ else:
+ self.shutdownStartTime = now
+ self._storeDom('xend/shutdown_start_time', now)
+ timeout = SHUTDOWN_TIMEOUT
+
+ log.trace(
+ "Scheduling refreshShutdown on domain %d in %ds.",
+ self.domid, timeout)
+ threading.Timer(timeout, self.refreshShutdown).start()
+
+ return True
+
+
+ #
+ # Public Attributes for the VM
+ #
def getDomid(self):
return self.domid
def setName(self, name):
- self.check_name(name)
+ self._checkName(name)
self.info['name'] = name
self.storeVm("name", name)
@@ -795,12 +799,13 @@ class XendDomainInfo:
def getDomainPath(self):
return self.dompath
+ def getShutdownReason(self):
+ return self._readDom('control/shutdown')
def getStorePort(self):
"""For use only by image.py and XendCheckpoint.py."""
return self.store_port
-
def getConsolePort(self):
"""For use only by image.py and XendCheckpoint.py"""
return self.console_port
@@ -812,11 +817,10 @@ class XendDomainInfo:
def getVCpuCount(self):
return self.info['vcpus']
-
def setVCpuCount(self, vcpus):
self.info['vcpu_avail'] = (1 << vcpus) - 1
self.storeVm('vcpu_avail', self.info['vcpu_avail'])
- self.writeDom(self.vcpuDomDetails())
+ self._writeDom(self._vcpuDomDetails())
def getLabel(self):
return security.get_security_info(self.info, 'label')
@@ -834,21 +838,23 @@ class XendDomainInfo:
def getWeight(self):
return self.info['cpu_weight']
- def endRestore(self):
- self.setResume(False)
-
def setResume(self, state):
self.info['resume'] = state
def getRestartCount(self):
- return self.readVm('xend/restart_count')
+ return self._readVm('xend/restart_count')
def refreshShutdown(self, xeninfo = None):
+ """ Checks the domain for whether a shutdown is required.
+
+ Called from XendDomainInfo and also image.py for HVM images.
+ """
+
# If set at the end of this method, a restart is required, with the
# given reason. This restart has to be done out of the scope of
# refresh_shutdown_lock.
restart_reason = None
-
+
self.refresh_shutdown_lock.acquire()
try:
if xeninfo is None:
@@ -862,6 +868,7 @@ class XendDomainInfo:
# VM may have migrated to a different domain on this
# machine.
self.cleanupDomain()
+ self._stateSet(DOM_STATE_HALTED)
return
if xeninfo['dying']:
@@ -873,10 +880,11 @@ class XendDomainInfo:
# holding the pages, by calling cleanupDomain. We can't
# clean up the VM, as above.
self.cleanupDomain()
+ self._stateSet(DOM_STATE_SHUTDOWN)
return
elif xeninfo['crashed']:
- if self.readDom('xend/shutdown_completed'):
+ if self._readDom('xend/shutdown_completed'):
# We've seen this shutdown already, but we are preserving
# the domain for debugging. Leave it alone.
return
@@ -888,9 +896,11 @@ class XendDomainInfo:
self.dumpCore()
restart_reason = 'crash'
+ self._stateSet(DOM_STATE_HALTED)
elif xeninfo['shutdown']:
- if self.readDom('xend/shutdown_completed'):
+ self._stateSet(DOM_STATE_SHUTDOWN)
+ if self._readDom('xend/shutdown_completed'):
# We've seen this shutdown already, but we are preserving
# the domain for debugging. Leave it alone.
return
@@ -901,15 +911,15 @@ class XendDomainInfo:
log.info('Domain has shutdown: name=%s id=%d reason=%s.',
self.info['name'], self.domid, reason)
- self.clearRestart()
+ self._clearRestart()
if reason == 'suspend':
- self.state_set(STATE_DOM_SHUTDOWN)
+ self._stateSet(DOM_STATE_SUSPENDED)
# Don't destroy the domain. XendCheckpoint will do
# this once it has finished. However, stop watching
# the VM path now, otherwise we will end up with one
# watch for the old domain, and one for the new.
- self.unwatchVm()
+ self._unwatchVm()
elif reason in ['poweroff', 'reboot']:
restart_reason = reason
else:
@@ -923,7 +933,11 @@ class XendDomainInfo:
else:
# Domain is alive. If we are shutting it down, then check
# the timeout on that, and destroy it if necessary.
-
+ if xeninfo['paused']:
+ self._stateSet(DOM_STATE_PAUSED)
+ else:
+ self._stateSet(DOM_STATE_RUNNING)
+
if self.shutdownStartTime:
timeout = (SHUTDOWN_TIMEOUT - time.time() +
self.shutdownStartTime)
@@ -936,61 +950,133 @@ class XendDomainInfo:
self.refresh_shutdown_lock.release()
if restart_reason:
- self.maybeRestart(restart_reason)
-
-
- def handleShutdownWatch(self, _):
- log.debug('XendDomainInfo.handleShutdownWatch')
-
- reason = self.readDom('control/shutdown')
-
- if reason and reason != 'suspend':
- sst = self.readDom('xend/shutdown_start_time')
- now = time.time()
- if sst:
- self.shutdownStartTime = float(sst)
- timeout = float(sst) + SHUTDOWN_TIMEOUT - now
- else:
- self.shutdownStartTime = now
- self.storeDom('xend/shutdown_start_time', now)
- timeout = SHUTDOWN_TIMEOUT
-
- log.trace(
- "Scheduling refreshShutdown on domain %d in %ds.",
- self.domid, timeout)
- threading.Timer(timeout, self.refreshShutdown).start()
-
- return True
-
-
- def shutdown(self, reason):
- if not reason in shutdown_reasons.values():
- raise XendError('Invalid reason: %s' % reason)
- if self.domid == 0:
- raise XendError("Can't specify Domain-0")
- self.storeDom("control/shutdown", reason)
-
-
- ## private:
-
- def clearRestart(self):
- self.removeDom("xend/shutdown_start_time")
-
-
- def maybeRestart(self, reason):
+ self._maybeRestart(restart_reason)
+
+
+ #
+ # Restart functions - handling whether we come back up on shutdown.
+ #
+
+ def _clearRestart(self):
+ self._removeDom("xend/shutdown_start_time")
+
+
+ def _maybeRestart(self, reason):
# Dispatch to the correct method based upon the configured on_{reason}
# behaviour.
{"destroy" : self.destroy,
- "restart" : self.restart,
- "preserve" : self.preserve,
- "rename-restart" : self.renameRestart}[self.info['on_' + reason]]()
-
-
- def renameRestart(self):
- self.restart(True)
-
-
- def dumpCore(self,corefile=None):
+ "restart" : self._restart,
+ "preserve" : self._preserve,
+ "rename-restart" : self._renameRestart}[self.info['on_' + reason]]()
+
+
+ def _renameRestart(self):
+ self._restart(True)
+
+ def _restart(self, rename = False):
+ """Restart the domain after it has exited.
+
+ @param rename True if the old domain is to be renamed and preserved,
+ False if it is to be destroyed.
+ """
+ from xen.xend import XendDomain
+
+ self._configureBootloader()
+ config = self.sxpr()
+
+ if self._infoIsSet('cpus') and len(self.info['cpus']) != 0:
+ config.append(['cpus', reduce(lambda x, y: str(x) + "," + str(y),
+ self.info['cpus'])])
+
+ if self._readVm(RESTART_IN_PROGRESS):
+ log.error('Xend failed during restart of domain %s. '
+ 'Refusing to restart to avoid loops.',
+ str(self.domid))
+ self.destroy()
+ return
+
+ old_domid = self.domid
+ self._writeVm(RESTART_IN_PROGRESS, 'True')
+
+ now = time.time()
+ rst = self._readVm('xend/previous_restart_time')
+ if rst:
+ rst = float(rst)
+ timeout = now - rst
+ if timeout < MINIMUM_RESTART_TIME:
+ log.error(
+ 'VM %s restarting too fast (%f seconds since the last '
+ 'restart). Refusing to restart to avoid loops.',
+ self.info['name'], timeout)
+ self.destroy()
+ return
+
+ self._writeVm('xend/previous_restart_time', str(now))
+
+ try:
+ if rename:
+ self._preserveForRestart()
+ else:
+ self._unwatchVm()
+ self.destroyDomain()
+
+ # new_dom's VM will be the same as this domain's VM, except where
+ # the rename flag has instructed us to call preserveForRestart.
+ # In that case, it is important that we remove the
+ # RESTART_IN_PROGRESS node from the new domain, not the old one,
+ # once the new one is available.
+
+ new_dom = None
+ try:
+ new_dom = XendDomain.instance().domain_create(config)
+ new_dom.unpause()
+ rst_cnt = self._readVm('xend/restart_count')
+ rst_cnt = int(rst_cnt) + 1
+ self._writeVm('xend/restart_count', str(rst_cnt))
+ new_dom._removeVm(RESTART_IN_PROGRESS)
+ except:
+ if new_dom:
+ new_dom._removeVm(RESTART_IN_PROGRESS)
+ new_dom.destroy()
+ else:
+ self._removeVm(RESTART_IN_PROGRESS)
+ raise
+ except:
+ log.exception('Failed to restart domain %s.', str(old_domid))
+
+ def _preserveForRestart(self):
+ """Preserve a domain that has been shut down, by giving it a new UUID,
+ cloning the VM details, and giving it a new name. This allows us to
+ keep this domain for debugging, but restart a new one in its place
+ preserving the restart semantics (name and UUID preserved).
+ """
+
+ new_uuid = uuid.createString()
+ new_name = 'Domain-%s' % new_uuid
+ log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
+ self.info['name'], self.domid, self.info['uuid'],
+ new_name, new_uuid)
+ self._unwatchVm()
+ self._releaseDevices()
+ self.info['name'] = new_name
+ self.info['uuid'] = new_uuid
+ self.vmpath = XS_VMROOT + new_uuid
+ self._storeVmDetails()
+ self._preserve()
+
+
+ def _preserve(self):
+ log.info("Preserving dead domain %s (%d).", self.info['name'],
+ self.domid)
+ self._unwatchVm()
+ self._storeDom('xend/shutdown_completed', 'True')
+ self._stateSet(DOM_STATE_HALTED)
+
+ #
+ # Debugging ..
+ #
+
+ def dumpCore(self, corefile = None):
"""Create a core dump for this domain. Nothrow guarantee."""
try:
@@ -1011,260 +1097,132 @@ class XendDomainInfo:
self.domid, self.info['name'])
raise XendError("Failed to dump core: %s" % str(ex))
- ## public:
-
- def setMemoryTarget(self, target):
- """Set the memory target of this domain.
- @param target In MiB.
- """
- if target <= 0:
- raise XendError('Invalid memory size')
-
- log.debug("Setting memory target of domain %s (%d) to %d MiB.",
- self.info['name'], self.domid, target)
-
- self.info['memory'] = target
- self.storeVm("memory", target)
- self.storeDom("memory/target", target << 10)
-
-
- def update(self, info = None):
- """Update with info from xc.domain_getinfo().
- """
-
- log.trace("XendDomainInfo.update(%s) on domain %d", info, self.domid)
- if not info:
- info = dom_get(self.domid)
- if not info:
- return
-
- #manually update ssidref / security fields
- if security.on() and info.has_key('ssidref'):
- if (info['ssidref'] != 0) and self.info.has_key('security'):
- security_field = self.info['security']
- if not security_field:
- #create new security element
- self.info.update({'security': [['ssidref',
str(info['ssidref'])]]})
- #ssidref field not used any longer
- info.pop('ssidref')
-
- self.info.update(info)
- self.validateInfo()
- self.refreshShutdown(info)
-
- log.trace("XendDomainInfo.update done on domain %d: %s", self.domid,
- self.info)
-
-
- ## private:
-
- def state_set(self, state):
- self.state_updated.acquire()
- try:
- if self.state != state:
- self.state = state
- self.state_updated.notifyAll()
- finally:
- self.state_updated.release()
-
-
- ## public:
-
- def waitForShutdown(self):
- self.state_updated.acquire()
- try:
- while self.state == STATE_DOM_OK:
- self.state_updated.wait()
- finally:
- self.state_updated.release()
-
-
- def __str__(self):
- s = "<domain"
- s += " id=" + str(self.domid)
- s += " name=" + self.info['name']
- s += " memory=" + str(self.info['memory'])
- s += ">"
- return s
-
- __repr__ = __str__
-
-
- ## private:
-
- def createDevice(self, deviceClass, devconfig):
- return self.getDeviceController(deviceClass).createDevice(devconfig)
-
-
- def waitForDevices_(self, deviceClass):
- return self.getDeviceController(deviceClass).waitForDevices()
-
-
- def waitForDevice(self, deviceClass, devid):
+ #
+ # Device creation/deletion functions
+ #
+
+ def _createDevice(self, deviceClass, devConfig):
+ return self.getDeviceController(deviceClass).createDevice(devConfig)
+
+ def _waitForDevice(self, deviceClass, devid):
return self.getDeviceController(deviceClass).waitForDevice(devid)
-
- def reconfigureDevice(self, deviceClass, devid, devconfig):
+ def _reconfigureDevice(self, deviceClass, devid, devconfig):
return self.getDeviceController(deviceClass).reconfigureDevice(
devid, devconfig)
-
- ## public:
-
- def destroyDevice(self, deviceClass, devid):
- if type(devid) is str:
- devicePath = '%s/device/%s' % (self.dompath, deviceClass)
- for entry in xstransact.List(devicePath):
- backend = xstransact.Read('%s/%s' % (devicePath, entry),
- "backend")
- devName = xstransact.Read(backend, "dev")
- if devName == devid:
- # We found the integer matching our devid, use it instead
- devid = entry
- break
- return self.getDeviceController(deviceClass).destroyDevice(devid)
-
-
- def getDeviceSxprs(self, deviceClass):
- return self.getDeviceController(deviceClass).sxprs()
+ def _createDevices(self):
+ """Create the devices for a vm.
+
+ @raise: VmError for invalid devices
+ """
+ for (devclass, config) in self.info.all_devices_sxpr():
+ log.info("createDevice: %s : %s" % (devclass, config))
+ self._createDevice(devclass, config)
+
+ if self.image:
+ self.image.createDeviceModel()
+
+ def _releaseDevices(self):
+ """Release all domain's devices. Nothrow guarantee."""
+
+ while True:
+ t = xstransact("%s/device" % self.dompath)
+ for devclass in XendDevices.valid_devices():
+ for dev in t.list(devclass):
+ try:
+ t.remove(dev)
+ except:
+ # Log and swallow any exceptions in removal --
+ # there's nothing more we can do.
+ log.exception(
+ "Device release failed: %s; %s; %s",
+ self.info['name'], devclass, dev)
+ if t.commit():
+ break
+
+ def getDeviceController(self, name):
+ """Get the device controller for this domain, and if it
+ doesn't exist, create it.
+
+ @param name: device class name
+ @type name: string
+ @rtype: subclass of DevController
+ """
+ if name not in self._deviceControllers:
+ devController = XendDevices.make_controller(name, self)
+ if not devController:
+ raise XendError("Unknown device type: %s" % name)
+ self._deviceControllers[name] = devController
+
+ return self._deviceControllers[name]
+
+ #
+ # Migration functions (public)
+ #
+
+ def testMigrateDevices(self, network, dst):
+ """ Notify all device about intention of migration
+ @raise: XendError for a device that cannot be migrated
+ """
+ for (n, c) in self.info.all_devices_sxpr():
+ rc = self.migrateDevice(n, c, network, dst, DEV_MIGRATE_TEST)
+ if rc != 0:
+ raise XendError("Device of type '%s' refuses migration." % n)
+
+ def migrateDevices(self, network, dst, step, domName=''):
+ """Notify the devices about migration
+ """
+ ctr = 0
+ try:
+ for (dev_type, dev_conf) in self.info.all_devices_sxpr():
+ self.migrateDevice(dev_type, dev_conf, network, dst,
+ step, domName)
+ ctr = ctr + 1
+ except:
+ for dev_type, dev_conf in self.info.all_devices_sxpr():
+ if ctr == 0:
+ step = step - 1
+ ctr = ctr - 1
+ self._recoverMigrateDevice(dev_type, dev_conf, network,
+ dst, step, domName)
+ raise
+
+ def migrateDevice(self, deviceClass, deviceConfig, network, dst,
+ step, domName=''):
+ return self.getDeviceController(deviceClass).migrate(deviceConfig,
+ network, dst, step, domName)
+
+ def _recoverMigrateDevice(self, deviceClass, deviceConfig, network,
+ dst, step, domName=''):
+ return self.getDeviceController(deviceClass).recover_migrate(
+ deviceConfig, network, dst, step, domName)
## private:
- def getDeviceConfigurations(self, deviceClass):
- return self.getDeviceController(deviceClass).configurations()
-
-
- def getDeviceController(self, name):
- if name not in controllerClasses:
- raise XendError("unknown device type: " + str(name))
-
- return controllerClasses[name](self)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|