* directory or online at http://www.openafs.org/dl/license10.html
*/
-#ifndef lint
-#endif
/*
* System: VICE-TWO
* Module: vol-salvage.c
/* Main program file. Define globals. */
#define MAIN 1
+#include <afsconfig.h>
#include <afs/param.h>
+
+RCSID("$Header$");
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#endif /* ITIMER_REAL */
#endif
-#if defined(AFS_AIX_ENV)
+#if defined(AFS_AIX_ENV) || defined(AFS_SUN4_ENV)
#define WCOREDUMP(x) (x & 0200)
#endif
#include <rx/xdr.h>
#ifdef AFS_SUN5_ENV
#include <sys/fs/ufs_inode.h>
#else
+#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+#else
#include <ufs/inode.h>
#endif
+#endif
#else /* AFS_VFSINCL_ENV */
#ifdef AFS_OSF_ENV
#include <ufs/inode.h>
#else /* AFS_OSF_ENV */
-#ifndef AFS_LINUX20_ENV
+#if !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV)
#include <sys/inode.h>
#endif
#endif
#include <afs/afsutil.h>
#include <afs/fileutil.h>
#include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
+#ifndef AFS_NT40_ENV
+#include <syslog.h>
+#endif
#include "nfs.h"
#include "lwp.h"
int ShowMounts = 0; /* -showmounts flag */
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
+
#define MAXPARALLEL 32
int OKToZap; /* -o flag */
{
register struct cmd_item *ti;
char pname[100], *temp;
- afs_int32 seenpart = 0, seenvol = 0, vid = 0;
+ afs_int32 seenpart = 0, seenvol = 0, vid = 0, seenany = 0, i;
struct DiskPartition *partP;
#ifdef AFS_SGI_VNODE_GLUE
}
#endif
+#ifdef FAST_RESTART
+ for (i = 0; i < CMD_MAXPARMS; i++) {
+ if (as->parms[i].items) {
+ seenany = 1;
+ break;
+ }
+ }
+ if (!seenany) {
+ printf("Exiting immediately without salvage. Look into the FileLog to find volumes which really need to be salvaged!\n");
+ Exit(0);
+ }
+#endif /* FAST_RESTART */
if (ti = as->parms[0].items) { /* -partition */
seenpart = 1;
strncpy(pname, ti->data, 100);
dirp = opendir(tmpdir);
if (!dirp) {
printf("Can't open temporary placeholder dir %s; using current partition \n", tmpdir);
- tmpdir = (char *)0;
+ tmpdir = NULL;
} else
closedir(dirp);
}
orphans = ORPH_ATTACH;
}
+#ifndef AFS_NT40_ENV /* ignore options on NT */
+ if ( ti = as->parms[16].items) { /* -syslog */
+ useSyslog = 1;
+ ShowLog = 0;
+ }
+ if ( ti = as->parms[17].items) { /* -syslogfacility */
+ useSyslogFacility = atoi(ti->data);
+ }
+#endif
+
+
+#ifdef FAST_RESTART
+ if (ti = as->parms[18].items) { /* -DontSalvage */
+ printf("Exiting immediately without salvage. Look into the FileLog");
+ printf(" to find volumes which really need to be salvaged!\n");
+ Exit(0);
+ }
+#endif /* FAST_RESTART */
+
/* Note: if seemvol we initialize this as a standard volume utility: this has the
implication that the file server may be running; negotations have to be made with
the file server in this case to take the read write volume and associated read-only
cmd_AddParm(ts, "-showsuid", CMD_FLAG,CMD_OPTIONAL, "Report on suid/sgid files");
cmd_AddParm(ts, "-showmounts", CMD_FLAG,CMD_OPTIONAL, "Report on mountpoints");
cmd_AddParm(ts, "-orphans", CMD_SINGLE, CMD_OPTIONAL, "ignore | remove | attach");
+
+ /* note - syslog isn't avail on NT, but if we make it conditional, have
+ to deal with screwy offsets for cmd params */
+ cmd_AddParm(ts, "-syslog", CMD_FLAG, CMD_OPTIONAL, "Write salvage log to syslogs");
+ cmd_AddParm(ts, "-syslogfacility", CMD_SINGLE, CMD_OPTIONAL, "Syslog facility number to use");
+
+#ifdef FAST_RESTART
+ cmd_AddParm(ts, "-DontSalvage", CMD_FLAG, CMD_OPTIONAL, "Don't salvage. This my be set in BosConfig to let the fileserver restart immediately after a crash. Bad volumes will be taken offline");
+#endif /* FAST_RESTART */
err = cmd_Dispatch(argc, argv);
Exit(err);
}
#else
salvageLock = open(AFSDIR_SERVER_SLVGLOCK_FILEPATH, O_CREAT|O_RDWR, 0666);
assert(salvageLock >= 0);
+#ifdef AFS_DARWIN_ENV
+ if (flock(salvageLock, LOCK_EX) == -1) {
+#else
if (lockf(salvageLock, F_LOCK, 0) == -1) {
+#endif
fprintf(stderr,
"salvager: There appears to be another salvager running! Aborted.\n");
Exit(1);
#endif
#ifdef AFS_AIX42_ENV
+#ifndef AFS_NAMEI_ENV
/* We don't want to salvage big files filesystems, since we can't put volumes on
* them.
*/
return 0;
}
#endif
+#endif
#ifdef AFS_NT40_ENV
#define HDSTR "\\Device\\Harddisk"
Log("Can't salvage '%s'. Not enough memory\n", partP->name);
return;
}
- bzero(thisjob, sizeof(struct job));
+ memset(thisjob, 0, sizeof(struct job));
thisjob->partP = partP;
thisjob->jobnumb = jobcount;
jobcount++;
ShowLog = 0;
for (fd =0; fd < 16; fd++) close(fd);
open("/", 0); dup2(0, 1); dup2(0, 2);
- sprintf(logFileName, "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH, jobs[startjob]->jobnumb);
- logFile = fopen(logFileName, "w");
+#ifndef AFS_NT40_ENV
+ if ( useSyslog ) {
+ openlog(NULL, LOG_PID, useSyslogFacility);
+ } else
+#endif
+ {
+ sprintf(logFileName, "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH, jobs[startjob]->jobnumb);
+ logFile = fopen(logFileName, "w");
+ }
if (!logFile) logFile = stdout;
SalvageFileSys1(jobs[startjob]->partP, 0);
} /* while ( thisjob || (!partP && numjobs > 0) ) */
/* If waited for all jobs to complete, now collect log files and return */
+#ifndef AFS_NT40_ENV
+ if ( ! useSyslog ) /* if syslogging - no need to collect */
+#endif
if (!partP) {
for (i=0; i<jobcount; i++) {
sprintf(logFileName, "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH, i);
(void)unlink(logFileName);
}
fflush(logFile);
- return;
}
+ return;
}
*ptr = '\0';
strcpy(wpath, pbuf);
} else
- return (char *)0;
+ return NULL;
ptr = (char *)strrchr(pbuffer, '/');
if (ptr) {
strcpy(pbuffer, ptr+1);
return pbuffer;
} else
- return (char *)0;
+ return NULL;
}
void SalvageFileSys1(struct DiskPartition *partP, VolumeId singleVolumeNumber)
int GetInodeSummary(char *path, VolumeId singleVolumeNumber)
{
struct stat status;
- int summaryFd, forceSal, err;
+ int forceSal, err;
struct ViceInodeInfo *ip;
struct InodeSummary summary;
char summaryFileName[50];
if (deleteMe)
*deleteMe = 0;
- bzero(&tempHeader, sizeof(tempHeader));
+ memset(&tempHeader, 0, sizeof(tempHeader));
tempHeader.stamp.magic = VOLUMEHEADERMAGIC;
tempHeader.stamp.version = VOLUMEHEADERVERSION;
tempHeader.id = isp->volumeId;
isp->volSummary->header.volumeAcl = 0;
isp->volSummary->header.volumeMountTable = 0;
- if (bcmp(&isp->volSummary->header, &tempHeader, sizeof(struct VolumeHeader))) {
+ 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(name, isp->volSummary->fileName);
}
}
if (headerFd) {
- bcopy(&tempHeader,&isp->volSummary->header,sizeof(struct VolumeHeader));
+ memcpy(&isp->volSummary->header, &tempHeader, sizeof(struct VolumeHeader));
if (Testing) {
if (!Showmode) Log("It would have written a new header file for volume %u\n", isp->volumeId);
} else {
/* The following code should be moved into vutil.c */
if (sp->inodeType == VI_VOLINFO) {
struct timeval tp;
- bzero(&header.volumeInfo, sizeof (header.volumeInfo));
+ memset(&header.volumeInfo, 0, sizeof (header.volumeInfo));
header.volumeInfo.stamp = sp->stamp;
header.volumeInfo.id = isp->volumeId;
header.volumeInfo.parentId = isp->RWvolumeId;
if (VNDISK_GET_INO(vnode) == 0) {
if (RW) {
/* Log("### DEBUG ### Deleted Vnode with 0 inode (vnode %d)\n", vnodeNumber); */
- bzero(vnode, vcp->diskSize);
+ memset(vnode, 0, vcp->diskSize);
vnodeChanged = 1;
}
}
if (vcp->magic != vnode->vnodeMagic) {
/* bad magic #, probably partially created vnode */
Log("Partially allocated vnode %d deleted.\n", vnodeNumber);
- bzero(vnode, vcp->diskSize);
+ memset(vnode, 0, vcp->diskSize);
vnodeChanged = 1;
goto vnodeDone;
}
if (check) {
if (!Showmode) {
Log("Vnode %d: inode number incorrect (is %s should be %s). FileSize=%d\n",
+ vnodeNumber,
PrintInode(stmp1, VNDISK_GET_INO(vnode)),
PrintInode(stmp2, ip->inodeNumber),
ip->byteCount);
} else {
if (!Showmode) Log("Vnode %d (unique %d): bad directory vnode (no inode number listed); vnode deleted, vnode mod time=%s", vnodeNumber, vnode->uniquifier, ctime((time_t *)&(vnode->serverModifyTime)));
}
- bzero(vnode, vcp->diskSize);
+ memset(vnode, 0, vcp->diskSize);
vnodeChanged = 1;
} else {
/* Should not reach here becuase we checked for
assert(fdP != NULL);
size = FDH_SIZE(fdP);
assert(size != -1);
- bzero(buf, 1024);
+ memset(buf, 0, 1024);
if (size > 1024) size = 1024;
code = FDH_READ(fdP, buf, size);
assert(code == size);
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);
- if (vnodeIdToClass(vnodeNumber) == vLarge && vnodeEssence->name == (char *)0) {
+ if (vnodeIdToClass(vnodeNumber) == vLarge && vnodeEssence->name == NULL) {
char *n;
if (n = (char*)malloc(strlen(name)+1))
strcpy(n, name);
struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
char buf[SIZEOF_LARGEDISKVNODE];
struct VnodeDiskObject *vnode = (struct VnodeDiskObject *) buf;
- int code;
int size;
StreamHandle_t *file;
int vnodeIndex;
/* Remember rootdir DirSummary _after_ it has been judged */
if (dir.vnodeNumber == 1 && dir.unique == 1) {
- bcopy(&dir, rootdir, sizeof(struct DirSummary));
+ memcpy(rootdir, &dir, sizeof(struct DirSummary));
*rootdirfound = 1;
}
code = IH_DEC(alinkH, VNDISK_GET_INO(&vnode), vid);
assert(code == 0);
}
- bzero(&vnode, sizeof(vnode));
+ memset(&vnode, 0, sizeof(vnode));
}
} else if (vnp->count) {
if (!Showmode) {
void AskOffline(VolumeId volumeId)
{
- if (FSYNC_askfs(volumeId, (char *)0, FSYNC_OFF, FSYNC_SALVAGE) == FSYNC_DENIED) {
+ if (FSYNC_askfs(volumeId, NULL, FSYNC_OFF, FSYNC_SALVAGE) == FSYNC_DENIED) {
Log("AskOffline: file server denied offline request; a general salvage is required.\n");
Abort("Salvage aborted\n");
}
char buf[4096];
IHandle_t *srcH, *destH;
FdHandle_t *srcFdP, *destFdP;
- register int n;
+ register int n = 0;
IH_INIT(srcH, device, rwvolume, inode1);
srcFdP = IH_OPEN(srcH);
{
char oldSlvgLog[AFSDIR_PATH_MAX];
+#ifndef AFS_NT40_ENV
+ if ( useSyslog ) {
+ ShowLog = 0;
+ return;
+ }
+#endif
+
strcpy(oldSlvgLog, AFSDIR_SERVER_SLVGLOG_FILEPATH);
strcat(oldSlvgLog, ".old");
if (!logFile) {
{
char line[256];
+#ifndef AFS_NT40_ENV
+ if ( useSyslog ) {
+ printf("Can't show log since using syslog.\n");
+ fflush(stdout);
+ return;
+ }
+#endif
+
rewind(logFile);
fclose(logFile);
char *a, *b, *c, *d, *e, *f, *g, *h, *i, *j, *k;
{
struct timeval now;
- gettimeofday(&now, 0);
- fprintf(logFile, "%s ", TimeStamp(now.tv_sec, 1));
- fprintf(logFile, a,b,c,d,e,f,g,h,i,j,k);
- fflush(logFile);
+
+#ifndef AFS_NT40_ENV
+ if ( useSyslog )
+ {
+ syslog(LOG_INFO, a,b,c,d,e,f,g,h,i,j,k);
+ } else
+#endif
+ {
+ gettimeofday(&now, 0);
+ fprintf(logFile, "%s ", TimeStamp(now.tv_sec, 1));
+ fprintf(logFile, a,b,c,d,e,f,g,h,i,j,k);
+ fflush(logFile);
+ }
}
void Abort(a,b,c,d,e,f,g,h,i,j,k)
char *a, *b, *c, *d, *e, *f, *g, *h, *i, *j, *k;
{
- fprintf(logFile, a,b,c,d,e,f,g,h,i,j,k);
- fflush(logFile);
- if (ShowLog) showlog();
+#ifndef AFS_NT40_ENV
+ if ( useSyslog )
+ {
+ syslog(LOG_INFO, a,b,c,d,e,f,g,h,i,j,k);
+ } else
+#endif
+ {
+ fprintf(logFile, a,b,c,d,e,f,g,h,i,j,k);
+ fflush(logFile);
+ if (ShowLog) showlog();
+ }
if (debug)
abort();
Exit(1);