#include <pthread.h>
#endif
-char *logFileName = NULL;
+extern int ClientMode;
#if !defined(AFS_DEMAND_ATTACH_FS)
#error "online salvager only supported for demand attach fileserver"
static int Reap_Child(char * prog, int * pid, int * status);
static void * SalvageLogCleanupThread(void *);
-static int SalvageLogCleanup(int pid);
+static void SalvageLogCleanup(int pid);
static void * SalvageLogScanningThread(void *);
static void ScanLogs(struct rx_queue *log_watch_queue);
}
#ifndef AFS_NT40_ENV /* ignore options on NT */
if (cmd_OptionPresent(opts, OPT_syslog)) {
- useSyslog = 1;
+ serverLogSyslog = 1;
}
- cmd_OptionAsInt(opts, OPT_syslogfacility, &useSyslogFacility);
+ cmd_OptionAsInt(opts, OPT_syslogfacility, &serverLogSyslogFacility);
#endif
if (cmd_OptionPresent(opts, OPT_client)) {
arock.argc = argc;
arock.argv = argv;
- logFileName = strdup(AFSDIR_SERVER_SALSRVLOG_FILEPATH);
ts = cmd_CreateSyntax("initcmd", handleit, &arock, 0, "initialize the program");
cmd_AddParmAtOffset(ts, OPT_partition, "-partition", CMD_SINGLE,
VolumePackageOptions opts;
/* Send Log() messages to stderr in client mode. */
- logFile = stderr;
+ ClientMode = 1;
VOptDefaults(volumeUtility, &opts);
if (VInitVolumePackage2(volumeUtility, &opts)) {
/* All entries to the log will be appended. Useful if there are
* multiple salvagers appending to the log.
*/
+ OpenLog(AFSDIR_SERVER_SALSRVLOG_FILEPATH);
+ SetupLogSignals();
- CheckLogFile(logFileName);
-#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);
-
- fprintf(logFile, "%s\n", cml_version_number);
+ Log("%s\n", cml_version_number);
LogCommandLine(argc, argv, "Online Salvage Server",
SalvageVersion, "Starting OpenAFS", Log);
/* Get and hold a lock for the duration of the salvage to make sure
/* do not allow further forking inside salvager */
canfork = 0;
- /* do not attempt to close parent's logFile handle as
- * another thread may have held the lock on the FILE
- * structure when fork was called! */
-
+ /*
+ * Do not attempt to close parent's log file handle as
+ * another thread may have held the lock when fork was
+ * called!
+ */
if (asprintf(&childLog, "%s.%d",
AFSDIR_SERVER_SLVGLOG_FILEPATH, getpid()) < 0) {
- logFile = stdout;
- } else {
- logFile = afs_fopen(childLog, "a");
- if (!logFile) { /* still nothing, use stdout */
- logFile = stdout;
- }
- free(childLog);
+ fprintf(stderr, "out of memory\n");
+ return ENOMEM;
}
+ OpenLog(childLog);
+ free(childLog);
if (node->command.sop.parent <= 0) {
Log("salvageServer: invalid volume id specified; salvage aborted\n");
/* Salvage individual volume; don't notify fs */
SalvageFileSys1(partP, node->command.sop.parent);
- fclose(logFile);
+ CloseLog();
return 0;
}
}
#define LOG_XFER_BUF_SIZE 65536
-static int
+static void
SalvageLogCleanup(int pid)
{
int pidlog, len;
- char *fn;
- static char buf[LOG_XFER_BUF_SIZE];
+ char *fn = NULL;
+ char *buf = NULL;
- if (asprintf(&fn, "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH, pid) < 0)
- return 1;
+ if (asprintf(&fn, "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH, pid) < 0) {
+ Log("Unable to write child log: out of memory\n");
+ goto done;
+ }
+
+ buf = calloc(1, LOG_XFER_BUF_SIZE);
+ if (buf != NULL) {
+ Log("Unable to write child log: out of memory\n");
+ goto done;
+ }
pidlog = open(fn, O_RDONLY);
unlink(fn);
- free(fn);
if (pidlog < 0)
- return 1;
+ goto done;
len = read(pidlog, buf, LOG_XFER_BUF_SIZE);
while (len) {
- fwrite(buf, len, 1, logFile);
+ WriteLogBuffer(buf, len);
len = read(pidlog, buf, LOG_XFER_BUF_SIZE);
}
close(pidlog);
- return 0;
+ done:
+ free(fn);
+ free(buf);
}
/* wake up every five minutes to see if a non-child salvage has finished */
pthread_t main_thread;
#endif
+extern char *ShowLogFilename;
+extern char cml_version_number[];
static int get_salvage_lock = 0;
+struct CmdLine {
+ int argc;
+ char **argv;
+};
+
+#ifndef AFS_NT40_ENV
+static int
+TimeStampLogFile(char **logfile)
+{
+ char *stampSlvgLog;
+ struct tm *lt;
+ time_t now;
+
+ now = time(0);
+ lt = localtime(&now);
+ if (asprintf(&stampSlvgLog,
+ "%s.%04d-%02d-%02d.%02d:%02d:%02d",
+ AFSDIR_SERVER_SLVGLOG_FILEPATH,
+ lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour,
+ lt->tm_min, lt->tm_sec) < 0) {
+ return ENOMEM;
+ }
+ free(*logfile); /* free the default name */
+ *logfile = stampSlvgLog;
+ return 0;
+}
+#endif
+
static int
handleit(struct cmd_syndesc *as, void *arock)
{
+ struct CmdLine *cmdline = (struct CmdLine*)arock;
struct cmd_item *ti;
char pname[100], *temp;
afs_int32 seenpart = 0, seenvol = 0;
VolumeId vid = 0;
ProgramType pt;
+ char *logfile = strdup(AFSDIR_SERVER_SLVGLOG_FILEPATH);
#ifdef FAST_RESTART
afs_int32 seenany = 0;
}
}
if (!seenany) {
- char *msg =
- "Exiting immediately without salvage. Look into the FileLog to find volumes which really need to be salvaged!";
-
-#ifndef AFS_NT40_ENV
- if (useSyslog)
- Log("%s", msg);
- else
-#endif
- printf("%s\n", msg);
-
+ printf
+ ("Exiting immediately without salvage. "
+ "Look into the FileLog to find volumes which really need to be salvaged!\n");
Exit(0);
}
#endif /* FAST_RESTART */
}
#ifndef AFS_NT40_ENV /* ignore options on NT */
if ((ti = as->parms[16].items)) { /* -syslog */
- useSyslog = 1;
+ if (ShowLog) {
+ fprintf(stderr, "Invalid options: -syslog and -showlog are exclusive.\n");
+ Exit(1);
+ }
+ serverLogSyslog = 1;
}
if ((ti = as->parms[17].items)) { /* -syslogfacility */
- useSyslogFacility = atoi(ti->data);
+ serverLogSyslogFacility = atoi(ti->data);
}
if ((ti = as->parms[18].items)) { /* -datelogs */
- TimeStampLogFile((char *)AFSDIR_SERVER_SLVGLOG_FILEPATH);
+ int code = TimeStampLogFile(&logfile);
+ if (code != 0) {
+ fprintf(stderr, "Failed to format log file name for -datelogs; code=%d\n", code);
+ Exit(code);
+ }
+ ShowLogFilename = logfile;
}
#endif
+ OpenLog(logfile);
+ SetupLogSignals();
+
+ Log("%s\n", cml_version_number);
+ LogCommandLine(cmdline->argc, cmdline->argv, "SALVAGER", SalvageVersion, "STARTING AFS", Log);
+
#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!";
-
-#ifndef AFS_NT40_ENV
- if (useSyslog)
- Log("%s", msg);
- else
-#endif
- printf("%s\n", msg);
+ Log("%s\n", msg);
+ printf("%s\n", msg);
Exit(0);
}
#endif
#endif
if (msg) {
-#ifndef AFS_NT40_ENV
- if (useSyslog)
- Log("%s", msg);
- else
-#endif
- printf("%s\n", msg);
+ Log("%s\n", msg);
+ printf("%s\n", msg);
Exit(1);
}
}
int
main(int argc, char **argv)
{
+ struct CmdLine cmdline;
struct cmd_syndesc *ts;
int err = 0;
- extern char cml_version_number[];
-
#ifdef AFS_AIX32_ENV
/*
* The following signal action for AIX is necessary so that in case of a
exit(3);
} else {
#endif
- /* All entries to the log will be appended. Useful if there are
- * multiple salvagers appending to the log.
- */
-
- CheckLogFile((char *)AFSDIR_SERVER_SLVGLOG_FILEPATH);
-#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) {
}
#endif
- /* bad for normal help flag processing, but can do nada */
-
- fprintf(logFile, "%s\n", cml_version_number);
- LogCommandLine(argc, argv, "SALVAGER", SalvageVersion, "STARTING AFS",
- Log);
-
/* 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
* VInitVolumePackage2 (called below) makes sure that a file server or
}
#endif
- ts = cmd_CreateSyntax("initcmd", handleit, NULL, 0, "initialize the program");
+ cmdline.argc = argc;
+ cmdline.argv = argv;
+ ts = cmd_CreateSyntax("initcmd", handleit, &cmdline, 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,
#include <pthread.h>
#endif
+#define SALV_BUFFER_SIZE 1024
+
#ifdef AFS_OSF_ENV
extern void *calloc();
#endif
-static char *TimeStamp(time_t clock, int precision);
+static char *TimeStamp(char *buffer, size_t size, time_t clock, int precision);
int debug; /* -d flag */
int PartsPerDisk = 8; /* Salvage up to 8 partitions on same disk sequentially */
int forceR = 0; /* -b flag */
int ShowLog = 0; /* -showlog flag */
+char *ShowLogFilename = NULL; /* log file name for -showlog */
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
+int ClientMode = 0; /* running as salvager server client */
#ifdef AFS_NT40_ENV
int canfork = 0;
int ForceSalvage; /* If salvage should occur despite the DONT_SALVAGE flag
* in the volume header */
-FILE *logFile = 0; /* one of {/usr/afs/logs,/vice/file}/SalvageLog */
-
#define ROOTINODE 2 /* Root inode of a 4.2 Unix file system
* partition */
/**
struct job *thisjob = 0;
static int numjobs = 0;
static int jobcount = 0;
- char buf[1024];
int wstatus;
struct job *oldjob;
int startjob;
FILE *passLog;
- char logFileName[256];
int i, j, pid;
if (partP) {
numjobs++;
} else {
int fd;
+ char *logFileName;
- ShowLog = 0; /* Child processes do not display. */
for (fd = 0; fd < 16; fd++)
close(fd);
open(OS_DIRSEP, 0);
dup2(0, 1);
dup2(0, 2);
-#ifndef AFS_NT40_ENV
- if (useSyslog) {
- openlog("salvager", LOG_PID, useSyslogFacility);
- } else
-#endif
- {
- snprintf(logFileName, sizeof logFileName, "%s.%d",
+
+ ShowLog = 0; /* Child processes do not display. */
+ if (asprintf(&logFileName, "%s.%d",
AFSDIR_SERVER_SLVGLOG_FILEPATH,
- jobs[startjob]->jobnumb);
- logFile = afs_fopen(logFileName, "w");
+ jobs[startjob]->jobnumb) >= 0) {
+ OpenLog(logFileName);
+ free(logFileName);
}
- if (!logFile)
- logFile = stdout;
SalvageFileSys1(jobs[startjob]->partP, 0);
Exit(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 */
+ if (!serverLogSyslog) /* if syslogging - no need to collect */
#endif
if (!partP) {
- for (i = 0; i < jobcount; i++) {
- snprintf(logFileName, sizeof logFileName, "%s.%d",
- AFSDIR_SERVER_SLVGLOG_FILEPATH, i);
- if ((passLog = afs_fopen(logFileName, "r"))) {
- while (fgets(buf, sizeof(buf), passLog)) {
- fputs(buf, logFile);
+ char *buf = calloc(1, SALV_BUFFER_SIZE);
+ char *logFileName;
+
+ if (buf == NULL) {
+ Log("out of memory");
+ } else {
+ for (i = 0; i < jobcount; i++) {
+ if (asprintf(&logFileName, "%s.%d",
+ AFSDIR_SERVER_SLVGLOG_FILEPATH, i) < 0) {
+ Log("out of memory");
+ break;
+ }
+ if ((passLog = afs_fopen(logFileName, "r"))) {
+ while (fgets(buf, SALV_BUFFER_SIZE, passLog)) {
+ WriteLogBuffer(buf, strlen(buf));
+ }
+ fclose(passLog);
}
- fclose(passLog);
+ (void)unlink(logFileName);
+ free(logFileName);
}
- (void)unlink(logFileName);
+ free(buf);
}
- fflush(logFile);
}
+
return;
}
if (sp->inodeType == VI_VOLINFO) {
salvinfo->VolInfo = header.volumeInfo;
if (check) {
- char update[25];
+ char update[64];
+ char buffer[64];
if (salvinfo->VolInfo.updateDate) {
- strcpy(update, TimeStamp(salvinfo->VolInfo.updateDate, 0));
+ strcpy(update, TimeStamp(buffer, sizeof(buffer), salvinfo->VolInfo.updateDate, 0));
if (!Showmode)
Log("%s (%" AFS_VOLID_FMT ") %supdated %s\n", salvinfo->VolInfo.name,
afs_printable_VolumeId_lu(salvinfo->VolInfo.id),
(Testing ? "it would have been " : ""), update);
} else {
- strcpy(update, TimeStamp(salvinfo->VolInfo.creationDate, 0));
+ strcpy(update, TimeStamp(buffer, sizeof(buffer), salvinfo->VolInfo.creationDate, 0));
if (!Showmode)
Log("%s (%" AFS_VOLID_FMT ") not updated (created %s)\n",
salvinfo->VolInfo.name, afs_printable_VolumeId_lu(salvinfo->VolInfo.id), update);
}
static char *
-TimeStamp(time_t clock, int precision)
+TimeStamp(char *buffer, size_t size, time_t clock, int precision)
{
struct tm *lt;
- static char timestamp[20];
+ size_t nbytes;
+
lt = localtime(&clock);
if (precision)
- (void)strftime(timestamp, 20, "%m/%d/%Y %H:%M:%S", lt);
+ nbytes = strftime(buffer, size, "%m/%d/%Y %H:%M:%S", lt);
else
- (void)strftime(timestamp, 20, "%m/%d/%Y %H:%M", lt);
- return timestamp;
-}
-
-void
-CheckLogFile(char * log_path)
-{
- char *oldSlvgLog;
-
-#ifndef AFS_NT40_ENV
- if (useSyslog) {
- return;
- }
-#endif
-
- if (!logFile) {
- if (asprintf(&oldSlvgLog, "%s.old", log_path) >= 0) {
- rk_rename(log_path, oldSlvgLog);
- free(oldSlvgLog);
- }
- logFile = afs_fopen(log_path, "a");
-
- if (!logFile) { /* still nothing, use stdout */
- logFile = stdout;
- }
-#ifndef AFS_NAMEI_ENV
- AFS_DEBUG_IOPS_LOG(logFile);
-#endif
- }
+ nbytes = strftime(buffer, size, "%m/%d/%Y %H:%M", lt);
+ if (nbytes == 0)
+ memset(buffer, 0, size);
+ return buffer;
}
-#ifndef AFS_NT40_ENV
-void
-TimeStampLogFile(char * log_path)
-{
- char *stampSlvgLog;
- struct tm *lt;
- time_t now;
-
- now = time(0);
- lt = localtime(&now);
- if (asprintf(&stampSlvgLog,
- "%s.%04d-%02d-%02d.%02d:%02d:%02d", log_path,
- lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour,
- lt->tm_min, lt->tm_sec) >= 0) {
- /* try to link the logfile to a timestamped filename */
- /* if it fails, oh well, nothing we can do */
- if (link(log_path, stampSlvgLog))
- ; /* oh well */
- free(stampSlvgLog);
- }
-}
-#endif
-
static void
SalvageShowLog(void)
{
char line[256];
+ FILE *logFile;
- if (ShowLog == 0 || logFile == stdout || logFile == stderr) {
+ if (ShowLog == 0 || ClientMode) {
return;
}
-#ifndef AFS_NT40_ENV
- if (useSyslog) {
- printf("Can't show log since using syslog.\n");
- fflush(stdout);
- return;
- }
-#endif
-
- if (logFile) {
- rewind(logFile);
- fclose(logFile);
+ if (ShowLogFilename == NULL) {
+ ShowLogFilename = strdup(AFSDIR_SERVER_SLVGLOG_FILEPATH);
}
-
- logFile = afs_fopen(AFSDIR_SERVER_SLVGLOG_FILEPATH, "r");
-
+ CloseLog();
+ logFile = afs_fopen(ShowLogFilename, "r");
if (!logFile)
- printf("Can't read %s, exiting\n", AFSDIR_SERVER_SLVGLOG_FILEPATH);
+ printf("Can't read %s, exiting\n", ShowLogFilename);
else {
- rewind(logFile);
while (fgets(line, sizeof(line), logFile))
printf("%s", line);
fflush(stdout);
}
}
+static void
+vLog(const char *format, va_list args)
+{
+ if (!ClientMode) {
+ vFSLog(format, args);
+ } else {
+ struct timeval now;
+ char buffer[64];
+
+ gettimeofday(&now, NULL);
+ fprintf(stderr, "%s ", TimeStamp(buffer, sizeof(buffer), now.tv_sec, 1));
+ vfprintf(stderr, format, args);
+ fflush(stderr);
+ }
+}
+
void
Log(const char *format, ...)
{
- struct timeval now;
- char tmp[1024];
va_list args;
va_start(args, format);
- vsnprintf(tmp, sizeof tmp, format, args);
+ vLog(format, args);
va_end(args);
-#ifndef AFS_NT40_ENV
- if (useSyslog) {
- syslog(LOG_INFO, "%s", tmp);
- } else
-#endif
- if (logFile) {
- gettimeofday(&now, NULL);
- fprintf(logFile, "%s %s", TimeStamp(now.tv_sec, 1), tmp);
- fflush(logFile);
- }
}
void
Abort(const char *format, ...)
{
va_list args;
- char tmp[1024];
va_start(args, format);
- vsnprintf(tmp, sizeof tmp, format, args);
+ vLog(format, args);
va_end(args);
-#ifndef AFS_NT40_ENV
- if (useSyslog) {
- syslog(LOG_INFO, "%s", tmp);
- } else
-#endif
- if (logFile) {
- fprintf(logFile, "%s", tmp);
- fflush(logFile);
- SalvageShowLog();
- }
-
+ SalvageShowLog();
if (debug)
abort();
QuietExit(1);
if (asprintf(&logname, "%s.%d", AFSDIR_SERVER_SLVGLOG_FILEPATH,
myjob.cj_number) < 0)
return -1;
- logFile = afs_fopen(logname, "w");
+ OpenLog(logname);
free(logname);
- if (!logFile)
- logFile = stdout;
return 0;
}
extern int orphans; /* -orphans option */
extern int Showmode;
-#ifndef AFS_NT40_ENV
-extern int useSyslog; /* -syslog flag */
-extern int useSyslogFacility; /* -syslogfacility option */
-#endif
-
#define MAXPARALLEL 32
extern int OKToZap; /* -o flag */
extern char * tmpdir;
-extern FILE *logFile; /* one of {/usr/afs/logs,/vice/file}/SalvageLog */
#ifdef AFS_NT40_ENV
extern void AskOnline(struct SalvInfo *salvinfo, VolumeId volumeId);
extern void AskDelete(struct SalvInfo *salvinfo, VolumeId volumeId);
extern void CheckLogFile(char * log_path);
-#ifndef AFS_NT40_ENV
-extern void TimeStampLogFile(char * log_path);
-#endif
extern void ClearROInUseBit(struct VolumeSummary *summary);
extern void CopyAndSalvage(struct SalvInfo *salvinfo, struct DirSummary *dir);
extern int CopyInode(Device device, Inode inode1, Inode inode2, int rwvolume);