提交 a65871aa 编写于 作者: J Ján Tomko

Fix vlan ID detection in udev interface driver

Instead of guessing it from the interface name, look into
/proc/net/vlan/<interface>.

This works for devices not named <real_device>.<vlan ID>,
avoiding an error flood when virt-manager keeps asking about
them every second:

https://bugzilla.redhat.com/show_bug.cgi?id=966329
上级 5c2f782f
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <libudev.h> #include <libudev.h>
#include "virerror.h" #include "virerror.h"
#include "virfile.h"
#include "c-ctype.h" #include "c-ctype.h"
#include "datatypes.h" #include "datatypes.h"
#include "domain_conf.h" #include "domain_conf.h"
...@@ -966,31 +967,64 @@ udevGetIfaceDefVlan(struct udev *udev ATTRIBUTE_UNUSED, ...@@ -966,31 +967,64 @@ udevGetIfaceDefVlan(struct udev *udev ATTRIBUTE_UNUSED,
const char *name, const char *name,
virInterfaceDef *ifacedef) virInterfaceDef *ifacedef)
{ {
const char *vid; char *procpath = NULL;
char *buf = NULL;
char *vid_pos, *dev_pos;
size_t vid_len, dev_len;
const char *vid_prefix = "VID: ";
const char *dev_prefix = "\nDevice: ";
int ret = -1;
if (virAsprintf(&procpath, "/proc/net/vlan/%s", name) < 0)
goto cleanup;
if (virFileReadAll(procpath, BUFSIZ, &buf) < 0)
goto cleanup;
/* Find the DEVICE.VID again */ if ((vid_pos = strstr(buf, vid_prefix)) == NULL) {
vid = strrchr(name, '.');
if (!vid) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to find the VID for the VLAN device '%s'"), _("failed to find the VID for the VLAN device '%s'"),
name); name);
return -1; goto cleanup;
} }
vid_pos += strlen(vid_prefix);
/* Set the VLAN specifics */ if ((vid_len = strspn(vid_pos, "0123456789")) == 0 ||
if (VIR_STRDUP(ifacedef->data.vlan.tag, vid + 1) < 0) !c_isspace(vid_pos[vid_len])) {
goto error; virReportError(VIR_ERR_INTERNAL_ERROR,
if (VIR_STRNDUP(ifacedef->data.vlan.devname, _("failed to find the VID for the VLAN device '%s'"),
name, (vid - name)) < 0) name);
goto error; goto cleanup;
}
return 0; if ((dev_pos = strstr(vid_pos + vid_len, dev_prefix)) == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to find the real device for the VLAN device '%s'"),
name);
goto cleanup;
}
dev_pos += strlen(dev_prefix);
error: if ((dev_len = strcspn(dev_pos, "\n")) == 0) {
VIR_FREE(ifacedef->data.vlan.tag); virReportError(VIR_ERR_INTERNAL_ERROR,
VIR_FREE(ifacedef->data.vlan.devname); _("failed to find the real device for the VLAN device '%s'"),
name);
goto cleanup;
}
return -1; if (VIR_STRNDUP(ifacedef->data.vlan.tag, vid_pos, vid_len) < 0)
goto cleanup;
if (VIR_STRNDUP(ifacedef->data.vlan.devname, dev_pos, dev_len) < 0) {
VIR_FREE(ifacedef->data.vlan.tag);
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(procpath);
VIR_FREE(buf);
return ret;
} }
static virInterfaceDef * ATTRIBUTE_NONNULL(1) static virInterfaceDef * ATTRIBUTE_NONNULL(1)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册