viced: avoid useless core if shutdown during initialization
authorMichael Meffie <mmeffie@sinenomine.net>
Thu, 5 Nov 2009 16:08:08 +0000 (11:08 -0500)
committerDerrick Brashear <shadow|account-1000005@unknown>
Mon, 9 Nov 2009 14:16:59 +0000 (06:16 -0800)
Avoid leaving an unnecessary core file when the fileserver is
shutdown while still attaching volumes.  The bosserver issues
SIQUIT to shutdown the fileserver which leaves a core file by
default.

Register the fileserver shutdown signal handler earlier in the
fileserver initialization, before the long running volume
attachment is started. The volume package shutdown has been
changed to allow the VShutdown to gracefully abort the volume
attachment (or pre-attachment for DAFS).

FIXES 124485

Change-Id: Ic22e68afb7bcc54ad956b2ae093375f29b969191
Reviewed-on: http://gerrit.openafs.org/764
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/viced/viced.c
src/vol/volume.c
src/vol/volume.h

index e166657..9d3eef8 100644 (file)
@@ -1971,6 +1971,9 @@ main(int argc, char *argv[])
 #endif
 #endif
     assert(DInit(buffs) == 0);
+#ifdef AFS_DEMAND_ATTACH_FS
+    FS_STATE_INIT;
+#endif
 
 #ifdef AFS_NT40_ENV
     if (afs_winsockInit() < 0) {
@@ -2188,6 +2191,22 @@ main(int argc, char *argv[])
        exit(1);
     }
 
+    /* Install handler to catch the shutdown signal;
+     * bosserver assumes SIGQUIT shutdown
+     */
+#if defined(AFS_PTHREAD_ENV) && !defined(AFS_NT40_ENV)
+    softsig_signal(SIGQUIT, ShutDown_Signal);
+#else
+    (void)signal(SIGQUIT, ShutDown_Signal);
+#endif
+
+    if (VInitAttachVolumes(fileServer)) {
+       ViceLog(0,
+               ("Shutting down: errors encountered initializing volume package\n"));
+       VShutdown();
+       exit(1);
+    }
+
 #ifdef AFS_DEMAND_ATTACH_FS
     if (fs_state.options.fs_state_restore) {
        /*
@@ -2206,9 +2225,6 @@ main(int argc, char *argv[])
 
 #ifdef AFS_PTHREAD_ENV
     ViceLog(5, ("Starting pthreads\n"));
-#ifdef AFS_DEMAND_ATTACH_FS
-    FS_STATE_INIT;
-#endif
     assert(pthread_attr_init(&tattr) == 0);
     assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
 
@@ -2268,15 +2284,6 @@ main(int argc, char *argv[])
                 FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
     }
 
-    /* Install handler to catch the shutdown signal;
-     * bosserver assumes SIGQUIT shutdown
-     */
-#if defined(AFS_PTHREAD_ENV) && !defined(AFS_NT40_ENV)
-    softsig_signal(SIGQUIT, ShutDown_Signal);
-#else
-    (void)signal(SIGQUIT, ShutDown_Signal);
-#endif
-
     t = tp.tv_sec;
     ViceLog(0,
            ("File Server started %s",
index 4c4f007..10a8d31 100644 (file)
@@ -152,6 +152,7 @@ pthread_mutex_t vol_glock_mutex;
 pthread_mutex_t vol_trans_mutex;
 pthread_cond_t vol_put_volume_cond;
 pthread_cond_t vol_sleep_cond;
+pthread_cond_t vol_init_attach_cond;
 int vol_attach_threads = 1;
 #endif /* AFS_PTHREAD_ENV */
 
@@ -419,6 +420,7 @@ int VInit;                  /* 0 - uninitialized,
                                 * 3 - initialized, all volumes have been attached, and
                                 * VConnectFS() has completed. */
 
+static int vinit_attach_abort = 0;
 
 bit32 VolumeCacheCheck;                /* Incremented everytime a volume goes on line--
                                 * used to stamp volume headers and in-core
@@ -462,6 +464,7 @@ VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes, afs_uint32 nSmallVno
     assert(pthread_mutex_init(&vol_trans_mutex, NULL) == 0);
     assert(pthread_cond_init(&vol_put_volume_cond, NULL) == 0);
     assert(pthread_cond_init(&vol_sleep_cond, NULL) == 0);
+    assert(pthread_cond_init(&vol_init_attach_cond, NULL) == 0);
 #else /* AFS_PTHREAD_ENV */
     IOMGR_Initialize();
 #endif /* AFS_PTHREAD_ENV */
@@ -510,7 +513,37 @@ VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes, afs_uint32 nSmallVno
     if (errors)
        return -1;
 
-    if (programType == fileServer) {
+    if (programType != fileServer) {
+        errors = VInitAttachVolumes(programType);
+        if (errors) {
+            return -1;
+        }
+    }
+
+#ifdef FSSYNC_BUILD_CLIENT
+    if (programType == volumeUtility && connect) {
+       if (!VConnectFS()) {
+           Log("Unable to connect to file server; will retry at need\n");
+           /*exit(1);*/
+       }
+    }
+#ifdef AFS_DEMAND_ATTACH_FS
+    else if (programType == salvageServer) {
+       if (!VConnectFS()) {
+           Log("Unable to connect to file server; aborted\n");
+           exit(1);
+       }
+    }
+#endif /* AFS_DEMAND_ATTACH_FS */
+#endif /* FSSYNC_BUILD_CLIENT */
+    return 0;
+}
+
+int
+VInitAttachVolumes(ProgramType pt)
+{
+    assert(VInit==1);
+    if (pt == fileServer) {
        struct DiskPartition64 *diskP;
 #ifdef AFS_PTHREAD_ENV
        struct vinitvolumepackage_thread_t params;
@@ -549,9 +582,12 @@ VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes, afs_uint32 nSmallVno
 
            VOL_LOCK;
            for (i=0; i < threads; i++) {
+                AFS_SIGSET_DECL;
+                AFS_SIGSET_CLEAR();
                assert(pthread_create
                       (&tid, &attrs, &VInitVolumePackageThread,
                        &params) == 0);
+                AFS_SIGSET_RESTORE();
            }
 
            while(params.n_threads_complete < threads) {
@@ -586,24 +622,14 @@ VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes, afs_uint32 nSmallVno
        }
 #endif /* AFS_PTHREAD_ENV */
     }
-
+    VOL_LOCK;
     VInit = 2;                 /* Initialized, and all volumes have been attached */
-#ifdef FSSYNC_BUILD_CLIENT
-    if (programType == volumeUtility && connect) {
-       if (!VConnectFS()) {
-           Log("Unable to connect to file server; will retry at need\n");
-           /*exit(1);*/
-       }
-    }
-#ifdef AFS_DEMAND_ATTACH_FS
-    else if (programType == salvageServer) {
-       if (!VConnectFS()) {
-           Log("Unable to connect to file server; aborted\n");
-           exit(1);
-       }
-    }
-#endif /* AFS_DEMAND_ATTACH_FS */
-#endif /* FSSYNC_BUILD_CLIENT */
+#ifdef AFS_PTHREAD_ENV
+    assert(pthread_cond_broadcast(&vol_init_attach_cond) == 0);
+#else
+    LWP_NoYieldSignal(VInitAttachVolumes);
+#endif /* AFS_PTHREAD_ENV */
+    VOL_UNLOCK;
     return 0;
 }
 
@@ -623,6 +649,11 @@ VInitVolumePackageThread(void * args) {
     while (queue_IsNotEmpty(params)) {
         int nAttached = 0, nUnattached = 0;
 
+        if (vinit_attach_abort) {
+            Log("Aborting initialization\n");
+            goto done;
+        }
+
         dpq = queue_First(params,diskpartition_queue_t);
        queue_Remove(dpq);
        VOL_UNLOCK;
@@ -634,6 +665,7 @@ VInitVolumePackageThread(void * args) {
        VOL_LOCK;
     }
 
+done:
     params->n_threads_complete++;
     pthread_cond_signal(&params->thread_done_cv);
     VOL_UNLOCK;
@@ -661,6 +693,12 @@ VAttachVolumesByPartition(struct DiskPartition64 *diskP, int * nAttached, int *
   while ((dp = readdir(dirp))) {
     char *p;
     p = strrchr(dp->d_name, '.');
+
+    if (vinit_attach_abort) {
+      Log("Partition %s: abort attach volumes\n", diskP->name);
+      goto done;
+    }
+
     if (p != NULL && strcmp(p, VHDREXT) == 0) {
       Error error;
       Volume *vp;
@@ -687,6 +725,7 @@ VAttachVolumesByPartition(struct DiskPartition64 *diskP, int * nAttached, int *
   }
 
   Log("Partition %s: attached %d volumes; %d volumes not attached\n", diskP->name, *nAttached, *nUnattached);
+done:
   closedir(dirp);
   return ret;
 }
@@ -763,6 +802,12 @@ VShutdown_r(void)
 
     memset(&params, 0, sizeof(vshutdown_thread_t));
 
+    if (VInit < 2) {
+        Log("VShutdown:  aborting attach volumes\n");
+        vinit_attach_abort = 1;
+        VOL_CV_WAIT(&vol_init_attach_cond);
+    }
+
     for (params.n_parts=0, diskP = DiskPartitionList;
         diskP; diskP = diskP->next, params.n_parts++);
 
@@ -879,6 +924,17 @@ VShutdown_r(void)
     int i;
     register Volume *vp, *np;
     register afs_int32 code;
+
+    if (VInit < 2) {
+        Log("VShutdown:  aborting attach volumes\n");
+        vinit_attach_abort = 1;
+#ifdef AFS_PTHREAD_ENV
+        VOL_CV_WAIT(&vol_init_attach_cond);
+#else
+        LWP_WaitProcess(VInitAttachVolumes);
+#endif /* AFS_PTHREAD_ENV */
+    }
+
     Log("VShutdown:  shutting down on-line volumes...\n");
     for (i = 0; i < VolumeHashTable.Size; i++) {
        /* try to hold first volume in the hash table */
@@ -902,6 +958,7 @@ VShutdown_r(void)
 void
 VShutdown(void)
 {
+    assert(VInit>0);
     VOL_LOCK;
     VShutdown_r();
     VOL_UNLOCK;
index d1d4d54..42741c3 100644 (file)
@@ -782,6 +782,7 @@ extern struct DiskPartition64 *VGetPartition(char *name, int abortp);
 extern struct DiskPartition64 *VGetPartition_r(char *name, int abortp);
 extern int VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes,
                              afs_uint32 nSmallVnodes, int connect, afs_uint32 volcache);
+extern int VInitAttachVolumes(ProgramType pt);
 extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
 extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
 extern void AssignVolumeName(VolumeDiskData * vol, char *name, char *ext);