summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn van Duren <martijn@cvs.openbsd.org>2020-09-23 15:52:07 +0000
committerMartijn van Duren <martijn@cvs.openbsd.org>2020-09-23 15:52:07 +0000
commit15b10d1d01071f6337882d8d75ff14b193859e63 (patch)
treeb254961864247b24298a9abd57a5ebb1f17c57b1
parentc196efec649375bb4bfadb6f3a18db593e12970e (diff)
Add support for agentx to vmd.
This is based around VM-MIB from RFC7666,but does not export the full spec. People more knowledgeable of vmd are encouraged to expand on this.
-rw-r--r--usr.sbin/vmd/Makefile10
-rw-r--r--usr.sbin/vmd/control.c13
-rw-r--r--usr.sbin/vmd/control_agentx.c778
-rw-r--r--usr.sbin/vmd/parse.y50
-rw-r--r--usr.sbin/vmd/vm.conf.517
-rw-r--r--usr.sbin/vmd/vmd.c22
-rw-r--r--usr.sbin/vmd/vmd.h16
7 files changed, 892 insertions, 14 deletions
diff --git a/usr.sbin/vmd/Makefile b/usr.sbin/vmd/Makefile
index 8645df7aecf..686026960c4 100644
--- a/usr.sbin/vmd/Makefile
+++ b/usr.sbin/vmd/Makefile
@@ -1,10 +1,10 @@
-# $OpenBSD: Makefile,v 1.22 2019/01/18 01:24:07 pd Exp $
+# $OpenBSD: Makefile,v 1.23 2020/09/23 15:52:06 martijn Exp $
.if ${MACHINE} == "amd64"
PROG= vmd
-SRCS= vmd.c control.c log.c priv.c proc.c config.c vmm.c
-SRCS+= vm.c loadfile_elf.c pci.c virtio.c i8259.c mc146818.c
+SRCS= vmd.c control.c control_agentx.c log.c priv.c proc.c config.c
+SRCS+= vmm.c vm.c loadfile_elf.c pci.c virtio.c i8259.c mc146818.c
SRCS+= ns8250.c i8253.c vmboot.c ufs.c disklabel.c dhcp.c packet.c
SRCS+= parse.y atomicio.c vioscsi.c vioraw.c vioqcow2.c fw_cfg.c
@@ -14,8 +14,8 @@ CFLAGS+= -Wmissing-declarations
CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
CFLAGS+= -Wsign-compare
-LDADD+= -lutil -lpthread -levent
-DPADD+= ${LIBUTIL} ${LIBPTHREAD} ${LIBEVENT}
+LDADD+= -lutil -lpthread -levent -lagentx
+DPADD+= ${LIBUTIL} ${LIBPTHREAD} ${LIBEVENT} ${LIBAGENTX}
YFLAGS=
diff --git a/usr.sbin/vmd/control.c b/usr.sbin/vmd/control.c
index 119fe460ca7..ad709d6d7f4 100644
--- a/usr.sbin/vmd/control.c
+++ b/usr.sbin/vmd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.30 2018/12/04 08:15:09 claudio Exp $ */
+/* $OpenBSD: control.c,v 1.31 2020/09/23 15:52:06 martijn Exp $ */
/*
* Copyright (c) 2010-2015 Reyk Floeter <reyk@openbsd.org>
@@ -29,6 +29,7 @@
#include <errno.h>
#include <event.h>
#include <fcntl.h>
+#include <libgen.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -38,6 +39,7 @@
#include "vmd.h"
#define CONTROL_BACKLOG 5
+#define CONTROL_AGENTX_PEERID UINT32_MAX
struct ctl_connlist ctl_conns;
@@ -80,6 +82,7 @@ control_dispatch_vmd(int fd, struct privsep_proc *p, struct imsg *imsg)
{
struct ctl_conn *c;
struct privsep *ps = p->p_ps;
+ struct vmd *env = ps->ps_env;
switch (imsg->hdr.type) {
case IMSG_VMDOP_START_VM_RESPONSE:
@@ -92,6 +95,10 @@ control_dispatch_vmd(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_VMDOP_GET_INFO_VM_END_DATA:
case IMSG_CTL_FAIL:
case IMSG_CTL_OK:
+ if (imsg->hdr.peerid == CONTROL_AGENTX_PEERID) {
+ control_agentx_dispatch_vmd(imsg);
+ break;
+ }
if ((c = control_connbyfd(imsg->hdr.peerid)) == NULL) {
log_warnx("%s: lost control connection: fd %d",
__func__, imsg->hdr.peerid);
@@ -103,10 +110,14 @@ control_dispatch_vmd(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_VMDOP_CONFIG:
config_getconfig(ps->ps_env, imsg);
proc_compose(ps, PROC_PARENT, IMSG_VMDOP_DONE, NULL, 0);
+ control_agentx(ps, &(env->vmd_cfg.cfg_agentx));
break;
case IMSG_CTL_RESET:
config_getreset(ps->ps_env, imsg);
break;
+ case IMSG_VMDOP_AGENTXFD:
+ control_agentx_connect(imsg->fd);
+ break;
default:
return (-1);
}
diff --git a/usr.sbin/vmd/control_agentx.c b/usr.sbin/vmd/control_agentx.c
new file mode 100644
index 00000000000..3f2b003ee00
--- /dev/null
+++ b/usr.sbin/vmd/control_agentx.c
@@ -0,0 +1,778 @@
+/* $OpenBSD: control_agentx.c,v 1.1 2020/09/23 15:52:06 martijn Exp $ */
+
+/*
+ * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/un.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <subagentx.h>
+#include <unistd.h>
+
+#include "proc.h"
+#include "vmd.h"
+
+#define CONTROL_AGENTX_PEERID UINT32_MAX
+
+struct control_agentx_vb {
+ struct subagentx_varbind *cav_vb;
+ struct subagentx_index *cav_idx;
+};
+
+static void control_agentx_nofd(struct subagentx *, void *, int);
+static void control_agentx_tryconnect(int, short, void *);
+static void control_agentx_read(int, short, void *);
+static int control_agentx_sortvir(const void *, const void *);
+static int control_agentx_adminstate(int);
+static int control_agentx_operstate(int);
+static void control_agentx_vmHvSoftware(struct subagentx_varbind *);
+static void control_agentx_vmHvVersion(struct subagentx_varbind *);
+static void control_agentx_vmHvObjectID(struct subagentx_varbind *);
+static void control_agentx_get_vmInfo(struct control_agentx_vb **, size_t *,
+ size_t *, struct subagentx_varbind *);
+static void control_agentx_vmNumber(struct subagentx_varbind *);
+static void control_agentx_emptystring_vm(struct subagentx_varbind *);
+static void control_agentx_vmName(struct subagentx_varbind *);
+static void control_agentx_vmAdminState(struct subagentx_varbind *);
+static void control_agentx_vmOperState(struct subagentx_varbind *);
+static void control_agentx_vmAutoStart(struct subagentx_varbind *);
+static void control_agentx_vmPersistent(struct subagentx_varbind *);
+static void control_agentx_vmCurCpuNumber(struct subagentx_varbind *);
+static void control_agentx_vmMemUnit(struct subagentx_varbind *);
+static void control_agentx_vmCurMem(struct subagentx_varbind *);
+static void control_agentx_vmMinMem(struct subagentx_varbind *);
+static void control_agentx_vmMaxMem(struct subagentx_varbind *);
+static void control_agentx_vm_finalize(struct control_agentx_vb *,
+ struct vmop_info_result *, uint32_t,
+ void (*)(struct subagentx_varbind *, struct vmop_info_result *));
+static void control_agentx_emptystring_vm_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmName_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmAdminState_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmOperState_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmAutoStart_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmPersistent_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmCurCpuNumber_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmMemUnit_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmCurMem_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmMinMem_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+static void control_agentx_vmMaxMem_finalize(struct subagentx_varbind *,
+ struct vmop_info_result *);
+
+static struct subagentx *sa;
+static struct subagentx_session *sas;
+static struct subagentx_context *sac;
+static struct subagentx_region *vmMIB;
+static struct subagentx_index *vmIndex;
+static struct subagentx_object *vmNumber;
+static struct event connev, rev;
+static struct agentx *agentx;
+static struct privsep *aps;
+
+static struct control_agentx_vb *vmNumbervb = NULL;
+static size_t vmNumbernvb = 0;
+static size_t vmNumbervblen = 0;
+static struct control_agentx_vb *vmEmptystringvb = NULL;
+static size_t vmEmptystringnvb = 0;
+static size_t vmEmptystringvblen = 0;
+static struct control_agentx_vb *vmNamevb = NULL;
+static size_t vmNamenvb = 0;
+static size_t vmNamevblen = 0;
+static struct control_agentx_vb *vmAdminStatevb = NULL;
+static size_t vmAdminStatenvb = 0;
+static size_t vmAdminStatevblen = 0;
+static struct control_agentx_vb *vmOperStatevb = NULL;
+static size_t vmOperStatenvb = 0;
+static size_t vmOperStatevblen = 0;
+static struct control_agentx_vb *vmAutoStartvb = NULL;
+static size_t vmAutoStartnvb = 0;
+static size_t vmAutoStartvblen = 0;
+static struct control_agentx_vb *vmPersistentvb = NULL;
+static size_t vmPersistentnvb = 0;
+static size_t vmPersistentvblen = 0;
+static struct control_agentx_vb *vmCurCpuNumbervb = NULL;
+static size_t vmCurCpuNumbernvb = 0;
+static size_t vmCurCpuNumbervblen = 0;
+static struct control_agentx_vb *vmMemUnitvb = NULL;
+static size_t vmMemUnitnvb = 0;
+static size_t vmMemUnitvblen = 0;
+static struct control_agentx_vb *vmCurMemvb = NULL;
+static size_t vmCurMemnvb = 0;
+static size_t vmCurMemvblen = 0;
+static struct control_agentx_vb *vmMinMemvb = NULL;
+static size_t vmMinMemnvb = 0;
+static size_t vmMinMemvblen = 0;
+static struct control_agentx_vb *vmMaxMemvb = NULL;
+static size_t vmMaxMemnvb = 0;
+static size_t vmMaxMemvblen = 0;
+static int vmcollecting = 0;
+
+#define VMMIB SUBAGENTX_MIB2, 236
+#define VMOBJECTS VMMIB, 1
+#define VMHVSOFTWARE VMOBJECTS, 1, 1
+#define VMHVVERSION VMOBJECTS, 1, 2
+#define VMHVOBJECTID VMOBJECTS, 1, 3
+#define VMNUMBER VMOBJECTS, 2
+#define VMENTRY VMOBJECTS, 4, 1
+#define VMINDEX VMENTRY, 1
+#define VMNAME VMENTRY, 2
+#define VMUUID VMENTRY, 3
+#define VMOSTYPE VMENTRY, 4
+#define VMADMINSTATE VMENTRY, 5
+#define VMOPERSTATE VMENTRY, 6
+#define VMAUTOSTART VMENTRY, 7
+#define VMPERSISTENT VMENTRY, 8
+#define VMCURCPUNUMBER VMENTRY, 9
+#define VMMINCPUNUMBER VMENTRY, 10
+#define VMMAXCPUNUMBER VMENTRY, 11
+#define VMMEMUNITS VMENTRY, 12
+#define VMCURMEM VMENTRY, 13
+#define VMMINMEM VMENTRY, 14
+#define VMMAXMEM VMENTRY, 15
+
+#define VIRTUALMACHINEADMINSTATE_RUNNING 1
+#define VIRTUALMACHINEADMINSTATE_SUSPENDED 2
+#define VIRTUALMACHINEADMINSTATE_PAUSED 3
+#define VIRTUALMACHINEADMINSTATE_SHUTDOWN 4
+
+#define VIRTUALMACHINEOPERSTATE_UNKNOWN 1
+#define VIRTUALMACHINEOPERSTATE_OTHER 2
+#define VIRTUALMACHINEOPERSTATE_PREPARING 3
+#define VIRTUALMACHINEOPERSTATE_RUNNING 4
+#define VIRTUALMACHINEOPERSTATE_SUSPENDING 5
+#define VIRTUALMACHINEOPERSTATE_SUSPENDED 6
+#define VIRTUALMACHINEOPERSTATE_RESUMING 7
+#define VIRTUALMACHINEOPERSTATE_PAUSED 8
+#define VIRTUALMACHINEOPERSTATE_MIGRATING 9
+#define VIRTUALMACHINEOPERSTATE_SHUTTINGDOWN 10
+#define VIRTUALMACHINEOPERSTATE_SHUTDOWN 11
+#define VIRTUALMACHINEOPERSTATE_CRASHED 12
+
+#define VIRTUALMACHINEAUTOSTART_UNKNOWN 1
+#define VIRTUALMACHINEAUTOSTART_ENABLED 2
+#define VIRTUALMACHINEAUTOSTART_DISABLED 3
+
+#define VIRTUALMACHINEPERSISTENT_UNKNOWN 1
+#define VIRTUALMACHINEPERSISTENT_PERSISTENT 2
+#define VIRTUALMACHINEPERSISTENT_TRANSIENT 3
+
+void
+control_agentx(struct privsep *ps, struct agentx *env)
+{
+ static char curpath[sizeof(((struct sockaddr_un *)0)->sun_path)];
+ static char curcontext[50];
+ char *context = env->context[0] == '\0' ? NULL : env->context;
+ int changed = 0;
+
+ agentx = env;
+ aps = ps;
+
+ subagentx_log_fatal = fatalx;
+ subagentx_log_warn = log_warnx;
+ subagentx_log_info = log_info;
+ subagentx_log_debug = log_debug;
+
+ if (!agentx->enabled) {
+ if (sa != NULL) {
+ subagentx_free(sa);
+ curpath[0] = '\0';
+ curcontext[0] = '\0';
+ sa = NULL;
+ }
+ return;
+ }
+
+ if (strcmp(curpath, agentx->path) != 0) {
+ if (sa != NULL)
+ subagentx_free(sa);
+ if ((sa = subagentx(control_agentx_nofd, NULL)) == NULL)
+ fatal("Can't setup agentx");
+ if ((sas = subagentx_session(sa, NULL, 0, "vmd", 0)) == NULL)
+ fatal("Can't setup agentx session");
+ (void) strlcpy(curpath, agentx->path, sizeof(curpath));
+ curcontext[0] = '\0';
+ changed = 1;
+ }
+
+ if (strcmp(curcontext, agentx->context) != 0 || changed) {
+ if (!changed)
+ subagentx_context_free(sac);
+ if ((sac = subagentx_context(sas, context)) == NULL)
+ fatal("Can't setup agentx context");
+ changed = 1;
+ }
+
+ if (!changed)
+ return;
+
+ if ((vmMIB = subagentx_region(sac,
+ SUBAGENTX_OID(VMMIB), 1)) == NULL)
+ fatal("subagentx_region vmMIB");
+
+ if ((vmIndex = subagentx_index_integer_dynamic(vmMIB,
+ SUBAGENTX_OID(VMINDEX))) == NULL)
+ fatal("subagentx_index_integer_dynamic");
+
+ if ((subagentx_object(vmMIB, SUBAGENTX_OID(VMHVSOFTWARE), NULL, 0, 0,
+ control_agentx_vmHvSoftware)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMHVVERSION), NULL, 0, 0,
+ control_agentx_vmHvVersion)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMHVOBJECTID), NULL, 0, 0,
+ control_agentx_vmHvObjectID)) == NULL ||
+ (vmNumber = subagentx_object(vmMIB, SUBAGENTX_OID(VMNUMBER), NULL,
+ 0, 0, control_agentx_vmNumber)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMNAME),
+ &vmIndex, 1, 0, control_agentx_vmName)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMUUID), &vmIndex, 1, 0,
+ control_agentx_emptystring_vm)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMOSTYPE), &vmIndex, 1, 0,
+ control_agentx_emptystring_vm)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMADMINSTATE),
+ &vmIndex, 1, 0, control_agentx_vmAdminState)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMOPERSTATE),
+ &vmIndex, 1, 0, control_agentx_vmOperState)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMAUTOSTART),
+ &vmIndex, 1, 0, control_agentx_vmAutoStart)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMPERSISTENT),
+ &vmIndex, 1, 0, control_agentx_vmPersistent)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMCURCPUNUMBER),
+ &vmIndex, 1, 0, control_agentx_vmCurCpuNumber)) == NULL ||
+ /* XXX Should be vmMinCpuNumber, but we don't support that */
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMMINCPUNUMBER),
+ &vmIndex, 1, 0, control_agentx_vmCurCpuNumber)) == NULL ||
+ /* XXX Should be vmMaxCpuNumber, but we don't support that */
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMMAXCPUNUMBER),
+ &vmIndex, 1, 0, control_agentx_vmCurCpuNumber)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMMEMUNITS),
+ &vmIndex, 1, 0, control_agentx_vmMemUnit)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMCURMEM),
+ &vmIndex, 1, 0, control_agentx_vmCurMem)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMMINMEM),
+ &vmIndex, 1, 0, control_agentx_vmMinMem)) == NULL ||
+ (subagentx_object(vmMIB, SUBAGENTX_OID(VMMAXMEM),
+ &vmIndex, 1, 0, control_agentx_vmMaxMem)) == NULL)
+ fatal("subagentx_object");
+}
+
+static void
+control_agentx_nofd(struct subagentx *lsa, void *cookie, int close)
+{
+ event_del(&rev);
+ if (!close)
+ control_agentx_tryconnect(-1, 0, lsa);
+}
+
+static void
+control_agentx_tryconnect(int fd, short event, void *cookie)
+{
+ sa = cookie;
+
+ proc_compose(aps, PROC_PARENT, IMSG_VMDOP_AGENTXFD, NULL, 0);
+}
+
+void
+control_agentx_connect(int fd)
+{
+ struct timeval timeout = {3, 0};
+
+ if (sa == NULL)
+ return;
+
+ if (fd == -1) {
+ evtimer_set(&connev, control_agentx_tryconnect, sa);
+ evtimer_add(&connev, &timeout);
+ return;
+ }
+
+ subagentx_connect(sa, fd);
+
+ event_set(&rev, fd, EV_READ|EV_PERSIST, control_agentx_read, sa);
+ event_add(&rev, NULL);
+}
+
+static void
+control_agentx_read(int fd, short event, void *cookie)
+{
+ struct subagentx *lsa = cookie;
+
+ subagentx_read(lsa);
+}
+
+static int
+control_agentx_sortvir(const void *c1, const void *c2)
+{
+ const struct vmop_info_result *v1 = c1, *v2 = c2;
+
+ return v1->vir_info.vir_id < v2->vir_info.vir_id ? -1 :
+ v1->vir_info.vir_id > v2->vir_info.vir_id;
+}
+
+/* XXX This needs more scrutiny from someone who knows vmd */
+static int
+control_agentx_adminstate(int mask)
+{
+ if (mask & VM_STATE_PAUSED)
+ return VIRTUALMACHINEADMINSTATE_PAUSED;
+ else if (mask & VM_STATE_RUNNING)
+ return VIRTUALMACHINEADMINSTATE_RUNNING;
+ else if (mask & VM_STATE_SHUTDOWN)
+ return VIRTUALMACHINEADMINSTATE_SHUTDOWN;
+ /* Presence of absence of other flags */
+ else if (!mask || (mask & VM_STATE_DISABLED))
+ return VIRTUALMACHINEADMINSTATE_SHUTDOWN;
+
+ return VIRTUALMACHINEADMINSTATE_SHUTDOWN;
+}
+
+/* XXX This needs more scrutiny from someone who knows vmd */
+static int
+control_agentx_operstate(int mask)
+{
+ if (mask & VM_STATE_PAUSED)
+ return VIRTUALMACHINEOPERSTATE_PAUSED;
+ else if (mask & VM_STATE_RUNNING)
+ return VIRTUALMACHINEOPERSTATE_RUNNING;
+ else if (mask & VM_STATE_SHUTDOWN)
+ return VIRTUALMACHINEOPERSTATE_SHUTDOWN;
+ /* Presence of absence of other flags */
+ else if (!mask || (mask & VM_STATE_DISABLED))
+ return VIRTUALMACHINEOPERSTATE_SHUTDOWN;
+
+ return VIRTUALMACHINEOPERSTATE_SHUTDOWN;
+}
+
+void
+control_agentx_dispatch_vmd(struct imsg *imsg)
+{
+ static struct vmop_info_result *vir = NULL;
+ struct vmop_info_result *tvir;
+ static uint32_t nvir = 0;
+ static size_t virlen = 0;
+ static int error = 0;
+ size_t i;
+
+ switch (imsg->hdr.type) {
+ case IMSG_VMDOP_GET_INFO_VM_DATA:
+ if (error)
+ break;
+ if (nvir + 1 > virlen) {
+ tvir = reallocarray(vir, virlen + 10, sizeof(*vir));
+ if (tvir == NULL) {
+ log_warn("%s: Couldn't dispatch vm information",
+ __func__);
+ error = 1;
+ break;
+ }
+ vir = tvir;
+ }
+ memcpy(&(vir[nvir++]), imsg->data, sizeof(vir[nvir]));
+ break;
+ case IMSG_VMDOP_GET_INFO_VM_END_DATA:
+ vmcollecting = 0;
+ if (error) {
+ for (i = 0; i < vmNumbernvb; i++)
+ subagentx_varbind_error(vmNumbervb[i].cav_vb);
+ vmNumbernvb = 0;
+ for (i = 0; i < vmEmptystringnvb; i++)
+ subagentx_varbind_error(
+ vmEmptystringvb[i].cav_vb);
+ vmEmptystringnvb = 0;
+ for (i = 0; i < vmNamenvb; i++)
+ subagentx_varbind_error(vmNamevb[i].cav_vb);
+ vmNamenvb = 0;
+ for (i = 0; i < vmAdminStatenvb; i++)
+ subagentx_varbind_error(
+ vmAdminStatevb[i].cav_vb);
+ vmAdminStatenvb = 0;
+ for (i = 0; i < vmOperStatenvb; i++)
+ subagentx_varbind_error(
+ vmOperStatevb[i].cav_vb);
+ vmOperStatenvb = 0;
+ for (i = 0; i < vmAutoStartnvb; i++)
+ subagentx_varbind_error(
+ vmAutoStartvb[i].cav_vb);
+ vmAutoStartnvb = 0;
+ for (i = 0; i < vmPersistentnvb; i++)
+ subagentx_varbind_error(
+ vmPersistentvb[i].cav_vb);
+ vmPersistentnvb = 0;
+ for (i = 0; i < vmCurCpuNumbernvb; i++)
+ subagentx_varbind_error(
+ vmCurCpuNumbervb[i].cav_vb);
+ vmCurCpuNumbernvb = 0;
+ for (i = 0; i < vmMemUnitnvb; i++)
+ subagentx_varbind_error(vmMemUnitvb[i].cav_vb);
+ vmMemUnitnvb = 0;
+ for (i = 0; i < vmCurMemnvb; i++)
+ subagentx_varbind_error(vmCurMemvb[i].cav_vb);
+ vmCurMemnvb = 0;
+ for (i = 0; i < vmMinMemnvb; i++)
+ subagentx_varbind_error(vmMinMemvb[i].cav_vb);
+ vmMinMemnvb = 0;
+ for (i = 0; i < vmMaxMemnvb; i++)
+ subagentx_varbind_error(vmMaxMemvb[i].cav_vb);
+ vmMaxMemnvb = 0;
+ error = 0;
+ nvir = 0;
+ return;
+ }
+
+ qsort(vir, nvir, sizeof(*vir), control_agentx_sortvir);
+ for (i = 0; i < vmNumbernvb; i++)
+ subagentx_varbind_integer(vmNumbervb[i].cav_vb, nvir);
+ vmNumbernvb = 0;
+ for (i = 0; i < vmEmptystringnvb; i++)
+ control_agentx_vm_finalize(&(vmEmptystringvb[i]), vir,
+ nvir, control_agentx_emptystring_vm_finalize);
+ vmEmptystringnvb = 0;
+ for (i = 0; i < vmNamenvb; i++)
+ control_agentx_vm_finalize(&(vmNamevb[i]), vir,
+ nvir, control_agentx_vmName_finalize);
+ vmNamenvb = 0;
+ for (i = 0; i < vmAdminStatenvb; i++)
+ control_agentx_vm_finalize(&(vmAdminStatevb[i]),
+ vir, nvir, control_agentx_vmAdminState_finalize);
+ vmAdminStatenvb = 0;
+ for (i = 0; i < vmOperStatenvb; i++)
+ control_agentx_vm_finalize(&(vmOperStatevb[i]),
+ vir, nvir, control_agentx_vmOperState_finalize);
+ vmOperStatenvb = 0;
+ for (i = 0; i < vmAutoStartnvb; i++)
+ control_agentx_vm_finalize(&(vmAutoStartvb[i]),
+ vir, nvir, control_agentx_vmAutoStart_finalize);
+ vmAutoStartnvb = 0;
+ for (i = 0; i < vmPersistentnvb; i++)
+ control_agentx_vm_finalize(&(vmPersistentvb[i]),
+ vir, nvir, control_agentx_vmPersistent_finalize);
+ vmPersistentnvb = 0;
+ for (i = 0; i < vmCurCpuNumbernvb; i++)
+ control_agentx_vm_finalize(&(vmCurCpuNumbervb[i]),
+ vir, nvir, control_agentx_vmCurCpuNumber_finalize);
+ vmCurCpuNumbernvb = 0;
+ for (i = 0; i < vmMemUnitnvb; i++)
+ control_agentx_vm_finalize(&(vmMemUnitvb[i]),
+ vir, nvir, control_agentx_vmMemUnit_finalize);
+ vmMemUnitnvb = 0;
+ for (i = 0; i < vmCurMemnvb; i++)
+ control_agentx_vm_finalize(&(vmCurMemvb[i]),
+ vir, nvir, control_agentx_vmCurMem_finalize);
+ vmCurMemnvb = 0;
+ for (i = 0; i < vmMinMemnvb; i++)
+ control_agentx_vm_finalize(&(vmMinMemvb[i]),
+ vir, nvir, control_agentx_vmMinMem_finalize);
+ vmMinMemnvb = 0;
+ for (i = 0; i < vmMaxMemnvb; i++)
+ control_agentx_vm_finalize(&(vmMaxMemvb[i]),
+ vir, nvir, control_agentx_vmMaxMem_finalize);
+ vmMaxMemnvb = 0;
+ nvir = 0;
+ break;
+ default:
+ fatalx("%s: error handling imsg %d", __func__, imsg->hdr.type);
+ }
+}
+
+static void
+control_agentx_vmHvSoftware(struct subagentx_varbind *vb)
+{
+ subagentx_varbind_string(vb, "OpenBSD VMM");
+}
+
+static void
+control_agentx_vmHvVersion(struct subagentx_varbind *vb)
+{
+ int osversid[] = {CTL_KERN, KERN_OSRELEASE};
+ static char osvers[10] = "";
+ size_t osverslen;
+
+ if (osvers[0] == '\0') {
+ osverslen = sizeof(osvers);
+ if (sysctl(osversid, 2, osvers, &osverslen, NULL,
+ 0) == -1) {
+ log_warn("Failed vmHvVersion sysctl");
+ subagentx_varbind_string(vb, "unknown");
+ return;
+ }
+ if (osverslen >= sizeof(osvers))
+ osverslen = sizeof(osvers) - 1;
+ osvers[osverslen] = '\0';
+ }
+ subagentx_varbind_string(vb, osvers);
+}
+
+static void
+control_agentx_vmHvObjectID(struct subagentx_varbind *vb)
+{
+ subagentx_varbind_oid(vb, NULL, 0);
+}
+
+static void
+control_agentx_get_vmInfo(struct control_agentx_vb **vblist, size_t *nvb,
+ size_t *vblen, struct subagentx_varbind *vb)
+{
+ extern struct vmd *env;
+ struct control_agentx_vb *tvb;
+
+ if (*nvb + 1 > *vblen) {
+ if ((tvb = reallocarray(*vblist, (*vblen) + 10,
+ sizeof(**vblist))) == NULL) {
+ log_warn("%s: Couldn't retrieve vm information",
+ __func__);
+ subagentx_varbind_error(vb);
+ return;
+ }
+ *vblist = tvb;
+ *vblen += 10;
+ }
+
+ if (!vmcollecting) {
+ if (proc_compose_imsg(&(env->vmd_ps), PROC_PARENT, UINT32_MAX,
+ IMSG_VMDOP_GET_INFO_VM_REQUEST, CONTROL_AGENTX_PEERID, -1,
+ NULL, 0) == -1) {
+ log_warn("%s: Couldn't retrieve vm information",
+ __func__);
+ subagentx_varbind_error(vb);
+ return;
+ }
+ vmcollecting = 1;
+ }
+
+ (*vblist)[*nvb].cav_vb = vb;
+ if (subagentx_varbind_get_object(vb) != vmNumber)
+ (*vblist)[(*nvb)].cav_idx = vmIndex;
+ (*nvb)++;
+
+}
+
+static void
+control_agentx_vmNumber(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmNumbervb, &vmNumbernvb, &vmNumbervblen,
+ vb);
+}
+
+static void
+control_agentx_emptystring_vm(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmEmptystringvb, &vmEmptystringnvb,
+ &vmEmptystringvblen, vb);
+}
+
+static void
+control_agentx_vmName(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmNamevb, &vmNamenvb, &vmNamevblen, vb);
+}
+
+static void
+control_agentx_vmAdminState(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmAdminStatevb, &vmAdminStatenvb,
+ &vmAdminStatevblen, vb);
+}
+
+static void
+control_agentx_vmOperState(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmOperStatevb, &vmOperStatenvb,
+ &vmOperStatevblen, vb);
+}
+
+static void
+control_agentx_vmAutoStart(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmAutoStartvb, &vmAutoStartnvb,
+ &vmAutoStartvblen, vb);
+}
+
+static void
+control_agentx_vmPersistent(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmPersistentvb, &vmPersistentnvb,
+ &vmPersistentvblen, vb);
+}
+
+static void
+control_agentx_vmCurCpuNumber(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmCurCpuNumbervb, &vmCurCpuNumbernvb,
+ &vmCurCpuNumbervblen, vb);
+}
+
+static void
+control_agentx_vmMemUnit(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmMemUnitvb, &vmMemUnitnvb, &vmMemUnitvblen,
+ vb);
+}
+
+static void
+control_agentx_vmCurMem(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmCurMemvb, &vmCurMemnvb, &vmCurMemvblen,
+ vb);
+}
+
+static void
+control_agentx_vmMinMem(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmMinMemvb, &vmMinMemnvb, &vmMinMemvblen,
+ vb);
+}
+
+static void
+control_agentx_vmMaxMem(struct subagentx_varbind *vb)
+{
+ control_agentx_get_vmInfo(&vmMaxMemvb, &vmMaxMemnvb, &vmMaxMemvblen,
+ vb);
+}
+
+static void
+control_agentx_vm_finalize(struct control_agentx_vb *vb,
+ struct vmop_info_result *vir, uint32_t nvir,
+ void (*match)(struct subagentx_varbind *, struct vmop_info_result *))
+{
+ uint32_t idx;
+ uint32_t i;
+
+ idx = subagentx_varbind_get_index_integer(vb->cav_vb, vb->cav_idx);
+ switch (subagentx_varbind_request(vb->cav_vb)) {
+ case SUBAGENTX_REQUEST_TYPE_GET:
+ for (i = 0; i < nvir; i++) {
+ if (vir[i].vir_info.vir_id == idx) {
+ match(vb->cav_vb, &(vir[i]));
+ return;
+ }
+ }
+ break;
+ case SUBAGENTX_REQUEST_TYPE_GETNEXT:
+ for (i = 0; i < nvir; i++) {
+ if (vir[i].vir_info.vir_id > idx) {
+ subagentx_varbind_set_index_integer(vb->cav_vb,
+ vb->cav_idx, vir[i].vir_info.vir_id);
+ match(vb->cav_vb, &(vir[i]));
+ return;
+ }
+ }
+ break;
+ case SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE:
+ for (i = 0; i < nvir; i++) {
+ if (vir[i].vir_info.vir_id >= idx) {
+ subagentx_varbind_set_index_integer(vb->cav_vb,
+ vb->cav_idx, vir[i].vir_info.vir_id);
+ match(vb->cav_vb, &(vir[i]));
+ return;
+ }
+ }
+ break;
+ }
+ subagentx_varbind_notfound(vb->cav_vb);
+ return;
+}
+
+static void
+control_agentx_emptystring_vm_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_string(vb, "");
+}
+
+static void
+control_agentx_vmName_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_string(vb, vir->vir_info.vir_name);
+}
+
+static void
+control_agentx_vmAdminState_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_integer(vb,
+ control_agentx_adminstate(vir->vir_state));
+}
+
+static void
+control_agentx_vmOperState_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_integer(vb, control_agentx_operstate(vir->vir_state));
+}
+
+static void
+control_agentx_vmAutoStart_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_integer(vb,
+ vir->vir_state & VM_STATE_DISABLED ?
+ VIRTUALMACHINEAUTOSTART_DISABLED : VIRTUALMACHINEAUTOSTART_ENABLED);
+}
+
+/* XXX We can dynamically create vm's but I don't know how to differentiate */
+static void
+control_agentx_vmPersistent_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_integer(vb, 1);
+}
+
+static void
+control_agentx_vmCurCpuNumber_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_integer(vb, vir->vir_info.vir_ncpus);
+}
+
+static void
+control_agentx_vmMemUnit_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_integer(vb, 1024 * 1024);
+}
+
+static void
+control_agentx_vmCurMem_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_integer(vb, vir->vir_info.vir_used_size / 1024 /1024);
+}
+
+static void
+control_agentx_vmMinMem_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_integer(vb, -1);
+}
+
+static void
+control_agentx_vmMaxMem_finalize(struct subagentx_varbind *vb,
+ struct vmop_info_result *vir)
+{
+ subagentx_varbind_integer(vb, vir->vir_info.vir_memory_size);
+}
diff --git a/usr.sbin/vmd/parse.y b/usr.sbin/vmd/parse.y
index be326146516..d44a02c60a1 100644
--- a/usr.sbin/vmd/parse.y
+++ b/usr.sbin/vmd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.54 2019/12/12 19:52:10 kn Exp $ */
+/* $OpenBSD: parse.y,v 1.55 2020/09/23 15:52:06 martijn Exp $ */
/*
* Copyright (c) 2007-2016 Reyk Floeter <reyk@openbsd.org>
@@ -48,6 +48,7 @@
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
+#include <subagentx.h>
#include "proc.h"
#include "vmd.h"
@@ -120,7 +121,8 @@ typedef struct {
%token INCLUDE ERROR
-%token ADD ALLOW BOOT CDROM DEVICE DISABLE DISK DOWN ENABLE FORMAT GROUP
+%token ADD AGENTX ALLOW BOOT CDROM CONTEXT DEVICE DISABLE DISK DOWN ENABLE
+%token FORMAT GROUP
%token INET6 INSTANCE INTERFACE LLADDR LOCAL LOCKED MEMORY NET NIFS OWNER
%token PATH PREFIX RDOMAIN SIZE SOCKET SWITCH UP VM VMID STAGGERED START
%token PARALLEL DELAY
@@ -218,6 +220,14 @@ main : LOCAL INET6 {
env->vmd_ps.ps_csock.cs_uid = $3.uid;
env->vmd_ps.ps_csock.cs_gid = $3.gid == -1 ? 0 : $3.gid;
}
+ | AGENTX {
+ env->vmd_cfg.cfg_agentx.enabled = 1;
+ } agentxopts {
+ if (env->vmd_cfg.cfg_agentx.path[0] == '\0')
+ strlcpy(env->vmd_cfg.cfg_agentx.path,
+ SUBAGENTX_AGENTX_MASTER,
+ sizeof(env->vmd_cfg.cfg_agentx.path));
+ }
| STAGGERED START PARALLEL NUMBER DELAY NUMBER {
env->vmd_cfg.cfg_flags |= VMD_CFG_STAGGERED_START;
env->vmd_cfg.delay.tv_sec = $6;
@@ -596,6 +606,35 @@ owner_id : NUMBER {
}
;
+agentxopt : CONTEXT STRING {
+ if (strlcpy(env->vmd_cfg.cfg_agentx.context, $2,
+ sizeof(env->vmd_cfg.cfg_agentx.context)) >=
+ sizeof(env->vmd_cfg.cfg_agentx.context)) {
+ yyerror("agentx context too large");
+ free($2);
+ YYERROR;
+ }
+ free($2);
+ }
+ | PATH STRING {
+ if (strlcpy(env->vmd_cfg.cfg_agentx.path, $2,
+ sizeof(env->vmd_cfg.cfg_agentx.path)) >=
+ sizeof(env->vmd_cfg.cfg_agentx.path)) {
+ yyerror("agentx path too large");
+ free($2);
+ YYERROR;
+ }
+ free($2);
+ if (env->vmd_cfg.cfg_agentx.path[0] != '/') {
+ yyerror("agentx path is not absolute");
+ YYERROR;
+ }
+ }
+
+agentxopts : /* none */
+ | agentxopts agentxopt
+ ;
+
image_format : /* none */ {
$$ = 0;
}
@@ -767,9 +806,11 @@ lookup(char *s)
/* this has to be sorted always */
static const struct keywords keywords[] = {
{ "add", ADD },
+ { "agentx", AGENTX },
{ "allow", ALLOW },
{ "boot", BOOT },
{ "cdrom", CDROM },
+ { "context", CONTEXT},
{ "delay", DELAY },
{ "device", DEVICE },
{ "disable", DISABLE },
@@ -791,6 +832,7 @@ lookup(char *s)
{ "net", NET },
{ "owner", OWNER },
{ "parallel", PARALLEL },
+ { "path", PATH },
{ "prefix", PREFIX },
{ "rdomain", RDOMAIN },
{ "size", SIZE },
@@ -1147,6 +1189,10 @@ parse_config(const char *filename)
/* Set the default switch type */
(void)strlcpy(vsw_type, VMD_SWITCH_TYPE, sizeof(vsw_type));
+ env->vmd_cfg.cfg_agentx.enabled = 0;
+ env->vmd_cfg.cfg_agentx.context[0] = '\0';
+ env->vmd_cfg.cfg_agentx.path[0] = '\0';
+
yyparse();
errors = file->errors;
popfile();
diff --git a/usr.sbin/vmd/vm.conf.5 b/usr.sbin/vmd/vm.conf.5
index 348d13d51fe..8ad6cfbe118 100644
--- a/usr.sbin/vmd/vm.conf.5
+++ b/usr.sbin/vmd/vm.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: vm.conf.5,v 1.53 2020/02/16 11:03:25 kn Exp $
+.\" $OpenBSD: vm.conf.5,v 1.54 2020/09/23 15:52:06 martijn Exp $
.\"
.\" Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
.\" Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: February 16 2020 $
+.Dd $Mdocdate: September 23 2020 $
.Dt VM.CONF 5
.Os
.Sh NAME
@@ -91,6 +91,19 @@ vm "vm1.example.com" {
.Sh GLOBAL CONFIGURATION
The following setting can be configured globally:
.Bl -tag -width Ds
+.It Ic agentx Oo Ic context Ar context Oc Oo Ic path Ar path Oc
+Export vm metrics via an agentx compatible
+.Pq snmp
+daemon by connecting to
+.Ar path .
+Metrics can be found under the vmMIB subtree
+.Pq mib-2.236 .
+If
+.Ar path
+is omitted it will default to
+.Pa /var/agentx/master .
+.Ar Context
+is the SNMPv3 context and can usually be omitted.
.It Ic local prefix Ar address Ns Li / Ns Ar prefix
Set the network prefix that is used to allocate subnets for
local interfaces, see
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index 634c81e79ac..46fd4c0cf62 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.117 2019/12/12 03:53:38 pd Exp $ */
+/* $OpenBSD: vmd.c,v 1.118 2020/09/23 15:52:06 martijn Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -96,6 +96,9 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
char *str = NULL;
uint32_t id = 0;
struct control_sock *rcs;
+ struct sockaddr_un sun;
+
+ fd = -1;
switch (imsg->hdr.type) {
case IMSG_VMDOP_START_VM_REQUEST:
@@ -300,6 +303,19 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
control_reset(rcs);
cmd = 0;
break;
+ case IMSG_VMDOP_AGENTXFD:
+ sun.sun_len = sizeof(sun);
+ sun.sun_family = AF_UNIX;
+ strlcpy(sun.sun_path, env->vmd_cfg.cfg_agentx.path,
+ sizeof(sun.sun_path));
+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ||
+ connect(fd, (struct sockaddr *)&sun, sun.sun_len) == -1) {
+ log_warn("agentx connect");
+ close(fd);
+ fd = -1;
+ }
+ cmd = IMSG_VMDOP_AGENTXFD;
+ break;
default:
return (-1);
}
@@ -318,7 +334,7 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
break;
default:
if (proc_compose_imsg(ps, PROC_CONTROL, -1, cmd,
- imsg->hdr.peerid, -1, &res, sizeof(res)) == -1)
+ imsg->hdr.peerid, fd, &res, sizeof(res)) == -1)
return (-1);
break;
}
@@ -910,7 +926,7 @@ vmd_configure(void)
* flock - locking disk files
*/
if (pledge("stdio rpath wpath proc tty recvfd sendfd getpw"
- " chown fattr flock", NULL) == -1)
+ " chown fattr flock unix", NULL) == -1)
fatal("pledge");
if (parse_config(env->vmd_conffile) == -1) {
diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h
index 8c77025f6dc..8ab726db632 100644
--- a/usr.sbin/vmd/vmd.h
+++ b/usr.sbin/vmd/vmd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.h,v 1.99 2020/06/28 16:52:45 pd Exp $ */
+/* $OpenBSD: vmd.h,v 1.100 2020/09/23 15:52:06 martijn Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <sys/queue.h>
+#include <sys/un.h>
#include <sys/socket.h>
#include <machine/vmmvar.h>
@@ -123,6 +124,7 @@ enum imsg_type {
IMSG_VMDOP_VM_SHUTDOWN,
IMSG_VMDOP_VM_REBOOT,
IMSG_VMDOP_CONFIG,
+ IMSG_VMDOP_AGENTXFD,
IMSG_VMDOP_DONE
};
@@ -319,6 +321,12 @@ struct address {
};
TAILQ_HEAD(addresslist, address);
+struct agentx {
+ int enabled;
+ char path[sizeof(((struct sockaddr_un *)0)->sun_path)];
+ char context[50];
+};
+
struct vmd_config {
unsigned int cfg_flags;
#define VMD_CFG_INET6 0x01
@@ -329,6 +337,7 @@ struct vmd_config {
int parallelism;
struct address cfg_localprefix;
struct address cfg_localprefix6;
+ struct agentx cfg_agentx;
};
struct vmd {
@@ -474,6 +483,11 @@ int config_getdisk(struct privsep *, struct imsg *);
int config_getif(struct privsep *, struct imsg *);
int config_getcdrom(struct privsep *, struct imsg *);
+/* control_agentx.c */
+void control_agentx(struct privsep *, struct agentx *);
+void control_agentx_dispatch_vmd(struct imsg *);
+void control_agentx_connect(int);
+
/* vmboot.c */
FILE *vmboot_open(int, int *, int, unsigned int, struct vmboot_params *);
void vmboot_close(FILE *, struct vmboot_params *);