--- /dev/null
+#include <sys/svrctl.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include <lib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void usage(void);
+
+#define VFS "vfs"
+#define PM "pm"
+#define SET "set"
+#define GET "get"
+
+static char *bin_name;
+
+int main (int argc, char *argv[])
+{
+ int r, param;
+ endpoint_t proc_e = NONE;
+ struct sysgetenv sysgetenv;
+ message m;
+ char *to_whom, *operation, *what, *value;
+ unsigned i;
+
+ bin_name = argv[0];
+ if (argc < 4 || argc > 5) usage();
+ if (geteuid() != 0) {
+ fprintf(stderr, "You have to be root to run this utility\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Make some parameters lower case to ease comparing */
+ to_whom = argv[1];
+ operation = argv[2];
+ what = argv[3];
+ for (i = 0; i < strlen(to_whom); ++i) to_whom[i] = tolower(to_whom[i]);
+ for (i = 0; i < strlen(operation); ++i) operation[i] = tolower(operation[i]);
+ for (i = 0; i < strlen(what); ++i) what[i] = tolower(what[i]);
+
+ if (!strncmp(to_whom, VFS, strlen(VFS)+1)) proc_e = VFS_PROC_NR;
+ else if (!strncmp(to_whom, PM, strlen(PM)+1)) proc_e = PM_PROC_NR;
+ else usage();
+
+ sysgetenv.key = what;
+ sysgetenv.keylen = strlen(what) + 1;
+
+ if (!strncmp(operation, SET, strlen(SET)+1)) {
+ if (argc != 5) usage();
+ value = argv[4];
+ sysgetenv.val = value;
+ sysgetenv.vallen = strlen(value) + 1;
+
+ if (proc_e == VFS_PROC_NR)
+ param = VFSSETPARAM;
+ else if (proc_e == PM_PROC_NR)
+ param = PMSETPARAM;
+ else
+ usage();
+
+ m.m2_i1 = param;
+ m.m2_p1 = (char *) &sysgetenv;
+ r = _syscall(proc_e, SVRCTL, &m);
+ if (r != 0) {
+ if (errno == ESRCH)
+ fprintf(stderr, "invalid parameter: %s\n", what);
+ else if (errno == EINVAL)
+ fprintf(stderr, "invalid value: %s\n", value);
+ else
+ perror("");
+ exit(EXIT_FAILURE);
+ }
+ return(EXIT_SUCCESS);
+ } else if (!strncmp(operation, GET, strlen(GET)+1)) {
+ char get_param_buffer[4096];
+
+ memset(get_param_buffer, '\0', sizeof(get_param_buffer));
+ sysgetenv.val = get_param_buffer;
+ sysgetenv.vallen = sizeof(get_param_buffer) - 1;
+
+ if (proc_e == VFS_PROC_NR)
+ param = VFSGETPARAM;
+ else if (proc_e == PM_PROC_NR)
+ param = PMGETPARAM;
+ else
+ usage();
+
+ m.m2_i1 = param;
+ m.m2_p1 = (char *) &sysgetenv;
+ r = _syscall(proc_e, SVRCTL, &m);
+ if (r != 0) {
+ if (errno == ESRCH)
+ fprintf(stderr, "invalid parameter: %s\n", what);
+ else
+ perror("");
+ return(EXIT_FAILURE);
+ } else {
+ if (sysgetenv.vallen > 0) {
+ get_param_buffer[sysgetenv.vallen] = '\0';
+ printf("%s\n", get_param_buffer);
+ }
+ }
+ return(EXIT_SUCCESS);
+ } else
+ usage();
+
+ return(EXIT_FAILURE);
+}
+
+static void usage()
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s <vfs|pm> set <request> <value>\n", bin_name);
+ fprintf(stderr, " %s <vfs|pm> get <request>\n", bin_name);
+ exit(EXIT_FAILURE);
+}
--- /dev/null
+.Dd $April 5, 2012$
+.Dt SVRCTL 1
+.Os
+.Sh NAME
+.Nm svrctl
+.Nd send servers control messages
+.Sh SYNOPSIS
+.Nm
+.Ar <vfs|pm> Ar get Ar <request>
+.Nm
+.Ar <vfs|pm> Ar set Ar <request> Ar <value>
+.Sh DESCRIPTION
+The
+.Nm
+utility allows to override the values of variables inside VFS or PM or to
+retrieve the values of variables. The variables that are allowed to be
+overridden are hard coded in the servers.
+.Sh EXAMPLES
+To retrieve how many threads are currently actively carrying out work in VFS:
+.Bd -literal -offset indent
+svrctl vfs get active_threads
+.Ed
+.Pp
+To generate a stack trace of all threads in VFS:
+.Bd -literal -offset indent
+svrctl vfs get print_traces
+.Ed
+.Pp
+To set verbosity level of VFS (allowed values range from 0 to 4)
+.Bd -literal -offset indent
+svrctl vfs set verbose 1
+.Ed
+.Pp
+To retrieve boot monitor parameters (note that these are also available through
+.Xr sysenv 1
+) such as
+.Va rootdevname
+,
+.Va memory
+,
+.Va hz
+, and if set,
+.Va bootopts
+,
+.Va cttyline
+,
+.Va cttybaud
+:
+.Bd -literal -offset indent
+svrctl pm get rootdevname
+svrctl pm get memory
+svrctl pm get hz
+svrctl pm get bootopts
+svrctl pm get cttyline
+svrctl pm get cttybaud
+.Ed
+.Sh EXIT STATUS
+In case
+.Nm
+is not properly invoked or the provided
+.Va request
+is not valid 1 is returned, otherwise 0.
+.Sh AUTHORS
+.An Thomas Veerman
+.Aq thomas@minix3.org