mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 15:27:47 +00:00
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:
parent
aadab51541
commit
f8d54e7c94
@ -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) {
|
||||
|
@ -179,7 +179,6 @@ int qemuBuildHostNetStr (virConnectPtr conn,
|
||||
int qemuBuildNicStr (virConnectPtr conn,
|
||||
virDomainNetDefPtr net,
|
||||
const char *prefix,
|
||||
char type_sep,
|
||||
int vlan,
|
||||
char **str);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user