Esempio n. 1
0
void RPC2_DispatchProcess()
{
    struct timeval tv;
    int fd;

    while ((fd = rpc2_MorePackets()) != -1)
        rpc2_ProcessPacket(fd);

    /* keep current time from being too inaccurate */
    (void)FT_GetTimeOfDay(&tv, (struct timezone *)0);

    /* also check for timed-out events, using current time */
    rpc2_ExpireEvents();

    LWP_DispatchProcess();
}
Esempio n. 2
0
int
OpenLog(const char *fileName)
{
    /*
     * This function should allow various libraries that inconsistently
     * use stdout/stderr to all go to the same place
     */
    int tempfd, isfifo = 0;
    char oldName[MAXPATHLEN];
    struct timeval Start;
    struct tm *TimeFields;
    char FileName[MAXPATHLEN];

#ifndef AFS_NT40_ENV
    struct stat statbuf;

    if (serverLogSyslog) {
	openlog(serverLogSyslogTag, LOG_PID, serverLogSyslogFacility);
	return (0);
    }

    /* Support named pipes as logs by not rotating them */
    if ((lstat(fileName, &statbuf) == 0)  && (S_ISFIFO(statbuf.st_mode))) {
	isfifo = 1;
    }
#endif

    if (mrafsStyleLogs) {
        time_t t;
	struct stat buf;
	FT_GetTimeOfDay(&Start, 0);
        t = Start.tv_sec;	
	TimeFields = localtime(&t);
	if (fileName) {
	    if (strncmp(fileName, (char *)&ourName, strlen(fileName)))
		strcpy((char *)&ourName, (char *)fileName);
	}
    makefilename:
	afs_snprintf(FileName, MAXPATHLEN, "%s.%d%02d%02d%02d%02d%02d",
		     ourName, TimeFields->tm_year + 1900,
		     TimeFields->tm_mon + 1, TimeFields->tm_mday,
		     TimeFields->tm_hour, TimeFields->tm_min,
		     TimeFields->tm_sec);
        if(lstat(FileName, &buf) == 0) {
            /* avoid clobbering a log */
            TimeFields->tm_sec++;
            goto makefilename;
        }
	if (!isfifo)
	    renamefile(fileName, FileName);	/* don't check error code */
	tempfd = open(fileName, O_WRONLY | O_TRUNC | O_CREAT | O_APPEND | (isfifo?O_NONBLOCK:0), 0666);
    } else {
	strcpy(oldName, fileName);
	strcat(oldName, ".old");

	/* don't check error */
	if (!isfifo)
	    renamefile(fileName, oldName);
	tempfd = open(fileName, O_WRONLY | O_TRUNC | O_CREAT | (isfifo?O_NONBLOCK:0), 0666);
    }

    if (tempfd < 0) {
	printf("Unable to open log file %s\n", fileName);
	return -1;
    }
    /* redirect stdout and stderr so random printf's don't write to data */
    (void)freopen(fileName, "a", stdout);
    (void)freopen(fileName, "a", stderr);
#ifdef HAVE_SETVBUF
    setvbuf(stderr, NULL, _IONBF, 0);
#else
    setbuf(stderr, NULL);
#endif

#if defined(AFS_PTHREAD_ENV)
    MUTEX_INIT(&serverLogMutex, "serverlog", MUTEX_DEFAULT, 0);
#endif /* AFS_PTHREAD_ENV */

    serverLogFD = tempfd;

    if (mrafsStyleLogs) {
	FSLog("Running version %s\n", cml_version_number +4); 
    }

    return 0;
}				/*OpenLog */
Esempio n. 3
0
int 
main(int argc, char **argv)
{
    afs_int32 code;
    struct rx_securityClass **securityClasses;
    afs_int32 numClasses;
    struct rx_service *service;
    struct ktc_encryptionKey tkey;
    int rxpackets = 100;
    int rxJumbograms = 0;	/* default is to send and receive jumbograms. */
    int rxMaxMTU = -1;
    int bufSize = 0;		/* temp variable to read in udp socket buf size */
    afs_uint32 host = ntohl(INADDR_ANY);
    char *auditFileName = NULL;
    VolumePackageOptions opts;

#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);
#endif
    osi_audit_init();
    osi_audit(VS_StartEvent, 0, AUD_END);

    /* Initialize dirpaths */
    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);
    }

    TTsleep = TTrun = 0;

    /* parse cmd line */
    for (code = 1; code < argc; code++) {
	if (strcmp(argv[code], "-log") == 0) {
	    /* set extra logging flag */
	    DoLogging = 1;
	} else if (strcmp(argv[code], "-help") == 0) {
	    goto usage;
	} else if (strcmp(argv[code], "-rxbind") == 0) {
	    rxBind = 1;
	} else if (strcmp(argv[code], "-allow-dotted-principals") == 0) {
	    rxkadDisableDotCheck = 1;
	} else if (strcmp(argv[code], "-d") == 0) {
	    if ((code + 1) >= argc) {
		fprintf(stderr, "missing argument for -d\n"); 
		return -1; 
	    }
	    debuglevel = atoi(argv[++code]);
	    LogLevel = debuglevel;
	} else if (strcmp(argv[code], "-p") == 0) {
	    lwps = atoi(argv[++code]);
	    if (lwps > MAXLWP) {
		printf("Warning: '-p %d' is too big; using %d instead\n",
		       lwps, MAXLWP);
		lwps = MAXLWP;
	    }
	} else if (strcmp(argv[code], "-auditlog") == 0) {
	    auditFileName = argv[++code];

	} else if (strcmp(argv[code], "-audit-interface") == 0) {
	    char *interface = argv[++code];

	    if (osi_audit_interface(interface)) {
		printf("Invalid audit interface '%s'\n", interface);
		return -1;
	    }
	} else if (strcmp(argv[code], "-nojumbo") == 0) {
	    rxJumbograms = 0;
	} else if (strcmp(argv[code], "-jumbo") == 0) {
	    rxJumbograms = 1;
	} else if (!strcmp(argv[code], "-rxmaxmtu")) {
	    if ((code + 1) >= argc) {
		fprintf(stderr, "missing argument for -rxmaxmtu\n"); 
		exit(1); 
	    }
	    rxMaxMTU = atoi(argv[++code]);
	    if ((rxMaxMTU < RX_MIN_PACKET_SIZE) || 
		(rxMaxMTU > RX_MAX_PACKET_DATA_SIZE)) {
		printf("rxMaxMTU %d invalid; must be between %d-%" AFS_SIZET_FMT "\n",
		       rxMaxMTU, RX_MIN_PACKET_SIZE, 
		       RX_MAX_PACKET_DATA_SIZE);
		exit(1);
	    }
	} else if (strcmp(argv[code], "-sleep") == 0) {
	    sscanf(argv[++code], "%d/%d", &TTsleep, &TTrun);
	    if ((TTsleep < 0) || (TTrun <= 0)) {
		printf("Warning: '-sleep %d/%d' is incorrect; ignoring\n",
		       TTsleep, TTrun);
		TTsleep = TTrun = 0;
	    }
        } else if (strcmp(argv[code], "-mbpersleep") == 0) {
            sscanf(argv[++code], "%d", &MBperSecSleep);
            if (MBperSecSleep < 0)
                MBperSecSleep = 0;
	} else if (strcmp(argv[code], "-udpsize") == 0) {
	    if ((code + 1) >= argc) {
		printf("You have to specify -udpsize <integer value>\n");
		exit(1);
	    }
	    sscanf(argv[++code], "%d", &bufSize);
	    if (bufSize < rx_GetMinUdpBufSize())
		printf
		    ("Warning:udpsize %d is less than minimum %d; ignoring\n",
		     bufSize, rx_GetMinUdpBufSize());
	    else
		udpBufSize = bufSize;
	} else if (strcmp(argv[code], "-enable_peer_stats") == 0) {
	    rx_enablePeerRPCStats();
	} else if (strcmp(argv[code], "-enable_process_stats") == 0) {
	    rx_enableProcessRPCStats();
	} else if (strcmp(argv[code], "-preserve-vol-stats") == 0) {
	    DoPreserveVolumeStats = 1;
        } else if (strcmp(argv[code], "-sync") == 0) {
            if ((code + 1) >= argc) {
                printf("You have to specify -sync <sync_behavior>\n");
                exit(1);
            }
            ih_PkgDefaults();
            if (ih_SetSyncBehavior(argv[++code])) {
                printf("Invalid -sync value %s\n", argv[code]);
                exit(1);
            }
        }
#ifndef AFS_NT40_ENV
	else if (strcmp(argv[code], "-syslog") == 0) {
	    /* set syslog logging flag */
	    serverLogSyslog = 1;
	} else if (strncmp(argv[code], "-syslog=", 8) == 0) {
	    serverLogSyslog = 1;
	    serverLogSyslogFacility = atoi(argv[code] + 8);
	}
#endif
#ifdef AFS_PTHREAD_ENV
        else if (strcmp(argv[code], "-convert") == 0)
            convertToOsd = 1;
        else if (strcmp(argv[code], "-libafsosd") == 0)
            libafsosd = 1;
#endif
	else {
	    printf("volserver: unrecognized flag '%s'\n", argv[code]);
	  usage:
#ifndef AFS_NT40_ENV
	    printf("Usage: volserver [-log] [-p <number of processes>] "
		   "[-auditlog <log path>] [-d <debug level>] "
		   "[-nojumbo] [-jumbo] [-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] "
		   "[-udpsize <size of socket buffer in bytes>] "
		   "[-syslog[=FACILITY]] -mbpersleep <MB / 1 sec sleep>"
		   "%s"
		   "[-enable_peer_stats] [-enable_process_stats] "
		   "[-sync <always | delayed | onclose | never>] "
#ifdef AFS_PTHREAD_ENV
		   , libafsosd ?  "[-convert] ":"",
#endif
		   "[-help]\n");
#else
	    printf("Usage: volserver [-log] [-p <number of processes>] "
		   "[-auditlog <log path>] [-d <debug level>] "
		   "[-nojumbo] [-jumbo] [-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] "
		   "[-udpsize <size of socket buffer in bytes>] "
		   "[-enable_peer_stats] [-enable_process_stats] "
		   "[-sync <always | delayed | onclose | never>] "
		   "[-help]\n");
#endif
	    VS_EXIT(1);
	}
    }

    if (auditFileName) {
	osi_audit_file(auditFileName);
	osi_audit(VS_StartEvent, 0, AUD_END);
    }
#ifdef AFS_SGI_VNODE_GLUE
    if (afs_init_kernel_config(-1) < 0) {
	printf
	    ("Can't determine NUMA configuration, not starting volserver.\n");
	exit(1);
    }
#endif
    InitErrTabs();

#ifdef AFS_PTHREAD_ENV
    SetLogThreadNumProgram( threadNum );
#endif

#ifdef AFS_NT40_ENV
    if (afs_winsockInit() < 0) {
	ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
	printf("Volume server unable to start winsock, exiting.\n");
	exit(1);
    }
#endif
    /* Open VolserLog and map stdout, stderr into it; VInitVolumePackage2 can
       log, so we need to do this here */
    OpenLog(AFSDIR_SERVER_VOLSERLOG_FILEPATH);

    VOptDefaults(volumeServer, &opts);
#ifdef AFS_PTHREAD_ENV
    if (libafsosd) {
        extern struct vol_data_v0 vol_data_v0;
        extern struct volser_data_v0 volser_data_v0;
        struct init_volser_inputs input = {
            &vol_data_v0,
            &volser_data_v0
        };
        struct init_volser_outputs output = {
            &osdvol,
            &osdvolser
        };

        code = load_libafsosd("init_volser_afsosd", &input, &output);
        if (code) {
            ViceLog(0, ("Loading libafsosd.so failed with code %d, aborting\n",
                        code));
            return -1;
        }
    }
#endif
    if (VInitVolumePackage2(volumeServer, &opts)) {
	Log("Shutting down: errors encountered initializing volume package\n");
	exit(1);
    }
    /* For nuke() */
    Lock_Init(&localLock);
    DInit(40);
#ifndef AFS_PTHREAD_ENV
    vol_PollProc = IOMGR_Poll;	/* tell vol pkg to poll io system periodically */
#endif
#ifndef AFS_NT40_ENV
    rxi_syscallp = volser_syscall;
#endif
    rx_nPackets = rxpackets;	/* set the max number of packets */
    if (udpBufSize)
	rx_SetUdpBufSize(udpBufSize);	/* set the UDP buffer size for receive */
    if (rxBind) {
	afs_int32 ccode;
        if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || 
            AFSDIR_SERVER_NETINFO_FILEPATH) {
            char reason[1024];
            ccode = parseNetFiles(SHostAddrs, NULL, NULL,
                                           ADDRSPERSITE, reason,
                                           AFSDIR_SERVER_NETINFO_FILEPATH,
                                           AFSDIR_SERVER_NETRESTRICT_FILEPATH);
        } else 
	{
            ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE);
        }
        if (ccode == 1) 
            host = SHostAddrs[0];
    }

    code = rx_InitHost(host, (int)htons(AFSCONF_VOLUMEPORT));
    if (code) {
	fprintf(stderr, "rx init failed on socket AFSCONF_VOLUMEPORT %u\n",
		AFSCONF_VOLUMEPORT);
	VS_EXIT(1);
    }
    if (!rxJumbograms) {
	/* Don't allow 3.4 vos clients to send jumbograms and we don't send. */
	rx_SetNoJumbo();
    }
    if (rxMaxMTU != -1) {
	rx_SetMaxMTU(rxMaxMTU);
    }
    rx_GetIFInfo();
#ifndef AFS_PTHREAD_ENV
    rx_SetRxDeadTime(420);
#endif
    memset(busyFlags, 0, sizeof(busyFlags));

    SetupLogSignals();

    {
#ifdef AFS_PTHREAD_ENV
	pthread_t tid;
	pthread_attr_t tattr;
	osi_Assert(pthread_attr_init(&tattr) == 0);
	osi_Assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);

	osi_Assert(pthread_create(&tid, &tattr, BKGLoop, NULL) == 0);
#else
	PROCESS pid;
	LWP_CreateProcess(BKGLoop, 16*1024, 3, 0, "vol bkg daemon", &pid);
	LWP_CreateProcess(BKGSleep,16*1024, 3, 0, "vol slp daemon", &pid);
#endif
    }

    /* Create a single security object, in this case the null security object, for unauthenticated connections, which will be used to control security on connections made to this server */

    tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
    if (!tdir) {
	Abort("volser: could not open conf files in %s\n",
	      AFSDIR_SERVER_ETC_DIRPATH);
	VS_EXIT(1);
    }
    afsconf_GetKey(tdir, 999, &tkey);
    afsconf_BuildServerSecurityObjects(tdir, 0, &securityClasses, &numClasses);
    if (securityClasses[0] == NULL)
	Abort("rxnull_NewServerSecurityObject");
    service =
	rx_NewServiceHost(host, 0, VOLSERVICE_ID, "VOLSER", securityClasses,
			  numClasses, AFSVolExecuteRequest);
    if (service == (struct rx_service *)0)
	Abort("rx_NewService");
    rx_SetBeforeProc(service, MyBeforeProc);
    rx_SetAfterProc(service, MyAfterProc);
    rx_SetIdleDeadTime(service, 0);	/* never timeout */
    if (lwps < 4)
	lwps = 4;
    rx_SetMaxProcs(service, lwps);
#if defined(AFS_XBSD_ENV)
    rx_SetStackSize(service, (128 * 1024));
#elif defined(AFS_SGI_ENV)
    rx_SetStackSize(service, (48 * 1024));
#else
    rx_SetStackSize(service, (32 * 1024));
#endif

    if (rxkadDisableDotCheck) {
        rx_SetSecurityConfiguration(service, RXS_CONFIG_FLAGS,
                                    (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
    }

    service =
	rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses,
		      numClasses, RXSTATS_ExecuteRequest);
    if (service == (struct rx_service *)0)
	Abort("rx_NewService");
    rx_SetMinProcs(service, 2);
    rx_SetMaxProcs(service, 4);

#ifdef AFS_PTHREAD_ENV
    if (libafsosd) {
        service =
            rx_NewService(0, 7, "afsosd", securityClasses,
                      numClasses, (osdvolser->op_AFSVOLOSD_ExecuteRequest));
        if (!service) {
            ViceLog(0, ("Failed to initialize afsosd rpc service.\n"));
            exit(-1);
        }
        rx_SetBeforeProc(service, MyBeforeProc);
        rx_SetAfterProc(service, MyAfterProc);
        rx_SetIdleDeadTime(service, 0);	/* never timeout */
        rx_SetMinProcs(service, 2);
        if (lwps < 4)
	    lwps = 4;
        rx_SetMaxProcs(service, lwps);
#if defined(AFS_XBSD_ENV)
        rx_SetStackSize(service, (128 * 1024));
#elif defined(AFS_SGI_ENV)
        rx_SetStackSize(service, (48 * 1024));
#else
        rx_SetStackSize(service, (32 * 1024));
#endif
    }
#endif /* AFS_PTHREAD_ENV */

    LogCommandLine(argc, argv, "Volserver", VolserVersion, "Starting AFS",
		   Log);
    FT_GetTimeOfDay(&statisticStart, 0);
    if (afsconf_GetLatestKey(tdir, NULL, NULL) == 0) {
	LogDesWarning();
    }
    if (TTsleep) {
	Log("Will sleep %d second%s every %d second%s\n", TTsleep,
	    (TTsleep > 1) ? "s" : "", TTrun + TTsleep,
	    (TTrun + TTsleep > 1) ? "s" : "");
    }

    /* allow super users to manage RX statistics */
    /* allow super users to manage RX statistics */
    rx_SetRxStatUserOk(vol_rxstat_userok);

    rx_StartServer(1);		/* Donate this process to the server process pool */

    osi_audit(VS_FinishEvent, (-1), AUD_END);
    Abort("StartServer returned?");
    return 0;	/* not reached */
}
Esempio n. 4
0
/* bnode lwp executes this code repeatedly */
static void *
bproc(void *unused)
{
    afs_int32 code;
    struct bnode *tb;
    afs_int32 temp;
    struct bnode_proc *tp;
    struct bnode *nb;
    int options;		/* must not be register */
    struct timeval tv;
    int setAny;
    int status;

    while (1) {
	/* first figure out how long to sleep for */
	temp = 0x7fffffff;	/* afs_int32 time; maxint doesn't work in select */
	setAny = 0;
	for (tb = allBnodes; tb; tb = tb->next) {
	    if (tb->flags & BNODE_NEEDTIMEOUT) {
		if (tb->nextTimeout < temp) {
		    setAny = 1;
		    temp = tb->nextTimeout;
		}
	    }
	}
	/* now temp has the time at which we should wakeup next */

	/* sleep */
	if (setAny)
	    temp -= FT_ApproxTime();	/* how many seconds until next event */
	else
	    temp = 999999;
	if (temp > 0) {
	    tv.tv_sec = temp;
	    tv.tv_usec = 0;
	    code = IOMGR_Select(0, 0, 0, 0, &tv);
	} else
	    code = 0;		/* fake timeout code */

	/* figure out why we woke up; child exit or timeouts */
	FT_GetTimeOfDay(&tv, 0);	/* must do the real gettimeofday once and a while */
	temp = tv.tv_sec;

	/* check all bnodes to see which ones need timeout events */
	for (tb = allBnodes; tb; tb = nb) {
	    if ((tb->flags & BNODE_NEEDTIMEOUT) && temp > tb->nextTimeout) {
		bnode_Hold(tb);
		BOP_TIMEOUT(tb);
		bnode_Check(tb);
		if (tb->flags & BNODE_NEEDTIMEOUT) {	/* check again, BOP_TIMEOUT could change */
		    tb->nextTimeout = FT_ApproxTime() + tb->period;
		}
		nb = tb->next;
		bnode_Release(tb);	/* delete may occur here */
	    } else
		nb = tb->next;
	}

	if (code < 0) {
	    /* signalled, probably by incoming signal */
	    while (1) {
		options = WNOHANG;
		bnode_waiting = options | 0x800000;
		code = waitpid((pid_t) - 1, &status, options);
		bnode_waiting = 0;
		if (code == 0 || code == -1)
		    break;	/* all done */
		/* otherwise code has a process id, which we now search for */
		for (tp = allProcs; tp; tp = tp->next)
		    if (tp->pid == code)
			break;
		if (tp) {
		    /* found the pid */
		    tb = tp->bnode;
		    bnode_Hold(tb);

		    /* count restarts in last 10 seconds */
		    if (temp > tb->rsTime + 30) {
			/* it's been 10 seconds we've been counting */
			tb->rsTime = temp;
			tb->rsCount = 0;
		    }

		    if (WIFSIGNALED(status) == 0) {
			/* exited, not signalled */
			tp->lastExit = WEXITSTATUS(status);
			tp->lastSignal = 0;
			if (tp->lastExit) {
			    tb->errorCode = tp->lastExit;
			    tb->lastErrorExit = FT_ApproxTime();
			    RememberProcName(tp);
			    tb->errorSignal = 0;
			}
			if (tp->coreName)
			    bozo_Log("%s:%s exited with code %d\n", tb->name,
				     tp->coreName, tp->lastExit);
			else
			    bozo_Log("%s exited with code %d\n", tb->name,
				     tp->lastExit);
		    } else {
			/* Signal occurred, perhaps spurious due to shutdown request.
			 * If due to a shutdown request, don't overwrite last error
			 * information.
			 */
			tp->lastSignal = WTERMSIG(status);
			tp->lastExit = 0;
			if (tp->lastSignal != SIGQUIT
			    && tp->lastSignal != SIGTERM
			    && tp->lastSignal != SIGKILL) {
			    tb->errorSignal = tp->lastSignal;
			    tb->lastErrorExit = FT_ApproxTime();
			    RememberProcName(tp);
			}
			if (tp->coreName)
			    bozo_Log("%s:%s exited on signal %d%s\n",
				     tb->name, tp->coreName, tp->lastSignal,
				     WCOREDUMP(status) ? " (core dumped)" :
				     "");
			else
			    bozo_Log("%s exited on signal %d%s\n", tb->name,
				     tp->lastSignal,
				     WCOREDUMP(status) ? " (core dumped)" :
				     "");
			SaveCore(tb, tp);
		    }
		    tb->lastAnyExit = FT_ApproxTime();

		    if (tb->notifier) {
			bozo_Log("BNODE: Notifier %s will be called\n",
				 tb->notifier);
			hdl_notifier(tp);
		    }
		    BOP_PROCEXIT(tb, tp);

		    bnode_Check(tb);
		    if (tb->rsCount++ > 10) {
			/* 10 in 10 seconds */
			tb->flags |= BNODE_ERRORSTOP;
			bnode_SetGoal(tb, BSTAT_SHUTDOWN);
			bozo_Log
			    ("BNODE '%s' repeatedly failed to start, perhaps missing executable.\n",
			     tb->name);
		    }
		    bnode_Release(tb);	/* bnode delete can happen here */
		    DeleteProc(tp);
		} else
		    bnode_stats.weirdPids++;
	    }
	}
    }
    return NULL;
}
Esempio n. 5
0
/* save core file, if any */
static void
SaveCore(struct bnode *abnode, struct bnode_proc
	 *aproc)
{
    char tbuffer[256];
    struct stat tstat;
    afs_int32 code = 0;
    char *corefile = NULL;
#ifdef BOZO_SAVE_CORES
    struct timeval Start;
    struct tm *TimeFields;
    char FileName[256];
#endif

    /* Linux always appends the PID to core dumps from threaded processes, so
     * we have to scan the directory to find core files under another name. */
    if (DoCore) {
	strcpy(tbuffer, DoCore);
	strcat(tbuffer, "/");
	strcat(tbuffer, AFSDIR_CORE_FILE);
    } else
	code = stat(AFSDIR_SERVER_CORELOG_FILEPATH, &tstat);
    if (code) {
        DIR *logdir;
        struct dirent *file;
        size_t length;
        unsigned long pid;
	const char *coredir = AFSDIR_LOGS_DIR;

	if (DoCore)
	  coredir = DoCore;

	logdir = opendir(coredir);
        if (logdir == NULL)
            return;
        while ((file = readdir(logdir)) != NULL) {
            if (strncmp(file->d_name, "core.", 5) != 0)
                continue;
            pid = atol(file->d_name + 5);
            if (pid == aproc->pid) {
                length = strlen(coredir) + strlen(file->d_name) + 2;
                corefile = malloc(length);
                if (corefile == NULL) {
                    closedir(logdir);
                    return;
                }
                snprintf(corefile, length, "%s/%s", coredir, file->d_name);
                code = 0;
                break;
            }
        }
        closedir(logdir);
    } else {
	corefile = strdup(tbuffer);
    }
    if (code)
	return;

    bnode_CoreName(abnode, aproc->coreName, tbuffer);
#ifdef BOZO_SAVE_CORES
    FT_GetTimeOfDay(&Start, 0);
    TimeFields = localtime(&Start.tv_sec);
    sprintf(FileName, "%s.%d%02d%02d%02d%02d%02d", tbuffer,
	    TimeFields->tm_year + 1900, TimeFields->tm_mon + 1, TimeFields->tm_mday,
	    TimeFields->tm_hour, TimeFields->tm_min, TimeFields->tm_sec);
    strcpy(tbuffer, FileName);
#endif
    code = renamefile(corefile, tbuffer);
    free(corefile);
}
Esempio n. 6
0
static void *IOMGR(void *dummy)
{
    for (;;) {
	int code;
	struct TM_Elem *earliest;
	struct timeval timeout, junk;
	bool woke_someone;

	FD_ZERO(&IOMGR_readfds);
	FD_ZERO(&IOMGR_writefds);
	FD_ZERO(&IOMGR_exceptfds);
	IOMGR_nfds = 0;

	/* Wake up anyone who has expired or who has received a
	   Unix signal between executions.  Keep going until we
	   run out. */
	do {
	    woke_someone = FALSE;
	    /* Wake up anyone waiting on signals. */
	    /* Note: SignalSignals() may yield! */
	    if (anySigsDelivered && SignalSignals ())
		woke_someone = TRUE;
	    FT_GetTimeOfDay(&junk, 0);    /* force accurate time check */
	    TM_Rescan(Requests);
	    for (;;) {
		struct IoRequest *req;
		struct TM_Elem *expired;
		expired = TM_GetExpired(Requests);
		if (expired == NULL) break;
		woke_someone = TRUE;
		req = (struct IoRequest *) expired -> BackPointer;
#ifdef DEBUG
		if (lwp_debug != 0) puts("[Polling SELECT]");
#endif /* DEBUG */
		/* no data ready */
		if (req->readfds)   FD_N_ZERO(req->nfds, req->readfds);
		if (req->writefds)  FD_N_ZERO(req->nfds, req->writefds);
		if (req->exceptfds) FD_N_ZERO(req->nfds, req->exceptfds);
		req->nfds = 0;
		req->result = 0; /* no fds ready */
		TM_Remove(Requests, &req->timeout);
#ifdef DEBUG
		req -> timeout.Next = (struct TM_Elem *) 2;
		req -> timeout.Prev = (struct TM_Elem *) 2;
#endif /* DEBUG */
		LWP_QSignal(req->pid);
		req->pid->iomgrRequest = 0;
	    }

	    if (woke_someone) LWP_DispatchProcess();
	} while (woke_someone);

	/* Collect requests & update times */
	FD_ZERO(&IOMGR_readfds);
	FD_ZERO(&IOMGR_writefds);
	FD_ZERO(&IOMGR_exceptfds);
	IOMGR_nfds = 0;

	FOR_ALL_ELTS(r, Requests, {
	    struct IoRequest *req;
	    req = (struct IoRequest *) r -> BackPointer;
	    FDSetSet(req->nfds, &IOMGR_readfds,   req->readfds);
	    FDSetSet(req->nfds, &IOMGR_writefds,  req->writefds);
	    FDSetSet(req->nfds, &IOMGR_exceptfds, req->exceptfds);
	    if (req->nfds > IOMGR_nfds)
		IOMGR_nfds = req->nfds;
	})
	earliest = TM_GetEarliest(Requests);
	if (earliest != NULL) {
	    timeout = earliest -> TimeLeft;


	    /* Do select */
#ifdef DEBUG
	    if (lwp_debug != 0) {
#ifdef AFS_NT40_ENV
		int idbg;
		printf("[Read Select:");
		if (IOMGR_readfds.fd_count == 0)
		    printf(" none]\n");
		else {
		    for (idbg=0; idbg<IOMGR_readfds.fd_count; idbg++)
			printf(" %d", IOMGR_readfds.fd_array[idbg]);
		    printf("]\n");
		}
		printf("[Write Select:");
		if (IOMGR_writefds.fd_count == 0)
		    printf(" none]\n");
		else {
		    for (idbg=0; idbg<IOMGR_writefds.fd_count; idbg++)
			printf(" %d", IOMGR_writefds.fd_array[idbg]);
		    printf("]\n");
		}
		printf("[Except Select:");
		if (IOMGR_exceptfds.fd_count == 0)
		    printf(" none]\n");
		else {
		    for (idbg=0; idbg<IOMGR_exceptfds.fd_count; idbg++)
			printf(" %d", IOMGR_exceptfds.fd_array[idbg]);
		    printf("]\n");
		}
#else
		/* Only prints first 32. */
		printf("[select(%d, 0x%x, 0x%x, 0x%x, ", IOMGR_nfds,
		       *(int*)&IOMGR_readfds, *(int*)&IOMGR_writefds,
		       *(int*)&IOMGR_exceptfds);
#endif /* AFS_NT40_ENV */
		if (timeout.tv_sec == -1 && timeout.tv_usec == -1)
		    puts("INFINITE)]");
		else
		    printf("<%d, %d>)]\n", timeout.tv_sec, timeout.tv_usec);
	    }
#endif /* DEBUG */
	    iomgr_timeout = timeout;
	    if (timeout.tv_sec == -1 && timeout.tv_usec == -1) {
		/* infinite, sort of */
		iomgr_timeout.tv_sec = 100000000;
		iomgr_timeout.tv_usec = 0;
	    }
#if defined(AFS_NT40_ENV) || defined(AFS_LINUX24_ENV)
	    /* On NT, signals don't interrupt a select call. So this can potentially
	     * lead to long wait times before a signal is honored. To avoid this we
	     * dont do select() for longer than IOMGR_MAXWAITTIME (5 secs) */
	    /* Whereas Linux seems to sometimes "lose" signals */
	    if (iomgr_timeout.tv_sec > (IOMGR_MAXWAITTIME - 1)) {
	      iomgr_timeout.tv_sec = IOMGR_MAXWAITTIME;
	      iomgr_timeout.tv_usec = 0;
	    }
#endif /* NT40 */

	    /* Check one last time for a signal delivery.  If one comes after
	       this, the signal handler will set iomgr_timeout to zero, causing
	       the select to return immediately.  The timer package won't return
	       a zero timeval because all of those guys were handled above.

	       I'm assuming that the kernel masks signals while it's picking up
	       the parameters to select.  This may a bad assumption.  -DN */
	    if (anySigsDelivered)
		continue;	/* go to the top and handle them. */

#ifdef AFS_NT40_ENV
	    if (IOMGR_readfds.fd_count == 0 && IOMGR_writefds.fd_count == 0
		&& IOMGR_exceptfds.fd_count == 0) {
		DWORD stime;
		code = 0;
		if (iomgr_timeout.tv_sec || iomgr_timeout.tv_usec) {
		    stime = iomgr_timeout.tv_sec * 1000
			+ iomgr_timeout.tv_usec/1000;
		    if (!stime)
			stime = 1;
		    Sleep(stime);
		}
	    }
	    else
#endif
		{    /* select runs much faster if 0's are passed instead of &0s */
		    code = select(IOMGR_nfds,
				  (FDSetEmpty(IOMGR_nfds, &IOMGR_readfds)) ?
				  (fd_set*)0 : &IOMGR_readfds,
				  (FDSetEmpty(IOMGR_nfds, &IOMGR_writefds)) ?
				  (fd_set*)0 : &IOMGR_writefds,
				  (FDSetEmpty(IOMGR_nfds, &IOMGR_exceptfds)) ?
				  (fd_set*)0 : &IOMGR_exceptfds,
				  &iomgr_timeout);
		}

	    if (code < 0) {
	       int e=1;

#if defined(AFS_SUN_ENV)
	       /* Tape drives on Sun boxes do not support select and return ENXIO */
	       if (errno == ENXIO) e=0, code=1;
#endif
#if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_AIX32_ENV)
	       /* For SGI and SVR4 - poll & select can return EAGAIN ... */
	       if (errno == EAGAIN) e=0;
#endif
#if defined(AFS_SUN5_ENV)
               /* On sun4x_55, select doesn't block signal. It could be
                  interupted by a signal that changes iomgr_timeout, and
                  then select returns with EINVAL. In this case, we need
                  to retry.
                */
               if (errno==EINVAL && anySigsDelivered)
                   e = 0;
#endif /* AFS_SUN5_ENV */

	       if ((errno != EINTR) && e) {
#ifndef AFS_NT40_ENV
		  int i;
		  for(i=0; i<FD_SETSIZE; i++) {
		     if (fcntl(i, F_GETFD, 0) < 0 && errno == EBADF)
			 FD_SET(i, &openMask);
		  }
#endif
		  iomgr_errno = errno;
		  opr_abort();
	       }
	    }

	    /* See what happened */
	    if (code > 0) {
		/* Action -- wake up everyone involved */
		SignalIO(IOMGR_nfds, &IOMGR_readfds, &IOMGR_writefds,
			 &IOMGR_exceptfds, code);
	    }
	    else if (code == 0
		&& (iomgr_timeout.tv_sec != 0 || iomgr_timeout.tv_usec != 0)) {
		/* Real timeout only if signal handler hasn't set
		   iomgr_timeout to zero. */

#if defined(AFS_NT40_ENV) || defined(AFS_LINUX24_ENV)
		/* On NT, real timeout only if above and if iomgr_timeout
		 * interval is equal to timeout interval (i.e., not adjusted
		 * to check for pseudo-signals).
		 */
		/* And also for Linux as above */
		if (iomgr_timeout.tv_sec  != timeout.tv_sec ||
		    iomgr_timeout.tv_usec != timeout.tv_usec) {
		    /* signal check interval timed out; not real timeout */
		    continue;
		}
#endif /* AFS_NT40_ENV */
	    	FT_GetTimeOfDay(&junk, 0);
		SignalTimeout(code, &timeout);
	    }
	}
	LWP_DispatchProcess();
    }