diff options
author | grog <grog@FreeBSD.org> | 1998-10-21 08:32:32 +0000 |
---|---|---|
committer | grog <grog@FreeBSD.org> | 1998-10-21 08:32:32 +0000 |
commit | c4f583ab45280938d0a6fb05b51d4ecadfc1f413 (patch) | |
tree | dae6747deab534df8daae0214b7739eb96b1f003 /lkm | |
parent | f8807b8fc154475494280090923ce6f4d311d64e (diff) | |
download | FreeBSD-src-c4f583ab45280938d0a6fb05b51d4ecadfc1f413.zip FreeBSD-src-c4f583ab45280938d0a6fb05b51d4ecadfc1f413.tar.gz |
config.c:
config_drive:
Catch an instance of anonymous drives. Doubtless many remain.
interrupt.c:
complete_rqe:
Call logrq to log iodone events if DEBUG_LASTREQS is set.
Call set_sd_state with setstate_noupdate to avoid buffered I/O out
of interrupt context.
Use define DEBUG_RESID instead of constant.
memory.c:
Remove dead expandrq() function
Malloc:
Remove directory component of file names in malloc table.
Add function vinum_rqinfo (part of the request tracing stuff).
request.c:
Add function logrq (part of the request tracing stuff).
vinumstrategy:
Check whether config needs to be written to disk, do it if so.
This is a stopgap until the Vinum daemon (bacchusd? oenologistd?)
is written.
If DEBUG_LASTREQS is set, call logrq to log user buffer headers.
launch_requests:
Correct format of debug output to console.
If DEBUG_LASTREQS is set, call logrq to log request elements.
request.h:
Add definitions for request trace.
state.c:
set_sd_state:
Check flags for setstate_noupdate. If set, don't write the config
to disk, just set global VF_DIRTYCONFIG flag. This is part of the
kludge to avoid writing config from an interrupt context.
vinumext.h:
Add declaration for vinum_rqinfo, put inside #ifdef DEBUG
Remove dead macro expandrq
vinumio.h:
Increase maximum ioctl reply length to 4 kB if DEBUG is set.
Define VINUM_RQINFO ioctl if DEBUG is set.
vinumioctl.c:
vinumioctl:
Change implementation of VINUM_DEBUG ioctl: use a debug flag
(DEBUG_REMOTEGDB) to decide whether to go into remote debugging or
not.
Implement VINUM_RQINFO.
vinumkw.h:
Define kw_info even when not debugging.
vinumvar.h:
Define VF_DIRTYCONFIG
Add pointers to request info to vinum_info if DEBUG is set.
Define setstate_noupdate
Define additional debug bits DEBUG_RESID, DEBUG_LASTREQS and
DEBUG_REMOTEGDB.
Diffstat (limited to 'lkm')
-rw-r--r-- | lkm/vinum/config.c | 9 | ||||
-rw-r--r-- | lkm/vinum/interrupt.c | 10 | ||||
-rw-r--r-- | lkm/vinum/memory.c | 46 | ||||
-rw-r--r-- | lkm/vinum/request.c | 77 | ||||
-rw-r--r-- | lkm/vinum/request.h | 32 | ||||
-rw-r--r-- | lkm/vinum/state.c | 8 | ||||
-rw-r--r-- | lkm/vinum/vinumext.h | 20 | ||||
-rw-r--r-- | lkm/vinum/vinumio.h | 9 | ||||
-rw-r--r-- | lkm/vinum/vinumioctl.c | 18 | ||||
-rw-r--r-- | lkm/vinum/vinumkw.h | 4 | ||||
-rw-r--r-- | lkm/vinum/vinumvar.h | 11 |
11 files changed, 188 insertions, 56 deletions
diff --git a/lkm/vinum/config.c b/lkm/vinum/config.c index fd31c5e..4875eb6 100644 --- a/lkm/vinum/config.c +++ b/lkm/vinum/config.c @@ -44,7 +44,7 @@ * otherwise) arising in any way out of the use of this software, even if * advised of the possibility of such damage. * - * $Id: config.c,v 1.17 1998/08/14 04:49:26 grog Exp grog $ + * $Id: config.c,v 1.19 1998/10/05 02:48:15 grog Exp grog $ */ #define STATIC /* nothing while we're testing XXX */ @@ -488,7 +488,7 @@ get_empty_drive(void) /* Find the named drive in vinum_conf.drive, return a pointer * return the index in vinum_conf.drive. - * Don't mark the drive as allocated (XXX MP) + * Don't mark the drive as allocated (XXX SMP) * If create != 0, create an entry if it doesn't exist */ /* XXX check if we have it open from attach */ @@ -936,9 +936,10 @@ config_drive(void) } } - if (drive->devicename[0] == '\0') + if (drive->devicename[0] == '\0') { + drive->state = drive_unallocated; /* deallocate the drive */ throw_rude_remark(EINVAL, "No device name for %s", drive->label.name); - + } } /* Handle a subdisk definition. We store the information in the global variable diff --git a/lkm/vinum/interrupt.c b/lkm/vinum/interrupt.c index e7eb034..1557cfe 100644 --- a/lkm/vinum/interrupt.c +++ b/lkm/vinum/interrupt.c @@ -69,14 +69,19 @@ complete_rqe(struct buf *bp) rqe = (struct rqelement *) bp; /* point to the element element that completed */ rqg = rqe->rqg; /* and the request group */ rq = rqg->rq; /* and the complete request */ + ubp = rq->bp; /* user buffer */ +#ifdef DEBUG + if (debug & DEBUG_LASTREQS) + logrq(loginfo_iodone, rqe, ubp); +#endif if ((bp->b_flags & B_ERROR) != 0) { /* transfer in error */ if (bp->b_error != 0) /* did it return a number? */ rq->error = bp->b_error; /* yes, put it in. */ else if (rq->error == 0) /* no: do we have one already? */ rq->error = EIO; /* no: catchall "I/O error" */ if (rq->error == EIO) /* I/O error, */ - set_sd_state(rqe->sdno, sd_crashed, setstate_force); /* take the subdisk down */ + set_sd_state(rqe->sdno, sd_crashed, setstate_force | setstate_noupdate); /* take the subdisk down */ } /* Now update the statistics */ if (bp->b_flags & B_READ) { /* read operation */ @@ -94,13 +99,12 @@ complete_rqe(struct buf *bp) PLEX[rqe->rqg->plexno].writes++; PLEX[rqe->rqg->plexno].bytes_written += bp->b_bcount; } - ubp = rq->bp; /* user buffer */ rqg->active--; /* one less request active */ if (rqg->active == 0) /* request group finished, */ rq->active--; /* one less */ if (rq->active == 0) { /* request finished, */ #if DEBUG - if (debug & 4) { + if (debug & DEBUG_RESID) { if (ubp->b_resid != 0) /* still something to transfer? */ Debugger("resid"); diff --git a/lkm/vinum/memory.c b/lkm/vinum/memory.c index 5dee671..e77af7e 100644 --- a/lkm/vinum/memory.c +++ b/lkm/vinum/memory.c @@ -1,4 +1,3 @@ - /*- * Copyright (c) 1997, 1998 * Nan Yang Computer Services Limited. All rights reserved. @@ -34,7 +33,7 @@ * otherwise) arising in any way out of the use of this software, even if * advised of the possibility of such damage. * - * $Id: memory.c,v 1.16 1998/08/08 04:43:22 grog Exp grog $ + * $Id: memory.c,v 1.17 1998/09/29 05:18:09 grog Exp grog $ */ #define REALLYKERNEL @@ -43,6 +42,12 @@ extern jmp_buf command_fail; /* return on a failed command */ +#ifdef DEBUG +#include "request.h" +extern struct rqinfo rqinfo[]; +extern struct rqinfo *rqip; +#endif + #if __FreeBSD__ >= 3 /* Why aren't these declared anywhere? XXX */ int setjmp(jmp_buf); @@ -68,20 +73,6 @@ expand_table(void **table, int oldsize, int newsize) } } -#ifndef DEBUG -/* increase the size of a request block */ -void -expandrq(struct plexrq *prq) -{ - expand_table((void **) &prq->rqe, - prq->requests * sizeof(struct rqelement), - (prq->requests + RQELTS) * sizeof(struct rqelement)); - bzero(&prq->rqe[prq->requests], RQELTS * sizeof(struct rqelement)); /* clear the new part */ - prq->rqcount += RQELTS; -} - -#endif - #if DEBUG /* XXX debug */ #define MALLOCENTRIES 16384 int malloccount = 0; @@ -115,6 +106,10 @@ MMalloc(int size, char *file, int line) Debugger("Malloc overlap"); } if (result) { + char *f = index(file, '/'); /* chop off dirname if present */ + + if (f == NULL) + f = file; i = malloccount++; total_malloced += size; malloced[i].address = result; @@ -123,7 +118,7 @@ MMalloc(int size, char *file, int line) malloced[i].seq = seq++; malloced[i].flags = me.flags; malloced[i].databuf = me.databuf; /* only used with kva alloc */ - bcopy(file, malloced[i].file, min(strlen(file) + 1, 16)); + bcopy(f, malloced[i].file, min(strlen(f) + 1, 16)); } if (malloccount > highwater) highwater = malloccount; @@ -183,4 +178,21 @@ vinum_mallocinfo(caddr_t data) return 0; } +/* return the nth request trace buffer entry. This + * is indexed back from the current entry (which + * has index 0) */ +int +vinum_rqinfo(caddr_t data) +{ + struct rqinfo *rq = (struct rqinfo *) data; + int ent = *(int *) data; /* 1st word is index */ + int lastent = rqip - rqinfo; /* entry number of current entry */ + + if (ent >= RQINFO_SIZE) /* out of the table */ + return ENOENT; + if ((ent = lastent - ent - 1) < 0) + ent += RQINFO_SIZE; /* roll over backwards */ + bcopy(&rqinfo[ent], rq, sizeof(struct rqinfo)); + return 0; +} #endif diff --git a/lkm/vinum/request.c b/lkm/vinum/request.c index 589eb3f..94df5b9 100644 --- a/lkm/vinum/request.c +++ b/lkm/vinum/request.c @@ -37,7 +37,7 @@ * otherwise) arising in any way out of the use of this software, even if * advised of the possibility of such damage. * - * $Id: request.c,v 1.17 1998/08/13 06:04:47 grog Exp grog $ + * $Id: request.c,v 1.18 1998/08/31 23:45:35 grog Exp grog $ */ #define REALLYKERNEL @@ -73,6 +73,50 @@ int vinum_bounds_check(struct buf *bp, struct volume *vol); caddr_t allocdatabuf(struct rqelement *rqe); void freedatabuf(struct rqelement *rqe); +#ifdef DEBUG +struct rqinfo rqinfo[RQINFO_SIZE]; +struct rqinfo *rqip = rqinfo; + +void +logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp) +{ + BROKEN_GDB; + int s = splhigh(); + + vinum_conf.rqipp = &rqip; /* XXX for broken gdb */ + vinum_conf.rqinfop = rqinfo; /* XXX for broken gdb */ + +#if __FreeBSD__ < 3 + rqip->timestamp = time; /* when did this happen? */ +#else + microtime(&rqip->timestamp); /* when did this happen? */ +#endif + rqip->type = type; + rqip->bp = ubp; /* user buffer */ + switch (type) { + case loginfo_user_bp: + case loginfo_user_bpl: + bcopy(info.bp, &rqip->info.b, sizeof(struct buf)); + break; + + case loginfo_iodone: + case loginfo_rqe: + case loginfo_raid5_data: + case loginfo_raid5_parity: + bcopy(info.rqe, &rqip->info.rqe, sizeof(struct rqelement)); + break; + + case loginfo_unused: + break; + } + rqip++; + if (rqip >= &rqinfo[RQINFO_SIZE]) /* wrap around */ + rqip = rqinfo; + splx(s); +} + +#endif + void vinumstrategy(struct buf *bp) { @@ -83,6 +127,17 @@ vinumstrategy(struct buf *bp) struct devcode *device = (struct devcode *) &bp->b_dev; /* decode device number */ enum requeststatus status; + /* We may have changed the configuration in + * an interrupt context. Update it now. It + * could change again, so do it in a loop. + * XXX this is broken and contains a race condition. + * The correct way is to hand it off the the Vinum + * daemon, but I haven't found a name for it yet */ + while (vinum_conf.flags & VF_DIRTYCONFIG) { /* config is dirty, save it now */ + vinum_conf.flags &= ~VF_DIRTYCONFIG; /* turn it off */ + save_config(); + } + switch (device->type) { case VINUM_SD_TYPE: sdio(bp); @@ -142,6 +197,11 @@ vinumstart(struct buf *bp, int reviveok) int rqno; /* index in request list */ enum requeststatus status; +#if DEBUG + if (debug & DEBUG_LASTREQS) + logrq(loginfo_user_bp, bp, bp); +#endif + /* XXX In these routines, we're assuming that * we will always be called with bp->b_bcount * which is a multiple of the sector size. This @@ -218,8 +278,8 @@ vinumstart(struct buf *bp, int reviveok) biodone(bp); freerq(rq); return -1; - } - return launch_requests(rq, reviveok); /* now start the requests if we can */ + } + return launch_requests(rq, reviveok); /* now start the requests if we can */ } else /* This is a write operation. We write to all * plexes. If this is a RAID 5 plex, we must also @@ -248,8 +308,8 @@ vinumstart(struct buf *bp, int reviveok) biodone(bp); freerq(rq); return -1; - } - return launch_requests(rq, reviveok); /* start the requests */ + } + return launch_requests (rq, reviveok); /* start the requests */ } } @@ -296,13 +356,16 @@ launch_requests(struct request *rq, int reviveok) } #if DEBUG if (debug & DEBUG_ADDRESSES) - printf("Request: %x\nWrite dev 0x%x, offset 0x%x, length %ld\n", + printf("Request: %x\n%s dev 0x%x, offset 0x%x, length %ld\n", (u_int) rq, + rq->bp->b_flags & B_READ ? "Read" : "Write", rq->bp->b_dev, rq->bp->b_blkno, rq->bp->b_bcount); /* XXX */ vinum_conf.lastrq = (int) rq; vinum_conf.lastbuf = rq->bp; + if (debug & DEBUG_LASTREQS) + logrq(loginfo_user_bpl, rq->bp, rq->bp); #endif for (rqg = rq->rqg; rqg != NULL; rqg = rqg->next) { /* through the whole request chain */ rqg->active = rqg->count; /* they're all active */ @@ -328,6 +391,8 @@ launch_requests(struct request *rq, int reviveok) printf(" vinumstart sd %d numoutput %ld\n", rqe->sdno, rqe->b.b_vp->v_numoutput); + if (debug & DEBUG_LASTREQS) + logrq(loginfo_rqe, rqe, rq->bp); #endif /* fire off the request */ s = splbio(); diff --git a/lkm/vinum/request.h b/lkm/vinum/request.h index b4beccc..6575204 100644 --- a/lkm/vinum/request.h +++ b/lkm/vinum/request.h @@ -157,3 +157,35 @@ enum requeststatus { REQUEST_DOWN, /* request failed: subdisk down */ REQUEST_ENOMEM /* ran out of memory */ }; + +#ifdef DEBUG +/* Trace entry for request info (DEBUG_LASTREQS) */ +enum rqinfo_type { + loginfo_unused, /* never been used */ + loginfo_user_bp, /* this is the bp when strategy is called */ + loginfo_user_bpl, /* and this is the bp at launch time */ + loginfo_rqe, /* user RQE */ + loginfo_iodone, /* iodone */ + loginfo_raid5_data, /* write RAID-5 data block */ + loginfo_raid5_parity /* write RAID-5 parity block */ +}; + +union rqinfou { /* info to pass to logrq */ + struct buf *bp; + struct rqelement *rqe; /* address of request, for correlation */ +}; + +struct rqinfo { + enum rqinfo_type type; /* kind of event */ + struct timeval timestamp; /* time it happened */ + struct buf *bp; /* point to user buffer */ + union { + struct buf b; /* yup, the *whole* buffer header */ + struct rqelement rqe; /* and the whole rqe */ + } info; +}; + +#define RQINFO_SIZE 64 /* number of info slots in buffer */ + +void logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp); +#endif diff --git a/lkm/vinum/state.c b/lkm/vinum/state.c index 2ce2ed0..928cb38 100644 --- a/lkm/vinum/state.c +++ b/lkm/vinum/state.c @@ -164,8 +164,12 @@ set_sd_state(int sdno, enum sdstate state, enum setstateflags flags) printf("vinum: subdisk %s is %s\n", sd->name, sd_state(sd->state)); if ((flags & setstate_norecurse) == 0) set_plex_state(sd->plexno, plex_up, setstate_recursing); /* update plex state */ - if ((flags & (setstate_configuring | setstate_recursing)) == 0) /* save config now */ - save_config(); + if ((flags & (setstate_configuring | setstate_recursing)) == 0) { /* save config now */ + if (setstate_noupdate) /* we can't update now, */ + vinum_conf.flags |= VF_DIRTYCONFIG; /* wait until later */ + else + save_config(); + } return status; } diff --git a/lkm/vinum/vinumext.h b/lkm/vinum/vinumext.h index 4b7d5a0..3b63918 100644 --- a/lkm/vinum/vinumext.h +++ b/lkm/vinum/vinumext.h @@ -33,7 +33,7 @@ * otherwise) arising in any way out of the use of this software, even if * advised of the possibility of such damage. * - * $Id: vinumext.h,v 1.14 1998/08/11 00:03:57 grog Exp grog $ + * $Id: vinumext.h,v 1.15 1998/09/29 05:17:56 grog Exp grog $ */ /* vinumext.h: external definitions */ @@ -136,9 +136,12 @@ int launch_requests(struct request *rq, int reviveok); /* XXX Do we need this? */ int vinumpart(dev_t); -/* Memory allocation */ +#ifdef DEBUG +/* Memory allocation and request tracing */ void vinum_meminfo(caddr_t data); int vinum_mallocinfo(caddr_t data); +int vinum_rqinfo(caddr_t data); +#endif void expand_table(void **, int, int); @@ -199,16 +202,3 @@ int lockrange(struct plex *plex, off_t first, off_t last); void unlockrange(struct plex *plex, off_t first, off_t last); int lock_config(void); void unlock_config(void); - -#ifdef DEBUG -#define expandrq(prq) \ -{ \ - expand_table ((void **) &prq->rqe, \ - prq->requests * sizeof (struct rqelement), \ - (prq->requests + RQELTS) * sizeof (struct rqelement) ); \ - bzero (&prq->rqe [prq->requests], RQELTS * sizeof (struct rqelement)); \ - prq->rqcount += RQELTS; \ - } -#else -void expandrq(struct plexrq *); -#endif diff --git a/lkm/vinum/vinumio.h b/lkm/vinum/vinumio.h index be79528..b99bd42 100644 --- a/lkm/vinum/vinumio.h +++ b/lkm/vinum/vinumio.h @@ -36,7 +36,12 @@ * $Id: vinumio.h,v 1.10 1998/08/10 05:46:19 grog Exp grog $ */ +#ifdef DEBUG +#define MAX_IOCTL_REPLY 4096 +#else #define MAX_IOCTL_REPLY 256 +#endif + #define L 'F' /* ID letter of our ioctls */ /* VINUM_CREATE returns a buffer of this kind */ struct _ioctl_reply { @@ -130,3 +135,7 @@ struct vinum_rename_msg { #define VINUM_RENAME _IOC(IOC_IN | IOC_OUT, L, 89, MAX_IOCTL_REPLY) /* reset object stats */ #define VINUM_REPLACE _IOC(IOC_IN | IOC_OUT, L, 90, MAX_IOCTL_REPLY) /* reset object stats */ + +#ifdef DEBUG +#define VINUM_RQINFO _IOWR(L, 91, struct rqinfo) /* get request info [i] from trace buffer */ +#endif diff --git a/lkm/vinum/vinumioctl.c b/lkm/vinum/vinumioctl.c index 6dbe3c6..fd91f79 100644 --- a/lkm/vinum/vinumioctl.c +++ b/lkm/vinum/vinumioctl.c @@ -35,7 +35,7 @@ * otherwise) arising in any way out of the use of this software, even if * advised of the possibility of such damage. * - * $Id: vinumioctl.c,v 1.1 1998/08/14 08:46:10 grog Exp grog $ + * $Id: vinumioctl.c,v 1.3 1998/09/29 05:26:37 grog Exp grog $ */ #define STATIC /* nothing while we're testing XXX */ @@ -45,6 +45,7 @@ #include "sys/sysproto.h" /* for sync(2) */ #ifdef DEBUG #include <sys/reboot.h> +#include "request.h" #endif jmp_buf command_fail; /* return on a failed command */ @@ -97,17 +98,21 @@ vinumioctl(dev_t dev, if (error) /* bombed out */ return 0; /* the reply will contain meaningful info */ switch (cmd) { - /* XXX #ifdef DEBUG */ +#ifdef DEBUG case VINUM_DEBUG: - boothowto |= RB_GDB; /* serial debug line */ if (((struct debuginfo *) data)->changeit) /* change debug settings */ debug = (((struct debuginfo *) data)->param); - else + else { + if (debug & DEBUG_REMOTEGDB) + boothowto |= RB_GDB; /* serial debug line */ + else + boothowto &= ~RB_GDB; /* local ddb */ Debugger("vinum debug"); + } ioctl_reply = (struct _ioctl_reply *) data; /* reinstate the address to reply to */ ioctl_reply->error = 0; return 0; - /* XXX #endif */ +#endif case VINUM_CREATE: /* create a vinum object */ error = lock_config(); /* get the config for us alone */ @@ -222,6 +227,9 @@ vinumioctl(dev_t dev, case VINUM_MALLOCINFO: return vinum_mallocinfo(data); + case VINUM_RQINFO: + return vinum_rqinfo(data); + case VINUM_LABEL: /* label a volume */ ioctl_reply->error = write_volume_label(*(int *) data); /* index of the volume to label */ ioctl_reply->msg[0] = '\0'; /* no message */ diff --git a/lkm/vinum/vinumkw.h b/lkm/vinum/vinumkw.h index 1a81f37..597d160 100644 --- a/lkm/vinum/vinumkw.h +++ b/lkm/vinum/vinumkw.h @@ -33,7 +33,7 @@ * otherwise) arising in any way out of the use of this software, even if * advised of the possibility of such damage. * - * $Id: vinumkw.h,v 1.7 1998/08/07 02:35:51 grog Exp grog $ + * $Id: vinumkw.h,v 1.8 1998/09/29 05:17:39 grog Exp grog $ */ /* Command keywords that vinum knows. These include both user-level @@ -98,8 +98,8 @@ enum keyword { kw_detached, #ifdef DEBUG kw_debug, /* go into debugger */ - kw_info, #endif + kw_info, kw_invalid_keyword = -1 }; diff --git a/lkm/vinum/vinumvar.h b/lkm/vinum/vinumvar.h index ca54f76..ee347fc 100644 --- a/lkm/vinum/vinumvar.h +++ b/lkm/vinum/vinumvar.h @@ -185,6 +185,7 @@ enum objflags { VF_CONFIG_SETUPSTATE = 0x2000, /* set a volume up if all plexes are empty */ VF_READING_CONFIG = 0x4000, /* we're reading config database from disk */ VF_KERNELOP = 0x8000, /* we're performing ops from kernel space */ + VF_DIRTYCONFIG = 0x10000, /* config needs updating */ }; /* Global configuration information for the vinum subsystem */ @@ -212,6 +213,8 @@ struct _vinum_conf { #if DEBUG int lastrq; struct buf *lastbuf; + struct rqinfo **rqipp; + struct rqinfo *rqinfop; #endif }; @@ -226,7 +229,7 @@ struct _vinum_conf { * Vinum drives start with this structure: * - * Sector + *\ Sector * |--------------------------------------| * | PDP-11 memorial boot block | 0 * |--------------------------------------| @@ -500,11 +503,15 @@ enum setstateflags { setstate_force = 1, /* force the state change */ setstate_configuring = 2, /* we're currently configuring, don't save */ setstate_recursing = 4, /* we're called from another setstate function */ - setstate_norecurse = 8 /* don't call other setstate functions */ + setstate_norecurse = 8, /* don't call other setstate functions */ + setstate_noupdate = 16 /* don't update config */ }; #ifdef DEBUG /* Debugging stuff */ #define DEBUG_ADDRESSES 1 #define DEBUG_NUMOUTPUT 2 +#define DEBUG_RESID 4 /* go into debugger in complete_rqe */ +#define DEBUG_LASTREQS 8 /* keep a circular buffer of last requests */ +#define DEBUG_REMOTEGDB 256 /* go into remote gdb */ #endif |