28 |
|
#include "statgrab.h" |
29 |
|
#include "tools.h" |
30 |
|
#include "vector.h" |
31 |
< |
#if defined(SOLARIS) || defined(LINUX) |
31 |
> |
#if defined(SOLARIS) || defined(LINUX) || defined(AIX) |
32 |
|
#include <stdio.h> |
33 |
|
#include <stdlib.h> |
34 |
|
#include <sys/types.h> |
82 |
|
#include <windows.h> |
83 |
|
#include <psapi.h> |
84 |
|
#endif |
85 |
+ |
#ifdef AIX |
86 |
+ |
#include <unistd.h> |
87 |
+ |
#include <errno.h> |
88 |
+ |
#include <time.h> |
89 |
+ |
#include <procinfo.h> |
90 |
+ |
#include <sys/time.h> |
91 |
+ |
extern int getprocs64(struct procentry64 *, int, struct fdsinfo64 *, int, pid_t *, int); |
92 |
+ |
extern int getargs(struct procentry64 *, int, char *, int); |
93 |
+ |
#endif |
94 |
|
|
95 |
|
static void proc_state_init(sg_process_stats *s) { |
96 |
|
s->process_name = NULL; |
113 |
|
long long pagesize; |
114 |
|
int num, i; |
115 |
|
#endif |
116 |
+ |
#ifdef AIX |
117 |
+ |
struct procentry64 *procs = NULL; |
118 |
+ |
long long pagesize; |
119 |
+ |
int fetched = 0; |
120 |
+ |
pid_t index = 0; |
121 |
+ |
unsigned proc_idx; |
122 |
+ |
time_t utime, stime; |
123 |
+ |
int ncpus; |
124 |
+ |
struct timeval now_tval; |
125 |
+ |
double now_time; |
126 |
+ |
char cmndline[ARG_MAX]; |
127 |
+ |
char comm[ARG_MAX]; |
128 |
+ |
struct procentry64 curproc_for_getargs; |
129 |
+ |
#define PROCS_TO_FETCH 1000 |
130 |
+ |
#endif |
131 |
|
#ifdef ALLBSD |
132 |
|
int mib[4]; |
133 |
|
size_t size; |
786 |
|
procidx = pstat_procinfo[num - 1].pst_idx + 1; |
787 |
|
} |
788 |
|
#endif |
789 |
+ |
|
790 |
+ |
#ifdef AIX |
791 |
+ |
#define TVALU_TO_SEC(x) ((x).tv_sec + ((double)((x).tv_usec) / 1000000.0)) |
792 |
+ |
#define TVALN_TO_SEC(x) ((x).tv_sec + ((double)((x).tv_usec) / 1000000000.0)) |
793 |
+ |
ncpus = sysconf(_SC_NPROCESSORS_ONLN); |
794 |
+ |
if( -1 == ncpus ) { |
795 |
+ |
ncpus = 1; /* sysconf error - assume 1 */ |
796 |
+ |
} |
797 |
+ |
|
798 |
+ |
if ((pagesize = sysconf(_SC_PAGESIZE)) == -1) { |
799 |
+ |
sg_set_error_with_errno(SG_ERROR_SYSCONF, "_SC_PAGESIZE"); |
800 |
+ |
return NULL; |
801 |
+ |
} |
802 |
+ |
|
803 |
+ |
proc_idx = 0; |
804 |
+ |
procs = /* (struct procentry64 *) */ malloc(sizeof(*procs) * PROCS_TO_FETCH); |
805 |
+ |
if(NULL == procs) { |
806 |
+ |
sg_set_error_with_errno(SG_ERROR_MALLOC, "sg_get_process_stats"); |
807 |
+ |
return 0; |
808 |
+ |
} |
809 |
+ |
|
810 |
+ |
gettimeofday(&now_tval, 0); |
811 |
+ |
now_time = TVALU_TO_SEC(now_tval); |
812 |
+ |
|
813 |
+ |
/* keep on grabbing chunks of processes until getprocs returns a smaller |
814 |
+ |
block than we asked for */ |
815 |
+ |
do { |
816 |
+ |
int i; |
817 |
+ |
fetched = getprocs64(procs, sizeof(*procs), NULL, 0, &index, PROCS_TO_FETCH); |
818 |
+ |
if (VECTOR_RESIZE(proc_state, proc_state_size + fetched) < 0) { |
819 |
+ |
sg_set_error_with_errno(SG_ERROR_MALLOC, "sg_get_process_stats"); |
820 |
+ |
free(procs); |
821 |
+ |
return NULL; |
822 |
+ |
} |
823 |
+ |
for( i = 0; i < fetched; ++i ) { |
824 |
+ |
struct procentry64 *pi = procs+i; |
825 |
+ |
int zombie = 0; |
826 |
+ |
|
827 |
+ |
proc_state_ptr = proc_state + proc_idx; |
828 |
+ |
|
829 |
+ |
zombie = 0; |
830 |
+ |
|
831 |
+ |
/* set a descriptive name for the process state */ |
832 |
+ |
switch( pi->pi_state ) { |
833 |
+ |
case SSLEEP: |
834 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; |
835 |
+ |
break; |
836 |
+ |
case SRUN: |
837 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; |
838 |
+ |
break; |
839 |
+ |
case SZOMB: |
840 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_ZOMBIE; |
841 |
+ |
zombie = 1; |
842 |
+ |
break; |
843 |
+ |
case SSTOP: |
844 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; |
845 |
+ |
break; |
846 |
+ |
case SACTIVE: |
847 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; |
848 |
+ |
break; |
849 |
+ |
case SIDL: |
850 |
+ |
default: |
851 |
+ |
proc_state_ptr->state = SG_PROCESS_STATE_UNKNOWN; |
852 |
+ |
break; |
853 |
+ |
} |
854 |
+ |
|
855 |
+ |
if( zombie ) { |
856 |
+ |
utime = pi->pi_utime; |
857 |
+ |
stime = pi->pi_stime; |
858 |
+ |
} else { |
859 |
+ |
utime = TVALN_TO_SEC(pi->pi_ru.ru_utime) + TVALN_TO_SEC(pi->pi_cru.ru_utime); |
860 |
+ |
stime = TVALN_TO_SEC(pi->pi_ru.ru_stime) + TVALN_TO_SEC(pi->pi_cru.ru_stime); |
861 |
+ |
} |
862 |
+ |
|
863 |
+ |
proc_state_ptr->pid = pi->pi_pid; |
864 |
+ |
proc_state_ptr->parent = pi->pi_ppid; |
865 |
+ |
proc_state_ptr->pgid = pi->pi_pgrp; |
866 |
+ |
proc_state_ptr->uid = pi->pi_cred.crx_ruid; |
867 |
+ |
proc_state_ptr->euid = pi->pi_cred.crx_uid; |
868 |
+ |
proc_state_ptr->gid = pi->pi_cred.crx_rgid; |
869 |
+ |
proc_state_ptr->egid = pi->pi_cred.crx_gid; |
870 |
+ |
proc_state_ptr->proc_size = pi->pi_size; |
871 |
+ |
proc_state_ptr->proc_resident = pi->pi_drss + pi->pi_trss; /* XXX might be wrong, see P::PT */ |
872 |
+ |
proc_state_ptr->time_spent = utime + stime; |
873 |
+ |
proc_state_ptr->cpu_percent = (((double)(utime + stime) * 100) / ( now_time - pi->pi_start )) / ncpus; |
874 |
+ |
proc_state_ptr->nice = pi->pi_nice; |
875 |
+ |
|
876 |
+ |
/* determine comm & cmndline */ |
877 |
+ |
if( (pi->pi_flags & SKPROC) == SKPROC ) { |
878 |
+ |
if( pi->pi_pid == 0 ) { |
879 |
+ |
snprintf(comm, ARG_MAX, "kproc (swapper)"); |
880 |
+ |
snprintf(cmndline, ARG_MAX, "kproc (swapper)"); |
881 |
+ |
} else { |
882 |
+ |
snprintf(comm, ARG_MAX, "kproc (%s)", pi->pi_comm); |
883 |
+ |
snprintf(cmndline, ARG_MAX, "kproc (%s)", pi->pi_comm); |
884 |
+ |
} |
885 |
+ |
} else { |
886 |
+ |
snprintf(comm, ARG_MAX, "%s", pi->pi_comm); |
887 |
+ |
curproc_for_getargs.pi_pid = pi->pi_pid; |
888 |
+ |
if( getargs(&curproc_for_getargs, sizeof(curproc_for_getargs), cmndline, ARG_MAX) < 0 ) { |
889 |
+ |
snprintf(cmndline, ARG_MAX, "%s", pi->pi_comm); |
890 |
+ |
} else { |
891 |
+ |
int done = 0; |
892 |
+ |
/* replace NUL characters in command line with spaces */ |
893 |
+ |
char *c = cmndline; |
894 |
+ |
while( ! done ) { |
895 |
+ |
if( *c == '\0' ) { |
896 |
+ |
if( *(c+1) == '\0' ) { |
897 |
+ |
done = 1; |
898 |
+ |
} else { |
899 |
+ |
*c++ = ' '; |
900 |
+ |
} |
901 |
+ |
} else { |
902 |
+ |
++c; |
903 |
+ |
} |
904 |
+ |
} |
905 |
+ |
} |
906 |
+ |
} |
907 |
+ |
|
908 |
+ |
|
909 |
+ |
if (sg_update_string(&proc_state_ptr->process_name, comm) < 0) { |
910 |
+ |
free(procs); |
911 |
+ |
return NULL; |
912 |
+ |
} |
913 |
+ |
if (sg_update_string(&proc_state_ptr->proctitle, cmndline) < 0) { |
914 |
+ |
free(procs); |
915 |
+ |
return NULL; |
916 |
+ |
} |
917 |
+ |
|
918 |
+ |
proc_idx++; |
919 |
+ |
} |
920 |
+ |
} while( fetched >= PROCS_TO_FETCH ); |
921 |
+ |
|
922 |
+ |
proc_state_size = proc_idx; |
923 |
+ |
|
924 |
+ |
free(procs); |
925 |
+ |
#endif |
926 |
+ |
|
927 |
|
|
928 |
|
#ifdef CYGWIN |
929 |
|
sg_set_error(SG_ERROR_UNSUPPORTED, "Cygwin"); |