From: Andrew Deason Date: Mon, 22 Feb 2010 17:56:07 +0000 (-0600) Subject: Prevent deadlock if fs_stateSave panics X-Git-Tag: openafs-devel-1_5_73~149 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=1e744d5e56106093924869924fffde3a9093d140;p=packages%2Fo%2Fopenafs.git Prevent deadlock if fs_stateSave panics fs_stateSave can call ShutDownAndCore(PANIC) if it detects host list corruption. Right now this will deadlock the shutdown thread, since we're still holding a read lock on the FS state when we do so, and ShutDownAndCore will attempt to acquire a write lock. Do two things to make this a bit better: -- Unlock the FS state before calling fs_stateSave, sine we're no longer looking at the FS state (the 'state' in fs_stateSave refers to the host list and callback lists, not the state locked by FS_STATE_*LOCK) -- If ShutDownAndCore detects that it was called inside of ShutDownAndCore, skip shutting down the volume and host packages, since they have already been shut down Change-Id: I24a994ff85a6d866a5800b777c0cf5ab2ba466e4 Reviewed-on: http://gerrit.openafs.org/1362 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- diff --git a/src/viced/viced.c b/src/viced/viced.c index 4874a6fa5..1cb55848f 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -802,6 +802,15 @@ ShutDownAndCore(int dopanic) #ifdef AFS_DEMAND_ATTACH_FS FS_STATE_WRLOCK; + if (fs_state.mode == FS_MODE_SHUTDOWN) { + /* it is possible for at least fs_stateSave() (called below) to call + * ShutDownAndCore if there's host list corruption; prevent + * deinitializing some stuff twice */ + ViceLog(0, ("ShutDownAndCore called during shutdown? Skipping volume " + "and host package shutdown\n")); + FS_STATE_UNLOCK; + goto done_vol_host; + } fs_state.mode = FS_MODE_SHUTDOWN; FS_STATE_UNLOCK; #endif @@ -847,11 +856,14 @@ ShutDownAndCore(int dopanic) FS_UNLOCK; FS_STATE_RDLOCK; } + FS_STATE_UNLOCK; /* ok. it should now be fairly safe. let's do the state dump */ fs_stateSave(); } } + done_vol_host: + #endif /* AFS_DEMAND_ATTACH_FS */ if (debugFile) {