virDomainBlockJobInfoPtr info,
unsigned int flags);
-int virDomainBlockJobSetSpeed(virDomainPtr dom, const char *disk,
- unsigned long bandwidth, unsigned int flags);
+/* Flags for use with virDomainBlockJobSetSpeed */
+typedef enum {
+ VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES = 1 << 0, /* bandwidth in bytes/s
+ instead of MiB/s */
+} virDomainBlockJobSetSpeedFlags;
+
+int virDomainBlockJobSetSpeed(virDomainPtr dom, const char *disk,
+ unsigned long bandwidth, unsigned int flags);
-int virDomainBlockPull(virDomainPtr dom, const char *disk,
- unsigned long bandwidth, unsigned int flags);
+/* Flags for use with virDomainBlockPull (values chosen to be a subset
+ * of the flags for virDomainBlockRebase) */
+typedef enum {
+ VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES = 1 << 6, /* bandwidth in bytes/s
+ instead of MiB/s */
+} virDomainBlockPullFlags;
+
+int virDomainBlockPull(virDomainPtr dom, const char *disk,
+ unsigned long bandwidth, unsigned int flags);
/**
* virDomainBlockRebaseFlags:
names */
VIR_DOMAIN_BLOCK_REBASE_COPY_DEV = 1 << 5, /* Treat destination as block
device instead of file */
+ VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES = 1 << 6, /* bandwidth in bytes/s
+ instead of MiB/s */
} virDomainBlockRebaseFlags;
-int virDomainBlockRebase(virDomainPtr dom, const char *disk,
- const char *base, unsigned long bandwidth,
- unsigned int flags);
+int virDomainBlockRebase(virDomainPtr dom, const char *disk,
+ const char *base, unsigned long bandwidth,
+ unsigned int flags);
/**
* virDomainBlockCopyFlags:
VIR_DOMAIN_BLOCK_COMMIT_RELATIVE = 1 << 3, /* keep the backing chain
referenced using relative
names */
+ VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES = 1 << 4, /* bandwidth in bytes/s
+ instead of MiB/s */
} virDomainBlockCommitFlags;
int virDomainBlockCommit(virDomainPtr dom, const char *disk, const char *base,
* virDomainBlockJobSetSpeed:
* @dom: pointer to domain object
* @disk: path to the block device, or device shorthand
- * @bandwidth: specify bandwidth limit in MiB/s
- * @flags: extra flags; not used yet, so callers should always pass 0
+ * @bandwidth: specify bandwidth limit; flags determine the unit
+ * @flags: bitwise-OR of virDomainBlockJobSetSpeedFlags
*
* Set the maximimum allowable bandwidth that a block job may consume. If
- * bandwidth is 0, the limit will revert to the hypervisor default.
+ * bandwidth is 0, the limit will revert to the hypervisor default of
+ * unlimited.
+ *
+ * If @flags contains VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES, @bandwidth
+ * is in bytes/second; otherwise, it is in MiB/second. Values larger than
+ * 2^52 bytes/sec may be rejected due to overflow considerations based on
+ * the word size of both client and server, and values larger than 2^31
+ * bytes/sec may cause overflow problems if later queried by
+ * virDomainGetBlockJobInfo() without scaling. Hypervisors may further
+ * restrict the range of valid bandwidth values.
*
* The @disk parameter is either an unambiguous source name of the
* block device (the <source file='...'/> sub-element, such as
* virDomainBlockPull:
* @dom: pointer to domain object
* @disk: path to the block device, or device shorthand
- * @bandwidth: (optional) specify copy bandwidth limit in MiB/s
- * @flags: extra flags; not used yet, so callers should always pass 0
+ * @bandwidth: (optional) specify bandwidth limit; flags determine the unit
+ * @flags: bitwise-OR of virDomainBlockPullFlags
*
* Populate a disk image with data from its backing image. Once all data from
* its backing image has been pulled, the disk no longer depends on a backing
* can be found by calling virDomainGetXMLDesc() and inspecting
* elements within //domain/devices/disk.
*
- * The maximum bandwidth (in MiB/s) that will be used to do the copy can be
- * specified with the bandwidth parameter. If set to 0, libvirt will choose a
- * suitable default. Some hypervisors do not support this feature and will
- * return an error if bandwidth is not 0; in this case, it might still be
- * possible for a later call to virDomainBlockJobSetSpeed() to succeed.
- * The actual speed can be determined with virDomainGetBlockJobInfo().
+ * The maximum bandwidth that will be used to do the copy can be
+ * specified with the @bandwidth parameter. If set to 0, there is no
+ * limit. If @flags includes VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES,
+ * @bandwidth is in bytes/second; otherwise, it is in MiB/second.
+ * Values larger than 2^52 bytes/sec may be rejected due to overflow
+ * considerations based on the word size of both client and server,
+ * and values larger than 2^31 bytes/sec may cause overflow problems
+ * if later queried by virDomainGetBlockJobInfo() without scaling.
+ * Hypervisors may further restrict the range of valid bandwidth
+ * values. Some hypervisors do not support this feature and will
+ * return an error if bandwidth is not 0; in this case, it might still
+ * be possible for a later call to virDomainBlockJobSetSpeed() to
+ * succeed. The actual speed can be determined with
+ * virDomainGetBlockJobInfo().
*
* This is shorthand for virDomainBlockRebase() with a NULL base.
*
* @disk: path to the block device, or device shorthand
* @base: path to backing file to keep, or device shorthand,
* or NULL for no backing file
- * @bandwidth: (optional) specify copy bandwidth limit in MiB/s
+ * @bandwidth: (optional) specify bandwidth limit; flags determine the unit
* @flags: bitwise-OR of virDomainBlockRebaseFlags
*
* Populate a disk image with data from its backing image chain, and
* example, "vda[3]" refers to the backing store with index equal to "3"
* in the chain of disk "vda".
*
- * The maximum bandwidth (in MiB/s) that will be used to do the copy can be
- * specified with the bandwidth parameter. If set to 0, libvirt will choose a
- * suitable default. Some hypervisors do not support this feature and will
- * return an error if bandwidth is not 0; in this case, it might still be
- * possible for a later call to virDomainBlockJobSetSpeed() to succeed.
- * The actual speed can be determined with virDomainGetBlockJobInfo().
+ * The maximum bandwidth that will be used to do the copy can be
+ * specified with the @bandwidth parameter. If set to 0, there is no
+ * limit. If @flags includes VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES,
+ * @bandwidth is in bytes/second; otherwise, it is in MiB/second.
+ * Values larger than 2^52 bytes/sec may be rejected due to overflow
+ * considerations based on the word size of both client and server,
+ * and values larger than 2^31 bytes/sec may cause overflow problems
+ * if later queried by virDomainGetBlockJobInfo() without scaling.
+ * Hypervisors may further restrict the range of valid bandwidth
+ * values. Some hypervisors do not support this feature and will
+ * return an error if bandwidth is not 0; in this case, it might still
+ * be possible for a later call to virDomainBlockJobSetSpeed() to
+ * succeed. The actual speed can be determined with
+ * virDomainGetBlockJobInfo().
*
* When @base is NULL and @flags is 0, this is identical to
* virDomainBlockPull(). When @flags contains VIR_DOMAIN_BLOCK_REBASE_COPY,
* or NULL for default
* @top: path to file within backing chain that contains data to be merged,
* or device shorthand, or NULL to merge all possible data
- * @bandwidth: (optional) specify commit bandwidth limit in MiB/s
+ * @bandwidth: (optional) specify bandwidth limit; flags determine the unit
* @flags: bitwise-OR of virDomainBlockCommitFlags
*
* Commit changes that were made to temporary top-level files within a disk
* example, "vda[3]" refers to the backing store with index equal to "3"
* in the chain of disk "vda".
*
- * The maximum bandwidth (in MiB/s) that will be used to do the commit can be
- * specified with the bandwidth parameter. If set to 0, libvirt will choose a
- * suitable default. Some hypervisors do not support this feature and will
- * return an error if bandwidth is not 0; in this case, it might still be
- * possible for a later call to virDomainBlockJobSetSpeed() to succeed.
- * The actual speed can be determined with virDomainGetBlockJobInfo().
+ * The maximum bandwidth that will be used to do the commit can be
+ * specified with the @bandwidth parameter. If set to 0, there is no
+ * limit. If @flags includes VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES,
+ * @bandwidth is in bytes/second; otherwise, it is in MiB/second.
+ * Values larger than 2^52 bytes/sec may be rejected due to overflow
+ * considerations based on the word size of both client and server,
+ * and values larger than 2^31 bytes/sec may cause overflow problems
+ * if later queried by virDomainGetBlockJobInfo() without scaling.
+ * Hypervisors may further restrict the range of valid bandwidth
+ * values. Some hypervisors do not support this feature and will
+ * return an error if bandwidth is not 0; in this case, it might still
+ * be possible for a later call to virDomainBlockJobSetSpeed() to
+ * succeed. The actual speed can be determined with
+ * virDomainGetBlockJobInfo().
*
* Returns 0 if the operation has started, -1 on failure.
*/
}
}
- /* Convert bandwidth MiB to bytes */
- if (speed > LLONG_MAX >> 20) {
- virReportError(VIR_ERR_OVERFLOW,
- _("bandwidth must be less than %llu"),
- LLONG_MAX >> 20);
- goto endjob;
+ /* Convert bandwidth MiB to bytes, if needed */
+ if ((mode == BLOCK_JOB_SPEED &&
+ !(flags & VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES)) ||
+ (mode == BLOCK_JOB_PULL &&
+ !(flags & VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES))) {
+ if (speed > LLONG_MAX >> 20) {
+ virReportError(VIR_ERR_OVERFLOW,
+ _("bandwidth must be less than %llu"),
+ LLONG_MAX >> 20);
+ goto endjob;
+ }
+ speed <<= 20;
}
- speed <<= 20;
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorBlockJob(priv->mon, device, basePath, backingPath,
unsigned long bandwidth, unsigned int flags)
{
virDomainObjPtr vm;
- virCheckFlags(0, -1);
+ virCheckFlags(VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
VIR_DOMAIN_BLOCK_REBASE_COPY |
VIR_DOMAIN_BLOCK_REBASE_COPY_RAW |
VIR_DOMAIN_BLOCK_REBASE_RELATIVE |
- VIR_DOMAIN_BLOCK_REBASE_COPY_DEV, -1);
+ VIR_DOMAIN_BLOCK_REBASE_COPY_DEV |
+ VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
if (flags & VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
dest->format = VIR_STORAGE_FILE_RAW;
- /* Convert bandwidth MiB to bytes */
- if (speed > LLONG_MAX >> 20) {
- virReportError(VIR_ERR_OVERFLOW,
- _("bandwidth must be less than %llu"),
- LLONG_MAX >> 20);
- goto cleanup;
+ /* Convert bandwidth MiB to bytes, if necessary */
+ if (!(flags & VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES)) {
+ if (speed > LLONG_MAX >> 20) {
+ virReportError(VIR_ERR_OVERFLOW,
+ _("bandwidth must be less than %llu"),
+ LLONG_MAX >> 20);
+ goto cleanup;
+ }
+ speed <<= 20;
}
- speed <<= 20;
/* XXX: If we are doing a shallow copy but not reusing an external
* file, we should attempt to pre-create the destination with a
unsigned int flags)
{
virDomainObjPtr vm;
- virCheckFlags(0, -1);
+ virCheckFlags(VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
/* XXX Add support for COMMIT_DELETE */
virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW |
VIR_DOMAIN_BLOCK_COMMIT_ACTIVE |
- VIR_DOMAIN_BLOCK_COMMIT_RELATIVE, -1);
+ VIR_DOMAIN_BLOCK_COMMIT_RELATIVE |
+ VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup;
goto endjob;
}
- /* Convert bandwidth MiB to bytes */
- if (speed > LLONG_MAX >> 20) {
- virReportError(VIR_ERR_OVERFLOW,
- _("bandwidth must be less than %llu"),
- LLONG_MAX >> 20);
- goto endjob;
+ /* Convert bandwidth MiB to bytes, if necessary */
+ if (!(flags & VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES)) {
+ if (speed > LLONG_MAX >> 20) {
+ virReportError(VIR_ERR_OVERFLOW,
+ _("bandwidth must be less than %llu"),
+ LLONG_MAX >> 20);
+ goto endjob;
+ }
+ speed <<= 20;
}
- speed <<= 20;
device = qemuDiskPathToAlias(vm, path, &idx);
if (!device)