[virt-tools-list] [vhostmd virtio PATCH v3 6/6] Add virtio support to vm-dump-metrics

Trapp, Michael michael.trapp at sap.com
Thu Dec 6 17:00:27 UTC 2018


Actually we wanted to have a shared library without any further dependencies for executables in the VM.

We had another discussion about the requirements from the VM side and you are right,
it should be sufficient to use vm-dump-metrics to read the metrics. I'll provide a patch to fix that.
 
Regards
Michael


On 04.12.18, 00:55, "Jim Fehlig" <jfehlig at suse.com> wrote:

    On 11/27/18 7:07 AM, Michael Trapp wrote:
    > 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.
    
    Why do you need this available as a separate library? libserialclient doesn't 
    seem to have much use outside of vm-dump-metrics. IMO it should simply be a 
    convenience library in vm-dump-metrics/.
    
    Regards,
    Jim
    
    > 
    > virtio adds the 3rd transport method to vhostmd and the available
    > '#ifdef WITH_XENSTORE' sections in vm-dump-metrics/main.c should be reviewed.
    > 
    >   libmetrics/Makefile.am       |  17 +++-
    >   libmetrics/libmetrics.h      |   6 ++
    >   libmetrics/libserialclient.c | 172 +++++++++++++++++++++++++++++++++++
    >   libmetrics/libserialclient.h |  30 ++++++
    >   vm-dump-metrics/main.c       |  29 ++++--
    >   5 files changed, 246 insertions(+), 8 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..468f08f 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 \
    > +     libserialclient.c \
    >        libmetrics.h
    >   
    >   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.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..61adc2b
    > --- /dev/null
    > +++ b/libmetrics/libserialclient.c
    > @@ -0,0 +1,172 @@
    > +/*
    > + * 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 at sap.com>
    > + */
    > +
    > +#include <config.h>
    > +
    > +#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;
    > +    size_t len;
    > +
    > +    response = 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, 1UL, 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
    > + */
    > +char *get_virtio_metrics(const char *dev_name)
    > +{
    > +    const char request[] = "GET /metrics/XML\n\n", end_token[] = "\n\n";
    > +    const char *dev;
    > +    char *response = NULL;
    > +    int fd = -1;
    > +    size_t pos;
    > +    size_t buf_size = (1 << 16);
    > +    const size_t req_len = (size_t) strlen(request);
    > +    const time_t start_time = time(NULL);
    > +
    > +    if (dev_name)
    > +        dev = dev_name;
    > +    else
    > +        dev = "/dev/virtio-ports/vhostmd";
    > +
    > +    response = calloc(1UL, 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) {
    > +        ssize_t len = write(fd, &request[pos], req_len - pos);
    > +        if (len > 0)
    > +            pos += (size_t) len;
    > +        else {
    > +            if (errno == EAGAIN)
    > +                usleep(10000);
    > +            else
    > +                goto error;
    > +        }
    > +    }
    > +
    > +    pos = 0;
    > +    do {
    > +        ssize_t len = read(fd, &response[pos], buf_size - pos - 1);
    > +        if (len > 0) {
    > +            pos += (size_t) 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 < (size_t) strlen(end_token) ||
    > +              strcmp(end_token, &response[pos - (size_t) 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..887c6a5
    > --- /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 at sap.com>
    > + */
    > +
    > +#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 */
    > +char *get_virtio_metrics(const char *dev_name);
    > +
    > +#endif
    > diff --git a/vm-dump-metrics/main.c b/vm-dump-metrics/main.c
    > index 53874e8..aff92ad 100644
    > --- a/vm-dump-metrics/main.c
    > +++ b/vm-dump-metrics/main.c
    > @@ -34,6 +34,7 @@ static void usage(const char *argv0)
    >   #ifdef WITH_XENSTORE
    >            "\t-x | --xenstore        Get metrics from xenstore.\n"
    >   #endif
    > +         "\t-i | --virtio          Get metrics from virtio channel.\n"
    >            "\t-b | --vbd             Get metrics from vbd.\n";
    >   
    >      fprintf (stderr, "\nUsage: %s [options]\n\n%s\n", argv0, options_str);
    > @@ -46,6 +47,7 @@ int main(int argc, char *argv[])
    >   #ifdef WITH_XENSTORE
    >      int xenstore = 0;
    >   #endif
    > +   int virtio = 0;
    >      const char *dfile = NULL;
    >   
    >      struct option opts[] = {
    > @@ -54,6 +56,7 @@ int main(int argc, char *argv[])
    >   #ifdef WITH_XENSTORE
    >         { "xenstore", no_argument, &xenstore, 1},
    >   #endif
    > +      { "virtio", no_argument, &virtio, 1},
    >         { "help", no_argument, NULL, '?' },
    >         { "dest", optional_argument, NULL, 'd'},
    >         {0, 0, 0, 0}
    > @@ -64,9 +67,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:vbix", opts, &optidx);
    >   #else
    > -      c = getopt_long(argc, argv, "d:vb", opts, &optidx);
    > +      c = getopt_long(argc, argv, "d:vbi", opts, &optidx);
    >   #endif
    >   
    >         if (c == -1)
    > @@ -82,6 +85,9 @@ int main(int argc, char *argv[])
    >            case 'b':
    >               vbd = 1;
    >               break;
    > +         case 'i':
    > +            virtio = 1;
    > +            break;
    >   #ifdef WITH_XENSTORE
    >            case 'x':
    >               xenstore = 1;
    > @@ -107,20 +113,31 @@ int main(int argc, char *argv[])
    >      }
    >   #endif
    >   
    > +   if (virtio) {
    > +       if (dump_virtio_metrics(dfile) == -1)
    > +           exit(1);
    > +       exit(0);
    > +   }
    > +
    >      if (vbd) {
    >          if (dump_metrics(dfile) == -1)
    >              exit(1);
    >          exit(0);
    >      }
    >   
    > -   /* If no metrics source is specfied, try disk first and then xenstore */
    > +   /*
    > +    * If no metrics source is specfied, try default order
    > +    * disk, virtio, xenstore
    > +    */
    >      if (dump_metrics(dfile) == -1) {
    > +       if (dump_virtio_metrics(dfile) == -1) {
    >   #ifdef WITH_XENSTORE
    > -       if (dump_xenstore_metrics(dfile) == -1)
    > -	       exit(1);
    > +           if (dump_xenstore_metrics(dfile) == -1)
    > +               exit(1);
    >   #else
    > -       exit(1);
    > +           exit(1);
    >   #endif
    > +       }
    >      }
    >   
    >      exit(0);
    > 
    
    





More information about the virt-tools-list mailing list