diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 32a5ba17436672dd7f9e660cb84afaa8c237d654..6f7a59d8f8784de18c86b574ef65ea383210a086 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -8289,114 +8289,6 @@ cleanup: return ret; } -static const char * -qemuDiskPathToAlias(virDomainObjPtr vm, const char *path) { - int i; - char *ret = NULL; - - for (i = 0 ; i < vm->def->ndisks ; i++) { - virDomainDiskDefPtr disk = vm->def->disks[i]; - - if (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK && - disk->type != VIR_DOMAIN_DISK_TYPE_FILE) - continue; - - if (disk->src != NULL && STREQ(disk->src, path)) { - if (virAsprintf(&ret, "drive-%s", disk->info.alias) < 0) { - virReportOOMError(); - return NULL; - } - break; - } - } - - if (!ret) { - qemuReportError(VIR_ERR_INVALID_ARG, - "%s", _("No device found for specified path")); - } - return ret; -} - -static int -qemuDomainBlockPullImpl(virDomainPtr dom, const char *path, - virDomainBlockPullInfoPtr info, - int mode) -{ - struct qemud_driver *driver = dom->conn->privateData; - virDomainObjPtr vm = NULL; - qemuDomainObjPrivatePtr priv; - char uuidstr[VIR_UUID_STRING_BUFLEN]; - const char *device = NULL; - int ret = -1; - - qemuDriverLock(driver); - virUUIDFormat(dom->uuid, uuidstr); - vm = virDomainFindByUUID(&driver->domains, dom->uuid); - if (!vm) { - qemuReportError(VIR_ERR_NO_DOMAIN, - _("no domain with matching uuid '%s'"), uuidstr); - goto cleanup; - } - - if (!virDomainObjIsActive(vm)) { - qemuReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("domain is not running")); - goto cleanup; - } - - device = qemuDiskPathToAlias(vm, path); - if (!device) { - goto cleanup; - } - - if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) - goto cleanup; - qemuDomainObjEnterMonitorWithDriver(driver, vm); - priv = vm->privateData; - ret = qemuMonitorBlockPull(priv->mon, device, info, mode); - qemuDomainObjExitMonitorWithDriver(driver, vm); - if (qemuDomainObjEndJob(vm) == 0) { - vm = NULL; - goto cleanup; - } - -cleanup: - VIR_FREE(device); - if (vm) - virDomainObjUnlock(vm); - qemuDriverUnlock(driver); - return ret; -} - -static int -qemuDomainBlockPull(virDomainPtr dom, const char *path, - virDomainBlockPullInfoPtr info, unsigned int flags) -{ - virCheckFlags(0, -1); - return qemuDomainBlockPullImpl(dom, path, info, BLOCK_PULL_MODE_ONE); -} - -static int -qemuDomainBlockPullAll(virDomainPtr dom, const char *path, unsigned int flags) -{ - virCheckFlags(0, -1); - return qemuDomainBlockPullImpl(dom, path, NULL, BLOCK_PULL_MODE_ALL); -} - -static int -qemuDomainBlockPullAbort(virDomainPtr dom, const char *path, unsigned int flags) -{ - virCheckFlags(0, -1); - return qemuDomainBlockPullImpl(dom, path, NULL, BLOCK_PULL_MODE_ABORT); -} - -static int -qemuDomainGetBlockPullInfo(virDomainPtr dom, const char *path, - virDomainBlockPullInfoPtr info, unsigned int flags) -{ - virCheckFlags(0, -1); - return qemuDomainBlockPullImpl(dom, path, info, BLOCK_PULL_MODE_INFO); -} static virDriver qemuDriver = { .no = VIR_DRV_QEMU, @@ -8521,10 +8413,6 @@ static virDriver qemuDriver = { .domainMigratePerform3 = qemuDomainMigratePerform3, /* 0.9.2 */ .domainMigrateFinish3 = qemuDomainMigrateFinish3, /* 0.9.2 */ .domainMigrateConfirm3 = qemuDomainMigrateConfirm3, /* 0.9.2 */ - .domainBlockPull = qemuDomainBlockPull, /* 0.9.3 */ - .domainBlockPullAll = qemuDomainBlockPullAll, /* 0.9.3 */ - .domainBlockPullAbort = qemuDomainBlockPullAbort, /* 0.9.3 */ - .domainGetBlockPullInfo = qemuDomainGetBlockPullInfo, /* 0.9.3 */ }; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 5e55d5173efd50ae6599f5fbc1f8fadb4a7f16a8..e995d978148f1dd6b5ef4a460a0817f1797f2e5f 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2395,19 +2395,3 @@ int qemuMonitorScreendump(qemuMonitorPtr mon, ret = qemuMonitorTextScreendump(mon, file); return ret; } - -int qemuMonitorBlockPull(qemuMonitorPtr mon, - const char *path, - virDomainBlockPullInfoPtr info, - int mode) -{ - int ret; - - VIR_DEBUG("mon=%p, path=%p, info=%p, mode=%i", mon, path, info, mode); - - if (mon->json) - ret = qemuMonitorJSONBlockPull(mon, path, info, mode); - else - ret = qemuMonitorTextBlockPull(mon, path, info, mode); - return ret; -} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index b172e20e399d677c689981dbd543c4a03da011c6..cb8f799e079ba04867c6e73f583beb055cdd4ee6 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -442,19 +442,6 @@ int qemuMonitorInjectNMI(qemuMonitorPtr mon); int qemuMonitorScreendump(qemuMonitorPtr mon, const char *file); -typedef enum { - BLOCK_PULL_MODE_ONE = 0, - BLOCK_PULL_MODE_ALL = 1, - BLOCK_PULL_MODE_ABORT = 2, - BLOCK_PULL_MODE_INFO = 3, -} BLOCK_PULL_MODE; - - -int qemuMonitorBlockPull(qemuMonitorPtr mon, - const char *path, - virDomainBlockPullInfoPtr info, - int mode); - /** * When running two dd process and using <> redirection, we need a * shell that will not truncate files. These two strings serve that diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 320a41f6b928bead1d8757d9c6f52789919b92c4..7d286d8f24455b523fe972c9b2042e50af2c1035 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2672,134 +2672,3 @@ int qemuMonitorJSONScreendump(qemuMonitorPtr mon, virJSONValueFree(reply); return ret; } - -static int qemuMonitorJSONGetBlockPullInfoOne(virJSONValuePtr entry, - const char *device, - virDomainBlockPullInfoPtr info) -{ - const char *this_dev; - - if ((this_dev = virJSONValueObjectGetString(entry, "device")) == NULL) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("entry was missing 'device'")); - return -1; - } - if (!STREQ(this_dev, device)) - return -1; - - if (virJSONValueObjectGetNumberUlong(entry, "offset", &info->cur) < 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("entry was missing 'offset'")); - return -1; - } - - if (virJSONValueObjectGetNumberUlong(entry, "len", &info->end) < 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("entry was missing 'len'")); - return -1; - } - return 0; -} - -/** qemuMonitorJSONGetBlockPullInfo: - * Parse Block Pull information. - * The reply can be a JSON array of objects or just an object. - */ -static int qemuMonitorJSONGetBlockPullInfo(virJSONValuePtr reply, - const char *device, - virDomainBlockPullInfoPtr info) -{ - virJSONValuePtr data; - int nr_results, i = 0; - - if (!info) - return -1; - - if ((data = virJSONValueObjectGet(reply, "return")) == NULL) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("reply was missing block_pull progress information")); - return -1; - } - - if (data->type == VIR_JSON_TYPE_OBJECT) { - if (qemuMonitorJSONGetBlockPullInfoOne(data, device, info) != 0) - goto not_found; - else - return 0; - } else if (data->type != VIR_JSON_TYPE_ARRAY) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("urecognized format of block pull information")); - return -1; - } - - if ((nr_results = virJSONValueArraySize(data)) < 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("unable to determine array size")); - return -1; - } - - for (i = 0; i < nr_results; i++) { - virJSONValuePtr entry = virJSONValueArrayGet(data, i); - if (qemuMonitorJSONGetBlockPullInfoOne(entry, device, info) == 0) - return 0; - } - -not_found: - qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("No associated information for the specified disk")); - return -1; -} - - -int qemuMonitorJSONBlockPull(qemuMonitorPtr mon, - const char *device, - virDomainBlockPullInfoPtr info, - int mode) -{ - int ret = -1; - virJSONValuePtr cmd = NULL; - virJSONValuePtr reply = NULL; - int parse_info = 0; - - if (mode == BLOCK_PULL_MODE_ONE) { - cmd = qemuMonitorJSONMakeCommand("block_stream", "s:device", device, NULL); - parse_info = 1; - } else if (mode == BLOCK_PULL_MODE_ALL) { - cmd = qemuMonitorJSONMakeCommand("block_stream", "s:device", device, - "b:all", 1, NULL); - } else if (mode == BLOCK_PULL_MODE_ABORT) { - cmd = qemuMonitorJSONMakeCommand("block_stream", "s:device", device, - "b:stop", 1, NULL); - } else if (mode == BLOCK_PULL_MODE_INFO) { - cmd = qemuMonitorJSONMakeCommand("query-block-stream", NULL); - parse_info = 1; - } - - if (!cmd) - return -1; - - ret = qemuMonitorJSONCommand(mon, cmd, &reply); - - if (ret == 0 && virJSONValueObjectHasKey(reply, "error")) { - if (qemuMonitorJSONHasError(reply, "DeviceNotActive")) - qemuReportError(VIR_ERR_OPERATION_INVALID, - _("No active operation on device: %s"), device); - else if (qemuMonitorJSONHasError(reply, "DeviceInUse")) - qemuReportError(VIR_ERR_OPERATION_FAILED, - _("Device %s in use"), device); - else if (qemuMonitorJSONHasError(reply, "NotSupported")) - qemuReportError(VIR_ERR_OPERATION_INVALID, - _("Operation is not supported for device: %s"), device); - else - qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Unexpected error")); - ret = -1; - } - - if (ret == 0 && parse_info) - ret = qemuMonitorJSONGetBlockPullInfo(reply, device, info); - - virJSONValueFree(cmd); - virJSONValueFree(reply); - return ret; -} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index a72bf7c6b4efd408633de0e74880a19da3893acb..c571adb8d38ec7b733993a25f36b62469717b2d6 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -218,9 +218,5 @@ int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon); int qemuMonitorJSONScreendump(qemuMonitorPtr mon, const char *file); -int qemuMonitorJSONBlockPull(qemuMonitorPtr mon, - const char *device, - virDomainBlockPullInfoPtr info, - int mode); #endif /* QEMU_MONITOR_JSON_H */ diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 67333aaee131b3da570b17f24e3118bf75dbe8eb..aa5d1c6eb84c1b111abf1aae76fde552bfe903f4 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -2763,159 +2763,3 @@ cleanup: VIR_FREE(cmd); return ret; } - -static int qemuMonitorTextParseBlockPullOne(const char *text, - const char *device, - virDomainBlockPullInfoPtr info, - const char **next) -{ - virDomainBlockPullInfo tmp; - char *p; - int mismatch = 0; - - if (next == NULL) - return -1; - *next = NULL; - - /* - * Each active stream will appear on its own line in the following format: - * Streaming device : Completed of bytes - */ - if ((text = STRSKIP(text, "Streaming device ")) == NULL) - return -EINVAL; - - if (!STREQLEN(text, device, strlen(device))) - mismatch = 1; - - if ((text = strstr(text, ": Completed ")) == NULL) - return -EINVAL; - text += 11; - - if (virStrToLong_ull (text, &p, 10, &tmp.cur)) - return -EINVAL; - text = p; - - if (!STRPREFIX(text, " of ")) - return -EINVAL; - text += 4; - - if (virStrToLong_ull (text, &p, 10, &tmp.end)) - return -EINVAL; - text = p; - - if (!STRPREFIX(text, " bytes")) - return -EINVAL; - - if (mismatch) { - *next = STRSKIP(text, "\n"); - return -EAGAIN; - } - - if (info) { - info->cur = tmp.cur; - info->end = tmp.end; - } - return 0; -} - -static int qemuMonitorTextParseBlockPull(const char *text, - const char *device, - virDomainBlockPullInfoPtr info) -{ - const char *next = NULL; - int ret = 0; - - /* Check error: Device not found */ - if (strstr(text, "Device '") && strstr(text, "' not found")) { - qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Device not found")); - return -1; - } - - /* Check error: Already streaming this device */ - if (strstr(text, "Device '") && strstr(text, "' is in use")) { - qemuReportError(VIR_ERR_OPERATION_FAILED, _("Device %s in use"), - device); - return -1; - } - - /* Check error: Stop non-existent stream */ - if (strstr(text, "has not been activated")) { - qemuReportError(VIR_ERR_OPERATION_INVALID,\ - _("No active operation on device: %s"), device); - return -1; - } - - /* - * Check: No active streams when calling info block_stream - * This is not an error condition, there are just no results to report. - */ - if (strstr(text, "No active stream")) { - return -1; - } - - /* Check for unsupported operation */ - if (strstr(text, "Operation is not supported")) { - qemuReportError(VIR_ERR_OPERATION_INVALID, - _("Operation is not supported for device: %s"), device); - return -1; - } - - /* No output indicates success for BlockPullAll and BlockPullAbort */ - if (STREQ(text, "")) - return 0; - - /* Now try to parse lines of block_stream output */ - do { - ret = qemuMonitorTextParseBlockPullOne(text, device, info, &next); - text = next; - } while (text && ret == -EAGAIN); - - if (ret != 0) { - qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("No associated information for the specified disk")); - ret = -1; - } - return ret; -} - -int qemuMonitorTextBlockPull(qemuMonitorPtr mon, - const char *device, - virDomainBlockPullInfoPtr info, - int mode) -{ - char *cmd = NULL; - char *reply = NULL; - int ret; - - if (mode == BLOCK_PULL_MODE_ONE) - ret = virAsprintf(&cmd, "block_stream %s", device); - else if (mode == BLOCK_PULL_MODE_ALL) - ret = virAsprintf(&cmd, "block_stream -a %s", device); - else if (mode == BLOCK_PULL_MODE_ABORT) - ret = virAsprintf(&cmd, "block_stream -s %s", device); - else if (mode == BLOCK_PULL_MODE_INFO) - ret = virAsprintf(&cmd, "info block_stream"); - else - return -1; - - if (ret < 0) { - virReportOOMError(); - return -1; - } - - ret = 0; - if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot run monitor command")); - ret = -1; - goto cleanup; - } - - if (qemuMonitorTextParseBlockPull(reply, device, info) != 0) - ret = -1; - -cleanup: - VIR_FREE(cmd); - VIR_FREE(reply); - return ret; -} diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 75365574232c09d26dd4ec5c885fde44c040696e..2d9288f50c8fd446a800918c75e0939258734883 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -211,9 +211,4 @@ int qemuMonitorTextInjectNMI(qemuMonitorPtr mon); int qemuMonitorTextScreendump(qemuMonitorPtr mon, const char *file); -int qemuMonitorTextBlockPull(qemuMonitorPtr mon, - const char *device, - virDomainBlockPullInfoPtr info, - int mode); - #endif /* QEMU_MONITOR_TEXT_H */