summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2014-01-27 13:59:15 +0100
committerChristophe Fergeau <cfergeau@redhat.com>2015-04-10 20:48:48 +0200
commitdf5c0876abc1dd09b23d87b1609ff5419d3cd927 (patch)
treeda81c940e5fb71f8d4cabeb19fd75948cc5405a8
parentb95ef65a01e86bc97bb2d20e0b3f22a8d9b0200f (diff)
virtxml: auto detect available network interface wipwip
-rw-r--r--examples/virt-designer.c98
1 files changed, 97 insertions, 1 deletions
diff --git a/examples/virt-designer.c b/examples/virt-designer.c
index f134b98..32708a8 100644
--- a/examples/virt-designer.c
+++ b/examples/virt-designer.c
@@ -24,10 +24,13 @@
#include <libvirt-designer/libvirt-designer.h>
#include <libvirt-gobject/libvirt-gobject.h>
+#include <errno.h>
+#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -363,6 +366,99 @@ add_iface_str(const gchar *option_name,
return TRUE;
}
+static gpointer has_unpriviledged_libvirt_bridge_once(gpointer user_data)
+{
+ int sock = -1;
+ struct ifreq ifr;
+ gboolean can_use_bridge = FALSE;
+ GError *error = NULL;
+ char *contents = NULL;
+
+ sock = socket(PF_INET, SOCK_STREAM, 0);
+ if (sock < 1) {
+ g_warning("socket() failed: %s", strerror(errno));
+ goto end;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, "virbr0", IFNAMSIZ);
+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
+ g_warning("ioctl(SIOCGIFFLAGS) failed: %s", strerror(errno));
+ goto end;
+ }
+ if (!(ifr.ifr_flags & IFF_UP)) {
+ g_debug("virbr0 is not up");
+ goto end;
+ }
+
+ if (!g_file_get_contents("/etc/qemu/bridge.conf", &contents, NULL, &error)) {
+ g_debug("Could not load /etc/qemu/bridge.conf: %s", error->message);
+ goto end;
+ }
+
+ if (g_regex_match_simple("^\\s*allow\\s*virbr0\\b", contents, 0, 0)) {
+ can_use_bridge = TRUE;
+ }
+
+end:
+ if (sock >= 0) {
+ close(sock);
+ }
+ if (error != NULL) {
+ g_error_free(error);
+ }
+ g_free(contents);
+
+ return GINT_TO_POINTER(can_use_bridge);
+}
+
+static gboolean has_unpriviledged_libvirt_bridge(void)
+{
+ GOnce libvirt_bridge = G_ONCE_INIT;
+ gpointer ret;
+
+ ret = g_once(&libvirt_bridge,
+ has_unpriviledged_libvirt_bridge_once,
+ NULL);
+
+ return GPOINTER_TO_INT(ret);
+}
+
+static void add_network_interface(GVirConnection *conn,
+ GVirDesignerDomain *domain,
+ GList *interfaces)
+{
+ const char *libvirt_uri;
+ gboolean unpriviledged = FALSE;
+ GVirConfigDomainInterface *iface;
+
+ if (interfaces != NULL) {
+ g_list_foreach(iface_str_list, add_iface, domain);
+ return;
+ }
+
+ /* This logic could eventually go in libvirt-builder */
+ libvirt_uri = gvir_connection_get_uri(conn);
+ if (g_strcmp0(libvirt_uri, "qemu:///session") == 0) {
+ unpriviledged = TRUE;
+ }
+
+ if (unpriviledged) {
+ if (has_unpriviledged_libvirt_bridge()) {
+ iface = gvir_designer_domain_add_interface_bridge(domain, "virbr0", NULL);
+ } else {
+ iface = gvir_designer_domain_add_interface_user(domain, NULL);
+ }
+ //gvir_designer_domain_add_interface_bridge(domain, "virbr0", NULL);
+ } else {
+ iface = gvir_designer_domain_add_interface_network(domain, "default", NULL);
+ }
+
+ if (iface != NULL) {
+ g_object_unref(iface);
+ }
+}
+
static OsinfoEntity *
find_entity_by_short_id(OsinfoList *ent_list,
const char *short_id)
@@ -718,7 +814,7 @@ main(int argc, char *argv[])
g_list_foreach(floppy_str_list, add_floppy, domain);
- g_list_foreach(iface_str_list, add_iface, domain);
+ add_network_interface(conn, domain, iface_str_list);
config = gvir_designer_domain_get_config(domain);
xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(config));