return 0;
}
-static int netcfConnectNumOfInterfaces(virConnectPtr conn)
+static int netcfConnectNumOfInterfacesImpl(virConnectPtr conn,
+ int status,
+ virInterfaceObjListFilter filter)
{
- int count;
struct interface_driver *driver = conn->interfacePrivateData;
+ int count;
+ int want = 0;
+ int ret = -1;
+ int i;
+ char **names = NULL;
- if (virConnectNumOfInterfacesEnsureACL(conn) < 0)
- return -1;
-
- interfaceDriverLock(driver);
- count = ncf_num_of_interfaces(driver->netcf, NETCF_IFACE_ACTIVE);
+ /* List all interfaces, in case we might support new filter flags
+ * beyond active|inactive in future.
+ */
+ count = ncf_num_of_interfaces(driver->netcf, status);
if (count < 0) {
const char *errmsg, *details;
int errcode = ncf_error(driver->netcf, &errmsg, &details);
virReportError(netcf_to_vir_err(errcode),
- _("failed to get number of interfaces on host: %s%s%s"),
- errmsg, details ? " - " : "", details ? details : "");
+ _("failed to get number of host interfaces: %s%s%s"),
+ errmsg, details ? " - " : "",
+ details ? details : "");
+ goto cleanup;
}
- interfaceDriverUnlock(driver);
- return count;
+ if (count == 0) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC_N(names, count) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if ((count = ncf_list_interfaces(driver->netcf, count, names, status)) < 0) {
+ const char *errmsg, *details;
+ int errcode = ncf_error(driver->netcf, &errmsg, &details);
+ virReportError(netcf_to_vir_err(errcode),
+ _("failed to list host interfaces: %s%s%s"),
+ errmsg, details ? " - " : "",
+ details ? details : "");
+ goto cleanup;
+ }
+
+ for (i = 0; i < count; i++) {
+ virInterfaceDefPtr def;
+ struct netcf_if *iface;
+
+ iface = ncf_lookup_by_name(driver->netcf, names[i]);
+ if (!iface) {
+ const char *errmsg, *details;
+ int errcode = ncf_error(driver->netcf, &errmsg, &details);
+ if (errcode != NETCF_NOERROR) {
+ virReportError(netcf_to_vir_err(errcode),
+ _("couldn't find interface named '%s': %s%s%s"),
+ names[i], errmsg,
+ details ? " - " : "", details ? details : "");
+ goto cleanup;
+ } else {
+ /* Ignore the NETCF_NOERROR, as the interface is very likely
+ * deleted by other management apps (e.g. virt-manager).
+ */
+ VIR_WARN("couldn't find interface named '%s', might be "
+ "deleted by other process", names[i]);
+ continue;
+ }
+ }
+
+ if (!(def = netcfGetMinimalDefForDevice(iface))) {
+ ncf_if_free(iface);
+ goto cleanup;
+ }
+ ncf_if_free(iface);
+
+ if (!filter(conn, def)) {
+ virInterfaceDefFree(def);
+ continue;
+ }
+ virInterfaceDefFree(def);
+
+ want++;
+ }
+
+ ret = want;
+
+cleanup:
+ if (names)
+ for (i = 0; i < count; i++)
+ VIR_FREE(names[i]);
+ VIR_FREE(names);
+ return ret;
}
-static int netcfConnectListInterfaces(virConnectPtr conn, char **const names, int nnames)
+
+static int netcfConnectListInterfacesImpl(virConnectPtr conn,
+ int status,
+ char **const names, int nnames,
+ virInterfaceObjListFilter filter)
{
struct interface_driver *driver = conn->interfacePrivateData;
- int count;
+ int count = 0;
+ int want = 0;
+ int ret = -1;
+ int i;
+ char **allnames = NULL;
- if (virConnectListInterfacesEnsureACL(conn) < 0)
- return -1;
+ count = ncf_num_of_interfaces(driver->netcf, status);
+ if (count < 0) {
+ const char *errmsg, *details;
+ int errcode = ncf_error(driver->netcf, &errmsg, &details);
+ virReportError(netcf_to_vir_err(errcode),
+ _("failed to get number of host interfaces: %s%s%s"),
+ errmsg, details ? " - " : "",
+ details ? details : "");
+ goto cleanup;
+ }
- interfaceDriverLock(driver);
+ if (count == 0) {
+ ret = 0;
+ goto cleanup;
+ }
- count = ncf_list_interfaces(driver->netcf, nnames, names, NETCF_IFACE_ACTIVE);
- if (count < 0) {
+ if (VIR_ALLOC_N(allnames, count) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if ((count = ncf_list_interfaces(driver->netcf, count, allnames, status)) < 0) {
const char *errmsg, *details;
int errcode = ncf_error(driver->netcf, &errmsg, &details);
virReportError(netcf_to_vir_err(errcode),
_("failed to list host interfaces: %s%s%s"),
errmsg, details ? " - " : "",
details ? details : "");
+ goto cleanup;
+ }
+
+ if (count == 0) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ for (i = 0; i < count && want < nnames; i++) {
+ virInterfaceDefPtr def;
+ struct netcf_if *iface;
+
+ iface = ncf_lookup_by_name(driver->netcf, allnames[i]);
+ if (!iface) {
+ const char *errmsg, *details;
+ int errcode = ncf_error(driver->netcf, &errmsg, &details);
+ if (errcode != NETCF_NOERROR) {
+ virReportError(netcf_to_vir_err(errcode),
+ _("couldn't find interface named '%s': %s%s%s"),
+ allnames[i], errmsg,
+ details ? " - " : "", details ? details : "");
+ goto cleanup;
+ } else {
+ /* Ignore the NETCF_NOERROR, as the interface is very likely
+ * deleted by other management apps (e.g. virt-manager).
+ */
+ VIR_WARN("couldn't find interface named '%s', might be "
+ "deleted by other process", allnames[i]);
+ continue;
+ }
+ }
+
+ if (!(def = netcfGetMinimalDefForDevice(iface))) {
+ ncf_if_free(iface);
+ goto cleanup;
+ }
+ ncf_if_free(iface);
+
+ if (!filter(conn, def)) {
+ virInterfaceDefFree(def);
+ continue;
+ }
+ virInterfaceDefFree(def);
+
+ names[want++] = allnames[i];
+ allnames[i] = NULL;
+ }
+
+ ret = want;
+
+cleanup:
+ if (allnames)
+ for (i = 0; i < count; i++)
+ VIR_FREE(allnames[i]);
+ VIR_FREE(allnames);
+ if (ret < 0) {
+ for (i = 0; i < nnames; i++)
+ VIR_FREE(names[i]);
}
+ return ret;
+}
+
+static int netcfConnectNumOfInterfaces(virConnectPtr conn)
+{
+ int count;
+ struct interface_driver *driver = conn->interfacePrivateData;
+
+ if (virConnectNumOfInterfacesEnsureACL(conn) < 0)
+ return -1;
+
+ interfaceDriverLock(driver);
+ count = netcfConnectNumOfInterfacesImpl(conn,
+ NETCF_IFACE_ACTIVE,
+ virConnectNumOfInterfacesCheckACL);
+ interfaceDriverUnlock(driver);
+ return count;
+}
+
+static int netcfConnectListInterfaces(virConnectPtr conn, char **const names, int nnames)
+{
+ struct interface_driver *driver = conn->interfacePrivateData;
+ int count;
+
+ if (virConnectListInterfacesEnsureACL(conn) < 0)
+ return -1;
+
+ interfaceDriverLock(driver);
+ count = netcfConnectListInterfacesImpl(conn,
+ NETCF_IFACE_ACTIVE,
+ names, nnames,
+ virConnectListInterfacesCheckACL);
interfaceDriverUnlock(driver);
return count;
return -1;
interfaceDriverLock(driver);
- count = ncf_num_of_interfaces(driver->netcf, NETCF_IFACE_INACTIVE);
- if (count < 0) {
- const char *errmsg, *details;
- int errcode = ncf_error(driver->netcf, &errmsg, &details);
- virReportError(netcf_to_vir_err(errcode),
- _("failed to get number of defined interfaces on host: %s%s%s"),
- errmsg, details ? " - " : "",
- details ? details : "");
- }
-
+ count = netcfConnectNumOfInterfacesImpl(conn,
+ NETCF_IFACE_INACTIVE,
+ virConnectNumOfDefinedInterfacesCheckACL);
interfaceDriverUnlock(driver);
return count;
}
return -1;
interfaceDriverLock(driver);
-
- count = ncf_list_interfaces(driver->netcf, nnames, names, NETCF_IFACE_INACTIVE);
- if (count < 0) {
- const char *errmsg, *details;
- int errcode = ncf_error(driver->netcf, &errmsg, &details);
- virReportError(netcf_to_vir_err(errcode),
- _("failed to list host defined interfaces: %s%s%s"),
- errmsg, details ? " - " : "",
- details ? details : "");
- }
-
+ count = netcfConnectListInterfacesImpl(conn,
+ NETCF_IFACE_INACTIVE,
+ names, nnames,
+ virConnectListDefinedInterfacesCheckACL);
interfaceDriverUnlock(driver);
return count;
}
for (i = 0; i < count; i++) {
+ virInterfaceDefPtr def;
iface = ncf_lookup_by_name(driver->netcf, names[i]);
if (!iface) {
const char *errmsg, *details;
goto cleanup;
}
- /* XXX: Filter the result, need to be splitted once new filter flags
+ if (!(def = netcfGetMinimalDefForDevice(iface)))
+ goto cleanup;
+
+ if (!virConnectListAllInterfacesCheckACL(conn, def)) {
+ ncf_if_free(iface);
+ iface = NULL;
+ virInterfaceDefFree(def);
+ continue;
+ }
+ virInterfaceDefFree(def);
+
+ /* XXX: Filter the result, need to be split once new filter flags
* except active|inactive are supported.
*/
if (MATCH(VIR_CONNECT_LIST_INTERFACES_FILTERS_ACTIVE) &&
}
static int
-udevNumOfInterfacesByStatus(virConnectPtr conn, virUdevStatus status)
+udevNumOfInterfacesByStatus(virConnectPtr conn, virUdevStatus status,
+ virInterfaceObjListFilter filter)
{
struct udev_iface_driver *driverState = conn->interfacePrivateData;
struct udev *udev = udev_ref(driverState->udev);
/* For each item so we can count */
udev_list_entry_foreach(dev_entry, devices) {
- count++;
+ struct udev_device *dev;
+ const char *path;
+ virInterfaceDefPtr def;
+
+ path = udev_list_entry_get_name(dev_entry);
+ dev = udev_device_new_from_syspath(udev, path);
+
+ def = udevGetMinimalDefForDevice(dev);
+ if (filter(conn, def))
+ count++;
+ udev_device_unref(dev);
+ virInterfaceDefFree(def);
}
cleanup:
udevListInterfacesByStatus(virConnectPtr conn,
char **const names,
int names_len,
- virUdevStatus status)
+ virUdevStatus status,
+ virInterfaceObjListFilter filter)
{
struct udev_iface_driver *driverState = conn->interfacePrivateData;
struct udev *udev = udev_ref(driverState->udev);
udev_list_entry_foreach(dev_entry, devices) {
struct udev_device *dev;
const char *path;
+ virInterfaceDefPtr def;
/* Ensure we won't exceed the size of our array */
if (count > names_len)
path = udev_list_entry_get_name(dev_entry);
dev = udev_device_new_from_syspath(udev, path);
- if (VIR_STRDUP(names[count], udev_device_get_sysname(dev)) < 0) {
- udev_device_unref(dev);
- goto error;
+
+ def = udevGetMinimalDefForDevice(dev);
+ if (filter(conn, def)) {
+ if (VIR_STRDUP(names[count], udev_device_get_sysname(dev)) < 0) {
+ udev_device_unref(dev);
+ virInterfaceDefFree(def);
+ goto error;
+ }
+ count++;
}
udev_device_unref(dev);
-
- count++;
+ virInterfaceDefFree(def);
}
udev_enumerate_unref(enumerate);
if (virConnectNumOfInterfacesEnsureACL(conn) < 0)
return -1;
- return udevNumOfInterfacesByStatus(conn, VIR_UDEV_IFACE_ACTIVE);
+ return udevNumOfInterfacesByStatus(conn, VIR_UDEV_IFACE_ACTIVE,
+ virConnectNumOfInterfacesCheckACL);
}
static int
return -1;
return udevListInterfacesByStatus(conn, names, names_len,
- VIR_UDEV_IFACE_ACTIVE);
+ VIR_UDEV_IFACE_ACTIVE,
+ virConnectListInterfacesCheckACL);
}
static int
if (virConnectNumOfDefinedInterfacesEnsureACL(conn) < 0)
return -1;
- return udevNumOfInterfacesByStatus(conn, VIR_UDEV_IFACE_INACTIVE);
+ return udevNumOfInterfacesByStatus(conn, VIR_UDEV_IFACE_INACTIVE,
+ virConnectNumOfDefinedInterfacesCheckACL);
}
static int
return -1;
return udevListInterfacesByStatus(conn, names, names_len,
- VIR_UDEV_IFACE_INACTIVE);
+ VIR_UDEV_IFACE_INACTIVE,
+ virConnectListDefinedInterfacesCheckACL);
}
#define MATCH(FLAG) (flags & (FLAG))
const char *path;
const char *name;
const char *macaddr;
+ virInterfaceDefPtr def;
path = udev_list_entry_get_name(dev_entry);
dev = udev_device_new_from_syspath(udev, path);
macaddr = udev_device_get_sysattr_value(dev, "address");
status = STREQ(udev_device_get_sysattr_value(dev, "operstate"), "up");
+ def = udevGetMinimalDefForDevice(dev);
+ if (!virConnectListAllInterfacesCheckACL(conn, def)) {
+ udev_device_unref(dev);
+ virInterfaceDefFree(def);
+ continue;
+ }
+ virInterfaceDefFree(def);
+
/* Filter the results */
if (MATCH(VIR_CONNECT_LIST_INTERFACES_FILTERS_ACTIVE) &&
!((MATCH(VIR_CONNECT_LIST_INTERFACES_ACTIVE) && status) ||