Add API for issuing 'pci_add nic' monitor command

* src/qemu/qemu_conf.c: Remove separator from qemuBuildNicStr()
  args, and remove hardcoded 'nic' prefix. Leave it upto callers
  instead
* src/qemu/qemu_driver.c: Switch over to using the new
  qemuMonitorAddPCINetwork() method for NIC hotplug
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorAddPCINetwork API for PCI network device hotplug
This commit is contained in:
Daniel P. Berrange 2009-09-23 17:01:39 +01:00
parent aadab51541
commit f8d54e7c94
5 changed files with 55 additions and 90 deletions

View File

@ -1263,14 +1263,12 @@ int
qemuBuildNicStr(virConnectPtr conn,
virDomainNetDefPtr net,
const char *prefix,
char type_sep,
int vlan,
char **str)
{
if (virAsprintf(str,
"%snic%cmacaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s%s%s",
"%smacaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s%s%s",
prefix ? prefix : "",
type_sep,
net->mac[0], net->mac[1],
net->mac[2], net->mac[3],
net->mac[4], net->mac[5],
@ -1988,7 +1986,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
qemuAssignNetNames(def, net) < 0)
goto no_memory;
if (qemuBuildNicStr(conn, net, NULL, ',', net->vlan, &nic) < 0)
if (qemuBuildNicStr(conn, net, "nic,", net->vlan, &nic) < 0)
goto error;
if ((qargv[qargc++] = strdup("-net")) == NULL) {

View File

@ -179,7 +179,6 @@ int qemuBuildHostNetStr (virConnectPtr conn,
int qemuBuildNicStr (virConnectPtr conn,
virDomainNetDefPtr net,
const char *prefix,
char type_sep,
int vlan,
char **str);

View File

@ -4478,72 +4478,6 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
return ret;
}
static int
qemudParsePciAddReply(virDomainObjPtr vm,
const char *reply,
unsigned *domain,
unsigned *bus,
unsigned *slot)
{
char *s, *e;
DEBUG("%s: pci_add reply: %s", vm->def->name, reply);
/* If the command succeeds qemu prints:
* OK bus 0, slot XXX...
* or
* OK domain 0, bus 0, slot XXX
*/
if (!(s = strstr(reply, "OK ")))
return -1;
s += 3;
if (STRPREFIX(s, "domain ")) {
s += strlen("domain ");
if (virStrToLong_ui(s, &e, 10, domain) == -1) {
VIR_WARN(_("Unable to parse domain number '%s'\n"), s);
return -1;
}
if (!STRPREFIX(e, ", ")) {
VIR_WARN(_("Expected ', ' parsing pci_add reply '%s'\n"), s);
return -1;
}
s = e + 2;
}
if (!STRPREFIX(s, "bus ")) {
VIR_WARN(_("Expected 'bus ' parsing pci_add reply '%s'\n"), s);
return -1;
}
s += strlen("bus ");
if (virStrToLong_ui(s, &e, 10, bus) == -1) {
VIR_WARN(_("Unable to parse bus number '%s'\n"), s);
return -1;
}
if (!STRPREFIX(e, ", ")) {
VIR_WARN(_("Expected ', ' parsing pci_add reply '%s'\n"), s);
return -1;
}
s = e + 2;
if (!STRPREFIX(s, "slot ")) {
VIR_WARN(_("Expected 'slot ' parsing pci_add reply '%s'\n"), s);
return -1;
}
s += strlen("slot ");
if (virStrToLong_ui(s, &e, 10, slot) == -1) {
VIR_WARN(_("Unable to parse slot number '%s'\n"), s);
return -1;
}
return 0;
}
static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
virDomainObjPtr vm,
@ -4621,7 +4555,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
char *cmd = NULL, *reply = NULL, *remove_cmd = NULL;
char *tapfd_name = NULL;
int i, tapfd = -1;
unsigned domain, bus, slot;
char *nicstr = NULL;
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_HOST_NET_ADD)) {
qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
@ -4693,30 +4627,18 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
close(tapfd);
tapfd = -1;
if (qemuBuildNicStr(conn, net,
"pci_add pci_addr=auto ", ' ', net->vlan, &cmd) < 0)
if (qemuBuildNicStr(conn, net, NULL, net->vlan, &nicstr) < 0)
goto try_remove;
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to add NIC with '%s'"), cmd);
if (qemuMonitorAddPCINetwork(vm, nicstr,
&net->pci_addr.domain,
&net->pci_addr.bus,
&net->pci_addr.slot) < 0)
goto try_remove;
}
if (qemudParsePciAddReply(vm, reply, &domain, &bus, &slot) < 0) {
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("parsing pci_add reply failed: %s"), reply);
goto try_remove;
}
VIR_FREE(cmd);
VIR_FREE(reply);
VIR_FREE(nicstr);
VIR_FREE(remove_cmd);
net->pci_addr.domain = domain;
net->pci_addr.bus = bus;
net->pci_addr.slot = slot;
vm->def->nets[vm->def->nnets++] = net;
return 0;
@ -4744,6 +4666,7 @@ try_tapfd_close:
no_memory:
virReportOOMError(conn);
cleanup:
VIR_FREE(nicstr);
VIR_FREE(cmd);
VIR_FREE(reply);
VIR_FREE(remove_cmd);

View File

@ -1492,6 +1492,42 @@ cleanup:
}
int qemuMonitorAddPCINetwork(const virDomainObjPtr vm,
const char *nicstr,
unsigned *guestDomain,
unsigned *guestBus,
unsigned *guestSlot)
{
char *cmd;
char *reply = NULL;
int ret = -1;
if (virAsprintf(&cmd, "pci_add pci_addr=auto nic %s", nicstr) < 0) {
virReportOOMError(NULL);
return -1;
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to add NIC with '%s'"), cmd);
goto cleanup;
}
if (qemuMonitorParsePciAddReply(vm, reply,
guestDomain, guestBus, guestSlot) < 0) {
qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("parsing pci_add reply failed: %s"), reply);
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(reply);
VIR_FREE(cmd);
return ret;
}
int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm,
unsigned guestDomain,

View File

@ -170,6 +170,15 @@ int qemuMonitorAddPCIDisk(const virDomainObjPtr vm,
unsigned *guestBus,
unsigned *guestSlot);
/* XXX do we really want to hardcode 'nicstr' as the
* sendable item here
*/
int qemuMonitorAddPCINetwork(const virDomainObjPtr vm,
const char *nicstr,
unsigned *guestDomain,
unsigned *guestBus,
unsigned *guestSlot);
int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm,
unsigned guestDomain,
unsigned guestBus,