diff --git a/commands/Makefile b/commands/Makefile index ac0be14f1..8be3ed5c7 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -26,7 +26,7 @@ SUBDIR= add_route arp ash at awk \ reboot remsync rev rget rlogin \ rotate rsh rshd sed service setup shar acksize \ sleep slip sort spell split srccrc \ - stty sum svclog swifi sync synctree sysenv \ + stty sum svclog svrctl swifi sync synctree sysenv \ syslogd tail tar tcpd tcpdp tcpstat tee telnet \ telnetd term termcap tget time touch tr \ truncate tsort tty udpstat umount uname unexpand \ diff --git a/commands/svrctl/Makefile b/commands/svrctl/Makefile new file mode 100644 index 000000000..1877b235c --- /dev/null +++ b/commands/svrctl/Makefile @@ -0,0 +1,5 @@ +PROG= svrctl +BINDIR= /usr/bin +MAN= + +.include diff --git a/commands/svrctl/svrctl.c b/commands/svrctl/svrctl.c new file mode 100644 index 000000000..6338281c3 --- /dev/null +++ b/commands/svrctl/svrctl.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +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 set \n", bin_name); + fprintf(stderr, " %s get \n", bin_name); + exit(EXIT_FAILURE); +} diff --git a/man/man1/Makefile b/man/man1/Makefile index 30c14fb8d..60d57f1d8 100644 --- a/man/man1/Makefile +++ b/man/man1/Makefile @@ -16,7 +16,7 @@ MAN= ash.1 at.1 banner.1 basename.1 \ profile.1 ps.1 pwd.1 rcp.1 readall.1 recwave.1 \ ref.1 remsync.1 rget.1 rlogin.1 rsh.1 rz.1 \ shar.1 acksize.1 sleep.1 sort.1 spell.1 \ - split.1 stty.1 sum.1 svc.1 \ + split.1 stty.1 sum.1 svc.1 svrctl.1 \ synctree.1 sysenv.1 sz.1 tail.1 tee.1 telnet.1 template.1 \ term.1 termcap.1 tget.1 time.1 tr.1 true.1 \ truncate.1 tsort.1 tty.1 umount.1 uname.1 unexpand.1 \ diff --git a/man/man1/svrctl.1 b/man/man1/svrctl.1 new file mode 100644 index 000000000..92a306614 --- /dev/null +++ b/man/man1/svrctl.1 @@ -0,0 +1,65 @@ +.Dd $April 5, 2012$ +.Dt SVRCTL 1 +.Os +.Sh NAME +.Nm svrctl +.Nd send servers control messages +.Sh SYNOPSIS +.Nm +.Ar Ar get Ar +.Nm +.Ar Ar set Ar Ar +.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