vol: Call memset with the correct size
[openafs.git] / src / vol / vol-salvage.c
index 78422f4..0b1fa26 100644 (file)
@@ -101,7 +101,6 @@ Vnodes with 0 inode pointers in RW volumes are now deleted.
 #endif
 #include <rx/xdr.h>
 #include <afs/afsint.h>
-#include <afs/afs_assert.h>
 #if !defined(AFS_SGI_ENV) && !defined(AFS_NT40_ENV)
 #if defined(AFS_VFSINCL_ENV)
 #include <sys/vnode.h>
@@ -166,6 +165,7 @@ Vnodes with 0 inode pointers in RW volumes are now deleted.
 #include "daemon_com.h"
 #include "daemon_com_inline.h"
 #include "fssync.h"
+#include "fssync_inline.h"
 #include "volume_inline.h"
 #include "salvsync.h"
 #include "viceinode.h"
@@ -233,7 +233,7 @@ FILE *logFile = 0;  /* one of {/usr/afs/logs,/vice/file}/SalvageLog */
 struct SalvInfo {
     Device fileSysDevice;    /**< The device number of the current partition
                              *   being salvaged */
-    char fileSysPath[8];     /**< The path of the mounted partition currently
+    char fileSysPath[9];     /**< The path of the mounted partition currently
                               *   being salvaged, i.e. the directory containing
                               *   the volume headers */
     char *fileSysPathName;   /**< NT needs this to make name pretty log. */
@@ -859,6 +859,16 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
        goto retry;
     }
 
+    if (singleVolumeNumber) {
+       /* If we delete a volume during the salvage, we indicate as such by
+        * setting the volsummary->deleted field. We need to know if we
+        * deleted a volume or not in order to know which volumes to bring
+        * back online after the salvage. If we fork, we will lose this
+        * information, since volsummary->deleted will not get set in the
+        * parent. So, don't fork. */
+       canfork = 0;
+    }
+
     for (i = j = 0, vsp = salvinfo->volumeSummaryp, esp = vsp + salvinfo->nVolumes;
         i < salvinfo->nVolumesInInodeFile; i = j) {
        VolumeId rwvid = salvinfo->inodeSummary[i].RWvolumeId;
@@ -872,7 +882,7 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
             * If there is one here that is not in the inode volume list,
             * delete it now. */
            for (; vsp < esp && (vsp->header.parent < rwvid); vsp++) {
-               if (vsp->fileName)
+               if (vsp->unused)
                    DeleteExtraVolumeHeaderFile(salvinfo, vsp);
            }
            /* Now match up the volume summary info from the root directory with the
@@ -881,7 +891,7 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
            for (tsp = vsp; tsp < esp && (tsp->header.parent == rwvid); tsp++) {
                if (tsp->header.id == vid) {
                    salvinfo->inodeSummary[j].volSummary = tsp;
-                   tsp->fileName = 0;
+                   tsp->unused = 0;
                    break;
                }
            }
@@ -889,12 +899,17 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
        /* Salvage the group of volumes (several read-only + 1 read/write)
         * starting with the current read-only volume we're looking at.
         */
-       SalvageVolumeGroup(salvinfo, &salvinfo->inodeSummary[i], j - i);
+#ifdef AFS_NT40_ENV
+       nt_SalvageVolumeGroup(salvinfo, &salvinfo->inodeSummary[i], j - i);
+#else
+       DoSalvageVolumeGroup(salvinfo, &salvinfo->inodeSummary[i], j - i);
+#endif /* AFS_NT40_ENV */
+
     }
 
     /* Delete any additional volumes that were listed in the partition but which didn't have any corresponding inodes */
     for (; vsp < esp; vsp++) {
-       if (vsp->fileName)
+       if (vsp->unused)
            DeleteExtraVolumeHeaderFile(salvinfo, vsp);
     }
 
@@ -953,7 +968,14 @@ void
 DeleteExtraVolumeHeaderFile(struct SalvInfo *salvinfo, struct VolumeSummary *vsp)
 {
     char path[64];
-    sprintf(path, "%s" OS_DIRSEP "%s", salvinfo->fileSysPath, vsp->fileName);
+    char filename[VMAXPATHLEN];
+
+    if (vsp->deleted) {
+       return;
+    }
+
+    VolumeExternalName_r(vsp->header.id, filename, sizeof(filename));
+    sprintf(path, "%s" OS_DIRSEP "%s", salvinfo->fileSysPath, filename);
 
     if (!Showmode)
        Log("The volume header file %s is not associated with any actual data (%sdeleted)\n", path, (Testing ? "would have been " : ""));
@@ -966,7 +988,7 @@ DeleteExtraVolumeHeaderFile(struct SalvInfo *salvinfo, struct VolumeSummary *vsp
                afs_printable_uint32_lu(vsp->header.id));
        }
 
-       /* make sure we actually delete the fileName file; ENOENT
+       /* make sure we actually delete the header file; ENOENT
         * is fine, since VDestroyVolumeDiskHeader probably already
         * unlinked it */
        if (unlink(path) && errno != ENOENT) {
@@ -977,7 +999,6 @@ DeleteExtraVolumeHeaderFile(struct SalvInfo *salvinfo, struct VolumeSummary *vsp
        }
        vsp->deleted = 1;
     }
-    vsp->fileName = 0;
 }
 
 int
@@ -1210,7 +1231,7 @@ GetInodeSummary(struct SalvInfo *salvinfo, FD_t inodeFile, VolumeId singleVolume
                GetVolumeSummary(salvinfo, singleVolumeNumber);
 
                for (i = 0, vsp = salvinfo->volumeSummaryp; i < salvinfo->nVolumes; i++) {
-                   if (vsp->fileName) {
+                   if (vsp->unused) {
                        if (vsp->header.id == singleVolumeNumber) {
                            foundSVN = 1;
                        }
@@ -1460,7 +1481,7 @@ AskVolumeSummary(struct SalvInfo *salvinfo, VolumeId singleVolumeNumber)
 
                DiskToVolumeHeader(&vsp->header, &diskHdr);
                VolumeExternalName_r(q_res.children[i], name, sizeof(name));
-               vsp->fileName = ToString(name);
+               vsp->unused = 1;
                salvinfo->nVolumes++;
                vsp++;
            }
@@ -1631,7 +1652,7 @@ RecordHeader(struct DiskPartition64 *dp, const char *name,
            return 1;
        }
 
-       summary.fileName = ToString(base);
+       summary.unused = 1;
        params->nVolumes++;
 
        if (params->nVolumes > params->totalVolumes) {
@@ -1803,7 +1824,7 @@ CreateLinkTable(struct SalvInfo *salvinfo, struct InodeSummary *isp, Inode ino)
 
     if (!VALID_INO(ino))
        ino =
-           IH_CREATE(NULL, salvinfo->fileSysDevice, salvinfo->fileSysPath, 0, isp->volumeId,
+           IH_CREATE(NULL, salvinfo->fileSysDevice, salvinfo->fileSysPath, 0, isp->RWvolumeId,
                      INODESPECIAL, VI_LINKTABLE, isp->RWvolumeId);
     if (!VALID_INO(ino))
        Abort
@@ -1848,7 +1869,7 @@ nt_SVG(void *arg)
 }
 
 void
-SalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nVols)
+nt_SalvageVolumeGroup(struct SalvInfo *salvinfo, struct InodeSummary *isp, int nVols)
 {
     pthread_t tid;
     pthread_attr_t tattr;
@@ -2335,7 +2356,6 @@ SalvageVolumeHeaderFile(struct SalvInfo *salvinfo, struct InodeSummary *isp,
                isp->volumeId, (Testing ? "it would have been " : ""),
                path);
        isp->volSummary = calloc(1, sizeof(struct VolumeSummary));
-       isp->volSummary->fileName = ToString(headerName);
 
        writefunc = VCreateVolumeDiskHeader;
     } else {
@@ -2348,14 +2368,7 @@ SalvageVolumeHeaderFile(struct SalvInfo *salvinfo, struct InodeSummary *isp,
        if (memcmp
            (&isp->volSummary->header, &tempHeader,
             sizeof(struct VolumeHeader))) {
-           /* We often remove the name before calling us, so we make a fake one up */
-           if (isp->volSummary->fileName) {
-               strcpy(headerName, isp->volSummary->fileName);
-           } else {
-               snprintf(headerName, sizeof headerName, VFORMAT,
-                        afs_printable_uint32_lu(isp->volumeId));
-               isp->volSummary->fileName = ToString(headerName);
-           }
+           VolumeExternalName_r(isp->volumeId, headerName, sizeof(headerName));
            snprintf(path, sizeof path, "%s" OS_DIRSEP "%s",
                     salvinfo->fileSysPath, headerName);
 
@@ -3093,20 +3106,19 @@ JudgeEntry(void *arock, char *name, afs_int32 vnodeNumber,
 
     if (strcmp(name, ".") == 0) {
        if (dir->vnodeNumber != vnodeNumber || (dir->unique != unique)) {
-           AFSFid fid;
            if (!Showmode)
                Log("directory vnode %u.%u: bad '.' entry (was %u.%u); fixed\n", dir->vnodeNumber, dir->unique, vnodeNumber, unique);
            if (!Testing) {
+               AFSFid fid;
                CopyOnWrite(salvinfo, dir);
                osi_Assert(afs_dir_Delete(&dir->dirHandle, ".") == 0);
                fid.Vnode = dir->vnodeNumber;
                fid.Unique = dir->unique;
                osi_Assert(afs_dir_Create(&dir->dirHandle, ".", &fid) == 0);
+               vnodeNumber = fid.Vnode;        /* Get the new Essence */
+               unique = fid.Unique;
+               vnodeEssence = CheckVnodeNumber(salvinfo, vnodeNumber);
            }
-
-           vnodeNumber = fid.Vnode;    /* Get the new Essence */
-           unique = fid.Unique;
-           vnodeEssence = CheckVnodeNumber(salvinfo, vnodeNumber);
        }
        dir->haveDot = 1;
     } else if (strcmp(name, "..") == 0) {
@@ -3311,7 +3323,7 @@ DistilVnodeEssence(struct SalvInfo *salvinfo, VolumeId rwVId,
                if (class != vLarge) {
                    VnodeId vnodeNumber = bitNumberToVnodeNumber(vnodeIndex, class);
                    vip->nAllocatedVnodes--;
-                   memset(vnode, 0, sizeof(vnode));
+                   memset(vnode, 0, sizeof(*vnode));
                    IH_IWRITE(salvinfo->vnodeInfo[vSmall].handle,
                              vnodeIndexOffset(vcp, vnodeNumber),
                              (char *)&vnode, sizeof(vnode));
@@ -3673,7 +3685,7 @@ CreateRootDir(struct SalvInfo *salvinfo, VolumeDiskData *volHeader,
     Inode *ip;
     afs_sfsize_t bytes;
     struct VnodeEssence *vep;
-    Inode readmeinode;
+    Inode readmeinode = 0;
     time_t now = time(NULL);
 
     if (!salvinfo->vnodeInfo[vLarge].vnodes && !salvinfo->vnodeInfo[vSmall].vnodes) {
@@ -4237,7 +4249,7 @@ MaybeZapVolume(struct SalvInfo *salvinfo, struct InodeSummary *isp,
                char *message, int deleteMe, int check)
 {
     if (readOnly(isp) || deleteMe) {
-       if (isp->volSummary && isp->volSummary->fileName) {
+       if (isp->volSummary && !isp->volSummary->deleted) {
            if (deleteMe) {
                if (!Showmode)
                    Log("Volume %u (is only a partial volume--probably an attempt was made to move/restore it when a machine crash occured.\n", isp->volumeId);
@@ -4252,7 +4264,9 @@ MaybeZapVolume(struct SalvInfo *salvinfo, struct InodeSummary *isp,
            if (!Testing) {
                afs_int32 code;
                char path[64];
-               sprintf(path, "%s" OS_DIRSEP "%s", salvinfo->fileSysPath, isp->volSummary->fileName);
+               char filename[VMAXPATHLEN];
+               VolumeExternalName_r(isp->volumeId, filename, sizeof(filename));
+               sprintf(path, "%s" OS_DIRSEP "%s", salvinfo->fileSysPath, filename);
 
                code = VDestroyVolumeDiskHeader(salvinfo->fileSysPartition, isp->volumeId, isp->RWvolumeId);
                if (code) {
@@ -4261,7 +4275,7 @@ MaybeZapVolume(struct SalvInfo *salvinfo, struct InodeSummary *isp,
                        afs_printable_uint32_lu(isp->volumeId));
                }
 
-               /* make sure we actually delete the fileName file; ENOENT
+               /* make sure we actually delete the header file; ENOENT
                 * is fine, since VDestroyVolumeDiskHeader probably already
                 * unlinked it */
                if (unlink(path) && errno != ENOENT) {
@@ -4315,7 +4329,7 @@ LockVolume(struct SalvInfo *salvinfo, VolumeId volumeId)
              afs_printable_uint32_lu(volumeId));
     }
 
-    code = FSYNC_VerifyCheckout(volumeId, salvinfo->fileSysPathName, FSYNC_VOL_OFF, FSYNC_SALVAGE);
+    code = FSYNC_VerifyCheckout(volumeId, salvinfo->fileSysPartition->name, FSYNC_VOL_OFF, FSYNC_SALVAGE);
     if (code == SYNC_DENIED) {
        /* need to retry checking out volumes */
        return -1;
@@ -4438,8 +4452,8 @@ static int isDAFS = -1;
 int
 AskDAFS(void)
 {
-    afs_int32 code, i, ret = 0;
     SYNC_response res;
+    afs_int32 code = 1, i;
 
     /* we don't care if we race. the answer shouldn't change */
     if (isDAFS != -1)
@@ -4447,35 +4461,29 @@ AskDAFS(void)
 
     memset(&res, 0, sizeof(res));
 
-    for (i = 0; i < 3; i++) {
-       code = FSYNC_VolOp(1, NULL,
-                          FSYNC_VOL_QUERY_VOP, FSYNC_SALVAGE, &res);
-
-       if (code == SYNC_OK) {
-           ret = 1;
-           break;
-       } else if (code == SYNC_DENIED) {
-           ret = 1;
-           break;
-       } else if (code == SYNC_BAD_COMMAND) {
-           ret = 0;
-           break;
-       } else if (code == SYNC_FAILED) {
-           if (res.hdr.reason == FSYNC_UNKNOWN_VOLID)
-               ret = 1;
-           else
-               ret = 0;
-           break;
-       } else if (i < 2) {
-           /* try it again */
-           Log("AskDAFS:  request to query fileserver failed; trying again...\n");
+    for (i = 0; code && i < 3; i++) {
+       code = FSYNC_VolOp(0, NULL, FSYNC_VOL_LISTVOLUMES, FSYNC_SALVAGE, &res);
+       if (code) {
+           Log("AskDAFS: FSYNC_VOL_LISTVOLUMES failed with code %ld reason "
+               "%ld (%s); trying again...\n", (long)code, (long)res.hdr.reason,
+               FSYNC_reason2string(res.hdr.reason));
            FSYNC_clientFinis();
            FSYNC_clientInit();
        }
     }
 
-    isDAFS = ret;
-    return ret;
+    if (code) {
+       Log("AskDAFS: could not determine DAFS-ness, assuming not DAFS\n");
+       res.hdr.flags = 0;
+    }
+
+    if ((res.hdr.flags & SYNC_FLAG_DAFS_EXTENSIONS)) {
+       isDAFS = 1;
+    } else {
+       isDAFS = 0;
+    }
+
+    return isDAFS;
 }
 
 static void
@@ -4629,17 +4637,6 @@ PrintInodeSummary(struct SalvInfo *salvinfo)
     }
 }
 
-void
-PrintVolumeSummary(struct SalvInfo *salvinfo)
-{
-    int i;
-    struct VolumeSummary *vsp;
-
-    for (i = 0, vsp = salvinfo->volumeSummaryp; i < salvinfo->nVolumes; vsp++, i++) {
-       Log("fileName:%s, header, wouldNeedCallback\n", vsp->fileName);
-    }
-}
-
 int
 Fork(void)
 {