diff --git a/0257ba8f-mig-speed-7.patch b/0257ba8f-mig-speed-7.patch new file mode 100644 index 0000000..b561159 --- /dev/null +++ b/0257ba8f-mig-speed-7.patch @@ -0,0 +1,50 @@ +commit 0257ba8f9f4bf522a106aa2bbb4756e391a3dd42 +Author: Jim Fehlig +Date: Fri Aug 26 12:10:27 2011 -0600 + + Use max bandwidth from qemuDomainObjPrivate struct when migrating + + Adjust qemuMigrationRun() to use migMaxBandwidth in qemuDomainObjPrivate + structure when setting qemu migration speed. Caller-specified 'resource' + parameter overrides migMaxBandwidth. + +Index: libvirt-0.9.4/src/qemu/qemu_migration.c +=================================================================== +--- libvirt-0.9.4.orig/src/qemu/qemu_migration.c ++++ libvirt-0.9.4/src/qemu/qemu_migration.c +@@ -1284,6 +1284,7 @@ static int doNativeMigrate(struct qemud_ + qemuDomainObjPrivatePtr priv = vm->privateData; + unsigned int background_flags = QEMU_MONITOR_MIGRATE_BACKGROUND; + qemuMigrationCookiePtr mig = NULL; ++ unsigned long migrate_speed = resource ? resource : priv->migMaxBandwidth; + VIR_DEBUG("driver=%p, vm=%p, uri=%s, cookiein=%s, cookieinlen=%d, " + "cookieout=%p, cookieoutlen=%p, flags=%x, dname=%s, resource=%lu", + driver, vm, uri, NULLSTR(cookiein), cookieinlen, +@@ -1334,8 +1335,7 @@ static int doNativeMigrate(struct qemud_ + QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + goto cleanup; + +- if (resource > 0 && +- qemuMonitorSetMigrationSpeed(priv->mon, resource) < 0) { ++ if (qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0) { + qemuDomainObjExitMonitorWithDriver(driver, vm); + goto cleanup; + } +@@ -1506,6 +1506,7 @@ static int doTunnelMigrate(struct qemud_ + int ret = -1; + qemuMigrationCookiePtr mig = NULL; + qemuMigrationIOThreadPtr iothread = NULL; ++ unsigned long migrate_speed = resource ? resource : priv->migMaxBandwidth; + VIR_DEBUG("driver=%p, vm=%p, st=%p, cookiein=%s, cookieinlen=%d, " + "cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu", + driver, vm, st, NULLSTR(cookiein), cookieinlen, +@@ -1597,8 +1598,7 @@ static int doTunnelMigrate(struct qemud_ + QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + goto cleanup; + +- if (resource > 0 && +- qemuMonitorSetMigrationSpeed(priv->mon, resource) < 0) { ++ if (qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0) { + qemuDomainObjExitMonitorWithDriver(driver, vm); + goto cleanup; + } diff --git a/1282bd80-mig-speed-2.patch b/1282bd80-mig-speed-2.patch new file mode 100644 index 0000000..e108366 --- /dev/null +++ b/1282bd80-mig-speed-2.patch @@ -0,0 +1,80 @@ +commit 1282bd80f752b1b11e031881b7b64dea214a2461 +Author: Jim Fehlig +Date: Fri Aug 26 12:10:24 2011 -0600 + + virsh: Expose virDomainMigrateGetMaxSpeed API + +Index: libvirt-0.9.4/tools/virsh.c +=================================================================== +--- libvirt-0.9.4.orig/tools/virsh.c ++++ libvirt-0.9.4/tools/virsh.c +@@ -5200,6 +5200,45 @@ done: + return ret; + } + ++/* ++ * "migrate-getspeed" command ++ */ ++static const vshCmdInfo info_migrate_getspeed[] = { ++ {"help", N_("Get the maximum migration bandwidth")}, ++ {"desc", N_("Get the maximum migration bandwidth (in Mbps) for a domain.")}, ++ {NULL, NULL} ++}; ++ ++static const vshCmdOptDef opts_migrate_getspeed[] = { ++ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, ++ {NULL, 0, 0, NULL} ++}; ++ ++static bool ++cmdMigrateGetMaxSpeed(vshControl *ctl, const vshCmd *cmd) ++{ ++ virDomainPtr dom = NULL; ++ unsigned long bandwidth; ++ bool ret = false; ++ ++ if (!vshConnectionUsability(ctl, ctl->conn)) ++ return false; ++ ++ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) ++ return false; ++ ++ if (virDomainMigrateGetMaxSpeed(dom, &bandwidth, 0) < 0) ++ goto done; ++ ++ vshPrint(ctl, "%lu\n", bandwidth); ++ ++ ret = true; ++ ++done: ++ virDomainFree(dom); ++ return ret; ++} ++ + typedef enum { + VSH_CMD_BLOCK_JOB_ABORT = 0, + VSH_CMD_BLOCK_JOB_INFO = 1, +@@ -12519,6 +12558,8 @@ static const vshCmdDef domManagementCmds + opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime, 0}, + {"migrate-setspeed", cmdMigrateSetMaxSpeed, + opts_migrate_setspeed, info_migrate_setspeed, 0}, ++ {"migrate-getspeed", cmdMigrateGetMaxSpeed, ++ opts_migrate_getspeed, info_migrate_getspeed, 0}, + {"reboot", cmdReboot, opts_reboot, info_reboot, 0}, + {"restore", cmdRestore, opts_restore, info_restore, 0}, + {"resume", cmdResume, opts_resume, info_resume, 0}, +Index: libvirt-0.9.4/tools/virsh.pod +=================================================================== +--- libvirt-0.9.4.orig/tools/virsh.pod ++++ libvirt-0.9.4/tools/virsh.pod +@@ -619,6 +619,10 @@ to be down at the end of live migration. + Set the maximum migration bandwidth (in Mbps) for a domain which is being + migrated to another host. + ++=item B I ++ ++Get the maximum migration bandwidth (in Mbps) for a domain. ++ + =item B I + + Reboot a domain. This acts just as if the domain had the B diff --git a/6f84e110-mig-speed-3.patch b/6f84e110-mig-speed-3.patch new file mode 100644 index 0000000..19e30b7 --- /dev/null +++ b/6f84e110-mig-speed-3.patch @@ -0,0 +1,47 @@ +commit 6f84e110d61e6e99ee80809f1d3c2c6dde352965 +Author: Jim Fehlig +Date: Fri Aug 26 12:10:22 2011 -0600 + + Store max migration bandwidth in qemuDomainObjPrivate struct + + The maximum bandwidth that can be consumed when migrating a domain + is better classified as an operational vs configuration parameter of + the dommain. As such, store this parameter in qemuDomainObjPrivate + structure. + +Index: libvirt-0.9.4/src/qemu/qemu_domain.c +=================================================================== +--- libvirt-0.9.4.orig/src/qemu/qemu_domain.c ++++ libvirt-0.9.4/src/qemu/qemu_domain.c +@@ -215,6 +215,8 @@ static void *qemuDomainObjPrivateAlloc(v + if (qemuDomainObjInitJob(priv) < 0) + VIR_FREE(priv); + ++ priv->migMaxBandwidth = QEMU_DOMAIN_DEFAULT_MIG_BANDWIDTH_MAX; ++ + return priv; + } + +Index: libvirt-0.9.4/src/qemu/qemu_domain.h +=================================================================== +--- libvirt-0.9.4.orig/src/qemu/qemu_domain.h ++++ libvirt-0.9.4/src/qemu/qemu_domain.h +@@ -36,6 +36,9 @@ + (1 << VIR_DOMAIN_VIRT_KVM) | \ + (1 << VIR_DOMAIN_VIRT_XEN)) + ++# define QEMU_DOMAIN_DEFAULT_MIG_BANDWIDTH_MAX (32 << 20) ++# define QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX (INT64_MAX / (1024 * 1024)) ++ + # define JOB_MASK(job) (1 << (job - 1)) + # define DEFAULT_JOB_MASK \ + (JOB_MASK(QEMU_JOB_QUERY) | \ +@@ -113,6 +116,8 @@ struct _qemuDomainObjPrivate { + char *lockState; + + bool fakeReboot; ++ ++ unsigned long migMaxBandwidth; + }; + + struct qemuDomainWatchdogEvent diff --git a/7e5f6a51-rpc-generator.patch b/7e5f6a51-rpc-generator.patch new file mode 100644 index 0000000..039eda1 --- /dev/null +++ b/7e5f6a51-rpc-generator.patch @@ -0,0 +1,73 @@ +commit 7e5f6a516c1b0066206364655be31276056da147 +Author: Jim Fehlig +Date: Fri Aug 26 11:46:41 2011 -0600 + + Fix generator to cope with call-by-ref long types + + From: Matthias Bolte + Tested-by: Jim Fehlig + + Matthias provided this patch to fix an issue I encountered in the + generator with APIs containing call-by-ref long type, e.g. + + int virDomainMigrateGetMaxSpeed(virDomainPtr domain, + unsigned long *bandwidth, + unsigned int flags); + +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index 0d344e8..f671ff0 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -640,10 +640,11 @@ elsif ($opt_b) { + } elsif ($ret_member =~ m/^(?:unsigned )?hyper (\S+)<\S+>;/) { + # error out on unannotated arrays + die "hyper array without insert@ annotation: $ret_member"; +- } elsif ($ret_member =~ m/^(unsigned )?hyper (\S+);/) { ++ } elsif ($ret_member =~ m/^(unsigned )?hyper (\S+);(?:\s*\/\*\s*insert@(\d+)\s*\*\/)?/) { + my $type_name = $1; + my $ret_name = $2; + my $ret_assign; ++ my $insert = $3; + + if (hyper_to_long($call->{ProcName}, "ret", $ret_name)) { + my $sign = ""; $sign = "U" if ($1); +@@ -657,7 +658,13 @@ elsif ($opt_b) { + + push(@vars_list, "$type_name $ret_name"); + push(@ret_list, $ret_assign); +- $single_ret_var = $ret_name; ++ ++ if ($insert) { ++ splice(@args_list, int($insert), 0, "&$ret_name"); ++ $single_ret_var = undef; ++ } else { ++ $single_ret_var = $ret_name; ++ } + + if ($call->{ProcName} eq "DomainGetMaxMemory" or + $call->{ProcName} eq "NodeGetFreeMemory") { +@@ -1285,6 +1292,24 @@ elsif ($opt_k) { + + $single_ret_var = "int rv = -1"; + $single_ret_type = "int"; ++ } elsif ($ret_member =~ m/^(unsigned )?hyper (\S+);\s*\/\*\s*insert@(\d+)\s*\*\//) { ++ my $type_name = $1; ++ my $sign = ""; $sign = "U" if ($1); ++ my $ret_name = $2; ++ my $insert = $3; ++ ++ if (hyper_to_long($call->{ProcName}, "ret", $ret_name)) { ++ $type_name .= "long"; ++ push(@ret_list, "if ($ret_name) HYPER_TO_${sign}LONG(*$ret_name, ret.$ret_name);"); ++ } else { ++ $type_name .= "long long"; ++ push(@ret_list, "if ($ret_name) *$ret_name = ret.$ret_name;"); ++ } ++ ++ splice(@args_list, int($insert), 0, ("$type_name *$ret_name")); ++ push(@ret_list, "rv = 0;"); ++ $single_ret_var = "int rv = -1"; ++ $single_ret_type = "int"; + } elsif ($ret_member =~ m/^unsigned hyper (\S+);/) { + my $ret_name = $1; + diff --git a/829bce17-mig-speed-4.patch b/829bce17-mig-speed-4.patch new file mode 100644 index 0000000..3e89728 --- /dev/null +++ b/829bce17-mig-speed-4.patch @@ -0,0 +1,57 @@ +commit 829bce174c8a958dee4eb5b1fea63e0f5f914af8 +Author: Jim Fehlig +Date: Fri Aug 26 12:10:23 2011 -0600 + + Impl virDomainMigrateGetMaxSpeed in qemu driver + +Index: libvirt-0.9.4/src/qemu/qemu_driver.c +=================================================================== +--- libvirt-0.9.4.orig/src/qemu/qemu_driver.c ++++ libvirt-0.9.4/src/qemu/qemu_driver.c +@@ -8329,6 +8329,38 @@ static int qemuDomainSnapshotSetCurrentI + } + + ++static int ++qemuDomainMigrateGetMaxSpeed(virDomainPtr dom, ++ unsigned long *bandwidth, ++ unsigned int flags) ++{ ++ struct qemud_driver *driver = dom->conn->privateData; ++ virDomainObjPtr vm; ++ int ret = -1; ++ ++ virCheckFlags(0, -1); ++ ++ qemuDriverLock(driver); ++ vm = virDomainFindByUUID(&driver->domains, dom->uuid); ++ qemuDriverUnlock(driver); ++ ++ if (!vm) { ++ char uuidstr[VIR_UUID_STRING_BUFLEN]; ++ virUUIDFormat(dom->uuid, uuidstr); ++ qemuReportError(VIR_ERR_NO_DOMAIN, ++ _("no domain with matching uuid '%s'"), uuidstr); ++ goto cleanup; ++ } ++ ++ *bandwidth = vm->privateData->migMaxBandwidth; ++ ret = 0; ++ ++cleanup: ++ if (vm) ++ virDomainObjUnlock(vm); ++ return ret; ++} ++ + static int qemuDomainSnapshotIsAllowed(virDomainObjPtr vm) + { + int i; +@@ -9494,6 +9526,7 @@ static virDriver qemuDriver = { + .domainAbortJob = qemuDomainAbortJob, /* 0.7.7 */ + .domainMigrateSetMaxDowntime = qemuDomainMigrateSetMaxDowntime, /* 0.8.0 */ + .domainMigrateSetMaxSpeed = qemuDomainMigrateSetMaxSpeed, /* 0.9.0 */ ++ .domainMigrateGetMaxSpeed = qemuDomainMigrateGetMaxSpeed, /* 0.9.5 */ + .domainEventRegisterAny = qemuDomainEventRegisterAny, /* 0.8.0 */ + .domainEventDeregisterAny = qemuDomainEventDeregisterAny, /* 0.8.0 */ + .domainManagedSave = qemuDomainManagedSave, /* 0.8.0 */ diff --git a/8fc40c51-mig-speed-5.patch b/8fc40c51-mig-speed-5.patch new file mode 100644 index 0000000..f321821 --- /dev/null +++ b/8fc40c51-mig-speed-5.patch @@ -0,0 +1,65 @@ +commit 8fc40c511c08143cb64ff0d212942dde8e81c279 +Author: Jim Fehlig +Date: Fri Aug 26 12:10:25 2011 -0600 + + Save migration speed in qemuDomainMigrateSetMaxSpeed + + Now that migration speed is stored in qemuDomainObjPrivate structure, + save the new value when invoking qemuDomainMigrateSetMaxSpeed(). + + Allow setting migration speed on inactive domain too. + +Index: libvirt-0.9.4/src/qemu/qemu_driver.c +=================================================================== +--- libvirt-0.9.4.orig/src/qemu/qemu_driver.c ++++ libvirt-0.9.4/src/qemu/qemu_driver.c +@@ -8202,32 +8202,26 @@ qemuDomainMigrateSetMaxSpeed(virDomainPt + return -1; + } + +- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0) +- goto cleanup; +- +- if (!virDomainObjIsActive(vm)) { +- qemuReportError(VIR_ERR_OPERATION_INVALID, +- "%s", _("domain is not running")); +- goto endjob; +- } +- + priv = vm->privateData; +- +- if (priv->job.asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT) { +- qemuReportError(VIR_ERR_OPERATION_INVALID, +- "%s", _("domain is not being migrated")); +- goto endjob; ++ if (virDomainObjIsActive(vm)) { ++ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0) ++ goto cleanup; ++ ++ VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth); ++ qemuDomainObjEnterMonitor(driver, vm); ++ ret = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth); ++ qemuDomainObjExitMonitor(driver, vm); ++ ++ if (ret == 0) ++ priv->migMaxBandwidth = bandwidth; ++ ++ if (qemuDomainObjEndJob(driver, vm) == 0) ++ vm = NULL; ++ } else { ++ priv->migMaxBandwidth = bandwidth; ++ ret = 0; + } + +- VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth); +- qemuDomainObjEnterMonitor(driver, vm); +- ret = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth); +- qemuDomainObjExitMonitor(driver, vm); +- +-endjob: +- if (qemuDomainObjEndJob(driver, vm) == 0) +- vm = NULL; +- + cleanup: + if (vm) + virDomainObjUnlock(vm); diff --git a/b12354be-mig-speed-1.patch b/b12354be-mig-speed-1.patch new file mode 100644 index 0000000..2160408 --- /dev/null +++ b/b12354be-mig-speed-1.patch @@ -0,0 +1,292 @@ +commit b12354befee9f8e88d3d5d96390856af8f05eb2f +Author: Jim Fehlig +Date: Fri Aug 26 12:10:21 2011 -0600 + + Add public API for getting migration speed + + Includes impl of python binding since the generator was not + able to cope. + + Note: Requires gendispatch.pl patch from Matthias Bolte + + https://www.redhat.com/archives/libvir-list/2011-August/msg01367.html + +Index: libvirt-0.9.4/docs/apibuild.py +=================================================================== +--- libvirt-0.9.4.orig/docs/apibuild.py ++++ libvirt-0.9.4/docs/apibuild.py +@@ -1643,7 +1643,8 @@ class CParser: + "virDomainSetMemory" : (False, ("memory")), + "virDomainSetMemoryFlags" : (False, ("memory")), + "virDomainBlockJobSetSpeed" : (False, ("bandwidth")), +- "virDomainBlockPull" : (False, ("bandwidth")) } ++ "virDomainBlockPull" : (False, ("bandwidth")), ++ "virDomainMigrateGetMaxSpeed" : (False, ("bandwidth")) } + + def checkLongLegacyFunction(self, name, return_type, signature): + if "long" in return_type and "long long" not in return_type: +Index: libvirt-0.9.4/include/libvirt/libvirt.h.in +=================================================================== +--- libvirt-0.9.4.orig/include/libvirt/libvirt.h.in ++++ libvirt-0.9.4/include/libvirt/libvirt.h.in +@@ -711,6 +711,10 @@ int virDomainMigrateSetMaxSpeed(virDomai + unsigned long bandwidth, + unsigned int flags); + ++int virDomainMigrateGetMaxSpeed(virDomainPtr domain, ++ unsigned long *bandwidth, ++ unsigned int flags); ++ + /** + * VIR_NODEINFO_MAXCPUS: + * @nodeinfo: virNodeInfo instance +Index: libvirt-0.9.4/python/generator.py +=================================================================== +--- libvirt-0.9.4.orig/python/generator.py ++++ libvirt-0.9.4/python/generator.py +@@ -372,6 +372,7 @@ skip_impl = ( + 'virNodeGetCPUStats', + 'virNodeGetMemoryStats', + 'virDomainGetBlockJobInfo', ++ 'virDomainMigrateGetMaxSpeed', + ) + + +Index: libvirt-0.9.4/python/libvirt-override-api.xml +=================================================================== +--- libvirt-0.9.4.orig/python/libvirt-override-api.xml ++++ libvirt-0.9.4/python/libvirt-override-api.xml +@@ -356,5 +356,11 @@ + + + ++ ++ Get currently configured maximum migration speed for a domain ++ ++ ++ ++ + + +Index: libvirt-0.9.4/python/libvirt-override.c +=================================================================== +--- libvirt-0.9.4.orig/python/libvirt-override.c ++++ libvirt-0.9.4/python/libvirt-override.c +@@ -4543,6 +4543,29 @@ libvirt_virDomainSendKey(PyObject *self + return py_retval; + } + ++static PyObject * ++libvirt_virDomainMigrateGetMaxSpeed(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { ++ PyObject *py_retval; ++ int c_retval; ++ unsigned long bandwidth; ++ virDomainPtr domain; ++ PyObject *pyobj_domain; ++ ++ if (!PyArg_ParseTuple(args, (char *)"O:virDomainMigrateGetMaxSpeed", &pyobj_domain)) ++ return(NULL); ++ ++ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); ++ ++ LIBVIRT_BEGIN_ALLOW_THREADS; ++ c_retval = virDomainMigrateGetMaxSpeed(domain, &bandwidth, 0); ++ LIBVIRT_END_ALLOW_THREADS; ++ ++ if (c_retval < 0) ++ return VIR_PY_INT_FAIL; ++ py_retval = libvirt_ulongWrap(bandwidth); ++ return(py_retval); ++} ++ + /************************************************************************ + * * + * The registration stuff * +@@ -4632,6 +4655,7 @@ static PyMethodDef libvirtMethods[] = { + {(char *) "virDomainRevertToSnapshot", libvirt_virDomainRevertToSnapshot, METH_VARARGS, NULL}, + {(char *) "virDomainGetBlockJobInfo", libvirt_virDomainGetBlockJobInfo, METH_VARARGS, NULL}, + {(char *) "virDomainSendKey", libvirt_virDomainSendKey, METH_VARARGS, NULL}, ++ {(char *) "virDomainMigrateGetMaxSpeed", libvirt_virDomainMigrateGetMaxSpeed, METH_VARARGS, NULL}, + {NULL, NULL, 0, NULL} + }; + +Index: libvirt-0.9.4/src/driver.h +=================================================================== +--- libvirt-0.9.4.orig/src/driver.h ++++ libvirt-0.9.4/src/driver.h +@@ -531,6 +531,11 @@ typedef int + unsigned int flags); + + typedef int ++ (*virDrvDomainMigrateGetMaxSpeed)(virDomainPtr domain, ++ unsigned long *bandwidth, ++ unsigned int flags); ++ ++typedef int + (*virDrvDomainEventRegisterAny)(virConnectPtr conn, + virDomainPtr dom, + int eventID, +@@ -827,6 +832,7 @@ struct _virDriver { + virDrvDomainGetJobInfo domainGetJobInfo; + virDrvDomainAbortJob domainAbortJob; + virDrvDomainMigrateSetMaxDowntime domainMigrateSetMaxDowntime; ++ virDrvDomainMigrateGetMaxSpeed domainMigrateGetMaxSpeed; + virDrvDomainMigrateSetMaxSpeed domainMigrateSetMaxSpeed; + virDrvDomainEventRegisterAny domainEventRegisterAny; + virDrvDomainEventDeregisterAny domainEventDeregisterAny; +Index: libvirt-0.9.4/src/libvirt.c +=================================================================== +--- libvirt-0.9.4.orig/src/libvirt.c ++++ libvirt-0.9.4/src/libvirt.c +@@ -15157,6 +15157,57 @@ error: + } + + /** ++ * virDomainMigrateGetMaxSpeed: ++ * @domain: a domain object ++ * @bandwidth: return value of current migration bandwidth limit in Mbps ++ * @flags: fine-tuning flags, currently unused, use 0 ++ * ++ * Get the current maximum bandwidth (in Mbps) that will be used if the ++ * domain is migrated. Not all hypervisors will support a bandwidth limit. ++ * ++ * Returns 0 in case of success, -1 otherwise. ++ */ ++int ++virDomainMigrateGetMaxSpeed(virDomainPtr domain, ++ unsigned long *bandwidth, ++ unsigned int flags) ++{ ++ virConnectPtr conn; ++ ++ VIR_DOMAIN_DEBUG(domain, "bandwidth = %p, flags=%x", bandwidth, flags); ++ ++ virResetLastError(); ++ ++ if (!VIR_IS_CONNECTED_DOMAIN(domain)) { ++ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); ++ virDispatchError(NULL); ++ return -1; ++ } ++ ++ if (!bandwidth) { ++ virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); ++ goto error; ++ } ++ ++ conn = domain->conn; ++ if (conn->flags & VIR_CONNECT_RO) { ++ virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); ++ goto error; ++ } ++ ++ if (conn->driver->domainMigrateGetMaxSpeed) { ++ if (conn->driver->domainMigrateGetMaxSpeed(domain, bandwidth, flags) < 0) ++ goto error; ++ return 0; ++ } ++ ++ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); ++error: ++ virDispatchError(conn); ++ return -1; ++} ++ ++/** + * virConnectDomainEventRegisterAny: + * @conn: pointer to the connection + * @dom: pointer to the domain +Index: libvirt-0.9.4/src/libvirt_public.syms +=================================================================== +--- libvirt-0.9.4.orig/src/libvirt_public.syms ++++ libvirt-0.9.4/src/libvirt_public.syms +@@ -480,4 +480,9 @@ LIBVIRT_0.9.4 { + virDomainBlockPull; + } LIBVIRT_0.9.3; + ++LIBVIRT_0.9.5 { ++ global: ++ virDomainMigrateGetMaxSpeed; ++} LIBVIRT_0.9.4; ++ + # .... define new API here using predicted next version number .... +Index: libvirt-0.9.4/src/remote/remote_driver.c +=================================================================== +--- libvirt-0.9.4.orig/src/remote/remote_driver.c ++++ libvirt-0.9.4/src/remote/remote_driver.c +@@ -4327,6 +4327,7 @@ static virDriver remote_driver = { + .domainAbortJob = remoteDomainAbortJob, /* 0.7.7 */ + .domainMigrateSetMaxDowntime = remoteDomainMigrateSetMaxDowntime, /* 0.8.0 */ + .domainMigrateSetMaxSpeed = remoteDomainMigrateSetMaxSpeed, /* 0.9.0 */ ++ .domainMigrateGetMaxSpeed = remoteDomainMigrateGetMaxSpeed, /* 0.9.5 */ + .domainEventRegisterAny = remoteDomainEventRegisterAny, /* 0.8.0 */ + .domainEventDeregisterAny = remoteDomainEventDeregisterAny, /* 0.8.0 */ + .domainManagedSave = remoteDomainManagedSave, /* 0.8.0 */ +Index: libvirt-0.9.4/src/remote/remote_protocol.x +=================================================================== +--- libvirt-0.9.4.orig/src/remote/remote_protocol.x ++++ libvirt-0.9.4/src/remote/remote_protocol.x +@@ -1913,6 +1913,16 @@ struct remote_domain_migrate_set_max_spe + unsigned int flags; + }; + ++struct remote_domain_migrate_get_max_speed_args { ++ remote_nonnull_domain dom; ++ unsigned int flags; ++}; ++ ++struct remote_domain_migrate_get_max_speed_ret { ++ unsigned hyper bandwidth; /* insert@1 */ ++}; ++ ++ + struct remote_domain_events_register_any_args { + int eventID; + }; +@@ -2475,7 +2485,8 @@ enum remote_procedure { + REMOTE_PROC_DOMAIN_BLOCK_JOB_SET_SPEED = 239, /* autogen autogen */ + REMOTE_PROC_DOMAIN_BLOCK_PULL = 240, /* autogen autogen */ + +- REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB = 241 /* skipgen skipgen */ ++ REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB = 241, /* skipgen skipgen */ ++ REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_SPEED = 242 /* autogen autogen */ + + /* + * Notice how the entries are grouped in sets of 10 ? +Index: libvirt-0.9.4/src/remote_protocol-structs +=================================================================== +--- libvirt-0.9.4.orig/src/remote_protocol-structs ++++ libvirt-0.9.4/src/remote_protocol-structs +@@ -1429,6 +1429,14 @@ struct remote_domain_migrate_set_max_spe + uint64_t bandwidth; + u_int flags; + }; ++struct remote_domain_migrate_get_max_speed_args { ++ remote_nonnull_domain dom; ++ u_int flags; ++}; ++struct remote_domain_migrate_get_max_speed_ret { ++ uint64_t bandwidth; ++}; ++ + struct remote_domain_events_register_any_args { + int eventID; + }; +@@ -1936,4 +1944,5 @@ enum remote_procedure { + REMOTE_PROC_DOMAIN_BLOCK_JOB_SET_SPEED = 239, + REMOTE_PROC_DOMAIN_BLOCK_PULL = 240, + REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB = 241, ++ REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_SPEED = 242, + }; +Index: libvirt-0.9.4/src/rpc/gendispatch.pl +=================================================================== +--- libvirt-0.9.4.orig/src/rpc/gendispatch.pl ++++ libvirt-0.9.4/src/rpc/gendispatch.pl +@@ -222,6 +222,7 @@ my $long_legacy = { + NodeGetInfo => { ret => { memory => 1 } }, + DomainBlockPull => { arg => { bandwidth => 1 } }, + DomainBlockJobSetSpeed => { arg => { bandwidth => 1 } }, ++ DomainMigrateGetMaxSpeed => { ret => { bandwidth => 1 } }, + }; + + sub hyper_to_long diff --git a/ef1065cf-mig-speed-6.patch b/ef1065cf-mig-speed-6.patch new file mode 100644 index 0000000..6af48f4 --- /dev/null +++ b/ef1065cf-mig-speed-6.patch @@ -0,0 +1,55 @@ +commit ef1065cf5acad13767c054758cbe7f4e8af5d241 +Author: Jim Fehlig +Date: Fri Aug 26 12:10:26 2011 -0600 + + Set qemu migration speed unlimited when migrating to file + + The qemu migration speed default is 32MiB/s as defined in migration.c + + /* Migration speed throttling */ + static int64_t max_throttle = (32 << 20); + + There's no need to throttle migration when targeting a file, so set migration + speed to unlimited prior to migration, and restore to libvirt default value + after migration. + + Default units is MB for migrate_set_speed monitor command, so + (INT64_MAX / (1024 * 1024)) is used for unlimited migration speed. + + Tested with both json and text monitors. + +Index: libvirt-0.9.4/src/qemu/qemu_migration.c +=================================================================== +--- libvirt-0.9.4.orig/src/qemu/qemu_migration.c ++++ libvirt-0.9.4/src/qemu/qemu_migration.c +@@ -2675,6 +2675,16 @@ qemuMigrationToFile(struct qemud_driver + bool restoreLabel = false; + virCommandPtr cmd = NULL; + int pipeFD[2] = { -1, -1 }; ++ unsigned long saveMigBandwidth = priv->migMaxBandwidth; ++ ++ /* Increase migration bandwidth to unlimited since target is a file. ++ * Failure to change migration speed is not fatal. */ ++ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) { ++ qemuMonitorSetMigrationSpeed(priv->mon, ++ QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX); ++ priv->migMaxBandwidth = QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX; ++ qemuDomainObjExitMonitorWithDriver(driver, vm); ++ } + + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && + (!compressor || pipe(pipeFD) == 0)) { +@@ -2783,6 +2793,13 @@ qemuMigrationToFile(struct qemud_driver + ret = 0; + + cleanup: ++ /* Restore max migration bandwidth */ ++ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) { ++ qemuMonitorSetMigrationSpeed(priv->mon, saveMigBandwidth); ++ priv->migMaxBandwidth = saveMigBandwidth; ++ qemuDomainObjExitMonitorWithDriver(driver, vm); ++ } ++ + VIR_FORCE_CLOSE(pipeFD[0]); + VIR_FORCE_CLOSE(pipeFD[1]); + virCommandFree(cmd); diff --git a/libvirt.changes b/libvirt.changes index aa420b5..ea03392 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Wed Sep 14 17:18:36 MDT 2011 - jfehlig@suse.com + +- Set qemu migration speed unlimited when migrating to file + 7e5f6a51-rpc-generator.patch b12354be-mig-speed-1.patch + 1282bd80-mig-speed-2.patch 6f84e110-mig-speed-3.patch + 829bce17-mig-speed-4.patch 8fc40c51-mig-speed-5.patch + ef1065cf-mig-speed-6.patch 0257ba8f-mig-speed-7.patch + bnc#706436 + ------------------------------------------------------------------- Wed Sep 14 16:12:49 MDT 2011 - jfehlig@suse.com diff --git a/libvirt.spec b/libvirt.spec index 88d6589..794a0c8 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -365,6 +365,14 @@ Patch1: 32620dab-fix-xen-err-msg.patch Patch2: 57c95175-xend-buff-size.patch Patch3: 6ff9fc26-quiet-libxl-logging.patch Patch4: 7f2498ef-no-log-invalid.patch +Patch5: 7e5f6a51-rpc-generator.patch +Patch6: b12354be-mig-speed-1.patch +Patch7: 1282bd80-mig-speed-2.patch +Patch8: 6f84e110-mig-speed-3.patch +Patch9: 829bce17-mig-speed-4.patch +Patch10: 8fc40c51-mig-speed-5.patch +Patch11: ef1065cf-mig-speed-6.patch +Patch12: 0257ba8f-mig-speed-7.patch # Need to go upstream Patch100: xen-name-for-devid.patch Patch101: clone.patch @@ -488,6 +496,14 @@ Authors: %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 %patch100 -p1 %patch101 %patch102 -p1