|
|
1.1 root 1: /*
2: * error logging
3: *
4: * other parts of the system may call logerr to record an error
5: * reading the device recovers the error records
6: */
7:
8: #include "sys/param.h"
9: #include "sys/conf.h"
10: #include "sys/systm.h" /* just for time */
11: #include "sys/user.h"
12: #include "sys/buf.h"
13: #include "sys/errlog.h"
14:
15: /*
16: * hackish use of overlays:
17: * if this device isn't configured,
18: * errcnt will be zero, errlog will be 1 item long (so it won't be undefined)
19: * if the device is configured,
20: * errcnt is the number of errlog buffers
21: */
22:
23: int errcnt;
24: struct errlog errlog[1]; /* 1 or more */
25:
26: static int errlost;
27: static char erptr, ewptr;
28:
29: int erropen(), errread(), errwrite();
30: struct cdevsw errcdev = cdinit(erropen, nodev, errread, errwrite, nodev);
31:
32: #define PERROR (PUSER-1)
33:
34: erropen(dev, flag)
35: dev_t dev;
36: int flag;
37: {
38:
39: if (errcnt == 0)
40: u.u_error = ENXIO;
41: }
42:
43: errread(dev)
44: dev_t dev;
45: {
46: register int s;
47:
48: if (u.u_count < sizeof(errlog)) {
49: u.u_error = EINVAL;
50: return;
51: }
52: s = spl7();
53: while (erptr == ewptr)
54: sleep((caddr_t)errlog, PERROR);
55: splx(s);
56: s = errlog[erptr].e_hdr.e_len + sizeof(struct errhdr);
57: iomove((caddr_t)&errlog[erptr], s, B_READ);
58: if (++erptr >= errcnt)
59: erptr = 0;
60: }
61:
62: /*
63: * mostly for debugging
64: */
65:
66: errwrite(dev)
67: dev_t dev;
68: {
69: char b[MAXEDATA+20];
70: register int len;
71: register char *p;
72:
73: if ((len = u.u_count) > sizeof(b)) {
74: u.u_error = EINVAL;
75: return;
76: }
77: iomove(b, len, B_WRITE);
78: if (u.u_error)
79: return;
80: p = b;
81: while (--len >= 0)
82: if (*p++ == '\n')
83: break;
84: p[-1] = 0;
85: if (len < 0)
86: len = 0;
87: logerr(b, 0, p, len, 0);
88: }
89:
90: /*
91: * here to log an error:
92: * dev is the name of the device or circumstance
93: * unit is a unit number, e.g. which disk number broke
94: * data is the stuff to be logged; there are len bytes
95: * data should be something bcopy can copy (maybe not device registers)
96: * `hard' is nonzero if this was a hard error
97: */
98:
99: logerr(dev, unit, data, len, hard)
100: char *dev;
101: int unit;
102: char *data;
103: int len;
104: int hard;
105: {
106: register struct errlog *ep;
107: register int s, i;
108: register char *p;
109:
110: s = spl7();
111: if ((i = ewptr + 1) >= errcnt)
112: i = 0;
113: if (i == erptr) { /* buffer full */
114: splx(s);
115: errlost++;
116: return;
117: }
118: ep = &errlog[ewptr];
119: ewptr = i;
120: splx(s);
121: ep->e_hdr.e_1magic = E_1MAGIC;
122: ep->e_hdr.e_2magic = E_2MAGIC;
123: len = min(len, MAXEDATA);
124: ep->e_hdr.e_len = len;
125: if (hard)
126: ep->e_hdr.e_len |= E_HARD;
127: ep->e_hdr.e_unit = unit;
128: ep->e_hdr.e_time = time;
129: p = dev;
130: while (*p++) /* should be strlen */
131: ;
132: bcopy(dev, ep->e_hdr.e_dev, min(p - dev, sizeof(ep->e_hdr.e_dev)));
133: if (len)
134: bcopy(data, ep->e_data, len);
135: wakeup((caddr_t)errlog);
136: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.