xref: /illumos-gate/usr/src/cmd/rcap/rcapd/rcapd_main.c (revision 141040e8a310da49386b596573e5dde5580572ec)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * rcapd is a long-running daemon enforcing project-based resource caps (see
31  * rcapd(1M)).  Each instance of a process aggregate (project or, generically,
32  * "collection") may have a memory cap.  A single thread monitors the resource
33  * utilization of capped collections, enforces caps when they are exceeded (and
34  * other conditions are met), and incorporates changes in configuration or
35  * caps.  Each of these actions occurs not more frequently than the rate
36  * specified with rcapadm(1M).
37  */
38 
39 #include <sys/priocntl.h>
40 #include <sys/proc.h>
41 #include <sys/resource.h>
42 #include <sys/sysinfo.h>
43 #include <sys/stat.h>
44 #include <sys/sysmacros.h>
45 #include <sys/time.h>
46 #include <sys/types.h>
47 #include <dirent.h>
48 #include <errno.h>
49 #include <fcntl.h>
50 #include <kstat.h>
51 #include <libintl.h>
52 #include <limits.h>
53 #include <locale.h>
54 #include <priv.h>
55 #include <signal.h>
56 #include <stdarg.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <strings.h>
60 #include <time.h>
61 #include <unistd.h>
62 #include <zone.h>
63 #include <assert.h>
64 #include "rcapd.h"
65 #include "rcapd_mapping.h"
66 #include "rcapd_rfd.h"
67 #include "rcapd_stat.h"
68 #include "utils.h"
69 
70 #define	POSITIVE_MIN(x, y) \
71 	(((x) <= 0) ? (y) : ((y) <= 0) ? (x) : MIN(x, y))
72 #define	NEXT_EVENT_TIME(base, seconds) \
73 	(((int)seconds > 0) ? (base + (hrtime_t)seconds * (hrtime_t)NANOSEC) \
74 	: (hrtime_t)0)
75 #define	NEXT_REPORT_EVENT_TIME(base, seconds) \
76 	((rcfg.rcfg_stat_file[0] != 0) ?  \
77 	    NEXT_EVENT_TIME(gethrtime(), seconds) : (hrtime_t)0)
78 #define	EVENT_TIME(time, eventtime) \
79 	(((time) > (eventtime)) && (eventtime) != 0)
80 #define	STAT_TEMPLATE_SUFFIX	".XXXXXX"	/* suffix of mkstemp() arg */
81 #define	DAEMON_UID		1		/* uid to use */
82 
83 typedef struct soft_scan_arg {
84 	uint64_t ssa_sum_excess;
85 	int64_t ssa_scan_goal;
86 } soft_scan_arg_t;
87 
88 static int debug_mode = 0;		/* debug mode flag */
89 static pid_t rcapd_pid;			/* rcapd's pid to ensure it's not */
90 					/* scanned */
91 static kstat_ctl_t *kctl;		/* kstat chain */
92 static uint64_t new_sp = 0, old_sp = 0;	/* measure delta in page scan count */
93 static int enforce_caps = 0;		/* cap enforcement flag, dependent on */
94 					/* enforce_soft_caps and */
95 					/* global_scanner_running */
96 static int enforce_soft_caps = 0;	/* soft cap enforcement flag, */
97 					/* depending on memory pressure */
98 static int memory_pressure = 0;		/* physical memory utilization (%) */
99 static int memory_pressure_sample = 0;	/* count of samples */
100 static int global_scanner_running = 0;	/* global scanning flag, to avoid */
101 					/* interference with kernel's page */
102 					/* scanner */
103 static hrtime_t next_report;		/* time of next report */
104 static int termination_signal = 0;	/* terminating signal */
105 
106 rcfg_t rcfg;
107 
108 /*
109  * Flags.
110  */
111 static int ever_ran;
112 int should_run;
113 static int should_reconfigure;
114 
115 static int verify_statistics(void);
116 static int update_statistics(void);
117 
118 /*
119  * Checks if a process is marked 'system'.  Returns zero only when it is not.
120  */
121 static int
122 proc_issystem(pid_t pid)
123 {
124 	char pc_clname[PC_CLNMSZ];
125 
126 	if (priocntl(P_PID, pid, PC_GETXPARMS, NULL, PC_KY_CLNAME, pc_clname,
127 	    PC_KY_NULL) != -1) {
128 		return (strcmp(pc_clname, "SYS") == 0);
129 	} else {
130 		debug("cannot get class-specific scheduling parameters; "
131 		    "assuming system process");
132 		return (-1);
133 	}
134 }
135 
136 /*
137  * fname is the process name, for debugging messages, and unscannable is a flag
138  * indicating whether the process should be scanned.
139  */
140 static void
141 lprocess_insert_mark(pid_t pid, id_t colid, char *fname, int unscannable)
142 {
143 	lcollection_t *lcol;
144 	lprocess_t *lproc;
145 
146 	if ((lcol = lcollection_find(colid)) == NULL)
147 		return;
148 
149 	/*
150 	 * If the process is already being tracked, update the unscannable flag,
151 	 * as determined by the caller, from the process's psinfo.
152 	 */
153 	lproc = lcol->lcol_lprocess;
154 	while (lproc != NULL) {
155 		if (lproc->lpc_pid == pid) {
156 			lproc->lpc_mark = 1;
157 			if (unscannable != 0 && lproc->lpc_unscannable == 0) {
158 				debug("process %d: became unscannable\n",
159 				    (int)lproc->lpc_pid);
160 				lproc->lpc_unscannable = 1;
161 			}
162 			return;
163 		}
164 		lproc = lproc->lpc_next;
165 	}
166 
167 	/*
168 	 * We've fallen off the list without finding our current process;
169 	 * insert it at the list head.
170 	 */
171 	if ((lproc = malloc(sizeof (*lproc))) == NULL)
172 		debug("insufficient memory to track new process %d", (int)pid);
173 	else {
174 		(void) bzero(lproc, sizeof (*lproc));
175 		lproc->lpc_pid = pid;
176 		lproc->lpc_mark = 1;
177 		lproc->lpc_collection = lcol;
178 		lproc->lpc_psinfo_fd = -1;
179 		lproc->lpc_pgdata_fd = -1;
180 		lproc->lpc_xmap_fd = -1;
181 
182 		/*
183 		 * If the caller didn't flag this process as unscannable
184 		 * already, do some more checking.
185 		 */
186 		lproc->lpc_unscannable = unscannable || proc_issystem(pid);
187 
188 #ifdef DEBUG
189 		/*
190 		 * Verify the sanity of lprocess.  It should not contain the
191 		 * process we are about to prepend.
192 		 */
193 		if (lcollection_member(lcol, lproc)) {
194 			lprocess_t *cur = lcol->lcol_lprocess;
195 			debug("The collection %lld already has these members, "
196 			    "including me, %d!\n", (long long)lcol->lcol_id,
197 			    (int)lproc->lpc_pid);
198 			while (cur != NULL) {
199 				debug("\t%d\n", (int)cur->lpc_pid);
200 				cur = cur->lpc_next;
201 			}
202 			info(gettext("process already on lprocess\n"));
203 			abort();
204 		}
205 #endif /* DEBUG */
206 		lproc->lpc_next = lcol->lcol_lprocess;
207 		if (lproc->lpc_next != NULL)
208 			lproc->lpc_next->lpc_prev = lproc;
209 		lproc->lpc_prev = NULL;
210 		lcol->lcol_lprocess = lproc;
211 
212 		debug("tracking %d %d %s%s\n", (int)colid, (int)pid, fname,
213 		    (lproc->lpc_unscannable != 0) ? " (not scannable)" : "");
214 		lcol->lcol_stat.lcols_proc_in++;
215 	}
216 }
217 
218 static int
219 list_walk_process_cb(lcollection_t *lcol, void *arg)
220 {
221 	int (*cb)(lcollection_t *, lprocess_t *) =
222 	    (int(*)(lcollection_t *, lprocess_t *))arg;
223 	lprocess_t *member;
224 	lprocess_t *next;
225 
226 	member = lcol->lcol_lprocess;
227 	while (member != NULL) {
228 		pid_t pid = member->lpc_pid;
229 		next = member->lpc_next;
230 
231 		debug_high("list_walk_all lpc %d\n", (int)pid);
232 		if (cb(lcol, member) != 0) {
233 			debug_high("list_walk_all aborted at lpc %d\n",
234 			    (int)pid);
235 			return (1);
236 		}
237 		member = next;
238 	}
239 
240 	return (0);
241 }
242 
243 /*
244  * Invoke the given callback for each process in each collection.  Callbacks
245  * are allowed to change the linkage of the process on which they act.
246  */
247 static void
248 list_walk_all(int (*cb)(lcollection_t *, lprocess_t *))
249 {
250 	list_walk_collection(list_walk_process_cb, (void *)cb);
251 }
252 
253 static void
254 revoke_psinfo(rfd_t *rfd)
255 {
256 	lprocess_t *lpc = (lprocess_t *)rfd->rfd_data;
257 
258 	if (lpc != NULL) {
259 		debug("revoking psinfo fd for process %d\n", (int)lpc->lpc_pid);
260 		ASSERT(lpc->lpc_psinfo_fd != -1);
261 		lpc->lpc_psinfo_fd = -1;
262 	} else
263 		debug("revoking psinfo fd for unknown process\n");
264 }
265 
266 /*
267  * Retrieve a process's psinfo via an already-opened or new file descriptor.
268  * The supplied descriptor will be closed on failure.  An optional callback
269  * will be invoked with the last descriptor tried, and a supplied callback
270  * argument, as its arguments, such that the new descriptor may be cached, or
271  * an old one may be invalidated.  If the result of the callback is zero, the
272  * the caller is to assume responsibility for the file descriptor, to close it
273  * with rfd_close().
274  *
275  * On failure, a nonzero value is returned.
276  */
277 int
278 get_psinfo(pid_t pid, psinfo_t *psinfo, int cached_fd,
279     int(*fd_update_cb)(void *, int), void *arg, lprocess_t *lpc)
280 {
281 	int fd;
282 	int can_try_uncached;
283 
284 	ASSERT(!(cached_fd > 0 && fd_update_cb == NULL));
285 
286 	do {
287 		if (cached_fd >= 0) {
288 			fd = cached_fd;
289 			can_try_uncached = 1;
290 			debug_high("%d/psinfo, trying cached fd %d\n",
291 			    (int)pid, fd);
292 		} else {
293 			char pathbuf[PROC_PATH_MAX];
294 
295 			can_try_uncached = 0;
296 			(void) snprintf(pathbuf, sizeof (pathbuf),
297 			    "/proc/%d/psinfo", (int)pid);
298 			if ((fd = rfd_open(pathbuf, 1, RFD_PSINFO,
299 			    revoke_psinfo, lpc, O_RDONLY, 0000)) < 0) {
300 				debug("cannot open %s", pathbuf);
301 				break;
302 			} else
303 				debug_high("opened %s, fd %d\n", pathbuf, fd);
304 		}
305 
306 		if (pread(fd, psinfo, sizeof (*psinfo), 0) ==
307 		    sizeof (*psinfo) && psinfo->pr_pid == pid)
308 			break;
309 		else {
310 			debug_high("closed fd %d\n", fd);
311 			if (rfd_close(fd) != 0)
312 				debug("could not close fd %d", fd);
313 			fd = cached_fd = -1;
314 		}
315 	} while (can_try_uncached == 1);
316 
317 	if (fd_update_cb == NULL || fd_update_cb(arg, fd) != 0)
318 		if (fd >= 0) {
319 			debug_high("closed %s fd %d\n", fd_update_cb == NULL ?
320 			    "uncached" : "cached", fd);
321 			if (rfd_close(fd) != 0)
322 				debug("could not close fd %d", fd);
323 		}
324 
325 	debug_high("get_psinfo ret %d, fd %d, %s\n", ((fd >= 0) ? 0 : -1), fd,
326 	    fd_update_cb != NULL ? "cached" : "uncached");
327 	return ((fd >= 0) ? 0 : -1);
328 }
329 
330 /*
331  * Retrieve the collection membership of all processes in our zone, and update
332  * the psinfo of those non-system, non-zombie ones in collections.
333  */
334 static void
335 proc_cb(const pid_t pid)
336 {
337 	static zoneid_t ours = (zoneid_t)-1;
338 	psinfo_t psinfo;
339 
340 	if (ours == (zoneid_t)-1)
341 		ours = getzoneid();
342 
343 	if (get_psinfo(pid, &psinfo, -1, NULL, NULL, NULL) == 0 &&
344 	    psinfo.pr_zoneid == ours)
345 		lprocess_insert_mark(psinfo.pr_pid, rc_getidbypsinfo(&psinfo),
346 		    psinfo.pr_psargs, psinfo.pr_nlwp == 0);
347 }
348 
349 /*
350  * Cache the process' psinfo fd, taking responsibility for freeing it.
351  */
352 int
353 lprocess_update_psinfo_fd_cb(void *arg, int fd)
354 {
355 	lprocess_t *lpc = arg;
356 
357 	lpc->lpc_psinfo_fd = fd;
358 	return (0);
359 }
360 
361 /*
362  * Update the RSS of processes in monitored collections.
363  */
364 /*ARGSUSED*/
365 static int
366 mem_sample_cb(lcollection_t *lcol, lprocess_t *lpc)
367 {
368 	psinfo_t psinfo;
369 
370 	if (get_psinfo(lpc->lpc_pid, &psinfo, lpc->lpc_psinfo_fd,
371 	    lprocess_update_psinfo_fd_cb, lpc, lpc) == 0) {
372 		lpc->lpc_rss = psinfo.pr_rssize;
373 		lpc->lpc_size = psinfo.pr_size;
374 	} else {
375 		if (errno == ENOENT)
376 			debug("process %d finished\n", (int)lpc->lpc_pid);
377 		else
378 			debug("process %d: cannot read psinfo",
379 			    (int)lpc->lpc_pid);
380 		lprocess_free(lpc);
381 	}
382 
383 	return (0);
384 }
385 
386 /*
387  * Sample the collection RSS, updating the collection's statistics with the
388  * results.
389  */
390 /*ARGSUSED*/
391 static int
392 rss_sample_col_cb(lcollection_t *lcol, void *arg)
393 {
394 	int64_t excess;
395 	uint64_t rss;
396 
397 	/*
398 	 * If updating statistics for a new interval, reset the affected
399 	 * counters.
400 	 */
401 	if (lcol->lcol_stat_invalidate != 0) {
402 		lcol->lcol_stat_old = lcol->lcol_stat;
403 		lcol->lcol_stat.lcols_min_rss = (int64_t)-1;
404 		lcol->lcol_stat.lcols_max_rss = 0;
405 		lcol->lcol_stat_invalidate = 0;
406 	}
407 
408 	lcol->lcol_stat.lcols_rss_sample++;
409 	excess = lcol->lcol_rss - lcol->lcol_rss_cap;
410 	rss = lcol->lcol_rss;
411 	if (excess > 0)
412 		lcol->lcol_stat.lcols_rss_act_sum += rss;
413 	lcol->lcol_stat.lcols_rss_sum += rss;
414 
415 	if (lcol->lcol_stat.lcols_min_rss > rss)
416 		lcol->lcol_stat.lcols_min_rss = rss;
417 	if (lcol->lcol_stat.lcols_max_rss < rss)
418 		lcol->lcol_stat.lcols_max_rss = rss;
419 
420 	return (0);
421 }
422 
423 /*
424  * Open /proc and walk entries.
425  */
426 static void
427 proc_walk_all(void (*cb)(const pid_t))
428 {
429 	DIR *pdir;
430 	struct dirent *dirent;
431 	pid_t pid;
432 
433 	(void) rfd_reserve(1);
434 	if ((pdir = opendir("/proc")) == NULL)
435 		die(gettext("couldn't open /proc!"));
436 
437 	while ((dirent = readdir(pdir)) != NULL) {
438 		if (strcmp(".", dirent->d_name) == 0 ||
439 		    strcmp("..", dirent->d_name) == 0)
440 			continue;
441 		pid = atoi(dirent->d_name);
442 		ASSERT(pid != 0 || strcmp(dirent->d_name, "0") == 0);
443 		if (pid == rcapd_pid)
444 			continue;
445 		else
446 			cb(pid);
447 	}
448 	(void) closedir(pdir);
449 }
450 
451 /*
452  * Memory update callback.
453  */
454 static int
455 memory_all_cb(lcollection_t *lcol, lprocess_t *lpc)
456 {
457 	debug_high("%s %s, pid %d: rss += %llu/%llu\n", rcfg.rcfg_mode_name,
458 	    lcol->lcol_name, (int)lpc->lpc_pid,
459 	    (unsigned long long)lpc->lpc_rss,
460 	    (unsigned long long)lpc->lpc_size);
461 	ASSERT(lpc->lpc_rss <= lpc->lpc_size);
462 	lcol->lcol_rss += lpc->lpc_rss;
463 	lcol->lcol_image_size += lpc->lpc_size;
464 
465 	return (0);
466 }
467 
468 /*
469  * Clear unmarked callback.
470  */
471 /*ARGSUSED*/
472 static int
473 sweep_process_cb(lcollection_t *lcol, lprocess_t *lpc)
474 {
475 	if (lpc->lpc_mark) {
476 		lpc->lpc_mark = 0;
477 	} else {
478 		debug("process %d finished\n", (int)lpc->lpc_pid);
479 		lprocess_free(lpc);
480 	}
481 
482 	return (0);
483 }
484 
485 /*
486  * Memory clear callback.
487  */
488 /*ARGSUSED*/
489 static int
490 collection_zero_mem_cb(lcollection_t *lcol, void *arg)
491 {
492 	lcol->lcol_rss = 0;
493 	lcol->lcol_image_size = 0;
494 
495 	return (0);
496 }
497 
498 /*
499  * Print, for debugging purposes, a collection's recently-sampled RSS and
500  * excess.
501  */
502 /*ARGSUSED*/
503 static int
504 excess_print_cb(lcollection_t *lcol, void *arg)
505 {
506 	int64_t excess = lcol->lcol_rss - lcol->lcol_rss_cap;
507 
508 	debug("%s %s rss/cap: %llu/%llu, excess = %lld kB\n",
509 	    rcfg.rcfg_mode_name, lcol->lcol_name,
510 	    (unsigned long long)lcol->lcol_rss,
511 	    (unsigned long long)lcol->lcol_rss_cap,
512 	    (long long)excess);
513 
514 	return (0);
515 }
516 
517 /*
518  * Scan those collections which have exceeded their caps.
519  */
520 /*ARGSUSED*/
521 static int
522 scan_cb(lcollection_t *lcol, void *arg)
523 {
524 	int64_t excess;
525 
526 	if ((excess = lcol->lcol_rss - lcol->lcol_rss_cap) > 0) {
527 		scan(lcol, excess);
528 		lcol->lcol_stat.lcols_scan++;
529 	}
530 
531 	return (0);
532 }
533 
534 /*
535  * Do a soft scan of those collections which have excesses.  A soft scan is one
536  * in which the cap enforcement pressure is taken into account.  The difference
537  * between the utilized physical memory and the cap enforcement pressure will
538  * be scanned-for, and each collection will be scanned proportionally by their
539  * present excesses.
540  */
541 static int
542 soft_scan_cb(lcollection_t *lcol, void *a)
543 {
544 	int64_t excess;
545 	soft_scan_arg_t *arg = a;
546 
547 	if ((excess = lcol->lcol_rss - lcol->lcol_rss_cap) > 0) {
548 		debug("col %lld excess %lld scan_goal %lld sum_excess %llu, "
549 		    "scanning %lld\n", (long long)lcol->lcol_id,
550 		    (long long)excess, (long long)arg->ssa_scan_goal,
551 		    (unsigned long long)arg->ssa_sum_excess,
552 		    (long long)(excess * arg->ssa_scan_goal /
553 		    arg->ssa_sum_excess));
554 
555 		scan(lcol, (int64_t)(excess * arg->ssa_scan_goal /
556 		    arg->ssa_sum_excess));
557 		lcol->lcol_stat.lcols_scan++;
558 	}
559 
560 	return (0);
561 }
562 
563 /*
564  * When a scan could happen, but caps aren't enforced tick the
565  * lcols_unenforced_cap counter.
566  */
567 /*ARGSUSED*/
568 static int
569 unenforced_cap_cb(lcollection_t *lcol, void *arg)
570 {
571 	lcol->lcol_stat.lcols_unenforced_cap++;
572 
573 	return (0);
574 }
575 
576 /*
577  * Update the count of physically installed memory.
578  */
579 static void
580 update_phys_total(void)
581 {
582 	uint64_t old_phys_total;
583 
584 	old_phys_total = phys_total;
585 	phys_total = (uint64_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE)
586 	    / 1024;
587 	if (phys_total != old_phys_total)
588 		debug("physical memory%s: %lluM\n", (old_phys_total == 0 ?
589 		    "" : " adjusted"), (unsigned long long)(phys_total / 1024));
590 }
591 
592 /*
593  * Unlink a process from its collection, updating relevant statistics, and
594  * freeing its associated memory.
595  */
596 void
597 lprocess_free(lprocess_t *lpc)
598 {
599 	pid_t pid;
600 
601 	lpc->lpc_collection->lcol_stat.lcols_proc_out++;
602 
603 	if (lpc->lpc_prev != NULL)
604 		lpc->lpc_prev->lpc_next = lpc->lpc_next;
605 	if (lpc->lpc_next != NULL)
606 		lpc->lpc_next->lpc_prev = lpc->lpc_prev;
607 	if (lpc->lpc_collection->lcol_lprocess == lpc)
608 		lpc->lpc_collection->lcol_lprocess = (lpc->lpc_next !=
609 		    lpc ? lpc->lpc_next : NULL);
610 	lpc->lpc_next = lpc->lpc_prev = NULL;
611 
612 	if (lpc->lpc_prpageheader != NULL)
613 		free(lpc->lpc_prpageheader);
614 	if (lpc->lpc_xmap != NULL)
615 		free(lpc->lpc_xmap);
616 	if (lpc->lpc_psinfo_fd >= 0) {
617 		if (rfd_close(lpc->lpc_psinfo_fd) != 0)
618 			debug("could not close %d lpc_psinfo_fd %d",
619 			    (int)lpc->lpc_pid, lpc->lpc_psinfo_fd);
620 		lpc->lpc_psinfo_fd = -1;
621 	}
622 	if (lpc->lpc_pgdata_fd >= 0) {
623 		if (rfd_close(lpc->lpc_pgdata_fd) != 0)
624 			debug("could not close %d lpc_pgdata_fd %d",
625 			    (int)lpc->lpc_pid, lpc->lpc_pgdata_fd);
626 		lpc->lpc_pgdata_fd = -1;
627 	}
628 	if (lpc->lpc_xmap_fd >= 0) {
629 		if (rfd_close(lpc->lpc_xmap_fd) != 0)
630 			debug("could not close %d lpc_xmap_fd %d",
631 			    (int)lpc->lpc_pid, lpc->lpc_xmap_fd);
632 		lpc->lpc_xmap_fd = -1;
633 	}
634 	if (lpc->lpc_ignore != NULL)
635 		lmapping_free(&lpc->lpc_ignore);
636 	pid = lpc->lpc_pid;
637 	free(lpc);
638 	debug_high("process %d freed\n", (int)pid);
639 }
640 
641 /*
642  * Collection clear callback.
643  */
644 /*ARGSUSED*/
645 static int
646 collection_clear_cb(lcollection_t *lcol, void *arg)
647 {
648 	lcol->lcol_mark = 0;
649 
650 	return (0);
651 }
652 
653 /*
654  * Respond to a terminating signal by setting a termination flag.
655  */
656 /*ARGSUSED*/
657 static void
658 terminate_signal(int signal)
659 {
660 	if (termination_signal == 0)
661 		termination_signal = signal;
662 	should_run = 0;
663 }
664 
665 /*
666  * Handle any synchronous or asynchronous signals that would ordinarily cause a
667  * process to abort.
668  */
669 /*ARGSUSED*/
670 static void
671 abort_signal(int signal)
672 {
673 	/*
674 	 * Allow the scanner to make a last-ditch effort to resume any stopped
675 	 * processes.
676 	 */
677 	scan_abort();
678 	abort();
679 }
680 
681 /*
682  * Clean up collections which have been removed due to configuration.  Unlink
683  * the collection from lcollection and free it.
684  */
685 /*ARGSUSED*/
686 static int
687 collection_sweep_cb(lcollection_t *lcol, void *arg)
688 {
689 	if (lcol->lcol_mark == 0) {
690 		debug("freeing %s %s\n", rcfg.rcfg_mode_name, lcol->lcol_name);
691 		lcollection_free(lcol);
692 	}
693 
694 	return (0);
695 }
696 
697 /*
698  * Set those variables which depend on the global configuration.
699  */
700 static void
701 finish_configuration(void)
702 {
703 	/*
704 	 * Warn that any lnode (or non-project) mode specification (by an SRM
705 	 * 1.3 configuration file, for example) is ignored.
706 	 */
707 	if (strcmp(rcfg.rcfg_mode_name, "project") != 0) {
708 		warn(gettext("%s mode specification ignored -- using project"
709 		    " mode\n"), rcfg.rcfg_mode_name);
710 		rcfg.rcfg_mode_name = "project";
711 		rcfg.rcfg_mode = rctype_project;
712 	}
713 
714 	lcollection_set_type(rcfg.rcfg_mode);
715 }
716 
717 /*
718  * Cause the configuration file to be reread and applied.
719  */
720 static void
721 reread_configuration_file(void)
722 {
723 	rcfg_t rcfg_new;
724 	struct stat st;
725 
726 	if (stat(rcfg.rcfg_filename, &st) == 0 && st.st_mtime ==
727 	    rcfg.rcfg_last_modification)
728 		return;
729 
730 	if (rcfg_read(rcfg.rcfg_filename, rcfg.rcfg_fd, &rcfg_new,
731 	    update_statistics) != 0)
732 		warn(gettext("can't reread configuration"));
733 	else {
734 		/*
735 		 * The configuration file has been read.  Remove existing
736 		 * collections in case there is a change in collection type.
737 		 */
738 		if (rcfg.rcfg_mode != rcfg_new.rcfg_mode) {
739 			list_walk_collection(collection_clear_cb, NULL);
740 			list_walk_collection(collection_sweep_cb, NULL);
741 		}
742 
743 		/*
744 		 * Make the newly-read configuration the global one, and update
745 		 * any variables that depend on it.
746 		 */
747 		rcfg = rcfg_new;
748 		finish_configuration();
749 	}
750 }
751 
752 /*
753  * Reread the configuration filex, then examine changes, additions, and
754  * deletions to cap definitions.
755  */
756 static void
757 reconfigure(void)
758 {
759 	debug("reconfigure...\n");
760 
761 	/*
762 	 * Reread the configuration data.
763 	 */
764 	reread_configuration_file();
765 
766 	/*
767 	 * Walk the lcollection, marking active collections so inactive ones
768 	 * can be freed.
769 	 */
770 	list_walk_collection(collection_clear_cb, NULL);
771 	lcollection_update(LCU_ACTIVE_ONLY); /* mark */
772 	list_walk_collection(collection_sweep_cb, NULL);
773 }
774 
775 /*
776  * Respond to SIGHUP by triggering the rereading the configuration file and cap
777  * definitions.
778  */
779 /*ARGSUSED*/
780 static void
781 sighup(int signal)
782 {
783 	should_reconfigure = 1;
784 }
785 
786 /*
787  * Print, for debugging purposes, each collection's interval statistics.
788  */
789 /*ARGSUSED*/
790 static int
791 simple_report_collection_cb(lcollection_t *lcol, void *arg)
792 {
793 #define	DELTA(field) \
794 	(unsigned long long)(lcol->lcol_stat_invalidate ? 0 : \
795 	    (lcol->lcol_stat.field - lcol->lcol_stat_old.field))
796 #define	VALID(field) \
797 	(unsigned long long)(lcol->lcol_stat_invalidate ? 0 : \
798 	    lcol->lcol_stat.field)
799 
800 	debug("%s %s status: succeeded/attempted (k): %llu/%llu, "
801 	    "ineffective/scans/unenforced/samplings:  %llu/%llu/%llu/%llu, RSS "
802 	    "min/max (k): %llu/%llu, cap %llu kB, processes/thpt: %llu/%llu, "
803 	    "%llu scans over %llu ms\n", rcfg.rcfg_mode_name, lcol->lcol_name,
804 	    DELTA(lcols_pg_eff), DELTA(lcols_pg_att),
805 	    DELTA(lcols_scan_ineffective), DELTA(lcols_scan),
806 	    DELTA(lcols_unenforced_cap), DELTA(lcols_rss_sample),
807 	    VALID(lcols_min_rss), VALID(lcols_max_rss),
808 	    (unsigned long long)lcol->lcol_rss_cap,
809 	    (unsigned long long)(lcol->lcol_stat.lcols_proc_in -
810 	    lcol->lcol_stat.lcols_proc_out), DELTA(lcols_proc_out),
811 	    DELTA(lcols_scan_count), DELTA(lcols_scan_time_complete) / (NANOSEC
812 	    / MILLISEC));
813 
814 #undef DELTA
815 #undef VALID
816 
817 	return (0);
818 }
819 
820 /*
821  * Record each collection's interval statistics in the statistics file.
822  */
823 static int
824 report_collection_cb(lcollection_t *lcol, void *arg)
825 {
826 	lcollection_report_t dc;
827 	int fd = (intptr_t)arg;
828 
829 	/*
830 	 * Copy the relevant fields to the collection's record.
831 	 */
832 	bzero(&dc, sizeof (dc));
833 	dc.lcol_id = lcol->lcol_id;
834 	(void) strcpy(dc.lcol_name, lcol->lcol_name);
835 	dc.lcol_rss = lcol->lcol_rss;
836 	dc.lcol_image_size = lcol->lcol_image_size;
837 	dc.lcol_rss_cap = lcol->lcol_rss_cap;
838 	dc.lcol_stat = lcol->lcol_stat;
839 
840 	if (write(fd, &dc, sizeof (dc)) == sizeof (dc)) {
841 		/*
842 		 * Set a flag to indicate that the exported interval snapshot
843 		 * values should be reset at the next sample.
844 		 */
845 		lcol->lcol_stat_invalidate = 1;
846 	} else {
847 		debug("can't write %s %s statistics", rcfg.rcfg_mode_name,
848 		    lcol->lcol_name);
849 	}
850 
851 	return (0);
852 }
853 
854 /*
855  * Determine the count of pages scanned by the global page scanner, obtained
856  * from the cpu_stat:*::scan kstats.  Return zero on success.
857  */
858 static int
859 get_globally_scanned_pages(uint64_t *scannedp)
860 {
861 	kstat_t *ksp;
862 	uint64_t scanned = 0;
863 
864 	if (kstat_chain_update(kctl) == -1) {
865 		warn(gettext("can't update kstat chain"));
866 		return (0);
867 	}
868 
869 	for (ksp = kctl->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
870 		if (strcmp(ksp->ks_module, "cpu_stat") == 0) {
871 			if (kstat_read(kctl, ksp, NULL) != -1) {
872 				scanned += ((cpu_stat_t *)
873 				    ksp->ks_data)->cpu_vminfo.scan;
874 			} else
875 				return (-1);
876 		}
877 	}
878 
879 	*scannedp = scanned;
880 	return (0);
881 }
882 
883 /*
884  * Update the shared statistics file with each collection's current statistics.
885  * Return zero on success.
886  */
887 static int
888 update_statistics(void)
889 {
890 	int fd, res;
891 	static char template[LINELEN];
892 
893 	/*
894 	 * Try to create a directory irrespective of whether it is existing
895 	 * or not. If it is not there then it will create. Otherwise any way
896 	 * it will fail at mkstemp call below.
897 	 */
898 	(void) mkdir(STAT_FILE_DIR, 0755);
899 
900 	/*
901 	 * Create a temporary file.
902 	 */
903 	if (sizeof (template) < (strlen(rcfg.rcfg_stat_file) +
904 	    strlen(STAT_TEMPLATE_SUFFIX) + 1)) {
905 		debug("temporary file template size too small\n");
906 		return (-1);
907 	}
908 	(void) strcpy(template, rcfg.rcfg_stat_file);
909 	(void) strcat(template, STAT_TEMPLATE_SUFFIX);
910 	(void) rfd_reserve(1);
911 	fd = mkstemp(template);
912 
913 	/*
914 	 * Write the header and per-collection statistics.
915 	 */
916 	if (fd >= 0) {
917 		rcapd_stat_hdr_t rs;
918 
919 		rs.rs_pid = rcapd_pid;
920 		rs.rs_time = gethrtime();
921 		ASSERT(sizeof (rs.rs_mode) > strlen(rcfg.rcfg_mode_name));
922 		(void) strcpy(rs.rs_mode, rcfg.rcfg_mode_name);
923 		rs.rs_pressure_cur = memory_pressure;
924 		rs.rs_pressure_cap = rcfg.rcfg_memory_cap_enforcement_pressure;
925 		rs.rs_pressure_sample = memory_pressure_sample;
926 
927 		if (fchmod(fd, 0644) == 0 && write(fd, &rs, sizeof (rs)) ==
928 		    sizeof (rs)) {
929 			list_walk_collection(report_collection_cb,
930 				(void *)(intptr_t)fd);
931 			/*
932 			 * Replace the existing statistics file with this new
933 			 * one.
934 			 */
935 			res = rename(template, rcfg.rcfg_stat_file);
936 		} else
937 			res = -1;
938 		(void) close(fd);
939 	} else
940 		res = -1;
941 
942 	return (res);
943 }
944 
945 /*
946  * Verify the statistics file can be created and written to, and die if an
947  * existing file may be in use by another rcapd.
948  */
949 static int
950 verify_statistics(void)
951 {
952 	pid_t pid;
953 
954 	/*
955 	 * Warn if another instance of rcapd might be active.
956 	 */
957 	(void) rfd_reserve(1);
958 	pid = stat_get_rcapd_pid(rcfg.rcfg_stat_file);
959 	if (pid != rcapd_pid && pid != -1)
960 		die(gettext("%s exists; rcapd may already be active\n"),
961 		    rcfg.rcfg_stat_file);
962 
963 	return (update_statistics());
964 }
965 
966 static int
967 sum_excess_cb(lcollection_t *lcol, void *arg)
968 {
969 	uint64_t *sum_excess = arg;
970 
971 	*sum_excess += MAX((int64_t)0, (int64_t)(lcol->lcol_rss -
972 	    lcol->lcol_rss_cap));
973 	return (0);
974 }
975 
976 static void
977 rcapd_usage(void)
978 {
979 	info(gettext("usage: rcapd [-d]\n"));
980 }
981 
982 void
983 check_update_statistics(void)
984 {
985 	hrtime_t now = gethrtime();
986 
987 	if (EVENT_TIME(now, next_report)) {
988 		debug("updating statistics...\n");
989 		list_walk_collection(simple_report_collection_cb, NULL);
990 		if (update_statistics() != 0)
991 			debug("couldn't update statistics");
992 		next_report = NEXT_REPORT_EVENT_TIME(now,
993 		    rcfg.rcfg_report_interval);
994 	}
995 }
996 
997 static void
998 verify_and_set_privileges(void)
999 {
1000 	priv_set_t *required =
1001 	    priv_str_to_set("zone,sys_resource,proc_owner", ",", NULL);
1002 
1003 	/*
1004 	 * Ensure the required privileges, suitable for controlling processes,
1005 	 * are possessed.
1006 	 */
1007 	if (setppriv(PRIV_SET, PRIV_PERMITTED, required) != 0 || setppriv(
1008 	    PRIV_SET, PRIV_EFFECTIVE, required) != 0)
1009 		die(gettext("can't set requisite privileges"));
1010 
1011 	/*
1012 	 * Ensure access to /var/run/daemon.
1013 	 */
1014 	if (setreuid(DAEMON_UID, DAEMON_UID) != 0)
1015 		die(gettext("cannot become user daemon"));
1016 
1017 	priv_freeset(required);
1018 }
1019 
1020 int
1021 main(int argc, char *argv[])
1022 {
1023 	int res;
1024 	int should_fork = 1;	/* fork flag */
1025 	hrtime_t now;		/* current time */
1026 	hrtime_t next;		/* time of next event */
1027 	int sig;		/* signal iteration */
1028 	struct rlimit rl;
1029 	hrtime_t next_proc_walk;	/* time of next /proc scan */
1030 	hrtime_t next_configuration;	/* time of next configuration */
1031 	hrtime_t next_rss_sample;	/* (latest) time of next RSS sample */
1032 	int old_enforce_caps;		/* track changes in enforcement */
1033 					/* conditions */
1034 	soft_scan_arg_t arg;
1035 
1036 	(void) set_message_priority(RCM_INFO);
1037 	(void) setprogname("rcapd");
1038 	rcapd_pid = getpid();
1039 	(void) chdir("/");
1040 	should_run = 1;
1041 	ever_ran = 0;
1042 
1043 	(void) setlocale(LC_ALL, "");
1044 	(void) textdomain(TEXT_DOMAIN);
1045 
1046 	/*
1047 	 * Parse command-line options.
1048 	 */
1049 	while ((res = getopt(argc, argv, "dF")) > 0)
1050 		switch (res) {
1051 		case 'd':
1052 			should_fork = 0;
1053 			if (debug_mode == 0) {
1054 				debug_mode = 1;
1055 				(void) set_message_priority(RCM_DEBUG);
1056 			} else
1057 				(void) set_message_priority(RCM_DEBUG_HIGH);
1058 			break;
1059 		case 'F':
1060 			should_fork = 0;
1061 			break;
1062 		default:
1063 			rcapd_usage();
1064 			return (E_USAGE);
1065 			/*NOTREACHED*/
1066 		}
1067 
1068 	/*
1069 	 * If not debugging, fork and continue operating, changing the
1070 	 * destination of messages to syslog().
1071 	 */
1072 	if (should_fork == 1) {
1073 		pid_t child;
1074 		debug("forking\n");
1075 		child = fork();
1076 		if (child == -1)
1077 			die(gettext("cannot fork"));
1078 		if (child > 0)
1079 			return (0);
1080 		else {
1081 			rcapd_pid = getpid();
1082 			(void) set_message_destination(RCD_SYSLOG);
1083 			(void) fclose(stdin);
1084 			(void) fclose(stdout);
1085 			(void) fclose(stderr);
1086 		}
1087 		/*
1088 		 * Start a new session and detatch from the controlling tty.
1089 		 */
1090 		if (setsid() == (pid_t)-1)
1091 			debug(gettext("setsid() failed; cannot detach from "
1092 			    "terminal"));
1093 	}
1094 
1095 	/*
1096 	 * Read the configuration file.
1097 	 */
1098 	if (rcfg_read(RCAPD_DEFAULT_CONF_FILE, -1, &rcfg, verify_statistics)
1099 	    != 0)
1100 		die(gettext("invalid configuration: %s"),
1101 		    RCAPD_DEFAULT_CONF_FILE);
1102 	finish_configuration();
1103 	should_reconfigure = 0;
1104 
1105 	/*
1106 	 * Check that required privileges are possessed.
1107 	 */
1108 	verify_and_set_privileges();
1109 
1110 	now = next_report = next_proc_walk = next_rss_sample = gethrtime();
1111 	next_configuration = NEXT_EVENT_TIME(gethrtime(),
1112 	    rcfg.rcfg_reconfiguration_interval);
1113 
1114 	if (rcfg.rcfg_memory_cap_enforcement_pressure == 0) {
1115 		/*
1116 		 * Always enforce caps when strict caps are used.
1117 		 */
1118 		enforce_caps = 1;
1119 	}
1120 
1121 	/*
1122 	 * Open the kstat chain.
1123 	 */
1124 	kctl = kstat_open();
1125 	if (kctl == NULL)
1126 		die(gettext("can't open kstats"));
1127 
1128 	/*
1129 	 * Set RLIMIT_NOFILE as high as practical, so roughly 10K processes can
1130 	 * be effectively managed without revoking descriptors (at 3 per
1131 	 * process).
1132 	 */
1133 	rl.rlim_cur = 32 * 1024;
1134 	rl.rlim_max = 32 * 1024;
1135 	if (setrlimit(RLIMIT_NOFILE, &rl) != 0 &&
1136 	    getrlimit(RLIMIT_NOFILE, &rl) == 0) {
1137 		rl.rlim_cur = rl.rlim_max;
1138 		(void) setrlimit(RLIMIT_NOFILE, &rl);
1139 	}
1140 	if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
1141 		debug("fd limit: %lu\n", rl.rlim_cur);
1142 	else
1143 		debug("fd limit: unknown\n");
1144 
1145 	/*
1146 	 * Handle those signals whose (default) exit disposition
1147 	 * prevents rcapd from finishing scanning before terminating.
1148 	 */
1149 	(void) sigset(SIGINT, terminate_signal);
1150 	(void) sigset(SIGQUIT, abort_signal);
1151 	(void) sigset(SIGILL, abort_signal);
1152 	(void) sigset(SIGEMT, abort_signal);
1153 	(void) sigset(SIGFPE, abort_signal);
1154 	(void) sigset(SIGBUS, abort_signal);
1155 	(void) sigset(SIGSEGV, abort_signal);
1156 	(void) sigset(SIGSYS, abort_signal);
1157 	(void) sigset(SIGPIPE, terminate_signal);
1158 	(void) sigset(SIGALRM, terminate_signal);
1159 	(void) sigset(SIGTERM, terminate_signal);
1160 	(void) sigset(SIGUSR1, terminate_signal);
1161 	(void) sigset(SIGUSR2, terminate_signal);
1162 	(void) sigset(SIGPOLL, terminate_signal);
1163 	(void) sigset(SIGVTALRM, terminate_signal);
1164 	(void) sigset(SIGXCPU, abort_signal);
1165 	(void) sigset(SIGXFSZ, abort_signal);
1166 	for (sig = SIGRTMIN; sig <= SIGRTMAX; sig++)
1167 		(void) sigset(sig, terminate_signal);
1168 
1169 	/*
1170 	 * Install a signal handler for reconfiguration processing.
1171 	 */
1172 	(void) sigset(SIGHUP, sighup);
1173 
1174 	/*
1175 	 * Determine which process collections to cap.
1176 	 */
1177 	lcollection_update(LCU_COMPLETE);
1178 
1179 	/*
1180 	 * Loop forever, monitoring collections' resident set sizes and
1181 	 * enforcing their caps.  Look for changes in caps and process
1182 	 * membership, as well as responding to requests to reread the
1183 	 * configuration.  Update per-collection statistics periodically.
1184 	 */
1185 	while (should_run != 0) {
1186 		struct timespec ts;
1187 
1188 		/*
1189 		 * Announce that rcapd is starting.
1190 		 */
1191 		if (ever_ran == 0) {
1192 			info(gettext("starting\n"));
1193 			ever_ran = 1;
1194 		}
1195 
1196 		/*
1197 		 * Update the process list once every proc_walk_interval.  The
1198 		 * condition of global memory pressure is also checked at the
1199 		 * same frequency, if strict caps are in use.
1200 		 */
1201 		now = gethrtime();
1202 
1203 		/*
1204 		 * Detect configuration and cap changes at every
1205 		 * reconfiguration_interval, or when SIGHUP has been received.
1206 		 */
1207 		if (EVENT_TIME(now, next_configuration) ||
1208 		    should_reconfigure == 1) {
1209 			reconfigure();
1210 			next_configuration = NEXT_EVENT_TIME(now,
1211 			    rcfg.rcfg_reconfiguration_interval);
1212 
1213 			/*
1214 			 * Reset each event time to the shorter of the
1215 			 * previous and new intervals.
1216 			 */
1217 			if (next_report == 0 &&
1218 			    rcfg.rcfg_report_interval > 0)
1219 				next_report = now;
1220 			else
1221 				next_report = POSITIVE_MIN(next_report,
1222 				    NEXT_REPORT_EVENT_TIME(now,
1223 				    rcfg.rcfg_report_interval));
1224 			if (next_proc_walk == 0 &&
1225 			    rcfg.rcfg_proc_walk_interval > 0)
1226 				next_proc_walk = now;
1227 			else
1228 				next_proc_walk = POSITIVE_MIN(next_proc_walk,
1229 				    NEXT_EVENT_TIME(now,
1230 				    rcfg.rcfg_proc_walk_interval));
1231 			if (next_rss_sample == 0 &&
1232 			    rcfg.rcfg_rss_sample_interval > 0)
1233 				next_rss_sample = now;
1234 			else
1235 				next_rss_sample = POSITIVE_MIN(next_rss_sample,
1236 				    NEXT_EVENT_TIME(now,
1237 				    rcfg.rcfg_rss_sample_interval));
1238 
1239 			should_reconfigure = 0;
1240 			continue;
1241 		}
1242 
1243 		if (EVENT_TIME(now, next_proc_walk)) {
1244 			debug("scanning process list...\n");
1245 			proc_walk_all(proc_cb); /* mark */
1246 			list_walk_all(sweep_process_cb);
1247 			next_proc_walk = NEXT_EVENT_TIME(now,
1248 			    rcfg.rcfg_proc_walk_interval);
1249 		}
1250 
1251 		if (EVENT_TIME(now, next_rss_sample)) {
1252 			/*
1253 			 * Check for changes to the amount of installed
1254 			 * physical memory, to compute the current memory
1255 			 * pressure.
1256 			 */
1257 			update_phys_total();
1258 
1259 			/*
1260 			 * If soft caps are in use, determine if global memory
1261 			 * pressure exceeds the configured maximum above which
1262 			 * soft caps are enforced.
1263 			 */
1264 			memory_pressure = 100 -
1265 			    (int)((sysconf(_SC_AVPHYS_PAGES) *
1266 			    (sysconf(_SC_PAGESIZE) / 1024)) * 100.0 /
1267 			    phys_total);
1268 			memory_pressure_sample++;
1269 			if (rcfg.rcfg_memory_cap_enforcement_pressure > 0) {
1270 				if (memory_pressure >
1271 				    rcfg.rcfg_memory_cap_enforcement_pressure) {
1272 					if (enforce_soft_caps == 0) {
1273 						debug("memory pressure %d%%\n",
1274 						    memory_pressure);
1275 						enforce_soft_caps = 1;
1276 					}
1277 				} else {
1278 					if (enforce_soft_caps == 1)
1279 						enforce_soft_caps = 0;
1280 				}
1281 			}
1282 
1283 			/*
1284 			 * Determine if the global page scanner is running,
1285 			 * while which no memory caps should be enforced, to
1286 			 * prevent interference with the global page scanner.
1287 			 */
1288 			if (get_globally_scanned_pages(&new_sp) == 0) {
1289 				if (old_sp == 0)
1290 					/*EMPTY*/
1291 					;
1292 				else if ((new_sp - old_sp) > 0) {
1293 					if (global_scanner_running == 0) {
1294 						debug("global memory pressure "
1295 						    "detected (%llu pages "
1296 						    "scanned since last "
1297 						    "interval)\n",
1298 						    (unsigned long long)
1299 						    (new_sp - old_sp));
1300 						global_scanner_running = 1;
1301 					}
1302 				} else if (global_scanner_running == 1) {
1303 					debug("global memory pressure "
1304 					    "relieved\n");
1305 					global_scanner_running = 0;
1306 				}
1307 				old_sp = new_sp;
1308 			} else {
1309 				warn(gettext("kstat_read() failed"));
1310 				new_sp = old_sp;
1311 			}
1312 
1313 			/*
1314 			 * Cap enforcement is determined by the previous two
1315 			 * conditions.
1316 			 */
1317 			old_enforce_caps = enforce_caps;
1318 			enforce_caps =
1319 			    (rcfg.rcfg_memory_cap_enforcement_pressure ==
1320 			    0 || enforce_soft_caps == 1) &&
1321 			    !global_scanner_running;
1322 			if (old_enforce_caps != enforce_caps)
1323 				debug("%senforcing caps\n", enforce_caps == 0 ?
1324 				    "not " : "");
1325 
1326 			/*
1327 			 * Sample collections' member processes' RSSes and
1328 			 * recompute collections' excess.
1329 			 */
1330 			list_walk_all(mem_sample_cb);
1331 			list_walk_collection(collection_zero_mem_cb, NULL);
1332 			list_walk_all(memory_all_cb);
1333 			list_walk_collection(rss_sample_col_cb, NULL);
1334 			if (rcfg.rcfg_memory_cap_enforcement_pressure > 0)
1335 				debug("memory pressure %d%%\n",
1336 				    memory_pressure);
1337 			list_walk_collection(excess_print_cb, NULL);
1338 
1339 			/*
1340 			 * If soft caps are in use, determine the size of the
1341 			 * portion from each collection to scan for.
1342 			 */
1343 			if (enforce_soft_caps == 1) {
1344 				/*
1345 				 * Compute the sum of the collections'
1346 				 * excesses, which will be the denominator.
1347 				 */
1348 				arg.ssa_sum_excess = 0;
1349 				list_walk_collection(sum_excess_cb,
1350 				    &arg.ssa_sum_excess);
1351 
1352 				/*
1353 				 * Compute the quantity of memory (in
1354 				 * kilobytes) above the cap enforcement
1355 				 * pressure.  Set the scan goal to that
1356 				 * quantity (or at most the excess).
1357 				 */
1358 				arg.ssa_scan_goal = MIN((
1359 				    sysconf(_SC_PHYS_PAGES) * (100 -
1360 				    rcfg.rcfg_memory_cap_enforcement_pressure)
1361 				    / 100 - sysconf(_SC_AVPHYS_PAGES)) *
1362 				    (sysconf(_SC_PAGESIZE) / 1024),
1363 				    arg.ssa_sum_excess);
1364 			}
1365 
1366 			/*
1367 			 * Victimize offending collections.
1368 			 */
1369 			if (enforce_caps == 1 && ((enforce_soft_caps == 1 &&
1370 			    arg.ssa_scan_goal > 0 && arg.ssa_sum_excess > 0) ||
1371 			    (enforce_soft_caps == 0)))
1372 				if (enforce_soft_caps == 1) {
1373 					debug("scan goal is %lldKB\n",
1374 					    (long long)arg.ssa_scan_goal);
1375 					list_walk_collection(soft_scan_cb,
1376 					    &arg);
1377 				} else
1378 					list_walk_collection(scan_cb, NULL);
1379 			else
1380 				list_walk_collection(unenforced_cap_cb, NULL);
1381 
1382 			next_rss_sample = NEXT_EVENT_TIME(now,
1383 			    rcfg.rcfg_rss_sample_interval);
1384 		}
1385 
1386 		/*
1387 		 * Update the statistics file, if it's time.
1388 		 */
1389 		check_update_statistics();
1390 
1391 		/*
1392 		 * Sleep for some time before repeating.
1393 		 */
1394 		now = gethrtime();
1395 		next = next_configuration;
1396 		next = POSITIVE_MIN(next, next_proc_walk);
1397 		next = POSITIVE_MIN(next, next_report);
1398 		next = POSITIVE_MIN(next, next_rss_sample);
1399 		if (next > now && should_run != 0) {
1400 			debug("sleeping %-4.2f seconds\n", (float)(next -
1401 			    now) / (float)NANOSEC);
1402 			hrt2ts(next - now, &ts);
1403 			(void) nanosleep(&ts, NULL);
1404 		}
1405 	}
1406 	if (termination_signal != 0)
1407 		debug("exiting due to signal %d\n", termination_signal);
1408 	if (ever_ran != 0)
1409 		info(gettext("exiting\n"));
1410 
1411 	/*
1412 	 * Unlink the statistics file before exiting.
1413 	 */
1414 	if (rcfg.rcfg_stat_file[0] != 0)
1415 		(void) unlink(rcfg.rcfg_stat_file);
1416 
1417 	return (E_SUCCESS);
1418 }
1419