Example #1
0
static int
refresh_lists (void)
{
    int n;

    n = virConnectNumOfDomains (conn);
    if (n < 0) {
        VIRT_ERROR (conn, "reading number of domains");
        return -1;
    }

    if (n > 0) {
        int i;
        int *domids;

        /* Get list of domains. */
        domids = malloc (sizeof (*domids) * n);
        if (domids == NULL) {
            ERROR (PLUGIN_NAME " plugin: malloc failed.");
            return -1;
        }

        n = virConnectListDomains (conn, domids, n);
        if (n < 0) {
            VIRT_ERROR (conn, "reading list of domains");
            sfree (domids);
            return -1;
        }

        free_block_devices ();
        free_interface_devices ();
        free_domains ();

        /* Fetch each domain and add it to the list, unless ignore. */
        for (i = 0; i < n; ++i) {
            virDomainPtr dom = NULL;
            const char *name;
            char *xml = NULL;
            xmlDocPtr xml_doc = NULL;
            xmlXPathContextPtr xpath_ctx = NULL;
            xmlXPathObjectPtr xpath_obj = NULL;
            int j;

            dom = virDomainLookupByID (conn, domids[i]);
            if (dom == NULL) {
                VIRT_ERROR (conn, "virDomainLookupByID");
                /* Could be that the domain went away -- ignore it anyway. */
                continue;
            }

            name = virDomainGetName (dom);
            if (name == NULL) {
                VIRT_ERROR (conn, "virDomainGetName");
                goto cont;
            }

            if (il_domains && ignorelist_match (il_domains, name) != 0)
                goto cont;

            if (add_domain (dom) < 0) {
                ERROR (PLUGIN_NAME " plugin: malloc failed.");
                goto cont;
            }

            /* Get a list of devices for this domain. */
            xml = virDomainGetXMLDesc (dom, 0);
            if (!xml) {
                VIRT_ERROR (conn, "virDomainGetXMLDesc");
                goto cont;
            }

            /* Yuck, XML.  Parse out the devices. */
            xml_doc = xmlReadDoc ((xmlChar *) xml, NULL, NULL, XML_PARSE_NONET);
            if (xml_doc == NULL) {
                VIRT_ERROR (conn, "xmlReadDoc");
                goto cont;
            }

            xpath_ctx = xmlXPathNewContext (xml_doc);

            /* Block devices. */
            xpath_obj = xmlXPathEval
                ((xmlChar *) "/domain/devices/disk/target[@dev]",
                 xpath_ctx);
            if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
                xpath_obj->nodesetval == NULL)
                goto cont;

            for (j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
                xmlNodePtr node;
                char *path = NULL;

                node = xpath_obj->nodesetval->nodeTab[j];
                if (!node) continue;
                path = (char *) xmlGetProp (node, (xmlChar *) "dev");
                if (!path) continue;

                if (il_block_devices &&
                    ignore_device_match (il_block_devices, name, path) != 0)
                    goto cont2;

                add_block_device (dom, path);
            cont2:
                if (path) xmlFree (path);
            }
            xmlXPathFreeObject (xpath_obj);

            /* Network interfaces. */
            xpath_obj = xmlXPathEval
                ((xmlChar *) "/domain/devices/interface[target[@dev]]",
                 xpath_ctx);
            if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
                xpath_obj->nodesetval == NULL)
                goto cont;

            xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval;

            for (j = 0; j < xml_interfaces->nodeNr; ++j) {
                char *path = NULL;
                char *address = NULL;
                xmlNodePtr xml_interface;

                xml_interface = xml_interfaces->nodeTab[j];
                if (!xml_interface) continue;
                xmlNodePtr child = NULL;

                for (child = xml_interface->children; child; child = child->next) {
                    if (child->type != XML_ELEMENT_NODE) continue;

                    if (xmlStrEqual(child->name, (const xmlChar *) "target")) {
                        path = (char *) xmlGetProp (child, (const xmlChar *) "dev");
                        if (!path) continue;
                    } else if (xmlStrEqual(child->name, (const xmlChar *) "mac")) {
                        address = (char *) xmlGetProp (child, (const xmlChar *) "address");
                        if (!address) continue;
                    }
                }

                if (il_interface_devices &&
                    (ignore_device_match (il_interface_devices, name, path) != 0 ||
                     ignore_device_match (il_interface_devices, name, address) != 0))
                    goto cont3;

                add_interface_device (dom, path, address, j+1);
                cont3:
                    if (path) xmlFree (path);
                    if (address) xmlFree (address);
            }

        cont:
            if (xpath_obj) xmlXPathFreeObject (xpath_obj);
            if (xpath_ctx) xmlXPathFreeContext (xpath_ctx);
            if (xml_doc) xmlFreeDoc (xml_doc);
            sfree (xml);
        }

        sfree (domids);
    }

    return 0;
}
Example #2
0
static int
lv_config (const char *key, const char *value)
{
    if (virInitialize () != 0)
        return 1;

    if (il_domains == NULL)
        il_domains = ignorelist_create (1);
    if (il_block_devices == NULL)
        il_block_devices = ignorelist_create (1);
    if (il_interface_devices == NULL)
        il_interface_devices = ignorelist_create (1);

    if (strcasecmp (key, "Connection") == 0) {
        if (conn != 0) {
            ERROR ("Connection may only be given once in config file");
            return 1;
        }
        conn = virConnectOpenReadOnly (value);
        if (!conn) {
            VIRT_ERROR (NULL, "connection failed");
            return 1;
        }
        return 0;
    }

    if (strcasecmp (key, "RefreshInterval") == 0) {
        char *eptr = NULL;
        interval = strtol (value, &eptr, 10);
        if (eptr == NULL || *eptr != '\0') return 1;
        return 0;
    }

    if (strcasecmp (key, "Domain") == 0) {
        if (ignorelist_add (il_domains, value)) return 1;
        return 0;
    }
    if (strcasecmp (key, "BlockDevice") == 0) {
        if (ignorelist_add (il_block_devices, value)) return 1;
        return 0;
    }
    if (strcasecmp (key, "InterfaceDevice") == 0) {
        if (ignorelist_add (il_interface_devices, value)) return 1;
        return 0;
    }

    if (strcasecmp (key, "IgnoreSelected") == 0) {
        if (strcasecmp (value, "True") == 0 ||
            strcasecmp (value, "Yes") == 0 ||
            strcasecmp (value, "On") == 0)
        {
            ignorelist_set_invert (il_domains, 0);
            ignorelist_set_invert (il_block_devices, 0);
            ignorelist_set_invert (il_interface_devices, 0);
        }
        else
        {
            ignorelist_set_invert (il_domains, 1);
            ignorelist_set_invert (il_block_devices, 1);
            ignorelist_set_invert (il_interface_devices, 1);
        }
        return 0;
    }

    if (strcasecmp (key, "HostnameFormat") == 0) {
        char *value_copy;
        char *fields[HF_MAX_FIELDS];
        int i, n;

        value_copy = strdup (value);
        if (value_copy == NULL) {
            ERROR ("libvirt plugin: strdup failed.");
            return -1;
        }

        n = strsplit (value_copy, fields, HF_MAX_FIELDS);
        if (n < 1) {
            free (value_copy);
            ERROR ("HostnameFormat: no fields");
            return -1;
        }

        for (i = 0; i < n; ++i) {
            if (strcasecmp (fields[i], "hostname") == 0)
                hostname_format[i] = hf_hostname;
            else if (strcasecmp (fields[i], "name") == 0)
                hostname_format[i] = hf_name;
            else if (strcasecmp (fields[i], "uuid") == 0)
                hostname_format[i] = hf_uuid;
            else {
                free (value_copy);
                ERROR ("unknown HostnameFormat field: %s", fields[i]);
                return -1;
            }
        }
        free (value_copy);

        for (i = n; i < HF_MAX_FIELDS; ++i)
            hostname_format[i] = hf_none;

        return 0;
    }

    /* Unrecognised option. */
    return -1;
}