linux-use-kernel-threads-and-completions-if-possible-20020911
authorDerrick Brashear <shadow@dementia.org>
Wed, 11 Sep 2002 17:15:31 +0000 (17:15 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 11 Sep 2002 17:15:31 +0000 (17:15 +0000)
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
acinclude.m4
src/afs/afs_call.c
src/cf/linux-test4.m4

index 37f9e37..fa4756b 100644 (file)
@@ -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
index 7b86cd4..a9d07ac 100644 (file)
@@ -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
index 00648ef..f10e123 100644 (file)
@@ -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
index 07e2764..6947327 100644 (file)
@@ -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 <linux/completion.h>],
+[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"