1 /*-
2  * Copyright (c) 2003 Andrey Simonenko
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include "config.h"
28 
29 #ifndef lint
30 static const char rcsid[] ATTR_UNUSED =
31   "@(#)$Id: ipa_limits.c,v 1.2 2011/01/23 18:42:34 simon Exp $";
32 #endif /* !lint */
33 
34 #include <sys/types.h>
35 
36 #include <errno.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <time.h>
41 
42 #include "ipa_mod.h"
43 
44 #include "queue.h"
45 
46 #include "dlapi.h"
47 #include "confcommon.h"
48 #include "memfunc.h"
49 #include "parser.h"
50 
51 #include "ipa_ac.h"
52 #include "ipa_db.h"
53 #include "ipa_ctl.h"
54 #include "ipa_cmd.h"
55 #include "ipa_time.h"
56 
57 #include "ipa_conf.h"
58 #include "ipa_log.h"
59 #include "ipa_main.h"
60 #include "ipa_rules.h"
61 #include "ipa_autorules.h"
62 
63 unsigned int	nstatlimits;		/* Number of static limits. */
64 unsigned int	ndynlimits;		/* Number of dynamic limits. */
65 
66 unsigned int	nstatsublimits;		/* Number of static sublimits. */
67 unsigned int	ndynsublimits;		/* Number of dynamic sublimits. */
68 
69 #ifdef WITH_LIMITS
70 
71 signed char	global_debug_limit;	/* global { debug_limit } */
72 signed char	global_debug_limit_init;/* global { debug_limit_init } */
73 signed char	global_load_limit;	/* global { load_limit } */
74 
75 ipa_mzone	*limit_mzone;		/* Mzone for all struct limit{}. */
76 
77 #ifdef WITH_SUBLIMITS
78 ipa_mzone	*sublimit_mzone;	/* Mzone for all struct sublimit{}. */
79 #endif
80 
81 #define set_limit_active(r, l)	mod_set_limit_active((r), (l), 1)
82 
83 const char *const limit_event_msg[] = {
84 	"START",			/*  0 */
85 	"RESTART",			/*  1 */
86 	"RESTART_EXEC",			/*  2 */
87 	"REACH",			/*  3 */
88 	"REACH_EXEC",			/*  4 */
89 	"EXPIRE",			/*  5 */
90 	"EXPIRE_EXEC",			/*  6 */
91 	"UPDATED",			/*  7 */
92 	"STARTUP_IF_REACHED",		/*  8 */
93 	"STARTUP_IF_NOT_REACHED",	/*  9 */
94 	"SHUTDOWN_IF_REACHED",		/* 10 */
95 	"SHUTDOWN_IF_NOT_REACHED"	/* 11 */
96 };
97 
98 #define event_msg limit_event_msg
99 #define EVENT(x) IPA_LIMIT_EVENT_ ## x
100 
101 /*
102  * Set limit active or inactive in modules it uses.
103  */
104 int
mod_set_limit_active(const struct rule * rule,struct limit * limit,int active)105 mod_set_limit_active(const struct rule *rule, struct limit *limit, int active)
106 {
107 	if ((limit->lim_flags & LIMIT_FLAG_ACTIVE) ==
108 	    (active ? LIMIT_FLAG_ACTIVE : 0)) {
109 		logmsgx(IPA_LOG_ERR, "internal error: "
110 		    "mod_set_limit_active(%s, %s, %d): limit is already %s",
111 		    rule->name, limit->name, active, active_msg[active]);
112 		return (-1);
113 	}
114 
115 	if (debug_worktime)
116 		logdbg("rule %s, limit %s: set limit %s",
117 		    rule->name, limit->name, active_msg[active]);
118 
119 	if (active)
120 		LIMIT_SET_ACTIVE(limit);
121 	else
122 		LIMIT_SET_INACTIVE(limit);
123 
124 	if (ac_set_limit_active(rule, limit, active) < 0)
125 		goto failed;
126 	if (db_set_limit_active(rule, limit, active) < 0)
127 		goto failed;
128 
129 	return (0);
130 
131 failed:
132 	logbt("mod_set_limit_active");
133 	return (-1);
134 }
135 
136 /*
137  * Set limit->event_sec from limit->event_tm.
138  */
139 void
limit_set_event_sec(struct limit * limit)140 limit_set_event_sec(struct limit *limit)
141 {
142 	const ipa_tm *tm;
143 
144 	tm = &limit->event_tm;
145 	if (cmp_ipa_tm(tm, &curdate) > 0) {
146 		if (tm->tm_year == curdate.tm_year &&
147 		    tm->tm_mon == curdate.tm_mon &&
148 		    tm->tm_mday == curdate.tm_mday)
149 			limit->event_sec = TIME_TO_SEC(tm);
150 		else
151 			limit->event_sec = EVENT_NOT_SCHEDULED;
152 	} else
153 		limit->event_sec = cursec;
154 }
155 
156 /*
157  * Add chunk to one limit, if positive counter overflows, then
158  * return -1, since this means incorrect configuration.
159  */
160 int
limit_add_chunk(const struct rule * rule,struct limit * limit,const uint64_t * chunk_ptr)161 limit_add_chunk(const struct rule *rule, struct limit *limit,
162     const uint64_t *chunk_ptr)
163 {
164 	uint64_t chunk;
165 
166 	chunk = *chunk_ptr;
167 	if (limit->cnt_neg >= chunk)
168 		limit->cnt_neg -= chunk;
169 	else {
170 		chunk -= limit->cnt_neg;
171 		if (limit->cnt > UINT64_MAX - chunk) {
172 			logmsgx(IPA_LOG_ERR, "rule %s, limit %s: "
173 			    "limit_add_chunk: positive counter overflowed",
174 			    rule->name, limit->name);
175 			logmsgx(IPA_LOG_ERR, "this means that something is "
176 			    "wrong in configuration");
177 			return (-1);
178 		}
179 		limit->cnt += chunk;
180 		limit->cnt_neg = 0;
181 	}
182 	return (0);
183 }
184 
185 /*
186  * Add chunk to every not reached and active rule's limit.
187  */
188 int
limits_add_chunk(const struct rule * rule,const uint64_t * chunk_ptr)189 limits_add_chunk(const struct rule *rule, const uint64_t *chunk_ptr)
190 {
191 	struct limit *limit;
192 
193 	STAILQ_FOREACH(limit, &rule->limits, link)
194 		if (LIMIT_IS_NOTREACHED(limit) && LIMIT_IS_ACTIVE(limit))
195 			if (limit_add_chunk(rule, limit, chunk_ptr) < 0) {
196 				logbt("limits_add_chunk");
197 				return (-1);
198 			}
199 	return (0);
200 }
201 
202 /*
203  * Subtract chunk from one limit, if negative counter overflows, then
204  * return -1, since this means incorrect configuration.
205  */
206 int
limit_sub_chunk(const struct rule * rule,struct limit * limit,const uint64_t * chunk_ptr)207 limit_sub_chunk(const struct rule *rule, struct limit *limit,
208     const uint64_t *chunk_ptr)
209 {
210 	uint64_t chunk;
211 
212 	chunk = *chunk_ptr;
213 	if (limit->cnt >= chunk)
214 		limit->cnt -= chunk;
215 	else {
216 		chunk -= limit->cnt;
217 		if (limit->cnt_neg > UINT64_MAX - chunk) {
218 			logmsgx(IPA_LOG_ERR, "rule %s, limit %s: "
219 			    "limit_sub_chunk: negative counter overflowed",
220 			    rule->name, limit->name);
221 			logmsgx(IPA_LOG_ERR, "this means that something is "
222 			    "wrong in configuration");
223 			return (-1);
224 		}
225 		limit->cnt_neg += chunk;
226 		limit->cnt = 0;
227 	}
228 	return (0);
229 }
230 
231 /*
232  * Subtract chunk from every not reached and active rule's limit.
233  */
234 int
limits_sub_chunk(const struct rule * rule,const uint64_t * chunk_ptr)235 limits_sub_chunk(const struct rule *rule, const uint64_t *chunk_ptr)
236 {
237 	struct limit *limit;
238 
239 	STAILQ_FOREACH(limit, &rule->limits, link)
240 		if (LIMIT_IS_NOTREACHED(limit) && LIMIT_IS_ACTIVE(limit))
241 			if (limit_sub_chunk(rule, limit, chunk_ptr) < 0) {
242 				logbt("limits_sub_chunk");
243 				return (-1);
244 			}
245 	return (0);
246 }
247 
248 /*
249  * Register a new state for the limit.
250  */
251 static int
new_limit_state(const struct rule * rule,struct limit * limit)252 new_limit_state(const struct rule *rule, struct limit *limit)
253 {
254 	struct ipa_limit_state nstat;
255 	ipa_tm event_tm;
256 #ifdef WITH_SUBLIMITS
257 	struct sublimit *sublimit;
258 #endif
259 
260 	if (rule->debug_limit_init || rule->debug_limit)
261 		logdbg("rule %s, limit %s: register new limit state",
262 		    rule->name, limit->name);
263 
264 	event_tm = curdate;
265 	/* This function can be called at 24:00:00. */
266 	if (newday_flag)
267 		fix_240000(&event_tm);
268 
269 	/* Set limit status as not reached. */
270 	LIMIT_SET_NOTREACHED(limit);
271 
272 	nstat.lim = limit->lim;
273 
274 	/* Flush limit's counter. */
275 	nstat.cnt = limit->cnt = 0;
276 
277 	nstat.event_date_set = EVENT(START_SET);
278 	nstat.event_date[EVENT(START)] = curdate;
279 
280 	if (limit->restart.restart.upto != TEXP_UPTO_NOTSET) {
281 		limit->event_tm = event_tm;
282 		ipa_tm_texp(&limit->event_tm, &limit->restart.restart);
283 		nstat.event_date_set |= EVENT(RESTART_SET);
284 		nstat.event_date[EVENT(RESTART)] = limit->event_tm;
285 		limit_set_event_sec(limit);
286 		if (rule->debug_limit || rule->debug_limit_init)
287 			logdbg("rule %s, limit %s: limit will be restarted "
288 			    "at %s", rule->name, limit->name,
289 			    tm_str(&limit->event_tm));
290 	} else
291 		limit->event_sec = EVENT_NOT_SCHEDULED;
292 
293 #ifdef WITH_SUBLIMITS
294 	STAILQ_FOREACH(sublimit, &limit->sublimits, link)
295 		SUBLIMIT_SET_NOTREACHED(sublimit);
296 #endif
297 
298 	if (db_set_limit_state(rule, limit, &nstat, 1) < 0) {
299 		logbt("new_limit_state");
300 		return (-1);
301 	}
302 	return (0);
303 }
304 
305 /*
306  * Check that a limit is not busy and make it busy.
307  */
308 static int
make_limit_busy(const struct rule * rule,struct limit * limit)309 make_limit_busy(const struct rule *rule, struct limit *limit)
310 {
311 	if (LIMIT_IS_BUSY(limit)) {
312 		logmsgx(IPA_LOG_ERR, "rule %s, limit %s: limit is busy, "
313 		    "wrong configuration of ictl commands",
314 		    rule->name, limit->name);
315 		return (-1);
316 	}
317 	LIMIT_SET_BUSY(limit);
318 	return (0);
319 }
320 
321 /*
322  * Restart a limit.
323  */
324 int
restart_limit(const struct rule * rule,struct limit * limit)325 restart_limit(const struct rule *rule, struct limit *limit)
326 {
327 	if (make_limit_busy(rule, limit) < 0)
328 		goto failed;
329 
330 	if (rule->debug_limit)
331 		logdbg("rule %s, limit %s: restart_limit: restart limit",
332 		    rule->name, limit->name);
333 
334 	if (limit->restart.cmds.has_cmd) {
335 		/* restart { exec } */
336 		if (run_cmds(rule, &limit->wpid, &limit->restart.cmds,
337 		    "rule %s { limit %s { restart {}}}", rule->name,
338 		    limit->name) < 0)
339 			goto failed;
340 		if (db_limit_event(rule, limit, EVENT(RESTART_EXEC),
341 		    &curdate) < 0)
342 			goto failed;
343 	}
344 
345 	if (ac_limit_event(rule, limit, EVENT(RESTART)) < 0)
346 		goto failed;
347 
348 	if (new_limit_state(rule, limit) < 0)
349 		goto failed;
350 
351 	LIMIT_SET_UNBUSY(limit);
352 	return (0);
353 
354 failed:
355 	logbt("restart_limit");
356 	return (-1);
357 }
358 
359 /*
360  * Expire a limit.
361  */
362 int
expire_limit(const struct rule * rule,struct limit * limit)363 expire_limit(const struct rule *rule, struct limit *limit)
364 {
365 	if (make_limit_busy(rule, limit) < 0)
366 		goto failed;
367 
368 	if (rule->debug_limit)
369 		logdbg("rule %s, limit %s: limit expired",
370 		    rule->name, limit->name);
371 
372 	if (limit->expire.cmds.has_cmd) {
373 		/* expire { exec } */
374 		if (run_cmds(rule, &limit->wpid, &limit->expire.cmds,
375 		    "rule %s { limit %s { expire {}}}", rule->name,
376 		    limit->name) < 0)
377 			goto failed;
378 		if (db_limit_event(rule, limit, EVENT(EXPIRE_EXEC),
379 		    &curdate) < 0)
380 			goto failed;
381 	}
382 
383 	if (ac_limit_event(rule, limit, EVENT(EXPIRE)) < 0)
384 		goto failed;
385 
386 	if (new_limit_state(rule, limit) < 0)
387 		goto failed;
388 
389 	LIMIT_SET_UNBUSY(limit);
390 
391 	if (limit->lim == 0) {
392 		/* Such limit is always reached. */
393 		if (reach_limit(rule, limit) < 0)
394 			goto failed;
395 	}
396 
397 	return (0);
398 
399 failed:
400 	logbt("expire_limit");
401 	return (-1);
402 }
403 
404 /*
405  * A limit is reached.
406  */
407 int
reach_limit(const struct rule * rule,struct limit * limit)408 reach_limit(const struct rule *rule, struct limit *limit)
409 {
410 	ipa_tm event_tm;
411 
412 	if (make_limit_busy(rule, limit) < 0)
413 		goto failed;
414 
415 	/* This function can be called at 24:00:00. */
416 	event_tm = curdate;
417 	if (newday_flag)
418 		fix_240000(&event_tm);
419 
420 	if (rule->debug_limit)
421 		logdbg("rule %s, limit %s: limit reached, cnt %"PRIu64,
422 		    rule->name, limit->name, limit->cnt);
423 
424 	/* Set limit status as reached. */
425 	LIMIT_SET_REACHED(limit);
426 
427 	if (db_limit_event(rule, limit, EVENT(REACH), &curdate) < 0)
428 		goto failed;
429 	if (limit->reach.has_cmd) {
430 		/* reach { exec } */
431 		if (run_cmds(rule, &limit->wpid, &limit->reach,
432 		    "rule %s { limit %s { reach {}}}", rule->name,
433 		    limit->name) < 0)
434 			goto failed;
435 		if (db_limit_event(rule, limit, EVENT(REACH_EXEC),
436 		    &curdate) < 0)
437 			goto failed;
438 	}
439 	if (ac_limit_event(rule, limit, EVENT(REACH)) < 0)
440 		goto failed;
441 
442 	LIMIT_SET_UNBUSY(limit);
443 
444 	if (limit->expire.expire.upto != TEXP_UPTO_NOTSET) {
445 		/* limit { expire } */
446 		limit->event_tm = event_tm;
447 		ipa_tm_texp(&limit->event_tm, &limit->expire.expire);
448 		limit_set_event_sec(limit);
449 		if (rule->debug_limit)
450 			logdbg("rule %s, limit %s: limit will expire at %s",
451 			    rule->name, limit->name, tm_str(&limit->event_tm));
452 		if (db_limit_event(rule, limit, EVENT(EXPIRE),
453 		    &limit->event_tm) < 0)
454 			goto failed;
455 		if (limit->event_sec == cursec) {
456 			/* expire == 0s */
457 			if (expire_limit(rule, limit) < 0)
458 				goto failed;
459 		}
460 	} else
461 		limit->event_sec = EVENT_NOT_SCHEDULED;
462 
463 	return (0);
464 
465 failed:
466 	logbt("reach_limit");
467 	return (-1);
468 }
469 
470 #ifdef WITH_SUBLIMITS
471 struct sublimit *
sublimit_by_name(const struct limit * limit,const char * name)472 sublimit_by_name(const struct limit *limit, const char *name)
473 {
474 	struct sublimit *sublimit;
475 
476 	STAILQ_FOREACH(sublimit, &limit->sublimits, link)
477 		if (strcmp(sublimit->name, name) == 0)
478 			break;
479 	return (sublimit);
480 }
481 
482 /*
483  * A sublimit is reached.
484  */
485 int
reach_sublimit(const struct rule * rule,const struct limit * limit,struct sublimit * sublimit)486 reach_sublimit(const struct rule *rule, const struct limit *limit,
487     struct sublimit *sublimit)
488 {
489 	if (rule->debug_limit)
490 		logdbg("rule %s, limit %s, sublimit %s: sublimit reached, "
491 		    "cnt %"PRIu64, rule->name, limit->name, sublimit->name,
492 		    limit->cnt);
493 
494 	SUBLIMIT_SET_REACHED(sublimit);
495 	if (sublimit->reach.has_cmd) {
496 		/* reach { exec } */
497 		if (run_cmds(rule, &sublimit->wpid, &sublimit->reach,
498 		    "rule %s { limit %s { sublimit %s { reach {}}}}",
499 		    rule->name, limit->name, sublimit->name) < 0) {
500 			logbt("reach_sublimit");
501 			return (-1);
502 		}
503 	}
504 
505 	return (0);
506 }
507 
508 /*
509  * Check for limit's sublimits events.
510  */
511 static int
check_sublimits_events(const struct rule * rule,const struct limit * limit)512 check_sublimits_events(const struct rule *rule, const struct limit *limit)
513 {
514 	struct sublimit	*sublimit;
515 
516 	STAILQ_FOREACH(sublimit, &limit->sublimits, link) {
517 		if (SUBLIMIT_IS_REACHED(sublimit))
518 			continue;
519 		/* Sublimit is not reached. */
520 		if (limit->cnt >= sublimit->lim) {
521 			/* Sublimit has just been reached. */
522 			if (reach_sublimit(rule, limit, sublimit) < 0) {
523 				logbt("check_sublimits_events");
524 				return (-1);
525 			}
526 		}
527 	}
528 	return (0);
529 }
530 #endif /* WITH_SUBLIMITS */
531 
532 /*
533  * Check for rule's limits events.
534  */
535 int
check_limits(const struct rule * rule,unsigned int * check_sec_ptr)536 check_limits(const struct rule *rule, unsigned int *check_sec_ptr)
537 {
538 	const struct worktime *wt;
539 	struct limit *limit;
540 	unsigned int check_sec, d;
541 
542 	check_sec = EVENT_NOT_SCHEDULED;
543 
544 	STAILQ_FOREACH(limit, &rule->limits, link) {
545 		wt = limit->worktime;
546 		if (LIMIT_IS_INACTIVE(limit)) {
547 			/* Limit is inactive. */
548 			if (wt->active_sec <= cursec) {
549 				/* It's time to make limit active. */
550 				if (set_limit_active(rule, limit) < 0)
551 					goto failed;
552 			} else {
553 				if (check_sec > wt->active_sec)
554 					check_sec = wt->active_sec;
555 				continue; /* do not check any time events. */
556 			}
557 		}
558 
559 		/* Here limit is active. */
560 		if (LIMIT_IS_REACHED(limit)) {
561 			/* Limit has been reached already. */
562 			if (limit->event_sec <= cursec) {
563 				/* { expire } and it's time to expire limit. */
564 				d = ipa_tm_diff(&curdate, &limit->event_tm);
565 				if (d > sensitive_time)
566 					logmsgx(IPA_LOG_WARNING, "rule %s, "
567 					    "limit %s: expire limit too late: "
568 					    "delta %s is greater than "
569 					    "\"sensitive_time\" %u seconds",
570 					    rule->name, limit->name,
571 					    time_str(d), sensitive_time);
572 				if (expire_limit(rule, limit) < 0)
573 					goto failed;
574 			}
575 		} else {
576 			/* Limit is not reached. */
577 			if (db_update_limit(rule, limit) < 0)
578 				goto failed;
579 #ifdef WITH_SUBLIMITS
580 			if (check_sublimits_events(rule, limit) < 0)
581 				goto failed;
582 #endif
583 			if (limit->cnt >= limit->lim) {
584 				/* Limit has just been reached. */
585 				if (reach_limit(rule, limit) < 0)
586 					goto failed;
587 			} else if (limit->event_sec <= cursec) {
588 				/* { restart } and it's time to restart. */
589 				d = ipa_tm_diff(&curdate, &limit->event_tm);
590 				if (d > sensitive_time)
591 					logmsgx(IPA_LOG_WARNING, "rule %s, "
592 					    "limit %s: restart limit too late: "
593 					    "delta %s is greater than "
594 					    "\"sensitive_time\" %u seconds",
595 					    rule->name, limit->name,
596 					    time_str(d), sensitive_time);
597 				if (restart_limit(rule, limit) < 0)
598 					goto failed;
599 			}
600 		}
601 
602 		if (WT_IS_INACTIVE(wt)) {
603 			/* Limit became inactive. */
604 			if (!newday_flag) {
605 				if (set_limit_inactive(rule, limit) < 0)
606 					goto failed;
607 				if (check_sec > wt->active_sec)
608 					check_sec = wt->active_sec;
609 			}
610 		} else {
611 			/* Limit is still active. */
612 			if (check_sec > wt->inactive_sec)
613 				check_sec = wt->inactive_sec;
614 			if (check_sec > limit->event_sec)
615 				check_sec = limit->event_sec;
616 		}
617 	}
618 
619 	*check_sec_ptr = check_sec;
620 	return (0);
621 
622 failed:
623 	logbt("check_limits");
624 	return (-1);
625 }
626 
627 /*
628  * Initialize one limit.
629  */
630 static int
init_limit(const struct rule * rule,struct limit * limit)631 init_limit(const struct rule *rule, struct limit *limit)
632 {
633 	struct ipa_limit_state ostat, nstat;
634 	ipa_tm tm;
635 	const char *rule_name, *limit_name;
636 	unsigned int bit, i;
637 	signed char debug_limit_init;
638 	char error;
639 
640 	/*
641 	 * If init_limit() is called second, third... time,
642 	 * then limit can be inactive.
643 	 */
644 	if (LIMIT_IS_INACTIVE(limit))
645 		if (set_limit_active(rule, limit) < 0)
646 			goto failed;
647 
648 	rule_name = rule->name;
649 	limit_name = limit->name;
650 	limit->cnt_neg = 0;
651 	limit->wpid.debug_exec = rule->debug_exec;
652 	debug_limit_init = rule->debug_limit_init;
653 
654 	if (STAILQ_EMPTY(limit->db_list)) {
655 		/* "null" database is used. */
656 		if (LIMIT_IS_INITED(limit)) {
657 			/* Imitate that old state is known. */
658 			ostat.lim = limit->lim;
659 			ostat.cnt = limit->cnt;
660 			ostat.event_date_set = limit->event_date_set;
661 			memcpy(ostat.event_date, limit->event_date,
662 			    sizeof(ostat.event_date));
663 			if (debug_limit_init)
664 				logdbg("rule %s, limit %s: init_limit: "
665 				    "continue to use previous limit state",
666 				    rule_name, limit_name);
667 		} else {
668 			if (debug_limit_init)
669 				logdbg("rule %s, limit %s: init_limit: "
670 				    "create limit with no database",
671 				    rule_name, limit_name);
672 			goto new_state;
673 		}
674 	} else {
675 		const char *db_name;
676 		int rv;
677 
678 		/* Get limit state from databases. */
679 		rv = db_get_limit_state(rule, limit, &ostat, &db_name);
680 		if (rv < 0)
681 			goto failed;
682 		if (db_name == NULL) {
683 			logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
684 			    "init_limit: no database used for this limit "
685 			    "supports db_get_limit_state function",
686 			    rule_name, limit_name);
687 			goto new_state;
688 		}
689 		if (rv > 0) {
690 			if (debug_limit_init)
691 				logdbg("rule %s, limit %s: init_limit: "
692 				    "got state from %s database",
693 				    rule_name, limit_name, db_name);
694 		} else {
695 			if (debug_limit_init)
696 				logdbg("rule %s, limit %s: init_limit: "
697 				    "database %s does not have limit state, "
698 				    "(a new limit)", rule_name, limit_name,
699 				    db_name);
700 			goto new_state;
701 		}
702 	}
703 
704 	/* Check and initialize "limit" parameter. */
705 	if (debug_limit_init && limit->lim != ostat.lim) {
706 		logdbg("rule %s, limit %s: init_limit: configuration "
707 		    "limit %"PRIu64", database limit %"PRIu64" (will use %s "
708 		    "value)", rule_name, limit_name, limit->lim, ostat.lim,
709 		    limit->load_limit ? "database" : "configuration");
710 	}
711 	if (limit->load_limit) {
712 		if (ostat.lim == 0 &&
713 		    limit->expire.expire.upto == TEXP_UPTO_SIMPLE &&
714 		    limit->expire.expire.seconds == 0) {
715  			logmsgx(IPA_LOG_ERR, "rule %s, limit %s: init_limit: "
716 			    "loaded \"limit\" parameter is equal to zero "
717 			    "and \"expire\" parameter is equal to 0s",
718 			    rule_name, limit_name);
719 			return (-1);
720 		}
721 		limit->lim = ostat.lim;
722 	}
723 
724 	/* START and UPDATED events must be present. */
725 	if (!(ostat.event_date_set & EVENT(START_SET))) {
726 		logmsgx(IPA_LOG_ERR, "rule %s, limit %s: init_limit: "
727 		    "EVENT_START is absent", rule_name, limit_name);
728 		goto new_state_error;
729 	}
730 	if (!(ostat.event_date_set & EVENT(UPDATED_SET))) {
731 		logmsgx(IPA_LOG_ERR, "rule %s, limit %s: init_limit: "
732 		    "EVENT_UPDATED is absent", rule_name, limit_name);
733 		goto new_state_error;
734 	}
735 
736 	/* RESTART_EXEC and EXPIRE_EXEC mean restarted or expired limit. */
737 	if (ostat.event_date_set & EVENT(RESTART_EXEC_SET)) {
738 		logmsgx(IPA_LOG_ERR, "rule %s, limit %s: init_limit: "
739 		    "limit has EVENT_RESTART_EXEC, this is wrong",
740 		    rule_name, limit_name);
741 		goto new_state_error;
742 	}
743 	if (ostat.event_date_set & EVENT(EXPIRE_EXEC_SET)) {
744 		logmsgx(IPA_LOG_ERR, "rule %s, limit %s: init_limit: "
745 		    "limit has EVENT_EXPIRE_EXEC, this is wrong",
746 		    rule_name, limit_name);
747 		goto new_state_error;
748 	}
749 
750 	/* Set limit status as not reached. */
751 	LIMIT_SET_NOTREACHED(limit);
752 
753 	/* Check START, REACH and UPDATED events. */
754 	error = 0;
755 	for (i = 0, bit = 1; i < IPA_LIMIT_EVENT_NUM; bit <<= 1, ++i) {
756 		if ((ostat.event_date_set & bit) && (i == EVENT(START) ||
757 		    i == EVENT(REACH) || i == EVENT(UPDATED))) {
758 			/* These events could happen at 24:00:00. */
759 			tm = ostat.event_date[i];
760 			fix_240000(&tm);
761 			if (check_ipa_tm(&tm) < 0) {
762 				logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
763 				    "init_limit: wrong value of EVENT_%s: %s",
764 				    rule_name, limit_name, event_msg[i],
765 				    tm_str(&tm));
766 				goto new_state_error;
767 			}
768 			/* Check whether time goes back. */
769 			if (cmp_ipa_tm(&tm, &curdate) > 0) {
770 				error = 1;
771 				logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
772 				    "init_limit: EVENT_%s %s is greater than "
773 				    "current time", rule_name, limit_name,
774 				    event_msg[i], tm_str(&tm));
775 			}
776 		}
777 	}
778 
779 	/*
780 	 * If not reached limit has START event greater than
781 	 * current time, then change START event.
782 	 */
783 	if (error && !(ostat.event_date_set & EVENT(REACH_SET)) &&
784 	    cmp_ipa_tm(&ostat.event_date[EVENT(START]), &curdate) > 0) {
785 		const char *cp;
786 
787 		cp = tm_str(&ostat.event_date[EVENT(START)]);
788 		ostat.event_date[EVENT(START)] = curdate;
789 		logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: init_limit: "
790 		    "start time changed %s -> %s", rule_name, limit_name, cp,
791 		    tm_str2(&ostat.event_date[EVENT(START)]));
792 	}
793 
794 	/* Set start time of limit. */
795 	nstat.event_date_set = EVENT(START_SET);
796 	nstat.event_date[EVENT(START)] = ostat.event_date[EVENT(START)];
797 
798 	if (ostat.cnt < ostat.lim ||
799 	    !(ostat.event_date_set & EVENT(REACH_SET))) {
800 		/*
801 		 * Limit was not reached or was not mark as reached
802 		 * with old "limit" parameter.
803 		 */
804 		nstat.lim = limit->lim;
805 		if (ostat.cnt >= ostat.lim)
806 			logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
807 			    "init_limit: limit was reached in old state, "
808 			    "but EVENT_REACH was not registered",
809 			    rule_name, limit_name);
810 
811 		if (limit->restart.restart.upto != TEXP_UPTO_NOTSET) {
812 			/* The "restart" parameter is used. */
813 			limit->event_tm = ostat.event_date[EVENT(START)];
814 			fix_240000(&limit->event_tm);
815 			if (set_wday(&limit->event_tm) < 0) {
816 				logmsgx(IPA_LOG_ERR, "rule %s, limit %s: "
817 				    "init_limit: set_wday failed", rule_name,
818 				    limit_name);
819 				return (-1);
820 			}
821 			ipa_tm_texp(&limit->event_tm, &limit->restart.restart);
822 			nstat.event_date_set |= EVENT(RESTART_SET);
823 			nstat.event_date[EVENT(RESTART)] = limit->event_tm;
824 			if (!(ostat.event_date_set & EVENT(RESTART_SET)))
825 				logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
826 				    "init_limit: limit has not EVENT_RESTART "
827 				    "in database, but has \"restart\" "
828 				    "parameter", rule_name, limit_name);
829 			else if (cmp_ipa_tm(&limit->event_tm,
830 			    &ostat.event_date[EVENT(RESTART)]) != 0)
831 				logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
832 				    "init_limit: restart time changed %s -> %s",
833 				    rule_name, limit_name,
834 				    tm_str(&ostat.event_date[EVENT(RESTART)]),
835 				    tm_str2(&limit->event_tm));
836 			if (rule->debug_limit || debug_limit_init)
837 				logdbg("rule %s, limit %s: limit will be "
838 				    "restarted at %s", rule_name, limit_name,
839 				    tm_str(&limit->event_tm));
840 		} else {
841 			if (ostat.event_date_set & EVENT(RESTART_SET))
842 				logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
843 				    "init_limit: limit has EVENT_RESTART in "
844 				    "database, but limit has not \"restart\" "
845 				    "parameter: forgot about EVENT_RESTART",
846 				    rule_name, limit_name);
847 			limit->event_sec = EVENT_NOT_SCHEDULED;
848 		}
849 	} else {
850 		/*
851 		 * Limit was reached and marked as reached
852 		 * with old "limit" parameter.
853 		 */
854 		if (ostat.event_date_set & EVENT(RESTART_SET)) {
855 			/*
856 			 * If limit had restart time in previous state,
857 			 * then simply copy it.
858 			 */
859 			nstat.event_date_set |= EVENT(RESTART_SET);
860 			nstat.event_date[EVENT(RESTART)] =
861 			    ostat.event_date[EVENT(RESTART)];
862 		}
863 		nstat.lim = ostat.lim;
864 		LIMIT_SET_REACHED(limit);
865 		nstat.event_date_set |= EVENT(REACH_SET);
866 		nstat.event_date[EVENT(REACH)] = ostat.event_date[EVENT(REACH)];
867 		if (ostat.event_date_set & EVENT(REACH_EXEC_SET)) {
868 			/*
869 			 * If limit run any commands, then save this
870 			 * in the new state.
871 			 */
872 			nstat.event_date_set |= EVENT(REACH_EXEC_SET);
873 			nstat.event_date[EVENT(REACH_EXEC)] =
874 			    ostat.event_date[EVENT(REACH_EXEC)];
875 		}
876 		if (limit->expire.expire.upto != TEXP_UPTO_NOTSET) {
877 			nstat.event_date_set |= EVENT(EXPIRE_SET);
878 			limit->event_tm = nstat.event_date[EVENT(REACH)];
879 			fix_240000(&limit->event_tm);
880 			if (set_wday(&limit->event_tm) < 0) {
881 				logmsgx(IPA_LOG_ERR, "rule %s, limit %s: "
882 				    "init_limit: set_wday failed", rule_name,
883 				    limit_name);
884 				return (-1);
885 			}
886 			ipa_tm_texp(&limit->event_tm, &limit->expire.expire);
887 			nstat.event_date[EVENT(EXPIRE)] = limit->event_tm;
888 			if (!(ostat.event_date_set & EVENT(EXPIRE_SET)))
889 				logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
890 				    "init_limit: limit has not EVENT_EXPIRE in "
891 				    "database, but has \"expire\" parameter",
892 				    rule_name, limit_name);
893 			else if (cmp_ipa_tm(&limit->event_tm,
894 			    &ostat.event_date[EVENT(EXPIRE])) != 0)
895 				logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
896 				    "init_limit: expire time is changed "
897 				    "%s -> %s", rule_name, limit_name,
898 				    tm_str(&ostat.event_date[EVENT(EXPIRE)]),
899 				    tm_str2(&limit->event_tm));
900 			if (rule->debug_limit || debug_limit_init)
901 				logdbg("rule %s, limit %s: reached limit "
902 				    "will expire at %s", rule_name, limit_name,
903 				    tm_str(&limit->event_tm));
904 		} else {
905 			if (ostat.event_date_set & EVENT(EXPIRE_SET))
906 				logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: "
907 				    "init_limit: limit has EVENT_EXPIRE in "
908 				    "database, but limit has not \"expire\" "
909 				    "section in configuration: forgot about "
910 				    "EVENT_EXPIRE", rule_name, limit_name);
911 			limit->event_sec = EVENT_NOT_SCHEDULED;
912 		}
913 	}
914 
915 	/* Copy counter value from the old state. */
916 	limit->cnt = nstat.cnt = ostat.cnt;
917 
918 	if (debug_limit_init) {
919 		logdbg("rule %s, limit %s: init_limit: lim %"PRIu64", "
920 		    "cnt %"PRIu64, rule_name, limit_name, limit->lim,
921 		    limit->cnt);
922 		logdbg("rule %s, limit %s: init_limit: set limit state",
923 		    rule_name, limit_name);
924 	}
925 
926 	if (db_set_limit_state(rule, limit, &nstat, 0) < 0)
927 		goto failed;
928 
929 	LIMIT_SET_INITED(limit);
930 	return (0);
931 
932 new_state_error:
933 	logmsgx(IPA_LOG_WARNING, "rule %s, limit %s: init_limit: set new "
934 	    "limit state, correcting errors found in database",
935 	    rule_name, limit_name);
936 
937 new_state:
938 	if (debug_limit_init)
939 		logdbg("rule %s, limit %s: init_limit: set new limit state",
940 		    rule_name, limit_name);
941 	if (new_limit_state(rule, limit) < 0)
942 		goto failed;
943 	LIMIT_SET_INITED(limit);
944 	return (0);
945 
946 failed:
947 	logbt("init_limit");
948 	return (-1);
949 }
950 
951 #ifdef WITH_SUBLIMITS
952 /*
953  * Initialize all sublimits for one limit.
954  */
955 static void
956 init_sublimits(const struct rule *rule, const struct limit *limit)
957 {
958 	struct sublimit *sublimit;
959 
960 	STAILQ_FOREACH(sublimit, &limit->sublimits, link) {
961 		sublimit->wpid.debug_exec = rule->debug_exec;
962 		if (sublimit->lim_pc != 0)
963 			sublimit->lim = uint64_per_cent(&limit->lim,
964 			    sublimit->lim_pc);
965 		if (sublimit->lim > limit->lim)
966 			logmsgx(IPA_LOG_WARNING, "rule %s, limit %s, "
967 			    "sublimit %s: init_sublimits: sublimit is greater "
968 			    "than limit %"PRIu64, rule->name, limit->name,
969 			    sublimit->name, limit->lim);
970 		/*
971 		 * If limit is reached, then "limit" parameter is
972 		 * not used and sublimit is always reached.
973 		 */
974 		if (LIMIT_IS_REACHED(limit) || limit->cnt >= sublimit->lim)
975 			SUBLIMIT_SET_REACHED(sublimit);
976 		else
977 			SUBLIMIT_SET_NOTREACHED(sublimit);
978 	}
979 }
980 
981 void
982 sublimit_init_cmds(struct sublimit *sublimit)
983 {
984 	cmds_init(&sublimit->reach);
985 	cmds_limit_init(&sublimit->rc[RC_STARTUP]);
986 	cmds_limit_init(&sublimit->rc[RC_SHUTDOWN]);
987 }
988 #endif /* WITH_SUBLIMITS */
989 
990 /*
991  * Initialize all limits in one rule.
992  */
993 int
994 init_limits(const struct rule *rule)
995 {
996 	struct limit *limit;
997 
998 	STAILQ_FOREACH(limit, &rule->limits, link) {
999 		if (init_limit(rule, limit) < 0) {
1000 			logbt("init_limits");
1001 			return (-1);
1002 		}
1003 #ifdef WITH_SUBLIMITS
1004 		init_sublimits(rule, limit);
1005 #endif
1006 	}
1007 	return (0);
1008 }
1009 
1010 /*
1011  * Return pointer to limit with the given name.
1012  */
1013 struct limit *
1014 limit_by_name(const struct rule *rule, const char *name)
1015 {
1016 	struct limit *limit;
1017 
1018 	STAILQ_FOREACH(limit, &rule->limits, link)
1019 		if (strcmp(name, limit->name) == 0)
1020 			break;
1021 	return (limit);
1022 }
1023 
1024 /*
1025  * This function is called from newday().
1026  */
1027 int
1028 limits_newday(struct rule *rule)
1029 {
1030 	struct limit *limit;
1031 	unsigned int check_sec;
1032 
1033 	check_sec = EVENT_NOT_SCHEDULED;
1034 
1035 	STAILQ_FOREACH(limit, &rule->limits, link) {
1036 		if (LIMIT_IS_REACHED(limit)) {
1037 			/* Is reached. */
1038 			if (limit->expire.expire.upto != TEXP_UPTO_NOTSET)
1039 				/* limit { expire } */
1040 				limit_set_event_sec(limit);
1041 		} else {
1042 			/* Is not reached. */
1043 			if (limit->restart.restart.upto != TEXP_UPTO_NOTSET)
1044 				/* limit { restart } */
1045 				limit_set_event_sec(limit);
1046 		}
1047 		if (WT_IS_INACTIVE(limit->worktime)) {
1048 			if (LIMIT_IS_ACTIVE(limit))
1049 				if (set_limit_inactive(rule, limit) < 0)
1050 					goto failed;
1051 			if (check_sec > limit->worktime->active_sec)
1052 				check_sec = limit->worktime->active_sec;
1053 		} else {
1054 			if (LIMIT_IS_INACTIVE(limit))
1055 				if (set_limit_active(rule, limit) < 0)
1056 					goto failed;
1057 			if (check_sec > limit->worktime->inactive_sec)
1058 				check_sec = limit->worktime->inactive_sec;
1059 			if (check_sec > limit->event_sec)
1060 				check_sec = limit->event_sec;
1061 		}
1062 		if (rule->check_sec > check_sec)
1063 			rule->check_sec = check_sec;
1064 	}
1065 	return (0);
1066 
1067 failed:
1068 	logbt("limits_newday");
1069 	return (-1);
1070 }
1071 
1072 #ifdef WITH_SUBLIMITS
1073 /*
1074  * Copy sublimits from limit2 to limit1.
1075  */
1076 static int
1077 copy_sublimits(struct rule *rule, struct limit *ldst, const struct limit *lsrc)
1078 {
1079 	const struct sublimit *ssrc;
1080 	struct sublimit *sdst;
1081 	unsigned int count;
1082 	int rv;
1083 
1084 	count = 0;
1085 	STAILQ_FOREACH(ssrc, &lsrc->sublimits, link) {
1086 		sdst = mzone_alloc(sublimit_mzone);
1087 		if (sdst == NULL) {
1088 			xlogmsgx(IPA_LOG_ERR, "copy_sublimits: "
1089 			    "mzone_alloc failed");
1090 			return (-1);
1091 		}
1092 
1093 		/* Copy settings from source sublimit. */
1094 		*sdst = *ssrc;
1095 
1096 		/*
1097 		 * Initialize fields which are pointers to memory,
1098 		 * which cannot be shared.
1099 		 */
1100 		sublimit_init_cmds(sdst);
1101 		sdst->limit = ldst;
1102 		sdst->wpid.u.sublimit = sdst;
1103 
1104 		/* Link just allocated sublimit to limit. */
1105 		STAILQ_INSERT_TAIL(&ldst->sublimits, sdst, link);
1106 
1107 		/*
1108 		 * If something goes wrong with memory allocation,
1109 		 * previous settings will allow to deinitialize current rule.
1110 		 */
1111 		rv =
1112 		    cmds_copy(rule, &sdst->reach, &ssrc->reach) +
1113 		    cmds_limit_copy(rule, &sdst->rc[0], &sdst->rc[0]) +
1114 		    cmds_limit_copy(rule, &sdst->rc[1], &ssrc->rc[1]);
1115 		if (rv < 0)
1116 			return (-1);
1117 		++count;
1118 	}
1119 	if (RULE_IS_DYNAMIC(rule))
1120 		ndynsublimits += count;
1121 	else
1122 		nstatsublimits += count;
1123 	return (0);
1124 }
1125 #endif
1126 
1127 /*
1128  * Copy all limits from the given limits list to rule.
1129  */
1130 int
1131 copy_limits(struct rule *rule, const struct limits_list *list)
1132 {
1133 	const struct limit *lsrc;
1134 	struct limit *ldst;
1135 	unsigned int count;
1136 	int rv;
1137 
1138 	count = 0;
1139 	STAILQ_FOREACH(lsrc, list, link) {
1140 		ldst = mzone_alloc(limit_mzone);
1141 		if (ldst == NULL) {
1142 			xlogmsgx(IPA_LOG_ERR, "copy_limits: "
1143 			    "mzone_alloc failed");
1144 			return (-1);
1145 		}
1146 
1147 		/* Copy settings from source limit. */
1148 		*ldst = *lsrc;
1149 
1150 		/*
1151 		 * Initialize fields, which are pointers to memory,
1152 		 * which cannot be shared.
1153 		 */
1154 		limit_init_cmds(ldst);
1155 		ldst->rule = rule;
1156 		ldst->wpid.u.limit = ldst;
1157 #ifdef WITH_SUBLIMITS
1158 		STAILQ_INIT(&ldst->sublimits);
1159 #endif
1160 
1161 		/* Link just allocated limit to rule. */
1162 		STAILQ_INSERT_TAIL(&rule->limits, ldst, link);
1163 
1164 		/*
1165 		 * If something goes wrong with memory allocation,
1166 		 * previous settings will allow to deinitialize current rule.
1167 		 */
1168 		rv =
1169 		    cmds_copy(rule, &ldst->restart.cmds, &lsrc->restart.cmds) +
1170 		    cmds_copy(rule, &ldst->reach, &lsrc->reach) +
1171 		    cmds_copy(rule, &ldst->expire.cmds, &lsrc->expire.cmds) +
1172 		    cmds_limit_copy(rule, &ldst->rc[0], &lsrc->rc[0]) +
1173 		    cmds_limit_copy(rule, &ldst->rc[1], &lsrc->rc[1]);
1174 		if (rv < 0)
1175 			return (-1);
1176 #ifdef WITH_SUBLIMITS
1177 		if (copy_sublimits(rule, ldst, lsrc) < 0)
1178 			return (-1);
1179 #endif
1180 		++count;
1181 	}
1182 	if (RULE_IS_DYNAMIC(rule))
1183 		ndynlimits += count;
1184 	else
1185 		nstatlimits += count;
1186 	return (0);
1187 }
1188 
1189 #ifdef WITH_SUBLIMITS
1190 static void
1191 free_sublimits(unsigned int rule_flags, struct sublimits_list *list,
1192     int dyn_flag)
1193 {
1194 	struct sublimit *sublimit, *sublimit_next;
1195 	unsigned int count;
1196 
1197 	count = 0;
1198 	STAILQ_FOREACH_SAFE(sublimit, list, link, sublimit_next) {
1199 		if (rule_flags & RULE_FLAG_FREE_LIMITS)
1200 			mem_free(sublimit->name, m_anon);
1201 		cmds_free(&sublimit->reach);
1202 		cmds_limit_free(&sublimit->rc[RC_STARTUP]);
1203 		cmds_limit_free(&sublimit->rc[RC_SHUTDOWN]);
1204 		mzone_free(sublimit_mzone, sublimit);
1205 		++count;
1206 	}
1207 	if (dyn_flag)
1208 		ndynsublimits -= count;
1209 }
1210 #endif
1211 
1212 /*
1213  * Release memory used by a list of limits, rule_flags determines
1214  * which part of limit{} structure to free.
1215  */
1216 void
1217 free_limits(unsigned int rule_flags, struct limits_list *limits,
1218     int dyn_flag)
1219 {
1220 	struct limit *limit, *limit_next;
1221 	unsigned int count;
1222 
1223 	count = 0;
1224 	STAILQ_FOREACH_SAFE(limit, limits, link, limit_next) {
1225 		if (rule_flags & RULE_FLAG_FREE_LIMITS) {
1226 			mem_free(limit->name, m_anon);
1227 			mem_free(limit->info, m_parser);
1228 		}
1229 		cmds_free(&limit->restart.cmds);
1230 		cmds_free(&limit->reach);
1231 		cmds_free(&limit->expire.cmds);
1232 		cmds_limit_free(&limit->rc[RC_STARTUP]);
1233 		cmds_limit_free(&limit->rc[RC_SHUTDOWN]);
1234 #ifdef WITH_SUBLIMITS
1235 		free_sublimits(rule_flags, &limit->sublimits, dyn_flag);
1236 #endif
1237 		mzone_free(limit_mzone, limit);
1238 		++count;
1239 	}
1240 	if (dyn_flag)
1241 		ndynlimits -= count;
1242 }
1243 
1244 void
1245 limit_init_cmds(struct limit *limit)
1246 {
1247 	cmds_init(&limit->restart.cmds);
1248 	cmds_init(&limit->reach);
1249 	cmds_init(&limit->expire.cmds);
1250 	cmds_limit_init(&limit->rc[RC_STARTUP]);
1251 	cmds_limit_init(&limit->rc[RC_SHUTDOWN]);
1252 }
1253 
1254 /*
1255  * Set default settings and inherit settings from global{} in limit{}.
1256  */
1257 void
1258 limit_inherit(struct limit *limit)
1259 {
1260 #ifdef WITH_SUBLIMITS
1261 	struct sublimit *sublimit;
1262 #endif
1263 
1264 	if (limit->load_limit < 0)
1265 		limit->load_limit = global_load_limit;
1266 	if (limit->restart.cmds.sync < 0)
1267 		limit->restart.cmds.sync = 0;
1268 	if (limit->reach.sync < 0)
1269 		limit->reach.sync = 0;
1270 	if (limit->expire.cmds.sync < 0)
1271 		limit->expire.cmds.sync = 0;
1272 	cmds_limit_set_sync(&limit->rc[RC_STARTUP]);
1273 	cmds_limit_set_sync(&limit->rc[RC_SHUTDOWN]);
1274 #ifdef WITH_SUBLIMITS
1275 	STAILQ_FOREACH(sublimit, &limit->sublimits, link) {
1276 		if (sublimit->reach.sync < 0)
1277 			sublimit->reach.sync = 0;
1278 		cmds_limit_set_sync(&sublimit->rc[RC_STARTUP]);
1279 		cmds_limit_set_sync(&sublimit->rc[RC_SHUTDOWN]);
1280 	}
1281 #endif
1282 }
1283 #endif /* WITH_LIMITS */
1284