virtio functions are available in libmetrics and in libserialclient (with minimal dependencies). --- We would like to have the serialclient code available in a library without additional dependencies, because linking against libmetrics requires libxml2. libmetrics/Makefile.am | 19 ++++- libmetrics/libmetrics.c | 10 +++ libmetrics/libmetrics.h | 6 ++ libmetrics/libserialclient.c | 167 +++++++++++++++++++++++++++++++++++++++++++ libmetrics/libserialclient.h | 30 ++++++++ vm-dump-metrics/main.c | 18 +++-- 6 files changed, 243 insertions(+), 7 deletions(-) create mode 100644 libmetrics/libserialclient.c create mode 100644 libmetrics/libserialclient.h diff --git a/libmetrics/Makefile.am b/libmetrics/Makefile.am index 28490ee..38d635c 100644 --- a/libmetrics/Makefile.am +++ b/libmetrics/Makefile.am @@ -6,7 +6,7 @@ if WITH_XENSTORE AM_CFLAGS += -DWITH_XENSTORE endif -lib_LTLIBRARIES=libmetrics.la +lib_LTLIBRARIES=libmetrics.la libserialclient.la libmetricsincdir=$(includedir)/vhostmd libmetricsinc_HEADERS = libmetrics.h @@ -15,8 +15,21 @@ libmetrics_la_SOURCES = \ libmetrics.c \ vm_metrics.c \ host_metrics.c \ - libmetrics.h + libmetrics.h \ + libserialclient.c libmetrics_la_DEPENDENCIES = \ - libmetrics.h + libmetrics.h \ + libserialclient.h + + +libserialclientincdir= +libserialclientinc_HEADERS = libserialclient.h + +libserialclient_la_SOURCES = \ + libserialclient.c \ + libserialclient.h + +libserialclient_la_DEPENDENCIES = \ + libserialclient.h diff --git a/libmetrics/libmetrics.c b/libmetrics/libmetrics.c index 81f4d1a..12cfed5 100644 --- a/libmetrics/libmetrics.c +++ b/libmetrics/libmetrics.c @@ -63,6 +63,16 @@ typedef struct _private_metric metric_type type; }private_metric; +typedef struct _virtio_buffer { + char uuid[256]; + char *virtio_name; + char *buffer; + uint32_t sum; + uint32_t length; + xmlParserCtxtPtr pctxt; + xmlDocPtr doc; +} virtio_buffer; + #define MDISK_SIGNATURE 0x6d766264 /* 'mvbd' */ #define SYS_BLOCK "/sys/block" #define HOST_CONTEXT "host" diff --git a/libmetrics/libmetrics.h b/libmetrics/libmetrics.h index 717bc73..1908de8 100644 --- a/libmetrics/libmetrics.h +++ b/libmetrics/libmetrics.h @@ -100,4 +100,10 @@ int dump_metrics(const char *dest_file); /* dump metrics from xenstore to xml formatted file */ int dump_xenstore_metrics(const char *dest_file); +/* dump metrics from virtio serial port to xml formatted file */ +int dump_virtio_metrics(const char *dest_file); + +/* dump metrics from virtio serial port to buffer */ +const char *get_virtio_metrics(const char *dev_name); + #endif diff --git a/libmetrics/libserialclient.c b/libmetrics/libserialclient.c new file mode 100644 index 0000000..9a197f2 --- /dev/null +++ b/libmetrics/libserialclient.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2018 SAP SE + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Michael Trapp <michael.trapp@xxxxxxx> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> + +#include "libserialclient.h" + + +/* + * dump metrics from virtio serial port to xml formatted file + */ +int dump_virtio_metrics(const char *dest_file) +{ + FILE *fp = stdout; + char *response; + int len; + + response = (char*) get_virtio_metrics(NULL); + if (response == NULL) + goto error; + + len = strlen(response); + + if (dest_file) { + fp = fopen(dest_file, "w"); + if (fp == NULL) { + fprintf(stderr,"LIB_SERIALCLIENT: Error, unable to dump metrics: fopen(%s) %s\n", + dest_file, strerror(errno)); + goto error; + } + } + + if (fwrite(response, 1, len, fp) != len) { + fprintf(stderr,"LIB_SERIALCLIENT: Error, unable to export metrics to file:%s - error:%s\n", + dest_file ? dest_file : "STDOUT", strerror(errno)); + goto error; + } + + if (response) + free(response); + + return 0; + + error: + if (dest_file && fp) + fclose(fp); + + if (response) + free(response); + + return -1; +} + +/* + * dump metrics from virtio serial port to buffer + */ +const char *get_virtio_metrics(const char *dev_name) +{ + const char request[] = "GET /metrics/XML\n\n", + end_token[] = "\n\n", + *dev; + char *response = NULL; + int fd = -1, pos, buf_size = (1 << 16); + const int req_len = strlen(request); + const time_t start_time = time(NULL); + + if (dev_name) + dev = dev_name; + else + dev = "/dev/virtio-ports/vhostmd"; + + response = calloc(1, buf_size); + if (response == NULL) + goto error; + + fd = open(dev, O_RDWR | O_NONBLOCK); + + if (fd < 0) { + fprintf(stderr,"LIB_SERIALCLIENT: Error, unable to dump metrics: open(%s) %s\n", + dev, strerror(errno)); + goto error; + } + + pos = 0; + while (pos < req_len) { + int len = write(fd, &request[pos], req_len - pos); + if (len > 0) + pos += len; + else { + if (errno == EAGAIN) + usleep(10000); + else + goto error; + } + } + + pos = 0; + do { + int len = read(fd, &response[pos], buf_size - pos - 1); + if (len > 0) { + pos += len; + response[pos] = 0; + + if ((pos + 1) >= buf_size) { + buf_size = buf_size << 1; // increase response buffer + if (buf_size > (1 << 24)) // max 16MB + goto error; + + response = realloc(response, buf_size); + if (response == NULL) + goto error; + + memset(&response[pos], 0, buf_size - pos); + } + } + else { + if (errno == EAGAIN) { + usleep(10000); + if (time(NULL) > (start_time + 30)) { + fprintf(stderr,"LIB_SERIALCLIENT: Error, unable to read metrics" + " - timeout after 30s\n"); + goto error; + } + } + else + goto error; + } + } while ((pos < strlen(end_token) || + strcmp(end_token, &response[pos - strlen(end_token)]) != 0) && + pos < buf_size); + + if (fd >= 0) + close(fd); + + return response; + + error: + if (fd >= 0) + close(fd); + if (response) + free(response); + + return NULL; +} diff --git a/libmetrics/libserialclient.h b/libmetrics/libserialclient.h new file mode 100644 index 0000000..d0327ea --- /dev/null +++ b/libmetrics/libserialclient.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 SAP SE + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Michael Trapp <michael.trapp@xxxxxxx> + */ + +#ifndef __LIBSERIALCLIENT_H__ +#define __LIBSERIALCLIENT_H__ + +/* dump metrics from virtio serial port to xml formatted file */ +int dump_virtio_metrics(const char *dest_file); + +/* dump metrics from virtio serial port to buffer */ +const char *get_virtio_metrics(const char *dev_name); + +#endif diff --git a/vm-dump-metrics/main.c b/vm-dump-metrics/main.c index f48a615..af35703 100644 --- a/vm-dump-metrics/main.c +++ b/vm-dump-metrics/main.c @@ -33,6 +33,7 @@ static void usage(const char *argv0) -v | --verbose Verbose messages.\n\ -d | --dest Metrics destination file .\n\ -b | --vbd Get metrics from vbd.\n\ + -i | --virtio Get metrics from virtio channel.\n\ -x | --xenstore Get metrics from xenstore.\n"; #else char *options_str = "Options:\n\ @@ -54,6 +55,7 @@ int main(int argc, char *argv[]) int verbose = 0; #ifdef WITH_XENSTORE int vbd = 0; + int virtio = 0; int xenstore = 0; #endif const char *dfile = NULL; @@ -62,6 +64,7 @@ int main(int argc, char *argv[]) { "verbose", no_argument, &verbose, 1}, #ifdef WITH_XENSTORE { "vbd", no_argument, &vbd, 1}, + { "virtio", no_argument, &virtio, 1}, { "xenstore", no_argument, &xenstore, 1}, #endif { "help", no_argument, NULL, '?' }, @@ -74,9 +77,9 @@ int main(int argc, char *argv[]) int c; #ifdef WITH_XENSTORE - c = getopt_long(argc, argv, "d:vbx", opts, &optidx); + c = getopt_long(argc, argv, "d:vibx", opts, &optidx); #else - c = getopt_long(argc, argv, "d:v", opts, &optidx); + c = getopt_long(argc, argv, "d:vi", opts, &optidx); #endif if (c == -1) @@ -97,6 +100,9 @@ int main(int argc, char *argv[]) xenstore = 1; break; #endif + case 'i': + virtio = 1; + break; case 'd': dfile = optarg; break; @@ -109,6 +115,10 @@ int main(int argc, char *argv[]) } } + if (virtio) { + if (dump_virtio_metrics(dfile) == -1) + exit (1); + } #ifdef WITH_XENSTORE if (xenstore) { if (dump_xenstore_metrics(dfile) == -1) @@ -119,10 +129,10 @@ int main(int argc, char *argv[]) exit (1); } /* Try disk first and if not found try xenstore */ - if (vbd == 0 && xenstore == 0) { + if (virtio == 0 && vbd == 0 && xenstore == 0) { if (dump_metrics(dfile) == -1) if (dump_xenstore_metrics(dfile) == -1) - exit (1); + exit (1); } #else if (dump_metrics(dfile) == -1) -- 2.15.2 (Apple Git-101.1) _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list