Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Fix assorted bugs around shutdown/reboot/panic time.
details: https://anonhg.NetBSD.org/src/rev/dfcc55d33e76
branches: trunk
changeset: 487649:dfcc55d33e76
user: sommerfeld <sommerfeld%NetBSD.org@localhost>
date: Sat Jun 10 18:44:43 2000 +0000
description:
Fix assorted bugs around shutdown/reboot/panic time.
- add a new global variable, doing_shutdown, which is nonzero if
vfs_shutdown() or panic() have been called.
- in panic, set RB_NOSYNC if doing_shutdown is already set on entry
so we don't reenter vfs_shutdown if we panic'ed there.
- in vfs_shutdown, don't use proc0's process for sys_sync unless
curproc is NULL.
- in lockmgr, attribute successful locks to proc0 if doing_shutdown
&& curproc==NULL, and panic if we can't get the lock right away; avoids the
spurious lockmgr DIAGNOSTIC panic from the ddb reboot command.
- in subr_pool, deal with curproc==NULL in the doing_shutdown case.
- in mfs_strategy, bitbucket writes if doing_shutdown, so we don't
wedge waiting for the mfs process.
- in ltsleep, treat ((curproc == NULL) && doing_shutdown) like the
panicstr case.
Appears to fix: kern/9239, kern/10187, kern/9367.
May also fix kern/10122.
diffstat:
sys/kern/kern_lock.c | 42 +++++++++++++++++++++++++++++++++++++-----
sys/kern/kern_synch.c | 13 ++++++++++---
sys/kern/subr_pool.c | 5 +++--
sys/kern/subr_prf.c | 10 ++++++----
sys/kern/vfs_subr.c | 30 +++++++++++++-----------------
sys/sys/mount.h | 4 ++--
sys/sys/systm.h | 3 ++-
7 files changed, 73 insertions(+), 34 deletions(-)
diffs (272 lines):
diff -r 22e1e7eed846 -r dfcc55d33e76 sys/kern/kern_lock.c
--- a/sys/kern/kern_lock.c Sat Jun 10 18:31:11 2000 +0000
+++ b/sys/kern/kern_lock.c Sat Jun 10 18:44:43 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_lock.c,v 1.31 2000/06/08 05:50:59 thorpej Exp $ */
+/* $NetBSD: kern_lock.c,v 1.32 2000/06/10 18:44:43 sommerfeld Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -322,6 +322,21 @@
}
/*
+ * XXX XXX kludge around another kludge..
+ *
+ * vfs_shutdown() may be called from interrupt context, either as a result
+ * of a panic, or from the debugger. It proceeds to call
+ * sys_sync(&proc0, ...), pretending its running on behalf of proc0
+ *
+ * We would like to make an attempt to sync the filesystems in this case, so
+ * if this happens, we treat attempts to acquire locks specially.
+ * All locks are acquired on behalf of proc0.
+ *
+ * If we've already paniced, we don't block waiting for locks, but
+ * just barge right ahead since we're already going down in flames.
+ */
+
+/*
* Set, change, or release a lock.
*
* Shared requests increment the shared count. Exclusive requests set the
@@ -339,6 +354,7 @@
int extflags;
cpuid_t cpu_id;
struct proc *p = curproc;
+ int lock_shutdown_noblock = 0;
error = 0;
@@ -359,10 +375,19 @@
if (extflags & LK_SPIN)
pid = LK_KERNPROC;
else {
-#ifdef DIAGNOSTIC /* { */
- if (p == NULL)
- panic("lockmgr: no context");
-#endif /* } */
+ if (p == NULL) {
+ if (!doing_shutdown) {
+#ifdef DIAGNOSTIC
+ panic("lockmgr: no context");
+#endif
+ } else {
+ p = &proc0;
+ if (panicstr && (!(flags & LK_NOWAIT))) {
+ flags |= LK_NOWAIT;
+ lock_shutdown_noblock = 1;
+ }
+ }
+ }
pid = p->p_pid;
}
cpu_id = cpu_number();
@@ -637,6 +662,13 @@
lkp->lk_flags &= ~LK_WAITDRAIN;
wakeup_one((void *)&lkp->lk_flags);
}
+ /*
+ * Note that this panic will be a recursive panic, since
+ * we only set lock_shutdown_noblock above if panicstr != NULL.
+ */
+ if (error && lock_shutdown_noblock)
+ panic("lockmgr: deadlock (see previous panic)");
+
simple_unlock(&lkp->lk_interlock);
return (error);
}
diff -r 22e1e7eed846 -r dfcc55d33e76 sys/kern/kern_synch.c
--- a/sys/kern/kern_synch.c Sat Jun 10 18:31:11 2000 +0000
+++ b/sys/kern/kern_synch.c Sat Jun 10 18:44:43 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_synch.c,v 1.77 2000/06/08 05:50:37 thorpej Exp $ */
+/* $NetBSD: kern_synch.c,v 1.78 2000/06/10 18:44:44 sommerfeld Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -355,15 +355,18 @@
int catch = priority & PCATCH;
int relock = (priority & PNORELOCK) == 0;
#if 0 /* XXXSMP */
- int dobiglock = (p->p_flags & P_BIGLOCK) != 0;
+ int dobiglock;
#endif
/*
* XXXSMP
* This is probably bogus. Figure out what the right
* thing to do here really is.
+ * Note that not sleeping if ltsleep is called with curproc == NULL
+ * in the shutdown case is disgusting but partly necessary given
+ * how shutdown (barely) works.
*/
- if (cold || panicstr) {
+ if (cold || (doing_shutdown && (panicstr || (p == NULL)))) {
/*
* After a panic, or during autoconfiguration,
* just give interrupts a chance, then just return;
@@ -378,6 +381,10 @@
return (0);
}
+#if 0 /* XXXSMP */
+ dobiglock = (p->p_flags & P_BIGLOCK) != 0;
+#endif
+
#ifdef KTRACE
if (KTRPOINT(p, KTR_CSW))
ktrcsw(p, 1, 0);
diff -r 22e1e7eed846 -r dfcc55d33e76 sys/kern/subr_pool.c
--- a/sys/kern/subr_pool.c Sat Jun 10 18:31:11 2000 +0000
+++ b/sys/kern/subr_pool.c Sat Jun 10 18:44:43 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_pool.c,v 1.36 2000/05/31 15:29:42 pk Exp $ */
+/* $NetBSD: subr_pool.c,v 1.37 2000/06/10 18:44:44 sommerfeld Exp $ */
/*-
* Copyright (c) 1997, 1999 The NetBSD Foundation, Inc.
@@ -594,7 +594,8 @@
}
#endif
- if (__predict_false(curproc == NULL && (flags & PR_WAITOK) != 0))
+ if (__predict_false(curproc == NULL && doing_shutdown == 0 &&
+ (flags & PR_WAITOK) != 0))
panic("pool_get: must have NOWAIT");
simple_lock(&pp->pr_slock);
diff -r 22e1e7eed846 -r dfcc55d33e76 sys/kern/subr_prf.c
--- a/sys/kern/subr_prf.c Sat Jun 10 18:31:11 2000 +0000
+++ b/sys/kern/subr_prf.c Sat Jun 10 18:44:43 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_prf.c,v 1.73 2000/05/29 23:10:03 jhawk Exp $ */
+/* $NetBSD: subr_prf.c,v 1.74 2000/06/10 18:44:44 sommerfeld Exp $ */
/*-
* Copyright (c) 1986, 1988, 1991, 1993
@@ -146,6 +146,7 @@
extern int log_open; /* subr_log: is /dev/klog open? */
const char *panicstr; /* arg to first call to panic (used as a flag
to indicate that panic has already been called). */
+int doing_shutdown; /* set to indicate shutdown in progress */
/*
* v_putc: routine to putc on virtual console
@@ -193,11 +194,12 @@
va_list ap;
bootopt = RB_AUTOBOOT | RB_DUMP;
- if (panicstr)
+ if (doing_shutdown)
bootopt |= RB_NOSYNC;
- else
+ if (!panicstr)
panicstr = fmt;
-
+ doing_shutdown = 1;
+
va_start(ap, fmt);
printf("panic: ");
vprintf(fmt, ap);
diff -r 22e1e7eed846 -r dfcc55d33e76 sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c Sat Jun 10 18:31:11 2000 +0000
+++ b/sys/kern/vfs_subr.c Sat Jun 10 18:44:43 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_subr.c,v 1.127 2000/06/10 18:27:01 assar Exp $ */
+/* $NetBSD: vfs_subr.c,v 1.128 2000/06/10 18:44:44 sommerfeld Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -2290,23 +2290,11 @@
* will avoid needing to worry about dependencies.
*/
void
-vfs_unmountall()
+vfs_unmountall(p)
+ struct proc *p;
{
struct mount *mp, *nmp;
int allerror, error;
- struct proc *p = curproc; /* XXX */
-
- /*
- * Unmounting a file system blocks the requesting process.
- * However, it's possible for this routine to be called when
- * curproc is NULL (e.g. panic situation, or via the debugger).
- * If we get stuck in this situation, just abort, since any
- * attempts to sleep will fault.
- */
- if (p == NULL) {
- printf("vfs_unmountall: no context, aborting\n");
- return;
- }
for (allerror = 0,
mp = mountlist.cqh_last; mp != (void *)&mountlist; mp = nmp) {
@@ -2335,13 +2323,21 @@
{
struct buf *bp;
int iter, nbusy, dcount, s;
+ struct proc *p = curproc;
+ /* XXX we're certainly not running in proc0's context! */
+ if (p == NULL)
+ p = &proc0;
+
printf("syncing disks... ");
/* XXX Should suspend scheduling. */
(void) spl0();
- sys_sync(&proc0, (void *)0, (register_t *)0);
+ /* avoid coming back this way again if we panic. */
+ doing_shutdown = 1;
+
+ sys_sync(p, (void *)0, (register_t *)0);
/* Wait for sync to finish. */
dcount = 10000;
@@ -2406,7 +2402,7 @@
vnshutdown();
#endif
/* Unmount file systems. */
- vfs_unmountall();
+ vfs_unmountall(p);
}
/*
diff -r 22e1e7eed846 -r dfcc55d33e76 sys/sys/mount.h
--- a/sys/sys/mount.h Sat Jun 10 18:31:11 2000 +0000
+++ b/sys/sys/mount.h Sat Jun 10 18:44:43 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mount.h,v 1.84 2000/06/10 18:27:04 assar Exp $ */
+/* $NetBSD: mount.h,v 1.85 2000/06/10 18:44:44 sommerfeld Exp $ */
/*
* Copyright (c) 1989, 1991, 1993
@@ -422,7 +422,7 @@
int vfs_mountroot __P((void));
void vfs_shutdown __P((void)); /* unmount and sync file systems */
void vfs_unlock __P((struct mount *)); /* unlock a vfs */
-void vfs_unmountall __P((void)); /* unmount file systems */
+void vfs_unmountall __P((struct proc *)); /* unmount file systems */
int vfs_busy __P((struct mount *, int, struct simplelock *));
int vfs_rootmountalloc __P((char *, char *, struct mount **));
void vfs_unbusy __P((struct mount *));
diff -r 22e1e7eed846 -r dfcc55d33e76 sys/sys/systm.h
--- a/sys/sys/systm.h Sat Jun 10 18:31:11 2000 +0000
+++ b/sys/sys/systm.h Sat Jun 10 18:44:43 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: systm.h,v 1.110 2000/05/28 05:49:06 thorpej Exp $ */
+/* $NetBSD: systm.h,v 1.111 2000/06/10 18:44:45 sommerfeld Exp $ */
/*-
* Copyright (c) 1982, 1988, 1991, 1993
@@ -87,6 +87,7 @@
extern int securelevel; /* system security level */
extern const char *panicstr; /* panic message */
+extern int doing_shutdown; /* shutting down */
extern char copyright[]; /* system copyright */
extern char cpu_model[]; /* machine/cpu model name */
Home |
Main Index |
Thread Index |
Old Index