From df5c0876abc1dd09b23d87b1609ff5419d3cd927 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Mon, 27 Jan 2014 13:59:15 +0100 Subject: virtxml: auto detect available network interface wip --- examples/virt-designer.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) 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 #include +#include +#include #include #include #include #include +#include #include #include #include @@ -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)); -- cgit v1.2.3