#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
#ifndef AFS_NT40_ENV
#include <sys/param.h>
#include <afs/osi_inode.h>
#endif
#include <afs/cmd.h>
+#include <afs/dir.h>
#include <afs/afsutil.h>
#include <afs/fileutil.h>
#include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
#include "salvage.h"
#include "volinodes.h" /* header magic number, etc. stuff */
#include "vol-salvage.h"
+#include "vol_internal.h"
+
#ifdef AFS_NT40_ENV
#include <pthread.h>
#endif
int orphans = ORPH_IGNORE; /* -orphans option */
int Showmode = 0;
+
#ifndef AFS_NT40_ENV
int useSyslog = 0; /* -syslog flag */
int useSyslogFacility = LOG_DAEMON; /* -syslogfacility option */
#endif
+#ifdef AFS_NT40_ENV
+int canfork = 0;
+#else
+int canfork = 1;
+#endif
+
#define MAXPARALLEL 32
int OKToZap; /* -o flag */
char *fileSysPathName; /* NT needs this to make name pretty in log. */
IHandle_t *VGLinkH; /* Link handle for current volume group. */
int VGLinkH_cnt; /* # of references to lnk handle. */
-struct DiskPartition *fileSysPartition; /* Partition being salvaged */
+struct DiskPartition64 *fileSysPartition; /* Partition being salvaged */
#ifndef AFS_NT40_ENV
char *fileSysDeviceName; /* The block device where the file system
* being salvaged was mounted */
return 0; /* otherwise may be transient, e.g. EMFILE */
}
-
#define MAX_ARGS 128
#ifdef AFS_NT40_ENV
char *save_args[MAX_ARGS];
int n_save_args = 0;
-pthread_t main_thread;
+extern pthread_t main_thread;
+childJob_t myjob = { SALVAGER_MAGIC, NOT_CHILD, "" };
#endif
-
/* Get the salvage lock if not already held. Hold until process exits. */
void
ObtainSalvageLock(void)
{
- int salvageLock;
+ FD_t salvageLock;
#ifdef AFS_NT40_ENV
salvageLock =
- (int)CreateFile(AFSDIR_SERVER_SLVGLOCK_FILEPATH, 0, 0, NULL,
+ (FD_t)CreateFile(AFSDIR_SERVER_SLVGLOCK_FILEPATH, 0, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (salvageLock == (int)INVALID_HANDLE_VALUE) {
+ if (salvageLock == INVALID_FD) {
fprintf(stderr,
"salvager: There appears to be another salvager running! Aborted.\n");
Exit(1);
#define HDSTR "\\Device\\Harddisk"
#define HDLEN (sizeof(HDSTR)-1) /* Length of "\Device\Harddisk" */
int
-SameDisk(struct DiskPartition *p1, struct DiskPartition *p2)
+SameDisk(struct DiskPartition64 *p1, struct DiskPartition64 *p2)
{
#define RES_LEN 256
char res[RES_LEN];
* PartsPerDisk are on the same disk.
*/
void
-SalvageFileSysParallel(struct DiskPartition *partP)
+SalvageFileSysParallel(struct DiskPartition64 *partP)
{
struct job {
- struct DiskPartition *partP;
+ struct DiskPartition64 *partP;
int pid; /* Pid for this job */
int jobnumb; /* Log file job number */
struct job *nextjob; /* Next partition on disk to salvage */
void
-SalvageFileSys(struct DiskPartition *partP, VolumeId singleVolumeNumber)
+SalvageFileSys(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
{
if (!canfork || debug || Fork() == 0) {
SalvageFileSys1(partP, singleVolumeNumber);
}
void
-SalvageFileSys1(struct DiskPartition *partP, VolumeId singleVolumeNumber)
+SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
{
char *name, *tdir;
char inodeListPath[256];
if ((programType != salvageServer) && !VConnectFS()) {
Abort("Couldn't connect to file server\n");
}
- AskOffline(singleVolumeNumber);
+ AskOffline(singleVolumeNumber, partP->name);
} else {
if (!Showmode)
Log("SALVAGING FILE SYSTEM PARTITION %s (device=%s%s)\n",
* modified to actually do that so that the NT crt can be used there.
*/
inodeFd =
- _open_osfhandle((long)nt_open(inodeListPath, O_RDWR, 0), O_RDWR);
+ _open_osfhandle((intptr_t)nt_open(inodeListPath, O_RDWR, 0), O_RDWR);
nt_unlink(inodeListPath); /* NT's crt unlink won't if file is open. */
#else
inodeFd = afs_open(inodeListPath, O_RDONLY);
void
DeleteExtraVolumeHeaderFile(register struct VolumeSummary *vsp)
{
+ char path[64];
+ sprintf(path, "%s/%s", fileSysPath, vsp->fileName);
+
if (!Showmode)
- Log("The volume header file %s is not associated with any actual data (%sdeleted)\n", vsp->fileName, (Testing ? "would have been " : ""));
- if (!Testing)
- unlink(vsp->fileName);
+ Log("The volume header file %s is not associated with any actual data (%sdeleted)\n", path, (Testing ? "would have been " : ""));
+ if (!Testing) {
+ if (unlink(path)) {
+ Log("Unable to unlink %s (errno = %d)\n", path, errno);
+ }
+ }
vsp->fileName = 0;
}
+int
CompareInodes(const void *_p1, const void *_p2)
{
register const struct ViceInodeInfo *p1 = _p1;
CountVolumeInodes(register struct ViceInodeInfo *ip, int maxInodes,
register struct InodeSummary *summary)
{
- int volume = ip->u.vnode.volumeId;
- int rwvolume = volume;
- register n, nSpecial;
+ VolumeId volume = ip->u.vnode.volumeId;
+ VolumeId rwvolume = volume;
+ register int n, nSpecial;
register Unique maxunique;
n = nSpecial = 0;
maxunique = 0;
}
int
-OnlyOneVolume(struct ViceInodeInfo *inodeinfo, int singleVolumeNumber, void *rock)
+OnlyOneVolume(struct ViceInodeInfo *inodeinfo, afs_uint32 singleVolumeNumber, void *rock)
{
if (inodeinfo->u.vnode.vnodeNumber == INODESPECIAL)
return (inodeinfo->u.special.parentId == singleVolumeNumber);
void
GetVolumeSummary(VolumeId singleVolumeNumber)
{
- DIR *dirp;
+ DIR *dirp = NULL;
afs_int32 nvols = 0;
struct VolumeSummary *vsp, vs;
struct VolumeDiskHeader diskHeader;
struct dirent *dp;
/* Get headers from volume directory */
- if (chdir(fileSysPath) == -1 || (dirp = opendir(".")) == NULL)
+ dirp = opendir(fileSysPath);
+ if (dirp == NULL)
Abort("Can't read directory %s; not salvaged\n", fileSysPath);
if (!singleVolumeNumber) {
while ((dp = readdir(dirp))) {
p = strrchr(dp->d_name, '.');
if (p != NULL && strcmp(p, VHDREXT) == 0) {
int fd;
- if ((fd = afs_open(dp->d_name, O_RDONLY)) != -1
+ char name[64];
+ sprintf(name, "%s/%s", fileSysPath, dp->d_name);
+ if ((fd = afs_open(name, O_RDONLY)) != -1
&& read(fd, (char *)&diskHeader, sizeof(diskHeader))
== sizeof(diskHeader)
&& diskHeader.stamp.magic == VOLUMEHEADERMAGIC) {
if (p != NULL && strcmp(p, VHDREXT) == 0) {
int error = 0;
int fd;
- if ((fd = afs_open(dp->d_name, O_RDONLY)) == -1
+ char name[64];
+ sprintf(name, "%s/%s", fileSysPath, dp->d_name);
+ if ((fd = afs_open(name, O_RDONLY)) == -1
|| read(fd, &diskHeader, sizeof(diskHeader))
!= sizeof(diskHeader)
|| diskHeader.stamp.magic != VOLUMEHEADERMAGIC) {
if (error) {
if (!singleVolumeNumber) {
if (!Showmode)
- Log("%s/%s is not a legitimate volume header file; %sdeleted\n", fileSysPathName, dp->d_name, (Testing ? "it would have been " : ""));
- if (!Testing)
- unlink(dp->d_name);
+ Log("%s is not a legitimate volume header file; %sdeleted\n", name, (Testing ? "it would have been " : ""));
+ if (!Testing) {
+ if (unlink(name)) {
+ Log("Unable to unlink %s (errno = %d)\n", name, errno);
+ }
+ }
}
} else {
char nameShouldBe[64];
DiskToVolumeHeader(&vsp->header, &diskHeader);
if (singleVolumeNumber && vsp->header.id == singleVolumeNumber
&& vsp->header.parent != singleVolumeNumber) {
- Log("%u is a read-only volume; not salvaged\n",
- singleVolumeNumber);
- Exit(1);
+ if (programType == salvageServer) {
+#ifdef SALVSYNC_BUILD_CLIENT
+ Log("fileserver requested salvage of clone %u; scheduling salvage of volume group %u...\n",
+ vsp->header.id, vsp->header.parent);
+ if (SALVSYNC_LinkVolume(vsp->header.parent,
+ vsp->header.id,
+ fileSysPartition->name,
+ NULL) != SYNC_OK) {
+ Log("schedule request failed\n");
+ }
+#endif
+ Exit(SALSRV_EXIT_VOLGROUP_LINK);
+ } else {
+ Log("%u is a read-only volume; not salvaged\n",
+ singleVolumeNumber);
+ Exit(1);
+ }
}
if (!singleVolumeNumber
|| (vsp->header.id == singleVolumeNumber
|| vsp->header.parent == singleVolumeNumber)) {
(void)afs_snprintf(nameShouldBe, sizeof nameShouldBe,
- VFORMAT, vsp->header.id);
- if (singleVolumeNumber)
- AskOffline(vsp->header.id);
+ VFORMAT, afs_printable_uint32_lu(vsp->header.id));
+ if (singleVolumeNumber
+ && vsp->header.id != singleVolumeNumber)
+ AskOffline(vsp->header.id, fileSysPartition->name);
if (strcmp(nameShouldBe, dp->d_name)) {
if (!Showmode)
- Log("Volume header file %s is incorrectly named; %sdeleted (it will be recreated later, if necessary)\n", dp->d_name, (Testing ? "it would have been " : ""));
- if (!Testing)
- unlink(dp->d_name);
+ Log("Volume header file %s is incorrectly named; %sdeleted (it will be recreated later, if necessary)\n", name, (Testing ? "it would have been " : ""));
+ if (!Testing) {
+ if (unlink(name)) {
+ Log("Unable to unlink %s (errno = %d)\n", name, errno);
+ }
+ }
} else {
vsp->fileName = ToString(dp->d_name);
nVolumes++;
int check;
Inode ino;
int dec_VGLinkH = 0;
- int VGLinkH_p1;
+ int VGLinkH_p1 =0;
FdHandle_t *fdP = NULL;
VGLinkH_cnt = 0;
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
}
}
}
&& volHeader.stamp.magic == VOLUMEINFOMAGIC
&& volHeader.dontSalvage == DONT_SALVAGE
&& volHeader.needsSalvaged == 0 && volHeader.destroyMe == 0) {
- if (volHeader.inUse == 1) {
+ if (volHeader.inUse != 0) {
volHeader.inUse = 0;
volHeader.inService = 1;
if (!Testing) {
}
if (isp->volSummary == NULL) {
- char name[64];
- (void)afs_snprintf(name, sizeof name, VFORMAT, isp->volumeId);
+ 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", fileSysPath, headerName);
if (check) {
Log("No header file for volume %u\n", isp->volumeId);
return -1;
}
if (!Showmode)
- Log("No header file for volume %u; %screating %s/%s\n",
+ Log("No header file for volume %u; %screating %s\n",
isp->volumeId, (Testing ? "it would have been " : ""),
- fileSysPathName, name);
- headerFd = afs_open(name, O_RDWR | O_CREAT | O_TRUNC, 0644);
+ path);
+ headerFd = afs_open(path, O_RDWR | O_CREAT | O_TRUNC, 0644);
assert(headerFd != -1);
isp->volSummary = (struct VolumeSummary *)
malloc(sizeof(struct VolumeSummary));
- isp->volSummary->fileName = ToString(name);
+ isp->volSummary->fileName = ToString(headerName);
} else {
- char name[64];
+ char path[64];
+ char headerName[64];
/* hack: these two fields are obsolete... */
isp->volSummary->header.volumeAcl = 0;
isp->volSummary->header.volumeMountTable = 0;
sizeof(struct VolumeHeader))) {
/* We often remove the name before calling us, so we make a fake one up */
if (isp->volSummary->fileName) {
- strcpy(name, isp->volSummary->fileName);
+ strcpy(headerName, isp->volSummary->fileName);
} else {
- (void)afs_snprintf(name, sizeof name, VFORMAT, isp->volumeId);
- isp->volSummary->fileName = ToString(name);
+ (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", fileSysPath, headerName);
- Log("Header file %s is damaged or no longer valid%s\n", name,
+ Log("Header file %s is damaged or no longer valid%s\n", path,
(check ? "" : "; repairing"));
if (check)
return -1;
- headerFd = afs_open(name, O_RDWR | O_TRUNC, 0644);
+ headerFd = afs_open(path, O_RDWR | O_TRUNC, 0644);
assert(headerFd != -1);
}
}
struct VnodeClassInfo *vcp = &VnodeClassInfo[vLarge];
Inode oldinode, newinode;
DirHandle newdir;
+ FdHandle_t *fdP;
afs_int32 code;
afs_sfsize_t lcode;
afs_int32 parentUnique = 1;
struct VnodeEssence *vnodeEssence;
+ afs_fsize_t length;
if (Testing)
return;
}
vnode.cloned = 0;
VNDISK_SET_INO(&vnode, newinode);
- VNDISK_SET_LEN(&vnode, Length(&newdir));
+ length = Length(&newdir);
+ VNDISK_SET_LEN(&vnode, length);
lcode =
IH_IWRITE(vnodeInfo[vLarge].handle,
vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode,
sizeof(vnode));
assert(lcode == sizeof(vnode));
+#if 0
#ifdef AFS_NT40_ENV
nt_sync(fileSysDevice);
#else
* an open FD on the file itself to fsync.
*/
#endif
+#else
+ vnodeInfo[vLarge].handle->ih_synced = 1;
+#endif
+ /* make sure old directory file is really closed */
+ fdP = IH_OPEN(dir->dirHandle.dirh_handle);
+ FDH_REALLYCLOSE(fdP);
+
code = IH_DEC(dir->ds_linkH, oldinode, dir->rwVid);
assert(code == 0);
dir->dirHandle = newdir;
}
-void
-JudgeEntry(struct DirSummary *dir, char *name, VnodeId vnodeNumber,
- Unique unique)
+int
+JudgeEntry(void *dirVal, char *name, afs_int32 vnodeNumber,
+ afs_int32 unique)
{
+ struct DirSummary *dir = (struct DirSummary *)dirVal;
struct VnodeEssence *vnodeEssence;
afs_int32 dirOrphaned, todelete;
CopyOnWrite(dir);
assert(Delete(&dir->dirHandle, name) == 0);
}
- return;
+ return 0;
}
#ifdef AFS_AIX_ENV
#ifndef AFS_NAMEI_ENV
CopyOnWrite(dir);
assert(Delete(&dir->dirHandle, name) == 0);
}
- return;
+ return 0;
}
#endif
#endif
CopyOnWrite(dir);
assert(Delete(&dir->dirHandle, name) == 0);
}
- return;
+ return 0;
}
}
* entry. Otherwise, it will get created in the next
* salvage and deleted again here. So Just skip it.
*/
- return;
+ return 0;
}
todelete = ((!vnodeEssence->unique || dirOrphaned) ? 1 : 0);
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")));
}
if (!Testing) {
- ViceFid fid;
+ AFSFid fid;
fid.Vnode = vnodeNumber;
fid.Unique = vnodeEssence->unique;
CopyOnWrite(dir);
assert(Create(&dir->dirHandle, name, &fid) == 0);
}
if (todelete)
- return; /* no need to continue */
+ return 0; /* no need to continue */
}
if (strcmp(name, ".") == 0) {
if (dir->vnodeNumber != vnodeNumber || (dir->unique != unique)) {
- ViceFid fid;
+ AFSFid fid;
if (!Showmode)
Log("directory vnode %u.%u: bad '.' entry (was %u.%u); fixed\n", dir->vnodeNumber, dir->unique, vnodeNumber, unique);
if (!Testing) {
}
dir->haveDot = 1;
} else if (strcmp(name, "..") == 0) {
- ViceFid pa;
+ AFSFid pa;
if (dir->parent) {
struct VnodeEssence *dotdot;
pa.Vnode = dir->parent;
}
vnodeEssence->claimed = 0; /* Not claimed: Orphaned */
vnodeEssence->todelete = 1; /* Will later delete vnode and decr inode */
- return;
+ 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);
- if (ShowMounts && (vnodeEssence->type == vSymlink)
+ if (/* ShowMounts && */ (vnodeEssence->type == vSymlink)
&& !(vnodeEssence->modeBits & 0111)) {
int code, size;
- char buf[1024];
+ char buf[1025];
IHandle_t *ihP;
FdHandle_t *fdP;
IH_INIT(ihP, fileSysDevice, dir->dirHandle.dirh_handle->ih_vid,
vnodeEssence->InodeNumber);
fdP = IH_OPEN(ihP);
- assert(fdP != NULL);
+ if (fdP == NULL) {
+ Log("ERROR %s could not open mount point vnode %u\n", dir->vname, vnodeNumber);
+ IH_RELEASE(ihP);
+ return 0;
+ }
size = FDH_SIZE(fdP);
- assert(size != -1);
- memset(buf, 0, 1024);
+ if (size < 0) {
+ Log("ERROR %s mount point has invalid size %d, vnode %u\n", dir->vname, size, vnodeNumber);
+ FDH_REALLYCLOSE(fdP);
+ IH_RELEASE(ihP);
+ return 0;
+ }
+
if (size > 1024)
size = 1024;
code = FDH_READ(fdP, buf, size);
- assert(code == size);
- Log("In volume %u (%s) found mountpoint %s/%s to '%s'\n",
- dir->dirHandle.dirh_handle->ih_vid, dir->vname,
- dir->name ? dir->name : "??", name, buf);
+ if (code == 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",
+ 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",
+ dir->dirHandle.dirh_handle->ih_vid, dir->vname,
+ dir->name ? dir->name : "??", name, buf);
+ } else {
+ Log("Volume %s cound not read mount point vnode %u size %d code %d\n",
+ dir->vname, vnodeNumber, size, code);
+ }
FDH_REALLYCLOSE(fdP);
IH_RELEASE(ihP);
}
CopyOnWrite(dir);
assert(Delete(&dir->dirHandle, name) == 0);
}
- return;
+ return 0;
}
}
/* This directory claims the vnode */
vnodeEssence->claimed = 1;
}
vnodeEssence->count--;
+ return 0;
}
void
vep->owner = vnode->owner;
vep->group = vnode->group;
if (vnode->type == vDirectory) {
- assert(class == vLarge);
- vip->inodes[vnodeIndex] = VNDISK_GET_INO(vnode);
+ if (class != vLarge) {
+ VnodeId vnodeNumber = bitNumberToVnodeNumber(vnodeIndex, class);
+ vip->nAllocatedVnodes--;
+ memset(vnode, 0, sizeof(vnode));
+ IH_IWRITE(vnodeInfo[vSmall].handle,
+ vnodeIndexOffset(vcp, vnodeNumber),
+ (char *)&vnode, sizeof(vnode));
+ VolumeChanged = 1;
+ } else
+ vip->inodes[vnodeIndex] = VNDISK_GET_INO(vnode);
}
}
}
afs_int32 v, pv;
IHandle_t *h;
afs_sfsize_t nBytes;
- ViceFid pa;
+ AFSFid pa;
VnodeId LFVnode, ThisVnode;
Unique LFUnique, ThisUnique;
char npath[128];
SalvageDir(volHeader.name, vid, dirVnodeInfo, alinkH, i, &rootdir,
&rootdirfound);
}
+#ifdef AFS_NT40_ENV
+ nt_sync(fileSysDevice);
+#else
+ sync(); /* This used to be done lower level, for every dir */
+#endif
if (Showmode) {
IH_RELEASE(h);
return 0;
* won't be visible there.
*/
if (class == vLarge) {
- ViceFid pa;
+ AFSFid pa;
DirHandle dh;
/* Remove and recreate the ".." entry in this orphaned directory */
if (!Showmode) {
Log("Vnode %u: link count incorrect (was %d, %s %d)\n", vnodeNumber, oldCount, (Testing ? "would have changed to" : "now"), vnode.linkCount);
}
+ } else {
+ vnode.modeBits = vnp->modeBits;
}
vnode.dataVersion++;
if (!Showmode)
Log("it will be deleted instead. It should be recloned.\n");
}
- if (!Testing)
- unlink(isp->volSummary->fileName);
+ if (!Testing) {
+ char path[64];
+ sprintf(path, "%s/%s", fileSysPath, isp->volSummary->fileName);
+ if (unlink(path)) {
+ Log("Unable to unlink %s (errno = %d)\n", path, errno);
+ }
+ }
}
} else if (!check) {
Log("%s salvage was unsuccessful: read-write volume %u\n", message,
void
-AskOffline(VolumeId volumeId)
+AskOffline(VolumeId volumeId, char * partition)
{
afs_int32 code, i;
for (i = 0; i < 3; i++) {
- code = FSYNC_VolOp(volumeId, NULL, FSYNC_VOL_OFF, FSYNC_SALVAGE, NULL);
+ code = FSYNC_VolOp(volumeId, partition, FSYNC_VOL_OFF, FSYNC_SALVAGE, NULL);
if (code == SYNC_OK) {
break;
Log("AskOffline: request for fileserver to take volume offline failed; salvage aborting.\n");
Abort("Salvage aborted\n");
}
+
+#ifdef AFS_DEMAND_ATTACH_FS
+ /* set inUse = programType in the volume header. We do this in case
+ * the fileserver restarts/crashes while we are salvaging.
+ * Otherwise, the fileserver could attach the volume again on
+ * startup while we are salvaging, which would be very bad, or
+ * schedule another salvage while we are salvaging, which would be
+ * annoying. */
+ if (!Testing) {
+ int fd;
+ IHandle_t *h;
+ char name[VMAXPATHLEN];
+ struct VolumeHeader header;
+ struct VolumeDiskHeader diskHeader;
+ struct VolumeDiskData volHeader;
+
+ afs_snprintf(name, sizeof(name), "%s/" VFORMAT, fileSysPathName,
+ afs_printable_uint32_lu(volumeId));
+
+ fd = afs_open(name, O_RDONLY);
+ if (fd < 0) {
+ return;
+ }
+ if (read(fd, &diskHeader, sizeof(diskHeader)) != sizeof(diskHeader) ||
+ diskHeader.stamp.magic != VOLUMEHEADERMAGIC) {
+
+ close(fd);
+ return;
+ }
+ close(fd);
+
+ DiskToVolumeHeader(&header, &diskHeader);
+
+ IH_INIT(h, fileSysDevice, header.parent, header.volumeInfo);
+ if (IH_IREAD(h, 0, (char*)&volHeader, sizeof(volHeader)) != sizeof(volHeader) ||
+ volHeader.stamp.magic != VOLUMEINFOMAGIC) {
+
+ IH_RELEASE(h);
+ return;
+ }
+
+ volHeader.inUse = programType;
+
+ /* If we can't re-write the header, bail out and error. We don't
+ * assert when reading the header, since it's possible the
+ * header isn't really there (when there's no data associated
+ * with the volume; we just delete the vol header file in that
+ * 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));
+
+ IH_RELEASE(h);
+ }
+#endif /* AFS_DEMAND_ATTACH_FS */
}
void
register struct ViceInodeInfo *ip;
struct ViceInodeInfo *buf;
struct afs_stat status;
- register nInodes;
+ register int nInodes;
assert(afs_fstat(inodeFd, &status) == 0);
buf = (struct ViceInodeInfo *)malloc(status.st_size);
#else
f = fork();
assert(f >= 0);
+#ifdef AFS_DEMAND_ATTACH_FS
+ if ((f == 0) && (programType == salvageServer)) {
+ /* we are a salvageserver child */
+#ifdef FSSYNC_BUILD_CLIENT
+ VChildProcReconnectFS_r();
+#endif
+#ifdef SALVSYNC_BUILD_CLIENT
+ VReconnectSALV_r();
#endif
+ }
+#endif /* AFS_DEMAND_ATTACH_FS */
+#endif /* !AFS_NT40_ENV */
return f;
}
void
-Exit(code)
- int code;
+Exit(int code)
{
if (ShowLog)
showlog();
+
+#ifdef AFS_DEMAND_ATTACH_FS
+ if (programType == salvageServer) {
+#ifdef SALVSYNC_BUILD_CLIENT
+ VDisconnectSALV();
+#endif
+#ifdef FSSYNC_BUILD_CLIENT
+ VDisconnectFS();
+#endif
+ }
+#endif /* AFS_DEMAND_ATTACH_FS */
+
#ifdef AFS_NT40_ENV
if (main_thread != pthread_self())
pthread_exit((void *)code);
static char timestamp[20];
lt = localtime(&clock);
if (precision)
- (void)strftime(timestamp, 20, "%m/%d/%Y %T", lt);
+ (void)strftime(timestamp, 20, "%m/%d/%Y %H:%M:%S", lt);
else
(void)strftime(timestamp, 20, "%m/%d/%Y %H:%M", lt);
return timestamp;
}
#endif
- rewind(logFile);
- fclose(logFile);
+ if (logFile) {
+ rewind(logFile);
+ fclose(logFile);
+ }
logFile = afs_fopen(AFSDIR_SERVER_SLVGLOG_FILEPATH, "r");
syslog(LOG_INFO, "%s", tmp);
} else
#endif
- {
- gettimeofday(&now, 0);
- fprintf(logFile, "%s %s", TimeStamp(now.tv_sec, 1), tmp);
- fflush(logFile);
- }
+ if (logFile) {
+ gettimeofday(&now, 0);
+ fprintf(logFile, "%s %s", TimeStamp(now.tv_sec, 1), tmp);
+ fflush(logFile);
+ }
}
void
syslog(LOG_INFO, "%s", tmp);
} else
#endif
- {
- fprintf(logFile, "%s", tmp);
- fflush(logFile);
- if (ShowLog)
- showlog();
- }
+ if (logFile) {
+ fprintf(logFile, "%s", tmp);
+ fflush(logFile);
+ if (ShowLog)
+ showlog();
+ }
if (debug)
abort();
assert(p != NULL);
strcpy(p, s);
return p;
-
}
/* Remove the FORCESALVAGE file */
void
RemoveTheForce(char *path)
{
+ char target[1024];
+ struct afs_stat force; /* so we can use afs_stat to find it */
+ strcpy(target,path);
+ strcat(target,"/FORCESALVAGE");
if (!Testing && ForceSalvage) {
- if (chdir(path) == 0)
- unlink("FORCESALVAGE");
+ if (afs_stat(target,&force) == 0) unlink(target);
}
}
UseTheForceLuke(char *path)
{
struct afs_stat force;
+ char target[1024];
+ strcpy(target,path);
+ strcat(target,"/FORCESALVAGE");
- assert(chdir(path) != -1);
-
- return (afs_stat("FORCESALVAGE", &force) == 0);
+ return (afs_stat(target, &force) == 0);
}
#else
/*