afs: Avoid panics on failed return from afs_CFileOpen
[openafs.git] / src / afs / afs_init.c
index bc55c25..5d72319 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
@@ -32,7 +32,7 @@
 /* Exported variables */
 struct osi_dev cacheDev;       /*Cache device */
 afs_int32 cacheInfoModTime;    /*Last time cache info modified */
-#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_NBSD_ENV)
 struct mount *afs_cacheVfsp = 0;
 #elif defined(AFS_LINUX20_ENV)
 struct super_block *afs_cacheSBp = 0;
@@ -57,9 +57,7 @@ const struct cred *cache_creds;
 #endif
 
 /* This is the kernel side of the dynamic vcache setting */
-#ifdef AFS_MAXVCOUNT_ENV
 int afsd_dynamic_vcaches = 0;  /* Enable dynamic-vcache support */
-#endif
 
 /*
  * Initialization order is important.  Must first call afs_CacheInit,
@@ -101,6 +99,7 @@ afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks,
              afs_int32 dynamic_vcaches)
 {
     afs_int32 i;
+    int code;
     struct volume *tv;
 
     AFS_STATCNT(afs_CacheInit);
@@ -135,15 +134,16 @@ afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks,
     QInit(&afs_disconShadow);
     osi_dnlc_init();
 
-    /* 
-     * create volume list structure 
+    /*
+     * create volume list structure
      */
     if (aVolumes < 50)
        aVolumes = 50;
     else if (aVolumes > 32767)
        aVolumes = 32767;
 
-    tv = (struct volume *)afs_osi_Alloc(aVolumes * sizeof(struct volume));
+    tv = afs_osi_Alloc(aVolumes * sizeof(struct volume));
+    osi_Assert(tv != NULL);
     for (i = 0; i < aVolumes - 1; i++)
        tv[i].next = &tv[i + 1];
     tv[aVolumes - 1].next = NULL;
@@ -153,7 +153,10 @@ afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks,
     afs_cacheFiles = afiles;
     afs_cacheStats = astatSize;
     afs_vcacheInit(astatSize);
-    afs_dcacheInit(afiles, ablocks, aDentries, achunk, aflags);
+    code = afs_dcacheInit(afiles, ablocks, aDentries, achunk, aflags);
+    if (code) {
+        return code;
+    }
 #if defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED)
     /*
      * Save current credentials for later access to disk cache files.
@@ -187,7 +190,7 @@ afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks,
     cm_initParams.cmi_firstChunkSize = AFS_FIRSTCSIZE;
     cm_initParams.cmi_otherChunkSize = AFS_OTHERCSIZE;
     cm_initParams.cmi_cacheSize = afs_cacheBlocks;
-    cm_initParams.cmi_setTime = afs_setTime;
+    cm_initParams.cmi_setTime = 0;
     cm_initParams.cmi_memCache = (aflags & AFSCALL_INIT_MEMCACHE) ? 1 : 0;
 
     return 0;
@@ -282,7 +285,7 @@ afs_InitCellInfo(char *afile)
 {
     afs_dcache_id_t inode;
     int code = 0;
-    
+
     code = afs_LookupInodeByPath(afile, &inode.ufs, NULL);
     return afs_cellname_init(&inode, code);
 }
@@ -331,11 +334,25 @@ afs_InitVolumeInfo(char *afile)
     if (code)
        return code;
     tfile = afs_CFileOpen(&volumeInode);
+    if (!tfile) {
+       return EIO;
+    }
     afs_CFileTruncate(tfile, 0);
     afs_CFileClose(tfile);
     return 0;
 }
 
+void
+afs_InitFHeader(struct afs_fheader *aheader)
+{
+    memset(aheader, 0, sizeof(*aheader));
+    aheader->magic = AFS_FHMAGIC;
+    aheader->version = AFS_CI_VERSION;
+    aheader->dataSize = sizeof(struct fcache);
+    aheader->firstCSize = AFS_FIRSTCSIZE;
+    aheader->otherCSize = AFS_OTHERCSIZE;
+}
+
 /*
  * afs_InitCacheInfo
  *
@@ -345,12 +362,12 @@ afs_InitVolumeInfo(char *afile)
  * Parameters:
  *     afile : Name of the file assumed to be the cache info file
  *             for the Cache Manager; it will be used as such.
- * Side Effects:  This sets afs_fragsize, which is used in the cache usage 
+ * Side Effects:  This sets afs_fragsize, which is used in the cache usage
  *                calculations such as in afs_adjustsize()
  *
  * Environment:
  *     This function is called only during initialization.  The given
- *     file should NOT be truncated to 0 lenght; its contents descrebe
+ *     file should NOT be truncated to 0 length; its contents describe
  *     what data is really in the cache.
  *
  *     WARNING: data will be written to this file over time by AFS.
@@ -383,17 +400,17 @@ afs_InitCacheInfo(char *afile)
     if (code || !filevp)
        return ENOENT;
     {
-#if    defined(AFS_SUN56_ENV)
+#if    defined(AFS_SUN5_ENV)
        struct statvfs64 st;
 #elif  defined(AFS_HPUX102_ENV)
        struct k_statvfs st;
-#elif  defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_HPUX100_ENV) || defined(AFS_NBSD40_ENV)
+#elif  defined(AFS_SGI_ENV) || defined(AFS_HPUX100_ENV) || defined(AFS_NBSD40_ENV)
        struct statvfs st;
 #elif defined(AFS_DARWIN80_ENV)
        struct vfsstatfs st;
 #else
        struct statfs st;
-#endif /* SUN56 */
+#endif /* SUN5 */
 
 #if    defined(AFS_SGI_ENV)
 #ifdef AFS_SGI65_ENV
@@ -417,8 +434,10 @@ afs_InitCacheInfo(char *afile)
 #elif defined(AFS_DARWIN80_ENV)
         afs_cacheVfsp = vnode_mount(filevp);
        if (afs_cacheVfsp && ((st = *(vfs_statfs(afs_cacheVfsp))),1))
-#elif defined(AFS_FBSD80_ENV)
+#elif defined(AFS_FBSD_ENV)
        if (!VFS_STATFS(filevp->v_mount, &st))
+#elif defined(AFS_NBSD50_ENV)
+       if (!VFS_STATVFS(filevp->v_vfsp, &st))
 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
        if (!VFS_STATFS(filevp->v_mount, &st, osi_curproc()))
 #else
@@ -471,6 +490,9 @@ afs_InitCacheInfo(char *afile)
        afs_fsfragsize = AFS_MIN_FRAGSIZE;
     }
     tfile = osi_UFSOpen(&cacheInode);
+    if (!tfile)
+       return ENOENT;
+
     afs_osi_Stat(tfile, &tstat);
     cacheInfoModTime = tstat.mtime;
     code = afs_osi_Read(tfile, -1, &theader, sizeof(theader));
@@ -486,11 +508,7 @@ afs_InitCacheInfo(char *afile)
     }
     if (!goodFile) {
        /* write out a good file label */
-       theader.magic = AFS_FHMAGIC;
-       theader.firstCSize = AFS_FIRSTCSIZE;
-       theader.otherCSize = AFS_OTHERCSIZE;
-       theader.dataSize = sizeof(struct fcache);
-       theader.version = AFS_CI_VERSION;
+       afs_InitFHeader(&theader);
        afs_osi_Write(tfile, 0, &theader, sizeof(theader));
        /*
         * Truncate the rest of the file, since it may be arbitrarily
@@ -522,7 +540,7 @@ afs_ResourceInit(int preallocs)
     AFS_RWLOCK_INIT(&afs_icl_lock, "afs_icl_lock");
     AFS_RWLOCK_INIT(&afs_xinterface, "afs_xinterface");
     LOCK_INIT(&afs_puttofileLock, "afs_puttofileLock");
-#ifndef AFS_FBSD_ENV
+#ifndef AFS_PRIVATE_OSI_ALLOCSPACES
     LOCK_INIT(&osi_fsplock, "osi_fsplock");
     LOCK_INIT(&osi_flplock, "osi_flplock");
 #endif
@@ -535,8 +553,10 @@ afs_ResourceInit(int preallocs)
        afs_resourceinit_flag = 1;
        for (i = 0; i < NFENTRIES; i++)
            fvTable[i] = 0;
-       for (i = 0; i < MAXNUMSYSNAMES; i++)
+       for (i = 0; i < MAXNUMSYSNAMES; i++) {
            afs_sysnamelist[i] = afs_osi_Alloc(MAXSYSNAME);
+           osi_Assert(afs_sysnamelist[i] != NULL);
+       }
        afs_sysname = afs_sysnamelist[0];
        strcpy(afs_sysname, SYS_NAME);
        afs_sysnamecount = 1;
@@ -679,7 +699,7 @@ void
 shutdown_cache(void)
 {
     AFS_STATCNT(shutdown_cache);
-    afs_WriteThroughDSlots();
+    osi_Assert(afs_WriteThroughDSlots() == 0);
     if (1/*afs_cold_shutdown*/) {
        afs_cacheinit_flag = 0;
        shutdown_dcache();
@@ -723,22 +743,11 @@ shutdown_cache(void)
 void
 shutdown_vnodeops(void)
 {
-#if !defined(AFS_SGI_ENV) && !defined(AFS_SUN5_ENV)
-    struct buf *afs_bread_freebp = 0;
-#endif
-
-
     AFS_STATCNT(shutdown_vnodeops);
     if (afs_cold_shutdown) {
-#ifndef        AFS_SUN5_ENV            /* XXX */
-       lastWarnTime = 0;
-#endif
 #ifndef AFS_LINUX20_ENV
        afs_rd_stash_i = 0;
 #endif
-#if !defined(AFS_SGI_ENV) && !defined(AFS_SUN5_ENV)
-       afs_bread_freebp = 0;
-#endif
        shutdown_mariner();
     }
 }
@@ -748,7 +757,6 @@ static void
 shutdown_server(void)
 {
     int i;
-    struct afs_conn *tc, *ntc;
     struct afs_cbr *tcbrp, *tbrp;
     struct srvAddr *sa;
 
@@ -760,22 +768,11 @@ shutdown_server(void)
            next = ts->next;
            for (sa = ts->addr; sa; sa = sa->next_sa) {
                if (sa->conns) {
-                   /*
-                    * Free all server's connection structs
-                    */
-                   tc = sa->conns;
-                   while (tc) {
-                       ntc = tc->next;
-#if 0
-                       /* we should destroy all connections
-                          when shutting down Rx, not here */
-                       AFS_GUNLOCK();
-                       rx_DestroyConnection(tc->id);
-                       AFS_GLOCK();
-#endif
-                       afs_osi_Free(tc, sizeof(struct afs_conn));
-                       tc = ntc;
-                   }
+                    /* afs_ReleaseConns has been updated to
+                     * defer rx_DestroyConnection to Rx
+                     * shutdown, as most recently was done
+                     * here */
+                    afs_ReleaseConns(sa->conns);
                }
            }
            for (tcbrp = ts->cbrs; tcbrp; tcbrp = tbrp) {
@@ -825,63 +822,67 @@ shutdown_AFS(void)
     int i;
 
     AFS_STATCNT(shutdown_AFS);
-    if (afs_cold_shutdown) {
-       afs_resourceinit_flag = 0;
 
-       shutdown_volume();
+    afs_resourceinit_flag = 0;
 
-       /* 
-        * Free FreeVolList allocations 
-        */
-       afs_osi_Free(Initialafs_freeVolList,
-                    afs_memvolumes * sizeof(struct volume));
-       afs_freeVolList = Initialafs_freeVolList = 0;
-
-       /* XXX HACK for MEM systems XXX
-        *
-        * For -memcache cache managers when we run out of free in memory volumes
-        * we simply malloc more; we won't be able to free those additional volumes.
-        */
+    shutdown_volume();
 
-       /* 
-        * Free Users table allocation 
-        */
-       {
-           struct unixuser *tu, *ntu;
-           for (i = 0; i < NUSERS; i++) {
-               for (tu = afs_users[i]; tu; tu = ntu) {
-                   ntu = tu->next;
-                   if (tu->stp)
-                       afs_osi_Free(tu->stp, tu->stLen);
-                   if (tu->exporter)
-                       EXP_RELE(tu->exporter);
-                   afs_osi_Free(tu, sizeof(struct unixuser));
-               }
-               afs_users[i] = 0;
+    /*
+     * Free FreeVolList allocations
+     */
+    afs_osi_Free(Initialafs_freeVolList,
+                afs_memvolumes * sizeof(struct volume));
+    afs_freeVolList = Initialafs_freeVolList = NULL;
+
+    /* XXX HACK for MEM systems XXX
+     *
+     * For -memcache cache managers when we run out of free in memory volumes
+     * we simply malloc more; we won't be able to free those additional volumes.
+     */
+
+    /*
+     * Free Users table allocation
+     */
+    {
+       struct unixuser *tu, *ntu;
+       for (i = 0; i < NUSERS; i++) {
+           for (tu = afs_users[i]; tu; tu = ntu) {
+               ntu = tu->next;
+               if (tu->tokens)
+                   afs_FreeTokens(&tu->tokens);
+               if (tu->exporter)
+                   EXP_RELE(tu->exporter);
+               afs_osi_Free(tu, sizeof(struct unixuser));
            }
+           afs_users[i] = NULL;
        }
+    }
 
-       for (i = 0; i < NFENTRIES; i++)
-           fvTable[i] = 0;
-       /* Reinitialize local globals to defaults */
-       for (i = 0; i < MAXNUMSYSNAMES; i++)
-           afs_osi_Free(afs_sysnamelist[i], MAXSYSNAME);
-       afs_sysname = 0;
-       afs_sysnamecount = 0;
-       afs_marinerHost = 0;
-       afs_setTimeHost = NULL;
-       afs_volCounter = 1;
-       afs_waitForever = afs_waitForeverCount = 0;
-       afs_FVIndex = -1;
-       afs_server = (struct rx_service *)0;
+    for (i = 0; i < NFENTRIES; i++)
+       fvTable[i] = 0;
+    /* Reinitialize local globals to defaults */
+    for (i = 0; i < MAXNUMSYSNAMES; i++) {
+       afs_osi_Free(afs_sysnamelist[i], MAXSYSNAME);
+       afs_sysnamelist[i] = NULL;
+    }
+    afs_sysname = NULL;
+    afs_sysnamecount = 0;
+    afs_marinerHost = 0;
+    afs_volCounter = 1;
+    afs_waitForever = afs_waitForeverCount = 0;
+    afs_FVIndex = -1;
+    afs_server = NULL;
+
+    if (afs_cold_shutdown) {
        AFS_RWLOCK_INIT(&afs_xconn, "afs_xconn");
        memset(&afs_rootFid, 0, sizeof(struct VenusFid));
        AFS_RWLOCK_INIT(&afs_xuser, "afs_xuser");
        AFS_RWLOCK_INIT(&afs_xvolume, "afs_xvolume");
        AFS_RWLOCK_INIT(&afs_xserver, "afs_xserver");
        LOCK_INIT(&afs_puttofileLock, "afs_puttofileLock");
-
-       shutdown_cell();
-       shutdown_server();
     }
+    shutdown_cell();
+    shutdown_server();
+    shutdown_rx();
+    shutdown_rxevent();
 }