?? proctrack.c
字號:
/* $Id: proctrack.c,v 1.17 2004/02/17 22:11:59 lars Exp $ *//* * Process tracking object. * * Copyright (c) 2002 International Business Machines * Author: Alan Robertson <alanr@unix.sh> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include <portability.h>#include <errno.h>#include <sys/wait.h>#include <heartbeat.h>#include <sys/types.h>#include <signal.h>#include <clplumbing/proctrack.h>#include <clplumbing/cl_log.h>#include <clplumbing/Gmain_timeout.h>#define DEBUGPROCTRACK debugproctrackint debugproctrack = 0;static int LoggingIsEnabled = 1;static GHashTable* ProcessTable = NULL;static void InitProcTable(void);static void ForEachProcHelper(gpointer key, gpointer value, void * helper);static gboolean TrackedProcTimeoutFunction(gpointer p);static voidInitProcTable(){ if (ProcessTable) { return; } ProcessTable = g_hash_table_new(g_direct_hash, g_direct_equal);}/* Create/Log a new tracked process */voidNewTrackedProc(pid_t pid, int isapgrp, ProcTrackLogType loglevel, void * privatedata, ProcTrack_ops* ops){ ProcTrack* p = g_new(ProcTrack, 1); InitProcTable(); p->pid = pid; p->isapgrp = isapgrp; p->loglevel = loglevel; p->privatedata = privatedata; p->ops = ops; p->startticks = time_longclock(); p->starttime = time(NULL); p->timerid = 0; p->timeoutseq = -1; p->killinfo = NULL; g_hash_table_insert(ProcessTable, GINT_TO_POINTER(pid), p); /* Tell them that someone registered a process */ if (p->ops->procregistered) { p->ops->procregistered(p); }}/* returns TRUE if 'pid' was registered */intReportProcHasDied(int pid, int status){ ProcTrack* p; int signo=0; int deathbyexit=0; int deathbysig=0; int exitcode=0; int doreport = 0; int debugreporting = 0; const char * type; ProcTrackLogType level;#ifdef WCOREDUMP int didcoredump = 0;#endif if ((p = GetProcInfo(pid)) == NULL) { if (DEBUGPROCTRACK) { cl_log(LOG_DEBUG , "Process %d died (%d) but is not tracked." , pid, status); } type = "untracked process"; level = PT_LOGNONE; }else{ type = p->ops->proctype(p); level = p->loglevel; } if (WIFEXITED(status)) { deathbyexit=1; exitcode = WEXITSTATUS(status); }else if (WIFSIGNALED(status)) { deathbysig=1; signo = WTERMSIG(status); doreport=1; }#ifdef WCOREDUMP if (WCOREDUMP(status)) { /* Force a report on all core dumping processes */ didcoredump=1; doreport=1; }#endif switch(level) { case PT_LOGVERBOSE: doreport=1; break; case PT_LOGNONE: doreport = 0; break; case PT_LOGNORMAL: break; } if (!LoggingIsEnabled) { doreport = 0; } if (DEBUGPROCTRACK && !doreport) { doreport = 1; debugreporting = 1; } if (doreport) { if (deathbyexit) { cl_log((exitcode == 0 ? LOG_INFO : LOG_WARNING) , "Exiting %s process %d returned rc %d." , type, pid, exitcode); }else if (deathbysig) { /* * Processes being killed isn't an error if * we're only logging because of debugging. */ cl_log((debugreporting ? LOG_DEBUG : LOG_ERR) , "Exiting %s process %d killed by signal %d." , type, pid, signo); }else{ cl_log(LOG_ERR, "Exiting %s process %d went away" " strangely (!)" , type, pid); } }#ifdef WCOREDUMP if (didcoredump) { /* We report ALL core dumps without exception */ cl_log(LOG_ERR, "Exiting %s process %d dumped core" , type, pid); }#endif if (p) { if (p->timerid > 0) { g_source_remove(p->timerid); p->timerid = 0; } /* * From clplumbing/proctrack.h: * (ProcTrack* p, int status, int signo, int exitcode * , int waslogged); */ p->ops->procdied(p, status, signo, exitcode, doreport); if (p->privatedata) { /* They may have forgotten to free something... */ cl_log(LOG_ERR, "Exiting %s process %d did not" " clean up private data!" , type, pid); } g_hash_table_remove(ProcessTable, GINT_TO_POINTER(pid)); g_free(p); } return doreport;}/* Return information associated with the given PID (or NULL) */ProcTrack*GetProcInfo(pid_t pid){ return (ProcessTable ? g_hash_table_lookup(ProcessTable, GINT_TO_POINTER(pid)) : NULL);}/* "info" is 0-terminated (terminated by a 0 signal) */intSetTrackedProcTimeouts(pid_t pid, ProcTrackKillInfo* info){ long mstimeout; ProcTrack* pinfo; pinfo = GetProcInfo(pid); if (pinfo == NULL) { return 0; } pinfo->timeoutseq = 0; pinfo->killinfo = info; mstimeout = pinfo->killinfo[0].mstimeout; pinfo->timerid = Gmain_timeout_add(mstimeout , TrackedProcTimeoutFunction , GINT_TO_POINTER(pid)); return pinfo->timerid;}static gbooleanTrackedProcTimeoutFunction(gpointer p){ pid_t pid = GPOINTER_TO_INT(p); ProcTrack* pinfo; int nsig; long mstimeout; pinfo = GetProcInfo(pid); if (pinfo == NULL || pinfo->timeoutseq < 0 || pinfo->killinfo == NULL) { return FALSE; } pinfo->timerid = 0; nsig = pinfo->killinfo[pinfo->timeoutseq].signalno; mstimeout = pinfo->killinfo[pinfo->timeoutseq].mstimeout; if (nsig == 0) { return FALSE; } cl_log(LOG_WARNING, "%s process (PID %d) timed out" ". Killing with signal %d." , pinfo->ops->proctype(pinfo), (int)pid, nsig); if (kill(pid, nsig) < 0) { if (errno == EEXIST) { /* No point in trying this again ;-) */ return FALSE; }else{ cl_perror("kill(%d,%d) failed" , pid, nsig); } } pinfo->timerid = Gmain_timeout_add(mstimeout , TrackedProcTimeoutFunction , GINT_TO_POINTER(pid)); return FALSE;}/* Helper struct to allow us to stuff 3 args into one ;-) */struct prochelper { ProcTrack_ops* type; ProcTrackFun fun; void* data;};/* Helper function to call user's function with right args... */static voidForEachProcHelper(gpointer key, gpointer value, void * helper){ ProcTrack* p = value; struct prochelper* ph = helper; if (ph->type != NULL && ph->type != p->ops) { return; } ph->fun(p, ph->data);}/* * Iterate over the set of tracked processes. * If proctype is NULL, then walk through them all, otherwise only those * of the given type. */voidForEachProc(ProcTrack_ops* proctype, ProcTrackFun f, void * data){ struct prochelper ph; InitProcTable(); ph.fun = f; ph.type = proctype; ph.data = data; g_hash_table_foreach(ProcessTable, ForEachProcHelper, &ph);}voidDisableProcLogging(){ LoggingIsEnabled = 0;}voidEnableProcLogging(){ LoggingIsEnabled = 1;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -