#include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
#include <sys/stat.h>
#include <fcntl.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
#ifdef AFS_NT40_ENV
#include <io.h>
#include <windows.h>
int eventlog = 0, rxlog = 0;
FILE *debugFile;
-FILE *console = NULL;
#ifdef AFS_PTHREAD_ENV
pthread_mutex_t fsync_glock_mutex;
#endif /* AFS_PTHREAD_ENV */
#ifdef AFS_NT40_ENV
-#define AFS_QUIETFS_ENV 1
#define NT_OPEN_MAX 1024 /* This is an arbitrary no. we came up with for
* now. We hope this will be replaced by a more
* intelligent estimate later. */
#endif
time_t StartTime;
+/**
+ * seconds to wait until forcing a panic during ShutDownAndCore(PANIC)
+ * in case we get stuck.
+ */
+#ifdef AFS_DEMAND_ATTACH_FS
+static int panic_timeout = 2 * 60;
+#else
+static int panic_timeout = 30 * 60;
+#endif
+
int rxpackets = 150; /* 100 */
int nSmallVns = 400; /* 200 */
int large = 400; /* 200 */
int udpBufSize = 0; /* UDP buffer size for receive */
int sendBufSize = 16384; /* send buffer size */
int saneacls = 0; /* Sane ACLs Flag */
+static int unsafe_attach = 0; /* avoid inUse check on vol attach? */
struct timeval tp;
}
#endif
-/* proc called by rxkad module to get a key */
-static int
-get_key(void *arock, register afs_int32 akvno, struct ktc_encryptionKey *akey)
-{
- /* find the key */
- static struct afsconf_key tkey;
- register afs_int32 code;
-
- if (!confDir) {
- ViceLog(0, ("conf dir not open\n"));
- return 1;
- }
- code = afsconf_GetKey(confDir, akvno, (struct ktc_encryptionKey *)tkey.key);
- if (code) {
- ViceLog(0, ("afsconf_GetKey failure: kvno %d code %d\n", akvno, code));
- return code;
- }
- memcpy(akey, tkey.key, sizeof(tkey.key));
- return 0;
-} /*get_key */
-
#ifndef AFS_NT40_ENV
int
viced_syscall(afs_uint32 a3, afs_uint32 a4, void *a5)
pthread_setspecific(rx_thread_id_key, (void *)(intptr_t)rxi_pthread_hinum);
MUTEX_EXIT(&rx_stats_mutex);
ViceLog(0,
- ("Set thread id %d for '%s'\n",
+ ("Set thread id %p for '%s'\n",
pthread_getspecific(rx_thread_id_key), s));
#endif
}
#endif
if (printBanner && (++msg & 1)) { /* Every 10 minutes */
time_t now = FT_ApproxTime();
- if (console != NULL) {
-#ifndef AFS_QUIETFS_ENV
- fprintf(console, "File server is running at %s\r",
- afs_ctime(&now, tbuffer, sizeof(tbuffer)));
-#endif /* AFS_QUIETFS_ENV */
- ViceLog(2,
- ("File server is running at %s\n",
- afs_ctime(&now, tbuffer, sizeof(tbuffer))));
- }
+ ViceLog(2,
+ ("File server is running at %s\n",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer))));
}
#ifdef AFS_DEMAND_ATTACH_FS
FS_STATE_WRLOCK;
return 0;
} /*CheckSignal */
+static void *
+ShutdownWatchdogLWP(void *unused)
+{
+ sleep(panic_timeout);
+ ViceLog(0, ("ShutdownWatchdogLWP: Failed to shutdown and panic "
+ "within %d seconds; forcing panic\n", panic_timeout));
+ assert(0);
+ return NULL;
+}
+
void
ShutDownAndCore(int dopanic)
{
time_t now = time(0);
char tbuffer[32];
+ if (dopanic) {
+#ifdef AFS_PTHREAD_ENV
+ pthread_t watchdogPid;
+ pthread_attr_t tattr;
+ assert(pthread_attr_init(&tattr) == 0);
+ assert(pthread_create(&watchdogPid, &tattr, ShutdownWatchdogLWP, NULL) == 0);
+#else
+ PROCESS watchdogPid;
+ assert(LWP_CreateProcess
+ (ShutdownWatchdogLWP, stack * 1024, LWP_MAX_PRIORITY - 2,
+ NULL, "ShutdownWatchdog", &watchdogPid) == LWP_SUCCESS);
+#endif
+ }
+
/* do not allows new reqests to be served from now on, all new requests
* are returned with an error code of RX_RESTARTING ( transient failure ) */
rx_SetRxTranquil(); /* dhruba */
#ifdef AFS_DEMAND_ATTACH_FS
FS_STATE_WRLOCK;
+ if (fs_state.mode == FS_MODE_SHUTDOWN) {
+ /* it is possible for at least fs_stateSave() (called below) to call
+ * ShutDownAndCore if there's host list corruption; prevent
+ * deinitializing some stuff twice */
+ ViceLog(0, ("ShutDownAndCore called during shutdown? Skipping volume "
+ "and host package shutdown\n"));
+ FS_STATE_UNLOCK;
+ goto done_vol_host;
+ }
fs_state.mode = FS_MODE_SHUTDOWN;
FS_STATE_UNLOCK;
#endif
afs_ctime(&now, tbuffer, sizeof(tbuffer))));
if (dopanic)
ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
-#ifndef AFS_QUIETFS_ENV
- if (console != NULL) {
- fprintf(console, "File server restart/shutdown received at %s\r",
- afs_ctime(&now, tbuffer, sizeof(tbuffer)));
- }
-#endif
DFlush();
if (!dopanic)
PrintCounters();
* demand attach fs
* save fileserver state to disk */
- /* make sure background threads have finished all of their asynchronous
- * work on host and callback structures */
- FS_STATE_RDLOCK;
- while (!fs_state.FiveMinuteLWP_tranquil ||
- !fs_state.HostCheckLWP_tranquil ||
- !fs_state.FsyncCheckLWP_tranquil) {
- FS_LOCK;
- FS_STATE_UNLOCK;
- ViceLog(0, ("waiting for background host/callback threads to quiesce before saving fileserver state...\n"));
- assert(pthread_cond_wait(&fs_state.worker_done_cv, &fileproc_glock_mutex) == 0);
- FS_UNLOCK;
+ if (dopanic) {
+ ViceLog(0, ("Not saving fileserver state; abnormal shutdown\n"));
+
+ } else {
+ /* make sure background threads have finished all of their asynchronous
+ * work on host and callback structures */
FS_STATE_RDLOCK;
- }
+ while (!fs_state.FiveMinuteLWP_tranquil ||
+ !fs_state.HostCheckLWP_tranquil ||
+ !fs_state.FsyncCheckLWP_tranquil) {
+ FS_LOCK;
+ FS_STATE_UNLOCK;
+ ViceLog(0, ("waiting for background host/callback threads to quiesce before saving fileserver state...\n"));
+ assert(pthread_cond_wait(&fs_state.worker_done_cv, &fileproc_glock_mutex) == 0);
+ FS_UNLOCK;
+ FS_STATE_RDLOCK;
+ }
+ FS_STATE_UNLOCK;
- /* ok. it should now be fairly safe. let's do the state dump */
- fs_stateSave();
+ /* ok. it should now be fairly safe. let's do the state dump */
+ fs_stateSave();
+ }
}
+ done_vol_host:
+
#endif /* AFS_DEMAND_ATTACH_FS */
if (debugFile) {
rx_PrintStats(debugFile);
fflush(debugFile);
}
- if (console != NULL) {
- now = time(0);
- if (dopanic) {
-#ifndef AFS_QUIETFS_ENV
- fprintf(console, "File server has terminated abnormally at %s\r",
- afs_ctime(&now, tbuffer, sizeof(tbuffer)));
-#endif
- ViceLog(0,
- ("File server has terminated abnormally at %s\n",
- afs_ctime(&now, tbuffer, sizeof(tbuffer))));
- } else {
-#ifndef AFS_QUIETFS_ENV
- fprintf(console, "File server has terminated normally at %s\r",
- afs_ctime(&now, tbuffer, sizeof(tbuffer)));
-#endif
- ViceLog(0,
- ("File server has terminated normally at %s\n",
- afs_ctime(&now, tbuffer, sizeof(tbuffer))));
- }
+ now = time(0);
+ if (dopanic) {
+ ViceLog(0,
+ ("File server has terminated abnormally at %s\n",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer))));
+ } else {
+ ViceLog(0,
+ ("File server has terminated normally at %s\n",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer))));
}
if (dopanic)
fputs("[-vlruthresh <minutes before unused volumes become eligible for soft detach> (default is 2 hours)] ", stdout);
fputs("[-vlruinterval <seconds between VLRU scans> (default is 2 minutes)] ", stdout);
fputs("[-vlrumax <max volumes to soft detach in one VLRU scan> (default is 8)] ", stdout);
+ fputs("[-unsafe-nosalvage (bypass volume inUse safety check on attach, bypassing salvage)] ", stdout);
#elif AFS_PTHREAD_ENV
fputs("[-vattachpar <number of volume attach threads> (default is 1)] ", stdout);
#endif
return -1;
}
VLRU_SetOptions(VLRU_SET_MAX, atoi(argv[++i]));
+ } else if (!strcmp(argv[i], "-unsafe-nosalvage")) {
+ unsafe_attach = 1;
#endif /* AFS_DEMAND_ATTACH_FS */
} else if (!strcmp(argv[i], "-s")) {
Sawsmall = 1;
ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
} else {
ViceLog(0,
- ("Read on parms failed; expected %d bytes but read %d\n",
- sbuf.st_size, i));
+ ("Read on parms failed; expected %ld bytes but read %d\n",
+ (long) sbuf.st_size, i));
}
free(parms);
return;
afs_int32
vl_Initialize(const char *confDir)
{
- afs_int32 code, scIndex = 0, i;
+ afs_int32 code, i;
+ afs_int32 scIndex = RX_SECIDX_NULL;
struct afsconf_dir *tdir;
struct rx_securityClass *sc;
struct afsconf_cell info;
{
afs_int32 code;
char tbuffer[32];
- struct rx_securityClass *sc[4];
+ struct rx_securityClass **securityClasses;
+ afs_int32 numClasses;
struct rx_service *tservice;
#ifdef AFS_PTHREAD_ENV
pthread_t serverPid;
int curLimit;
time_t t;
afs_uint32 rx_bindhost;
+ VolumePackageOptions opts;
#ifdef AFS_AIX32_ENV
struct sigaction nsa;
argv[0]);
exit(2);
}
-#ifndef AFS_QUIETFS_ENV
- console = afs_fopen("/dev/console", "w");
-#endif
/* set ihandle package defaults prior to parsing args */
ih_PkgDefaults();
}
rx_GetIFInfo();
rx_SetRxDeadTime(30);
- sc[0] = rxnull_NewServerSecurityObject();
- sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
- sc[2] = rxkad_NewServerSecurityObject(rxkad_clear, NULL, get_key, NULL);
- sc[3] = rxkad_NewServerSecurityObject(rxkad_crypt, NULL, get_key, NULL);
+ afsconf_BuildServerSecurityObjects(confDir, AFSCONF_SEC_OBJS_RXKAD_CRYPT,
+ &securityClasses, &numClasses);
+
tservice = rx_NewServiceHost(rx_bindhost, /* port */ 0, /* service id */
1, /*service name */
"AFS",
- /* security classes */ sc,
- /* numb sec classes */
- 4, RXAFS_ExecuteRequest);
+ securityClasses, numClasses,
+ RXAFS_ExecuteRequest);
if (!tservice) {
ViceLog(0,
("Failed to initialize RX, probably two servers running.\n"));
rx_SetServerIdleDeadErr(tservice, VNOSERVICE);
tservice =
- rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4,
- RXSTATS_ExecuteRequest);
+ rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses,
+ numClasses, RXSTATS_ExecuteRequest);
if (!tservice) {
ViceLog(0, ("Failed to initialize rpc stat service.\n"));
exit(-1);
* will be available "real soon now". Worry about whether we can satisfy the
* calls in the volume package itself.
*/
- if (VInitVolumePackage(fileServer, large, nSmallVns, 0, volcache)) {
+ VOptDefaults(fileServer, &opts);
+ opts.nLargeVnodes = large;
+ opts.nSmallVnodes = nSmallVns;
+ opts.volcache = volcache;
+ opts.unsafe_attach = unsafe_attach;
+
+ if (VInitVolumePackage2(fileServer, &opts)) {
ViceLog(0,
("Shutting down: errors encountered initializing volume package\n"));
VShutdown();
FT_GetTimeOfDay(&tp, 0);
-#ifndef AFS_QUIETFS_ENV
- if (console != NULL) {
- time_t t = tp.tv_sec;
- fprintf(console, "File server has started at %s\r",
- afs_ctime(&t, tbuffer, sizeof(tbuffer)));
- }
-#endif
+ ViceLog(0, ("File server has started at %s",
+ afs_ctime((time_t *)&(tp.tv_sec), tbuffer, sizeof(tbuffer))));
/*
* Figure out the FileServer's name and primary address.