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