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); > +} > --