xref: /onnv-gate/usr/src/cmd/rcap/rcapd/rcapd_collection_project.c (revision 3247:e05001c14ea2)
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*3247Sgjelinek  * Common Development and Distribution License (the "License").
6*3247Sgjelinek  * 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*3247Sgjelinek  * Copyright 2006 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 <procfs.h>
290Sstevel@tonic-gate #include <project.h>
300Sstevel@tonic-gate #include <stdlib.h>
310Sstevel@tonic-gate #include <strings.h>
320Sstevel@tonic-gate #include "rcapd.h"
330Sstevel@tonic-gate #include "utils.h"
340Sstevel@tonic-gate 
350Sstevel@tonic-gate 				/* absolute cap name */
360Sstevel@tonic-gate #define	PJ_ABS_ATTR_NAME	"rcap.max-rss"
370Sstevel@tonic-gate 				/* round up to next y = 2^n */
380Sstevel@tonic-gate #define	ROUNDUP(x, y)		(((x) + ((y) - 1)) & ~((y) - 1))
390Sstevel@tonic-gate 
400Sstevel@tonic-gate static int
lcollection_update_project_cb(const struct project * proj,void * walk_data)410Sstevel@tonic-gate lcollection_update_project_cb(const struct project *proj, void *walk_data)
420Sstevel@tonic-gate {
43*3247Sgjelinek 	void(*update_notification_cb)(char *, char *, int, uint64_t, int) =
44*3247Sgjelinek 	    (void(*)(char *, char *, int, uint64_t, int))walk_data;
450Sstevel@tonic-gate 	char *capattr_abs;
460Sstevel@tonic-gate 	char *end;
470Sstevel@tonic-gate 	int changes;
480Sstevel@tonic-gate 	int64_t max_rss;
490Sstevel@tonic-gate 	lcollection_t *lcol;
50*3247Sgjelinek 	rcid_t colid;
510Sstevel@tonic-gate 
520Sstevel@tonic-gate 	capattr_abs = strstr(proj->pj_attr, PJ_ABS_ATTR_NAME "=");
530Sstevel@tonic-gate 	if (capattr_abs != NULL) {
540Sstevel@tonic-gate 		if (capattr_abs > proj->pj_attr)
550Sstevel@tonic-gate 			if (*(capattr_abs - 1) != ';') {
560Sstevel@tonic-gate 				/*
570Sstevel@tonic-gate 				 * PJ_ABS_ATTR_NAME only matched part
580Sstevel@tonic-gate 				 * of an attribute.
590Sstevel@tonic-gate 				 */
600Sstevel@tonic-gate 				return (0);
610Sstevel@tonic-gate 			}
620Sstevel@tonic-gate 		capattr_abs += strlen(PJ_ABS_ATTR_NAME "=");
630Sstevel@tonic-gate 		max_rss = ROUNDUP(strtoll(capattr_abs, &end, 10), 1024) / 1024;
640Sstevel@tonic-gate 		if (end == capattr_abs || *end != ';' && *end != 0)
65*3247Sgjelinek 			warn(gettext("project %s: malformed %s value '%s'\n"),
66*3247Sgjelinek 			    proj->pj_name, PJ_ABS_ATTR_NAME, capattr_abs);
670Sstevel@tonic-gate 	} else
680Sstevel@tonic-gate 		max_rss = 0;
690Sstevel@tonic-gate 
70*3247Sgjelinek 	colid.rcid_type = RCIDT_PROJECT;
71*3247Sgjelinek 	colid.rcid_val = proj->pj_projid;
72*3247Sgjelinek 
73*3247Sgjelinek 	lcol = lcollection_insert_update(&colid, max_rss, proj->pj_name,
74*3247Sgjelinek 	    &changes);
750Sstevel@tonic-gate 	if (update_notification_cb != NULL)
76*3247Sgjelinek 		update_notification_cb("project", proj->pj_name, changes,
77*3247Sgjelinek 		    max_rss, (lcol != NULL) ? lcol->lcol_mark : 0);
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 	return (0);
800Sstevel@tonic-gate }
810Sstevel@tonic-gate 
820Sstevel@tonic-gate static int
lcollection_update_project_byid_cb(const projid_t id,void * walk_data)830Sstevel@tonic-gate lcollection_update_project_byid_cb(const projid_t id, void *walk_data)
840Sstevel@tonic-gate {
850Sstevel@tonic-gate 	char buf[PROJECT_BUFSZ];
860Sstevel@tonic-gate 	struct project proj;
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	if (getprojbyid(id, &proj, buf, sizeof (buf)) != NULL && proj.pj_attr !=
890Sstevel@tonic-gate 	    NULL)
900Sstevel@tonic-gate 		return (lcollection_update_project_cb(&proj, walk_data));
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	return (0);
930Sstevel@tonic-gate }
940Sstevel@tonic-gate 
950Sstevel@tonic-gate static int
lcollection_update_onceactive_cb(lcollection_t * lcol,void * walk_data)960Sstevel@tonic-gate lcollection_update_onceactive_cb(lcollection_t *lcol, void *walk_data)
970Sstevel@tonic-gate {
98*3247Sgjelinek 	void(*update_notification_cb)(char *, char *, int, uint64_t, int) =
99*3247Sgjelinek 	    (void(*)(char *, char *, int, uint64_t, int))walk_data;
1000Sstevel@tonic-gate 
101*3247Sgjelinek 	if (lcol->lcol_id.rcid_type != RCIDT_PROJECT)
102*3247Sgjelinek 		return (0);
103*3247Sgjelinek 
104*3247Sgjelinek 	return (lcollection_update_project_byid_cb(lcol->lcol_id.rcid_val,
1050Sstevel@tonic-gate 	    (void *)update_notification_cb));
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate static int
project_walk_all(int (* cb)(const struct project *,void *),void * walk_data)1090Sstevel@tonic-gate project_walk_all(int(*cb)(const struct project *, void *), void *walk_data)
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate 	char buf[PROJECT_BUFSZ];
1120Sstevel@tonic-gate 	struct project proj;
1130Sstevel@tonic-gate 	int res = 0;
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	setprojent();
1160Sstevel@tonic-gate 	while (getprojent(&proj, buf, sizeof (buf)) != NULL && res == 0)
1170Sstevel@tonic-gate 		res = cb(&proj, walk_data);
1180Sstevel@tonic-gate 	endprojent();
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	return (res);
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate void
lcollection_update_project(lcollection_update_type_t ut,void (* update_notification_cb)(char *,char *,int,uint64_t,int))1240Sstevel@tonic-gate lcollection_update_project(lcollection_update_type_t ut,
125*3247Sgjelinek     void(*update_notification_cb)(char *, char *, int, uint64_t, int))
1260Sstevel@tonic-gate {
1270Sstevel@tonic-gate 	switch (ut) {
1280Sstevel@tonic-gate 	case LCU_ACTIVE_ONLY:
1290Sstevel@tonic-gate 		/*
1300Sstevel@tonic-gate 		 * Enumerate active projects.  This is much faster than
1310Sstevel@tonic-gate 		 * enumerating all projects (as is done below, in the default
1320Sstevel@tonic-gate 		 * case), and is done to efficiently and incrementally update
1330Sstevel@tonic-gate 		 * lcollection with capped projects.  The default case performs
1340Sstevel@tonic-gate 		 * the initialization.
1350Sstevel@tonic-gate 		 */
1360Sstevel@tonic-gate 		(void) project_walk(lcollection_update_project_byid_cb,
1370Sstevel@tonic-gate 		    (void *)update_notification_cb);
1380Sstevel@tonic-gate 		/*
1390Sstevel@tonic-gate 		 * Enumerate once-active projects, including the active
1400Sstevel@tonic-gate 		 * projects just enumerated, meaning active projects will be
1410Sstevel@tonic-gate 		 * updated and marked twice.
1420Sstevel@tonic-gate 		 */
1430Sstevel@tonic-gate 		list_walk_collection(lcollection_update_onceactive_cb,
1440Sstevel@tonic-gate 		    (void *)update_notification_cb);
1450Sstevel@tonic-gate 		break;
1460Sstevel@tonic-gate 	default:
1470Sstevel@tonic-gate 		/*
1480Sstevel@tonic-gate 		 * Enumerate all projects.
1490Sstevel@tonic-gate 		 */
1500Sstevel@tonic-gate 		(void) project_walk_all(lcollection_update_project_cb,
1510Sstevel@tonic-gate 		    (void *)update_notification_cb);
1520Sstevel@tonic-gate 	}
1530Sstevel@tonic-gate }
154