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?  
> 

At the first look, it seems to be a good thing.

But from a technical standpoint I agree with mlarkin here.  It doesn't
provide much value and it adds new complexity to systat.

I also have another reason for not putting it into systat: vmd, vmctl,
"vmctl status", and the related imsgs are still under active
development.  I don't want to take care of another consumer right now.

Reyk

> 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