? sys/kern/sys_zones.c ? sys/sys/_zones.h Index: bin/ps/extern.h =================================================================== RCS file: /cvs/src/bin/ps/extern.h,v retrieving revision 1.21 diff -u -p -r1.21 extern.h --- bin/ps/extern.h 23 Jun 2019 17:18:50 -0000 1.21 +++ bin/ps/extern.h 9 Oct 2019 10:19:04 -0000 @@ -60,6 +60,7 @@ void nlisterr(struct nlist *); void p_rssize(const struct kinfo_proc *, VARENT *); void pagein(const struct kinfo_proc *, VARENT *); void parsefmt(char *); +void zonefmt(void); void pcpu(const struct kinfo_proc *, VARENT *); void pmem(const struct kinfo_proc *, VARENT *); void pri(const struct kinfo_proc *, VARENT *); @@ -83,4 +84,5 @@ void curwd(const struct kinfo_proc *, V void euname(const struct kinfo_proc *, VARENT *); void vsize(const struct kinfo_proc *, VARENT *); void wchan(const struct kinfo_proc *, VARENT *); +void zvar(const struct kinfo_proc *, VARENT *); __END_DECLS Index: bin/ps/keyword.c =================================================================== RCS file: /cvs/src/bin/ps/keyword.c,v retrieving revision 1.47 diff -u -p -r1.47 keyword.c --- bin/ps/keyword.c 23 Jun 2019 17:18:50 -0000 1.47 +++ bin/ps/keyword.c 9 Oct 2019 10:19:04 -0000 @@ -187,6 +187,7 @@ VAR var[] = { {"vsz", "VSZ", NULL, 0, vsize, 5}, {"wchan", "WCHAN", NULL, LJUST, wchan, KI_WMESGLEN - 1}, {"xstat", "XSTAT", NULL, 0, pvar, 4, 0, POFF(p_xstat), UINT16, "x"}, + {"zone", "ZONE", NULL, 0, zvar, 8, 0, POFF(p_zoneid)}, {""}, }; @@ -243,6 +244,20 @@ parsefmt(char *p) } if (!vhead) errx(1, "no valid keywords"); +} + +void +zonefmt(void) +{ + struct varent *vent; + + vent = malloc(sizeof(*vent)); + if (vent == NULL) + err(1, "zone fmt malloc"); + + vent->var = findvar("zone"); + vent->next = vhead; + vhead = vent; } static VAR * Index: bin/ps/print.c =================================================================== RCS file: /cvs/src/bin/ps/print.c,v retrieving revision 1.74 diff -u -p -r1.74 print.c --- bin/ps/print.c 23 Jun 2019 17:18:50 -0000 1.74 +++ bin/ps/print.c 9 Oct 2019 10:19:04 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -743,6 +744,23 @@ pvar(const struct kinfo_proc *kp, VARENT (void)printf("%*s", v->width, "-"); else printval((char *)kp + v->off, v); +} + +void +zvar(const struct kinfo_proc *kp, VARENT *ve) +{ + char zonename[MAXZONENAMELEN]; + VAR *v = ve->var; + int width; + + if (zone_name(kp->p_zoneid, zonename, sizeof(zonename)) == -1) + err(1, "zone_name"); + + if (strlen(zonename) > v->width) { + width = v->width - 1; + (void)printf("%*.*s*", width, width, zonename); + } else + (void)printf("%*s", (int)v->width, zonename); } void Index: bin/ps/ps.1 =================================================================== RCS file: /cvs/src/bin/ps/ps.1,v retrieving revision 1.116 diff -u -p -r1.116 ps.1 --- bin/ps/ps.1 5 Sep 2019 22:01:14 -0000 1.116 +++ bin/ps/ps.1 9 Oct 2019 10:19:04 -0000 @@ -39,7 +39,7 @@ .Sh SYNOPSIS .Nm ps .Sm off -.Op Oo Fl Oc Cm AaceHhjkLlmrSTuvwx +.Op Oo Fl Oc Cm AaceHhjkLlmrSTuvwxZ .Sm on .Op Fl M Ar core .Op Fl N Ar system @@ -49,6 +49,7 @@ .Op Fl t Ar tty .Op Fl U Ar username .Op Fl W Ar swap +.Op Fl z Ar zone .Sh DESCRIPTION The .Nm @@ -173,6 +174,10 @@ option is specified more than once, will use as many columns as necessary without regard for window size. .It Fl x Display information about processes without controlling terminals. +.It Fl Z +Prepends the displayed information with the zone field. +.It Fl z Ar zone +Display information about processes running in the specified zone. .El .Sh KEYWORDS The following is a complete list of the available keywords Index: bin/ps/ps.c =================================================================== RCS file: /cvs/src/bin/ps/ps.c,v retrieving revision 1.75 diff -u -p -r1.75 ps.c --- bin/ps/ps.c 24 Mar 2019 05:30:35 -0000 1.75 +++ bin/ps/ps.c 9 Oct 2019 10:19:04 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include "ps.h" @@ -70,6 +71,7 @@ int needcomm, needenv, neednlist, comman enum sort { DEFAULT, SORTMEM, SORTCPU } sortby = DEFAULT; static char *kludge_oldps_options(char *); +static zoneid_t zone_lookup_name(const char *); static int pscomp(const void *, const void *); static void scanvars(void); static void usage(void); @@ -98,6 +100,9 @@ main(int argc, char *argv[]) int all, ch, flag, i, fmt, lineno, nentries; int prtheader, showthreads, wflag, kflag, what, Uflag, xflg; char *nlistf, *memf, *swapf, *cols, errbuf[_POSIX2_LINE_MAX]; + int Zflag = 0; + const char *zone = NULL; + zoneid_t zoneid = -1; setlocale(LC_CTYPE, ""); @@ -122,7 +127,7 @@ main(int argc, char *argv[]) ttydev = NODEV; memf = nlistf = swapf = NULL; while ((ch = getopt(argc, argv, - "AaCcegHhjkLlM:mN:O:o:p:rSTt:U:uvW:wx")) != -1) + "AaCcegHhjkLlM:mN:O:o:p:rSTt:U:uvW:wxZz:")) != -1) switch (ch) { case 'A': all = 1; @@ -248,6 +253,12 @@ main(int argc, char *argv[]) case 'x': xflg = 1; break; + case 'Z': + Zflag = 1; + break; + case 'z': + zone = optarg; + break; default: usage(); } @@ -275,6 +286,9 @@ main(int argc, char *argv[]) if (kd == NULL) errx(1, "%s", errbuf); + if (zone != NULL) + zoneid = zone_lookup_name(zone); + if (unveil(_PATH_DEVDB, "r") == -1 && errno != ENOENT) err(1, "unveil"); if (unveil(_PATH_DEV, "r") == -1 && errno != ENOENT) @@ -297,6 +311,8 @@ main(int argc, char *argv[]) else parsefmt(dfmt); } + if (Zflag) + zonefmt(); /* XXX - should be cleaner */ if (!all && ttydev == NODEV && pid == -1 && !Uflag) { @@ -361,6 +377,8 @@ main(int argc, char *argv[]) * for each proc, call each variable output function. */ for (i = lineno = 0; i < nentries; i++) { + if (zoneid != -1 && zoneid != kinfo[i]->p_zoneid) + continue; if (showthreads == 0 && (kinfo[i]->p_flag & P_THREAD) != 0) continue; if (xflg == 0 && ((int)kinfo[i]->p_tdev == NODEV || @@ -383,6 +401,25 @@ main(int argc, char *argv[]) exit(eval); } +static zoneid_t +zone_lookup_name(const char *zone) +{ + const char *errstr; + zoneid_t z; + + z = zone_lookup(zone); + if (z != -1) + return (z); + if (errno != ESRCH) + err(1, "zone %s", zone); + + z = strtonum(zone, 0, MAXZONEIDS, &errstr); + if (errstr != NULL) + errx(1, "zone %s: %s", zone, errstr); + + return (z); +} + static void scanvars(void) { @@ -488,9 +525,9 @@ static void usage(void) { (void)fprintf(stderr, - "usage: %s [-AaceHhjkLlmrSTuvwx] [-M core] [-N system] [-O fmt] [-o fmt] [-p pid]\n", + "usage: %s [-AaceHhjkLlmrSTuvwxZ] [-M core] [-N system] [-O fmt] [-o fmt] [-p pid]\n", __progname); (void)fprintf(stderr, - "%-*s[-t tty] [-U username] [-W swap]\n", (int)strlen(__progname) + 8, ""); + "%-*s[-t tty] [-U username] [-W swap] [-z zone]\n", (int)strlen(__progname) + 8, ""); exit(1); } Index: include/Makefile =================================================================== RCS file: /cvs/src/include/Makefile,v retrieving revision 1.225 diff -u -p -r1.225 Makefile --- include/Makefile 6 Apr 2019 02:56:16 -0000 1.225 +++ include/Makefile 9 Oct 2019 10:19:14 -0000 @@ -29,7 +29,8 @@ FILES= a.out.h ar.h asr.h assert.h \ tar.h tgmath.h tib.h time.h ttyent.h \ unistd.h utime.h utmp.h uuid.h \ vis.h \ - wchar.h wctype.h + wchar.h wctype.h \ + zones.h MFILES= frame.h LFILES= endian.h fcntl.h syslog.h termios.h stdarg.h stdint.h varargs.h Index: include/zones.h =================================================================== RCS file: include/zones.h diff -N include/zones.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ include/zones.h 9 Oct 2019 10:19:14 -0000 @@ -0,0 +1,33 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2019 The University of Queensland + * + * 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. + */ + +#ifndef _ZONES_H_ +#define _ZONES_H_ + +#include + +__BEGIN_DECLS +zoneid_t zone_create(const char *); +int zone_destroy(zoneid_t); +int zone_enter(zoneid_t); +int zone_list(zoneid_t *, size_t *); +zoneid_t zone_lookup(const char *); +int zone_name(zoneid_t, char *, size_t); +__END_DECLS + +#endif /* !_UNISTD_H_ */ Index: lib/libc/Symbols.list =================================================================== RCS file: /cvs/src/lib/libc/Symbols.list,v retrieving revision 1.72 diff -u -p -r1.72 Symbols.list --- lib/libc/Symbols.list 28 May 2019 14:49:38 -0000 1.72 +++ lib/libc/Symbols.list 9 Oct 2019 10:19:14 -0000 @@ -1763,3 +1763,11 @@ yperr_string ypprot_err _yp_check /* chpass, passwd, login_chpass */ yp_unbind /* passwd */ + +/* zones */ +zone_create +zone_destroy +zone_enter +zone_list +zone_lookup +zone_name Index: lib/libc/shlib_version =================================================================== RCS file: /cvs/src/lib/libc/shlib_version,v retrieving revision 1.208 diff -u -p -r1.208 shlib_version --- lib/libc/shlib_version 13 May 2019 22:25:27 -0000 1.208 +++ lib/libc/shlib_version 9 Oct 2019 10:19:14 -0000 @@ -1,4 +1,4 @@ major=95 -minor=1 +minor=2 # note: If changes were made to include/thread_private.h or if system calls # were added/changed then librthread/shlib_version must also be updated. Index: lib/libc/sys/Makefile.inc =================================================================== RCS file: /cvs/src/lib/libc/sys/Makefile.inc,v retrieving revision 1.157 diff -u -p -r1.157 Makefile.inc --- lib/libc/sys/Makefile.inc 28 May 2019 13:08:56 -0000 1.157 +++ lib/libc/sys/Makefile.inc 9 Oct 2019 10:19:14 -0000 @@ -73,7 +73,9 @@ ASM= __semctl.o __syscall.o __thrsigdive shmget.o shutdown.o sigaltstack.o socket.o \ socketpair.o stat.o statfs.o swapctl.o symlink.o symlinkat.o \ sysarch.o sysctl.o thrkill.o unlink.o unlinkat.o \ - unmount.o unveil.o utimensat.o utimes.o utrace.o + unmount.o unveil.o utimensat.o utimes.o utrace.o \ + zone_create.o zone_destroy.o zone_enter.o zone_list.o \ + zone_lookup.o zone_name.o SRCS+= ${SRCS_${MACHINE_CPU}} .for i in ${SRCS_${MACHINE_CPU}} Index: sys/kern/kern_pledge.c =================================================================== RCS file: /cvs/src/sys/kern/kern_pledge.c,v retrieving revision 1.255 diff -u -p -r1.255 kern_pledge.c --- sys/kern/kern_pledge.c 25 Aug 2019 18:46:40 -0000 1.255 +++ sys/kern/kern_pledge.c 9 Oct 2019 10:19:18 -0000 @@ -364,6 +364,9 @@ const uint64_t pledge_syscalls[SYS_MAXSY [SYS_flock] = PLEDGE_FLOCK | PLEDGE_YPACTIVE, [SYS_swapctl] = PLEDGE_VMINFO, /* XXX should limit to "get" operations */ + + /* [SYS_zone_name] = PLEDGE_ALWAYS, */ + /* [SYS_zone_lookup] = PLEDGE_ALWAYS, */ }; static const struct { Index: sys/sys/_types.h =================================================================== RCS file: /cvs/src/sys/sys/_types.h,v retrieving revision 1.9 diff -u -p -r1.9 _types.h --- sys/sys/_types.h 22 Aug 2014 23:05:15 -0000 1.9 +++ sys/sys/_types.h 9 Oct 2019 10:19:18 -0000 @@ -64,6 +64,7 @@ typedef __int32_t __swblk_t; /* swap off typedef __int64_t __time_t; /* epoch time */ typedef __int32_t __timer_t; /* POSIX timer identifiers */ typedef __uint32_t __uid_t; /* user id */ +typedef __int32_t __zoneid_t; /* zone id */ typedef __uint32_t __useconds_t; /* microseconds */ /* Index: sys/sys/sysctl.h =================================================================== RCS file: /cvs/src/sys/sys/sysctl.h,v retrieving revision 1.195 diff -u -p -r1.195 sysctl.h --- sys/sys/sysctl.h 21 Aug 2019 20:44:09 -0000 1.195 +++ sys/sys/sysctl.h 9 Oct 2019 10:19:18 -0000 @@ -472,6 +472,7 @@ struct kinfo_proc { u_int32_t p_rtableid; /* U_INT: Routing table identifier. */ u_int64_t p_pledge; /* U_INT64_T: Pledge flags. */ + int32_t p_zoneid; /* ZONEID_T: zone identifier */ }; /* Index: sys/sys/types.h =================================================================== RCS file: /cvs/src/sys/sys/types.h,v retrieving revision 1.48 diff -u -p -r1.48 types.h --- sys/sys/types.h 9 Feb 2019 04:54:11 -0000 1.48 +++ sys/sys/types.h 9 Oct 2019 10:19:18 -0000 @@ -146,6 +146,7 @@ typedef __rlim_t rlim_t; /* resource li typedef __segsz_t segsz_t; /* segment size */ typedef __swblk_t swblk_t; /* swap offset */ typedef __uid_t uid_t; /* user id */ +typedef __zoneid_t zoneid_t; /* zone id */ typedef __useconds_t useconds_t; /* microseconds */ typedef __suseconds_t suseconds_t; /* microseconds (signed) */ typedef __fsblkcnt_t fsblkcnt_t; /* file system block count */ Index: sys/sys/zones.h =================================================================== RCS file: sys/sys/zones.h diff -N sys/sys/zones.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sys/zones.h 9 Oct 2019 10:19:18 -0000 @@ -0,0 +1,29 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2019 The University of Queensland + * + * 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. + */ + +#ifndef _SYS_ZONES_H_ +#define _SYS_ZONES_H_ + +#define MAXZONENAMELEN 256 /* max zone name length w/ NUL */ +#define MAXZONES 1024 +#define MAXZONEIDS (MAXZONES * 32) + +/* your assignment code goes in src/sys/sys/_zones.h */ +#include + +#endif /* _SYS_ZONES_H_ */ Index: usr.bin/pkill/pkill.c =================================================================== RCS file: /cvs/src/usr.bin/pkill/pkill.c,v retrieving revision 1.41 diff -u -p -r1.41 pkill.c --- usr.bin/pkill/pkill.c 28 Jun 2019 13:35:02 -0000 1.41 +++ usr.bin/pkill/pkill.c 9 Oct 2019 10:19:18 -0000 @@ -52,6 +52,7 @@ #include #include #include +#include #define STATUS_MATCH 0 #define STATUS_NOMATCH 1 @@ -107,6 +108,7 @@ static int grepact(struct kinfo_proc *, static void makelist(struct listhead *, enum listtype, char *); static char *getargv(struct kinfo_proc *); static int askyn(struct kinfo_proc *); +static zoneid_t getzoneid(const char *); extern char *__progname; @@ -148,6 +150,8 @@ main(int argc, char **argv) u_int32_t bestsec, bestusec; regex_t reg; regmatch_t regmatch; + const char *zone = NULL; + zoneid_t z = -1; if (strcmp(__progname, "pgrep") == 0) { action = grepact; @@ -180,7 +184,7 @@ main(int argc, char **argv) criteria = 0; - while ((ch = getopt(argc, argv, "G:P:T:U:d:fg:Ilnoqs:t:u:vx")) != -1) + while ((ch = getopt(argc, argv, "G:P:T:U:d:fg:Ilnoqs:t:u:vxz:")) != -1) switch (ch) { case 'G': makelist(&rgidlist, LT_GROUP, optarg); @@ -245,6 +249,9 @@ main(int argc, char **argv) case 'x': fullmatch = 1; break; + case 'z': + zone = optarg; + break; default: usage(); /* NOTREACHED */ @@ -259,6 +266,9 @@ main(int argc, char **argv) mypid = getpid(); + if (zone != NULL) + z = getzoneid(zone); + /* * Retrieve the list of running processes from the kernel. */ @@ -298,6 +308,7 @@ main(int argc, char **argv) for (i = 0, kp = plist; i < nproc; i++, kp++) { if ((kp->p_flag & (P_SYSTEM | P_THREAD)) != 0 || + (z != -1 && z != kp->p_zoneid) || kp->p_pid == mypid) continue; @@ -436,6 +447,7 @@ main(int argc, char **argv) rv = STATUS_NOMATCH; for (i = 0, j = 0, kp = plist; i < nproc; i++, kp++) { if ((kp->p_flag & (P_SYSTEM | P_THREAD)) != 0 || + (z != -1 && z != kp->p_zoneid) || kp->p_pid == mypid) continue; if (selected[i] == inverse) @@ -471,7 +483,8 @@ usage(void) ustr = "[-signal] [-fIlnoqvx]"; fprintf(stderr, "usage: %s %s [-G gid] [-g pgrp] [-P ppid] [-s sid]" - "\n\t[-T rtable] [-t tty] [-U uid] [-u euid] [pattern ...]\n", + "\n\t[-T rtable] [-t tty] [-U uid] [-u euid] [-z zone]" + " [pattern ...]\n", __progname, ustr); exit(STATUS_BADUSAGE); @@ -632,4 +645,23 @@ makelist(struct listhead *head, enum lis if (empty) usage(); +} + +static zoneid_t +getzoneid(const char *zone) +{ + const char *errstr; + zoneid_t z; + + z = zone_lookup(zone); + if (z != -1) + return (z); + if (errno != ESRCH) + err(1, "zone %s", zone); + + z = strtonum(zone, 0, MAXZONEIDS, &errstr); + if (errstr != NULL) + errx(1, "zone id %s: %s", zone, errstr); + + return (z); } Index: usr.sbin/Makefile =================================================================== RCS file: /cvs/src/usr.sbin/Makefile,v retrieving revision 1.207 diff -u -p -r1.207 Makefile --- usr.sbin/Makefile 16 Aug 2019 17:03:55 -0000 1.207 +++ usr.sbin/Makefile 9 Oct 2019 10:19:18 -0000 @@ -19,7 +19,7 @@ SUBDIR= ac accton acme-client acpidump a snmpd spamdb switchctl switchd syslogc syslogd sysmerge \ syspatch sysupgrade tcpdrop tcpdump tftp-proxy tftpd tokenadm \ tokeninit traceroute trpt unbound unwindctl usbdevs user vmd vmctl \ - vipw watchdogd wsconscfg wsfontload wsmoused zdump zic + vipw watchdogd wsconscfg wsfontload wsmoused zdump zic zone .if (${YP:L} == "yes") SUBDIR+=ypbind ypldap yppoll ypset ypserv Index: usr.sbin/zone/Makefile =================================================================== RCS file: usr.sbin/zone/Makefile diff -N usr.sbin/zone/Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.sbin/zone/Makefile 9 Oct 2019 10:19:19 -0000 @@ -0,0 +1,6 @@ +PROG=zone +SRCS=zone.c +MAN= +CFLAGS+=-Wall + +.include Index: usr.sbin/zone/zone.c =================================================================== RCS file: usr.sbin/zone/zone.c diff -N usr.sbin/zone/zone.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.sbin/zone/zone.c 9 Oct 2019 10:19:19 -0000 @@ -0,0 +1,273 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2015, 2019 The University of Queensland + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef nitems +#define nitems(_a) (sizeof(_a) / sizeof(_a[0])) +#endif + +static int zcreate(int, char *[]); +static int zdestroy(int, char *[]); +static int zexec(int, char *[]); +static int zlist(int, char *[]); +static int zname(int, char *[]); +static int zlookup(int, char *[]); + +__dead void usage(void); + +struct task { + const char *name; + int (*task)(int, char *[]); +}; + +/* must be sorted alphanumerically */ +static const struct task tasks[] = { + { "create", zcreate }, + { "destroy", zdestroy }, + { "exec", zexec }, + { "list", zlist }, + { "lookup", zlookup }, + { "name", zname }, +}; + +static int task_cmp(const void *, const void *); + +static int +task_cmp(const void *a, const void *b) +{ + const struct task *ta = a; + const struct task *tb = b; + + return (strcmp(ta->name, tb->name)); +} + +__dead void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, "usage:\t%s create zonename\n", __progname); + fprintf(stderr, "\t%s destroy zonename|zoneid\n", __progname); + fprintf(stderr, "\t%s list\n", __progname); + fprintf(stderr, "\t%s lookup [zonename]\n", __progname); + fprintf(stderr, "\t%s name [zoneid]\n", __progname); + fprintf(stderr, "\t%s exec zonename|zoneid command ...\n", __progname); + + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct task key, *t; + + if (argc < 2) + usage(); + + key.name = argv[1]; + t = bsearch(&key, tasks, nitems(tasks), sizeof(tasks[0]), task_cmp); + if (t == NULL) + usage(); + + argc -= 2; + argv += 2; + + return (t->task(argc, argv)); +} + +static zoneid_t +getzoneid(const char *zone) +{ + const char *errstr; + zoneid_t z; + + z = zone_lookup(zone); + if (z != -1) + return (z); + if (errno != ESRCH) + err(1, "lookup %s", zone); + + z = strtonum(zone, 0, MAXZONEIDS, &errstr); + if (errstr != NULL) + errx(1, "lookup %s: %s", zone, errstr); + + return (z); +} + +static int +zcreate(int argc, char *argv[]) +{ + const char *zone; + + if (argc != 1) + usage(); + + zone = argv[0]; + if (zone_create(zone) == -1) + err(1, "create %s", zone); + + return (0); +} + +static int +zdestroy(int argc, char *argv[]) +{ + const char *zone; + zoneid_t z; + + if (argc != 1) + usage(); + + zone = argv[0]; + + z = getzoneid(zone); + if (zone_destroy(z) == -1) + err(1, "destroy %s", zone); + + return (0); +} + +static int +zexec(int argc, char *argv[]) +{ + const char *zone; + zoneid_t z; + + if (argc < 2) + usage(); + + zone = argv[0]; + z = getzoneid(zone); + + argc -= 1; + argv += 1; + + if (zone_enter(z) == -1) + err(1, "enter %s", zone); + + execvp(argv[0], argv); + + err(1, "exec %s", argv[0]); + /* NOTREACHED */ +} + +static int +zlist(int argc, char *argv[]) +{ + char zonename[MAXZONENAMELEN]; + zoneid_t *zs = NULL; + size_t nzs, i = 8; + zoneid_t z; + + if (argc != 0) + usage(); + + for (;;) { + nzs = i; + + zs = reallocarray(zs, nzs, sizeof(*zs)); + if (zs == NULL) + err(1, "lookup"); + + if (zone_list(zs, &nzs) == 0) + break; + + if (errno != EFAULT) + err(1, "list"); + + i <<= 1; + } + + printf("%8s %s\n", "ID", "NAME"); + + for (i = 0; i < nzs; i++) { + z = zs[i]; + if (zone_name(z, zonename, sizeof(zonename)) == -1) + err(1, "name"); + printf("%8d %s\n", z, zonename); + } + + free(zs); + + return (0); +} + +static int +zname(int argc, char *argv[]) +{ + char zonename[MAXZONENAMELEN]; + const char *zid; + const char *errstr; + zoneid_t z = -1; + + switch (argc) { + case 1: + zid = argv[0]; + z = strtonum(zid, 0, MAXZONEIDS, &errstr); + if (errstr != NULL) + errx(1, "name %s: %s", zid, errstr); + break; + case 0: + break; + default: + usage(); + } + + if (zone_name(z, zonename, sizeof(zonename)) == -1) + err(1, "name %d", z); + + printf("%s\n", zonename); + + return (0); +} + +static int +zlookup(int argc, char *argv[]) +{ + const char *zone = NULL; + zoneid_t z; + + switch (argc) { + case 1: + zone = argv[0]; + break; + case 0: + break; + default: + usage(); + } + + z = zone_lookup(zone); + if (z == -1) + err(1, "lookup %s", zone); + + printf("%d\n", z); + + return (0); +}