Mike Larkin <mlar...@azathoth.net> writes:

> On Sun, Feb 26, 2017 at 08:16:18PM +0100, Christian Barthel wrote:
>> Hi, 
>> 
>> I've added the 'vmctl status' view to systat(1).  I am not sure if this
>> is of general interest.  
>> 
>> Any opinions about it?  
>
> I don't know what to think about systat using imsg to talk to other
> daemons.
>
> Is there a reason vmctl's current output isn't sufficient for this
> purpose?

Thanks for your answer!
I thought it might be useful to see that output under the hood of
systat (printing various system statistics).  But I agree with you, it
adds some complexity, is not strictly necessary because same
functionality is there with vmctl/while loop and even worse, the code is
very similar to that of vmctl.  

>> 
>> Index: usr.bin/systat/Makefile
>> ===================================================================
>> RCS file: /cvs/src/usr.bin/systat/Makefile,v
>> retrieving revision 1.27
>> diff -u -p -r1.27 Makefile
>> --- usr.bin/systat/Makefile  12 Mar 2015 01:03:00 -0000      1.27
>> +++ usr.bin/systat/Makefile  26 Feb 2017 11:21:16 -0000
>> @@ -5,13 +5,14 @@ PROG=      systat
>>  .PATH:      ${.CURDIR}/../../usr.bin/vmstat
>>  
>>  CFLAGS+=-DNOKVM
>> +CPPFLAGS+=-I${.CURDIR}/../../usr.sbin/vmd/
>>  CPPFLAGS+=-I${.CURDIR}/../../usr.bin/vmstat
>>  CPPFLAGS+=-I${.CURDIR}/../../sbin/pfctl
>>  SRCS=       dkstats.c engine.c if.c inetname.c iostat.c main.c mbufs.c 
>> netstat.c \
>>      nfs.c pigs.c sensors.c swap.c vmstat.c pftop.c cache.c pf.c \
>> -    pool.c malloc.c cpu.c
>> +    pool.c malloc.c cpu.c vmm.c
>>  
>>  DPADD=      ${LIBCURSES} ${LIBM} ${LIBKVM}
>> -LDADD=      -lcurses -lm -lkvm
>> +LDADD=      -lcurses -lm -lkvm -lutil
>>  
>>  .include <bsd.prog.mk>
>> Index: usr.bin/systat/engine.c
>> ===================================================================
>> RCS file: /cvs/src/usr.bin/systat/engine.c,v
>> retrieving revision 1.19
>> diff -u -p -r1.19 engine.c
>> --- usr.bin/systat/engine.c  2 Jan 2016 20:01:48 -0000       1.19
>> +++ usr.bin/systat/engine.c  26 Feb 2017 11:21:17 -0000
>> @@ -1320,6 +1320,7 @@ engine_initialize(void)
>>      signal(SIGQUIT, sig_close);
>>      signal(SIGWINCH, sig_resize);
>>      signal(SIGALRM, sig_alarm);
>> +    signal(SIGPIPE, SIG_IGN); 
>>  }
>>  
>>  void
>> Index: usr.bin/systat/main.c
>> ===================================================================
>> RCS file: /cvs/src/usr.bin/systat/main.c,v
>> retrieving revision 1.66
>> diff -u -p -r1.66 main.c
>> --- usr.bin/systat/main.c    13 Oct 2016 11:22:46 -0000      1.66
>> +++ usr.bin/systat/main.c    26 Feb 2017 11:21:17 -0000
>> @@ -362,6 +362,7 @@ initialize(void)
>>      initmalloc();
>>      initnfs();
>>      initcpu();
>> +    initvmm();
>>  }
>>  
>>  void
>> Index: usr.bin/systat/vmm.c
>> ===================================================================
>> RCS file: usr.bin/systat/vmm.c
>> diff -N usr.bin/systat/vmm.c
>> --- /dev/null        1 Jan 1970 00:00:00 -0000
>> +++ usr.bin/systat/vmm.c     26 Feb 2017 11:21:25 -0000
>> @@ -0,0 +1,239 @@
>> +#include <sys/types.h>
>> +#include <sys/socket.h>
>> +#include <sys/signal.h>
>> +#include <sys/queue.h>
>> +#include <sys/un.h>
>> +#include <sys/uio.h>
>> +#include <machine/vmmvar.h>
>> +
>> +#include <imsg.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +#include <errno.h>
>> +#include <err.h>
>> +#include <unistd.h>
>> +
>> +#include "systat.h"
>> +#include "vmd.h"
>> +
>> +#define VMM_IDENT 256
>> +
>> +int initvmm(void);
>> +void print_vmm(void);
>> +int read_vmm(void);
>> +int vmm_keyboard_callback(int ch); 
>> +
>> +static void connect_vmd(void); 
>> +static void get_info_vm(uint32_t id, const char *name, int console);
>> +static int add_info(struct imsg *imsg, int *ret);
>> +
>> +static struct vmop_info_result*     vir     = NULL;
>> +static struct imsgbuf       *ibuf;
>> +static const char   *socket_name = SOCKET_NAME;
>> +static int is_connected = 0; 
>> +static int ctl_sock = -1; 
>> +static size_t       ct = 0;                                         /* 
>> counter for number of VM's */
>> +
>> +field_def fields_vmm[] = {
>> +    {"ID",     6, 10, 1, FLD_ALIGN_LEFT,  -1, 0, 0, 0},
>> +    {"PID",    5, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
>> +    {"VCPUS",  5, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
>> +    {"MAXMEM", 5, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
>> +    {"CURMEM", 5, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
>> +    {"TTY",    5, 15, 1, FLD_ALIGN_LEFT,  -1, 0, 0, 0},
>> +    {"NAME",   5, 15, 1, FLD_ALIGN_LEFT,  -1, 0, 0, 0},
>> +};
>> +
>> +#define FLD_VMM_ID      FIELD_ADDR(fields_vmm,0)
>> +#define FLD_VMM_PID     FIELD_ADDR(fields_vmm,1)
>> +#define FLD_VMM_VCPUS   FIELD_ADDR(fields_vmm,2)
>> +#define FLD_VMM_MAXMEM  FIELD_ADDR(fields_vmm,3)
>> +#define FLD_VMM_CURMEM  FIELD_ADDR(fields_vmm,4)
>> +#define FLD_VMM_TTYNAME FIELD_ADDR(fields_vmm,5)
>> +#define FLD_VMM_NAME    FIELD_ADDR(fields_vmm,6)
>> +
>> +/* Define views */
>> +field_def *view_vmm_0[] = {
>> +    FLD_VMM_ID, FLD_VMM_PID, FLD_VMM_VCPUS, FLD_VMM_MAXMEM, 
>> +    FLD_VMM_CURMEM, FLD_VMM_TTYNAME, FLD_VMM_NAME, NULL
>> +};
>> +
>> +/* Define view managers */
>> +struct view_manager vmm_mgr = {
>> +    "VMM", NULL, read_vmm, NULL, print_header,
>> +    print_vmm, vmm_keyboard_callback, NULL, NULL
>> +};
>> +
>> +field_view views_vmm[] = {
>> +    {view_vmm_0, "vmm", '6', &vmm_mgr},
>> +    {NULL, NULL, 0, NULL}
>> +};
>> +
>> +static void 
>> +connect_vmd(void) 
>> +{
>> +    struct sockaddr_un sun;
>> +
>> +    if (ctl_sock != -1) {
>> +            close(ibuf->fd); 
>> +            free(ibuf); 
>> +    }
>> +
>> +    if ((ctl_sock = socket(AF_UNIX,
>> +                    SOCK_STREAM|SOCK_CLOEXEC, 0)) == -1)
>> +            err(1, "socket");
>> +    
>> +    bzero(&sun, sizeof(sun));
>> +    sun.sun_family = AF_UNIX;
>> +    strlcpy(sun.sun_path, socket_name, sizeof(sun.sun_path));
>> +    
>> +    if (connect(ctl_sock,
>> +                                                    (struct sockaddr 
>> *)&sun, sizeof(sun)) == -1) 
>> +      is_connected = 0;
>> +    else
>> +            is_connected = 1; 
>> +    
>> +    if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
>> +            err(1, "malloc");
>> +    imsg_init(ibuf, ctl_sock);
>> +}
>> +
>> +static void
>> +get_info_vm(uint32_t id, const char *name, int console)
>> +{
>> +    if (imsg_compose(ibuf, IMSG_VMDOP_GET_INFO_VM_REQUEST, 
>> +        0, 0, -1, NULL, 0) < 0)
>> +            errx(1, "imsg_compose");
>> +}
>> +
>> +
>> +static int
>> +add_info(struct imsg *imsg, int *ret)
>> +{
>> +    if (imsg->hdr.type == IMSG_VMDOP_GET_INFO_VM_DATA) {
>> +            if ((vir = reallocarray(vir, ct + 1,
>> +                             sizeof(struct vmop_info_result))) == NULL) {
>> +                    *ret = ENOMEM;
>> +                    return (1);
>> +            }
>> +            memcpy(&vir[ct], imsg->data, sizeof(struct vmop_info_result));
>> +            ct++;
>> +            *ret = 0;
>> +            return (0);
>> +    } else if (imsg->hdr.type == IMSG_VMDOP_GET_INFO_VM_END_DATA) {
>> +            *ret = 0;
>> +            return (1);
>> +    } else {
>> +            *ret = EINVAL;
>> +            return (1);
>> +    }
>> +}
>> +
>> +int
>> +read_vmm(void)
>> +{
>> +    int n; 
>> +    struct imsg     imsg;
>> +    int ret, done = 0; 
>> +    
>> +    if (!is_connected)
>> +            connect_vmd(); 
>> +
>> +    get_info_vm(0, NULL, 0);
>> +    while (is_connected && ibuf->w.queued) 
>> +            if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) 
>> +                    is_connected = 0; 
>> +    ct = 0; 
>> +            
>> +    while (is_connected && !done) {
>> +            if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
>> +                    errx(1, "imsg_read error");
>> +            if (n == 0)
>> +                    errx(1, "pipe closed");
>> +            
>> +            while (is_connected && !done) {
>> +                    if ((n = imsg_get(ibuf, &imsg)) == -1)
>> +                            errx(1, "imsg_get error");
>> +                    if (n == 0)
>> +                            break;
>> +                    
>> +                    if (imsg.hdr.type == IMSG_CTL_FAIL) {
>> +                            if (IMSG_DATA_SIZE(&imsg) == sizeof(ret)) {
>> +                                    memcpy(&ret, imsg.data, sizeof(ret));
>> +                                    errno = ret;
>> +                                    warn("command failed");
>> +                            } else 
>> +                                    warn("command failed");
>> +                            done = 1;
>> +                            break;
>> +                    }
>> +                    
>> +                    ret = 0;
>> +                    done = add_info(&imsg, &ret);
>> +                    
>> +                    imsg_free(&imsg);
>> +            }
>> +    }
>> +    
>> +    return 0;
>> +}
>> +
>> +void
>> +print_vmm(void)
>> +{
>> +    char mem[VMM_IDENT];
>> +    char cmem[VMM_IDENT];
>> +    char tty[VMM_IDENT];
>> +    char name[VMM_MAX_NAME_LEN];
>> +    struct vm_info_result *v;
>> +    int i; 
>> +
>> +    for (i = 0; vir != NULL && i < ct; i++) {
>> +            v = &vir[i].vir_info;
>> +            if (v != NULL) {
>> +                    print_fld_uint(FLD_VMM_ID, v->vir_id);
>> +                    print_fld_uint(FLD_VMM_PID, v->vir_creator_pid);
>> +                    print_fld_uint(FLD_VMM_VCPUS, v->vir_ncpus);
>> +                    
>> +                    snprintf(mem, sizeof(mem), "%7zdMB", 
>> v->vir_memory_size);
>> +                    print_fld_str(FLD_VMM_MAXMEM, mem);
>> +                    snprintf(cmem, sizeof(cmem), "%7zdMB", 
>> v->vir_used_size/1024/1024);
>> +                    print_fld_str(FLD_VMM_CURMEM, cmem);
>> +                    snprintf(tty, sizeof(tty), "%s", vir[i].vir_ttyname);
>> +                    print_fld_str(FLD_VMM_TTYNAME, tty);
>> +                    snprintf(name, VMM_MAX_NAME_LEN, "%s", v->vir_name);
>> +                    print_fld_str(FLD_VMM_NAME, name);
>> +                    
>> +                    end_line();
>> +            }
>> +    }
>> +    end_line();
>> +    print_fld_str(FLD_VMM_ID, "Total:");
>> +    print_fld_uint(FLD_VMM_PID, ct);
>> +    print_fld_str(FLD_VMM_NAME, 
>> +                  (is_connected) ? "connected" : "disconnected");
>> +    
>> +    if (vir != NULL)
>> +            free(vir); 
>> +    vir = NULL; 
>> +}
>> +
>> +int 
>> +vmm_keyboard_callback(int ch) 
>> +{
>> +    keyboard_callback(ch);
>> +    read_vmm();
>> +}
>> +
>> +int
>> +initvmm(void)
>> +{
>> +    field_view *v;
>> +    
>> +    connect_vmd();
>> +    for (v = views_vmm; v->name != NULL; v++)
>> +            add_view(v);
>> +    
>> +    return(1);
>> +}
>> 
>

Reply via email to