#include "dat.h"
#include "fns.h"
#include "../port/error.h"
-#include "pool.h"
#include <authsrv.h>
char *sysname;
vlong fasthz;
-static void seedrand(void);
static int readtime(ulong, char*, int);
static int readbintime(char*, int);
static int writetime(char*, int);
enum
{
- CMhalt,
CMreboot,
CMpanic,
CMrdb,
Cmdtab rebootmsg[] =
{
- CMhalt, "halt", 1,
CMreboot, "reboot", 0,
CMpanic, "panic", 0,
CMrdb, "rdb", 0,
break;
}
-/*
- * Log console output so it can be retrieved via /dev/kmesg.
- * This is good for catching boot-time messages after the fact.
- */
-struct {
- Lock lk;
-// char buf[16384]; /* normal */
- char buf[256*1024]; /* for acpi debugging */
- uint n;
-} kmesg;
-
static void
kmesgputs(char *str, int n)
{
{
int m;
char *t;
-
- if(!islo())
- usewrite = 0;
+ int (*wq)(Queue*, void*, int);
/*
* how many different output devices do we need?
* if there's a serial line being used as a console,
* put the message there.
*/
- if(kprintoq != nil && !qisclosed(kprintoq)){
- if(usewrite)
- qwrite(kprintoq, str, n);
- else
- qiwrite(kprintoq, str, n);
- }else if(screenputs != nil)
+ wq = usewrite && islo() ? qwrite : qiwrite;
+ if(kprintoq != nil && !qisclosed(kprintoq))
+ (*wq)(kprintoq, str, n);
+ else if(screenputs != nil)
screenputs(str, n);
if(serialoq == nil){
while(n > 0) {
t = memchr(str, '\n', n);
- if(t) {
+ if(t != nil) {
m = t-str;
- if(usewrite){
- qwrite(serialoq, str, m);
- qwrite(serialoq, "\r\n", 2);
- } else {
- qiwrite(serialoq, str, m);
- qiwrite(serialoq, "\r\n", 2);
- }
+ (*wq)(serialoq, str, m);
+ (*wq)(serialoq, "\r\n", 2);
n -= m+1;
str = t+1;
} else {
- if(usewrite)
- qwrite(serialoq, str, n);
- else
- qiwrite(serialoq, str, n);
+ (*wq)(serialoq, str, n);
break;
}
}
void
panic(char *fmt, ...)
{
- int n, s;
+ int s;
va_list arg;
char buf[PRINTSIZE];
s = splhi();
strcpy(buf, "panic: ");
va_start(arg, fmt);
- n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf;
+ vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg);
va_end(arg);
iprint("%s\n", buf);
if(consdebug)
(*consdebug)();
splx(s);
prflush();
- buf[n] = '\n';
- putstrn(buf, n+1);
dumpstack();
- exit(1);
+ /* reboot cpu servers and headless machines when not debugging */
+ if(getconf("*debug") == nil)
+ if(cpuserver || !conf.monitor)
+ exit(1);
+
+ /* otherwise, just hang */
+ while(islo()) idlehands();
+ for(;;);
}
/* libmp at least contains a few calls to sysfatal; simulate with panic */
return 0;
c = up->fgrp->fd[2];
- if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR))
+ if(c==nil || (c->flag&CMSG)!=0 || (c->mode!=OWRITE && c->mode!=ORDWR))
return 0;
n = snprint(buf, sizeof buf, "%s %lud: ", up->text, up->pid);
va_start(arg, fmt);
Qppid,
Qrandom,
Qreboot,
- Qswap,
Qsysname,
Qsysstat,
Qtime,
"ppid", {Qppid}, NUMSIZE, 0444,
"random", {Qrandom}, 0, 0444,
"reboot", {Qreboot}, 0, 0664,
- "swap", {Qswap}, 0, 0664,
"sysname", {Qsysname}, 0, 0664,
"sysstat", {Qsysstat}, 0, 0666,
"time", {Qtime}, NUMSIZE+3*VLNUMSIZE, 0664,
ulong l;
Mach *mp;
char *b, *bp;
- char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */
+ char tmp[256];
int i, k, id;
vlong offset = off;
extern char configfile[];
l = up->time[i];
if(i == TReal)
l = MACHP(0)->ticks - l;
- l = TK2MS(l);
- readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
+ readnum(0, tmp+NUMSIZE*i, NUMSIZE, tk2ms(l), NUMSIZE);
}
memmove(buf, tmp+k, n);
return n;
case Qsysstat:
b = smalloc(conf.nmach*(NUMSIZE*11+1) + 1); /* +1 for NUL */
bp = b;
- for(id = 0; id < 32; id++) {
- if(active.machs & (1<<id)) {
+ for(id = 0; id < MAXMACH; id++) {
+ if(active.machs[id]) {
mp = MACHP(id);
readnum(0, bp, NUMSIZE, id, NUMSIZE);
bp += NUMSIZE;
bp += NUMSIZE;
readnum(0, bp, NUMSIZE, mp->load, NUMSIZE);
bp += NUMSIZE;
+ l = mp->perf.period;
+ if(l == 0)
+ l = 1;
readnum(0, bp, NUMSIZE,
- (mp->perf.avg_inidle*100)/mp->perf.period,
- NUMSIZE);
+ (mp->perf.avg_inidle*100)/l, NUMSIZE);
bp += NUMSIZE;
readnum(0, bp, NUMSIZE,
- (mp->perf.avg_inintr*100)/mp->perf.period,
- NUMSIZE);
+ (mp->perf.avg_inintr*100)/l, NUMSIZE);
bp += NUMSIZE;
*bp++ = '\n';
}
poperror();
return n;
- case Qswap:
- snprint(tmp, sizeof tmp,
- "%lud memory\n"
- "%d pagesize\n"
- "%lud kernel\n"
- "%lud/%lud user\n"
- "%lud/%lud swap\n"
- "%lud/%lud kernel malloc\n"
- "%lud/%lud kernel draw\n",
- conf.npage*BY2PG,
- BY2PG,
- conf.npage-conf.upages,
- palloc.user-palloc.freecount, palloc.user,
- conf.nswap-swapalloc.free, conf.nswap,
- mainmem->cursize, mainmem->maxsize,
- imagmem->cursize, imagmem->maxsize);
-
- return readstr((ulong)offset, buf, n, tmp);
-
case Qsysname:
if(sysname == nil)
return 0;
return randomread(buf, n);
case Qdrivers:
- b = malloc(READSTR);
- if(b == nil)
- error(Enomem);
+ b = smalloc(READSTR);
k = 0;
for(i = 0; devtab[i] != nil; i++)
k += snprint(b+k, READSTR-k, "#%C %s\n",
nexterror();
}
n = readstr((ulong)offset, buf, n, b);
- free(b);
poperror();
+ free(b);
return n;
case Qzero:
long l, bp;
char *a;
Mach *mp;
- int id, fd;
- Chan *swc;
+ int id;
ulong offset;
Cmdbuf *cb;
Cmdtab *ct;
}
ct = lookupcmd(cb, rebootmsg, nelem(rebootmsg));
switch(ct->index) {
- case CMhalt:
- reboot(nil, 0, 0);
- break;
case CMreboot:
rebootcmd(cb->nf-1, cb->f+1);
break;
break;
case Qsysstat:
- for(id = 0; id < 32; id++) {
- if(active.machs & (1<<id)) {
+ for(id = 0; id < MAXMACH; id++) {
+ if(active.machs[id]) {
mp = MACHP(id);
mp->cs = 0;
mp->intr = 0;
}
break;
- case Qswap:
- if(n >= sizeof buf)
- error(Egreg);
- memmove(buf, va, n); /* so we can NUL-terminate */
- buf[n] = 0;
- /* start a pager if not already started */
- if(strncmp(buf, "start", 5) == 0){
- kickpager();
- break;
- }
- if(!iseve())
- error(Eperm);
- if(buf[0]<'0' || '9'<buf[0])
- error(Ebadarg);
- fd = strtoul(buf, 0, 0);
- swc = fdtochan(fd, -1, 1, 1);
- setswapchan(swc);
- break;
-
case Qsysname:
if(offset != 0)
error(Ebadarg);
devwstat,
};
-static ulong randn;
-
-static void
-seedrand(void)
-{
- if(!waserror()){
- randomread((void*)&randn, sizeof(randn));
- poperror();
- }
-}
-
-int
-nrand(int n)
-{
- if(randn == 0)
- seedrand();
- randn = randn*1103515245 + 12345 + MACHP(0)->ticks;
- return (randn>>16) % n;
-}
-
-int
-rand(void)
-{
- nrand(1);
- return randn;
-}
-
static uvlong uvorder = 0x0001020304050607ULL;
static uchar*
vlong delta;
long period;
- n--;
+ if(--n <= 0)
+ error(Ebadtimectl);
p = (uchar*)buf + 1;
switch(*buf){
case 'n':
todsetfreq(fasthz);
break;
}
- return n;
+ return n+1;
+}
+
+void
+cpushutdown(void)
+{
+ int ms, once;
+
+ once = active.machs[m->machno];
+ active.machs[m->machno] = 0;
+ active.exiting = 1;
+
+ if(once)
+ iprint("cpu%d: exiting\n", m->machno);
+
+ /* wait for any other processors to shutdown */
+ spllo();
+ for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
+ delay(TK2MS(2));
+ if(memchr(active.machs, 1, MAXMACH) == nil && consactive() == 0)
+ break;
+ }
}