Add API for issuing 'pci_add storage' monitor command

* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  API qemuMonitorAddPCIDisk()
* src/qemu/qemu_driver.c: Convert over to using the new
  qemuMonitorAddPCIDisk() method, and remove now obsolete
  qemudEscape() method
This commit is contained in:
Daniel P. Berrange 2009-09-23 16:38:44 +01:00
parent 3e11f9ff90
commit 85df93399c
3 changed files with 76 additions and 123 deletions

View File

@ -3093,83 +3093,6 @@ cleanup:
}
static char *qemudEscape(const char *in, int shell)
{
int len = 0;
int i, j;
char *out;
/* To pass through the QEMU monitor, we need to use escape
sequences: \r, \n, \", \\
To pass through both QEMU + the shell, we need to escape
the single character ' as the five characters '\\''
*/
for (i = 0; in[i] != '\0'; i++) {
switch(in[i]) {
case '\r':
case '\n':
case '"':
case '\\':
len += 2;
break;
case '\'':
if (shell)
len += 5;
else
len += 1;
break;
default:
len += 1;
break;
}
}
if (VIR_ALLOC_N(out, len + 1) < 0)
return NULL;
for (i = j = 0; in[i] != '\0'; i++) {
switch(in[i]) {
case '\r':
out[j++] = '\\';
out[j++] = 'r';
break;
case '\n':
out[j++] = '\\';
out[j++] = 'n';
break;
case '"':
case '\\':
out[j++] = '\\';
out[j++] = in[i];
break;
case '\'':
if (shell) {
out[j++] = '\'';
out[j++] = '\\';
out[j++] = '\\';
out[j++] = '\'';
out[j++] = '\'';
} else {
out[j++] = in[i];
}
break;
default:
out[j++] = in[i];
break;
}
}
out[j] = '\0';
return out;
}
static char *qemudEscapeMonitorArg(const char *in)
{
return qemudEscape(in, 0);
}
#define QEMUD_SAVE_MAGIC "LibvirtQemudSave"
#define QEMUD_SAVE_VERSION 2
@ -4626,12 +4549,8 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
{
int ret, i;
char *cmd, *reply;
char *safe_path;
int i;
const char* type = virDomainDiskBusTypeToString(dev->data.disk->bus);
int tryOldSyntax = 0;
unsigned domain, bus, slot;
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
@ -4646,48 +4565,13 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
return -1;
}
try_command:
safe_path = qemudEscapeMonitorArg(dev->data.disk->src);
if (!safe_path) {
virReportOOMError(conn);
if (qemuMonitorAddPCIDisk(vm,
dev->data.disk->src,
type,
&dev->data.disk->pci_addr.domain,
&dev->data.disk->pci_addr.bus,
&dev->data.disk->pci_addr.slot) < 0)
return -1;
}
ret = virAsprintf(&cmd, "pci_add %s storage file=%s,if=%s",
(tryOldSyntax ? "0": "pci_addr=auto"), safe_path, type);
VIR_FREE(safe_path);
if (ret == -1) {
virReportOOMError(conn);
return ret;
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("cannot attach %s disk"), type);
VIR_FREE(cmd);
return -1;
}
VIR_FREE(cmd);
if (qemudParsePciAddReply(vm, reply, &domain, &bus, &slot) < 0) {
if (!tryOldSyntax && strstr(reply, "invalid char in expression")) {
VIR_FREE(reply);
tryOldSyntax = 1;
goto try_command;
}
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("adding %s disk failed: %s"), type, reply);
VIR_FREE(reply);
return -1;
}
VIR_FREE(reply);
dev->data.disk->pci_addr.domain = domain;
dev->data.disk->pci_addr.bus = bus;
dev->data.disk->pci_addr.slot = slot;
virDomainDiskInsertPreAlloced(vm->def, dev->data.disk);

View File

@ -1437,6 +1437,62 @@ cleanup:
}
int qemuMonitorAddPCIDisk(const virDomainObjPtr vm,
const char *path,
const char *bus,
unsigned *guestDomain,
unsigned *guestBus,
unsigned *guestSlot) {
char *cmd = NULL;
char *reply = NULL;
char *safe_path = NULL;
int tryOldSyntax = 0;
int ret = -1;
safe_path = qemudEscapeMonitorArg(path);
if (!safe_path) {
virReportOOMError(NULL);
return -1;
}
try_command:
if (virAsprintf(&cmd, "pci_add %s storage file=%s,if=%s",
(tryOldSyntax ? "0": "pci_addr=auto"), safe_path, bus) < 0) {
virReportOOMError(NULL);
goto cleanup;
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("cannot attach %s disk %s"), bus, path);
goto cleanup;
}
if (qemuMonitorParsePciAddReply(vm, reply,
guestDomain, guestBus, guestSlot) < 0) {
if (!tryOldSyntax && strstr(reply, "invalid char in expression")) {
VIR_FREE(reply);
VIR_FREE(cmd);
tryOldSyntax = 1;
goto try_command;
}
qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("adding %s disk failed %s: %s"), bus, path, reply);
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(safe_path);
VIR_FREE(cmd);
VIR_FREE(reply);
return ret;
}
int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm,
unsigned guestDomain,
unsigned guestBus,

View File

@ -137,6 +137,9 @@ int qemuMonitorMigrateToCommand(const virDomainObjPtr vm,
const char *target);
/* XXX disk driver type eg, qcow/etc.
* XXX cache mode
*/
int qemuMonitorAddUSBDisk(const virDomainObjPtr vm,
const char *path);
@ -157,6 +160,16 @@ int qemuMonitorAddPCIHostDevice(const virDomainObjPtr vm,
unsigned *guestBus,
unsigned *guestSlot);
/* XXX disk driver type eg, qcow/etc.
* XXX cache mode
*/
int qemuMonitorAddPCIDisk(const virDomainObjPtr vm,
const char *path,
const char *bus,
unsigned *guestDomain,
unsigned *guestBus,
unsigned *guestSlot);
int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm,
unsigned guestDomain,
unsigned guestBus,