blockResize: add flag for bytes

Qemu supports sizing by bytes; we shouldn't force the user to
round up if they really wanted an unaligned total size.

* include/libvirt/libvirt.h.in (VIR_DOMAIN_BLOCK_RESIZE_BYTES):
New flag.
* src/libvirt.c (virDomainBlockResize): Document it.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONBlockResize): Take
size in bytes.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextBlockResize):
Likewise.  Pass bytes, not megabytes, to monitor.
* src/qemu/qemu_driver.c (qemuDomainBlockResize): Implement new
flag.
This commit is contained in:
Eric Blake 2012-03-03 07:43:22 -07:00
parent 07dd6fb610
commit 877fd769b9
5 changed files with 41 additions and 21 deletions

View File

@ -1636,6 +1636,16 @@ int virDomainBlockPeek (virDomainPtr dom,
size_t size,
void *buffer,
unsigned int flags);
/**
* virDomainBlockResizeFlags:
*
* Flags available for virDomainBlockResize().
*/
typedef enum {
VIR_DOMAIN_BLOCK_RESIZE_BYTES = 1 << 0, /* size in bytes instead of KiB */
} virDomainBlockResizeFlags;
int virDomainBlockResize (virDomainPtr dom,
const char *disk,
unsigned long long size,

View File

@ -7601,12 +7601,15 @@ error:
* virDomainBlockResize:
* @dom: pointer to the domain object
* @disk: path to the block image, or shorthand
* @size: new size of the block image in kilobytes
* @flags: extra flags; not used yet, so callers should always pass 0
* @size: new size of the block image, see below for unit
* @flags: bitwise-OR of virDomainBlockResizeFlags
*
* Note that this call may fail if the underlying virtualization hypervisor
* does not support it. And this call requires privileged access to the
* hypervisor.
* Resize a block device of domain while the domain is running. If
* @flags is 0, then @size is in kibibytes (blocks of 1024); since
* 0.9.11, if @flags includes VIR_DOMAIN_BLOCK_RESIZE_BYTES, @size is
* in bytes instead. @size is taken directly as the new size.
* Depending on the file format, the hypervisor may round up to the
* next alignment boundary.
*
* The @disk parameter is either an unambiguous source name of the
* block device (the <source file='...'/> sub-element, such as
@ -7615,7 +7618,9 @@ error:
* can be found by calling virDomainGetXMLDesc() and inspecting
* elements within //domain/devices/disk.
*
* Resize a block device of domain while the domain is running.
* Note that this call may fail if the underlying virtualization hypervisor
* does not support it; this call requires privileged access to the
* hypervisor.
*
* Returns: 0 in case of success or -1 in case of failure.
*/

View File

@ -7348,10 +7348,10 @@ qemuGetSchedulerParameters(virDomainPtr dom,
* like LVM volumes.
*/
static int
qemuDomainBlockResize (virDomainPtr dom,
const char *path,
unsigned long long size,
unsigned int flags)
qemuDomainBlockResize(virDomainPtr dom,
const char *path,
unsigned long long size,
unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
@ -7360,7 +7360,7 @@ qemuDomainBlockResize (virDomainPtr dom,
char *device = NULL;
virDomainDiskDefPtr disk = NULL;
virCheckFlags(0, -1);
virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES, -1);
if (path[0] == '\0') {
qemuReportError(VIR_ERR_INVALID_ARG,
@ -7368,11 +7368,15 @@ qemuDomainBlockResize (virDomainPtr dom,
return -1;
}
if (size > ULLONG_MAX / 1024) {
qemuReportError(VIR_ERR_INVALID_ARG,
_("size must be less than %llu"),
ULLONG_MAX / 1024);
return -1;
/* We prefer operating on bytes. */
if ((flags & VIR_DOMAIN_BLOCK_RESIZE_BYTES) == 0) {
if (size > ULLONG_MAX / 1024) {
qemuReportError(VIR_ERR_INVALID_ARG,
_("size must be less than %llu"),
ULLONG_MAX / 1024);
return -1;
}
size *= 1024;
}
qemuDriverLock(driver);

View File

@ -1783,7 +1783,8 @@ cleanup:
return ret;
}
/* Return 0 on success, -1 on failure, or -2 if not supported. */
/* Return 0 on success, -1 on failure, or -2 if not supported. Size
* is in bytes. */
int qemuMonitorJSONBlockResize(qemuMonitorPtr mon,
const char *device,
unsigned long long size)
@ -1794,7 +1795,7 @@ int qemuMonitorJSONBlockResize(qemuMonitorPtr mon,
cmd = qemuMonitorJSONMakeCommand("block_resize",
"s:device", device,
"U:size", size * 1024,
"U:size", size,
NULL);
if (!cmd)
return -1;

View File

@ -1097,7 +1097,8 @@ int qemuMonitorTextGetBlockExtent(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
return -1;
}
/* Return 0 on success, -1 on failure, or -2 if not supported. */
/* Return 0 on success, -1 on failure, or -2 if not supported. Size
* is in bytes. */
int qemuMonitorTextBlockResize(qemuMonitorPtr mon,
const char *device,
unsigned long long size)
@ -1106,8 +1107,7 @@ int qemuMonitorTextBlockResize(qemuMonitorPtr mon,
char *reply = NULL;
int ret = -1;
if (virAsprintf(&cmd, "block_resize %s %llu",
device, VIR_DIV_UP(size, 1024)) < 0) {
if (virAsprintf(&cmd, "block_resize %s %lluB", device, size) < 0) {
virReportOOMError();
goto cleanup;
}