/libvirt-0.9.11/src/xen/xen_hypervisor.c
C | 3720 lines | 2636 code | 476 blank | 608 comment | 591 complexity | f2299dc4a0741d9f9279da5608c34bc1 MD5 | raw file
Possible License(s): LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- /*
- * xen_internal.c: direct access to Xen hypervisor level
- *
- * Copyright (C) 2005-2012 Red Hat, Inc.
- *
- * See COPYING.LIB for the License of this software
- *
- * Daniel Veillard <veillard@redhat.com>
- */
- #include <config.h>
- #include <stdio.h>
- #include <string.h>
- /* required for uint8_t, uint32_t, etc ... */
- #include <stdint.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <sys/ioctl.h>
- #include <limits.h>
- #include <stdint.h>
- #include <regex.h>
- #include <errno.h>
- #include <sys/utsname.h>
- #ifdef __sun
- # include <sys/systeminfo.h>
- # include <priv.h>
- # ifndef PRIV_XVM_CONTROL
- # define PRIV_XVM_CONTROL ((const char *)"xvm_control")
- # endif
- #endif /* __sun */
- /* required for dom0_getdomaininfo_t */
- #include <xen/dom0_ops.h>
- #include <xen/version.h>
- #ifdef HAVE_XEN_LINUX_PRIVCMD_H
- # include <xen/linux/privcmd.h>
- #else
- # ifdef HAVE_XEN_SYS_PRIVCMD_H
- # include <xen/sys/privcmd.h>
- # endif
- #endif
- /* required for shutdown flags */
- #include <xen/sched.h>
- #include "virterror_internal.h"
- #include "logging.h"
- #include "datatypes.h"
- #include "driver.h"
- #include "util.h"
- #include "xen_driver.h"
- #include "xen_hypervisor.h"
- #include "xs_internal.h"
- #include "stats_linux.h"
- #include "block_stats.h"
- #include "xend_internal.h"
- #include "buf.h"
- #include "capabilities.h"
- #include "memory.h"
- #include "virfile.h"
- #include "virnodesuspend.h"
- #include "virtypedparam.h"
- #define VIR_FROM_THIS VIR_FROM_XEN
- /*
- * so far there is 2 versions of the structures usable for doing
- * hypervisor calls.
- */
- /* the old one */
- typedef struct v0_hypercall_struct {
- unsigned long op;
- unsigned long arg[5];
- } v0_hypercall_t;
- #ifdef __linux__
- # define XEN_V0_IOCTL_HYPERCALL_CMD \
- _IOC(_IOC_NONE, 'P', 0, sizeof(v0_hypercall_t))
- /* the new one */
- typedef struct v1_hypercall_struct
- {
- uint64_t op;
- uint64_t arg[5];
- } v1_hypercall_t;
- # define XEN_V1_IOCTL_HYPERCALL_CMD \
- _IOC(_IOC_NONE, 'P', 0, sizeof(v1_hypercall_t))
- typedef v1_hypercall_t hypercall_t;
- #elif defined(__sun)
- typedef privcmd_hypercall_t hypercall_t;
- #else
- # error "unsupported platform"
- #endif
- #ifndef __HYPERVISOR_sysctl
- # define __HYPERVISOR_sysctl 35
- #endif
- #ifndef __HYPERVISOR_domctl
- # define __HYPERVISOR_domctl 36
- #endif
- #ifdef WITH_RHEL5_API
- # define SYS_IFACE_MIN_VERS_NUMA 3
- #else
- # define SYS_IFACE_MIN_VERS_NUMA 4
- #endif
- static int xen_ioctl_hypercall_cmd = 0;
- static int initialized = 0;
- static int in_init = 0;
- static struct xenHypervisorVersions hv_versions = {
- .hv = 0,
- .hypervisor = 2,
- .sys_interface = -1,
- .dom_interface = -1,
- };
- static int kb_per_pages = 0;
- /* Regular expressions used by xenHypervisorGetCapabilities, and
- * compiled once by xenHypervisorInit. Note that these are POSIX.2
- * extended regular expressions (regex(7)).
- */
- static const char *flags_hvm_re = "^flags[[:blank:]]+:.* (vmx|svm)[[:space:]]";
- static regex_t flags_hvm_rec;
- static const char *flags_pae_re = "^flags[[:blank:]]+:.* pae[[:space:]]";
- static regex_t flags_pae_rec;
- static const char *xen_cap_re = "(xen|hvm)-[[:digit:]]+\\.[[:digit:]]+-(x86_32|x86_64|ia64|powerpc64)(p|be)?";
- static regex_t xen_cap_rec;
- /*
- * The content of the structures for a getdomaininfolist system hypercall
- */
- #ifndef DOMFLAGS_DYING
- # define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */
- # define DOMFLAGS_HVM (1<<1) /* Domain is HVM */
- # define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */
- # define DOMFLAGS_PAUSED (1<<3) /* Currently paused by control software. */
- # define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */
- # define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */
- # define DOMFLAGS_CPUMASK 255 /* CPU to which this domain is bound. */
- # define DOMFLAGS_CPUSHIFT 8
- # define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code. */
- # define DOMFLAGS_SHUTDOWNSHIFT 16
- #endif
- /*
- * These flags explain why a system is in the state of "shutdown". Normally,
- * They are defined in xen/sched.h
- */
- #ifndef SHUTDOWN_poweroff
- # define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */
- # define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */
- # define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */
- # define SHUTDOWN_crash 3 /* Tell controller we've crashed. */
- #endif
- #define XEN_V0_OP_GETDOMAININFOLIST 38
- #define XEN_V1_OP_GETDOMAININFOLIST 38
- #define XEN_V2_OP_GETDOMAININFOLIST 6
- struct xen_v0_getdomaininfo {
- domid_t domain; /* the domain number */
- uint32_t flags; /* flags, see before */
- uint64_t tot_pages; /* total number of pages used */
- uint64_t max_pages; /* maximum number of pages allowed */
- unsigned long shared_info_frame; /* MFN of shared_info struct */
- uint64_t cpu_time; /* CPU time used */
- uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
- uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
- uint32_t ssidref;
- xen_domain_handle_t handle;
- };
- typedef struct xen_v0_getdomaininfo xen_v0_getdomaininfo;
- struct xen_v2_getdomaininfo {
- domid_t domain; /* the domain number */
- uint32_t flags; /* flags, see before */
- uint64_t tot_pages; /* total number of pages used */
- uint64_t max_pages; /* maximum number of pages allowed */
- uint64_t shared_info_frame; /* MFN of shared_info struct */
- uint64_t cpu_time; /* CPU time used */
- uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
- uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
- uint32_t ssidref;
- xen_domain_handle_t handle;
- };
- typedef struct xen_v2_getdomaininfo xen_v2_getdomaininfo;
- /* As of Hypervisor Call v2, DomCtl v5 we are now 8-byte aligned
- even on 32-bit archs when dealing with uint64_t */
- #define ALIGN_64 __attribute__((aligned(8)))
- struct xen_v2d5_getdomaininfo {
- domid_t domain; /* the domain number */
- uint32_t flags; /* flags, see before */
- uint64_t tot_pages ALIGN_64; /* total number of pages used */
- uint64_t max_pages ALIGN_64; /* maximum number of pages allowed */
- uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
- uint64_t cpu_time ALIGN_64; /* CPU time used */
- uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
- uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
- uint32_t ssidref;
- xen_domain_handle_t handle;
- };
- typedef struct xen_v2d5_getdomaininfo xen_v2d5_getdomaininfo;
- struct xen_v2d6_getdomaininfo {
- domid_t domain; /* the domain number */
- uint32_t flags; /* flags, see before */
- uint64_t tot_pages ALIGN_64; /* total number of pages used */
- uint64_t max_pages ALIGN_64; /* maximum number of pages allowed */
- uint64_t shr_pages ALIGN_64; /* number of shared pages */
- uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
- uint64_t cpu_time ALIGN_64; /* CPU time used */
- uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
- uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
- uint32_t ssidref;
- xen_domain_handle_t handle;
- };
- typedef struct xen_v2d6_getdomaininfo xen_v2d6_getdomaininfo;
- struct xen_v2d7_getdomaininfo {
- domid_t domain; /* the domain number */
- uint32_t flags; /* flags, see before */
- uint64_t tot_pages ALIGN_64; /* total number of pages used */
- uint64_t max_pages ALIGN_64; /* maximum number of pages allowed */
- uint64_t shr_pages ALIGN_64; /* number of shared pages */
- uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
- uint64_t cpu_time ALIGN_64; /* CPU time used */
- uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
- uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
- uint32_t ssidref;
- xen_domain_handle_t handle;
- uint32_t cpupool;
- };
- typedef struct xen_v2d7_getdomaininfo xen_v2d7_getdomaininfo;
- struct xen_v2d8_getdomaininfo {
- domid_t domain; /* the domain number */
- uint32_t flags; /* flags, see before */
- uint64_t tot_pages ALIGN_64; /* total number of pages used */
- uint64_t max_pages ALIGN_64; /* maximum number of pages allowed */
- uint64_t shr_pages ALIGN_64; /* number of shared pages */
- uint64_t paged_pages ALIGN_64; /* number of paged pages */
- uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
- uint64_t cpu_time ALIGN_64; /* CPU time used */
- uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
- uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
- uint32_t ssidref;
- xen_domain_handle_t handle;
- uint32_t cpupool;
- };
- typedef struct xen_v2d8_getdomaininfo xen_v2d8_getdomaininfo;
- union xen_getdomaininfo {
- struct xen_v0_getdomaininfo v0;
- struct xen_v2_getdomaininfo v2;
- struct xen_v2d5_getdomaininfo v2d5;
- struct xen_v2d6_getdomaininfo v2d6;
- struct xen_v2d7_getdomaininfo v2d7;
- struct xen_v2d8_getdomaininfo v2d8;
- };
- typedef union xen_getdomaininfo xen_getdomaininfo;
- union xen_getdomaininfolist {
- struct xen_v0_getdomaininfo *v0;
- struct xen_v2_getdomaininfo *v2;
- struct xen_v2d5_getdomaininfo *v2d5;
- struct xen_v2d6_getdomaininfo *v2d6;
- struct xen_v2d7_getdomaininfo *v2d7;
- struct xen_v2d8_getdomaininfo *v2d8;
- };
- typedef union xen_getdomaininfolist xen_getdomaininfolist;
- struct xen_v2_getschedulerid {
- uint32_t sched_id; /* Get Scheduler ID from Xen */
- };
- typedef struct xen_v2_getschedulerid xen_v2_getschedulerid;
- union xen_getschedulerid {
- struct xen_v2_getschedulerid *v2;
- };
- typedef union xen_getschedulerid xen_getschedulerid;
- struct xen_v2s4_availheap {
- uint32_t min_bitwidth; /* Smallest address width (zero if don't care). */
- uint32_t max_bitwidth; /* Largest address width (zero if don't care). */
- int32_t node; /* NUMA node (-1 for sum across all nodes). */
- uint64_t avail_bytes; /* Bytes available in the specified region. */
- };
- typedef struct xen_v2s4_availheap xen_v2s4_availheap;
- struct xen_v2s5_availheap {
- uint32_t min_bitwidth; /* Smallest address width (zero if don't care). */
- uint32_t max_bitwidth; /* Largest address width (zero if don't care). */
- int32_t node; /* NUMA node (-1 for sum across all nodes). */
- uint64_t avail_bytes ALIGN_64; /* Bytes available in the specified region. */
- };
- typedef struct xen_v2s5_availheap xen_v2s5_availheap;
- #define XEN_GETDOMAININFOLIST_ALLOC(domlist, size) \
- (hv_versions.hypervisor < 2 ? \
- (VIR_ALLOC_N(domlist.v0, (size)) == 0) : \
- (hv_versions.dom_interface >= 8 ? \
- (VIR_ALLOC_N(domlist.v2d8, (size)) == 0) : \
- (hv_versions.dom_interface == 7 ? \
- (VIR_ALLOC_N(domlist.v2d7, (size)) == 0) : \
- (hv_versions.dom_interface == 6 ? \
- (VIR_ALLOC_N(domlist.v2d6, (size)) == 0) : \
- (hv_versions.dom_interface == 5 ? \
- (VIR_ALLOC_N(domlist.v2d5, (size)) == 0) : \
- (VIR_ALLOC_N(domlist.v2, (size)) == 0))))))
- #define XEN_GETDOMAININFOLIST_FREE(domlist) \
- (hv_versions.hypervisor < 2 ? \
- VIR_FREE(domlist.v0) : \
- (hv_versions.dom_interface >= 8 ? \
- VIR_FREE(domlist.v2d8) : \
- (hv_versions.dom_interface == 7 ? \
- VIR_FREE(domlist.v2d7) : \
- (hv_versions.dom_interface == 6 ? \
- VIR_FREE(domlist.v2d6) : \
- (hv_versions.dom_interface == 5 ? \
- VIR_FREE(domlist.v2d5) : \
- VIR_FREE(domlist.v2))))))
- #define XEN_GETDOMAININFOLIST_CLEAR(domlist, size) \
- (hv_versions.hypervisor < 2 ? \
- memset(domlist.v0, 0, sizeof(*domlist.v0) * size) : \
- (hv_versions.dom_interface >= 8 ? \
- memset(domlist.v2d8, 0, sizeof(*domlist.v2d8) * size) : \
- (hv_versions.dom_interface == 7 ? \
- memset(domlist.v2d7, 0, sizeof(*domlist.v2d7) * size) : \
- (hv_versions.dom_interface == 6 ? \
- memset(domlist.v2d6, 0, sizeof(*domlist.v2d6) * size) : \
- (hv_versions.dom_interface == 5 ? \
- memset(domlist.v2d5, 0, sizeof(*domlist.v2d5) * size) : \
- memset(domlist.v2, 0, sizeof(*domlist.v2) * size))))))
- #define XEN_GETDOMAININFOLIST_DOMAIN(domlist, n) \
- (hv_versions.hypervisor < 2 ? \
- domlist.v0[n].domain : \
- (hv_versions.dom_interface >= 8 ? \
- domlist.v2d8[n].domain : \
- (hv_versions.dom_interface == 7 ? \
- domlist.v2d7[n].domain : \
- (hv_versions.dom_interface == 6 ? \
- domlist.v2d6[n].domain : \
- (hv_versions.dom_interface == 5 ? \
- domlist.v2d5[n].domain : \
- domlist.v2[n].domain)))))
- #define XEN_GETDOMAININFOLIST_UUID(domlist, n) \
- (hv_versions.hypervisor < 2 ? \
- domlist.v0[n].handle : \
- (hv_versions.dom_interface >= 8 ? \
- domlist.v2d8[n].handle : \
- (hv_versions.dom_interface == 7 ? \
- domlist.v2d7[n].handle : \
- (hv_versions.dom_interface == 6 ? \
- domlist.v2d6[n].handle : \
- (hv_versions.dom_interface == 5 ? \
- domlist.v2d5[n].handle : \
- domlist.v2[n].handle)))))
- #define XEN_GETDOMAININFOLIST_DATA(domlist) \
- (hv_versions.hypervisor < 2 ? \
- (void*)(domlist->v0) : \
- (hv_versions.dom_interface >= 8 ? \
- (void*)(domlist->v2d8) : \
- (hv_versions.dom_interface == 7 ? \
- (void*)(domlist->v2d7) : \
- (hv_versions.dom_interface == 6 ? \
- (void*)(domlist->v2d6) : \
- (hv_versions.dom_interface == 5 ? \
- (void*)(domlist->v2d5) : \
- (void*)(domlist->v2))))))
- #define XEN_GETDOMAININFO_SIZE \
- (hv_versions.hypervisor < 2 ? \
- sizeof(xen_v0_getdomaininfo) : \
- (hv_versions.dom_interface >= 8 ? \
- sizeof(xen_v2d8_getdomaininfo) : \
- (hv_versions.dom_interface == 7 ? \
- sizeof(xen_v2d7_getdomaininfo) : \
- (hv_versions.dom_interface == 6 ? \
- sizeof(xen_v2d6_getdomaininfo) : \
- (hv_versions.dom_interface == 5 ? \
- sizeof(xen_v2d5_getdomaininfo) : \
- sizeof(xen_v2_getdomaininfo))))))
- #define XEN_GETDOMAININFO_CLEAR(dominfo) \
- (hv_versions.hypervisor < 2 ? \
- memset(&(dominfo.v0), 0, sizeof(xen_v0_getdomaininfo)) : \
- (hv_versions.dom_interface >= 8 ? \
- memset(&(dominfo.v2d8), 0, sizeof(xen_v2d8_getdomaininfo)) : \
- (hv_versions.dom_interface == 7 ? \
- memset(&(dominfo.v2d7), 0, sizeof(xen_v2d7_getdomaininfo)) : \
- (hv_versions.dom_interface == 6 ? \
- memset(&(dominfo.v2d6), 0, sizeof(xen_v2d6_getdomaininfo)) : \
- (hv_versions.dom_interface == 5 ? \
- memset(&(dominfo.v2d5), 0, sizeof(xen_v2d5_getdomaininfo)) : \
- memset(&(dominfo.v2), 0, sizeof(xen_v2_getdomaininfo)))))))
- #define XEN_GETDOMAININFO_DOMAIN(dominfo) \
- (hv_versions.hypervisor < 2 ? \
- dominfo.v0.domain : \
- (hv_versions.dom_interface >= 8 ? \
- dominfo.v2d8.domain : \
- (hv_versions.dom_interface == 7 ? \
- dominfo.v2d7.domain : \
- (hv_versions.dom_interface == 6 ? \
- dominfo.v2d6.domain : \
- (hv_versions.dom_interface == 5 ? \
- dominfo.v2d5.domain : \
- dominfo.v2.domain)))))
- #define XEN_GETDOMAININFO_CPUTIME(dominfo) \
- (hv_versions.hypervisor < 2 ? \
- dominfo.v0.cpu_time : \
- (hv_versions.dom_interface >= 8 ? \
- dominfo.v2d8.cpu_time : \
- (hv_versions.dom_interface == 7 ? \
- dominfo.v2d7.cpu_time : \
- (hv_versions.dom_interface == 6 ? \
- dominfo.v2d6.cpu_time : \
- (hv_versions.dom_interface == 5 ? \
- dominfo.v2d5.cpu_time : \
- dominfo.v2.cpu_time)))))
- #define XEN_GETDOMAININFO_CPUCOUNT(dominfo) \
- (hv_versions.hypervisor < 2 ? \
- dominfo.v0.nr_online_vcpus : \
- (hv_versions.dom_interface >= 8 ? \
- dominfo.v2d8.nr_online_vcpus : \
- (hv_versions.dom_interface == 7 ? \
- dominfo.v2d7.nr_online_vcpus : \
- (hv_versions.dom_interface == 6 ? \
- dominfo.v2d6.nr_online_vcpus : \
- (hv_versions.dom_interface == 5 ? \
- dominfo.v2d5.nr_online_vcpus : \
- dominfo.v2.nr_online_vcpus)))))
- #define XEN_GETDOMAININFO_MAXCPUID(dominfo) \
- (hv_versions.hypervisor < 2 ? \
- dominfo.v0.max_vcpu_id : \
- (hv_versions.dom_interface >= 8 ? \
- dominfo.v2d8.max_vcpu_id : \
- (hv_versions.dom_interface == 7 ? \
- dominfo.v2d7.max_vcpu_id : \
- (hv_versions.dom_interface == 6 ? \
- dominfo.v2d6.max_vcpu_id : \
- (hv_versions.dom_interface == 5 ? \
- dominfo.v2d5.max_vcpu_id : \
- dominfo.v2.max_vcpu_id)))))
- #define XEN_GETDOMAININFO_FLAGS(dominfo) \
- (hv_versions.hypervisor < 2 ? \
- dominfo.v0.flags : \
- (hv_versions.dom_interface >= 8 ? \
- dominfo.v2d8.flags : \
- (hv_versions.dom_interface == 7 ? \
- dominfo.v2d7.flags : \
- (hv_versions.dom_interface == 6 ? \
- dominfo.v2d6.flags : \
- (hv_versions.dom_interface == 5 ? \
- dominfo.v2d5.flags : \
- dominfo.v2.flags)))))
- #define XEN_GETDOMAININFO_TOT_PAGES(dominfo) \
- (hv_versions.hypervisor < 2 ? \
- dominfo.v0.tot_pages : \
- (hv_versions.dom_interface >= 8 ? \
- dominfo.v2d8.tot_pages : \
- (hv_versions.dom_interface == 7 ? \
- dominfo.v2d7.tot_pages : \
- (hv_versions.dom_interface == 6 ? \
- dominfo.v2d6.tot_pages : \
- (hv_versions.dom_interface == 5 ? \
- dominfo.v2d5.tot_pages : \
- dominfo.v2.tot_pages)))))
- #define XEN_GETDOMAININFO_MAX_PAGES(dominfo) \
- (hv_versions.hypervisor < 2 ? \
- dominfo.v0.max_pages : \
- (hv_versions.dom_interface >= 8 ? \
- dominfo.v2d8.max_pages : \
- (hv_versions.dom_interface == 7 ? \
- dominfo.v2d7.max_pages : \
- (hv_versions.dom_interface == 6 ? \
- dominfo.v2d6.max_pages : \
- (hv_versions.dom_interface == 5 ? \
- dominfo.v2d5.max_pages : \
- dominfo.v2.max_pages)))))
- #define XEN_GETDOMAININFO_UUID(dominfo) \
- (hv_versions.hypervisor < 2 ? \
- dominfo.v0.handle : \
- (hv_versions.dom_interface >= 8 ? \
- dominfo.v2d8.handle : \
- (hv_versions.dom_interface == 7 ? \
- dominfo.v2d7.handle : \
- (hv_versions.dom_interface == 6 ? \
- dominfo.v2d6.handle : \
- (hv_versions.dom_interface == 5 ? \
- dominfo.v2d5.handle : \
- dominfo.v2.handle)))))
- static int
- lock_pages(void *addr, size_t len)
- {
- #ifdef __linux__
- return mlock(addr, len);
- #elif defined(__sun)
- return 0;
- #endif
- }
- static int
- unlock_pages(void *addr, size_t len)
- {
- #ifdef __linux__
- return munlock(addr, len);
- #elif defined(__sun)
- return 0;
- #endif
- }
- struct xen_v0_getdomaininfolistop {
- domid_t first_domain;
- uint32_t max_domains;
- struct xen_v0_getdomaininfo *buffer;
- uint32_t num_domains;
- };
- typedef struct xen_v0_getdomaininfolistop xen_v0_getdomaininfolistop;
- struct xen_v2_getdomaininfolistop {
- domid_t first_domain;
- uint32_t max_domains;
- struct xen_v2_getdomaininfo *buffer;
- uint32_t num_domains;
- };
- typedef struct xen_v2_getdomaininfolistop xen_v2_getdomaininfolistop;
- /* As of HV version 2, sysctl version 3 the *buffer pointer is 64-bit aligned */
- struct xen_v2s3_getdomaininfolistop {
- domid_t first_domain;
- uint32_t max_domains;
- #ifdef __BIG_ENDIAN__
- struct {
- int __pad[(sizeof(long long) - sizeof(struct xen_v2d5_getdomaininfo *)) / sizeof(int)];
- struct xen_v2d5_getdomaininfo *v;
- } buffer;
- #else
- union {
- struct xen_v2d5_getdomaininfo *v;
- uint64_t pad ALIGN_64;
- } buffer;
- #endif
- uint32_t num_domains;
- };
- typedef struct xen_v2s3_getdomaininfolistop xen_v2s3_getdomaininfolistop;
- struct xen_v0_domainop {
- domid_t domain;
- };
- typedef struct xen_v0_domainop xen_v0_domainop;
- /*
- * The information for a destroydomain system hypercall
- */
- #define XEN_V0_OP_DESTROYDOMAIN 9
- #define XEN_V1_OP_DESTROYDOMAIN 9
- #define XEN_V2_OP_DESTROYDOMAIN 2
- /*
- * The information for a pausedomain system hypercall
- */
- #define XEN_V0_OP_PAUSEDOMAIN 10
- #define XEN_V1_OP_PAUSEDOMAIN 10
- #define XEN_V2_OP_PAUSEDOMAIN 3
- /*
- * The information for an unpausedomain system hypercall
- */
- #define XEN_V0_OP_UNPAUSEDOMAIN 11
- #define XEN_V1_OP_UNPAUSEDOMAIN 11
- #define XEN_V2_OP_UNPAUSEDOMAIN 4
- /*
- * The information for a setmaxmem system hypercall
- */
- #define XEN_V0_OP_SETMAXMEM 28
- #define XEN_V1_OP_SETMAXMEM 28
- #define XEN_V2_OP_SETMAXMEM 11
- struct xen_v0_setmaxmem {
- domid_t domain;
- uint64_t maxmem;
- };
- typedef struct xen_v0_setmaxmem xen_v0_setmaxmem;
- typedef struct xen_v0_setmaxmem xen_v1_setmaxmem;
- struct xen_v2_setmaxmem {
- uint64_t maxmem;
- };
- typedef struct xen_v2_setmaxmem xen_v2_setmaxmem;
- struct xen_v2d5_setmaxmem {
- uint64_t maxmem ALIGN_64;
- };
- typedef struct xen_v2d5_setmaxmem xen_v2d5_setmaxmem;
- /*
- * The information for a setmaxvcpu system hypercall
- */
- #define XEN_V0_OP_SETMAXVCPU 41
- #define XEN_V1_OP_SETMAXVCPU 41
- #define XEN_V2_OP_SETMAXVCPU 15
- struct xen_v0_setmaxvcpu {
- domid_t domain;
- uint32_t maxvcpu;
- };
- typedef struct xen_v0_setmaxvcpu xen_v0_setmaxvcpu;
- typedef struct xen_v0_setmaxvcpu xen_v1_setmaxvcpu;
- struct xen_v2_setmaxvcpu {
- uint32_t maxvcpu;
- };
- typedef struct xen_v2_setmaxvcpu xen_v2_setmaxvcpu;
- /*
- * The information for a setvcpumap system hypercall
- * Note that between 1 and 2 the limitation to 64 physical CPU was lifted
- * hence the difference in structures
- */
- #define XEN_V0_OP_SETVCPUMAP 20
- #define XEN_V1_OP_SETVCPUMAP 20
- #define XEN_V2_OP_SETVCPUMAP 9
- struct xen_v0_setvcpumap {
- domid_t domain;
- uint32_t vcpu;
- cpumap_t cpumap;
- };
- typedef struct xen_v0_setvcpumap xen_v0_setvcpumap;
- typedef struct xen_v0_setvcpumap xen_v1_setvcpumap;
- struct xen_v2_cpumap {
- uint8_t *bitmap;
- uint32_t nr_cpus;
- };
- struct xen_v2_setvcpumap {
- uint32_t vcpu;
- struct xen_v2_cpumap cpumap;
- };
- typedef struct xen_v2_setvcpumap xen_v2_setvcpumap;
- /* HV version 2, Dom version 5 requires 64-bit alignment */
- struct xen_v2d5_cpumap {
- #ifdef __BIG_ENDIAN__
- struct {
- int __pad[(sizeof(long long) - sizeof(uint8_t *)) / sizeof(int)];
- uint8_t *v;
- } bitmap;
- #else
- union {
- uint8_t *v;
- uint64_t pad ALIGN_64;
- } bitmap;
- #endif
- uint32_t nr_cpus;
- };
- struct xen_v2d5_setvcpumap {
- uint32_t vcpu;
- struct xen_v2d5_cpumap cpumap;
- };
- typedef struct xen_v2d5_setvcpumap xen_v2d5_setvcpumap;
- /*
- * The information for a vcpuinfo system hypercall
- */
- #define XEN_V0_OP_GETVCPUINFO 43
- #define XEN_V1_OP_GETVCPUINFO 43
- #define XEN_V2_OP_GETVCPUINFO 14
- struct xen_v0_vcpuinfo {
- domid_t domain; /* owner's domain */
- uint32_t vcpu; /* the vcpu number */
- uint8_t online; /* seen as on line */
- uint8_t blocked; /* blocked on event */
- uint8_t running; /* scheduled on CPU */
- uint64_t cpu_time; /* nanosecond of CPU used */
- uint32_t cpu; /* current mapping */
- cpumap_t cpumap; /* deprecated in V2 */
- };
- typedef struct xen_v0_vcpuinfo xen_v0_vcpuinfo;
- typedef struct xen_v0_vcpuinfo xen_v1_vcpuinfo;
- struct xen_v2_vcpuinfo {
- uint32_t vcpu; /* the vcpu number */
- uint8_t online; /* seen as on line */
- uint8_t blocked; /* blocked on event */
- uint8_t running; /* scheduled on CPU */
- uint64_t cpu_time; /* nanosecond of CPU used */
- uint32_t cpu; /* current mapping */
- };
- typedef struct xen_v2_vcpuinfo xen_v2_vcpuinfo;
- struct xen_v2d5_vcpuinfo {
- uint32_t vcpu; /* the vcpu number */
- uint8_t online; /* seen as on line */
- uint8_t blocked; /* blocked on event */
- uint8_t running; /* scheduled on CPU */
- uint64_t cpu_time ALIGN_64; /* nanosecond of CPU used */
- uint32_t cpu; /* current mapping */
- };
- typedef struct xen_v2d5_vcpuinfo xen_v2d5_vcpuinfo;
- /*
- * from V2 the pinning of a vcpu is read with a separate call
- */
- #define XEN_V2_OP_GETVCPUMAP 25
- typedef struct xen_v2_setvcpumap xen_v2_getvcpumap;
- typedef struct xen_v2d5_setvcpumap xen_v2d5_getvcpumap;
- /*
- * from V2 we get the scheduler information
- */
- #define XEN_V2_OP_GETSCHEDULERID 4
- /*
- * from V2 we get the available heap information
- */
- #define XEN_V2_OP_GETAVAILHEAP 9
- /*
- * from V2 we get the scheduler parameter
- */
- #define XEN_V2_OP_SCHEDULER 16
- /* Scheduler types. */
- #define XEN_SCHEDULER_SEDF 4
- #define XEN_SCHEDULER_CREDIT 5
- /* get/set scheduler parameters */
- #define XEN_DOMCTL_SCHEDOP_putinfo 0
- #define XEN_DOMCTL_SCHEDOP_getinfo 1
- struct xen_v2_setschedinfo {
- uint32_t sched_id;
- uint32_t cmd;
- union {
- struct xen_domctl_sched_sedf {
- uint64_t period ALIGN_64;
- uint64_t slice ALIGN_64;
- uint64_t latency ALIGN_64;
- uint32_t extratime;
- uint32_t weight;
- } sedf;
- struct xen_domctl_sched_credit {
- uint16_t weight;
- uint16_t cap;
- } credit;
- } u;
- };
- typedef struct xen_v2_setschedinfo xen_v2_setschedinfo;
- typedef struct xen_v2_setschedinfo xen_v2_getschedinfo;
- /*
- * The hypercall operation structures also have changed on
- * changeset 86d26e6ec89b
- */
- /* the old structure */
- struct xen_op_v0 {
- uint32_t cmd;
- uint32_t interface_version;
- union {
- xen_v0_getdomaininfolistop getdomaininfolist;
- xen_v0_domainop domain;
- xen_v0_setmaxmem setmaxmem;
- xen_v0_setmaxvcpu setmaxvcpu;
- xen_v0_setvcpumap setvcpumap;
- xen_v0_vcpuinfo getvcpuinfo;
- uint8_t padding[128];
- } u;
- };
- typedef struct xen_op_v0 xen_op_v0;
- typedef struct xen_op_v0 xen_op_v1;
- /* the new structure for systems operations */
- struct xen_op_v2_sys {
- uint32_t cmd;
- uint32_t interface_version;
- union {
- xen_v2_getdomaininfolistop getdomaininfolist;
- xen_v2s3_getdomaininfolistop getdomaininfolists3;
- xen_v2_getschedulerid getschedulerid;
- xen_v2s4_availheap availheap;
- xen_v2s5_availheap availheap5;
- uint8_t padding[128];
- } u;
- };
- typedef struct xen_op_v2_sys xen_op_v2_sys;
- /* the new structure for domains operation */
- struct xen_op_v2_dom {
- uint32_t cmd;
- uint32_t interface_version;
- domid_t domain;
- union {
- xen_v2_setmaxmem setmaxmem;
- xen_v2d5_setmaxmem setmaxmemd5;
- xen_v2_setmaxvcpu setmaxvcpu;
- xen_v2_setvcpumap setvcpumap;
- xen_v2d5_setvcpumap setvcpumapd5;
- xen_v2_vcpuinfo getvcpuinfo;
- xen_v2d5_vcpuinfo getvcpuinfod5;
- xen_v2_getvcpumap getvcpumap;
- xen_v2d5_getvcpumap getvcpumapd5;
- xen_v2_setschedinfo setschedinfo;
- xen_v2_getschedinfo getschedinfo;
- uint8_t padding[128];
- } u;
- };
- typedef struct xen_op_v2_dom xen_op_v2_dom;
- #ifdef __linux__
- # define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
- # define HYPERVISOR_CAPABILITIES "/sys/hypervisor/properties/capabilities"
- #elif defined(__sun)
- # define XEN_HYPERVISOR_SOCKET "/dev/xen/privcmd"
- #else
- # error "unsupported platform"
- #endif
- static unsigned long long xenHypervisorGetMaxMemory(virDomainPtr domain);
- struct xenUnifiedDriver xenHypervisorDriver = {
- .xenClose = xenHypervisorClose,
- .xenVersion = xenHypervisorGetVersion,
- .xenDomainSuspend = xenHypervisorPauseDomain,
- .xenDomainResume = xenHypervisorResumeDomain,
- .xenDomainDestroyFlags = xenHypervisorDestroyDomainFlags,
- .xenDomainGetOSType = xenHypervisorDomainGetOSType,
- .xenDomainGetMaxMemory = xenHypervisorGetMaxMemory,
- .xenDomainSetMaxMemory = xenHypervisorSetMaxMemory,
- .xenDomainGetInfo = xenHypervisorGetDomainInfo,
- .xenDomainPinVcpu = xenHypervisorPinVcpu,
- .xenDomainGetVcpus = xenHypervisorGetVcpus,
- .xenDomainGetSchedulerType = xenHypervisorGetSchedulerType,
- .xenDomainGetSchedulerParameters = xenHypervisorGetSchedulerParameters,
- .xenDomainSetSchedulerParameters = xenHypervisorSetSchedulerParameters,
- };
- #define virXenError(code, ...) \
- if (in_init == 0) \
- virReportErrorHelper(VIR_FROM_XEN, code, __FILE__, \
- __FUNCTION__, __LINE__, __VA_ARGS__)
- /**
- * xenHypervisorDoV0Op:
- * @handle: the handle to the Xen hypervisor
- * @op: pointer to the hypervisor operation structure
- *
- * Do a hypervisor operation though the old interface,
- * this leads to a hypervisor call through ioctl.
- *
- * Returns 0 in case of success and -1 in case of error.
- */
- static int
- xenHypervisorDoV0Op(int handle, xen_op_v0 * op)
- {
- int ret;
- v0_hypercall_t hc;
- memset(&hc, 0, sizeof(hc));
- op->interface_version = hv_versions.hv << 8;
- hc.op = __HYPERVISOR_dom0_op;
- hc.arg[0] = (unsigned long) op;
- if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
- return -1;
- }
- ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
- if (ret < 0) {
- virXenError(VIR_ERR_XEN_CALL, " ioctl %d",
- xen_ioctl_hypercall_cmd);
- }
- if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " releasing");
- ret = -1;
- }
- if (ret < 0)
- return -1;
- return 0;
- }
- /**
- * xenHypervisorDoV1Op:
- * @handle: the handle to the Xen hypervisor
- * @op: pointer to the hypervisor operation structure
- *
- * Do a hypervisor v1 operation, this leads to a hypervisor call through
- * ioctl.
- *
- * Returns 0 in case of success and -1 in case of error.
- */
- static int
- xenHypervisorDoV1Op(int handle, xen_op_v1* op)
- {
- int ret;
- hypercall_t hc;
- memset(&hc, 0, sizeof(hc));
- op->interface_version = DOM0_INTERFACE_VERSION;
- hc.op = __HYPERVISOR_dom0_op;
- hc.arg[0] = (unsigned long) op;
- if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
- return -1;
- }
- ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
- if (ret < 0) {
- virXenError(VIR_ERR_XEN_CALL, " ioctl %d",
- xen_ioctl_hypercall_cmd);
- }
- if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " releasing");
- ret = -1;
- }
- if (ret < 0)
- return -1;
- return 0;
- }
- /**
- * xenHypervisorDoV2Sys:
- * @handle: the handle to the Xen hypervisor
- * @op: pointer to the hypervisor operation structure
- *
- * Do a hypervisor v2 system operation, this leads to a hypervisor
- * call through ioctl.
- *
- * Returns 0 in case of success and -1 in case of error.
- */
- static int
- xenHypervisorDoV2Sys(int handle, xen_op_v2_sys* op)
- {
- int ret;
- hypercall_t hc;
- memset(&hc, 0, sizeof(hc));
- op->interface_version = hv_versions.sys_interface;
- hc.op = __HYPERVISOR_sysctl;
- hc.arg[0] = (unsigned long) op;
- if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
- return -1;
- }
- ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
- if (ret < 0) {
- virXenError(VIR_ERR_XEN_CALL, " sys ioctl %d",
- xen_ioctl_hypercall_cmd);
- }
- if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " releasing");
- ret = -1;
- }
- if (ret < 0)
- return -1;
- return 0;
- }
- /**
- * xenHypervisorDoV2Dom:
- * @handle: the handle to the Xen hypervisor
- * @op: pointer to the hypervisor domain operation structure
- *
- * Do a hypervisor v2 domain operation, this leads to a hypervisor
- * call through ioctl.
- *
- * Returns 0 in case of success and -1 in case of error.
- */
- static int
- xenHypervisorDoV2Dom(int handle, xen_op_v2_dom* op)
- {
- int ret;
- hypercall_t hc;
- memset(&hc, 0, sizeof(hc));
- op->interface_version = hv_versions.dom_interface;
- hc.op = __HYPERVISOR_domctl;
- hc.arg[0] = (unsigned long) op;
- if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
- return -1;
- }
- ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
- if (ret < 0) {
- virXenError(VIR_ERR_XEN_CALL, " ioctl %d",
- xen_ioctl_hypercall_cmd);
- }
- if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " releasing");
- ret = -1;
- }
- if (ret < 0)
- return -1;
- return 0;
- }
- /**
- * virXen_getdomaininfolist:
- * @handle: the hypervisor handle
- * @first_domain: first domain in the range
- * @maxids: maximum number of domains to list
- * @dominfos: output structures
- *
- * Do a low level hypercall to list existing domains information
- *
- * Returns the number of domains or -1 in case of failure
- */
- static int
- virXen_getdomaininfolist(int handle, int first_domain, int maxids,
- xen_getdomaininfolist *dominfos)
- {
- int ret = -1;
- if (lock_pages(XEN_GETDOMAININFOLIST_DATA(dominfos),
- XEN_GETDOMAININFO_SIZE * maxids) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
- return -1;
- }
- if (hv_versions.hypervisor > 1) {
- xen_op_v2_sys op;
- memset(&op, 0, sizeof(op));
- op.cmd = XEN_V2_OP_GETDOMAININFOLIST;
- if (hv_versions.sys_interface < 3) {
- op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
- op.u.getdomaininfolist.max_domains = maxids;
- op.u.getdomaininfolist.buffer = dominfos->v2;
- op.u.getdomaininfolist.num_domains = maxids;
- } else {
- op.u.getdomaininfolists3.first_domain = (domid_t) first_domain;
- op.u.getdomaininfolists3.max_domains = maxids;
- op.u.getdomaininfolists3.buffer.v = dominfos->v2d5;
- op.u.getdomaininfolists3.num_domains = maxids;
- }
- ret = xenHypervisorDoV2Sys(handle, &op);
- if (ret == 0) {
- if (hv_versions.sys_interface < 3)
- ret = op.u.getdomaininfolist.num_domains;
- else
- ret = op.u.getdomaininfolists3.num_domains;
- }
- } else if (hv_versions.hypervisor == 1) {
- xen_op_v1 op;
- memset(&op, 0, sizeof(op));
- op.cmd = XEN_V1_OP_GETDOMAININFOLIST;
- op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
- op.u.getdomaininfolist.max_domains = maxids;
- op.u.getdomaininfolist.buffer = dominfos->v0;
- op.u.getdomaininfolist.num_domains = maxids;
- ret = xenHypervisorDoV1Op(handle, &op);
- if (ret == 0)
- ret = op.u.getdomaininfolist.num_domains;
- } else if (hv_versions.hypervisor == 0) {
- xen_op_v0 op;
- memset(&op, 0, sizeof(op));
- op.cmd = XEN_V0_OP_GETDOMAININFOLIST;
- op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
- op.u.getdomaininfolist.max_domains = maxids;
- op.u.getdomaininfolist.buffer = dominfos->v0;
- op.u.getdomaininfolist.num_domains = maxids;
- ret = xenHypervisorDoV0Op(handle, &op);
- if (ret == 0)
- ret = op.u.getdomaininfolist.num_domains;
- }
- if (unlock_pages(XEN_GETDOMAININFOLIST_DATA(dominfos),
- XEN_GETDOMAININFO_SIZE * maxids) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " release");
- ret = -1;
- }
- return ret;
- }
- static int
- virXen_getdomaininfo(int handle, int first_domain,
- xen_getdomaininfo *dominfo) {
- xen_getdomaininfolist dominfos;
- if (hv_versions.hypervisor < 2) {
- dominfos.v0 = &(dominfo->v0);
- } else {
- dominfos.v2 = &(dominfo->v2);
- }
- return virXen_getdomaininfolist(handle, first_domain, 1, &dominfos);
- }
- /**
- * xenHypervisorGetSchedulerType:
- * @domain: pointer to the Xen Hypervisor block
- * @nparams:give a number of scheduler parameters.
- *
- * Do a low level hypercall to get scheduler type
- *
- * Returns scheduler name or NULL in case of failure
- */
- char *
- xenHypervisorGetSchedulerType(virDomainPtr domain, int *nparams)
- {
- char *schedulertype = NULL;
- xenUnifiedPrivatePtr priv;
- if (domain->conn == NULL) {
- virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("domain or conn is NULL"));
- return NULL;
- }
- priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
- if (priv->handle < 0) {
- virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("priv->handle invalid"));
- return NULL;
- }
- if (domain->id < 0) {
- virXenError(VIR_ERR_OPERATION_INVALID,
- "%s", _("domain is not running"));
- return NULL;
- }
- /*
- * Support only hv_versions.dom_interface >=5
- * (Xen3.1.0 or later)
- * TODO: check on Xen 3.0.3
- */
- if (hv_versions.dom_interface < 5) {
- virXenError(VIR_ERR_NO_XEN, "%s",
- _("unsupported in dom interface < 5"));
- return NULL;
- }
- if (hv_versions.hypervisor > 1) {
- xen_op_v2_sys op;
- int ret;
- memset(&op, 0, sizeof(op));
- op.cmd = XEN_V2_OP_GETSCHEDULERID;
- ret = xenHypervisorDoV2Sys(priv->handle, &op);
- if (ret < 0)
- return NULL;
- switch (op.u.getschedulerid.sched_id){
- case XEN_SCHEDULER_SEDF:
- schedulertype = strdup("sedf");
- if (schedulertype == NULL)
- virReportOOMError();
- if (nparams)
- *nparams = XEN_SCHED_SEDF_NPARAM;
- break;
- case XEN_SCHEDULER_CREDIT:
- schedulertype = strdup("credit");
- if (schedulertype == NULL)
- virReportOOMError();
- if (nparams)
- *nparams = XEN_SCHED_CRED_NPARAM;
- break;
- default:
- break;
- }
- }
- return schedulertype;
- }
- /**
- * xenHypervisorGetSchedulerParameters:
- * @domain: pointer to the Xen Hypervisor block
- * @params: pointer to scheduler parameters.
- * This memory area should be allocated before calling.
- * @nparams: this parameter must be at least as large as
- * the given number of scheduler parameters.
- * from xenHypervisorGetSchedulerType().
- *
- * Do a low level hypercall to get scheduler parameters
- *
- * Returns 0 or -1 in case of failure
- */
- int
- xenHypervisorGetSchedulerParameters(virDomainPtr domain,
- virTypedParameterPtr params, int *nparams)
- {
- xenUnifiedPrivatePtr priv;
- if (domain->conn == NULL) {
- virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("domain or conn is NULL"));
- return -1;
- }
- priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
- if (priv->handle < 0) {
- virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("priv->handle invalid"));
- return -1;
- }
- if (domain->id < 0) {
- virXenError(VIR_ERR_OPERATION_INVALID,
- "%s", _("domain is not running"));
- return -1;
- }
- /*
- * Support only hv_versions.dom_interface >=5
- * (Xen3.1.0 or later)
- * TODO: check on Xen 3.0.3
- */
- if (hv_versions.dom_interface < 5) {
- virXenError(VIR_ERR_NO_XEN, "%s",
- _("unsupported in dom interface < 5"));
- return -1;
- }
- if (hv_versions.hypervisor > 1) {
- xen_op_v2_sys op_sys;
- xen_op_v2_dom op_dom;
- int ret;
- memset(&op_sys, 0, sizeof(op_sys));
- op_sys.cmd = XEN_V2_OP_GETSCHEDULERID;
- ret = xenHypervisorDoV2Sys(priv->handle, &op_sys);
- if (ret < 0)
- return -1;
- switch (op_sys.u.getschedulerid.sched_id){
- case XEN_SCHEDULER_SEDF:
- if (*nparams < XEN_SCHED_SEDF_NPARAM) {
- virXenError(VIR_ERR_INVALID_ARG,
- "%s", _("Invalid parameter count"));
- return -1;
- }
- /* TODO: Implement for Xen/SEDF */
- TODO
- return -1;
- case XEN_SCHEDULER_CREDIT:
- memset(&op_dom, 0, sizeof(op_dom));
- op_dom.cmd = XEN_V2_OP_SCHEDULER;
- op_dom.domain = (domid_t) domain->id;
- op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT;
- op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_getinfo;
- ret = xenHypervisorDoV2Dom(priv->handle, &op_dom);
- if (ret < 0)
- return -1;
- if (virTypedParameterAssign(¶ms[0],
- VIR_DOMAIN_SCHEDULER_WEIGHT,
- VIR_TYPED_PARAM_UINT,
- op_dom.u.getschedinfo.u.credit.weight) < 0)
- return -1;
- if (*nparams > 1 &&
- virTypedParameterAssign(¶ms[1],
- VIR_DOMAIN_SCHEDULER_CAP,
- VIR_TYPED_PARAM_UINT,
- op_dom.u.getschedinfo.u.credit.cap) < 0)
- return -1;
- if (*nparams > XEN_SCHED_CRED_NPARAM)
- *nparams = XEN_SCHED_CRED_NPARAM;
- break;
- default:
- virXenError(VIR_ERR_INVALID_ARG,
- _("Unknown scheduler %d"),
- op_sys.u.getschedulerid.sched_id);
- return -1;
- }
- }
- return 0;
- }
- /**
- * xenHypervisorSetSchedulerParameters:
- * @domain: pointer to the Xen Hypervisor block
- * @nparams:give a number of scheduler setting parameters .
- *
- * Do a low level hypercall to set scheduler parameters
- *
- * Returns 0 or -1 in case of failure
- */
- int
- xenHypervisorSetSchedulerParameters(virDomainPtr domain,
- virTypedParameterPtr params, int nparams)
- {
- int i;
- unsigned int val;
- xenUnifiedPrivatePtr priv;
- char buf[256];
- if (domain->conn == NULL) {
- virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("domain or conn is NULL"));
- return -1;
- }
- if (nparams == 0) {
- /* nothing to do, exit early */
- return 0;
- }
- if (virTypedParameterArrayValidate(params, nparams,
- VIR_DOMAIN_SCHEDULER_WEIGHT,
- VIR_TYPED_PARAM_UINT,
- VIR_DOMAIN_SCHEDULER_CAP,
- VIR_TYPED_PARAM_UINT,
- NULL) < 0)
- return -1;
- priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
- if (priv->handle < 0) {
- virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("priv->handle invalid"));
- return -1;
- }
- if (domain->id < 0) {
- virXenError(VIR_ERR_OPERATION_INVALID,
- "%s", _("domain is not running"));
- return -1;
- }
- /*
- * Support only hv_versions.dom_interface >=5
- * (Xen3.1.0 or later)
- * TODO: check on Xen 3.0.3
- */
- if (hv_versions.dom_interface < 5) {
- virXenError(VIR_ERR_NO_XEN, "%s",
- _("unsupported in dom interface < 5"));
- return -1;
- }
- if (hv_versions.hypervisor > 1) {
- xen_op_v2_sys op_sys;
- xen_op_v2_dom op_dom;
- int ret;
- memset(&op_sys, 0, sizeof(op_sys));
- op_sys.cmd = XEN_V2_OP_GETSCHEDULERID;
- ret = xenHypervisorDoV2Sys(priv->handle, &op_sys);
- if (ret == -1) return -1;
- switch (op_sys.u.getschedulerid.sched_id){
- case XEN_SCHEDULER_SEDF:
- /* TODO: Implement for Xen/SEDF */
- TODO
- return -1;
- case XEN_SCHEDULER_CREDIT: {
- memset(&op_dom, 0, sizeof(op_dom));
- op_dom.cmd = XEN_V2_OP_SCHEDULER;
- op_dom.domain = (domid_t) domain->id;
- op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT;
- op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_putinfo;
- /*
- * credit scheduler parameters
- * following values do not change the parameters
- */
- op_dom.u.getschedinfo.u.credit.weight = 0;
- op_dom.u.getschedinfo.u.credit.cap = (uint16_t)~0U;
- for (i = 0; i < nparams; i++) {
- memset(&buf, 0, sizeof(buf));
- if (STREQ(params[i].field, VIR_DOMAIN_SCHEDULER_WEIGHT)) {
- val = params[i].value.ui;
- if ((val < 1) || (val > USHRT_MAX)) {
- virXenError(VIR_ERR_INVALID_ARG,
- _("Credit scheduler weight parameter (%d) "
- "is out of range (1-65535)"), val);
- return -1;
- }
- op_dom.u.getschedinfo.u.credit.weight = val;
- } else if (STREQ(params[i].field, VIR_DOMAIN_SCHEDULER_CAP)) {
- val = params[i].value.ui;
- if (val >= USHRT_MAX) {
- virXenError(VIR_ERR_INVALID_ARG,
- _("Credit scheduler cap parameter (%d) is "
- "out of range (0-65534)"), val);
- return -1;
- }
- op_dom.u.getschedinfo.u.credit.cap = val;
- }
- }
- ret = xenHypervisorDoV2Dom(priv->handle, &op_dom);
- if (ret < 0)
- return -1;
- break;
- }
- default:
- virXenError(VIR_ERR_INVALID_ARG,
- _("Unknown scheduler %d"),
- op_sys.u.getschedulerid.sched_id);
- return -1;
- }
- }
- return 0;
- }
- int
- xenHypervisorDomainBlockStats (virDomainPtr dom,
- const char *path,
- struct _virDomainBlockStats *stats)
- {
- #ifdef __linux__
- xenUnifiedPrivatePtr priv;
- int ret;
- priv = (xenUnifiedPrivatePtr) dom->conn->privateData;
- xenUnifiedLock(priv);
- /* Need to lock because it hits the xenstore handle :-( */
- ret = xenLinuxDomainBlockStats (priv, dom, path, stats);
- xenUnifiedUnlock(priv);
- return ret;
- #else
- virXenError(VIR_ERR_OPERATION_INVALID, "%s",
- _("block statistics not supported on this platform"));
- return -1;
- #endif
- }
- /* Paths have the form vif<domid>.<n> (this interface checks that
- * <domid> is the real domain ID and returns an error if not).
- *
- * In future we may allow you to query bridge stats (virbrX or
- * xenbrX), but that will probably be through a separate
- * virNetwork interface, as yet not decided.
- */
- int
- xenHypervisorDomainInterfaceStats (virDomainPtr dom,
- const char *path,
- struct _virDomainInterfaceStats *stats)
- {
- #ifdef __linux__
- int rqdomid, device;
- /* Verify that the vif requested is one belonging to the current
- * domain.
- */
- if (sscanf(path, "vif%d.%d", &rqdomid, &device) != 2) {
- virXenError(VIR_ERR_INVALID_ARG, "%s",
- _("invalid path, should be vif<domid>.<n>."));
- return -1;
- }
- if (rqdomid != dom->id) {
- virXenError(VIR_ERR_INVALID_ARG, "%s",
- _("in…
Large files files are truncated, but you can click here to view the full file