*/
-#define SalvageVersion "2.4"
-
-/* Main program file. Define globals. */
-#define MAIN 1
-
#include <afsconfig.h>
#include <afs/param.h>
RCSID
("$Header$");
+#ifndef AFS_NT40_ENV
+#include <sys/param.h>
+#include <sys/file.h>
+#ifndef ITIMER_REAL
+#include <sys/time.h>
+#endif /* ITIMER_REAL */
+#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef AFS_NT40_ENV
#include <io.h>
#include <WINNT/afsevent.h>
-#else
-#include <sys/param.h>
-#include <sys/file.h>
-#ifndef ITIMER_REAL
-#include <sys/time.h>
-#endif /* ITIMER_REAL */
#endif
#if defined(AFS_AIX_ENV) || defined(AFS_SUN4_ENV)
#define WCOREDUMP(x) (x & 0200)
#include "vnode.h"
#include "volume.h"
#include "partition.h"
+#include "daemon_com.h"
#include "fssync.h"
+#include "salvsync.h"
#include "viceinode.h"
#include "salvage.h"
#include "volinodes.h" /* header magic number, etc. stuff */
+#include "vol-salvage.h"
#ifdef AFS_NT40_ENV
#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
-extern char *vol_DevName();
static char *TimeStamp(time_t clock, int precision);
-#define ORPH_IGNORE 0
-#define ORPH_REMOVE 1
-#define ORPH_ATTACH 2
-
int debug; /* -d flag */
-int Testing = 0; /* -n flag */
+extern int Testing; /* -n flag */
int ListInodeOption; /* -i flag */
int ShowRootFiles; /* -r flag */
int RebuildDirs; /* -sal 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
+#ifdef AFS_NT40_ENV
+int canfork = 0;
+#else
+int canfork = 1;
+#endif
+
#define MAXPARALLEL 32
int OKToZap; /* -o flag */
int ForceSalvage; /* If salvage should occur despite the DONT_SALVAGE flag
* in the volume header */
-static FILE *logFile = 0; /* one of {/usr/afs/logs,/vice/file}/SalvageLog */
+FILE *logFile = 0; /* one of {/usr/afs/logs,/vice/file}/SalvageLog */
#define ROOTINODE 2 /* Root inode of a 4.2 Unix file system
* partition */
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 */
VolumeDiskData VolInfo; /* A copy of the last good or salvaged volume header dealt with */
-struct InodeSummary { /* Inode summary file--an entry for each
- * volume in the inode file for a partition */
- VolId volumeId; /* Volume id */
- VolId RWvolumeId; /* RW volume associated */
- int index; /* index into inode file (0, 1, 2 ...) */
- int nInodes; /* Number of inodes for this volume */
- int nSpecialInodes; /* Number of special inodes, i.e. volume
- * header, index, etc. These are all
- * marked (viceinode.h) and will all be sorted
- * to the beginning of the information for
- * this volume. Read-only volumes should
- * ONLY have special inodes (all the other
- * inodes look as if they belong to the
- * original RW volume). */
- Unique maxUniquifier; /* The maximum uniquifier found in all the inodes.
- * This is only useful for RW volumes and is used
- * to compute a new volume uniquifier in the event
- * that the header needs to be recreated. The inode
- * uniquifier may be a truncated version of vnode
- * uniquifier (AFS_3DISPARES). The real maxUniquifer
- * is from the vnodes and later calcuated from it */
- struct VolumeSummary *volSummary;
- /* Either a pointer to the original volume
- * header summary, or constructed summary
- * information */
-} *inodeSummary;
-#define readOnly(isp) ((isp)->volumeId != (isp)->RWvolumeId)
int nVolumesInInodeFile; /* Number of read-write volumes summarized */
int inodeFd; /* File descriptor for inode file */
-struct VolumeSummary { /* Volume summary an entry for each
- * volume in a volume directory.
- * Assumption: one volume directory per
- * partition */
- char *fileName; /* File name on the partition for the volume
- * header */
- struct VolumeHeader header;
- /* volume number, rw volume number, inode
- * numbers of each major component of
- * the volume */
- IHandle_t *volumeInfoHandle;
- byte wouldNeedCallback; /* set if the file server should issue
- * call backs for all the files in this volume when
- * the volume goes back on line */
-};
-
-struct VnodeInfo {
- IHandle_t *handle; /* Inode containing this index */
- int nVnodes; /* Total number of vnodes in index */
- int nAllocatedVnodes; /* Total number actually used */
- int volumeBlockCount; /* Total number of blocks used by volume */
- Inode *inodes; /* Directory only */
- struct VnodeEssence {
- short count; /* Number of references to vnode; MUST BE SIGNED */
- unsigned claimed:1; /* Set when a parent directory containing an entry
- * referencing this vnode is found. The claim
- * is that the parent in "parent" can point to
- * this vnode, and no other */
- unsigned changed:1; /* Set if any parameters (other than the count)
- * in the vnode change. It is determined if the
- * link count has changed by noting whether it is
- * 0 after scanning all directories */
- unsigned salvaged:1; /* Set if this directory vnode has already been salvaged. */
- unsigned todelete:1; /* Set if this vnode is to be deleted (should not be claimed) */
- afs_uint32 blockCount;
- /* Number of blocks (1K) used by this vnode,
- * approximately */
- VnodeId parent; /* parent in vnode */
- Unique unique; /* Must match entry! */
- char *name; /* Name of directory entry */
- int modeBits; /* File mode bits */
- Inode InodeNumber; /* file's inode */
- int type; /* File type */
- int author; /* File author */
- int owner; /* File owner */
- int group; /* File group */
- } *vnodes;
-} vnodeInfo[nVNODECLASSES];
-
-struct DirSummary {
- struct DirHandle dirHandle;
- VnodeId vnodeNumber;
- Unique unique;
- unsigned haveDot, haveDotDot;
- VolumeId rwVid;
- int copied; /* If the copy-on-write stuff has been applied */
- VnodeId parent;
- char *name;
- char *vname;
- IHandle_t *ds_linkH;
-};
+struct VnodeInfo vnodeInfo[nVNODECLASSES];
struct VolumeSummary *volumeSummaryp; /* Holds all the volumes in a part */
int nVolumes; /* Number of volumes (read-write and read-only)
* in volume summary */
-#ifdef AFS_NT40_ENV
-/* For NT, we can fork the per partition salvagers to gain the required
- * safety against Aborts. But there's too many complex data structures at
- * the per volume salvager layer to easilty copy the data across.
- * childJobNumber is resset from -1 to the job number if this is a
- * per partition child of the main salvager. This information is passed
- * out-of-band in the extra data area setup for the now unused parent/child
- * data transfer.
- */
-#define SALVAGER_MAGIC 0x00BBaaDD
-#define NOT_CHILD -1 /* job numbers start at 0 */
-/* If new options need to be passed to child, add them here. */
-typedef struct {
- int cj_magic;
- int cj_number;
- char cj_part[32];
-} childJob_t;
-
-/* Child job this process is running. */
-childJob_t myjob = { SALVAGER_MAGIC, NOT_CHILD };
-
-int nt_SalvagePartition(char *partName, int jobn);
-int nt_SetupPartitionSalvage(void *datap, int len);
-
-typedef struct {
- struct InodeSummary *svgp_inodeSummaryp;
- int svgp_count;
-} SVGParms_t;
-#define canfork 0
-#else
-#define canfork 1
-#endif
+char *tmpdir = NULL;
/* Forward declarations */
/*@printflike@*/ void Log(const char *format, ...);
/*@printflike@*/ void Abort(const char *format, ...);
-void Exit(int code);
-int Fork(void);
-int Wait(char *prog);
-char *ToString(char *s);
-void AskOffline(VolumeId volumeId);
-void AskOnline(VolumeId volumeId, char *partition);
-void CheckLogFile(void);
-#ifndef AFS_NT40_ENV
-void TimeStampLogFile(void);
-#endif
-void ClearROInUseBit(struct VolumeSummary *summary);
-void CopyAndSalvage(register struct DirSummary *dir);
-int CopyInode(Device device, Inode inode1, Inode inode2, int rwvolume);
-void CopyOnWrite(register struct DirSummary *dir);
-void CountVolumeInodes(register struct ViceInodeInfo *ip, int maxInodes,
- register struct InodeSummary *summary);
-void DeleteExtraVolumeHeaderFile(register struct VolumeSummary *vsp);
-void DistilVnodeEssence(VolumeId vid, VnodeClass class, Inode ino,
- Unique * maxu);
-int GetInodeSummary(char *path, VolumeId singleVolumeNumber);
-void GetVolumeSummary(VolumeId singleVolumeNumber);
-void JudgeEntry(struct DirSummary *dir, char *name, VnodeId vnodeNumber,
- Unique unique);
-void MaybeZapVolume(register struct InodeSummary *isp, char *message,
- int deleteMe, int check);
-void ObtainSalvageLock(void);
-void PrintInodeList(void);
-void PrintInodeSummary(void);
-void PrintVolumeSummary(void);
-int QuickCheck(register struct InodeSummary *isp, int nVols);
-void RemoveTheForce(char *path);
-void SalvageDir(char *name, VolumeId rwVid, struct VnodeInfo *dirVnodeInfo,
- IHandle_t * alinkH, int i, struct DirSummary *rootdir,
- int *rootdirfound);
-void SalvageFileSysParallel(struct DiskPartition *partP);
-void SalvageFileSys(struct DiskPartition *partP, VolumeId singleVolumeNumber);
-void SalvageFileSys1(struct DiskPartition *partP,
- VolumeId singleVolumeNumber);
-int SalvageHeader(register struct stuff *sp, struct InodeSummary *isp,
- int check, int *deleteMe);
-int SalvageIndex(Inode ino, VnodeClass class, int RW,
- register struct ViceInodeInfo *ip, int nInodes,
- struct VolumeSummary *volSummary, int check);
-int SalvageVnodes(register struct InodeSummary *rwIsp,
- register struct InodeSummary *thisIsp,
- register struct ViceInodeInfo *inodes, int check);
-int SalvageVolume(register struct InodeSummary *rwIsp, IHandle_t * alinkH);
-void DoSalvageVolumeGroup(register struct InodeSummary *isp, int nVols);
-#ifdef AFS_NT40_ENV
-void SalvageVolumeGroup(register struct InodeSummary *isp, int nVols);
-#else
-#define SalvageVolumeGroup DoSalvageVolumeGroup
-#endif
-int SalvageVolumeHeaderFile(register struct InodeSummary *isp,
- register struct ViceInodeInfo *inodes, int RW,
- int check, int *deleteMe);
-void showlog(void);
-int UseTheForceLuke(char *path);
-
static int IsVnodeOrphaned(VnodeId vnode);
/* Uniquifier stored in the Inode */
return 0; /* otherwise may be transient, e.g. EMFILE */
}
-
-char *tmpdir = 0;
-static int
-handleit(struct cmd_syndesc *as)
-{
- register struct cmd_item *ti;
- char pname[100], *temp;
- afs_int32 seenpart = 0, seenvol = 0, vid = 0, seenany = 0, i;
- struct DiskPartition *partP;
-
-#ifdef AFS_SGI_VNODE_GLUE
- if (afs_init_kernel_config(-1) < 0) {
- printf
- ("Can't determine NUMA configuration, not starting salvager.\n");
- exit(1);
- }
-#endif
-
-#ifdef FAST_RESTART
- for (i = 0; i < CMD_MAXPARMS; i++) {
- if (as->parms[i].items) {
- seenany = 1;
- break;
- }
- }
- if (!seenany) {
- char *msg =
- "Exiting immediately without salvage. Look into the FileLog to find volumes which really need to be salvaged!";
-
- if (useSyslog)
- Log(msg);
- else
- printf("%s\n", msg);
-
- Exit(0);
- }
-#endif /* FAST_RESTART */
- if ((ti = as->parms[0].items)) { /* -partition */
- seenpart = 1;
- strncpy(pname, ti->data, 100);
- }
- if ((ti = as->parms[1].items)) { /* -volumeid */
- if (!seenpart) {
- printf
- ("You must also specify '-partition' option with the '-volumeid' option\n");
- exit(-1);
- }
- seenvol = 1;
- vid = atoi(ti->data);
- }
- if (as->parms[2].items) /* -debug */
- debug = 1;
- if (as->parms[3].items) /* -nowrite */
- Testing = 1;
- if (as->parms[4].items) /* -inodes */
- ListInodeOption = 1;
- if (as->parms[5].items) /* -force */
- ForceSalvage = 1;
- if (as->parms[6].items) /* -oktozap */
- OKToZap = 1;
- if (as->parms[7].items) /* -rootinodes */
- ShowRootFiles = 1;
- if (as->parms[8].items) /* -RebuildDirs */
- RebuildDirs = 1;
- if (as->parms[9].items) /* -ForceReads */
- forceR = 1;
- if ((ti = as->parms[10].items)) { /* -Parallel # */
- temp = ti->data;
- if (strncmp(temp, "all", 3) == 0) {
- PartsPerDisk = 1;
- temp += 3;
- }
- if (strlen(temp) != 0) {
- Parallel = atoi(temp);
- if (Parallel < 1)
- Parallel = 1;
- if (Parallel > MAXPARALLEL) {
- printf("Setting parallel salvages to maximum of %d \n",
- MAXPARALLEL);
- Parallel = MAXPARALLEL;
- }
- }
- }
- if ((ti = as->parms[11].items)) { /* -tmpdir */
- DIR *dirp;
-
- tmpdir = ti->data;
- dirp = opendir(tmpdir);
- if (!dirp) {
- printf
- ("Can't open temporary placeholder dir %s; using current partition \n",
- tmpdir);
- tmpdir = NULL;
- } else
- closedir(dirp);
- }
- if ((ti = as->parms[12].items)) /* -showlog */
- ShowLog = 1;
- if ((ti = as->parms[13].items)) { /* -log */
- Testing = 1;
- ShowSuid = 1;
- Showmode = 1;
- }
- if ((ti = as->parms[14].items)) { /* -showmounts */
- Testing = 1;
- Showmode = 1;
- ShowMounts = 1;
- }
- if ((ti = as->parms[15].items)) { /* -orphans */
- if (Testing)
- orphans = ORPH_IGNORE;
- else if (strcmp(ti->data, "remove") == 0
- || strcmp(ti->data, "r") == 0)
- orphans = ORPH_REMOVE;
- else if (strcmp(ti->data, "attach") == 0
- || strcmp(ti->data, "a") == 0)
- 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);
- }
-
- if ((ti = as->parms[18].items)) { /* -datelogs */
- TimeStampLogFile();
- }
-#endif
-
-#ifdef FAST_RESTART
- if (ti = as->parms[19].items) { /* -DontSalvage */
- char *msg =
- "Exiting immediately without salvage. Look into the FileLog to find volumes which really need to be salvaged!";
-
- if (useSyslog)
- Log(msg);
- else
- printf("%s\n", msg);
- 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
- * volumes off line before salvaging */
-#ifdef AFS_NT40_ENV
- if (seenvol) {
- if (afs_winsockInit() < 0) {
- ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0,
- AFSDIR_SALVAGER_FILE, 0);
- Log("Failed to initailize winsock, exiting.\n");
- Exit(1);
- }
- }
-#endif
- VInitVolumePackage(seenvol ? volumeUtility : salvager, 5, 5,
- DONT_CONNECT_FS, 0);
- DInit(10);
-#ifdef AFS_NT40_ENV
- if (myjob.cj_number != NOT_CHILD) {
- if (!seenpart) {
- seenpart = 1;
- (void)strcpy(pname, myjob.cj_part);
- }
- }
-#endif
- if (seenpart == 0) {
- for (partP = DiskPartitionList; partP; partP = partP->next) {
- SalvageFileSysParallel(partP);
- }
- SalvageFileSysParallel(0);
- } else {
- partP = VGetPartition(pname, 0);
- if (!partP) {
- Log("salvage: Unknown or unmounted partition %s; salvage aborted\n", pname);
- Exit(1);
- }
- if (!seenvol)
- SalvageFileSys(partP, 0);
- else {
- /* Salvage individual volume */
- if (vid <= 0) {
- Log("salvage: invalid volume id specified; salvage aborted\n");
- Exit(1);
- }
- SalvageFileSys(partP, vid);
- }
- }
- return (0);
-}
-
-
-#ifndef AFS_NT40_ENV
-#include "AFS_component_version_number.c"
-#endif
#define MAX_ARGS 128
#ifdef AFS_NT40_ENV
char *save_args[MAX_ARGS];
int n_save_args = 0;
-pthread_t main_thread;
-#endif
-
-int
-main(int argc, char **argv)
-{
- struct cmd_syndesc *ts;
- int err = 0;
- char commandLine[150];
-
- int i;
- extern char cml_version_number[];
-
-#ifdef AFS_AIX32_ENV
- /*
- * The following signal action for AIX is necessary so that in case of a
- * crash (i.e. core is generated) we can include the user's data section
- * in the core dump. Unfortunately, by default, only a partial core is
- * generated which, in many cases, isn't too useful.
- */
- struct sigaction nsa;
-
- sigemptyset(&nsa.sa_mask);
- nsa.sa_handler = SIG_DFL;
- nsa.sa_flags = SA_FULLDUMP;
- sigaction(SIGABRT, &nsa, NULL);
- sigaction(SIGSEGV, &nsa, NULL);
+extern pthread_t main_thread;
+childJob_t myjob = { SALVAGER_MAGIC, NOT_CHILD, "" };
#endif
- /* Initialize directory paths */
- if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
-#ifdef AFS_NT40_ENV
- ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
-#endif
- fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
- argv[0]);
- exit(2);
- }
-#ifdef AFS_NT40_ENV
- main_thread = pthread_self();
- if (spawnDatap && spawnDataLen) {
- /* This is a child per partition salvager. Don't setup log or
- * try to lock the salvager lock.
- */
- if (nt_SetupPartitionSalvage(spawnDatap, spawnDataLen) < 0)
- exit(3);
- } else {
-#endif
- for (commandLine[0] = '\0', i = 0; i < argc; i++) {
- if (i > 0)
- strcat(commandLine, " ");
- strcat(commandLine, argv[i]);
- }
-
- /* All entries to the log will be appended. Useful if there are
- * multiple salvagers appending to the log.
- */
-
- CheckLogFile();
-#ifndef AFS_NT40_ENV
-#ifdef AFS_LINUX20_ENV
- fcntl(fileno(logFile), F_SETFL, O_APPEND); /* Isn't this redundant? */
-#else
- fcntl(fileno(logFile), F_SETFL, FAPPEND); /* Isn't this redundant? */
-#endif
-#endif
- setlinebuf(logFile);
-
-#ifndef AFS_NT40_ENV
- if (geteuid() != 0) {
- printf("Salvager must be run as root.\n");
- fflush(stdout);
- Exit(0);
- }
-#endif
-
- /* bad for normal help flag processing, but can do nada */
-
- fprintf(logFile, "%s\n", cml_version_number);
- Log("STARTING AFS SALVAGER %s (%s)\n", SalvageVersion, commandLine);
-
- /* Get and hold a lock for the duration of the salvage to make sure
- * that no other salvage runs at the same time. The routine
- * VInitVolumePackage (called below) makes sure that a file server or
- * other volume utilities don't interfere with the salvage.
- */
- ObtainSalvageLock();
-#ifdef AFS_NT40_ENV
- }
-#endif
-
- ts = cmd_CreateSyntax("initcmd", handleit, 0, "initialize the program");
- cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
- "Name of partition to salvage");
- cmd_AddParm(ts, "-volumeid", CMD_SINGLE, CMD_OPTIONAL,
- "Volume Id to salvage");
- cmd_AddParm(ts, "-debug", CMD_FLAG, CMD_OPTIONAL,
- "Run in Debugging mode");
- cmd_AddParm(ts, "-nowrite", CMD_FLAG, CMD_OPTIONAL,
- "Run readonly/test mode");
- cmd_AddParm(ts, "-inodes", CMD_FLAG, CMD_OPTIONAL,
- "Just list affected afs inodes - debugging flag");
- cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "Force full salvaging");
- cmd_AddParm(ts, "-oktozap", CMD_FLAG, CMD_OPTIONAL,
- "Give permission to destroy bogus inodes/volumes - debugging flag");
- cmd_AddParm(ts, "-rootinodes", CMD_FLAG, CMD_OPTIONAL,
- "Show inodes owned by root - debugging flag");
- cmd_AddParm(ts, "-salvagedirs", CMD_FLAG, CMD_OPTIONAL,
- "Force rebuild/salvage of all directories");
- cmd_AddParm(ts, "-blockreads", CMD_FLAG, CMD_OPTIONAL,
- "Read smaller blocks to handle IO/bad blocks");
- cmd_AddParm(ts, "-parallel", CMD_SINGLE, CMD_OPTIONAL,
- "# of max parallel partition salvaging");
- cmd_AddParm(ts, "-tmpdir", CMD_SINGLE, CMD_OPTIONAL,
- "Name of dir to place tmp files ");
- cmd_AddParm(ts, "-showlog", CMD_FLAG, CMD_OPTIONAL,
- "Show log file upon completion");
- 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");
- cmd_AddParm(ts, "-datelogs", CMD_FLAG, CMD_OPTIONAL,
- "Include timestamp in logfile filename");
-
-#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);
-}
-
/* Get the salvage lock if not already held. Hold until process exits. */
void
ObtainSalvageLock(void)
}
#else
salvageLock =
- open(AFSDIR_SERVER_SLVGLOCK_FILEPATH, O_CREAT | O_RDWR, 0666);
- assert(salvageLock >= 0);
+ afs_open(AFSDIR_SERVER_SLVGLOCK_FILEPATH, O_CREAT | O_RDWR, 0666);
+ if (salvageLock < 0) {
+ fprintf(stderr,
+ "salvager: can't open salvage lock file %s, aborting\n",
+ AFSDIR_SERVER_SLVGLOCK_FILEPATH);
+ Exit(1);
+ }
#ifdef AFS_DARWIN_ENV
if (flock(salvageLock, LOCK_EX) == -1) {
#else
/* Check if the given inode is the root of the filesystem. */
#ifndef AFS_SGI_XFS_IOPS_ENV
int
-IsRootInode(struct stat *status)
+IsRootInode(struct afs_stat *status)
{
/*
* The root inode is not a fixed value in XFS partitions. So we need to
#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 */
"%s.%d",
AFSDIR_SERVER_SLVGLOG_FILEPATH,
jobs[startjob]->jobnumb);
- logFile = fopen(logFileName, "w");
+ logFile = afs_fopen(logFileName, "w");
}
if (!logFile)
logFile = stdout;
for (i = 0; i < jobcount; i++) {
(void)afs_snprintf(logFileName, sizeof logFileName, "%s.%d",
AFSDIR_SERVER_SLVGLOG_FILEPATH, i);
- if ((passLog = fopen(logFileName, "r"))) {
+ if ((passLog = afs_fopen(logFileName, "r"))) {
while (fgets(buf, sizeof(buf), passLog)) {
fputs(buf, logFile);
}
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];
ForceSalvage = UseTheForceLuke(fileSysPath);
if (singleVolumeNumber) {
- if (!VConnectFS()) {
+ /* salvageserver already setup fssync conn for us */
+ if ((programType != salvageServer) && !VConnectFS()) {
Abort("Couldn't connect to file server\n");
}
AskOffline(singleVolumeNumber);
_open_osfhandle((long)nt_open(inodeListPath, O_RDWR, 0), O_RDWR);
nt_unlink(inodeListPath); /* NT's crt unlink won't if file is open. */
#else
- inodeFd = open(inodeListPath, O_RDONLY);
+ inodeFd = afs_open(inodeListPath, O_RDONLY);
unlink(inodeListPath);
#endif
if (inodeFd == -1)
}
int
-OnlyOneVolume(struct ViceInodeInfo *inodeinfo, VolumeId singleVolumeNumber)
+OnlyOneVolume(struct ViceInodeInfo *inodeinfo, int singleVolumeNumber, void *rock)
{
if (inodeinfo->u.vnode.vnodeNumber == INODESPECIAL)
return (inodeinfo->u.special.parentId == singleVolumeNumber);
int
GetInodeSummary(char *path, VolumeId singleVolumeNumber)
{
- struct stat status;
+ struct afs_stat status;
int forceSal, err;
struct ViceInodeInfo *ip;
struct InodeSummary summary;
if ((err =
ListViceInodes(dev, fileSysPath, path,
singleVolumeNumber ? OnlyOneVolume : 0,
- singleVolumeNumber, &forceSal, forceR, wpath)) < 0) {
+ singleVolumeNumber, &forceSal, forceR, wpath, NULL)) < 0) {
if (err == -2) {
Log("*** I/O error %d when writing a tmp inode file %s; Not salvaged %s ***\nIncrease space on partition or use '-tmpdir'\n", errno, path, dev);
return -1;
Log("***Forced salvage of all volumes on this partition***\n");
ForceSalvage = 1;
}
- inodeFd = open(path, O_RDWR);
- if (inodeFd == -1 || fstat(inodeFd, &status) == -1) {
+ inodeFd = afs_open(path, O_RDWR);
+ if (inodeFd == -1 || afs_fstat(inodeFd, &status) == -1) {
unlink(path);
Abort("No inode description file for \"%s\"; not salvaged\n", dev);
}
(void)afs_snprintf(summaryFileName, sizeof summaryFileName,
"%s/salvage.temp.%d", tdir, getpid());
#endif
- summaryFile = fopen(summaryFileName, "a+");
+ summaryFile = afs_fopen(summaryFileName, "a+");
if (summaryFile == NULL) {
close(inodeFd);
unlink(path);
}
if (!canfork || debug || Fork() == 0) {
int nInodes;
- nInodes = status.st_size / sizeof(struct ViceInodeInfo);
+ unsigned long st_size=(unsigned long) status.st_size;
+ nInodes = st_size / sizeof(struct ViceInodeInfo);
if (nInodes == 0) {
fclose(summaryFile);
close(inodeFd);
unlink(summaryFileName);
if (!singleVolumeNumber) /* Remove the FORCESALVAGE file */
RemoveTheForce(fileSysPath);
+ else {
+ struct VolumeSummary *vsp;
+ int i;
+
+ GetVolumeSummary(singleVolumeNumber);
+
+ for (i = 0, vsp = volumeSummaryp; i < nVolumes; i++) {
+ if (vsp->fileName)
+ DeleteExtraVolumeHeaderFile(vsp);
+ }
+ }
Log("%s vice inodes on %s; not salvaged\n",
singleVolumeNumber ? "No applicable" : "No", dev);
return -1;
}
- ip = (struct ViceInodeInfo *)malloc(status.st_size);
+ ip = (struct ViceInodeInfo *)malloc(nInodes*sizeof(struct ViceInodeInfo));
if (ip == NULL) {
fclose(summaryFile);
close(inodeFd);
("Unable to allocate enough space to read inode table; %s not salvaged\n",
dev);
}
- if (read(inodeFd, ip, status.st_size) != status.st_size) {
+ if (read(inodeFd, ip, st_size) != st_size) {
fclose(summaryFile);
close(inodeFd);
unlink(path);
Abort("Unable to read inode table; %s not salvaged\n", dev);
}
qsort(ip, nInodes, sizeof(struct ViceInodeInfo), CompareInodes);
- if (lseek(inodeFd, 0, SEEK_SET) == -1
- || write(inodeFd, ip, status.st_size) != status.st_size) {
+ if (afs_lseek(inodeFd, 0, SEEK_SET) == -1
+ || write(inodeFd, ip, st_size) != st_size) {
fclose(summaryFile);
close(inodeFd);
unlink(path);
Exit(1); /* salvage of this partition aborted */
}
}
- assert(fstat(fileno(summaryFile), &status) != -1);
+ assert(afs_fstat(fileno(summaryFile), &status) != -1);
if (status.st_size != 0) {
int ret;
- inodeSummary = (struct InodeSummary *)malloc(status.st_size);
+ unsigned long st_status=(unsigned long)status.st_size;
+ inodeSummary = (struct InodeSummary *)malloc(st_status);
assert(inodeSummary != NULL);
/* For GNU we need to do lseek to get the file pointer moved. */
- assert(lseek(fileno(summaryFile), 0, SEEK_SET) == 0);
- ret = read(fileno(summaryFile), inodeSummary, status.st_size);
- assert(ret == status.st_size);
+ assert(afs_lseek(fileno(summaryFile), 0, SEEK_SET) == 0);
+ ret = read(fileno(summaryFile), inodeSummary, st_status);
+ assert(ret == st_status);
}
- nVolumesInInodeFile = status.st_size / sizeof(struct InodeSummary);
+ nVolumesInInodeFile =(unsigned long)(status.st_size) / sizeof(struct InodeSummary);
+ Log("%d nVolumesInInodeFile %d \n",nVolumesInInodeFile,(unsigned long)(status.st_size));
fclose(summaryFile);
close(inodeFd);
unlink(summaryFileName);
p = strrchr(dp->d_name, '.');
if (p != NULL && strcmp(p, VHDREXT) == 0) {
int fd;
- if ((fd = open(dp->d_name, O_RDONLY)) != -1
+ if ((fd = afs_open(dp->d_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 = open(dp->d_name, O_RDONLY)) == -1
+ if ((fd = afs_open(dp->d_name, O_RDONLY)) == -1
|| read(fd, &diskHeader, sizeof(diskHeader))
!= sizeof(diskHeader)
|| diskHeader.stamp.magic != VOLUMEHEADERMAGIC) {
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)) {
- sprintf(nameShouldBe, VFORMAT, vsp->header.id);
+ (void)afs_snprintf(nameShouldBe, sizeof nameShouldBe,
+ VFORMAT, vsp->header.id);
if (singleVolumeNumber)
AskOffline(vsp->header.id);
if (strcmp(nameShouldBe, dp->d_name)) {
Abort("Can't open link table for volume %u (error = %d)\n",
isp->RWvolumeId, errno);
- if (FDH_TRUNC(fdP, 0) < 0)
+ if (FDH_TRUNC(fdP, sizeof(version) + sizeof(short)) < 0)
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(lseek(inodeFd, isp->index * sizeof(struct ViceInodeInfo), SEEK_SET)
- != -1);
+ assert(afs_lseek
+ (inodeFd, isp->index * sizeof(struct ViceInodeInfo),
+ SEEK_SET) != -1);
assert(read(inodeFd, inodes, size) == size);
/* Don't try to salvage a read write volume if there isn't one on this
if (Testing) {
IH_INIT(VGLinkH, fileSysDevice, -1, -1);
} else {
+ int i, j;
+ struct ViceInodeInfo *ip;
CreateLinkTable(isp, ino);
+ fdP = IH_OPEN(VGLinkH);
+ /* Sync fake 1 link counts to the link table, now that it exists */
+ if (fdP) {
+ 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
+ }
+ }
+ }
}
}
if (fdP)
/* Fix actual inode counts */
if (!Showmode) {
+ Log("totalInodes %d\n",totalInodes);
for (ip = inodes; totalInodes; ip++, totalInodes--) {
static int TraceBadLinkCounts = 0;
#ifdef AFS_NAMEI_ENV
&& 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) {
Log("No header file for volume %u; %screating %s/%s\n",
isp->volumeId, (Testing ? "it would have been " : ""),
fileSysPathName, name);
- headerFd = open(name, O_RDWR | O_CREAT | O_TRUNC, 0644);
+ headerFd = afs_open(name, O_RDWR | O_CREAT | O_TRUNC, 0644);
assert(headerFd != -1);
isp->volSummary = (struct VolumeSummary *)
malloc(sizeof(struct VolumeSummary));
if (check)
return -1;
- headerFd = open(name, O_RDWR | O_TRUNC, 0644);
+ headerFd = afs_open(name, O_RDWR | O_TRUNC, 0644);
assert(headerFd != -1);
}
}
* if no such match, take the first determined by our sort
* order */
register struct ViceInodeInfo *lip = ip;
- register lnInodes = nInodes;
+ register int lnInodes = nInodes;
while (lnInodes
&& lip->u.vnode.vnodeNumber == vnodeNumber) {
if (VNDISK_GET_INO(vnode) == lip->inodeNumber) {
if (ip->inodeNumber != VNDISK_GET_INO(vnode)) {
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);
+ Log("Vnode %d: inode number incorrect (is %s should be %s). FileSize=%llu\n", vnodeNumber, PrintInode(stmp1, VNDISK_GET_INO(vnode)), PrintInode(stmp2, ip->inodeNumber), (afs_uintmax_t) ip->byteCount);
}
VNDISK_SET_INO(vnode, ip->inodeNumber);
err = -1;
if (check) {
if (VNDISK_GET_INO(vnode)) {
if (!Showmode) {
- Log("Vnode %d (unique %d): 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(NULL, VNDISK_GET_INO(vnode)));
}
} else {
if (!Showmode)
- Log("Vnode %d (unique %d): bad directory vnode (no inode number listed)\n", vnodeNumber, vnode->uniquifier);
+ Log("Vnode %d (unique %u): bad directory vnode (no inode number listed)\n", vnodeNumber, vnode->uniquifier);
}
err = -1;
goto zooks;
}
if (VNDISK_GET_INO(vnode)) {
if (!Showmode) {
- Log("Vnode %d (unique %d): corresponding inode %s is missing; vnode deleted, vnode mod time=%s", vnodeNumber, vnode->uniquifier, PrintInode(NULL, VNDISK_GET_INO(vnode)), ctime((time_t *) & (vnode->serverModifyTime)));
+ 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));
}
} 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)));
+ if (!Showmode) {
+ time_t serverModifyTime = vnode->serverModifyTime;
+ Log("Vnode %d (unique %u): bad directory vnode (no inode number listed); vnode deleted, vnode mod time=%s", vnodeNumber, vnode->uniquifier, ctime(&serverModifyTime));
+ }
}
memset(vnode, 0, vcp->diskSize);
vnodeChanged = 1;
struct VnodeDiskObject vnode;
struct VnodeClassInfo *vcp = &VnodeClassInfo[vLarge];
Inode oldinode, newinode;
- int code;
+ afs_sfsize_t code;
if (dir->copied || Testing)
return;
struct VnodeClassInfo *vcp = &VnodeClassInfo[vLarge];
Inode oldinode, newinode;
DirHandle newdir;
- register afs_int32 code;
+ afs_int32 code;
+ afs_sfsize_t lcode;
afs_int32 parentUnique = 1;
struct VnodeEssence *vnodeEssence;
if (Testing)
return;
Log("Salvaging directory %u...\n", dir->vnodeNumber);
- code =
+ lcode =
IH_IREAD(vnodeInfo[vLarge].handle,
vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode,
sizeof(vnode));
- assert(code == sizeof(vnode));
+ 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
if (code) {
/* didn't really build the new directory properly, let's just give up. */
code = IH_DEC(dir->ds_linkH, newinode, dir->rwVid);
- assert(code == 0);
Log("Directory salvage returned code %d, continuing.\n", code);
+ if (code) {
+ Log("also failed to decrement link count on new inode");
+ }
assert(1 == 2);
}
Log("Checking the results of the directory salvage...\n");
vnode.cloned = 0;
VNDISK_SET_INO(&vnode, newinode);
VNDISK_SET_LEN(&vnode, Length(&newdir));
- code =
+ lcode =
IH_IWRITE(vnodeInfo[vLarge].handle,
vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode,
sizeof(vnode));
- assert(code == 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
code = IH_DEC(dir->ds_linkH, oldinode, dir->rwVid);
assert(code == 0);
dir->dirHandle = newdir;
* from different directories.
*/
if (vnodeEssence->parent != dir->vnodeNumber) {
- if (!vnodeEssence->claimed && !dirOrphaned) {
+ if (!vnodeEssence->claimed && !dirOrphaned && vnodeNumber != 1) {
/* Vnode does not point back to this directory.
* Orphaned dirs cannot claim a file (it may belong to
* another non-orphaned dir).
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 " : ""));
+ } 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 " : ""));
} 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 " : ""));
}
struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
char buf[SIZEOF_LARGEDISKVNODE];
struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf;
- int size;
+ afs_sfsize_t size;
StreamHandle_t *file;
int vnodeIndex;
int nVnodes;
if (dirVnodeInfo->inodes[i] == 0)
return; /* Not allocated to a directory */
- parent = CheckVnodeNumber(dirVnodeInfo->vnodes[i].parent);
- if (parent && parent->salvaged == 0)
- SalvageDir(name, rwVid, dirVnodeInfo, alinkH,
- vnodeIdToBitNumber(dirVnodeInfo->vnodes[i].parent),
- rootdir, rootdirfound);
+ if (bitNumberToVnodeNumber(i, vLarge) == 1) {
+ if (dirVnodeInfo->vnodes[i].parent) {
+ Log("Bad parent, vnode 1; %s...\n",
+ (Testing ? "skipping" : "salvaging"));
+ dirVnodeInfo->vnodes[i].parent = 0;
+ dirVnodeInfo->vnodes[i].changed = 1;
+ }
+ } else {
+ parent = CheckVnodeNumber(dirVnodeInfo->vnodes[i].parent);
+ if (parent && parent->salvaged == 0)
+ SalvageDir(name, rwVid, dirVnodeInfo, alinkH,
+ vnodeIdToBitNumber(dirVnodeInfo->vnodes[i].parent),
+ rootdir, rootdirfound);
+ }
+
dir.vnodeNumber = bitNumberToVnodeNumber(i, vLarge);
dir.unique = dirVnodeInfo->vnodes[i].unique;
dir.copied = 0;
struct VnodeEssence *vep;
afs_int32 v, pv;
IHandle_t *h;
- int nBytes;
+ afs_sfsize_t nBytes;
ViceFid pa;
VnodeId LFVnode, ThisVnode;
Unique LFUnique, ThisUnique;
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;
ClearROInUseBit(struct VolumeSummary *summary)
{
IHandle_t *h = summary->volumeInfoHandle;
- int nBytes;
+ afs_sfsize_t nBytes;
VolumeDiskData volHeader;
volHeader.inService = 1;
volHeader.dontSalvage = DONT_SALVAGE;
if (!Testing) {
- nBytes = IH_IREAD(h, 0, (char *)&volHeader, sizeof(volHeader));
+ nBytes = IH_IWRITE(h, 0, (char *)&volHeader, sizeof(volHeader));
assert(nBytes == sizeof(volHeader));
}
}
void
AskOffline(VolumeId volumeId)
{
- if (FSYNC_askfs(volumeId, NULL, FSYNC_OFF, FSYNC_SALVAGE) == FSYNC_DENIED) {
- Log("AskOffline: file server denied offline request; a general salvage is required.\n");
+ afs_int32 code, i;
+
+ for (i = 0; i < 3; i++) {
+ code = FSYNC_VolOp(volumeId, NULL, FSYNC_VOL_OFF, FSYNC_SALVAGE, NULL);
+
+ 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
+ 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");
+#else
+ 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 */
+ Log("AskOffline: request for fileserver to take volume offline failed; trying again...\n");
+ FSYNC_clientFinis();
+ FSYNC_clientInit();
+ }
+ }
+ if (code != SYNC_OK) {
+ Log("AskOffline: request for fileserver to take volume offline failed; salvage aborting.\n");
Abort("Salvage aborted\n");
}
}
void
AskOnline(VolumeId volumeId, char *partition)
{
- if (FSYNC_askfs(volumeId, partition, FSYNC_ON, 0) == FSYNC_DENIED) {
- Log("AskOnline: file server denied online request to volume %u partition %s\n", volumeId, partition);
+ afs_int32 code, i;
+
+ for (i = 0; i < 3; i++) {
+ code = FSYNC_VolOp(volumeId, partition, FSYNC_VOL_ON, FSYNC_WHATEVER, NULL);
+
+ if (code == SYNC_OK) {
+ break;
+ } else if (code == SYNC_DENIED) {
+ Log("AskOnline: file server denied online request to volume %u partition %s; trying again...\n", volumeId, partition);
+ } 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");
+#else
+ Log("AskOnline: please make sure fileserver, volserver and salvager binaries are same version.\n");
+#endif
+ break;
+ } else if (i < 2) {
+ /* try it again */
+ Log("AskOnline: request for fileserver to take volume offline failed; trying again...\n");
+ FSYNC_clientFinis();
+ FSYNC_clientInit();
+ }
}
}
{
register struct ViceInodeInfo *ip;
struct ViceInodeInfo *buf;
- struct stat status;
+ struct afs_stat status;
register nInodes;
- assert(fstat(inodeFd, &status) == 0);
+ assert(afs_fstat(inodeFd, &status) == 0);
buf = (struct ViceInodeInfo *)malloc(status.st_size);
assert(buf != NULL);
nInodes = status.st_size / sizeof(struct ViceInodeInfo);
#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;
}
{
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);
}
void
-CheckLogFile(void)
+CheckLogFile(char * log_path)
{
char oldSlvgLog[AFSDIR_PATH_MAX];
}
#endif
- strcpy(oldSlvgLog, AFSDIR_SERVER_SLVGLOG_FILEPATH);
+ strcpy(oldSlvgLog, log_path);
strcat(oldSlvgLog, ".old");
if (!logFile) {
- renamefile(AFSDIR_SERVER_SLVGLOG_FILEPATH, oldSlvgLog);
- logFile = fopen(AFSDIR_SERVER_SLVGLOG_FILEPATH, "a");
+ renamefile(log_path, oldSlvgLog);
+ logFile = afs_fopen(log_path, "a");
if (!logFile) { /* still nothing, use stdout */
logFile = stdout;
#ifndef AFS_NT40_ENV
void
-TimeStampLogFile(void)
+TimeStampLogFile(char * log_path)
{
char stampSlvgLog[AFSDIR_PATH_MAX];
struct tm *lt;
lt = localtime(&now);
(void)afs_snprintf(stampSlvgLog, sizeof stampSlvgLog,
"%s.%04d-%02d-%02d.%02d:%02d:%02d",
- AFSDIR_SERVER_SLVGLOG_FILEPATH, lt->tm_year + 1900,
+ log_path, lt->tm_year + 1900,
lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min,
lt->tm_sec);
/* try to link the logfile to a timestamped filename */
/* if it fails, oh well, nothing we can do */
- link(AFSDIR_SERVER_SLVGLOG_FILEPATH, stampSlvgLog);
+ link(log_path, stampSlvgLog);
}
#endif
rewind(logFile);
fclose(logFile);
- logFile = fopen(AFSDIR_SERVER_SLVGLOG_FILEPATH, "r");
+ logFile = afs_fopen(AFSDIR_SERVER_SLVGLOG_FILEPATH, "r");
if (!logFile)
printf("Can't read %s, exiting\n", AFSDIR_SERVER_SLVGLOG_FILEPATH);
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();
int
UseTheForceLuke(char *path)
{
- struct stat force;
+ struct afs_stat force;
assert(chdir(path) != -1);
- return (stat("FORCESALVAGE", &force) == 0);
+ return (afs_stat("FORCESALVAGE", &force) == 0);
}
#else
/*
*
* NOTE:
* The VRMIX fsck will not muck with the filesystem it is supposedly
- * fixing and create a "FORCESAVAGE" file (by design). Instead, we
+ * fixing and create a "FORCESALVAGE" file (by design). Instead, we
* muck directly with the root inode, which is within the normal
* domain of fsck.
* ListViceInodes() has a side effect of setting ForceSalvage if
/* Open logFile */
(void)sprintf(logname, "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH,
myjob.cj_number);
- logFile = fopen(logname, "w");
+ logFile = afs_fopen(logname, "w");
if (!logFile)
logFile = stdout;