linux-tasklist-lock-export-detection-20020829
[openafs.git] / src / afs / afs_osi.c
index e987925..468655f 100644 (file)
@@ -7,7 +7,11 @@
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
-#include "../afs/param.h"      /* Should be always first */
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
 #include "../afs/sysincludes.h"        /* Standard vendor system headers */
 #include "../afs/afsincludes.h"        /* Afs-based standard headers */
 #include "../afs/afs_stats.h"   /* afs statistics */
@@ -16,7 +20,6 @@
 #endif
 
 static char memZero;                   /* address of 0 bytes for kmem_alloc */
-extern int afs_osicred_initialized;
 
 struct osimem {
     struct osimem *next;
@@ -36,7 +39,7 @@ lock_t afs_event_lock;
 flid_t osi_flid;
 #endif
 
-void osi_Init()
+void osi_Init(void)
 {
     static int once = 0;
     if (once++ > 0)                    /* just in case */
@@ -50,9 +53,9 @@ void osi_Init()
 #elif defined(AFS_OSF_ENV)
     usimple_lock_init(&afs_global_lock);
     afs_global_owner = (thread_t)0;
-#elif defined(AFS_DARWIN_ENV)
+#elif defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
     lockinit(&afs_global_lock, PLOCK, "afs global lock", 0, 0);
-    afs_global_owner = (thread_t)0;
+    afs_global_owner = 0;
 #elif defined(AFS_AIX41_ENV)
     lock_alloc((void*)&afs_global_lock, LOCK_ALLOC_PIN, 1, 1);
     simple_lock_init((void *)&afs_global_lock);
@@ -68,7 +71,7 @@ void osi_Init()
 
        if ( !afs_osicred_initialized )
        {
-               bzero((char *)&afs_osi_cred, sizeof(struct AFS_UCRED));
+               memset((char *)&afs_osi_cred, 0, sizeof(struct AFS_UCRED));
                crhold(&afs_osi_cred);      /* don't let it evaporate */
                afs_osicred_initialized = 1;
        }
@@ -77,20 +80,20 @@ void osi_Init()
 #endif
 }
 
-osi_Active(avc)
-register struct vcache *avc; {
+int osi_Active(register struct vcache *avc)
+{
     AFS_STATCNT(osi_Active);
-#if defined(AFS_SUN_ENV) || defined(AFS_AIX_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || (AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV)
+#if defined(AFS_SUN_ENV) || defined(AFS_AIX_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || (AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
     if ((avc->opens > 0) || (avc->states & CMAPPED))   return 1;   /* XXX: Warning, verify this XXX  */
 #else
 #if    defined(AFS_MACH_ENV)
     if (avc->opens > 0 || ((avc->v.v_flag & VTEXT) && !inode_uncache_try(avc))) return 1;
 #else
 #if defined(AFS_SGI_ENV)
-    if ((avc->opens > 0) || AFS_VN_MAPPED((struct vnode *)avc))
+    if ((avc->opens > 0) || AFS_VN_MAPPED(AFSTOV(avc)))
         return 1;
 #else
-    if (avc->opens > 0 || (avc->v.v_flag & VTEXT)) return(1);
+    if (avc->opens > 0 || (AFSTOV(avc)->v_flag & VTEXT)) return(1);
 #endif
 #endif /* AFS_MACH_ENV */
 #endif
@@ -106,9 +109,7 @@ register struct vcache *avc; {
    avc->pvnLock is already held, avc->lock is guaranteed not to be held (by
    us, of course).
 */
-void osi_FlushPages(avc, credp)
-    register struct vcache *avc; 
-    struct AFS_UCRED *credp;    
+void osi_FlushPages(register struct vcache *avc, struct AFS_UCRED *credp)
 {
     afs_hyper_t origDV;
     ObtainReadLock(&avc->lock);
@@ -162,8 +163,8 @@ afs_lock_t afs_ftf;         /* flush text lock */
  * shouldn't do anything that would discard newly written data before
  * it is written to the file system. */
 
-void osi_FlushText_really(vp)
-    register struct vcache *vp; {
+void osi_FlushText_really(register struct vcache *vp)
+{
     afs_hyper_t fdv;   /* version before which we'll flush */
 
     AFS_STATCNT(osi_FlushText);
@@ -230,9 +231,8 @@ void osi_FlushText_really(vp)
  * cacheinval().  But they would panic.  So it might be worth looking
  * into some middle ground...
  */
-static void
-afs_gfs_FlushText(vp)
-    register struct vcache *vp; {
+static void afs_gfs_FlushText(register struct vcache *vp)
+{
     afs_hyper_t fdv;   /* version before which we'll flush */
     register struct text *xp;
     struct gnode * gp;
@@ -256,7 +256,7 @@ afs_gfs_FlushText(vp)
            return;
          }
        }
-       else xp = (struct text *) 0;
+       else xp = NULL;
 
        if (gp->g_flag & GTEXT) {/* still has a text object? */
          xinval(gp);
@@ -276,45 +276,64 @@ afs_gfs_FlushText(vp)
 
 #endif /* AFS_TEXT_ENV */
 
+/* mask signals in afsds */
+void afs_osi_MaskSignals(void)
+{
+#ifdef AFS_LINUX22_ENV
+    osi_linux_mask();
+#endif
+}
+    
+/* unmask signals in rxk listener */
+void afs_osi_UnmaskRxkSignals(void)
+{
+#ifdef AFS_LINUX22_ENV
+    osi_linux_unmask();
+#endif
+}
+    
+/* register rxk listener proc info */
+void afs_osi_RxkRegister(void)
+{
+#ifdef AFS_LINUX22_ENV
+    osi_linux_rxkreg();
+#endif
+}
+
 /* procedure for making our processes as invisible as we can */
-void afs_osi_Invisible() {
-#ifndef        AFS_AIX32_ENV
-    /* called once per "kernel" lwp to make it invisible */
+void afs_osi_Invisible(void)
+{
+#ifdef AFS_LINUX22_ENV
+    afs_osi_MaskSignals();
+#endif 
 #ifdef AFS_DEC_ENV
     u.u_procp->p_type |= SSYS;
-#else
-#if    defined(AFS_SUN5_ENV)
+#endif 
+#if AFS_SUN5_ENV
     curproc->p_flag |= SSYS;
-#else
-#if defined(AFS_SGI_ENV)
-    vrelvm();
-#endif
-#ifdef AFS_SUN_ENV
-    relvm(u.u_procp);  /* release all the resources */
 #endif
-#if    defined(AFS_HPUX101_ENV)
+#if AFS_HPUX101_ENV
     set_system_proc(u.u_procp);
-#else
+#endif
 #if defined(AFS_DARWIN_ENV)
+    /* maybe call init_process instead? */
     current_proc()->p_flag |= P_SYSTEM;
-#else
-#if !defined(AFS_SGI64_ENV) && !defined(AFS_LINUX20_ENV)
-    u.u_procp->p_flag |= SSYS;
-#endif /* AFS_SGI64_ENV */
-#endif
-#endif
-#endif
 #endif
+#if defined(AFS_FBSD_ENV)
+    curproc->p_flag |= P_SYSTEM;
 #endif
+#if defined(AFS_SGI_ENV)
+    vrelvm();
+#endif /* AFS_SGI_ENV */
+
     AFS_STATCNT(osi_Invisible);
 }
 
 
 #ifndef AFS_LINUX20_ENV /* Linux version in osi_misc.c */
 /* set the real time */
-afs_osi_SetTime(atv)
-    register osi_timeval_t *atv; {
-
+int afs_osi_SetTime(register osi_timeval_t *atv)
+{
 #ifdef AFS_AIX32_ENV
     struct timestruc_t t;
 
@@ -334,7 +353,6 @@ afs_osi_SetTime(atv)
     struct stimea {
        time_t time;
     } sta;
-    extern int stime(struct stimea *time, rval_t *rvp);
 
     sta.time = atv->tv_sec;
 
@@ -344,14 +362,32 @@ afs_osi_SetTime(atv)
     struct stimea {
        sysarg_t time;
     } sta;
-    extern int stime(struct stimea *time);
 
     AFS_GUNLOCK();
     sta.time = atv->tv_sec;
     stime(&sta);
     AFS_GLOCK();
 #else
-#ifdef AFS_DARWIN_ENV
+#if defined(AFS_FBSD_ENV)
+    /* does not impliment security features of kern_time.c:settime() */
+    struct timespec ts;
+    struct timeval tv,delta;
+    int s;
+    AFS_GUNLOCK();
+    s=splclock();
+    microtime(&tv);
+    delta=*atv;
+    timevalsub(&delta, &tv);
+    ts.tv_sec=atv->tv_sec;
+    ts.tv_nsec=atv->tv_usec * 1000;
+    set_timecounter(&ts);
+    (void) splsoftclock();
+    lease_updatetime(delta.tv_sec);
+    splx(s);
+    resettodr();
+    AFS_GLOCK();
+#else
+#if defined(AFS_DARWIN_ENV)
     AFS_GUNLOCK();
     setthetime(atv);
     AFS_GLOCK();
@@ -380,6 +416,7 @@ afs_osi_SetTime(atv)
     logtchg(atv->tv_sec);
 #endif
 #endif  /* AFS_DARWIN_ENV */
+#endif  /* AFS_FBSD_ENV */
 #endif /* AFS_SGI_ENV */
 #endif /* AFS_SUN55_ENV */
 #endif /* AFS_SUN5_ENV */
@@ -403,7 +440,7 @@ void *afs_osi_Alloc(size_t x)
     AFS_STATS(afs_stats_cmperf.OutStandingAllocs++);
     AFS_STATS(afs_stats_cmperf.OutStandingMemUsage += x);
 #ifdef AFS_LINUX20_ENV
-    return osi_linux_alloc(x);
+    return osi_linux_alloc(x, 1);
 #else
     size = x;
     tm = (struct osimem *) AFS_KALLOC(size);
@@ -453,6 +490,10 @@ void afs_osi_Free(void *x, size_t asize)
 #endif
 }
 
+void afs_osi_FreeStr(char *x)
+{
+    afs_osi_Free(x, strlen(x) + 1);
+}
 
 /* ? is it moderately likely that there are dirty VM pages associated with 
  * this vnode?
@@ -467,9 +508,7 @@ void afs_osi_Free(void *x, size_t asize)
  *      correctly (or at least, not to introduce worse bugs than already exist)
  */
 #ifdef notdef
-int
-osi_VMDirty_p(avc)
-     struct vcache *avc;
+int osi_VMDirty_p(struct vcache *avc)
 {
     int dirtyPages;
 
@@ -492,7 +531,6 @@ osi_VMDirty_p(avc)
 
     if (avc->vmh) {
        unsigned int pagef, pri, index, next;
-       extern struct vmkerdata vmker;
 
        index = VMHASH(avc->vmh);
        if (scb_valid(index)) {  /* could almost be an ASSERT */
@@ -541,10 +579,7 @@ return 0;
  *
  * Locking:  the vcache entry lock is held.  It is dropped and re-obtained.
  */
-void
-osi_ReleaseVM(avc, acred)
-    struct vcache *avc;
-    struct AFS_UCRED *acred;
+void osi_ReleaseVM(struct vcache *avc, struct AFS_UCRED *acred)
 {
 #ifdef AFS_SUN5_ENV
     AFS_GUNLOCK();
@@ -560,18 +595,15 @@ osi_ReleaseVM(avc, acred)
 }
 
 
-void shutdown_osi()
+void shutdown_osi(void)
 {
-    extern int afs_cold_shutdown;
-
     AFS_STATCNT(shutdown_osi);
     if (afs_cold_shutdown) {
        LOCK_INIT(&afs_ftf, "afs_ftf"); 
       }
 }
 
-afs_osi_suser(credp) 
-  void * credp;
+int afs_osi_suser(void *credp) 
 {
 #ifdef AFS_SUN5_ENV
   return afs_suser(credp);
@@ -587,7 +619,7 @@ afs_osi_suser(credp)
  */
 
 #if defined(AFS_SUN5_ENV)
-void afs_osi_TraverseProcTable()
+void afs_osi_TraverseProcTable(void)
 {
     struct proc *prp;
     for (prp = practive; prp != NULL; prp = prp->p_next) {
@@ -609,7 +641,7 @@ void afs_osi_TraverseProcTable()
  * changes.  To be safe, we use both.
  */
 
-void afs_osi_TraverseProcTable()
+void afs_osi_TraverseProcTable(void)
 {
     register proc_t *p;
     int endchain = 0;
@@ -670,14 +702,14 @@ static int SGI_ProcScanFunc(proc_t *p, void *arg, int mode)
 }
 #endif /* AFS_SGI65_ENV */
 
-void afs_osi_TraverseProcTable()
+void afs_osi_TraverseProcTable(void)
 {
     procscan(SGI_ProcScanFunc, afs_GCPAGs_perproc_func);
 }
 #endif /* AFS_SGI_ENV */
 
 #if defined(AFS_AIX_ENV)
-void afs_osi_TraverseProcTable()
+void afs_osi_TraverseProcTable(void)
 {
     struct proc *p;
     int i;
@@ -723,12 +755,10 @@ void afs_osi_TraverseProcTable()
 #endif
 
 #if defined(AFS_OSF_ENV)
-void afs_osi_TraverseProcTable()
+void afs_osi_TraverseProcTable(void)
 {
     struct pid_entry *pe;
 #ifdef AFS_DUX50_ENV
-extern struct pid_entry *pidtab;
-extern int npid; 
 #define pidNPID (pidtab + npid)
 #define PID_LOCK()
 #define PID_UNLOCK()
@@ -742,8 +772,8 @@ extern int npid;
 }
 #endif
 
-#if defined(AFS_DARWIN_ENV)
-void afs_osi_TraverseProcTable()
+#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+void afs_osi_TraverseProcTable(void)
 {   
     struct proc *p;
     LIST_FOREACH(p, &allproc, p_list) {
@@ -758,18 +788,37 @@ void afs_osi_TraverseProcTable()
 }   
 #endif
 
+#if defined(AFS_LINUX22_ENV)
+void afs_osi_TraverseProcTable()
+{   
+    struct task_struct *p;
+
+#ifdef EXPORTED_TASKLIST_LOCK
+    read_lock(&tasklist_lock);
+#endif
+    for_each_task(p) if (p->pid) {
+        if (p->state & TASK_ZOMBIE)
+            continue;
+       afs_GCPAGs_perproc_func(p);
+    }
+#ifdef EXPORTED_TASKLIST_LOCK
+    read_unlock(&tasklist_lock);
+#endif
+}   
+#endif
+
 /* return a pointer (sometimes a static copy ) to the cred for a
  * given AFS_PROC.
  * subsequent calls may overwrite the previously returned value.
  */
 
 #if defined(AFS_SGI65_ENV)
-const struct AFS_UCRED *afs_osi_proc2cred(AFS_PROC *pr)
+const struct AFS_UCRED *afs_osi_proc2cred(AFS_PROC *p)
 {
     return NULL;
 }
 #elif defined(AFS_HPUX_ENV)
-const struct AFS_UCRED *afs_osi_proc2cred(proc_t *p)
+const struct AFS_UCRED *afs_osi_proc2cred(AFS_PROC *p)
 {
     if (!p)
        return;
@@ -786,9 +835,6 @@ const struct AFS_UCRED *afs_osi_proc2cred(proc_t *p)
 
 /* GLOBAL DECLARATIONS */
 
-extern int      xmattach();        /* fills out cross memory descriptor */
-extern int      xmdetach();        /* decrements reference count to segment */
-
 /*
  * LOCKS: the caller must do
  *  simple_lock(&proc_tbl_lock);
@@ -914,7 +960,7 @@ const struct AFS_UCRED *afs_osi_proc2cred(AFS_PROC *pr)
 
     return rv;
 }
-#elif defined(AFS_DARWIN_ENV)
+#elif defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
 const struct AFS_UCRED *afs_osi_proc2cred(AFS_PROC *pr)
 {   
     struct AFS_UCRED *rv=NULL;
@@ -931,7 +977,7 @@ const struct AFS_UCRED *afs_osi_proc2cred(AFS_PROC *pr)
        cr.cr_ref=1;
        cr.cr_uid=pr->p_cred->pc_ucred->cr_uid;
        cr.cr_ngroups=pr->p_cred->pc_ucred->cr_ngroups;
-       bcopy(pr->p_cred->pc_ucred->cr_groups, cr.cr_groups,NGROUPS *
+       memcpy(cr.cr_groups, pr->p_cred->pc_ucred->cr_groups, NGROUPS *
              sizeof(gid_t));
        pcred_unlock(pr);
        rv = &cr;
@@ -939,6 +985,29 @@ const struct AFS_UCRED *afs_osi_proc2cred(AFS_PROC *pr)
     
     return rv;
 }  
+#elif defined(AFS_LINUX22_ENV)
+const struct AFS_UCRED *afs_osi_proc2cred(AFS_PROC *pr)
+{   
+    struct AFS_UCRED *rv=NULL;
+    static struct AFS_UCRED cr;
+
+    if(pr == NULL) {
+       return NULL;
+    }
+   
+    if ((pr->state == TASK_RUNNING) ||
+       (pr->state == TASK_INTERRUPTIBLE) ||
+       (pr->state == TASK_UNINTERRUPTIBLE) ||
+       (pr->state == TASK_STOPPED)) {
+       cr.cr_ref=1;
+       cr.cr_uid=pr->uid;
+       cr.cr_ngroups=pr->ngroups;
+       memcpy(cr.cr_groups, pr->groups, NGROUPS * sizeof(gid_t));
+       rv = &cr;
+    }
+    
+    return rv;
+}  
 #else
 const struct AFS_UCRED *afs_osi_proc2cred(AFS_PROC *pr)
 {