From a0154cf196b54c411e2fa47cf36f5fe5af45746e Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Wed, 11 Sep 2002 17:15:31 +0000 Subject: [PATCH] linux-use-kernel-threads-and-completions-if-possible-20020911 configure glue is all my fault ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== with minor rewriting by shadow@dementia.org ==================== rest of the configure glue ==================== fix ifdef to encapsulate correct code ==================== fix ifdef ==================== and deal with change to afsd ops ==================== sys_exit not exported everywhere --- acconfig.h | 1 + acinclude.m4 | 4 + src/afs/afs_call.c | 245 +++++++++++++++++++++++++++++++++++------- src/cf/linux-test4.m4 | 14 +++ 4 files changed, 228 insertions(+), 36 deletions(-) diff --git a/acconfig.h b/acconfig.h index 37f9e3740..fa4756b95 100644 --- a/acconfig.h +++ b/acconfig.h @@ -36,6 +36,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #undef STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS #undef STRUCT_INODE_HAS_I_DEVICES #undef EXPORTED_TASKLIST_LOCK +#undef COMPLETION_H_EXISTS #undef ssize_t #undef HAVE_STRUCT_BUF diff --git a/acinclude.m4 b/acinclude.m4 index 7b86cd4a6..a9d07ac26 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -140,12 +140,16 @@ case $system in LINUX_FS_STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS LINUX_FS_STRUCT_INODE_HAS_I_DEVICES LINUX_INODE_SETATTR_RETURN_TYPE + LINUX_COMPLETION_H_EXISTS LINUX_EXPORTS_TASKLIST_LOCK LINUX_NEED_RHCONFIG LINUX_WHICH_MODULES if test "x$ac_cv_linux_exports_tasklist_lock" = "xyes" ; then AC_DEFINE(EXPORTED_TASKLIST_LOCK) fi + if test "x$ac_cv_linux_completion_h_exists" = "xyes" ; then + AC_DEFINE(COMPLETION_H_EXISTS) + fi if test "x$ac_cv_linux_func_inode_setattr_returns_int" = "xyes" ; then AC_DEFINE(INODE_SETATTR_NOT_VOID) fi diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index 00648ef47..f10e12393 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -135,6 +135,172 @@ static int afs_InitSetup(int preallocs) return code; } +#if defined(AFS_LINUX24_ENV) && defined(COMPLETION_H_EXISTS) +struct afsd_thread_info { + unsigned long parm; + struct completion *complete; +}; + +static int afsd_thread(void *rock) { + struct afsd_thread_info *arg=rock; + unsigned long parm=arg->parm; +#ifdef SYS_SETPRIORITY_EXPORTED + int (*sys_setpriority)(int,int,int) = sys_call_table[__NR_setpriority]; +#endif + daemonize(); /* doesn't do much, since we were forked from keventd, but + does call mm_release, which wakes up our parent (since it + used CLONE_VFORK) */ + afs_osi_MaskSignals(); + switch (parm) { + case AFSOP_START_RXCALLBACK: + sprintf(current->comm, "afs_cbstart"); + AFS_GLOCK(); + complete(arg->complete); + afs_CB_Running = 1; + while (afs_RX_Running != 2) + afs_osi_Sleep(&afs_RX_Running); + sprintf(current->comm, "afs_callback"); + afs_RXCallBackServer(); + AFS_GUNLOCK(); + complete_and_exit(0,0); + break; + case AFSOP_START_AFS: + sprintf(current->comm, "afs_afsstart"); + AFS_GLOCK(); + complete(arg->complete); + AFS_Running = 1; + while (afs_initState < AFSOP_START_AFS) + afs_osi_Sleep(&afs_initState); + afs_initState = AFSOP_START_BKG; + afs_osi_Wakeup(&afs_initState); + sprintf(current->comm, "afsd"); + afs_Daemon(); + AFS_GUNLOCK(); + complete_and_exit(0,0); + break; + case AFSOP_START_BKG: + sprintf(current->comm, "afs_bkgstart"); + AFS_GLOCK(); + complete(arg->complete); + 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); + } + sprintf(current->comm, "afs_background"); + afs_BackgroundDaemon(); + AFS_GUNLOCK(); + complete_and_exit(0,0); + break; + case AFSOP_START_TRUNCDAEMON: + sprintf(current->comm, "afs_trimstart"); + AFS_GLOCK(); + complete(arg->complete); + while (afs_initState < AFSOP_GO) + afs_osi_Sleep(&afs_initState); + sprintf(current->comm, "afs_cachetrim"); + afs_CacheTruncateDaemon(); + AFS_GUNLOCK(); + complete_and_exit(0,0); + break; + case AFSOP_START_CS: + sprintf(current->comm, "afs_checkserver"); + AFS_GLOCK(); + complete(arg->complete); + afs_CheckServerDaemon(); + AFS_GUNLOCK(); + complete_and_exit(0,0); + break; + case AFSOP_RXEVENT_DAEMON: + sprintf(current->comm, "afs_evtstart"); +#ifdef SYS_SETPRIORITY_EXPORTED + sys_setpriority(PRIO_PROCESS,0,-10); +#else +#ifdef CURRENT_INCLUDES_NICE + current->nice=-10; +#endif +#endif + AFS_GLOCK(); + complete(arg->complete); + while (afs_initState < AFSOP_START_BKG) + afs_osi_Sleep(&afs_initState); + sprintf(current->comm, "afs_rxevent"); + afs_rxevent_daemon(); + AFS_GUNLOCK(); + complete_and_exit(0,0); + break; + case AFSOP_RXLISTENER_DAEMON: + sprintf(current->comm, "afs_lsnstart"); +#ifdef SYS_SETPRIORITY_EXPORTED + sys_setpriority(PRIO_PROCESS,0,-10); +#else +#ifdef CURRENT_INCLUDES_NICE + current->nice=-10; +#endif +#endif + AFS_GLOCK(); + complete(arg->complete); + afs_initState = AFSOP_START_AFS; + afs_osi_Wakeup(&afs_initState); + afs_RX_Running = 2; + afs_osi_Wakeup(&afs_RX_Running); + afs_osi_RxkRegister(); + sprintf(current->comm, "afs_rxlistener"); + rxk_Listener(); + AFS_GUNLOCK(); + complete_and_exit(0,0); + break; + default: + printf("Unknown op %d in StartDaemon()\n"); + break; + } + return 0; +} + +void afsd_launcher(void *rock) { + if (!kernel_thread(afsd_thread,rock, CLONE_VFORK|SIGCHLD)) + printf("kernel_thread failed. afs startup will not complete\n"); +} + +void afs_DaemonOp(long parm, long parm2, long parm3, long parm4, long parm5, + long parm6) +{ + int code; + DECLARE_COMPLETION(c); + struct tq_struct tq; + struct afsd_thread_info info; + if (parm == AFSOP_START_RXCALLBACK) { + if (afs_CB_Running) return; + } else if (parm == AFSOP_RXLISTENER_DAEMON) { + if (afs_RX_Running) return; + afs_RX_Running=1; + code = afs_InitSetup(parm2); + if (parm3) { + rx_enablePeerRPCStats(); + } + if (parm4) { + rx_enableProcessRPCStats(); + } + if (code) + return; + } else if (parm == AFSOP_START_AFS) { + if (AFS_Running) return; + } /* other functions don't need setup in the parent */ + info.complete=&c; + info.parm=parm; + tq.sync=0; + INIT_LIST_HEAD(&tq.list); + tq.routine=afsd_launcher; + tq.data=&info; + schedule_task(&tq); + AFS_GUNLOCK(); + /* we need to wait cause we passed stack pointers around.... */ + wait_for_completion(&c); + AFS_GLOCK(); +} +#endif + /* leaving as is, probably will barf if we add prototypes here since it's likely being called with partial list */ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) @@ -161,37 +327,43 @@ long parm, parm2, parm3, parm4, parm5, parm6; setuerror(EACCES); return(EACCES); #else -#if defined(AFS_OSF_ENV) +#if defined(AFS_OSF_ENV) return EACCES; -#else /* AFS_OSF_ENV */ +#else /* AFS_OSF_ENV */ return EPERM; -#endif +#endif /* AFS_OSF_ENV */ #endif #endif } AFS_GLOCK(); +#if defined(AFS_LINUX24_ENV) && defined(COMPLETION_H_EXISTS) && !defined(UKERNEL) + if (parm < AFSOP_ADDCELL || parm == AFSOP_RXEVENT_DAEMON + || parm == AFSOP_RXLISTENER_DAEMON) { + afs_DaemonOp(parm,parm2,parm3,parm4,parm5,parm6); + } +#else /* !(AFS_LINUX24_ENV && !UKERNEL) */ if (parm == AFSOP_START_RXCALLBACK) { if (afs_CB_Running) goto out; afs_CB_Running = 1; #ifndef RXK_LISTENER_ENV code = afs_InitSetup(parm2); if (!code) -#endif /* RXK_LISTENER_ENV */ +#endif /* !RXK_LISTENER_ENV */ { #ifdef RXK_LISTENER_ENV while (afs_RX_Running != 2) afs_osi_Sleep(&afs_RX_Running); -#else +#else /* !RXK_LISTENER_ENV */ afs_initState = AFSOP_START_AFS; afs_osi_Wakeup(&afs_initState); #endif /* RXK_LISTENER_ENV */ afs_osi_Invisible(); afs_RXCallBackServer(); } -#ifdef AFS_SGI_ENV +#ifdef AFS_SGI_ENV AFS_GUNLOCK(); exit(CLD_EXITED, code); -#endif +#endif /* AFS_SGI_ENV */ } #ifdef RXK_LISTENER_ENV else if (parm == AFSOP_RXLISTENER_DAEMON) { @@ -212,34 +384,15 @@ long parm, parm2, parm3, parm4, parm5, parm6; afs_osi_Wakeup(&afs_RX_Running); #ifndef UKERNEL afs_osi_RxkRegister(); -#endif +#endif /* !UKERNEL */ rxk_Listener(); } #ifdef AFS_SGI_ENV AFS_GUNLOCK(); exit(CLD_EXITED, code); -#endif - } -#endif - else if (parm == AFSOP_BASIC_INIT) { - afs_int32 temp; - - while (!afs_InitSetup_done) - afs_osi_Sleep(&afs_InitSetup_done); - -#if defined(AFS_SUN_ENV) || defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) - temp = AFS_MINBUFFERS; /* Should fix this soon */ -#else - /* number of 2k buffers we could get from all of the buffer space */ - temp = ((afs_bufferpages * NBPG)>>11); - temp = temp>>2; /* don't take more than 25% (our magic parameter) */ - if (temp < AFS_MINBUFFERS) - temp = AFS_MINBUFFERS; /* though we really should have this many */ -#endif - DInit(temp); - afs_rootFid.Fid.Volume = 0; - code = 0; +#endif /* AFS_SGI_ENV */ } +#endif /* RXK_LISTENER_ENV */ else if (parm == AFSOP_START_AFS) { /* afs daemon */ if (AFS_Running) goto out; @@ -254,7 +407,7 @@ long parm, parm2, parm3, parm4, parm5, parm6; #ifdef AFS_SGI_ENV AFS_GUNLOCK(); exit(CLD_EXITED, 0); -#endif +#endif /* AFS_SGI_ENV */ } else if (parm == AFSOP_START_CS) { afs_osi_Invisible(); @@ -262,7 +415,7 @@ long parm, parm2, parm3, parm4, parm5, parm6; #ifdef AFS_SGI_ENV AFS_GUNLOCK(); exit(CLD_EXITED, 0); -#endif +#endif /* AFS_SGI_ENV */ } else if (parm == AFSOP_START_BKG) { while (afs_initState < AFSOP_START_BKG) @@ -273,16 +426,16 @@ long parm, parm2, parm3, parm4, parm5, parm6; } /* start the bkg daemon */ afs_osi_Invisible(); -#ifdef AFS_AIX32_ENV +#ifdef AFS_AIX32_ENV if (parm2) afs_BioDaemon(parm2); else -#endif +#endif /* AFS_AIX32_ENV */ afs_BackgroundDaemon(); #ifdef AFS_SGI_ENV AFS_GUNLOCK(); exit(CLD_EXITED, 0); -#endif +#endif /* AFS_SGI_ENV */ } else if (parm == AFSOP_START_TRUNCDAEMON) { while (afs_initState < AFSOP_GO) @@ -293,7 +446,7 @@ long parm, parm2, parm3, parm4, parm5, parm6; #ifdef AFS_SGI_ENV AFS_GUNLOCK(); exit(CLD_EXITED, 0); -#endif +#endif /* AFS_SGI_ENV */ } #if defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV) else if (parm == AFSOP_RXEVENT_DAEMON) { @@ -303,9 +456,29 @@ long parm, parm2, parm3, parm4, parm5, parm6; #ifdef AFS_SGI_ENV AFS_GUNLOCK(); exit(CLD_EXITED, 0); +#endif /* AFS_SGI_ENV */ + } +#endif /* AFS_SUN5_ENV || RXK_LISTENER_ENV */ +#endif /* AFS_LINUX24_ENV && !UKERNEL */ + else if (parm == AFSOP_BASIC_INIT) { + afs_int32 temp; + + while (!afs_InitSetup_done) + afs_osi_Sleep(&afs_InitSetup_done); + +#if defined(AFS_SUN_ENV) || defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) + temp = AFS_MINBUFFERS; /* Should fix this soon */ +#else + /* number of 2k buffers we could get from all of the buffer space */ + temp = ((afs_bufferpages * NBPG)>>11); + temp = temp>>2; /* don't take more than 25% (our magic parameter) */ + if (temp < AFS_MINBUFFERS) + temp = AFS_MINBUFFERS; /* though we really should have this many */ #endif + DInit(temp); + afs_rootFid.Fid.Volume = 0; + code = 0; } -#endif else if (parm == AFSOP_ADDCELL) { /* add a cell. Parameter 2 is 8 hosts (in net order), parm 3 is the null-terminated name. Parameter 4 is the length of the name, including the null. Parm 5 is the diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 07e276426..694732753 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -14,6 +14,20 @@ ac_cv_linux_exports_tasklist_lock=no)]) AC_MSG_RESULT($ac_cv_linux_exports_tasklist_lock) CPPFLAGS="$save_CPPFLAGS"]) +AC_DEFUN(LINUX_COMPLETION_H_EXISTS, [ +AC_MSG_CHECKING(for linux/completion.h existance) +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS" +AC_CACHE_VAL(ac_cv_linux_completion_h_exists, +[ +AC_TRY_COMPILE( +[#include ], +[struct completion _c;], +ac_cv_linux_completion_h_exists=yes, +ac_cv_linux_completion_h_exists=no)]) +AC_MSG_RESULT($ac_cv_linux_completion_h_exists) +CPPFLAGS="$save_CPPFLAGS"]) + AC_DEFUN(LINUX_FS_STRUCT_INODE_HAS_I_MMAP_SHARED, [ AC_MSG_CHECKING(for i_mmap_shared in struct inode) save_CPPFLAGS="$CPPFLAGS" -- 2.39.5