salvager: redd up showlog global flag
[openafs.git] / src / vol / vol-salvage.c
index 659fb99..4a7b2eb 100644 (file)
@@ -281,15 +281,17 @@ char *tmpdir = NULL;
 
 
 /* Forward declarations */
+static void QuietExit(int) AFS_NORETURN;
+static void SalvageShowLog(void);
 static int IsVnodeOrphaned(struct SalvInfo *salvinfo, VnodeId vnode);
 static int AskVolumeSummary(struct SalvInfo *salvinfo,
                             VolumeId singleVolumeNumber);
 static void MaybeAskOnline(struct SalvInfo *salvinfo, VolumeId volumeId);
 static void AskError(struct SalvInfo *salvinfo, VolumeId volumeId);
 
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
 static int LockVolume(struct SalvInfo *salvinfo, VolumeId volumeId);
-#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
+#endif /* AFS_DEMAND_ATTACH_FS */
 
 /* Uniquifier stored in the Inode */
 static Unique
@@ -608,7 +610,7 @@ SalvageFileSysParallel(struct DiskPartition64 *partP)
            } else {
                int fd;
 
-               ShowLog = 0;
+               ShowLog = 0; /* Child processes do not display. */
                for (fd = 0; fd < 16; fd++)
                    close(fd);
                open(OS_DIRSEP, 0);
@@ -663,8 +665,7 @@ SalvageFileSys(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
     if (!canfork || debug || Fork() == 0) {
        SalvageFileSys1(partP, singleVolumeNumber);
        if (canfork && !debug) {
-           ShowLog = 0;
-           Exit(0);
+           QuietExit(0);
        }
     } else
        Wait("SalvageFileSys");
@@ -716,13 +717,13 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
        Abort("Raced too many times with fileserver restarts while trying to "
              "checkout/lock volumes; Aborted\n");
     }
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
     if (tries > 1) {
        /* unlock all previous volume locks, since we're about to lock them
         * again */
        VLockFileReinit(&partP->volLockFile);
     }
-#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
+#endif /* AFS_DEMAND_ATTACH_FS */
 
     salvinfo->fileSysPartition = partP;
     salvinfo->fileSysDevice = salvinfo->fileSysPartition->device;
@@ -741,11 +742,11 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
 #endif
 
     if (singleVolumeNumber) {
-#if !(defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL))
+#ifndef AFS_DEMAND_ATTACH_FS
        /* only non-DAFS locks the partition when salvaging a single volume;
         * DAFS will lock the individual volumes in the VG */
        VLockPartition(partP->name);
-#endif /* !(AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL) */
+#endif /* !AFS_DEMAND_ATTACH_FS */
 
        ForceSalvage = 1;
 
@@ -756,11 +757,11 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
 
        salvinfo->useFSYNC = 1;
        AskOffline(salvinfo, singleVolumeNumber);
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
        if (LockVolume(salvinfo, singleVolumeNumber)) {
            goto retry;
        }
-#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
+#endif /* AFS_DEMAND_ATTACH_FS */
 
     } else {
        salvinfo->useFSYNC = 0;
@@ -922,10 +923,10 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
 
     if (!Testing && singleVolumeNumber) {
        int foundSVN = 0;
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
        /* unlock vol headers so the fs can attach them when we AskOnline */
        VLockFileReinit(&salvinfo->fileSysPartition->volLockFile);
-#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
+#endif /* AFS_DEMAND_ATTACH_FS */
 
        /* Step through the volumeSummary list and set all volumes on-line.
         * Most volumes were taken off-line in GetVolumeSummary.
@@ -1304,8 +1305,7 @@ GetInodeSummary(struct SalvInfo *salvinfo, FD_t inodeFile, VolumeId singleVolume
            goto error;
        }
        if (canfork && !debug) {
-           ShowLog = 0;
-           Exit(0);
+           QuietExit(0);
        }
     } else {
        if (Wait("Inode summary") == -1) {
@@ -1635,7 +1635,7 @@ RecordHeader(struct DiskPartition64 *dp, const char *name,
 
                AskOffline(salvinfo, summary.header.id);
 
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
                if (!badname) {
                    /* don't lock the volume if the header is bad, since we're
                     * about to delete it anyway. */
@@ -1644,7 +1644,7 @@ RecordHeader(struct DiskPartition64 *dp, const char *name,
                        return -1;
                    }
                }
-#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
+#endif /* AFS_DEMAND_ATTACH_FS */
            }
        }
        if (badname) {
@@ -1801,10 +1801,11 @@ GetVolumeSummary(struct SalvInfo *salvinfo, VolumeId singleVolumeNumber)
     return 0;
 }
 
-/* Find the link table. This should be associated with the RW volume or, if
- * a RO only site, then the RO volume. For now, be cautious and hunt carefully.
+#ifdef AFS_NAMEI_ENV
+/* Find the link table. This should be associated with the RW volume, even
+ * if there is only an RO volume at this site.
  */
-Inode
+static Inode
 FindLinkHandle(struct InodeSummary *isp, int nVols,
               struct ViceInodeInfo *allInodes)
 {
@@ -1814,13 +1815,65 @@ FindLinkHandle(struct InodeSummary *isp, int nVols,
     for (i = 0; i < nVols; i++) {
        ip = allInodes + isp[i].index;
        for (j = 0; j < isp[i].nSpecialInodes; j++) {
-           if (ip[j].u.special.type == VI_LINKTABLE)
+           if (ip[j].u.special.volumeId == isp->RWvolumeId &&
+               ip[j].u.special.parentId == isp->RWvolumeId &&
+               ip[j].u.special.type == VI_LINKTABLE) {
                return ip[j].inodeNumber;
+           }
        }
     }
     return (Inode) - 1;
 }
 
+static int
+CheckDupLinktable(struct SalvInfo *salvinfo, struct InodeSummary *isp, struct ViceInodeInfo *ip)
+{
+    afs_ino_str_t stmp;
+    if (ip->u.vnode.vnodeNumber != INODESPECIAL) {
+       /* not a linktable; process as a normal file */
+       return 0;
+    }
+    if (ip->u.special.type != VI_LINKTABLE) {
+       /* not a linktable; process as a normal file */
+       return 0;
+    }
+
+    /* make sure nothing inc/decs it */
+    ip->linkCount = 0;
+
+    if (ip->u.special.volumeId == ip->u.special.parentId) {
+       /* This is a little weird, but shouldn't break anything, and there is
+        * no known way that this can happen; just do nothing, in case deleting
+        * it would screw something up. */
+       Log("Inode %s appears to be a valid linktable for id (%u), but it's not\n",
+           PrintInode(stmp, ip->inodeNumber), ip->u.special.parentId);
+       Log("the linktable for our volume group (%u). This is unusual, since\n",
+           isp->RWvolumeId);
+       Log("there should only be one linktable per volume group. I'm leaving\n");
+       Log("it alone, just to be safe.\n");
+       return -1;
+    }
+
+    Log("Linktable %s appears to be invalid (parentid/volumeid mismatch: %u != %u)\n",
+        PrintInode(stmp, ip->inodeNumber), ip->u.special.parentId, ip->u.special.volumeId);
+    if (Testing) {
+       Log("Would have deleted linktable inode %s\n", PrintInode(stmp, ip->inodeNumber));
+    } else {
+       IHandle_t *tmpH;
+       namei_t ufs_name;
+
+       Log("Deleting linktable inode %s\n", PrintInode(stmp, ip->inodeNumber));
+       IH_INIT(tmpH, salvinfo->fileSysDevice, isp->RWvolumeId, ip->inodeNumber);
+       namei_HandleToName(&ufs_name, tmpH);
+       if (unlink(ufs_name.n_path) < 0) {
+           Log("Error %d unlinking path %s\n", errno, ufs_name.n_path);
+       }
+    }
+
+    return -1;
+}
+#endif
+
 int
 CreateLinkTable(struct SalvInfo *salvinfo, struct InodeSummary *isp, Inode ino)
 {
@@ -1976,18 +2029,19 @@ DoSalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nV
        if (Testing) {
            IH_INIT(salvinfo->VGLinkH, salvinfo->fileSysDevice, -1, -1);
        } else {
-            int i, j;
-            struct ViceInodeInfo *ip;
+           int i, j;
+           struct ViceInodeInfo *ip;
            CreateLinkTable(salvinfo, isp, ino);
            fdP = IH_OPEN(salvinfo->VGLinkH);
-            /* Sync fake 1 link counts to the link table, now that it exists */
-            if (fdP) {
-               for (i = 0; i < nVols; i++) {
-                       ip = allInodes + isp[i].index;
-                        for (j = isp[i].nSpecialInodes; j < isp[i].nInodes; j++) {
-                                namei_SetLinkCount(fdP, ip[j].inodeNumber, 1, 1);
+           /* Sync fake 1 link counts to the link table, now that it exists */
+           if (fdP) {
+               for (i = 0; i < nVols; i++) {
+                   ip = allInodes + isp[i].index;
+                   for (j = isp[i].nSpecialInodes; j < isp[i].nInodes; j++) {
+                       namei_SetLinkCount(fdP, ip[j].inodeNumber, 1, 0);
+                       ip[j].linkCount = 1;
                    }
-               }
+               }
            }
        }
     }
@@ -2005,15 +2059,33 @@ DoSalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nV
        int rw = (i == 0);
        struct InodeSummary *lisp = &isp[i];
 #ifdef AFS_NAMEI_ENV
-       /* If only the RO is present on this partition, the link table
-        * shows up as a RW volume special file. Need to make sure the
-        * salvager doesn't try to salvage the non-existent RW.
-        */
-       if (rw && nVols > 1 && isp[i].nSpecialInodes == 1) {
-           /* If this only special inode is the link table, continue */
-           if (inodes->u.special.type == VI_LINKTABLE) {
-               haveRWvolume = 0;
-               continue;
+       if (rw && (nVols > 1 || isp[i].nSpecialInodes == isp[i].nInodes)) {
+           /* If nVols > 1, we have more than one vol in this volgroup, so
+            * the RW inodes we detected may just be for the linktable, and
+            * there is no actual RW volume.
+            *
+            * Additionally, if we only have linktable inodes (no other
+            * special inodes, no data inodes), there is also no actual RW
+            * volume to salvage; this is just cruft left behind by something
+            * else. In that case nVols will only be 1, though, so also
+            * perform this linktables-only check if we don't have any
+            * non-special inodes. */
+           int inode_i;
+           int all_linktables = 1;
+           for (inode_i = 0; inode_i < isp[i].nSpecialInodes; inode_i++) {
+               if (inodes[inode_i].u.special.type != VI_LINKTABLE) {
+                   all_linktables = 0;
+                   break;
+               }
+           }
+           if (all_linktables) {
+               /* All we have are linktable special inodes, so skip salvaging
+                * the RW; there was never an RW volume here. If we don't do
+                * this, we risk creating a new "phantom" RW that the VLDB
+                * doesn't know about, which is confusing and can cause
+                * problems. */
+                haveRWvolume = 0;
+                continue;
            }
        }
 #endif
@@ -2055,14 +2127,29 @@ DoSalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nV
                dec_VGLinkH = ip->linkCount - salvinfo->VGLinkH_cnt;
                VGLinkH_p1 = ip->u.param[0];
                continue;       /* Deal with this last. */
+           } else if (CheckDupLinktable(salvinfo, isp, ip)) {
+               /* Don't touch this inode; CheckDupLinktable has handled it */
+               continue;
            }
 #endif
            if (ip->linkCount != 0 && TraceBadLinkCounts) {
                TraceBadLinkCounts--;   /* Limit reports, per volume */
                Log("#### DEBUG #### Link count incorrect by %d; inode %s, size %llu, p=(%u,%u,%u,%u)\n", ip->linkCount, PrintInode(stmp, ip->inodeNumber), (afs_uintmax_t) ip->byteCount, ip->u.param[0], ip->u.param[1], ip->u.param[2], ip->u.param[3]); /* VolumeId in param */
            }
+
+           /* If ip->linkCount is non-zero at this point, then the linkcount
+            * for the inode on disk is wrong. Initially linkCount is set to
+            * the actual link count of the inode on disk, and then we (the
+            * salvager) decrement it for every reference to that inode that we
+            * find. So if linkCount is still positive by this point, it means
+            * that the linkcount on disk is too high, so we should DEC the
+            * inode. If linkCount is negative, it means the linkcount is too
+            * low, so we should INC the inode.
+            *
+            * If we get an error while INC'ing or DEC'ing, that's a little
+            * odd and indicates a bug, but try to continue anyway, so the
+            * volume may still be made accessible. */
            while (ip->linkCount > 0) {
-               /* below used to assert, not break */
                if (!Testing) {
                    if (IH_DEC(salvinfo->VGLinkH, ip->inodeNumber, ip->u.param[0])) {
                        Log("idec failed. inode %s errno %d\n",
@@ -2073,7 +2160,6 @@ DoSalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nV
                ip->linkCount--;
            }
            while (ip->linkCount < 0) {
-               /* these used to be asserts */
                if (!Testing) {
                    if (IH_INC(salvinfo->VGLinkH, ip->inodeNumber, ip->u.param[0])) {
                        Log("iinc failed. inode %s errno %d\n",
@@ -2106,8 +2192,7 @@ DoSalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nV
     IH_RELEASE(salvinfo->VGLinkH);
 
     if (canfork && !debug) {
-       ShowLog = 0;
-       Exit(0);
+       QuietExit(0);
     }
 }
 
@@ -2999,17 +3084,8 @@ CopyAndSalvage(struct SalvInfo *salvinfo, struct DirSummary *dir)
                  vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode,
                  sizeof(vnode));
     opr_Assert(lcode == sizeof(vnode));
-#if 0
-#ifdef AFS_NT40_ENV
-    nt_sync(salvinfo->fileSysDevice);
-#else
-    sync();                    /* this is slow, but hopefully rarely called.  We don't have
-                                * an open FD on the file itself to fsync.
-                                */
-#endif
-#else
-    salvinfo->vnodeInfo[vLarge].handle->ih_synced = 1;
-#endif
+    IH_CONDSYNC(salvinfo->vnodeInfo[vLarge].handle);
+
     /* make sure old directory file is really closed */
     fdP = IH_OPEN(dir->dirHandle.dirh_handle);
     FDH_REALLYCLOSE(fdP);
@@ -3089,31 +3165,42 @@ JudgeEntry(void *arock, char *name, afs_int32 vnodeNumber,
      * or if the directory is orphaned.
      */
     if (!vnodeEssence->unique || (vnodeEssence->unique) != unique) {
-       if (!vnodeEssence->unique
-           && ((strcmp(name, "..") == 0) || (strcmp(name, ".") == 0))) {
-           /* This is an orphaned directory. Don't delete the . or ..
-            * entry. Otherwise, it will get created in the next
-            * salvage and deleted again here. So Just skip it.
-            */
-           return 0;
-       }
-
        todelete = ((!vnodeEssence->unique || dirOrphaned) ? 1 : 0);
 
-       if (!Showmode) {
-           Log("dir vnode %u: %s" OS_DIRSEP "%s (vnode %u): unique changed from %u to %u %s\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique, vnodeEssence->unique, (!todelete ? "" : (Testing ? "-- would have deleted" : "-- deleted")));
-       }
-       if (!Testing) {
-           AFSFid fid;
-           fid.Vnode = vnodeNumber;
-           fid.Unique = vnodeEssence->unique;
-           CopyOnWrite(salvinfo, dir);
-           opr_Verify(afs_dir_Delete(&dir->dirHandle, name) == 0);
-           if (!todelete)
-               opr_Verify(afs_dir_Create(&dir->dirHandle, name, &fid) == 0);
+       if (todelete
+           && ((strcmp(name, "..") == 0) || (strcmp(name, ".") == 0))) {
+               if (dirOrphaned) {
+                   /* This is an orphaned directory. Don't delete the . or ..
+                    * entry. Otherwise, it will get created in the next
+                    * salvage and deleted again here. So Just skip it.
+                    * */
+                   return 0;
+               }
+               /* (vnodeEssence->unique == 0 && ('.' || '..'));
+                * Entries arriving here should be deleted, but the directory
+                * is not orphaned. Therefore, the entry must be pointing at
+                * the wrong vnode.  Skip the 'else' clause and fall through;
+                * the code below will repair the entry so it correctly points
+                * at the vnode of the current directory (if '.') or the parent
+                * directory (if '..'). */
+       } else {
+           if (!Showmode) {
+               Log("dir vnode %u: %s" OS_DIRSEP "%s (vnode %u): unique changed from %u to %u %s\n",
+                   dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique,
+                   vnodeEssence->unique, (!todelete ? "" : (Testing ? "-- would have deleted" : "-- deleted")));
+           }
+           if (!Testing) {
+               AFSFid fid;
+               fid.Vnode = vnodeNumber;
+               fid.Unique = vnodeEssence->unique;
+               CopyOnWrite(salvinfo, dir);
+               opr_Verify(afs_dir_Delete(&dir->dirHandle, name) == 0);
+               if (!todelete)
+                   opr_Verify(afs_dir_Create(&dir->dirHandle, name, &fid) == 0);
+           }
+           if (todelete)
+               return 0;               /* no need to continue */
        }
-       if (todelete)
-           return 0;           /* no need to continue */
     }
 
     if (strcmp(name, ".") == 0) {
@@ -4157,7 +4244,7 @@ SalvageVolume(struct SalvInfo *salvinfo, struct InodeSummary *rwIsp, IHandle_t *
     /* Make sure the uniquifer is big enough: maxunique is the real maxUniquifier */
     if (volHeader.uniquifier < (maxunique + 1)) {
        if (!Showmode)
-           Log("Volume uniquifier is too low; fixed\n");
+           Log("Volume uniquifier %u is too low (max uniq %u); fixed\n", volHeader.uniquifier, maxunique);
        /* Plus 2,000 in case there are workstations out there with
         * cached vnodes that have since been deleted
         */
@@ -4188,7 +4275,7 @@ SalvageVolume(struct SalvInfo *salvinfo, struct InodeSummary *rwIsp, IHandle_t *
        }
 #endif /* FSSYNC_BUILD_CLIENT */
 
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
        if (!salvinfo->useFSYNC) {
            /* A volume's contents have changed, but the fileserver will not
             * break callbacks on the volume until it tries to load the vol
@@ -4305,7 +4392,7 @@ MaybeZapVolume(struct SalvInfo *salvinfo, struct InodeSummary *isp,
     }
 }
 
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
 /**
  * Locks a volume on disk for salvaging.
  *
@@ -4392,7 +4479,7 @@ LockVolume(struct SalvInfo *salvinfo, VolumeId volumeId)
 
     return 0;
 }
-#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
+#endif /* AFS_DEMAND_ATTACH_FS */
 
 static void
 AskError(struct SalvInfo *salvinfo, VolumeId volumeId)
@@ -4433,13 +4520,13 @@ AskOffline(struct SalvInfo *salvinfo, VolumeId volumeId)
            Log("AskOffline:  fssync protocol mismatch (bad command word '%d'); salvage aborting.\n",
                FSYNC_VOL_OFF);
            if (AskDAFS()) {
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
                Log("AskOffline:  please make sure dafileserver, davolserver, salvageserver and dasalvager binaries are same version.\n");
 #else
                Log("AskOffline:  fileserver is DAFS but we are not.\n");
 #endif
            } else {
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
                Log("AskOffline:  fileserver is not DAFS but we are.\n");
 #else
                Log("AskOffline:  please make sure fileserver, volserver and salvager binaries are same version.\n");
@@ -4557,13 +4644,13 @@ AskDelete(struct SalvInfo *salvinfo, VolumeId volumeId)
            Log("AskOnline:  fssync protocol mismatch (bad command word '%d')\n",
                FSYNC_VOL_DONE);
            if (AskDAFS()) {
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
                Log("AskOnline:  please make sure dafileserver, davolserver, salvageserver and dasalvager binaries are same version.\n");
 #else
                Log("AskOnline:  fileserver is DAFS but we are not.\n");
 #endif
            } else {
-#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+#ifdef AFS_DEMAND_ATTACH_FS
                Log("AskOnline:  fileserver is not DAFS but we are.\n");
 #else
                Log("AskOnline:  please make sure fileserver, volserver and salvager binaries are same version.\n");
@@ -4675,12 +4762,9 @@ Fork(void)
     return f;
 }
 
-void
-Exit(int code)
+static void
+QuietExit(int code)
 {
-    if (ShowLog)
-       showlog();
-
 #ifdef AFS_DEMAND_ATTACH_FS
     if (programType == salvageServer) {
        /* release all volume locks before closing down our SYNC channels.
@@ -4714,6 +4798,14 @@ Exit(int code)
 #endif
 }
 
+void
+Exit(int code)
+{
+    SalvageShowLog();
+    QuietExit(code);
+}
+
+
 int
 Wait(char *prog)
 {
@@ -4744,24 +4836,23 @@ TimeStamp(time_t clock, int precision)
 void
 CheckLogFile(char * log_path)
 {
-    char oldSlvgLog[AFSDIR_PATH_MAX];
+    char *oldSlvgLog;
 
 #ifndef AFS_NT40_ENV
     if (useSyslog) {
-       ShowLog = 0;
        return;
     }
 #endif
 
-    strcpy(oldSlvgLog, log_path);
-    strcat(oldSlvgLog, ".old");
     if (!logFile) {
-       rk_rename(log_path, oldSlvgLog);
+       if (asprintf(&oldSlvgLog, "%s.old", log_path) >= 0) {
+           rk_rename(log_path, oldSlvgLog);
+           free(oldSlvgLog);
+       }
        logFile = afs_fopen(log_path, "a");
 
        if (!logFile) {         /* still nothing, use stdout */
            logFile = stdout;
-           ShowLog = 0;
        }
 #ifndef AFS_NAMEI_ENV
        AFS_DEBUG_IOPS_LOG(logFile);
@@ -4773,28 +4864,34 @@ CheckLogFile(char * log_path)
 void
 TimeStampLogFile(char * log_path)
 {
-    char stampSlvgLog[AFSDIR_PATH_MAX];
+    char *stampSlvgLog;
     struct tm *lt;
     time_t now;
 
     now = time(0);
     lt = localtime(&now);
-    snprintf(stampSlvgLog, sizeof stampSlvgLog,
-            "%s.%04d-%02d-%02d.%02d:%02d:%02d", log_path,
-            lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour,
-            lt->tm_min, lt->tm_sec);
-
-    /* try to link the logfile to a timestamped filename */
-    /* if it fails, oh well, nothing we can do */
-    link(log_path, stampSlvgLog);
+    if (asprintf(&stampSlvgLog,
+                "%s.%04d-%02d-%02d.%02d:%02d:%02d", log_path,
+                lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour,
+                lt->tm_min, lt->tm_sec) >= 0) {
+       /* try to link the logfile to a timestamped filename */
+       /* if it fails, oh well, nothing we can do */
+       if (link(log_path, stampSlvgLog))
+           ; /* oh well */
+       free(stampSlvgLog);
+    }
 }
 #endif
 
-void
-showlog(void)
+static void
+SalvageShowLog(void)
 {
     char line[256];
 
+    if (ShowLog == 0 || logFile == stdout || logFile == stderr) {
+       return;
+    }
+
 #ifndef AFS_NT40_ENV
     if (useSyslog) {
        printf("Can't show log since using syslog.\n");
@@ -4859,13 +4956,12 @@ Abort(const char *format, ...)
        if (logFile) {
            fprintf(logFile, "%s", tmp);
            fflush(logFile);
-           if (ShowLog)
-               showlog();
+           SalvageShowLog();
        }
 
     if (debug)
        abort();
-    Exit(1);
+    QuietExit(1);
 }
 
 char *
@@ -4950,7 +5046,7 @@ int
 nt_SetupPartitionSalvage(void *datap, int len)
 {
     childJob_t *jobp = (childJob_t *) datap;
-    char logname[AFSDIR_PATH_MAX];
+    char *logname;
 
     if (len != sizeof(childJob_t))
        return -1;
@@ -4959,9 +5055,11 @@ nt_SetupPartitionSalvage(void *datap, int len)
     myjob = *jobp;
 
     /* Open logFile */
-    (void)sprintf(logname, "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH,
-                 myjob.cj_number);
+    if (asprintf(&logname, "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH,
+                myjob.cj_number) < 0)
+       return -1;
     logFile = afs_fopen(logname, "w");
+    free(logname);
     if (!logFile)
        logFile = stdout;