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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/ctfs.h>
29 #include <sys/contract.h>
30 #include <sys/contract/process.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <libnvpair.h>
34 #include <libcontract.h>
35 #include "libcontract_impl.h"
36 
37 /*
38  * Process contract template routines
39  */
40 
41 int
42 ct_pr_tmpl_set_transfer(int fd, ctid_t ctid)
43 {
44 	return (ct_tmpl_set_internal(fd, CTPP_SUBSUME, ctid));
45 }
46 
47 int
48 ct_pr_tmpl_set_fatal(int fd, uint_t events)
49 {
50 	return (ct_tmpl_set_internal(fd, CTPP_EV_FATAL, events));
51 }
52 
53 int
54 ct_pr_tmpl_set_param(int fd, uint_t param)
55 {
56 	return (ct_tmpl_set_internal(fd, CTPP_PARAMS, param));
57 }
58 
59 int
60 ct_pr_tmpl_set_svc_fmri(int fd, const char *fmri)
61 {
62 	return (ct_tmpl_set_internal_string(fd, CTPP_SVC_FMRI, fmri));
63 }
64 
65 int
66 ct_pr_tmpl_set_svc_aux(int fd, const char *desc)
67 {
68 	return (ct_tmpl_set_internal_string(fd, CTPP_CREATOR_AUX, desc));
69 }
70 
71 int
72 ct_pr_tmpl_get_transfer(int fd, ctid_t *ctid)
73 {
74 	return (ct_tmpl_get_internal(fd, CTPP_SUBSUME, (uint_t *)ctid));
75 }
76 
77 int
78 ct_pr_tmpl_get_fatal(int fd, uint_t *events)
79 {
80 	return (ct_tmpl_get_internal(fd, CTPP_EV_FATAL, events));
81 }
82 
83 int
84 ct_pr_tmpl_get_param(int fd, uint_t *param)
85 {
86 	return (ct_tmpl_get_internal(fd, CTPP_PARAMS, param));
87 }
88 
89 int
90 ct_pr_tmpl_get_svc_fmri(int fd, char *fmri, size_t size)
91 {
92 	return (ct_tmpl_get_internal_string(fd, CTPP_SVC_FMRI, fmri, size));
93 }
94 
95 int
96 ct_pr_tmpl_get_svc_aux(int fd, char *desc, size_t size)
97 {
98 	return (ct_tmpl_get_internal_string(fd, CTPP_CREATOR_AUX, desc, size));
99 }
100 
101 /*
102  * Process contract event routines
103  */
104 
105 int
106 ct_pr_event_get_pid(ct_evthdl_t evthdl, pid_t *pid)
107 {
108 	struct ctlib_event_info *info = evthdl;
109 	if (info->event.ctev_cttype != CTT_PROCESS)
110 		return (EINVAL);
111 	if (info->nvl == NULL)
112 		return (ENOENT);
113 	return (nvlist_lookup_uint32(info->nvl, CTPE_PID, (uint_t *)pid));
114 }
115 
116 int
117 ct_pr_event_get_ppid(ct_evthdl_t evthdl, pid_t *ppid)
118 {
119 	struct ctlib_event_info *info = evthdl;
120 	if (info->event.ctev_cttype != CTT_PROCESS)
121 		return (EINVAL);
122 	if (info->event.ctev_type != CT_PR_EV_FORK)
123 		return (EINVAL);
124 	if (info->nvl == NULL)
125 		return (ENOENT);
126 	return (nvlist_lookup_uint32(info->nvl, CTPE_PPID, (uint_t *)ppid));
127 }
128 
129 int
130 ct_pr_event_get_signal(ct_evthdl_t evthdl, int *signal)
131 {
132 	struct ctlib_event_info *info = evthdl;
133 	if (info->event.ctev_cttype != CTT_PROCESS)
134 		return (EINVAL);
135 	if (info->event.ctev_type != CT_PR_EV_SIGNAL)
136 		return (EINVAL);
137 	if (info->nvl == NULL)
138 		return (ENOENT);
139 	return (nvlist_lookup_uint32(info->nvl, CTPE_SIGNAL, (uint_t *)signal));
140 }
141 
142 int
143 ct_pr_event_get_sender(ct_evthdl_t evthdl, pid_t *sender)
144 {
145 	struct ctlib_event_info *info = evthdl;
146 	if (info->event.ctev_cttype != CTT_PROCESS)
147 		return (EINVAL);
148 	if (info->event.ctev_type != CT_PR_EV_SIGNAL)
149 		return (EINVAL);
150 	if (info->nvl == NULL)
151 		return (ENOENT);
152 	return (nvlist_lookup_uint32(info->nvl, CTPE_SENDER, (uint_t *)sender));
153 }
154 
155 int
156 ct_pr_event_get_senderct(ct_evthdl_t evthdl, ctid_t *sendct)
157 {
158 	struct ctlib_event_info *info = evthdl;
159 	if (info->event.ctev_cttype != CTT_PROCESS)
160 		return (EINVAL);
161 	if (info->event.ctev_type != CT_PR_EV_SIGNAL)
162 		return (EINVAL);
163 	if (info->nvl == NULL)
164 		return (ENOENT);
165 	return (nvlist_lookup_uint32(info->nvl, CTPE_SENDCT, (uint_t *)sendct));
166 }
167 
168 int
169 ct_pr_event_get_exitstatus(ct_evthdl_t evthdl, int *exitstatus)
170 {
171 	struct ctlib_event_info *info = evthdl;
172 	if (info->event.ctev_cttype != CTT_PROCESS)
173 		return (EINVAL);
174 	if (info->event.ctev_type != CT_PR_EV_EXIT)
175 		return (EINVAL);
176 	if (info->nvl == NULL)
177 		return (ENOENT);
178 	return (nvlist_lookup_int32(info->nvl, CTPE_EXITSTATUS, exitstatus));
179 }
180 
181 int
182 ct_pr_event_get_pcorefile(ct_evthdl_t evthdl, const char **pcorefile)
183 {
184 	struct ctlib_event_info *info = evthdl;
185 	if (info->event.ctev_cttype != CTT_PROCESS)
186 		return (EINVAL);
187 	if (info->event.ctev_type != CT_PR_EV_CORE)
188 		return (EINVAL);
189 	if (info->nvl == NULL)
190 		return (ENOENT);
191 	return (nvlist_lookup_string(info->nvl, CTPE_PCOREFILE,
192 	    (char **)pcorefile));
193 }
194 
195 int
196 ct_pr_event_get_gcorefile(ct_evthdl_t evthdl, const char **gcorefile)
197 {
198 	struct ctlib_event_info *info = evthdl;
199 	if (info->event.ctev_cttype != CTT_PROCESS)
200 		return (EINVAL);
201 	if (info->event.ctev_type != CT_PR_EV_CORE)
202 		return (EINVAL);
203 	if (info->nvl == NULL)
204 		return (ENOENT);
205 	return (nvlist_lookup_string(info->nvl, CTPE_GCOREFILE,
206 	    (char **)gcorefile));
207 }
208 
209 int
210 ct_pr_event_get_zcorefile(ct_evthdl_t evthdl, const char **zcorefile)
211 {
212 	struct ctlib_event_info *info = evthdl;
213 	if (info->event.ctev_cttype != CTT_PROCESS)
214 		return (EINVAL);
215 	if (info->event.ctev_type != CT_PR_EV_CORE)
216 		return (EINVAL);
217 	if (info->nvl == NULL)
218 		return (ENOENT);
219 	return (nvlist_lookup_string(info->nvl, CTPE_ZCOREFILE,
220 	    (char **)zcorefile));
221 }
222 
223 /*
224  * Process contract status routines
225  */
226 
227 int
228 ct_pr_status_get_param(ct_stathdl_t stathdl, uint_t *param)
229 {
230 	struct ctlib_status_info *info = stathdl;
231 	if (info->status.ctst_type != CTT_PROCESS)
232 		return (EINVAL);
233 	if (info->nvl == NULL)
234 		return (ENOENT);
235 	return (nvlist_lookup_uint32(info->nvl, CTPS_PARAMS, param));
236 }
237 
238 int
239 ct_pr_status_get_fatal(ct_stathdl_t stathdl, uint_t *fatal)
240 {
241 	struct ctlib_status_info *info = stathdl;
242 	if (info->status.ctst_type != CTT_PROCESS)
243 		return (EINVAL);
244 	if (info->nvl == NULL)
245 		return (ENOENT);
246 	return (nvlist_lookup_uint32(info->nvl, CTPS_EV_FATAL, fatal));
247 }
248 
249 int
250 ct_pr_status_get_members(ct_stathdl_t stathdl, pid_t **members, uint_t *n)
251 {
252 	struct ctlib_status_info *info = stathdl;
253 	if (info->status.ctst_type != CTT_PROCESS)
254 		return (EINVAL);
255 	if (info->nvl == NULL)
256 		return (ENOENT);
257 	return (nvlist_lookup_uint32_array(info->nvl, CTPS_MEMBERS,
258 	    (uint_t **)members, n));
259 }
260 
261 int
262 ct_pr_status_get_contracts(ct_stathdl_t stathdl, ctid_t **contracts,
263     uint_t *n)
264 {
265 	struct ctlib_status_info *info = stathdl;
266 	if (info->status.ctst_type != CTT_PROCESS)
267 		return (EINVAL);
268 	if (info->nvl == NULL)
269 		return (ENOENT);
270 	return (nvlist_lookup_uint32_array(info->nvl, CTPS_CONTRACTS,
271 	    (uint_t **)contracts, n));
272 }
273 
274 int
275 ct_pr_status_get_svc_fmri(ct_stathdl_t stathdl, char **svc_fmri)
276 {
277 	struct ctlib_status_info *info = stathdl;
278 	if (info->status.ctst_type != CTT_PROCESS)
279 		return (EINVAL);
280 	if (info->nvl == NULL)
281 		return (ENOENT);
282 	return (nvlist_lookup_string(info->nvl, CTPS_SVC_FMRI, svc_fmri));
283 }
284 
285 int
286 ct_pr_status_get_svc_aux(ct_stathdl_t stathdl, char **svc_aux)
287 {
288 	struct ctlib_status_info *info = stathdl;
289 	if (info->status.ctst_type != CTT_PROCESS)
290 		return (EINVAL);
291 	if (info->nvl == NULL)
292 		return (ENOENT);
293 	return (nvlist_lookup_string(info->nvl, CTPS_CREATOR_AUX, svc_aux));
294 }
295 
296 int
297 ct_pr_status_get_svc_ctid(ct_stathdl_t stathdl, ctid_t *ctid)
298 {
299 	struct ctlib_status_info *info = stathdl;
300 	if (info->status.ctst_type != CTT_PROCESS)
301 		return (EINVAL);
302 	if (info->nvl == NULL)
303 		return (ENOENT);
304 	return (nvlist_lookup_int32(info->nvl, CTPS_SVC_CTID,
305 	    (int32_t *)ctid));
306 }
307 
308 int
309 ct_pr_status_get_svc_creator(ct_stathdl_t stathdl, char **svc_creator)
310 {
311 	struct ctlib_status_info *info = stathdl;
312 	if (info->status.ctst_type != CTT_PROCESS)
313 		return (EINVAL);
314 	if (info->nvl == NULL)
315 		return (ENOENT);
316 	return (nvlist_lookup_string(info->nvl, CTPS_SVC_CREATOR, svc_creator));
317 }
318