#include <afsconfig.h>
#include <afs/param.h>
+#include <afs/procmgmt.h>
+#include <roken.h>
#ifndef AFS_NT40_ENV
#include <sys/param.h>
#endif
#include <rx/xdr.h>
#include <afs/afsint.h>
-#include <afs/assert.h>
+#include <afs/afs_assert.h>
#if !defined(AFS_SGI_ENV) && !defined(AFS_NT40_ENV)
#if defined(AFS_VFSINCL_ENV)
#include <sys/vnode.h>
#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
#include <pthread.h>
#endif
-/*@+fcnmacros +macrofcndecl@*/
-#ifdef O_LARGEFILE
-#ifdef S_SPLINT_S
-extern off64_t afs_lseek(int FD, off64_t O, int F);
-#endif /*S_SPLINT_S */
-#define afs_lseek(FD, O, F) lseek64(FD, (off64_t) (O), F)
-#define afs_stat stat64
-#define afs_fstat fstat64
-#define afs_open open64
-#define afs_fopen fopen64
-#else /* !O_LARGEFILE */
-#ifdef S_SPLINT_S
-extern off_t afs_lseek(int FD, off_t O, int F);
-#endif /*S_SPLINT_S */
-#define afs_lseek(FD, O, F) lseek(FD, (off_t) (O), F)
-#define afs_stat stat
-#define afs_fstat fstat
-#define afs_open open
-#define afs_fopen fopen
-#endif /* !O_LARGEFILE */
-/*@=fcnmacros =macrofcndecl@*/
-
#ifdef AFS_OSF_ENV
extern void *calloc();
#endif
* header dealt with */
int nVolumesInInodeFile; /**< Number of read-write volumes summarized */
- int inodeFd; /**< File descriptor for inode file */
+ FD_t inodeFd; /**< File descriptor for inode file */
struct VolumeSummary *volumeSummaryp; /**< Holds all the volumes in a part */
int nVolumes; /**< Number of volumes (read-write and read-only)
* vnodes in the volume that
* we are currently looking
* at */
+ int useFSYNC; /**< 0 if the fileserver is unavailable; 1 if we should try
+ * to contact the fileserver over FSYNC */
};
char *tmpdir = NULL;
static int IsVnodeOrphaned(struct SalvInfo *salvinfo, VnodeId vnode);
static int AskVolumeSummary(struct SalvInfo *salvinfo,
VolumeId singleVolumeNumber);
+static void MaybeAskOnline(struct SalvInfo *salvinfo, VolumeId volumeId);
-#ifdef AFS_DEMAND_ATTACH_FS
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
static int LockVolume(struct SalvInfo *salvinfo, VolumeId volumeId);
-#endif /* AFS_DEMAND_ATTACH_FS */
+#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
/* Uniquifier stored in the Inode */
static Unique
FILE *mntfp;
struct mntent *mntent;
- assert(mntfp = setmntent(MOUNTED, "r"));
+ osi_Assert(mntfp = setmntent(MOUNTED, "r"));
while (mntent = getmntent(mntfp)) {
if (!strcmp(part, mntent->mnt_dir))
break;
/* Check if the given inode is the root of the filesystem. */
#ifndef AFS_SGI_XFS_IOPS_ENV
int
-IsRootInode(struct afs_stat *status)
+IsRootInode(struct afs_stat_st *status)
{
/*
* The root inode is not a fixed value in XFS partitions. So we need to
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)
* job to finish. When it's done, clean up after it.
*/
pid = wait(&wstatus);
- assert(pid != -1);
+ osi_Assert(pid != -1);
for (j = 0; j < numjobs; j++) { /* Find which job it is */
if (pid == jobs[j]->pid)
break;
}
- assert(j < numjobs);
+ osi_Assert(j < numjobs);
if (WCOREDUMP(wstatus)) { /* Say if the job core dumped */
Log("Salvage of %s core dumped!\n", jobs[j]->partP->name);
}
ShowLog = 0;
for (fd = 0; fd < 16; fd++)
close(fd);
- open("/", 0);
+ open(OS_DIRSEP, 0);
dup2(0, 1);
dup2(0, 2);
#ifndef AFS_NT40_ENV
{
char pbuf[128], *ptr;
strcpy(pbuf, pbuffer);
- ptr = (char *)strrchr(pbuf, '/');
+ ptr = (char *)strrchr(pbuf, OS_DIRSEPC);
if (ptr) {
*ptr = '\0';
strcpy(wpath, pbuf);
} else
return NULL;
- ptr = (char *)strrchr(pbuffer, '/');
+ ptr = (char *)strrchr(pbuffer, OS_DIRSEPC);
if (ptr) {
strcpy(pbuffer, ptr + 1);
return pbuffer;
{
char *name, *tdir;
char inodeListPath[256];
- FILE *inodeFile = NULL;
+ FD_t inodeFile = INVALID_FD;
static char tmpDevName[100];
static char wpath[100];
struct VolumeSummary *vsp, *esp;
memset(salvinfo, 0, sizeof(*salvinfo));
tries++;
- if (inodeFile) {
- fclose(inodeFile);
- inodeFile = NULL;
+ if (inodeFile != INVALID_FD) {
+ OS_CLOSE(inodeFile);
+ inodeFile = INVALID_FD;
}
if (tries > VOL_MAX_CHECKOUT_RETRIES) {
Abort("Raced too many times with fileserver restarts while trying to "
"checkout/lock volumes; Aborted\n");
}
-#ifdef AFS_DEMAND_ATTACH_FS
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
if (tries > 1) {
/* unlock all previous volume locks, since we're about to lock them
* again */
VLockFileReinit(&partP->volLockFile);
}
-#endif /* AFS_DEMAND_ATTACH_FS */
+#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
salvinfo->fileSysPartition = partP;
salvinfo->fileSysDevice = salvinfo->fileSysPartition->device;
#ifdef AFS_NT40_ENV
/* Opendir can fail on "C:" but not on "C:\" if C is empty! */
- (void)sprintf(salvinfo->fileSysPath, "%s\\", salvinfo->fileSysPathName);
+ (void)sprintf(salvinfo->fileSysPath, "%s" OS_DIRSEP, salvinfo->fileSysPathName);
name = partP->devName;
#else
strlcpy(salvinfo->fileSysPath, salvinfo->fileSysPathName, sizeof(salvinfo->fileSysPath));
#endif
if (singleVolumeNumber) {
-#ifndef AFS_DEMAND_ATTACH_FS
+#if !(defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL))
/* 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 */
+#endif /* !(AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL) */
ForceSalvage = 1;
Abort("Couldn't connect to file server\n");
}
+ salvinfo->useFSYNC = 1;
AskOffline(salvinfo, singleVolumeNumber);
-#ifdef AFS_DEMAND_ATTACH_FS
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
if (LockVolume(salvinfo, singleVolumeNumber)) {
goto retry;
}
-#endif /* AFS_DEMAND_ATTACH_FS */
+#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
} else {
+ salvinfo->useFSYNC = 0;
VLockPartition(partP->name);
if (ForceSalvage) {
ForceSalvage = 1;
DIR *dirp;
struct dirent *dp;
- assert((dirp = opendir(salvinfo->fileSysPath)) != NULL);
+ osi_Assert((dirp = opendir(salvinfo->fileSysPath)) != NULL);
while ((dp = readdir(dirp))) {
if (!strncmp(dp->d_name, "salvage.inodes.", 15)
|| !strncmp(dp->d_name, "salvage.temp.", 13)) {
char npath[1024];
Log("Removing old salvager temp files %s\n", dp->d_name);
strcpy(npath, salvinfo->fileSysPath);
- strcat(npath, "/");
+ strcat(npath, OS_DIRSEP);
strcat(npath, dp->d_name);
- unlink(npath);
+ OS_UNLINK(npath);
}
}
closedir(dirp);
(void)_putenv("TMP="); /* If "TMP" is set, then that overrides tdir. */
(void)strncpy(inodeListPath, _tempnam(tdir, "salvage.inodes."), 255);
#else
- snprintf(inodeListPath, 255, "%s/salvage.inodes.%s.%d", tdir, name,
+ snprintf(inodeListPath, 255, "%s" OS_DIRSEP "salvage.inodes.%s.%d", tdir, name,
getpid());
#endif
- inodeFile = fopen(inodeListPath, "w+b");
- if (!inodeFile) {
+ inodeFile = OS_OPEN(inodeListPath, O_RDWR|O_TRUNC|O_CREAT, 0666);
+ if (inodeFile == INVALID_FD) {
Abort("Error %d when creating inode description file %s; not salvaged\n", errno, inodeListPath);
}
#ifdef AFS_NT40_ENV
* 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
}
if (GetInodeSummary(salvinfo, inodeFile, singleVolumeNumber) < 0) {
- fclose(inodeFile);
+ OS_CLOSE(inodeFile);
+ if (singleVolumeNumber) {
+ /* the volume group -- let alone the volume -- does not exist,
+ * but we checked it out, so give it back to the fileserver */
+ AskDelete(salvinfo, singleVolumeNumber);
+ }
return;
}
- salvinfo->inodeFd = fileno(inodeFile);
- if (salvinfo->inodeFd == -1)
+ salvinfo->inodeFd = inodeFile;
+ if (salvinfo->inodeFd == INVALID_FD)
Abort("Temporary file %s is missing...\n", inodeListPath);
- afs_lseek(salvinfo->inodeFd, 0L, SEEK_SET);
+ OS_SEEK(salvinfo->inodeFd, 0L, SEEK_SET);
if (ListInodeOption) {
PrintInodeList(salvinfo);
+ if (singleVolumeNumber) {
+ /* We've checked out the volume from the fileserver, and we need
+ * to give it back. We don't know if the volume exists or not,
+ * so we don't know whether to AskOnline or not. Try to determine
+ * if the volume exists by trying to read the volume header, and
+ * AskOnline if it is readable. */
+ MaybeAskOnline(salvinfo, singleVolumeNumber);
+ }
return;
}
/* enumerate volumes in the partition.
RemoveTheForce(salvinfo->fileSysPath);
if (!Testing && singleVolumeNumber) {
-#ifdef AFS_DEMAND_ATTACH_FS
+ int foundSVN = 0;
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
/* unlock vol headers so the fs can attach them when we AskOnline */
VLockFileReinit(&salvinfo->fileSysPartition->volLockFile);
-#endif /* AFS_DEMAND_ATTACH_FS */
-
- AskOnline(salvinfo, singleVolumeNumber);
+#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
/* 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) {
+ /* If singleVolumeNumber is not in our volumeSummary, it means that
+ * at least one other volume in the VG is on the partition, but the
+ * RW volume is not. We've already AskOffline'd it by now, though,
+ * so make sure we don't still have the volume checked out. */
+ AskDelete(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)
salvinfo->fileSysPartition->name, (Testing ? " (READONLY mode)" : ""));
}
- fclose(inodeFile); /* SalvageVolumeGroup was the last which needed it. */
+ OS_CLOSE(inodeFile); /* SalvageVolumeGroup was the last which needed it. */
}
void
DeleteExtraVolumeHeaderFile(struct SalvInfo *salvinfo, struct VolumeSummary *vsp)
{
char path[64];
- sprintf(path, "%s/%s", salvinfo->fileSysPath, vsp->fileName);
+ sprintf(path, "%s" OS_DIRSEP "%s", salvinfo->fileSysPath, vsp->fileName);
if (!Showmode)
Log("The volume header file %s is not associated with any actual data (%sdeleted)\n", path, (Testing ? "would have been " : ""));
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;
}
* be unlinked by the caller.
*/
int
-GetInodeSummary(struct SalvInfo *salvinfo, FILE *inodeFile, VolumeId singleVolumeNumber)
+GetInodeSummary(struct SalvInfo *salvinfo, FD_t inodeFile, VolumeId singleVolumeNumber)
{
- struct afs_stat status;
int forceSal, err;
int code;
struct ViceInodeInfo *ip, *ip_save;
struct InodeSummary summary;
char summaryFileName[50];
- FILE *summaryFile;
+ FD_t summaryFile = INVALID_FD;
#ifdef AFS_NT40_ENV
char *dev = salvinfo->fileSysPath;
char *wpath = salvinfo->fileSysPath;
char *part = salvinfo->fileSysPath;
char *tdir;
int i;
+ afs_sfsize_t st_size;
/* This file used to come from vfsck; cobble it up ourselves now... */
if ((err =
Log("***Forced salvage of all volumes on this partition***\n");
ForceSalvage = 1;
}
- fseek(inodeFile, 0L, SEEK_SET);
- salvinfo->inodeFd = fileno(inodeFile);
- if (salvinfo->inodeFd == -1 || afs_fstat(salvinfo->inodeFd, &status) == -1) {
+ OS_SEEK(inodeFile, 0L, SEEK_SET);
+ salvinfo->inodeFd = inodeFile;
+ if (salvinfo->inodeFd == INVALID_FD ||
+ (st_size = OS_SIZE(salvinfo->inodeFd)) == -1) {
Abort("No inode description file for \"%s\"; not salvaged\n", dev);
}
tdir = (tmpdir ? tmpdir : part);
#ifdef AFS_NT40_ENV
(void)_putenv("TMP="); /* If "TMP" is set, then that overrides tdir. */
- (void)strcpy(summaryFileName, _tempnam(tdir, "salvage.temp"));
+ (void)strcpy(summaryFileName, _tempnam(tdir, "salvage.temp."));
#else
(void)afs_snprintf(summaryFileName, sizeof summaryFileName,
- "%s/salvage.temp.%d", tdir, getpid());
+ "%s" OS_DIRSEP "salvage.temp.%d", tdir, getpid());
#endif
- summaryFile = afs_fopen(summaryFileName, "a+");
- if (summaryFile == NULL) {
+ summaryFile = OS_OPEN(summaryFileName, O_RDWR|O_APPEND|O_CREAT, 0666);
+ if (summaryFile == INVALID_FD) {
Abort("Unable to create inode summary file\n");
}
* 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
}
if (!canfork || debug || Fork() == 0) {
- int nInodes;
- unsigned long st_size=(unsigned long) status.st_size;
- nInodes = st_size / sizeof(struct ViceInodeInfo);
+ int nInodes = st_size / sizeof(struct ViceInodeInfo);
if (nInodes == 0) {
- fclose(summaryFile);
+ OS_CLOSE(summaryFile);
if (!singleVolumeNumber) /* Remove the FORCESALVAGE file */
RemoveTheForce(salvinfo->fileSysPath);
else {
}
ip = (struct ViceInodeInfo *)malloc(nInodes*sizeof(struct ViceInodeInfo));
if (ip == NULL) {
- fclose(summaryFile);
+ OS_CLOSE(summaryFile);
Abort
("Unable to allocate enough space to read inode table; %s not salvaged\n",
dev);
}
- if (read(salvinfo->inodeFd, ip, st_size) != st_size) {
- fclose(summaryFile);
+ if (OS_READ(salvinfo->inodeFd, ip, st_size) != st_size) {
+ OS_CLOSE(summaryFile);
Abort("Unable to read inode table; %s not salvaged\n", dev);
}
qsort(ip, nInodes, sizeof(struct ViceInodeInfo), CompareInodes);
- if (afs_lseek(salvinfo->inodeFd, 0, SEEK_SET) == -1
- || write(salvinfo->inodeFd, ip, st_size) != st_size) {
- fclose(summaryFile);
+ if (OS_SEEK(salvinfo->inodeFd, 0, SEEK_SET) == -1
+ || OS_WRITE(salvinfo->inodeFd, ip, st_size) != st_size) {
+ OS_CLOSE(summaryFile);
Abort("Unable to rewrite inode table; %s not salvaged\n", dev);
}
summary.index = 0;
ip_save = ip;
while (nInodes) {
CountVolumeInodes(ip, nInodes, &summary);
- if (fwrite(&summary, sizeof(summary), 1, summaryFile) != 1) {
+ if (OS_WRITE(summaryFile, &summary, sizeof(summary)) != sizeof(summary)) {
Log("Difficulty writing summary file (errno = %d); %s not salvaged\n", errno, dev);
- fclose(summaryFile);
+ OS_CLOSE(summaryFile);
return -1;
}
summary.index += (summary.nInodes);
free(ip_save);
ip = ip_save = NULL;
/* Following fflush is not fclose, because if it was debug mode would not work */
- if (fflush(summaryFile) == EOF || fsync(fileno(summaryFile)) == -1) {
+ if (OS_SYNC(summaryFile) == -1) {
Log("Unable to write summary file (errno = %d); %s not salvaged\n", errno, dev);
- fclose(summaryFile);
+ OS_CLOSE(summaryFile);
return -1;
}
if (canfork && !debug) {
}
} else {
if (Wait("Inode summary") == -1) {
- fclose(summaryFile);
+ OS_CLOSE(summaryFile);
Exit(1); /* salvage of this partition aborted */
}
}
- assert(afs_fstat(fileno(summaryFile), &status) != -1);
- if (status.st_size != 0) {
+
+ st_size = OS_SIZE(summaryFile);
+ osi_Assert(st_size >= 0);
+ if (st_size != 0) {
int ret;
- unsigned long st_status=(unsigned long)status.st_size;
- salvinfo->inodeSummary = (struct InodeSummary *)malloc(st_status);
- assert(salvinfo->inodeSummary != NULL);
+ salvinfo->inodeSummary = (struct InodeSummary *)malloc(st_size);
+ osi_Assert(salvinfo->inodeSummary != NULL);
/* For GNU we need to do lseek to get the file pointer moved. */
- assert(afs_lseek(fileno(summaryFile), 0, SEEK_SET) == 0);
- ret = read(fileno(summaryFile), salvinfo->inodeSummary, st_status);
- assert(ret == st_status);
+ osi_Assert(OS_SEEK(summaryFile, 0, SEEK_SET) == 0);
+ ret = OS_READ(summaryFile, salvinfo->inodeSummary, st_size);
+ osi_Assert(ret == st_size);
}
- salvinfo->nVolumesInInodeFile =(unsigned long)(status.st_size) / sizeof(struct InodeSummary);
+ salvinfo->nVolumesInInodeFile = st_size / sizeof(struct InodeSummary);
for (i = 0; i < salvinfo->nVolumesInInodeFile; i++) {
salvinfo->inodeSummary[i].volSummary = NULL;
}
- Log("%d nVolumesInInodeFile %lu \n",salvinfo->nVolumesInInodeFile,(unsigned long)(status.st_size));
- fclose(summaryFile);
+ Log("%d nVolumesInInodeFile %lu \n",salvinfo->nVolumesInInodeFile,(unsigned long)st_size);
+ OS_CLOSE(summaryFile);
return 0;
}
Exit(SALSRV_EXIT_VOLGROUP_LINK);
}
- salvinfo->volumeSummaryp = malloc(VOL_VG_MAX_VOLS * sizeof(struct VolumeSummary));
- assert(salvinfo->volumeSummaryp != NULL);
+ salvinfo->volumeSummaryp = calloc(VOL_VG_MAX_VOLS, sizeof(struct VolumeSummary));
+ osi_Assert(salvinfo->volumeSummaryp != NULL);
salvinfo->nVolumes = 0;
vsp = salvinfo->volumeSummaryp;
/* check if the header file is incorrectly named */
int badname = 0;
- const char *base = strrchr(name, '/');
+ const char *base = strrchr(name, OS_DIRSEPC);
if (base) {
base++;
} else {
AskOffline(salvinfo, summary.header.id);
-#ifdef AFS_DEMAND_ATTACH_FS
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
if (!badname) {
/* don't lock the volume if the header is bad, since we're
* about to delete it anyway. */
return -1;
}
}
-#endif /* AFS_DEMAND_ATTACH_FS */
+#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
}
}
if (badname) {
nvols = VOL_VG_MAX_VOLS;
}
- salvinfo->volumeSummaryp = malloc(nvols * sizeof(struct VolumeSummary));
- assert(salvinfo->volumeSummaryp != NULL);
+ salvinfo->volumeSummaryp = calloc(nvols, sizeof(struct VolumeSummary));
+ osi_Assert(salvinfo->volumeSummaryp != NULL);
params.singleVolumeNumber = singleVolumeNumber;
params.vsp = salvinfo->volumeSummaryp;
version.magic = LINKTABLEMAGIC;
version.version = LINKTABLEVERSION;
- if (FDH_WRITE(fdP, (char *)&version, sizeof(version))
+ if (FDH_PWRITE(fdP, (char *)&version, sizeof(version), 0)
!= sizeof(version))
Abort("Can't truncate link table for volume %u (error = %d)\n",
isp->RWvolumeId, errno);
allInodes = inodes - isp->index; /* this would the base of all the inodes
* for the partition, if all the inodes
* had been read into memory */
- assert(afs_lseek
+ osi_Assert(OS_SEEK
(salvinfo->inodeFd, isp->index * sizeof(struct ViceInodeInfo),
SEEK_SET) != -1);
- assert(read(salvinfo->inodeFd, inodes, size) == size);
+ osi_Assert(OS_READ(salvinfo->inodeFd, inodes, size) == size);
/* Don't try to salvage a read write volume if there isn't one on this
* partition */
for (i = 0; i < nVols; i++) {
ip = allInodes + isp[i].index;
for (j = isp[i].nSpecialInodes; j < isp[i].nInodes; j++) {
-#ifdef AFS_NT40_ENV
- nt_SetLinkCount(fdP, ip[j].inodeNumber, 1, 1);
-#else
namei_SetLinkCount(fdP, ip[j].inodeNumber, 1, 1);
-#endif
}
}
}
/* Fix actual inode counts */
if (!Showmode) {
+ afs_ino_str_t stmp;
Log("totalInodes %d\n",totalInodes);
for (ip = inodes; totalInodes; ip++, totalInodes--) {
static int TraceBadLinkCounts = 0;
#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(NULL, ip->inodeNumber), (afs_uintmax_t) ip->byteCount, ip->u.param[0], ip->u.param[1], ip->u.param[2], ip->u.param[3]);
+ 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]);
}
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",
- PrintInode(NULL, ip->inodeNumber), errno);
+ PrintInode(stmp, ip->inodeNumber), errno);
break;
}
}
if (!Testing) {
if (IH_INC(salvinfo->VGLinkH, ip->inodeNumber, ip->u.param[0])) {
Log("iinc failed. inode %s errno %d\n",
- PrintInode(NULL, ip->inodeNumber), errno);
+ PrintInode(stmp, ip->inodeNumber), errno);
break;
}
}
}
}
for (i = 0; i < isp->nSpecialInodes; i++) {
+ afs_ino_str_t stmp;
ip = &inodes[isp->index + i];
if (ip->u.special.type <= 0 || ip->u.special.type > MAXINODETYPE) {
if (check) {
Log("Rubbish header inode %s of type %d\n",
- PrintInode(NULL, ip->inodeNumber),
+ PrintInode(stmp, ip->inodeNumber),
ip->u.special.type);
if (skip) {
free(skip);
return -1;
}
Log("Rubbish header inode %s of type %d; deleted\n",
- PrintInode(NULL, ip->inodeNumber),
+ PrintInode(stmp, ip->inodeNumber),
ip->u.special.type);
} else if (!stuff[ip->u.special.type - 1].obsolete) {
if (skip && skip[i]) {
if (orphans == ORPH_REMOVE) {
Log("Removing orphan special inode %s of type %d\n",
- PrintInode(NULL, ip->inodeNumber), ip->u.special.type);
+ PrintInode(stmp, ip->inodeNumber), ip->u.special.type);
continue;
} else {
Log("Ignoring orphan special inode %s of type %d\n",
- PrintInode(NULL, ip->inodeNumber), ip->u.special.type);
+ PrintInode(stmp, ip->inodeNumber), ip->u.special.type);
/* fall through to the ip->linkCount--; line below */
}
} else {
char path[64];
char headerName[64];
(void)afs_snprintf(headerName, sizeof headerName, VFORMAT, afs_printable_uint32_lu(isp->volumeId));
- (void)afs_snprintf(path, sizeof path, "%s/%s", salvinfo->fileSysPath, headerName);
+ (void)afs_snprintf(path, sizeof path, "%s" OS_DIRSEP "%s", salvinfo->fileSysPath, headerName);
if (check) {
Log("No header file for volume %u\n", isp->volumeId);
return -1;
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;
(void)afs_snprintf(headerName, sizeof headerName, VFORMAT, afs_printable_uint32_lu(isp->volumeId));
isp->volSummary->fileName = ToString(headerName);
}
- (void)afs_snprintf(path, sizeof path, "%s/%s", salvinfo->fileSysPath, headerName);
+ (void)afs_snprintf(path, sizeof path, "%s" OS_DIRSEP "%s", salvinfo->fileSysPath, headerName);
Log("Header file %s is damaged or no longer valid%s\n", path,
(check ? "" : "; repairing"));
sp->description, errno);
if (!recreate
- && (FDH_READ(fdP, (char *)&header, sp->size) != sp->size
+ && (FDH_PREAD(fdP, (char *)&header, sp->size, 0) != sp->size
|| header.fileHeader.magic != sp->stamp.magic)) {
if (check) {
Log("Part of the header (%s) is corrupted\n", sp->description);
header.volumeInfo.needsCallback = 0;
gettimeofday(&tp, 0);
header.volumeInfo.creationDate = tp.tv_sec;
- if (FDH_SEEK(fdP, 0, SEEK_SET) < 0) {
- Abort
- ("Unable to seek to beginning of volume header file (%s) (errno = %d)\n",
- sp->description, errno);
- }
nBytes =
- FDH_WRITE(fdP, (char *)&header.volumeInfo,
- sizeof(header.volumeInfo));
+ FDH_PWRITE(fdP, (char *)&header.volumeInfo,
+ sizeof(header.volumeInfo), 0);
if (nBytes != sizeof(header.volumeInfo)) {
if (nBytes < 0)
Abort
sp->description);
}
} else {
- if (FDH_SEEK(fdP, 0, SEEK_SET) < 0) {
- Abort
- ("Unable to seek to beginning of volume header file (%s) (errno = %d)\n",
- sp->description, errno);
- }
- nBytes = FDH_WRITE(fdP, (char *)&sp->stamp, sizeof(sp->stamp));
+ nBytes = FDH_PWRITE(fdP, (char *)&sp->stamp, sizeof(sp->stamp), 0);
if (nBytes != sizeof(sp->stamp)) {
if (nBytes < 0)
Abort
struct ViceInodeInfo *ip, int nInodes,
struct VolumeSummary *volSummary, int check)
{
- VolumeId volumeNumber;
char buf[SIZEOF_LARGEDISKVNODE];
struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf;
int err = 0;
IHandle_t *handle;
FdHandle_t *fdP;
- volumeNumber = volSummary->header.id;
IH_INIT(handle, salvinfo->fileSysDevice, volSummary->header.parent, ino);
fdP = IH_OPEN(handle);
- assert(fdP != NULL);
+ osi_Assert(fdP != NULL);
file = FDH_FDOPEN(fdP, "r+");
- assert(file != NULL);
+ osi_Assert(file != NULL);
vcp = &VnodeClassInfo[class];
size = OS_SIZE(fdP->fd_fd);
- assert(size != -1);
+ osi_Assert(size != -1);
nVnodes = (size / vcp->diskSize) - 1;
if (nVnodes > 0) {
- assert((nVnodes + 1) * vcp->diskSize == size);
- assert(STREAM_SEEK(file, vcp->diskSize, 0) == 0);
+ osi_Assert((nVnodes + 1) * vcp->diskSize == size);
+ osi_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
} else {
nVnodes = 0;
}
if (vnode->type != vNull) {
int vnodeChanged = 0;
int vnodeNumber = bitNumberToVnodeNumber(vnodeIndex, class);
- /* Log programs that belong to root (potentially suid root);
- * don't bother for read-only or backup volumes */
-#ifdef notdef /* This is done elsewhere */
- if (ShowRootFiles && RW && vnode->owner == 0 && vnodeNumber != 1)
- Log("OWNER IS ROOT %s %u dir %u vnode %u author %u owner %u mode %o\n", salvinfo->VolInfo.name, volumeNumber, vnode->parent, vnodeNumber, vnode->author, vnode->owner, vnode->modeBits);
-#endif
if (VNDISK_GET_INO(vnode) == 0) {
if (RW) {
/* Log("### DEBUG ### Deleted Vnode with 0 inode (vnode %d)\n", vnodeNumber); */
} 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);
ip++;
nInodes--;
} else { /* no matching inode */
+ afs_ino_str_t stmp;
if (VNDISK_GET_INO(vnode) != 0
|| vnode->type == vDirectory) {
/* No matching inode--get rid of the vnode */
if (check) {
if (VNDISK_GET_INO(vnode)) {
if (!Showmode) {
- Log("Vnode %d (unique %u): corresponding inode %s is missing\n", vnodeNumber, vnode->uniquifier, PrintInode(NULL, VNDISK_GET_INO(vnode)));
+ Log("Vnode %d (unique %u): corresponding inode %s is missing\n", vnodeNumber, vnode->uniquifier, PrintInode(stmp, VNDISK_GET_INO(vnode)));
}
} else {
if (!Showmode)
if (VNDISK_GET_INO(vnode)) {
if (!Showmode) {
time_t serverModifyTime = vnode->serverModifyTime;
- Log("Vnode %d (unique %u): corresponding inode %s is missing; vnode deleted, vnode mod time=%s", vnodeNumber, vnode->uniquifier, PrintInode(NULL, VNDISK_GET_INO(vnode)), ctime(&serverModifyTime));
+ Log("Vnode %d (unique %u): corresponding inode %s is missing; vnode deleted, vnode mod time=%s", vnodeNumber, vnode->uniquifier, PrintInode(stmp, VNDISK_GET_INO(vnode)), ctime(&serverModifyTime));
}
} else {
if (!Showmode) {
}
} /* VNDISK_GET_INO(vnode) != 0 */
vnodeDone:
- assert(!(vnodeChanged && check));
+ osi_Assert(!(vnodeChanged && check));
if (vnodeChanged && !Testing) {
- assert(IH_IWRITE
+ osi_Assert(IH_IWRITE
(handle, vnodeIndexOffset(vcp, vnodeNumber),
(char *)vnode, vcp->diskSize)
== vcp->diskSize);
IH_IREAD(salvinfo->vnodeInfo[vLarge].handle,
vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode,
sizeof(vnode));
- assert(code == sizeof(vnode));
+ osi_Assert(code == sizeof(vnode));
oldinode = VNDISK_GET_INO(&vnode);
/* Increment the version number by a whole lot to avoid problems with
* clients that were promised new version numbers--but the file server
IH_CREATE(dir->ds_linkH, salvinfo->fileSysDevice, salvinfo->fileSysPath, 0, dir->rwVid,
dir->vnodeNumber, vnode.uniquifier, vnode.dataVersion +=
200);
- assert(VALID_INO(newinode));
- assert(CopyInode(salvinfo->fileSysDevice, oldinode, newinode, dir->rwVid) == 0);
+ osi_Assert(VALID_INO(newinode));
+ osi_Assert(CopyInode(salvinfo->fileSysDevice, oldinode, newinode, dir->rwVid) == 0);
vnode.cloned = 0;
VNDISK_SET_INO(&vnode, newinode);
code =
IH_IWRITE(salvinfo->vnodeInfo[vLarge].handle,
vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode,
sizeof(vnode));
- assert(code == sizeof(vnode));
+ osi_Assert(code == sizeof(vnode));
SetSalvageDirHandle(&dir->dirHandle, dir->dirHandle.dirh_handle->ih_vid,
salvinfo->fileSysDevice, newinode,
IH_IREAD(salvinfo->vnodeInfo[vLarge].handle,
vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode,
sizeof(vnode));
- assert(lcode == sizeof(vnode));
+ osi_Assert(lcode == sizeof(vnode));
oldinode = VNDISK_GET_INO(&vnode);
/* Increment the version number by a whole lot to avoid problems with
* clients that were promised new version numbers--but the file server
IH_CREATE(dir->ds_linkH, salvinfo->fileSysDevice, salvinfo->fileSysPath, 0, dir->rwVid,
dir->vnodeNumber, vnode.uniquifier, vnode.dataVersion +=
200);
- assert(VALID_INO(newinode));
+ osi_Assert(VALID_INO(newinode));
SetSalvageDirHandle(&newdir, dir->rwVid, salvinfo->fileSysDevice, newinode,
&salvinfo->VolumeChanged);
if (code) {
Log("also failed to decrement link count on new inode");
}
- assert(1 == 2);
+ osi_Assert(1 == 2);
}
Log("Checking the results of the directory salvage...\n");
if (!DirOK(&newdir)) {
Log("Directory salvage failed!!!; restoring old version of the directory.\n");
code = IH_DEC(dir->ds_linkH, newinode, dir->rwVid);
- assert(code == 0);
- assert(1 == 2);
+ osi_Assert(code == 0);
+ osi_Assert(1 == 2);
}
vnode.cloned = 0;
VNDISK_SET_INO(&vnode, newinode);
IH_IWRITE(salvinfo->vnodeInfo[vLarge].handle,
vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode,
sizeof(vnode));
- assert(lcode == sizeof(vnode));
+ osi_Assert(lcode == sizeof(vnode));
#if 0
#ifdef AFS_NT40_ENV
nt_sync(salvinfo->fileSysDevice);
FDH_REALLYCLOSE(fdP);
code = IH_DEC(dir->ds_linkH, oldinode, dir->rwVid);
- assert(code == 0);
+ osi_Assert(code == 0);
dir->dirHandle = newdir;
}
vnodeEssence = CheckVnodeNumber(salvinfo, vnodeNumber);
if (vnodeEssence == NULL) {
if (!Showmode) {
- Log("dir vnode %u: invalid entry deleted: %s/%s (vnode %u, unique %u)\n", dir->vnodeNumber, dir->name ? dir->name : "??", name, vnodeNumber, unique);
+ Log("dir vnode %u: invalid entry deleted: %s" OS_DIRSEP "%s (vnode %u, unique %u)\n", dir->vnodeNumber, dir->name ? dir->name : "??", name, vnodeNumber, unique);
}
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(Delete(&dir->dirHandle, name) == 0);
}
return 0;
}
* the machine.
*/
if (vnodeEssence->InodeNumber == 0) {
- Log("dir vnode %d: invalid entry: %s/%s has no inode (vnode %d, unique %d)%s\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique, (Testing ? "-- would have deleted" : " -- deleted"));
+ Log("dir vnode %d: invalid entry: %s" OS_DIRSEP "%s has no inode (vnode %d, unique %d)%s\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique, (Testing ? "-- would have deleted" : " -- deleted"));
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(Delete(&dir->dirHandle, name) == 0);
}
return 0;
}
if (!(vnodeNumber & 1) && !Showmode
&& !(vnodeEssence->count || vnodeEssence->unique
|| vnodeEssence->modeBits)) {
- Log("dir vnode %u: invalid entry: %s/%s (vnode %u, unique %u)%s\n",
+ Log("dir vnode %u: invalid entry: %s" OS_DIRSEP "%s (vnode %u, unique %u)%s\n",
dir->vnodeNumber, (dir->name ? dir->name : "??"), name,
vnodeNumber, unique,
((!unique) ? (Testing ? "-- would have deleted" : " -- deleted") :
if (!unique) {
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(Delete(&dir->dirHandle, name) == 0);
}
return 0;
}
todelete = ((!vnodeEssence->unique || dirOrphaned) ? 1 : 0);
if (!Showmode) {
- Log("dir vnode %u: %s/%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")));
+ 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);
- assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(Delete(&dir->dirHandle, name) == 0);
if (!todelete)
- assert(Create(&dir->dirHandle, name, &fid) == 0);
+ osi_Assert(Create(&dir->dirHandle, name, &fid) == 0);
}
if (todelete)
return 0; /* no need to continue */
Log("directory vnode %u.%u: bad '.' entry (was %u.%u); fixed\n", dir->vnodeNumber, dir->unique, vnodeNumber, unique);
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- assert(Delete(&dir->dirHandle, ".") == 0);
+ osi_Assert(Delete(&dir->dirHandle, ".") == 0);
fid.Vnode = dir->vnodeNumber;
fid.Unique = dir->unique;
- assert(Create(&dir->dirHandle, ".", &fid) == 0);
+ osi_Assert(Create(&dir->dirHandle, ".", &fid) == 0);
}
vnodeNumber = fid.Vnode; /* Get the new Essence */
struct VnodeEssence *dotdot;
pa.Vnode = dir->parent;
dotdot = CheckVnodeNumber(salvinfo, pa.Vnode);
- assert(dotdot != NULL); /* XXX Should not be assert */
+ osi_Assert(dotdot != NULL); /* XXX Should not be assert */
pa.Unique = dotdot->unique;
} else {
pa.Vnode = dir->vnodeNumber;
Log("directory vnode %u.%u: bad '..' entry (was %u.%u); fixed\n", dir->vnodeNumber, dir->unique, vnodeNumber, unique);
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- assert(Delete(&dir->dirHandle, "..") == 0);
- assert(Create(&dir->dirHandle, "..", &pa) == 0);
+ osi_Assert(Delete(&dir->dirHandle, "..") == 0);
+ osi_Assert(Create(&dir->dirHandle, "..", &pa) == 0);
}
vnodeNumber = pa.Vnode; /* Get the new Essence */
}
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(Delete(&dir->dirHandle, name) == 0);
}
vnodeEssence->claimed = 0; /* Not claimed: Orphaned */
vnodeEssence->todelete = 1; /* Will later delete vnode and decr inode */
return 0;
} else {
if (ShowSuid && (vnodeEssence->modeBits & 06000))
- Log("FOUND suid/sgid file: %s/%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);
+ 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;
if (size > 1024)
size = 1024;
- nBytes = FDH_READ(fdP, buf, size);
+ nBytes = FDH_PREAD(fdP, buf, size, 0);
if (nBytes == size) {
buf[size] = '\0';
if ( (*buf != '#' && *buf != '%') || buf[strlen(buf)-1] != '.' ) {
- Log("Volume %u (%s) mount point %s/%s to '%s' invalid, %s to symbolic link\n",
+ Log("Volume %u (%s) mount point %s" OS_DIRSEP "%s to '%s' invalid, %s to symbolic link\n",
dir->dirHandle.dirh_handle->ih_vid, dir->vname, dir->name ? dir->name : "??", name, buf,
Testing ? "would convert" : "converted");
vnodeEssence->modeBits |= 0111;
vnodeEssence->changed = 1;
- } else if (ShowMounts) Log("In volume %u (%s) found mountpoint %s/%s to '%s'\n",
+ } else if (ShowMounts) Log("In volume %u (%s) found mountpoint %s" OS_DIRSEP "%s to '%s'\n",
dir->dirHandle.dirh_handle->ih_vid, dir->vname,
dir->name ? dir->name : "??", name, buf);
} else {
IH_RELEASE(ihP);
}
if (ShowRootFiles && vnodeEssence->owner == 0 && vnodeNumber != 1)
- Log("FOUND root file: %s/%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);
+ Log("FOUND root 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 (vnodeIdToClass(vnodeNumber) == vLarge
&& vnodeEssence->name == NULL) {
char *n;
* another non-orphaned dir).
*/
if (!Showmode) {
- Log("dir vnode %u: %s/%s (vnode %u, unique %u) -- parent vnode %schanged from %u to %u\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique, (Testing ? "would have been " : ""), vnodeEssence->parent, dir->vnodeNumber);
+ Log("dir vnode %u: %s" OS_DIRSEP "%s (vnode %u, unique %u) -- parent vnode %schanged from %u to %u\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique, (Testing ? "would have been " : ""), vnodeEssence->parent, dir->vnodeNumber);
}
vnodeEssence->parent = dir->vnodeNumber;
vnodeEssence->changed = 1;
/* Vnode was claimed by another directory */
if (!Showmode) {
if (dirOrphaned) {
- Log("dir vnode %u: %s/%s parent vnode is %u (vnode %u, unique %u) -- %sdeleted\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeEssence->parent, vnodeNumber, unique, (Testing ? "would have been " : ""));
+ Log("dir vnode %u: %s" OS_DIRSEP "%s parent vnode is %u (vnode %u, unique %u) -- %sdeleted\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeEssence->parent, vnodeNumber, unique, (Testing ? "would have been " : ""));
} else if (vnodeNumber == 1) {
- Log("dir vnode %d: %s/%s is invalid (vnode %d, unique %d) -- %sdeleted\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique, (Testing ? "would have been " : ""));
+ Log("dir vnode %d: %s" OS_DIRSEP "%s is invalid (vnode %d, unique %d) -- %sdeleted\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeNumber, unique, (Testing ? "would have been " : ""));
} else {
- Log("dir vnode %u: %s/%s already claimed by directory vnode %u (vnode %u, unique %u) -- %sdeleted\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeEssence->parent, vnodeNumber, unique, (Testing ? "would have been " : ""));
+ Log("dir vnode %u: %s" OS_DIRSEP "%s already claimed by directory vnode %u (vnode %u, unique %u) -- %sdeleted\n", dir->vnodeNumber, (dir->name ? dir->name : "??"), name, vnodeEssence->parent, vnodeNumber, unique, (Testing ? "would have been " : ""));
}
}
if (!Testing) {
CopyOnWrite(salvinfo, dir);
- assert(Delete(&dir->dirHandle, name) == 0);
+ osi_Assert(Delete(&dir->dirHandle, name) == 0);
}
return 0;
}
IH_INIT(vip->handle, salvinfo->fileSysDevice, rwVId, ino);
fdP = IH_OPEN(vip->handle);
- assert(fdP != NULL);
+ osi_Assert(fdP != NULL);
file = FDH_FDOPEN(fdP, "r+");
- assert(file != NULL);
+ osi_Assert(file != NULL);
size = OS_SIZE(fdP->fd_fd);
- assert(size != -1);
+ osi_Assert(size != -1);
vip->nVnodes = (size / vcp->diskSize) - 1;
if (vip->nVnodes > 0) {
- assert((vip->nVnodes + 1) * vcp->diskSize == size);
- assert(STREAM_SEEK(file, vcp->diskSize, 0) == 0);
- assert((vip->vnodes = (struct VnodeEssence *)
+ osi_Assert((vip->nVnodes + 1) * vcp->diskSize == size);
+ osi_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
+ osi_Assert((vip->vnodes = (struct VnodeEssence *)
calloc(vip->nVnodes, sizeof(struct VnodeEssence))) != NULL);
if (class == vLarge) {
- assert((vip->inodes = (Inode *)
+ osi_Assert((vip->inodes = (Inode *)
calloc(vip->nVnodes, sizeof(Inode))) != NULL);
} else {
vip->inodes = NULL;
}
if (vp->parent && vp->name && (parentvp = CheckVnodeNumber(salvinfo, vp->parent))
&& GetDirName(salvinfo, vp->parent, parentvp, path)) {
- strcat(path, "/");
+ strcat(path, OS_DIRSEP);
strcat(path, vp->name);
return path;
}
judge_params.salvinfo = salvinfo;
judge_params.dir = &dir;
- assert(EnumerateDir(&dirHandle, JudgeEntry, &judge_params) == 0);
+ osi_Assert(EnumerateDir(&dirHandle, JudgeEntry, &judge_params) == 0);
}
/* Delete the old directory if it was copied in order to salvage.
DFlush();
if (dir.copied && !Testing) {
code = IH_DEC(dir.ds_linkH, dirHandle.dirh_handle->ih_ino, rwVid);
- assert(code == 0);
+ osi_Assert(code == 0);
dirVnodeInfo->inodes[i] = dir.dirHandle.dirh_inode;
}
salvinfo->vnodeInfo[vLarge].vnodes = calloc(1, sizeof(struct VnodeEssence));
salvinfo->vnodeInfo[vLarge].inodes = calloc(1, sizeof(Inode));
- assert(salvinfo->vnodeInfo[vLarge].vnodes);
- assert(salvinfo->vnodeInfo[vLarge].inodes);
+ osi_Assert(salvinfo->vnodeInfo[vLarge].vnodes);
+ osi_Assert(salvinfo->vnodeInfo[vLarge].inodes);
}
vep = &salvinfo->vnodeInfo[vLarge].vnodes[vnodeIdToBitNumber(1)];
vid = rwIsp->volSummary->header.id;
IH_INIT(h, salvinfo->fileSysDevice, vid, rwIsp->volSummary->header.volumeInfo);
nBytes = IH_IREAD(h, 0, (char *)&volHeader, sizeof(volHeader));
- assert(nBytes == sizeof(volHeader));
- assert(volHeader.stamp.magic == VOLUMEINFOMAGIC);
- assert(volHeader.destroyMe != DESTROY_ME);
+ osi_Assert(nBytes == sizeof(volHeader));
+ osi_Assert(volHeader.stamp.magic == VOLUMEINFOMAGIC);
+ osi_Assert(volHeader.destroyMe != DESTROY_ME);
/* (should not have gotten this far with DESTROY_ME flag still set!) */
DistilVnodeEssence(salvinfo, vid, vLarge,
&salvinfo->VolumeChanged);
pa.Vnode = LFVnode;
pa.Unique = LFUnique;
- assert(Delete(&dh, "..") == 0);
- assert(Create(&dh, "..", &pa) == 0);
+ osi_Assert(Delete(&dh, "..") == 0);
+ osi_Assert(Create(&dh, "..", &pa) == 0);
/* The original parent's link count was decremented above.
* Here we increment the new parent's link count.
ThisUnique += 50; /* Try creating a different file */
}
- assert(code == 0);
+ osi_Assert(code == 0);
Log("Attaching orphaned %s to volume's root dir as %s\n",
((class == vLarge) ? "directory" : "file"), npath);
}
code =
IH_DEC(oldrootdir.ds_linkH, oldrootdir.dirHandle.dirh_inode,
oldrootdir.rwVid);
- assert(code == 0);
+ osi_Assert(code == 0);
/* dirVnodeInfo->inodes[?] is not updated with new inode number */
}
* 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;
IH_IREAD(salvinfo->vnodeInfo[class].handle,
vnodeIndexOffset(vcp, vnodeNumber),
(char *)&vnode, sizeof(vnode));
- assert(nBytes == sizeof(vnode));
+ osi_Assert(nBytes == sizeof(vnode));
vnode.parent = vnp->parent;
oldCount = vnode.linkCount;
if (orphaned) {
if (!vnp->todelete) {
/* Orphans should have already been attached (if requested) */
- assert(orphans != ORPH_ATTACH);
+ osi_Assert(orphans != ORPH_ATTACH);
oblocks += vnp->blockCount;
ofiles++;
}
if (VNDISK_GET_INO(&vnode)) {
code =
IH_DEC(alinkH, VNDISK_GET_INO(&vnode), vid);
- assert(code == 0);
+ osi_Assert(code == 0);
}
memset(&vnode, 0, sizeof(vnode));
}
IH_IWRITE(salvinfo->vnodeInfo[class].handle,
vnodeIndexOffset(vcp, vnodeNumber),
(char *)&vnode, sizeof(vnode));
- assert(nBytes == sizeof(vnode));
+ osi_Assert(nBytes == sizeof(vnode));
}
salvinfo->VolumeChanged = 1;
}
}
#ifdef FSSYNC_BUILD_CLIENT
- if (!Testing && salvinfo->VolumeChanged) {
+ if (!Testing && salvinfo->VolumeChanged && salvinfo->useFSYNC) {
afs_int32 fsync_code;
fsync_code = FSYNC_VolOp(vid, NULL, FSYNC_VOL_BREAKCBKS, FSYNC_SALVAGE, NULL);
salvinfo->VolumeChanged = 0;
if (!Testing) {
nBytes = IH_IWRITE(h, 0, (char *)&volHeader, sizeof(volHeader));
- assert(nBytes == sizeof(volHeader));
+ osi_Assert(nBytes == sizeof(volHeader));
}
if (!Showmode) {
Log("%sSalvaged %s (%u): %d files, %d blocks\n",
VolumeDiskData volHeader;
nBytes = IH_IREAD(h, 0, (char *)&volHeader, sizeof(volHeader));
- assert(nBytes == sizeof(volHeader));
- assert(volHeader.stamp.magic == VOLUMEINFOMAGIC);
+ osi_Assert(nBytes == sizeof(volHeader));
+ osi_Assert(volHeader.stamp.magic == VOLUMEINFOMAGIC);
volHeader.inUse = 0;
volHeader.needsSalvaged = 0;
volHeader.inService = 1;
volHeader.dontSalvage = DONT_SALVAGE;
if (!Testing) {
nBytes = IH_IWRITE(h, 0, (char *)&volHeader, sizeof(volHeader));
- assert(nBytes == sizeof(volHeader));
+ osi_Assert(nBytes == sizeof(volHeader));
}
}
if (!Testing) {
afs_int32 code;
char path[64];
- sprintf(path, "%s/%s", salvinfo->fileSysPath, isp->volSummary->fileName);
+ sprintf(path, "%s" OS_DIRSEP "%s", salvinfo->fileSysPath, isp->volSummary->fileName);
code = VDestroyVolumeDiskHeader(salvinfo->fileSysPartition, isp->volumeId, isp->RWvolumeId);
if (code) {
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) {
}
}
-#ifdef AFS_DEMAND_ATTACH_FS
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
/**
* Locks a volume on disk for salvaging.
*
* case). But if it's there enough that we can read it, but
* somehow we cannot write to it to signify we're salvaging it,
* we've got a big problem and we cannot continue. */
- assert(IH_IWRITE(h, 0, (char*)&volHeader, sizeof(volHeader)) == sizeof(volHeader));
+ osi_Assert(IH_IWRITE(h, 0, (char*)&volHeader, sizeof(volHeader)) == sizeof(volHeader));
IH_RELEASE(h);
}
return 0;
}
-#endif /* AFS_DEMAND_ATTACH_FS */
+#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
void
AskOffline(struct SalvInfo *salvinfo, VolumeId volumeId)
if (code == SYNC_OK) {
break;
} else if (code == SYNC_DENIED) {
-#ifdef DEMAND_ATTACH_ENABLE
- Log("AskOffline: file server denied offline request; a general salvage may be required.\n");
-#else
- Log("AskOffline: file server denied offline request; a general salvage is required.\n");
-#endif
+ if (AskDAFS())
+ Log("AskOffline: file server denied offline request; a general salvage may be required.\n");
+ else
+ Log("AskOffline: file server denied offline request; a general salvage is required.\n");
Abort("Salvage aborted\n");
} else if (code == SYNC_BAD_COMMAND) {
Log("AskOffline: fssync protocol mismatch (bad command word '%d'); salvage aborting.\n",
FSYNC_VOL_OFF);
-#ifdef DEMAND_ATTACH_ENABLE
- Log("AskOffline: please make sure fileserver, volserver, salvageserver and salvager binaries are same version.\n");
+ if (AskDAFS()) {
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+ 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)
+ 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");
+ Log("AskOffline: please make sure fileserver, volserver and salvager binaries are same version.\n");
#endif
+ }
Abort("Salvage aborted\n");
} else if (i < 2) {
/* try it again */
}
}
+/* don't want to pass around state; remember it here */
+static int isDAFS = -1;
+int
+AskDAFS(void)
+{
+ afs_int32 code, i, ret = 0;
+ SYNC_response res;
+
+ /* we don't care if we race. the answer shouldn't change */
+ if (isDAFS != -1)
+ return isDAFS;
+
+ 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;
+ } else if (i < 2) {
+ /* try it again */
+ Log("AskDAFS: request to query fileserver failed; trying again...\n");
+ FSYNC_clientFinis();
+ FSYNC_clientInit();
+ }
+ }
+
+ isDAFS = ret;
+ return ret;
+}
+
+static void
+MaybeAskOnline(struct SalvInfo *salvinfo, VolumeId volumeId)
+{
+ struct VolumeDiskHeader diskHdr;
+ int code;
+ code = VReadVolumeDiskHeader(volumeId, salvinfo->fileSysPartition, &diskHdr);
+ if (code) {
+ /* volume probably does not exist; no need to bring back online */
+ return;
+ }
+ AskOnline(salvinfo, volumeId);
+}
+
void
AskOnline(struct SalvInfo *salvinfo, VolumeId volumeId)
{
} else if (code == SYNC_BAD_COMMAND) {
Log("AskOnline: fssync protocol mismatch (bad command word '%d')\n",
FSYNC_VOL_ON);
-#ifdef DEMAND_ATTACH_ENABLE
- Log("AskOnline: please make sure fileserver, volserver, salvageserver and salvager binaries are same version.\n");
+ Log("AskOnline: please make sure file server binaries are same version.\n");
+ break;
+ } else if (i < 2) {
+ /* try it again */
+ 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;
+ SYNC_response res;
+
+ for (i = 0; i < 3; i++) {
+ memset(&res, 0, sizeof(res));
+ code = FSYNC_VolOp(volumeId, salvinfo->fileSysPartition->name,
+ FSYNC_VOL_DONE, FSYNC_SALVAGE, &res);
+
+ 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);
+ if (AskDAFS()) {
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+ Log("AskOnline: please make sure dafileserver, davolserver, salvageserver and dasalvager binaries are same version.\n");
#else
- Log("AskOnline: please make sure fileserver, volserver and salvager binaries are same version.\n");
+ Log("AskOnline: fileserver is DAFS but we are not.\n");
#endif
+ } else {
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
+ 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");
+#endif
+ }
+ break;
+ } else if (code == SYNC_FAILED &&
+ (res.hdr.reason == FSYNC_UNKNOWN_VOLID ||
+ res.hdr.reason == FSYNC_WRONG_PART)) {
+ /* volume is already effectively 'deleted' */
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 delete volume failed; trying again...\n");
FSYNC_clientFinis();
FSYNC_clientInit();
}
IHandle_t *srcH, *destH;
FdHandle_t *srcFdP, *destFdP;
ssize_t nBytes = 0;
+ afs_foff_t size = 0;
IH_INIT(srcH, device, rwvolume, inode1);
srcFdP = IH_OPEN(srcH);
- assert(srcFdP != NULL);
+ osi_Assert(srcFdP != NULL);
IH_INIT(destH, device, rwvolume, inode2);
destFdP = IH_OPEN(destH);
- while ((nBytes = FDH_READ(srcFdP, buf, sizeof(buf))) > 0)
- assert(FDH_WRITE(destFdP, buf, nBytes) == nBytes);
- assert(nBytes == 0);
+ while ((nBytes = FDH_PREAD(srcFdP, buf, sizeof(buf), size)) > 0) {
+ osi_Assert(FDH_PWRITE(destFdP, buf, nBytes, size) == nBytes);
+ size += nBytes;
+ }
+ osi_Assert(nBytes == 0);
FDH_REALLYCLOSE(srcFdP);
FDH_REALLYCLOSE(destFdP);
IH_RELEASE(srcH);
{
struct ViceInodeInfo *ip;
struct ViceInodeInfo *buf;
- struct afs_stat status;
int nInodes;
-
- assert(afs_fstat(salvinfo->inodeFd, &status) == 0);
- buf = (struct ViceInodeInfo *)malloc(status.st_size);
- assert(buf != NULL);
- nInodes = status.st_size / sizeof(struct ViceInodeInfo);
- assert(read(salvinfo->inodeFd, buf, status.st_size) == status.st_size);
+ afs_ino_str_t stmp;
+ afs_sfsize_t st_size;
+
+ st_size = OS_SIZE(salvinfo->inodeFd);
+ osi_Assert(st_size >= 0);
+ buf = (struct ViceInodeInfo *)malloc(st_size);
+ osi_Assert(buf != NULL);
+ nInodes = st_size / sizeof(struct ViceInodeInfo);
+ osi_Assert(OS_READ(salvinfo->inodeFd, buf, st_size) == st_size);
for (ip = buf; nInodes--; ip++) {
Log("Inode:%s, linkCount=%d, size=%#llx, p=(%u,%u,%u,%u)\n",
- PrintInode(NULL, ip->inodeNumber), ip->linkCount,
+ PrintInode(stmp, ip->inodeNumber), ip->linkCount,
(afs_uintmax_t) ip->byteCount, ip->u.param[0], ip->u.param[1],
ip->u.param[2], ip->u.param[3]);
}
int f;
#ifdef AFS_NT40_ENV
f = 0;
- assert(0); /* Fork is never executed in the NT code path */
+ osi_Assert(0); /* Fork is never executed in the NT code path */
#else
f = fork();
- assert(f >= 0);
+ osi_Assert(f >= 0);
#ifdef AFS_DEMAND_ATTACH_FS
if ((f == 0) && (programType == salvageServer)) {
/* we are a salvageserver child */
int status;
int pid;
pid = wait(&status);
- assert(pid != -1);
+ osi_Assert(pid != -1);
if (WCOREDUMP(status))
Log("\"%s\" core dumped!\n", prog);
if (WIFSIGNALED(status) != 0 || WEXITSTATUS(status) != 0)
{
char *p;
p = (char *)malloc(strlen(s) + 1);
- assert(p != NULL);
+ osi_Assert(p != NULL);
strcpy(p, s);
return p;
}
RemoveTheForce(char *path)
{
char target[1024];
- struct afs_stat force; /* so we can use afs_stat to find it */
+ struct afs_stat_st force; /* so we can use afs_stat to find it */
strcpy(target,path);
strcat(target,"/FORCESALVAGE");
if (!Testing && ForceSalvage) {
int
UseTheForceLuke(char *path)
{
- struct afs_stat force;
+ struct afs_stat_st force;
char target[1024];
strcpy(target,path);
strcat(target,"/FORCESALVAGE");