예제 #1
0
파일: virt.c 프로젝트: 4thAce/collectd
static int
lv_read (void)
{
    time_t t;
    int i;

    if (conn == NULL) {
        /* `conn_string == NULL' is acceptable. */
        conn = virConnectOpenReadOnly (conn_string);
        if (conn == NULL) {
            c_complain (LOG_ERR, &conn_complain,
                    PLUGIN_NAME " plugin: Unable to connect: "
                    "virConnectOpenReadOnly failed.");
            return -1;
        }
    }
    c_release (LOG_NOTICE, &conn_complain,
            PLUGIN_NAME " plugin: Connection established.");

    time (&t);

    /* Need to refresh domain or device lists? */
    if ((last_refresh == (time_t) 0) ||
            ((interval > 0) && ((last_refresh + interval) <= t))) {
        if (refresh_lists () != 0) {
            if (conn != NULL)
                virConnectClose (conn);
            conn = NULL;
            return -1;
        }
        last_refresh = t;
    }

#if 0
    for (i = 0; i < nr_domains; ++i)
        fprintf (stderr, "domain %s\n", virDomainGetName (domains[i]));
    for (i = 0; i < nr_block_devices; ++i)
        fprintf  (stderr, "block device %d %s:%s\n",
                  i, virDomainGetName (block_devices[i].dom),
                  block_devices[i].path);
    for (i = 0; i < nr_interface_devices; ++i)
        fprintf (stderr, "interface device %d %s:%s\n",
                 i, virDomainGetName (interface_devices[i].dom),
                 interface_devices[i].path);
#endif

    /* Get CPU usage, memory, VCPU usage for each domain. */
    for (i = 0; i < nr_domains; ++i) {
        virDomainInfo info;
        virVcpuInfoPtr vinfo = NULL;
        virDomainMemoryStatPtr minfo = NULL;
        int status;
        int j;

        status = virDomainGetInfo (domains[i], &info);
        if (status != 0)
        {
            ERROR (PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.",
                    status);
            continue;
        }

        if (info.state != VIR_DOMAIN_RUNNING)
        {
            /* only gather stats for running domains */
            continue;
        }

        cpu_submit (info.cpuTime, domains[i], "virt_cpu_total");
        memory_submit ((gauge_t) info.memory * 1024, domains[i]);

        vinfo = malloc (info.nrVirtCpu * sizeof (vinfo[0]));
        if (vinfo == NULL) {
            ERROR (PLUGIN_NAME " plugin: malloc failed.");
            continue;
        }

        status = virDomainGetVcpus (domains[i], vinfo, info.nrVirtCpu,
                /* cpu map = */ NULL, /* cpu map length = */ 0);
        if (status < 0)
        {
            ERROR (PLUGIN_NAME " plugin: virDomainGetVcpus failed with status %i.",
                    status);
            sfree (vinfo);
            continue;
        }

        for (j = 0; j < info.nrVirtCpu; ++j)
            vcpu_submit (vinfo[j].cpuTime,
                    domains[i], vinfo[j].number, "virt_vcpu");

        sfree (vinfo);

        minfo = malloc (VIR_DOMAIN_MEMORY_STAT_NR * sizeof (virDomainMemoryStatStruct));
        if (minfo == NULL) {
            ERROR ("virt plugin: malloc failed.");
            continue;
        }

        status =  virDomainMemoryStats (domains[i], minfo, VIR_DOMAIN_MEMORY_STAT_NR, 0);

        if (status < 0) {
            ERROR ("virt plugin: virDomainMemoryStats failed with status %i.",
                    status);
            sfree (minfo);
            continue;
        }

        for (j = 0; j < status; j++) {
            memory_stats_submit ((gauge_t) minfo[j].val * 1024, domains[i], minfo[j].tag);
        }

        sfree (minfo);
    }


    /* Get block device stats for each domain. */
    for (i = 0; i < nr_block_devices; ++i) {
        struct _virDomainBlockStats stats;

        if (virDomainBlockStats (block_devices[i].dom, block_devices[i].path,
                    &stats, sizeof stats) != 0)
            continue;

        if ((stats.rd_req != -1) && (stats.wr_req != -1))
            submit_derive2 ("disk_ops",
                    (derive_t) stats.rd_req, (derive_t) stats.wr_req,
                    block_devices[i].dom, block_devices[i].path);

        if ((stats.rd_bytes != -1) && (stats.wr_bytes != -1))
            submit_derive2 ("disk_octets",
                    (derive_t) stats.rd_bytes, (derive_t) stats.wr_bytes,
                    block_devices[i].dom, block_devices[i].path);
    } /* for (nr_block_devices) */

    /* Get interface stats for each domain. */
    for (i = 0; i < nr_interface_devices; ++i) {
        struct _virDomainInterfaceStats stats;
        char *display_name = NULL;


        switch (interface_format) {
            case if_address:
                display_name = interface_devices[i].address;
                break;
            case if_number:
                display_name = interface_devices[i].number;
                break;
            case if_name:
            default:
                display_name = interface_devices[i].path;
        }

        if (virDomainInterfaceStats (interface_devices[i].dom,
                    interface_devices[i].path,
                    &stats, sizeof stats) != 0)
            continue;

	if ((stats.rx_bytes != -1) && (stats.tx_bytes != -1))
	    submit_derive2 ("if_octets",
		    (derive_t) stats.rx_bytes, (derive_t) stats.tx_bytes,
		    interface_devices[i].dom, display_name);

	if ((stats.rx_packets != -1) && (stats.tx_packets != -1))
	    submit_derive2 ("if_packets",
		    (derive_t) stats.rx_packets, (derive_t) stats.tx_packets,
		    interface_devices[i].dom, display_name);

	if ((stats.rx_errs != -1) && (stats.tx_errs != -1))
	    submit_derive2 ("if_errors",
		    (derive_t) stats.rx_errs, (derive_t) stats.tx_errs,
		    interface_devices[i].dom, display_name);

	if ((stats.rx_drop != -1) && (stats.tx_drop != -1))
	    submit_derive2 ("if_dropped",
		    (derive_t) stats.rx_drop, (derive_t) stats.tx_drop,
		    interface_devices[i].dom, display_name);
    } /* for (nr_interface_devices) */

    return 0;
}
예제 #2
0
파일: libvirt.c 프로젝트: haojunyu/collectd
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;
}
예제 #3
0
파일: libvirt.c 프로젝트: gnosek/collectd
static int
lv_read (void)
{
    time_t t;
    int i;

    if (conn == NULL) {
        /* `conn_string == NULL' is acceptable. */
        conn = virConnectOpenReadOnly (conn_string);
        if (conn == NULL) {
            c_complain (LOG_ERR, &conn_complain,
                    "libvirt plugin: Unable to connect: "
                    "virConnectOpenReadOnly failed.");
            return -1;
        }
    }
    c_release (LOG_NOTICE, &conn_complain,
            "libvirt plugin: Connection established.");

    time (&t);

    /* Need to refresh domain or device lists? */
    if ((last_refresh == (time_t) 0) ||
            ((interval > 0) && ((last_refresh + interval) <= t))) {
        if (refresh_lists () != 0) {
            if (conn != NULL)
                virConnectClose (conn);
            conn = NULL;
            return -1;
        }
        last_refresh = t;
    }

#if 0
    for (i = 0; i < nr_domains; ++i)
        fprintf (stderr, "domain %s\n", virDomainGetName (domains[i]));
    for (i = 0; i < nr_block_devices; ++i)
        fprintf  (stderr, "block device %d %s:%s\n",
                  i, virDomainGetName (block_devices[i].dom),
                  block_devices[i].path);
    for (i = 0; i < nr_interface_devices; ++i)
        fprintf (stderr, "interface device %d %s:%s\n",
                 i, virDomainGetName (interface_devices[i].dom),
                 interface_devices[i].path);
#endif

    /* Get CPU usage, VCPU usage for each domain. */
    for (i = 0; i < nr_domains; ++i) {
        virDomainInfo info;
        virVcpuInfoPtr vinfo = NULL;
        int j;

        if (virDomainGetInfo (domains[i], &info) != 0)
            continue;

        cpu_submit (info.cpuTime, domains[i], "virt_cpu_total");

        vinfo = malloc (info.nrVirtCpu * sizeof vinfo[0]);
        if (vinfo == NULL) {
            ERROR ("libvirt plugin: malloc failed.");
            continue;
        }

        if (virDomainGetVcpus (domains[i], vinfo, info.nrVirtCpu,
                    NULL, 0) != 0) {
            sfree (vinfo);
            continue;
        }

        for (j = 0; j < info.nrVirtCpu; ++j)
            vcpu_submit (vinfo[j].cpuTime,
                    domains[i], vinfo[j].number, "virt_vcpu");

        sfree (vinfo);
    }

    /* Get block device stats for each domain. */
    for (i = 0; i < nr_block_devices; ++i) {
        struct _virDomainBlockStats stats;

        if (virDomainBlockStats (block_devices[i].dom, block_devices[i].path,
                    &stats, sizeof stats) != 0)
            continue;

        if ((stats.rd_req != -1) && (stats.wr_req != -1))
            submit_derive2 ("disk_ops",
                    (derive_t) stats.rd_req, (derive_t) stats.wr_req,
                    block_devices[i].dom, block_devices[i].path);

        if ((stats.rd_bytes != -1) && (stats.wr_bytes != -1))
            submit_derive2 ("disk_octets",
                    (derive_t) stats.rd_bytes, (derive_t) stats.wr_bytes,
                    block_devices[i].dom, block_devices[i].path);
    } /* for (nr_block_devices) */

    /* Get interface stats for each domain. */
    for (i = 0; i < nr_interface_devices; ++i) {
        struct _virDomainInterfaceStats stats;
        char *display_name = interface_devices[i].path;

        if (interface_format == if_address)
            display_name = interface_devices[i].address;

        if (virDomainInterfaceStats (interface_devices[i].dom,
                    interface_devices[i].path,
                    &stats, sizeof stats) != 0)
            continue;

	if ((stats.rx_bytes != -1) && (stats.tx_bytes != -1))
	    submit_derive2 ("if_octets",
		    (derive_t) stats.rx_bytes, (derive_t) stats.tx_bytes,
		    interface_devices[i].dom, display_name);

	if ((stats.rx_packets != -1) && (stats.tx_packets != -1))
	    submit_derive2 ("if_packets",
		    (derive_t) stats.rx_packets, (derive_t) stats.tx_packets,
		    interface_devices[i].dom, display_name);

	if ((stats.rx_errs != -1) && (stats.tx_errs != -1))
	    submit_derive2 ("if_errors",
		    (derive_t) stats.rx_errs, (derive_t) stats.tx_errs,
		    interface_devices[i].dom, display_name);

	if ((stats.rx_drop != -1) && (stats.tx_drop != -1))
	    submit_derive2 ("if_dropped",
		    (derive_t) stats.rx_drop, (derive_t) stats.tx_drop,
		    interface_devices[i].dom, display_name);
    } /* for (nr_interface_devices) */

    return 0;
}
예제 #4
0
void
get_domains_from_libvirt (void)
{
  virErrorPtr err;
  virConnectPtr conn;
  int n;
  size_t i, j, nr_disks_added;

  nr_domains = 0;
  domains = NULL;

  /* Get the list of all domains. */
  conn = virConnectOpenReadOnly (libvirt_uri);
  if (!conn) {
    err = virGetLastError ();
    fprintf (stderr,
             _("%s: could not connect to libvirt (code %d, domain %d): %s"),
             program_name, err->code, err->domain, err->message);
    exit (EXIT_FAILURE);
  }

  n = virConnectNumOfDomains (conn);
  if (n == -1) {
    err = virGetLastError ();
    fprintf (stderr,
             _("%s: could not get number of running domains (code %d, domain %d): %s"),
             program_name, err->code, err->domain, err->message);
    exit (EXIT_FAILURE);
  }

  int ids[n];
  n = virConnectListDomains (conn, ids, n);
  if (n == -1) {
    err = virGetLastError ();
    fprintf (stderr,
             _("%s: could not list running domains (code %d, domain %d): %s"),
             program_name, err->code, err->domain, err->message);
    exit (EXIT_FAILURE);
  }

  add_domains_by_id (conn, ids, n);

  n = virConnectNumOfDefinedDomains (conn);
  if (n == -1) {
    err = virGetLastError ();
    fprintf (stderr,
             _("%s: could not get number of inactive domains (code %d, domain %d): %s"),
             program_name, err->code, err->domain, err->message);
    exit (EXIT_FAILURE);
  }

  char *names[n];
  n = virConnectListDefinedDomains (conn, names, n);
  if (n == -1) {
    err = virGetLastError ();
    fprintf (stderr,
             _("%s: could not list inactive domains (code %d, domain %d): %s"),
             program_name, err->code, err->domain, err->message);
    exit (EXIT_FAILURE);
  }

  add_domains_by_name (conn, names, n);

  /* You must free these even though the libvirt documentation doesn't
   * mention it.
   */
  for (i = 0; i < (size_t) n; ++i)
    free (names[i]);

  virConnectClose (conn);

  /* No domains? */
  if (nr_domains == 0)
    return;

  /* Sort the domains alphabetically by name for display. */
  qsort (domains, nr_domains, sizeof (struct domain), compare_domain_names);

  print_title ();

  /* To minimize the number of times we have to launch the appliance,
   * shuffle as many domains together as we can, but not exceeding
   * MAX_DISKS per request.  If --one-per-guest was requested then only
   * request disks from a single guest each time.
   * Interesting application for NP-complete knapsack problem here.
   */
  if (one_per_guest) {
    for (i = 0; i < nr_domains; ++i)
      multi_df (&domains[i], 1);
  } else {
    for (i = 0; i < nr_domains; /**/) {
      nr_disks_added = 0;

      /* Make a request with domains [i..j-1]. */
      for (j = i; j < nr_domains; ++j) {
        if (nr_disks_added + domains[j].nr_disks > MAX_DISKS)
          break;
        nr_disks_added += domains[j].nr_disks;
      }
      multi_df (&domains[i], j-i);

      i = j;
    }
  }

  /* Free up domains structure. */
  for (i = 0; i < nr_domains; ++i)
    free_domain (&domains[i]);
  free (domains);
}
예제 #5
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  virConnectPtr conn;
  virDomainPtr dom;
  virErrorPtr err;
  int r;
  char *backend;
  char *cwd;
  FILE *fp;
  char libvirt_uri[1024];

  cwd = xgetcwd ();

  /* Create the guestfs handle. */
  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, "failed to create handle\n");
    exit (EXIT_FAILURE);
  }

  backend = guestfs_get_backend (g);
  if (STREQ (backend, "uml")) {
    printf ("%s: test skipped because UML backend does not support qcow2\n",
            argv[0]);
    free (backend);
    exit (77);
  }
  free (backend);

  /* Create the libvirt XML and test images in the current
   * directory.
   */
  fp = fopen ("test-add-libvirt-dom.xml", "w");
  if (fp == NULL) {
    perror ("test-add-libvirt-dom.xml");
    exit (EXIT_FAILURE);
  }
  make_test_xml (fp, cwd);
  fclose (fp);

  if (guestfs_disk_create (g, "test-add-libvirt-dom-1.img", "raw",
                           1024*1024, -1) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_disk_create (g, "test-add-libvirt-dom-2.img", "raw",
                           1024*1024, -1) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_disk_create (g, "test-add-libvirt-dom-3.img", "qcow2",
                           1024*1024, -1) == -1)
    exit (EXIT_FAILURE);

  /* Create the libvirt connection. */
  snprintf (libvirt_uri, sizeof libvirt_uri,
            "test://%s/test-add-libvirt-dom.xml", cwd);
  conn = virConnectOpenReadOnly (libvirt_uri);
  if (!conn) {
    err = virGetLastError ();
    fprintf (stderr,
             "%s: could not connect to libvirt (code %d, domain %d): %s\n",
             argv[0], err->code, err->domain, err->message);
    exit (EXIT_FAILURE);
  }

  dom = virDomainLookupByName (conn, "guest");
  if (!dom) {
    err = virGetLastError ();
    fprintf (stderr,
             "%s: no libvirt domain called '%s': %s\n",
             argv[0], "guest", err->message);
    exit (EXIT_FAILURE);
  }

  r = guestfs_add_libvirt_dom (g, dom,
                               GUESTFS_ADD_LIBVIRT_DOM_READONLY, 1,
                               -1);
  if (r == -1)
    exit (EXIT_FAILURE);

  if (r != 3) {
    fprintf (stderr,
             "%s: incorrect number of disks added (%d, expected 3)\n",
             argv[0], r);
    exit (EXIT_FAILURE);
  }

  guestfs_close (g);

  virDomainFree (dom);
  virConnectClose (conn);
  free (cwd);

  unlink ("test-add-libvirt-dom.xml");
  unlink ("test-add-libvirt-dom-1.img");
  unlink ("test-add-libvirt-dom-2.img");
  unlink ("test-add-libvirt-dom-3.img");

  exit (EXIT_SUCCESS);
}
예제 #6
0
int main()
{
    int idCount;
    int i;
    int id;
    //int ids[MAXID];
	int *ids;
    //timeInfoNode timeInfos[MAXID];

    printf("--------------------------------------------------------\n");
    printf("             XEN Domain Monitor \n");
    printf("--------------------------------------------------------\n");

    /* NULL means connect to local Xen hypervisor */
    conn = virConnectOpenReadOnly(NULL);
    if (conn == NULL)
    {
        fprintf(stderr, "Failed to connect to hypervisor\n");
        closeConn();
        return 0;
    }

	/*char* caps;
	caps = virConnectGetCapabilities(conn);
	printf("Capabilities:\n%s\n",caps);
	free(caps);*/
	char *host;
	host = virConnectGetHostname(conn);
	fprintf(stdout, "Hostname:%s\n",host);
	free(host);
	int vcpus;
	vcpus = virConnectGetMaxVcpus(conn,NULL);
	fprintf(stdout, "Maxmum support vcpus:%d\n",vcpus);
	unsigned long long node_free_memory;
	node_free_memory = virNodeGetFreeMemory(conn);
	fprintf(stdout, "free memory:%lld\n",node_free_memory);
	virNodeInfo nodeinfo;
	virNodeGetInfo(conn,&nodeinfo);
	fprintf(stdout, "Model: %s\n", nodeinfo.model);
    fprintf(stdout, "Memory size: %lukb\n", nodeinfo.memory);
    fprintf(stdout, "Number of CPUs: %u\n", nodeinfo.cpus);
    fprintf(stdout, "MHz of CPUs: %u\n", nodeinfo.mhz);
    fprintf(stdout, "Number of NUMA nodes: %u\n", nodeinfo.nodes);
    fprintf(stdout, "Number of CPU sockets: %u\n", nodeinfo.sockets);
    fprintf(stdout, "Number of CPU cores per socket: %u\n", nodeinfo.cores);
    fprintf(stdout, "Number of CPU threads per core: %u\n", nodeinfo.threads);	
    fprintf(stdout, "Virtualization type: %s\n", virConnectGetType(conn));
	unsigned long ver;
	virConnectGetVersion(conn, &ver);
	fprintf(stdout, "Version: %lu\n", ver);
	/*unsigned long Libver;
	virConnectGetLibVersion(conn, &Libver);
	fprintf(stdout, "Libvirt Version: %lu\n", Libver);*/
	char *uri;
	uri = virConnectGetURI(conn);
	fprintf(stdout, "Canonical URI: %s\n", uri);
	free(uri);
	/* get the count of IDs and save these ID into ids[] */
    idCount = virConnectNumOfDomains(conn);
	ids = malloc(sizeof(int) *idCount);
	idCount = virConnectListDomains(conn,ids,idCount);
	//idCount = virConnectListDomains(conn, &ids[0], MAXID);
    if (idCount < 0)
    {
        fprintf(stderr, "Failed to list the domains\n");
        closeConn();
        return 0;
    }

    timeInfoNode timeInfos[idCount];
	printf("Domain Totals: %d\n", idCount);
    printf("ID\tCPU\tMEM\tMaxMEM\tVCPUs\tState\tNAME\n");

    /* loop get the CPUtime info by IDs */
    for (i = 0; i < idCount; i++)
    {
        id = ids[i];
        getTimeInfo(id, &(timeInfos[i]));
    }

    sleep(1);

    /* loop print the domain info and calculate the usage of cpus*/
    for (i = 0; i < idCount; i++)
    {
        id = ids[i];
        getDomainInfo(id, timeInfos[i]);
    }

    free(ids);
	printf("--------------------------------------------------------\n");
    closeConn();
    return 0;
}