Re: [libvirt] [RFC 4/7] qemu-agent: add qemuAgentCreateBond interface

2015-05-19 Thread Michael S. Tsirkin
On Fri, Apr 17, 2015 at 04:53:06PM +0800, Chen Fan wrote:
 via initialize callback to create bond device.
 
 Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com
 ---
  src/qemu/qemu_agent.c   | 118 
 
  src/qemu/qemu_agent.h   |  10 
  src/qemu/qemu_domain.c  |  70 
  src/qemu/qemu_domain.h  |   7 +++
  src/qemu/qemu_process.c |   4 ++
  5 files changed, 209 insertions(+)
 
 diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
 index cee0f8b..b8eba01 100644
 --- a/src/qemu/qemu_agent.c
 +++ b/src/qemu/qemu_agent.c
 @@ -2169,3 +2169,121 @@ qemuAgentGetInterfaces(qemuAgentPtr mon,
  
  goto cleanup;
  }
 +
 +static virDomainInterfacePtr
 +findInterfaceByMac(virDomainInterfacePtr *info,
 +   size_t len,
 +   const char *macstr)
 +{
 +size_t i;
 +bool found = false;
 +
 +for (i = 0; i  len; i++) {
 +if (info[i]-hwaddr 
 +STREQ(info[i]-hwaddr, macstr)) {
 +found = true;
 +break;
 +}
 +}
 +
 +if (found) {
 +return info[i];
 +}
 +
 +return NULL;
 +}
 +

I think PCI addresses are a better way to identify the devices
for this purpose. This will mean softmac doesn't break this
functionality.
See anything wrong with it?


 +/*
 + * qemuAgentSetInterface:
 + */
 +int
 +qemuAgentCreateBond(qemuAgentPtr mon,
 +virDomainHostdevSubsysPCIPtr pcisrc)
 +{
 +int ret = -1;
 +virJSONValuePtr cmd = NULL;
 +virJSONValuePtr reply = NULL;
 +size_t i;
 +char macstr[VIR_MAC_STRING_BUFLEN];
 +virDomainInterfacePtr *interfaceInfo = NULL;
 +virDomainInterfacePtr interface;
 +virJSONValuePtr new_interface = NULL;
 +virJSONValuePtr subInterfaces = NULL;
 +virJSONValuePtr subInterface = NULL;
 +int len;
 +
 +if (!(pcisrc-nmac || pcisrc-macs))
 +return ret;
 +
 +len = qemuAgentGetInterfaces(mon, interfaceInfo);
 +if (len  0)
 +return ret;
 +
 +if (!(new_interface = virJSONValueNewObject()))
 +goto cleanup;
 +
 +if (virJSONValueObjectAppendString(new_interface, type, bond)  0)
 +goto cleanup;
 +
 +if (virJSONValueObjectAppendString(new_interface, name, bond0)  0)
 +goto cleanup;
 +
 +if (virJSONValueObjectAppendString(new_interface, onboot, onboot)  
 0)
 +goto cleanup;
 +
 +if (!(subInterfaces = virJSONValueNewArray()))
 +goto cleanup;
 +
 +for (i = 0; i  pcisrc-nmac; i++) {
 +virMacAddrFormat(pcisrc-macs[i], macstr);
 +interface = findInterfaceByMac(interfaceInfo, len, macstr);
 +if (!interface) {
 +goto cleanup;
 +}
 +
 +if (!(subInterface = virJSONValueNewObject()))
 +goto cleanup;
 +
 +if (virJSONValueObjectAppendString(subInterface, name, 
 interface-name)  0)
 +goto cleanup;
 +
 +if (virJSONValueArrayAppend(subInterfaces, subInterface)  0)
 +goto cleanup;
 +
 +subInterface = NULL;
 +}
 +
 +if (i  virJSONValueObjectAppend(new_interface, subInterfaces, 
 subInterfaces)  0)
 +goto cleanup;
 +
 +cmd = qemuAgentMakeCommand(guest-network-set-interface,
 +   a:interface, new_interface,
 +   NULL);
 +
 +if (!cmd)
 +goto cleanup;
 +
 +subInterfaces = NULL;
 +new_interface = NULL;
 +
 +if (qemuAgentCommand(mon, cmd, reply, true,
 + VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK)  0)
 +goto cleanup;
 +
 +if (virJSONValueObjectGetNumberInt(reply, return, ret)  0) {
 +virReportError(VIR_ERR_INTERNAL_ERROR, %s,
 +   _(malformed return value));
 +}
 +
 + cleanup:
 +virJSONValueFree(subInterfaces);
 +virJSONValueFree(subInterface);
 +virJSONValueFree(new_interface);
 +virJSONValueFree(cmd);
 +virJSONValueFree(reply);
 +if (interfaceInfo)
 +for (i = 0; i  len; i++)
 +virDomainInterfaceFree(interfaceInfo[i]);
 +VIR_FREE(interfaceInfo);
 +return ret;
 +}
 diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
 index 42414a7..744cb0a 100644
 --- a/src/qemu/qemu_agent.h
 +++ b/src/qemu/qemu_agent.h
 @@ -97,6 +97,13 @@ struct _qemuAgentCPUInfo {
  bool offlinable;/* true if the CPU can be offlined */
  };
  
 +typedef struct _qemuAgentInterfaceInfo qemuAgentInterfaceInfo;
 +typedef qemuAgentInterfaceInfo *qemuAgentInterfaceInfoPtr;
 +struct _qemuAgentInterfaceInfo {
 +char *name;
 +char *hardware_address;
 +};
 +
  int qemuAgentGetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr *info);
  int qemuAgentSetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr cpus, size_t 
 ncpus);
  int qemuAgentUpdateCPUInfo(unsigned int nvcpus,
 @@ -114,4 +121,7 @@ int qemuAgentSetTime(qemuAgentPtr mon,
  int qemuAgentGetInterfaces(qemuAgentPtr mon,
 

[libvirt] [RFC 4/7] qemu-agent: add qemuAgentCreateBond interface

2015-04-17 Thread Chen Fan
via initialize callback to create bond device.

Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com
---
 src/qemu/qemu_agent.c   | 118 
 src/qemu/qemu_agent.h   |  10 
 src/qemu/qemu_domain.c  |  70 
 src/qemu/qemu_domain.h  |   7 +++
 src/qemu/qemu_process.c |   4 ++
 5 files changed, 209 insertions(+)

diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index cee0f8b..b8eba01 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -2169,3 +2169,121 @@ qemuAgentGetInterfaces(qemuAgentPtr mon,
 
 goto cleanup;
 }
+
+static virDomainInterfacePtr
+findInterfaceByMac(virDomainInterfacePtr *info,
+   size_t len,
+   const char *macstr)
+{
+size_t i;
+bool found = false;
+
+for (i = 0; i  len; i++) {
+if (info[i]-hwaddr 
+STREQ(info[i]-hwaddr, macstr)) {
+found = true;
+break;
+}
+}
+
+if (found) {
+return info[i];
+}
+
+return NULL;
+}
+
+/*
+ * qemuAgentSetInterface:
+ */
+int
+qemuAgentCreateBond(qemuAgentPtr mon,
+virDomainHostdevSubsysPCIPtr pcisrc)
+{
+int ret = -1;
+virJSONValuePtr cmd = NULL;
+virJSONValuePtr reply = NULL;
+size_t i;
+char macstr[VIR_MAC_STRING_BUFLEN];
+virDomainInterfacePtr *interfaceInfo = NULL;
+virDomainInterfacePtr interface;
+virJSONValuePtr new_interface = NULL;
+virJSONValuePtr subInterfaces = NULL;
+virJSONValuePtr subInterface = NULL;
+int len;
+
+if (!(pcisrc-nmac || pcisrc-macs))
+return ret;
+
+len = qemuAgentGetInterfaces(mon, interfaceInfo);
+if (len  0)
+return ret;
+
+if (!(new_interface = virJSONValueNewObject()))
+goto cleanup;
+
+if (virJSONValueObjectAppendString(new_interface, type, bond)  0)
+goto cleanup;
+
+if (virJSONValueObjectAppendString(new_interface, name, bond0)  0)
+goto cleanup;
+
+if (virJSONValueObjectAppendString(new_interface, onboot, onboot)  0)
+goto cleanup;
+
+if (!(subInterfaces = virJSONValueNewArray()))
+goto cleanup;
+
+for (i = 0; i  pcisrc-nmac; i++) {
+virMacAddrFormat(pcisrc-macs[i], macstr);
+interface = findInterfaceByMac(interfaceInfo, len, macstr);
+if (!interface) {
+goto cleanup;
+}
+
+if (!(subInterface = virJSONValueNewObject()))
+goto cleanup;
+
+if (virJSONValueObjectAppendString(subInterface, name, 
interface-name)  0)
+goto cleanup;
+
+if (virJSONValueArrayAppend(subInterfaces, subInterface)  0)
+goto cleanup;
+
+subInterface = NULL;
+}
+
+if (i  virJSONValueObjectAppend(new_interface, subInterfaces, 
subInterfaces)  0)
+goto cleanup;
+
+cmd = qemuAgentMakeCommand(guest-network-set-interface,
+   a:interface, new_interface,
+   NULL);
+
+if (!cmd)
+goto cleanup;
+
+subInterfaces = NULL;
+new_interface = NULL;
+
+if (qemuAgentCommand(mon, cmd, reply, true,
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK)  0)
+goto cleanup;
+
+if (virJSONValueObjectGetNumberInt(reply, return, ret)  0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(malformed return value));
+}
+
+ cleanup:
+virJSONValueFree(subInterfaces);
+virJSONValueFree(subInterface);
+virJSONValueFree(new_interface);
+virJSONValueFree(cmd);
+virJSONValueFree(reply);
+if (interfaceInfo)
+for (i = 0; i  len; i++)
+virDomainInterfaceFree(interfaceInfo[i]);
+VIR_FREE(interfaceInfo);
+return ret;
+}
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 42414a7..744cb0a 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -97,6 +97,13 @@ struct _qemuAgentCPUInfo {
 bool offlinable;/* true if the CPU can be offlined */
 };
 
+typedef struct _qemuAgentInterfaceInfo qemuAgentInterfaceInfo;
+typedef qemuAgentInterfaceInfo *qemuAgentInterfaceInfoPtr;
+struct _qemuAgentInterfaceInfo {
+char *name;
+char *hardware_address;
+};
+
 int qemuAgentGetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr *info);
 int qemuAgentSetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr cpus, size_t 
ncpus);
 int qemuAgentUpdateCPUInfo(unsigned int nvcpus,
@@ -114,4 +121,7 @@ int qemuAgentSetTime(qemuAgentPtr mon,
 int qemuAgentGetInterfaces(qemuAgentPtr mon,
virDomainInterfacePtr **ifaces);
 
+int qemuAgentCreateBond(qemuAgentPtr mon,
+virDomainHostdevSubsysPCIPtr pcisrc);
+
 #endif /* __QEMU_AGENT_H__ */
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 603360f..584fefb 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2722,6 +2722,46 @@ qemuDomainCleanupRun(virQEMUDriverPtr driver,