xref: /onnv-gate/usr/src/cmd/wbem/provider/tools/rds/rdimpl.c (revision 5006:304eb1332eef)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*5006Sek110237  * Common Development and Distribution License (the "License").
6*5006Sek110237  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*5006Sek110237  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <sys/types.h>
290Sstevel@tonic-gate #include <sys/resource.h>
300Sstevel@tonic-gate #include <sys/loadavg.h>
310Sstevel@tonic-gate #include <sys/time.h>
320Sstevel@tonic-gate #include <sys/stat.h>
330Sstevel@tonic-gate #include <sys/utsname.h>
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #include <stdio.h>
360Sstevel@tonic-gate #include <stdlib.h>
370Sstevel@tonic-gate #include <unistd.h>
380Sstevel@tonic-gate #include <dirent.h>
390Sstevel@tonic-gate #include <string.h>
400Sstevel@tonic-gate #include <errno.h>
410Sstevel@tonic-gate #include <poll.h>
420Sstevel@tonic-gate #include <ctype.h>
430Sstevel@tonic-gate #include <fcntl.h>
440Sstevel@tonic-gate #include <limits.h>
450Sstevel@tonic-gate #include <time.h>
460Sstevel@tonic-gate #include <project.h>
470Sstevel@tonic-gate #include <libintl.h>
480Sstevel@tonic-gate #include <pthread.h>
490Sstevel@tonic-gate 
500Sstevel@tonic-gate #include "rdimpl.h"
510Sstevel@tonic-gate #include "rdutil.h"
520Sstevel@tonic-gate #include "rdtable.h"
530Sstevel@tonic-gate #include "rdfile.h"
540Sstevel@tonic-gate #include "rdlist.h"
550Sstevel@tonic-gate 
560Sstevel@tonic-gate /* global variables */
570Sstevel@tonic-gate 
580Sstevel@tonic-gate extern pthread_mutex_t listLock;
590Sstevel@tonic-gate 
600Sstevel@tonic-gate list_t	lwps;		/* list of lwps/processes */
610Sstevel@tonic-gate list_t	users;		/* list of users */
620Sstevel@tonic-gate list_t	projects;	/* list of projects */
630Sstevel@tonic-gate list_t	processes;	/* list of processes */
640Sstevel@tonic-gate 
650Sstevel@tonic-gate sys_info_t sys_info;
660Sstevel@tonic-gate 
670Sstevel@tonic-gate jmp_buf dm_jmpbuffer;
680Sstevel@tonic-gate char	errmsg[NL_TEXTMAX];	/* error message max 255 */
690Sstevel@tonic-gate 
700Sstevel@tonic-gate static float	total_mem;	/* total memory usage */
710Sstevel@tonic-gate static float	total_cpu;	/* total cpu usage */
720Sstevel@tonic-gate static char *nullstr = "null";
730Sstevel@tonic-gate static double		loadavg[3];
740Sstevel@tonic-gate static DIR		*procdir;
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 
770Sstevel@tonic-gate /*
780Sstevel@tonic-gate  * Add a LWP entry to the specifed list.
790Sstevel@tonic-gate  */
800Sstevel@tonic-gate lwp_info_t *
list_add_lwp(list_t * list,pid_t pid,id_t lwpid)810Sstevel@tonic-gate list_add_lwp(list_t *list, pid_t pid, id_t lwpid)
820Sstevel@tonic-gate {
830Sstevel@tonic-gate 	lwp_info_t *lwp;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	if (list->l_head == NULL) {
860Sstevel@tonic-gate 		list->l_head = list->l_tail = lwp = Zalloc(sizeof (lwp_info_t));
870Sstevel@tonic-gate 	} else {
880Sstevel@tonic-gate 		lwp = Zalloc(sizeof (lwp_info_t));
890Sstevel@tonic-gate 		lwp->li_prev = list->l_tail;
900Sstevel@tonic-gate 		((lwp_info_t *)list->l_tail)->li_next = lwp;
910Sstevel@tonic-gate 		list->l_tail = lwp;
920Sstevel@tonic-gate 	}
930Sstevel@tonic-gate 	lwp->li_lwpsinfo = Zalloc(sizeof (lwpsinfo_t));
940Sstevel@tonic-gate 	lwp->li_psinfo = Zalloc(sizeof (psinfo_t));
950Sstevel@tonic-gate 	lwp->li_psinfo->pr_pid = pid;
960Sstevel@tonic-gate 	lwp->li_lwpsinfo->pr_lwpid = lwpid;
970Sstevel@tonic-gate 	lwpid_add(lwp, pid, lwpid);
980Sstevel@tonic-gate 	list->l_count++;
990Sstevel@tonic-gate 	return (lwp);
1000Sstevel@tonic-gate }
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate /*
1040Sstevel@tonic-gate  * Remove an LWP entry from the specified list.
1050Sstevel@tonic-gate  */
1060Sstevel@tonic-gate static void
list_remove_lwp(list_t * list,lwp_info_t * lwp)1070Sstevel@tonic-gate list_remove_lwp(list_t *list, lwp_info_t *lwp)
1080Sstevel@tonic-gate {
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 	if (lwp->li_prev)
1110Sstevel@tonic-gate 		lwp->li_prev->li_next = lwp->li_next;
1120Sstevel@tonic-gate 	else
1130Sstevel@tonic-gate 		list->l_head = lwp->li_next;	/* removing the head */
1140Sstevel@tonic-gate 	if (lwp->li_next)
1150Sstevel@tonic-gate 		lwp->li_next->li_prev = lwp->li_prev;
1160Sstevel@tonic-gate 	else
1170Sstevel@tonic-gate 		list->l_tail = lwp->li_prev;	/* removing the tail */
1180Sstevel@tonic-gate 	lwpid_del(lwp->li_psinfo->pr_pid, lwp->li_lwpsinfo->pr_lwpid);
1190Sstevel@tonic-gate 	if (lwpid_pidcheck(lwp->li_psinfo->pr_pid) == 0)
1200Sstevel@tonic-gate 		fds_rm(lwp->li_psinfo->pr_pid);
1210Sstevel@tonic-gate 	list->l_count--;
1220Sstevel@tonic-gate 	Free(lwp->li_lwpsinfo);
1230Sstevel@tonic-gate 	Free(lwp->li_psinfo);
1240Sstevel@tonic-gate 	Free(lwp);
1250Sstevel@tonic-gate }
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate /*
1290Sstevel@tonic-gate  * Remove entry from the specified list.
1300Sstevel@tonic-gate  */
1310Sstevel@tonic-gate static void
list_remove_id(list_t * list,id_info_t * id)1320Sstevel@tonic-gate list_remove_id(list_t *list, id_info_t *id)
1330Sstevel@tonic-gate {
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate 	if (id->id_prev)
1360Sstevel@tonic-gate 		id->id_prev->id_next = id->id_next;
1370Sstevel@tonic-gate 	else
1380Sstevel@tonic-gate 		list->l_head = id->id_next;	/* removing the head */
1390Sstevel@tonic-gate 	if (id->id_next)
1400Sstevel@tonic-gate 		id->id_next->id_prev = id->id_prev;
1410Sstevel@tonic-gate 	else
1420Sstevel@tonic-gate 		list->l_tail = id->id_prev;	/* removing the tail */
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate 	list->l_count--;
1450Sstevel@tonic-gate 	/* anly free if doesn't point to static 'nullstr' def */
1460Sstevel@tonic-gate 	if (id->id_name != nullstr)
1470Sstevel@tonic-gate 		Free(id->id_name);
1480Sstevel@tonic-gate 	Free(id);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate /*
1530Sstevel@tonic-gate  * Empty the specified list.
1540Sstevel@tonic-gate  * If it's an LWP list, this will traverse /proc to
1550Sstevel@tonic-gate  * restore microstate accounting to its original value.
1560Sstevel@tonic-gate  */
1570Sstevel@tonic-gate void
list_clear(list_t * list)1580Sstevel@tonic-gate list_clear(list_t *list)
1590Sstevel@tonic-gate {
1600Sstevel@tonic-gate 	if (list->l_type == LT_LWPS) {
1610Sstevel@tonic-gate 		lwp_info_t	*lwp = list->l_tail;
1620Sstevel@tonic-gate 		lwp_info_t	*lwp_tmp;
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 		fd_closeall();
1650Sstevel@tonic-gate 		while (lwp) {
1660Sstevel@tonic-gate 			lwp_tmp = lwp;
1670Sstevel@tonic-gate 			lwp = lwp->li_prev;
1680Sstevel@tonic-gate 			list_remove_lwp(&lwps, lwp_tmp);
1690Sstevel@tonic-gate 		}
1700Sstevel@tonic-gate 	} else {
1710Sstevel@tonic-gate 		id_info_t *id = list->l_head;
1720Sstevel@tonic-gate 		id_info_t *nextid;
1730Sstevel@tonic-gate 		while (id) {
1740Sstevel@tonic-gate 			nextid = id->id_next;
1750Sstevel@tonic-gate 			/* anly free if doesn't point to static 'nullstr' def */
1760Sstevel@tonic-gate 			if (id->id_name != nullstr)
1770Sstevel@tonic-gate 				Free(id->id_name);
1780Sstevel@tonic-gate 			Free(id);
1790Sstevel@tonic-gate 			id = nextid;
1800Sstevel@tonic-gate 		}
1810Sstevel@tonic-gate 		list->l_count = 0;
1820Sstevel@tonic-gate 		list->l_head = list->l_tail = NULL;
1830Sstevel@tonic-gate 	}
1840Sstevel@tonic-gate }
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate /*
1880Sstevel@tonic-gate  * Calculate a process' statistics from its lwp statistics.
1890Sstevel@tonic-gate  */
1900Sstevel@tonic-gate static void
id_update(id_info_t * id,lwp_info_t * lwp,int l_type)1910Sstevel@tonic-gate id_update(id_info_t *id, lwp_info_t *lwp, int l_type) {
1920Sstevel@tonic-gate 	char usrname[LOGNAME_MAX+1];
1930Sstevel@tonic-gate 	char projname[PROJNAME_MAX+1];
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	/*
1960Sstevel@tonic-gate 	 * When an id is processed first time in an update run its
1970Sstevel@tonic-gate 	 * id_alive flag set to false.
1980Sstevel@tonic-gate 	 * The next values are gauges, their old values from the previous
1990Sstevel@tonic-gate 	 * calculation should be set to null.
2000Sstevel@tonic-gate 	 * The names and timestamp must be set once.
2010Sstevel@tonic-gate 	 */
2020Sstevel@tonic-gate 	if (id->id_alive == B_FALSE) {
2030Sstevel@tonic-gate 		id->id_hpsize = 0;
2040Sstevel@tonic-gate 		id->id_size = 0;
2050Sstevel@tonic-gate 		id->id_rssize = 0;
2060Sstevel@tonic-gate 		id->id_pctmem = 0;
2070Sstevel@tonic-gate 		id->id_timestamp = 0;
2080Sstevel@tonic-gate 		id->id_time = 0;
2090Sstevel@tonic-gate 		id->id_pctcpu = 0;
2100Sstevel@tonic-gate 		id->id_nlwps = 0;
2110Sstevel@tonic-gate 		id->id_nproc = 0;
2120Sstevel@tonic-gate 		id->id_pid = (int)-1;
2130Sstevel@tonic-gate 		id->id_taskid	= lwp->li_psinfo->pr_taskid;
2140Sstevel@tonic-gate 		id->id_projid	= lwp->li_psinfo->pr_projid;
2150Sstevel@tonic-gate 		id->id_psetid	= lwp->li_lwpsinfo->pr_bindpset;
2160Sstevel@tonic-gate 		id->id_uid	= lwp->li_psinfo->pr_uid;
2170Sstevel@tonic-gate 		if (l_type == LT_USERS) {
2180Sstevel@tonic-gate 			getusrname(id->id_uid, usrname, LOGNAME_MAX+1);
2190Sstevel@tonic-gate 			id->id_name = Realloc(id->id_name,
2200Sstevel@tonic-gate 					strlen(usrname) + 1);
2210Sstevel@tonic-gate 			(void) strcpy(id->id_name, usrname);
2220Sstevel@tonic-gate 		} else if (l_type == LT_PROJECTS) {
2230Sstevel@tonic-gate 			getprojname(id->id_projid, projname, PROJNAME_MAX);
2240Sstevel@tonic-gate 			id->id_name = Realloc(id->id_name,
2250Sstevel@tonic-gate 					strlen(projname) + 1);
2260Sstevel@tonic-gate 			(void) strcpy(id->id_name, projname);
2270Sstevel@tonic-gate 		} else {
2280Sstevel@tonic-gate 			id->id_name = nullstr;
2290Sstevel@tonic-gate 		}
2300Sstevel@tonic-gate 		id->id_timestamp = get_timestamp();
2310Sstevel@tonic-gate 		/* mark this id as changed in this update run */
2320Sstevel@tonic-gate 		id->id_alive = B_TRUE;
2330Sstevel@tonic-gate 	}
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 	if (lwp->li_psinfo->pr_nlwp > 0) {
2360Sstevel@tonic-gate 	    id->id_nlwps++;
2370Sstevel@tonic-gate 	}
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate 	/*
2400Sstevel@tonic-gate 	 * The next values are calculated only one time for each pid.
2410Sstevel@tonic-gate 	 */
2420Sstevel@tonic-gate 	if ((id->id_pid != lwp->li_psinfo->pr_pid) &&
2430Sstevel@tonic-gate 		(lwp->rlwpid == lwp->li_lwpsinfo->pr_lwpid)) {
2440Sstevel@tonic-gate 		id->id_nproc++;
2450Sstevel@tonic-gate 		id->id_hpsize	+= (lwp->li_hpsize/1024);
2460Sstevel@tonic-gate 		id->id_size	+= lwp->li_psinfo->pr_size;
2470Sstevel@tonic-gate 		id->id_rssize	+= lwp->li_psinfo->pr_rssize;
2480Sstevel@tonic-gate 		id->id_pctmem	+= FRC2PCT(lwp->li_psinfo->pr_pctmem);
2490Sstevel@tonic-gate 		id->id_pid	= lwp->li_psinfo->pr_pid;
2500Sstevel@tonic-gate 		if (l_type == LT_PROCESS)
2510Sstevel@tonic-gate 			total_mem += FRC2PCT(lwp->li_psinfo->pr_pctmem);
2520Sstevel@tonic-gate 	}
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	id->id_pctcpu	+= FRC2PCT(lwp->li_lwpsinfo->pr_pctcpu);
2550Sstevel@tonic-gate 	if (l_type == LT_PROCESS)
2560Sstevel@tonic-gate 		total_cpu += FRC2PCT(lwp->li_lwpsinfo->pr_pctcpu);
2570Sstevel@tonic-gate 	id->id_time	+= TIME2SEC(lwp->li_lwpsinfo->pr_time);
2580Sstevel@tonic-gate 	id->id_usr	+= lwp->li_usr;
2590Sstevel@tonic-gate 	id->id_sys	+= lwp->li_sys;
2600Sstevel@tonic-gate 	id->id_ttime	+= lwp->li_ttime;
2610Sstevel@tonic-gate 	id->id_tpftime	+= lwp->li_tpftime;
2620Sstevel@tonic-gate 	id->id_dpftime	+= lwp->li_dpftime;
2630Sstevel@tonic-gate 	id->id_kpftime	+= lwp->li_kpftime;
2640Sstevel@tonic-gate 	id->id_lck	+= lwp->li_lck;
2650Sstevel@tonic-gate 	id->id_slp	+= lwp->li_slp;
2660Sstevel@tonic-gate 	id->id_lat	+= lwp->li_lat;
2670Sstevel@tonic-gate 	id->id_stime	+= lwp->li_stime;
2680Sstevel@tonic-gate 	id->id_minf	+= lwp->li_minf;
2690Sstevel@tonic-gate 	id->id_majf	+= lwp->li_majf;
2700Sstevel@tonic-gate 	id->id_nswap	+= lwp->li_nswap;
2710Sstevel@tonic-gate 	id->id_inblk	+= lwp->li_inblk;
2720Sstevel@tonic-gate 	id->id_oublk	+= lwp->li_oublk;
2730Sstevel@tonic-gate 	id->id_msnd	+= lwp->li_msnd;
2740Sstevel@tonic-gate 	id->id_mrcv	+= lwp->li_mrcv;
2750Sstevel@tonic-gate 	id->id_sigs	+= lwp->li_sigs;
2760Sstevel@tonic-gate 	id->id_vctx	+= lwp->li_vctx;
2770Sstevel@tonic-gate 	id->id_ictx	+= lwp->li_ictx;
2780Sstevel@tonic-gate 	id->id_scl	+= lwp->li_scl;
2790Sstevel@tonic-gate 	id->id_ioch	+= lwp->li_ioch;
2800Sstevel@tonic-gate }
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate static void
list_update(list_t * list,lwp_info_t * lwp)2830Sstevel@tonic-gate list_update(list_t *list, lwp_info_t *lwp)
2840Sstevel@tonic-gate {
2850Sstevel@tonic-gate 	id_info_t *id;
2860Sstevel@tonic-gate 	if (list->l_head == NULL) {			/* first element */
2870Sstevel@tonic-gate 		list->l_head = list->l_tail = id = Zalloc(sizeof (id_info_t));
2880Sstevel@tonic-gate 		id_update(id, lwp, list->l_type);
2890Sstevel@tonic-gate 		list->l_count++;
2900Sstevel@tonic-gate 		return;
2910Sstevel@tonic-gate 	}
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate 	for (id = list->l_head; id; id = id->id_next) {
2940Sstevel@tonic-gate 		if ((list->l_type == LT_PROCESS) &&
295*5006Sek110237 		    (id->id_pid != lwp->li_psinfo->pr_pid))
2960Sstevel@tonic-gate 			continue;
2970Sstevel@tonic-gate 		if ((list->l_type == LT_USERS) &&
298*5006Sek110237 		    (id->id_uid != lwp->li_psinfo->pr_uid))
2990Sstevel@tonic-gate 			continue;
3000Sstevel@tonic-gate 		if ((list->l_type == LT_PROJECTS) &&
301*5006Sek110237 		    (id->id_projid != lwp->li_psinfo->pr_projid))
3020Sstevel@tonic-gate 			continue;
3030Sstevel@tonic-gate 		id_update(id, lwp, list->l_type);
3040Sstevel@tonic-gate 		return;
3050Sstevel@tonic-gate 	}
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate 	/* a new element */
3080Sstevel@tonic-gate 	id = list->l_tail;
3090Sstevel@tonic-gate 	id->id_next = Zalloc(sizeof (id_info_t));
3100Sstevel@tonic-gate 	id->id_next->id_prev = list->l_tail;
3110Sstevel@tonic-gate 	id->id_next->id_next = NULL;
3120Sstevel@tonic-gate 	list->l_tail = id->id_next;
3130Sstevel@tonic-gate 	id = list->l_tail;
3140Sstevel@tonic-gate 	id_update(id, lwp, list->l_type);
3150Sstevel@tonic-gate 	list->l_count++;
3160Sstevel@tonic-gate }
3170Sstevel@tonic-gate 
3180Sstevel@tonic-gate /*
3190Sstevel@tonic-gate  * This procedure removes all dead procs/user/.. from the specified list.
3200Sstevel@tonic-gate  */
3210Sstevel@tonic-gate static void
list_refresh_id(list_t * list)3220Sstevel@tonic-gate list_refresh_id(list_t *list)
3230Sstevel@tonic-gate {
3240Sstevel@tonic-gate 	id_info_t *id, *id_next;
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 	if (!(list->l_type & LT_PROCESS) && !(list->l_type & LT_USERS) &&
327*5006Sek110237 	    !(list->l_type & LT_TASKS) && !(list->l_type & LT_PROJECTS) &&
328*5006Sek110237 	    !(list->l_type & LT_PSETS)) {
3290Sstevel@tonic-gate 		return;
3300Sstevel@tonic-gate 	}
3310Sstevel@tonic-gate 	id = list->l_head;
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate 	while (id) {
3340Sstevel@tonic-gate 		if (id->id_alive == B_FALSE) {	/* id is dead */
3350Sstevel@tonic-gate 			id_next = id->id_next;
3360Sstevel@tonic-gate 			list_remove_id(list, id);
3370Sstevel@tonic-gate 			id = id_next;
3380Sstevel@tonic-gate 		} else {
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 			/* normalize total mem and cpu across all processes. */
3410Sstevel@tonic-gate 			if (total_mem >= 100)
3420Sstevel@tonic-gate 				id->id_pctmem = (100 * id->id_pctmem) /
343*5006Sek110237 				    total_mem;
3440Sstevel@tonic-gate 			if (total_cpu >= 100)
3450Sstevel@tonic-gate 				id->id_pctcpu = (100 * id->id_pctcpu) /
346*5006Sek110237 				    total_cpu;
3470Sstevel@tonic-gate 
3480Sstevel@tonic-gate 			id->id_alive = B_FALSE;
3490Sstevel@tonic-gate 			id = id->id_next;
3500Sstevel@tonic-gate 		}
3510Sstevel@tonic-gate 	}
3520Sstevel@tonic-gate }
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate /*
3550Sstevel@tonic-gate  * This procedure removes all dead lwps from the specified lwp list.
3560Sstevel@tonic-gate  */
3570Sstevel@tonic-gate static void
list_refresh(list_t * list)3580Sstevel@tonic-gate list_refresh(list_t *list)
3590Sstevel@tonic-gate {
3600Sstevel@tonic-gate 	lwp_info_t *lwp, *lwp_next;
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 	if (!(list->l_type & LT_LWPS))
3630Sstevel@tonic-gate 		return;
3640Sstevel@tonic-gate 	lwp = list->l_head;
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 	while (lwp) {
3670Sstevel@tonic-gate 		if (lwp->li_alive == B_FALSE) {	/* lwp is dead */
3680Sstevel@tonic-gate 			lwp_next = lwp->li_next;
3690Sstevel@tonic-gate 			list_remove_lwp(&lwps, lwp);
3700Sstevel@tonic-gate 			lwp = lwp_next;
3710Sstevel@tonic-gate 		} else {
3720Sstevel@tonic-gate 			lwp->li_alive = B_FALSE;
3730Sstevel@tonic-gate 			lwp = lwp->li_next;
3740Sstevel@tonic-gate 		}
3750Sstevel@tonic-gate 	}
3760Sstevel@tonic-gate }
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate /*
3800Sstevel@tonic-gate  * Update a LWP entry according to the specified usage data.
3810Sstevel@tonic-gate  */
3820Sstevel@tonic-gate static void
lwp_update(lwp_info_t * lwp,struct prusage * usage_buf)3830Sstevel@tonic-gate lwp_update(lwp_info_t *lwp, struct prusage *usage_buf)
3840Sstevel@tonic-gate {
3850Sstevel@tonic-gate 	lwp->li_usr	= (double)(TIME2NSEC(usage_buf->pr_utime) -
386*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_utime)) / NANOSEC;
3870Sstevel@tonic-gate 	lwp->li_sys	= (double)(TIME2NSEC(usage_buf->pr_stime) -
388*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_stime)) / NANOSEC;
3890Sstevel@tonic-gate 	lwp->li_ttime	= (double)(TIME2NSEC(usage_buf->pr_ttime) -
390*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_ttime)) / NANOSEC;
3910Sstevel@tonic-gate 	lwp->li_tpftime = (double)(TIME2NSEC(usage_buf->pr_tftime) -
392*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_tftime)) / NANOSEC;
3930Sstevel@tonic-gate 	lwp->li_dpftime = (double)(TIME2NSEC(usage_buf->pr_dftime) -
394*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_dftime)) / NANOSEC;
3950Sstevel@tonic-gate 	lwp->li_kpftime = (double)(TIME2NSEC(usage_buf->pr_kftime) -
396*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_kftime)) / NANOSEC;
3970Sstevel@tonic-gate 	lwp->li_lck	= (double)(TIME2NSEC(usage_buf->pr_ltime) -
398*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_ltime)) / NANOSEC;
3990Sstevel@tonic-gate 	lwp->li_slp	= (double)(TIME2NSEC(usage_buf->pr_slptime) -
400*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_slptime)) / NANOSEC;
4010Sstevel@tonic-gate 	lwp->li_lat	= (double)(TIME2NSEC(usage_buf->pr_wtime) -
402*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_wtime)) / NANOSEC;
4030Sstevel@tonic-gate 	lwp->li_stime	= (double)(TIME2NSEC(usage_buf->pr_stoptime) -
404*5006Sek110237 	    TIME2NSEC(lwp->li_usage.pr_stoptime)) / NANOSEC;
4050Sstevel@tonic-gate 	lwp->li_minf = usage_buf->pr_minf - lwp->li_usage.pr_minf;
4060Sstevel@tonic-gate 	lwp->li_majf = usage_buf->pr_majf - lwp->li_usage.pr_majf;
4070Sstevel@tonic-gate 	lwp->li_nswap = usage_buf->pr_nswap - lwp->li_usage.pr_nswap;
4080Sstevel@tonic-gate 	lwp->li_inblk = usage_buf->pr_inblk - lwp->li_usage.pr_inblk;
4090Sstevel@tonic-gate 	lwp->li_oublk = usage_buf->pr_oublk -lwp->li_usage.pr_oublk;
4100Sstevel@tonic-gate 	lwp->li_msnd = usage_buf->pr_msnd - lwp->li_usage.pr_msnd;
4110Sstevel@tonic-gate 	lwp->li_mrcv = usage_buf->pr_mrcv - lwp->li_usage.pr_mrcv;
4120Sstevel@tonic-gate 	lwp->li_sigs = usage_buf->pr_sigs - lwp->li_usage.pr_sigs;
4130Sstevel@tonic-gate 	lwp->li_vctx = usage_buf->pr_vctx - lwp->li_usage.pr_vctx;
4140Sstevel@tonic-gate 	lwp->li_ictx = usage_buf->pr_ictx - lwp->li_usage.pr_ictx;
4150Sstevel@tonic-gate 	lwp->li_scl = usage_buf->pr_sysc - lwp->li_usage.pr_sysc;
4160Sstevel@tonic-gate 	lwp->li_ioch = usage_buf->pr_ioch - lwp->li_usage.pr_ioch;
4170Sstevel@tonic-gate 	lwp->li_timestamp = TIME2NSEC(usage_buf->pr_tstamp);
4180Sstevel@tonic-gate 	(void) memcpy(&lwp->li_usage, usage_buf, sizeof (prusage_t));
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate /*
4230Sstevel@tonic-gate  * This is the meat of the /proc scanner.
4240Sstevel@tonic-gate  * It will visit every single LWP in /proc.
4250Sstevel@tonic-gate  */
4260Sstevel@tonic-gate static void
collect_lwp_data()4270Sstevel@tonic-gate collect_lwp_data()
4280Sstevel@tonic-gate {
4290Sstevel@tonic-gate 	char *pidstr;
4300Sstevel@tonic-gate 	pid_t pid;
4310Sstevel@tonic-gate 	id_t lwpid;
4320Sstevel@tonic-gate 	size_t entsz;
4330Sstevel@tonic-gate 	long nlwps, nent, i;
4340Sstevel@tonic-gate 	char *buf, *ptr;
4350Sstevel@tonic-gate 	char pfile[MAX_PROCFS_PATH];
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 	fds_t *fds;
4380Sstevel@tonic-gate 	lwp_info_t *lwp;
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 	dirent_t *direntp;
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 	prheader_t	header_buf;
4430Sstevel@tonic-gate 	psinfo_t	psinfo_buf;
4440Sstevel@tonic-gate 	prusage_t	usage_buf;
4450Sstevel@tonic-gate 	lwpsinfo_t	*lwpsinfo_buf;
4460Sstevel@tonic-gate 	prusage_t	*lwpusage_buf;
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate 	log_msg("->collect_lwp_data(): %d files open\n", fd_count());
4490Sstevel@tonic-gate 	for (rewinddir(procdir); (direntp = readdir(procdir)); ) {
4500Sstevel@tonic-gate 		pidstr = direntp->d_name;
4510Sstevel@tonic-gate 		if (pidstr[0] == '.')	/* skip "." and ".."  */
4520Sstevel@tonic-gate 			continue;
4530Sstevel@tonic-gate 		pid = atoi(pidstr);
4540Sstevel@tonic-gate 		if (pid == 0 || pid == 2 || pid == 3)
4550Sstevel@tonic-gate 			continue;	/* skip sched, pageout and fsflush */
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate 		fds = fds_get(pid);	/* get ptr to file descriptors */
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate 		/*
4600Sstevel@tonic-gate 		 * Here we are going to read information about
4610Sstevel@tonic-gate 		 * current process (pid) from /proc/pid/psinfo file.
4620Sstevel@tonic-gate 		 * If process has more than one lwp, we also should
4630Sstevel@tonic-gate 		 * read /proc/pid/lpsinfo for information about all lwps.
4640Sstevel@tonic-gate 		 */
4650Sstevel@tonic-gate 		(void) snprintf(pfile, MAX_PROCFS_PATH,
466*5006Sek110237 		    "/proc/%s/psinfo", pidstr);
4670Sstevel@tonic-gate 		if ((fds->fds_psinfo = fd_open(pfile, O_RDONLY,
468*5006Sek110237 		    fds->fds_psinfo)) == NULL)
4690Sstevel@tonic-gate 			continue;
4700Sstevel@tonic-gate 		if (pread(fd_getfd(fds->fds_psinfo), &psinfo_buf,
4710Sstevel@tonic-gate 			sizeof (struct psinfo), 0) != sizeof (struct psinfo)) {
4720Sstevel@tonic-gate 			fd_close(fds->fds_psinfo);
4730Sstevel@tonic-gate 			continue;
4740Sstevel@tonic-gate 		}
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 		fd_close(fds->fds_psinfo);
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 		nlwps = psinfo_buf.pr_nlwp + psinfo_buf.pr_nzomb;
4790Sstevel@tonic-gate 		if (nlwps > 1) {
4800Sstevel@tonic-gate 			(void) snprintf(pfile, MAX_PROCFS_PATH,
481*5006Sek110237 			    "/proc/%s/lpsinfo", pidstr);
4820Sstevel@tonic-gate 			if ((fds->fds_lpsinfo = fd_open(pfile, O_RDONLY,
4830Sstevel@tonic-gate 			    fds->fds_lpsinfo)) == NULL)
4840Sstevel@tonic-gate 				continue;
4850Sstevel@tonic-gate 			entsz = sizeof (struct prheader);
4860Sstevel@tonic-gate 			if (pread(fd_getfd(fds->fds_lpsinfo), &header_buf,
487*5006Sek110237 			    entsz, 0) != entsz) {
4880Sstevel@tonic-gate 				fd_close(fds->fds_lpsinfo);
4890Sstevel@tonic-gate 				continue;
4900Sstevel@tonic-gate 			}
4910Sstevel@tonic-gate 			nent = header_buf.pr_nent;
4920Sstevel@tonic-gate 			entsz = header_buf.pr_entsize * nent;
4930Sstevel@tonic-gate 			ptr = buf = Malloc(entsz);
4940Sstevel@tonic-gate 			if (pread(fd_getfd(fds->fds_lpsinfo), buf,
4950Sstevel@tonic-gate 			    entsz, sizeof (struct prheader)) != entsz) {
4960Sstevel@tonic-gate 				fd_close(fds->fds_lpsinfo);
4970Sstevel@tonic-gate 				Free(buf);
4980Sstevel@tonic-gate 				continue;
4990Sstevel@tonic-gate 			}
5000Sstevel@tonic-gate 
5010Sstevel@tonic-gate 			fd_close(fds->fds_lpsinfo);
5020Sstevel@tonic-gate 
5030Sstevel@tonic-gate 			for (i = 0; i < nent;
504*5006Sek110237 			    i++, ptr += header_buf.pr_entsize) {
5050Sstevel@tonic-gate 				/*LINTED ALIGNMENT*/
5060Sstevel@tonic-gate 				lwpsinfo_buf = (lwpsinfo_t *)ptr;
5070Sstevel@tonic-gate 				lwpid = lwpsinfo_buf->pr_lwpid;
5080Sstevel@tonic-gate 				if ((lwp = lwpid_get(pid, lwpid)) == NULL) {
5090Sstevel@tonic-gate 					lwp = list_add_lwp(&lwps, pid, lwpid);
5100Sstevel@tonic-gate 				}
5110Sstevel@tonic-gate 				if (i == 0)
5120Sstevel@tonic-gate 					lwp->rlwpid = lwpid;
5130Sstevel@tonic-gate 				(void) memcpy(lwp->li_psinfo, &psinfo_buf,
514*5006Sek110237 				    sizeof (psinfo_t) - sizeof (lwpsinfo_t));
5150Sstevel@tonic-gate 				lwp->li_alive = B_TRUE;
5160Sstevel@tonic-gate 				(void) memcpy(lwp->li_lwpsinfo,
517*5006Sek110237 				    lwpsinfo_buf, sizeof (lwpsinfo_t));
5180Sstevel@tonic-gate 			}
5190Sstevel@tonic-gate 			Free(buf);
5200Sstevel@tonic-gate 		} else {
5210Sstevel@tonic-gate 			lwpid = psinfo_buf.pr_lwp.pr_lwpid;
5220Sstevel@tonic-gate 			if ((lwp = lwpid_get(pid, lwpid)) == NULL) {
5230Sstevel@tonic-gate 				lwp = list_add_lwp(&lwps, pid, lwpid);
5240Sstevel@tonic-gate 			}
5250Sstevel@tonic-gate 			lwp->rlwpid = lwpid;
5260Sstevel@tonic-gate 			(void) memcpy(lwp->li_psinfo, &psinfo_buf,
527*5006Sek110237 			    sizeof (psinfo_t) - sizeof (lwpsinfo_t));
5280Sstevel@tonic-gate 			lwp->li_alive = B_TRUE;
5290Sstevel@tonic-gate 			(void) memcpy(lwp->li_lwpsinfo,
530*5006Sek110237 			    &psinfo_buf.pr_lwp, sizeof (lwpsinfo_t));
531*5006Sek110237 			lwp->li_lwpsinfo->pr_pctcpu = lwp->li_psinfo->pr_pctcpu;
5320Sstevel@tonic-gate 		}
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 		/*
5350Sstevel@tonic-gate 		 * At this part of scandir we read additional information
5360Sstevel@tonic-gate 		 * about processes from /proc/pid/usage file.
5370Sstevel@tonic-gate 		 * Again, if process has more than one lwp, then we
5380Sstevel@tonic-gate 		 * will get information about all its lwps from
5390Sstevel@tonic-gate 		 * /proc/pid/lusage file.
5400Sstevel@tonic-gate 		 */
5410Sstevel@tonic-gate 		if (nlwps > 1) {
5420Sstevel@tonic-gate 			(void) snprintf(pfile, MAX_PROCFS_PATH,
543*5006Sek110237 			    "/proc/%s/lusage", pidstr);
5440Sstevel@tonic-gate 			if ((fds->fds_lusage = fd_open(pfile, O_RDONLY,
545*5006Sek110237 			    fds->fds_lusage)) == NULL)
5460Sstevel@tonic-gate 				continue;
5470Sstevel@tonic-gate 			entsz = sizeof (struct prheader);
5480Sstevel@tonic-gate 			if (pread(fd_getfd(fds->fds_lusage), &header_buf,
549*5006Sek110237 			    entsz, 0) != entsz) {
5500Sstevel@tonic-gate 				fd_close(fds->fds_lusage);
5510Sstevel@tonic-gate 				continue;
5520Sstevel@tonic-gate 			}
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate 			nent = header_buf.pr_nent;
5550Sstevel@tonic-gate 			entsz = header_buf.pr_entsize * nent;
5560Sstevel@tonic-gate 			buf = Malloc(entsz);
5570Sstevel@tonic-gate 			if (pread(fd_getfd(fds->fds_lusage), buf,
5580Sstevel@tonic-gate 				entsz, sizeof (struct prheader)) != entsz) {
5590Sstevel@tonic-gate 				fd_close(fds->fds_lusage);
5600Sstevel@tonic-gate 				Free(buf);
5610Sstevel@tonic-gate 				continue;
5620Sstevel@tonic-gate 			}
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate 			fd_close(fds->fds_lusage);
5650Sstevel@tonic-gate 
5660Sstevel@tonic-gate 			for (i = 1, ptr = buf + header_buf.pr_entsize; i < nent;
567*5006Sek110237 			    i++, ptr += header_buf.pr_entsize) {
5680Sstevel@tonic-gate 				/*LINTED ALIGNMENT*/
5690Sstevel@tonic-gate 				lwpusage_buf = (prusage_t *)ptr;
5700Sstevel@tonic-gate 				lwpid = lwpusage_buf->pr_lwpid;
5710Sstevel@tonic-gate 				if ((lwp = lwpid_get(pid, lwpid)) == NULL)
5720Sstevel@tonic-gate 					continue;
5730Sstevel@tonic-gate 				lwp_update(lwp, lwpusage_buf);
5740Sstevel@tonic-gate 			}
5750Sstevel@tonic-gate 			Free(buf);
5760Sstevel@tonic-gate 		} else {
5770Sstevel@tonic-gate 			(void) snprintf(pfile, MAX_PROCFS_PATH,
578*5006Sek110237 			    "/proc/%s/usage", pidstr);
5790Sstevel@tonic-gate 			if ((fds->fds_usage = fd_open(pfile, O_RDONLY,
580*5006Sek110237 			    fds->fds_usage)) == NULL)
5810Sstevel@tonic-gate 				continue;
5820Sstevel@tonic-gate 			entsz = sizeof (prusage_t);
5830Sstevel@tonic-gate 			if (pread(fd_getfd(fds->fds_usage), &usage_buf,
584*5006Sek110237 			    entsz, 0) != entsz) {
5850Sstevel@tonic-gate 				fd_close(fds->fds_usage);
5860Sstevel@tonic-gate 				continue;
5870Sstevel@tonic-gate 			}
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate 			fd_close(fds->fds_usage);
5900Sstevel@tonic-gate 
5910Sstevel@tonic-gate 			lwpid = psinfo_buf.pr_lwp.pr_lwpid;
5920Sstevel@tonic-gate 			if ((lwp = lwpid_get(pid, lwpid)) == NULL)
5930Sstevel@tonic-gate 				continue;
5940Sstevel@tonic-gate 			lwp_update(lwp, &usage_buf);
5950Sstevel@tonic-gate 		}
5960Sstevel@tonic-gate 	}
5970Sstevel@tonic-gate 	list_refresh(&lwps);
5980Sstevel@tonic-gate 	fd_update();
5990Sstevel@tonic-gate 	log_msg("<-collect_lwp_data(): %d files open\n", fd_count());
6000Sstevel@tonic-gate }
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate /*
6040Sstevel@tonic-gate  * Create linked lists of users, projects and sets.
6050Sstevel@tonic-gate  *
6060Sstevel@tonic-gate  * Updates of the process, users and projects lists are done in
6070Sstevel@tonic-gate  * a critical section so that the consumer of these lists will
6080Sstevel@tonic-gate  * always get consistent data.
6090Sstevel@tonic-gate  */
6100Sstevel@tonic-gate static void
list_create()6110Sstevel@tonic-gate list_create()
6120Sstevel@tonic-gate {
6130Sstevel@tonic-gate 	struct utsname	utsn;
6140Sstevel@tonic-gate 	lwp_info_t *lwp;
6150Sstevel@tonic-gate 	hrtime_t t1, t2, t3;
6160Sstevel@tonic-gate 	double d;
6170Sstevel@tonic-gate 	int rv;
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate 	lwp = lwps.l_head;
6200Sstevel@tonic-gate 	total_mem = 0;
6210Sstevel@tonic-gate 	total_cpu = 0;
6220Sstevel@tonic-gate 	log_msg("->list_create()\n");
6230Sstevel@tonic-gate 	t1 = gethrtime();
6240Sstevel@tonic-gate 	if ((rv = pthread_mutex_lock(&listLock)) == 0) {
625*5006Sek110237 		t2 = gethrtime();
626*5006Sek110237 		d = (double)(t2 - t1) / 1000000000.0;
627*5006Sek110237 		log_msg("Scanner process lock wait was %1.5f sec\n", d);
6280Sstevel@tonic-gate 
629*5006Sek110237 		while (lwp) {
6300Sstevel@tonic-gate 			list_update(&processes, lwp);
6310Sstevel@tonic-gate 			list_update(&users, lwp);
6320Sstevel@tonic-gate 			list_update(&projects, lwp);
6330Sstevel@tonic-gate 			lwp = lwp->li_next;
634*5006Sek110237 		}
635*5006Sek110237 		list_refresh_id(&processes);
636*5006Sek110237 		list_refresh_id(&users);
637*5006Sek110237 		list_refresh_id(&projects);
638*5006Sek110237 		/* release the mutex */
639*5006Sek110237 		if ((rv = pthread_mutex_unlock(&listLock)) != 0)
6400Sstevel@tonic-gate 			log_msg("pthread_mutex_unlock failed with %d\n", rv);
641*5006Sek110237 
642*5006Sek110237 		t3 = gethrtime();
6430Sstevel@tonic-gate 
644*5006Sek110237 		d = (double)(t3 - t2) / 1000000000.0;
645*5006Sek110237 		log_msg("Scanner process lock time was %1.5f sec\n", d);
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate 	} else {
648*5006Sek110237 		log_msg("pthread_mutex_lock failed with %d\n", rv);
6490Sstevel@tonic-gate 	}
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate 	if (uname(&utsn) != -1) {
6520Sstevel@tonic-gate 		sys_info.name =
653*5006Sek110237 		    Realloc(sys_info.name, strlen(utsn.sysname) + 1);
6540Sstevel@tonic-gate 		(void) strcpy(sys_info.name, utsn.sysname);
6550Sstevel@tonic-gate 		sys_info.nodename =
656*5006Sek110237 		    Realloc(sys_info.nodename, strlen(utsn.nodename) + 1);
6570Sstevel@tonic-gate 		(void) strcpy(sys_info.nodename, utsn.nodename);
6580Sstevel@tonic-gate 	} else {
6590Sstevel@tonic-gate 		log_err("uname()\n");
6600Sstevel@tonic-gate 	}
6610Sstevel@tonic-gate 
6620Sstevel@tonic-gate 	log_msg("<-list_create()\n");
6630Sstevel@tonic-gate }
6640Sstevel@tonic-gate 
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate static void
collect_data()6670Sstevel@tonic-gate collect_data() {
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	collect_lwp_data();
6700Sstevel@tonic-gate 	if (getloadavg(loadavg, 3) == -1)
6710Sstevel@tonic-gate 		dmerror("cannot get load average\n");
6720Sstevel@tonic-gate }
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 
6750Sstevel@tonic-gate void
monitor_stop()6760Sstevel@tonic-gate monitor_stop()
6770Sstevel@tonic-gate {
6780Sstevel@tonic-gate 	/* store the list state */
6790Sstevel@tonic-gate 	if (ltdb_file != NULL)
6800Sstevel@tonic-gate 		(void) list_store(ltdb_file);
6810Sstevel@tonic-gate 	list_clear(&lwps);
6820Sstevel@tonic-gate 	list_clear(&processes);
6830Sstevel@tonic-gate 	list_clear(&users);
6840Sstevel@tonic-gate 	list_clear(&projects);
6850Sstevel@tonic-gate 	fd_exit();
6860Sstevel@tonic-gate }
6870Sstevel@tonic-gate 
6880Sstevel@tonic-gate 
6890Sstevel@tonic-gate /*
6900Sstevel@tonic-gate  * Initialize the monitor.
6910Sstevel@tonic-gate  * Creates list data structures.
6920Sstevel@tonic-gate  * If a saved list data file exists it is loaded.
6930Sstevel@tonic-gate  * The /proc directory is opened.
6940Sstevel@tonic-gate  * No actual scanning of /proc is done.
6950Sstevel@tonic-gate  *
6960Sstevel@tonic-gate  * Returns 0 if OK or -1 on error (leaving errno unchanged)
6970Sstevel@tonic-gate  */
6980Sstevel@tonic-gate int
monitor_start()6990Sstevel@tonic-gate monitor_start()
7000Sstevel@tonic-gate {
7010Sstevel@tonic-gate 
7020Sstevel@tonic-gate 	if (setjmp(dm_jmpbuffer) == 0) {
7030Sstevel@tonic-gate 		lwpid_init();
7040Sstevel@tonic-gate 		fd_init(Setrlimit());
7050Sstevel@tonic-gate 
7060Sstevel@tonic-gate 		list_alloc(&lwps, LS_LWPS);
7070Sstevel@tonic-gate 		list_alloc(&processes, LT_PROCESS);
7080Sstevel@tonic-gate 		list_alloc(&users, LS_USERS);
7090Sstevel@tonic-gate 		list_alloc(&projects, LS_PROJECTS);
7100Sstevel@tonic-gate 
7110Sstevel@tonic-gate 		list_init(&lwps, LT_LWPS);
7120Sstevel@tonic-gate 		list_init(&processes, LT_PROCESS);
7130Sstevel@tonic-gate 		list_init(&users, LT_USERS);
7140Sstevel@tonic-gate 		list_init(&projects, LT_PROJECTS);
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate 		sys_info.name = NULL;
7170Sstevel@tonic-gate 		sys_info.nodename = NULL;
7180Sstevel@tonic-gate 
7190Sstevel@tonic-gate 		if ((procdir = opendir("/proc")) == NULL)
7200Sstevel@tonic-gate 			dmerror("cannot open /proc directory\n");
7210Sstevel@tonic-gate 
7220Sstevel@tonic-gate 		/* restore the lists state */
7230Sstevel@tonic-gate 		if (ltdb_file != NULL)
7240Sstevel@tonic-gate 			(void) list_restore(ltdb_file);
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 		return (0);
7270Sstevel@tonic-gate 	} else {
7280Sstevel@tonic-gate 		return (-1);
7290Sstevel@tonic-gate 	}
7300Sstevel@tonic-gate }
7310Sstevel@tonic-gate 
7320Sstevel@tonic-gate 
7330Sstevel@tonic-gate /*
7340Sstevel@tonic-gate  * Update the monitor data lists.
7350Sstevel@tonic-gate  * return 0, or -1 on error and leave errno unchanged
7360Sstevel@tonic-gate  */
7370Sstevel@tonic-gate int
monitor_update()7380Sstevel@tonic-gate monitor_update()
7390Sstevel@tonic-gate {
7400Sstevel@tonic-gate 	if (setjmp(dm_jmpbuffer) == 0) {
7410Sstevel@tonic-gate 		collect_data();
7420Sstevel@tonic-gate 		list_create();
7430Sstevel@tonic-gate 		return (0);
7440Sstevel@tonic-gate 	} else {
7450Sstevel@tonic-gate 		return (-1);
7460Sstevel@tonic-gate 	}
7470Sstevel@tonic-gate }
748