virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
- char drivestr[PATH_MAX];
+ char *drivestr = NULL;
i = qemudFindDisk(vm->def, dev->data.disk->dst);
/* build the actual drive id string as the disk->info.alias doesn't
* contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
- if ((ret = snprintf(drivestr, sizeof(drivestr), "%s%s",
- QEMU_DRIVE_HOST_PREFIX,
- detach->info.alias))
- < 0 || ret >= sizeof(drivestr)) {
+ if (virAsprintf(&drivestr, "%s%s",
+ QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0) {
virReportOOMError();
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
- ret = qemuMonitorDriveUnplug(priv->mon, drivestr);
- DEBUG("DriveUnplug ret=%d", ret);
- /* ret > 0 indicates unplug isn't supported, issue will be logged */
- if (ret < 0) {
- qemuDomainObjExitMonitor(vm);
- goto cleanup;
- }
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitor(vm);
goto cleanup;
}
} else {
- ret = qemuMonitorDriveUnplug(priv->mon, drivestr);
- /* ret > 0 indicates unplug isn't supported, issue will be logged */
- if (ret < 0) {
- qemuDomainObjExitMonitor(vm);
- goto cleanup;
- }
if (qemuMonitorRemovePCIDevice(priv->mon,
&detach->info.addr.pci) < 0) {
qemuDomainObjExitMonitor(vm);
goto cleanup;
}
}
+
+ /* disconnect guest from host device */
+ qemuMonitorDriveDel(priv->mon, drivestr);
+
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0);
ret = 0;
cleanup:
+ VIR_FREE(drivestr);
return ret;
}
virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
- char drivestr[PATH_MAX];
+ char *drivestr = NULL;
i = qemudFindDisk(vm->def, dev->data.disk->dst);
/* build the actual drive id string as the disk->info.alias doesn't
* contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
- if ((ret = snprintf(drivestr, sizeof(drivestr), "%s%s",
- QEMU_DRIVE_HOST_PREFIX,
- detach->info.alias))
- < 0 || ret >= sizeof(drivestr)) {
+ if (virAsprintf(&drivestr, "%s%s",
+ QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0) {
virReportOOMError();
goto cleanup;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
- /* ret > 0 indicates unplug isn't supported, issue will be logged */
- if (qemuMonitorDriveUnplug(priv->mon, drivestr) < 0) {
- qemuDomainObjExitMonitor(vm);
- goto cleanup;
- }
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitor(vm);
goto cleanup;
}
+
+ /* disconnect guest from host device */
+ qemuMonitorDriveDel(priv->mon, drivestr);
+
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0);
ret = 0;
cleanup:
+ VIR_FREE(drivestr);
virCgroupFree(&cgroup);
return ret;
}
return ret;
}
-int qemuMonitorDriveUnplug(qemuMonitorPtr mon,
- const char *drivestr)
+int qemuMonitorDriveDel(qemuMonitorPtr mon,
+ const char *drivestr)
{
DEBUG("mon=%p drivestr=%s", mon, drivestr);
int ret;
}
if (mon->json)
- ret = qemuMonitorJSONDriveUnplug(mon, drivestr);
+ ret = qemuMonitorJSONDriveDel(mon, drivestr);
else
- ret = qemuMonitorTextDriveUnplug(mon, drivestr);
+ ret = qemuMonitorTextDriveDel(mon, drivestr);
return ret;
}
int qemuMonitorAddDrive(qemuMonitorPtr mon,
const char *drivestr);
-int qemuMonitorDriveUnplug(qemuMonitorPtr mon,
+int qemuMonitorDriveDel(qemuMonitorPtr mon,
const char *drivestr);
int qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon,
}
-int qemuMonitorJSONDriveUnplug(qemuMonitorPtr mon,
- const char *drivestr)
+int qemuMonitorJSONDriveDel(qemuMonitorPtr mon,
+ const char *drivestr)
{
int ret;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
- DEBUG("JSONDriveUnplug drivestr=%s", drivestr);
- cmd = qemuMonitorJSONMakeCommand("drive_unplug",
+ DEBUG("JSONDriveDel drivestr=%s", drivestr);
+ cmd = qemuMonitorJSONMakeCommand("drive_del",
"s:id", drivestr,
NULL);
if (!cmd)
ret = qemuMonitorJSONCommand(mon, cmd, &reply);
if (ret == 0) {
- /* See if drive_unplug isn't supported */
+ /* See if drive_del isn't supported */
if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
- VIR_ERROR0(_("unplugging disk is not supported. "
+ VIR_ERROR0(_("deleting disk is not supported. "
"This may leak data if disk is reassigned"));
ret = 1;
goto cleanup;
+ } else if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) {
+ /* NB: device not found errors mean the drive was
+ * auto-deleted and we ignore the error */
+ ret = 0;
+ } else {
+ ret = qemuMonitorJSONCheckError(cmd, reply);
}
- ret = qemuMonitorJSONCheckError(cmd, reply);
}
cleanup:
int qemuMonitorJSONAddDrive(qemuMonitorPtr mon,
const char *drivestr);
-int qemuMonitorJSONDriveUnplug(qemuMonitorPtr mon,
+int qemuMonitorJSONDriveDel(qemuMonitorPtr mon,
const char *drivestr);
int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
goto cleanup;
}
+ DEBUG("TextDelDevice devalias=%s", devalias);
if (qemuMonitorCommand(mon, cmd, &reply) < 0) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
_("cannot detach %s device"), devalias);
return ret;
}
-/* Attempts to unplug a drive. Returns 1 if unsupported, 0 if ok, and -1 on
- * other failure */
-int qemuMonitorTextDriveUnplug(qemuMonitorPtr mon,
- const char *drivestr)
+/* Attempts to remove a host drive.
+ * Returns 1 if unsupported, 0 if ok, and -1 on other failure */
+int qemuMonitorTextDriveDel(qemuMonitorPtr mon,
+ const char *drivestr)
{
char *cmd = NULL;
char *reply = NULL;
char *safedev;
int ret = -1;
- DEBUG("TextDriveUnplug drivestr=%s", drivestr);
+ DEBUG("TextDriveDel drivestr=%s", drivestr);
if (!(safedev = qemuMonitorEscapeArg(drivestr))) {
virReportOOMError();
goto cleanup;
}
- if (virAsprintf(&cmd, "drive_unplug %s", safedev) < 0) {
+ if (virAsprintf(&cmd, "drive_del %s", safedev) < 0) {
virReportOOMError();
goto cleanup;
}
if (qemuMonitorCommand(mon, cmd, &reply) < 0) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
- _("cannot unplug %s drive"), drivestr);
+ _("cannot delete %s drive"), drivestr);
goto cleanup;
}
if (strstr(reply, "unknown command:")) {
- VIR_ERROR0(_("unplugging disk is not supported. "
+ VIR_ERROR0(_("deleting drive is not supported. "
"This may leak data if disk is reassigned"));
ret = 1;
goto cleanup;
+
+ /* (qemu) drive_del wark
+ * Device 'wark' not found */
+ } else if (STRPREFIX(reply, "Device '") && (strstr(reply, "not found"))) {
+ /* NB: device not found errors mean the drive was auto-deleted and we
+ * ignore the error */
+ ret = 0;
} else if (STRNEQ(reply, "")) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
- _("unplugging %s drive failed: %s"), drivestr, reply);
+ _("deleting %s drive failed: %s"), drivestr, reply);
goto cleanup;
}
int qemuMonitorTextAddDrive(qemuMonitorPtr mon,
const char *drivestr);
-int qemuMonitorTextDriveUnplug(qemuMonitorPtr mon,
+int qemuMonitorTextDriveDel(qemuMonitorPtr mon,
const char *drivestr);
int qemuMonitorTextSetDrivePassphrase(qemuMonitorPtr mon,