debuggers.hg

changeset 20375:3ffdb094c2c0

Refresh to unstable c/s 21811
author Mukesh Rathor
date Fri Jul 16 17:16:06 2010 -0700 (2010-07-16)
parents 926cc93296dd
children 18593e055101
files .hgignore Config.mk Makefile README buildconfigs/enable-xen-config buildconfigs/mk.linux-2.6-pvops buildconfigs/src.git-clone docs/man/xm.pod.1 docs/misc/tmem-internals.html docs/xen-api/coversheet.tex docs/xen-api/revision-history.tex docs/xen-api/xenapi-coversheet.tex docs/xen-api/xenapi-datamodel-graph.dot docs/xen-api/xenapi-datamodel.tex extras/mini-os/blkfront.c extras/mini-os/fbfront.c extras/mini-os/kernel.c extras/mini-os/lib/sys.c extras/mini-os/netfront.c extras/mini-os/pcifront.c extras/mini-os/xenbus/xenbus.c patch.out stubdom/Makefile stubdom/grub/kexec.c stubdom/grub/mini-os.c tools/Makefile tools/Rules.mk tools/blktap/drivers/blktapctrl_linux.c tools/blktap/drivers/block-qcow.c tools/blktap2/Makefile tools/blktap2/control/Makefile tools/blktap2/control/tap-ctl-allocate.c tools/blktap2/control/tap-ctl-attach.c tools/blktap2/control/tap-ctl-check.c tools/blktap2/control/tap-ctl-close.c tools/blktap2/control/tap-ctl-create.c tools/blktap2/control/tap-ctl-destroy.c tools/blktap2/control/tap-ctl-detach.c tools/blktap2/control/tap-ctl-free.c tools/blktap2/control/tap-ctl-ipc.c tools/blktap2/control/tap-ctl-list.c tools/blktap2/control/tap-ctl-major.c tools/blktap2/control/tap-ctl-open.c tools/blktap2/control/tap-ctl-pause.c tools/blktap2/control/tap-ctl-spawn.c tools/blktap2/control/tap-ctl-unpause.c tools/blktap2/control/tap-ctl.c tools/blktap2/control/tap-ctl.h tools/blktap2/drivers/Makefile tools/blktap2/drivers/blktap2.h tools/blktap2/drivers/block-qcow.c tools/blktap2/drivers/block-remus.c tools/blktap2/drivers/block-vhd.c tools/blktap2/drivers/disktypes.h tools/blktap2/drivers/img2qcow.c tools/blktap2/drivers/md5.c tools/blktap2/drivers/md5.h tools/blktap2/drivers/qcow2raw.c tools/blktap2/drivers/tapdisk-control.c tools/blktap2/drivers/tapdisk-control.h tools/blktap2/drivers/tapdisk-diff.c tools/blktap2/drivers/tapdisk-disktype.c tools/blktap2/drivers/tapdisk-disktype.h tools/blktap2/drivers/tapdisk-driver.c tools/blktap2/drivers/tapdisk-driver.h tools/blktap2/drivers/tapdisk-image.c tools/blktap2/drivers/tapdisk-image.h tools/blktap2/drivers/tapdisk-interface.c tools/blktap2/drivers/tapdisk-interface.h tools/blktap2/drivers/tapdisk-ipc.c tools/blktap2/drivers/tapdisk-ipc.h tools/blktap2/drivers/tapdisk-server.c tools/blktap2/drivers/tapdisk-server.h tools/blktap2/drivers/tapdisk-stream.c tools/blktap2/drivers/tapdisk-utils.c tools/blktap2/drivers/tapdisk-utils.h tools/blktap2/drivers/tapdisk-vbd.c tools/blktap2/drivers/tapdisk-vbd.h tools/blktap2/drivers/tapdisk.h tools/blktap2/drivers/tapdisk2.c tools/blktap2/include/blktap2.h tools/blktap2/include/blktaplib.h tools/blktap2/include/list.h tools/blktap2/include/tapdisk-message.h tools/console/client/main.c tools/console/daemon/io.c tools/console/daemon/utils.c tools/console/daemon/utils.h tools/debugger/gdb/README tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/Makefile.in tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.in tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c tools/debugger/gdb/gdb-6.2.1-xen-sparse/mkbuildtree tools/debugger/gdb/gdbbuild tools/debugger/gdbsx/README tools/debugger/gdbsx/gx/gx_main.c tools/debugger/xenitp/xenitp.c tools/examples/xend-config.sxp tools/firmware/Makefile tools/firmware/etherboot/Config tools/firmware/etherboot/Makefile tools/firmware/etherboot/eb-roms.h tools/firmware/hvmloader/Makefile tools/firmware/hvmloader/acpi/acpi2_0.h tools/firmware/hvmloader/acpi/static_tables.c tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/smbios.c tools/firmware/hvmloader/smbios_types.h tools/firmware/hvmloader/util.h tools/firmware/hvmloader/xenbus.c tools/firmware/rombios/rombios.c tools/flask/libflask/flask_op.c tools/flask/libflask/include/libflask.h tools/flask/utils/getenforce.c tools/flask/utils/loadpolicy.c tools/flask/utils/setenforce.c tools/fs-back/fs-backend.c tools/fs-back/fs-backend.h tools/fs-back/fs-ops.c tools/hotplug/Linux/Makefile tools/hotplug/Linux/blktap tools/hotplug/Linux/block tools/hotplug/Linux/init.d/sysconfig.xencommons tools/hotplug/Linux/init.d/sysconfig.xend tools/hotplug/Linux/init.d/xen-watchdog tools/hotplug/Linux/init.d/xencommons tools/hotplug/Linux/init.d/xend tools/hotplug/Linux/init.d/xendomains tools/hotplug/Linux/locking.sh tools/hotplug/Linux/network-bridge tools/hotplug/Linux/vif-setup tools/hotplug/Linux/vtpm-common.sh tools/hotplug/Linux/xen-backend.rules tools/hotplug/Linux/xen-hotplug-cleanup tools/hotplug/NetBSD/Makefile tools/hotplug/NetBSD/rc.d/xen-watchdog tools/hotplug/NetBSD/rc.d/xencommons tools/hotplug/NetBSD/rc.d/xend tools/hotplug/NetBSD/rc.d/xendomains tools/libfsimage/Rules.mk tools/libfsimage/common/fsimage_grub.h tools/libfsimage/zfs/Makefile tools/libfsimage/zfs/filesys.h tools/libfsimage/zfs/fsi_zfs.c tools/libfsimage/zfs/fsi_zfs.h tools/libfsimage/zfs/fsys_zfs.c tools/libfsimage/zfs/fsys_zfs.h tools/libfsimage/zfs/shared.h tools/libfsimage/zfs/zfs-include/dmu.h tools/libfsimage/zfs/zfs-include/dnode.h tools/libfsimage/zfs/zfs-include/dsl_dataset.h tools/libfsimage/zfs/zfs-include/dsl_dir.h tools/libfsimage/zfs/zfs-include/sa_impl.h tools/libfsimage/zfs/zfs-include/spa.h tools/libfsimage/zfs/zfs-include/uberblock_impl.h tools/libfsimage/zfs/zfs-include/vdev_impl.h tools/libfsimage/zfs/zfs-include/zap_impl.h tools/libfsimage/zfs/zfs-include/zap_leaf.h tools/libfsimage/zfs/zfs-include/zfs.h tools/libfsimage/zfs/zfs-include/zfs_acl.h tools/libfsimage/zfs/zfs-include/zfs_znode.h tools/libfsimage/zfs/zfs-include/zil.h tools/libfsimage/zfs/zfs-include/zio.h tools/libfsimage/zfs/zfs-include/zio_checksum.h tools/libfsimage/zfs/zfs_fletcher.c tools/libfsimage/zfs/zfs_lzjb.c tools/libfsimage/zfs/zfs_sha256.c tools/libxc/Makefile tools/libxc/ia64/xc_dom_ia64_util.c tools/libxc/ia64/xc_ia64.h tools/libxc/ia64/xc_ia64_dom_fwloader.c tools/libxc/ia64/xc_ia64_hvm_build.c tools/libxc/ia64/xc_ia64_linux_restore.c tools/libxc/ia64/xc_ia64_linux_save.c tools/libxc/ia64/xc_ia64_stubs.c tools/libxc/xc_acm.c tools/libxc/xc_core.c tools/libxc/xc_core.h tools/libxc/xc_core_ia64.c tools/libxc/xc_core_ia64.h tools/libxc/xc_core_x86.c tools/libxc/xc_core_x86.h tools/libxc/xc_cpu_hotplug.c tools/libxc/xc_cpufeature.h tools/libxc/xc_cpuid_x86.c tools/libxc/xc_cpupool.c tools/libxc/xc_csched.c tools/libxc/xc_csched2.c tools/libxc/xc_dom.h tools/libxc/xc_dom_binloader.c tools/libxc/xc_dom_boot.c tools/libxc/xc_dom_bzimageloader.c tools/libxc/xc_dom_compat_linux.c tools/libxc/xc_dom_core.c tools/libxc/xc_dom_elfloader.c tools/libxc/xc_dom_ia64.c tools/libxc/xc_dom_x86.c tools/libxc/xc_domain.c tools/libxc/xc_domain_restore.c tools/libxc/xc_domain_save.c tools/libxc/xc_evtchn.c tools/libxc/xc_flask.c tools/libxc/xc_hvm_build.c tools/libxc/xc_linux.c tools/libxc/xc_mem_event.c tools/libxc/xc_mem_paging.c tools/libxc/xc_memshr.c tools/libxc/xc_minios.c tools/libxc/xc_misc.c tools/libxc/xc_netbsd.c tools/libxc/xc_offline_page.c tools/libxc/xc_pagetab.c tools/libxc/xc_physdev.c tools/libxc/xc_pm.c tools/libxc/xc_private.c tools/libxc/xc_private.h tools/libxc/xc_ptrace.c tools/libxc/xc_ptrace.h tools/libxc/xc_ptrace_core.c tools/libxc/xc_resume.c tools/libxc/xc_sedf.c tools/libxc/xc_solaris.c tools/libxc/xc_suspend.c tools/libxc/xc_tbuf.c tools/libxc/xc_tmem.c tools/libxc/xenctrl.h tools/libxc/xenguest.h tools/libxc/xentoollog.h tools/libxc/xg_private.c tools/libxc/xg_private.h tools/libxc/xg_save_restore.h tools/libxc/xtl_core.c tools/libxc/xtl_logger_stdio.c tools/libxen/include/xen/api/xen_all.h tools/libxen/include/xen/api/xen_cpu_pool.h tools/libxen/include/xen/api/xen_cpu_pool_decl.h tools/libxen/include/xen/api/xen_host.h tools/libxen/include/xen/api/xen_host_cpu.h tools/libxen/include/xen/api/xen_vm.h tools/libxen/src/xen_cpu_pool.c tools/libxen/src/xen_host.c tools/libxen/src/xen_host_cpu.c tools/libxen/src/xen_vm.c tools/libxen/test/test_bindings.c tools/libxl/Makefile tools/libxl/bash-completion tools/libxl/libxl.c tools/libxl/libxl.h tools/libxl/libxl_bootloader.c tools/libxl/libxl_device.c tools/libxl/libxl_dom.c tools/libxl/libxl_exec.c tools/libxl/libxl_internal.c tools/libxl/libxl_internal.h tools/libxl/libxl_paths.c tools/libxl/libxl_utils.c tools/libxl/libxl_utils.h tools/libxl/libxl_xshelp.c tools/libxl/libxlu_cfg.c tools/libxl/libxlutil.h tools/libxl/xenguest.c tools/libxl/xl.c tools/libxl/xl.h tools/libxl/xl_cmdimpl.c tools/libxl/xl_cmdtable.c tools/memshr/interface.c tools/misc/Makefile tools/misc/xen-hptool.c tools/misc/xen-hvmctx.c tools/misc/xen-tmem-list-parse.c tools/misc/xend tools/misc/xenlockprof.c tools/misc/xenperf.c tools/misc/xenpm.c tools/misc/xenwatchdogd.c tools/ocaml/LICENSE tools/ocaml/Makefile tools/ocaml/Makefile.rules tools/ocaml/common.make tools/ocaml/libs/eventchn/META.in tools/ocaml/libs/eventchn/Makefile tools/ocaml/libs/eventchn/eventchn.ml tools/ocaml/libs/eventchn/eventchn.mli tools/ocaml/libs/eventchn/eventchn_stubs.c tools/ocaml/libs/log/META.in tools/ocaml/libs/log/Makefile tools/ocaml/libs/log/log.ml tools/ocaml/libs/log/log.mli tools/ocaml/libs/log/logs.ml tools/ocaml/libs/log/logs.mli tools/ocaml/libs/log/syslog.ml tools/ocaml/libs/log/syslog.mli tools/ocaml/libs/log/syslog_stubs.c tools/ocaml/libs/mmap/META.in tools/ocaml/libs/mmap/Makefile tools/ocaml/libs/mmap/mmap.ml tools/ocaml/libs/mmap/mmap.mli tools/ocaml/libs/mmap/mmap_stubs.c tools/ocaml/libs/mmap/mmap_stubs.h tools/ocaml/libs/uuid/META.in tools/ocaml/libs/uuid/Makefile tools/ocaml/libs/uuid/uuid.ml tools/ocaml/libs/uuid/uuid.mli tools/ocaml/libs/xb/META.in tools/ocaml/libs/xb/Makefile tools/ocaml/libs/xb/op.ml tools/ocaml/libs/xb/packet.ml tools/ocaml/libs/xb/partial.ml tools/ocaml/libs/xb/xb.ml tools/ocaml/libs/xb/xb.mli tools/ocaml/libs/xb/xb_stubs.c tools/ocaml/libs/xb/xs_ring.ml tools/ocaml/libs/xb/xs_ring_stubs.c tools/ocaml/libs/xc/META.in tools/ocaml/libs/xc/Makefile tools/ocaml/libs/xc/xc.h tools/ocaml/libs/xc/xc.ml tools/ocaml/libs/xc/xc.mli tools/ocaml/libs/xc/xc_cpufeature.h tools/ocaml/libs/xc/xc_cpuid.h tools/ocaml/libs/xc/xc_e820.h tools/ocaml/libs/xc/xc_lib.c tools/ocaml/libs/xc/xc_stubs.c tools/ocaml/libs/xl/Makefile tools/ocaml/libs/xl/xl.ml tools/ocaml/libs/xl/xl.mli tools/ocaml/libs/xl/xl_stubs.c tools/ocaml/libs/xs/META.in tools/ocaml/libs/xs/Makefile tools/ocaml/libs/xs/queueop.ml tools/ocaml/libs/xs/xs.ml tools/ocaml/libs/xs/xs.mli tools/ocaml/libs/xs/xsraw.ml tools/ocaml/libs/xs/xsraw.mli tools/ocaml/libs/xs/xst.ml tools/ocaml/libs/xs/xst.mli tools/ocaml/xenstored/Makefile tools/ocaml/xenstored/config.ml tools/ocaml/xenstored/connection.ml tools/ocaml/xenstored/connections.ml tools/ocaml/xenstored/define.ml tools/ocaml/xenstored/disk.ml tools/ocaml/xenstored/domain.ml tools/ocaml/xenstored/domains.ml tools/ocaml/xenstored/event.ml tools/ocaml/xenstored/logging.ml tools/ocaml/xenstored/parse_arg.ml tools/ocaml/xenstored/perms.ml tools/ocaml/xenstored/process.ml tools/ocaml/xenstored/quota.ml tools/ocaml/xenstored/stdext.ml tools/ocaml/xenstored/store.ml tools/ocaml/xenstored/symbol.ml tools/ocaml/xenstored/symbol.mli tools/ocaml/xenstored/transaction.ml tools/ocaml/xenstored/trie.ml tools/ocaml/xenstored/trie.mli tools/ocaml/xenstored/utils.ml tools/ocaml/xenstored/xenstored.conf tools/ocaml/xenstored/xenstored.ml tools/pygrub/src/ExtLinuxConf.py tools/pygrub/src/GrubConf.py tools/pygrub/src/LiloConf.py tools/pygrub/src/pygrub tools/python/xen/lowlevel/acm/acm.c tools/python/xen/lowlevel/checkpoint/checkpoint.h tools/python/xen/lowlevel/checkpoint/libcheckpoint.c tools/python/xen/lowlevel/flask/flask.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/remus/device.py tools/python/xen/remus/netlink.py tools/python/xen/remus/qdisc.py tools/python/xen/remus/util.py tools/python/xen/remus/vif.py tools/python/xen/remus/vm.py tools/python/xen/util/auxbin.py tools/python/xen/util/blkif.py tools/python/xen/util/diagnose.py tools/python/xen/util/pci.py tools/python/xen/util/sxputils.py tools/python/xen/web/tcp.py tools/python/xen/xend/XendAPI.py tools/python/xen/xend/XendBootloader.py tools/python/xen/xend/XendCPUPool.py tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendConstants.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendError.py tools/python/xen/xend/XendNode.py tools/python/xen/xend/XendOptions.py tools/python/xen/xend/XendVMMetrics.py tools/python/xen/xend/balloon.py tools/python/xen/xend/image.py tools/python/xen/xend/server/BlktapController.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/SrvServer.py tools/python/xen/xend/server/XMLRPCServer.py tools/python/xen/xend/sxp.py tools/python/xen/xm/console.py tools/python/xen/xm/create.dtd tools/python/xen/xm/create.py tools/python/xen/xm/main.py tools/python/xen/xm/pool-create.py tools/python/xen/xm/pool-new.py tools/python/xen/xm/pool.py tools/python/xen/xm/xenapi_create.py tools/remus/kmod/Makefile tools/remus/kmod/ebt_imq.c tools/remus/kmod/ebt_imq.h tools/remus/kmod/sch_queue.c tools/remus/remus tools/security/secpol_tool.c tools/xcutils/lsevtchn.c tools/xcutils/readnotes.c tools/xcutils/xc_restore.c tools/xcutils/xc_save.c tools/xenmon/setmask.c tools/xenmon/xenbaked.c tools/xenpaging/file_ops.c tools/xenpaging/policy.h tools/xenpaging/policy_default.c tools/xenpaging/xc.c tools/xenpaging/xc.h tools/xenpaging/xenpaging.c tools/xenpaging/xenpaging.h tools/xenstat/libxenstat/src/xenstat.c tools/xenstat/libxenstat/src/xenstat_linux.c tools/xenstat/libxenstat/src/xenstat_priv.h tools/xenstore/Makefile tools/xenstore/xenstored_domain.c tools/xenstore/xs.c tools/xenstore/xs.h tools/xentrace/Makefile tools/xentrace/formats tools/xentrace/setsize.c tools/xentrace/xenctx.c tools/xentrace/xentrace.c tools/xm-test/configure.ac tools/xm-test/grouptest/cpupool tools/xm-test/lib/XmTestLib/NetConfig.py tools/xm-test/lib/XmTestLib/XenDomain.py tools/xm-test/runtest.sh tools/xm-test/tests/Makefile.am tools/xm-test/tests/cpupool/01_cpupool_basic_pos.py tools/xm-test/tests/cpupool/02_cpupool_manage_pos.py tools/xm-test/tests/cpupool/03_cpupool_domain.py tools/xm-test/tests/cpupool/04_cpupool_migrate.py tools/xm-test/tests/cpupool/Makefile.am tools/xm-test/tests/cpupool/pool1.cfg tools/xm-test/tests/cpupool/pools.py tools/xm-test/tests/xapi/20_xapi-cpu_pool_basic.py tools/xm-test/tests/xapi/Makefile.am unmodified_drivers/linux-2.6/overrides.mk xen/Makefile xen/Rules.mk xen/arch/ia64/linux-xen/perfmon.c xen/arch/ia64/linux-xen/smp.c xen/arch/ia64/linux-xen/smpboot.c xen/arch/ia64/vmx/vmmu.c xen/arch/ia64/vmx/vmx_support.c xen/arch/ia64/xen/dom0_ops.c xen/arch/ia64/xen/dom_fw_common.c xen/arch/ia64/xen/dom_fw_domu.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/irq.c xen/arch/ia64/xen/machine_kexec.c xen/arch/ia64/xen/mm.c xen/arch/ia64/xen/xen.lds.S xen/arch/ia64/xen/xensetup.c xen/arch/x86/Makefile xen/arch/x86/acpi/boot.c xen/arch/x86/acpi/cpu_idle.c xen/arch/x86/acpi/cpufreq/cpufreq.c xen/arch/x86/acpi/cpufreq/powernow.c xen/arch/x86/acpi/power.c xen/arch/x86/acpi/suspend.c xen/arch/x86/acpi/wakeup_prot.S xen/arch/x86/apic.c xen/arch/x86/boot/Makefile xen/arch/x86/boot/build32.mk xen/arch/x86/boot/cmdline.S xen/arch/x86/boot/head.S xen/arch/x86/boot/reloc.c xen/arch/x86/boot/x86_32.S xen/arch/x86/boot/x86_64.S xen/arch/x86/cpu/amd.c xen/arch/x86/cpu/amd.h xen/arch/x86/cpu/centaur.c xen/arch/x86/cpu/common.c xen/arch/x86/cpu/cpu.h xen/arch/x86/cpu/intel.c xen/arch/x86/cpu/intel_cacheinfo.c xen/arch/x86/cpu/mcheck/Makefile xen/arch/x86/cpu/mcheck/amd_f10.c xen/arch/x86/cpu/mcheck/amd_k8.c xen/arch/x86/cpu/mcheck/amd_nonfatal.c xen/arch/x86/cpu/mcheck/k7.c xen/arch/x86/cpu/mcheck/mce.c xen/arch/x86/cpu/mcheck/mce.h xen/arch/x86/cpu/mcheck/mce_intel.c xen/arch/x86/cpu/mcheck/mctelem.c xen/arch/x86/cpu/mcheck/non-fatal.c xen/arch/x86/cpu/mcheck/vmce.c xen/arch/x86/cpu/mcheck/x86_mca.h xen/arch/x86/cpu/mtrr/generic.c xen/arch/x86/cpu/mtrr/main.c xen/arch/x86/cpu/mtrr/mtrr.h xen/arch/x86/cpu/mtrr/state.c xen/arch/x86/crash.c xen/arch/x86/domain.c xen/arch/x86/domain_build.c xen/arch/x86/domctl.c xen/arch/x86/flushtlb.c xen/arch/x86/genapic/bigsmp.c xen/arch/x86/genapic/default.c xen/arch/x86/genapic/summit.c xen/arch/x86/genapic/x2apic.c xen/arch/x86/hpet.c xen/arch/x86/hvm/Makefile xen/arch/x86/hvm/emulate.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/io.c xen/arch/x86/hvm/irq.c xen/arch/x86/hvm/mtrr.c xen/arch/x86/hvm/rtc.c xen/arch/x86/hvm/save.c xen/arch/x86/hvm/svm/Makefile xen/arch/x86/hvm/svm/asid.c xen/arch/x86/hvm/svm/emulate.c xen/arch/x86/hvm/svm/entry.S xen/arch/x86/hvm/svm/intr.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/vmcb.c xen/arch/x86/hvm/svm/vpmu.c xen/arch/x86/hvm/vioapic.c xen/arch/x86/hvm/viridian.c xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmsi.c xen/arch/x86/hvm/vmx/Makefile xen/arch/x86/hvm/vmx/entry.S xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/hvm/vmx/vpmu.c xen/arch/x86/hvm/vmx/vpmu_core2.c xen/arch/x86/hvm/vpmu.c xen/arch/x86/hvm/vpt.c xen/arch/x86/i8259.c xen/arch/x86/io_apic.c xen/arch/x86/irq.c xen/arch/x86/microcode.c xen/arch/x86/microcode_amd.c xen/arch/x86/microcode_intel.c xen/arch/x86/mm.c xen/arch/x86/mm/Makefile xen/arch/x86/mm/hap/hap.c xen/arch/x86/mm/hap/p2m-ept.c xen/arch/x86/mm/hap/private.h xen/arch/x86/mm/mem_event.c xen/arch/x86/mm/mem_sharing.c xen/arch/x86/mm/p2m.c xen/arch/x86/mm/paging.c xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/multi.c xen/arch/x86/mm/shadow/multi.h xen/arch/x86/mm/shadow/private.h xen/arch/x86/mpparse.c xen/arch/x86/msi.c xen/arch/x86/nmi.c xen/arch/x86/numa.c xen/arch/x86/oprofile/nmi_int.c xen/arch/x86/oprofile/op_model_athlon.c xen/arch/x86/oprofile/op_model_p4.c xen/arch/x86/oprofile/op_model_ppro.c xen/arch/x86/oprofile/op_x86_model.h xen/arch/x86/percpu.c xen/arch/x86/physdev.c xen/arch/x86/platform_hypercall.c xen/arch/x86/setup.c xen/arch/x86/shutdown.c xen/arch/x86/smp.c xen/arch/x86/smpboot.c xen/arch/x86/srat.c xen/arch/x86/string.c xen/arch/x86/sysctl.c xen/arch/x86/tboot.c xen/arch/x86/time.c xen/arch/x86/traps.c xen/arch/x86/x86_32/asm-offsets.c xen/arch/x86/x86_32/domain_page.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/supervisor_mode_kernel.S xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/asm-offsets.c xen/arch/x86/x86_64/compat/entry.S xen/arch/x86/x86_64/compat/traps.c xen/arch/x86/x86_64/compat_kexec.S xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/mm.c xen/arch/x86/x86_64/mmconfig-shared.c xen/arch/x86/x86_64/mmconfig_64.c xen/arch/x86/x86_emulate/x86_emulate.c xen/arch/x86/xen.lds.S xen/common/Makefile xen/common/compat/memory.c xen/common/cpu.c xen/common/cpupool.c xen/common/decompress.c xen/common/domain.c xen/common/domctl.c xen/common/event_channel.c xen/common/gdbstub.c xen/common/grant_table.c xen/common/hvm/save.c xen/common/kernel.c xen/common/kexec.c xen/common/keyhandler.c xen/common/libelf/libelf-loader.c xen/common/libelf/libelf-private.h xen/common/libelf/libelf-relocate.c xen/common/memory.c xen/common/notifier.c xen/common/page_alloc.c xen/common/perfc.c xen/common/radix-tree.c xen/common/rcupdate.c xen/common/sched_credit.c xen/common/sched_credit2.c xen/common/sched_sedf.c xen/common/schedule.c xen/common/shutdown.c xen/common/softirq.c xen/common/spinlock.c xen/common/stop_machine.c xen/common/sysctl.c xen/common/tasklet.c xen/common/time.c xen/common/timer.c xen/common/tmem.c xen/common/tmem_xen.c xen/common/trace.c xen/common/unlzo.c xen/drivers/acpi/numa.c xen/drivers/acpi/pmstat.c xen/drivers/acpi/tables.c xen/drivers/char/console.c xen/drivers/char/ns16550.c xen/drivers/cpufreq/cpufreq.c xen/drivers/cpufreq/cpufreq_misc_governors.c xen/drivers/cpufreq/cpufreq_ondemand.c xen/drivers/cpufreq/utility.c xen/drivers/passthrough/amd/iommu_acpi.c xen/drivers/passthrough/amd/iommu_init.c xen/drivers/passthrough/amd/iommu_intr.c xen/drivers/passthrough/amd/iommu_map.c xen/drivers/passthrough/amd/pci_amd_iommu.c xen/drivers/passthrough/io.c xen/drivers/passthrough/iommu.c xen/drivers/passthrough/pci.c xen/drivers/passthrough/vtd/dmar.c xen/drivers/passthrough/vtd/dmar.h xen/drivers/passthrough/vtd/extern.h xen/drivers/passthrough/vtd/ia64/ats.c xen/drivers/passthrough/vtd/ia64/vtd.c xen/drivers/passthrough/vtd/intremap.c xen/drivers/passthrough/vtd/iommu.c xen/drivers/passthrough/vtd/qinval.c xen/drivers/passthrough/vtd/utils.c xen/drivers/passthrough/vtd/vtd.h xen/drivers/passthrough/vtd/x86/ats.c xen/drivers/passthrough/vtd/x86/vtd.c xen/include/acpi/actbl1.h xen/include/acpi/cpufreq/cpufreq.h xen/include/acpi/cpufreq/processor_perf.h xen/include/asm-ia64/dom_fw_common.h xen/include/asm-ia64/dom_fw_domu.h xen/include/asm-ia64/domain.h xen/include/asm-ia64/linux-xen/asm/processor.h xen/include/asm-ia64/linux-xen/asm/ptrace.h xen/include/asm-ia64/linux-xen/asm/smp.h xen/include/asm-ia64/linux-xen/linux/cpu.h xen/include/asm-ia64/p2m_entry.h xen/include/asm-ia64/perfc.h xen/include/asm-x86/acpi.h xen/include/asm-x86/amd.h xen/include/asm-x86/apic.h xen/include/asm-x86/bzimage.h xen/include/asm-x86/config.h xen/include/asm-x86/cpufeature.h xen/include/asm-x86/current.h xen/include/asm-x86/debugger.h xen/include/asm-x86/desc.h xen/include/asm-x86/domain.h xen/include/asm-x86/genapic.h xen/include/asm-x86/guest_pt.h xen/include/asm-x86/hardirq.h xen/include/asm-x86/hvm/domain.h xen/include/asm-x86/hvm/emulate.h xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/io.h xen/include/asm-x86/hvm/iommu.h xen/include/asm-x86/hvm/irq.h xen/include/asm-x86/hvm/support.h xen/include/asm-x86/hvm/svm/amd-iommu-defs.h xen/include/asm-x86/hvm/svm/amd-iommu-proto.h xen/include/asm-x86/hvm/svm/svm.h xen/include/asm-x86/hvm/svm/vmcb.h xen/include/asm-x86/hvm/trace.h xen/include/asm-x86/hvm/vcpu.h xen/include/asm-x86/hvm/vlapic.h xen/include/asm-x86/hvm/vmx/vmcs.h xen/include/asm-x86/hvm/vmx/vmx.h xen/include/asm-x86/hvm/vmx/vpmu.h xen/include/asm-x86/hvm/vpmu.h xen/include/asm-x86/io_apic.h xen/include/asm-x86/irq.h xen/include/asm-x86/mach-default/mach_wakecpu.h xen/include/asm-x86/mach-generic/mach_apic.h xen/include/asm-x86/mce.h xen/include/asm-x86/mem_sharing.h xen/include/asm-x86/mm.h xen/include/asm-x86/mpspec.h xen/include/asm-x86/msi.h xen/include/asm-x86/msr-index.h xen/include/asm-x86/msr.h xen/include/asm-x86/mtrr.h xen/include/asm-x86/numa.h xen/include/asm-x86/p2m.h xen/include/asm-x86/page.h xen/include/asm-x86/paging.h xen/include/asm-x86/percpu.h xen/include/asm-x86/perfc.h xen/include/asm-x86/processor.h xen/include/asm-x86/regs.h xen/include/asm-x86/setup.h xen/include/asm-x86/smp.h xen/include/asm-x86/string.h xen/include/asm-x86/time.h xen/include/asm-x86/traps.h xen/include/asm-x86/x86_32/asm_defns.h xen/include/asm-x86/x86_32/page.h xen/include/asm-x86/x86_64/asm_defns.h xen/include/asm-x86/x86_64/page.h xen/include/asm-x86/x86_64/uaccess.h xen/include/asm-x86/xenoprof.h xen/include/public/arch-x86/xen-mca.h xen/include/public/domctl.h xen/include/public/features.h xen/include/public/hvm/hvm_op.h xen/include/public/hvm/params.h xen/include/public/io/ring.h xen/include/public/io/xs_wire.h xen/include/public/mem_event.h xen/include/public/memory.h xen/include/public/sched.h xen/include/public/sysctl.h xen/include/public/trace.h xen/include/public/xen.h xen/include/xen/acpi.h xen/include/xen/compat.h xen/include/xen/cpu.h xen/include/xen/cpuidle.h xen/include/xen/cpumask.h xen/include/xen/decompress.h xen/include/xen/domain.h xen/include/xen/event.h xen/include/xen/gdbstub.h xen/include/xen/hvm/irq.h xen/include/xen/init.h xen/include/xen/iommu.h xen/include/xen/irq.h xen/include/xen/irq_cpustat.h xen/include/xen/kexec.h xen/include/xen/lib.h xen/include/xen/libelf.h xen/include/xen/mm.h xen/include/xen/nodemask.h xen/include/xen/notifier.h xen/include/xen/pci_regs.h xen/include/xen/rcupdate.h xen/include/xen/sched-if.h xen/include/xen/sched.h xen/include/xen/smp.h xen/include/xen/softirq.h xen/include/xen/spinlock.h xen/include/xen/tasklet.h xen/include/xen/timer.h xen/include/xen/tmem.h xen/include/xen/tmem_xen.h xen/include/xen/trace.h xen/include/xlat.lst xen/kdb/include/kdbinc.h xen/kdb/kdb_cmds.c xen/xsm/flask/avc.c xen/xsm/flask/flask_op.c
line diff
     1.1 --- a/.hgignore	Wed Jun 09 19:53:32 2010 -0700
     1.2 +++ b/.hgignore	Fri Jul 16 17:16:06 2010 -0700
     1.3 @@ -2,7 +2,7 @@
     1.4  .*\.cmi$
     1.5  .*\.cmo$
     1.6  .*\.cmx$
     1.7 -.*\.d$
     1.8 +\..*\.d$
     1.9  .*\.o$
    1.10  .*\.opic$
    1.11  .*\.pyc$
    1.12 @@ -104,12 +104,11 @@
    1.13  ^stubdom/ioemu/
    1.14  ^stubdom/stubdompath\.sh$
    1.15  ^tools/.*/build/lib.*/.*\.py$
    1.16 -^tools/blktap2/daemon/blktapctrl$
    1.17 +^tools/blktap2/control/tap-ctl$
    1.18  ^tools/blktap2/drivers/img2qcow$
    1.19  ^tools/blktap2/drivers/lock-util$
    1.20  ^tools/blktap2/drivers/qcow-create$
    1.21  ^tools/blktap2/drivers/qcow2raw$
    1.22 -^tools/blktap2/drivers/tapdisk$
    1.23  ^tools/blktap2/drivers/tapdisk-client$
    1.24  ^tools/blktap2/drivers/tapdisk-diff$
    1.25  ^tools/blktap2/drivers/tapdisk-stream$
    1.26 @@ -134,6 +133,7 @@
    1.27  ^tools/firmware/.*\.bin$
    1.28  ^tools/firmware/.*\.sym$
    1.29  ^tools/firmware/.*bios/.*bios.*\.txt$
    1.30 +^tools/firmware/etherboot/eb-roms\.h$
    1.31  ^tools/firmware/etherboot/gpxe/.*$
    1.32  ^tools/firmware/extboot/extboot.img$
    1.33  ^tools/firmware/extboot/signrom$
    1.34 @@ -180,6 +180,7 @@
    1.35  ^tools/libxen/libxenapi-
    1.36  ^tools/libxen/test/test_bindings$
    1.37  ^tools/libxen/test/test_event_handling$
    1.38 +^tools/libxl/_.*\.h$
    1.39  ^tools/libxl/libxlu_cfg_y\.output$
    1.40  ^tools/libxl/xl$
    1.41  ^tools/libaio/src/.*\.ol$
    1.42 @@ -196,6 +197,7 @@
    1.43  ^tools/misc/xc_shadow$
    1.44  ^tools/misc/xen_cpuperf$
    1.45  ^tools/misc/xen-detect$
    1.46 +^tools/misc/xen-hptool$
    1.47  ^tools/misc/xen-tmem-list-parse$
    1.48  ^tools/misc/xenperf$
    1.49  ^tools/misc/xenpm$
    1.50 @@ -235,6 +237,7 @@
    1.51  ^tools/xcutils/xc_restore$
    1.52  ^tools/xcutils/xc_save$
    1.53  ^tools/xcutils/readnotes$
    1.54 +^tools/misc/xenwatchdogd$
    1.55  ^tools/xenfb/sdlfb$
    1.56  ^tools/xenfb/vncfb$
    1.57  ^tools/xenmon/xentrace_setmask$
    1.58 @@ -279,7 +282,10 @@
    1.59  ^tools/xm-test/tests/.*\.test$
    1.60  ^tools/ioemu-remote
    1.61  ^tools/ioemu-dir$
    1.62 -^tools/ocaml-xenstored.*$
    1.63 +^tools/ocaml/.*/.*\.annot$
    1.64 +^tools/ocaml/.*/.*\.cmx?a$
    1.65 +^tools/ocaml/.*/\.ocamldep\.make$
    1.66 +^tools/ocaml/xenstored/oxenstored$
    1.67  ^xen/\.banner.*$
    1.68  ^xen/BLOG$
    1.69  ^xen/System.map$
     2.1 --- a/Config.mk	Wed Jun 09 19:53:32 2010 -0700
     2.2 +++ b/Config.mk	Fri Jul 16 17:16:06 2010 -0700
     2.3 @@ -29,6 +29,7 @@ include $(XEN_ROOT)/config/$(XEN_TARGET_
     2.4  SHAREDIR    ?= $(PREFIX)/share
     2.5  DOCDIR      ?= $(SHAREDIR)/doc/xen
     2.6  MANDIR      ?= $(SHAREDIR)/man
     2.7 +BASH_COMPLETION_DIR ?= $(CONFIG_DIR)/bash_completion.d
     2.8  
     2.9  ifneq ($(EXTRA_PREFIX),)
    2.10  EXTRA_INCLUDES += $(EXTRA_PREFIX)/include
    2.11 @@ -156,23 +157,21 @@ QEMU_REMOTE=http://xenbits.xensource.com
    2.12  # CONFIG_QEMU ?= ../qemu-xen.git
    2.13  CONFIG_QEMU ?= $(QEMU_REMOTE)
    2.14  
    2.15 -QEMU_TAG := xen-4.0.0-rc6
    2.16 -#QEMU_TAG ?= e5d14857cd67490bf956d97c8888c0be95ed3f78
    2.17 -# Thu Feb 18 15:36:29 2010 +0000
    2.18 -# When xen_platform_pci=0 also disable fixed Xen platform ioports
    2.19 -
    2.20 -OCAML_XENSTORED_REPO=http://xenbits.xensource.com/ext/xen-ocaml-tools.hg
    2.21 -
    2.22 -# Build OCAML version of xenstored instead of the in-tree C version?
    2.23 -# This will cause $(OCAML_XENSTORED_REPO) to be cloned.
    2.24 -CONFIG_OCAML_XENSTORED ?= n
    2.25 +QEMU_TAG ?= 833e7e9a4c95739429dc0c803bbbf2346f9897fd
    2.26 +# Thu Jul 8 17:33:29 2010 +0100
    2.27 +# Move the xenfb pointer handler to the connected method
    2.28  
    2.29  # Optional components
    2.30  XENSTAT_XENTOP     ?= y
    2.31  VTPM_TOOLS         ?= n
    2.32  LIBXENAPI_BINDINGS ?= n
    2.33  PYTHON_TOOLS       ?= y
    2.34 +OCAML_TOOLS        ?= y
    2.35  CONFIG_MINITERM    ?= n
    2.36  CONFIG_LOMOUNT     ?= n
    2.37  
    2.38 +ifeq ($(OCAML_TOOLS),y)
    2.39 +OCAML_TOOLS := $(shell ocamlopt -v > /dev/null 2>&1 && echo "y" || echo "n")
    2.40 +endif
    2.41 +
    2.42  -include $(XEN_ROOT)/.config
     3.1 --- a/Makefile	Wed Jun 09 19:53:32 2010 -0700
     3.2 +++ b/Makefile	Fri Jul 16 17:16:06 2010 -0700
     3.3 @@ -37,7 +37,9 @@ test:
     3.4  # build and install everything into local dist directory
     3.5  .PHONY: dist
     3.6  dist: DESTDIR=$(DISTDIR)/install
     3.7 -dist: dist-xen dist-kernels dist-tools dist-stubdom dist-docs
     3.8 +dist: dist-xen dist-kernels dist-tools dist-stubdom dist-docs dist-misc
     3.9 +
    3.10 +dist-misc:
    3.11  	$(INSTALL_DIR) $(DISTDIR)/check
    3.12  	$(INSTALL_DATA) ./COPYING $(DISTDIR)
    3.13  	$(INSTALL_DATA) ./README $(DISTDIR)
    3.14 @@ -72,7 +74,7 @@ install-kernels:
    3.15  	for i in $(XKERNELS) ; do $(MAKE) $$i-install || exit 1; done
    3.16  
    3.17  .PHONY: install-stubdom
    3.18 -install-stubdom: tools/ioemu-dir
    3.19 +install-stubdom: tools/ioemu-dir install-tools
    3.20  	$(MAKE) -C stubdom install
    3.21  ifeq (x86_64,$(XEN_TARGET_ARCH))
    3.22  	XEN_TARGET_ARCH=x86_32 $(MAKE) -C stubdom install-grub
     4.1 --- a/README	Wed Jun 09 19:53:32 2010 -0700
     4.2 +++ b/README	Fri Jul 16 17:16:06 2010 -0700
     4.3 @@ -1,10 +1,10 @@
     4.4  #################################
     4.5 - __  __            _  _    ___  
     4.6 - \ \/ /___ _ __   | || |  / _ \ 
     4.7 -  \  // _ \ '_ \  | || |_| | | |
     4.8 -  /  \  __/ | | | |__   _| |_| |
     4.9 - /_/\_\___|_| |_|    |_|(_)___/ 
    4.10 -
    4.11 + __  __            _  _    _ 
    4.12 + \ \/ /___ _ __   | || |  / |
    4.13 +  \  // _ \ '_ \  | || |_ | |
    4.14 +  /  \  __/ | | | |__   _|| |
    4.15 + /_/\_\___|_| |_|    |_|(_)_|
    4.16 +                             
    4.17  #################################
    4.18  
    4.19  http://www.xen.org/
    4.20 @@ -19,7 +19,7 @@ is freely-distributable Open Source soft
    4.21  GPL. Since its initial public release, Xen has grown a large
    4.22  development community, spearheaded by xen.org (http://www.xen.org).
    4.23  
    4.24 -The 4.0 release offers excellent performance, hardware support and
    4.25 +The 4.1 release offers excellent performance, hardware support and
    4.26  enterprise-grade features such as x86_32-PAE, x86_64, SMP guests and
    4.27  live relocation of VMs. Ports to Linux, NetBSD, FreeBSD and Solaris
    4.28  are available from the community.
     5.1 --- a/buildconfigs/enable-xen-config	Wed Jun 09 19:53:32 2010 -0700
     5.2 +++ b/buildconfigs/enable-xen-config	Fri Jul 16 17:16:06 2010 -0700
     5.3 @@ -15,7 +15,7 @@ setopt()
     5.4  	VALUE=$2
     5.5  
     5.6  	# First remove any existing instances of this option
     5.7 -	sed -e "s/^# ${OPTION} is not set$//g ; s/^^{OPTION}=.$//g" -i "${CONFIG}"
     5.8 +	sed -e "s/^# ${OPTION} is not set$//g ; s/^${OPTION}=.*$//g" -i "${CONFIG}"
     5.9  
    5.10  	# Then append the new value
    5.11  	case ${VALUE} in
    5.12 @@ -48,6 +48,7 @@ setopt CONFIG_XEN_DOM0 y
    5.13  setopt CONFIG_XEN_SYS_HYPERVISOR y
    5.14  setopt CONFIG_XEN_GNTDEV y
    5.15  setopt CONFIG_VMI y
    5.16 +setopt CONFIG_TUN y
    5.17  
    5.18  setopt CONFIG_KVM y
    5.19  setopt CONFIG_KVM_INTEL y
     6.1 --- a/buildconfigs/mk.linux-2.6-pvops	Wed Jun 09 19:53:32 2010 -0700
     6.2 +++ b/buildconfigs/mk.linux-2.6-pvops	Fri Jul 16 17:16:06 2010 -0700
     6.3 @@ -10,7 +10,7 @@ XEN_LINUX_GIT_URL ?= http://www.kernel.o
     6.4  else
     6.5  XEN_LINUX_GIT_URL ?= git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen.git
     6.6  endif
     6.7 -XEN_LINUX_GIT_REMOTEBRANCH ?= xen/master
     6.8 +XEN_LINUX_GIT_REMOTEBRANCH ?= xen/stable-2.6.32.x
     6.9  
    6.10  EXTRAVERSION ?=
    6.11  
     7.1 --- a/buildconfigs/src.git-clone	Wed Jun 09 19:53:32 2010 -0700
     7.2 +++ b/buildconfigs/src.git-clone	Fri Jul 16 17:16:06 2010 -0700
     7.3 @@ -13,19 +13,20 @@ ifeq ($(XEN_LINUX_GIT_REMOTEBRANCH),)
     7.4  .ERROR: XEN_LINUX_GIT_REMOTEBRANCH not specified
     7.5  endif
     7.6  
     7.7 -XEN_LINUX_GIT_LOCALBRANCH ?= master
     7.8 +XEN_GIT_ORIGIN ?= xen
     7.9 +
    7.10 +XEN_LINUX_GIT_LOCALBRANCH ?= $(XEN_LINUX_GIT_REMOTEBRANCH)
    7.11  
    7.12  # Set XEN_LINUX_GITREV to update to a particlar revision.
    7.13 -XEN_LINUX_GITREV  ?= 
    7.14 +XEN_LINUX_GITREV  ?= $(XEN_GIT_ORIGIN)/$(XEN_LINUX_GIT_REMOTEBRANCH)
    7.15  
    7.16  $(LINUX_SRCDIR)/.valid-src: $(__XEN_LINUX_UPDATE)
    7.17  	set -ex; \
    7.18  	if ! [ -d $(LINUX_SRCDIR) ]; then \
    7.19  		rm -rf $(LINUX_SRCDIR) $(LINUX_SRCDIR).tmp; \
    7.20  		mkdir $(LINUX_SRCDIR).tmp; rmdir $(LINUX_SRCDIR).tmp; \
    7.21 -		$(GIT) clone $(XEN_LINUX_GIT_URL) $(LINUX_SRCDIR).tmp; \
    7.22 -		cd $(LINUX_SRCDIR).tmp; \
    7.23 -		$(GIT) checkout $(XEN_LINUX_GIT_REMOTEBRANCH); \
    7.24 -		cd ..; mv $(LINUX_SRCDIR).tmp $(LINUX_SRCDIR); \
    7.25 +		$(GIT) clone -o $(XEN_GIT_ORIGIN) -n $(XEN_LINUX_GIT_URL) $(LINUX_SRCDIR).tmp; \
    7.26 +		(cd $(LINUX_SRCDIR).tmp; git checkout -b $(XEN_LINUX_GIT_LOCALBRANCH) $(XEN_LINUX_GITREV) ); \
    7.27 +		mv $(LINUX_SRCDIR).tmp $(LINUX_SRCDIR); \
    7.28  	fi
    7.29  	touch $@
     8.1 --- a/docs/man/xm.pod.1	Wed Jun 09 19:53:32 2010 -0700
     8.2 +++ b/docs/man/xm.pod.1	Fri Jul 16 17:16:06 2010 -0700
     8.3 @@ -40,12 +40,10 @@ Most B<xm> commands require root privile
     8.4  communications channels used to talk to the hypervisor.  Running as
     8.5  non root will return an error.
     8.6  
     8.7 -Most B<xm> commands act asynchronously, so just because the B<xm>
     8.8 -command returned doesn't mean the action is complete.  This is
     8.9 -important, as many operations on domains, like create and shutdown,
    8.10 -can take considerable time (30 seconds or more) to bring the machine
    8.11 -into a fully compliant state.  If you want to know when one of these
    8.12 -actions has finished you must poll through B<xm list> periodically.
    8.13 +Most B<xm> commands act synchronously, except maybe create, shutdown,
    8.14 +mem-set and vcpu-set. The fact that the B<xm> command returned doesn't
    8.15 +necessarily mean that the action is complete and you must poll through
    8.16 +xm list periodically to detect that the operation completed.
    8.17  
    8.18  =head1 DOMAIN SUBCOMMANDS
    8.19  
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/docs/misc/tmem-internals.html	Fri Jul 16 17:16:06 2010 -0700
     9.3 @@ -0,0 +1,798 @@
     9.4 +<h1>Transcendent Memory Internals in Xen</h1>
     9.5 +<P>
     9.6 +by Dan Magenheimer, Oracle Corp.</p>
     9.7 +<P>
     9.8 +Draft 0.1 -- Updated: 20100324
     9.9 +<h2>Overview</h2>
    9.10 +<P>
    9.11 +This document focuses on the internal implementation of
    9.12 +Transcendent Memory (tmem) on Xen.  It assumes
    9.13 +that the reader has a basic knowledge of the terminology, objectives, and
    9.14 +functionality of tmem and also has access to the Xen source code.
    9.15 +It corresponds to the Xen 4.0 release, with
    9.16 +patch added to support page deduplication (V2).
    9.17 +<P>
    9.18 +The primary responsibilities of the tmem implementation are to:
    9.19 +<ul>
    9.20 +<li>manage a potentially huge and extremely dynamic
    9.21 +number of memory pages from a potentially large number of clients (domains)
    9.22 +with low memory overhead and proper isolation
    9.23 +<li>provide quick and efficient access to these
    9.24 +pages with as much concurrency as possible
    9.25 +<li>enable efficient reclamation and <i>eviction</i> of pages (e.g. when
    9.26 +memory is fully utilized)
    9.27 +<li>optionally, increase page density through compression and/or
    9.28 +deduplication
    9.29 +<li>where necessary, properly assign and account for
    9.30 +memory belonging to guests to avoid malicious and/or accidental unfairness
    9.31 +and/or denial-of-service
    9.32 +<li>record utilization statistics and make them available to management tools
    9.33 +</ul>
    9.34 +<h2>Source Code Organization</h2>
    9.35 +
    9.36 +<P>
    9.37 +The source code in Xen that provides the tmem functionality
    9.38 +is divided up into four files: tmem.c, tmem.h, tmem_xen.c, and tmem_xen.h.
    9.39 +The files tmem.c and tmem.h are intended to
    9.40 +be implementation- (and hypervisor-) independent and the other two files
    9.41 +provide the Xen-specific code.  This
    9.42 +division is intended to make it easier to port tmem functionality to other
    9.43 +hypervisors, though at this time porting to other hypervisors has not been
    9.44 +attempted.  Together, these four files
    9.45 +total less than 4000 lines of C code.
    9.46 +<P>
    9.47 +Even ignoring the implementation-specific functionality, the
    9.48 +implementation-independent part of tmem has several dependencies on
    9.49 +library functionality (Xen source filenames in parentheses):
    9.50 +<ul>
    9.51 +<li>
    9.52 +a good fast general-purpose dynamic memory
    9.53 +allocator with bounded response time and efficient use of memory for a very
    9.54 +large number of sub-page allocations.  To
    9.55 +achieve this in Xen, the bad old memory allocator was replaced with a
    9.56 +slightly-modified version of TLSF (xmalloc_tlsf.c), first ported to Linux by
    9.57 +Nitin Gupta for compcache.
    9.58 +<li>
    9.59 +good tree data structure libraries, specifically
    9.60 +<i>red-black</i> trees (rbtree.c) and <i>radix</i> trees (radix-tree.c).
    9.61 +Code for these was borrowed for Linux and adapted for tmem and Xen.
    9.62 +<li>
    9.63 +good locking and list code.  Both of these existed in Xen and required
    9.64 +little or no change.
    9.65 +<li>
    9.66 +optionally, a good fast lossless compression
    9.67 +library.  The Xen implementation added to
    9.68 +support tmem uses LZO1X (lzo.c), also ported for Linux by Nitin Gupta.
    9.69 +</ul>
    9.70 +<P>
    9.71 +More information about the specific functionality of these
    9.72 +libraries can easily be found through a search engine, via wikipedia, or in the
    9.73 +Xen or Linux source logs so we will not elaborate further here.
    9.74 +
    9.75 +<h2>Prefixes/Abbreviations/Glossary</h2>
    9.76 +
    9.77 +<P>
    9.78 +The tmem code uses several prefixes and abbreviations.
    9.79 +Knowledge of these will improve code readability:
    9.80 +<ul>
    9.81 +<li>
    9.82 +<i>tmh</i> ==
    9.83 +transcendent memory host.  Functions or
    9.84 +data structures that are defined by the implementation-specific code, i.e. the
    9.85 +Xen host code
    9.86 +<li>
    9.87 +<i>tmemc</i>
    9.88 +== transcendent memory control.
    9.89 +Functions or data structures that provide management tool functionality,
    9.90 +rather than core tmem operations.
    9.91 +<li>
    9.92 +<i>cli </i>or
    9.93 +<i>client</i> == client.
    9.94 +The tmem generic term for a domain or a guest OS.
    9.95 +</ul>
    9.96 +<P>
    9.97 +When used in prose, common tmem operations are indicated
    9.98 +with a different font, such as <big><kbd>put</kbd></big>
    9.99 +and <big><kbd>get</kbd></big>.
   9.100 +
   9.101 +<h2>Key Data Structures</h2>
   9.102 +
   9.103 +<P>
   9.104 +To manage a huge number of pages, efficient data structures
   9.105 +must be carefully selected.
   9.106 +<P>
   9.107 +Recall that a tmem-enabled guest OS may create one or more
   9.108 +pools with different attributes.  It then
   9.109 +<kbd>put</kbd></big>s and <kbd>get</kbd></big>s
   9.110 +pages to/from this pool, identifying the page
   9.111 +with a <i>handle</i> that consists of a <i>pool_id</i>, an <i>
   9.112 +object_id</i>, and a <i>page_id </i>(sometimes
   9.113 +called an <i>index</i>).
   9.114 +This suggests a few obvious core data
   9.115 +structures:
   9.116 +<ul>
   9.117 +<li>
   9.118 +When a guest OS first calls tmem, a <i>client_t</i> is created to contain
   9.119 +and track all uses of tmem by that guest OS.  Among
   9.120 +other things, a <i>client_t</i> keeps pointers
   9.121 +to a fixed number of pools (16 in the current Xen implementation).
   9.122 +<li>
   9.123 +When a guest OS requests a new pool, a <i>pool_t</i> is created.
   9.124 +Some pools are shared and are kept in a
   9.125 +sharelist (<i>sharelist_t</i>) which points
   9.126 +to all the clients that are sharing the pool.
   9.127 +Since an <i>object_id</i> is 64-bits,
   9.128 +a <i>pool_t</i> must be able to keep track
   9.129 +of a potentially very large number of objects.
   9.130 +To do so, it maintains a number of parallel trees (256 in the current
   9.131 +Xen implementation) and a hash algorithm is applied to the <i>object_id</i>
   9.132 +to select the correct tree.
   9.133 +Each tree element points to an object.
   9.134 +Because an <i>object_id</i> usually represents an <i>inode</i>
   9.135 +(a unique file number identifier), and <i>inode</i> numbers
   9.136 +are fairly random, though often &quot;clumpy&quot;, a <i>red-black tree</i>
   9.137 +is used.
   9.138 +<li>
   9.139 +When a guest first
   9.140 +<kbd>put</kbd></big>s a page to a pool with an as-yet-unused <i>object_id,</i> an
   9.141 +<i>obj_t</i> is created.  Since a <i
   9.142 +>page_id</i> is usually an index into a file,
   9.143 +it is often a small number, but may sometimes be very large (up to
   9.144 +32-bits).  A <i>radix tree</i> is a good data structure to contain items
   9.145 +with this kind of index distribution.
   9.146 +<li>
   9.147 +When a page is
   9.148 +<kbd>put</kbd></big>, a page descriptor, or <i>pgp_t</i>, is created, which
   9.149 +among other things will point to the storage location where the data is kept.
   9.150 +In the normal case the pointer is to a <i>pfp_t</i>, which is an
   9.151 +implementation-specific datatype representing a physical pageframe in memory
   9.152 +(which in Xen is a &quot;struct page_info&quot;).
   9.153 +When deduplication is enabled, it points to
   9.154 +yet another data structure, a <i>pcd_</i>t
   9.155 +(see below).  When compression is enabled
   9.156 +(and deduplication is not), the pointer points directly to the compressed data.
   9.157 +For reasons we will see shortly, each <i>pgp_t</i> that represents
   9.158 +an <i>ephemeral</i> page (that is, a page placed
   9.159 +in an <i>ephemeral</i> pool) is also placed
   9.160 +into two doubly-linked linked lists, one containing all ephemeral pages
   9.161 +<kbd>put</kbd></big> by the same client and one
   9.162 +containing all ephemeral pages across all clients (&quot;global&quot;).
   9.163 +<li>
   9.164 +When deduplication is enabled, multiple <i>pgp_</i>t's may need to point to
   9.165 +the same data, so another data structure (and level of indirection) is used
   9.166 +called a page content descriptor, or <i>pcd_t</i>.
   9.167 +Multiple page descriptors (<i>pgp_t</i>'s) may point to the same <i>pcd_t</i>.
   9.168 +The <i>pcd_t</i>, in turn, points to either a <i>pfp_t</i>
   9.169 +(if a full page of data), directly to a
   9.170 +location in memory (if the page has been compressed or trailing zeroes have
   9.171 +been eliminated), or even a NULL pointer (if the page contained all zeroes and
   9.172 +trailing zero elimination is enabled).
   9.173 +</ul>
   9.174 +<P>
   9.175 +The most apparent usage of this multi-layer web of data structures
   9.176 +is &quot;top-down&quot; because, in normal operation, the vast majority of tmem
   9.177 +operations invoked by a client are
   9.178 +<kbd>put</kbd></big>s and <kbd>get</kbd></big>s, which require the various
   9.179 +data structures to be walked starting with the <i>client_t</i>, then
   9.180 +a <i>pool_t</i>, then an <i>obj_t</i>, then a <i>pgd_t</i>.
   9.181 +However, there is another highly frequent tmem operation that is not
   9.182 +visible from a client: memory reclamation.
   9.183 +Since tmem attempts to use all spare memory in the system, it must
   9.184 +frequently free up, or <i>evict</i>,
   9.185 +pages.  The eviction algorithm will be
   9.186 +explained in more detail later but, in brief, to free memory, ephemeral pages
   9.187 +are removed from the tail of one of the doubly-linked lists, which means that
   9.188 +all of the data structures associated with that page-to-be-removed must be
   9.189 +updated or eliminated and freed.  As a
   9.190 +result, each data structure also contains a <i>back-pointer</i>
   9.191 +to its parent, for example every <i>obj_t</i>
   9.192 +contains a pointer to its containing <i>pool_t</i>.
   9.193 +<P>
   9.194 +This complex web of interconnected data structures is updated constantly and
   9.195 +thus extremely sensitive to careless code changes which, for example, may
   9.196 +result in unexpected hypervisor crashes or non-obvious memory leaks.
   9.197 +On the other hand, the code is fairly well
   9.198 +modularized so, once understood, it is possible to relatively easily switch out
   9.199 +one kind of data structure for another.
   9.200 +To catch problems as quickly as possible when debug is enabled, most of
   9.201 +the data structures are equipped with <i>sentinels</i>and many inter-function
   9.202 +assumptions are documented and tested dynamically
   9.203 +with <i>assertions</i>.
   9.204 +While these clutter and lengthen the tmem
   9.205 +code substantially, their presence has proven invaluable on many occasions.
   9.206 +<P>
   9.207 +For completeness, we should also describe a key data structure in the Xen
   9.208 +implementation-dependent code: the <i>tmh_page_list</i>. For security and
   9.209 +performance reasons, pages that are freed due to tmem operations (such
   9.210 +as <kbd>get</kbd></big>) are not immediately put back into Xen's pool
   9.211 +of free memory (aka the Xen <i>heap</i>).
   9.212 +Tmem pages may contain guest-private data that must be <i>scrubbed</i> before
   9.213 +those memory pages are released for the use of other guests.
   9.214 +But if a page is immediately re-used inside of tmem itself, the entire
   9.215 +page is overwritten with new data, so need not be scrubbed.
   9.216 +Since tmem is usually the most frequent
   9.217 +customer of the Xen heap allocation code, it would be a waste of time to scrub
   9.218 +a page, release it to the Xen heap, and then immediately re-allocate it
   9.219 +again.  So, instead, tmem maintains
   9.220 +currently-unused pages of memory on its own free list, <i>tmh_page_list</i>,
   9.221 +and returns the pages to Xen only when non-tmem Xen
   9.222 +heap allocation requests would otherwise fail.
   9.223 +
   9.224 +<h2>Scalablility/Concurrency</h2>
   9.225 +
   9.226 +<P>Tmem has been designed to be highly scalable.
   9.227 +Since tmem access is invoked similarly in
   9.228 +many ways to asynchronous disk access, a &quot;big SMP&quot; tmem-aware guest
   9.229 +OS can, and often will, invoke tmem hypercalls simultaneously on many different
   9.230 +physical CPUs.  And, of course, multiple
   9.231 +tmem-aware guests may independently and simultaneously invoke tmem
   9.232 +hypercalls.  While the normal frequency
   9.233 +of tmem invocations is rarely extremely high, some tmem operations such as data
   9.234 +compression or lookups in a very large tree may take tens of thousands of
   9.235 +cycles or more to complete.  Measurements
   9.236 +have shown that normal workloads spend no more than about 0.2% (2% with
   9.237 +compression enabled) of CPU time executing tmem operations.
   9.238 +But those familiar with OS scalability issues
   9.239 +recognize that even this limited execution time can create concurrency problems
   9.240 +in large systems and result in poorly-scalable performance.
   9.241 +<P>
   9.242 +A good locking strategy is critical to concurrency, but also
   9.243 +must be designed carefully to avoid deadlock and <i>livelock</i> problems.  For
   9.244 +debugging purposes, tmem supports a &quot;big kernel lock&quot; which disables
   9.245 +concurrency altogether (enabled in Xen with &quot;tmem_lock&quot;, but note
   9.246 +that this functionality is rarely tested and likely has bit-rotted). Infrequent
   9.247 +but invasive tmem hypercalls, such as pool creation or the control operations,
   9.248 +are serialized on a single <i>read-write lock</i>, called tmem_rwlock,
   9.249 +which must be held for writing.  All other tmem operations must hold this lock
   9.250 +for reading, so frequent operations such as
   9.251 +<kbd>put</kbd></big> and <kbd>get</kbd></big> <kbd>flush</kbd></big> can execute simultaneously
   9.252 +as long as no invasive operations are occurring.
   9.253 +<P>
   9.254 +Once a pool has been selected, there is a per-pool
   9.255 +read-write lock (<i>pool_rwlock</i>) which
   9.256 +must be held for writing if any transformative operations might occur within
   9.257 +that pool, such as when an<i> obj_t</i> is
   9.258 +created or destroyed.  For the highly
   9.259 +frequent operation of finding an<i> obj_t</i>
   9.260 +within a pool, pool_rwlock must be held for reading.
   9.261 +<P>
   9.262 +Once an object has been selected, there is a per-object
   9.263 +spinlock (<i>obj_spinlock)</i>.
   9.264 +This is a spinlock rather than a read-write
   9.265 +lock because nearly all of the most frequent tmem operations (e.g.
   9.266 +<kbd>put</kbd></big> and <kbd>get</kbd></big> <kbd>flush</kbd></big>)
   9.267 +are transformative, in
   9.268 +that they add or remove a page within the object.
   9.269 +This lock is generally taken whenever an
   9.270 +object lookup occurs and released when the tmem operation is complete.
   9.271 +<P>
   9.272 +Next, the per-client and global ephemeral lists are
   9.273 +protected by a single global spinlock (<i>eph_lists_</i>spinlock)
   9.274 +and the per-client persistent lists are also protected by a single global
   9.275 +spinlock (<i>pers_list_spinlock</i>).
   9.276 +And to complete the description of
   9.277 +implementation-independent locks, if page deduplication is enabled, all pages
   9.278 +for which the first byte match are contained in one of 256 trees that are
   9.279 +protected by one of 256 corresponding read-write locks
   9.280 +(<i>pcd_tree_rwlocks</i>).
   9.281 +<P>
   9.282 +In the Xen-specific code (tmem_xen.c), page frames (e.g.  struct page_info)
   9.283 +that have been released are kept in a list (<i>tmh_page_list</i>) that
   9.284 +is protected by a spinlock (<i>tmh_page_list_lock</i>).
   9.285 +There is also an &quot;implied&quot; lock
   9.286 +associated with compression, which is likely the most time-consuming operation
   9.287 +in all of tmem (of course, only when compression is enabled): A compression
   9.288 +buffer is allocated one-per-physical-cpu early in Xen boot and a pointer to
   9.289 +this buffer is returned to implementation-independent code and used without a
   9.290 +lock.
   9.291 +<P>
   9.292 +The proper method to avoid deadlocks is to take and release
   9.293 +locks in a very specific predetermined order.
   9.294 +Unfortunately, since tmem data structures must simultaneously be
   9.295 +accessed &quot;top-down&quot; (
   9.296 +<kbd>put</kbd></big> and <kbd>get</kbd></big>)
   9.297 +and &quot;bottoms-up&quot;
   9.298 +(memory reclamation), more complex methods must be employed:
   9.299 +A <i>trylock</i>mechanism is used (c.f. <i>tmem_try_to_evict_pgp()</i>),
   9.300 +which takes the lock if it is available but returns immediately (rather than
   9.301 +spinning and waiting) if the lock is not available.
   9.302 +When walking the ephemeral list to identify
   9.303 +pages to free, any page that belongs to an object that is locked is simply
   9.304 +skipped.  Further, if the page is the
   9.305 +last page belonging to an object, and the pool read-write lock for the pool the
   9.306 +object belongs to is not available (for writing), that object is skipped.
   9.307 +These constraints modify the LRU algorithm
   9.308 +somewhat, but avoid the potential for deadlock.
   9.309 +<P>
   9.310 +Unfortunately, a livelock was still discovered in this approach:
   9.311 +When memory is scarce and each client is
   9.312 +<kbd>put</kbd></big>ting a large number of pages
   9.313 +for exactly one object (and thus holding the object spinlock for that object),
   9.314 +memory reclamation takes a very long time to determine that it is unable to
   9.315 +free any pages, and so the time to do a
   9.316 +<kbd>put</kbd></big> (which eventually fails) becomes linear to the
   9.317 +number of pages in the object!  To avoid
   9.318 +this situation, a workaround was added to always ensure a minimum amount of
   9.319 +memory (1MB) is available before any object lock is taken for the client
   9.320 +invoking tmem (see <i>tmem_ensure_avail_pages()</i>).
   9.321 +Other such livelocks (and perhaps deadlocks)
   9.322 +may be lurking.
   9.323 +<P>
   9.324 +A last issue related to concurrency is atomicity of counters.
   9.325 +Tmem gathers a large number of
   9.326 +statistics.  Some of these counters are
   9.327 +informational only, while some are critical to tmem operation and must be
   9.328 +incremented and decremented atomically to ensure, for example, that the number
   9.329 +of pages in a tree never goes negative if two concurrent tmem operations access
   9.330 +the counter exactly simultaneously.  Some
   9.331 +of the atomic counters are used for debugging (in assertions) and perhaps need
   9.332 +not be atomic; fixing these may increase performance slightly by reducing
   9.333 +cache-coherency traffic.  Similarly, some
   9.334 +of the non-atomic counters may yield strange results to management tools, such
   9.335 +as showing the total number of successful
   9.336 +<kbd>put</kbd></big>s as being higher than the number of
   9.337 +<kbd>put</kbd></big>s attempted.
   9.338 +These are left as exercises for future tmem implementors.
   9.339 +
   9.340 +<h2>Control and Manageability</h2>
   9.341 +
   9.342 +<P>
   9.343 +Tmem has a control interface to, for example, set various
   9.344 +parameters and obtain statistics.  All
   9.345 +tmem control operations funnel through <i>do_tmem_control()</i>
   9.346 +and other functions supporting tmem control operations are prefixed
   9.347 +with <i>tmemc_</i>.
   9.348 +
   9.349 +<P>
   9.350 +During normal operation, even if only one tmem-aware guest
   9.351 +is running, tmem may absorb nearly all free memory in the system for its own
   9.352 +use.  Then if a management tool wishes to
   9.353 +create a new guest (or migrate a guest from another system to this one), it may
   9.354 +notice that there is insufficient &quot;free&quot; memory and fail the creation
   9.355 +(or migration).  For this reason, tmem
   9.356 +introduces a new tool-visible class of memory -- <i>freeable</i> memory --
   9.357 +and provides a control interface to access
   9.358 +it.  All ephemeral memory and all pages on the <i>tmh_page_list</i>
   9.359 +are freeable. To properly access freeable
   9.360 +memory, a management tool must follow a sequence of steps:
   9.361 +<ul>
   9.362 +<li>
   9.363 +<i>freeze</i>
   9.364 +tmem:When tmem is frozen, all 
   9.365 +<kbd>put</kbd></big>s fail, which ensures that no
   9.366 +additional memory may be absorbed by tmem.
   9.367 +(See <i>tmemc_freeze_pools()</i>, and
   9.368 +note that individual clients may be frozen, though this functionality may be
   9.369 +used only rarely.)
   9.370 +<li>
   9.371 +<i>query freeable MB: </i>If all freeable memory were released to the Xen
   9.372 +heap, this is the amount of memory (in MB) that would be freed.
   9.373 +See <i>tmh_freeable_pages()</i>.
   9.374 +<li>
   9.375 +<i>flush</i>:
   9.376 +Tmem may be requested to flush, or relinquish, a certain amount of memory, e.g.
   9.377 +back to the Xen heap.  This amount is
   9.378 +specified in KB.  See <i
   9.379 +>tmemc_flush_mem()</i> and <i
   9.380 +>tmem_relinquish_npages()</i>.
   9.381 +<li>
   9.382 +At this point the management tool may allocate
   9.383 +the memory, e.g. using Xen's published interfaces.
   9.384 +<li>
   9.385 +<i>thaw</i>
   9.386 +tmem: This terminates the freeze, allowing tmem to accept 
   9.387 +<kbd>put</kbd></big>s again.
   9.388 +</ul>
   9.389 +<P>
   9.390 +Extensive tmem statistics are available through tmem's
   9.391 +control interface (see <i>tmemc_list </i>and
   9.392 +the separate source for the &quot;xm tmem-list&quot; command and the
   9.393 +xen-tmem-list-parse tool).  To maximize
   9.394 +forward/backward compatibility with future tmem and tools versions, statistical
   9.395 +information is passed via an ASCII interface where each individual counter is
   9.396 +identified by an easily parseable two-letter ASCII sequence.
   9.397 +
   9.398 +<h2>Save/Restore/Migrate</h2>
   9.399 +
   9.400 +<P>
   9.401 +Another piece of functionality that has a major impact on
   9.402 +the tmem code is support for save/restore of a tmem client and, highly related,
   9.403 +live migration of a tmem client.
   9.404 +Ephemeral pages, by definition, do not need to be saved or
   9.405 +live-migrated, but persistent pages are part of the state of a running VM and
   9.406 +so must be properly preserved.
   9.407 +<P>
   9.408 +When a save (or live-migrate) of a tmem-enabled VM is initiated, the first step
   9.409 +is for the tmem client to be frozen (see the manageability section).
   9.410 +Next, tmem API version information is
   9.411 +recorded (to avoid possible incompatibility issues as the tmem spec evolves in
   9.412 +the future).  Then, certain high-level
   9.413 +tmem structural information specific to the client is recorded, including
   9.414 +information about the existing pools.
   9.415 +Finally, the contents of all persistent pages are recorded.
   9.416 +<P>
   9.417 +For live-migration, the process is somewhat more complicated.
   9.418 +Ignoring tmem for a moment, recall that in
   9.419 +live migration, the vast majority of the VM's memory is transferred while the
   9.420 +VM is still fully operational.  During
   9.421 +each phase, memory pages belonging to the VM that are changed are marked and
   9.422 +then retransmitted during a later phase.
   9.423 +Eventually only a small amount of memory remains, the VM is paused, the
   9.424 +remaining memory is transmitted, and the VM is unpaused on the target machine.
   9.425 +<P>
   9.426 +The number of persistent tmem pages may be quite large,
   9.427 +possibly even larger than all the other memory used by the VM; so it is
   9.428 +unacceptable to transmit persistent tmem pages during the &quot;paused&quot;
   9.429 +phase of live migration.  But if the VM
   9.430 +is still operational, it may be making calls to tmem:
   9.431 +A frozen tmem client will reject any 
   9.432 +<big><kbd>put</kbd></big> operations, but tmem must
   9.433 +still correctly process <big><kbd>flush</kbd></big>es
   9.434 +(page and object), including implicit flushes due to duplicate 
   9.435 +<big><kbd>put</kbd></big>s.
   9.436 +Fortunately, these operations can only
   9.437 +invalidate tmem pages, not overwrite tmem pages or create new pages.
   9.438 +So, when a live-migrate has been initiated,
   9.439 +the client is frozen.  Then during the
   9.440 +&quot;live&quot; phase, tmem transmits all persistent pages, but also records
   9.441 +the handle of all persistent pages that are invalidated.
   9.442 +Then, during the &quot;paused&quot; phase,
   9.443 +only the handles of invalidated persistent pages are transmitted, resulting in
   9.444 +the invalidation on the target machine of any matching pages that were
   9.445 +previously transmitted during the &quot;live&quot; phase.
   9.446 +<P>
   9.447 +For restore (and on the target machine of a live migration),
   9.448 +tmem must be capable of reconstructing the internal state of the client from
   9.449 +the saved/migrated data.  However, it is
   9.450 +not the client itself that is <big><kbd>put</kbd></big>'ing
   9.451 +the pages but the management tools conducting the restore/migration.
   9.452 +This slightly complicates tmem by requiring
   9.453 +new API calls and new functions in the implementation, but the code is
   9.454 +structured so that duplication is minimized.
   9.455 +Once all tmem data structures for the client are reconstructed, all
   9.456 +persistent pages are recreated and, in the case of live-migration, all
   9.457 +invalidations have been processed and the client has been thawed, the restored
   9.458 +client can be resumed.
   9.459 +<P>
   9.460 +Finally, tmem's data structures must be cluttered a bit to
   9.461 +support save/restore/migration.  Notably,
   9.462 +a per-pool list of persistent pages must be maintained and, during live
   9.463 +migration, a per-client list of invalidated pages must be logged.
   9.464 +A reader of the code will note that these
   9.465 +lists are overlaid into space-sensitive data structures as a union, which may
   9.466 +be more error-prone but eliminates significant space waste.
   9.467 +
   9.468 +<h2>Miscellaneous Tmem Topics</h2>
   9.469 +
   9.470 +<P>
   9.471 +<i><b>Duplicate <big><kbd>puts</kbd></big></b></i>.
   9.472 +One interesting corner case that
   9.473 +significantly complicates the tmem source code is the possibility
   9.474 +of a <i>duplicate</i>
   9.475 +<big><kbd>put</kbd></big>,
   9.476 +which occurs when two
   9.477 +<big><kbd>put</kbd></big>s
   9.478 +are requested with the same handle but with possibly different data.
   9.479 +The tmem API addresses
   9.480 +<i>
   9.481 +<big><kbd>put</kbd></big>-<big><kbd>put</kbd></big>-<big><kbd>get</kbd></big>
   9.482 +coherence</i> explicitly: When a duplicate
   9.483 +<big><kbd>put</kbd></big> occurs, tmem may react one of two ways: (1) The 
   9.484 +<big><kbd>put</kbd></big> may succeed with the old
   9.485 +data overwritten by the new data, or (2) the
   9.486 +<big><kbd>put</kbd></big> may be failed with the original data flushed and
   9.487 +neither the old nor the new data accessible.
   9.488 +Tmem may <i>not</i> fail the 
   9.489 +<big><kbd>put</kbd></big> and leave the old data accessible.
   9.490 +<P>
   9.491 +When tmem has been actively working for an extended period,
   9.492 +system memory may be in short supply and it is possible for a memory allocation
   9.493 +for a page (or even a data structure such as a <i>pgd_t</i>) to fail. Thus,
   9.494 +for a duplicate 
   9.495 +<big><kbd>put</kbd></big>, it may be impossible for tmem to temporarily
   9.496 +simultaneously maintain data structures and data for both the original 
   9.497 +<big><kbd>put</kbd></big> and the duplicate 
   9.498 +<big><kbd>put</kbd></big>.
   9.499 +When the space required for the data is
   9.500 +identical, tmem may be able to overwrite <i>in place </i>the old data with
   9.501 +the new data (option 1).  But in some circumstances, such as when data
   9.502 +is being compressed, overwriting is not always possible and option 2 must be
   9.503 +performed.
   9.504 +<P>
   9.505 +<i><b>Page deduplication and trailing-zero elimination.</b></i>
   9.506 +When page deduplication is enabled
   9.507 +(&quot;tmem_dedup&quot; option to Xen), ephemeral pages for which the contents
   9.508 +are identical -- whether the pages belong
   9.509 +to the same client or different clients -- utilize the same pageframe of
   9.510 +memory.  In Xen environments where
   9.511 +multiple domains have a highly similar workload, this can save a substantial
   9.512 +amount of memory, allowing a much larger number of ephemeral pages to be
   9.513 +used.  Tmem page deduplication uses
   9.514 +methods similar to the KSM implementation in Linux [ref], but differences between
   9.515 +the two are sufficiently great that tmem does not directly leverage the
   9.516 +code.  In particular, ephemeral pages in
   9.517 +tmem are never dirtied, so need never be <i>copied-on-write</i>.
   9.518 +Like KSM, however, tmem avoids hashing,
   9.519 +instead employing <i>red-black trees</i>
   9.520 +that use the entire page contents as the <i>lookup
   9.521 +key</i>.  There may be better ways to implement this.
   9.522 +<P>
   9.523 +Dedup'ed pages may optionally be compressed
   9.524 +(&quot;tmem_compress&quot; and &quot;tmem_dedup&quot; Xen options specified),
   9.525 +to save even more space, at the cost of more time.
   9.526 +Additionally, <i>trailing zero elimination (tze)</i> may be applied to dedup'ed
   9.527 +pages.  With tze, pages that contain a
   9.528 +significant number of zeroes at the end of the page are saved without the trailing
   9.529 +zeroes; an all-zero page requires no data to be saved at all.
   9.530 +In certain workloads that utilize a large number
   9.531 +of small files (and for which the last partial page of a file is padded with
   9.532 +zeroes), a significant space savings can be realized without the high cost of
   9.533 +compression/decompression.
   9.534 +<P>
   9.535 +Both compression and tze significantly complicate memory
   9.536 +allocation.  This will be discussed more below.
   9.537 +<P>
   9.538 +<b><i>Memory accounting</i>.</b>
   9.539 +Accounting is boring, but poor accounting may
   9.540 +result in some interesting problems.  In
   9.541 +the implementation-independent code of tmem, most data structures, page frames,
   9.542 +and partial pages (e.g. for compresssion) are <i>billed</i> to a pool,
   9.543 +and thus to a client.  Some <i>infrastructure</i> data structures, such as
   9.544 +pools and clients, are allocated with <i>tmh_alloc_infra()</i>, which does not
   9.545 +require a pool to be specified.  Two other
   9.546 +exceptions are page content descriptors (<i>pcd_t</i>)
   9.547 +and sharelists (<i>sharelist_t</i>) which
   9.548 +are explicitly not associated with a pool/client by specifying NULL instead of
   9.549 +a <i>pool_t</i>.
   9.550 +(Note to self:
   9.551 +These should probably just use the <i>tmh_alloc_infra()</i> interface too.)
   9.552 +As we shall see, persistent pool pages and
   9.553 +data structures may need to be handled a bit differently, so the
   9.554 +implementation-independent layer calls a different allocation/free routine for
   9.555 +persistent pages (e.g. <i>tmh_alloc_page_thispool()</i>)
   9.556 +than for ephemeral pages (e.g. <i>tmh_alloc_page()</i>).
   9.557 +<P>
   9.558 +In the Xen-specific layer, we
   9.559 +disregard the <i>pool_t</i> for ephemeral
   9.560 +pages, as we use the generic Xen heap for all ephemeral pages and data
   9.561 +structures.(Denial-of-service attacks
   9.562 +can be handled in the implementation-independent layer because ephemeral pages
   9.563 +are kept in per-client queues each with a counted length.
   9.564 +See the discussion on weights and caps below.)
   9.565 +However we explicitly bill persistent pages
   9.566 +and data structures against the client/domain that is using them.
   9.567 +(See the calls to the Xen routine <i>alloc_domheap_pages() </i>in tmem_xen.h; of
   9.568 +the first argument is a domain, the pages allocated are billed by Xen to that
   9.569 +domain.)This means that a Xen domain
   9.570 +cannot allocate even a single tmem persistent page when it is currently utilizing
   9.571 +its maximum assigned memory allocation!
   9.572 +This is reasonable for persistent pages because, even though the data is
   9.573 +not directly accessible by the domain, the data is permanently saved until
   9.574 +either the domain flushes it or the domain dies.
   9.575 +<P>
   9.576 +Note that proper accounting requires (even for ephemeral pools) that the same
   9.577 +pool is referenced when memory is freed as when it was allocated, even if the
   9.578 +ownership of a pool has been moved from one client to another (c.f. <i
   9.579 +>shared_pool_reassign()</i>).
   9.580 +The underlying Xen-specific information may
   9.581 +not always enforce this for ephemeral pools, but incorrect alloc/free matching
   9.582 +can cause some difficult-to-find memory leaks and bent pointers.
   9.583 +<P>
   9.584 +Page deduplication is not possible for persistent pools for
   9.585 +accounting reasons: Imagine a page that is created by persistent pool A, which
   9.586 +belongs to a domain that is currently well under its maximum allocation.
   9.587 +Then the <i>pcd_t</i>is matched by persistent pool B, which is
   9.588 +currently at its maximum.
   9.589 +Then the domain owning pool A is destroyed.
   9.590 +Is B beyond its maximum?
   9.591 +(There may be a clever way around this
   9.592 +problem.  Exercise for the reader!)
   9.593 +<P>
   9.594 +<b><i>Memory allocation.</i></b> The implementation-independent layer assumes
   9.595 +there is a good fast general-purpose dynamic memory allocator with bounded
   9.596 +response time and efficient use of memory for a very large number of sub-page
   9.597 +allocations.  The old xmalloc memory
   9.598 +allocator in Xen was not a good match for this purpose, so was replaced by the
   9.599 +TLSF allocator.  Note that the TLSF
   9.600 +allocator is used only for allocations smaller than a page (and, more
   9.601 +precisely, no larger than <i>tmem_subpage_maxsize()</i>);
   9.602 +full pages are allocated by Xen's normal heap allocator.
   9.603 +<P>
   9.604 +After the TLSF allocator was integrated into Xen, more work
   9.605 +was required so that each client could allocate memory from a separate
   9.606 +independent pool. (See the call to <i>xmem_pool_create()</i>in
   9.607 +<i>tmh_client_init()</i>.) 
   9.608 +This allows the data structures allocated for the
   9.609 +purpose of supporting persistent pages to be billed to the same client as the
   9.610 +pages themselves.  It also allows partial
   9.611 +(e.g. compressed) pages to be properly billed.
   9.612 +Further, when partial page allocations cause internal fragmentation,
   9.613 +this fragmentation can be isolated per-client.
   9.614 +And, when a domain dies, full pages can be freed, rather than only
   9.615 +partial pages. One other change was
   9.616 +required in the TLSF allocator: In the original version, when a TLSF memory
   9.617 +pool was allocated, the first page of memory was also allocated.
   9.618 +Since, for a persistent pool, this page would
   9.619 +be billed to the client, the allocation of the first page failed if the domain
   9.620 +was started at its maximum memory, and this resulted in a failure to create the
   9.621 +memory pool.  To avoid this, the code was
   9.622 +changed to delay the allocation of the first page until first use of the memory
   9.623 +pool.
   9.624 +<P>
   9.625 +<b><i>Memory allocation interdependency.</i></b>
   9.626 +As previously described,
   9.627 +pages of memory must be moveable back and forth between the Xen heap and the
   9.628 +tmem ephemeral lists (and page lists).
   9.629 +When tmem needs a page but doesn't have one, it requests one from the
   9.630 +Xen heap (either indirectly via xmalloc, or directly via Xen's <i
   9.631 +>alloc_domheap_pages()</i>).
   9.632 +And when Xen needs a page but doesn't have
   9.633 +one, it requests one from tmem (via a call to <i
   9.634 +>tmem_relinquish_pages()</i> in Xen's <i
   9.635 +>alloc_heap_pages() </i>in page_alloc.c).
   9.636 +This leads to a potential infinite loop!
   9.637 +To break this loop, a new memory flag (<i>MEMF_tmem</i>) was added to Xen
   9.638 +to flag and disallow the loop.
   9.639 +See <i>tmh_called_from_tmem()</i>
   9.640 +in <i>tmem_relinquish_pages()</i>.
   9.641 +Note that the <i
   9.642 +>tmem_relinquish_pages()</i> interface allows for memory requests of
   9.643 +order &gt; 0 (multiple contiguous pages), but the tmem implementation disallows
   9.644 +any requests larger than a single page.
   9.645 +<P>
   9.646 +<b><i>LRU page reclamation</i></b>.
   9.647 +Ephemeral pages generally <i>age </i>in
   9.648 +a queue, and the space associated with the oldest -- or <i
   9.649 +>least-recently-used -- </i>page is reclaimed when tmem needs more
   9.650 +memory.  But there are a few exceptions
   9.651 +to strict LRU queuing.  First is when
   9.652 +removal from a queue is constrained by locks, as previously described above.
   9.653 +Second, when an ephemeral pool is <i>shared,</i> unlike a private ephemeral
   9.654 +pool, a
   9.655 +<big><kbd>get</kbd></big>
   9.656 +does not imply a
   9.657 +<big><kbd>flush</kbd></big>
   9.658 +Instead, in a shared pool, a 
   9.659 +results in the page being promoted to the front of the queue.
   9.660 +Third, when a page that is deduplicated (i.e.
   9.661 +is referenced by more than one <i>pgp_</i>t)
   9.662 +reaches the end of the LRU queue, it is marked as <i
   9.663 +>eviction attempted</i> and promoted to the front of the queue; if it
   9.664 +reaches the end of the queue a second time, eviction occurs.
   9.665 +Note that only the <i
   9.666 +>pgp_</i>t is evicted; the actual data is only reclaimed if there is no
   9.667 +other <i>pgp_t </i>pointing to the data.
   9.668 +<P>
   9.669 +All of these modified- LRU algorithms deserve to be studied
   9.670 +carefully against a broad range of workloads.
   9.671 +<P>
   9.672 +<b><i>Internal fragmentation</i>.</b>
   9.673 +When
   9.674 +compression or tze is enabled, allocations between a half-page and a full-page
   9.675 +in size are very common and this places a great deal of pressure on even the
   9.676 +best memory allocator.  Additionally,
   9.677 +problems may be caused for memory reclamation: When one tmem ephemeral page is
   9.678 +evicted, only a fragment of a physical page of memory might be reclaimed.
   9.679 +As a result, when compression or tze is
   9.680 +enabled, it may take a very large number of eviction attempts to free up a full
   9.681 +contiguous page of memory and so, to avoid near-infinite loops and livelocks, eviction
   9.682 +must be assumed to be able to fail.
   9.683 +While all memory allocation paths in tmem are resilient to failure, very
   9.684 +complex corner cases may eventually occur.
   9.685 +As a result, compression and tze are disabled by default and should be
   9.686 +used with caution until they have been tested with a much broader set of
   9.687 +workloads.(Note to self: The 
   9.688 +code needs work.)
   9.689 +<P>
   9.690 +<b><i>Weights and caps</i>.</b>
   9.691 +Because
   9.692 +of the just-discussed LRU-based eviction algorithms, a client that uses tmem at
   9.693 +a very high frequency can quickly swamp tmem so that it provides little benefit
   9.694 +to a client that uses it less frequently.
   9.695 +To reduce the possibility of this denial-of-service, limits can be
   9.696 +specified via management tools that are enforced internally by tmem.
   9.697 +On Xen, the &quot;xm tmem-set&quot; command
   9.698 +can specify &quot;weight=&lt;weight&gt;&quot; or &quot;cap=&lt;cap&gt;&quot;
   9.699 +for any client.  If weight is non-zero
   9.700 +for a client and the current percentage of ephemeral pages in use by the client
   9.701 +exceeds its share (as measured by the sum of weights of all clients), the next
   9.702 +page chosen for eviction is selected from the requesting client's ephemeral
   9.703 +queue, instead of the global ephemeral queue that contains pages from all
   9.704 +clients.(See <i>client_over_quota().</i>)
   9.705 +Setting a cap for a client is currently a no-op.
   9.706 +<P>
   9.707 +<b><i>Shared pools and authentication.</i></b>
   9.708 +When tmem was first proposed to the linux kernel mailing list
   9.709 +(LKML), there was concern expressed about security of shared ephemeral
   9.710 +pools.  The initial tmem implementation only
   9.711 +required a client to provide a 128-bit UUID to identify a shared pool, and the
   9.712 +linux-side tmem implementation obtained this UUID from the superblock of the
   9.713 +shared filesystem (in ocfs2).  It was
   9.714 +pointed out on LKML that the UUID was essentially a security key and any
   9.715 +malicious domain that guessed it would have access to any data from the shared
   9.716 +filesystem that found its way into tmem.
   9.717 +Ocfs2 has only very limited security; it is assumed that anyone who can
   9.718 +access the filesystem bits on the shared disk can mount the filesystem and use
   9.719 +it.  But in a virtualized data center,
   9.720 +higher isolation requirements may apply.
   9.721 +As a result, a Xen boot option -- &quot;tmem_shared_auth&quot; -- was
   9.722 +added.  The option defaults to disabled,
   9.723 +but when it is enabled, management tools must explicitly authenticate (or may
   9.724 +explicitly deny) shared pool access to any client.
   9.725 +On Xen, this is done with the &quot;xm
   9.726 +tmem-shared-auth&quot; command.
   9.727 +<P>
   9.728 +<b><i>32-bit implementation</i>.</b>
   9.729 +There was some effort put into getting tmem working on a 32-bit Xen.
   9.730 +However, the Xen heap is limited in size on
   9.731 +32-bit Xen so tmem did not work very well.
   9.732 +There are still 32-bit ifdefs in some places in the code, but things may
   9.733 +have bit-rotted so using tmem on a 32-bit Xen is not recommended.
   9.734 +<P>
   9.735 +<b><i>IA-64 implementation. </i></b>
   9.736 +The vast majority of the tmem
   9.737 +implementation is architecture-independent.
   9.738 +For tmem to run on Xen/ia64, it is believed that only one or two
   9.739 +routines needs to be written.(See the
   9.740 +#ifdef __ia64__ at <i>cli_mfn_to_va()</i>.)
   9.741 +
   9.742 +<h2>Known Issues</h2>
   9.743 +
   9.744 +<p><b><i>Fragmentation.</i></b>When tmem
   9.745 +is active, all physically memory becomes <i>fragmented</i>
   9.746 +into individual pages.  However, the Xen
   9.747 +memory allocator allows memory to be requested in multi-page contiguous
   9.748 +quantities, called order&gt;0 allocations.
   9.749 +(e.g. 2<sup>order</sup> so
   9.750 +order==4 is sixteen contiguous pages.)
   9.751 +In some cases, a request for a larger order will fail gracefully if no
   9.752 +matching contiguous allocation is available from Xen.
   9.753 +As of Xen 4.0, however, there are several
   9.754 +critical order&gt;0 allocation requests that do not fail gracefully.
   9.755 +Notably, when a domain is created, and
   9.756 +order==4 structure is required or the domain creation will fail.
   9.757 +And shadow paging requires many order==2
   9.758 +allocations; if these fail, a PV live-migration may fail.
   9.759 +There are likely other such issues.
   9.760 +<P>
   9.761 +But, fragmentation can occur even without tmem if any domU does
   9.762 +any extensive ballooning; tmem just accelerates the fragmentation.
   9.763 +So the fragmentation problem must be solved
   9.764 +anyway.  The best solution is to disallow
   9.765 +order&gt;0 allocations altogether in Xen -- or at least ensure that any attempt
   9.766 +to allocate order&gt;0 can fail gracefully, e.g. by falling back to a sequence
   9.767 +of single page allocations. However this restriction may require a major rewrite
   9.768 +in some of Xen's most sensitive code.
   9.769 +(Note that order&gt;0 allocations during Xen boot and early in domain0
   9.770 +launch are safe and, if dom0 does not enable tmem, any order&gt;0 allocation by
   9.771 +dom0 is safe, until the first domU is created.)
   9.772 +<P>
   9.773 +Until Xen can be rewritten to be <i>fragmentation-safe</i>, a small hack
   9.774 +was added in the Xen page
   9.775 +allocator.(See the comment &quot;
   9.776 +memory is scarce&quot; in <i>alloc_heap_pages()</i>.)
   9.777 +Briefly, a portion of memory is pre-reserved
   9.778 +for allocations where order&gt;0 and order&lt;9.
   9.779 +(Domain creation uses 2MB pages, but fails
   9.780 +gracefully, and there are no other known order==9 allocations or order&gt;9
   9.781 +allocations currently in Xen.)
   9.782 +<P>
   9.783 +<b><i>NUMA</i></b>.  Tmem assumes that
   9.784 +all memory pages are equal and any RAM page can store a page of data for any
   9.785 +client.  This has potential performance
   9.786 +consequences in any NUMA machine where access to <i
   9.787 +>far memory</i> is significantly slower than access to <i
   9.788 +>near memory</i>.
   9.789 +On nearly all of today's servers, however,
   9.790 +access times to <i>far memory</i> is still
   9.791 +much faster than access to disk or network-based storage, and tmem's primary performance
   9.792 +advantage comes from the fact that paging and swapping are reduced.
   9.793 +So, the current tmem implementation ignores
   9.794 +NUMA-ness; future tmem design for NUMA machines is an exercise left for the
   9.795 +reader.
   9.796 +
   9.797 +<h2>Bibliography</h2>
   9.798 +
   9.799 +<P>
   9.800 +(needs work)<b style='mso-bidi-font-weight:>
   9.801 +<P><a href="http://oss.oracle.com/projects/tmem">http://oss.oracle.com/projects/tmem</a>
    10.1 --- a/docs/xen-api/coversheet.tex	Wed Jun 09 19:53:32 2010 -0700
    10.2 +++ b/docs/xen-api/coversheet.tex	Fri Jul 16 17:16:06 2010 -0700
    10.3 @@ -52,6 +52,7 @@ Mike Day, IBM & Daniel Veillard, Red Hat
    10.4  Jim Fehlig, Novell & Tom Wilkie, University of Cambridge \\
    10.5  Jon Harrop, XenSource & Yosuke Iwamatsu, NEC \\
    10.6  Masaki Kanno, FUJITSU \\
    10.7 +Lutz Dube, FUJITSU TECHNOLOGY SOLUTIONS \\
    10.8  \end{tabular}
    10.9  \end{large}
   10.10  
    11.1 --- a/docs/xen-api/revision-history.tex	Wed Jun 09 19:53:32 2010 -0700
    11.2 +++ b/docs/xen-api/revision-history.tex	Fri Jul 16 17:16:06 2010 -0700
    11.3 @@ -50,6 +50,12 @@
    11.4       between classes. Added host.PSCSI\_HBAs and VM.DSCSI\_HBAs
    11.5       fields.\tabularnewline
    11.6    \hline
    11.7 +  1.0.10 & 10th Jan. 10 & L. Dube &
    11.8 +     Added definitions of new classes cpu\_pool. Updated the table
    11.9 +     and the diagram representing relationships between classes.
   11.10 +     Added fields host.resident\_cpu\_pools, VM.cpu\_pool and
   11.11 +     host\_cpu.cpu\_pool.\tabularnewline
   11.12 +  \hline
   11.13   \end{tabular}
   11.14  \end{center}
   11.15  \end{flushleft}
    12.1 --- a/docs/xen-api/xenapi-coversheet.tex	Wed Jun 09 19:53:32 2010 -0700
    12.2 +++ b/docs/xen-api/xenapi-coversheet.tex	Fri Jul 16 17:16:06 2010 -0700
    12.3 @@ -17,12 +17,12 @@
    12.4  \newcommand{\coversheetlogo}{xen.eps}
    12.5  
    12.6  %% Document date
    12.7 -\newcommand{\datestring}{20th November 2009}
    12.8 +\newcommand{\datestring}{10th January 2010}
    12.9  
   12.10  \newcommand{\releasestatement}{Stable Release}
   12.11  
   12.12  %% Document revision
   12.13 -\newcommand{\revstring}{API Revision 1.0.9}
   12.14 +\newcommand{\revstring}{API Revision 1.0.10}
   12.15  
   12.16  %% Document authors
   12.17  \newcommand{\docauthors}{
    13.1 --- a/docs/xen-api/xenapi-datamodel-graph.dot	Wed Jun 09 19:53:32 2010 -0700
    13.2 +++ b/docs/xen-api/xenapi-datamodel-graph.dot	Fri Jul 16 17:16:06 2010 -0700
    13.3 @@ -14,7 +14,7 @@ fontname="Verdana";
    13.4  
    13.5  node [ shape=box ]; session VM host network VIF PIF SR VDI VBD PBD user;
    13.6  node [ shape=box ]; XSPolicy ACMPolicy DPCI PPCI host_cpu console VTPM;
    13.7 -node [ shape=box ]; DSCSI PSCSI DSCSI_HBA PSCSI_HBA;
    13.8 +node [ shape=box ]; DSCSI PSCSI DSCSI_HBA PSCSI_HBA cpu_pool;
    13.9  node [ shape=ellipse ]; VM_metrics VM_guest_metrics host_metrics;
   13.10  node [ shape=ellipse ]; PIF_metrics VIF_metrics VBD_metrics PBD_metrics;
   13.11  session -> host [ arrowhead="none" ]
   13.12 @@ -51,4 +51,7 @@ DSCSI_HBA -> PSCSI_HBA [ arrowhead="crow
   13.13  PSCSI -> host [ arrowhead="none", arrowtail="crow" ]
   13.14  PSCSI_HBA -> host [ arrowhead="none", arrowtail="crow" ]
   13.15  PSCSI -> PSCSI_HBA [ arrowhead="none", arrowtail="crow" ]
   13.16 +cpu_pool -> host_cpu [ arrowhead="crow", arrowtail="none" ]
   13.17 +cpu_pool -> VM [ arrowhead="crow", arrowtail="none" ]
   13.18 +host -> cpu_pool [ arrowhead="crow", arrowtail="none" ]
   13.19  }
    14.1 --- a/docs/xen-api/xenapi-datamodel.tex	Wed Jun 09 19:53:32 2010 -0700
    14.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Fri Jul 16 17:16:06 2010 -0700
    14.3 @@ -56,6 +56,7 @@ Name & Description \\
    14.4  {\tt debug} & A basic class for testing \\
    14.5  {\tt XSPolicy} & A class for handling Xen Security Policies \\
    14.6  {\tt ACMPolicy} & A class for handling ACM-type policies \\
    14.7 +{\tt cpu\_pool} & A container for VMs which should shared the same host\_cpu(s) \\
    14.8  \hline
    14.9  \end{tabular}\end{center}
   14.10  \section{Relationships Between Classes}
   14.11 @@ -88,6 +89,9 @@ PSCSI.HBA & PSCSI\_HBA.PSCSIs & one-to-m
   14.12  PSCSI\_HBA.host & host.PSCSI\_HBAs & one-to-many\\
   14.13  host.resident\_VMs & VM.resident\_on & many-to-one\\
   14.14  host.host\_CPUs & host\_cpu.host & many-to-one\\
   14.15 +host.resident\_cpu\_pools & cpu\_pool.resident\_on & many-to-one\\
   14.16 +cpu\_pool.started\_VMs & VM.cpu\_pool & many-to-one\\
   14.17 +cpu\_pool.host\_CPUs & host\_cpu.cpu\_pool & many-to-one\\
   14.18  \hline
   14.19  \end{tabular}\end{center}
   14.20  
   14.21 @@ -499,6 +503,56 @@ error code and a message describing the 
   14.22  \begin{verbatim}SECURITY_ERROR(xserr, message)\end{verbatim}
   14.23  \begin{center}\rule{10em}{0.1pt}\end{center}
   14.24  
   14.25 +\subsubsection{POOL\_BAD\_STATE}
   14.26 +
   14.27 +You attempted an operation on a pool that was not in an appropriate state
   14.28 +at the time; for example, you attempted to activate a pool that was
   14.29 +already activated.
   14.30 +
   14.31 +\vspace{0.3cm}
   14.32 +{\bf Signature:}
   14.33 +\begin{verbatim}POOL_BAD_STATE(current pool state)\end{verbatim}
   14.34 +\begin{center}\rule{10em}{0.1pt}\end{center}
   14.35 +
   14.36 +\subsubsection{INSUFFICIENT\_CPUS}
   14.37 +
   14.38 +You attempted to activate a cpu\_pool but there are not enough
   14.39 +unallocated CPUs to satisfy the request.
   14.40 +
   14.41 +\vspace{0.3cm}
   14.42 +{\bf Signature:}
   14.43 +\begin{verbatim}INSUFFICIENT_CPUS(needed cpu count, available cpu count)\end{verbatim}
   14.44 +\begin{center}\rule{10em}{0.1pt}\end{center}
   14.45 +
   14.46 +\subsubsection{UNKOWN\_SCHED\_POLICY}
   14.47 +
   14.48 +The specified scheduler policy is unkown to the host.
   14.49 +
   14.50 +\vspace{0.3cm}
   14.51 +{\bf Signature:}
   14.52 +\begin{verbatim}UNKOWN_SCHED_POLICY()\end{verbatim}
   14.53 +\begin{center}\rule{10em}{0.1pt}\end{center}
   14.54 +
   14.55 +\subsubsection{INVALID\_CPU}
   14.56 +
   14.57 +You tried to reconfigure a cpu\_pool with a CPU that is unkown to the host
   14.58 +or has a wrong state.
   14.59 +
   14.60 +\vspace{0.3cm}
   14.61 +{\bf Signature:}
   14.62 +\begin{verbatim}INVALID_CPU(message)\end{verbatim}
   14.63 +\begin{center}\rule{10em}{0.1pt}\end{center}
   14.64 +
   14.65 +\subsubsection{LAST\_CPU\_NOT\_REMOVEABLE}
   14.66 +
   14.67 +You tried to remove the last CPU from a cpu\_pool that has one or more
   14.68 +active domains.
   14.69 +
   14.70 +\vspace{0.3cm}
   14.71 +{\bf Signature:}
   14.72 +\begin{verbatim}LAST_CPU_NOT_REMOVEABLE(message)\end{verbatim}
   14.73 +\begin{center}\rule{10em}{0.1pt}\end{center}
   14.74 +
   14.75  
   14.76  \newpage
   14.77  \section{Class: session}
   14.78 @@ -4847,6 +4901,135 @@ references to objects with match names
   14.79  \vspace{0.3cm}
   14.80  \vspace{0.3cm}
   14.81  \vspace{0.3cm}
   14.82 +\subsubsection{RPC name:~get\_cpu\_pool}
   14.83 +
   14.84 +{\bf Overview:}
   14.85 +Get the cpu\_pool field of the given VM.
   14.86 +
   14.87 + \noindent {\bf Signature:}
   14.88 +\begin{verbatim} ((cpu_pool ref) Set) get_cpu_pool (session_id s, VM ref self)\end{verbatim}
   14.89 +
   14.90 +
   14.91 +\noindent{\bf Arguments:}
   14.92 +
   14.93 +
   14.94 +\vspace{0.3cm}
   14.95 +\begin{tabular}{|c|c|p{7cm}|}
   14.96 +\hline
   14.97 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   14.98 +{\tt VM ref } & self & reference to the object \\ \hline
   14.99 +\end{tabular}
  14.100 +
  14.101 +\vspace{0.3cm}
  14.102 +
  14.103 + \noindent {\bf Return Type:}
  14.104 +{\tt
  14.105 +(cpu\_pool ref) Set
  14.106 +}
  14.107 +
  14.108 +
  14.109 +references to cpu\_pool objects.
  14.110 +\vspace{0.3cm}
  14.111 +\vspace{0.3cm}
  14.112 +\vspace{0.3cm}
  14.113 +\subsubsection{RPC name:~get\_pool\_name}
  14.114 +
  14.115 +{\bf Overview:}
  14.116 +Get the pool\_name field of the given VM.
  14.117 +
  14.118 + \noindent {\bf Signature:}
  14.119 +\begin{verbatim} string get_cpu_pool (session_id s, VM ref self)\end{verbatim}
  14.120 +
  14.121 +
  14.122 +\noindent{\bf Arguments:}
  14.123 +
  14.124 +
  14.125 +\vspace{0.3cm}
  14.126 +\begin{tabular}{|c|c|p{7cm}|}
  14.127 +\hline
  14.128 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.129 +{\tt VM ref } & self & reference to the object \\ \hline
  14.130 +\end{tabular}
  14.131 +
  14.132 +\vspace{0.3cm}
  14.133 +
  14.134 + \noindent {\bf Return Type:}
  14.135 +{\tt
  14.136 +string
  14.137 +}
  14.138 +
  14.139 +
  14.140 +name of cpu pool to use
  14.141 +\vspace{0.3cm}
  14.142 +\vspace{0.3cm}
  14.143 +\vspace{0.3cm}
  14.144 +\subsubsection{RPC name:~cpu\_pool\_migrate}
  14.145 +
  14.146 +{\bf Overview:}
  14.147 +Migrate the VM to another cpu\_pool.
  14.148 +
  14.149 + \noindent {\bf Signature:}
  14.150 +\begin{verbatim} void cpu_pool_migrate (session_id s, VM ref self, cpu_pool ref pool)\end{verbatim}
  14.151 +
  14.152 +
  14.153 +\noindent{\bf Arguments:}
  14.154 +
  14.155 +
  14.156 +\vspace{0.3cm}
  14.157 +\begin{tabular}{|c|c|p{7cm}|}
  14.158 +\hline
  14.159 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.160 +{\tt VM ref } & self & reference to the object \\ \hline
  14.161 +{\tt cpu\_pool ref} & pool & reference to new cpu\_pool \\ \hline
  14.162 +\end{tabular}
  14.163 +
  14.164 +\vspace{0.3cm}
  14.165 +
  14.166 + \noindent {\bf Return Type:}
  14.167 +{\tt
  14.168 +void
  14.169 +}
  14.170 +
  14.171 +\vspace{0.3cm}
  14.172 +
  14.173 +\noindent{\bf Possible Error Codes:} {\tt POOL\_BAD\_STATE, VM\_BAD\_POWER\_STATE}
  14.174 +
  14.175 +\vspace{0.3cm}
  14.176 +\vspace{0.3cm}
  14.177 +\vspace{0.3cm}
  14.178 +\subsubsection{RPC name:~set\_pool\_name}
  14.179 +
  14.180 +{\bf Overview:}
  14.181 +Set cpu pool name to use for next activation.
  14.182 +
  14.183 + \noindent {\bf Signature:}
  14.184 +\begin{verbatim} void set_pool_name (session_id s, VM ref self, string pool\_name)\end{verbatim}
  14.185 +
  14.186 +
  14.187 +\noindent{\bf Arguments:}
  14.188 +
  14.189 +
  14.190 +\vspace{0.3cm}
  14.191 +\begin{tabular}{|c|c|p{7cm}|}
  14.192 +\hline
  14.193 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.194 +{\tt VM ref } & self & reference to the object \\ \hline
  14.195 +{\tt string} & pool\_name & New pool name \\ \hline
  14.196 +\end{tabular}
  14.197 +
  14.198 +\vspace{0.3cm}
  14.199 +
  14.200 + \noindent {\bf Return Type:}
  14.201 +{\tt
  14.202 +void
  14.203 +}
  14.204 +
  14.205 +\vspace{0.3cm}
  14.206 +\vspace{0.3cm}
  14.207 +\vspace{0.3cm}
  14.208 +
  14.209 +
  14.210 +
  14.211  
  14.212  \vspace{1cm}
  14.213  \newpage
  14.214 @@ -5681,6 +5864,7 @@ Quals & Field & Type & Description \\
  14.215  $\mathit{RO}_\mathit{run}$ &  {\tt PSCSI\_HBAs} & (PSCSI\_HBA ref) Set & physical SCSI host bus adapters \\
  14.216  $\mathit{RO}_\mathit{run}$ &  {\tt host\_CPUs} & (host\_cpu ref) Set & The physical CPUs on this host \\
  14.217  $\mathit{RO}_\mathit{run}$ &  {\tt metrics} & host\_metrics ref & metrics associated with this host \\
  14.218 +$\mathit{RO}_\mathit{run}$ &  {\tt resident\_cpu\_pools} & (cpu\_pool ref) Set & list of cpu\_pools currently resident on the host \\
  14.219  \hline
  14.220  \end{longtable}
  14.221  \subsection{RPCs associated with class: host}
  14.222 @@ -7229,6 +7413,38 @@ references to objects with match names
  14.223  \vspace{0.3cm}
  14.224  \vspace{0.3cm}
  14.225  \vspace{0.3cm}
  14.226 +\subsubsection{RPC name:~get\_resident\_cpu\_pools}
  14.227 +
  14.228 +{\bf Overview:}
  14.229 +Get the resident\_cpu\_pools field of the given host.
  14.230 +
  14.231 + \noindent {\bf Signature:}
  14.232 +\begin{verbatim} ((cpu_pool ref) Set) get_resident_cpu_pools (session_id s, host ref self)\end{verbatim}
  14.233 +
  14.234 +
  14.235 +\noindent{\bf Arguments:}
  14.236 +
  14.237 +
  14.238 +\vspace{0.3cm}
  14.239 +\begin{tabular}{|c|c|p{7cm}|}
  14.240 + \hline
  14.241 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.242 +{\tt host ref } & self & reference to the object \\ \hline
  14.243 +\end{tabular}
  14.244 +
  14.245 +\vspace{0.3cm}
  14.246 +
  14.247 + \noindent {\bf Return Type:}
  14.248 +{\tt
  14.249 +(cpu\_pool ref) Set
  14.250 +}
  14.251 +
  14.252 +
  14.253 +references to all known cpu\_pools.
  14.254 +\vspace{0.3cm}
  14.255 +\vspace{0.3cm}
  14.256 +\vspace{0.3cm}
  14.257 +
  14.258  
  14.259  \vspace{1cm}
  14.260  \newpage
  14.261 @@ -7484,6 +7700,7 @@ Quals & Field & Type & Description \\
  14.262  $\mathit{RO}_\mathit{run}$ &  {\tt flags} & string & the flags of the physical CPU (a decoded version of the features field) \\
  14.263  $\mathit{RO}_\mathit{run}$ &  {\tt features} & string & the physical CPU feature bitmap \\
  14.264  $\mathit{RO}_\mathit{run}$ &  {\tt utilisation} & float & the current CPU utilisation \\
  14.265 +$\mathit{RO}_\mathit{run}$ &  {\tt cpu\_pool} & (cpu\_pool ref) Set & reference to cpu\_pool the cpu belongs to \\
  14.266  \hline
  14.267  \end{longtable}
  14.268  \subsection{RPCs associated with class: host\_cpu}
  14.269 @@ -7896,6 +8113,70 @@ all fields from the object
  14.270  \vspace{0.3cm}
  14.271  \vspace{0.3cm}
  14.272  \vspace{0.3cm}
  14.273 +\subsubsection{RPC name:~get\_cpu\_pool}
  14.274 +
  14.275 +{\bf Overview:}
  14.276 +Get the cpu\_pool field of the given host\_cpu.
  14.277 +
  14.278 + \noindent {\bf Signature:}
  14.279 +\begin{verbatim} ((cpu_pool) Set) get_cpu_pool (session_id s, host_cpu ref self)\end{verbatim}
  14.280 +
  14.281 +
  14.282 +\noindent{\bf Arguments:}
  14.283 +
  14.284 +
  14.285 +\vspace{0.3cm}
  14.286 +\begin{tabular}{|c|c|p{7cm}|}
  14.287 + \hline
  14.288 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.289 +{\tt host\_cpu ref } & self & reference to the object \\ \hline
  14.290 +
  14.291 +\end{tabular}
  14.292 +
  14.293 +\vspace{0.3cm}
  14.294 +
  14.295 + \noindent {\bf Return Type:}
  14.296 +{\tt
  14.297 +(cpu\_pool) Set
  14.298 +}
  14.299 +
  14.300 +
  14.301 +value of the field
  14.302 +\vspace{0.3cm}
  14.303 +\vspace{0.3cm}
  14.304 +\vspace{0.3cm}
  14.305 +\subsubsection{RPC name:~get\_unassigned\_cpus}
  14.306 +
  14.307 +{\bf Overview:}
  14.308 +Get a reference to all cpus that are not assigend to any cpu\_pool.
  14.309 +
  14.310 + \noindent {\bf Signature:}
  14.311 +\begin{verbatim} ((host_cpu) Set) get_unassigned_cpus (session_id s)\end{verbatim}
  14.312 +
  14.313 +
  14.314 +\noindent{\bf Arguments:}
  14.315 +
  14.316 +
  14.317 +\vspace{0.3cm}
  14.318 +\begin{tabular}{|c|c|p{7cm}|}
  14.319 + \hline
  14.320 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.321 +\end{tabular}
  14.322 +
  14.323 +\vspace{0.3cm}
  14.324 +
  14.325 + \noindent {\bf Return Type:}
  14.326 +{\tt
  14.327 +(host\_cpu ref) Set
  14.328 +}
  14.329 +
  14.330 +
  14.331 +Set of free (not assigned) cpus
  14.332 +\vspace{0.3cm}
  14.333 +\vspace{0.3cm}
  14.334 +\vspace{0.3cm}
  14.335 +
  14.336 +
  14.337  
  14.338  \vspace{1cm}
  14.339  \newpage
  14.340 @@ -18892,3 +19173,1073 @@ all fields from the object
  14.341  \vspace{0.3cm}
  14.342  \vspace{0.3cm}
  14.343  
  14.344 +\newpage
  14.345 +\section{Class: cpu\_pool}
  14.346 +\subsection{Fields for class: cpu\_pool}
  14.347 +\begin{longtable}{|lllp{0.38\textwidth}|}
  14.348 +\hline
  14.349 +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf cpu\_pool} \\
  14.350 +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A CPU pool}} \\
  14.351 +\hline
  14.352 +Quals & Field & Type & Description \\
  14.353 +\hline
  14.354 +$\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier / object reference \\
  14.355 +$\mathit{RW}$              &  {\tt name\_label} & string & name of cpu\_pool \\
  14.356 +$\mathit{RW}$              &  {\tt name\_description} & string & cpu\_pool description \\
  14.357 +$\mathit{RO}_\mathit{run}$ &  {\tt resident\_on} & host ref & the host the cpu\_pool is currently resident on \\
  14.358 +$\mathit{RW}$              &  {\tt auto\_power\_on} & bool & True if this cpu\_pool should be activated automatically after host boot \\
  14.359 +$\mathit{RO}_\mathit{run}$ &  {\tt started\_VMs} & (VM ref) Set & list of VMs currently started in this cpu\_pool \\
  14.360 +$\mathit{RW}$              &  {\tt ncpu} & integer & number of host\_CPUs requested for this cpu\_pool at next start \\
  14.361 +$\mathit{RW}$              &  {\tt sched\_policy} & string & scheduler policy on this cpu\_pool \\
  14.362 +$\mathit{RW}$              &  {\tt proposed\_CPUs} & (string) Set & list of proposed host\_CPUs to assign at next activation \\
  14.363 +$\mathit{RO}_\mathit{run}$ &  {\tt host\_CPUs} & (VM ref) Set & list of host\_cpus currently assigned to this cpu\_pool \\
  14.364 +$\mathit{RO}_\mathit{run}$ &  {\tt activated} & bool & True if this cpu\_pool is activated \\
  14.365 +$\mathit{RW}$              &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
  14.366 +\hline
  14.367 +\end{longtable}
  14.368 +\subsection{RPCs associated with class: cpu\_pool}
  14.369 +\subsubsection{RPC name:~activate}
  14.370 +
  14.371 +{\bf Overview:}
  14.372 +Activate the cpu\_pool and assign the given CPUs to it.
  14.373 +CPUs specified in field proposed\_CPUs, that are not existing or not free, are
  14.374 +ignored. If value of ncpu is greater than the number of CPUs in field
  14.375 +proposed\_CPUs, additional free CPUs are assigned to the cpu\_pool.
  14.376 +
  14.377 + \noindent {\bf Signature:}
  14.378 +\begin{verbatim} void activate (session_id s, cpu_pool ref self)\end{verbatim}
  14.379 +
  14.380 +
  14.381 +\noindent{\bf Arguments:}
  14.382 +
  14.383 +
  14.384 +\vspace{0.3cm}
  14.385 +\begin{tabular}{|c|c|p{7cm}|}
  14.386 + \hline
  14.387 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.388 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.389 +\end{tabular}
  14.390 +
  14.391 +\vspace{0.3cm}
  14.392 +
  14.393 + \noindent {\bf Return Type:}
  14.394 +{\tt
  14.395 +void
  14.396 +}
  14.397 +
  14.398 +\vspace{0.3cm}
  14.399 +
  14.400 +\noindent {\bf Possible Error Codes:}
  14.401 +    {\tt POOL\_BAD\_STATE, INSUFFICIENT\_CPUS, UNKOWN\_SCHED\_POLICY}
  14.402 +
  14.403 +\vspace{0.3cm}
  14.404 +\vspace{0.3cm}
  14.405 +\vspace{0.3cm}
  14.406 +\subsubsection{RPC name:~create}
  14.407 +
  14.408 +{\bf Overview:}
  14.409 +Create a new cpu\_pool instance, and return its handle.
  14.410 +
  14.411 + \noindent {\bf Signature:}
  14.412 +\begin{verbatim} (cpu_pool ref) create (session_id s, cpu_pool record args)\end{verbatim}
  14.413 +
  14.414 +
  14.415 +\noindent{\bf Arguments:}
  14.416 +
  14.417 +
  14.418 +\vspace{0.3cm}
  14.419 +\begin{tabular}{|c|c|p{7cm}|}
  14.420 + \hline
  14.421 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.422 +{\tt cpu\_pool record } & args & All constructor arguments \\ \hline
  14.423 +\end{tabular}
  14.424 +
  14.425 +\vspace{0.3cm}
  14.426 +
  14.427 + \noindent {\bf Return Type:}
  14.428 +{\tt
  14.429 +cpu\_pool ref
  14.430 +}
  14.431 +
  14.432 +
  14.433 +reference to the newly created object
  14.434 +\vspace{0.3cm}
  14.435 +\vspace{0.3cm}
  14.436 +\vspace{0.3cm}
  14.437 +\subsubsection{RPC name:~deactivate}
  14.438 +
  14.439 +{\bf Overview:}
  14.440 +Deactivate the cpu\_pool and release all CPUs assigned to it.
  14.441 +This function can only be called if there are no domains active in the
  14.442 +cpu\_pool.
  14.443 +
  14.444 + \noindent {\bf Signature:}
  14.445 +\begin{verbatim} void deactivate (session_id s, cpu_pool ref self)\end{verbatim}
  14.446 +
  14.447 +
  14.448 +\noindent{\bf Arguments:}
  14.449 +
  14.450 +
  14.451 +\vspace{0.3cm}
  14.452 +\begin{tabular}{|c|c|p{7cm}|}
  14.453 + \hline
  14.454 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.455 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.456 +\end{tabular}
  14.457 +
  14.458 +\vspace{0.3cm}
  14.459 +
  14.460 + \noindent {\bf Return Type:}
  14.461 +{\tt
  14.462 +void
  14.463 +}
  14.464 +
  14.465 +\vspace{0.3cm}
  14.466 +
  14.467 +\noindent {\bf Possible Error Codes:} {\tt POOL\_BAD\_STATE}
  14.468 +
  14.469 +\vspace{0.3cm}
  14.470 +\vspace{0.3cm}
  14.471 +\vspace{0.3cm}
  14.472 +\subsubsection{RPC name:~destroy}
  14.473 +
  14.474 +{\bf Overview:}
  14.475 +Destroy the specified cpu\_pool. The cpu\_pool is completely removed from the
  14.476 +system.
  14.477 +This function can only be called if the cpu\_pool is deactivated.
  14.478 +
  14.479 + \noindent {\bf Signature:}
  14.480 +\begin{verbatim} void destroy (session_id s, cpu_pool ref self)\end{verbatim}
  14.481 +
  14.482 +
  14.483 +\noindent{\bf Arguments:}
  14.484 +
  14.485 +
  14.486 +\vspace{0.3cm}
  14.487 +\begin{tabular}{|c|c|p{7cm}|}
  14.488 + \hline
  14.489 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.490 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.491 +\end{tabular}
  14.492 +
  14.493 +\vspace{0.3cm}
  14.494 +
  14.495 + \noindent {\bf Return Type:}
  14.496 +{\tt
  14.497 +void
  14.498 +}
  14.499 +
  14.500 +\vspace{0.3cm}
  14.501 +
  14.502 +\noindent {\bf Possible Error Codes:} {\tt POOL\_BAD\_STATE}
  14.503 +
  14.504 +
  14.505 +\vspace{0.3cm}
  14.506 +\vspace{0.3cm}
  14.507 +\vspace{0.3cm}
  14.508 +\subsubsection{RPC name:~add\_host\_CPU\_live}
  14.509 +
  14.510 +
  14.511 +{\bf Overview:}
  14.512 +Add a additional CPU immediatly to the cpu\_pool.
  14.513 +
  14.514 + \noindent {\bf Signature:}
  14.515 +\begin{verbatim} void add_host_CPU_live (session_id s, cpu_pool ref self, host_cpu ref host_cpu)\end{verbatim}
  14.516 +
  14.517 +
  14.518 +\noindent{\bf Arguments:}
  14.519 +
  14.520 +
  14.521 +\vspace{0.3cm}
  14.522 +\begin{tabular}{|c|c|p{7cm}|}
  14.523 + \hline
  14.524 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.525 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.526 +{\tt host\_cpu ref } & host\_cpu & CPU to add \\ \hline
  14.527 +\end{tabular}
  14.528 +
  14.529 +\vspace{0.3cm}
  14.530 +
  14.531 + \noindent {\bf Return Type:}
  14.532 +{\tt
  14.533 +void
  14.534 +}
  14.535 +
  14.536 +\vspace{0.3cm}
  14.537 +
  14.538 +\noindent {\bf Possible Error Codes:}
  14.539 +    {\tt POOL\_BAD\_STATE, INVALID\_CPU}
  14.540 +
  14.541 +
  14.542 +\vspace{0.3cm}
  14.543 +\vspace{0.3cm}
  14.544 +\vspace{0.3cm}
  14.545 +\subsubsection{RPC name:~remove\_host\_CPU\_live}
  14.546 +
  14.547 +
  14.548 +{\bf Overview:}
  14.549 +Remove a CPU immediatly from the cpu\_pool.
  14.550 +
  14.551 + \noindent {\bf Signature:}
  14.552 +\begin{verbatim} void remove_host_CPU_live (session_id s, cpu_pool ref self, host_cpu ref host_cpu)\end{verbatim}
  14.553 +
  14.554 +
  14.555 +\noindent{\bf Arguments:}
  14.556 +
  14.557 +
  14.558 +\vspace{0.3cm}
  14.559 +\begin{tabular}{|c|c|p{7cm}|}
  14.560 + \hline
  14.561 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.562 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.563 +{\tt host\_cpu ref } & host\_cpu & CPU to remove \\ \hline
  14.564 +\end{tabular}
  14.565 +
  14.566 +\vspace{0.3cm}
  14.567 +
  14.568 + \noindent {\bf Return Type:}
  14.569 +{\tt
  14.570 +void
  14.571 +}
  14.572 +
  14.573 +\vspace{0.3cm}
  14.574 +
  14.575 +\noindent {\bf Possible Error Codes:}
  14.576 +    {\tt POOL\_BAD\_STATE, INVALID\_CPU, LAST\_CPU\_NOT\_REMOVEABLE}
  14.577 +
  14.578 +
  14.579 +\vspace{0.3cm}
  14.580 +\vspace{0.3cm}
  14.581 +\vspace{0.3cm}
  14.582 +\subsubsection{RPC name:~get\_all}
  14.583 +
  14.584 +
  14.585 +{\bf Overview:}
  14.586 +Return a list of all the cpu pools known to the system.
  14.587 +
  14.588 + \noindent {\bf Signature:}
  14.589 +\begin{verbatim} ((cpu_pool ref) Set) get_all (session_id s)\end{verbatim}
  14.590 +
  14.591 +
  14.592 + \noindent {\bf Return Type:}
  14.593 +{\tt
  14.594 +(cpu\_pool ref) Set
  14.595 +}
  14.596 +A list of all the IDs of the cpu pools.
  14.597 +
  14.598 +\vspace{0.3cm}
  14.599 +\vspace{0.3cm}
  14.600 +\vspace{0.3cm}
  14.601 +\subsubsection{RPC name:~get\_all\_records}
  14.602 +
  14.603 +
  14.604 +{\bf Overview:}
  14.605 +Return a map of all the cpu pool records known to the system.
  14.606 +
  14.607 + \noindent {\bf Signature:}
  14.608 +\begin{verbatim} (((cpu_pool ref) -> (cpu_pool record)) Map) get_all_records (session_id s)\end{verbatim}
  14.609 +
  14.610 +
  14.611 + \noindent {\bf Return Type:}
  14.612 +{\tt
  14.613 +((cpu\_pool ref) $\rightarrow$ (cpu\_pool record)) Map
  14.614 +}
  14.615 +A map of all the cpu pool records indexed by cpu pool ref.
  14.616 +
  14.617 +\vspace{0.3cm}
  14.618 +\vspace{0.3cm}
  14.619 +\vspace{0.3cm}
  14.620 +\subsubsection{RPC name:~get\_by\_name\_label}
  14.621 +
  14.622 +{\bf Overview:}
  14.623 +Get all the cpu\_pool instances with the given label.
  14.624 +
  14.625 + \noindent {\bf Signature:}
  14.626 +\begin{verbatim} ((cpu_pool ref) Set) get_by_name_label (session_id s, string label)\end{verbatim}
  14.627 +
  14.628 +
  14.629 +\noindent{\bf Arguments:}
  14.630 +
  14.631 +
  14.632 +\vspace{0.3cm}
  14.633 +\begin{tabular}{|c|c|p{7cm}|}
  14.634 + \hline
  14.635 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.636 +{\tt string } & label & label of object to return \\ \hline
  14.637 +
  14.638 +\end{tabular}
  14.639 +
  14.640 +\vspace{0.3cm}
  14.641 +
  14.642 + \noindent {\bf Return Type:}
  14.643 +{\tt
  14.644 +(cpu\_pool ref) Set
  14.645 +}
  14.646 +
  14.647 +
  14.648 +references to objects with matching names
  14.649 +\vspace{0.3cm}
  14.650 +\vspace{0.3cm}
  14.651 +\vspace{0.3cm}
  14.652 +\subsubsection{RPC name:~get\_by\_uuid}
  14.653 +
  14.654 +{\bf Overview:}
  14.655 +Get a reference to the cpu\_pool instance with the specified UUID.
  14.656 +
  14.657 + \noindent {\bf Signature:}
  14.658 +\begin{verbatim} (cpu_pool ref) get_by_uuid (session_id s, string uuid)\end{verbatim}
  14.659 +
  14.660 +
  14.661 +\noindent{\bf Arguments:}
  14.662 +
  14.663 +
  14.664 +\vspace{0.3cm}
  14.665 +\begin{tabular}{|c|c|p{7cm}|}
  14.666 + \hline
  14.667 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.668 +{\tt string } & uuid & UUID of object to return \\ \hline
  14.669 +
  14.670 +\end{tabular}
  14.671 +
  14.672 +\vspace{0.3cm}
  14.673 +
  14.674 + \noindent {\bf Return Type:}
  14.675 +{\tt
  14.676 +cpu\_pool ref
  14.677 +}
  14.678 +
  14.679 +
  14.680 +reference to the object
  14.681 +\vspace{0.3cm}
  14.682 +\vspace{0.3cm}
  14.683 +\vspace{0.3cm}
  14.684 +\subsubsection{RPC name:~get\_activated}
  14.685 +
  14.686 +
  14.687 +{\bf Overview:}
  14.688 +Return the activation state of the cpu\_pool object.
  14.689 +
  14.690 + \noindent {\bf Signature:}
  14.691 +\begin{verbatim} bool get_activated (session_id s, cpu_pool ref self)\end{verbatim}
  14.692 +
  14.693 +
  14.694 +\noindent{\bf Arguments:}
  14.695 +
  14.696 +
  14.697 +\vspace{0.3cm}
  14.698 +\begin{tabular}{|c|c|p{7cm}|}
  14.699 + \hline
  14.700 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.701 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.702 +\end{tabular}
  14.703 +
  14.704 +\vspace{0.3cm}
  14.705 +
  14.706 + \noindent {\bf Return Type:}
  14.707 +{\tt
  14.708 +bool
  14.709 +}
  14.710 +Returns {\bf true} if cpu\_pool is active.
  14.711 +
  14.712 +\vspace{0.3cm}
  14.713 +\vspace{0.3cm}
  14.714 +\vspace{0.3cm}
  14.715 +\subsubsection{RPC name:~get\_auto\_power\_on}
  14.716 +
  14.717 +
  14.718 +{\bf Overview:}
  14.719 +Return the auto power attribute of the cpu\_pool object.
  14.720 +
  14.721 + \noindent {\bf Signature:}
  14.722 +\begin{verbatim} bool get_auto_power_on (session_id s, cpu_pool ref self)\end{verbatim}
  14.723 +
  14.724 +
  14.725 +\noindent{\bf Arguments:}
  14.726 +
  14.727 +
  14.728 +\vspace{0.3cm}
  14.729 +\begin{tabular}{|c|c|p{7cm}|}
  14.730 + \hline
  14.731 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.732 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.733 +\end{tabular}
  14.734 +
  14.735 +\vspace{0.3cm}
  14.736 +
  14.737 + \noindent {\bf Return Type:}
  14.738 +{\tt
  14.739 +bool
  14.740 +}
  14.741 +Returns {\bf true} if cpu\_pool has to be activated on xend start.
  14.742 +
  14.743 +\vspace{0.3cm}
  14.744 +\vspace{0.3cm}
  14.745 +\vspace{0.3cm}
  14.746 +\subsubsection{RPC name:~get\_host\_CPUs}
  14.747 +
  14.748 +
  14.749 +{\bf Overview:}
  14.750 +Return the list of host\_cpu refs assigned to the cpu\_pool object.
  14.751 +
  14.752 + \noindent {\bf Signature:}
  14.753 +\begin{verbatim} ((host_cpu ref) Set) get_host_CPUs (session_id s, cpu_pool ref self)\end{verbatim}
  14.754 +
  14.755 +
  14.756 +\noindent{\bf Arguments:}
  14.757 +
  14.758 +
  14.759 +\vspace{0.3cm}
  14.760 +\begin{tabular}{|c|c|p{7cm}|}
  14.761 + \hline
  14.762 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.763 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.764 +\end{tabular}
  14.765 +
  14.766 +\vspace{0.3cm}
  14.767 +
  14.768 + \noindent {\bf Return Type:}
  14.769 +{\tt
  14.770 +(host\_cpu ref) Set
  14.771 +}
  14.772 +Returns a list of references of all host cpus assigned to the cpu\_pool.
  14.773 +
  14.774 +\vspace{0.3cm}
  14.775 +\vspace{0.3cm}
  14.776 +\vspace{0.3cm}
  14.777 +\subsubsection{RPC name:~get\_name\_description}
  14.778 +
  14.779 +{\bf Overview:}
  14.780 +Get the name/description field of the given cpu\_pool.
  14.781 +
  14.782 + \noindent {\bf Signature:}
  14.783 +\begin{verbatim} string get_name_description (session_id s, cpu_pool ref self)\end{verbatim}
  14.784 +
  14.785 +
  14.786 +\noindent{\bf Arguments:}
  14.787 +
  14.788 +
  14.789 +\vspace{0.3cm}
  14.790 +\begin{tabular}{|c|c|p{7cm}|}
  14.791 + \hline
  14.792 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.793 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.794 +
  14.795 +\end{tabular}
  14.796 +
  14.797 +\vspace{0.3cm}
  14.798 +
  14.799 + \noindent {\bf Return Type:}
  14.800 +{\tt
  14.801 +string
  14.802 +}
  14.803 +
  14.804 +
  14.805 +value of the field
  14.806 +\vspace{0.3cm}
  14.807 +\vspace{0.3cm}
  14.808 +\vspace{0.3cm}
  14.809 +\subsubsection{RPC name:~get\_name\_label}
  14.810 +
  14.811 +{\bf Overview:}
  14.812 +Get the name/label field of the given cpu\_pool.
  14.813 +
  14.814 + \noindent {\bf Signature:}
  14.815 +\begin{verbatim} string get_name_label (session_id s, cpu_pool ref self)\end{verbatim}
  14.816 +
  14.817 +
  14.818 +\noindent{\bf Arguments:}
  14.819 +
  14.820 +
  14.821 +\vspace{0.3cm}
  14.822 +\begin{tabular}{|c|c|p{7cm}|}
  14.823 + \hline
  14.824 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.825 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.826 +
  14.827 +\end{tabular}
  14.828 +
  14.829 +\vspace{0.3cm}
  14.830 +
  14.831 + \noindent {\bf Return Type:}
  14.832 +{\tt
  14.833 +string
  14.834 +}
  14.835 +
  14.836 +
  14.837 +value of the field
  14.838 +\vspace{0.3cm}
  14.839 +\vspace{0.3cm}
  14.840 +\vspace{0.3cm}
  14.841 +\subsubsection{RPC name:~get\_ncpu}
  14.842 +
  14.843 +{\bf Overview:}
  14.844 +Get the ncpu field of the given cpu\_pool.
  14.845 +
  14.846 + \noindent {\bf Signature:}
  14.847 +\begin{verbatim} int get_ncpu (session_id s, cpu_pool ref self)\end{verbatim}
  14.848 +
  14.849 +
  14.850 +\noindent{\bf Arguments:}
  14.851 +
  14.852 +
  14.853 +\vspace{0.3cm}
  14.854 +\begin{tabular}{|c|c|p{7cm}|}
  14.855 + \hline
  14.856 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.857 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.858 +
  14.859 +\end{tabular}
  14.860 +
  14.861 +\vspace{0.3cm}
  14.862 +
  14.863 + \noindent {\bf Return Type:}
  14.864 +{\tt
  14.865 +int
  14.866 +}
  14.867 +
  14.868 +
  14.869 +value of the field
  14.870 +\vspace{0.3cm}
  14.871 +\vspace{0.3cm}
  14.872 +\vspace{0.3cm}
  14.873 +\subsubsection{RPC name:~get\_proposed\_CPUs}
  14.874 +
  14.875 +{\bf Overview:}
  14.876 +Get the proposed\_CPUs field of the given cpu\_pool.
  14.877 +
  14.878 + \noindent {\bf Signature:}
  14.879 +\begin{verbatim} ((string) Set) get_proposed_CPUs (session_id s, cpu_pool ref self)\end{verbatim}
  14.880 +
  14.881 +
  14.882 +\noindent{\bf Arguments:}
  14.883 +
  14.884 +
  14.885 +\vspace{0.3cm}
  14.886 +\begin{tabular}{|c|c|p{7cm}|}
  14.887 + \hline
  14.888 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.889 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.890 +
  14.891 +\end{tabular}
  14.892 +
  14.893 +\vspace{0.3cm}
  14.894 +
  14.895 + \noindent {\bf Return Type:}
  14.896 +{\tt
  14.897 +(string) Set
  14.898 +}
  14.899 +
  14.900 +
  14.901 +value of the field
  14.902 +\vspace{0.3cm}
  14.903 +\vspace{0.3cm}
  14.904 +\vspace{0.3cm}
  14.905 +\subsubsection{RPC name:~get\_other\_config}
  14.906 +
  14.907 +{\bf Overview:}
  14.908 +Get the other\_config field of the given cpu\_pool.
  14.909 +
  14.910 +\noindent {\bf Signature:}
  14.911 +\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, cpu_pool ref self)\end{verbatim}
  14.912 +
  14.913 +
  14.914 +\noindent{\bf Arguments:}
  14.915 +
  14.916 +
  14.917 +\vspace{0.3cm}
  14.918 +\begin{tabular}{|c|c|p{7cm}|}
  14.919 + \hline
  14.920 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.921 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.922 +\end{tabular}
  14.923 +
  14.924 +\vspace{0.3cm}
  14.925 +
  14.926 +\noindent {\bf Return Type:}
  14.927 +{\tt
  14.928 +(string $\rightarrow$ string) Map
  14.929 +}
  14.930 +
  14.931 +
  14.932 +value of the field
  14.933 +\vspace{0.3cm}
  14.934 +\vspace{0.3cm}
  14.935 +\vspace{0.3cm}
  14.936 +\subsubsection{RPC name:~get\_record}
  14.937 +
  14.938 +{\bf Overview:}
  14.939 +Get a record containing the current state of the given cpu\_pool.
  14.940 +
  14.941 +\noindent {\bf Signature:}
  14.942 +\begin{verbatim} (cpu_pool record) get_record (session_id s, cpu_pool ref self)\end{verbatim}
  14.943 +
  14.944 +
  14.945 +\noindent{\bf Arguments:}
  14.946 +
  14.947 +
  14.948 +\vspace{0.3cm}
  14.949 +\begin{tabular}{|c|c|p{7cm}|}
  14.950 + \hline
  14.951 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.952 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.953 +\end{tabular}
  14.954 +
  14.955 +\vspace{0.3cm}
  14.956 +
  14.957 +\noindent {\bf Return Type:}
  14.958 +{\tt
  14.959 +cpu\_pool record
  14.960 +}
  14.961 +
  14.962 +
  14.963 +all fields of the object.
  14.964 +\vspace{0.3cm}
  14.965 +\vspace{0.3cm}
  14.966 +\vspace{0.3cm}
  14.967 +\subsubsection{RPC name:~get\_resident\_on}
  14.968 +
  14.969 +{\bf Overview:}
  14.970 +Get the resident\_on field of the given cpu\_pool.
  14.971 +
  14.972 +\noindent {\bf Signature:}
  14.973 +\begin{verbatim} (host ref) get_resident_on (session_id s, cpu_pool ref self)\end{verbatim}
  14.974 +
  14.975 +
  14.976 +\noindent{\bf Arguments:}
  14.977 +
  14.978 +
  14.979 +\vspace{0.3cm}
  14.980 +\begin{tabular}{|c|c|p{7cm}|}
  14.981 + \hline
  14.982 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  14.983 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
  14.984 +\end{tabular}
  14.985 +
  14.986 +\vspace{0.3cm}
  14.987 +
  14.988 +\noindent {\bf Return Type:}
  14.989 +{\tt
  14.990 +host ref
  14.991 +}
  14.992 +
  14.993 +
  14.994 +value of the field
  14.995 +\vspace{0.3cm}
  14.996 +\vspace{0.3cm}
  14.997 +\vspace{0.3cm}
  14.998 +\subsubsection{RPC name:~get\_sched\_policy}
  14.999 +
 14.1000 +{\bf Overview:}
 14.1001 +Get the sched\_policy field of the given cpu\_pool.
 14.1002 +
 14.1003 +\noindent {\bf Signature:}
 14.1004 +\begin{verbatim} string get_sched_policy (session_id s, cpu_pool ref self)\end{verbatim}
 14.1005 +
 14.1006 +
 14.1007 +\noindent{\bf Arguments:}
 14.1008 +
 14.1009 +
 14.1010 +\vspace{0.3cm}
 14.1011 +\begin{tabular}{|c|c|p{7cm}|}
 14.1012 + \hline
 14.1013 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1014 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1015 +\end{tabular}
 14.1016 +
 14.1017 +\vspace{0.3cm}
 14.1018 +
 14.1019 +\noindent {\bf Return Type:}
 14.1020 +{\tt
 14.1021 +string
 14.1022 +}
 14.1023 +
 14.1024 +
 14.1025 +value of the field
 14.1026 +\vspace{0.3cm}
 14.1027 +\vspace{0.3cm}
 14.1028 +\vspace{0.3cm}
 14.1029 +\subsubsection{RPC name:~get\_started\_VMs}
 14.1030 +
 14.1031 +{\bf Overview:}
 14.1032 +Get the started\_VMs field of the given cpu\_pool.
 14.1033 +
 14.1034 +\noindent {\bf Signature:}
 14.1035 +\begin{verbatim} ((VM ref) Set) get_started_VMs (session_id s, cpu_pool ref self)\end{verbatim}
 14.1036 +
 14.1037 +
 14.1038 +\noindent{\bf Arguments:}
 14.1039 +
 14.1040 +
 14.1041 +\vspace{0.3cm}
 14.1042 +\begin{tabular}{|c|c|p{7cm}|}
 14.1043 + \hline
 14.1044 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1045 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1046 +\end{tabular}
 14.1047 +
 14.1048 +\vspace{0.3cm}
 14.1049 +
 14.1050 +\noindent {\bf Return Type:}
 14.1051 +{\tt
 14.1052 +(VM ref) Set
 14.1053 +}
 14.1054 +
 14.1055 +
 14.1056 +value of the field
 14.1057 +\vspace{0.3cm}
 14.1058 +\vspace{0.3cm}
 14.1059 +\vspace{0.3cm}
 14.1060 +\subsubsection{RPC name:~get\_uuid}
 14.1061 +
 14.1062 +{\bf Overview:}
 14.1063 +Get the uuid field of the given cpu\_pool.
 14.1064 +
 14.1065 + \noindent {\bf Signature:}
 14.1066 +\begin{verbatim} string get_uuid (session_id s, cpu_pool ref self)\end{verbatim}
 14.1067 +
 14.1068 +
 14.1069 +\noindent{\bf Arguments:}
 14.1070 +
 14.1071 +
 14.1072 +\vspace{0.3cm}
 14.1073 +\begin{tabular}{|c|c|p{7cm}|}
 14.1074 + \hline
 14.1075 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1076 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1077 +\end{tabular}
 14.1078 +
 14.1079 +\vspace{0.3cm}
 14.1080 +
 14.1081 + \noindent {\bf Return Type:}
 14.1082 +{\tt
 14.1083 +string
 14.1084 +}
 14.1085 +
 14.1086 +
 14.1087 +value of the field
 14.1088 +\vspace{0.3cm}
 14.1089 +\vspace{0.3cm}
 14.1090 +\vspace{0.3cm}
 14.1091 +\subsubsection{RPC name:~set\_auto\_power\_on}
 14.1092 +
 14.1093 +{\bf Overview:}
 14.1094 +Set the auto\_power\_on field of the given cpu\_pool.
 14.1095 +
 14.1096 +\noindent {\bf Signature:}
 14.1097 +\begin{verbatim} void set_auto_power_on (session_id s, cpu_pool ref self, bool value)\end{verbatim}
 14.1098 +
 14.1099 +
 14.1100 +\noindent{\bf Arguments:}
 14.1101 +
 14.1102 +
 14.1103 +\vspace{0.3cm}
 14.1104 +\begin{tabular}{|c|c|p{7cm}|}
 14.1105 + \hline
 14.1106 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1107 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1108 +{\tt bool } & value & new auto\_power\_on value \\ \hline
 14.1109 +\end{tabular}
 14.1110 +
 14.1111 +\vspace{0.3cm}
 14.1112 +
 14.1113 +\noindent {\bf Return Type:}
 14.1114 +{\tt
 14.1115 +void
 14.1116 +}
 14.1117 +\vspace{0.3cm}
 14.1118 +\vspace{0.3cm}
 14.1119 +\vspace{0.3cm}
 14.1120 +\subsubsection{RPC name:~set\_proposed\_CPUs}
 14.1121 +
 14.1122 +{\bf Overview:}
 14.1123 +Set the proposed\_CPUs field of the given cpu\_pool.
 14.1124 +
 14.1125 +\noindent {\bf Signature:}
 14.1126 +\begin{verbatim} void set_proposed_CPUs (session_id s, cpu_pool ref self, string Set cpus)\end{verbatim}
 14.1127 +
 14.1128 +
 14.1129 +\noindent{\bf Arguments:}
 14.1130 +
 14.1131 +
 14.1132 +\vspace{0.3cm}
 14.1133 +\begin{tabular}{|c|c|p{7cm}|}
 14.1134 + \hline
 14.1135 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1136 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1137 +{\tt string Set } & cpus & Set of preferred CPU (numbers) to use \\ \hline
 14.1138 +\end{tabular}
 14.1139 +
 14.1140 +\vspace{0.3cm}
 14.1141 +
 14.1142 +\noindent {\bf Return Type:}
 14.1143 +{\tt
 14.1144 +void
 14.1145 +}
 14.1146 +\vspace{0.3cm}
 14.1147 +
 14.1148 +\noindent {\bf Possible Error Codes:}
 14.1149 +    {\tt POOL\_BAD\_STATE}
 14.1150 +
 14.1151 +\vspace{0.3cm}
 14.1152 +\vspace{0.3cm}
 14.1153 +\vspace{0.3cm}
 14.1154 +\subsubsection{RPC name:add\_to\_proposed\_CPUs}
 14.1155 +
 14.1156 +{\bf Overview:}
 14.1157 +Add a CPU (number) to the proposed\_CPUs field of the given cpu\_pool.
 14.1158 +
 14.1159 +\noindent {\bf Signature:}
 14.1160 +\begin{verbatim} void add_to_proposed_CPUs (session_id s, cpu_pool ref self, integer cpu)\end{verbatim}
 14.1161 +
 14.1162 +
 14.1163 +\noindent{\bf Arguments:}
 14.1164 +
 14.1165 +
 14.1166 +\vspace{0.3cm}
 14.1167 +\begin{tabular}{|c|c|p{7cm}|}
 14.1168 + \hline
 14.1169 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1170 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1171 +{\tt integer } & cpu & Number of CPU to add \\ \hline
 14.1172 +\end{tabular}
 14.1173 +
 14.1174 +\vspace{0.3cm}
 14.1175 +
 14.1176 +\noindent {\bf Return Type:}
 14.1177 +{\tt
 14.1178 +void
 14.1179 +}
 14.1180 +\vspace{0.3cm}
 14.1181 +
 14.1182 +\noindent {\bf Possible Error Codes:}
 14.1183 +    {\tt POOL\_BAD\_STATE}
 14.1184 +
 14.1185 +\vspace{0.3cm}
 14.1186 +\vspace{0.3cm}
 14.1187 +\vspace{0.3cm}
 14.1188 +\subsubsection{RPC name:remove\_from\_proposed\_CPUs}
 14.1189 +
 14.1190 +{\bf Overview:}
 14.1191 +Remove a CPU (number) from the proposed\_CPUs field of the given cpu\_pool.
 14.1192 +
 14.1193 +\noindent {\bf Signature:}
 14.1194 +\begin{verbatim} void remove_from_proposed_CPUs (session_id s, cpu_pool ref self, integer cpu)\end{verbatim}
 14.1195 +
 14.1196 +
 14.1197 +\noindent{\bf Arguments:}
 14.1198 +
 14.1199 +
 14.1200 +\vspace{0.3cm}
 14.1201 +\begin{tabular}{|c|c|p{7cm}|}
 14.1202 +\hline
 14.1203 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1204 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1205 +{\tt integer } & cpu & Number of CPU to remove \\ \hline
 14.1206 +\end{tabular}
 14.1207 +
 14.1208 +\vspace{0.3cm}
 14.1209 +
 14.1210 +\noindent {\bf Return Type:}
 14.1211 +{\tt
 14.1212 +void
 14.1213 +}
 14.1214 +\vspace{0.3cm}
 14.1215 +
 14.1216 +\noindent {\bf Possible Error Codes:}
 14.1217 +    {\tt POOL\_BAD\_STATE}
 14.1218 +
 14.1219 +\vspace{0.3cm}
 14.1220 +\vspace{0.3cm}
 14.1221 +\vspace{0.3cm}
 14.1222 +\subsubsection{RPC name:~set\_name\_label}
 14.1223 +
 14.1224 +{\bf Overview:}
 14.1225 +Set the name/label field of the given cpu\_pool.
 14.1226 +
 14.1227 + \noindent {\bf Signature:}
 14.1228 +\begin{verbatim} void set_name_label (session_id s, cpu_pool ref self, string value)\end{verbatim}
 14.1229 +
 14.1230 +
 14.1231 +\noindent{\bf Arguments:}
 14.1232 +
 14.1233 +
 14.1234 +\vspace{0.3cm}
 14.1235 +\begin{tabular}{|c|c|p{7cm}|}
 14.1236 +\hline
 14.1237 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1238 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1239 +{\tt string } & value & New value to set \\ \hline
 14.1240 +\end{tabular}
 14.1241 +
 14.1242 +\vspace{0.3cm}
 14.1243 +
 14.1244 + \noindent {\bf Return Type:}
 14.1245 +{\tt
 14.1246 +void
 14.1247 +}
 14.1248 +
 14.1249 +
 14.1250 +
 14.1251 +\vspace{0.3cm}
 14.1252 +\vspace{0.3cm}
 14.1253 +\vspace{0.3cm}
 14.1254 +\subsubsection{RPC name:~set\_ncpu}
 14.1255 +
 14.1256 +{\bf Overview:}
 14.1257 +Set the ncpu field of the given cpu\_pool.
 14.1258 +
 14.1259 + \noindent {\bf Signature:}
 14.1260 +\begin{verbatim} void set_ncpu (session_id s, cpu_pool ref self, integer value)\end{verbatim}
 14.1261 +
 14.1262 +
 14.1263 +\noindent{\bf Arguments:}
 14.1264 +
 14.1265 +
 14.1266 +\vspace{0.3cm}
 14.1267 +\begin{tabular}{|c|c|p{7cm}|}
 14.1268 +\hline
 14.1269 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1270 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1271 +{\tt integer } & value & Number of cpus to use \\ \hline
 14.1272 +\end{tabular}
 14.1273 +
 14.1274 +\vspace{0.3cm}
 14.1275 +
 14.1276 + \noindent {\bf Return Type:}
 14.1277 +{\tt
 14.1278 +void
 14.1279 +}
 14.1280 +
 14.1281 +\vspace{0.3cm}
 14.1282 +
 14.1283 +\noindent {\bf Possible Error Codes:}
 14.1284 +    {\tt POOL\_BAD\_STATE}
 14.1285 +
 14.1286 +\vspace{0.3cm}
 14.1287 +\vspace{0.3cm}
 14.1288 +\vspace{0.3cm}
 14.1289 +\subsubsection{RPC name:~set\_other\_config}
 14.1290 +
 14.1291 +{\bf Overview:}
 14.1292 +Set the other\_config field of the given cpu\_pool.
 14.1293 +
 14.1294 + \noindent {\bf Signature:}
 14.1295 +\begin{verbatim} void set_other_config (session_id s, cpu_pool ref self, (string -> string) Map value)\end{verbatim}
 14.1296 +
 14.1297 +
 14.1298 +\noindent{\bf Arguments:}
 14.1299 +
 14.1300 +
 14.1301 +\vspace{0.3cm}
 14.1302 +\begin{tabular}{|c|c|p{7cm}|}
 14.1303 +\hline
 14.1304 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1305 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1306 +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline
 14.1307 +\end{tabular}
 14.1308 +
 14.1309 +\vspace{0.3cm}
 14.1310 +
 14.1311 +\noindent {\bf Return Type:}
 14.1312 +{\tt
 14.1313 +void
 14.1314 +}
 14.1315 +
 14.1316 +
 14.1317 +
 14.1318 +\vspace{0.3cm}
 14.1319 +\vspace{0.3cm}
 14.1320 +\vspace{0.3cm}
 14.1321 +\subsubsection{RPC name:~add\_to\_other\_config}
 14.1322 +
 14.1323 +{\bf Overview:}
 14.1324 +Add the given key-value pair to the other\_config field of the given cpu\_pool.
 14.1325 +
 14.1326 + \noindent {\bf Signature:}
 14.1327 +\begin{verbatim} void add_to_other_config (session_id s, cpu_pool ref self, string key, string value)\end{verbatim}
 14.1328 +
 14.1329 +
 14.1330 +\noindent{\bf Arguments:}
 14.1331 +
 14.1332 +
 14.1333 +\vspace{0.3cm}
 14.1334 +\begin{tabular}{|c|c|p{7cm}|}
 14.1335 +\hline
 14.1336 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1337 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1338 +{\tt string } & key & Key to add \\ \hline
 14.1339 +{\tt string } & value & Value to add \\ \hline
 14.1340 +\end{tabular}
 14.1341 +
 14.1342 +\vspace{0.3cm}
 14.1343 +
 14.1344 + \noindent {\bf Return Type:}
 14.1345 +{\tt
 14.1346 +void
 14.1347 +}
 14.1348 +
 14.1349 +
 14.1350 +
 14.1351 +\vspace{0.3cm}
 14.1352 +\vspace{0.3cm}
 14.1353 +\vspace{0.3cm}
 14.1354 +\subsubsection{RPC name:~remove\_from\_other\_config}
 14.1355 +
 14.1356 +{\bf Overview:}
 14.1357 +Remove the given key and its corresponding value from the other\_config
 14.1358 +field of the given cpu\_pool.  If the key is not in that Map, then do nothing.
 14.1359 +
 14.1360 + \noindent {\bf Signature:}
 14.1361 +\begin{verbatim} void remove_from_other_config (session_id s, cpu_pool ref self, string key)\end{verbatim}
 14.1362 +
 14.1363 +
 14.1364 +\noindent{\bf Arguments:}
 14.1365 +
 14.1366 +
 14.1367 +\vspace{0.3cm}
 14.1368 +\begin{tabular}{|c|c|p{7cm}|}
 14.1369 +\hline
 14.1370 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1371 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1372 +{\tt string } & key & Key to remove \\ \hline
 14.1373 +\end{tabular}
 14.1374 +
 14.1375 +\vspace{0.3cm}
 14.1376 +
 14.1377 +\noindent {\bf Return Type:}
 14.1378 +{\tt
 14.1379 +void
 14.1380 +}
 14.1381 +
 14.1382 +
 14.1383 +
 14.1384 +\vspace{0.3cm}
 14.1385 +\vspace{0.3cm}
 14.1386 +\vspace{0.3cm}
 14.1387 +\subsubsection{RPC name:~set\_sched\_policy}
 14.1388 +
 14.1389 +{\bf Overview:}
 14.1390 +Set the sched\_policy field of the given cpu\_pool.
 14.1391 +
 14.1392 + \noindent {\bf Signature:}
 14.1393 +\begin{verbatim} void set_sched_policy (session_id s, cpu_pool ref self, string new_sched_policy)\end{verbatim}
 14.1394 +
 14.1395 +
 14.1396 +\noindent{\bf Arguments:}
 14.1397 +
 14.1398 +
 14.1399 +\vspace{0.3cm}
 14.1400 +\begin{tabular}{|c|c|p{7cm}|}
 14.1401 +\hline
 14.1402 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 14.1403 +{\tt cpu\_pool ref } & self & reference to the object \\ \hline
 14.1404 +{\tt string } & new\_sched\_policy & New value to set \\ \hline
 14.1405 +\end{tabular}
 14.1406 +\vspace{0.3cm}
 14.1407 +
 14.1408 +\noindent {\bf Return Type:}
 14.1409 +{\tt
 14.1410 +void
 14.1411 +}
 14.1412 +
 14.1413 +
    15.1 --- a/extras/mini-os/blkfront.c	Wed Jun 09 19:53:32 2010 -0700
    15.2 +++ b/extras/mini-os/blkfront.c	Fri Jul 16 17:16:06 2010 -0700
    15.3 @@ -278,7 +278,7 @@ void shutdown_blkfront(struct blkfront_d
    15.4          goto close;
    15.5      }
    15.6      state = xenbus_read_integer(path);
    15.7 -    if (state < XenbusStateClosed) {
    15.8 +    while (state < XenbusStateClosed) {
    15.9          err = xenbus_wait_for_state_change(path, &state, &dev->events);
   15.10          if (err) free(err);
   15.11      }
   15.12 @@ -302,7 +302,8 @@ close:
   15.13      snprintf(path, sizeof(path), "%s/event-channel", nodename);
   15.14      xenbus_rm(XBT_NIL, path);
   15.15  
   15.16 -    free_blkfront(dev);
   15.17 +    if (!err)
   15.18 +        free_blkfront(dev);
   15.19  }
   15.20  
   15.21  static void blkfront_wait_slot(struct blkfront_dev *dev)
    16.1 --- a/extras/mini-os/fbfront.c	Wed Jun 09 19:53:32 2010 -0700
    16.2 +++ b/extras/mini-os/fbfront.c	Fri Jul 16 17:16:06 2010 -0700
    16.3 @@ -261,7 +261,7 @@ void shutdown_kbdfront(struct kbdfront_d
    16.4          goto close_kbdfront;
    16.5      }
    16.6      state = xenbus_read_integer(path);
    16.7 -    if (state < XenbusStateClosed) {
    16.8 +    while (state < XenbusStateClosed) {
    16.9          err = xenbus_wait_for_state_change(path, &state, &dev->events);
   16.10          if (err) free(err);
   16.11      }
   16.12 @@ -271,8 +271,10 @@ void shutdown_kbdfront(struct kbdfront_d
   16.13                  XenbusStateInitialising, err);
   16.14          goto close_kbdfront;
   16.15      }
   16.16 -    // does not work yet.
   16.17 -    //xenbus_wait_for_value(path, "2", &dev->events);
   16.18 +    err = NULL;
   16.19 +    state = xenbus_read_integer(path);
   16.20 +    while (err == NULL && (state < XenbusStateInitWait || state >= XenbusStateClosed))
   16.21 +    err = xenbus_wait_for_state_change(path, &state, &dev->events);
   16.22  
   16.23  close_kbdfront:
   16.24      if (err) free(err);
   16.25 @@ -285,7 +287,8 @@ close_kbdfront:
   16.26      snprintf(path, sizeof(path), "%s/request-abs-pointer", nodename);
   16.27      xenbus_rm(XBT_NIL, path);
   16.28  
   16.29 -    free_kbdfront(dev);
   16.30 +    if (!err)
   16.31 +        free_kbdfront(dev);
   16.32  }
   16.33  
   16.34  #ifdef HAVE_LIBC
   16.35 @@ -659,8 +662,11 @@ void shutdown_fbfront(struct fbfront_dev
   16.36                  XenbusStateInitialising, err);
   16.37          goto close_fbfront;
   16.38      }
   16.39 -    // does not work yet
   16.40 -    //xenbus_wait_for_value(path, "2", &dev->events);
   16.41 +
   16.42 +    err = NULL;
   16.43 +    state = xenbus_read_integer(path);
   16.44 +    while (err == NULL && (state < XenbusStateInitWait || state >= XenbusStateClosed))
   16.45 +        err = xenbus_wait_for_state_change(path, &state, &dev->events);
   16.46  
   16.47  close_fbfront:
   16.48      if (err) free(err);
   16.49 @@ -675,7 +681,8 @@ close_fbfront:
   16.50      snprintf(path, sizeof(path), "%s/feature-update", nodename);
   16.51      xenbus_rm(XBT_NIL, path);
   16.52  
   16.53 -    free_fbfront(dev);
   16.54 +    if (!err)
   16.55 +        free_fbfront(dev);
   16.56  }
   16.57  
   16.58  #ifdef HAVE_LIBC
    17.1 --- a/extras/mini-os/kernel.c	Wed Jun 09 19:53:32 2010 -0700
    17.2 +++ b/extras/mini-os/kernel.c	Fri Jul 16 17:16:06 2010 -0700
    17.3 @@ -353,6 +353,7 @@ static struct kbdfront_dev *kbd_dev;
    17.4  static void kbdfront_thread(void *p)
    17.5  {
    17.6      DEFINE_WAIT(w);
    17.7 +    DEFINE_WAIT(w2);
    17.8      int x = WIDTH / 2, y = HEIGHT / 2, z = 0;
    17.9  
   17.10      kbd_dev = init_kbdfront(NULL, 1);
   17.11 @@ -367,7 +368,7 @@ static void kbdfront_thread(void *p)
   17.12          int sleep = 1;
   17.13  
   17.14          add_waiter(w, kbdfront_queue);
   17.15 -        add_waiter(w, fbfront_queue);
   17.16 +        add_waiter(w2, fbfront_queue);
   17.17  
   17.18          while (kbdfront_receive(kbd_dev, &kbdevent, 1) != 0) {
   17.19              sleep = 0;
    18.1 --- a/extras/mini-os/lib/sys.c	Wed Jun 09 19:53:32 2010 -0700
    18.2 +++ b/extras/mini-os/lib/sys.c	Fri Jul 16 17:16:06 2010 -0700
    18.3 @@ -84,7 +84,8 @@
    18.4  
    18.5  #define NOFILE 32
    18.6  extern int xc_evtchn_close(int fd);
    18.7 -extern int xc_interface_close(int fd);
    18.8 +struct xc_interface;
    18.9 +extern int xc_interface_close_core(struct xc_interface*, int fd);
   18.10  extern int xc_gnttab_close(int fd);
   18.11  
   18.12  pthread_mutex_t fd_lock = PTHREAD_MUTEX_INITIALIZER;
   18.13 @@ -413,7 +414,7 @@ int close(int fd)
   18.14  	}
   18.15  #endif
   18.16  	case FTYPE_XC:
   18.17 -	    xc_interface_close(fd);
   18.18 +	    xc_interface_close_core(0,fd);
   18.19  	    return 0;
   18.20  	case FTYPE_EVTCHN:
   18.21              xc_evtchn_close(fd);
    19.1 --- a/extras/mini-os/netfront.c	Wed Jun 09 19:53:32 2010 -0700
    19.2 +++ b/extras/mini-os/netfront.c	Fri Jul 16 17:16:06 2010 -0700
    19.3 @@ -534,7 +534,7 @@ void shutdown_netfront(struct netfront_d
    19.4          goto close;
    19.5      }
    19.6      state = xenbus_read_integer(path);
    19.7 -    if (state < XenbusStateClosed) {
    19.8 +    while (state < XenbusStateClosed) {
    19.9          err = xenbus_wait_for_state_change(path, &state, &dev->events);
   19.10          if (err) free(err);
   19.11      }
   19.12 @@ -562,7 +562,8 @@ close:
   19.13      snprintf(path, sizeof(path), "%s/request-rx-copy", nodename);
   19.14      xenbus_rm(XBT_NIL, path);
   19.15  
   19.16 -    free_netfront(dev);
   19.17 +    if (!err)
   19.18 +        free_netfront(dev);
   19.19  }
   19.20  
   19.21  
    20.1 --- a/extras/mini-os/pcifront.c	Wed Jun 09 19:53:32 2010 -0700
    20.2 +++ b/extras/mini-os/pcifront.c	Fri Jul 16 17:16:06 2010 -0700
    20.3 @@ -69,7 +69,7 @@ void pcifront_watches(void *opaque)
    20.4      snprintf(fe_state, sizeof(fe_state), "%s/state", nodename);
    20.5  
    20.6      while (1) {
    20.7 -        printk("pcifront_watches: waiting for backend path to happear %s\n", path);
    20.8 +        printk("pcifront_watches: waiting for backend path to appear %s\n", path);
    20.9          xenbus_watch_path_token(XBT_NIL, path, path, &events);
   20.10          while ((err = xenbus_read(XBT_NIL, path, &be_path)) != NULL) {
   20.11              free(err);
   20.12 @@ -353,7 +353,7 @@ void shutdown_pcifront(struct pcifront_d
   20.13          goto close_pcifront;
   20.14      }
   20.15      state = xenbus_read_integer(path);
   20.16 -    if (state < XenbusStateClosed) {
   20.17 +    while (state < XenbusStateClosed) {
   20.18          err = xenbus_wait_for_state_change(path, &state, &dev->events);
   20.19          free(err);
   20.20      }
   20.21 @@ -377,7 +377,8 @@ close_pcifront:
   20.22      snprintf(path, sizeof(path), "%s/event-channel", nodename);
   20.23      xenbus_rm(XBT_NIL, path);
   20.24  
   20.25 -    free_pcifront(dev);
   20.26 +    if (!err)
   20.27 +        free_pcifront(dev);
   20.28  }
   20.29  
   20.30  int pcifront_physical_to_virtual (struct pcifront_dev *dev,
    21.1 --- a/extras/mini-os/xenbus/xenbus.c	Wed Jun 09 19:53:32 2010 -0700
    21.2 +++ b/extras/mini-os/xenbus/xenbus.c	Fri Jul 16 17:16:06 2010 -0700
    21.3 @@ -154,8 +154,10 @@ char *xenbus_switch_state(xenbus_transac
    21.4          msg = xenbus_write(xbt, path, value);
    21.5  
    21.6  exit:
    21.7 -        if (xbt_flag)
    21.8 +        if (xbt_flag) {
    21.9              msg2 = xenbus_transaction_end(xbt, 0, &retry);
   21.10 +            xbt = XBT_NIL;
   21.11 +        }
   21.12          if (msg == NULL && msg2 != NULL)
   21.13              msg = msg2;
   21.14      } while (retry);
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/patch.out	Fri Jul 16 17:16:06 2010 -0700
    22.3 @@ -0,0 +1,899 @@
    22.4 +patching file Config.mk
    22.5 +Hunk #3 succeeded at 157 (offset 3 lines).
    22.6 +patching file Makefile
    22.7 +patching file README
    22.8 +patching file buildconfigs/enable-xen-config
    22.9 +patching file buildconfigs/mk.linux-2.6-pvops
   22.10 +patching file buildconfigs/src.git-clone
   22.11 +patching file docs/man/xm.pod.1
   22.12 +patching file docs/misc/tmem-internals.html
   22.13 +patching file docs/xen-api/coversheet.tex
   22.14 +patching file docs/xen-api/revision-history.tex
   22.15 +patching file docs/xen-api/xenapi-coversheet.tex
   22.16 +patching file docs/xen-api/xenapi-datamodel-graph.dot
   22.17 +patching file docs/xen-api/xenapi-datamodel.tex
   22.18 +patching file extras/mini-os/blkfront.c
   22.19 +patching file extras/mini-os/fbfront.c
   22.20 +patching file extras/mini-os/kernel.c
   22.21 +patching file extras/mini-os/lib/sys.c
   22.22 +patching file extras/mini-os/netfront.c
   22.23 +patching file extras/mini-os/pcifront.c
   22.24 +patching file extras/mini-os/xenbus/xenbus.c
   22.25 +patching file stubdom/Makefile
   22.26 +patching file stubdom/grub/kexec.c
   22.27 +patching file stubdom/grub/mini-os.c
   22.28 +patching file tools/Makefile
   22.29 +patching file tools/Rules.mk
   22.30 +patching file tools/blktap/drivers/blktapctrl_linux.c
   22.31 +patching file tools/blktap/drivers/block-qcow.c
   22.32 +patching file tools/blktap2/Makefile
   22.33 +patching file tools/blktap2/control/Makefile
   22.34 +patching file tools/blktap2/control/tap-ctl-allocate.c
   22.35 +patching file tools/blktap2/control/tap-ctl-attach.c
   22.36 +patching file tools/blktap2/control/tap-ctl-check.c
   22.37 +patching file tools/blktap2/control/tap-ctl-close.c
   22.38 +patching file tools/blktap2/control/tap-ctl-create.c
   22.39 +patching file tools/blktap2/control/tap-ctl-destroy.c
   22.40 +patching file tools/blktap2/control/tap-ctl-detach.c
   22.41 +patching file tools/blktap2/control/tap-ctl-free.c
   22.42 +patching file tools/blktap2/control/tap-ctl-ipc.c
   22.43 +patching file tools/blktap2/control/tap-ctl-list.c
   22.44 +patching file tools/blktap2/control/tap-ctl-major.c
   22.45 +patching file tools/blktap2/control/tap-ctl-open.c
   22.46 +patching file tools/blktap2/control/tap-ctl-pause.c
   22.47 +patching file tools/blktap2/control/tap-ctl-spawn.c
   22.48 +patching file tools/blktap2/control/tap-ctl-unpause.c
   22.49 +patching file tools/blktap2/control/tap-ctl.c
   22.50 +patching file tools/blktap2/control/tap-ctl.h
   22.51 +patching file tools/blktap2/drivers/Makefile
   22.52 +patching file tools/blktap2/drivers/blktap2.h
   22.53 +patching file tools/blktap2/drivers/block-qcow.c
   22.54 +patching file tools/blktap2/drivers/block-remus.c
   22.55 +patching file tools/blktap2/drivers/block-vhd.c
   22.56 +patching file tools/blktap2/drivers/disktypes.h
   22.57 +patching file tools/blktap2/drivers/img2qcow.c
   22.58 +patching file tools/blktap2/drivers/md5.c
   22.59 +patching file tools/blktap2/drivers/md5.h
   22.60 +patching file tools/blktap2/drivers/qcow2raw.c
   22.61 +patching file tools/blktap2/drivers/tapdisk-control.c
   22.62 +patching file tools/blktap2/drivers/tapdisk-control.h
   22.63 +patching file tools/blktap2/drivers/tapdisk-diff.c
   22.64 +patching file tools/blktap2/drivers/tapdisk-disktype.c
   22.65 +patching file tools/blktap2/drivers/tapdisk-disktype.h
   22.66 +patching file tools/blktap2/drivers/tapdisk-driver.c
   22.67 +patching file tools/blktap2/drivers/tapdisk-driver.h
   22.68 +patching file tools/blktap2/drivers/tapdisk-image.c
   22.69 +patching file tools/blktap2/drivers/tapdisk-image.h
   22.70 +patching file tools/blktap2/drivers/tapdisk-interface.c
   22.71 +patching file tools/blktap2/drivers/tapdisk-interface.h
   22.72 +patching file tools/blktap2/drivers/tapdisk-ipc.c
   22.73 +patching file tools/blktap2/drivers/tapdisk-ipc.h
   22.74 +patching file tools/blktap2/drivers/tapdisk-server.c
   22.75 +patching file tools/blktap2/drivers/tapdisk-server.h
   22.76 +patching file tools/blktap2/drivers/tapdisk-stream.c
   22.77 +patching file tools/blktap2/drivers/tapdisk-utils.c
   22.78 +patching file tools/blktap2/drivers/tapdisk-utils.h
   22.79 +patching file tools/blktap2/drivers/tapdisk-vbd.c
   22.80 +patching file tools/blktap2/drivers/tapdisk-vbd.h
   22.81 +patching file tools/blktap2/drivers/tapdisk.h
   22.82 +patching file tools/blktap2/drivers/tapdisk2.c
   22.83 +patching file tools/blktap2/include/blktap2.h
   22.84 +patching file tools/blktap2/include/blktaplib.h
   22.85 +patching file tools/blktap2/include/list.h
   22.86 +patching file tools/blktap2/include/tapdisk-message.h
   22.87 +patching file tools/console/client/main.c
   22.88 +patching file tools/console/daemon/io.c
   22.89 +patching file tools/console/daemon/utils.c
   22.90 +patching file tools/console/daemon/utils.h
   22.91 +patching file tools/debugger/gdb/README
   22.92 +patching file tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/Makefile.in
   22.93 +patching file tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure
   22.94 +patching file tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.in
   22.95 +patching file tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv
   22.96 +patching file tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
   22.97 +patching file tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c
   22.98 +patching file tools/debugger/gdb/gdb-6.2.1-xen-sparse/mkbuildtree
   22.99 +patching file tools/debugger/gdb/gdbbuild
  22.100 +patching file tools/debugger/gdbsx/README
  22.101 +patching file tools/debugger/gdbsx/gx/gx_main.c
  22.102 +patching file tools/debugger/xenitp/xenitp.c
  22.103 +patching file tools/examples/xend-config.sxp
  22.104 +patching file tools/firmware/Makefile
  22.105 +patching file tools/firmware/etherboot/Config
  22.106 +patching file tools/firmware/etherboot/Makefile
  22.107 +patching file tools/firmware/etherboot/eb-roms.h
  22.108 +patching file tools/firmware/hvmloader/Makefile
  22.109 +patching file tools/firmware/hvmloader/acpi/acpi2_0.h
  22.110 +patching file tools/firmware/hvmloader/acpi/static_tables.c
  22.111 +patching file tools/firmware/hvmloader/hvmloader.c
  22.112 +patching file tools/firmware/hvmloader/smbios.c
  22.113 +patching file tools/firmware/hvmloader/smbios_types.h
  22.114 +patching file tools/firmware/hvmloader/util.h
  22.115 +patching file tools/firmware/hvmloader/xenbus.c
  22.116 +patching file tools/firmware/rombios/rombios.c
  22.117 +patching file tools/flask/libflask/flask_op.c
  22.118 +patching file tools/flask/libflask/include/libflask.h
  22.119 +patching file tools/flask/utils/getenforce.c
  22.120 +patching file tools/flask/utils/loadpolicy.c
  22.121 +patching file tools/flask/utils/setenforce.c
  22.122 +patching file tools/fs-back/fs-backend.c
  22.123 +patching file tools/fs-back/fs-backend.h
  22.124 +patching file tools/fs-back/fs-ops.c
  22.125 +patching file tools/hotplug/Linux/Makefile
  22.126 +patching file tools/hotplug/Linux/blktap
  22.127 +patching file tools/hotplug/Linux/block
  22.128 +patching file tools/hotplug/Linux/init.d/sysconfig.xencommons
  22.129 +patching file tools/hotplug/Linux/init.d/sysconfig.xend
  22.130 +patching file tools/hotplug/Linux/init.d/xen-watchdog
  22.131 +patching file tools/hotplug/Linux/init.d/xencommons
  22.132 +patching file tools/hotplug/Linux/init.d/xend
  22.133 +patching file tools/hotplug/Linux/init.d/xendomains
  22.134 +patching file tools/hotplug/Linux/locking.sh
  22.135 +patching file tools/hotplug/Linux/network-bridge
  22.136 +patching file tools/hotplug/Linux/vif-setup
  22.137 +patching file tools/hotplug/Linux/vtpm-common.sh
  22.138 +patching file tools/hotplug/Linux/xen-backend.rules
  22.139 +patching file tools/hotplug/Linux/xen-hotplug-cleanup
  22.140 +patching file tools/hotplug/NetBSD/Makefile
  22.141 +patching file tools/hotplug/NetBSD/rc.d/xen-watchdog
  22.142 +patching file tools/hotplug/NetBSD/rc.d/xencommons
  22.143 +patching file tools/hotplug/NetBSD/rc.d/xend
  22.144 +patching file tools/hotplug/NetBSD/rc.d/xendomains
  22.145 +patching file tools/libfsimage/Rules.mk
  22.146 +patching file tools/libfsimage/common/fsimage_grub.h
  22.147 +patching file tools/libfsimage/zfs/Makefile
  22.148 +patching file tools/libfsimage/zfs/filesys.h
  22.149 +patching file tools/libfsimage/zfs/fsi_zfs.c
  22.150 +patching file tools/libfsimage/zfs/fsi_zfs.h
  22.151 +patching file tools/libfsimage/zfs/fsys_zfs.c
  22.152 +patching file tools/libfsimage/zfs/fsys_zfs.h
  22.153 +patching file tools/libfsimage/zfs/shared.h
  22.154 +patching file tools/libfsimage/zfs/zfs-include/dmu.h
  22.155 +patching file tools/libfsimage/zfs/zfs-include/dnode.h
  22.156 +patching file tools/libfsimage/zfs/zfs-include/dsl_dataset.h
  22.157 +patching file tools/libfsimage/zfs/zfs-include/dsl_dir.h
  22.158 +patching file tools/libfsimage/zfs/zfs-include/sa_impl.h
  22.159 +patching file tools/libfsimage/zfs/zfs-include/spa.h
  22.160 +patching file tools/libfsimage/zfs/zfs-include/uberblock_impl.h
  22.161 +patching file tools/libfsimage/zfs/zfs-include/vdev_impl.h
  22.162 +patching file tools/libfsimage/zfs/zfs-include/zap_impl.h
  22.163 +patching file tools/libfsimage/zfs/zfs-include/zap_leaf.h
  22.164 +patching file tools/libfsimage/zfs/zfs-include/zfs.h
  22.165 +patching file tools/libfsimage/zfs/zfs-include/zfs_acl.h
  22.166 +patching file tools/libfsimage/zfs/zfs-include/zfs_znode.h
  22.167 +patching file tools/libfsimage/zfs/zfs-include/zil.h
  22.168 +patching file tools/libfsimage/zfs/zfs-include/zio.h
  22.169 +patching file tools/libfsimage/zfs/zfs-include/zio_checksum.h
  22.170 +patching file tools/libfsimage/zfs/zfs_fletcher.c
  22.171 +patching file tools/libfsimage/zfs/zfs_lzjb.c
  22.172 +patching file tools/libfsimage/zfs/zfs_sha256.c
  22.173 +patching file tools/libxc/Makefile
  22.174 +patching file tools/libxc/ia64/xc_dom_ia64_util.c
  22.175 +patching file tools/libxc/ia64/xc_ia64.h
  22.176 +patching file tools/libxc/ia64/xc_ia64_dom_fwloader.c
  22.177 +patching file tools/libxc/ia64/xc_ia64_hvm_build.c
  22.178 +patching file tools/libxc/ia64/xc_ia64_linux_restore.c
  22.179 +patching file tools/libxc/ia64/xc_ia64_linux_save.c
  22.180 +patching file tools/libxc/ia64/xc_ia64_stubs.c
  22.181 +patching file tools/libxc/xc_acm.c
  22.182 +patching file tools/libxc/xc_core.c
  22.183 +patching file tools/libxc/xc_core.h
  22.184 +patching file tools/libxc/xc_core_ia64.c
  22.185 +patching file tools/libxc/xc_core_ia64.h
  22.186 +patching file tools/libxc/xc_core_x86.c
  22.187 +patching file tools/libxc/xc_core_x86.h
  22.188 +patching file tools/libxc/xc_cpu_hotplug.c
  22.189 +patching file tools/libxc/xc_cpufeature.h
  22.190 +patching file tools/libxc/xc_cpuid_x86.c
  22.191 +patching file tools/libxc/xc_cpupool.c
  22.192 +patching file tools/libxc/xc_csched.c
  22.193 +patching file tools/libxc/xc_csched2.c
  22.194 +patching file tools/libxc/xc_dom.h
  22.195 +patching file tools/libxc/xc_dom_binloader.c
  22.196 +patching file tools/libxc/xc_dom_boot.c
  22.197 +patching file tools/libxc/xc_dom_bzimageloader.c
  22.198 +patching file tools/libxc/xc_dom_compat_linux.c
  22.199 +patching file tools/libxc/xc_dom_core.c
  22.200 +patching file tools/libxc/xc_dom_elfloader.c
  22.201 +patching file tools/libxc/xc_dom_ia64.c
  22.202 +patching file tools/libxc/xc_dom_x86.c
  22.203 +patching file tools/libxc/xc_domain.c
  22.204 +patching file tools/libxc/xc_domain_restore.c
  22.205 +patching file tools/libxc/xc_domain_save.c
  22.206 +patching file tools/libxc/xc_evtchn.c
  22.207 +patching file tools/libxc/xc_flask.c
  22.208 +patching file tools/libxc/xc_hvm_build.c
  22.209 +patching file tools/libxc/xc_linux.c
  22.210 +patching file tools/libxc/xc_mem_event.c
  22.211 +patching file tools/libxc/xc_mem_paging.c
  22.212 +patching file tools/libxc/xc_memshr.c
  22.213 +patching file tools/libxc/xc_minios.c
  22.214 +patching file tools/libxc/xc_misc.c
  22.215 +patching file tools/libxc/xc_netbsd.c
  22.216 +patching file tools/libxc/xc_offline_page.c
  22.217 +patching file tools/libxc/xc_pagetab.c
  22.218 +patching file tools/libxc/xc_physdev.c
  22.219 +patching file tools/libxc/xc_pm.c
  22.220 +patching file tools/libxc/xc_private.c
  22.221 +patching file tools/libxc/xc_private.h
  22.222 +patching file tools/libxc/xc_ptrace.c
  22.223 +patching file tools/libxc/xc_ptrace.h
  22.224 +patching file tools/libxc/xc_ptrace_core.c
  22.225 +patching file tools/libxc/xc_resume.c
  22.226 +patching file tools/libxc/xc_sedf.c
  22.227 +patching file tools/libxc/xc_solaris.c
  22.228 +patching file tools/libxc/xc_suspend.c
  22.229 +patching file tools/libxc/xc_tbuf.c
  22.230 +patching file tools/libxc/xc_tmem.c
  22.231 +patching file tools/libxc/xenctrl.h
  22.232 +patching file tools/libxc/xenguest.h
  22.233 +patching file tools/libxc/xentoollog.h
  22.234 +patching file tools/libxc/xg_private.c
  22.235 +patching file tools/libxc/xg_private.h
  22.236 +patching file tools/libxc/xg_save_restore.h
  22.237 +patching file tools/libxc/xtl_core.c
  22.238 +patching file tools/libxc/xtl_logger_stdio.c
  22.239 +patching file tools/libxen/include/xen/api/xen_all.h
  22.240 +patching file tools/libxen/include/xen/api/xen_cpu_pool.h
  22.241 +patching file tools/libxen/include/xen/api/xen_cpu_pool_decl.h
  22.242 +patching file tools/libxen/include/xen/api/xen_host.h
  22.243 +patching file tools/libxen/include/xen/api/xen_host_cpu.h
  22.244 +patching file tools/libxen/include/xen/api/xen_vm.h
  22.245 +patching file tools/libxen/src/xen_cpu_pool.c
  22.246 +patching file tools/libxen/src/xen_host.c
  22.247 +patching file tools/libxen/src/xen_host_cpu.c
  22.248 +patching file tools/libxen/src/xen_vm.c
  22.249 +patching file tools/libxen/test/test_bindings.c
  22.250 +patching file tools/libxl/Makefile
  22.251 +patching file tools/libxl/bash-completion
  22.252 +patching file tools/libxl/libxl.c
  22.253 +patching file tools/libxl/libxl.h
  22.254 +patching file tools/libxl/libxl_bootloader.c
  22.255 +patching file tools/libxl/libxl_device.c
  22.256 +patching file tools/libxl/libxl_dom.c
  22.257 +patching file tools/libxl/libxl_exec.c
  22.258 +patching file tools/libxl/libxl_internal.c
  22.259 +patching file tools/libxl/libxl_internal.h
  22.260 +patching file tools/libxl/libxl_paths.c
  22.261 +patching file tools/libxl/libxl_utils.c
  22.262 +patching file tools/libxl/libxl_utils.h
  22.263 +patching file tools/libxl/libxl_xshelp.c
  22.264 +patching file tools/libxl/libxlu_cfg.c
  22.265 +patching file tools/libxl/libxlutil.h
  22.266 +patching file tools/libxl/xenguest.c
  22.267 +patching file tools/libxl/xl.c
  22.268 +patching file tools/libxl/xl.h
  22.269 +patching file tools/libxl/xl_cmdimpl.c
  22.270 +patching file tools/libxl/xl_cmdtable.c
  22.271 +patching file tools/memshr/interface.c
  22.272 +patching file tools/misc/Makefile
  22.273 +patching file tools/misc/xen-hptool.c
  22.274 +patching file tools/misc/xen-hvmctx.c
  22.275 +patching file tools/misc/xen-tmem-list-parse.c
  22.276 +patching file tools/misc/xend
  22.277 +patching file tools/misc/xenlockprof.c
  22.278 +patching file tools/misc/xenperf.c
  22.279 +patching file tools/misc/xenpm.c
  22.280 +patching file tools/misc/xenwatchdogd.c
  22.281 +patching file tools/ocaml/LICENSE
  22.282 +patching file tools/ocaml/Makefile
  22.283 +patching file tools/ocaml/Makefile.rules
  22.284 +patching file tools/ocaml/common.make
  22.285 +patching file tools/ocaml/libs/eventchn/META.in
  22.286 +patching file tools/ocaml/libs/eventchn/Makefile
  22.287 +patching file tools/ocaml/libs/eventchn/eventchn.ml
  22.288 +patching file tools/ocaml/libs/eventchn/eventchn.mli
  22.289 +patching file tools/ocaml/libs/eventchn/eventchn_stubs.c
  22.290 +patching file tools/ocaml/libs/log/META.in
  22.291 +patching file tools/ocaml/libs/log/Makefile
  22.292 +patching file tools/ocaml/libs/log/log.ml
  22.293 +patching file tools/ocaml/libs/log/log.mli
  22.294 +patching file tools/ocaml/libs/log/logs.ml
  22.295 +patching file tools/ocaml/libs/log/logs.mli
  22.296 +patching file tools/ocaml/libs/log/syslog.ml
  22.297 +patching file tools/ocaml/libs/log/syslog.mli
  22.298 +patching file tools/ocaml/libs/log/syslog_stubs.c
  22.299 +patching file tools/ocaml/libs/mmap/META.in
  22.300 +patching file tools/ocaml/libs/mmap/Makefile
  22.301 +patching file tools/ocaml/libs/mmap/mmap.ml
  22.302 +patching file tools/ocaml/libs/mmap/mmap.mli
  22.303 +patching file tools/ocaml/libs/mmap/mmap_stubs.c
  22.304 +patching file tools/ocaml/libs/mmap/mmap_stubs.h
  22.305 +patching file tools/ocaml/libs/uuid/META.in
  22.306 +patching file tools/ocaml/libs/uuid/Makefile
  22.307 +patching file tools/ocaml/libs/uuid/uuid.ml
  22.308 +patching file tools/ocaml/libs/uuid/uuid.mli
  22.309 +patching file tools/ocaml/libs/xb/META.in
  22.310 +patching file tools/ocaml/libs/xb/Makefile
  22.311 +patching file tools/ocaml/libs/xb/op.ml
  22.312 +patching file tools/ocaml/libs/xb/packet.ml
  22.313 +patching file tools/ocaml/libs/xb/partial.ml
  22.314 +patching file tools/ocaml/libs/xb/xb.ml
  22.315 +patching file tools/ocaml/libs/xb/xb.mli
  22.316 +patching file tools/ocaml/libs/xb/xb_stubs.c
  22.317 +patching file tools/ocaml/libs/xb/xs_ring.ml
  22.318 +patching file tools/ocaml/libs/xb/xs_ring_stubs.c
  22.319 +patching file tools/ocaml/libs/xc/META.in
  22.320 +patching file tools/ocaml/libs/xc/Makefile
  22.321 +patching file tools/ocaml/libs/xc/xc.h
  22.322 +patching file tools/ocaml/libs/xc/xc.ml
  22.323 +patching file tools/ocaml/libs/xc/xc.mli
  22.324 +patching file tools/ocaml/libs/xc/xc_cpufeature.h
  22.325 +patching file tools/ocaml/libs/xc/xc_cpuid.h
  22.326 +patching file tools/ocaml/libs/xc/xc_e820.h
  22.327 +patching file tools/ocaml/libs/xc/xc_lib.c
  22.328 +patching file tools/ocaml/libs/xc/xc_stubs.c
  22.329 +patching file tools/ocaml/libs/xl/Makefile
  22.330 +patching file tools/ocaml/libs/xl/xl.ml
  22.331 +patching file tools/ocaml/libs/xl/xl.mli
  22.332 +patching file tools/ocaml/libs/xl/xl_stubs.c
  22.333 +patching file tools/ocaml/libs/xs/META.in
  22.334 +patching file tools/ocaml/libs/xs/Makefile
  22.335 +patching file tools/ocaml/libs/xs/queueop.ml
  22.336 +patching file tools/ocaml/libs/xs/xs.ml
  22.337 +patching file tools/ocaml/libs/xs/xs.mli
  22.338 +patching file tools/ocaml/libs/xs/xsraw.ml
  22.339 +patching file tools/ocaml/libs/xs/xsraw.mli
  22.340 +patching file tools/ocaml/libs/xs/xst.ml
  22.341 +patching file tools/ocaml/libs/xs/xst.mli
  22.342 +patching file tools/ocaml/xenstored/Makefile
  22.343 +patching file tools/ocaml/xenstored/config.ml
  22.344 +patching file tools/ocaml/xenstored/connection.ml
  22.345 +patching file tools/ocaml/xenstored/connections.ml
  22.346 +patching file tools/ocaml/xenstored/define.ml
  22.347 +patching file tools/ocaml/xenstored/disk.ml
  22.348 +patching file tools/ocaml/xenstored/domain.ml
  22.349 +patching file tools/ocaml/xenstored/domains.ml
  22.350 +patching file tools/ocaml/xenstored/event.ml
  22.351 +patching file tools/ocaml/xenstored/logging.ml
  22.352 +patching file tools/ocaml/xenstored/parse_arg.ml
  22.353 +patching file tools/ocaml/xenstored/perms.ml
  22.354 +patching file tools/ocaml/xenstored/process.ml
  22.355 +patching file tools/ocaml/xenstored/quota.ml
  22.356 +patching file tools/ocaml/xenstored/stdext.ml
  22.357 +patching file tools/ocaml/xenstored/store.ml
  22.358 +patching file tools/ocaml/xenstored/symbol.ml
  22.359 +patching file tools/ocaml/xenstored/symbol.mli
  22.360 +patching file tools/ocaml/xenstored/transaction.ml
  22.361 +patching file tools/ocaml/xenstored/trie.ml
  22.362 +patching file tools/ocaml/xenstored/trie.mli
  22.363 +patching file tools/ocaml/xenstored/utils.ml
  22.364 +patching file tools/ocaml/xenstored/xenstored.conf
  22.365 +patching file tools/ocaml/xenstored/xenstored.ml
  22.366 +patching file tools/pygrub/src/ExtLinuxConf.py
  22.367 +patching file tools/pygrub/src/GrubConf.py
  22.368 +patching file tools/pygrub/src/LiloConf.py
  22.369 +patching file tools/pygrub/src/pygrub
  22.370 +patching file tools/python/xen/lowlevel/acm/acm.c
  22.371 +patching file tools/python/xen/lowlevel/checkpoint/checkpoint.h
  22.372 +patching file tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
  22.373 +patching file tools/python/xen/lowlevel/flask/flask.c
  22.374 +patching file tools/python/xen/lowlevel/xc/xc.c
  22.375 +patching file tools/python/xen/remus/device.py
  22.376 +patching file tools/python/xen/remus/netlink.py
  22.377 +patching file tools/python/xen/remus/qdisc.py
  22.378 +patching file tools/python/xen/remus/util.py
  22.379 +patching file tools/python/xen/remus/vif.py
  22.380 +patching file tools/python/xen/remus/vm.py
  22.381 +patching file tools/python/xen/util/auxbin.py
  22.382 +patching file tools/python/xen/util/blkif.py
  22.383 +patching file tools/python/xen/util/diagnose.py
  22.384 +patching file tools/python/xen/util/pci.py
  22.385 +patching file tools/python/xen/util/sxputils.py
  22.386 +patching file tools/python/xen/web/tcp.py
  22.387 +patching file tools/python/xen/xend/XendAPI.py
  22.388 +patching file tools/python/xen/xend/XendBootloader.py
  22.389 +patching file tools/python/xen/xend/XendCPUPool.py
  22.390 +patching file tools/python/xen/xend/XendCheckpoint.py
  22.391 +patching file tools/python/xen/xend/XendConfig.py
  22.392 +patching file tools/python/xen/xend/XendConstants.py
  22.393 +patching file tools/python/xen/xend/XendDomain.py
  22.394 +patching file tools/python/xen/xend/XendDomainInfo.py
  22.395 +patching file tools/python/xen/xend/XendError.py
  22.396 +patching file tools/python/xen/xend/XendNode.py
  22.397 +patching file tools/python/xen/xend/XendOptions.py
  22.398 +patching file tools/python/xen/xend/XendVMMetrics.py
  22.399 +patching file tools/python/xen/xend/balloon.py
  22.400 +patching file tools/python/xen/xend/image.py
  22.401 +patching file tools/python/xen/xend/server/BlktapController.py
  22.402 +patching file tools/python/xen/xend/server/SrvDomain.py
  22.403 +patching file tools/python/xen/xend/server/SrvServer.py
  22.404 +patching file tools/python/xen/xend/server/XMLRPCServer.py
  22.405 +patching file tools/python/xen/xend/sxp.py
  22.406 +patching file tools/python/xen/xm/console.py
  22.407 +patching file tools/python/xen/xm/create.dtd
  22.408 +patching file tools/python/xen/xm/create.py
  22.409 +patching file tools/python/xen/xm/main.py
  22.410 +patching file tools/python/xen/xm/pool-create.py
  22.411 +patching file tools/python/xen/xm/pool-new.py
  22.412 +patching file tools/python/xen/xm/pool.py
  22.413 +patching file tools/python/xen/xm/xenapi_create.py
  22.414 +patching file tools/remus/kmod/Makefile
  22.415 +patching file tools/remus/kmod/ebt_imq.c
  22.416 +patching file tools/remus/kmod/ebt_imq.h
  22.417 +patching file tools/remus/kmod/sch_queue.c
  22.418 +patching file tools/remus/remus
  22.419 +patching file tools/security/secpol_tool.c
  22.420 +patching file tools/xcutils/lsevtchn.c
  22.421 +patching file tools/xcutils/readnotes.c
  22.422 +patching file tools/xcutils/xc_restore.c
  22.423 +patching file tools/xcutils/xc_save.c
  22.424 +patching file tools/xenmon/setmask.c
  22.425 +patching file tools/xenmon/xenbaked.c
  22.426 +patching file tools/xenpaging/file_ops.c
  22.427 +patching file tools/xenpaging/policy.h
  22.428 +patching file tools/xenpaging/policy_default.c
  22.429 +patching file tools/xenpaging/xc.c
  22.430 +patching file tools/xenpaging/xc.h
  22.431 +patching file tools/xenpaging/xenpaging.c
  22.432 +patching file tools/xenpaging/xenpaging.h
  22.433 +patching file tools/xenstat/libxenstat/src/xenstat.c
  22.434 +patching file tools/xenstat/libxenstat/src/xenstat_linux.c
  22.435 +patching file tools/xenstat/libxenstat/src/xenstat_priv.h
  22.436 +patching file tools/xenstore/Makefile
  22.437 +patching file tools/xenstore/xenstored_domain.c
  22.438 +patching file tools/xenstore/xs.c
  22.439 +patching file tools/xenstore/xs.h
  22.440 +patching file tools/xentrace/Makefile
  22.441 +patching file tools/xentrace/formats
  22.442 +patching file tools/xentrace/setsize.c
  22.443 +patching file tools/xentrace/xenctx.c
  22.444 +patching file tools/xentrace/xentrace.c
  22.445 +patching file tools/xm-test/configure.ac
  22.446 +patching file tools/xm-test/grouptest/cpupool
  22.447 +patching file tools/xm-test/lib/XmTestLib/NetConfig.py
  22.448 +patching file tools/xm-test/lib/XmTestLib/XenDomain.py
  22.449 +patching file tools/xm-test/runtest.sh
  22.450 +patching file tools/xm-test/tests/Makefile.am
  22.451 +patching file tools/xm-test/tests/cpupool/01_cpupool_basic_pos.py
  22.452 +patching file tools/xm-test/tests/cpupool/02_cpupool_manage_pos.py
  22.453 +patching file tools/xm-test/tests/cpupool/03_cpupool_domain.py
  22.454 +patching file tools/xm-test/tests/cpupool/04_cpupool_migrate.py
  22.455 +patching file tools/xm-test/tests/cpupool/Makefile.am
  22.456 +patching file tools/xm-test/tests/cpupool/pool1.cfg
  22.457 +patching file tools/xm-test/tests/cpupool/pools.py
  22.458 +patching file tools/xm-test/tests/xapi/20_xapi-cpu_pool_basic.py
  22.459 +patching file tools/xm-test/tests/xapi/Makefile.am
  22.460 +patching file unmodified_drivers/linux-2.6/overrides.mk
  22.461 +patching file xen/Makefile
  22.462 +patching file xen/Rules.mk
  22.463 +Hunk #1 FAILED at 8.
  22.464 +Hunk #2 FAILED at 53.
  22.465 +Hunk #3 succeeded at 85 (offset 3 lines).
  22.466 +2 out of 3 hunks FAILED -- saving rejects to file xen/Rules.mk.rej
  22.467 +patching file xen/arch/ia64/linux-xen/perfmon.c
  22.468 +patching file xen/arch/ia64/linux-xen/smp.c
  22.469 +patching file xen/arch/ia64/linux-xen/smpboot.c
  22.470 +patching file xen/arch/ia64/vmx/vmmu.c
  22.471 +patching file xen/arch/ia64/vmx/vmx_support.c
  22.472 +patching file xen/arch/ia64/xen/dom0_ops.c
  22.473 +patching file xen/arch/ia64/xen/dom_fw_common.c
  22.474 +patching file xen/arch/ia64/xen/dom_fw_domu.c
  22.475 +patching file xen/arch/ia64/xen/domain.c
  22.476 +patching file xen/arch/ia64/xen/irq.c
  22.477 +patching file xen/arch/ia64/xen/machine_kexec.c
  22.478 +patching file xen/arch/ia64/xen/mm.c
  22.479 +patching file xen/arch/ia64/xen/xen.lds.S
  22.480 +patching file xen/arch/ia64/xen/xensetup.c
  22.481 +patching file xen/arch/x86/Makefile
  22.482 +Hunk #3 FAILED at 58.
  22.483 +1 out of 3 hunks FAILED -- saving rejects to file xen/arch/x86/Makefile.rej
  22.484 +patching file xen/arch/x86/acpi/boot.c
  22.485 +patching file xen/arch/x86/acpi/cpu_idle.c
  22.486 +patching file xen/arch/x86/acpi/cpufreq/cpufreq.c
  22.487 +patching file xen/arch/x86/acpi/cpufreq/powernow.c
  22.488 +patching file xen/arch/x86/acpi/power.c
  22.489 +patching file xen/arch/x86/acpi/suspend.c
  22.490 +patching file xen/arch/x86/acpi/wakeup_prot.S
  22.491 +patching file xen/arch/x86/apic.c
  22.492 +patching file xen/arch/x86/boot/Makefile
  22.493 +patching file xen/arch/x86/boot/build32.mk
  22.494 +patching file xen/arch/x86/boot/cmdline.S
  22.495 +patching file xen/arch/x86/boot/head.S
  22.496 +patching file xen/arch/x86/boot/reloc.c
  22.497 +patching file xen/arch/x86/boot/x86_32.S
  22.498 +patching file xen/arch/x86/boot/x86_64.S
  22.499 +patching file xen/arch/x86/cpu/amd.c
  22.500 +patching file xen/arch/x86/cpu/amd.h
  22.501 +patching file xen/arch/x86/cpu/centaur.c
  22.502 +patching file xen/arch/x86/cpu/common.c
  22.503 +patching file xen/arch/x86/cpu/cpu.h
  22.504 +patching file xen/arch/x86/cpu/intel.c
  22.505 +patching file xen/arch/x86/cpu/intel_cacheinfo.c
  22.506 +patching file xen/arch/x86/cpu/mcheck/Makefile
  22.507 +patching file xen/arch/x86/cpu/mcheck/amd_f10.c
  22.508 +patching file xen/arch/x86/cpu/mcheck/amd_k8.c
  22.509 +patching file xen/arch/x86/cpu/mcheck/amd_nonfatal.c
  22.510 +patching file xen/arch/x86/cpu/mcheck/k7.c
  22.511 +patching file xen/arch/x86/cpu/mcheck/mce.c
  22.512 +patching file xen/arch/x86/cpu/mcheck/mce.h
  22.513 +patching file xen/arch/x86/cpu/mcheck/mce_intel.c
  22.514 +patching file xen/arch/x86/cpu/mcheck/mctelem.c
  22.515 +patching file xen/arch/x86/cpu/mcheck/non-fatal.c
  22.516 +patching file xen/arch/x86/cpu/mcheck/vmce.c
  22.517 +patching file xen/arch/x86/cpu/mcheck/x86_mca.h
  22.518 +patching file xen/arch/x86/cpu/mtrr/generic.c
  22.519 +patching file xen/arch/x86/cpu/mtrr/main.c
  22.520 +patching file xen/arch/x86/cpu/mtrr/mtrr.h
  22.521 +patching file xen/arch/x86/cpu/mtrr/state.c
  22.522 +patching file xen/arch/x86/crash.c
  22.523 +patching file xen/arch/x86/domain.c
  22.524 +patching file xen/arch/x86/domain_build.c
  22.525 +patching file xen/arch/x86/domctl.c
  22.526 +patching file xen/arch/x86/flushtlb.c
  22.527 +patching file xen/arch/x86/genapic/bigsmp.c
  22.528 +patching file xen/arch/x86/genapic/default.c
  22.529 +patching file xen/arch/x86/genapic/summit.c
  22.530 +patching file xen/arch/x86/genapic/x2apic.c
  22.531 +patching file xen/arch/x86/hpet.c
  22.532 +patching file xen/arch/x86/hvm/Makefile
  22.533 +patching file xen/arch/x86/hvm/emulate.c
  22.534 +patching file xen/arch/x86/hvm/hvm.c
  22.535 +patching file xen/arch/x86/hvm/io.c
  22.536 +patching file xen/arch/x86/hvm/irq.c
  22.537 +patching file xen/arch/x86/hvm/mtrr.c
  22.538 +patching file xen/arch/x86/hvm/rtc.c
  22.539 +patching file xen/arch/x86/hvm/save.c
  22.540 +patching file xen/arch/x86/hvm/svm/Makefile
  22.541 +patching file xen/arch/x86/hvm/svm/asid.c
  22.542 +patching file xen/arch/x86/hvm/svm/emulate.c
  22.543 +patching file xen/arch/x86/hvm/svm/entry.S
  22.544 +patching file xen/arch/x86/hvm/svm/intr.c
  22.545 +patching file xen/arch/x86/hvm/svm/svm.c
  22.546 +Hunk #3 FAILED at 54.
  22.547 +Hunk #4 succeeded at 70 (offset 4 lines).
  22.548 +Hunk #5 succeeded at 108 (offset 4 lines).
  22.549 +Hunk #6 succeeded at 217 (offset 4 lines).
  22.550 +Hunk #7 succeeded at 263 (offset 4 lines).
  22.551 +Hunk #8 succeeded at 642 (offset 4 lines).
  22.552 +Hunk #9 succeeded at 681 (offset 4 lines).
  22.553 +Hunk #10 succeeded at 747 (offset 4 lines).
  22.554 +Hunk #11 succeeded at 818 (offset 4 lines).
  22.555 +Hunk #12 succeeded at 934 (offset 4 lines).
  22.556 +Hunk #13 succeeded at 1032 (offset 4 lines).
  22.557 +Hunk #14 succeeded at 1059 (offset 4 lines).
  22.558 +Hunk #15 succeeded at 1068 (offset 4 lines).
  22.559 +Hunk #16 succeeded at 1128 (offset 4 lines).
  22.560 +Hunk #17 succeeded at 1179 (offset 4 lines).
  22.561 +Hunk #18 succeeded at 1206 (offset 4 lines).
  22.562 +Hunk #19 succeeded at 1218 (offset 4 lines).
  22.563 +Hunk #20 succeeded at 1287 (offset 4 lines).
  22.564 +Hunk #21 succeeded at 1335 (offset 4 lines).
  22.565 +Hunk #22 succeeded at 1354 (offset 4 lines).
  22.566 +Hunk #23 succeeded at 1381 (offset 4 lines).
  22.567 +Hunk #24 FAILED at 1489.
  22.568 +Hunk #25 succeeded at 1543 (offset 12 lines).
  22.569 +Hunk #26 succeeded at 1588 (offset 12 lines).
  22.570 +2 out of 26 hunks FAILED -- saving rejects to file xen/arch/x86/hvm/svm/svm.c.rej
  22.571 +patching file xen/arch/x86/hvm/svm/vmcb.c
  22.572 +patching file xen/arch/x86/hvm/svm/vpmu.c
  22.573 +patching file xen/arch/x86/hvm/vioapic.c
  22.574 +patching file xen/arch/x86/hvm/viridian.c
  22.575 +patching file xen/arch/x86/hvm/vlapic.c
  22.576 +patching file xen/arch/x86/hvm/vmsi.c
  22.577 +patching file xen/arch/x86/hvm/vmx/Makefile
  22.578 +patching file xen/arch/x86/hvm/vmx/entry.S
  22.579 +patching file xen/arch/x86/hvm/vmx/vmcs.c
  22.580 +patching file xen/arch/x86/hvm/vmx/vmx.c
  22.581 +Hunk #1 succeeded at 53 with fuzz 2.
  22.582 +Hunk #2 succeeded at 74 (offset 4 lines).
  22.583 +Hunk #3 succeeded at 83 (offset 4 lines).
  22.584 +Hunk #4 succeeded at 100 (offset 4 lines).
  22.585 +Hunk #5 succeeded at 152 (offset 4 lines).
  22.586 +Hunk #6 succeeded at 168 (offset 4 lines).
  22.587 +Hunk #7 succeeded at 239 (offset 4 lines).
  22.588 +Hunk #8 succeeded at 272 (offset 4 lines).
  22.589 +Hunk #9 succeeded at 346 (offset 4 lines).
  22.590 +Hunk #10 succeeded at 677 (offset 4 lines).
  22.591 +Hunk #11 succeeded at 1215 (offset 4 lines).
  22.592 +Hunk #12 succeeded at 1233 (offset 4 lines).
  22.593 +Hunk #13 succeeded at 1378 (offset 4 lines).
  22.594 +Hunk #14 succeeded at 1412 (offset 4 lines).
  22.595 +Hunk #15 succeeded at 1717 (offset 4 lines).
  22.596 +Hunk #16 succeeded at 1812 (offset 4 lines).
  22.597 +Hunk #17 succeeded at 1856 (offset 4 lines).
  22.598 +Hunk #18 succeeded at 1947 (offset 4 lines).
  22.599 +Hunk #19 succeeded at 1987 (offset 4 lines).
  22.600 +Hunk #20 succeeded at 2002 (offset 4 lines).
  22.601 +Hunk #21 succeeded at 2090 (offset 4 lines).
  22.602 +Hunk #22 succeeded at 2149 (offset 4 lines).
  22.603 +Hunk #23 FAILED at 2409.
  22.604 +Hunk #24 succeeded at 2570 (offset 17 lines).
  22.605 +Hunk #25 succeeded at 2614 (offset 17 lines).
  22.606 +1 out of 25 hunks FAILED -- saving rejects to file xen/arch/x86/hvm/vmx/vmx.c.rej
  22.607 +patching file xen/arch/x86/hvm/vmx/vpmu.c
  22.608 +patching file xen/arch/x86/hvm/vmx/vpmu_core2.c
  22.609 +patching file xen/arch/x86/hvm/vpmu.c
  22.610 +patching file xen/arch/x86/hvm/vpt.c
  22.611 +patching file xen/arch/x86/i8259.c
  22.612 +patching file xen/arch/x86/io_apic.c
  22.613 +patching file xen/arch/x86/irq.c
  22.614 +patching file xen/arch/x86/microcode.c
  22.615 +patching file xen/arch/x86/microcode_amd.c
  22.616 +patching file xen/arch/x86/microcode_intel.c
  22.617 +patching file xen/arch/x86/mm.c
  22.618 +patching file xen/arch/x86/mm/Makefile
  22.619 +patching file xen/arch/x86/mm/hap/hap.c
  22.620 +patching file xen/arch/x86/mm/hap/p2m-ept.c
  22.621 +patching file xen/arch/x86/mm/hap/private.h
  22.622 +patching file xen/arch/x86/mm/mem_event.c
  22.623 +patching file xen/arch/x86/mm/mem_sharing.c
  22.624 +patching file xen/arch/x86/mm/p2m.c
  22.625 +patching file xen/arch/x86/mm/paging.c
  22.626 +patching file xen/arch/x86/mm/shadow/common.c
  22.627 +patching file xen/arch/x86/mm/shadow/multi.c
  22.628 +patching file xen/arch/x86/mm/shadow/multi.h
  22.629 +patching file xen/arch/x86/mm/shadow/private.h
  22.630 +patching file xen/arch/x86/mpparse.c
  22.631 +patching file xen/arch/x86/msi.c
  22.632 +patching file xen/arch/x86/nmi.c
  22.633 +patching file xen/arch/x86/numa.c
  22.634 +patching file xen/arch/x86/oprofile/nmi_int.c
  22.635 +patching file xen/arch/x86/oprofile/op_model_athlon.c
  22.636 +patching file xen/arch/x86/oprofile/op_model_p4.c
  22.637 +patching file xen/arch/x86/oprofile/op_model_ppro.c
  22.638 +patching file xen/arch/x86/oprofile/op_x86_model.h
  22.639 +patching file xen/arch/x86/percpu.c
  22.640 +patching file xen/arch/x86/physdev.c
  22.641 +patching file xen/arch/x86/platform_hypercall.c
  22.642 +patching file xen/arch/x86/setup.c
  22.643 +Hunk #3 succeeded at 76 (offset 7 lines).
  22.644 +Hunk #4 succeeded at 110 (offset 7 lines).
  22.645 +Hunk #5 succeeded at 154 (offset 7 lines).
  22.646 +Hunk #6 succeeded at 189 (offset 7 lines).
  22.647 +Hunk #7 succeeded at 419 (offset 7 lines).
  22.648 +Hunk #8 succeeded at 573 (offset 7 lines).
  22.649 +Hunk #9 succeeded at 758 (offset 7 lines).
  22.650 +Hunk #10 succeeded at 833 (offset 7 lines).
  22.651 +Hunk #11 succeeded at 908 (offset 7 lines).
  22.652 +Hunk #12 succeeded at 916 (offset 7 lines).
  22.653 +Hunk #13 succeeded at 937 (offset 7 lines).
  22.654 +Hunk #14 FAILED at 942.
  22.655 +Hunk #15 succeeded at 1006 (offset 13 lines).
  22.656 +Hunk #16 succeeded at 1098 (offset 13 lines).
  22.657 +Hunk #17 succeeded at 1140 (offset 13 lines).
  22.658 +Hunk #18 succeeded at 1154 (offset 13 lines).
  22.659 +Hunk #19 succeeded at 1162 (offset 13 lines).
  22.660 +1 out of 19 hunks FAILED -- saving rejects to file xen/arch/x86/setup.c.rej
  22.661 +patching file xen/arch/x86/shutdown.c
  22.662 +patching file xen/arch/x86/smp.c
  22.663 +patching file xen/arch/x86/smpboot.c
  22.664 +patching file xen/arch/x86/srat.c
  22.665 +patching file xen/arch/x86/string.c
  22.666 +patching file xen/arch/x86/sysctl.c
  22.667 +patching file xen/arch/x86/tboot.c
  22.668 +patching file xen/arch/x86/time.c
  22.669 +patching file xen/arch/x86/traps.c
  22.670 +Hunk #15 succeeded at 3121 (offset 5 lines).
  22.671 +Hunk #16 succeeded at 3271 (offset 5 lines).
  22.672 +Hunk #17 succeeded at 3314 (offset 5 lines).
  22.673 +patching file xen/arch/x86/x86_32/asm-offsets.c
  22.674 +patching file xen/arch/x86/x86_32/domain_page.c
  22.675 +patching file xen/arch/x86/x86_32/entry.S
  22.676 +Reversed (or previously applied) patch detected!  Assume -R? [n] 
  22.677 +Apply anyway? [n] 
  22.678 +Skipping patch.
  22.679 +2 out of 2 hunks ignored -- saving rejects to file xen/arch/x86/x86_32/entry.S.rej
  22.680 +patching file xen/arch/x86/x86_32/supervisor_mode_kernel.S
  22.681 +patching file xen/arch/x86/x86_32/traps.c
  22.682 +patching file xen/arch/x86/x86_64/asm-offsets.c
  22.683 +patching file xen/arch/x86/x86_64/compat/entry.S
  22.684 +patching file xen/arch/x86/x86_64/compat/traps.c
  22.685 +patching file xen/arch/x86/x86_64/compat_kexec.S
  22.686 +patching file xen/arch/x86/x86_64/entry.S
  22.687 +Hunk #1 succeeded at 24 with fuzz 2 (offset 12 lines).
  22.688 +Hunk #2 succeeded at 439 (offset 16 lines).
  22.689 +Hunk #3 succeeded at 621 (offset 22 lines).
  22.690 +patching file xen/arch/x86/x86_64/mm.c
  22.691 +patching file xen/arch/x86/x86_64/mmconfig-shared.c
  22.692 +patching file xen/arch/x86/x86_64/mmconfig_64.c
  22.693 +patching file xen/arch/x86/x86_emulate/x86_emulate.c
  22.694 +patching file xen/arch/x86/xen.lds.S
  22.695 +patching file xen/common/Makefile
  22.696 +patching file xen/common/compat/memory.c
  22.697 +patching file xen/common/cpu.c
  22.698 +patching file xen/common/cpupool.c
  22.699 +patching file xen/common/decompress.c
  22.700 +patching file xen/common/domain.c
  22.701 +Hunk #9 succeeded at 501 with fuzz 2 (offset 9 lines).
  22.702 +Hunk #10 succeeded at 517 (offset 9 lines).
  22.703 +Hunk #11 succeeded at 548 (offset 9 lines).
  22.704 +Hunk #12 succeeded at 609 (offset 9 lines).
  22.705 +Hunk #13 succeeded at 618 (offset 9 lines).
  22.706 +Hunk #14 succeeded at 869 (offset 9 lines).
  22.707 +Hunk #15 succeeded at 920 (offset 9 lines).
  22.708 +patching file xen/common/domctl.c
  22.709 +patching file xen/common/event_channel.c
  22.710 +patching file xen/common/gdbstub.c
  22.711 +patching file xen/common/grant_table.c
  22.712 +patching file xen/common/hvm/save.c
  22.713 +patching file xen/common/kernel.c
  22.714 +patching file xen/common/kexec.c
  22.715 +patching file xen/common/keyhandler.c
  22.716 +patching file xen/common/libelf/libelf-loader.c
  22.717 +patching file xen/common/libelf/libelf-private.h
  22.718 +patching file xen/common/libelf/libelf-relocate.c
  22.719 +patching file xen/common/memory.c
  22.720 +patching file xen/common/notifier.c
  22.721 +patching file xen/common/page_alloc.c
  22.722 +patching file xen/common/perfc.c
  22.723 +patching file xen/common/radix-tree.c
  22.724 +patching file xen/common/rcupdate.c
  22.725 +patching file xen/common/sched_credit.c
  22.726 +Hunk #38 succeeded at 1379 with fuzz 1 (offset 27 lines).
  22.727 +Hunk #39 succeeded at 1421 (offset 31 lines).
  22.728 +Hunk #40 succeeded at 1441 (offset 31 lines).
  22.729 +Hunk #41 succeeded at 1454 (offset 31 lines).
  22.730 +Hunk #42 succeeded at 1476 (offset 31 lines).
  22.731 +Hunk #43 succeeded at 1549 (offset 31 lines).
  22.732 +patching file xen/common/sched_credit2.c
  22.733 +patching file xen/common/sched_sedf.c
  22.734 +patching file xen/common/schedule.c
  22.735 +Hunk #27 succeeded at 1165 with fuzz 1.
  22.736 +patching file xen/common/shutdown.c
  22.737 +patching file xen/common/softirq.c
  22.738 +patching file xen/common/spinlock.c
  22.739 +patching file xen/common/stop_machine.c
  22.740 +patching file xen/common/sysctl.c
  22.741 +patching file xen/common/tasklet.c
  22.742 +patching file xen/common/time.c
  22.743 +patching file xen/common/timer.c
  22.744 +patching file xen/common/tmem.c
  22.745 +patching file xen/common/tmem_xen.c
  22.746 +patching file xen/common/trace.c
  22.747 +patching file xen/common/unlzo.c
  22.748 +patching file xen/drivers/acpi/numa.c
  22.749 +patching file xen/drivers/acpi/pmstat.c
  22.750 +patching file xen/drivers/acpi/tables.c
  22.751 +patching file xen/drivers/char/console.c
  22.752 +Hunk #3 succeeded at 610 (offset 17 lines).
  22.753 +Hunk #4 succeeded at 634 (offset 17 lines).
  22.754 +patching file xen/drivers/char/ns16550.c
  22.755 +patching file xen/drivers/cpufreq/cpufreq.c
  22.756 +patching file xen/drivers/cpufreq/cpufreq_misc_governors.c
  22.757 +patching file xen/drivers/cpufreq/cpufreq_ondemand.c
  22.758 +patching file xen/drivers/cpufreq/utility.c
  22.759 +patching file xen/drivers/passthrough/amd/iommu_acpi.c
  22.760 +patching file xen/drivers/passthrough/amd/iommu_init.c
  22.761 +patching file xen/drivers/passthrough/amd/iommu_intr.c
  22.762 +patching file xen/drivers/passthrough/amd/iommu_map.c
  22.763 +patching file xen/drivers/passthrough/amd/pci_amd_iommu.c
  22.764 +patching file xen/drivers/passthrough/io.c
  22.765 +patching file xen/drivers/passthrough/iommu.c
  22.766 +patching file xen/drivers/passthrough/pci.c
  22.767 +patching file xen/drivers/passthrough/vtd/dmar.c
  22.768 +patching file xen/drivers/passthrough/vtd/dmar.h
  22.769 +patching file xen/drivers/passthrough/vtd/extern.h
  22.770 +patching file xen/drivers/passthrough/vtd/ia64/ats.c
  22.771 +patching file xen/drivers/passthrough/vtd/ia64/vtd.c
  22.772 +patching file xen/drivers/passthrough/vtd/intremap.c
  22.773 +patching file xen/drivers/passthrough/vtd/iommu.c
  22.774 +patching file xen/drivers/passthrough/vtd/qinval.c
  22.775 +patching file xen/drivers/passthrough/vtd/utils.c
  22.776 +patching file xen/drivers/passthrough/vtd/vtd.h
  22.777 +patching file xen/drivers/passthrough/vtd/x86/ats.c
  22.778 +patching file xen/drivers/passthrough/vtd/x86/vtd.c
  22.779 +patching file xen/include/acpi/actbl1.h
  22.780 +patching file xen/include/acpi/cpufreq/cpufreq.h
  22.781 +patching file xen/include/acpi/cpufreq/processor_perf.h
  22.782 +patching file xen/include/asm-ia64/dom_fw_common.h
  22.783 +patching file xen/include/asm-ia64/dom_fw_domu.h
  22.784 +patching file xen/include/asm-ia64/domain.h
  22.785 +patching file xen/include/asm-ia64/linux-xen/asm/processor.h
  22.786 +patching file xen/include/asm-ia64/linux-xen/asm/ptrace.h
  22.787 +patching file xen/include/asm-ia64/linux-xen/asm/smp.h
  22.788 +patching file xen/include/asm-ia64/linux-xen/linux/cpu.h
  22.789 +patching file xen/include/asm-ia64/p2m_entry.h
  22.790 +patching file xen/include/asm-ia64/perfc.h
  22.791 +patching file xen/include/asm-x86/acpi.h
  22.792 +patching file xen/include/asm-x86/amd.h
  22.793 +patching file xen/include/asm-x86/apic.h
  22.794 +patching file xen/include/asm-x86/bzimage.h
  22.795 +patching file xen/include/asm-x86/config.h
  22.796 +patching file xen/include/asm-x86/cpufeature.h
  22.797 +patching file xen/include/asm-x86/current.h
  22.798 +patching file xen/include/asm-x86/debugger.h
  22.799 +Hunk #1 succeeded at 84 (offset 16 lines).
  22.800 +patching file xen/include/asm-x86/desc.h
  22.801 +patching file xen/include/asm-x86/domain.h
  22.802 +patching file xen/include/asm-x86/genapic.h
  22.803 +patching file xen/include/asm-x86/guest_pt.h
  22.804 +patching file xen/include/asm-x86/hardirq.h
  22.805 +patching file xen/include/asm-x86/hvm/domain.h
  22.806 +patching file xen/include/asm-x86/hvm/emulate.h
  22.807 +patching file xen/include/asm-x86/hvm/hvm.h
  22.808 +patching file xen/include/asm-x86/hvm/io.h
  22.809 +patching file xen/include/asm-x86/hvm/iommu.h
  22.810 +patching file xen/include/asm-x86/hvm/irq.h
  22.811 +patching file xen/include/asm-x86/hvm/support.h
  22.812 +patching file xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
  22.813 +patching file xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
  22.814 +patching file xen/include/asm-x86/hvm/svm/svm.h
  22.815 +patching file xen/include/asm-x86/hvm/svm/vmcb.h
  22.816 +patching file xen/include/asm-x86/hvm/trace.h
  22.817 +patching file xen/include/asm-x86/hvm/vcpu.h
  22.818 +patching file xen/include/asm-x86/hvm/vlapic.h
  22.819 +patching file xen/include/asm-x86/hvm/vmx/vmcs.h
  22.820 +patching file xen/include/asm-x86/hvm/vmx/vmx.h
  22.821 +patching file xen/include/asm-x86/hvm/vmx/vpmu.h
  22.822 +patching file xen/include/asm-x86/hvm/vpmu.h
  22.823 +patching file xen/include/asm-x86/io_apic.h
  22.824 +patching file xen/include/asm-x86/irq.h
  22.825 +patching file xen/include/asm-x86/mach-default/mach_wakecpu.h
  22.826 +patching file xen/include/asm-x86/mach-generic/mach_apic.h
  22.827 +patching file xen/include/asm-x86/mce.h
  22.828 +patching file xen/include/asm-x86/mem_sharing.h
  22.829 +patching file xen/include/asm-x86/mm.h
  22.830 +patching file xen/include/asm-x86/mpspec.h
  22.831 +patching file xen/include/asm-x86/msi.h
  22.832 +patching file xen/include/asm-x86/msr-index.h
  22.833 +patching file xen/include/asm-x86/msr.h
  22.834 +patching file xen/include/asm-x86/mtrr.h
  22.835 +patching file xen/include/asm-x86/numa.h
  22.836 +patching file xen/include/asm-x86/p2m.h
  22.837 +patching file xen/include/asm-x86/page.h
  22.838 +patching file xen/include/asm-x86/paging.h
  22.839 +patching file xen/include/asm-x86/percpu.h
  22.840 +patching file xen/include/asm-x86/perfc.h
  22.841 +patching file xen/include/asm-x86/processor.h
  22.842 +patching file xen/include/asm-x86/regs.h
  22.843 +patching file xen/include/asm-x86/setup.h
  22.844 +patching file xen/include/asm-x86/smp.h
  22.845 +patching file xen/include/asm-x86/string.h
  22.846 +patching file xen/include/asm-x86/time.h
  22.847 +patching file xen/include/asm-x86/traps.h
  22.848 +patching file xen/include/asm-x86/x86_32/asm_defns.h
  22.849 +patching file xen/include/asm-x86/x86_32/page.h
  22.850 +patching file xen/include/asm-x86/x86_64/asm_defns.h
  22.851 +patching file xen/include/asm-x86/x86_64/page.h
  22.852 +patching file xen/include/asm-x86/x86_64/uaccess.h
  22.853 +patching file xen/include/asm-x86/xenoprof.h
  22.854 +patching file xen/include/public/arch-x86/xen-mca.h
  22.855 +patching file xen/include/public/domctl.h
  22.856 +patching file xen/include/public/features.h
  22.857 +patching file xen/include/public/hvm/hvm_op.h
  22.858 +patching file xen/include/public/hvm/params.h
  22.859 +patching file xen/include/public/io/ring.h
  22.860 +patching file xen/include/public/io/xs_wire.h
  22.861 +patching file xen/include/public/mem_event.h
  22.862 +patching file xen/include/public/memory.h
  22.863 +patching file xen/include/public/sched.h
  22.864 +patching file xen/include/public/sysctl.h
  22.865 +patching file xen/include/public/trace.h
  22.866 +patching file xen/include/public/xen.h
  22.867 +patching file xen/include/xen/acpi.h
  22.868 +patching file xen/include/xen/compat.h
  22.869 +patching file xen/include/xen/cpu.h
  22.870 +patching file xen/include/xen/cpuidle.h
  22.871 +patching file xen/include/xen/cpumask.h
  22.872 +patching file xen/include/xen/decompress.h
  22.873 +patching file xen/include/xen/domain.h
  22.874 +patching file xen/include/xen/event.h
  22.875 +patching file xen/include/xen/gdbstub.h
  22.876 +patching file xen/include/xen/hvm/irq.h
  22.877 +patching file xen/include/xen/init.h
  22.878 +patching file xen/include/xen/iommu.h
  22.879 +patching file xen/include/xen/irq.h
  22.880 +patching file xen/include/xen/irq_cpustat.h
  22.881 +patching file xen/include/xen/kexec.h
  22.882 +patching file xen/include/xen/lib.h
  22.883 +Hunk #2 succeeded at 128 with fuzz 2 (offset 12 lines).
  22.884 +patching file xen/include/xen/libelf.h
  22.885 +patching file xen/include/xen/mm.h
  22.886 +patching file xen/include/xen/nodemask.h
  22.887 +patching file xen/include/xen/notifier.h
  22.888 +patching file xen/include/xen/pci_regs.h
  22.889 +patching file xen/include/xen/rcupdate.h
  22.890 +patching file xen/include/xen/sched-if.h
  22.891 +patching file xen/include/xen/sched.h
  22.892 +patching file xen/include/xen/smp.h
  22.893 +patching file xen/include/xen/softirq.h
  22.894 +patching file xen/include/xen/spinlock.h
  22.895 +patching file xen/include/xen/tasklet.h
  22.896 +patching file xen/include/xen/timer.h
  22.897 +patching file xen/include/xen/tmem.h
  22.898 +patching file xen/include/xen/tmem_xen.h
  22.899 +patching file xen/include/xen/trace.h
  22.900 +patching file xen/include/xlat.lst
  22.901 +patching file xen/xsm/flask/avc.c
  22.902 +patching file xen/xsm/flask/flask_op.c
    23.1 --- a/stubdom/Makefile	Wed Jun 09 19:53:32 2010 -0700
    23.2 +++ b/stubdom/Makefile	Fri Jul 16 17:16:06 2010 -0700
    23.3 @@ -102,6 +102,8 @@ newlib-$(NEWLIB_VERSION): newlib-$(NEWLI
    23.4  	patch -d $@ -p0 < newlib.patch
    23.5  	patch -d $@ -p0 < newlib-chk.patch
    23.6  	patch -d $@ -p1 < newlib-stdint-size_max-fix-from-1.17.0.patch
    23.7 +	find $@ -type f | xargs perl -i.bak \
    23.8 +		-pe 's/\b_(tzname|daylight|timezone)\b/$$1/g'
    23.9  	touch $@
   23.10  
   23.11  NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libc.a
    24.1 --- a/stubdom/grub/kexec.c	Wed Jun 09 19:53:32 2010 -0700
    24.2 +++ b/stubdom/grub/kexec.c	Fri Jul 16 17:16:06 2010 -0700
    24.3 @@ -50,7 +50,7 @@ static unsigned long *pages;
    24.4  static unsigned long *pages_mfns;
    24.5  static unsigned long allocated;
    24.6  
    24.7 -int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
    24.8 +int pin_table(xc_interface *xc_handle, unsigned int type, unsigned long mfn,
    24.9                domid_t dom);
   24.10  
   24.11  /* We need mfn to appear as target_pfn, so exchange with the MFN there */
   24.12 @@ -109,7 +109,7 @@ void kexec(void *kernel, long kernel_siz
   24.13      int rc;
   24.14      domid_t domid = DOMID_SELF;
   24.15      xen_pfn_t pfn;
   24.16 -    int xc_handle;
   24.17 +    xc_interface *xc_handle;
   24.18      unsigned long i;
   24.19      void *seg;
   24.20      xen_pfn_t boot_page_mfn = virt_to_mfn(&_boot_page);
   24.21 @@ -118,9 +118,9 @@ void kexec(void *kernel, long kernel_siz
   24.22      unsigned long nr_m2p_updates;
   24.23  
   24.24      DEBUG("booting with cmdline %s\n", cmdline);
   24.25 -    xc_handle = xc_interface_open();
   24.26 +    xc_handle = xc_interface_open(0,0,0);
   24.27  
   24.28 -    dom = xc_dom_allocate(cmdline, features);
   24.29 +    dom = xc_dom_allocate(xc_handle, cmdline, features);
   24.30      dom->allocate = kexec_allocate;
   24.31  
   24.32      dom->kernel_blob = kernel;
   24.33 @@ -160,7 +160,7 @@ void kexec(void *kernel, long kernel_siz
   24.34  #endif
   24.35  
   24.36      /* equivalent of xc_dom_mem_init */
   24.37 -    dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type);
   24.38 +    dom->arch_hooks = xc_dom_find_arch_hooks(xc_handle, dom->guest_type);
   24.39      dom->total_pages = start_info.nr_pages;
   24.40  
   24.41      /* equivalent of arch_setup_meminit */
   24.42 @@ -238,7 +238,7 @@ void kexec(void *kernel, long kernel_siz
   24.43          munmap((void*) pages[pfn], PAGE_SIZE);
   24.44  
   24.45      /* Pin the boot page table base */
   24.46 -    if ( (rc = pin_table(dom->guest_xc, 
   24.47 +    if ( (rc = pin_table(dom->xch,
   24.48  #ifdef __i386__
   24.49                  MMUEXT_PIN_L3_TABLE,
   24.50  #endif
    25.1 --- a/stubdom/grub/mini-os.c	Wed Jun 09 19:53:32 2010 -0700
    25.2 +++ b/stubdom/grub/mini-os.c	Fri Jul 16 17:16:06 2010 -0700
    25.3 @@ -651,12 +651,11 @@ int console_getkey (void)
    25.4      return 0;
    25.5  }
    25.6  
    25.7 +static DECLARE_MUTEX_LOCKED(kbd_sem);
    25.8  static void kbd_thread(void *p)
    25.9  {
   25.10 -    struct semaphore *sem = p;
   25.11 -
   25.12      kbd_dev = init_kbdfront(NULL, 1);
   25.13 -    up(sem);
   25.14 +    up(&kbd_sem);
   25.15  }
   25.16  
   25.17  struct fbfront_dev *fb_open(void *fb, int width, int height, int depth)
   25.18 @@ -665,10 +664,9 @@ struct fbfront_dev *fb_open(void *fb, in
   25.19      int linesize = width * (depth / 8);
   25.20      int memsize = linesize * height;
   25.21      int numpages = (memsize + PAGE_SIZE - 1) / PAGE_SIZE;
   25.22 -    DECLARE_MUTEX_LOCKED(sem);
   25.23      int i;
   25.24  
   25.25 -    create_thread("kbdfront", kbd_thread, &sem);
   25.26 +    create_thread("kbdfront", kbd_thread, &kbd_sem);
   25.27  
   25.28      mfns = malloc(numpages * sizeof(*mfns));
   25.29      for (i = 0; i < numpages; i++) {
   25.30 @@ -681,7 +679,7 @@ struct fbfront_dev *fb_open(void *fb, in
   25.31      if (!fb_dev)
   25.32          return NULL;
   25.33  
   25.34 -    down(&sem);
   25.35 +    down(&kbd_sem);
   25.36      if (!kbd_dev)
   25.37          return NULL;
   25.38  
    26.1 --- a/tools/Makefile	Wed Jun 09 19:53:32 2010 -0700
    26.2 +++ b/tools/Makefile	Fri Jul 16 17:16:06 2010 -0700
    26.3 @@ -6,7 +6,6 @@ SUBDIRS-y += check
    26.4  SUBDIRS-y += include
    26.5  SUBDIRS-y += libxc
    26.6  SUBDIRS-y += flask
    26.7 -SUBDIRS-$(CONFIG_OCAML_XENSTORED) += ocaml-xenstored
    26.8  SUBDIRS-y += xenstore
    26.9  SUBDIRS-y += misc
   26.10  SUBDIRS-y += examples
   26.11 @@ -36,11 +35,13 @@ SUBDIRS-y += xenpmd
   26.12  SUBDIRS-y += libxl
   26.13  SUBDIRS-y += remus
   26.14  SUBDIRS-$(CONFIG_X86) += xenpaging
   26.15 +SUBDIRS-$(CONFIG_X86) += debugger/gdbsx
   26.16  
   26.17  # These don't cross-compile
   26.18  ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
   26.19  SUBDIRS-$(PYTHON_TOOLS) += python
   26.20  SUBDIRS-$(PYTHON_TOOLS) += pygrub
   26.21 +SUBDIRS-$(OCAML_TOOLS) += ocaml
   26.22  endif
   26.23  
   26.24  # For the sake of linking, set the sys-root
   26.25 @@ -115,22 +116,8 @@ subdir-clean-ioemu-dir:
   26.26  		$(MAKE) -C ioemu-dir clean; \
   26.27  	fi
   26.28  
   26.29 -ocaml-xenstored:
   26.30 -	set -ex; \
   26.31 -	rm -rf ocaml-xenstored.tmp; \
   26.32 -	hg clone $(OCAML_XENSTORED_REPO) ocaml-xenstored.tmp; \
   26.33 -	if [ "$(OCAML_XENSTORED_TAG)" ]; then \
   26.34 -		hg -R ocaml-xenstored.tmp update -r $(OCAML_XENSTORED_TAG) ;\
   26.35 -		hg -R ocaml-xenstored.tmp branch mybranch ;\
   26.36 -	fi;						\
   26.37 -	mv ocaml-xenstored.tmp ocaml-xenstored; \
   26.38 +subdir-clean-debugger/gdbsx:
   26.39 +	$(MAKE) -C debugger/gdbsx clean
   26.40  
   26.41 -subdir-all-ocaml-xenstored subdir-install-ocaml-xenstored: ocaml-xenstored
   26.42 -	$(absolutify_xen_root); \
   26.43 -	$(MAKE) -C ocaml-xenstored $(patsubst subdir-%-ocaml-xenstored,%,$@);
   26.44 -
   26.45 -subdir-clean-ocaml-xenstored:
   26.46 -	set -e; if test -d ocaml-xenstored; then \
   26.47 -		$(MAKE) -C ocaml-xenstored clean; \
   26.48 -	fi
   26.49 -
   26.50 +subdir-install-debugger/gdbsx:
   26.51 +	$(MAKE) -C debugger/gdbsx install
    27.1 --- a/tools/Rules.mk	Wed Jun 09 19:53:32 2010 -0700
    27.2 +++ b/tools/Rules.mk	Fri Jul 16 17:16:06 2010 -0700
    27.3 @@ -13,6 +13,7 @@ XEN_XC             = $(XEN_ROOT)/tools/p
    27.4  XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
    27.5  XEN_XENSTORE       = $(XEN_ROOT)/tools/xenstore
    27.6  XEN_LIBXENSTAT     = $(XEN_ROOT)/tools/xenstat/libxenstat/src
    27.7 +XEN_BLKTAP2        = $(XEN_ROOT)/tools/blktap2
    27.8  
    27.9  CFLAGS_include = -I$(XEN_INCLUDE)
   27.10  
   27.11 @@ -25,6 +26,9 @@ LDFLAGS_libxenguest = -L$(XEN_LIBXC) -lx
   27.12  CFLAGS_libxenstore = -I$(XEN_XENSTORE) $(CFLAGS_include)
   27.13  LDFLAGS_libxenstore = -L$(XEN_XENSTORE) -lxenstore
   27.14  
   27.15 +CFLAGS_libblktapctl = -I$(XEN_BLKTAP2)/control -I$(XEN_BLKTAP2)/include $(CFLAGS_include)
   27.16 +LDFLAGS_libblktapctl = -L$(XEN_BLKTAP2)/control -lblktapctl
   27.17 +
   27.18  X11_LDPATH = -L/usr/X11R6/$(LIBLEAFDIR)
   27.19  
   27.20  CFLAGS += -D__XEN_TOOLS__
    28.1 --- a/tools/blktap/drivers/blktapctrl_linux.c	Wed Jun 09 19:53:32 2010 -0700
    28.2 +++ b/tools/blktap/drivers/blktapctrl_linux.c	Fri Jul 16 17:16:06 2010 -0700
    28.3 @@ -79,31 +79,11 @@ int blktap_interface_create(int ctlfd, i
    28.4  
    28.5  int blktap_interface_open(void)
    28.6  {
    28.7 -	char *devname;
    28.8 -	int ret;
    28.9  	int ctlfd;
   28.10  
   28.11 -	/* Attach to blktap0 */
   28.12 -	if (asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME) == -1)
   28.13 -		goto open_failed;
   28.14 -
   28.15 -	ret = xc_find_device_number("blktap0");
   28.16 -	if (ret < 0) {
   28.17 -		DPRINTF("couldn't find device number for 'blktap0'\n");
   28.18 -		goto open_failed;
   28.19 -	}
   28.20 -
   28.21 -	blktap_major = major(ret);
   28.22 -	make_blktap_dev(devname,blktap_major, 0);
   28.23 -
   28.24 -	ctlfd = open(devname, O_RDWR);
   28.25 -	if (ctlfd == -1) {
   28.26 +	ctlfd = open(BLKTAP_DEV_DIR "/" BLKTAP_DEV_NAME "0", O_RDWR);
   28.27 +	if (ctlfd == -1)
   28.28  		DPRINTF("blktap0 open failed\n");
   28.29 -		goto open_failed;
   28.30 -	}
   28.31  
   28.32  	return ctlfd;
   28.33 -
   28.34 -open_failed:
   28.35 -	return -1;
   28.36  }
    29.1 --- a/tools/blktap/drivers/block-qcow.c	Wed Jun 09 19:53:32 2010 -0700
    29.2 +++ b/tools/blktap/drivers/block-qcow.c	Fri Jul 16 17:16:06 2010 -0700
    29.3 @@ -862,11 +862,12 @@ static int tdqcow_open (struct disk_driv
    29.4  		be32_to_cpus(&exthdr->xmagic);
    29.5  		if(exthdr->xmagic != XEN_MAGIC) 
    29.6  			goto end_xenhdr;
    29.7 -    
    29.8 +	
    29.9 +		be32_to_cpus(&exthdr->flags);
   29.10  		/* Try to detect old tapdisk images. They have to be fixed because 
   29.11  		 * they don't use big endian but native endianess for the L1 table */
   29.12  		if ((exthdr->flags & EXTHDR_L1_BIG_ENDIAN) == 0) {
   29.13 -
   29.14 +			QCowHeader_ext *tmphdr = (QCowHeader_ext *)(buf2 + sizeof(QCowHeader));
   29.15  			/* 
   29.16  			   The image is broken. Fix it. The L1 table has already been 
   29.17  			   byte-swapped, so we can write it to the image file as it is
   29.18 @@ -874,6 +875,11 @@ static int tdqcow_open (struct disk_driv
   29.19  			   for operation.
   29.20  			 */
   29.21  
   29.22 +			/* Change ENDIAN flag and copy it to store buffer */
   29.23 +			exthdr->flags |= EXTHDR_L1_BIG_ENDIAN;
   29.24 +			tmphdr->flags = cpu_to_be32(exthdr->flags);
   29.25 +
   29.26 +
   29.27  			DPRINTF("qcow: Converting image to big endian L1 table\n");
   29.28  
   29.29  			memcpy(buf2 + s->l1_table_offset, s->l1_table, l1_table_size);
   29.30 @@ -888,13 +894,6 @@ static int tdqcow_open (struct disk_driv
   29.31  				cpu_to_be64s(&s->l1_table[i]);
   29.32  			}
   29.33  
   29.34 -			/* Write the big endian flag to the extended header */
   29.35 -			exthdr->flags |= EXTHDR_L1_BIG_ENDIAN;
   29.36 -
   29.37 -			if (write(fd, buf, 512) != 512) {
   29.38 -				DPRINTF("qcow: Failed to write extended header\n");
   29.39 -				goto fail;
   29.40 -			}
   29.41  		}
   29.42  
   29.43  		/*Finally check the L1 table cksum*/
   29.44 @@ -905,7 +904,6 @@ static int tdqcow_open (struct disk_driv
   29.45  			goto end_xenhdr;
   29.46  			
   29.47  		be32_to_cpus(&exthdr->min_cluster_alloc);
   29.48 -		be32_to_cpus(&exthdr->flags);
   29.49  		s->sparse = (exthdr->flags & SPARSE_FILE);
   29.50  		s->min_cluster_alloc = exthdr->min_cluster_alloc; 
   29.51  	}
   29.52 @@ -1263,6 +1261,7 @@ int qcow_create(const char *filename, ui
   29.53  	} else
   29.54  		flags = SPARSE_FILE;
   29.55  
   29.56 +	flags |= EXTHDR_L1_BIG_ENDIAN;
   29.57  	exthdr.flags = cpu_to_be32(flags);
   29.58  	
   29.59  	/* write all the data */
    30.1 --- a/tools/blktap2/Makefile	Wed Jun 09 19:53:32 2010 -0700
    30.2 +++ b/tools/blktap2/Makefile	Fri Jul 16 17:16:06 2010 -0700
    30.3 @@ -8,7 +8,8 @@ SUBDIRS-y :=
    30.4  SUBDIRS-y += include
    30.5  SUBDIRS-y += lvm
    30.6  SUBDIRS-y += vhd
    30.7 -SUBDIRS-y += drivers
    30.8 +SUBDIRS-$(CONFIG_Linux) += drivers
    30.9 +SUBDIRS-$(CONFIG_Linux) += control
   30.10  
   30.11  clean:
   30.12  	rm -rf *.a *.so *.o *.rpm $(LIB) *~ $(DEPS) TAGS
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/tools/blktap2/control/Makefile	Fri Jul 16 17:16:06 2010 -0700
    31.3 @@ -0,0 +1,65 @@
    31.4 +XEN_ROOT := ../../../
    31.5 +include $(XEN_ROOT)/tools/Rules.mk
    31.6 +
    31.7 +IBIN               = tap-ctl
    31.8 +
    31.9 +CFLAGS            += -Werror
   31.10 +CFLAGS            += -Wno-unused
   31.11 +CFLAGS            += -I../include -I../drivers
   31.12 +CFLAGS            += -I$(XEN_INCLUDE) -I$(XEN_LIBXC)
   31.13 +CFLAGS            += -D_GNU_SOURCE
   31.14 +CFLAGS            += -DTAPCTL
   31.15 +
   31.16 +# Get gcc to generate the dependencies for us.
   31.17 +CFLAGS            += -Wp,-MD,.$(@F).d
   31.18 +DEPS               = .*.d
   31.19 +
   31.20 +CTL_OBJS  := tap-ctl-ipc.o
   31.21 +CTL_OBJS  += tap-ctl-list.o
   31.22 +CTL_OBJS  += tap-ctl-allocate.o
   31.23 +CTL_OBJS  += tap-ctl-free.o
   31.24 +CTL_OBJS  += tap-ctl-create.o
   31.25 +CTL_OBJS  += tap-ctl-destroy.o
   31.26 +CTL_OBJS  += tap-ctl-spawn.o
   31.27 +CTL_OBJS  += tap-ctl-attach.o
   31.28 +CTL_OBJS  += tap-ctl-detach.o
   31.29 +CTL_OBJS  += tap-ctl-open.o
   31.30 +CTL_OBJS  += tap-ctl-close.o
   31.31 +CTL_OBJS  += tap-ctl-pause.o
   31.32 +CTL_OBJS  += tap-ctl-unpause.o
   31.33 +CTL_OBJS  += tap-ctl-major.o
   31.34 +CTL_OBJS  += tap-ctl-check.o
   31.35 +
   31.36 +CTL_PICS  = $(patsubst %.o,%.opic,$(CTL_OBJS))
   31.37 +
   31.38 +OBJS = $(CTL_OBJS) tap-ctl.o
   31.39 +PICS = $(CTL_PICS)
   31.40 +
   31.41 +LIBS = libblktapctl.a libblktapctl.so
   31.42 +IBIN = tap-ctl
   31.43 +
   31.44 +all: build
   31.45 +
   31.46 +build: $(IBIN) $(LIBS)
   31.47 +
   31.48 +tap-ctl: tap-ctl.o libblktapctl.so
   31.49 +	$(CC) $(CFLAGS) -o $@ $^
   31.50 +
   31.51 +libblktapctl.a: $(CTL_OBJS)
   31.52 +	$(AR) r $@ $^
   31.53 +
   31.54 +libblktapctl.so: $(CTL_PICS)
   31.55 +	$(CC) $(CFLAGS) -fPIC -shared -rdynamic $^ -o $@
   31.56 +
   31.57 +install: $(IBIN) $(LIBS)
   31.58 +	$(INSTALL_DIR) -p $(DESTDIR)$(SBINDIR)
   31.59 +	$(INSTALL_PROG) $(IBIN) $(DESTDIR)$(SBINDIR)
   31.60 +	$(INSTALL_PROG) $(LIBS) $(DESTDIR)$(LIBDIR)
   31.61 +
   31.62 +clean:
   31.63 +	rm -f $(OBJS) $(PICS) $(DEPS) $(IBIN) $(LIBS)
   31.64 +	rm -f *~
   31.65 +
   31.66 +.PHONY: all build clean install
   31.67 +
   31.68 +-include $(DEPS)
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/tools/blktap2/control/tap-ctl-allocate.c	Fri Jul 16 17:16:06 2010 -0700
    32.3 @@ -0,0 +1,242 @@
    32.4 +/*
    32.5 + * Copyright (c) 2008, XenSource Inc.
    32.6 + * All rights reserved.
    32.7 + *
    32.8 + * Redistribution and use in source and binary forms, with or without
    32.9 + * modification, are permitted provided that the following conditions are met:
   32.10 + *     * Redistributions of source code must retain the above copyright
   32.11 + *       notice, this list of conditions and the following disclaimer.
   32.12 + *     * Redistributions in binary form must reproduce the above copyright
   32.13 + *       notice, this list of conditions and the following disclaimer in the
   32.14 + *       documentation and/or other materials provided with the distribution.
   32.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   32.16 + *       may be used to endorse or promote products derived from this software
   32.17 + *       without specific prior written permission.
   32.18 + *
   32.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   32.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   32.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   32.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   32.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   32.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   32.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   32.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   32.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   32.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   32.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32.30 + */
   32.31 +#include <stdio.h>
   32.32 +#include <errno.h>
   32.33 +#include <fcntl.h>
   32.34 +#include <stdlib.h>
   32.35 +#include <unistd.h>
   32.36 +#include <string.h>
   32.37 +#include <getopt.h>
   32.38 +#include <libgen.h>
   32.39 +#include <sys/stat.h>
   32.40 +#include <sys/types.h>
   32.41 +#include <sys/ioctl.h>
   32.42 +#include <linux/major.h>
   32.43 +
   32.44 +#include "tap-ctl.h"
   32.45 +#include "blktap2.h"
   32.46 +
   32.47 +static int
   32.48 +tap_ctl_prepare_directory(const char *dir)
   32.49 +{
   32.50 +	int err;
   32.51 +	char *ptr, *name, *start;
   32.52 +
   32.53 +	err = access(dir, W_OK | R_OK);
   32.54 +	if (!err)
   32.55 +		return 0;
   32.56 +
   32.57 +	name = strdup(dir);
   32.58 +	if (!name)
   32.59 +		return ENOMEM;
   32.60 +
   32.61 +	start = name;
   32.62 +
   32.63 +	for (;;) {
   32.64 +		ptr = strchr(start + 1, '/');
   32.65 +		if (ptr)
   32.66 +			*ptr = '\0';
   32.67 +
   32.68 +		err = mkdir(name, 0755);
   32.69 +		if (err && errno != EEXIST) {
   32.70 +			PERROR("mkdir %s", name);
   32.71 +			err = errno;
   32.72 +			break;
   32.73 +		}
   32.74 +
   32.75 +		if (!ptr)
   32.76 +			break;
   32.77 +		else {
   32.78 +			*ptr = '/';
   32.79 +			start = ptr + 1;
   32.80 +		}
   32.81 +	}
   32.82 +
   32.83 +	free(name);
   32.84 +	return err;
   32.85 +}
   32.86 +
   32.87 +static int
   32.88 +tap_ctl_make_device(const char *devname, const int major,
   32.89 +		    const int minor, const int perm)
   32.90 +{
   32.91 +	int err;
   32.92 +	char *copy, *dir;
   32.93 +
   32.94 +	copy = strdup(devname);
   32.95 +	if (!copy)
   32.96 +		return ENOMEM;
   32.97 +
   32.98 +	dir = dirname(copy);
   32.99 +
  32.100 +	err = tap_ctl_prepare_directory(dir);
  32.101 +	free(copy);
  32.102 +
  32.103 +	if (err)
  32.104 +		return err;
  32.105 +
  32.106 +	if (!access(devname, F_OK))
  32.107 +		if (unlink(devname)) {
  32.108 +			PERROR("unlink %s", devname);
  32.109 +			return errno;
  32.110 +		}
  32.111 +
  32.112 +	err = mknod(devname, perm, makedev(major, minor));
  32.113 +	if (err) {
  32.114 +		PERROR("mknod %s", devname);
  32.115 +		return errno;
  32.116 +	}
  32.117 +
  32.118 +	return 0;
  32.119 +}
  32.120 +
  32.121 +static int
  32.122 +tap_ctl_check_environment(void)
  32.123 +{
  32.124 +	FILE *f;
  32.125 +	int err, minor;
  32.126 +	char name[256];
  32.127 +
  32.128 +	err = tap_ctl_prepare_directory(BLKTAP2_CONTROL_DIR);
  32.129 +	if (err)
  32.130 +		return err;
  32.131 +
  32.132 +	if (!access(BLKTAP2_CONTROL_DEVICE, R_OK | W_OK))
  32.133 +		return 0;
  32.134 +
  32.135 +	memset(name, 0, sizeof(name));
  32.136 +
  32.137 +	f = fopen("/proc/misc", "r");
  32.138 +	if (!f) {
  32.139 +		EPRINTF("failed to open /proc/misc: %d\n", errno);
  32.140 +		return errno;
  32.141 +	}
  32.142 +
  32.143 +	while (fscanf(f, "%d %256s", &minor, name) == 2)
  32.144 +		if (!strcmp(name, BLKTAP2_CONTROL_NAME)) {
  32.145 +			err = tap_ctl_make_device(BLKTAP2_CONTROL_DEVICE,
  32.146 +						  MISC_MAJOR,
  32.147 +						  minor, S_IFCHR | 0600);
  32.148 +			goto out;
  32.149 +		}
  32.150 +
  32.151 +	err = ENOSYS;
  32.152 +	EPRINTF("didn't find %s in /proc/misc\n", BLKTAP2_CONTROL_NAME);
  32.153 +
  32.154 +out:
  32.155 +	fclose(f);
  32.156 +	return err;
  32.157 +}
  32.158 +
  32.159 +static int
  32.160 +tap_ctl_allocate_device(int *minor, char **devname)
  32.161 +{
  32.162 +	char *name;
  32.163 +	int fd, err;
  32.164 +	struct blktap2_handle handle;
  32.165 +
  32.166 +	*minor = -1;
  32.167 +	if (!devname)
  32.168 +		return EINVAL;
  32.169 +
  32.170 +	fd = open(BLKTAP2_CONTROL_DEVICE, O_RDONLY);
  32.171 +	if (fd == -1) {
  32.172 +		EPRINTF("failed to open control device: %d\n", errno);
  32.173 +		return errno;
  32.174 +	}
  32.175 +
  32.176 +	err = ioctl(fd, BLKTAP2_IOCTL_ALLOC_TAP, &handle);
  32.177 +	close(fd);
  32.178 +	if (err == -1) {
  32.179 +		EPRINTF("failed to allocate new device: %d\n", errno);
  32.180 +		return errno;
  32.181 +	}
  32.182 +
  32.183 +	err = asprintf(&name, "%s%d", BLKTAP2_RING_DEVICE, handle.minor);
  32.184 +	if (err == -1) {
  32.185 +		err = ENOMEM;
  32.186 +		goto fail;
  32.187 +	}
  32.188 +
  32.189 +	err = tap_ctl_make_device(name, handle.ring,
  32.190 +				  handle.minor, S_IFCHR | 0600);
  32.191 +	free(name);
  32.192 +	if (err) {
  32.193 +		EPRINTF("creating ring device for %d failed: %d\n",
  32.194 +			handle.minor, err);
  32.195 +		goto fail;
  32.196 +	}
  32.197 +
  32.198 +	if (*devname)
  32.199 +		name = *devname;
  32.200 +	else {
  32.201 +		err = asprintf(&name, "%s%d",
  32.202 +			       BLKTAP2_IO_DEVICE, handle.minor);
  32.203 +		if (err == -1) {
  32.204 +			err = ENOMEM;
  32.205 +			goto fail;
  32.206 +		}
  32.207 +		*devname = name;
  32.208 +	}
  32.209 +
  32.210 +	err = tap_ctl_make_device(name, handle.device,
  32.211 +				  handle.minor, S_IFBLK | 0600);
  32.212 +	if (err) {
  32.213 +		EPRINTF("creating IO device for %d failed: %d\n",
  32.214 +			handle.minor, err);
  32.215 +		goto fail;
  32.216 +	}
  32.217 +
  32.218 +	DBG("new interface: ring: %u, device: %u, minor: %u\n",
  32.219 +	    handle.ring, handle.device, handle.minor);
  32.220 +
  32.221 +	*minor = handle.minor;
  32.222 +	return 0;
  32.223 +
  32.224 +fail:
  32.225 +	tap_ctl_free(handle.minor);
  32.226 +	return err;
  32.227 +}
  32.228 +
  32.229 +int
  32.230 +tap_ctl_allocate(int *minor, char **devname)
  32.231 +{
  32.232 +	int err;
  32.233 +
  32.234 +	*minor = -1;
  32.235 +
  32.236 +	err = tap_ctl_check_environment();
  32.237 +	if (err)
  32.238 +		return err;
  32.239 +
  32.240 +	err = tap_ctl_allocate_device(minor, devname);
  32.241 +	if (err)
  32.242 +		return err;
  32.243 +
  32.244 +	return 0;
  32.245 +}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/tools/blktap2/control/tap-ctl-attach.c	Fri Jul 16 17:16:06 2010 -0700
    33.3 @@ -0,0 +1,61 @@
    33.4 +/*
    33.5 + * Copyright (c) 2008, XenSource Inc.
    33.6 + * All rights reserved.
    33.7 + *
    33.8 + * Redistribution and use in source and binary forms, with or without
    33.9 + * modification, are permitted provided that the following conditions are met:
   33.10 + *     * Redistributions of source code must retain the above copyright
   33.11 + *       notice, this list of conditions and the following disclaimer.
   33.12 + *     * Redistributions in binary form must reproduce the above copyright
   33.13 + *       notice, this list of conditions and the following disclaimer in the
   33.14 + *       documentation and/or other materials provided with the distribution.
   33.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   33.16 + *       may be used to endorse or promote products derived from this software
   33.17 + *       without specific prior written permission.
   33.18 + *
   33.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   33.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   33.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   33.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   33.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   33.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   33.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   33.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   33.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   33.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   33.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33.30 + */
   33.31 +#include <stdio.h>
   33.32 +#include <errno.h>
   33.33 +#include <stdlib.h>
   33.34 +#include <string.h>
   33.35 +#include <getopt.h>
   33.36 +
   33.37 +#include "tap-ctl.h"
   33.38 +
   33.39 +int
   33.40 +tap_ctl_attach(const int id, const int minor)
   33.41 +{
   33.42 +	int err;
   33.43 +	tapdisk_message_t message;
   33.44 +
   33.45 +	memset(&message, 0, sizeof(message));
   33.46 +	message.type = TAPDISK_MESSAGE_ATTACH;
   33.47 +	message.cookie = minor;
   33.48 +
   33.49 +	err = tap_ctl_connect_send_and_receive(id, &message, 5);
   33.50 +	if (err)
   33.51 +		return err;
   33.52 +
   33.53 +	if (message.type == TAPDISK_MESSAGE_ATTACH_RSP) {
   33.54 +		err = message.u.response.error;
   33.55 +		if (err)
   33.56 +			EPRINTF("attach failed: %d\n", err);
   33.57 +	} else {
   33.58 +		EPRINTF("got unexpected result '%s' from %d\n",
   33.59 +			tapdisk_message_name(message.type), id);
   33.60 +		err = EINVAL;
   33.61 +	}
   33.62 +
   33.63 +	return err;
   33.64 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/tools/blktap2/control/tap-ctl-check.c	Fri Jul 16 17:16:06 2010 -0700
    34.3 @@ -0,0 +1,79 @@
    34.4 +/*
    34.5 + * Copyright (c) 2008, XenSource Inc.
    34.6 + * All rights reserved.
    34.7 + *
    34.8 + * Redistribution and use in source and binary forms, with or without
    34.9 + * modification, are permitted provided that the following conditions are met:
   34.10 + *     * Redistributions of source code must retain the above copyright
   34.11 + *       notice, this list of conditions and the following disclaimer.
   34.12 + *     * Redistributions in binary form must reproduce the above copyright
   34.13 + *       notice, this list of conditions and the following disclaimer in the
   34.14 + *       documentation and/or other materials provided with the distribution.
   34.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   34.16 + *       may be used to endorse or promote products derived from this software
   34.17 + *       without specific prior written permission.
   34.18 + *
   34.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   34.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   34.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   34.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   34.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   34.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   34.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   34.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   34.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   34.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   34.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   34.30 + */
   34.31 +#include <stdio.h>
   34.32 +#include <errno.h>
   34.33 +#include <unistd.h>
   34.34 +#include <string.h>
   34.35 +
   34.36 +#include "tap-ctl.h"
   34.37 +#include "blktap2.h"
   34.38 +
   34.39 +int
   34.40 +tap_ctl_check_blktap(const char **msg)
   34.41 +{
   34.42 +	FILE *f;
   34.43 +	int err = 0, minor;
   34.44 +	char name[32];
   34.45 +
   34.46 +	memset(name, 0, sizeof(name));
   34.47 +
   34.48 +	f = fopen("/proc/misc", "r");
   34.49 +	if (!f) {
   34.50 +		*msg = "failed to open /proc/misc";
   34.51 +		return -errno;
   34.52 +	}
   34.53 +
   34.54 +	while (fscanf(f, "%d %32s", &minor, name) == 2) {
   34.55 +		if (!strcmp(name, BLKTAP2_CONTROL_NAME))
   34.56 +			goto out;
   34.57 +	}
   34.58 +
   34.59 +	err = -ENOSYS;
   34.60 +	*msg = "blktap kernel module not installed";
   34.61 +
   34.62 +out:
   34.63 +	fclose(f);
   34.64 +	return err;
   34.65 +}
   34.66 +
   34.67 +int
   34.68 +tap_ctl_check(const char **msg)
   34.69 +{
   34.70 +	int err;
   34.71 +	uid_t uid;
   34.72 +
   34.73 +	err = tap_ctl_check_blktap(msg);
   34.74 +	if (err)
   34.75 +		goto out;
   34.76 +
   34.77 +	err  = 0;
   34.78 +	*msg = "ok";
   34.79 +
   34.80 +out:
   34.81 +	return err;
   34.82 +}
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/tools/blktap2/control/tap-ctl-close.c	Fri Jul 16 17:16:06 2010 -0700
    35.3 @@ -0,0 +1,87 @@
    35.4 +/*
    35.5 + * Copyright (c) 2008, XenSource Inc.
    35.6 + * All rights reserved.
    35.7 + *
    35.8 + * Redistribution and use in source and binary forms, with or without
    35.9 + * modification, are permitted provided that the following conditions are met:
   35.10 + *     * Redistributions of source code must retain the above copyright
   35.11 + *       notice, this list of conditions and the following disclaimer.
   35.12 + *     * Redistributions in binary form must reproduce the above copyright
   35.13 + *       notice, this list of conditions and the following disclaimer in the
   35.14 + *       documentation and/or other materials provided with the distribution.
   35.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   35.16 + *       may be used to endorse or promote products derived from this software
   35.17 + *       without specific prior written permission.
   35.18 + *
   35.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   35.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   35.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   35.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   35.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   35.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   35.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   35.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   35.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   35.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   35.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35.30 + */
   35.31 +#include <stdio.h>
   35.32 +#include <errno.h>
   35.33 +#include <stdlib.h>
   35.34 +#include <unistd.h>
   35.35 +#include <string.h>
   35.36 +#include <getopt.h>
   35.37 +
   35.38 +#include "tap-ctl.h"
   35.39 +
   35.40 +static int
   35.41 +__tap_ctl_close(const int id, const int minor, const int force)
   35.42 +{
   35.43 +	int err;
   35.44 +	tapdisk_message_t message;
   35.45 +
   35.46 +	memset(&message, 0, sizeof(message));
   35.47 +	message.type = TAPDISK_MESSAGE_CLOSE;
   35.48 +	if (force)
   35.49 +		message.type = TAPDISK_MESSAGE_FORCE_SHUTDOWN;
   35.50 +	message.cookie = minor;
   35.51 +
   35.52 +	err = tap_ctl_connect_send_and_receive(id, &message, 5);
   35.53 +	if (err)
   35.54 +		return err;
   35.55 +
   35.56 +	if (message.type == TAPDISK_MESSAGE_CLOSE_RSP) {
   35.57 +		err = message.u.response.error;
   35.58 +		if (err)
   35.59 +			EPRINTF("close failed: %d\n", err);
   35.60 +	} else {
   35.61 +		EPRINTF("got unexpected result '%s' from %d\n",
   35.62 +			tapdisk_message_name(message.type), id);
   35.63 +		err = EINVAL;
   35.64 +	}
   35.65 +
   35.66 +	return err;
   35.67 +}
   35.68 +
   35.69 +int
   35.70 +tap_ctl_close(const int id, const int minor, const int force)
   35.71 +{
   35.72 +	int i, err;
   35.73 +
   35.74 +	for (i = 0; i < 20; i++) {
   35.75 +		err = __tap_ctl_close(id, minor, force);
   35.76 +		if (!err)
   35.77 +			return 0;
   35.78 +
   35.79 +		err = (err < 0 ? -err : err);
   35.80 +		if (err != EAGAIN) {
   35.81 +			EPRINTF("close failed: %d\n", err);
   35.82 +			return err;
   35.83 +		}
   35.84 +
   35.85 +		usleep(1000);
   35.86 +	}
   35.87 +
   35.88 +	EPRINTF("close timed out\n");
   35.89 +	return EIO;
   35.90 +}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/tools/blktap2/control/tap-ctl-create.c	Fri Jul 16 17:16:06 2010 -0700
    36.3 @@ -0,0 +1,65 @@
    36.4 +/*
    36.5 + * Copyright (c) 2008, XenSource Inc.
    36.6 + * All rights reserved.
    36.7 + *
    36.8 + * Redistribution and use in source and binary forms, with or without
    36.9 + * modification, are permitted provided that the following conditions are met:
   36.10 + *     * Redistributions of source code must retain the above copyright
   36.11 + *       notice, this list of conditions and the following disclaimer.
   36.12 + *     * Redistributions in binary form must reproduce the above copyright
   36.13 + *       notice, this list of conditions and the following disclaimer in the
   36.14 + *       documentation and/or other materials provided with the distribution.
   36.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   36.16 + *       may be used to endorse or promote products derived from this software
   36.17 + *       without specific prior written permission.
   36.18 + *
   36.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   36.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   36.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   36.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   36.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   36.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   36.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   36.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   36.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   36.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   36.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   36.30 + */
   36.31 +#include <stdio.h>
   36.32 +#include <errno.h>
   36.33 +#include <stdlib.h>
   36.34 +#include <unistd.h>
   36.35 +#include <getopt.h>
   36.36 +
   36.37 +#include "tap-ctl.h"
   36.38 +#include "blktap2.h"
   36.39 +
   36.40 +int
   36.41 +tap_ctl_create(const char *params, char **devname)
   36.42 +{
   36.43 +	int err, id, minor;
   36.44 +
   36.45 +	err = tap_ctl_allocate(&minor, devname);
   36.46 +	if (err)
   36.47 +		return err;
   36.48 +
   36.49 +	id = tap_ctl_spawn();
   36.50 +	if (id < 0)
   36.51 +		goto destroy;
   36.52 +
   36.53 +	err = tap_ctl_attach(id, minor);
   36.54 +	if (err)
   36.55 +		goto destroy;
   36.56 +
   36.57 +	err = tap_ctl_open(id, minor, params);
   36.58 +	if (err)
   36.59 +		goto detach;
   36.60 +
   36.61 +	return 0;
   36.62 +
   36.63 +detach:
   36.64 +	tap_ctl_detach(id, minor);
   36.65 +destroy:
   36.66 +	tap_ctl_free(minor);
   36.67 +	return err;
   36.68 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/tools/blktap2/control/tap-ctl-destroy.c	Fri Jul 16 17:16:06 2010 -0700
    37.3 @@ -0,0 +1,56 @@
    37.4 +/*
    37.5 + * Copyright (c) 2008, XenSource Inc.
    37.6 + * All rights reserved.
    37.7 + *
    37.8 + * Redistribution and use in source and binary forms, with or without
    37.9 + * modification, are permitted provided that the following conditions are met:
   37.10 + *     * Redistributions of source code must retain the above copyright
   37.11 + *       notice, this list of conditions and the following disclaimer.
   37.12 + *     * Redistributions in binary form must reproduce the above copyright
   37.13 + *       notice, this list of conditions and the following disclaimer in the
   37.14 + *       documentation and/or other materials provided with the distribution.
   37.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   37.16 + *       may be used to endorse or promote products derived from this software
   37.17 + *       without specific prior written permission.
   37.18 + *
   37.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   37.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   37.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   37.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   37.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   37.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   37.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   37.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   37.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   37.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   37.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   37.30 + */
   37.31 +#include <stdio.h>
   37.32 +#include <errno.h>
   37.33 +#include <fcntl.h>
   37.34 +#include <stdlib.h>
   37.35 +#include <unistd.h>
   37.36 +#include <getopt.h>
   37.37 +
   37.38 +#include "tap-ctl.h"
   37.39 +#include "blktap2.h"
   37.40 +
   37.41 +int
   37.42 +tap_ctl_destroy(const int id, const int minor)
   37.43 +{
   37.44 +	int err;
   37.45 +
   37.46 +	err = tap_ctl_close(id, minor, 0);
   37.47 +	if (err)
   37.48 +		return err;
   37.49 +
   37.50 +	err = tap_ctl_detach(id, minor);
   37.51 +	if (err)
   37.52 +		return err;
   37.53 +
   37.54 +	err = tap_ctl_free(minor);
   37.55 +	if (err)
   37.56 +		return err;
   37.57 +
   37.58 +	return 0;
   37.59 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/tools/blktap2/control/tap-ctl-detach.c	Fri Jul 16 17:16:06 2010 -0700
    38.3 @@ -0,0 +1,61 @@
    38.4 +/*
    38.5 + * Copyright (c) 2008, XenSource Inc.
    38.6 + * All rights reserved.
    38.7 + *
    38.8 + * Redistribution and use in source and binary forms, with or without
    38.9 + * modification, are permitted provided that the following conditions are met:
   38.10 + *     * Redistributions of source code must retain the above copyright
   38.11 + *       notice, this list of conditions and the following disclaimer.
   38.12 + *     * Redistributions in binary form must reproduce the above copyright
   38.13 + *       notice, this list of conditions and the following disclaimer in the
   38.14 + *       documentation and/or other materials provided with the distribution.
   38.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   38.16 + *       may be used to endorse or promote products derived from this software
   38.17 + *       without specific prior written permission.
   38.18 + *
   38.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   38.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   38.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   38.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   38.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   38.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   38.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   38.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   38.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   38.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   38.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   38.30 + */
   38.31 +#include <stdio.h>
   38.32 +#include <errno.h>
   38.33 +#include <stdlib.h>
   38.34 +#include <string.h>
   38.35 +#include <getopt.h>
   38.36 +
   38.37 +#include "tap-ctl.h"
   38.38 +
   38.39 +int
   38.40 +tap_ctl_detach(const int id, const int minor)
   38.41 +{
   38.42 +	int err;
   38.43 +	tapdisk_message_t message;
   38.44 +
   38.45 +	memset(&message, 0, sizeof(message));
   38.46 +	message.type = TAPDISK_MESSAGE_DETACH;
   38.47 +	message.cookie = minor;
   38.48 +
   38.49 +	err = tap_ctl_connect_send_and_receive(id, &message, 5);
   38.50 +	if (err)
   38.51 +		return err;
   38.52 +
   38.53 +	if (message.type == TAPDISK_MESSAGE_DETACH_RSP) {
   38.54 +		err = message.u.response.error;
   38.55 +		if (err < 0)
   38.56 +			printf("detach failed: %d\n", err);
   38.57 +	} else {
   38.58 +		printf("got unexpected result '%s' from %d\n",
   38.59 +		       tapdisk_message_name(message.type), id);
   38.60 +		err = EINVAL;
   38.61 +	}
   38.62 +
   38.63 +	return err;
   38.64 +}
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/tools/blktap2/control/tap-ctl-free.c	Fri Jul 16 17:16:06 2010 -0700
    39.3 @@ -0,0 +1,54 @@
    39.4 +/*
    39.5 + * Copyright (c) 2008, XenSource Inc.
    39.6 + * All rights reserved.
    39.7 + *
    39.8 + * Redistribution and use in source and binary forms, with or without
    39.9 + * modification, are permitted provided that the following conditions are met:
   39.10 + *     * Redistributions of source code must retain the above copyright
   39.11 + *       notice, this list of conditions and the following disclaimer.
   39.12 + *     * Redistributions in binary form must reproduce the above copyright
   39.13 + *       notice, this list of conditions and the following disclaimer in the
   39.14 + *       documentation and/or other materials provided with the distribution.
   39.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   39.16 + *       may be used to endorse or promote products derived from this software
   39.17 + *       without specific prior written permission.
   39.18 + *
   39.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   39.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   39.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   39.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   39.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   39.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   39.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   39.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   39.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   39.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   39.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   39.30 + */
   39.31 +#include <stdio.h>
   39.32 +#include <errno.h>
   39.33 +#include <fcntl.h>
   39.34 +#include <stdlib.h>
   39.35 +#include <unistd.h>
   39.36 +#include <getopt.h>
   39.37 +#include <sys/ioctl.h>
   39.38 +
   39.39 +#include "tap-ctl.h"
   39.40 +#include "blktap2.h"
   39.41 +
   39.42 +int
   39.43 +tap_ctl_free(const int minor)
   39.44 +{
   39.45 +	int fd, err;
   39.46 +
   39.47 +	fd = open(BLKTAP2_CONTROL_DEVICE, O_RDONLY);
   39.48 +	if (fd == -1) {
   39.49 +		EPRINTF("failed to open control device: %d\n", errno);
   39.50 +		return errno;
   39.51 +	}
   39.52 +
   39.53 +	err = ioctl(fd, BLKTAP2_IOCTL_FREE_TAP, minor);
   39.54 +	close(fd);
   39.55 +
   39.56 +	return err;
   39.57 +}
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/tools/blktap2/control/tap-ctl-ipc.c	Fri Jul 16 17:16:06 2010 -0700
    40.3 @@ -0,0 +1,237 @@
    40.4 +/*
    40.5 + * Copyright (c) 2008, XenSource Inc.
    40.6 + * All rights reserved.
    40.7 + *
    40.8 + * Redistribution and use in source and binary forms, with or without
    40.9 + * modification, are permitted provided that the following conditions are met:
   40.10 + *     * Redistributions of source code must retain the above copyright
   40.11 + *       notice, this list of conditions and the following disclaimer.
   40.12 + *     * Redistributions in binary form must reproduce the above copyright
   40.13 + *       notice, this list of conditions and the following disclaimer in the
   40.14 + *       documentation and/or other materials provided with the distribution.
   40.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   40.16 + *       may be used to endorse or promote products derived from this software
   40.17 + *       without specific prior written permission.
   40.18 + *
   40.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   40.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   40.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   40.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   40.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   40.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   40.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   40.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   40.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   40.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   40.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   40.30 + */
   40.31 +#include <stdio.h>
   40.32 +#include <errno.h>
   40.33 +#include <unistd.h>
   40.34 +#include <stdlib.h>
   40.35 +#include <string.h>
   40.36 +#include <sys/un.h>
   40.37 +#include <sys/stat.h>
   40.38 +#include <sys/types.h>
   40.39 +#include <sys/socket.h>
   40.40 +
   40.41 +#include "tap-ctl.h"
   40.42 +#include "blktap2.h"
   40.43 +
   40.44 +int tap_ctl_debug = 0;
   40.45 +
   40.46 +int
   40.47 +tap_ctl_read_message(int fd, tapdisk_message_t *message, int timeout)
   40.48 +{
   40.49 +	fd_set readfds;
   40.50 +	int ret, len, offset;
   40.51 +	struct timeval tv, *t;
   40.52 +
   40.53 +	t      = NULL;
   40.54 +	offset = 0;
   40.55 +	len    = sizeof(tapdisk_message_t);
   40.56 +
   40.57 +	if (timeout) {
   40.58 +		tv.tv_sec  = timeout;
   40.59 +		tv.tv_usec = 0;
   40.60 +		t = &tv;
   40.61 +	}
   40.62 +
   40.63 +	memset(message, 0, sizeof(tapdisk_message_t));
   40.64 +
   40.65 +	while (offset < len) {
   40.66 +		FD_ZERO(&readfds);
   40.67 +		FD_SET(fd, &readfds);
   40.68 +
   40.69 +		ret = select(fd + 1, &readfds, NULL, NULL, t);
   40.70 +		if (ret == -1)
   40.71 +			break;
   40.72 +		else if (FD_ISSET(fd, &readfds)) {
   40.73 +			ret = read(fd, message + offset, len - offset);
   40.74 +			if (ret <= 0)
   40.75 +				break;
   40.76 +			offset += ret;
   40.77 +		} else
   40.78 +			break;
   40.79 +	}
   40.80 +
   40.81 +	if (offset != len) {
   40.82 +		EPRINTF("failure reading message\n");
   40.83 +		return -EIO;
   40.84 +	}
   40.85 +
   40.86 +	DBG("received '%s' message (uuid = %u)\n",
   40.87 +	    tapdisk_message_name(message->type), message->cookie);
   40.88 +
   40.89 +	return 0;
   40.90 +}
   40.91 +
   40.92 +int
   40.93 +tap_ctl_write_message(int fd, tapdisk_message_t *message, int timeout)
   40.94 +{
   40.95 +	fd_set writefds;
   40.96 +	int ret, len, offset;
   40.97 +	struct timeval tv, *t;
   40.98 +
   40.99 +	t      = NULL;
  40.100 +	offset = 0;
  40.101 +	len    = sizeof(tapdisk_message_t);
  40.102 +
  40.103 +	if (timeout) {
  40.104 +		tv.tv_sec  = timeout;
  40.105 +		tv.tv_usec = 0;
  40.106 +		t = &tv;
  40.107 +	}
  40.108 +
  40.109 +	DBG("sending '%s' message (uuid = %u)\n",
  40.110 +	    tapdisk_message_name(message->type), message->cookie);
  40.111 +
  40.112 +	while (offset < len) {
  40.113 +		FD_ZERO(&writefds);
  40.114 +		FD_SET(fd, &writefds);
  40.115 +
  40.116 +		/* we don't bother reinitializing tv. at worst, it will wait a
  40.117 +		 * bit more time than expected. */
  40.118 +
  40.119 +		ret = select(fd + 1, NULL, &writefds, NULL, t);
  40.120 +		if (ret == -1)
  40.121 +			break;
  40.122 +		else if (FD_ISSET(fd, &writefds)) {
  40.123 +			ret = write(fd, message + offset, len - offset);
  40.124 +			if (ret <= 0)
  40.125 +				break;
  40.126 +			offset += ret;
  40.127 +		} else
  40.128 +			break;
  40.129 +	}
  40.130 +
  40.131 +	if (offset != len) {
  40.132 +		EPRINTF("failure writing message\n");
  40.133 +		return -EIO;
  40.134 +	}
  40.135 +
  40.136 +	return 0;
  40.137 +}
  40.138 +
  40.139 +int
  40.140 +tap_ctl_send_and_receive(int sfd, tapdisk_message_t *message, int timeout)
  40.141 +{
  40.142 +	int err;
  40.143 +
  40.144 +	err = tap_ctl_write_message(sfd, message, timeout);
  40.145 +	if (err) {
  40.146 +		EPRINTF("failed to send '%s' message\n",
  40.147 +			tapdisk_message_name(message->type));
  40.148 +		return err;
  40.149 +	}
  40.150 +
  40.151 +	err = tap_ctl_read_message(sfd, message, timeout);
  40.152 +	if (err) {
  40.153 +		EPRINTF("failed to receive '%s' message\n",
  40.154 +			tapdisk_message_name(message->type));
  40.155 +		return err;
  40.156 +	}
  40.157 +
  40.158 +	return 0;
  40.159 +}
  40.160 +
  40.161 +char *
  40.162 +tap_ctl_socket_name(int id)
  40.163 +{
  40.164 +	char *name;
  40.165 +
  40.166 +	if (asprintf(&name, "%s/%s%d",
  40.167 +		     BLKTAP2_CONTROL_DIR, BLKTAP2_CONTROL_SOCKET, id) == -1)
  40.168 +		return NULL;
  40.169 +
  40.170 +	return name;
  40.171 +}
  40.172 +
  40.173 +int
  40.174 +tap_ctl_connect(const char *name, int *sfd)
  40.175 +{
  40.176 +	int fd, err;
  40.177 +	struct sockaddr_un saddr;
  40.178 +
  40.179 +	*sfd = -1;
  40.180 +
  40.181 +	fd = socket(AF_UNIX, SOCK_STREAM, 0);
  40.182 +	if (fd == -1) {
  40.183 +		EPRINTF("couldn't create socket for %s: %d\n", name, errno);
  40.184 +		return -errno;
  40.185 +	}
  40.186 +
  40.187 +	memset(&saddr, 0, sizeof(saddr));
  40.188 +	saddr.sun_family = AF_UNIX;
  40.189 +	strcpy(saddr.sun_path, name);
  40.190 +
  40.191 +	err = connect(fd, (const struct sockaddr *)&saddr, sizeof(saddr));
  40.192 +	if (err) {
  40.193 +		EPRINTF("couldn't connect to %s: %d\n", name, errno);
  40.194 +		close(fd);
  40.195 +		return -errno;
  40.196 +	}
  40.197 +
  40.198 +	*sfd = fd;
  40.199 +	return 0;
  40.200 +}
  40.201 +
  40.202 +int
  40.203 +tap_ctl_connect_id(int id, int *sfd)
  40.204 +{
  40.205 +	int err;
  40.206 +	char *name;
  40.207 +
  40.208 +	*sfd = -1;
  40.209 +
  40.210 +	if (id < 0) {
  40.211 +		EPRINTF("invalid id %d\n", id);
  40.212 +		return -EINVAL;
  40.213 +	}
  40.214 +
  40.215 +	name = tap_ctl_socket_name(id);
  40.216 +	if (!name) {
  40.217 +		EPRINTF("couldn't name socket for %d\n", id);
  40.218 +		return -ENOMEM;
  40.219 +	}
  40.220 +
  40.221 +	err = tap_ctl_connect(name, sfd);
  40.222 +	free(name);
  40.223 +
  40.224 +	return err;
  40.225 +}
  40.226 +
  40.227 +int
  40.228 +tap_ctl_connect_send_and_receive(int id, tapdisk_message_t *message, int timeout)
  40.229 +{
  40.230 +	int err, sfd;
  40.231 +
  40.232 +	err = tap_ctl_connect_id(id, &sfd);
  40.233 +	if (err)
  40.234 +		return err;
  40.235 +
  40.236 +	err = tap_ctl_send_and_receive(sfd, message, timeout);
  40.237 +
  40.238 +	close(sfd);
  40.239 +	return err;
  40.240 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/tools/blktap2/control/tap-ctl-list.c	Fri Jul 16 17:16:06 2010 -0700
    41.3 @@ -0,0 +1,536 @@
    41.4 +/*
    41.5 + * Copyright (c) 2008, XenSource Inc.
    41.6 + * All rights reserved.
    41.7 + *
    41.8 + * Redistribution and use in source and binary forms, with or without
    41.9 + * modification, are permitted provided that the following conditions are met:
   41.10 + *     * Redistributions of source code must retain the above copyright
   41.11 + *       notice, this list of conditions and the following disclaimer.
   41.12 + *     * Redistributions in binary form must reproduce the above copyright
   41.13 + *       notice, this list of conditions and the following disclaimer in the
   41.14 + *       documentation and/or other materials provided with the distribution.
   41.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   41.16 + *       may be used to endorse or promote products derived from this software
   41.17 + *       without specific prior written permission.
   41.18 + *
   41.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   41.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   41.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   41.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   41.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   41.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   41.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   41.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   41.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   41.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   41.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   41.30 + */
   41.31 +
   41.32 +#include <stdio.h>
   41.33 +#include <errno.h>
   41.34 +#include <stdlib.h>
   41.35 +#include <unistd.h>
   41.36 +#include <string.h>
   41.37 +#include <glob.h>
   41.38 +
   41.39 +#include "tap-ctl.h"
   41.40 +#include "blktap2.h"
   41.41 +#include "list.h"
   41.42 +
   41.43 +static void
   41.44 +free_list(tap_list_t *entry)
   41.45 +{
   41.46 +	if (entry->type) {
   41.47 +		free(entry->type);
   41.48 +		entry->type = NULL;
   41.49 +	}
   41.50 +
   41.51 +	if (entry->path) {
   41.52 +		free(entry->path);
   41.53 +		entry->path = NULL;
   41.54 +	}
   41.55 +
   41.56 +	free(entry);
   41.57 +}
   41.58 +
   41.59 +int
   41.60 +_parse_params(const char *params, char **type, char **path)
   41.61 +{
   41.62 +	char *ptr;
   41.63 +	size_t len;
   41.64 +
   41.65 +	ptr = strchr(params, ':');
   41.66 +	if (!ptr)
   41.67 +		return -EINVAL;
   41.68 +
   41.69 +	len = ptr - params;
   41.70 +
   41.71 +	*type = strndup(params, len);
   41.72 +	*path =  strdup(params + len + 1);
   41.73 +
   41.74 +	if (!*type || !*path) {
   41.75 +		free(*type);
   41.76 +		*type = NULL;
   41.77 +
   41.78 +		free(*path);
   41.79 +		*path = NULL;
   41.80 +
   41.81 +		return -errno;
   41.82 +	}
   41.83 +
   41.84 +	return 0;
   41.85 +}
   41.86 +
   41.87 +static int
   41.88 +init_list(tap_list_t *entry,
   41.89 +	  int tap_id, pid_t tap_pid, int vbd_minor, int vbd_state,
   41.90 +	  const char *params)
   41.91 +{
   41.92 +	int err = 0;
   41.93 +
   41.94 +	entry->id     = tap_id;
   41.95 +	entry->pid    = tap_pid;
   41.96 +	entry->minor  = vbd_minor;
   41.97 +	entry->state  = vbd_state;
   41.98 +
   41.99 +	if (params)
  41.100 +		err = _parse_params(params, &entry->type, &entry->path);
  41.101 +
  41.102 +	return err;
  41.103 +}
  41.104 +
  41.105 +void
  41.106 +tap_ctl_free_list(tap_list_t **list)
  41.107 +{
  41.108 +	tap_list_t **_entry;
  41.109 +
  41.110 +	for (_entry = list; *_entry != NULL; ++_entry)
  41.111 +		free_list(*_entry);
  41.112 +
  41.113 +	free(list);
  41.114 +}
  41.115 +
  41.116 +static tap_list_t**
  41.117 +tap_ctl_alloc_list(int n)
  41.118 +{
  41.119 +	tap_list_t **list, *entry;
  41.120 +	size_t size;
  41.121 +	int i;
  41.122 +
  41.123 +	size = sizeof(tap_list_t*) * (n+1);
  41.124 +	list = malloc(size);
  41.125 +	if (!list)
  41.126 +		goto fail;
  41.127 +
  41.128 +	memset(list, 0, size);
  41.129 +
  41.130 +	for (i = 0; i < n; ++i) {
  41.131 +		tap_list_t *entry;
  41.132 +
  41.133 +		entry = malloc(sizeof(tap_list_t));
  41.134 +		if (!entry)
  41.135 +			goto fail;
  41.136 +
  41.137 +		memset(entry, 0, sizeof(tap_list_t));
  41.138 +
  41.139 +		list[i] = entry;
  41.140 +	}
  41.141 +
  41.142 +	return list;
  41.143 +
  41.144 +fail:
  41.145 +	if (list)
  41.146 +		tap_ctl_free_list(list);
  41.147 +
  41.148 +	return NULL;
  41.149 +}
  41.150 +
  41.151 +static int
  41.152 +tap_ctl_list_length(const tap_list_t **list)
  41.153 +{
  41.154 +	const tap_list_t **_entry;
  41.155 +	int n;
  41.156 +
  41.157 +	n = 0;
  41.158 +	for (_entry = list; *_entry != NULL; ++_entry)
  41.159 +		n++;
  41.160 +
  41.161 +	return n;
  41.162 +}
  41.163 +
  41.164 +static int
  41.165 +_tap_minor_cmp(const void *a, const void *b)
  41.166 +{
  41.167 +	return *(int*)a - *(int*)b;
  41.168 +}
  41.169 +
  41.170 +int
  41.171 +_tap_ctl_find_minors(int **_minorv)
  41.172 +{
  41.173 +	glob_t glbuf = { 0 };
  41.174 +	const char *pattern, *format;
  41.175 +	int *minorv = NULL, n_minors = 0;
  41.176 +	int err, i;
  41.177 +
  41.178 +	pattern = BLKTAP2_SYSFS_DIR"/blktap*";
  41.179 +	format  = BLKTAP2_SYSFS_DIR"/blktap%d";
  41.180 +
  41.181 +	n_minors = 0;
  41.182 +	minorv   = NULL;
  41.183 +
  41.184 +	err = glob(pattern, 0, NULL, &glbuf);
  41.185 +	switch (err) {
  41.186 +	case GLOB_NOMATCH:
  41.187 +		goto done;
  41.188 +
  41.189 +	case GLOB_ABORTED:
  41.190 +	case GLOB_NOSPACE:
  41.191 +		err = -errno;
  41.192 +		EPRINTF("%s: glob failed, err %d", pattern, err);
  41.193 +		goto fail;
  41.194 +	}
  41.195 +
  41.196 +	minorv = malloc(sizeof(int) * glbuf.gl_pathc);
  41.197 +	if (!minorv) {
  41.198 +		err = -errno;
  41.199 +		goto fail;
  41.200 +	}
  41.201 +
  41.202 +	for (i = 0; i < glbuf.gl_pathc; ++i) {
  41.203 +		int n;
  41.204 +
  41.205 +		n = sscanf(glbuf.gl_pathv[i], format, &minorv[n_minors]);
  41.206 +		if (n != 1)
  41.207 +			continue;
  41.208 +
  41.209 +		n_minors++;
  41.210 +	}
  41.211 +
  41.212 +	qsort(minorv, n_minors, sizeof(int), _tap_minor_cmp);
  41.213 +
  41.214 +done:
  41.215 +	*_minorv = minorv;
  41.216 +	err = 0;
  41.217 +
  41.218 +out:
  41.219 +	if (glbuf.gl_pathv)
  41.220 +		globfree(&glbuf);
  41.221 +
  41.222 +	return err ? : n_minors;
  41.223 +
  41.224 +fail:
  41.225 +	if (minorv)
  41.226 +		free(minorv);
  41.227 +
  41.228 +	goto out;
  41.229 +}
  41.230 +
  41.231 +struct tapdisk {
  41.232 +	int    id;
  41.233 +	pid_t  pid;
  41.234 +	struct list_head list;
  41.235 +};
  41.236 +
  41.237 +static int
  41.238 +_tap_tapdisk_cmp(const void *a, const void *b)
  41.239 +{
  41.240 +	return ((struct tapdisk*)a)->id - ((struct tapdisk*)b)->id;
  41.241 +}
  41.242 +
  41.243 +int
  41.244 +_tap_ctl_find_tapdisks(struct tapdisk **_tapv)
  41.245 +{
  41.246 +	glob_t glbuf = { 0 };
  41.247 +	const char *pattern, *format;
  41.248 +	struct tapdisk *tapv = NULL;
  41.249 +	int err, i, n_taps = 0;
  41.250 +
  41.251 +	pattern = BLKTAP2_CONTROL_DIR"/"BLKTAP2_CONTROL_SOCKET"*";
  41.252 +	format  = BLKTAP2_CONTROL_DIR"/"BLKTAP2_CONTROL_SOCKET"%d";
  41.253 +
  41.254 +	n_taps = 0;
  41.255 +	tapv   = NULL;
  41.256 +
  41.257 +	err = glob(pattern, 0, NULL, &glbuf);
  41.258 +	switch (err) {
  41.259 +	case GLOB_NOMATCH:
  41.260 +		goto done;
  41.261 +
  41.262 +	case GLOB_ABORTED:
  41.263 +	case GLOB_NOSPACE:
  41.264 +		err = -errno;
  41.265 +		EPRINTF("%s: glob failed, err %d", pattern, err);
  41.266 +		goto fail;
  41.267 +	}
  41.268 +
  41.269 +	tapv = malloc(sizeof(struct tapdisk) * glbuf.gl_pathc);
  41.270 +	if (!tapv) {
  41.271 +		err = -errno;
  41.272 +		goto fail;
  41.273 +	}
  41.274 +
  41.275 +	for (i = 0; i < glbuf.gl_pathc; ++i) {
  41.276 +		struct tapdisk *tap;
  41.277 +		int n;
  41.278 +
  41.279 +		tap = &tapv[n_taps];
  41.280 +
  41.281 +		err = sscanf(glbuf.gl_pathv[i], format, &tap->id);
  41.282 +		if (err != 1)
  41.283 +			continue;
  41.284 +
  41.285 +		tap->pid = tap_ctl_get_pid(tap->id);
  41.286 +		if (tap->pid < 0)
  41.287 +			continue;
  41.288 +
  41.289 +		n_taps++;
  41.290 +	}
  41.291 +
  41.292 +	qsort(tapv, n_taps, sizeof(struct tapdisk), _tap_tapdisk_cmp);
  41.293 +
  41.294 +	for (i = 0; i < n_taps; ++i)
  41.295 +		INIT_LIST_HEAD(&tapv[i].list);
  41.296 +
  41.297 +done:
  41.298 +	*_tapv = tapv;
  41.299 +	err = 0;
  41.300 +
  41.301 +out:
  41.302 +	if (glbuf.gl_pathv)
  41.303 +		globfree(&glbuf);
  41.304 +
  41.305 +	return err ? : n_taps;
  41.306 +
  41.307 +fail:
  41.308 +	if (tapv)
  41.309 +		free(tapv);
  41.310 +
  41.311 +	goto out;
  41.312 +}
  41.313 +
  41.314 +struct tapdisk_list {
  41.315 +	int  minor;
  41.316 +	int  state;
  41.317 +	char *params;
  41.318 +	struct list_head entry;
  41.319 +};
  41.320 +
  41.321 +int
  41.322 +_tap_ctl_list_tapdisk(int id, struct list_head *_list)
  41.323 +{
  41.324 +	tapdisk_message_t message;
  41.325 +	struct list_head list;
  41.326 +	struct tapdisk_list *tl, *next;
  41.327 +	int err, sfd;
  41.328 +
  41.329 +	err = tap_ctl_connect_id(id, &sfd);
  41.330 +	if (err)
  41.331 +		return err;
  41.332 +
  41.333 +	memset(&message, 0, sizeof(message));
  41.334 +	message.type   = TAPDISK_MESSAGE_LIST;
  41.335 +	message.cookie = -1;
  41.336 +
  41.337 +	err = tap_ctl_write_message(sfd, &message, 2);
  41.338 +	if (err)
  41.339 +		return err;
  41.340 +
  41.341 +	INIT_LIST_HEAD(&list);
  41.342 +	do {
  41.343 +		err = tap_ctl_read_message(sfd, &message, 2);
  41.344 +		if (err) {
  41.345 +			err = -EPROTO;
  41.346 +			break;
  41.347 +		}
  41.348 +
  41.349 +		if (message.u.list.count == 0)
  41.350 +			break;
  41.351 +
  41.352 +		tl = malloc(sizeof(struct tapdisk_list));
  41.353 +		if (!tl) {
  41.354 +			err = -ENOMEM;
  41.355 +			break;
  41.356 +		}
  41.357 +
  41.358 +		tl->minor  = message.u.list.minor;
  41.359 +		tl->state  = message.u.list.state;
  41.360 +		if (message.u.list.path[0] != 0) {
  41.361 +			tl->params = strndup(message.u.list.path,
  41.362 +					     sizeof(message.u.list.path));
  41.363 +			if (!tl->params) {
  41.364 +				err = -errno;
  41.365 +				break;
  41.366 +			}
  41.367 +		} else
  41.368 +			tl->params = NULL;
  41.369 +
  41.370 +		list_add(&tl->entry, &list);
  41.371 +	} while (1);
  41.372 +
  41.373 +	if (err)
  41.374 +		list_for_each_entry_safe(tl, next, &list, entry) {
  41.375 +			list_del(&tl->entry);
  41.376 +			free(tl->params);
  41.377 +			free(tl);
  41.378 +		}
  41.379 +
  41.380 +	close(sfd);
  41.381 +	list_splice(&list, _list);
  41.382 +	return err;
  41.383 +}
  41.384 +
  41.385 +void
  41.386 +_tap_ctl_free_tapdisks(struct tapdisk *tapv, int n_taps)
  41.387 +{
  41.388 +	struct tapdisk *tap;
  41.389 +
  41.390 +	for (tap = tapv; tap < &tapv[n_taps]; ++tap) {
  41.391 +		struct tapdisk_list *tl;
  41.392 +
  41.393 +		list_for_each_entry(tl, &tap->list, entry) {
  41.394 +			free(tl->params);
  41.395 +			free(tl);
  41.396 +		}
  41.397 +	}
  41.398 +
  41.399 +	free(tapv);
  41.400 +}
  41.401 +
  41.402 +int
  41.403 +_tap_list_join3(int n_minors, int *minorv, int n_taps, struct tapdisk *tapv,
  41.404 +		tap_list_t ***_list)
  41.405 +{
  41.406 +	tap_list_t **list, **_entry, *entry;
  41.407 +	int i, _m, err;
  41.408 +
  41.409 +	list = tap_ctl_alloc_list(n_minors + n_taps);
  41.410 +	if (!list) {
  41.411 +		err = -ENOMEM;
  41.412 +		goto fail;
  41.413 +	}
  41.414 +
  41.415 +	_entry = list;
  41.416 +
  41.417 +	for (i = 0; i < n_taps; ++i) {
  41.418 +		struct tapdisk *tap = &tapv[i];
  41.419 +		struct tapdisk_list *tl;
  41.420 +
  41.421 +		/* orphaned tapdisk */
  41.422 +		if (list_empty(&tap->list)) {
  41.423 +			err = init_list(*_entry++, tap->id, tap->pid, -1, -1, NULL);
  41.424 +			if (err)
  41.425 +				goto fail;
  41.426 +			continue;
  41.427 +		}
  41.428 +
  41.429 +		list_for_each_entry(tl, &tap->list, entry) {
  41.430 +
  41.431 +			err = init_list(*_entry++,
  41.432 +					tap->id, tap->pid,
  41.433 +					tl->minor, tl->state, tl->params);
  41.434 +			if (err)
  41.435 +				goto fail;
  41.436 +
  41.437 +			if (tl->minor >= 0) {
  41.438 +				/* clear minor */
  41.439 +				for (_m = 0; _m < n_minors; ++_m) {
  41.440 +					if (minorv[_m] == tl->minor) {
  41.441 +						minorv[_m] = -1;
  41.442 +						break;
  41.443 +					}
  41.444 +				}
  41.445 +			}
  41.446 +		}
  41.447 +	}
  41.448 +
  41.449 +	/* orphaned minors */
  41.450 +	for (_m = 0; _m < n_minors; ++_m) {
  41.451 +		int minor = minorv[_m];
  41.452 +		if (minor >= 0) {
  41.453 +			err = init_list(*_entry++, -1, -1, minor, -1, NULL);
  41.454 +			if (err)
  41.455 +				goto fail;
  41.456 +		}
  41.457 +	}
  41.458 +
  41.459 +	/* free extraneous list entries */
  41.460 +	for (; *_entry != NULL; ++entry) {
  41.461 +		free_list(*_entry);
  41.462 +		*_entry = NULL;
  41.463 +	}
  41.464 +
  41.465 +	*_list = list;
  41.466 +
  41.467 +	return 0;
  41.468 +
  41.469 +fail:
  41.470 +	if (list)
  41.471 +		tap_ctl_free_list(list);
  41.472 +
  41.473 +	return err;
  41.474 +}
  41.475 +
  41.476 +int
  41.477 +tap_ctl_list(tap_list_t ***list)
  41.478 +{
  41.479 +	int n_taps, n_minors, err, *minorv;
  41.480 +	struct tapdisk *tapv, *tap;
  41.481 +
  41.482 +	n_taps   = -1;
  41.483 +	n_minors = -1;
  41.484 +
  41.485 +	err = n_minors = _tap_ctl_find_minors(&minorv);
  41.486 +	if (err < 0)
  41.487 +		goto out;
  41.488 +
  41.489 +	err = n_taps = _tap_ctl_find_tapdisks(&tapv);
  41.490 +	if (err < 0)
  41.491 +		goto out;
  41.492 +
  41.493 +	for (tap = tapv; tap < &tapv[n_taps]; ++tap) {
  41.494 +		err = _tap_ctl_list_tapdisk(tap->id, &tap->list);
  41.495 +		if (err)
  41.496 +			goto out;
  41.497 +	}
  41.498 +
  41.499 +	err = _tap_list_join3(n_minors, minorv, n_taps, tapv, list);
  41.500 +
  41.501 +out:
  41.502 +	if (n_taps > 0)
  41.503 +		_tap_ctl_free_tapdisks(tapv, n_taps);
  41.504 +
  41.505 +	if (n_minors > 0)
  41.506 +		free(minorv);
  41.507 +
  41.508 +	return err;
  41.509 +}
  41.510 +
  41.511 +int
  41.512 +tap_ctl_find_minor(const char *type, const char *path)
  41.513 +{
  41.514 +	tap_list_t **list, **_entry;
  41.515 +	int minor, err;
  41.516 +
  41.517 +	err = tap_ctl_list(&list);
  41.518 +	if (err)
  41.519 +		return err;
  41.520 +
  41.521 +	minor = -1;
  41.522 +
  41.523 +	for (_entry = list; *_entry != NULL; ++_entry) {
  41.524 +		tap_list_t *entry  = *_entry;
  41.525 +
  41.526 +		if (type && (!entry->type || strcmp(entry->type, type)))
  41.527 +			continue;
  41.528 +
  41.529 +		if (path && (!entry->path || strcmp(entry->path, path)))
  41.530 +			continue;
  41.531 +
  41.532 +		minor = entry->minor;
  41.533 +		break;
  41.534 +	}
  41.535 +
  41.536 +	tap_ctl_free_list(list);
  41.537 +
  41.538 +	return minor >= 0 ? minor : -ENOENT;
  41.539 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/tools/blktap2/control/tap-ctl-major.c	Fri Jul 16 17:16:06 2010 -0700
    42.3 @@ -0,0 +1,69 @@
    42.4 +/*
    42.5 + * Copyright (c) 2008, XenSource Inc.
    42.6 + * All rights reserved.
    42.7 + *
    42.8 + * Redistribution and use in source and binary forms, with or without
    42.9 + * modification, are permitted provided that the following conditions are met:
   42.10 + *     * Redistributions of source code must retain the above copyright
   42.11 + *       notice, this list of conditions and the following disclaimer.
   42.12 + *     * Redistributions in binary form must reproduce the above copyright
   42.13 + *       notice, this list of conditions and the following disclaimer in the
   42.14 + *       documentation and/or other materials provided with the distribution.
   42.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   42.16 + *       may be used to endorse or promote products derived from this software
   42.17 + *       without specific prior written permission.
   42.18 + *
   42.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   42.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   42.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   42.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   42.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   42.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   42.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   42.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   42.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   42.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   42.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   42.30 + */
   42.31 +
   42.32 +#include <stdio.h>
   42.33 +#include <errno.h>
   42.34 +
   42.35 +#include "tap-ctl.h"
   42.36 +
   42.37 +int
   42.38 +tap_ctl_blk_major(void)
   42.39 +{
   42.40 +	FILE *devices;
   42.41 +	int rv, major;
   42.42 +
   42.43 +	devices = fopen("/proc/devices", "r");
   42.44 +	if (!devices) {
   42.45 +		rv = -errno;
   42.46 +		goto out;
   42.47 +	}
   42.48 +
   42.49 +	do {
   42.50 +		char buf[32], *s;
   42.51 +		int n, offset;
   42.52 +
   42.53 +		s = fgets(buf, sizeof(buf), devices);
   42.54 +		if (!s)
   42.55 +			break;
   42.56 +
   42.57 +		major  = -ENODEV;
   42.58 +		offset = 0;
   42.59 +
   42.60 +		n = sscanf(buf, "%d tapdev%n", &major, &offset);
   42.61 +		if (n == 1 && offset)
   42.62 +			break;
   42.63 +	} while (1);
   42.64 +
   42.65 +	rv = major;
   42.66 +
   42.67 +out:
   42.68 +	if (devices)
   42.69 +		fclose(devices);
   42.70 +
   42.71 +	return rv;
   42.72 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/tools/blktap2/control/tap-ctl-open.c	Fri Jul 16 17:16:06 2010 -0700
    43.3 @@ -0,0 +1,75 @@
    43.4 +/*
    43.5 + * Copyright (c) 2008, XenSource Inc.
    43.6 + * All rights reserved.
    43.7 + *
    43.8 + * Redistribution and use in source and binary forms, with or without
    43.9 + * modification, are permitted provided that the following conditions are met:
   43.10 + *     * Redistributions of source code must retain the above copyright
   43.11 + *       notice, this list of conditions and the following disclaimer.
   43.12 + *     * Redistributions in binary form must reproduce the above copyright
   43.13 + *       notice, this list of conditions and the following disclaimer in the
   43.14 + *       documentation and/or other materials provided with the distribution.
   43.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   43.16 + *       may be used to endorse or promote products derived from this software
   43.17 + *       without specific prior written permission.
   43.18 + *
   43.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   43.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   43.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   43.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   43.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   43.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   43.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   43.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   43.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   43.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   43.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   43.30 + */
   43.31 +#include <stdio.h>
   43.32 +#include <errno.h>
   43.33 +#include <stdlib.h>
   43.34 +#include <unistd.h>
   43.35 +#include <string.h>
   43.36 +#include <getopt.h>
   43.37 +
   43.38 +#include "tap-ctl.h"
   43.39 +#include "blktaplib.h"
   43.40 +
   43.41 +int
   43.42 +tap_ctl_open(const int id, const int minor, const char *params)
   43.43 +{
   43.44 +	int err;
   43.45 +	tapdisk_message_t message;
   43.46 +
   43.47 +	memset(&message, 0, sizeof(message));
   43.48 +	message.type = TAPDISK_MESSAGE_OPEN;
   43.49 +	message.cookie = minor;
   43.50 +	message.u.params.storage = TAPDISK_STORAGE_TYPE_DEFAULT;
   43.51 +	message.u.params.devnum = minor;
   43.52 +
   43.53 +	err = snprintf(message.u.params.path,
   43.54 +		       sizeof(message.u.params.path) - 1, "%s", params);
   43.55 +	if (err >= sizeof(message.u.params.path)) {
   43.56 +		EPRINTF("name too long\n");
   43.57 +		return ENAMETOOLONG;
   43.58 +	}
   43.59 +
   43.60 +	err = tap_ctl_connect_send_and_receive(id, &message, 5);
   43.61 +	if (err)
   43.62 +		return err;
   43.63 +
   43.64 +	switch (message.type) {
   43.65 +	case TAPDISK_MESSAGE_OPEN_RSP:
   43.66 +		break;
   43.67 +	case TAPDISK_MESSAGE_ERROR:
   43.68 +		err = -message.u.response.error;
   43.69 +		EPRINTF("open failed, err %d\n", err);
   43.70 +		break;
   43.71 +	default:
   43.72 +		EPRINTF("got unexpected result '%s' from %d\n",
   43.73 +			tapdisk_message_name(message.type), id);
   43.74 +		err = EINVAL;
   43.75 +	}
   43.76 +
   43.77 +	return err;
   43.78 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/tools/blktap2/control/tap-ctl-pause.c	Fri Jul 16 17:16:06 2010 -0700
    44.3 @@ -0,0 +1,59 @@
    44.4 +/*
    44.5 + * Copyright (c) 2008, XenSource Inc.
    44.6 + * All rights reserved.
    44.7 + *
    44.8 + * Redistribution and use in source and binary forms, with or without
    44.9 + * modification, are permitted provided that the following conditions are met:
   44.10 + *     * Redistributions of source code must retain the above copyright
   44.11 + *       notice, this list of conditions and the following disclaimer.
   44.12 + *     * Redistributions in binary form must reproduce the above copyright
   44.13 + *       notice, this list of conditions and the following disclaimer in the
   44.14 + *       documentation and/or other materials provided with the distribution.
   44.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   44.16 + *       may be used to endorse or promote products derived from this software
   44.17 + *       without specific prior written permission.
   44.18 + *
   44.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   44.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   44.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   44.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   44.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   44.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   44.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   44.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   44.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   44.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   44.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   44.30 + */
   44.31 +#include <stdio.h>
   44.32 +#include <errno.h>
   44.33 +#include <stdlib.h>
   44.34 +#include <unistd.h>
   44.35 +#include <string.h>
   44.36 +
   44.37 +#include "tap-ctl.h"
   44.38 +
   44.39 +int
   44.40 +tap_ctl_pause(const int id, const int minor)
   44.41 +{
   44.42 +	int err;
   44.43 +	tapdisk_message_t message;
   44.44 +
   44.45 +	memset(&message, 0, sizeof(message));
   44.46 +	message.type = TAPDISK_MESSAGE_PAUSE;
   44.47 +	message.cookie = minor;
   44.48 +
   44.49 +	err = tap_ctl_connect_send_and_receive(id, &message, 5);
   44.50 +	if (err)
   44.51 +		return err;
   44.52 +
   44.53 +	if (message.type == TAPDISK_MESSAGE_PAUSE_RSP)
   44.54 +		err = message.u.response.error;
   44.55 +	else {
   44.56 +		err = EINVAL;
   44.57 +		EPRINTF("got unexpected result '%s' from %d\n",
   44.58 +			tapdisk_message_name(message.type), id);
   44.59 +	}
   44.60 +
   44.61 +	return err;
   44.62 +}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/tools/blktap2/control/tap-ctl-spawn.c	Fri Jul 16 17:16:06 2010 -0700
    45.3 @@ -0,0 +1,174 @@
    45.4 +/*
    45.5 + * Copyright (c) 2008, XenSource Inc.
    45.6 + * All rights reserved.
    45.7 + *
    45.8 + * Redistribution and use in source and binary forms, with or without
    45.9 + * modification, are permitted provided that the following conditions are met:
   45.10 + *     * Redistributions of source code must retain the above copyright
   45.11 + *       notice, this list of conditions and the following disclaimer.
   45.12 + *     * Redistributions in binary form must reproduce the above copyright
   45.13 + *       notice, this list of conditions and the following disclaimer in the
   45.14 + *       documentation and/or other materials provided with the distribution.
   45.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   45.16 + *       may be used to endorse or promote products derived from this software
   45.17 + *       without specific prior written permission.
   45.18 + *
   45.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   45.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   45.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   45.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   45.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   45.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   45.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   45.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   45.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   45.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   45.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   45.30 + */
   45.31 +
   45.32 +#include <stdio.h>
   45.33 +#include <errno.h>
   45.34 +#include <unistd.h>
   45.35 +#include <stdlib.h>
   45.36 +#include <string.h>
   45.37 +#include <sys/wait.h>
   45.38 +
   45.39 +#include "tap-ctl.h"
   45.40 +#include "blktap2.h"
   45.41 +
   45.42 +static pid_t
   45.43 +__tap_ctl_spawn(int *readfd)
   45.44 +{
   45.45 +	int err, child, channel[2];
   45.46 +	char *tapdisk;
   45.47 +
   45.48 +	if (pipe(channel)) {
   45.49 +		EPRINTF("pipe failed: %d\n", errno);
   45.50 +		return -errno;
   45.51 +	}
   45.52 +
   45.53 +	if ((child = fork()) == -1) {
   45.54 +		EPRINTF("fork failed: %d\n", errno);
   45.55 +		return -errno;
   45.56 +	}
   45.57 +
   45.58 +	if (child) {
   45.59 +		close(channel[1]);
   45.60 +		*readfd = channel[0];
   45.61 +		return child;
   45.62 +	}
   45.63 +
   45.64 +	if (dup2(channel[1], STDOUT_FILENO) == -1) {
   45.65 +		EPRINTF("dup2 failed: %d\n", errno);
   45.66 +		exit(errno);
   45.67 +	}
   45.68 +
   45.69 +	if (dup2(channel[1], STDERR_FILENO) == -1) {
   45.70 +		EPRINTF("dup2 failed: %d\n", errno);
   45.71 +		exit(errno);
   45.72 +	}
   45.73 +
   45.74 +	close(channel[0]);
   45.75 +	close(channel[1]);
   45.76 +
   45.77 +	tapdisk = getenv("TAPDISK2");
   45.78 +	if (!tapdisk)
   45.79 +		tapdisk = "tapdisk2";
   45.80 +
   45.81 +	execlp(tapdisk, tapdisk, NULL);
   45.82 +
   45.83 +	EPRINTF("exec failed\n");
   45.84 +	exit(1);
   45.85 +}
   45.86 +
   45.87 +pid_t
   45.88 +tap_ctl_get_pid(const int id)
   45.89 +{
   45.90 +	int err;
   45.91 +	tapdisk_message_t message;
   45.92 +
   45.93 +	memset(&message, 0, sizeof(message));
   45.94 +	message.type = TAPDISK_MESSAGE_PID;
   45.95 +
   45.96 +	err = tap_ctl_connect_send_and_receive(id, &message, 2);
   45.97 +	if (err)
   45.98 +		return err;
   45.99 +
  45.100 +	return message.u.tapdisk_pid;
  45.101 +}
  45.102 +
  45.103 +static int
  45.104 +tap_ctl_wait(pid_t child)
  45.105 +{
  45.106 +	pid_t pid;
  45.107 +	int status;
  45.108 +
  45.109 +	pid = waitpid(child, &status, 0);
  45.110 +	if (pid < 0) {
  45.111 +		EPRINTF("wait(%d) failed, err %d\n", child, errno);
  45.112 +		return -errno;
  45.113 +	}
  45.114 +
  45.115 +	if (WIFEXITED(status)) {
  45.116 +		int code = WEXITSTATUS(status);
  45.117 +		if (code)
  45.118 +			EPRINTF("tapdisk2[%d] failed, status %d\n", child, code);
  45.119 +		return -code;
  45.120 +	}
  45.121 +
  45.122 +	if (WIFSIGNALED(status)) {
  45.123 +		int signo = WTERMSIG(status);
  45.124 +		EPRINTF("tapdisk2[%d] killed by signal %d\n", child, signo);
  45.125 +		return -EINTR;
  45.126 +	}
  45.127 +
  45.128 +	EPRINTF("tapdisk2[%d]: unexpected status %#x\n", child, status);
  45.129 +	return -EAGAIN;
  45.130 +}
  45.131 +
  45.132 +static int
  45.133 +tap_ctl_get_child_id(int readfd)
  45.134 +{
  45.135 +	int id;
  45.136 +	FILE *f;
  45.137 +
  45.138 +	f = fdopen(readfd, "r");
  45.139 +	if (!f) {
  45.140 +		EPRINTF("fdopen failed: %d\n", errno);
  45.141 +		return -1;
  45.142 +	}
  45.143 +
  45.144 +	errno = 0;
  45.145 +	if (fscanf(f, BLKTAP2_CONTROL_DIR"/"
  45.146 +		   BLKTAP2_CONTROL_SOCKET"%d", &id) != 1) {
  45.147 +		errno = (errno ? : EINVAL);
  45.148 +		EPRINTF("parsing id failed: %d\n", errno);
  45.149 +		id = -1;
  45.150 +	}
  45.151 +
  45.152 +	fclose(f);
  45.153 +	return id;
  45.154 +}
  45.155 +
  45.156 +int
  45.157 +tap_ctl_spawn(void)
  45.158 +{
  45.159 +	pid_t child;
  45.160 +	int err, id, readfd;
  45.161 +
  45.162 +	readfd = -1;
  45.163 +
  45.164 +	child = __tap_ctl_spawn(&readfd);
  45.165 +	if (child < 0)
  45.166 +		return child;
  45.167 +
  45.168 +	err = tap_ctl_wait(child);
  45.169 +	if (err)
  45.170 +		return err;
  45.171 +
  45.172 +	id = tap_ctl_get_child_id(readfd);
  45.173 +	if (id < 0)
  45.174 +		EPRINTF("get_id failed, child %d err %d\n", child, errno);
  45.175 +
  45.176 +	return id;
  45.177 +}
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/tools/blktap2/control/tap-ctl-unpause.c	Fri Jul 16 17:16:06 2010 -0700
    46.3 @@ -0,0 +1,64 @@
    46.4 +/*
    46.5 + * Copyright (c) 2008, XenSource Inc.
    46.6 + * All rights reserved.
    46.7 + *
    46.8 + * Redistribution and use in source and binary forms, with or without
    46.9 + * modification, are permitted provided that the following conditions are met:
   46.10 + *     * Redistributions of source code must retain the above copyright
   46.11 + *       notice, this list of conditions and the following disclaimer.
   46.12 + *     * Redistributions in binary form must reproduce the above copyright
   46.13 + *       notice, this list of conditions and the following disclaimer in the
   46.14 + *       documentation and/or other materials provided with the distribution.
   46.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   46.16 + *       may be used to endorse or promote products derived from this software
   46.17 + *       without specific prior written permission.
   46.18 + *
   46.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   46.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   46.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   46.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   46.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   46.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   46.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   46.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   46.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   46.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   46.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   46.30 + */
   46.31 +#include <stdio.h>
   46.32 +#include <errno.h>
   46.33 +#include <stdlib.h>
   46.34 +#include <unistd.h>
   46.35 +#include <string.h>
   46.36 +#include <getopt.h>
   46.37 +
   46.38 +#include "tap-ctl.h"
   46.39 +
   46.40 +int
   46.41 +tap_ctl_unpause(const int id, const int minor, const char *params)
   46.42 +{
   46.43 +	int err;
   46.44 +	tapdisk_message_t message;
   46.45 +
   46.46 +	memset(&message, 0, sizeof(message));
   46.47 +	message.type = TAPDISK_MESSAGE_RESUME;
   46.48 +	message.cookie = minor;
   46.49 +
   46.50 +	if (params)
   46.51 +		strncpy(message.u.params.path, params,
   46.52 +			sizeof(message.u.params.path) - 1);
   46.53 +
   46.54 +	err = tap_ctl_connect_send_and_receive(id, &message, 15);
   46.55 +	if (err)
   46.56 +		return err;
   46.57 +
   46.58 +	if (message.type == TAPDISK_MESSAGE_RESUME_RSP)
   46.59 +		err = message.u.response.error;
   46.60 +	else {
   46.61 +		err = EINVAL;
   46.62 +		EPRINTF("got unexpected result '%s' from %d\n",
   46.63 +			tapdisk_message_name(message.type), id);
   46.64 +	}
   46.65 +
   46.66 +	return err;
   46.67 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/tools/blktap2/control/tap-ctl.c	Fri Jul 16 17:16:06 2010 -0700
    47.3 @@ -0,0 +1,815 @@
    47.4 +/*
    47.5 + * Copyright (c) 2008, XenSource Inc.
    47.6 + * All rights reserved.
    47.7 + *
    47.8 + * Redistribution and use in source and binary forms, with or without
    47.9 + * modification, are permitted provided that the following conditions are met:
   47.10 + *     * Redistributions of source code must retain the above copyright
   47.11 + *       notice, this list of conditions and the following disclaimer.
   47.12 + *     * Redistributions in binary form must reproduce the above copyright
   47.13 + *       notice, this list of conditions and the following disclaimer in the
   47.14 + *       documentation and/or other materials provided with the distribution.
   47.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   47.16 + *       may be used to endorse or promote products derived from this software
   47.17 + *       without specific prior written permission.
   47.18 + *
   47.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   47.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   47.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   47.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   47.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   47.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   47.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   47.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   47.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   47.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   47.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   47.30 + */
   47.31 +
   47.32 +#include <stdio.h>
   47.33 +#include <stdlib.h>
   47.34 +#include <string.h>
   47.35 +#include <unistd.h>
   47.36 +#include <getopt.h>
   47.37 +
   47.38 +#include "tap-ctl.h"
   47.39 +
   47.40 +typedef int (*tap_ctl_func_t) (int, char **);
   47.41 +
   47.42 +struct command {
   47.43 +	char                     *name;
   47.44 +	tap_ctl_func_t            func;
   47.45 +};
   47.46 +
   47.47 +static void
   47.48 +tap_cli_list_usage(FILE *stream)
   47.49 +{
   47.50 +	fprintf(stream,
   47.51 +		"usage: list [-h] [-p pid] [-m minor] [-t type] [-f file]\n");
   47.52 +}
   47.53 +
   47.54 +static void
   47.55 +tap_ctl_list_row(tap_list_t *entry)
   47.56 +{
   47.57 +	char minor_str[10] = "-";
   47.58 +	char state_str[10] = "-";
   47.59 +	char pid_str[10]   = "-";
   47.60 +
   47.61 +	if (entry->pid != -1)
   47.62 +		sprintf(pid_str, "%d", entry->pid);
   47.63 +
   47.64 +	if (entry->minor != -1)
   47.65 +		sprintf(minor_str, "%d", entry->minor);
   47.66 +
   47.67 +	if (entry->state != -1)
   47.68 +		sprintf(state_str, "%x", entry->state);
   47.69 +
   47.70 +	printf("%8s %2s %4s %10s %s\n",
   47.71 +	       pid_str, minor_str, state_str,
   47.72 +	       entry->type ? : "-", entry->path ? : "-");
   47.73 +}
   47.74 +
   47.75 +static void
   47.76 +tap_ctl_list_dict(tap_list_t *entry)
   47.77 +{
   47.78 +	int d = 0;
   47.79 +
   47.80 +	if (entry->pid != -1) {
   47.81 +		if (d) putc(' ', stdout);
   47.82 +		d = printf("pid=%d", entry->pid);
   47.83 +	}
   47.84 +
   47.85 +	if (entry->minor != -1) {
   47.86 +		if (d) putc(' ', stdout);
   47.87 +		d = printf("minor=%d", entry->minor);
   47.88 +	}
   47.89 +
   47.90 +	if (entry->state != -1) {
   47.91 +		if (d) putc(' ', stdout);
   47.92 +		d = printf("state=%d", entry->state);
   47.93 +	}
   47.94 +
   47.95 +	if (entry->type && entry->path) {
   47.96 +		if (d) putc(' ', stdout);
   47.97 +		d = printf("args=%s:%s", entry->type, entry->path);
   47.98 +	}
   47.99 +
  47.100 +	putc('\n', stdout);
  47.101 +}
  47.102 +
  47.103 +int
  47.104 +tap_cli_list(int argc, char **argv)
  47.105 +{
  47.106 +	tap_list_t **list, **_entry;
  47.107 +	int c, minor, tty, err;
  47.108 +	const char *type, *file;
  47.109 +	pid_t pid;
  47.110 +
  47.111 +	err = tap_ctl_list(&list);
  47.112 +	if (err)
  47.113 +		return -err;
  47.114 +
  47.115 +	pid   = -1;
  47.116 +	minor = -1;
  47.117 +	type  = NULL;
  47.118 +	file  = NULL;
  47.119 +
  47.120 +	while ((c = getopt(argc, argv, "m:p:t:f:h")) != -1) {
  47.121 +		switch (c) {
  47.122 +		case 'm':
  47.123 +			minor = atoi(optarg);
  47.124 +			break;
  47.125 +		case 'p':
  47.126 +			pid = atoi(optarg);
  47.127 +			break;
  47.128 +		case 't':
  47.129 +			type = optarg;
  47.130 +			break;
  47.131 +		case 'f':
  47.132 +			file = optarg;
  47.133 +			break;
  47.134 +		case '?':
  47.135 +			goto usage;
  47.136 +		case 'h':
  47.137 +			tap_cli_list_usage(stdout);
  47.138 +			return 0;
  47.139 +		}
  47.140 +	}
  47.141 +
  47.142 +	tty = isatty(STDOUT_FILENO);
  47.143 +
  47.144 +	for (_entry = list; *_entry != NULL; ++_entry) {
  47.145 +		tap_list_t *entry  = *_entry;
  47.146 +
  47.147 +		if (minor >= 0 && entry->minor != minor)
  47.148 +			continue;
  47.149 +
  47.150 +		if (pid >= 0 && entry->pid != pid)
  47.151 +			continue;
  47.152 +
  47.153 +		if (type && (!entry->type || strcmp(entry->type, type)))
  47.154 +			continue;
  47.155 +
  47.156 +		if (file && (!entry->path || strcmp(entry->path, file)))
  47.157 +			continue;
  47.158 +
  47.159 +		if (tty)
  47.160 +			tap_ctl_list_row(entry);
  47.161 +		else
  47.162 +			tap_ctl_list_dict(entry);
  47.163 +	}
  47.164 +
  47.165 +	tap_ctl_free_list(list);
  47.166 +
  47.167 +	return 0;
  47.168 +
  47.169 +usage:
  47.170 +	tap_cli_list_usage(stderr);
  47.171 +	return EINVAL;
  47.172 +}
  47.173 +
  47.174 +static void
  47.175 +tap_cli_allocate_usage(FILE *stream)
  47.176 +{
  47.177 +	fprintf(stream, "usage: allocate [-d device name]>\n");
  47.178 +}
  47.179 +
  47.180 +static int
  47.181 +tap_cli_allocate(int argc, char **argv)
  47.182 +{
  47.183 +	char *devname;
  47.184 +	int c, minor, err;
  47.185 +
  47.186 +	devname = NULL;
  47.187 +
  47.188 +	optind = 0;
  47.189 +	while ((c = getopt(argc, argv, "d:h")) != -1) {
  47.190 +		switch (c) {
  47.191 +		case 'd':
  47.192 +			devname = optarg;
  47.193 +			break;
  47.194 +		case '?':
  47.195 +			goto usage;
  47.196 +		case 'h':
  47.197 +			tap_cli_allocate_usage(stdout);
  47.198 +			return 0;
  47.199 +		}
  47.200 +	}
  47.201 +
  47.202 +	err = tap_ctl_allocate(&minor, &devname);
  47.203 +	if (!err)
  47.204 +		printf("%s\n", devname);
  47.205 +
  47.206 +	return err;
  47.207 +
  47.208 +usage:
  47.209 +	tap_cli_allocate_usage(stderr);
  47.210 +	return EINVAL;
  47.211 +}
  47.212 +
  47.213 +static void
  47.214 +tap_cli_free_usage(FILE *stream)
  47.215 +{
  47.216 +	fprintf(stream, "usage: free <-m minor>\n");
  47.217 +}
  47.218 +
  47.219 +static int
  47.220 +tap_cli_free(int argc, char **argv)
  47.221 +{
  47.222 +	int c, minor;
  47.223 +
  47.224 +	minor = -1;
  47.225 +
  47.226 +	optind = 0;
  47.227 +	while ((c = getopt(argc, argv, "m:h")) != -1) {
  47.228 +		switch (c) {
  47.229 +		case 'm':
  47.230 +			minor = atoi(optarg);
  47.231 +			break;
  47.232 +		case '?':
  47.233 +			goto usage;
  47.234 +		case 'h':
  47.235 +			tap_cli_free_usage(stdout);
  47.236 +			return 0;
  47.237 +		}
  47.238 +	}
  47.239 +
  47.240 +	if (minor == -1)
  47.241 +		goto usage;
  47.242 +
  47.243 +	return tap_ctl_free(minor);
  47.244 +
  47.245 +usage:
  47.246 +	tap_cli_free_usage(stderr);
  47.247 +	return EINVAL;
  47.248 +}
  47.249 +
  47.250 +static void
  47.251 +tap_cli_create_usage(FILE *stream)
  47.252 +{
  47.253 +	fprintf(stream, "usage: create <-a args> [-d device name]\n");
  47.254 +}
  47.255 +
  47.256 +static int
  47.257 +tap_cli_create(int argc, char **argv)
  47.258 +{
  47.259 +	int c, err;
  47.260 +	char *args, *devname;
  47.261 +
  47.262 +	args    = NULL;
  47.263 +	devname = NULL;
  47.264 +
  47.265 +	optind = 0;
  47.266 +	while ((c = getopt(argc, argv, "a:d:h")) != -1) {
  47.267 +		switch (c) {
  47.268 +		case 'a':
  47.269 +			args = optarg;
  47.270 +			break;
  47.271 +		case 'd':
  47.272 +			devname = optarg;
  47.273 +			break;
  47.274 +		case '?':
  47.275 +			goto usage;
  47.276 +		case 'h':
  47.277 +			tap_cli_create_usage(stdout);
  47.278 +			return 0;
  47.279 +		}
  47.280 +	}
  47.281 +
  47.282 +	if (!args)
  47.283 +		goto usage;
  47.284 +
  47.285 +	err = tap_ctl_create(args, &devname);
  47.286 +	if (!err)
  47.287 +		printf("%s\n", devname);
  47.288 +
  47.289 +	return err;
  47.290 +
  47.291 +usage:
  47.292 +	tap_cli_create_usage(stderr);
  47.293 +	return EINVAL;
  47.294 +}
  47.295 +
  47.296 +static void
  47.297 +tap_cli_destroy_usage(FILE *stream)
  47.298 +{
  47.299 +	fprintf(stream, "usage: destroy <-p pid> <-m minor>\n");
  47.300 +}
  47.301 +
  47.302 +static int
  47.303 +tap_cli_destroy(int argc, char **argv)
  47.304 +{
  47.305 +	int c, pid, minor;
  47.306 +
  47.307 +	pid   = -1;
  47.308 +	minor = -1;
  47.309 +
  47.310 +	optind = 0;
  47.311 +	while ((c = getopt(argc, argv, "p:m:h")) != -1) {
  47.312 +		switch (c) {
  47.313 +		case 'p':
  47.314 +			pid = atoi(optarg);
  47.315 +			break;
  47.316 +		case 'm':
  47.317 +			minor = atoi(optarg);
  47.318 +			break;
  47.319 +		case '?':
  47.320 +			goto usage;
  47.321 +		case 'h':
  47.322 +			tap_cli_destroy_usage(stdout);
  47.323 +			return 0;
  47.324 +		}
  47.325 +	}
  47.326 +
  47.327 +	if (pid == -1 || minor == -1)
  47.328 +		goto usage;
  47.329 +
  47.330 +	return tap_ctl_destroy(pid, minor);
  47.331 +
  47.332 +usage:
  47.333 +	tap_cli_destroy_usage(stderr);
  47.334 +	return EINVAL;
  47.335 +}
  47.336 +
  47.337 +static void
  47.338 +tap_cli_spawn_usage(FILE *stream)
  47.339 +{
  47.340 +	fprintf(stream, "usage: spawn\n");
  47.341 +}
  47.342 +
  47.343 +static int
  47.344 +tap_cli_spawn(int argc, char **argv)
  47.345 +{
  47.346 +	int c;
  47.347 +	pid_t task;
  47.348 +
  47.349 +	optind = 0;
  47.350 +	while ((c = getopt(argc, argv, "h")) != -1) {
  47.351 +		switch (c) {
  47.352 +		case '?':
  47.353 +			goto usage;
  47.354 +		case 'h':
  47.355 +			tap_cli_spawn_usage(stdout);
  47.356 +			return 0;
  47.357 +		}
  47.358 +	}
  47.359 +
  47.360 +	task = tap_ctl_spawn();
  47.361 +	if (task < 0) {
  47.362 +		printf("spawn failed: %d\n", errno);
  47.363 +		return task;
  47.364 +	}
  47.365 +
  47.366 +	printf("tapdisk spawned with pid %d\n", task);
  47.367 +	return 0;
  47.368 +
  47.369 +usage:
  47.370 +	tap_cli_spawn_usage(stderr);
  47.371 +	return EINVAL;
  47.372 +}
  47.373 +
  47.374 +static void
  47.375 +tap_cli_attach_usage(FILE *stream)
  47.376 +{
  47.377 +	fprintf(stream, "usage: attach <-p pid> <-m minor>\n");
  47.378 +}
  47.379 +
  47.380 +static int
  47.381 +tap_cli_attach(int argc, char **argv)
  47.382 +{
  47.383 +	int c, pid, minor;
  47.384 +
  47.385 +	pid   = -1;
  47.386 +	minor = -1;
  47.387 +
  47.388 +	optind = 0;
  47.389 +	while ((c = getopt(argc, argv, "p:m:h")) != -1) {
  47.390 +		switch (c) {
  47.391 +		case 'p':
  47.392 +			pid = atoi(optarg);
  47.393 +			break;
  47.394 +		case 'm':
  47.395 +			minor = atoi(optarg);
  47.396 +			break;
  47.397 +		case '?':
  47.398 +			goto usage;
  47.399 +		case 'h':
  47.400 +			tap_cli_attach_usage(stderr);
  47.401 +			return 0;
  47.402 +		}
  47.403 +	}
  47.404 +
  47.405 +	if (pid == -1 || minor == -1)
  47.406 +		goto usage;
  47.407 +
  47.408 +	return tap_ctl_attach(pid, minor);
  47.409 +
  47.410 +usage:
  47.411 +	tap_cli_attach_usage(stderr);
  47.412 +	return EINVAL;
  47.413 +}
  47.414 +
  47.415 +static void
  47.416 +tap_cli_detach_usage(FILE *stream)
  47.417 +{
  47.418 +	fprintf(stream, "usage: detach <-p pid> <-m minor>\n");
  47.419 +}
  47.420 +
  47.421 +static int
  47.422 +tap_cli_detach(int argc, char **argv)
  47.423 +{
  47.424 +	int c, pid, minor;
  47.425 +
  47.426 +	pid   = -1;
  47.427 +	minor = -1;
  47.428 +
  47.429 +	optind = 0;
  47.430 +	while ((c = getopt(argc, argv, "p:m:h")) != -1) {
  47.431 +		switch (c) {
  47.432 +		case 'p':
  47.433 +			pid = atoi(optarg);
  47.434 +			break;
  47.435 +		case 'm':
  47.436 +			minor = atoi(optarg);
  47.437 +			break;
  47.438 +		case '?':
  47.439 +			goto usage;
  47.440 +		case 'h':
  47.441 +			tap_cli_detach_usage(stdout);
  47.442 +			return 0;
  47.443 +		}
  47.444 +	}
  47.445 +
  47.446 +	if (pid == -1 || minor == -1)
  47.447 +		goto usage;
  47.448 +
  47.449 +	return tap_ctl_detach(pid, minor);
  47.450 +
  47.451 +usage:
  47.452 +	tap_cli_detach_usage(stderr);
  47.453 +	return EINVAL;
  47.454 +}
  47.455 +
  47.456 +static void
  47.457 +tap_cli_close_usage(FILE *stream)
  47.458 +{
  47.459 +	fprintf(stream, "usage: close <-p pid> <-m minor> [-f force]\n");
  47.460 +}
  47.461 +
  47.462 +static int
  47.463 +tap_cli_close(int argc, char **argv)
  47.464 +{
  47.465 +	int c, pid, minor, force;
  47.466 +
  47.467 +	pid   = -1;
  47.468 +	minor = -1;
  47.469 +	force = 0;
  47.470 +
  47.471 +	optind = 0;
  47.472 +	while ((c = getopt(argc, argv, "p:m:fh")) != -1) {
  47.473 +		switch (c) {
  47.474 +		case 'p':
  47.475 +			pid = atoi(optarg);
  47.476 +			break;
  47.477 +		case 'm':
  47.478 +			minor = atoi(optarg);
  47.479 +			break;
  47.480 +		case 'f':
  47.481 +			force = -1;
  47.482 +			break;
  47.483 +		case '?':
  47.484 +			goto usage;
  47.485 +		case 'h':
  47.486 +			tap_cli_close_usage(stdout);
  47.487 +			return 0;
  47.488 +		}
  47.489 +	}
  47.490 +
  47.491 +	if (pid == -1 || minor == -1)
  47.492 +		goto usage;
  47.493 +
  47.494 +	return tap_ctl_close(pid, minor, force);
  47.495 +
  47.496 +usage:
  47.497 +	tap_cli_close_usage(stderr);
  47.498 +	return EINVAL;
  47.499 +}
  47.500 +
  47.501 +static void
  47.502 +tap_cli_pause_usage(FILE *stream)
  47.503 +{
  47.504 +	fprintf(stream, "usage: pause <-p pid> <-m minor>\n");
  47.505 +}
  47.506 +
  47.507 +static int
  47.508 +tap_cli_pause(int argc, char **argv)
  47.509 +{
  47.510 +	int c, pid, minor;
  47.511 +
  47.512 +	pid   = -1;
  47.513 +	minor = -1;
  47.514 +
  47.515 +	optind = 0;
  47.516 +	while ((c = getopt(argc, argv, "p:m:h")) != -1) {
  47.517 +		switch (c) {
  47.518 +		case 'p':
  47.519 +			pid = atoi(optarg);
  47.520 +			break;
  47.521 +		case 'm':
  47.522 +			minor = atoi(optarg);
  47.523 +			break;
  47.524 +		case '?':
  47.525 +			goto usage;
  47.526 +		case 'h':
  47.527 +			tap_cli_pause_usage(stdout);
  47.528 +			return 0;
  47.529 +		}
  47.530 +	}
  47.531 +
  47.532 +	if (pid == -1 || minor == -1)
  47.533 +		goto usage;
  47.534 +
  47.535 +	return tap_ctl_pause(pid, minor);
  47.536 +
  47.537 +usage:
  47.538 +	tap_cli_pause_usage(stderr);
  47.539 +	return EINVAL;
  47.540 +}
  47.541 +
  47.542 +static void
  47.543 +tap_cli_unpause_usage(FILE *stream)
  47.544 +{
  47.545 +	fprintf(stream, "usage: unpause <-p pid> <-m minor> [-a args]\n");
  47.546 +}
  47.547 +
  47.548 +int
  47.549 +tap_cli_unpause(int argc, char **argv)
  47.550 +{
  47.551 +	const char *args;
  47.552 +	int c, pid, minor;
  47.553 +
  47.554 +	pid   = -1;
  47.555 +	minor = -1;
  47.556 +	args  = NULL;
  47.557 +
  47.558 +	optind = 0;
  47.559 +	while ((c = getopt(argc, argv, "p:m:a:h")) != -1) {
  47.560 +		switch (c) {
  47.561 +		case 'p':
  47.562 +			pid = atoi(optarg);
  47.563 +			break;
  47.564 +		case 'm':
  47.565 +			minor = atoi(optarg);
  47.566 +			break;
  47.567 +		case 'a':
  47.568 +			args = optarg;
  47.569 +			break;
  47.570 +		case '?':
  47.571 +			goto usage;
  47.572 +		case 'h':
  47.573 +			tap_cli_unpause_usage(stdout);
  47.574 +			return 0;
  47.575 +		}
  47.576 +	}
  47.577 +
  47.578 +	if (pid == -1 || minor == -1)
  47.579 +		goto usage;
  47.580 +
  47.581 +	return tap_ctl_unpause(pid, minor, args);
  47.582 +
  47.583 +usage:
  47.584 +	tap_cli_unpause_usage(stderr);
  47.585 +	return EINVAL;
  47.586 +}
  47.587 +
  47.588 +static void
  47.589 +tap_cli_major_usage(FILE *stream)
  47.590 +{
  47.591 +	fprintf(stream, "usage: major [-h]\n");
  47.592 +}
  47.593 +
  47.594 +static int
  47.595 +tap_cli_major(int argc, char **argv)
  47.596 +{
  47.597 +	int c, chr, major;
  47.598 +
  47.599 +	chr = 0;
  47.600 +
  47.601 +	while ((c = getopt(argc, argv, "bch")) != -1) {
  47.602 +		switch (c) {
  47.603 +		case 'b':
  47.604 +			chr = 0;
  47.605 +			break;
  47.606 +		case 'c':
  47.607 +			chr = 1;
  47.608 +			break;
  47.609 +		case '?':
  47.610 +			goto usage;
  47.611 +		case 'h':
  47.612 +			tap_cli_major_usage(stdout);
  47.613 +			return 0;
  47.614 +		default:
  47.615 +			goto usage;
  47.616 +		}
  47.617 +	}
  47.618 +
  47.619 +	if (chr)
  47.620 +		major = -EINVAL;
  47.621 +	else
  47.622 +		major = tap_ctl_blk_major();
  47.623 +
  47.624 +	if (major < 0)
  47.625 +		return -major;
  47.626 +
  47.627 +	printf("%d\n", major);
  47.628 +
  47.629 +	return 0;
  47.630 +
  47.631 +usage:
  47.632 +	tap_cli_major_usage(stderr);
  47.633 +	return EINVAL;
  47.634 +}
  47.635 +
  47.636 +static void
  47.637 +tap_cli_open_usage(FILE *stream)
  47.638 +{
  47.639 +	fprintf(stream, "usage: open <-p pid> <-m minor> <-a args>\n");
  47.640 +}
  47.641 +
  47.642 +static int
  47.643 +tap_cli_open(int argc, char **argv)
  47.644 +{
  47.645 +	const char *args;
  47.646 +	int c, pid, minor;
  47.647 +
  47.648 +	pid   = -1;
  47.649 +	minor = -1;
  47.650 +	args  = NULL;
  47.651 +
  47.652 +	optind = 0;
  47.653 +	while ((c = getopt(argc, argv, "a:m:p:h")) != -1) {
  47.654 +		switch (c) {
  47.655 +		case 'p':
  47.656 +			pid = atoi(optarg);
  47.657 +			break;
  47.658 +		case 'm':
  47.659 +			minor = atoi(optarg);
  47.660 +			break;
  47.661 +		case 'a':
  47.662 +			args = optarg;
  47.663 +			break;
  47.664 +		case '?':
  47.665 +			goto usage;
  47.666 +		case 'h':
  47.667 +			tap_cli_open_usage(stdout);
  47.668 +			return 0;
  47.669 +		}
  47.670 +	}
  47.671 +
  47.672 +	if (pid == -1 || minor == -1 || !args)
  47.673 +		goto usage;
  47.674 +
  47.675 +	return tap_ctl_open(pid, minor, args);
  47.676 +
  47.677 +usage:
  47.678 +	tap_cli_open_usage(stderr);
  47.679 +	return EINVAL;
  47.680 +}
  47.681 +
  47.682 +static void
  47.683 +tap_cli_check_usage(FILE *stream)
  47.684 +{
  47.685 +	fprintf(stream, "usage: check\n"
  47.686 +		"(checks whether environment is suitable for tapdisk2)\n");
  47.687 +}
  47.688 +
  47.689 +static int
  47.690 +tap_cli_check(int argc, char **argv)
  47.691 +{
  47.692 +	int err;
  47.693 +	const char *msg;
  47.694 +
  47.695 +	if (argc != 1)
  47.696 +		goto usage;
  47.697 +
  47.698 +	err = tap_ctl_check(&msg);
  47.699 +	printf("%s\n", msg);
  47.700 +
  47.701 +	return err;
  47.702 +
  47.703 +usage:
  47.704 +	tap_cli_check_usage(stderr);
  47.705 +	return EINVAL;
  47.706 +}
  47.707 +
  47.708 +struct command commands[] = {
  47.709 +	{ .name = "list",         .func = tap_cli_list          },
  47.710 +	{ .name = "allocate",     .func = tap_cli_allocate      },
  47.711 +	{ .name = "free",         .func = tap_cli_free          },
  47.712 +	{ .name = "create",       .func = tap_cli_create        },
  47.713 +	{ .name = "destroy",      .func = tap_cli_destroy       },
  47.714 +	{ .name = "spawn",        .func = tap_cli_spawn         },
  47.715 +	{ .name = "attach",       .func = tap_cli_attach        },
  47.716 +	{ .name = "detach",       .func = tap_cli_detach        },
  47.717 +	{ .name = "open",         .func = tap_cli_open          },
  47.718 +	{ .name = "close",        .func = tap_cli_close         },
  47.719 +	{ .name = "pause",        .func = tap_cli_pause         },
  47.720 +	{ .name = "unpause",      .func = tap_cli_unpause       },
  47.721 +	{ .name = "major",        .func = tap_cli_major         },
  47.722 +	{ .name = "check",        .func = tap_cli_check         },
  47.723 +};
  47.724 +
  47.725 +#define print_commands()					\
  47.726 +	do {							\
  47.727 +		int i, n;					\
  47.728 +		n = sizeof(commands) / sizeof(struct command);	\
  47.729 +		printf("COMMAND := { ");			\
  47.730 +		printf("%s", commands[0].name);			\
  47.731 +		for (i = 1; i < n; i++)				\
  47.732 +			printf(" | %s", commands[i].name);	\
  47.733 +		printf(" }\n");					\
  47.734 +	} while (0)
  47.735 +
  47.736 +void
  47.737 +help(void)
  47.738 +{
  47.739 +	printf("usage: tap-ctl COMMAND [OPTIONS]\n");
  47.740 +	print_commands();
  47.741 +	exit(0);
  47.742 +}
  47.743 +
  47.744 +struct command *
  47.745 +get_command(char *command)
  47.746 +{
  47.747 +	int i, n;
  47.748 +
  47.749 +	if (strnlen(command, 25) >= 25)
  47.750 +		return NULL;
  47.751 +
  47.752 +	n = sizeof(commands) / sizeof (struct command);
  47.753 +
  47.754 +	for (i = 0; i < n; i++)
  47.755 +		if (!strcmp(command, commands[i].name))
  47.756 +			return &commands[i];
  47.757 +
  47.758 +	return NULL;
  47.759 +}
  47.760 +
  47.761 +int
  47.762 +main(int argc, char *argv[])
  47.763 +{
  47.764 +	char **cargv;
  47.765 +	const char *msg;
  47.766 +	struct command *cmd;
  47.767 +	int cargc, i, cnt, ret;
  47.768 +
  47.769 +#ifdef CORE_DUMP
  47.770 +	#include <sys/resource.h>
  47.771 +	struct rlimit rlim;
  47.772 +	rlim.rlim_cur = RLIM_INFINITY;
  47.773 +	rlim.rlim_max = RLIM_INFINITY;
  47.774 +	if (setrlimit(RLIMIT_CORE, &rlim) < 0)
  47.775 +		PERROR("setrlimit failed");
  47.776 +#endif
  47.777 +
  47.778 +	ret = 0;
  47.779 +
  47.780 +	if (argc < 2)
  47.781 +		help();
  47.782 +
  47.783 +	cargc = argc - 1;
  47.784 +	cmd   = get_command(argv[1]);
  47.785 +	if (!cmd) {
  47.786 +		EPRINTF("invalid COMMAND %s", argv[1]);
  47.787 +		help();
  47.788 +	}
  47.789 +
  47.790 +	ret = tap_ctl_check(&msg);
  47.791 +	if (ret) {
  47.792 +		printf("%s\n", msg);
  47.793 +		return ret;
  47.794 +	}
  47.795 +
  47.796 +	cargv = malloc(sizeof(char *) * cargc);
  47.797 +	if (!cargv)
  47.798 +		exit(ENOMEM);
  47.799 +
  47.800 +	cnt      = 1;
  47.801 +	cargv[0] = cmd->name;
  47.802 +	for (i = 1; i < cargc; i++) {
  47.803 +		char *arg = argv[i + (argc - cargc)];
  47.804 +
  47.805 +		if (!strcmp(arg, "--debug")) {
  47.806 +			tap_ctl_debug = 1;
  47.807 +			continue;
  47.808 +		}
  47.809 +
  47.810 +		cargv[cnt++] = arg;
  47.811 +	}
  47.812 +
  47.813 +	ret = cmd->func(cnt, cargv);
  47.814 +
  47.815 +	free(cargv);
  47.816 +
  47.817 +	return (ret >= 0 ? ret : -ret);
  47.818 +}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/tools/blktap2/control/tap-ctl.h	Fri Jul 16 17:16:06 2010 -0700
    48.3 @@ -0,0 +1,101 @@
    48.4 +/*
    48.5 + * Copyright (c) 2008, XenSource Inc.
    48.6 + * All rights reserved.
    48.7 + *
    48.8 + * Redistribution and use in source and binary forms, with or without
    48.9 + * modification, are permitted provided that the following conditions are met:
   48.10 + *     * Redistributions of source code must retain the above copyright
   48.11 + *       notice, this list of conditions and the following disclaimer.
   48.12 + *     * Redistributions in binary form must reproduce the above copyright
   48.13 + *       notice, this list of conditions and the following disclaimer in the
   48.14 + *       documentation and/or other materials provided with the distribution.
   48.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   48.16 + *       may be used to endorse or promote products derived from this software
   48.17 + *       without specific prior written permission.
   48.18 + *
   48.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   48.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   48.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   48.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   48.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   48.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   48.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   48.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   48.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   48.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   48.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   48.30 + */
   48.31 +#ifndef __TAP_CTL_H__
   48.32 +#define __TAP_CTL_H__
   48.33 +
   48.34 +#include <syslog.h>
   48.35 +#include <errno.h>
   48.36 +#include <tapdisk-message.h>
   48.37 +
   48.38 +extern int tap_ctl_debug;
   48.39 +
   48.40 +#ifdef TAPCTL
   48.41 +#define DBG(_f, _a...)				\
   48.42 +	do {					\
   48.43 +		if (tap_ctl_debug)		\
   48.44 +			printf(_f, ##_a);	\
   48.45 +	} while (0)
   48.46 +
   48.47 +#define DPRINTF(_f, _a...) syslog(LOG_INFO, _f, ##_a)
   48.48 +#define EPRINTF(_f, _a...) syslog(LOG_ERR, "tap-err:%s: " _f, __func__, ##_a)
   48.49 +#define  PERROR(_f, _a...) syslog(LOG_ERR, "tap-err:%s: " _f ": %s", __func__, ##_a, \
   48.50 +				  strerror(errno))
   48.51 +#endif
   48.52 +
   48.53 +void tap_ctl_version(int *major, int *minor);
   48.54 +int tap_ctl_kernel_version(int *major, int *minor);
   48.55 +
   48.56 +int tap_ctl_check_blktap(const char **message);
   48.57 +int tap_ctl_check_version(const char **message);
   48.58 +int tap_ctl_check(const char **message);
   48.59 +
   48.60 +int tap_ctl_connect(const char *path, int *socket);
   48.61 +int tap_ctl_connect_id(int id, int *socket);
   48.62 +int tap_ctl_read_message(int fd, tapdisk_message_t *message, int timeout);
   48.63 +int tap_ctl_write_message(int fd, tapdisk_message_t *message, int timeout);
   48.64 +int tap_ctl_send_and_receive(int fd, tapdisk_message_t *message, int timeout);
   48.65 +int tap_ctl_connect_send_and_receive(int id,
   48.66 +				     tapdisk_message_t *message, int timeout);
   48.67 +char *tap_ctl_socket_name(int id);
   48.68 +
   48.69 +typedef struct {
   48.70 +	int         id;
   48.71 +	pid_t       pid;
   48.72 +	int         minor;
   48.73 +	int         state;
   48.74 +	char       *type;
   48.75 +	char       *path;
   48.76 +} tap_list_t;
   48.77 +
   48.78 +int tap_ctl_get_driver_id(const char *handle);
   48.79 +
   48.80 +int tap_ctl_list(tap_list_t ***list);
   48.81 +void tap_ctl_free_list(tap_list_t **list);
   48.82 +int tap_ctl_find_minor(const char *type, const char *path);
   48.83 +
   48.84 +int tap_ctl_allocate(int *minor, char **devname);
   48.85 +int tap_ctl_free(const int minor);
   48.86 +
   48.87 +int tap_ctl_create(const char *params, char **devname);
   48.88 +int tap_ctl_destroy(const int id, const int minor);
   48.89 +
   48.90 +int tap_ctl_spawn(void);
   48.91 +pid_t tap_ctl_get_pid(const int id);
   48.92 +
   48.93 +int tap_ctl_attach(const int id, const int minor);
   48.94 +int tap_ctl_detach(const int id, const int minor);
   48.95 +
   48.96 +int tap_ctl_open(const int id, const int minor, const char *params);
   48.97 +int tap_ctl_close(const int id, const int minor, const int force);
   48.98 +
   48.99 +int tap_ctl_pause(const int id, const int minor);
  48.100 +int tap_ctl_unpause(const int id, const int minor, const char *params);
  48.101 +
  48.102 +int tap_ctl_blk_major(void);
  48.103 +
  48.104 +#endif
    49.1 --- a/tools/blktap2/drivers/Makefile	Wed Jun 09 19:53:32 2010 -0700
    49.2 +++ b/tools/blktap2/drivers/Makefile	Fri Jul 16 17:16:06 2010 -0700
    49.3 @@ -12,8 +12,7 @@ INST_DIR   = $(SBINDIR)
    49.4  CFLAGS    += -Werror -g -O0
    49.5  CFLAGS    += -Wno-unused
    49.6  CFLAGS    += -fno-strict-aliasing
    49.7 -CFLAGS    += -I../lib -I../../libxc
    49.8 -CFLAGS    += -I../include -I../../include
    49.9 +CFLAGS    += -I$(BLKTAP_ROOT)/include -I$(BLKTAP_ROOT)/drivers
   49.10  CFLAGS    += $(CFLAGS_libxenctrl)
   49.11  CFLAGS    += -I $(LIBAIO_DIR)
   49.12  CFLAGS    += -I $(MEMSHR_DIR)
   49.13 @@ -26,18 +25,6 @@ endif
   49.14  
   49.15  LIBS      += -lrt -lz
   49.16  
   49.17 -ifeq ($(CONFIG_Linux),y)
   49.18 -ifeq ($(shell . ./check_gcrypt $(CC)),yes)
   49.19 -CFLAGS += -DUSE_GCRYPT
   49.20 -CRYPT_LIB += -lgcrypt
   49.21 -else
   49.22 -CRYPT_LIB += -lcrypto
   49.23 -$(warning === libgcrypt not installed: falling back to libcrypto ===)
   49.24 -endif
   49.25 -else
   49.26 -CRYPT_LIB += -lcrypto
   49.27 -endif
   49.28 -
   49.29  LDFLAGS_img := $(LDFLAGS_libxenctrl) $(CRYPT_LIB) -lpthread -lz -lm
   49.30  
   49.31  LIBS += -L$(LIBVHDDIR) -lvhd
   49.32 @@ -74,10 +61,11 @@ PORTABLE-OBJS-$(CONFIG_Linux)  += blk_li
   49.33  PORTABLE-OBJS-$(CONFIG_NetBSD) += blk_netbsd.o
   49.34  
   49.35  TAP-OBJS-y  := scheduler.o
   49.36 -TAP-OBJS-y  += tapdisk-ipc.o
   49.37  TAP-OBJS-y  += tapdisk-vbd.o
   49.38 +TAP-OBJS-y  += tapdisk-control.o
   49.39  TAP-OBJS-y  += tapdisk-image.o
   49.40  TAP-OBJS-y  += tapdisk-driver.o
   49.41 +TAP-OBJS-y  += tapdisk-disktype.o
   49.42  TAP-OBJS-y  += tapdisk-interface.o
   49.43  TAP-OBJS-y  += tapdisk-server.o
   49.44  TAP-OBJS-y  += tapdisk-queue.o
   49.45 @@ -97,6 +85,7 @@ BLK-OBJS-y  += block-vhd.o
   49.46  BLK-OBJS-y  += block-log.o
   49.47  BLK-OBJS-y  += block-qcow.o
   49.48  BLK-OBJS-y  += aes.o
   49.49 +BLK-OBJS-y  += md5.o
   49.50  BLK-OBJS-y  += $(PORTABLE-OBJS-y)
   49.51  BLK-OBJS-y  += $(REMUS-OBJS)
   49.52  
    50.1 --- a/tools/blktap2/drivers/blktap2.h	Wed Jun 09 19:53:32 2010 -0700
    50.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.3 @@ -1,66 +0,0 @@
    50.4 -/*
    50.5 - * Copyright (c) 2008, XenSource Inc.
    50.6 - * All rights reserved.
    50.7 - *
    50.8 - * Redistribution and use in source and binary forms, with or without
    50.9 - * modification, are permitted provided that the following conditions are met:
   50.10 - *     * Redistributions of source code must retain the above copyright
   50.11 - *       notice, this list of conditions and the following disclaimer.
   50.12 - *     * Redistributions in binary form must reproduce the above copyright
   50.13 - *       notice, this list of conditions and the following disclaimer in the
   50.14 - *       documentation and/or other materials provided with the distribution.
   50.15 - *     * Neither the name of XenSource Inc. nor the names of its contributors
   50.16 - *       may be used to endorse or promote products derived from this software
   50.17 - *       without specific prior written permission.
   50.18 - *
   50.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   50.20 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   50.21 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   50.22 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   50.23 - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   50.24 - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   50.25 - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   50.26 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   50.27 - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   50.28 - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   50.29 - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   50.30 - */
   50.31 -#ifndef _BLKTAP_2_H_
   50.32 -#define _BLKTAP_2_H_
   50.33 -
   50.34 -#define MISC_MAJOR_NUMBER              10
   50.35 -
   50.36 -#define BLKTAP2_MAX_MESSAGE_LEN        256
   50.37 -
   50.38 -#define BLKTAP2_RING_MESSAGE_PAUSE     1
   50.39 -#define BLKTAP2_RING_MESSAGE_RESUME    2
   50.40 -#define BLKTAP2_RING_MESSAGE_CLOSE     3
   50.41 -
   50.42 -#define BLKTAP2_IOCTL_KICK_FE          1
   50.43 -#define BLKTAP2_IOCTL_ALLOC_TAP        200
   50.44 -#define BLKTAP2_IOCTL_FREE_TAP         201
   50.45 -#define BLKTAP2_IOCTL_CREATE_DEVICE    202
   50.46 -#define BLKTAP2_IOCTL_SET_PARAMS       203
   50.47 -#define BLKTAP2_IOCTL_PAUSE            204
   50.48 -#define BLKTAP2_IOCTL_REOPEN           205
   50.49 -#define BLKTAP2_IOCTL_RESUME           206
   50.50 -
   50.51 -#define BLKTAP2_CONTROL_NAME           "blktap-control"
   50.52 -#define BLKTAP2_DIRECTORY              "/dev/xen/blktap-2"
   50.53 -#define BLKTAP2_CONTROL_DEVICE         BLKTAP2_DIRECTORY"/control"
   50.54 -#define BLKTAP2_RING_DEVICE            BLKTAP2_DIRECTORY"/blktap"
   50.55 -#define BLKTAP2_IO_DEVICE              BLKTAP2_DIRECTORY"/tapdev"
   50.56 -
   50.57 -struct blktap2_handle {
   50.58 -	unsigned int                   ring;
   50.59 -	unsigned int                   device;
   50.60 -	unsigned int                   minor;
   50.61 -};
   50.62 -
   50.63 -struct blktap2_params {
   50.64 -	char                           name[BLKTAP2_MAX_MESSAGE_LEN];
   50.65 -	unsigned long long             capacity;
   50.66 -	unsigned long                  sector_size;
   50.67 -};
   50.68 -
   50.69 -#endif
    51.1 --- a/tools/blktap2/drivers/block-qcow.c	Wed Jun 09 19:53:32 2010 -0700
    51.2 +++ b/tools/blktap2/drivers/block-qcow.c	Fri Jul 16 17:16:06 2010 -0700
    51.3 @@ -33,14 +33,15 @@
    51.4  #include <zlib.h>
    51.5  #include <inttypes.h>
    51.6  #include <libaio.h>
    51.7 -#include <openssl/md5.h>
    51.8  #include <limits.h>
    51.9  #include "bswap.h"
   51.10  #include "aes.h"
   51.11 +#include "md5.h"
   51.12  
   51.13  #include "tapdisk.h"
   51.14  #include "tapdisk-driver.h"
   51.15  #include "tapdisk-interface.h"
   51.16 +#include "tapdisk-disktype.h"
   51.17  #include "qcow.h"
   51.18  #include "blk.h"
   51.19  #include "atomicio.h"
   51.20 @@ -80,47 +81,17 @@ struct qcow_request {
   51.21  
   51.22  static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset);
   51.23  
   51.24 -#ifdef USE_GCRYPT
   51.25 -
   51.26 -#include <gcrypt.h>
   51.27 -
   51.28  uint32_t gen_cksum(char *ptr, int len)
   51.29  {
   51.30    int i;
   51.31    uint32_t md[4];
   51.32  
   51.33    /* Generate checksum */
   51.34 -  gcry_md_hash_buffer(GCRY_MD_MD5, md, ptr, len);
   51.35 +  md5_sum((const uint8_t*)ptr, len, (uint8_t*)md);
   51.36  
   51.37    return md[0];
   51.38  }
   51.39  
   51.40 -#else /* use libcrypto */
   51.41 -
   51.42 -#include <openssl/md5.h>
   51.43 -
   51.44 -uint32_t gen_cksum(char *ptr, int len)
   51.45 -{
   51.46 -  int i;
   51.47 -  unsigned char *md;
   51.48 -  uint32_t ret;
   51.49 -
   51.50 -  md = malloc(MD5_DIGEST_LENGTH);
   51.51 -  if(!md) return 0;
   51.52 -
   51.53 -  /* Generate checksum */
   51.54 -  if (MD5((unsigned char *)ptr, len, md) != md)
   51.55 -    ret = 0;
   51.56 -  else
   51.57 -    memcpy(&ret, md, sizeof(uint32_t));
   51.58 -
   51.59 -  free(md);
   51.60 -  return ret;
   51.61 -}
   51.62 -
   51.63 -#endif
   51.64 -
   51.65 -
   51.66  static void free_aio_state(struct tdqcow_state* s)
   51.67  {
   51.68  	free(s->aio_requests);
    52.1 --- a/tools/blktap2/drivers/block-remus.c	Wed Jun 09 19:53:32 2010 -0700
    52.2 +++ b/tools/blktap2/drivers/block-remus.c	Fri Jul 16 17:16:06 2010 -0700
    52.3 @@ -33,7 +33,6 @@
    52.4  
    52.5  /* due to architectural choices in tapdisk, block-buffer is forced to
    52.6   * reimplement some code which is meant to be private */
    52.7 -#define TAPDISK
    52.8  #include "tapdisk.h"
    52.9  #include "tapdisk-server.h"
   52.10  #include "tapdisk-driver.h"
   52.11 @@ -98,6 +97,7 @@ struct req_ring {
   52.12   */
   52.13  td_vbd_t *device_vbd = NULL;
   52.14  td_image_t *remus_image = NULL;
   52.15 +struct tap_disk tapdisk_remus;
   52.16  
   52.17  struct ramdisk {
   52.18  	size_t sector_size;
    53.1 --- a/tools/blktap2/drivers/block-vhd.c	Wed Jun 09 19:53:32 2010 -0700
    53.2 +++ b/tools/blktap2/drivers/block-vhd.c	Fri Jul 16 17:16:06 2010 -0700
    53.3 @@ -58,6 +58,7 @@
    53.4  #include "tapdisk.h"
    53.5  #include "tapdisk-driver.h"
    53.6  #include "tapdisk-interface.h"
    53.7 +#include "tapdisk-disktype.h"
    53.8  
    53.9  unsigned int SPB;
   53.10  
    54.1 --- a/tools/blktap2/drivers/disktypes.h	Wed Jun 09 19:53:32 2010 -0700
    54.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.3 @@ -1,197 +0,0 @@
    54.4 -/* 
    54.5 - * Copyright (c) 2007, XenSource Inc.
    54.6 - * All rights reserved.
    54.7 - *
    54.8 - * Redistribution and use in source and binary forms, with or without
    54.9 - * modification, are permitted provided that the following conditions are met:
   54.10 - *     * Redistributions of source code must retain the above copyright
   54.11 - *       notice, this list of conditions and the following disclaimer.
   54.12 - *     * Redistributions in binary form must reproduce the above copyright
   54.13 - *       notice, this list of conditions and the following disclaimer in the
   54.14 - *       documentation and/or other materials provided with the distribution.
   54.15 - *     * Neither the name of XenSource Inc. nor the names of its contributors
   54.16 - *       may be used to endorse or promote products derived from this software
   54.17 - *       without specific prior written permission.
   54.18 - *
   54.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   54.20 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   54.21 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   54.22 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   54.23 - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   54.24 - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   54.25 - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   54.26 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   54.27 - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   54.28 - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   54.29 - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   54.30 - */
   54.31 -
   54.32 -#ifndef __DISKTYPES_H__
   54.33 -#define __DISKTYPES_H__
   54.34 -
   54.35 -typedef struct disk_info {
   54.36 -       int  idnum;
   54.37 -       char name[50];       /* e.g. "RAMDISK" */
   54.38 -       char handle[10];     /* xend handle, e.g. 'ram' */
   54.39 -       int  single_handler; /* is there a single controller for all */
   54.40 -                            /* instances of disk type? */
   54.41 -#ifdef TAPDISK
   54.42 -       struct tap_disk *drv;
   54.43 -#endif
   54.44 -} disk_info_t;
   54.45 -
   54.46 -extern struct tap_disk tapdisk_aio;
   54.47 -/* extern struct tap_disk tapdisk_sync;    */
   54.48 -/* extern struct tap_disk tapdisk_vmdk;    */
   54.49 -/* extern struct tap_disk tapdisk_vhdsync; */
   54.50 -extern struct tap_disk tapdisk_vhd;
   54.51 -extern struct tap_disk tapdisk_ram;
   54.52 - extern struct tap_disk tapdisk_qcow; 
   54.53 -extern struct tap_disk tapdisk_block_cache;
   54.54 -extern struct tap_disk tapdisk_log;
   54.55 -extern struct tap_disk tapdisk_remus;
   54.56 -
   54.57 -#define MAX_DISK_TYPES        20
   54.58 -
   54.59 -#define DISK_TYPE_AIO         0
   54.60 -#define DISK_TYPE_SYNC        1
   54.61 -#define DISK_TYPE_VMDK        2
   54.62 -#define DISK_TYPE_VHDSYNC     3
   54.63 -#define DISK_TYPE_VHD         4
   54.64 -#define DISK_TYPE_RAM         5
   54.65 -#define DISK_TYPE_QCOW        6
   54.66 -#define DISK_TYPE_BLOCK_CACHE 7
   54.67 -#define DISK_TYPE_LOG         9
   54.68 -#define DISK_TYPE_REMUS       10
   54.69 -
   54.70 -/*Define Individual Disk Parameters here */
   54.71 -static disk_info_t null_disk = {
   54.72 -       -1,
   54.73 -       "null disk",
   54.74 -       "null",
   54.75 -       0,
   54.76 -#ifdef TAPDISK
   54.77 -       0,
   54.78 -#endif
   54.79 -};
   54.80 -
   54.81 -static disk_info_t aio_disk = {
   54.82 -       DISK_TYPE_AIO,
   54.83 -       "raw image (aio)",
   54.84 -       "aio",
   54.85 -       0,
   54.86 -#ifdef TAPDISK
   54.87 -       &tapdisk_aio,
   54.88 -#endif
   54.89 -};
   54.90 -/*
   54.91 -static disk_info_t sync_disk = {
   54.92 -       DISK_TYPE_SYNC,
   54.93 -       "raw image (sync)",
   54.94 -       "sync",
   54.95 -       0,
   54.96 -#ifdef TAPDISK
   54.97 -       &tapdisk_sync,
   54.98 -#endif
   54.99 -};
  54.100 -
  54.101 -static disk_info_t vmdk_disk = {
  54.102 -       DISK_TYPE_VMDK,
  54.103 -       "vmware image (vmdk)",
  54.104 -       "vmdk",
  54.105 -       1,
  54.106 -#ifdef TAPDISK
  54.107 -       &tapdisk_vmdk,
  54.108 -#endif
  54.109 -};
  54.110 -
  54.111 -static disk_info_t vhdsync_disk = {
  54.112 -       DISK_TYPE_VHDSYNC,
  54.113 -       "virtual server image (vhd) - synchronous",
  54.114 -       "vhdsync",
  54.115 -       1,
  54.116 -#ifdef TAPDISK
  54.117 -       &tapdisk_vhdsync,
  54.118 -#endif
  54.119 -};
  54.120 -*/
  54.121 -
  54.122 -static disk_info_t vhd_disk = {
  54.123 -       DISK_TYPE_VHD,
  54.124 -       "virtual server image (vhd)",
  54.125 -       "vhd",
  54.126 -       0,
  54.127 -#ifdef TAPDISK
  54.128 -       &tapdisk_vhd,
  54.129 -#endif
  54.130 -};
  54.131 -
  54.132 -
  54.133 -static disk_info_t ram_disk = {
  54.134 -       DISK_TYPE_RAM,
  54.135 -       "ramdisk image (ram)",
  54.136 -       "ram",
  54.137 -       1,
  54.138 -#ifdef TAPDISK
  54.139 -       &tapdisk_ram,
  54.140 -#endif
  54.141 -};
  54.142 -
  54.143 -
  54.144 -static disk_info_t qcow_disk = {
  54.145 -       DISK_TYPE_QCOW,
  54.146 -       "qcow disk (qcow)",
  54.147 -       "qcow",
  54.148 -       0,
  54.149 -#ifdef TAPDISK
  54.150 -       &tapdisk_qcow,
  54.151 -#endif
  54.152 -};
  54.153 -
  54.154 -
  54.155 -static disk_info_t block_cache_disk = {
  54.156 -       DISK_TYPE_BLOCK_CACHE,
  54.157 -       "block cache image (bc)",
  54.158 -       "bc",
  54.159 -       1,
  54.160 -#ifdef TAPDISK
  54.161 -       &tapdisk_block_cache,
  54.162 -#endif
  54.163 -};
  54.164 -
  54.165 -static disk_info_t log_disk = {
  54.166 -	DISK_TYPE_LOG,
  54.167 -	"write logger (log)",
  54.168 -	"log",
  54.169 -	0,
  54.170 -#ifdef TAPDISK
  54.171 -	&tapdisk_log,
  54.172 -#endif
  54.173 -};
  54.174 -
  54.175 -static disk_info_t remus_disk = {
  54.176 -       DISK_TYPE_REMUS,
  54.177 -       "remus disk replicator (remus)",
  54.178 -       "remus",
  54.179 -       0,
  54.180 -#ifdef TAPDISK
  54.181 -       &tapdisk_remus,
  54.182 -#endif
  54.183 -};
  54.184 -
  54.185 -/*Main disk info array */
  54.186 -static disk_info_t *dtypes[] = {
  54.187 -       &aio_disk,
  54.188 -       &null_disk, /* &sync_disk, */
  54.189 -       &null_disk, /* &vmdk_disk, */
  54.190 -        &null_disk, /* &vhdsync_disk, */
  54.191 -       &vhd_disk,
  54.192 -       &ram_disk,
  54.193 -       &qcow_disk,
  54.194 -       &block_cache_disk,
  54.195 -       &null_disk,
  54.196 -       &log_disk,
  54.197 -       &remus_disk,
  54.198 -};
  54.199 -
  54.200 -#endif
    55.1 --- a/tools/blktap2/drivers/img2qcow.c	Wed Jun 09 19:53:32 2010 -0700
    55.2 +++ b/tools/blktap2/drivers/img2qcow.c	Fri Jul 16 17:16:06 2010 -0700
    55.3 @@ -41,7 +41,6 @@
    55.4  #include <zlib.h>
    55.5  #include <inttypes.h>
    55.6  #include <libaio.h>
    55.7 -#include <openssl/md5.h>
    55.8  
    55.9  #include "bswap.h"
   55.10  #include "aes.h"
   55.11 @@ -49,6 +48,7 @@
   55.12  #include "tapdisk-server.h"
   55.13  #include "tapdisk-driver.h"
   55.14  #include "tapdisk-interface.h"
   55.15 +#include "tapdisk-disktype.h"
   55.16  #include "qcow.h"
   55.17  #include "blk.h"
   55.18  
   55.19 @@ -64,8 +64,6 @@
   55.20  #define O_LARGEFILE	0
   55.21  #endif
   55.22  
   55.23 -
   55.24 -#define TAPDISK 1
   55.25  #define BLOCK_PROCESSSZ 4096
   55.26  #define QCOW_VBD 0
   55.27  #define PROGRESS_QUANT 2
   55.28 @@ -201,13 +199,13 @@ int main(int argc, const char *argv[])
   55.29  			(uint64_t)info.size);
   55.30  	
   55.31          /* Open Qcow image*/
   55.32 -        err = tapdisk_server_initialize(NULL, NULL);
   55.33 +        err = tapdisk_server_initialize();
   55.34          if( err ) {
   55.35            DPRINTF("qcow2raw Couldn't initialize server instance.\n");
   55.36            return err;
   55.37          }
   55.38  
   55.39 -        err=tapdisk_vbd_initialize(-1,-1, QCOW_VBD);
   55.40 +        err=tapdisk_vbd_initialize(QCOW_VBD);
   55.41          if( err ) {
   55.42            DPRINTF("qcow2raw Couldn't initialize qcow vbd.\n");
   55.43            return err;
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/tools/blktap2/drivers/md5.c	Fri Jul 16 17:16:06 2010 -0700
    56.3 @@ -0,0 +1,278 @@
    56.4 +/* start - public domain MD5 implementation */
    56.5 +/*
    56.6 + * This code implements the MD5 message-digest algorithm.
    56.7 + * The algorithm is due to Ron Rivest.  This code was
    56.8 + * written by Colin Plumb in 1993, no copyright is claimed.
    56.9 + * This code is in the public domain; do with it what you wish.
   56.10 + *
   56.11 + * Equivalent code is available from RSA Data Security, Inc.
   56.12 + * This code has been tested against that, and is equivalent,
   56.13 + * except that you don't need to include two pages of legalese
   56.14 + * with every copy.
   56.15 + *
   56.16 + * To compute the message digest of a chunk of bytes, declare an
   56.17 + * MD5Context structure, pass it to MD5Init, call MD5Update as
   56.18 + * needed on buffers full of bytes, and then call MD5Final, which
   56.19 + * will fill a supplied 16-byte array with the digest.
   56.20 + */
   56.21 +
   56.22 +#include <string.h>
   56.23 +#include <stdint.h>
   56.24 +
   56.25 +struct MD5Context {
   56.26 +        uint32_t buf[4];
   56.27 +        uint32_t bits[2];
   56.28 +        uint8_t in[64];
   56.29 +};
   56.30 +
   56.31 +static void MD5Init(struct MD5Context *context);
   56.32 +static void MD5Update(struct MD5Context *context, unsigned char const *buf,
   56.33 +                          unsigned len);
   56.34 +static void MD5Final(unsigned char digest[16], struct MD5Context *context);
   56.35 +static void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
   56.36 +
   56.37 +
   56.38 +typedef struct MD5Context MD5_CTX;
   56.39 +
   56.40 +
   56.41 +/**
   56.42 + * md5_sum - MD5 hash for a data block
   56.43 + * @addr: Pointers to the data area
   56.44 + * @len: Lengths of the data block
   56.45 + * @mac: Buffer for the hash
   56.46 + */
   56.47 +void md5_sum(const uint8_t *addr, const size_t len, uint8_t *mac)
   56.48 +{
   56.49 +        MD5_CTX ctx;
   56.50 +
   56.51 +        MD5Init(&ctx);
   56.52 +       MD5Update(&ctx, addr, len);
   56.53 +        MD5Final(mac, &ctx);
   56.54 +}
   56.55 +
   56.56 +
   56.57 +#ifndef WORDS_BIGENDIAN
   56.58 +#define byteReverse(buf, len)   /* Nothing */
   56.59 +#else
   56.60 +/*
   56.61 + * Note: this code is harmless on little-endian machines.
   56.62 + */
   56.63 +static void byteReverse(unsigned char *buf, unsigned longs)
   56.64 +{
   56.65 +    uint32_t t;
   56.66 +    do {
   56.67 +        t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
   56.68 +            ((unsigned) buf[1] << 8 | buf[0]);
   56.69 +        *(uint32_t *) buf = t;
   56.70 +        buf += 4;
   56.71 +    } while (--longs);
   56.72 +}
   56.73 +#endif
   56.74 +
   56.75 +/*
   56.76 + * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
   56.77 + * initialization constants.
   56.78 + */
   56.79 +void MD5Init(struct MD5Context *ctx)
   56.80 +{
   56.81 +    ctx->buf[0] = 0x67452301;
   56.82 +    ctx->buf[1] = 0xefcdab89;
   56.83 +    ctx->buf[2] = 0x98badcfe;
   56.84 +    ctx->buf[3] = 0x10325476;
   56.85 +
   56.86 +    ctx->bits[0] = 0;
   56.87 +    ctx->bits[1] = 0;
   56.88 +}
   56.89 +
   56.90 +/*
   56.91 + * Update context to reflect the concatenation of another buffer full
   56.92 + * of bytes.
   56.93 + */
   56.94 +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
   56.95 +{
   56.96 +    uint32_t t;
   56.97 +
   56.98 +    /* Update bitcount */
   56.99 +
  56.100 +    t = ctx->bits[0];
  56.101 +    if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
  56.102 +        ctx->bits[1]++;         /* Carry from low to high */
  56.103 +    ctx->bits[1] += len >> 29;
  56.104 +
  56.105 +    t = (t >> 3) & 0x3f;        /* Bytes already in shsInfo->data */
  56.106 +
  56.107 +    /* Handle any leading odd-sized chunks */
  56.108 +
  56.109 +    if (t) {
  56.110 +        unsigned char *p = (unsigned char *) ctx->in + t;
  56.111 +
  56.112 +        t = 64 - t;
  56.113 +        if (len < t) {
  56.114 +            memcpy(p, buf, len);
  56.115 +            return;
  56.116 +        }
  56.117 +        memcpy(p, buf, t);
  56.118 +        byteReverse(ctx->in, 16);
  56.119 +        MD5Transform(ctx->buf, (uint32_t *) ctx->in);
  56.120 +        buf += t;
  56.121 +        len -= t;
  56.122 +    }
  56.123 +    /* Process data in 64-byte chunks */
  56.124 +
  56.125 +    while (len >= 64) {
  56.126 +        memcpy(ctx->in, buf, 64);
  56.127 +        byteReverse(ctx->in, 16);
  56.128 +        MD5Transform(ctx->buf, (uint32_t *) ctx->in);
  56.129 +        buf += 64;
  56.130 +        len -= 64;
  56.131 +    }
  56.132 +
  56.133 +    /* Handle any remaining bytes of data. */
  56.134 +
  56.135 +    memcpy(ctx->in, buf, len);
  56.136 +}
  56.137 +
  56.138 +/*
  56.139 + * Final wrapup - pad to 64-byte boundary with the bit pattern
  56.140 + * 1 0* (64-bit count of bits processed, MSB-first)
  56.141 + */
  56.142 +void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
  56.143 +{
  56.144 +    unsigned count;
  56.145 +    unsigned char *p;
  56.146 +
  56.147 +    /* Compute number of bytes mod 64 */
  56.148 +    count = (ctx->bits[0] >> 3) & 0x3F;
  56.149 +
  56.150 +    /* Set the first char of padding to 0x80.  This is safe since there is
  56.151 +       always at least one byte free */
  56.152 +    p = ctx->in + count;
  56.153 +    *p++ = 0x80;
  56.154 +
  56.155 +    /* Bytes of padding needed to make 64 bytes */
  56.156 +    count = 64 - 1 - count;
  56.157 +
  56.158 +    /* Pad out to 56 mod 64 */
  56.159 +    if (count < 8) {
  56.160 +        /* Two lots of padding:  Pad the first block to 64 bytes */
  56.161 +        memset(p, 0, count);
  56.162 +        byteReverse(ctx->in, 16);
  56.163 +        MD5Transform(ctx->buf, (uint32_t *) ctx->in);
  56.164 +
  56.165 +        /* Now fill the next block with 56 bytes */
  56.166 +        memset(ctx->in, 0, 56);
  56.167 +    } else {
  56.168 +        /* Pad block to 56 bytes */
  56.169 +        memset(p, 0, count - 8);
  56.170 +    }
  56.171 +    byteReverse(ctx->in, 14);
  56.172 +
  56.173 +    /* Append length in bits and transform */
  56.174 +    ((uint32_t *) ctx->in)[14] = ctx->bits[0];
  56.175 +    ((uint32_t *) ctx->in)[15] = ctx->bits[1];
  56.176 +
  56.177 +    MD5Transform(ctx->buf, (uint32_t *) ctx->in);
  56.178 +    byteReverse((unsigned char *) ctx->buf, 4);
  56.179 +    memcpy(digest, ctx->buf, 16);
  56.180 +    memset(ctx, 0, sizeof(ctx));     /* In case it's sensitive */
  56.181 +}
  56.182 +
  56.183 +/* The four core functions - F1 is optimized somewhat */
  56.184 +
  56.185 +/* #define F1(x, y, z) (x & y | ~x & z) */
  56.186 +#define F1(x, y, z) (z ^ (x & (y ^ z)))
  56.187 +#define F2(x, y, z) F1(z, x, y)
  56.188 +#define F3(x, y, z) (x ^ y ^ z)
  56.189 +#define F4(x, y, z) (y ^ (x | ~z))
  56.190 +
  56.191 +/* This is the central step in the MD5 algorithm. */
  56.192 +#define MD5STEP(f, w, x, y, z, data, s) \
  56.193 +        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
  56.194 +
  56.195 +/*
  56.196 + * The core of the MD5 algorithm, this alters an existing MD5 hash to
  56.197 + * reflect the addition of 16 longwords of new data.  MD5Update blocks
  56.198 + * the data and converts bytes into longwords for this routine.
  56.199 + */
  56.200 +static void MD5Transform(uint32_t buf[4], uint32_t const in[16])
  56.201 +{
  56.202 +    register uint32_t a, b, c, d;
  56.203 +
  56.204 +    a = buf[0];
  56.205 +    b = buf[1];
  56.206 +    c = buf[2];
  56.207 +    d = buf[3];
  56.208 +
  56.209 +    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  56.210 +    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  56.211 +    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  56.212 +    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  56.213 +    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  56.214 +    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  56.215 +    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  56.216 +    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  56.217 +    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  56.218 +    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  56.219 +    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  56.220 +    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  56.221 +    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  56.222 +    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  56.223 +    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  56.224 +    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  56.225 +
  56.226 +    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  56.227 +    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  56.228 +    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  56.229 +    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  56.230 +    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  56.231 +    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  56.232 +    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  56.233 +    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  56.234 +    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  56.235 +    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  56.236 +    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  56.237 +    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  56.238 +    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  56.239 +    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  56.240 +    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  56.241 +    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  56.242 +
  56.243 +    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  56.244 +    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  56.245 +    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  56.246 +    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  56.247 +    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  56.248 +    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  56.249 +    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  56.250 +    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  56.251 +    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  56.252 +    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  56.253 +    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  56.254 +    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  56.255 +    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  56.256 +    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  56.257 +    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  56.258 +    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  56.259 +
  56.260 +    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  56.261 +    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  56.262 +    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  56.263 +    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  56.264 +    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  56.265 +    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  56.266 +    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  56.267 +    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  56.268 +    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  56.269 +    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  56.270 +    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  56.271 +    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  56.272 +    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  56.273 +    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  56.274 +    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  56.275 +    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  56.276 +
  56.277 +    buf[0] += a;
  56.278 +    buf[1] += b;
  56.279 +    buf[2] += c;
  56.280 +    buf[3] += d;
  56.281 +}
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/tools/blktap2/drivers/md5.h	Fri Jul 16 17:16:06 2010 -0700
    57.3 @@ -0,0 +1,15 @@
    57.4 +#ifndef MD5_H
    57.5 +#define MD5_H
    57.6 +
    57.7 +#include <stdint.h>
    57.8 +#include <stddef.h>
    57.9 +
   57.10 +/**
   57.11 + * md5_sum - MD5 hash for a data block
   57.12 + * @addr: Pointers to the data area
   57.13 + * @len: Lengths of the data block
   57.14 + * @mac: Buffer for the hash
   57.15 + */
   57.16 +void md5_sum(const uint8_t *addr, const size_t len, uint8_t *mac);
   57.17 +
   57.18 +#endif
    58.1 --- a/tools/blktap2/drivers/qcow2raw.c	Wed Jun 09 19:53:32 2010 -0700
    58.2 +++ b/tools/blktap2/drivers/qcow2raw.c	Fri Jul 16 17:16:06 2010 -0700
    58.3 @@ -47,6 +47,7 @@
    58.4  #include "tapdisk-server.h"
    58.5  #include "tapdisk-driver.h"
    58.6  #include "tapdisk-interface.h"
    58.7 +#include "tapdisk-disktype.h"
    58.8  #include "qcow.h"
    58.9  
   58.10  #if 1
   58.11 @@ -61,7 +62,6 @@
   58.12  #define O_LARGEFILE 0
   58.13  #endif
   58.14  
   58.15 -#define TAPDISK 1
   58.16  #define BLOCK_PROCESSSZ 4096
   58.17  #define QCOW_VBD 0
   58.18  #define AIO_VBD 1
   58.19 @@ -217,13 +217,13 @@ int main(int argc, const char *argv[])
   58.20  		exit(-1);
   58.21  	}
   58.22  
   58.23 -        err = tapdisk_server_initialize(NULL, NULL);
   58.24 +        err = tapdisk_server_initialize();
   58.25          if( err ) {
   58.26            DPRINTF("qcow2raw Couldn't initialize server instance.\n");
   58.27            return err;
   58.28          }
   58.29  
   58.30 -        err=tapdisk_vbd_initialize(-1,-1, QCOW_VBD);
   58.31 +        err=tapdisk_vbd_initialize(QCOW_VBD);
   58.32          if( err ) {
   58.33            DPRINTF("qcow2raw Couldn't initialize qcow vbd.\n");
   58.34            return err;
   58.35 @@ -335,7 +335,7 @@ int main(int argc, const char *argv[])
   58.36  	}
   58.37  
   58.38          //Now the output file should be there, reopen it as an aio VBD
   58.39 -        err=tapdisk_vbd_initialize(-1,-1, AIO_VBD);
   58.40 +        err=tapdisk_vbd_initialize(AIO_VBD);
   58.41          if( err ) {
   58.42            DPRINTF("qcow2raw Couldn't initialize aio vbd.\n");
   58.43            return err;
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/tools/blktap2/drivers/tapdisk-control.c	Fri Jul 16 17:16:06 2010 -0700
    59.3 @@ -0,0 +1,836 @@
    59.4 +/*
    59.5 + * Copyright (c) 2008, XenSource Inc.
    59.6 + * All rights reserved.
    59.7 + *
    59.8 + * Redistribution and use in source and binary forms, with or without
    59.9 + * modification, are permitted provided that the following conditions are met:
   59.10 + *     * Redistributions of source code must retain the above copyright
   59.11 + *       notice, this list of conditions and the following disclaimer.
   59.12 + *     * Redistributions in binary form must reproduce the above copyright
   59.13 + *       notice, this list of conditions and the following disclaimer in the
   59.14 + *       documentation and/or other materials provided with the distribution.
   59.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   59.16 + *       may be used to endorse or promote products derived from this software
   59.17 + *       without specific prior written permission.
   59.18 + *
   59.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   59.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   59.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   59.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   59.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   59.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   59.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   59.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   59.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   59.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   59.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   59.30 + */
   59.31 +#include <stdio.h>
   59.32 +#include <errno.h>
   59.33 +#include <fcntl.h>
   59.34 +#include <unistd.h>
   59.35 +#include <stdlib.h>
   59.36 +#include <string.h>
   59.37 +#include <signal.h>
   59.38 +#include <sys/un.h>
   59.39 +#include <sys/stat.h>
   59.40 +#include <sys/types.h>
   59.41 +#include <sys/ioctl.h>
   59.42 +#include <sys/socket.h>
   59.43 +
   59.44 +#include "list.h"
   59.45 +#include "tapdisk.h"
   59.46 +#include "blktap2.h"
   59.47 +#include "blktaplib.h"
   59.48 +#include "tapdisk-vbd.h"
   59.49 +#include "tapdisk-utils.h"
   59.50 +#include "tapdisk-server.h"
   59.51 +#include "tapdisk-message.h"
   59.52 +#include "tapdisk-disktype.h"
   59.53 +
   59.54 +struct tapdisk_control {
   59.55 +	char              *path;
   59.56 +	int                socket;
   59.57 +	int                event_id;
   59.58 +};
   59.59 +
   59.60 +struct tapdisk_control_connection {
   59.61 +	int                socket;
   59.62 +	event_id_t         event_id;
   59.63 +};
   59.64 +
   59.65 +static struct tapdisk_control td_control;
   59.66 +
   59.67 +static void
   59.68 +tapdisk_control_initialize(void)
   59.69 +{
   59.70 +	td_control.socket   = -1;
   59.71 +	td_control.event_id = -1;
   59.72 +
   59.73 +	signal(SIGPIPE, SIG_IGN);
   59.74 +}
   59.75 +
   59.76 +void
   59.77 +tapdisk_control_close(void)
   59.78 +{
   59.79 +	if (td_control.path) {
   59.80 +		unlink(td_control.path);
   59.81 +		free(td_control.path);
   59.82 +		td_control.path = NULL;
   59.83 +	}
   59.84 +
   59.85 +	if (td_control.socket != -1) {
   59.86 +		close(td_control.socket);
   59.87 +		td_control.socket = -1;
   59.88 +	}
   59.89 +}
   59.90 +
   59.91 +static struct tapdisk_control_connection *
   59.92 +tapdisk_control_allocate_connection(int fd)
   59.93 +{
   59.94 +	struct tapdisk_control_connection *connection;
   59.95 +	size_t sz;
   59.96 +
   59.97 +	connection = calloc(1, sizeof(*connection));
   59.98 +	if (!connection) {
   59.99 +		EPRINTF("calloc");
  59.100 +		return NULL;
  59.101 +	}
  59.102 +
  59.103 +	connection->socket = fd;
  59.104 +	return connection;
  59.105 +}
  59.106 +
  59.107 +static void
  59.108 +tapdisk_control_close_connection(struct tapdisk_control_connection *connection)
  59.109 +{
  59.110 +	tapdisk_server_unregister_event(connection->event_id);
  59.111 +	close(connection->socket);
  59.112 +	free(connection);
  59.113 +}
  59.114 +
  59.115 +static int
  59.116 +tapdisk_control_read_message(int fd, tapdisk_message_t *message, int timeout)
  59.117 +{
  59.118 +	fd_set readfds;
  59.119 +	int ret, len, offset;
  59.120 +	struct timeval tv, *t;
  59.121 +
  59.122 +	t      = NULL;
  59.123 +	offset = 0;
  59.124 +	len    = sizeof(tapdisk_message_t);
  59.125 +
  59.126 +	if (timeout) {
  59.127 +		tv.tv_sec  = timeout;
  59.128 +		tv.tv_usec = 0;
  59.129 +		t = &tv;
  59.130 +	}
  59.131 +
  59.132 +	memset(message, 0, sizeof(tapdisk_message_t));
  59.133 +
  59.134 +	while (offset < len) {
  59.135 +		FD_ZERO(&readfds);
  59.136 +		FD_SET(fd, &readfds);
  59.137 +
  59.138 +		ret = select(fd + 1, &readfds, NULL, NULL, t);
  59.139 +		if (ret == -1)
  59.140 +			break;
  59.141 +		else if (FD_ISSET(fd, &readfds)) {
  59.142 +			ret = read(fd, message + offset, len - offset);
  59.143 +			if (ret <= 0)
  59.144 +				break;
  59.145 +			offset += ret;
  59.146 +		} else
  59.147 +			break;
  59.148 +	}
  59.149 +
  59.150 +	if (offset != len) {
  59.151 +		EPRINTF("failure reading message (wanted %d but got %d)\n",
  59.152 +			len, offset);
  59.153 +		return -EIO;
  59.154 +	}
  59.155 +
  59.156 +	DPRINTF("received '%s' message (uuid = %u)\n",
  59.157 +		tapdisk_message_name(message->type), message->cookie);
  59.158 +
  59.159 +	return 0;
  59.160 +}
  59.161 +
  59.162 +static int
  59.163 +tapdisk_control_write_message(int fd, tapdisk_message_t *message, int timeout)
  59.164 +{
  59.165 +	fd_set writefds;
  59.166 +	int ret, len, offset;
  59.167 +	struct timeval tv, *t;
  59.168 +
  59.169 +	t      = NULL;
  59.170 +	offset = 0;
  59.171 +	len    = sizeof(tapdisk_message_t);
  59.172 +
  59.173 +	if (timeout) {
  59.174 +		tv.tv_sec  = timeout;
  59.175 +		tv.tv_usec = 0;
  59.176 +		t = &tv;
  59.177 +	}
  59.178 +
  59.179 +	DPRINTF("sending '%s' message (uuid = %u)\n",
  59.180 +		tapdisk_message_name(message->type), message->cookie);
  59.181 +
  59.182 +	while (offset < len) {
  59.183 +		FD_ZERO(&writefds);
  59.184 +		FD_SET(fd, &writefds);
  59.185 +
  59.186 +		/* we don't bother reinitializing tv. at worst, it will wait a
  59.187 +		 * bit more time than expected. */
  59.188 +
  59.189 +		ret = select(fd + 1, NULL, &writefds, NULL, t);
  59.190 +		if (ret == -1)
  59.191 +			break;
  59.192 +		else if (FD_ISSET(fd, &writefds)) {
  59.193 +			ret = write(fd, message + offset, len - offset);
  59.194 +			if (ret <= 0)
  59.195 +				break;
  59.196 +			offset += ret;
  59.197 +		} else
  59.198 +			break;
  59.199 +	}
  59.200 +
  59.201 +	if (offset != len) {
  59.202 +		EPRINTF("failure writing message\n");
  59.203 +		return -EIO;
  59.204 +	}
  59.205 +
  59.206 +	return 0;
  59.207 +}
  59.208 +
  59.209 +static int
  59.210 +tapdisk_control_validate_request(tapdisk_message_t *request)
  59.211 +{
  59.212 +	if (strnlen(request->u.params.path,
  59.213 +		    TAPDISK_MESSAGE_MAX_PATH_LENGTH) >=
  59.214 +	    TAPDISK_MESSAGE_MAX_PATH_LENGTH)
  59.215 +		return EINVAL;
  59.216 +
  59.217 +	return 0;
  59.218 +}
  59.219 +
  59.220 +static void
  59.221 +tapdisk_control_list_minors(struct tapdisk_control_connection *connection,
  59.222 +			    tapdisk_message_t *request)
  59.223 +{
  59.224 +	int i;
  59.225 +	td_vbd_t *vbd;
  59.226 +	struct list_head *head;
  59.227 +	tapdisk_message_t response;
  59.228 +
  59.229 +	i = 0;
  59.230 +	memset(&response, 0, sizeof(response));
  59.231 +
  59.232 +	response.type = TAPDISK_MESSAGE_LIST_MINORS_RSP;
  59.233 +	response.cookie = request->cookie;
  59.234 +
  59.235 +	head = tapdisk_server_get_all_vbds();
  59.236 +
  59.237 +	list_for_each_entry(vbd, head, next) {
  59.238 +		response.u.minors.list[i++] = vbd->minor;
  59.239 +		if (i >= TAPDISK_MESSAGE_MAX_MINORS) {
  59.240 +			response.type = TAPDISK_MESSAGE_ERROR;
  59.241 +			response.u.response.error = ERANGE;
  59.242 +			break;
  59.243 +		}
  59.244 +	}
  59.245 +
  59.246 +	response.u.minors.count = i;
  59.247 +	tapdisk_control_write_message(connection->socket, &response, 2);
  59.248 +	tapdisk_control_close_connection(connection);
  59.249 +}
  59.250 +
  59.251 +static void
  59.252 +tapdisk_control_list(struct tapdisk_control_connection *connection,
  59.253 +		     tapdisk_message_t *request)
  59.254 +{
  59.255 +	td_vbd_t *vbd;
  59.256 +	struct list_head *head;
  59.257 +	tapdisk_message_t response;
  59.258 +	int count, i;
  59.259 +
  59.260 +	memset(&response, 0, sizeof(response));
  59.261 +	response.type = TAPDISK_MESSAGE_LIST_RSP;
  59.262 +	response.cookie = request->cookie;
  59.263 +
  59.264 +	head = tapdisk_server_get_all_vbds();
  59.265 +
  59.266 +	count = 0;
  59.267 +	list_for_each_entry(vbd, head, next)
  59.268 +		count++;
  59.269 +
  59.270 +	list_for_each_entry(vbd, head, next) {
  59.271 +		response.u.list.count   = count--;
  59.272 +		response.u.list.minor   = vbd->minor;
  59.273 +		response.u.list.state   = vbd->state;
  59.274 +		response.u.list.path[0] = 0;
  59.275 +
  59.276 +		if (!list_empty(&vbd->images)) {
  59.277 +			td_image_t *image = list_entry(vbd->images.next,
  59.278 +						       td_image_t, next);
  59.279 +			snprintf(response.u.list.path,
  59.280 +				 sizeof(response.u.list.path),
  59.281 +				 "%s:%s",
  59.282 +				 tapdisk_disk_types[image->type]->name,
  59.283 +				 image->name);
  59.284 +		}
  59.285 +
  59.286 +		tapdisk_control_write_message(connection->socket, &response, 2);
  59.287 +	}
  59.288 +
  59.289 +	response.u.list.count   = count;
  59.290 +	response.u.list.minor   = -1;
  59.291 +	response.u.list.path[0] = 0;
  59.292 +
  59.293 +	tapdisk_control_write_message(connection->socket, &response, 2);
  59.294 +	tapdisk_control_close_connection(connection);
  59.295 +}
  59.296 +
  59.297 +static void
  59.298 +tapdisk_control_get_pid(struct tapdisk_control_connection *connection,
  59.299 +			tapdisk_message_t *request)
  59.300 +{
  59.301 +	tapdisk_message_t response;
  59.302 +
  59.303 +	memset(&response, 0, sizeof(response));
  59.304 +	response.type = TAPDISK_MESSAGE_PID_RSP;
  59.305 +	response.cookie = request->cookie;
  59.306 +	response.u.tapdisk_pid = getpid();
  59.307 +
  59.308 +	tapdisk_control_write_message(connection->socket, &response, 2);
  59.309 +	tapdisk_control_close_connection(connection);
  59.310 +}
  59.311 +
  59.312 +static void
  59.313 +tapdisk_control_attach_vbd(struct tapdisk_control_connection *connection,
  59.314 +			   tapdisk_message_t *request)
  59.315 +{
  59.316 +	tapdisk_message_t response;
  59.317 +	char *devname;
  59.318 +	td_vbd_t *vbd;
  59.319 +	struct blktap2_params params;
  59.320 +	image_t image;
  59.321 +	int minor, err;
  59.322 +
  59.323 +	/*
  59.324 +	 * TODO: check for max vbds per process
  59.325 +	 */
  59.326 +
  59.327 +	vbd = tapdisk_server_get_vbd(request->cookie);
  59.328 +	if (vbd) {
  59.329 +		err = -EEXIST;
  59.330 +		goto out;
  59.331 +	}
  59.332 +
  59.333 +	minor = request->cookie;
  59.334 +	if (minor < 0) {
  59.335 +		err = -EINVAL;
  59.336 +		goto out;
  59.337 +	}
  59.338 +
  59.339 +	vbd = tapdisk_vbd_create(minor);
  59.340 +	if (!vbd) {
  59.341 +		err = -ENOMEM;
  59.342 +		goto out;
  59.343 +	}
  59.344 +
  59.345 +	err = asprintf(&devname, BLKTAP2_RING_DEVICE"%d", minor);
  59.346 +	if (err == -1) {
  59.347 +		err = -ENOMEM;
  59.348 +		goto fail_vbd;
  59.349 +	}
  59.350 +
  59.351 +	err = tapdisk_vbd_attach(vbd, devname, minor);
  59.352 +	free(devname);
  59.353 +	if (err)
  59.354 +		goto fail_vbd;
  59.355 +
  59.356 +	tapdisk_server_add_vbd(vbd);
  59.357 +
  59.358 +out:
  59.359 +	memset(&response, 0, sizeof(response));
  59.360 +	response.type = TAPDISK_MESSAGE_ATTACH_RSP;
  59.361 +	response.cookie = request->cookie;
  59.362 +	response.u.response.error = -err;
  59.363 +
  59.364 +	tapdisk_control_write_message(connection->socket, &response, 2);
  59.365 +	tapdisk_control_close_connection(connection);
  59.366 +
  59.367 +	return;
  59.368 +
  59.369 +fail_vbd:
  59.370 +	tapdisk_vbd_detach(vbd);
  59.371 +	free(vbd);
  59.372 +	goto out;
  59.373 +}
  59.374 +
  59.375 +
  59.376 +static void
  59.377 +tapdisk_control_detach_vbd(struct tapdisk_control_connection *connection,
  59.378 +			   tapdisk_message_t *request)
  59.379 +{
  59.380 +	tapdisk_message_t response;
  59.381 +	td_vbd_t *vbd;
  59.382 +	int err;
  59.383 +
  59.384 +	vbd = tapdisk_server_get_vbd(request->cookie);
  59.385 +	if (!vbd) {
  59.386 +		err = -EINVAL;
  59.387 +		goto out;
  59.388 +	}
  59.389 +
  59.390 +	tapdisk_vbd_detach(vbd);
  59.391 +
  59.392 +	if (list_empty(&vbd->images)) {
  59.393 +		tapdisk_server_remove_vbd(vbd);
  59.394 +		free(vbd);
  59.395 +	}
  59.396 +
  59.397 +	err = 0;
  59.398 +out:
  59.399 +	memset(&response, 0, sizeof(response));
  59.400 +	response.type = TAPDISK_MESSAGE_DETACH_RSP;
  59.401 +	response.cookie = request->cookie;
  59.402 +	response.u.response.error = -err;
  59.403 +
  59.404 +	tapdisk_control_write_message(connection->socket, &response, 2);
  59.405 +	tapdisk_control_close_connection(connection);
  59.406 +}
  59.407 +
  59.408 +static void
  59.409 +tapdisk_control_open_image(struct tapdisk_control_connection *connection,
  59.410 +			   tapdisk_message_t *request)
  59.411 +{
  59.412 +	int err;
  59.413 +	image_t image;
  59.414 +	td_vbd_t *vbd;
  59.415 +	td_flag_t flags;
  59.416 +	tapdisk_message_t response;
  59.417 +	struct blktap2_params params;
  59.418 +
  59.419 +	vbd = tapdisk_server_get_vbd(request->cookie);
  59.420 +	if (!vbd) {
  59.421 +		err = -EINVAL;
  59.422 +		goto out;
  59.423 +	}
  59.424 +
  59.425 +	if (vbd->minor == -1) {
  59.426 +		err = -EINVAL;
  59.427 +		goto out;
  59.428 +	}
  59.429 +
  59.430 +	if (vbd->name) {
  59.431 +		err = -EALREADY;
  59.432 +		goto out;
  59.433 +	}
  59.434 +
  59.435 +	flags = 0;
  59.436 +	if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_RDONLY)
  59.437 +		flags |= TD_OPEN_RDONLY;
  59.438 +	if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_SHARED)
  59.439 +		flags |= TD_OPEN_SHAREABLE;
  59.440 +	if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_ADD_CACHE)
  59.441 +		flags |= TD_OPEN_ADD_CACHE;
  59.442 +	if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_VHD_INDEX)
  59.443 +		flags |= TD_OPEN_VHD_INDEX;
  59.444 +	if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_LOG_DIRTY)
  59.445 +		flags |= TD_OPEN_LOG_DIRTY;
  59.446 +
  59.447 +	vbd->name = strndup(request->u.params.path,
  59.448 +			    sizeof(request->u.params.path));
  59.449 +	if (!vbd->name) {
  59.450 +		err = -ENOMEM;
  59.451 +		goto out;
  59.452 +	}
  59.453 +
  59.454 +	err = tapdisk_vbd_parse_stack(vbd, request->u.params.path);
  59.455 +	if (err)
  59.456 +		goto out;
  59.457 +
  59.458 +	err = tapdisk_vbd_open_stack(vbd, request->u.params.storage, flags);
  59.459 +	if (err)
  59.460 +		goto out;
  59.461 +
  59.462 +	err = tapdisk_vbd_get_image_info(vbd, &image);
  59.463 +	if (err)
  59.464 +		goto fail_close;
  59.465 +
  59.466 +	params.capacity = image.size;
  59.467 +	params.sector_size = image.secsize;
  59.468 +
  59.469 +	err = ioctl(vbd->ring.fd, BLKTAP2_IOCTL_CREATE_DEVICE, &params);
  59.470 +	if (err && errno != EEXIST) {
  59.471 +		err = -errno;
  59.472 +		EPRINTF("create device failed: %d\n", err);
  59.473 +		goto fail_close;
  59.474 +	}
  59.475 +
  59.476 +	err = 0;
  59.477 +
  59.478 +out:
  59.479 +	memset(&response, 0, sizeof(response));
  59.480 +	response.cookie = request->cookie;
  59.481 +
  59.482 +	if (err) {
  59.483 +		response.type                = TAPDISK_MESSAGE_ERROR;
  59.484 +		response.u.response.error    = -err;
  59.485 +	} else {
  59.486 +		response.u.image.sectors     = image.size;
  59.487 +		response.u.image.sector_size = image.secsize;
  59.488 +		response.u.image.info        = image.info;
  59.489 +		response.type                = TAPDISK_MESSAGE_OPEN_RSP;
  59.490 +	}
  59.491 +
  59.492 +	tapdisk_control_write_message(connection->socket, &response, 2);
  59.493 +	tapdisk_control_close_connection(connection);
  59.494 +
  59.495 +	return;
  59.496 +
  59.497 +fail_close:
  59.498 +	tapdisk_vbd_close_vdi(vbd);
  59.499 +	free(vbd->name);
  59.500 +	vbd->name = NULL;
  59.501 +	goto out;
  59.502 +}
  59.503 +
  59.504 +static void
  59.505 +tapdisk_control_close_image(struct tapdisk_control_connection *connection,
  59.506 +			    tapdisk_message_t *request)
  59.507 +{
  59.508 +	tapdisk_message_t response;
  59.509 +	td_vbd_t *vbd;
  59.510 +	int err;
  59.511 +
  59.512 +	vbd = tapdisk_server_get_vbd(request->cookie);
  59.513 +	if (!vbd) {
  59.514 +		err = -EINVAL;
  59.515 +		goto out;
  59.516 +	}
  59.517 +
  59.518 +	if (!list_empty(&vbd->pending_requests)) {
  59.519 +		err = -EAGAIN;
  59.520 +		goto out;
  59.521 +	}
  59.522 +
  59.523 +	tapdisk_vbd_close_vdi(vbd);
  59.524 +
  59.525 +	/* NB. vbd->name free should probably belong into close_vdi,
  59.526 +	   but the current blktap1 reopen-stuff likely depends on a
  59.527 +	   lifetime extended until shutdown. */
  59.528 +	free(vbd->name);
  59.529 +	vbd->name = NULL;
  59.530 +
  59.531 +	if (vbd->minor == -1) {
  59.532 +		tapdisk_server_remove_vbd(vbd);
  59.533 +		tapdisk_vbd_free(vbd);
  59.534 +	}
  59.535 +
  59.536 +	err = 0;
  59.537 +out:
  59.538 +	memset(&response, 0, sizeof(response));
  59.539 +	response.type = TAPDISK_MESSAGE_CLOSE_RSP;
  59.540 +	response.cookie = request->cookie;
  59.541 +	response.u.response.error = -err;
  59.542 +
  59.543 +	tapdisk_control_write_message(connection->socket, &response, 2);
  59.544 +	tapdisk_control_close_connection(connection);
  59.545 +}
  59.546 +
  59.547 +static void
  59.548 +tapdisk_control_pause_vbd(struct tapdisk_control_connection *connection,
  59.549 +			  tapdisk_message_t *request)
  59.550 +{
  59.551 +	int err;
  59.552 +	td_vbd_t *vbd;
  59.553 +	tapdisk_message_t response;
  59.554 +
  59.555 +	memset(&response, 0, sizeof(response));
  59.556 +
  59.557 +	response.type = TAPDISK_MESSAGE_PAUSE_RSP;
  59.558 +
  59.559 +	vbd = tapdisk_server_get_vbd(request->cookie);
  59.560 +	if (!vbd) {
  59.561 +		err = -EINVAL;
  59.562 +		goto out;
  59.563 +	}
  59.564 +
  59.565 +	do {
  59.566 +		err = tapdisk_vbd_pause(vbd);
  59.567 +
  59.568 +		if (!err || err != -EAGAIN)
  59.569 +			break;
  59.570 +
  59.571 +		tapdisk_server_iterate();
  59.572 +	} while (1);
  59.573 +
  59.574 +out:
  59.575 +	response.cookie = request->cookie;
  59.576 +	response.u.response.error = -err;
  59.577 +	tapdisk_control_write_message(connection->socket, &response, 2);
  59.578 +	tapdisk_control_close_connection(connection);
  59.579 +}
  59.580 +
  59.581 +static void
  59.582 +tapdisk_control_resume_vbd(struct tapdisk_control_connection *connection,
  59.583 +			   tapdisk_message_t *request)
  59.584 +{
  59.585 +	int err;
  59.586 +	td_vbd_t *vbd;
  59.587 +	tapdisk_message_t response;
  59.588 +
  59.589 +	memset(&response, 0, sizeof(response));
  59.590 +
  59.591 +	response.type = TAPDISK_MESSAGE_RESUME_RSP;
  59.592 +
  59.593 +	vbd = tapdisk_server_get_vbd(request->cookie);
  59.594 +	if (!vbd) {
  59.595 +		err = -EINVAL;
  59.596 +		goto out;
  59.597 +	}
  59.598 +
  59.599 +	if (!td_flag_test(vbd->state, TD_VBD_PAUSED)) {
  59.600 +		err = -EINVAL;
  59.601 +		goto out;
  59.602 +	}
  59.603 +
  59.604 +	if (request->u.params.path[0]) {
  59.605 +		free(vbd->name);
  59.606 +		vbd->name = strndup(request->u.params.path,
  59.607 +				    sizeof(request->u.params.path));
  59.608 +		if (!vbd->name) {
  59.609 +			err = -ENOMEM;
  59.610 +			goto out;
  59.611 +		}
  59.612 +	} else if (!vbd->name) {
  59.613 +		err = -EINVAL;
  59.614 +		goto out;
  59.615 +	}
  59.616 +
  59.617 +	err = tapdisk_vbd_parse_stack(vbd, vbd->name);
  59.618 +	if (err)
  59.619 +		goto out;
  59.620 +
  59.621 +	err = tapdisk_vbd_resume(vbd, NULL, -1);
  59.622 +	if (err)
  59.623 +		goto out;
  59.624 +
  59.625 +out:
  59.626 +	response.cookie = request->cookie;
  59.627 +	response.u.response.error = -err;
  59.628 +	tapdisk_control_write_message(connection->socket, &response, 2);
  59.629 +	tapdisk_control_close_connection(connection);
  59.630 +}
  59.631 +
  59.632 +static void
  59.633 +tapdisk_control_handle_request(event_id_t id, char mode, void *private)
  59.634 +{
  59.635 +	int err;
  59.636 +	tapdisk_message_t message;
  59.637 +	struct tapdisk_control_connection *connection =
  59.638 +		(struct tapdisk_control_connection *)private;
  59.639 +
  59.640 +	if (tapdisk_control_read_message(connection->socket, &message, 2)) {
  59.641 +		EPRINTF("failed to read message from %d\n", connection->socket);
  59.642 +		tapdisk_control_close_connection(connection);
  59.643 +		return;
  59.644 +	}
  59.645 +
  59.646 +	err = tapdisk_control_validate_request(&message);
  59.647 +	if (err)
  59.648 +		goto fail;
  59.649 +
  59.650 +	switch (message.type) {
  59.651 +	case TAPDISK_MESSAGE_PID:
  59.652 +		return tapdisk_control_get_pid(connection, &message);
  59.653 +	case TAPDISK_MESSAGE_LIST_MINORS:
  59.654 +		return tapdisk_control_list_minors(connection, &message);
  59.655 +	case TAPDISK_MESSAGE_LIST:
  59.656 +		return tapdisk_control_list(connection, &message);
  59.657 +	case TAPDISK_MESSAGE_ATTACH:
  59.658 +		return tapdisk_control_attach_vbd(connection, &message);
  59.659 +	case TAPDISK_MESSAGE_DETACH:
  59.660 +		return tapdisk_control_detach_vbd(connection, &message);
  59.661 +	case TAPDISK_MESSAGE_OPEN:
  59.662 +		return tapdisk_control_open_image(connection, &message);
  59.663 +	case TAPDISK_MESSAGE_PAUSE:
  59.664 +		return tapdisk_control_pause_vbd(connection, &message);
  59.665 +	case TAPDISK_MESSAGE_RESUME:
  59.666 +		return tapdisk_control_resume_vbd(connection, &message);
  59.667 +	case TAPDISK_MESSAGE_CLOSE:
  59.668 +		return tapdisk_control_close_image(connection, &message);
  59.669 +	default: {
  59.670 +		tapdisk_message_t response;
  59.671 +	fail:
  59.672 +
  59.673 +		EPRINTF("received unsupported message '%s'\n",
  59.674 +			tapdisk_message_name(message.type));
  59.675 +
  59.676 +		memset(&response, 0, sizeof(response));
  59.677 +
  59.678 +		response.type = TAPDISK_MESSAGE_ERROR;
  59.679 +		response.u.response.error = (err ? -err : EINVAL);
  59.680 +		tapdisk_control_write_message(connection->socket, &response, 2);
  59.681 +
  59.682 +		tapdisk_control_close_connection(connection);
  59.683 +		break;
  59.684 +	}
  59.685 +	}
  59.686 +}
  59.687 +
  59.688 +static void
  59.689 +tapdisk_control_accept(event_id_t id, char mode, void *private)
  59.690 +{
  59.691 +	int err, fd;
  59.692 +	struct tapdisk_control_connection *connection;
  59.693 +
  59.694 +	fd = accept(td_control.socket, NULL, NULL);
  59.695 +	if (fd == -1) {
  59.696 +		EPRINTF("failed to accept new control connection: %d\n", errno);
  59.697 +		return;
  59.698 +	}
  59.699 +
  59.700 +	connection = tapdisk_control_allocate_connection(fd);
  59.701 +	if (!connection) {
  59.702 +		close(fd);
  59.703 +		EPRINTF("failed to allocate new control connection\n");
  59.704 +	}
  59.705 +
  59.706 +	err = tapdisk_server_register_event(SCHEDULER_POLL_READ_FD,
  59.707 +					    connection->socket, 0,
  59.708 +					    tapdisk_control_handle_request,
  59.709 +					    connection);
  59.710 +	if (err == -1) {
  59.711 +		close(fd);
  59.712 +		free(connection);
  59.713 +		EPRINTF("failed to register new control event: %d\n", err);
  59.714 +	}
  59.715 +
  59.716 +	connection->event_id = err;
  59.717 +}
  59.718 +
  59.719 +static int
  59.720 +tapdisk_control_mkdir(const char *dir)
  59.721 +{
  59.722 +	int err;
  59.723 +	char *ptr, *name, *start;
  59.724 +
  59.725 +	err = access(dir, W_OK | R_OK);
  59.726 +	if (!err)
  59.727 +		return 0;
  59.728 +
  59.729 +	name = strdup(dir);
  59.730 +	if (!name)
  59.731 +		return -ENOMEM;
  59.732 +
  59.733 +	start = name;
  59.734 +
  59.735 +	for (;;) {
  59.736 +		ptr = strchr(start + 1, '/');
  59.737 +		if (ptr)
  59.738 +			*ptr = '\0';
  59.739 +
  59.740 +		err = mkdir(name, 0755);
  59.741 +		if (err && errno != EEXIST) {
  59.742 +			err = -errno;
  59.743 +			EPRINTF("failed to create directory %s: %d\n",
  59.744 +				  name, err);
  59.745 +			break;
  59.746 +		}
  59.747 +
  59.748 +		if (!ptr)
  59.749 +			break;
  59.750 +		else {
  59.751 +			*ptr = '/';
  59.752 +			start = ptr + 1;
  59.753 +		}
  59.754 +	}
  59.755 +
  59.756 +	free(name);
  59.757 +	return err;
  59.758 +}
  59.759 +
  59.760 +static int
  59.761 +tapdisk_control_create_socket(char **socket_path)
  59.762 +{
  59.763 +	int err, flags;
  59.764 +	struct sockaddr_un saddr;
  59.765 +
  59.766 +	err = tapdisk_control_mkdir(BLKTAP2_CONTROL_DIR);
  59.767 +	if (err) {
  59.768 +		EPRINTF("failed to create directory %s: %d\n",
  59.769 +			BLKTAP2_CONTROL_DIR, err);
  59.770 +		return err;
  59.771 +	}
  59.772 +
  59.773 +	err = asprintf(&td_control.path, "%s/%s%d",
  59.774 +		       BLKTAP2_CONTROL_DIR, BLKTAP2_CONTROL_SOCKET, getpid());
  59.775 +	if (err == -1) {
  59.776 +		td_control.path = NULL;
  59.777 +		err = (errno ? : ENOMEM);
  59.778 +		goto fail;
  59.779 +	}
  59.780 +
  59.781 +	if (unlink(td_control.path) && errno != ENOENT) {
  59.782 +		err = errno;
  59.783 +		EPRINTF("failed to unlink %s: %d\n", td_control.path, errno);
  59.784 +		goto fail;
  59.785 +	}
  59.786 +
  59.787 +	td_control.socket = socket(AF_UNIX, SOCK_STREAM, 0);
  59.788 +	if (td_control.socket == -1) {
  59.789 +		err = errno;
  59.790 +		EPRINTF("failed to create control socket: %d\n", err);
  59.791 +		goto fail;
  59.792 +	}
  59.793 +
  59.794 +	memset(&saddr, 0, sizeof(saddr));
  59.795 +	strncpy(saddr.sun_path, td_control.path, sizeof(saddr.sun_path));
  59.796 +	saddr.sun_family = AF_UNIX;
  59.797 +
  59.798 +	err = bind(td_control.socket,
  59.799 +		   (const struct sockaddr *)&saddr, sizeof(saddr));
  59.800 +	if (err == -1) {
  59.801 +		err = errno;
  59.802 +		EPRINTF("failed to bind to %s: %d\n", saddr.sun_path, err);
  59.803 +		goto fail;
  59.804 +	}
  59.805 +
  59.806 +	err = listen(td_control.socket, 10);
  59.807 +	if (err == -1) {
  59.808 +		err = errno;
  59.809 +		EPRINTF("failed to listen: %d\n", err);
  59.810 +		goto fail;
  59.811 +	}
  59.812 +
  59.813 +	err = tapdisk_server_register_event(SCHEDULER_POLL_READ_FD,
  59.814 +					    td_control.socket, 0,
  59.815 +					    tapdisk_control_accept, NULL);
  59.816 +	if (err < 0) {
  59.817 +		EPRINTF("failed to add watch: %d\n", err);
  59.818 +		goto fail;
  59.819 +	}
  59.820 +
  59.821 +	td_control.event_id = err;
  59.822 +	*socket_path = td_control.path;
  59.823 +
  59.824 +	return 0;
  59.825 +
  59.826 +fail:
  59.827 +	tapdisk_control_close();
  59.828 +	return err;
  59.829 +}
  59.830 +
  59.831 +int
  59.832 +tapdisk_control_open(char **path)
  59.833 +{
  59.834 +	int err;
  59.835 +
  59.836 +	tapdisk_control_initialize();
  59.837 +
  59.838 +	return tapdisk_control_create_socket(path);
  59.839 +}
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/tools/blktap2/drivers/tapdisk-control.h	Fri Jul 16 17:16:06 2010 -0700
    60.3 @@ -0,0 +1,35 @@
    60.4 +/*
    60.5 + * Copyright (c) 2008, XenSource Inc.
    60.6 + * All rights reserved.
    60.7 + *
    60.8 + * Redistribution and use in source and binary forms, with or without
    60.9 + * modification, are permitted provided that the following conditions are met:
   60.10 + *     * Redistributions of source code must retain the above copyright
   60.11 + *       notice, this list of conditions and the following disclaimer.
   60.12 + *     * Redistributions in binary form must reproduce the above copyright
   60.13 + *       notice, this list of conditions and the following disclaimer in the
   60.14 + *       documentation and/or other materials provided with the distribution.
   60.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   60.16 + *       may be used to endorse or promote products derived from this software
   60.17 + *       without specific prior written permission.
   60.18 + *
   60.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   60.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   60.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   60.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   60.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   60.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   60.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   60.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   60.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   60.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   60.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   60.30 + */
   60.31 +
   60.32 +#ifndef __TAPDISK_CONTROL_H__
   60.33 +#define __TAPDISK_CONTROL_H__
   60.34 +
   60.35 +int tapdisk_control_open(char **path);
   60.36 +void tapdisk_control_close(void);
   60.37 +
   60.38 +#endif
    61.1 --- a/tools/blktap2/drivers/tapdisk-diff.c	Wed Jun 09 19:53:32 2010 -0700
    61.2 +++ b/tools/blktap2/drivers/tapdisk-diff.c	Fri Jul 16 17:16:06 2010 -0700
    61.3 @@ -38,6 +38,7 @@
    61.4  #include "scheduler.h"
    61.5  #include "tapdisk-vbd.h"
    61.6  #include "tapdisk-server.h"
    61.7 +#include "tapdisk-disktype.h"
    61.8  #include "libvhd.h"
    61.9  
   61.10  #define POLL_READ                        0
   61.11 @@ -540,7 +541,7 @@ tapdisk_stream_open_image(struct tapdisk
   61.12  
   61.13  	s->id = tapdisk_stream_count++;
   61.14  
   61.15 -	err = tapdisk_vbd_initialize(-1, -1, s->id);
   61.16 +	err = tapdisk_vbd_initialize(s->id);
   61.17  	if (err)
   61.18  		goto out;
   61.19  
   61.20 @@ -670,11 +671,11 @@ static int
   61.21  tapdisk_stream_open(struct tapdisk_stream *s, const char *arg)
   61.22  {
   61.23  	int err, type;
   61.24 -	char *path;
   61.25 +	const char *path;
   61.26  
   61.27 -	err = tapdisk_parse_disk_type(arg, &path, &type);
   61.28 -	if (err)
   61.29 -		return err;
   61.30 +	type = tapdisk_disktype_parse_params(arg, &path);
   61.31 +	if (type < 0)
   61.32 +		return type;
   61.33  
   61.34  	tapdisk_stream_initialize(s);
   61.35  
   61.36 @@ -716,7 +717,8 @@ main(int argc, char *argv[])
   61.37  {
   61.38  	int c, err, type1;
   61.39  	const char *arg1 = NULL, *arg2 = NULL;
   61.40 -	char *path1;
   61.41 +	const disk_info_t *info;
   61.42 +	const char *path1;
   61.43  
   61.44  	err    = 0;
   61.45  
   61.46 @@ -741,9 +743,10 @@ main(int argc, char *argv[])
   61.47  	if (!arg1 || !arg2)
   61.48  		goto fail_usage;
   61.49  
   61.50 -	err = tapdisk_parse_disk_type(arg1, &path1, &type1);
   61.51 -	if (err)
   61.52 -		return err;
   61.53 +	type1 = tapdisk_disktype_parse_params(arg1, &path1);
   61.54 +	if (type1 < 0)
   61.55 +		return type1;
   61.56 +
   61.57  	if (type1 != DISK_TYPE_VHD) {
   61.58  		printf("error: first VDI is not VHD\n");
   61.59  		return EINVAL;
   61.60 @@ -755,7 +758,7 @@ main(int argc, char *argv[])
   61.61  
   61.62  	tapdisk_start_logging("tapdisk-diff");
   61.63  
   61.64 -	err = tapdisk_server_initialize(NULL, NULL);
   61.65 +	err = tapdisk_server_initialize();
   61.66  	if (err)
   61.67  		goto out;
   61.68  
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/tools/blktap2/drivers/tapdisk-disktype.c	Fri Jul 16 17:16:06 2010 -0700
    62.3 @@ -0,0 +1,204 @@
    62.4 +/*
    62.5 + * Copyright (c) 2007, 2010, XenSource Inc.
    62.6 + * All rights reserved.
    62.7 + *
    62.8 + * Redistribution and use in source and binary forms, with or without
    62.9 + * modification, are permitted provided that the following conditions are met:
   62.10 + *     * Redistributions of source code must retain the above copyright
   62.11 + *       notice, this list of conditions and the following disclaimer.
   62.12 + *     * Redistributions in binary form must reproduce the above copyright
   62.13 + *       notice, this list of conditions and the following disclaimer in the
   62.14 + *       documentation and/or other materials provided with the distribution.
   62.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   62.16 + *       may be used to endorse or promote products derived from this software
   62.17 + *       without specific prior written permission.
   62.18 + *
   62.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   62.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   62.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   62.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   62.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   62.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   62.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   62.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   62.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   62.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   62.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   62.30 + */
   62.31 +
   62.32 +#include <stddef.h>
   62.33 +#include <string.h>
   62.34 +#include <errno.h>
   62.35 +
   62.36 +#include "tapdisk-disktype.h"
   62.37 +#include "tapdisk-message.h"
   62.38 +
   62.39 +static const disk_info_t aio_disk = {
   62.40 +       "aio",
   62.41 +       "raw image (aio)",
   62.42 +       0,
   62.43 +};
   62.44 +
   62.45 +static const disk_info_t sync_disk = {
   62.46 +       "sync",
   62.47 +       "raw image (sync)",
   62.48 +       0,
   62.49 +};
   62.50 +
   62.51 +static const disk_info_t vmdk_disk = {
   62.52 +       "vmdk",
   62.53 +       "vmware image (vmdk)",
   62.54 +       1,
   62.55 +};
   62.56 +
   62.57 +static const disk_info_t vhdsync_disk = {
   62.58 +       "vhdsync",
   62.59 +       "virtual server image (vhd) - synchronous",
   62.60 +       1,
   62.61 +};
   62.62 +
   62.63 +static const disk_info_t vhd_disk = {
   62.64 +       "vhd",
   62.65 +       "virtual server image (vhd)",
   62.66 +       0,
   62.67 +};
   62.68 +
   62.69 +
   62.70 +static const disk_info_t ram_disk = {
   62.71 +       "ram",
   62.72 +       "ramdisk image (ram)",
   62.73 +       1,
   62.74 +};
   62.75 +
   62.76 +static const disk_info_t qcow_disk = {
   62.77 +       "qcow",
   62.78 +       "qcow disk (qcow)",
   62.79 +       0,
   62.80 +};
   62.81 +
   62.82 +static const disk_info_t block_cache_disk = {
   62.83 +       "bc",
   62.84 +       "block cache image (bc)",
   62.85 +       1,
   62.86 +};
   62.87 +
   62.88 +static const disk_info_t vhd_index_disk = {
   62.89 +       "vhdi",
   62.90 +       "vhd index image (vhdi)",
   62.91 +       1,
   62.92 +};
   62.93 +
   62.94 +static const disk_info_t log_disk = {
   62.95 +	"log",
   62.96 +	"write logger (log)",
   62.97 +	0,
   62.98 +};
   62.99 +
  62.100 +static disk_info_t remus_disk = {
  62.101 +       "remus disk replicator (remus)",
  62.102 +       "remus",
  62.103 +       0,
  62.104 +};
  62.105 +
  62.106 +const disk_info_t *tapdisk_disk_types[] = {
  62.107 +	[DISK_TYPE_AIO]	= &aio_disk,
  62.108 +	[DISK_TYPE_SYNC]	= &sync_disk,
  62.109 +	[DISK_TYPE_VMDK]	= &vmdk_disk,
  62.110 +	[DISK_TYPE_VHDSYNC]	= &vhdsync_disk,
  62.111 +	[DISK_TYPE_VHD]	= &vhd_disk,
  62.112 +	[DISK_TYPE_RAM]	= &ram_disk,
  62.113 +	[DISK_TYPE_QCOW]	= &qcow_disk,
  62.114 +	[DISK_TYPE_BLOCK_CACHE] = &block_cache_disk,
  62.115 +	[DISK_TYPE_LOG]	= &log_disk,
  62.116 +	[DISK_TYPE_VINDEX]	= &vhd_index_disk,
  62.117 +	[DISK_TYPE_REMUS]	= &remus_disk,
  62.118 +	0,
  62.119 +};
  62.120 +
  62.121 +extern struct tap_disk tapdisk_aio;
  62.122 +extern struct tap_disk tapdisk_sync;
  62.123 +extern struct tap_disk tapdisk_vmdk;
  62.124 +extern struct tap_disk tapdisk_vhdsync;
  62.125 +extern struct tap_disk tapdisk_vhd;
  62.126 +extern struct tap_disk tapdisk_ram;
  62.127 +extern struct tap_disk tapdisk_qcow;
  62.128 +extern struct tap_disk tapdisk_block_cache;
  62.129 +extern struct tap_disk tapdisk_vhd_index;
  62.130 +extern struct tap_disk tapdisk_log;
  62.131 +extern struct tap_disk tapdisk_remus;
  62.132 +
  62.133 +const struct tap_disk *tapdisk_disk_drivers[] = {
  62.134 +	[DISK_TYPE_AIO]         = &tapdisk_aio,
  62.135 +#if 0
  62.136 +	[DISK_TYPE_SYNC]        = &tapdisk_sync,
  62.137 +	[DISK_TYPE_VMDK]        = &tapdisk_vmdk,
  62.138 +#endif
  62.139 +	[DISK_TYPE_VHD]         = &tapdisk_vhd,
  62.140 +	[DISK_TYPE_RAM]         = &tapdisk_ram,
  62.141 +	[DISK_TYPE_QCOW]        = &tapdisk_qcow,
  62.142 +	[DISK_TYPE_BLOCK_CACHE] = &tapdisk_block_cache,
  62.143 +	[DISK_TYPE_VINDEX]      = &tapdisk_vhd_index,
  62.144 +	[DISK_TYPE_LOG]         = &tapdisk_log,
  62.145 +	[DISK_TYPE_REMUS]       = &tapdisk_remus,
  62.146 +	0,
  62.147 +};
  62.148 +
  62.149 +int
  62.150 +tapdisk_disktype_find(const char *name)
  62.151 +{
  62.152 +	const disk_info_t *info;
  62.153 +	int i;
  62.154 +
  62.155 +	for (i = 0; info = tapdisk_disk_types[i], info != NULL; ++i) {
  62.156 +		if (strcmp(name, info->name))
  62.157 +			continue;
  62.158 +
  62.159 +		if (!tapdisk_disk_drivers[i])
  62.160 +			return -ENOSYS;
  62.161 +
  62.162 +		return i;
  62.163 +	}
  62.164 +
  62.165 +	return -ENOENT;
  62.166 +}
  62.167 +
  62.168 +int
  62.169 +tapdisk_disktype_parse_params(const char *params, const char **_path)
  62.170 +{
  62.171 +	char name[DISK_TYPE_NAME_MAX], *ptr;
  62.172 +	size_t len;
  62.173 +	int type;
  62.174 +
  62.175 +	ptr = strchr(params, ':');
  62.176 +	if (!ptr)
  62.177 +		return -EINVAL;
  62.178 +
  62.179 +	len = ptr - params;
  62.180 +
  62.181 +	if (len > sizeof(name) - 1)
  62.182 +		return -ENAMETOOLONG;
  62.183 +
  62.184 +	memset(name, 0, sizeof(name));
  62.185 +	strncpy(name, params, len);
  62.186 +
  62.187 +	type = tapdisk_disktype_find(name);
  62.188 +
  62.189 +	if (type >= 0)
  62.190 +		*_path = params + len + 1;
  62.191 +
  62.192 +	return type;
  62.193 +}
  62.194 +
  62.195 +int
  62.196 +tapdisk_parse_disk_type(const char *params, const char **_path, int *_type)
  62.197 +{
  62.198 +	int type;
  62.199 +
  62.200 +	type = tapdisk_disktype_parse_params(params, _path);
  62.201 +	if (type < 0)
  62.202 +		return type;
  62.203 +
  62.204 +	*_type = type;
  62.205 +
  62.206 +	return 0;
  62.207 +}
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/tools/blktap2/drivers/tapdisk-disktype.h	Fri Jul 16 17:16:06 2010 -0700
    63.3 @@ -0,0 +1,62 @@
    63.4 +/*
    63.5 + * Copyright (c) 2007, 2010, XenSource Inc.
    63.6 + * All rights reserved.
    63.7 + *
    63.8 + * Redistribution and use in source and binary forms, with or without
    63.9 + * modification, are permitted provided that the following conditions are met:
   63.10 + *     * Redistributions of source code must retain the above copyright
   63.11 + *       notice, this list of conditions and the following disclaimer.
   63.12 + *     * Redistributions in binary form must reproduce the above copyright
   63.13 + *       notice, this list of conditions and the following disclaimer in the
   63.14 + *       documentation and/or other materials provided with the distribution.
   63.15 + *     * Neither the name of XenSource Inc. nor the names of its contributors
   63.16 + *       may be used to endorse or promote products derived from this software
   63.17 + *       without specific prior written permission.
   63.18 + *
   63.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   63.20 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   63.21 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   63.22 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   63.23 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   63.24 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   63.25 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   63.26 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   63.27 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   63.28 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   63.29 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   63.30 + */
   63.31 +
   63.32 +#ifndef __DISKTYPES_H__
   63.33 +#define __DISKTYPES_H__
   63.34 +
   63.35 +#define DISK_TYPE_AIO         0
   63.36 +#define DISK_TYPE_SYNC        1
   63.37 +#define DISK_TYPE_VMDK        2
   63.38 +#define DISK_TYPE_VHDSYNC     3
   63.39 +#define DISK_TYPE_VHD         4
   63.40 +#define DISK_TYPE_RAM         5
   63.41 +#define DISK_TYPE_QCOW        6
   63.42 +#define DISK_TYPE_BLOCK_CACHE 7
   63.43 +#define DISK_TYPE_LOG         9
   63.44 +#define DISK_TYPE_REMUS       10
   63.45 +#define DISK_TYPE_VINDEX      11
   63.46 +
   63.47 +#define DISK_TYPE_NAME_MAX    32
   63.48 +
   63.49 +typedef struct disk_info {
   63.50 +	const char     *name; /* driver name, e.g. 'aio' */
   63.51 +	char           *desc;  /* e.g. "raw image" */
   63.52 +	unsigned int    flags; 
   63.53 +} disk_info_t;
   63.54 +
   63.55 +extern const disk_info_t     *tapdisk_disk_types[];
   63.56 +extern const struct tap_disk *tapdisk_disk_drivers[];
   63.57 +
   63.58 +/* one single controller for all instances of disk type */
   63.59 +#define DISK_TYPE_SINGLE_CONTROLLER (1<<0)
   63.60 +
   63.61 +int tapdisk_disktype_find(const char *name);
   63.62 +int tapdisk_disktype_parse_params(const char *params, const char **_path);
   63.63 +int tapdisk_parse_disk_type(const char *, const char **, int *);
   63.64 +
   63.65 +#endif
    64.1 --- a/tools/blktap2/drivers/tapdisk-driver.c	Wed Jun 09 19:53:32 2010 -0700
    64.2 +++ b/tools/blktap2/drivers/tapdisk-driver.c	Fri Jul 16 17:16:06 2010 -0700
    64.3 @@ -29,15 +29,16 @@
    64.4  
    64.5  #include "tapdisk-driver.h"
    64.6  #include "tapdisk-server.h"
    64.7 +#include "tapdisk-disktype.h"
    64.8  
    64.9  td_driver_t *
   64.10  tapdisk_driver_allocate(int type, char *name, td_flag_t flags, int storage)
   64.11  {
   64.12  	int err;
   64.13  	td_driver_t *driver;
   64.14 -	struct tap_disk *ops;
   64.15 +	const struct tap_disk *ops;
   64.16  
   64.17 -	ops = tapdisk_server_find_driver_interface(type);
   64.18 +	ops = tapdisk_disk_drivers[type];
   64.19  	if (!ops)
   64.20  		return NULL;
   64.21  
    65.1 --- a/tools/blktap2/drivers/tapdisk-driver.h	Wed Jun 09 19:53:32 2010 -0700
    65.2 +++ b/tools/blktap2/drivers/tapdisk-driver.h	Fri Jul 16 17:16:06 2010 -0700
    65.3 @@ -47,7 +47,7 @@ struct td_driver_handle {
    65.4  	td_disk_info_t               info;
    65.5  
    65.6  	void                        *data;
    65.7 -	struct tap_disk             *ops;
    65.8 +	const struct tap_disk       *ops;
    65.9  
   65.10  	struct list_head             next;
   65.11  };
    66.1 --- a/tools/blktap2/drivers/tapdisk-image.c	Wed Jun 09 19:53:32 2010 -0700
    66.2 +++ b/tools/blktap2/drivers/tapdisk-image.c	Fri Jul 16 17:16:06 2010 -0700
    66.3 @@ -39,7 +39,7 @@
    66.4  #define ERR(_err, _f, _a...) tlog_error(_err, _f, ##_a)
    66.5  
    66.6  td_image_t *
    66.7 -tapdisk_image_allocate(char *file, int type, int storage,
    66.8 +tapdisk_image_allocate(const char *file, int type, int storage,
    66.9  		       td_flag_t flags, void *private)
   66.10  {
   66.11  	int err;
    67.1 --- a/tools/blktap2/drivers/tapdisk-image.h	Wed Jun 09 19:53:32 2010 -0700
    67.2 +++ b/tools/blktap2/drivers/tapdisk-image.h	Fri Jul 16 17:16:06 2010 -0700
    67.3 @@ -47,7 +47,7 @@ struct td_image_handle {
    67.4  	struct list_head             next;
    67.5  };
    67.6  
    67.7 -td_image_t *tapdisk_image_allocate(char *, int, int, td_flag_t, void *);
    67.8 +td_image_t *tapdisk_image_allocate(const char *, int, int, td_flag_t, void *);
    67.9  void tapdisk_image_free(td_image_t *);
   67.10  
   67.11  int tapdisk_image_check_td_request(td_image_t *, td_request_t);
    68.1 --- a/tools/blktap2/drivers/tapdisk-interface.c	Wed Jun 09 19:53:32 2010 -0700
    68.2 +++ b/tools/blktap2/drivers/tapdisk-interface.c	Fri Jul 16 17:16:06 2010 -0700
    68.3 @@ -59,7 +59,7 @@ td_load(td_image_t *image)
    68.4  }
    68.5  
    68.6  int
    68.7 -td_open(td_image_t *image)
    68.8 +__td_open(td_image_t *image, td_disk_info_t *info)
    68.9  {
   68.10  	int err;
   68.11  	td_driver_t *driver;
   68.12 @@ -72,6 +72,9 @@ td_open(td_image_t *image)
   68.13  						 image->storage);
   68.14  		if (!driver)
   68.15  			return -ENOMEM;
   68.16 +
   68.17 +		if (info) /* pre-seed driver->info for virtual drivers */
   68.18 +			driver->info = *info;
   68.19  	}
   68.20  
   68.21  	if (!td_flag_test(driver->state, TD_DRIVER_OPEN)) {
   68.22 @@ -95,6 +98,12 @@ td_open(td_image_t *image)
   68.23  }
   68.24  
   68.25  int
   68.26 +td_open(td_image_t *image)
   68.27 +{
   68.28 +	return __td_open(image, NULL);
   68.29 +}
   68.30 +
   68.31 +int
   68.32  td_close(td_image_t *image)
   68.33  {
   68.34  	td_driver_t *driver;
    69.1 --- a/tools/blktap2/drivers/tapdisk-interface.h	Wed Jun 09 19:53:32 2010 -0700
    69.2 +++ b/tools/blktap2/drivers/tapdisk-interface.h	Fri Jul 16 17:16:06 2010 -0700
    69.3 @@ -32,6 +32,7 @@
    69.4  #include "tapdisk-queue.h"
    69.5  
    69.6  int td_open(td_image_t *);
    69.7 +int __td_open(td_image_t *, td_disk_info_t *);
    69.8  int td_load(td_image_t *);
    69.9  int td_close(td_image_t *);
   69.10  int td_get_parent_id(td_image_t *, td_disk_id_t *);
    70.1 --- a/tools/blktap2/drivers/tapdisk-ipc.c	Wed Jun 09 19:53:32 2010 -0700
    70.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.3 @@ -1,353 +0,0 @@
    70.4 -/* 
    70.5 - * Copyright (c) 2008, XenSource Inc.
    70.6 - * All rights reserved.
    70.7 - *
    70.8 - * Redistribution and use in source and binary forms, with or without
    70.9 - * modification, are permitted provided that the following conditions are met:
   70.10 - *     * Redistributions of source code must retain the above copyright
   70.11 - *       notice, this list of conditions and the following disclaimer.
   70.12 - *     * Redistributions in binary form must reproduce the above copyright
   70.13 - *       notice, this list of conditions and the following disclaimer in the
   70.14 - *       documentation and/or other materials provided with the distribution.
   70.15 - *     * Neither the name of XenSource Inc. nor the names of its contributors
   70.16 - *       may be used to endorse or promote products derived from this software
   70.17 - *       without specific prior written permission.
   70.18 - *
   70.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   70.20 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   70.21 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   70.22 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   70.23 - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   70.24 - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   70.25 - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   70.26 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   70.27 - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   70.28 - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   70.29 - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   70.30 - */
   70.31 -#include <stdio.h>
   70.32 -#include <errno.h>
   70.33 -#include <stdlib.h>
   70.34 -#include <unistd.h>
   70.35 -#include <string.h>
   70.36 -#include <fcntl.h>
   70.37 -
   70.38 -#include "tapdisk.h"
   70.39 -#include "tapdisk-ipc.h"
   70.40 -#include "tapdisk-vbd.h"
   70.41 -#include "tapdisk-server.h"
   70.42 -
   70.43 -static void
   70.44 -tapdisk_ipc_read_event(event_id_t id, char mode, void *private)
   70.45 -{
   70.46 -	td_ipc_t *ipc = private;
   70.47 -	tapdisk_ipc_read(ipc);
   70.48 -}
   70.49 -
   70.50 -static void
   70.51 -__tapdisk_ipc_init(td_ipc_t *ipc)
   70.52 -{
   70.53 -	ipc->rfd = -1;
   70.54 -	ipc->wfd = -1;
   70.55 -	ipc->rfd_event = -1;
   70.56 -}
   70.57 -
   70.58 -int
   70.59 -tapdisk_ipc_open(td_ipc_t *ipc, const char *read, const char *write)
   70.60 -{
   70.61 -	int err;
   70.62 -
   70.63 -	memset(ipc, 0, sizeof(td_ipc_t));
   70.64 -	__tapdisk_ipc_init(ipc);
   70.65 -
   70.66 -	if (read) {
   70.67 -		ipc->rfd = open(read, O_RDWR | O_NONBLOCK);
   70.68 -		if (ipc->rfd < 0) {
   70.69 -			err = -errno;
   70.70 -			EPRINTF("FD open failed %s: %d\n", read, err);
   70.71 -			goto fail;
   70.72 -		}
   70.73 -
   70.74 -		ipc->rfd_event = 
   70.75 -			tapdisk_server_register_event(SCHEDULER_POLL_READ_FD,
   70.76 -						      ipc->rfd, 0,
   70.77 -						      tapdisk_ipc_read_event,
   70.78 -						      ipc);
   70.79 -		if (ipc->rfd_event < 0) {
   70.80 -			err = ipc->rfd_event;
   70.81 -			goto fail;
   70.82 -		}
   70.83 -	}
   70.84 -
   70.85 -	if (write) {
   70.86 -		ipc->wfd = open(write, O_RDWR | O_NONBLOCK);
   70.87 -		if (ipc->wfd < 0) {
   70.88 -			err = -errno;
   70.89 -			EPRINTF("FD open failed %s, %d\n", write, err);
   70.90 -			goto fail;
   70.91 -		}
   70.92 -	}
   70.93 -
   70.94 -	return 0;
   70.95 -
   70.96 -fail:
   70.97 -	tapdisk_ipc_close(ipc);
   70.98 -	return err;
   70.99 -}
  70.100 -
  70.101 -void
  70.102 -tapdisk_ipc_close(td_ipc_t *ipc)
  70.103 -{
  70.104 -	if (ipc->rfd > 0)
  70.105 -		close(ipc->rfd);
  70.106 -
  70.107 -	if (ipc->wfd > 0)
  70.108 -		close(ipc->wfd);
  70.109 -
  70.110 -	if (ipc->rfd_event >= 0)
  70.111 -		tapdisk_server_unregister_event(ipc->rfd_event);
  70.112 -
  70.113 -	__tapdisk_ipc_init(ipc);
  70.114 -}
  70.115 -
  70.116 -static int
  70.117 -tapdisk_ipc_write_message(int fd, tapdisk_message_t *message, int timeout)
  70.118 -{
  70.119 -	fd_set writefds;
  70.120 -	int ret, len, offset;
  70.121 -	struct timeval tv, *t;
  70.122 -
  70.123 -	t      = NULL;
  70.124 -	offset = 0;
  70.125 -	len    = sizeof(tapdisk_message_t);
  70.126 -
  70.127 -	if (timeout) {
  70.128 -		tv.tv_sec  = timeout;
  70.129 -		tv.tv_usec = 0;
  70.130 -		t = &tv;
  70.131 -	}
  70.132 -
  70.133 -	DPRINTF("sending '%s' message (uuid = %u)\n",
  70.134 -		tapdisk_message_name(message->type), message->cookie);
  70.135 -
  70.136 -	while (offset < len) {
  70.137 -		FD_ZERO(&writefds);
  70.138 -		FD_SET(fd, &writefds);
  70.139 -
  70.140 -		/* we don't bother reinitializing tv. at worst, it will wait a
  70.141 -		 * bit more time than expected. */
  70.142 -
  70.143 -		ret = select(fd + 1, NULL, &writefds, NULL, t);
  70.144 -		if (ret == -1)
  70.145 -			break;
  70.146 -		else if (FD_ISSET(fd, &writefds)) {
  70.147 -			ret = write(fd, message + offset, len - offset);
  70.148 -			if (ret <= 0)
  70.149 -				break;
  70.150 -			offset += ret;
  70.151 -		} else
  70.152 -			break;
  70.153 -	}
  70.154 -
  70.155 -	if (offset != len) {
  70.156 -		EPRINTF("failure writing message\n");
  70.157 -		return -EIO;
  70.158 -	}
  70.159 -
  70.160 -	return 0;
  70.161 -}
  70.162 -
  70.163 -int
  70.164 -tapdisk_ipc_write(td_ipc_t *ipc, int type)
  70.165 -{
  70.166 -	tapdisk_message_t message;
  70.167 -
  70.168 -	if (ipc->wfd == -1)
  70.169 -		return 0;
  70.170 -
  70.171 -	memset(&message, 0, sizeof(tapdisk_message_t));
  70.172 -	message.type   = type;
  70.173 -	message.cookie = ipc->uuid;
  70.174 -
  70.175 -	return tapdisk_ipc_write_message(ipc->wfd, &message, 2);
  70.176 -}
  70.177 -
  70.178 -int
  70.179 -tapdisk_ipc_write_error(td_ipc_t *ipc, const char *text)
  70.180 -{
  70.181 -	tapdisk_message_t message;
  70.182 -
  70.183 -	memset(&message, 0, sizeof(message));
  70.184 -	message.type   = TAPDISK_MESSAGE_RUNTIME_ERROR;
  70.185 -	message.cookie = ipc->uuid;
  70.186 -	snprintf(message.u.string.text, sizeof(message.u.string.text), "%s", text);
  70.187 -
  70.188 -	return tapdisk_ipc_write_message(ipc->wfd, &message, 2);
  70.189 -}
  70.190 -
  70.191 -static int
  70.192 -tapdisk_ipc_read_message(int fd, tapdisk_message_t *message, int timeout)
  70.193 -{
  70.194 -	fd_set readfds;
  70.195 -	int ret, len, offset;
  70.196 -	struct timeval tv, *t;
  70.197 -
  70.198 -	t      = NULL;
  70.199 -	offset = 0;
  70.200 -	len    = sizeof(tapdisk_message_t);
  70.201 -
  70.202 -	if (timeout) {
  70.203 -		tv.tv_sec  = timeout;
  70.204 -		tv.tv_usec = 0;
  70.205 -		t = &tv;
  70.206 -	}
  70.207 -
  70.208 -	memset(message, 0, sizeof(tapdisk_message_t));
  70.209 -
  70.210 -	while (offset < len) {
  70.211 -		FD_ZERO(&readfds);
  70.212 -		FD_SET(fd, &readfds);
  70.213 -
  70.214 -		/* we don't bother reinitializing tv. at worst, it will wait a
  70.215 -		 * bit more time than expected. */
  70.216 -
  70.217 -		ret = select(fd + 1, &readfds, NULL, NULL, t);
  70.218 -		if (ret == -1)
  70.219 -			break;
  70.220 -		else if (FD_ISSET(fd, &readfds)) {
  70.221 -			ret = read(fd, message + offset, len - offset);
  70.222 -			if (ret <= 0)
  70.223 -				break;
  70.224 -			offset += ret;
  70.225 -		} else
  70.226 -			break;
  70.227 -	}
  70.228 -
  70.229 -	if (offset != len) {
  70.230 -		EPRINTF("failure reading message\n");
  70.231 -		return -EIO;
  70.232 -	}
  70.233 -
  70.234 -	DPRINTF("received '%s' message (uuid = %u)\n",
  70.235 -		tapdisk_message_name(message->type), message->cookie);
  70.236 -
  70.237 -	return 0;
  70.238 -}
  70.239 -
  70.240 -int
  70.241 -tapdisk_ipc_read(td_ipc_t *ipc)
  70.242 -{
  70.243 -	int err;
  70.244 -	td_vbd_t *vbd;
  70.245 -	td_uuid_t uuid;
  70.246 -	tapdisk_message_t message;
  70.247 -
  70.248 -	err = tapdisk_ipc_read_message(ipc->rfd, &message, 2);
  70.249 -	if (err) {
  70.250 -		tapdisk_server_check_state();
  70.251 -		return err;
  70.252 -	}
  70.253 -
  70.254 -	uuid = message.cookie;
  70.255 -	vbd  = tapdisk_server_get_vbd(uuid);
  70.256 -
  70.257 -	if (!vbd && message.type != TAPDISK_MESSAGE_PID) {
  70.258 -		EPRINTF("received message for non-existing vbd: %u\n", uuid);
  70.259 -		err = -EINVAL;
  70.260 -		goto fail;
  70.261 -	}
  70.262 -
  70.263 -	switch (message.type) {
  70.264 -	case TAPDISK_MESSAGE_PID:
  70.265 -		err = tapdisk_vbd_initialize(ipc->rfd, ipc->wfd, uuid);
  70.266 -
  70.267 -		memset(&message, 0, sizeof(tapdisk_message_t));
  70.268 -		message.cookie = uuid;
  70.269 -
  70.270 -		if (!err) {
  70.271 -			message.type          = TAPDISK_MESSAGE_PID_RSP;
  70.272 -			message.u.tapdisk_pid = getpid();
  70.273 -		} else
  70.274 -			message.type          = TAPDISK_MESSAGE_ERROR;
  70.275 -
  70.276 -		return tapdisk_ipc_write_message(ipc->wfd, &message, 0);
  70.277 -
  70.278 -	case TAPDISK_MESSAGE_OPEN:
  70.279 -	{
  70.280 -		image_t image;
  70.281 -		char *devname;
  70.282 -		td_flag_t flags;
  70.283 -
  70.284 -		flags = 0;
  70.285 -
  70.286 -		if (message.u.params.flags & TAPDISK_MESSAGE_FLAG_RDONLY)
  70.287 -			flags |= TD_OPEN_RDONLY;
  70.288 -		if (message.u.params.flags & TAPDISK_MESSAGE_FLAG_SHARED)
  70.289 -			flags |= TD_OPEN_SHAREABLE;
  70.290 -		if (message.u.params.flags & TAPDISK_MESSAGE_FLAG_ADD_CACHE)
  70.291 -			flags |= TD_OPEN_ADD_CACHE;
  70.292 -		if (message.u.params.flags & TAPDISK_MESSAGE_FLAG_VHD_INDEX)
  70.293 -			flags |= TD_OPEN_VHD_INDEX;
  70.294 -		if (message.u.params.flags & TAPDISK_MESSAGE_FLAG_LOG_DIRTY)
  70.295 -			flags |= TD_OPEN_LOG_DIRTY;
  70.296 -
  70.297 -		err   = aspri