Exemplo n.º 1
0
void
afs_CheckServerDaemon(void)
{
    afs_int32 now, delay, lastCheck, last10MinCheck;

    afs_CheckServerDaemonStarted = 1;

    while (afs_initState < 101)
	afs_osi_Sleep(&afs_initState);
    afs_osi_Wait(PROBE_WAIT(), &AFS_CSWaitHandler, 0);

    last10MinCheck = lastCheck = osi_Time();
    while (1) {
	if (afs_termState == AFSOP_STOP_CS) {
	    afs_termState = AFSOP_STOP_TRUNCDAEMON;
	    afs_osi_Wakeup(&afs_termState);
	    break;
	}

	now = osi_Time();
	if (afs_probe_interval + lastCheck <= now) {
	    afs_CheckServers(1, NULL);	/* check down servers */
	    lastCheck = now = osi_Time();
	}

	if (afs_probe_all_interval + last10MinCheck <= now) {
	    afs_Trace1(afs_iclSetp, CM_TRACE_PROBEUP, ICL_TYPE_INT32, afs_probe_all_interval);
	    afs_CheckServers(0, NULL);
	    last10MinCheck = now = osi_Time();
	}
	/* shutdown check. */
	if (afs_termState == AFSOP_STOP_CS) {
	    afs_termState = AFSOP_STOP_TRUNCDAEMON;
	    afs_osi_Wakeup(&afs_termState);
	    break;
	}

	/* Compute time to next probe. */
	delay = afs_probe_interval + lastCheck;
	if (delay > afs_probe_all_interval + last10MinCheck)
	    delay = afs_probe_all_interval + last10MinCheck;
	delay -= now;
	if (delay < 1)
	    delay = 1;
	afs_osi_Wait(delay * 1000, &AFS_CSWaitHandler, 0);
    }
    afs_CheckServerDaemonStarted = 0;
}
Exemplo n.º 2
0
int
afs_readlink(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
{
    afs_int32 code;
    struct vrequest *treq = NULL;
    char *tp;
    struct afs_fakestat_state fakestat;
    OSI_VC_CONVERT(avc);

    AFS_STATCNT(afs_readlink);
    afs_Trace1(afs_iclSetp, CM_TRACE_READLINK, ICL_TYPE_POINTER, avc);
    if ((code = afs_CreateReq(&treq, acred)))
	return code;
    afs_InitFakeStat(&fakestat);

    AFS_DISCON_LOCK();
    
    code = afs_EvalFakeStat(&avc, &fakestat, treq);
    if (code)
	goto done;
    code = afs_VerifyVCache(avc, treq);
    if (code)
	goto done;
    if (vType(avc) != VLNK) {
	code = EINVAL;
	goto done;
    }
    ObtainWriteLock(&avc->lock, 158);
    code = afs_HandleLink(avc, treq);
    /* finally uiomove it to user-land */
    if (code == 0) {
	tp = avc->linkData;
	if (tp)
	    AFS_UIOMOVE(tp, strlen(tp), UIO_READ, auio, code);
	else {
	    code = EIO;
	}
    }
    ReleaseWriteLock(&avc->lock);
  done:
    afs_PutFakeStat(&fakestat);
    AFS_DISCON_UNLOCK();
    code = afs_CheckCode(code, treq, 32);
    afs_DestroyReq(treq);
    return code;
}
Exemplo n.º 3
0
/* This function always holds the GLOCK whilst it is running. The caller
 * gets the GLOCK before invoking it, and afs_osi_Sleep drops the GLOCK
 * whilst we are sleeping, and regains it when we're woken up.
 */
void
afs_Daemon(void)
{
    afs_int32 code;
    struct afs_exporter *exporter;
    afs_int32 now;
    afs_int32 last3MinCheck, last10MinCheck, last60MinCheck, lastNMinCheck;
    afs_int32 last1MinCheck, last5MinCheck;
    afs_uint32 lastCBSlotBump;
    char cs_warned = 0;

    AFS_STATCNT(afs_Daemon);

    afs_rootFid.Fid.Volume = 0;
    while (afs_initState < 101)
	afs_osi_Sleep(&afs_initState);

#ifdef AFS_DARWIN80_ENV
    if (afs_osi_ctxtp_initialized)
        osi_Panic("vfs context already initialized");
    while (afs_osi_ctxtp && vfs_context_ref)
        afs_osi_Sleep(&afs_osi_ctxtp);
    if (afs_osi_ctxtp && !vfs_context_ref)
       vfs_context_rele(afs_osi_ctxtp);
    afs_osi_ctxtp = vfs_context_create(NULL);
    afs_osi_ctxtp_initialized = 1;
#endif
    now = osi_Time();
    lastCBSlotBump = now;

    /* when a lot of clients are booted simultaneously, they develop
     * annoying synchronous VL server bashing behaviors.  So we stagger them.
     */
    last1MinCheck = now + ((afs_random() & 0x7fffffff) % 60);	/* an extra 30 */
    last3MinCheck = now - 90 + ((afs_random() & 0x7fffffff) % 180);
    last60MinCheck = now - 1800 + ((afs_random() & 0x7fffffff) % 3600);
    last10MinCheck = now - 300 + ((afs_random() & 0x7fffffff) % 600);
    last5MinCheck = now - 150 + ((afs_random() & 0x7fffffff) % 300);
    lastNMinCheck = now - 90 + ((afs_random() & 0x7fffffff) % 180);

    /* start off with afs_initState >= 101 (basic init done) */
    while (1) {
	afs_CheckCallbacks(20);	/* unstat anything which will expire soon */

	/* things to do every 20 seconds or less - required by protocol spec */
	if (afs_nfsexporter)
	    afs_FlushActiveVcaches(0);	/* flush NFS writes */
	afs_FlushVCBs(1);	/* flush queued callbacks */

	afs_MaybeWakeupTruncateDaemon();	/* free cache space if have too */
	rx_CheckPackets();	/* Does RX need more packets? */

	now = osi_Time();
	if (lastCBSlotBump + CBHTSLOTLEN < now) {	/* pretty time-dependant */
	    lastCBSlotBump = now;
	    if (afs_BumpBase()) {
		afs_CheckCallbacks(20);	/* unstat anything which will expire soon */
	    }
	}

	if (last1MinCheck + 60 < now) {
	    /* things to do every minute */
	    DFlush();		/* write out dir buffers */
	    afs_WriteThroughDSlots();	/* write through cacheinfo entries */
	    ObtainWriteLock(&afs_xvcache, 736);
	    afs_FlushReclaimedVcaches();
	    ReleaseWriteLock(&afs_xvcache);
	    afs_FlushActiveVcaches(1);	/* keep flocks held & flush nfs writes */
#if 0
	    afs_StoreDirtyVcaches();
#endif
	    afs_CheckRXEpoch();
	    last1MinCheck = now;
	}

	if (last3MinCheck + 180 < now) {
	    afs_CheckTokenCache();	/* check for access cache resets due to expired
					 * tickets */
	    last3MinCheck = now;
	}

        if (afsd_dynamic_vcaches && (last5MinCheck + 300 < now)) {
            /* start with trying to drop us back to our base usage */
            int anumber = VCACHE_FREE + (afs_vcount - afs_cacheStats);

	    if (anumber > 0) {
		ObtainWriteLock(&afs_xvcache, 734);
		afs_ShakeLooseVCaches(anumber);
		ReleaseWriteLock(&afs_xvcache);
	    }
            last5MinCheck = now;
        }

	if (!afs_CheckServerDaemonStarted) {
	    /* Do the check here if the correct afsd is not installed. */
	    if (!cs_warned) {
		cs_warned = 1;
		afs_warn("Please install afsd with check server daemon.\n");
	    }
	    if (lastNMinCheck + afs_probe_interval < now) {
		/* only check down servers */
		afs_CheckServers(1, NULL);
		lastNMinCheck = now;
	    }
	}
	if (last10MinCheck + 600 < now) {
#ifdef AFS_USERSPACE_IP_ADDR
	    extern int rxi_GetcbiInfo(void);
#endif
	    afs_Trace1(afs_iclSetp, CM_TRACE_PROBEUP, ICL_TYPE_INT32, 600);
#ifdef AFS_USERSPACE_IP_ADDR
	    if (rxi_GetcbiInfo()) {	/* addresses changed from last time */
		afs_FlushCBs();
	    }
#else /* AFS_USERSPACE_IP_ADDR */
	    if (rxi_GetIFInfo()) {	/* addresses changed from last time */
		afs_FlushCBs();
	    }
#endif /* else AFS_USERSPACE_IP_ADDR */
	    if (!afs_CheckServerDaemonStarted)
		afs_CheckServers(0, NULL);
	    afs_GCUserData(0);	/* gc old conns */
	    /* This is probably the wrong way of doing GC for the various exporters but it will suffice for a while */
	    for (exporter = root_exported; exporter;
		 exporter = exporter->exp_next) {
		(void)EXP_GC(exporter, 0);	/* Generalize params */
	    }
	    {
		static int cnt = 0;
		if (++cnt < 12) {
		    afs_CheckVolumeNames(AFS_VOLCHECK_EXPIRED |
					 AFS_VOLCHECK_BUSY);
		} else {
		    cnt = 0;
		    afs_CheckVolumeNames(AFS_VOLCHECK_EXPIRED |
					 AFS_VOLCHECK_BUSY |
					 AFS_VOLCHECK_MTPTS);
		}
	    }
	    last10MinCheck = now;
	}
	if (last60MinCheck + 3600 < now) {
	    afs_Trace1(afs_iclSetp, CM_TRACE_PROBEVOLUME, ICL_TYPE_INT32,
		       3600);
	    afs_CheckRootVolume();
#if AFS_GCPAGS
	    if (afs_gcpags == AFS_GCPAGS_OK) {
		afs_int32 didany;
		afs_GCPAGs(&didany);
	    }
#endif
	    last60MinCheck = now;
	}
	if (afs_initState < 300) {	/* while things ain't rosy */
	    code = afs_CheckRootVolume();
	    if (code == 0)
		afs_initState = 300;	/* succeeded */
	    if (afs_initState < 200)
		afs_initState = 200;	/* tried once */
	    afs_osi_Wakeup(&afs_initState);
	}

	/* 18285 is because we're trying to divide evenly into 128, that is,
	 * CBSlotLen, while staying just under 20 seconds.  If CBSlotLen
	 * changes, should probably change this interval, too.
	 * Some of the preceding actions may take quite some time, so we
	 * might not want to wait the entire interval */
	now = 18285 - (osi_Time() - now);
	if (now > 0) {
	    afs_osi_Wait(now, &AFS_WaitHandler, 0);
	}

	if (afs_termState == AFSOP_STOP_AFS) {
	    if (afs_CheckServerDaemonStarted)
		afs_termState = AFSOP_STOP_CS;
	    else
		afs_termState = AFSOP_STOP_TRUNCDAEMON;
	    afs_osi_Wakeup(&afs_termState);
	    return;
	}
    }
}
Exemplo n.º 4
0
void
afs_BackgroundDaemon(void)
#endif
{
    struct brequest *tb;
    int i, foundAny;

    AFS_STATCNT(afs_BackgroundDaemon);
    /* initialize subsystem */
    if (brsInit == 0)
	/* Irix with "short stack" exits */
	afs_BackgroundDaemon_once();

#ifdef AFS_NEW_BKG
    /* If it's a re-entering syscall, complete the request and release */
    if (uspc->ts > -1) {
        tb = afs_brs;
        for (i = 0; i < NBRS; i++, tb++) {
            if (tb->ts == uspc->ts) {
                /* copy the userspace status back in */
                ((struct afs_uspc_param *) tb->ptr_parm[0])->retval =
                    uspc->retval;
                /* mark it valid and notify our caller */
                tb->flags |= BUVALID;
                if (tb->flags & BUWAIT) {
                    tb->flags &= ~BUWAIT;
                    afs_osi_Wakeup(tb);
                }
                brequest_release(tb);
                break;
            }
        }
    } else {
        afs_osi_MaskUserLoop();
#endif
        /* Otherwise it's a new one */
	afs_nbrs++;
#ifdef AFS_NEW_BKG
    }
#endif

    ObtainWriteLock(&afs_xbrs, 302);
    while (1) {
	int min_ts = 0;
	struct brequest *min_tb = NULL;

	if (afs_termState == AFSOP_STOP_BKG) {
	    if (--afs_nbrs <= 0)
		afs_termState = AFSOP_STOP_RXCALLBACK;
	    ReleaseWriteLock(&afs_xbrs);
	    afs_osi_Wakeup(&afs_termState);
#ifdef AFS_NEW_BKG
	    return -2;
#else
	    return;
#endif
	}

	/* find a request */
	tb = afs_brs;
	foundAny = 0;
	for (i = 0; i < NBRS; i++, tb++) {
	    /* look for request with smallest ts */
	    if ((tb->refCount > 0) && !(tb->flags & BSTARTED)) {
		/* new request, not yet picked up */
		if ((min_tb && (min_ts - tb->ts > 0)) || !min_tb) {
		    min_tb = tb;
		    min_ts = tb->ts;
		}
	    }
	}
	if ((tb = min_tb)) {
	    /* claim and process this request */
	    tb->flags |= BSTARTED;
	    ReleaseWriteLock(&afs_xbrs);
	    foundAny = 1;
	    afs_Trace1(afs_iclSetp, CM_TRACE_BKG1, ICL_TYPE_INT32,
		       tb->opcode);
	    if (tb->opcode == BOP_FETCH)
		BPrefetch(tb);
#if defined(AFS_CACHE_BYPASS)
	    else if (tb->opcode == BOP_FETCH_NOCACHE)
		BPrefetchNoCache(tb);
#endif
	    else if (tb->opcode == BOP_STORE)
		BStore(tb);
	    else if (tb->opcode == BOP_PATH)
		BPath(tb);
#ifdef AFS_DARWIN80_ENV
            else if (tb->opcode == BOP_MOVE) {
                memcpy(uspc, (struct afs_uspc_param *) tb->ptr_parm[0],
                       sizeof(struct afs_uspc_param));
                uspc->ts = tb->ts;
                /* string lengths capped in move vop; copy NUL tho */
                memcpy(param1, (char *)tb->ptr_parm[1],
                       strlen(tb->ptr_parm[1])+1);
                memcpy(param2, (char *)tb->ptr_parm[2],
                       strlen(tb->ptr_parm[2])+1);
                return 0;
            }
#endif
	    else if (tb->opcode == BOP_PARTIAL_STORE)
		BPartialStore(tb);
	    else
		panic("background bop");
	    brequest_release(tb);
	    ObtainWriteLock(&afs_xbrs, 305);
	}
	if (!foundAny) {
	    /* wait for new request */
	    afs_brsDaemons++;
	    ReleaseWriteLock(&afs_xbrs);
	    afs_osi_Sleep(&afs_brsDaemons);
	    ObtainWriteLock(&afs_xbrs, 307);
	    afs_brsDaemons--;
	}
    }
#ifdef AFS_NEW_BKG
    return -2;
#endif
}