1 /*-
2 * Copyright (c) 1997, 1998, 1999
3 * Nan Yang Computer Services Limited. All rights reserved.
4 *
5 * Parts copyright (c) 1997, 1998 Cybernet Corporation, NetMAX project.
6 *
7 * Written by Greg Lehey
8 *
9 * This software is distributed under the so-called ``Berkeley
10 * License'':
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by Nan Yang Computer
23 * Services Limited.
24 * 4. Neither the name of the Company nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * This software is provided ``as is'', and any express or implied
29 * warranties, including, but not limited to, the implied warranties of
30 * merchantability and fitness for a particular purpose are disclaimed.
31 * In no event shall the company or contributors be liable for any
32 * direct, indirect, incidental, special, exemplary, or consequential
33 * damages (including, but not limited to, procurement of substitute
34 * goods or services; loss of use, data, or profits; or business
35 * interruption) however caused and on any theory of liability, whether
36 * in contract, strict liability, or tort (including negligence or
37 * otherwise) arising in any way out of the use of this software, even if
38 * advised of the possibility of such damage.
39 *
40 * $Id: vinumvar.h,v 1.24 2000/03/01 02:34:57 grog Exp grog $
41 * $FreeBSD$
42 */
43
44 #include <sys/time.h>
45 #include <dev/vinum/vinumstate.h>
46 /*
47 * Some configuration maxima. They're an enum because
48 * we can't define global constants. Sorry about that.
49 *
50 * These aren't as bad as they look: most of them are soft limits.
51 */
52
53 #define VINUMROOT
54 enum constants {
55 VINUM_HEADER = 512, /* size of header on disk */
56 MAXCONFIGLINE = 1024, /* maximum size of a single config line */
57 MINVINUMSLICE = 1048576, /* minimum size of a slice */
58
59 VINUM_CDEV_MAJOR = 91, /* major number for character device */
60 VINUM_BDEV_MAJOR = 25, /* and legacy major number for block device */
61
62 ROUND_ROBIN_READPOL = -1, /* round robin read policy */
63
64 /* type field in minor number */
65 VINUM_VOLUME_TYPE = 0,
66 VINUM_PLEX_TYPE = 1,
67 VINUM_SD_TYPE = 2,
68 VINUM_DRIVE_TYPE = 3,
69 VINUM_SUPERDEV_TYPE = 4, /* super device. */
70 VINUM_RAWPLEX_TYPE = 5, /* anonymous plex */
71 VINUM_RAWSD_TYPE = 6, /* anonymous subdisk */
72
73 /* Shifts for the individual fields in the device */
74 VINUM_TYPE_SHIFT = 28,
75 VINUM_VOL_SHIFT = 0,
76 VINUM_PLEX_SHIFT = 16,
77 VINUM_SD_SHIFT = 20,
78 VINUM_VOL_WIDTH = 8,
79 VINUM_PLEX_WIDTH = 3,
80 VINUM_SD_WIDTH = 8,
81
82 /*
83 * Shifts for the second half of raw plex and
84 * subdisk numbers
85 */
86 VINUM_RAWPLEX_SHIFT = 8, /* shift the second half this much */
87 VINUM_RAWPLEX_WIDTH = 12, /* width of second half */
88
89 MAJORDEV_SHIFT = 8,
90
91 MAXPLEX = 8, /* maximum number of plexes in a volume */
92 MAXSD = 256, /* maximum number of subdisks in a plex */
93 MAXDRIVENAME = 32, /* maximum length of a device name */
94 MAXSDNAME = 64, /* maximum length of a subdisk name */
95 MAXPLEXNAME = 64, /* maximum length of a plex name */
96 MAXVOLNAME = 64, /* maximum length of a volume name */
97 MAXNAME = 64, /* maximum length of any name */
98
99
100 /*
101 * Define a minor device number.
102 * This is not used directly; instead, it's
103 * called by the other macros.
104 */
105 #define VINUMMINOR(v,p,s,t) ( (v << VINUM_VOL_SHIFT) \
106 | (p << VINUM_PLEX_SHIFT) \
107 | (s << VINUM_SD_SHIFT) \
108 | (t << VINUM_TYPE_SHIFT) )
109
110 /* Create device minor numbers */
111 #define VINUMDEV(v,p,s,t) makedev (VINUM_CDEV_MAJOR, VINUMMINOR (v, p, s, t))
112
113 #define VINUM_PLEX(p) makedev (VINUM_CDEV_MAJOR, \
114 (VINUM_RAWPLEX_TYPE << VINUM_TYPE_SHIFT) \
115 | (p & 0xff) \
116 | ((p & ~0xff) << 8) )
117
118 #define VINUM_SD(s) makedev (VINUM_CDEV_MAJOR, \
119 (VINUM_RAWSD_TYPE << VINUM_TYPE_SHIFT) \
120 | (s & 0xff) \
121 | ((s & ~0xff) << 8) )
122
123 /* Create a bit mask for x bits */
124 #define MASK(x) ((1 << (x)) - 1)
125
126 /* Create a raw block device minor number */
127 #define VINUMRMINOR(d,t) ( ((d & MASK (VINUM_VOL_WIDTH)) << VINUM_VOL_SHIFT) \
128 | ((d & ~MASK (VINUM_VOL_WIDTH)) \
129 << (VINUM_PLEX_SHIFT + VINUM_VOL_WIDTH)) \
130 | (t << VINUM_TYPE_SHIFT) )
131
132 #define VINUMRBDEV(d,t) makedev (VINUM_BDEV_MAJOR, VINUMRMINOR (d, t))
133
134 /* Block device stuff */
135 #define VINUMDEV(v,p,s,t) makedev (VINUM_CDEV_MAJOR, VINUMMINOR (v, p, s, t))
136
137 #define VINUM_BLOCK_PLEX(p) makedev (VINUM_BDEV_MAJOR, \
138 (VINUM_RAWPLEX_TYPE << VINUM_TYPE_SHIFT) \
139 | (p & 0xff) \
140 | ((p & ~0xff) << 8) )
141
142 #define VINUM_BLOCK_SD(s) makedev (VINUM_BDEV_MAJOR, \
143 (VINUM_RAWSD_TYPE << VINUM_TYPE_SHIFT) \
144 | (s & 0xff) \
145 | ((s & ~0xff) << 8) )
146
147 #define VINUMBDEV(v,p,s,t) makedev (VINUM_BDEV_MAJOR, VINUMMINOR (v, p, s, t))
148
149 /* extract device type */
150 #define DEVTYPE(x) ((minor (x) >> VINUM_TYPE_SHIFT) & 7)
151
152 /*
153 * This mess is used to catch people who compile
154 * a debug vinum(8) and non-debug kernel module,
155 * or the other way round.
156 */
157
158 #ifdef VINUMDEBUG
159 #define VINUM_SUPERDEV VINUMMINOR (1, 0, 0, VINUM_SUPERDEV_TYPE) /* superdevice number */
160 #define VINUM_WRONGSUPERDEV VINUMMINOR (2, 0, 0, VINUM_SUPERDEV_TYPE) /* non-debug superdevice number */
161 #else
162 #define VINUM_SUPERDEV VINUMMINOR (2, 0, 0, VINUM_SUPERDEV_TYPE) /* superdevice number */
163 #define VINUM_WRONGSUPERDEV VINUMMINOR (1, 0, 0, VINUM_SUPERDEV_TYPE) /* debug superdevice number */
164 #endif
165
166 #define VINUM_DAEMON_DEV VINUMMINOR (0, 0, 0, VINUM_SUPERDEV_TYPE) /* daemon superdevice number */
167
168 /*
169 * the number of object entries to cater for initially, and also the
170 * value by which they are incremented. It doesn't take long
171 * to extend them, so theoretically we could start with 1 of each, but
172 * it's untidy to allocate such small areas. These values are
173 * probably too small.
174 */
175
176 INITIAL_DRIVES = 4,
177 INITIAL_VOLUMES = 4,
178 INITIAL_PLEXES = 8,
179 INITIAL_SUBDISKS = 16,
180 INITIAL_SUBDISKS_IN_PLEX = 4, /* number of subdisks to allocate to a plex */
181 INITIAL_SUBDISKS_IN_DRIVE = 4, /* number of subdisks to allocate to a drive */
182 INITIAL_DRIVE_FREELIST = 16, /* number of entries in drive freelist */
183 PLEX_REGION_TABLE_SIZE = 8, /* number of entries in plex region tables */
184 INITIAL_LOCKS = 256, /* number of locks to allocate to a plex */
185 MAX_REVIVE_BLOCKSIZE = MAXPHYS, /* maximum revive block size */
186 DEFAULT_REVIVE_BLOCKSIZE = 65536, /* default revive block size */
187 VINUMHOSTNAMELEN = 32, /* host name field in label */
188 };
189
190 /* device numbers */
191
192 /*
193 * 31 30 28 27 20 19 18 16 15 8 7 0
194 * |-----------------------------------------------------------------------------------------------|
195 * |X | Type | Subdisk number | X| Plex | Major number | volume number |
196 * |-----------------------------------------------------------------------------------------------|
197 *
198 * 0x2 03 1 19 06
199 *
200 * The fields in the minor number are interpreted as follows:
201 *
202 * Volume: Only type and volume number are relevant
203 * Plex in volume: type, plex number in volume and volume number are relevant
204 * raw plex: type, plex number is made of bits 27-16 and 7-0
205 * raw subdisk: type, subdisk number is made of bits 27-16 and 7-0
206 */
207
208 /* This doesn't get used. Consider removing it. */
209 struct devcode {
210 /*
211 * CARE. These fields assume a big-endian word. On a
212 * little-endian system, they're the wrong way around
213 */
214 unsigned volume:8; /* up to 256 volumes */
215 unsigned major:8; /* this is where the major number fits */
216 unsigned plex:3; /* up to 8 plexes per volume */
217 unsigned unused:1; /* up for grabs */
218 unsigned sd:8; /* up to 256 subdisks per plex */
219 unsigned type:3; /* type of object */
220 /*
221 * type field
222 VINUM_VOLUME = 0,
223 VINUM_PLEX = 1,
224 VINUM_SUBDISK = 2,
225 VINUM_DRIVE = 3,
226 VINUM_SUPERDEV = 4,
227 VINUM_RAWPLEX = 5,
228 VINUM_RAWSD = 6 */
229 unsigned signbit:1; /* to make 32 bits */
230 };
231
232 #define VINUM_DIR "/dev/vinum"
233 #define VINUM_RDIR "/dev/rvinum"
234
235 /*
236 * These definitions help catch
237 * userland/kernel mismatches.
238 */
239 #if VINUMDEBUG
240 #define VINUM_WRONGSUPERDEV_NAME VINUM_DIR"/control" /* normal super device */
241 #define VINUM_SUPERDEV_NAME VINUM_DIR"/Control" /* debug super device */
242 #else
243 #define VINUM_WRONGSUPERDEV_NAME VINUM_DIR"/Control" /* debug super device */
244 #define VINUM_SUPERDEV_NAME VINUM_DIR"/control" /* normal super device */
245 #endif
246 #define VINUM_DAEMON_DEV_NAME VINUM_DIR"/controld" /* super device for daemon only */
247
248 /*
249 * Flags for all objects. Most of them only apply to
250 * specific objects, but we have space for all in any
251 * 32 bit flags word.
252 */
253 enum objflags {
254 VF_LOCKED = 1, /* somebody has locked access to this object */
255 VF_LOCKING = 2, /* we want access to this object */
256 VF_OPEN = 4, /* object has openers */
257 VF_WRITETHROUGH = 8, /* volume: write through */
258 VF_INITED = 0x10, /* unit has been initialized */
259 VF_WLABEL = 0x20, /* label area is writable */
260 VF_LABELLING = 0x40, /* unit is currently being labelled */
261 VF_WANTED = 0x80, /* someone is waiting to obtain a lock */
262 VF_RAW = 0x100, /* raw volume (no file system) */
263 VF_LOADED = 0x200, /* module is loaded */
264 VF_CONFIGURING = 0x400, /* somebody is changing the config */
265 VF_WILL_CONFIGURE = 0x800, /* somebody wants to change the config */
266 VF_CONFIG_INCOMPLETE = 0x1000, /* haven't finished changing the config */
267 VF_CONFIG_SETUPSTATE = 0x2000, /* set a volume up if all plexes are empty */
268 VF_READING_CONFIG = 0x4000, /* we're reading config database from disk */
269 VF_FORCECONFIG = 0x8000, /* configure drives even with different names */
270 VF_NEWBORN = 0x10000, /* for objects: we've just created it */
271 VF_CONFIGURED = 0x20000, /* for drives: we read the config */
272 VF_STOPPING = 0x40000, /* for vinum_conf: stop on last close */
273 VF_DAEMONOPEN = 0x80000, /* the daemon has us open (only superdev) */
274 VF_CREATED = 0x100000, /* for volumes: freshly created, more then new */
275 VF_HOTSPARE = 0x200000, /* for drives: use as hot spare */
276 };
277
278 /* Global configuration information for the vinum subsystem */
279 struct _vinum_conf {
280 /* Pointers to vinum structures */
281 struct drive *drive;
282 struct sd *sd;
283 struct plex *plex;
284 struct volume *volume;
285
286 /* the number allocated */
287 int drives_allocated;
288 int subdisks_allocated;
289 int plexes_allocated;
290 int volumes_allocated;
291
292 /* and the number currently in use */
293 int drives_used;
294 int subdisks_used;
295 int plexes_used;
296 int volumes_used;
297
298 int flags;
299
300 #define VINUM_MAXACTIVE 30000 /* maximum number of active requests */
301 int active; /* current number of requests outstanding */
302 int maxactive; /* maximum number of requests ever outstanding */
303 #if VINUMDEBUG
304 struct request *lastrq;
305 struct buf *lastbuf;
306 #endif
307 };
308
309 /* Use these defines to simplify code */
310 #define DRIVE vinum_conf.drive
311 #define SD vinum_conf.sd
312 #define PLEX vinum_conf.plex
313 #define VOL vinum_conf.volume
314 #define VFLAGS vinum_conf.flags
315
316 /*
317 * Slice header
318 *
319 * Vinum drives start with this structure:
320 *
321 *\ Sector
322 * |--------------------------------------|
323 * | PDP-11 memorial boot block | 0
324 * |--------------------------------------|
325 * | Disk label, maybe | 1
326 * |--------------------------------------|
327 * | Slice definition (vinum_hdr) | 8
328 * |--------------------------------------|
329 * | |
330 * | Configuration info, first copy | 9
331 * | |
332 * |--------------------------------------|
333 * | |
334 * | Configuration info, second copy | 9 + size of config
335 * | |
336 * |--------------------------------------|
337 */
338
339 /* Sizes and offsets of our information */
340 enum {
341 VINUM_LABEL_OFFSET = 4096, /* offset of vinum label */
342 VINUMHEADERLEN = 512, /* size of vinum label */
343 VINUM_CONFIG_OFFSET = 4608, /* offset of first config copy */
344 MAXCONFIG = 65536, /* and size of config copy */
345 DATASTART = (MAXCONFIG * 2 + VINUM_CONFIG_OFFSET) / DEV_BSIZE /* this is where the data starts */
346 };
347
348 /*
349 * hostname is 256 bytes long, but we don't need to shlep
350 * multiple copies in vinum. We use the host name just
351 * to identify this system, and 32 bytes should be ample
352 * for that purpose
353 */
354
355 struct vinum_label {
356 char sysname[VINUMHOSTNAMELEN]; /* system name at time of creation */
357 char name[MAXDRIVENAME]; /* our name of the drive */
358 struct timeval date_of_birth; /* the time it was created */
359 struct timeval last_update; /* and the time of last update */
360 /*
361 * total size in bytes of the drive. This value
362 * includes the headers.
363 */
364 off_t drive_size;
365 };
366
367 struct vinum_hdr {
368 uint64_t magic; /* we're long on magic numbers */
369 #define VINUM_MAGIC 22322600044678729LL /* should be this */
370 #define VINUM_NOMAGIC 22322600044678990LL /* becomes this after obliteration */
371 /*
372 * Size in bytes of each copy of the
373 * configuration info. This must be a multiple
374 * of the sector size.
375 */
376 int config_length;
377 struct vinum_label label; /* unique label */
378 };
379
380 /* Information returned from read_drive_label */
381 enum drive_label_info {
382 DL_CANT_OPEN, /* invalid partition */
383 DL_NOT_OURS, /* valid partition, but no vinum label */
384 DL_DELETED_LABEL, /* valid partition, deleted label found */
385 DL_WRONG_DRIVE, /* drive name doesn't match */
386 DL_OURS /* valid partition and label found */
387 };
388
389 /*** Drive definitions ***/
390 /*
391 * A drive corresponds to a disk slice. We use a different term to show
392 * the difference in usage: it doesn't have to be a slice, and could
393 * theoretically be a complete, unpartitioned disk
394 */
395
396 struct drive {
397 enum drivestate state; /* current state */
398 int flags; /* flags */
399 int subdisks_allocated; /* number of entries in sd */
400 int subdisks_used; /* and the number used */
401 int blocksize; /* size of fs blocks */
402 int pid; /* of locker */
403 u_int64_t sectors_available; /* number of sectors still available */
404 int secsperblock;
405 int lasterror; /* last error on drive */
406 int driveno; /* index of drive in vinum_conf */
407 int opencount; /* number of up subdisks */
408 u_int64_t reads; /* number of reads on this drive */
409 u_int64_t writes; /* number of writes on this drive */
410 u_int64_t bytes_read; /* number of bytes read */
411 u_int64_t bytes_written; /* number of bytes written */
412 char devicename[MAXDRIVENAME]; /* name of the slice it's on */
413 dev_t dev; /* device information */
414 struct vinum_label label; /* and the label information */
415 struct partinfo partinfo; /* partition information */
416 int freelist_size; /* number of entries alloced in free list */
417 int freelist_entries; /* number of entries used in free list */
418 struct drive_freelist { /* sorted list of free space on drive */
419 u_int64_t offset; /* offset of entry */
420 u_int64_t sectors; /* and length in sectors */
421 } *freelist;
422 #define DRIVE_MAXACTIVE 30000 /* maximum number of active requests */
423 int active; /* current number of requests outstanding */
424 int maxactive; /* maximum number of requests ever outstanding */
425 #ifdef VINUMDEBUG
426 char lockfilename[16]; /* name of file from which we were locked */
427 int lockline; /* and the line number */
428 #endif
429 };
430
431 /*** Subdisk definitions ***/
432
433 struct sd {
434 enum sdstate state; /* state */
435 int flags;
436 int lasterror; /* last error occurred */
437 /* offsets in blocks */
438 int64_t driveoffset; /* offset on drive */
439 /*
440 * plexoffset is the offset from the beginning
441 * of the plex to the very first part of the
442 * subdisk, in sectors. For striped, RAID-4 and
443 * RAID-5 plexes, only the first stripe is
444 * located at this offset
445 */
446 int64_t plexoffset; /* offset in plex */
447 u_int64_t sectors; /* and length in sectors */
448 int plexno; /* index of plex, if it belongs */
449 int driveno; /* index of the drive on which it is located */
450 int sdno; /* our index in vinum_conf */
451 int plexsdno; /* and our number in our plex */
452 /* (undefined if no plex) */
453 u_int64_t reads; /* number of reads on this subdisk */
454 u_int64_t writes; /* number of writes on this subdisk */
455 u_int64_t bytes_read; /* number of bytes read */
456 u_int64_t bytes_written; /* number of bytes written */
457 /* revive parameters */
458 u_int64_t revived; /* block number of current revive request */
459 int revive_blocksize; /* revive block size (bytes) */
460 int revive_interval; /* and time to wait between transfers */
461 pid_t reviver; /* PID of reviving process */
462 struct request *waitlist; /* list of requests waiting on revive op */
463 /* init parameters */
464 u_int64_t initialized; /* block number of current init request */
465 int init_blocksize; /* init block size (bytes) */
466 int init_interval; /* and time to wait between transfers */
467 char name[MAXSDNAME]; /* name of subdisk */
468 };
469
470 /*** Plex definitions ***/
471
472 /* kinds of plex organization */
473 enum plexorg {
474 plex_disorg, /* disorganized */
475 plex_concat, /* concatenated plex */
476 plex_striped, /* striped plex */
477 plex_raid4, /* RAID4 plex */
478 plex_raid5 /* RAID5 plex */
479 };
480
481 /* Recognize plex organizations */
482 #define isstriped(p) (p->organization >= plex_striped) /* RAID 1, 4 or 5 */
483 #define isparity(p) (p->organization >= plex_raid4) /* RAID 4 or 5 */
484
485 struct plex {
486 enum plexorg organization; /* Plex organization */
487 enum plexstate state; /* and current state */
488 u_int64_t length; /* total length of plex (sectors) */
489 int flags;
490 int stripesize; /* size of stripe or raid band, in sectors */
491 int subdisks; /* number of associated subdisks */
492 int subdisks_allocated; /* number of subdisks allocated space for */
493 int *sdnos; /* list of component subdisks */
494 int plexno; /* index of plex in vinum_conf */
495 int volno; /* index of volume */
496 int volplexno; /* number of plex in volume */
497 /* Lock information */
498 int alloclocks; /* number of locks allocated */
499 int usedlocks; /* number currently in use */
500 int lockwaits; /* and number of waits for locks */
501 struct rangelock *lock; /* ranges of locked addresses */
502 off_t checkblock; /* block number for parity op */
503 /* Statistics */
504 u_int64_t reads; /* number of reads on this plex */
505 u_int64_t writes; /* number of writes on this plex */
506 u_int64_t bytes_read; /* number of bytes read */
507 u_int64_t bytes_written; /* number of bytes written */
508 u_int64_t recovered_reads; /* number of recovered read operations */
509 u_int64_t degraded_writes; /* number of degraded writes */
510 u_int64_t parityless_writes; /* number of parityless writes */
511 u_int64_t multiblock; /* requests that needed more than one block */
512 u_int64_t multistripe; /* requests that needed more than one stripe */
513 int sddowncount; /* number of subdisks down */
514 char name[MAXPLEXNAME]; /* name of plex */
515 };
516
517 /*** Volume definitions ***/
518
519 /* Address range definitions, for locking volumes */
520 struct rangelock {
521 daddr_t stripe; /* address + 1 of the range being locked */
522 struct buf *bp; /* user's buffer pointer */
523 int plexno; /* and number of plex it affects */
524 };
525
526 struct volume {
527 enum volumestate state; /* current state */
528 int plexes; /* number of plexes */
529 int preferred_plex; /* plex to read from, -1 for round-robin */
530 /*
531 * index of plex used for last read, for
532 * round-robin.
533 */
534 int last_plex_read;
535 int volno; /* volume number */
536 int flags; /* status and configuration flags */
537 int openflags; /* flags supplied to last open(2) */
538 u_int64_t size; /* size of volume */
539 int blocksize; /* logical block size */
540 int active; /* number of outstanding requests active */
541 int subops; /* and the number of suboperations */
542 /* Statistics */
543 u_int64_t bytes_read; /* number of bytes read */
544 u_int64_t bytes_written; /* number of bytes written */
545 u_int64_t reads; /* number of reads on this volume */
546 u_int64_t writes; /* number of writes on this volume */
547 u_int64_t recovered_reads; /* reads recovered from another plex */
548 /*
549 * Unlike subdisks in the plex, space for the
550 * plex pointers is static.
551 */
552 int plex[MAXPLEX]; /* index of plexes */
553 char name[MAXVOLNAME]; /* name of volume */
554 struct disklabel label; /* for DIOCGPART */
555 };
556
557 /*
558 * Table expansion. Expand table, which contains oldcount
559 * entries of type element, by increment entries, and change
560 * oldcount accordingly
561 */
562 #define EXPAND(table, element, oldcount, increment) \
563 { \
564 expand_table ((void **) &table, \
565 oldcount * sizeof (element), \
566 (oldcount + increment) * sizeof (element) ); \
567 oldcount += increment; \
568 }
569
570 /* Information on vinum's memory usage */
571 struct meminfo {
572 int mallocs; /* number of malloced blocks */
573 int total_malloced; /* total amount malloced */
574 int highwater; /* maximum number of mallocs */
575 struct mc *malloced; /* pointer to kernel table */
576 };
577
578 #define MCFILENAMELEN 16
579 struct mc {
580 struct timeval time;
581 int seq;
582 int size;
583 short line;
584 caddr_t address;
585 char file[MCFILENAMELEN];
586 };
587
588 /*
589 * These enums are used by the state transition
590 * routines. They're in bit map format:
591 *
592 * Bit 0: Other plexes in the volume are down
593 * Bit 1: Other plexes in the volume are up
594 * Bit 2: The current plex is up
595 * Maybe they should be local to
596 * state.c
597 */
598 enum volplexstate {
599 volplex_onlyusdown = 0, /* 0: we're the only plex, and we're down */
600 volplex_alldown, /* 1: another plex is down, and so are we */
601 volplex_otherup, /* 2: another plex is up */
602 volplex_otherupdown, /* 3: other plexes are up and down */
603 volplex_onlyus, /* 4: we're up and alone */
604 volplex_onlyusup, /* 5: only we are up, others are down */
605 volplex_allup, /* 6: all plexes are up */
606 volplex_someup /* 7: some plexes are up, including us */
607 };
608
609 /* state map for plex */
610 enum sdstates {
611 sd_emptystate = 1,
612 sd_downstate = 2, /* SD is down */
613 sd_crashedstate = 4, /* SD is crashed */
614 sd_obsoletestate = 8, /* SD is obsolete */
615 sd_stalestate = 16, /* SD is stale */
616 sd_rebornstate = 32, /* SD is reborn */
617 sd_upstate = 64, /* SD is up */
618 sd_initstate = 128, /* SD is initializing */
619 sd_initializedstate = 256, /* SD is initialized */
620 sd_otherstate = 512, /* SD is in some other state */
621 };
622
623 /*
624 * This is really just a parameter to pass to
625 * set_<foo>_state, but since it needs to be known
626 * in the external definitions, we need to define
627 * it here
628 */
629 enum setstateflags {
630 setstate_none = 0, /* no flags */
631 setstate_force = 1, /* force the state change */
632 setstate_configuring = 2, /* we're currently configuring, don't save */
633 };
634
635 /* Operations for parityops to perform. */
636 enum parityop {
637 checkparity,
638 rebuildparity,
639 rebuildandcheckparity, /* rebuildparity with the -v option */
640 };
641
642 #ifdef VINUMDEBUG
643 /* Debugging stuff */
644 enum debugflags {
645 DEBUG_ADDRESSES = 1, /* show buffer information during requests */
646 DEBUG_NUMOUTPUT = 2, /* show the value of vp->v_numoutput */
647 DEBUG_RESID = 4, /* go into debugger in complete_rqe */
648 DEBUG_LASTREQS = 8, /* keep a circular buffer of last requests */
649 DEBUG_REVIVECONFLICT = 16, /* print info about revive conflicts */
650 DEBUG_EOFINFO = 32, /* print info about EOF detection */
651 DEBUG_MEMFREE = 64, /* keep info about Frees */
652 DEBUG_BIGDRIVE = 128, /* pretend our drives are 100 times the size */
653 DEBUG_REMOTEGDB = 256, /* go into remote gdb */
654 DEBUG_WARNINGS = 512, /* log various relatively harmless warnings */
655 };
656
657 #ifdef KERNEL
658 #ifdef __i386__
659 #define longjmp LongJmp /* test our longjmps */
660 #endif
661 #endif
662 #endif
663 /* Local Variables: */
664 /* fill-column: 50 */
665 /* End: */
Cache object: 1bd04df294eada4f7a57411e442d4131
|