diff --git a/2dc1cf19-libxl-double-free.patch b/2dc1cf19-libxl-double-free.patch new file mode 100644 index 0000000..eaca4ed --- /dev/null +++ b/2dc1cf19-libxl-double-free.patch @@ -0,0 +1,27 @@ +commit 2dc1cf19dbaf648662fbf3c810db65ddcf5d0444 +Author: Jim Fehlig +Date: Wed Feb 15 10:45:27 2017 -0700 + + libxl: fix potential double free in libxlDriverGetDom0MaxmemConf + + Commit 4ab0c959 fixed a memory leak in libxlDriverGetDom0MaxmemConf + but introduced a potential double free of mem_tokens + + *** Error in `/usr/sbin/libvirtd': double free or corruption (out): + 0x00007fffc808cfd0 *** + + Avoid double free by setting mem_tokens to NULL after calling + virStringListFree. + +Index: libvirt-3.0.0/src/libxl/libxl_conf.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.c ++++ libvirt-3.0.0/src/libxl/libxl_conf.c +@@ -1623,6 +1623,7 @@ libxlDriverGetDom0MaxmemConf(libxlDriver + } + } + virStringListFree(mem_tokens); ++ mem_tokens = NULL; + } + + physmem: diff --git a/321a28c6-libxl-default-disk-format.patch b/321a28c6-libxl-default-disk-format.patch new file mode 100644 index 0000000..4b3fa20 --- /dev/null +++ b/321a28c6-libxl-default-disk-format.patch @@ -0,0 +1,99 @@ +commit 321a28c6aef6fb31b4ba309a1b3d252f7cd0f05c +Author: Jim Fehlig +Date: Tue Feb 7 11:00:33 2017 -0700 + + libxl: set default disk format in device post-parse + + When starting a domian, a libxl_domain_config object is created from + virDomainDef. Any virDomainDiskDef devices with a format of + VIR_STORAGE_FILE_NONE are mapped to LIBXL_DISK_FORMAT_RAW in the + corresponding libxl_disk_device, but the virDomainDiskDef format is + never updated to reflect the change. + + A better place to set a default format for disk devices is the + device post-parse callback, ensuring the virDomainDiskDef object + reflects the default format. + +Index: libvirt-3.0.0/src/libxl/libxl_conf.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.c ++++ libvirt-3.0.0/src/libxl/libxl_conf.c +@@ -765,8 +765,6 @@ libxlMakeDisk(virDomainDiskDefPtr l_disk + x_disk->format = LIBXL_DISK_FORMAT_VHD; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; + break; +- case VIR_STORAGE_FILE_NONE: +- /* No subtype specified, default to raw/tap */ + case VIR_STORAGE_FILE_RAW: + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; +@@ -802,8 +800,6 @@ libxlMakeDisk(virDomainDiskDefPtr l_disk + case VIR_STORAGE_FILE_VHD: + x_disk->format = LIBXL_DISK_FORMAT_VHD; + break; +- case VIR_STORAGE_FILE_NONE: +- /* No subtype specified, default to raw */ + case VIR_STORAGE_FILE_RAW: + x_disk->format = LIBXL_DISK_FORMAT_RAW; + break; +@@ -816,8 +812,7 @@ libxlMakeDisk(virDomainDiskDefPtr l_disk + return -1; + } + } else if (STREQ(driver, "file")) { +- if (format != VIR_STORAGE_FILE_NONE && +- format != VIR_STORAGE_FILE_RAW) { ++ if (format != VIR_STORAGE_FILE_RAW) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("libxenlight does not support disk format %s " + "with disk driver %s"), +@@ -828,8 +823,7 @@ libxlMakeDisk(virDomainDiskDefPtr l_disk + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_QDISK; + } else if (STREQ(driver, "phy")) { +- if (format != VIR_STORAGE_FILE_NONE && +- format != VIR_STORAGE_FILE_RAW) { ++ if (format != VIR_STORAGE_FILE_RAW) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("libxenlight does not support disk format %s " + "with disk driver %s"), +Index: libvirt-3.0.0/src/libxl/libxl_domain.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_domain.c ++++ libvirt-3.0.0/src/libxl/libxl_domain.c +@@ -362,16 +362,21 @@ libxlDomainDeviceDefPostParse(virDomainD + } + } + +- /* for network-based disks, set 'qemu' as the default driver */ + if (dev->type == VIR_DOMAIN_DEVICE_DISK) { + virDomainDiskDefPtr disk = dev->data.disk; + int actual_type = virStorageSourceGetActualType(disk->src); ++ int format = virDomainDiskGetFormat(disk); + ++ /* for network-based disks, set 'qemu' as the default driver */ + if (actual_type == VIR_STORAGE_TYPE_NETWORK) { + if (!virDomainDiskGetDriver(disk) && + virDomainDiskSetDriver(disk, "qemu") < 0) + return -1; + } ++ ++ /* xl.cfg default format is raw. See xl-disk-configuration(5) */ ++ if (format == VIR_STORAGE_FILE_NONE) ++ virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW); + } + + return 0; +Index: libvirt-3.0.0/src/libxl/libxl_driver.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_driver.c ++++ libvirt-3.0.0/src/libxl/libxl_driver.c +@@ -5466,8 +5466,7 @@ libxlDomainBlockStatsGatherSingle(virDom + disk_drv = "qemu"; + + if (STREQ(disk_drv, "phy")) { +- if (disk_fmt != VIR_STORAGE_FILE_RAW && +- disk_fmt != VIR_STORAGE_FILE_NONE) { ++ if (disk_fmt != VIR_STORAGE_FILE_RAW) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("unsupported format %s"), + virStorageFileFormatTypeToString(disk_fmt)); diff --git a/4ab0c959-libxl-mem-leak.patch b/4ab0c959-libxl-mem-leak.patch new file mode 100644 index 0000000..cc12b64 --- /dev/null +++ b/4ab0c959-libxl-mem-leak.patch @@ -0,0 +1,25 @@ +commit 4ab0c959e936de7fa2752160ff532913740d4da9 +Author: John Ferlan +Date: Fri Feb 10 06:54:56 2017 -0500 + + libxl: Resolve possible resource leak in dom0 maximum memory setting + + If either the "if (STRPREFIX(mem_tokens[j], "max:"))" is never entered + or the "if (virStrToLong_ull(mem_tokens[j] + 4, &p, 10, maxmem) < 0)" break + is hit, control goes back to the outer loop processing 'cmd_tokens' and + it's possible that the 'mem_tokens' would be overwritten. + + Found by Coverity + +Index: libvirt-3.0.0/src/libxl/libxl_conf.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.c ++++ libvirt-3.0.0/src/libxl/libxl_conf.c +@@ -1622,6 +1622,7 @@ libxlDriverGetDom0MaxmemConf(libxlDriver + goto cleanup; + } + } ++ virStringListFree(mem_tokens); + } + + physmem: diff --git a/6e4759d0-libxl-timer-fix.patch b/6e4759d0-libxl-timer-fix.patch new file mode 100644 index 0000000..7beda56 --- /dev/null +++ b/6e4759d0-libxl-timer-fix.patch @@ -0,0 +1,81 @@ +commit 6e4759d0695429e36765f3e1c516939a369799f2 +Author: Jim Fehlig +Date: Mon Jan 16 15:37:40 2017 -0700 + + libxl: fix timer configuration + + The current logic around configuring timers in libxl based on + virDomainDef object is a bit brain dead. Unsupported timers are + silently ignored and tsc is only recognized if it is the first + timer specified. + + Change the logic to reject unsupported timers and honor the tsc + timer regardless of its order when multiple timers are specified. + +Index: libvirt-3.0.0/src/libxl/libxl_conf.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.c ++++ libvirt-3.0.0/src/libxl/libxl_conf.c +@@ -313,9 +313,10 @@ libxlMakeDomBuildInfo(virDomainDefPtr de + for (i = 0; i < virDomainDefGetVcpus(def); i++) + libxl_bitmap_set((&b_info->avail_vcpus), i); + +- if (def->clock.ntimers > 0 && +- def->clock.timers[0]->name == VIR_DOMAIN_TIMER_NAME_TSC) { +- switch (def->clock.timers[0]->mode) { ++ for (i = 0; i < def->clock.ntimers; i++) { ++ switch ((virDomainTimerNameType) def->clock.timers[i]->name) { ++ case VIR_DOMAIN_TIMER_NAME_TSC: ++ switch (def->clock.timers[i]->mode) { + case VIR_DOMAIN_TIMER_MODE_NATIVE: + b_info->tsc_mode = 2; + break; +@@ -324,8 +325,35 @@ libxlMakeDomBuildInfo(virDomainDefPtr de + break; + default: + b_info->tsc_mode = 1; ++ } ++ break; ++ ++ case VIR_DOMAIN_TIMER_NAME_HPET: ++ if (!hvm) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unsupported timer type (name) '%s'"), ++ virDomainTimerNameTypeToString(def->clock.timers[i]->name)); ++ return -1; ++ } ++ if (def->clock.timers[i]->present == 1) ++ libxl_defbool_set(&b_info->u.hvm.hpet, 1); ++ break; ++ ++ case VIR_DOMAIN_TIMER_NAME_PLATFORM: ++ case VIR_DOMAIN_TIMER_NAME_KVMCLOCK: ++ case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK: ++ case VIR_DOMAIN_TIMER_NAME_RTC: ++ case VIR_DOMAIN_TIMER_NAME_PIT: ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unsupported timer type (name) '%s'"), ++ virDomainTimerNameTypeToString(def->clock.timers[i]->name)); ++ return -1; ++ ++ case VIR_DOMAIN_TIMER_NAME_LAST: ++ break; + } + } ++ + b_info->sched_params.weight = 1000; + b_info->max_memkb = virDomainDefGetMemoryInitial(def); + b_info->target_memkb = def->mem.cur_balloon; +@@ -341,12 +369,6 @@ libxlMakeDomBuildInfo(virDomainDefPtr de + libxl_defbool_set(&b_info->u.hvm.acpi, + def->features[VIR_DOMAIN_FEATURE_ACPI] == + VIR_TRISTATE_SWITCH_ON); +- for (i = 0; i < def->clock.ntimers; i++) { +- if (def->clock.timers[i]->name == VIR_DOMAIN_TIMER_NAME_HPET && +- def->clock.timers[i]->present == 1) { +- libxl_defbool_set(&b_info->u.hvm.hpet, 1); +- } +- } + + if (def->nsounds > 0) { + /* diff --git a/79692c38-libxl-dom0-maxmem.patch b/79692c38-libxl-dom0-maxmem.patch new file mode 100644 index 0000000..1237f60 --- /dev/null +++ b/79692c38-libxl-dom0-maxmem.patch @@ -0,0 +1,159 @@ +commit 79692c387497a0b67f65b0293291d1137461985f +Author: Jim Fehlig +Date: Tue Jan 31 17:10:34 2017 -0700 + + libxl: fix dom0 maximum memory setting + + When the libxl driver is initialized, it creates a virDomainDef + object for dom0 and adds it to the list of domains. Total memory + for dom0 was being set from the max_memkb field of libxl_dominfo + struct retrieved from libxl, but this field can be set to + LIBXL_MEMKB_DEFAULT (~0ULL) if dom0 maximum memory has not been + explicitly set by the user. + + This patch adds some simple parsing of the Xen commandline, + looking for a dom0_mem parameter that also specifies a 'max' value. + If not specified, dom0 maximum memory is effectively all physical + host memory. + + Signed-off-by: Jim Fehlig + +Index: libvirt-3.0.0/src/libxl/libxl_conf.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.c ++++ libvirt-3.0.0/src/libxl/libxl_conf.c +@@ -34,6 +34,7 @@ + #include "internal.h" + #include "virlog.h" + #include "virerror.h" ++#include "c-ctype.h" + #include "datatypes.h" + #include "virconf.h" + #include "virfile.h" +@@ -1559,6 +1560,88 @@ int libxlDriverConfigLoadFile(libxlDrive + + } + ++/* ++ * dom0's maximum memory can be controled by the user with the 'dom0_mem' Xen ++ * command line parameter. E.g. to set dom0's initial memory to 4G and max ++ * memory to 8G: dom0_mem=4G,max:8G ++ * Supported unit suffixes are [bBkKmMgGtT]. If not specified the default ++ * unit is kilobytes. ++ * ++ * If not constrained by the user, dom0 can effectively use all host memory. ++ * This function returns the configured maximum memory for dom0 in kilobytes, ++ * either the user-specified value or total physical memory as a default. ++ */ ++int ++libxlDriverGetDom0MaxmemConf(libxlDriverConfigPtr cfg, ++ unsigned long long *maxmem) ++{ ++ char **cmd_tokens = NULL; ++ char **mem_tokens = NULL; ++ size_t i; ++ size_t j; ++ libxl_physinfo physinfo; ++ int ret = -1; ++ ++ if (cfg->verInfo->commandline == NULL || ++ !(cmd_tokens = virStringSplit(cfg->verInfo->commandline, " ", 0))) ++ goto physmem; ++ ++ for (i = 0; cmd_tokens[i] != NULL; i++) { ++ if (!STRPREFIX(cmd_tokens[i], "dom0_mem=")) ++ continue; ++ ++ if (!(mem_tokens = virStringSplit(cmd_tokens[i], ",", 0))) ++ break; ++ for (j = 0; mem_tokens[j] != NULL; j++) { ++ if (STRPREFIX(mem_tokens[j], "max:")) { ++ char *p = mem_tokens[j] + 4; ++ unsigned long long multiplier = 1; ++ ++ while (c_isdigit(*p)) ++ p++; ++ if (virStrToLong_ull(mem_tokens[j] + 4, &p, 10, maxmem) < 0) ++ break; ++ if (*p) { ++ switch (*p) { ++ case 'm': ++ case 'M': ++ multiplier = 1024; ++ break; ++ case 'g': ++ case 'G': ++ multiplier = 1024 * 1024; ++ break; ++ case 't': ++ case 'T': ++ multiplier = 1024 * 1024 * 1024; ++ break; ++ } ++ } ++ *maxmem = *maxmem * multiplier; ++ ret = 0; ++ goto cleanup; ++ } ++ } ++ } ++ ++ physmem: ++ /* No 'max' specified in dom0_mem, so dom0 can use all physical memory */ ++ libxl_physinfo_init(&physinfo); ++ if (libxl_get_physinfo(cfg->ctx, &physinfo)) { ++ VIR_WARN("libxl_get_physinfo failed"); ++ goto cleanup; ++ } ++ *maxmem = (physinfo.total_pages * cfg->verInfo->pagesize) / 1024; ++ libxl_physinfo_dispose(&physinfo); ++ ret = 0; ++ ++ cleanup: ++ virStringListFree(cmd_tokens); ++ virStringListFree(mem_tokens); ++ return ret; ++} ++ ++ + #ifdef LIBXL_HAVE_DEVICE_CHANNEL + static int + libxlPrepareChannel(virDomainChrDefPtr channel, +Index: libvirt-3.0.0/src/libxl/libxl_conf.h +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.h ++++ libvirt-3.0.0/src/libxl/libxl_conf.h +@@ -174,6 +174,10 @@ int libxlDriverConfigLoadFile(libxlDrive + const char *filename); + + int ++libxlDriverGetDom0MaxmemConf(libxlDriverConfigPtr cfg, ++ unsigned long long *maxmem); ++ ++int + libxlMakeDisk(virDomainDiskDefPtr l_dev, libxl_device_disk *x_dev); + + void +Index: libvirt-3.0.0/src/libxl/libxl_driver.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_driver.c ++++ libvirt-3.0.0/src/libxl/libxl_driver.c +@@ -576,6 +576,7 @@ libxlAddDom0(libxlDriverPrivatePtr drive + virDomainObjPtr vm = NULL; + virDomainDefPtr oldDef = NULL; + libxl_dominfo d_info; ++ unsigned long long maxmem; + int ret = -1; + + libxl_dominfo_init(&d_info); +@@ -615,7 +616,9 @@ libxlAddDom0(libxlDriverPrivatePtr drive + if (virDomainDefSetVcpus(vm->def, d_info.vcpu_online) < 0) + goto cleanup; + vm->def->mem.cur_balloon = d_info.current_memkb; +- virDomainDefSetMemoryTotal(vm->def, d_info.max_memkb); ++ if (libxlDriverGetDom0MaxmemConf(cfg, &maxmem) < 0) ++ maxmem = d_info.current_memkb; ++ virDomainDefSetMemoryTotal(vm->def, maxmem); + + ret = 0; + diff --git a/87df87e0-libxl-timer-tsc-emulate.patch b/87df87e0-libxl-timer-tsc-emulate.patch new file mode 100644 index 0000000..4fab960 --- /dev/null +++ b/87df87e0-libxl-timer-tsc-emulate.patch @@ -0,0 +1,33 @@ +commit 87df87e06b57dedd39906cd46166842179732668 +Author: Jim Fehlig +Date: Thu Jan 19 16:21:34 2017 -0700 + + libxl: support emulate mode of tsc timer + + While at it, use members of libxl_tsc_mode enum instead of literal + int values. + +Index: libvirt-3.0.0/src/libxl/libxl_conf.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.c ++++ libvirt-3.0.0/src/libxl/libxl_conf.c +@@ -318,13 +318,16 @@ libxlMakeDomBuildInfo(virDomainDefPtr de + case VIR_DOMAIN_TIMER_NAME_TSC: + switch (def->clock.timers[i]->mode) { + case VIR_DOMAIN_TIMER_MODE_NATIVE: +- b_info->tsc_mode = 2; ++ b_info->tsc_mode = LIBXL_TSC_MODE_NATIVE; + break; + case VIR_DOMAIN_TIMER_MODE_PARAVIRT: +- b_info->tsc_mode = 3; ++ b_info->tsc_mode = LIBXL_TSC_MODE_NATIVE_PARAVIRT; ++ break; ++ case VIR_DOMAIN_TIMER_MODE_EMULATE: ++ b_info->tsc_mode = LIBXL_TSC_MODE_ALWAYS_EMULATE; + break; + default: +- b_info->tsc_mode = 1; ++ b_info->tsc_mode = LIBXL_TSC_MODE_DEFAULT; + } + break; + diff --git a/apparmor-alt-seclabel.patch b/apparmor-alt-seclabel.patch new file mode 100644 index 0000000..234f56f --- /dev/null +++ b/apparmor-alt-seclabel.patch @@ -0,0 +1,167 @@ +commit 8f6a7866102346691fce84ade9a6d8534aaffcdc +Author: Jim Fehlig +Date: Thu Feb 2 19:26:13 2017 -0700 + + apparmor: don't fail on non-apparmor + + If the apparmor security driver is loaded/enabled and domain config + contains a element whose type attribute is not 'apparmor', + starting the domain fails when attempting to label resources such + as tap FDs. + + Many of the apparmor driver entry points attempt to retrieve the + apparmor security label from the domain def, returning failure if + not found. Functions such as AppArmorSetFDLabel fail even though + domain config contains an explicit 'none' secuirty driver, e.g. + + + + Change the entry points to succeed if the domain config + is not apparmor. This matches the behavior of the selinux driver. + +Index: libvirt-3.0.0/src/security/security_apparmor.c +=================================================================== +--- libvirt-3.0.0.orig/src/security/security_apparmor.c ++++ libvirt-3.0.0/src/security/security_apparmor.c +@@ -289,10 +289,7 @@ reload_profile(virSecurityManagerPtr mgr + virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef( + def, SECURITY_APPARMOR_NAME); + +- if (!secdef) +- return rc; +- +- if (!secdef->relabel) ++ if (!secdef || !secdef->relabel) + return 0; + + if ((profile_name = get_profile_name(def)) == NULL) +@@ -435,7 +432,7 @@ AppArmorGenSecurityLabel(virSecurityMana + SECURITY_APPARMOR_NAME); + + if (!secdef) +- return -1; ++ return 0; + + if ((secdef->type == VIR_DOMAIN_SECLABEL_STATIC) || + (secdef->type == VIR_DOMAIN_SECLABEL_NONE)) +@@ -495,10 +492,7 @@ AppArmorSetSecurityAllLabel(virSecurityM + { + virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def, + SECURITY_APPARMOR_NAME); +- if (!secdef) +- return -1; +- +- if (!secdef->relabel) ++ if (!secdef || !secdef->relabel) + return 0; + + /* Reload the profile if stdin_path is specified. Note that +@@ -559,12 +553,11 @@ AppArmorReleaseSecurityLabel(virSecurity + { + virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def, + SECURITY_APPARMOR_NAME); +- if (!secdef) +- return -1; +- +- VIR_FREE(secdef->model); +- VIR_FREE(secdef->label); +- VIR_FREE(secdef->imagelabel); ++ if (secdef) { ++ VIR_FREE(secdef->model); ++ VIR_FREE(secdef->label); ++ VIR_FREE(secdef->imagelabel); ++ } + + return 0; + } +@@ -580,7 +573,7 @@ AppArmorRestoreSecurityAllLabel(virSecur + virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME); + + if (!secdef) +- return -1; ++ return 0; + + if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) { + if ((rc = remove_profile(secdef->label)) != 0) { +@@ -604,10 +597,7 @@ AppArmorSetSecurityProcessLabel(virSecur + virSecurityLabelDefPtr secdef = + virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME); + +- if (!secdef) +- return -1; +- +- if (secdef->label == NULL) ++ if (!secdef || !secdef->label) + return 0; + + if ((profile_name = get_profile_name(def)) == NULL) +@@ -653,10 +643,7 @@ AppArmorSetSecurityChildProcessLabel(vir + virSecurityLabelDefPtr secdef = + virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME); + +- if (!secdef) +- goto cleanup; +- +- if (secdef->label == NULL) ++ if (!secdef || !secdef->label) + return 0; + + if (STRNEQ(SECURITY_APPARMOR_NAME, secdef->model)) { +@@ -738,10 +725,8 @@ AppArmorSetSecurityImageLabel(virSecurit + if (!src->path || !virStorageSourceIsLocalStorage(src)) + return 0; + +- if (!(secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME))) +- return -1; +- +- if (!secdef->relabel) ++ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME); ++ if (!secdef || !secdef->relabel) + return 0; + + if (secdef->imagelabel) { +@@ -792,7 +777,7 @@ AppArmorSecurityVerify(virSecurityManage + virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME); + + if (!secdef) +- return -1; ++ return 0; + + if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) { + if (use_apparmor() < 0 || profile_status(secdef->label, 0) < 0) { +@@ -829,10 +814,7 @@ AppArmorSetSecurityHostdevLabel(virSecur + virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi; + virDomainHostdevSubsysSCSIVHostPtr hostsrc = &dev->source.subsys.u.scsi_host; + +- if (!secdef) +- return -1; +- +- if (!secdef->relabel) ++ if (!secdef || !secdef->relabel) + return 0; + + if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) +@@ -940,10 +922,7 @@ AppArmorRestoreSecurityHostdevLabel(virS + virSecurityLabelDefPtr secdef = + virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME); + +- if (!secdef) +- return -1; +- +- if (!secdef->relabel) ++ if (!secdef || !secdef->relabel) + return 0; + + return reload_profile(mgr, def, NULL, false); +@@ -978,10 +957,7 @@ AppArmorSetFDLabel(virSecurityManagerPtr + virSecurityLabelDefPtr secdef = + virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME); + +- if (!secdef) +- return -1; +- +- if (secdef->imagelabel == NULL) ++ if (!secdef || !secdef->imagelabel) + return 0; + + if (virAsprintf(&proc, "/proc/self/fd/%d", fd) == -1) diff --git a/apparmor-errormsg-fix.patch b/apparmor-errormsg-fix.patch new file mode 100644 index 0000000..0bba9a6 --- /dev/null +++ b/apparmor-errormsg-fix.patch @@ -0,0 +1,34 @@ +commit 789999f481b31398f147e547550184bf303ce729 +Author: Jim Fehlig +Date: Thu Feb 2 19:17:29 2017 -0700 + + apparmor: don't overwrite error from reload_profile + + Like other callers of reload_profile, don't overwrite errors in + AppArmorSetSecurityHostdevLabelHelper. + +Index: libvirt-3.0.0/src/security/security_apparmor.c +=================================================================== +--- libvirt-3.0.0.orig/src/security/security_apparmor.c ++++ libvirt-3.0.0/src/security/security_apparmor.c +@@ -322,19 +322,7 @@ AppArmorSetSecurityHostdevLabelHelper(co + struct SDPDOP *ptr = opaque; + virDomainDefPtr def = ptr->def; + +- if (reload_profile(ptr->mgr, def, file, true) < 0) { +- virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef( +- def, SECURITY_APPARMOR_NAME); +- if (!secdef) { +- virReportOOMError(); +- return -1; +- } +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("cannot update AppArmor profile \'%s\'"), +- secdef->imagelabel); +- return -1; +- } +- return 0; ++ return reload_profile(ptr->mgr, def, file, true); + } + + static int diff --git a/b4386fda-xenconfig-timer-fix.patch b/b4386fda-xenconfig-timer-fix.patch new file mode 100644 index 0000000..f0bcdb7 --- /dev/null +++ b/b4386fda-xenconfig-timer-fix.patch @@ -0,0 +1,145 @@ +commit b4386fdac7b063fc1775e1554f6f1f21b034b355 +Author: Jim Fehlig +Date: Thu Jan 19 16:51:05 2017 -0700 + + xenconfig: add support for more timers + + Currently xenconfig only supports the hpet timer for HVM domains. + Include support for tsc timer for both PV and HVM domains. + +Index: libvirt-3.0.0/src/xenconfig/xen_common.c +=================================================================== +--- libvirt-3.0.0.orig/src/xenconfig/xen_common.c ++++ libvirt-3.0.0/src/xenconfig/xen_common.c +@@ -490,6 +490,7 @@ xenParseCPUFeatures(virConfPtr conf, + unsigned long count = 0; + const char *str = NULL; + int val = 0; ++ virDomainTimerDefPtr timer; + + if (xenConfigGetULong(conf, "vcpus", &count, 1) < 0) + return -1; +@@ -514,6 +515,29 @@ xenParseCPUFeatures(virConfPtr conf, + if (str && (virBitmapParse(str, &def->cpumask, 4096) < 0)) + return -1; + ++ if (xenConfigGetString(conf, "tsc_mode", &str, NULL) < 0) ++ return -1; ++ ++ if (str) { ++ if (VIR_EXPAND_N(def->clock.timers, def->clock.ntimers, 1) < 0 || ++ VIR_ALLOC(timer) < 0) ++ return -1; ++ ++ timer->name = VIR_DOMAIN_TIMER_NAME_TSC; ++ timer->present = 1; ++ timer->tickpolicy = -1; ++ timer->mode = VIR_DOMAIN_TIMER_MODE_AUTO; ++ timer->track = -1; ++ if (STREQ_NULLABLE(str, "always_emulate")) ++ timer->mode = VIR_DOMAIN_TIMER_MODE_EMULATE; ++ else if (STREQ_NULLABLE(str, "native")) ++ timer->mode = VIR_DOMAIN_TIMER_MODE_NATIVE; ++ else if (STREQ_NULLABLE(str, "native_paravirt")) ++ timer->mode = VIR_DOMAIN_TIMER_MODE_PARAVIRT; ++ ++ def->clock.timers[def->clock.ntimers - 1] = timer; ++ } ++ + if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { + if (xenConfigGetBool(conf, "pae", &val, 1) < 0) + return -1; +@@ -545,9 +569,7 @@ xenParseCPUFeatures(virConfPtr conf, + return -1; + + if (val != -1) { +- virDomainTimerDefPtr timer; +- +- if (VIR_ALLOC_N(def->clock.timers, 1) < 0 || ++ if (VIR_EXPAND_N(def->clock.timers, def->clock.ntimers, 1) < 0 || + VIR_ALLOC(timer) < 0) + return -1; + +@@ -557,8 +579,7 @@ xenParseCPUFeatures(virConfPtr conf, + timer->mode = -1; + timer->track = -1; + +- def->clock.ntimers = 1; +- def->clock.timers[0] = timer; ++ def->clock.timers[def->clock.ntimers - 1] = timer; + } + } + +@@ -1584,8 +1605,9 @@ static int + xenFormatCPUFeatures(virConfPtr conf, virDomainDefPtr def) + { + size_t i; ++ bool hvm = !!(def->os.type == VIR_DOMAIN_OSTYPE_HVM); + +- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { ++ if (hvm) { + if (xenConfigSetInt(conf, "pae", + (def->features[VIR_DOMAIN_FEATURE_PAE] == + VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0) +@@ -1610,12 +1632,57 @@ xenFormatCPUFeatures(virConfPtr conf, vi + (def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] == + VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0) + return -1; ++ } ++ ++ for (i = 0; i < def->clock.ntimers; i++) { ++ switch ((virDomainTimerNameType) def->clock.timers[i]->name) { ++ case VIR_DOMAIN_TIMER_NAME_TSC: ++ switch (def->clock.timers[i]->mode) { ++ case VIR_DOMAIN_TIMER_MODE_NATIVE: ++ if (xenConfigSetString(conf, "tsc_mode", "native") < 0) ++ return -1; ++ break; ++ case VIR_DOMAIN_TIMER_MODE_PARAVIRT: ++ if (xenConfigSetString(conf, "tsc_mode", "native_paravirt") < 0) ++ return -1; ++ break; ++ case VIR_DOMAIN_TIMER_MODE_EMULATE: ++ if (xenConfigSetString(conf, "tsc_mode", "always_emulate") < 0) ++ return -1; ++ break; ++ default: ++ if (xenConfigSetString(conf, "tsc_mode", "default") < 0) ++ return -1; ++ } ++ break; ++ ++ case VIR_DOMAIN_TIMER_NAME_HPET: ++ if (hvm) { ++ int enable_hpet = def->clock.timers[i]->present != 0; + +- for (i = 0; i < def->clock.ntimers; i++) { +- if (def->clock.timers[i]->name == VIR_DOMAIN_TIMER_NAME_HPET && +- def->clock.timers[i]->present != -1 && +- xenConfigSetInt(conf, "hpet", def->clock.timers[i]->present) < 0) ++ /* disable hpet if 'present' is 0, enable otherwise */ ++ if (xenConfigSetInt(conf, "hpet", enable_hpet) < 0) ++ return -1; ++ } else { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unsupported timer type (name) '%s'"), ++ virDomainTimerNameTypeToString(def->clock.timers[i]->name)); + return -1; ++ } ++ break; ++ ++ case VIR_DOMAIN_TIMER_NAME_PLATFORM: ++ case VIR_DOMAIN_TIMER_NAME_KVMCLOCK: ++ case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK: ++ case VIR_DOMAIN_TIMER_NAME_RTC: ++ case VIR_DOMAIN_TIMER_NAME_PIT: ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unsupported timer type (name) '%s'"), ++ virDomainTimerNameTypeToString(def->clock.timers[i]->name)); ++ return -1; ++ ++ case VIR_DOMAIN_TIMER_NAME_LAST: ++ break; + } + } + diff --git a/bd116810-libxl-fix-disk-detach.patch b/bd116810-libxl-fix-disk-detach.patch new file mode 100644 index 0000000..afda3c2 --- /dev/null +++ b/bd116810-libxl-fix-disk-detach.patch @@ -0,0 +1,132 @@ +commit bd1168101a0ea5efcf3b2dc5ee782af6ad911320 +Author: Jim Fehlig +Date: Tue Feb 7 12:05:15 2017 -0700 + + libxl: fix disk detach when not specified + + When a user does not explicitly set a in the disk config, + libvirt defers selection of a default to libxl. This approach works + fine when starting a domain with such configuration or attaching a + disk to a running domain. But when detaching such a disk, libxl + will fail with "unrecognized disk backend type: 0". libxl makes no + attempt to recalculate a default backend (driver) on detach and + simply fails when uninitialized. + + This patch updates the libvirt disk config with the backend selected + by libxl when starting a domain or attaching a disk to a running + domain. Another benefit of this approach is that the live XML is + also updated with the backend driver selected by libxl. + +Index: libvirt-3.0.0/src/libxl/libxl_conf.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.c ++++ libvirt-3.0.0/src/libxl/libxl_conf.c +@@ -907,6 +907,38 @@ libxlMakeDiskList(virDomainDefPtr def, l + return -1; + } + ++/* ++ * Update libvirt disk config with libxl disk config. ++ * ++ * This function can be used to update the libvirt disk config with default ++ * values selected by libxl. Currently only the backend type is selected by ++ * libxl when not explicitly specified by the user. ++ */ ++void ++libxlUpdateDiskDef(virDomainDiskDefPtr l_disk, libxl_device_disk *x_disk) ++{ ++ const char *driver = NULL; ++ ++ if (virDomainDiskGetDriver(l_disk)) ++ return; ++ ++ switch (x_disk->backend) { ++ case LIBXL_DISK_BACKEND_QDISK: ++ driver = "qemu"; ++ break; ++ case LIBXL_DISK_BACKEND_TAP: ++ driver = "tap"; ++ break; ++ case LIBXL_DISK_BACKEND_PHY: ++ driver = "phy"; ++ break; ++ case LIBXL_DISK_BACKEND_UNKNOWN: ++ break; ++ } ++ if (driver) ++ ignore_value(virDomainDiskSetDriver(l_disk, driver)); ++} ++ + int + libxlMakeNic(virDomainDefPtr def, + virDomainNetDefPtr l_nic, +Index: libvirt-3.0.0/src/libxl/libxl_conf.h +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.h ++++ libvirt-3.0.0/src/libxl/libxl_conf.h +@@ -175,6 +175,10 @@ int libxlDriverConfigLoadFile(libxlDrive + + int + libxlMakeDisk(virDomainDiskDefPtr l_dev, libxl_device_disk *x_dev); ++ ++void ++libxlUpdateDiskDef(virDomainDiskDefPtr l_dev, libxl_device_disk *x_dev); ++ + int + libxlMakeNic(virDomainDefPtr def, + virDomainNetDefPtr l_nic, +Index: libvirt-3.0.0/src/libxl/libxl_domain.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_domain.c ++++ libvirt-3.0.0/src/libxl/libxl_domain.c +@@ -1072,6 +1072,30 @@ libxlDomainCreateIfaceNames(virDomainDef + } + } + ++static void ++libxlDomainUpdateDiskParams(virDomainDefPtr def, libxl_ctx *ctx) ++{ ++ libxl_device_disk *disks; ++ int num_disks = 0; ++ size_t i; ++ int idx; ++ ++ disks = libxl_device_disk_list(ctx, def->id, &num_disks); ++ if (!disks) ++ return; ++ ++ for (i = 0; i < num_disks; i++) { ++ if ((idx = virDomainDiskIndexByName(def, disks[i].vdev, false)) < 0) ++ continue; ++ ++ libxlUpdateDiskDef(def->disks[idx], &disks[i]); ++ } ++ ++ for (i = 0; i < num_disks; i++) ++ libxl_device_disk_dispose(&disks[i]); ++ VIR_FREE(disks); ++} ++ + #ifdef LIBXL_HAVE_DEVICE_CHANNEL + static void + libxlDomainCreateChannelPTY(virDomainDefPtr def, libxl_ctx *ctx) +@@ -1315,6 +1339,7 @@ libxlDomainStart(libxlDriverPrivatePtr d + goto destroy_dom; + + libxlDomainCreateIfaceNames(vm->def, &d_config); ++ libxlDomainUpdateDiskParams(vm->def, cfg->ctx); + + #ifdef LIBXL_HAVE_DEVICE_CHANNEL + if (vm->def->nchannels > 0) +Index: libvirt-3.0.0/src/libxl/libxl_driver.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_driver.c ++++ libvirt-3.0.0/src/libxl/libxl_driver.c +@@ -3028,6 +3028,7 @@ libxlDomainAttachDeviceDiskLive(virDomai + goto cleanup; + } + ++ libxlUpdateDiskDef(l_disk, &x_disk); + virDomainDiskInsertPreAlloced(vm->def, l_disk); + + } else { diff --git a/c89a6e78-libxl-physinfo-cleanup.patch b/c89a6e78-libxl-physinfo-cleanup.patch new file mode 100644 index 0000000..9900169 --- /dev/null +++ b/c89a6e78-libxl-physinfo-cleanup.patch @@ -0,0 +1,103 @@ +commit c89a6e7878e630718cce0af940e9c070c132ce30 +Author: Jim Fehlig +Date: Tue Jan 31 20:07:30 2017 -0700 + + libxl: use init and dispose functions with libxl_physinfo + + The typical pattern when calling libxl functions that populate a + structure is + + libxl_foo foo; + libxl_foo_init(&foo); + libxl_get_foo(ctx, &foo); + ... + libxl_foo_dispose(&foo); + + Fix several instances of libxl_physinfo missing the init and + dispose calls. + + Signed-off-by: Jim Fehlig + +Index: libvirt-3.0.0/src/libxl/libxl_capabilities.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_capabilities.c ++++ libvirt-3.0.0/src/libxl/libxl_capabilities.c +@@ -211,27 +211,33 @@ libxlCapsInitHost(libxl_ctx *ctx, virCap + const libxl_version_info *ver_info; + enum libxlHwcapVersion version; + libxl_physinfo phy_info; ++ int ret = -1; + ++ libxl_physinfo_init(&phy_info); + if (libxl_get_physinfo(ctx, &phy_info) != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to get node physical info from libxenlight")); +- return -1; ++ goto cleanup; + } + + if ((ver_info = libxl_get_version_info(ctx)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to get version info from libxenlight")); +- return -1; ++ goto cleanup; + } + + version = (ver_info->xen_version_minor >= 7); + if (libxlCapsInitCPU(caps, &phy_info, version) < 0) +- return -1; ++ goto cleanup; + + if (virCapabilitiesSetNetPrefix(caps, LIBXL_GENERATED_PREFIX_XEN) < 0) +- return -1; ++ goto cleanup; + +- return 0; ++ ret = 0; ++ ++ cleanup: ++ libxl_physinfo_dispose(&phy_info); ++ return ret; + } + + static int +Index: libvirt-3.0.0/src/libxl/libxl_conf.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_conf.c ++++ libvirt-3.0.0/src/libxl/libxl_conf.c +@@ -1969,6 +1969,7 @@ libxlDriverNodeGetInfo(libxlDriverPrivat + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); + int ret = -1; + ++ libxl_physinfo_init(&phy_info); + if (libxl_get_physinfo(cfg->ctx, &phy_info)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("libxl_get_physinfo_info failed")); +@@ -1993,6 +1994,7 @@ libxlDriverNodeGetInfo(libxlDriverPrivat + ret = 0; + + cleanup: ++ libxl_physinfo_dispose(&phy_info); + virObjectUnref(cfg); + return ret; + } +Index: libvirt-3.0.0/src/libxl/libxl_driver.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_driver.c ++++ libvirt-3.0.0/src/libxl/libxl_driver.c +@@ -4284,6 +4284,7 @@ libxlNodeGetFreeMemory(virConnectPtr con + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); + unsigned long long ret = 0; + ++ libxl_physinfo_init(&phy_info); + if (virNodeGetFreeMemoryEnsureACL(conn) < 0) + goto cleanup; + +@@ -4296,6 +4297,7 @@ libxlNodeGetFreeMemory(virConnectPtr con + ret = phy_info.free_pages * cfg->verInfo->pagesize; + + cleanup: ++ libxl_physinfo_dispose(&phy_info); + virObjectUnref(cfg); + return ret; + } diff --git a/d2b77608-libxl-maxmem-fix.patch b/d2b77608-libxl-maxmem-fix.patch new file mode 100644 index 0000000..5dbe958 --- /dev/null +++ b/d2b77608-libxl-maxmem-fix.patch @@ -0,0 +1,57 @@ +commit d2b77608e9e9c23416a9ac93a50054348cb51653 +Author: Jim Fehlig +Date: Mon Jan 16 10:51:40 2017 -0700 + + libxl: fix reporting of maximum memory + + The libxl driver reports different values of maximum memory depending + on state of a domain. If inactive, maximum memory value is reported + correctly. When active, maximum memory is derived from max_pages value + returned by the XEN_SYSCTL_getdomaininfolist sysctl operation. But + max_pages can be changed by toolstacks and does not necessarily + represent the maximum memory a domain can use during its active + lifetime. + + A better location for determining a domain's maximum memory is the + /local/domain//memory/static-max node in xenstore. This value + is set from the libxl_domain_build_info.max_memkb field when creating + the domain. Currently it cannot be changed nor can its value be + exceeded by a balloon operation. From libvirt's perspective, always + reporting maximum memory with virDomainDefGetMemoryTotal() will produce + the same results as reading the static-max node in xenstore. + + Signed-off-by: Jim Fehlig + +Index: libvirt-3.0.0/src/libxl/libxl_driver.c +=================================================================== +--- libvirt-3.0.0.orig/src/libxl/libxl_driver.c ++++ libvirt-3.0.0/src/libxl/libxl_driver.c +@@ -1640,10 +1640,10 @@ libxlDomainGetInfo(virDomainPtr dom, vir + if (virDomainGetInfoEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + ++ info->maxMem = virDomainDefGetMemoryTotal(vm->def); + if (!virDomainObjIsActive(vm)) { + info->cpuTime = 0; + info->memory = vm->def->mem.cur_balloon; +- info->maxMem = virDomainDefGetMemoryTotal(vm->def); + } else { + libxl_dominfo_init(&d_info); + +@@ -1655,7 +1655,6 @@ libxlDomainGetInfo(virDomainPtr dom, vir + } + info->cpuTime = d_info.cpu_time; + info->memory = d_info.current_memkb; +- info->maxMem = d_info.max_memkb; + + libxl_dominfo_dispose(&d_info); + } +@@ -5175,7 +5174,7 @@ libxlDomainMemoryStats(virDomainPtr dom, + goto endjob; + } + mem = d_info.current_memkb; +- maxmem = d_info.max_memkb; ++ maxmem = virDomainDefGetMemoryTotal(vm->def); + + LIBXL_SET_MEMSTAT(VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON, mem); + LIBXL_SET_MEMSTAT(VIR_DOMAIN_MEMORY_STAT_AVAILABLE, maxmem); diff --git a/d3970925-timer-tests.patch b/d3970925-timer-tests.patch new file mode 100644 index 0000000..42acd31 --- /dev/null +++ b/d3970925-timer-tests.patch @@ -0,0 +1,325 @@ +commit d397092591518006b41131f9fc921f74248e60a3 +Author: Jim Fehlig +Date: Thu Jan 19 17:19:18 2017 -0700 + + tests: add xlconfig tests for configurations + +Index: libvirt-3.0.0/tests/xlconfigdata/test-fullvirt-hpet-timer.cfg +=================================================================== +--- /dev/null ++++ libvirt-3.0.0/tests/xlconfigdata/test-fullvirt-hpet-timer.cfg +@@ -0,0 +1,27 @@ ++name = "XenGuest2" ++uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809" ++maxmem = 579 ++memory = 394 ++vcpus = 1 ++pae = 1 ++acpi = 1 ++apic = 1 ++hap = 0 ++viridian = 0 ++hpet = 1 ++rtc_timeoffset = 0 ++localtime = 0 ++on_poweroff = "destroy" ++on_reboot = "restart" ++on_crash = "restart" ++device_model = "/usr/lib/xen/bin/qemu-system-i386" ++sdl = 0 ++vnc = 1 ++vncunused = 1 ++vnclisten = "127.0.0.1" ++vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge,model=e1000,rate=10240KB/s" ] ++parallel = "none" ++serial = "none" ++builder = "hvm" ++boot = "d" ++disk = [ "format=raw,vdev=hda,access=rw,backendtype=phy,target=/dev/HostVG/XenGuest2", "format=qcow2,vdev=hdb,access=rw,backendtype=qdisk,target=/var/lib/libvirt/images/XenGuest2-home", "format=raw,vdev=hdc,access=ro,backendtype=qdisk,devtype=cdrom,target=/root/boot.iso" ] +Index: libvirt-3.0.0/tests/xlconfigdata/test-fullvirt-hpet-timer.xml +=================================================================== +--- /dev/null ++++ libvirt-3.0.0/tests/xlconfigdata/test-fullvirt-hpet-timer.xml +@@ -0,0 +1,64 @@ ++ ++ XenGuest2 ++ c7a5fdb2-cdaf-9455-926a-d65c16db1809 ++ 592896 ++ 403456 ++ 1 ++ ++ hvm ++ /usr/lib/xen/boot/hvmloader ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ destroy ++ restart ++ restart ++ ++ /usr/lib/xen/bin/qemu-system-i386 ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++ ++ ++