prototypes-fixes-20020821
[openafs.git] / src / vol / vol-salvage.c
index ca6550d..354b0cd 100644 (file)
@@ -1,10 +1,10 @@
-
-#ifndef lint
-#endif
-
 /*
- * (C) COPYRIGHT IBM CORPORATION 1998
- * LICENSED MATERIALS - PROPERTY OF IBM
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
  */
 
 /*
@@ -88,7 +88,11 @@ Vnodes with 0 inode pointers in RW volumes are now deleted.
 /* 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>
@@ -106,7 +110,7 @@ Vnodes with 0 inode pointers in RW volumes are now deleted.
 #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>
@@ -118,13 +122,18 @@ Vnodes with 0 inode pointers in RW volumes are now deleted.
 #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
@@ -164,6 +173,9 @@ Vnodes with 0 inode pointers in RW volumes are now deleted.
 #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"
@@ -205,6 +217,12 @@ int     ShowSuid = 0;              /* -showsuid flag */
 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 */
@@ -429,7 +447,7 @@ int SalvageVolumeHeaderFile(register struct InodeSummary *isp,
 void showlog(void);
 int UseTheForceLuke(char *path);
 
-
+static int IsVnodeOrphaned(VnodeId vnode);
 
 /* Uniquifier stored in the Inode */
 static Unique IUnique(u)
@@ -460,7 +478,7 @@ static handleit(as)
 {
     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
@@ -470,6 +488,18 @@ static handleit(as)
     }
 #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);
@@ -520,7 +550,7 @@ static handleit(as)
        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);
     }
@@ -545,6 +575,25 @@ static handleit(as)
          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
@@ -711,6 +760,15 @@ char **argv;
     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);
 }
@@ -732,7 +790,11 @@ void ObtainSalvageLock(void)
 #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);
@@ -774,6 +836,7 @@ struct stat *status;
 #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.
  */
@@ -802,6 +865,7 @@ int CheckIfBigFilesFS(mountPoint, devName)
     return 0;
 }
 #endif
+#endif
 
 #ifdef AFS_NT40_ENV
 #define HDSTR "\\Device\\Harddisk"
@@ -873,7 +937,7 @@ void SalvageFileSysParallel(struct DiskPartition *partP)
          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++;
@@ -988,8 +1052,15 @@ void SalvageFileSysParallel(struct DiskPartition *partP)
             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);
@@ -1000,6 +1071,9 @@ void SalvageFileSysParallel(struct DiskPartition *partP)
     } /* 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);
@@ -1012,8 +1086,8 @@ void SalvageFileSysParallel(struct DiskPartition *partP)
          (void)unlink(logFileName);
        }
        fflush(logFile);
-       return;
     }
+       return;
 }
 
 
@@ -1040,13 +1114,13 @@ char *wpath, *pbuffer;
        *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)
@@ -1364,7 +1438,7 @@ int OnlyOneVolume(inodeinfo, 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];
@@ -1942,7 +2016,7 @@ int SalvageVolumeHeaderFile(register struct InodeSummary *isp,
 
     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;
@@ -2023,7 +2097,7 @@ int SalvageVolumeHeaderFile(register struct InodeSummary *isp,
        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);
@@ -2042,7 +2116,7 @@ int SalvageVolumeHeaderFile(register struct InodeSummary *isp,
          }
     }
     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 {
@@ -2143,7 +2217,7 @@ int SalvageHeader(register struct stuff *sp, struct InodeSummary *isp,
        /* 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;
@@ -2274,7 +2348,7 @@ int SalvageIndex(Inode ino, VnodeClass class, int RW,
            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;
                }
            }
@@ -2282,7 +2356,7 @@ int SalvageIndex(Inode ino, VnodeClass class, int RW,
                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;
                }
@@ -2391,6 +2465,7 @@ int SalvageIndex(Inode ino, VnodeClass class, int RW,
                        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);
@@ -2452,7 +2527,7 @@ int SalvageIndex(Inode ino, VnodeClass class, int RW,
                        } 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 
@@ -2784,7 +2859,7 @@ void JudgeEntry(struct DirSummary *dir, char *name, VnodeId vnodeNumber,
            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);
@@ -2797,7 +2872,7 @@ void JudgeEntry(struct DirSummary *dir, char *name, VnodeId vnodeNumber,
        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);
@@ -2860,7 +2935,6 @@ void DistilVnodeEssence(VolumeId rwVId, VnodeClass class, Inode ino,
     struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
     char buf[SIZEOF_LARGEDISKVNODE];
     struct VnodeDiskObject *vnode = (struct VnodeDiskObject *) buf;
-    int code;
     int size;
     StreamHandle_t *file;
     int vnodeIndex;
@@ -3027,7 +3101,7 @@ void SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo,
 
     /* 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;
     }
 
@@ -3239,7 +3313,7 @@ int SalvageVolume(register struct InodeSummary *rwIsp, IHandle_t *alinkH)
                           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) {
@@ -3362,7 +3436,7 @@ void MaybeZapVolume(register struct InodeSummary *isp, char *message,
 
 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");
     }
@@ -3384,7 +3458,7 @@ int CopyInode(Device device, Inode inode1, Inode inode2, int rwvolume)
     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);
@@ -3500,6 +3574,13 @@ void CheckLogFile(void)
 {
   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) {
@@ -3521,6 +3602,14 @@ void showlog(void)
 {
     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);
 
@@ -3540,18 +3629,35 @@ void Log(a,b,c,d,e,f,g,h,i,j,k)
 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);