📄 garbage_linux.c
字号:
#ifdef DEV DbgLog (DL5, "Garbage collection attempting global shared memory lock"); #endif /* DEV */ /* Grab the global Shared mem mutex since we might modify global_session_count */#if 1 Err = XProcLock(&(MemPtr->slt_mutex)); if ( Err != TRUE ) { DbgLog (DL0, "Garbage collection: Locking attempt for global shmem mutex returned %s", SysConst(Err) ); return FALSE; }#else#ifdef PKCS64 Err = msem_lock(&(MemPtr->slt_mutex),0);#else Err = pthread_mutex_lock ( &(MemPtr->slt_mutex) );#endif if ( Err != 0 ) { DbgLog (DL0, "Garbage collection: Locking attempt for global shmem mutex returned %s", SysConst(Err) ); return FALSE; }#endif #ifdef DEV DbgLog ( DL5, "Garbage collection: Got global shared memory lock"); #endif /* DEV */ for ( ProcIndex = 0; ProcIndex < NUMBER_PROCESSES_ALLOWED; ProcIndex++ ) {#ifdef PKCS64 Slot_Mgr_Proc_t_64 *pProc = &(MemPtr->proc_table[ProcIndex]);#else Slot_Mgr_Proc_t *pProc = &(MemPtr->proc_table[ProcIndex]);#endif ASSERT(pProc != NULL_PTR); if ( ! (pProc->inuse) ) { continue; } ValidPid = ( (IsValidProcessEntry ( pProc->proc_id, pProc->reg_time )) && (pProc->proc_id != 0) ); if ( ( pProc->inuse ) && (! ValidPid ) ) { #ifdef DEV DbgLog(DL1, "Garbage collection routine found bad entry for pid %d (Index: %d); removing from table", pProc->proc_id, ProcIndex ); #endif /* DEV */ /* */ /* Clean up session counts */ /* */ for ( SlotIndex = 0; SlotIndex < NUMBER_SLOTS_MANAGED; SlotIndex++ ) {#ifdef PKCS64 unsigned int *pGlobalSessions = &(MemPtr->slot_info[SlotIndex].global_sessions); unsigned int *pProcSessions = &(pProc->slot_session_count[SlotIndex]);#else int *pGlobalSessions = &(MemPtr->slot_info[SlotIndex].global_sessions); int *pProcSessions = &(pProc->slot_session_count[SlotIndex]);#endif if ( *pProcSessions > 0 ) { #ifdef DEV DbgLog ( DL2, "GC: Invalid pid (%d) is holding %d sessions open on slot %d. Global session count for this slot is %d", pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions ); #endif /* DEV */ if ( *pProcSessions > *pGlobalSessions ) { #ifdef DEV WarnLog ( "Garbage Collection: Illegal values in table for defunct process"); DbgLog ( DL0, "Garbage collection: A process ( Index: %d, pid: %d ) showed %d sessions open on slot %s, but the global count for this slot is only %d", ProcIndex, pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions ); #endif /* DEV */ *pGlobalSessions = 0; } else { *pGlobalSessions -= *pProcSessions; } *pProcSessions = 0; } /* end if *pProcSessions */ } /* end for SlotIndex */ /* */ /* NULL out everything except the mutex */ /* */#if PER_PROCESS_MUTEXES /* Grab the mutex for this proc's shared memory data structure */#ifdef PKCS64 Err = msem_lock(&(pProc->proc_mutex),MSEM_IF_NOWAIT);#else Err = pthread_mutex_trylock( &(pProc->proc_mutex) );#endif if ( ( Err != 0 ) ) { /* We didn't get the lock! */ /* Attempting to destroy a locked mutex results in undefined behavior */ /* http://techlib.austin.ibm.com/techlib/manuals/adoclib/libs/basetrf1/pthreads.htm */ DbgLog (DL0,"Unable to get per-process mutex for pid %d (%s) - skipping", pProc->proc_id, SysConst( Err ) ); /* The exit routine will figure out that this is an invalid process entry (by calling IsValidProcessEntry()), and won't prevent the slotd from exiting because of this entry. */ continue; }#endif /* PER_PROCESS_MUTEXES */ memset( &(pProc->inuse), '\0', sizeof(pProc->inuse) ); memset( &(pProc->proc_id), '\0', sizeof(pProc->proc_id) ); memset( &(pProc->slotmap), '\0', sizeof(pProc->slotmap) ); memset( &(pProc->blocking), '\0', sizeof(pProc->blocking )); memset( &(pProc->error), '\0', sizeof(pProc->error) ); memset( &(pProc->slot_session_count), '\0', sizeof(pProc->slot_session_count) ); memset( &(pProc->reg_time), '\0', sizeof(pProc->reg_time) ); } /* end if inuse && ValidPid */ #if PER_PROCESS_MUTEXES#ifdef PKCS64 msem_unlock(&(pProc->proc_mutex),0) #else pthread_mutex_unlock( &(pProc->proc_mutex));#endif #endif /* PER_PROCESS_MUTEXES */ } /* end for ProcIndex */ #if 1 XProcUnLock(&(MemPtr->slt_mutex));#else#ifdef PKCS64 msem_unlock(&(MemPtr->slt_mutex),0);#else pthread_mutex_unlock ( &(MemPtr->slt_mutex) );#endif#endif DbgLog ( DL5, "Garbage collection: Released global shared memory lock"); return TRUE; }/********************************************************************************* * Stat2Proc - * * Fills a proc_t structure (defined in garbage_linux.h) * with a given pid's stat information found in the /proc/<pid>/stat file * *********************************************************************************/int Stat2Proc (int pid, proc_t *p) { char buf[800]; // about 40 fields, 64-bit decimal is about 20 chars char fbuf[800]; // about 40 fields, 64-bit decimal is about 20 chars char *tmp; int fd, num; FILE *fp; // sprintf(buf, "%s/%d/stat", PROC_BASE, pid); // if( (fp = fopen(buf, "r")) == NULL ) // return FALSE; sprintf(fbuf, "%s/%d/stat", PROC_BASE, pid); printf("Buff = %s \n",fbuf); fflush(stdout); if( (fd = open(fbuf, O_RDONLY, 0)) == -1) return FALSE; num = read(fd, buf, 800); close(fd); if(num < 80) return FALSE; // buf[num] = '\0'; tmp = strrchr(buf, ')'); // split into "PID (cmd" and "<rest>" *tmp = NULL; // replacing trailing ')' with NULL // Tmp now points to the rest of the buffer. // buff points to the command... /* fill in default values for older kernels */ p->exit_signal = SIGCHLD; p->processor = 0; /* now parse the two strings, tmp & buf, separately, skipping the leading "(" */ memset(&p->cmd, 0, sizeof(p->cmd)); sscanf(buf, "%d (%15c", &p->pid, p->cmd); // comm[16] in kernel num = sscanf(tmp + 2, // skip space after ')' as well "%c " "%d %d %d %d %d " "%lu %lu %lu %lu %lu %lu %lu " "%ld %ld %ld %ld %ld %ld " "%lu %lu " "%ld " "%lu %lu %lu %lu %lu %lu " "%*s %*s %*s %*s " // discard, no RT signals & Linux 2.1 used hex (no use for RT signals) "%lu %lu %lu " "%d %d", &p->state, &p->ppid, &p->pgrp, &p->session, &p->tty, &p->tpgid, &p->flags, &p->min_flt, &p->cmin_flt, &p->maj_flt, &p->cmaj_flt, &p->utime, &p->stime, &p->cutime, &p->cstime, &p->priority, &p->nice, &p->timeout, &p->it_real_value, &p->start_time, &p->vsize, &p->rss, &p->rss_rlim, &p->start_code, &p->end_code, &p->start_stack, &p->kstk_esp, &p->kstk_eip, /* p->signal, p->blocked, p->sigignore, p->sigcatch, */ /* can't use */ &p->wchan, &p->nswap, &p->cnswap, /* -- Linux 2.0.35 ends here -- */ &p->exit_signal, &p->processor /* 2.2.1 ends with "exit_signal" */ /* -- Linux 2.2.8 and 2.3.47 end here -- */ ); /* fprintf(stderr, "Stat2Proc() converted %d fields.\n", num); */ if (p->tty == 0) p->tty = -1; // the old notty val, updated elsewhere before moving to 0 p->vsize /= 1024; if(num < 30) return FALSE; if(p->pid != pid) return FALSE; return TRUE; }/********************************************************************************* * IsValidProcessEntry - * * Checks to see if the process identifed by pid is the same process * that registered with us * *********************************************************************************/#ifdef PKCS64BOOL IsValidProcessEntry ( pid_t_64 pid, time_t_64 RegTime ) {#elseBOOL IsValidProcessEntry ( pid_t pid, time_t RegTime ) {#endif int Err; int valid; proc_t *p; proc_t procstore; /* If kill(pid, 0) returns -1 and errno/Err = ESRCH, the pid doesn't exist */ if ( kill(pid, 0) == -1 ) { Err = errno; if ( Err == ESRCH ) { /* The process was not found */ DbgLog(DL3, "IsValidProcessEntry: PID %d was not found in the process table (kill() returned %s)", pid, SysConst(Err) ); return FALSE; } else { /* some other error occurred */ DbgLog(DL3, "IsValidProcessEntry: kill() returned %s (%d; %#x)", SysConst(Err), Err, Err); return FALSE; } } /* end if kill */ /* Okay, the process exists, now we see if it's really ours */#ifdef ALLOCATE p = (proc_t *)malloc(sizeof(proc_t));#else p = &procstore; bzero(p, sizeof(proc_t));#endif if( !(valid = Stat2Proc( (int)pid, p )) ) return FALSE; if ( p->pid == pid ) { if ( RegTime >= p->start_time ) { // checking for matching start times return TRUE; } else { /* p->start_time contains the time at which the process began ?? (22nd element in /proc/<pid>/stat file) */ DbgLog(DL1, "IsValidProcessEntry: PID %d started at %lu; registered at %ld", pid, p->start_time, RegTime); DbgLog(DL4, "IsValidProcessEntry: PID Returned %d flags at %#x; state at %#x", p->pid, p->flags, p->state); } } return FALSE;}#endif // NO Garbage
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -