[libvirt] virConnectClose() API function question
by Michal Novotny
Hi,
as I've been working on libvirt-php I've been able to see that sometimes
the virConnectClose() API function is returning the undefined value,
like in this example:
[2011-06-21 17:29:59 libvirt-php/core]: libvirt_domain_get_info:
virDomainGetInfo(0xb3184158) returned 0
[2011-06-21 17:29:59 libvirt-php/core]: Freeing libvirt domain resource
at 0x3d9751b3184158
[2011-06-21 17:29:59 libvirt-php/core]: free_resource:
virDomainFree(0xb3184158) completed successfully
[2011-06-21 17:29:59 libvirt-php/core]: php_libvirt_connection_dtor:
virConnectClose(0xb3382588) returned 1 ((null))
[2011-06-21 17:29:59 libvirt-php/core]: check_resource_allocation:
libvirt domain resource (conn 0xb3184158) is not allocated
In the API reference of libvirt there's an information that it returns 0
or -1 ("0 in case of success or -1 in case of error" as can be seen at
[1]) however according to my libvirt-php tests with the debug log
enabled there's a return value of 1 with the error string (as caught by
libvirt error handler) undefined, i.e. NULL.
Does anybody have an idea what may be wrong and why is libvirt sometimes
returning undefined value for this function?
Thanks,
Michal
[1] http://libvirt.org/html/libvirt-libvirt.html#virConnectClose
--
Michal Novotny <minovotn(a)redhat.com>, RHCE, Red Hat
Virtualization Team (xen userspace) | libvirt-php bindings
13 years, 5 months
[libvirt] [PATCH 0/2] Expose flags for several commands
by Osier Yang
APIs virDomainAttachDeviceFlags, virDomainDetachDeviceFlags, and
virDomainUpdateDeviceFlags support three flags: VIR_DOMAIN_AFFECT_LIVE,
VIR_DOMAIN_AFFECT_CONFIG, and VIR_DOMAIN_AFFECT_CURRENT, however,
the commands based on those 3 APIs only expose one option "--persistent".
These two patches expose the other two options as "--live" and "--current",
and changes "--persistent" into "--config", just as other similiar commands
do, e.g. "vcpupin", "schedinfo".
Affected commands:
attach-device
attach-disk
attach-interface
detach-device
detach-disk
detach-interface
update-device
[PATCH 1/2] virsh: Add options for several commands which change domain config
[PATCH 2/2] doc: Update docs for the changed commands
Regards
Osier
13 years, 5 months
[libvirt] [PATCH 2/2 V2] cleanup: make several interface functions commonly available
by Stefan Berger
In a second cleanup step this patch makes several interface functions
from macvtap.c commonly available by moving them into interface.c and
prefixing their names with 'iface'.
ifaceRestoreMacAddress returns the return code from the
ifaceSetMacAddres call and display an error message if setting the MAC
address did not work. The caller is unchanged and still ignores the
return code (which is ok).
This patch also fixes a problem with the return code of
ifaceSetMacAddress being used for error reporting in one place rather
than errno.
v2:
- making all functions visible on all platforms
Signed-off-by: Stefan Berger <stefanb(a)linux.vnet.ibm.com>
---
src/libvirt_private.syms | 8
src/util/interface.c | 609 +++++++++++++++++++++++++++++++++++++++++++++++
src/util/interface.h | 37 ++
src/util/macvtap.c | 495 --------------------------------------
4 files changed, 663 insertions(+), 486 deletions(-)
Index: libvirt-acl/src/util/interface.c
===================================================================
--- libvirt-acl.orig/src/util/interface.c
+++ libvirt-acl/src/util/interface.c
@@ -27,6 +27,7 @@
#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <fcntl.h>
#ifdef __linux__
# include <linux/if.h>
@@ -40,6 +41,10 @@
#include "interface.h"
#include "virterror_internal.h"
#include "files.h"
+#include "memory.h"
+#include "netlink.h"
+
+#define VIR_FROM_THIS VIR_FROM_NET
#define ifaceError(code, ...) \
virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \
@@ -486,3 +491,607 @@ ifaceSetMacaddr(const char *ifname ATTRI
}
#endif /* __linux__ */
+
+
+/**
+ * ifaceLinkAdd
+ *
+ * @type: The type of device, i.e., "macvtap"
+ * @macaddress: The MAC address of the device
+ * @macaddrsize: The size of the MAC address, typically '6'
+ * @ifname: The name the interface is supposed to have; optional parameter
+ * @srcdev: The name of the 'link' device
+ * @macvlan_mode: The macvlan mode to use
+ * @retry: Pointer to integer that will be '1' upon return if an interface
+ * with the same name already exists and it is worth to try
+ * again with a different name
+ *
+ * Create a macvtap device with the given properties.
+ *
+ * Returns 0 on success, -1 on fatal error.
+ */
+#if __linux__
+int
+ifaceMacvtapLinkAdd(const char *type,
+ const unsigned char *macaddress, int macaddrsize,
+ const char *ifname,
+ const char *srcdev,
+ uint32_t macvlan_mode,
+ int *retry)
+{
+ int rc = 0;
+ struct nlmsghdr *resp;
+ struct nlmsgerr *err;
+ struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
+ int ifindex;
+ unsigned char *recvbuf = NULL;
+ unsigned int recvbuflen;
+ struct nl_msg *nl_msg;
+ struct nlattr *linkinfo, *info_data;
+
+ if (ifaceGetIndex(true, srcdev, &ifindex) != 0)
+ return -1;
+
+ *retry = 0;
+
+ nl_msg = nlmsg_alloc_simple(RTM_NEWLINK,
+ NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
+ if (!nl_msg) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
+ goto buffer_too_small;
+
+ if (nla_put_u32(nl_msg, IFLA_LINK, ifindex) < 0)
+ goto buffer_too_small;
+
+ if (nla_put(nl_msg, IFLA_ADDRESS, macaddrsize, macaddress) < 0)
+ goto buffer_too_small;
+
+ if (ifname &&
+ nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
+ goto buffer_too_small;
+
+ if (!(linkinfo = nla_nest_start(nl_msg, IFLA_LINKINFO)))
+ goto buffer_too_small;
+
+ if (nla_put(nl_msg, IFLA_INFO_KIND, strlen(type), type) < 0)
+ goto buffer_too_small;
+
+ if (macvlan_mode > 0) {
+ if (!(info_data = nla_nest_start(nl_msg, IFLA_INFO_DATA)))
+ goto buffer_too_small;
+
+ if (nla_put(nl_msg, IFLA_MACVLAN_MODE, sizeof(macvlan_mode),
+ &macvlan_mode) < 0)
+ goto buffer_too_small;
+
+ nla_nest_end(nl_msg, info_data);
+ }
+
+ nla_nest_end(nl_msg, linkinfo);
+
+ if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) {
+ rc = -1;
+ goto err_exit;
+ }
+
+ if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
+ goto malformed_resp;
+
+ resp = (struct nlmsghdr *)recvbuf;
+
+ switch (resp->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(resp);
+ if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
+ goto malformed_resp;
+
+ switch (err->error) {
+
+ case 0:
+ break;
+
+ case -EEXIST:
+ *retry = 1;
+ rc = -1;
+ break;
+
+ default:
+ virReportSystemError(-err->error,
+ _("error creating %s type of interface"),
+ type);
+ rc = -1;
+ }
+ break;
+
+ case NLMSG_DONE:
+ break;
+
+ default:
+ goto malformed_resp;
+ }
+
+err_exit:
+ nlmsg_free(nl_msg);
+
+ VIR_FREE(recvbuf);
+
+ return rc;
+
+malformed_resp:
+ nlmsg_free(nl_msg);
+
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ VIR_FREE(recvbuf);
+ return -1;
+
+buffer_too_small:
+ nlmsg_free(nl_msg);
+
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("allocated netlink buffer is too small"));
+ return -1;
+}
+
+#else
+
+int
+ifaceMacvtapLinkAdd(const char *type ATTRIBUTE_UNUSED,
+ const unsigned char *macaddress ATTRIBUTE_UNUSED,
+ int macaddrsize ATTRIBUTE_UNUSED,
+ const char *ifname ATTRIBUTE_UNUSED,
+ const char *srcdev ATTRIBUTE_UNUSED,
+ uint32_t macvlan_mode ATTRIBUTE_UNUSED,
+ int *retry ATTRIBUTE_UNUSED)
+{
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("ifaceMacvtapLinkAdd is not supported on non-linux "
+ "platforms"));
+ return -1;
+}
+
+#endif
+
+
+/**
+ * ifaceLinkDel
+ *
+ * @ifname: Name of the interface
+ *
+ * Tear down an interface with the given name.
+ *
+ * Returns 0 on success, -1 on fatal error.
+ */
+#if __linux__
+int
+ifaceLinkDel(const char *ifname)
+{
+ int rc = 0;
+ struct nlmsghdr *resp;
+ struct nlmsgerr *err;
+ struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
+ unsigned char *recvbuf = NULL;
+ unsigned int recvbuflen;
+ struct nl_msg *nl_msg;
+
+ nl_msg = nlmsg_alloc_simple(RTM_DELLINK,
+ NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
+ if (!nl_msg) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
+ goto buffer_too_small;
+
+ if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
+ goto buffer_too_small;
+
+ if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) {
+ rc = -1;
+ goto err_exit;
+ }
+
+ if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
+ goto malformed_resp;
+
+ resp = (struct nlmsghdr *)recvbuf;
+
+ switch (resp->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(resp);
+ if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
+ goto malformed_resp;
+
+ if (err->error) {
+ virReportSystemError(-err->error,
+ _("error destroying %s interface"),
+ ifname);
+ rc = -1;
+ }
+ break;
+
+ case NLMSG_DONE:
+ break;
+
+ default:
+ goto malformed_resp;
+ }
+
+err_exit:
+ nlmsg_free(nl_msg);
+
+ VIR_FREE(recvbuf);
+
+ return rc;
+
+malformed_resp:
+ nlmsg_free(nl_msg);
+
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ VIR_FREE(recvbuf);
+ return -1;
+
+buffer_too_small:
+ nlmsg_free(nl_msg);
+
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("allocated netlink buffer is too small"));
+ return -1;
+}
+
+#else
+
+int
+ifaceLinkDel(const char *ifname ATTRIBUTE_UNUSED)
+{
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("ifaceLinkDel is not supported on non-linux platforms"));
+ return -1;
+}
+
+#endif
+
+
+#if __linux__
+static struct nla_policy ifla_policy[IFLA_MAX + 1] =
+{
+ [IFLA_VF_PORTS] = { .type = NLA_NESTED },
+};
+
+/**
+ * ifaceMacvtapLinkDump
+ *
+ * @nltarget_kernel: whether to send the message to the kernel or another
+ * process
+ * @ifname: The name of the interface; only use if ifindex < 0
+ * @ifindex: The interface index; may be < 0 if ifname is given
+ * @nlattr: pointer to a pointer of netlink attributes that will contain
+ * the results
+ * @recvbuf: Pointer to the buffer holding the returned netlink response
+ * message; free it, once not needed anymore
+ * @getPidFunc: Pointer to a function that will be invoked if the kernel
+ * is not the target of the netlink message but it is to be
+ * sent to another process.
+ *
+ * Get information about an interface given its name or index.
+ *
+ * Returns 0 on success, -1 on fatal error.
+ */
+int
+ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex,
+ struct nlattr **tb, unsigned char **recvbuf,
+ uint32_t (*getPidFunc)(void))
+{
+ int rc = 0;
+ struct nlmsghdr *resp;
+ struct nlmsgerr *err;
+ struct ifinfomsg ifinfo = {
+ .ifi_family = AF_UNSPEC,
+ .ifi_index = ifindex
+ };
+ unsigned int recvbuflen;
+ uint32_t pid = 0;
+ struct nl_msg *nl_msg;
+
+ *recvbuf = NULL;
+
+ nl_msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
+ if (!nl_msg) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
+ goto buffer_too_small;
+
+ if (ifindex < 0 && ifname) {
+ if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
+ goto buffer_too_small;
+ }
+
+ if (!nltarget_kernel) {
+ pid = getPidFunc();
+ if (pid == 0) {
+ rc = -1;
+ goto err_exit;
+ }
+ }
+
+ if (nlComm(nl_msg, recvbuf, &recvbuflen, pid) < 0) {
+ rc = -1;
+ goto err_exit;
+ }
+
+ if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL)
+ goto malformed_resp;
+
+ resp = (struct nlmsghdr *)*recvbuf;
+
+ switch (resp->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(resp);
+ if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
+ goto malformed_resp;
+
+ if (err->error) {
+ virReportSystemError(-err->error,
+ _("error dumping %s (%d) interface"),
+ ifname, ifindex);
+ rc = -1;
+ }
+ break;
+
+ case GENL_ID_CTRL:
+ case NLMSG_DONE:
+ if (nlmsg_parse(resp, sizeof(struct ifinfomsg),
+ tb, IFLA_MAX, ifla_policy)) {
+ goto malformed_resp;
+ }
+ break;
+
+ default:
+ goto malformed_resp;
+ }
+
+ if (rc != 0)
+ VIR_FREE(*recvbuf);
+
+err_exit:
+ nlmsg_free(nl_msg);
+
+ return rc;
+
+malformed_resp:
+ nlmsg_free(nl_msg);
+
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ VIR_FREE(*recvbuf);
+ return -1;
+
+buffer_too_small:
+ nlmsg_free(nl_msg);
+
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("allocated netlink buffer is too small"));
+ return -1;
+}
+
+#else
+
+int
+ifaceMacvtapLinkDump(bool nltarget_kernel ATTRIBUTE_UNUSED,
+ const char *ifname ATTRIBUTE_UNUSED,
+ int ifindex ATTRIBUTE_UNUSED,
+ struct nlattr **tb ATTRIBUTE_UNUSED,
+ unsigned char **recvbuf ATTRIBUTE_UNUSED,
+ uint32_t (*getPidFunc)(void) ATTRIBUTE_UNUSED)
+{
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("ifaceMacvtapLinkDump is not supported on non-linux "
+ "platforms"));
+ return -1;
+}
+
+#endif
+
+
+/**
+ * ifaceGetNthParent
+ *
+ * @ifindex : the index of the interface or -1 if ifname is given
+ * @ifname : the name of the interface; ignored if ifindex is valid
+ * @nthParent : the nth parent interface to get
+ * @parent_ifindex : pointer to int
+ * @parent_ifname : pointer to buffer of size IFNAMSIZ
+ * @nth : the nth parent that is actually returned; if for example eth0.100
+ * was given and the 100th parent is to be returned, then eth0 will
+ * most likely be returned with nth set to 1 since the chain does
+ * not have more interfaces
+ *
+ * Get the nth parent interface of the given interface. 0 is the interface
+ * itself.
+ *
+ * Return 0 on success, != 0 otherwise
+ */
+#if __linux__
+int
+ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent,
+ int *parent_ifindex, char *parent_ifname,
+ unsigned int *nth)
+{
+ int rc;
+ struct nlattr *tb[IFLA_MAX + 1] = { NULL, };
+ unsigned char *recvbuf = NULL;
+ bool end = false;
+ unsigned int i = 0;
+
+ *nth = 0;
+
+ if (ifindex <= 0 && ifaceGetIndex(true, ifname, &ifindex) != 0)
+ return 1;
+
+ while (!end && i <= nthParent) {
+ rc = ifaceMacvtapLinkDump(true, ifname, ifindex, tb, &recvbuf, NULL);
+ if (rc)
+ break;
+
+ if (tb[IFLA_IFNAME]) {
+ if (!virStrcpy(parent_ifname, (char*)RTA_DATA(tb[IFLA_IFNAME]),
+ IFNAMSIZ)) {
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("buffer for root interface name is too small"));
+ VIR_FREE(recvbuf);
+ return 1;
+ }
+ *parent_ifindex = ifindex;
+ }
+
+ if (tb[IFLA_LINK]) {
+ ifindex = *(int *)RTA_DATA(tb[IFLA_LINK]);
+ ifname = NULL;
+ } else
+ end = true;
+
+ VIR_FREE(recvbuf);
+
+ i++;
+ }
+
+ if (nth)
+ *nth = i - 1;
+
+ return rc;
+}
+
+#else
+
+int
+ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED,
+ const char *ifname ATTRIBUTE_UNUSED,
+ unsigned int nthParent ATTRIBUTE_UNUSED,
+ int *parent_ifindex ATTRIBUTE_UNUSED,
+ char *parent_ifname ATTRIBUTE_UNUSED,
+ unsigned int *nth ATTRIBUTE_UNUSED)
+{
+ ifaceError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("ifaceGetNthParent is not supported on non-linux platforms"));
+ return -1;
+}
+
+#endif
+
+/**
+ * ifaceReplaceMacAddress:
+ * @macaddress: new MAC address for interface
+ * @linkdev: name of interface
+ * @stateDir: directory to store old MAC address
+ *
+ * Returns 0 on success, -1 in case of fatal error, error code otherwise.
+ *
+ */
+int
+ifaceReplaceMacAddress(const unsigned char *macaddress,
+ const char *linkdev,
+ const char *stateDir)
+{
+ unsigned char oldmac[6];
+ int rc;
+
+ rc = ifaceGetMacaddr(linkdev, oldmac);
+
+ if (rc) {
+ virReportSystemError(rc,
+ _("Getting MAC address from '%s' "
+ "to '%02x:%02x:%02x:%02x:%02x:%02x' failed."),
+ linkdev,
+ oldmac[0], oldmac[1], oldmac[2],
+ oldmac[3], oldmac[4], oldmac[5]);
+ } else {
+ char *path = NULL;
+ char macstr[VIR_MAC_STRING_BUFLEN];
+
+ if (virAsprintf(&path, "%s/%s",
+ stateDir,
+ linkdev) < 0) {
+ virReportOOMError();
+ return errno;
+ }
+ virFormatMacAddr(oldmac, macstr);
+ if (virFileWriteStr(path, macstr, O_CREAT|O_TRUNC|O_WRONLY) < 0) {
+ virReportSystemError(errno, _("Unable to preserve mac for %s"),
+ linkdev);
+ return errno;
+ }
+ }
+
+ rc = ifaceSetMacaddr(linkdev, macaddress);
+ if (rc) {
+ virReportSystemError(rc,
+ _("Setting MAC address on '%s' to "
+ "'%02x:%02x:%02x:%02x:%02x:%02x' failed."),
+ linkdev,
+ macaddress[0], macaddress[1], macaddress[2],
+ macaddress[3], macaddress[4], macaddress[5]);
+ }
+
+ return rc;
+}
+
+/**
+ * ifaceRestoreMacAddress:
+ * @linkdev: name of interface
+ * @stateDir: directory containing old MAC address
+ *
+ * Returns 0 on success, -1 in case of fatal error, error code otherwise.
+ *
+ */
+int
+ifaceRestoreMacAddress(const char *linkdev,
+ const char *stateDir)
+{
+ int rc;
+ char *oldmacname = NULL;
+ char *macstr = NULL;
+ char *path = NULL;
+ unsigned char oldmac[6];
+
+ if (virAsprintf(&path, "%s/%s",
+ stateDir,
+ linkdev) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if (virFileReadAll(path, VIR_MAC_STRING_BUFLEN, &macstr) < 0) {
+ return errno;
+ }
+
+ if (virParseMacAddr(macstr, &oldmac[0]) != 0) {
+ ifaceError(VIR_ERR_INTERNAL_ERROR,
+ _("Cannot parse MAC address from '%s'"),
+ oldmacname);
+ return -1;
+ }
+
+ /*reset mac and remove file-ignore results*/
+ rc = ifaceSetMacaddr(linkdev, oldmac);
+ if (rc) {
+ virReportSystemError(rc,
+ _("Setting MAC address on '%s' to "
+ "'%02x:%02x:%02x:%02x:%02x:%02x' failed."),
+ linkdev,
+ oldmac[0], oldmac[1], oldmac[2],
+ oldmac[3], oldmac[4], oldmac[5]);
+ }
+ ignore_value(unlink(path));
+ VIR_FREE(macstr);
+
+ return rc;
+}
Index: libvirt-acl/src/util/interface.h
===================================================================
--- libvirt-acl.orig/src/util/interface.h
+++ libvirt-acl/src/util/interface.h
@@ -10,6 +10,19 @@
#ifndef __VIR_INTERFACE_H__
# define __VIR_INTERFACE_H__
+# include <stdint.h>
+
+# if __linux__
+
+# include <sys/socket.h>
+# include <linux/netlink.h>
+
+# else
+
+struct nlattr;
+
+# endif
+
# include "datatypes.h"
int ifaceGetFlags(const char *name, short *flags);
@@ -36,4 +49,28 @@ int ifaceSetMacaddr(const char *ifname,
int ifaceGetMacaddr(const char *ifname, unsigned char *macaddr);
+int ifaceMacvtapLinkAdd(const char *type,
+ const unsigned char *macaddress, int macaddrsize,
+ const char *ifname,
+ const char *srcdev,
+ uint32_t macvlan_mode,
+ int *retry);
+
+int ifaceLinkDel(const char *ifname);
+
+int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex,
+ struct nlattr **tb, unsigned char **recvbuf,
+ uint32_t (*getPidFunc)(void));
+
+int ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent,
+ int *parent_ifindex, char *parent_ifname,
+ unsigned int *nth);
+
+int ifaceReplaceMacAddress(const unsigned char *macaddress,
+ const char *linkdev,
+ const char *stateDir);
+
+int ifaceRestoreMacAddress(const char *linkdev,
+ const char *stateDir);
+
#endif /* __VIR_INTERFACE_H__ */
Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -95,212 +95,6 @@ enum virVirtualPortOp {
# if WITH_MACVTAP
-static int
-link_add(const char *type,
- const unsigned char *macaddress, int macaddrsize,
- const char *ifname,
- const char *srcdev,
- uint32_t macvlan_mode,
- int *retry)
-{
- int rc = 0;
- struct nlmsghdr *resp;
- struct nlmsgerr *err;
- struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
- int ifindex;
- unsigned char *recvbuf = NULL;
- unsigned int recvbuflen;
- struct nl_msg *nl_msg;
- struct nlattr *linkinfo, *info_data;
-
- if (ifaceGetIndex(true, srcdev, &ifindex) != 0)
- return -1;
-
- *retry = 0;
-
- nl_msg = nlmsg_alloc_simple(RTM_NEWLINK,
- NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
- if (!nl_msg) {
- virReportOOMError();
- return -1;
- }
-
- if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
- goto buffer_too_small;
-
- if (nla_put_u32(nl_msg, IFLA_LINK, ifindex) < 0)
- goto buffer_too_small;
-
- if (nla_put(nl_msg, IFLA_ADDRESS, macaddrsize, macaddress) < 0)
- goto buffer_too_small;
-
- if (ifname &&
- nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
- goto buffer_too_small;
-
- if (!(linkinfo = nla_nest_start(nl_msg, IFLA_LINKINFO)))
- goto buffer_too_small;
-
- if (nla_put(nl_msg, IFLA_INFO_KIND, strlen(type), type) < 0)
- goto buffer_too_small;
-
- if (macvlan_mode > 0) {
- if (!(info_data = nla_nest_start(nl_msg, IFLA_INFO_DATA)))
- goto buffer_too_small;
-
- if (nla_put(nl_msg, IFLA_MACVLAN_MODE, sizeof(macvlan_mode),
- &macvlan_mode) < 0)
- goto buffer_too_small;
-
- nla_nest_end(nl_msg, info_data);
- }
-
- nla_nest_end(nl_msg, linkinfo);
-
- if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) {
- rc = -1;
- goto err_exit;
- }
-
- if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
- goto malformed_resp;
-
- resp = (struct nlmsghdr *)recvbuf;
-
- switch (resp->nlmsg_type) {
- case NLMSG_ERROR:
- err = (struct nlmsgerr *)NLMSG_DATA(resp);
- if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
- goto malformed_resp;
-
- switch (err->error) {
-
- case 0:
- break;
-
- case -EEXIST:
- *retry = 1;
- rc = -1;
- break;
-
- default:
- virReportSystemError(-err->error,
- _("error creating %s type of interface"),
- type);
- rc = -1;
- }
- break;
-
- case NLMSG_DONE:
- break;
-
- default:
- goto malformed_resp;
- }
-
-err_exit:
- nlmsg_free(nl_msg);
-
- VIR_FREE(recvbuf);
-
- return rc;
-
-malformed_resp:
- nlmsg_free(nl_msg);
-
- macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("malformed netlink response message"));
- VIR_FREE(recvbuf);
- return -1;
-
-buffer_too_small:
- nlmsg_free(nl_msg);
-
- macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("allocated netlink buffer is too small"));
- return -1;
-}
-
-
-static int
-link_del(const char *ifname)
-{
- int rc = 0;
- struct nlmsghdr *resp;
- struct nlmsgerr *err;
- struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
- unsigned char *recvbuf = NULL;
- unsigned int recvbuflen;
- struct nl_msg *nl_msg;
-
- nl_msg = nlmsg_alloc_simple(RTM_DELLINK,
- NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
- if (!nl_msg) {
- virReportOOMError();
- return -1;
- }
-
- if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
- goto buffer_too_small;
-
- if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
- goto buffer_too_small;
-
- if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) {
- rc = -1;
- goto err_exit;
- }
-
- if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
- goto malformed_resp;
-
- resp = (struct nlmsghdr *)recvbuf;
-
- switch (resp->nlmsg_type) {
- case NLMSG_ERROR:
- err = (struct nlmsgerr *)NLMSG_DATA(resp);
- if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
- goto malformed_resp;
-
- if (err->error) {
- virReportSystemError(-err->error,
- _("error destroying %s interface"),
- ifname);
- rc = -1;
- }
- break;
-
- case NLMSG_DONE:
- break;
-
- default:
- goto malformed_resp;
- }
-
-err_exit:
- nlmsg_free(nl_msg);
-
- VIR_FREE(recvbuf);
-
- return rc;
-
-malformed_resp:
- nlmsg_free(nl_msg);
-
- macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("malformed netlink response message"));
- VIR_FREE(recvbuf);
- return -1;
-
-buffer_too_small:
- nlmsg_free(nl_msg);
-
- macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("allocated netlink buffer is too small"));
- return -1;
-}
-
-
/* Open the macvtap's tap device.
* @ifname: Name of the macvtap interface
* @retries : Number of retries in case udev for example may need to be
@@ -450,104 +244,6 @@ configMacvtapTap(int tapfd, int vnet_hdr
}
/**
- * replaceMacAdress:
- * @macaddress: new MAC address for interface
- * @linkdev: name of interface
- * @stateDir: directory to store old MAC address
- *
- * Returns 0 on success, -1 in case of fatal error, error code otherwise.
- *
- */
-static int
-replaceMacAdress(const unsigned char *macaddress,
- const char *linkdev,
- char *stateDir)
-{
- unsigned char oldmac[6];
- int rc;
-
- rc = ifaceGetMacaddr(linkdev, oldmac);
-
- if (rc) {
- virReportSystemError(rc,
- _("Getting MAC address from '%s' "
- "to '%02x:%02x:%02x:%02x:%02x:%02x' failed."),
- linkdev,
- oldmac[0], oldmac[1], oldmac[2],
- oldmac[3], oldmac[4], oldmac[5]);
- } else {
- char *path = NULL;
- char macstr[VIR_MAC_STRING_BUFLEN];
-
- if (virAsprintf(&path, "%s/%s",
- stateDir,
- linkdev) < 0) {
- virReportOOMError();
- return errno;
- }
- virFormatMacAddr(oldmac, macstr);
- if (virFileWriteStr(path, macstr, O_CREAT|O_TRUNC|O_WRONLY) < 0) {
- virReportSystemError(errno, _("Unable to preserve mac for %s"),
- linkdev);
- return errno;
- }
- }
-
- rc = ifaceSetMacaddr(linkdev, macaddress);
- if (rc) {
- virReportSystemError(errno,
- _("Setting MAC address on '%s' to "
- "'%02x:%02x:%02x:%02x:%02x:%02x' failed."),
- linkdev,
- macaddress[0], macaddress[1], macaddress[2],
- macaddress[3], macaddress[4], macaddress[5]);
- }
- return rc;
-}
-
-/**
- * restoreMacAddress:
- * @linkdev: name of interface
- * @stateDir: directory containing old MAC address
- *
- * Returns 0 on success, -1 in case of fatal error, error code otherwise.
- *
- */
-static int
-restoreMacAddress(const char *linkdev,
- char *stateDir)
-{
- char *oldmacname = NULL;
- char *macstr = NULL;
- char *path = NULL;
- unsigned char oldmac[6];
-
- if (virAsprintf(&path, "%s/%s",
- stateDir,
- linkdev) < 0) {
- virReportOOMError();
- return -1;
- }
-
- if (virFileReadAll(path, VIR_MAC_STRING_BUFLEN, &macstr) < 0) {
- return errno;
- }
-
- if (virParseMacAddr(macstr, &oldmac[0]) != 0) {
- macvtapError(VIR_ERR_INTERNAL_ERROR,
- _("Cannot parse MAC address from '%s'"),
- oldmacname);
- return -1;
- }
-
- /*reset mac and remove file-ignore results*/
- ignore_value(ifaceSetMacaddr(linkdev, oldmac));
- ignore_value(unlink(path));
- VIR_FREE(macstr);
- return 0;
-}
-
-/**
* openMacvtapTap:
* Create an instance of a macvtap device and open its tap character
* device.
@@ -599,7 +295,7 @@ openMacvtapTap(const char *tgifname,
* emulate their switch in firmware.
*/
if (mode == VIR_DOMAIN_NETDEV_MACVTAP_MODE_PASSTHRU) {
- if (replaceMacAdress(macaddress, linkdev, stateDir) != 0) {
+ if (ifaceReplaceMacAddress(macaddress, linkdev, stateDir) != 0) {
return -1;
}
}
@@ -615,8 +311,8 @@ openMacvtapTap(const char *tgifname,
return -1;
}
cr_ifname = tgifname;
- rc = link_add(type, macaddress, 6, tgifname, linkdev,
- macvtapMode, &do_retry);
+ rc = ifaceMacvtapLinkAdd(type, macaddress, 6, tgifname, linkdev,
+ macvtapMode, &do_retry);
if (rc)
return -1;
} else {
@@ -625,8 +321,8 @@ create_name:
for (c = 0; c < 8192; c++) {
snprintf(ifname, sizeof(ifname), MACVTAP_NAME_PATTERN, c);
if (ifaceGetIndex(false, ifname, &ifindex) == ENODEV) {
- rc = link_add(type, macaddress, 6, ifname, linkdev,
- macvtapMode, &do_retry);
+ rc = ifaceMacvtapLinkAdd(type, macaddress, 6, ifname, linkdev,
+ macvtapMode, &do_retry);
if (rc == 0)
break;
@@ -679,7 +375,7 @@ disassociate_exit:
vmOp);
link_del_exit:
- link_del(cr_ifname);
+ ifaceLinkDel(cr_ifname);
return rc;
}
@@ -704,7 +400,7 @@ delMacvtap(const char *ifname,
char *stateDir)
{
if (mode == VIR_DOMAIN_NETDEV_MACVTAP_MODE_PASSTHRU) {
- restoreMacAddress(linkdev, stateDir);
+ ifaceRestoreMacAddress(linkdev, stateDir);
}
if (ifname) {
@@ -712,7 +408,7 @@ delMacvtap(const char *ifname,
linkdev,
virtPortProfile,
VIR_VM_OP_DESTROY);
- link_del(ifname);
+ ifaceLinkDel(ifname);
}
}
@@ -720,11 +416,6 @@ delMacvtap(const char *ifname,
# ifdef IFLA_PORT_MAX
-static struct nla_policy ifla_policy[IFLA_MAX + 1] =
-{
- [IFLA_VF_PORTS] = { .type = NLA_NESTED },
-};
-
static struct nla_policy ifla_port_policy[IFLA_PORT_MAX + 1] =
{
[IFLA_PORT_RESPONSE] = { .type = NLA_U16 },
@@ -764,173 +455,6 @@ getLldpadPid(void) {
}
-static int
-link_dump(bool nltarget_kernel, const char *ifname, int ifindex,
- struct nlattr **tb, unsigned char **recvbuf)
-{
- int rc = 0;
- struct nlmsghdr *resp;
- struct nlmsgerr *err;
- struct ifinfomsg ifinfo = {
- .ifi_family = AF_UNSPEC,
- .ifi_index = ifindex
- };
- unsigned int recvbuflen;
- uint32_t pid = 0;
- struct nl_msg *nl_msg;
-
- *recvbuf = NULL;
-
- nl_msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
- if (!nl_msg) {
- virReportOOMError();
- return -1;
- }
-
- if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
- goto buffer_too_small;
-
- if (ifindex < 0 && ifname) {
- if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
- goto buffer_too_small;
- }
-
- if (!nltarget_kernel) {
- pid = getLldpadPid();
- if (pid == 0) {
- rc = -1;
- goto err_exit;
- }
- }
-
- if (nlComm(nl_msg, recvbuf, &recvbuflen, pid) < 0) {
- rc = -1;
- goto err_exit;
- }
-
- if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL)
- goto malformed_resp;
-
- resp = (struct nlmsghdr *)*recvbuf;
-
- switch (resp->nlmsg_type) {
- case NLMSG_ERROR:
- err = (struct nlmsgerr *)NLMSG_DATA(resp);
- if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
- goto malformed_resp;
-
- if (err->error) {
- virReportSystemError(-err->error,
- _("error dumping %s (%d) interface"),
- ifname, ifindex);
- rc = -1;
- }
- break;
-
- case GENL_ID_CTRL:
- case NLMSG_DONE:
- if (nlmsg_parse(resp, sizeof(struct ifinfomsg),
- tb, IFLA_MAX, ifla_policy)) {
- goto malformed_resp;
- }
- break;
-
- default:
- goto malformed_resp;
- }
-
- if (rc != 0)
- VIR_FREE(*recvbuf);
-
-err_exit:
- nlmsg_free(nl_msg);
-
- return rc;
-
-malformed_resp:
- nlmsg_free(nl_msg);
-
- macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("malformed netlink response message"));
- VIR_FREE(*recvbuf);
- return -1;
-
-buffer_too_small:
- nlmsg_free(nl_msg);
-
- macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("allocated netlink buffer is too small"));
- return -1;
-}
-
-
-/**
- * ifaceGetNthParent
- *
- * @ifindex : the index of the interface or -1 if ifname is given
- * @ifname : the name of the interface; ignored if ifindex is valid
- * @nthParent : the nth parent interface to get
- * @parent_ifindex : pointer to int
- * @parent_ifname : pointer to buffer of size IFNAMSIZ
- * @nth : the nth parent that is actually returned; if for example eth0.100
- * was given and the 100th parent is to be returned, then eth0 will
- * most likely be returned with nth set to 1 since the chain does
- * not have more interfaces
- *
- * Get the nth parent interface of the given interface. 0 is the interface
- * itself.
- *
- * Return 0 on success, != 0 otherwise
- */
-static int
-ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent,
- int *parent_ifindex, char *parent_ifname,
- unsigned int *nth)
-{
- int rc;
- struct nlattr *tb[IFLA_MAX + 1] = { NULL, };
- unsigned char *recvbuf = NULL;
- bool end = false;
- unsigned int i = 0;
-
- *nth = 0;
-
- if (ifindex <= 0 && ifaceGetIndex(true, ifname, &ifindex) != 0)
- return 1;
-
- while (!end && i <= nthParent) {
- rc = link_dump(true, ifname, ifindex, tb, &recvbuf);
- if (rc)
- break;
-
- if (tb[IFLA_IFNAME]) {
- if (!virStrcpy(parent_ifname, (char*)RTA_DATA(tb[IFLA_IFNAME]),
- IFNAMSIZ)) {
- macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("buffer for root interface name is too small"));
- VIR_FREE(recvbuf);
- return 1;
- }
- *parent_ifindex = ifindex;
- }
-
- if (tb[IFLA_LINK]) {
- ifindex = *(int *)RTA_DATA(tb[IFLA_LINK]);
- ifname = NULL;
- } else
- end = true;
-
- VIR_FREE(recvbuf);
-
- i++;
- }
-
- if (nth)
- *nth = i - 1;
-
- return rc;
-}
-
/**
* getPortProfileStatus
*
@@ -1258,7 +782,8 @@ doPortProfileOpCommon(bool nltarget_kern
}
while (--repeats >= 0) {
- rc = link_dump(nltarget_kernel, NULL, ifindex, tb, &recvbuf);
+ rc = ifaceMacvtapLinkDump(nltarget_kernel, NULL, ifindex, tb,
+ &recvbuf, getLldpadPid);
if (rc)
goto err_exit;
rc = getPortProfileStatus(tb, vf, instanceId, nltarget_kernel,
Index: libvirt-acl/src/libvirt_private.syms
===================================================================
--- libvirt-acl.orig/src/libvirt_private.syms
+++ libvirt-acl/src/libvirt_private.syms
@@ -499,9 +499,15 @@ ifaceCtrl;
ifaceGetFlags;
ifaceGetIndex;
ifaceGetMacaddr;
+ifaceGetNthParent;
ifaceGetVlanID;
-ifaceSetMacaddr;
ifaceIsUp;
+ifaceLinkDel;
+ifaceMacvtapLinkAdd;
+ifaceMacvtapLinkDump;
+ifaceReplaceMacAddress;
+ifaceRestoreMacaddress;
+ifaceSetMacaddr;
# interface_conf.h
13 years, 5 months
[libvirt] [PATCH 1/4] virStorageVol: avoid PATH_MAX-sized array
by Eric Blake
POSIX allows implementations where PATH_MAX is undefined, leading
to compilation error. Not to mention that even if it is defined,
it is often wasteful in relation to the amount of data being stored.
All clients of vol->key were audited, and found not to care about
whether key is static or dynamic, except for these offenders:
* src/datatypes.h (struct _virStorageVol): Manage key dynamically.
* src/datatypes.c (virReleaseStorageVol): Free key.
(virGetStorageVol): Copy key.
---
I'm also adding a 'make syntax-check' rule in gnulib to catch this
from being a problem in the future:
http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/27259
src/datatypes.c | 8 +++++---
src/datatypes.h | 5 ++---
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/datatypes.c b/src/datatypes.c
index 4c4cbd0..f0b5025 100644
--- a/src/datatypes.c
+++ b/src/datatypes.c
@@ -738,10 +738,10 @@ virGetStorageVol(virConnectPtr conn, const char *pool, const char *name,
virReportOOMError();
goto error;
}
- if (virStrcpyStatic(ret->key, key) == NULL) {
+ ret->key = strdup(key);
+ if (ret->key == NULL) {
virMutexUnlock(&conn->lock);
- virLibConnError(VIR_ERR_INTERNAL_ERROR,
- _("Volume key %s too large for destination"), key);
+ virReportOOMError();
goto error;
}
ret->magic = VIR_STORAGE_VOL_MAGIC;
@@ -754,6 +754,7 @@ virGetStorageVol(virConnectPtr conn, const char *pool, const char *name,
error:
if (ret != NULL) {
+ VIR_FREE(ret->key);
VIR_FREE(ret->name);
VIR_FREE(ret->pool);
VIR_FREE(ret);
@@ -780,6 +781,7 @@ virReleaseStorageVol(virStorageVolPtr vol) {
VIR_DEBUG("release vol %p %s", vol, vol->name);
vol->magic = -1;
+ VIR_FREE(vol->key);
VIR_FREE(vol->name);
VIR_FREE(vol->pool);
VIR_FREE(vol);
diff --git a/src/datatypes.h b/src/datatypes.h
index ebda992..f114360 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -1,7 +1,7 @@
/*
* datatypes.h: management of structs for public data types
*
- * Copyright (C) 2006-2008, 2010 Red Hat, Inc.
+ * Copyright (C) 2006-2008, 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -254,8 +254,7 @@ struct _virStorageVol {
virConnectPtr conn; /* pointer back to the connection */
char *pool; /* Pool name of owner */
char *name; /* the storage vol external name */
- /* XXX currently abusing path for this. Ought not to be so evil */
- char key[PATH_MAX]; /* unique key for storage vol */
+ char *key; /* unique key for storage vol */
};
/**
--
1.7.4.4
13 years, 5 months
[libvirt] [PATCH] maint: add omitted copyright header
by Eric Blake
Bug introduced in commit 6a597883.
* src/util/netlink.h: Add boilerplate.
---
Pushing under the trivial rule.
src/util/netlink.h | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/src/util/netlink.h b/src/util/netlink.h
index dc634aa..05981bd 100644
--- a/src/util/netlink.h
+++ b/src/util/netlink.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010 IBM Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
#ifndef __VIR_NETLINK_H__
# define __VIR_NETLINK_H__
--
1.7.4.4
13 years, 5 months
[libvirt] [PATCH 0/5 v3] Add NUMA memory tuning support
by Osier Yang
Hi,
This series incorporated previous feedbacks received on the
XML schema, especially on syntax of "nodeset". Now using same
syntax of "cpuset" of "vcpu". And doing conversion in qemu
driver internally, as libnuma uses different bitmask format
to represent NUMA nodes.
The XML is like:
<numatune>
<memory mode="strict" nodeset="0-10,^5"/>
</numatune>
Value of "mode" can be either of "strict", "preferred", or
"interleave".
One may specify nodemask which is out of range, for this
case, libvirt will report soft warnings instead of hard
error. (Kernel is silent as long as one of the set bit is
valid, E.g. For a host with 2 NUMA nodes, kernel will be
silent for nodemask "0101010101", as first "bit" which
represents the first NUMA node is set). The reason for
reporting soft warnings instead of hard error is one may
want to define the memory tuning policy priorly with a node
doesn't exist yet, but may come soon.
Any feedback is appreciated.
[PATCH 1/5 v3] numatune: Define xml schema
[PATCH 2/5 v3] numatune: Add doc for new numatune xml
[PATCH 3/5 v3] numatune: Support persistent XML for numatune
[PATCH 4/5 v3] numatune: Support numa tuning in qemu driver.
[PATCH 5/5 v3] numatune: Add tests for numatune XML
Regards
Osier
13 years, 5 months
[libvirt] [PATCH] docs: fix docs to match behavior of virConnectClose
by Eric Blake
* src/libvirt.c (virConnectClose): Mention reference count return.
Reported by Michal Novotny, analyzed by Matthias Bolte.
---
src/libvirt.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index c57e0c3..b9765b1 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1295,7 +1295,12 @@ error:
* especially if there is running domain which need further monitoring by
* the application.
*
- * Returns 0 in case of success or -1 in case of error.
+ * Connections are reference counted; the connection is not actually
+ * closed until all calls to virConnectRef have had a matching
+ * virConnectClose call.
+ *
+ * Returns the number of remaining references (positive if the connection
+ * remains open, 0 if closed) in case of success or -1 in case of error.
*/
int
virConnectClose(virConnectPtr conn)
--
1.7.4.4
13 years, 5 months
[libvirt] [PATCH 0/6] Add support for injecting NMI to guest
by Lai Jiangshan
This patch series implements a feature of injecting NMI to guest,
which is accessible via new virDomainInjectNMI API and
'inject-nmi' command in virsh.
Lai Jiangshan (6):
inject-nmi: Defining the public API
inject-nmi: Defining the internal API
inject-nmi: Implementing the public API
inject-nmi: Implementing the remote protocol
inject-nmi: Expose the new API in virsh
qemu,inject-nmi: Implement the driver methods
daemon/remote.c | 26 ++++++++++++++++++++
daemon/remote_dispatch_args.h | 1 +
daemon/remote_dispatch_prototypes.h | 8 ++++++
daemon/remote_dispatch_table.h | 5 ++++
include/libvirt/libvirt.h.in | 2 +
src/driver.h | 4 +++
src/esx/esx_driver.c | 1 +
src/libvirt.c | 44 +++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 5 ++++
src/libxl/libxl_driver.c | 1 +
src/lxc/lxc_driver.c | 1 +
src/openvz/openvz_driver.c | 1 +
src/phyp/phyp_driver.c | 3 +-
src/qemu/qemu_driver.c | 43 ++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor.c | 14 +++++++++++
src/qemu/qemu_monitor.h | 2 +
src/qemu/qemu_monitor_json.c | 29 +++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 1 +
src/qemu/qemu_monitor_text.c | 20 ++++++++++++++++
src/qemu/qemu_monitor_text.h | 1 +
src/remote/remote_driver.c | 25 +++++++++++++++++++
src/remote/remote_protocol.c | 11 ++++++++
src/remote/remote_protocol.h | 10 ++++++++
src/remote/remote_protocol.x | 8 +++++-
src/remote_protocol-structs | 4 +++
src/test/test_driver.c | 1 +
src/uml/uml_driver.c | 1 +
src/vbox/vbox_tmpl.c | 1 +
src/vmware/vmware_driver.c | 1 +
src/xen/xen_driver.c | 1 +
src/xen/xen_driver.h | 1 +
src/xen/xen_hypervisor.c | 1 +
src/xen/xen_inotify.c | 1 +
src/xen/xend_internal.c | 1 +
src/xen/xm_internal.c | 1 +
src/xen/xs_internal.c | 1 +
src/xenapi/xenapi_driver.c | 1 +
tools/virsh.c | 36 ++++++++++++++++++++++++++++
tools/virsh.pod | 4 +++
39 files changed, 320 insertions(+), 2 deletions(-)
--
1.7.4
13 years, 5 months
[libvirt] [PATCH 1/2 V2] cleanup: make nlComm commonly available
by Stefan Berger
In a first cleanup step, make nlComm from macvtap.c commonly available
for other code to use. Since nlComm uses Linux-specific structures as
parameters it's prototype is only visible on Linux.
v2:
- making nlComm visible also on non-Linux platforms
Signed-off-by: Stefan Berger <stefanb(a)linux.vnet.ibm.com>
---
src/Makefile.am | 1
src/libvirt_private.syms | 4 +
src/util/macvtap.c | 98 ------------------------------
src/util/netlink.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++
src/util/netlink.h | 18 +++++
5 files changed, 176 insertions(+), 97 deletions(-)
Index: libvirt-acl/src/Makefile.am
===================================================================
--- libvirt-acl.orig/src/Makefile.am
+++ libvirt-acl/src/Makefile.am
@@ -63,6 +63,7 @@ UTIL_SOURCES = \
util/logging.c util/logging.h \
util/macvtap.c util/macvtap.h \
util/memory.c util/memory.h \
+ util/netlink.c util/netlink.h \
util/pci.c util/pci.h \
util/processinfo.c util/processinfo.h \
util/hostusb.c util/hostusb.h \
Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -39,12 +39,8 @@
# include <sys/ioctl.h>
# include <linux/if.h>
-# include <linux/netlink.h>
-# include <linux/rtnetlink.h>
# include <linux/if_tun.h>
-# include <netlink/msg.h>
-
/* Older kernels lacked this enum value. */
# if !HAVE_DECL_MACVLAN_MODE_PASSTHRU
# define MACVLAN_MODE_PASSTHRU 8
@@ -64,6 +60,7 @@
# include "virterror_internal.h"
# include "uuid.h"
# include "files.h"
+# include "netlink.h"
# define VIR_FROM_THIS VIR_FROM_NET
@@ -79,8 +76,6 @@
# define NLMSGBUF_SIZE 256
# define RATTBUF_SIZE 64
-# define NETLINK_ACK_TIMEOUT_S 2
-
# define STATUS_POLL_TIMEOUT_USEC (10 * MICROSEC_PER_SEC)
# define STATUS_POLL_INTERVL_USEC (MICROSEC_PER_SEC / 8)
@@ -96,97 +91,6 @@ enum virVirtualPortOp {
};
-/**
- * nlComm:
- * @nlmsg: pointer to netlink message
- * @respbuf: pointer to pointer where response buffer will be allocated
- * @respbuflen: pointer to integer holding the size of the response buffer
- * on return of the function.
- * @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
- *
- * Send the given message to the netlink layer and receive response.
- * Returns 0 on success, -1 on error. In case of error, no response
- * buffer will be returned.
- */
-static
-int nlComm(struct nl_msg *nl_msg,
- unsigned char **respbuf, unsigned int *respbuflen,
- int nl_pid)
-{
- int rc = 0;
- struct sockaddr_nl nladdr = {
- .nl_family = AF_NETLINK,
- .nl_pid = nl_pid,
- .nl_groups = 0,
- };
- ssize_t nbytes;
- struct timeval tv = {
- .tv_sec = NETLINK_ACK_TIMEOUT_S,
- };
- fd_set readfds;
- int fd;
- int n;
- struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
- struct nl_handle *nlhandle = nl_handle_alloc();
-
- if (!nlhandle) {
- virReportSystemError(errno,
- "%s", _("cannot allocate nlhandle for netlink"));
- return -1;
- }
-
- if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
- virReportSystemError(errno,
- "%s", _("cannot connect to netlink socket"));
- rc = -1;
- goto err_exit;
- }
-
- nlmsg_set_dst(nl_msg, &nladdr);
-
- nlmsg->nlmsg_pid = getpid();
-
- nbytes = nl_send_auto_complete(nlhandle, nl_msg);
- if (nbytes < 0) {
- virReportSystemError(errno,
- "%s", _("cannot send to netlink socket"));
- rc = -1;
- goto err_exit;
- }
-
- fd = nl_socket_get_fd(nlhandle);
-
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
-
- n = select(fd + 1, &readfds, NULL, NULL, &tv);
- if (n <= 0) {
- if (n < 0)
- virReportSystemError(errno, "%s",
- _("error in select call"));
- if (n == 0)
- virReportSystemError(ETIMEDOUT, "%s",
- _("no valid netlink response was received"));
- rc = -1;
- goto err_exit;
- }
-
- *respbuflen = nl_recv(nlhandle, &nladdr, respbuf, NULL);
- if (*respbuflen <= 0) {
- virReportSystemError(errno,
- "%s", _("nl_recv failed"));
- rc = -1;
- }
-err_exit:
- if (rc == -1) {
- VIR_FREE(*respbuf);
- *respbuf = NULL;
- *respbuflen = 0;
- }
-
- nl_handle_destroy(nlhandle);
- return rc;
-}
# if WITH_MACVTAP
Index: libvirt-acl/src/util/netlink.c
===================================================================
--- /dev/null
+++ libvirt-acl/src/util/netlink.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010 IBM Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Stefan Berger <stefanb(a)us.ibm.com>
+ *
+ * Notes:
+ * netlink: http://lovezutto.googlepages.com/netlink.pdf
+ * iproute2 package
+ *
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "netlink.h"
+#include "memory.h"
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_NET
+
+# define netlinkError(code, ...) \
+ virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define NETLINK_ACK_TIMEOUT_S 2
+
+/**
+ * nlComm:
+ * @nlmsg: pointer to netlink message
+ * @respbuf: pointer to pointer where response buffer will be allocated
+ * @respbuflen: pointer to integer holding the size of the response buffer
+ * on return of the function.
+ * @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
+ *
+ * Send the given message to the netlink layer and receive response.
+ * Returns 0 on success, -1 on error. In case of error, no response
+ * buffer will be returned.
+ */
+#if __linux__
+int nlComm(struct nl_msg *nl_msg,
+ unsigned char **respbuf, unsigned int *respbuflen,
+ int nl_pid)
+{
+ int rc = 0;
+ struct sockaddr_nl nladdr = {
+ .nl_family = AF_NETLINK,
+ .nl_pid = nl_pid,
+ .nl_groups = 0,
+ };
+ ssize_t nbytes;
+ struct timeval tv = {
+ .tv_sec = NETLINK_ACK_TIMEOUT_S,
+ };
+ fd_set readfds;
+ int fd;
+ int n;
+ struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
+ struct nl_handle *nlhandle = nl_handle_alloc();
+
+ if (!nlhandle) {
+ virReportSystemError(errno,
+ "%s", _("cannot allocate nlhandle for netlink"));
+ return -1;
+ }
+
+ if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
+ virReportSystemError(errno,
+ "%s", _("cannot connect to netlink socket"));
+ rc = -1;
+ goto err_exit;
+ }
+
+ nlmsg_set_dst(nl_msg, &nladdr);
+
+ nlmsg->nlmsg_pid = getpid();
+
+ nbytes = nl_send_auto_complete(nlhandle, nl_msg);
+ if (nbytes < 0) {
+ virReportSystemError(errno,
+ "%s", _("cannot send to netlink socket"));
+ rc = -1;
+ goto err_exit;
+ }
+
+ fd = nl_socket_get_fd(nlhandle);
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ n = select(fd + 1, &readfds, NULL, NULL, &tv);
+ if (n <= 0) {
+ if (n < 0)
+ virReportSystemError(errno, "%s",
+ _("error in select call"));
+ if (n == 0)
+ virReportSystemError(ETIMEDOUT, "%s",
+ _("no valid netlink response was received"));
+ rc = -1;
+ goto err_exit;
+ }
+
+ *respbuflen = nl_recv(nlhandle, &nladdr, respbuf, NULL);
+ if (*respbuflen <= 0) {
+ virReportSystemError(errno,
+ "%s", _("nl_recv failed"));
+ rc = -1;
+ }
+err_exit:
+ if (rc == -1) {
+ VIR_FREE(*respbuf);
+ *respbuf = NULL;
+ *respbuflen = 0;
+ }
+
+ nl_handle_destroy(nlhandle);
+ return rc;
+}
+
+#else
+
+int nlComm(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
+ unsigned char **respbuf ATTRIBUTE_UNUSED,
+ unsigned int *respbuflen ATTRIBUTE_UNUSED,
+ int nl_pid ATTRIBUTE_UNUSED)
+{
+ netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("nlComm is not supported on non-linux platforms"));
+ return -1;
+}
+
+
+#endif /* __linux__ */
+
Index: libvirt-acl/src/util/netlink.h
===================================================================
--- /dev/null
+++ libvirt-acl/src/util/netlink.h
@@ -0,0 +1,18 @@
+#ifndef __VIR_NETLINK_H__
+# define __VIR_NETLINK_H__
+
+# if __linux__
+
+# include <netlink/msg.h>
+
+# else
+
+struct nl_msg;
+
+#endif /* __linux__ */
+
+int nlComm(struct nl_msg *nl_msg,
+ unsigned char **respbuf, unsigned int *respbuflen,
+ int nl_pid);
+
+#endif /* __VIR_NETLINK_H__ */
Index: libvirt-acl/src/libvirt_private.syms
===================================================================
--- libvirt-acl.orig/src/libvirt_private.syms
+++ libvirt-acl/src/libvirt_private.syms
@@ -668,6 +668,10 @@ virResizeN;
virShrinkN;
+#netlink.h
+nlComm;
+
+
# network.h
virSocketAddrBroadcast;
virSocketAddrBroadcastByPrefix;
13 years, 5 months
[libvirt] [PATCH] Replace @SYSCONFDIR@ with ::SYSCONFDIR:: to avoid syntax-check warning
by Daniel P. Berrange
make syntax-check complains if any Makefile.am uses the old
style @FOO@ for replacement, rather than $(FOO).
Unfortunately the tools/Makefile.am intentionally uses the
@FOO@ syntax for generating some scripts. Currently these
are whitelisted in cfg.mk, but adding more to this whitelist
makes the entire check rather worthless.
This changes the tools/ directory to use ::FOO:: as the
replacement syntax for virt-pki-validate.in and
virt-xml-validate.in
* tools/Makefile.am, tools/virt-pki-validate.in
tools/virt-xml-validate.in: Change @FOO@ to ::FOO::
* cfg.mk: Remove _makefile_at_at_check_exceptions
---
cfg.mk | 3 ---
tools/Makefile.am | 4 ++--
tools/virt-pki-validate.in | 2 +-
tools/virt-xml-validate.in | 2 +-
4 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index 5d3ef26..c2230b8 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -581,9 +581,6 @@ _autogen:
$(srcdir)/autogen.sh
./config.status
-# Exempt @...@ uses of these symbols.
-_makefile_at_at_check_exceptions = ' && !/(SCHEMA|SYSCONF)DIR/'
-
# regenerate HACKING as part of the syntax-check
syntax-check: $(top_srcdir)/HACKING
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 826674a..7a1a5c6 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -23,14 +23,14 @@ dist_man1_MANS = virt-xml-validate.1 virt-pki-validate.1 virsh.1
virt-xml-validate: virt-xml-validate.in Makefile
- $(AM_V_GEN)sed -e 's,@SCHEMADIR@,$(pkgdatadir)/schemas,' < $< > $@ \
+ $(AM_V_GEN)sed -e 's,::SCHEMADIR::,$(pkgdatadir)/schemas,' < $< > $@ \
|| (rm $@ && exit 1) && chmod +x $@
virt-xml-validate.1: virt-xml-validate.in
$(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
virt-pki-validate: virt-pki-validate.in Makefile
- $(AM_V_GEN)sed -e 's,@SYSCONFDIR@,$(sysconfdir),' < $< > $@ \
+ $(AM_V_GEN)sed -e 's,::SYSCONFDIR::,$(sysconfdir),' < $< > $@ \
|| (rm $@ && exit 1) && chmod +x $@
virt-pki-validate.1: virt-pki-validate.in
diff --git a/tools/virt-pki-validate.in b/tools/virt-pki-validate.in
index 01825d1..f429d77 100755
--- a/tools/virt-pki-validate.in
+++ b/tools/virt-pki-validate.in
@@ -25,7 +25,7 @@ echo Found "$CERTOOL"
#
# Check the directory structure
#
-SYSCONFDIR="@SYSCONFDIR@"
+SYSCONFDIR="::SYSCONFDIR::"
PKI="$SYSCONFDIR/pki"
if [ ! -d "$PKI" ]
then
diff --git a/tools/virt-xml-validate.in b/tools/virt-xml-validate.in
index 1959261..33f6c0f 100644
--- a/tools/virt-xml-validate.in
+++ b/tools/virt-xml-validate.in
@@ -57,7 +57,7 @@ if [ -z "$TYPE" ]; then
esac
fi
-SCHEMA="@SCHEMADIR(a)/${TYPE}.rng"
+SCHEMA="::SCHEMADIR::/${TYPE}.rng"
if [ ! -f "$SCHEMA" ]; then
echo "$0: schema $SCHEMA does not exist"
--
1.7.4.4
13 years, 5 months