mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-25 22:15:20 +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,
|
qemuBuildNicStr(virConnectPtr conn,
|
||||||
virDomainNetDefPtr net,
|
virDomainNetDefPtr net,
|
||||||
const char *prefix,
|
const char *prefix,
|
||||||
char type_sep,
|
|
||||||
int vlan,
|
int vlan,
|
||||||
char **str)
|
char **str)
|
||||||
{
|
{
|
||||||
if (virAsprintf(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 : "",
|
prefix ? prefix : "",
|
||||||
type_sep,
|
|
||||||
net->mac[0], net->mac[1],
|
net->mac[0], net->mac[1],
|
||||||
net->mac[2], net->mac[3],
|
net->mac[2], net->mac[3],
|
||||||
net->mac[4], net->mac[5],
|
net->mac[4], net->mac[5],
|
||||||
@ -1988,7 +1986,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
qemuAssignNetNames(def, net) < 0)
|
qemuAssignNetNames(def, net) < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
if (qemuBuildNicStr(conn, net, NULL, ',', net->vlan, &nic) < 0)
|
if (qemuBuildNicStr(conn, net, "nic,", net->vlan, &nic) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if ((qargv[qargc++] = strdup("-net")) == NULL) {
|
if ((qargv[qargc++] = strdup("-net")) == NULL) {
|
||||||
|
@ -179,7 +179,6 @@ int qemuBuildHostNetStr (virConnectPtr conn,
|
|||||||
int qemuBuildNicStr (virConnectPtr conn,
|
int qemuBuildNicStr (virConnectPtr conn,
|
||||||
virDomainNetDefPtr net,
|
virDomainNetDefPtr net,
|
||||||
const char *prefix,
|
const char *prefix,
|
||||||
char type_sep,
|
|
||||||
int vlan,
|
int vlan,
|
||||||
char **str);
|
char **str);
|
||||||
|
|
||||||
|
@ -4478,72 +4478,6 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
|
|||||||
return ret;
|
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,
|
static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
@ -4621,7 +4555,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
|
|||||||
char *cmd = NULL, *reply = NULL, *remove_cmd = NULL;
|
char *cmd = NULL, *reply = NULL, *remove_cmd = NULL;
|
||||||
char *tapfd_name = NULL;
|
char *tapfd_name = NULL;
|
||||||
int i, tapfd = -1;
|
int i, tapfd = -1;
|
||||||
unsigned domain, bus, slot;
|
char *nicstr = NULL;
|
||||||
|
|
||||||
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_HOST_NET_ADD)) {
|
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_HOST_NET_ADD)) {
|
||||||
qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
|
qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
|
||||||
@ -4693,30 +4627,18 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
|
|||||||
close(tapfd);
|
close(tapfd);
|
||||||
tapfd = -1;
|
tapfd = -1;
|
||||||
|
|
||||||
if (qemuBuildNicStr(conn, net,
|
if (qemuBuildNicStr(conn, net, NULL, net->vlan, &nicstr) < 0)
|
||||||
"pci_add pci_addr=auto ", ' ', net->vlan, &cmd) < 0)
|
|
||||||
goto try_remove;
|
goto try_remove;
|
||||||
|
|
||||||
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
|
if (qemuMonitorAddPCINetwork(vm, nicstr,
|
||||||
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
&net->pci_addr.domain,
|
||||||
_("failed to add NIC with '%s'"), cmd);
|
&net->pci_addr.bus,
|
||||||
|
&net->pci_addr.slot) < 0)
|
||||||
goto try_remove;
|
goto try_remove;
|
||||||
}
|
|
||||||
|
|
||||||
if (qemudParsePciAddReply(vm, reply, &domain, &bus, &slot) < 0) {
|
VIR_FREE(nicstr);
|
||||||
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(remove_cmd);
|
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;
|
vm->def->nets[vm->def->nnets++] = net;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -4744,6 +4666,7 @@ try_tapfd_close:
|
|||||||
no_memory:
|
no_memory:
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
cleanup:
|
cleanup:
|
||||||
|
VIR_FREE(nicstr);
|
||||||
VIR_FREE(cmd);
|
VIR_FREE(cmd);
|
||||||
VIR_FREE(reply);
|
VIR_FREE(reply);
|
||||||
VIR_FREE(remove_cmd);
|
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,
|
int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm,
|
||||||
unsigned guestDomain,
|
unsigned guestDomain,
|
||||||
|
@ -170,6 +170,15 @@ int qemuMonitorAddPCIDisk(const virDomainObjPtr vm,
|
|||||||
unsigned *guestBus,
|
unsigned *guestBus,
|
||||||
unsigned *guestSlot);
|
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,
|
int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm,
|
||||||
unsigned guestDomain,
|
unsigned guestDomain,
|
||||||
unsigned guestBus,
|
unsigned guestBus,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user