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  *   @(#)$Id: ipa_limits.h,v 1.2 2011/01/23 18:42:34 simon Exp $
27  */
28 
29 #ifndef IPA_LIMITS_H
30 #define IPA_LIMITS_H
31 
32 #ifdef WITH_LIMITS
33 
34 #ifndef LIMIT_NSIZE
35 # define LIMIT_NSIZE	30
36 #endif
37 
38 #ifndef LIMIT_NALLOC
39 # define LIMIT_NALLOC	20
40 #endif
41 
42 #ifdef WITH_SUBLIMITS
43 
44 #ifndef SUBLIMIT_NSIZE
45 # define SUBLIMIT_NSIZE	LIMIT_NSIZE
46 #endif
47 
48 #ifndef SUBLIMIT_NALLOC
49 # define SUBLIMIT_NALLOC LIMIT_NALLOC
50 #endif
51 
52 struct rule;
53 struct limit;
54 
55 #define SUBLIMIT_FLAG_REACHED	0x1	/* Sublimit is reached. */
56 
57 #define SUBLIMIT_IS_REACHED(x)	   ((x)->subl_flags == SUBLIMIT_FLAG_REACHED)
58 #define SUBLIMIT_IS_NOTREACHED(x)  (!SUBLIMIT_IS_REACHED(x))
59 
60 #define SUBLIMIT_SET_REACHED(x)	   ((x)->subl_flags = SUBLIMIT_FLAG_REACHED)
61 #define SUBLIMIT_SET_NOTREACHED(x) ((x)->subl_flags = 0)
62 
63 /*
64  * limit { sublimit {}} section.
65  */
66 struct sublimit {
67 	STAILQ_ENTRY(sublimit) link;	/* Link for list of sublimits. */
68 
69 	uint64_t	lim;		/* sublimit <limit> */
70 
71 	unsigned int	subl_flags;	/* ORed SUBLIMIT_FLAG_xxx */
72 
73 	struct cmds	reach;		/* { reach {}} */
74 
75 	struct wpid	wpid;		/* Sublimit's wpid structure. */
76 
77 	struct limit	*limit;		/* Pointer to sublimit's limit. */
78 
79 	unsigned char	cnt_type;	/* Type of "sublimit" argument. */
80 	unsigned int	lim_pc;		/* sublimit <limit> if it is xx%. */
81 	char		*name;		/* sublimit <limit> string. */
82 
83 	struct cmds_limit rc[2];	/* { startup } and { shutdown } */
84 };
85 
86 /*
87  * List of all sublimits in one limit.
88  */
89 STAILQ_HEAD(sublimits_list, sublimit);
90 
91 extern ipa_mzone *sublimit_mzone;
92 
93 extern struct sublimit *sublimit_by_name(const struct limit *, const char *);
94 
95 extern int	reach_sublimit(const struct rule *, const struct limit *,
96 		    struct sublimit *);
97 
98 extern void	sublimit_init_cmds(struct sublimit *);
99 
100 #endif /* WITH_SUBLIMITS */
101 
102 /*
103  * limit { expire {}} section.
104  */
105 struct expire {
106 	struct texp	expire;		/* expire { expire } */
107 	struct cmds	cmds;		/* Commands. */
108 };
109 
110 /*
111  * limit { restart {}} section.
112  */
113 struct restart {
114 	struct texp	restart;	/* restart { restart } */
115 	struct cmds	cmds;		/* Commands. */
116 };
117 
118 #define LIMIT_FLAG_ACTIVE	0x01	/* Limit is active. */
119 #define LIMIT_FLAG_REACHED	0x02	/* Limit is reached. */
120 #define LIMIT_FLAG_SET		0x04	/* "limit" parameter was given. */
121 #define LIMIT_FLAG_INITED	0x08	/* Limit was initialized. */
122 #define LIMIT_FLAG_BUSY		0x10	/* Limit is busy. */
123 
124 #define LIMIT_IS_ACTIVE(x)	((x)->lim_flags & LIMIT_FLAG_ACTIVE)
125 #define LIMIT_IS_INACTIVE(x)	(!LIMIT_IS_ACTIVE(x))
126 #define LIMIT_IS_REACHED(x)	((x)->lim_flags & LIMIT_FLAG_REACHED)
127 #define LIMIT_IS_NOTREACHED(x)	(!LIMIT_IS_REACHED(x))
128 #define LIMIT_IS_SET(x)		((x)->lim_flags & LIMIT_FLAG_SET)
129 #define LIMIT_IS_NOTSET(x)	(!LIMIT_IS_SET(x))
130 #define LIMIT_IS_INITED(x)	((x)->lim_flags & LIMIT_FLAG_INITED)
131 #define LIMIT_IS_BUSY(x)	((x)->lim_flags & LIMIT_FLAG_BUSY)
132 
133 #define LIMIT_SET_ACTIVE(x)	((x)->lim_flags |= LIMIT_FLAG_ACTIVE)
134 #define LIMIT_SET_INACTIVE(x)	((x)->lim_flags &= ~LIMIT_FLAG_ACTIVE)
135 #define LIMIT_SET_REACHED(x)	((x)->lim_flags |= LIMIT_FLAG_REACHED)
136 #define LIMIT_SET_NOTREACHED(x)	((x)->lim_flags &= ~LIMIT_FLAG_REACHED)
137 #define LIMIT_SET_INITED(x)	((x)->lim_flags |= LIMIT_FLAG_INITED)
138 #define LIMIT_SET_BUSY(x)	((x)->lim_flags |= LIMIT_FLAG_BUSY)
139 #define LIMIT_SET_UNBUSY(x)	((x)->lim_flags &= ~LIMIT_FLAG_BUSY)
140 
141 /*
142  * rule { limit {}} section.
143  */
144 struct limit {
145 	STAILQ_ENTRY(limit) link;	/* Link for list of limits. */
146 
147 	unsigned int	no;		/* Limit ordinal number. */
148 
149 	unsigned int	lim_flags;	/* ORed LIMIT_FLAG_xxx */
150 
151 	uint64_t	lim;		/* { limit } */
152 	uint64_t	cnt;		/* Positive counter. */
153 	uint64_t	cnt_neg;	/* Negative counter. */
154 
155 	const struct db_list *db_list;	/* { db_list } */
156 
157 #ifdef WITH_SUBLIMITS
158 	struct sublimits_list sublimits;/* All { sublimit {}} */
159 #endif
160 
161 	struct restart	restart;	/* { restart {}} */
162 	struct cmds	reach;		/* { reach {}} */
163 	struct expire	expire;		/* { expire {}} */
164 	const struct worktime *worktime;/* { worktime } */
165 
166 	ipa_tm		event_tm;	/* Exact time when to check some
167 					   limit's event. */
168 	unsigned int	event_sec;	/* Time when to check some limit's
169 					   event. */
170 	unsigned int	event_date_set;	/* The same as in ipa_limit_state. */
171 	ipa_tm	event_date[IPA_LIMIT_EVENT_NUM]; /* See ipa_limit_state. */
172 
173 	struct wpid	wpid;		/* Limit's wpid structure. */
174 
175 	const struct rule *rule;	/* Pointer to limit's rule. */
176 
177 	unsigned char	cnt_type;	/* Type of "limit" parameter. */
178 	signed char	load_limit;	/* { load_limit } */
179 
180 	char		*name;		/* Name of this limit. */
181 	char		*info;		/* { info } */
182 
183 	struct cmds_limit rc[2];	/* { startup } and { shutdown } */
184 };
185 
186 /*
187  * List of all limits in one rule.
188  */
189 STAILQ_HEAD(limits_list, limit);
190 
191 extern const char *const limit_event_msg[];
192 
193 extern signed char global_debug_limit;
194 extern signed char global_debug_limit_init;
195 extern signed char global_load_limit;
196 
197 extern ipa_mzone *limit_mzone;
198 
199 extern int	limit_add_chunk(const struct rule *, struct limit *,
200 		    const uint64_t *);
201 extern int	limit_sub_chunk(const struct rule *, struct limit *,
202 		    const uint64_t *);
203 extern int	limits_add_chunk(const struct rule *, const uint64_t *);
204 extern int	limits_sub_chunk(const struct rule *, const uint64_t *);
205 
206 extern int	init_limits(const struct rule *);
207 extern int	check_limits(const struct rule *, unsigned int *);
208 extern void	limit_set_event_sec(struct limit *);
209 extern int	limits_newday(struct rule *);
210 
211 extern int	restart_limit(const struct rule *, struct limit *);
212 extern int	reach_limit(const struct rule *, struct limit *);
213 extern int	expire_limit(const struct rule *, struct limit *);
214 
215 #define set_limit_inactive(r, l) mod_set_limit_active((r), (l), 0)
216 extern int	mod_set_limit_active(const struct rule *, struct limit *, int);
217 
218 extern int	copy_limits(struct rule *, const struct limits_list *);
219 extern void	free_limits(unsigned int, struct limits_list *, int);
220 
221 extern void	limit_init_cmds(struct limit *);
222 extern void	limit_inherit(struct limit *);
223 
224 extern struct limit *limit_by_name(const struct rule *, const char *);
225 
226 #endif /* WITH_LIMITS */
227 
228 extern unsigned int nstatlimits;
229 extern unsigned int ndynlimits;
230 
231 extern unsigned int nstatsublimits;
232 extern unsigned int ndynsublimits;
233 
234 #endif /* !IPA_LIMITS_H */
235