#ifdef AFS_OSF_ENV
#include <ufs/inode.h>
#else /* AFS_OSF_ENV */
-#if !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV)
+#if !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV) && !defined(AFS_ARM_DARWIN_ENV)
#include <sys/inode.h>
#endif
#endif
SameDisk(struct DiskPartition64 *p1, struct DiskPartition64 *p2)
{
#define RES_LEN 256
- char res[RES_LEN];
- int d1, d2;
+ char res1[RES_LEN];
+ char res2[RES_LEN];
+
static int dowarn = 1;
- if (!QueryDosDevice(p1->devName, res, RES_LEN - 1))
+ if (!QueryDosDevice(p1->devName, res1, RES_LEN - 1))
return 1;
- if (strncmp(res, HDSTR, HDLEN)) {
+ if (strncmp(res1, HDSTR, HDLEN)) {
if (dowarn) {
dowarn = 0;
Log("WARNING: QueryDosDevice is returning %s, not %s for %s\n",
- res, HDSTR, p1->devName);
+ res1, HDSTR, p1->devName);
}
- return 1;
}
- d1 = atoi(&res[HDLEN]);
-
- if (!QueryDosDevice(p2->devName, res, RES_LEN - 1))
+ if (!QueryDosDevice(p2->devName, res2, RES_LEN - 1))
return 1;
- if (strncmp(res, HDSTR, HDLEN)) {
+ if (strncmp(res2, HDSTR, HDLEN)) {
if (dowarn) {
dowarn = 0;
Log("WARNING: QueryDosDevice is returning %s, not %s for %s\n",
- res, HDSTR, p2->devName);
+ res2, HDSTR, p2->devName);
}
- return 1;
}
- d2 = atoi(&res[HDLEN]);
- return d1 == d2;
+ return (0 == _strnicmp(res1, res2, RES_LEN - 1));
}
#else
#define SameDisk(P1, P2) ((P1)->device/PartsPerDisk == (P2)->device/PartsPerDisk)
* semantics of unlink. In most places in the salvager, we really do
* mean to unlink the file at that point. Those places have been
* modified to actually do that so that the NT crt can be used there.
+ *
+ * jaltman - On NT delete on close cannot be applied to a file while the
+ * process has an open file handle that does not have DELETE file
+ * access and FILE_SHARE_DELETE. fopen() calls CreateFile() without
+ * delete privileges. As a result the nt_unlink() call will always
+ * fail.
*/
code = nt_unlink(inodeListPath);
#else
RemoveTheForce(salvinfo->fileSysPath);
if (!Testing && singleVolumeNumber) {
+ int foundSVN = 0;
#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 */
- AskOnline(salvinfo, singleVolumeNumber);
-
/* Step through the volumeSummary list and set all volumes on-line.
- * The volumes were taken off-line in GetVolumeSummary.
+ * Most volumes were taken off-line in GetVolumeSummary.
+ * If a volume was deleted, don't tell the fileserver anything, since
+ * we already told the fileserver the volume was deleted back when we
+ * we destroyed the volume header.
+ * Also, make sure we bring the singleVolumeNumber back online first.
*/
+
+ for (j = 0; j < salvinfo->nVolumes; j++) {
+ if (salvinfo->volumeSummaryp[j].header.id == singleVolumeNumber) {
+ foundSVN = 1;
+ if (!salvinfo->volumeSummaryp[j].deleted) {
+ AskOnline(salvinfo, singleVolumeNumber);
+ }
+ }
+ }
+
+ if (!foundSVN) {
+ /* singleVolumeNumber generally should always be in the constructed
+ * volumeSummary, but just in case it's not... */
+ AskOnline(salvinfo, singleVolumeNumber);
+ }
+
for (j = 0; j < salvinfo->nVolumes; j++) {
- AskOnline(salvinfo, salvinfo->volumeSummaryp[j].header.id);
+ if (salvinfo->volumeSummaryp[j].header.id != singleVolumeNumber) {
+ if (!salvinfo->volumeSummaryp[j].deleted) {
+ AskOnline(salvinfo, salvinfo->volumeSummaryp[j].header.id);
+ }
+ }
}
} else {
if (!Showmode)
if (unlink(path) && errno != ENOENT) {
Log("Unable to unlink %s (errno = %d)\n", path, errno);
}
+ if (salvinfo->useFSYNC) {
+ AskDelete(salvinfo, vsp->header.id);
+ }
+ vsp->deleted = 1;
}
vsp->fileName = 0;
}
* semantics of unlink. In most places in the salvager, we really do
* mean to unlink the file at that point. Those places have been
* modified to actually do that so that the NT crt can be used there.
+ *
+ * jaltman - As commented elsewhere, this cannot work because fopen()
+ * does not open files with DELETE and FILE_SHARE_DELETE.
*/
code = nt_unlink(summaryFileName);
#else
Exit(SALSRV_EXIT_VOLGROUP_LINK);
}
- salvinfo->volumeSummaryp = malloc(VOL_VG_MAX_VOLS * sizeof(struct VolumeSummary));
+ salvinfo->volumeSummaryp = calloc(VOL_VG_MAX_VOLS, sizeof(struct VolumeSummary));
osi_Assert(salvinfo->volumeSummaryp != NULL);
salvinfo->nVolumes = 0;
nvols = VOL_VG_MAX_VOLS;
}
- salvinfo->volumeSummaryp = malloc(nvols * sizeof(struct VolumeSummary));
+ salvinfo->volumeSummaryp = calloc(nvols, sizeof(struct VolumeSummary));
osi_Assert(salvinfo->volumeSummaryp != NULL);
params.singleVolumeNumber = singleVolumeNumber;
Log("No header file for volume %u; %screating %s\n",
isp->volumeId, (Testing ? "it would have been " : ""),
path);
- isp->volSummary = (struct VolumeSummary *)
- malloc(sizeof(struct VolumeSummary));
+ isp->volSummary = calloc(1, sizeof(struct VolumeSummary));
isp->volSummary->fileName = ToString(headerName);
writefunc = VCreateVolumeDiskHeader;
} else {
if (vcp->magic != vnode->vnodeMagic) {
/* bad magic #, probably partially created vnode */
+ if (check) {
+ Log("Partially allocated vnode %d: bad magic (is %lx should be %lx)\n",
+ vnodeNumber, afs_printable_uint32_lu(vnode->vnodeMagic),
+ afs_printable_uint32_lu(vcp->magic));
+ memset(vnode, 0, vcp->diskSize);
+ err = -1;
+ goto zooks;
+ }
Log("Partially allocated vnode %d deleted.\n",
vnodeNumber);
memset(vnode, 0, vcp->diskSize);
Log("FOUND suid/sgid file: %s" OS_DIRSEP "%s (%u.%u %05o) author %u (vnode %u dir %u)\n", dir->name ? dir->name : "??", name, vnodeEssence->owner, vnodeEssence->group, vnodeEssence->modeBits, vnodeEssence->author, vnodeNumber, dir->vnodeNumber);
if (/* ShowMounts && */ (vnodeEssence->type == vSymlink)
&& !(vnodeEssence->modeBits & 0111)) {
- ssize_t nBytes;
+ afs_sfsize_t nBytes;
afs_sfsize_t size;
char buf[1025];
IHandle_t *ihP;
* will get removed here also (if requested).
*/
for (class = 0; class < nVNODECLASSES; class++) {
- int nVnodes = salvinfo->vnodeInfo[class].nVnodes;
+ afs_sfsize_t nVnodes = salvinfo->vnodeInfo[class].nVnodes;
struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
struct VnodeEssence *vnodes = salvinfo->vnodeInfo[class].vnodes;
FilesInVolume += salvinfo->vnodeInfo[class].nAllocatedVnodes;
if (unlink(path) && errno != ENOENT) {
Log("Unable to unlink %s (errno = %d)\n", path, errno);
}
+ if (salvinfo->useFSYNC) {
+ AskDelete(salvinfo, isp->volumeId);
+ }
+ isp->volSummary->deleted = 1;
}
}
} else if (!check) {
break;
} else if (i < 2) {
/* try it again */
- Log("AskOnline: request for fileserver to take volume offline failed; trying again...\n");
+ Log("AskOnline: request for fileserver to put volume online failed; trying again...\n");
+ FSYNC_clientFinis();
+ FSYNC_clientInit();
+ }
+ }
+}
+
+void
+AskDelete(struct SalvInfo *salvinfo, VolumeId volumeId)
+{
+ afs_int32 code, i;
+
+ for (i = 0; i < 3; i++) {
+ code = FSYNC_VolOp(volumeId, salvinfo->fileSysPartition->name,
+ FSYNC_VOL_DONE, FSYNC_SALVAGE, NULL);
+
+ if (code == SYNC_OK) {
+ break;
+ } else if (code == SYNC_DENIED) {
+ Log("AskOnline: file server denied DONE request to volume %u partition %s; trying again...\n", volumeId, salvinfo->fileSysPartition->name);
+ } else if (code == SYNC_BAD_COMMAND) {
+ Log("AskOnline: fssync protocol mismatch (bad command word '%d')\n",
+ FSYNC_VOL_DONE);
+#ifdef DEMAND_ATTACH_ENABLE
+ Log("AskOnline: please make sure fileserver, volserver, salvageserver and salvager binaries are same version.\n");
+#else
+ Log("AskOnline: please make sure fileserver, volserver and salvager binaries are same version.\n");
+#endif
+ break;
+ } else if (i < 2) {
+ /* try it again */
+ Log("AskOnline: request for fileserver to delete volume failed; trying again...\n");
FSYNC_clientFinis();
FSYNC_clientInit();
}