From: Andrew Deason Date: Tue, 8 Mar 2011 22:59:32 +0000 (-0600) Subject: SOLARIS: Perform daemon syscalls as kernel threads X-Git-Tag: openafs-devel-1_7_1~744 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=e261238470ed28ee7c1068d914de171b34033e09 SOLARIS: Perform daemon syscalls as kernel threads Add AFS_SUN5_ENV to the list of platforms where AFS_DAEMONOP_ENV is defined. Implement the necessary functionality so we spawn kernel threads when a daemon syscall is called. Remove the rxk_Listener wrapper, since it will be called in a separate thread via the afs_DaemonOp interface. Change-Id: I3c2570696a83f1837d08522fdd9dfc30dfefda4b Reviewed-on: http://gerrit.openafs.org/4189 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index 3da9264..521df2b 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -38,7 +38,7 @@ #define AFS_MINBUFFERS 50 #endif -#if ((defined(AFS_LINUX24_ENV) && defined(HAVE_LINUX_COMPLETION_H)) || defined(AFS_DARWIN80_ENV)) && !defined(UKERNEL) +#if (defined(AFS_SUN5_ENV) || (defined(AFS_LINUX24_ENV) && defined(HAVE_LINUX_COMPLETION_H)) || defined(AFS_DARWIN80_ENV)) && !defined(UKERNEL) /* If AFS_DAEMONOP_ENV is defined, it indicates we run "daemon" AFS syscalls by * spawning a kernel thread to do the work, instead of running them in the * calling process. */ @@ -474,6 +474,115 @@ afs_DaemonOp(long parm, long parm2, long parm3, long parm4, long parm5, } #endif +#ifdef AFS_SUN5_ENV +struct afs_daemonop_args { + kcondvar_t cv; + long parm; +}; + +static void +afsd_thread(struct afs_daemonop_args *args) +{ + long parm = args->parm; + + AFS_GLOCK(); + cv_signal(&args->cv); + + switch (parm) { + case AFSOP_START_RXCALLBACK: + if (afs_CB_Running) + goto out; + afs_CB_Running = 1; + while (afs_RX_Running != 2) + afs_osi_Sleep(&afs_RX_Running); + afs_RXCallBackServer(); + AFS_GUNLOCK(); + return; + case AFSOP_START_AFS: + if (AFS_Running) + goto out; + AFS_Running = 1; + while (afs_initState < AFSOP_START_AFS) + afs_osi_Sleep(&afs_initState); + afs_initState = AFSOP_START_BKG; + afs_osi_Wakeup(&afs_initState); + afs_Daemon(); + AFS_GUNLOCK(); + return; + case AFSOP_START_BKG: + while (afs_initState < AFSOP_START_BKG) + afs_osi_Sleep(&afs_initState); + if (afs_initState < AFSOP_GO) { + afs_initState = AFSOP_GO; + afs_osi_Wakeup(&afs_initState); + } + afs_BackgroundDaemon(); + AFS_GUNLOCK(); + return; + case AFSOP_START_TRUNCDAEMON: + while (afs_initState < AFSOP_GO) + afs_osi_Sleep(&afs_initState); + afs_CacheTruncateDaemon(); + AFS_GUNLOCK(); + return; + case AFSOP_START_CS: + afs_CheckServerDaemon(); + AFS_GUNLOCK(); + return; + case AFSOP_RXEVENT_DAEMON: + while (afs_initState < AFSOP_START_BKG) + afs_osi_Sleep(&afs_initState); + afs_rxevent_daemon(); + AFS_GUNLOCK(); + return; + case AFSOP_RXLISTENER_DAEMON: + afs_initState = AFSOP_START_AFS; + afs_osi_Wakeup(&afs_initState); + afs_RX_Running = 2; + afs_osi_Wakeup(&afs_RX_Running); + afs_osi_RxkRegister(); + rxk_Listener(); + AFS_GUNLOCK(); + return; + default: + AFS_GUNLOCK(); + afs_warn("Unknown op %ld in afsd_thread()\n", parm); + return; + } + out: + AFS_GUNLOCK(); + return; +} + +static void +afs_DaemonOp(long parm, long parm2, long parm3, long parm4, long parm5, + long parm6) +{ + struct afs_daemonop_args args; + + if (daemonOp_common(parm, parm2, parm3, parm4, parm5, parm6)) { + return; + } + + args.parm = parm; + + cv_init(&args.cv, "AFS DaemonOp cond var", CV_DEFAULT, NULL); + + if (thread_create(NULL, 0, afsd_thread, &args, 0, &p0, TS_RUN, + minclsyspri) == NULL) { + + afs_warn("thread_create failed: AFS startup will not complete\n"); + } + + /* we passed &args to the new thread, which is on the stack. wait until + * it has read the arguments so it doesn't try to read the args after we + * have returned */ + cv_wait(&args.cv, &afs_global_lock); + + cv_destroy(&args.cv); +} +#endif /* AFS_SUN5_ENV */ + #ifdef AFS_DARWIN100_ENV # define AFSKPTR(X) k ## X int diff --git a/src/rx/rx_kcommon.c b/src/rx/rx_kcommon.c index 27649fa..b04429f 100644 --- a/src/rx/rx_kcommon.c +++ b/src/rx/rx_kcommon.c @@ -1199,27 +1199,8 @@ int rxk_ListenerPid; /* Used to signal process to wakeup at shutdown */ struct task_struct *rxk_ListenerTask; #endif -#ifdef AFS_SUN5_ENV -/* - * Run the listener as a kernel thread. - */ -void -rxk_Listener(void) -{ - extern id_t syscid; - void rxk_ListenerProc(void); - if (thread_create - (NULL, DEFAULTSTKSZ, rxk_ListenerProc, 0, 0, &p0, TS_RUN, - minclsyspri) == NULL) - osi_Panic("rxk_Listener: failed to start listener thread!\n"); -} - -void -rxk_ListenerProc(void) -#else /* AFS_SUN5_ENV */ void rxk_Listener(void) -#endif /* AFS_SUN5_ENV */ { struct rx_packet *rxp = NULL; int code; @@ -1240,9 +1221,9 @@ rxk_Listener(void) #elif defined(AFS_DARWIN_ENV) rxk_ListenerPid = current_proc()->p_pid; #endif -#if defined(RX_ENABLE_LOCKS) && !defined(AFS_SUN5_ENV) +#ifdef RX_ENABLE_LOCKS AFS_GUNLOCK(); -#endif /* RX_ENABLE_LOCKS && !AFS_SUN5_ENV */ +#endif /* RX_ENABLE_LOCKS */ while (afs_termState != AFSOP_STOP_RXK_LISTENER) { /* See if a check for additional packets was issued */ rx_CheckPackets(); @@ -1278,9 +1259,6 @@ rxk_Listener(void) #if defined(AFS_SUN5_ENV) || defined(AFS_FBSD_ENV) osi_rxWakeup(&rxk_ListenerPid); #endif -#ifdef AFS_SUN5_ENV - AFS_GUNLOCK(); -#endif /* AFS_SUN5_ENV */ } #if !defined(AFS_LINUX20_ENV) && !defined(AFS_SUN5_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)