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 #include <sys/ctfs.h>
27 #include <sys/contract.h>
28 #include <sys/contract/process.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <libnvpair.h>
32 #include <libcontract.h>
33 #include "libcontract_impl.h"
34 
35 /*
36  * Process contract template routines
37  */
38 
39 int
ct_pr_tmpl_set_transfer(int fd,ctid_t ctid)40 ct_pr_tmpl_set_transfer(int fd, ctid_t ctid)
41 {
42 	return (ct_tmpl_set_internal(fd, CTPP_SUBSUME, ctid));
43 }
44 
45 int
ct_pr_tmpl_set_fatal(int fd,uint_t events)46 ct_pr_tmpl_set_fatal(int fd, uint_t events)
47 {
48 	return (ct_tmpl_set_internal(fd, CTPP_EV_FATAL, events));
49 }
50 
51 int
ct_pr_tmpl_set_param(int fd,uint_t param)52 ct_pr_tmpl_set_param(int fd, uint_t param)
53 {
54 	return (ct_tmpl_set_internal(fd, CTPP_PARAMS, param));
55 }
56 
57 int
ct_pr_tmpl_set_svc_fmri(int fd,const char * fmri)58 ct_pr_tmpl_set_svc_fmri(int fd, const char *fmri)
59 {
60 	return (ct_tmpl_set_internal_string(fd, CTPP_SVC_FMRI, fmri));
61 }
62 
63 int
ct_pr_tmpl_set_svc_aux(int fd,const char * desc)64 ct_pr_tmpl_set_svc_aux(int fd, const char *desc)
65 {
66 	return (ct_tmpl_set_internal_string(fd, CTPP_CREATOR_AUX, desc));
67 }
68 
69 int
ct_pr_tmpl_get_transfer(int fd,ctid_t * ctid)70 ct_pr_tmpl_get_transfer(int fd, ctid_t *ctid)
71 {
72 	return (ct_tmpl_get_internal(fd, CTPP_SUBSUME, (uint_t *)ctid));
73 }
74 
75 int
ct_pr_tmpl_get_fatal(int fd,uint_t * events)76 ct_pr_tmpl_get_fatal(int fd, uint_t *events)
77 {
78 	return (ct_tmpl_get_internal(fd, CTPP_EV_FATAL, events));
79 }
80 
81 int
ct_pr_tmpl_get_param(int fd,uint_t * param)82 ct_pr_tmpl_get_param(int fd, uint_t *param)
83 {
84 	return (ct_tmpl_get_internal(fd, CTPP_PARAMS, param));
85 }
86 
87 int
ct_pr_tmpl_get_svc_fmri(int fd,char * fmri,size_t size)88 ct_pr_tmpl_get_svc_fmri(int fd, char *fmri, size_t size)
89 {
90 	return (ct_tmpl_get_internal_string(fd, CTPP_SVC_FMRI, fmri, size));
91 }
92 
93 int
ct_pr_tmpl_get_svc_aux(int fd,char * desc,size_t size)94 ct_pr_tmpl_get_svc_aux(int fd, char *desc, size_t size)
95 {
96 	return (ct_tmpl_get_internal_string(fd, CTPP_CREATOR_AUX, desc, size));
97 }
98 
99 /*
100  * Process contract event routines
101  */
102 
103 int
ct_pr_event_get_pid(ct_evthdl_t evthdl,pid_t * pid)104 ct_pr_event_get_pid(ct_evthdl_t evthdl, pid_t *pid)
105 {
106 	struct ctlib_event_info *info = evthdl;
107 	if (info->event.ctev_cttype != CTT_PROCESS)
108 		return (EINVAL);
109 	if (info->nvl == NULL)
110 		return (ENOENT);
111 	return (nvlist_lookup_uint32(info->nvl, CTPE_PID, (uint_t *)pid));
112 }
113 
114 int
ct_pr_event_get_ppid(ct_evthdl_t evthdl,pid_t * ppid)115 ct_pr_event_get_ppid(ct_evthdl_t evthdl, pid_t *ppid)
116 {
117 	struct ctlib_event_info *info = evthdl;
118 	if (info->event.ctev_cttype != CTT_PROCESS)
119 		return (EINVAL);
120 	if (info->event.ctev_type != CT_PR_EV_FORK)
121 		return (EINVAL);
122 	if (info->nvl == NULL)
123 		return (ENOENT);
124 	return (nvlist_lookup_uint32(info->nvl, CTPE_PPID, (uint_t *)ppid));
125 }
126 
127 int
ct_pr_event_get_signal(ct_evthdl_t evthdl,int * signal)128 ct_pr_event_get_signal(ct_evthdl_t evthdl, int *signal)
129 {
130 	struct ctlib_event_info *info = evthdl;
131 	if (info->event.ctev_cttype != CTT_PROCESS)
132 		return (EINVAL);
133 	if (info->event.ctev_type != CT_PR_EV_SIGNAL)
134 		return (EINVAL);
135 	if (info->nvl == NULL)
136 		return (ENOENT);
137 	return (nvlist_lookup_uint32(info->nvl, CTPE_SIGNAL, (uint_t *)signal));
138 }
139 
140 int
ct_pr_event_get_sender(ct_evthdl_t evthdl,pid_t * sender)141 ct_pr_event_get_sender(ct_evthdl_t evthdl, pid_t *sender)
142 {
143 	struct ctlib_event_info *info = evthdl;
144 	if (info->event.ctev_cttype != CTT_PROCESS)
145 		return (EINVAL);
146 	if (info->event.ctev_type != CT_PR_EV_SIGNAL)
147 		return (EINVAL);
148 	if (info->nvl == NULL)
149 		return (ENOENT);
150 	return (nvlist_lookup_uint32(info->nvl, CTPE_SENDER, (uint_t *)sender));
151 }
152 
153 int
ct_pr_event_get_senderct(ct_evthdl_t evthdl,ctid_t * sendct)154 ct_pr_event_get_senderct(ct_evthdl_t evthdl, ctid_t *sendct)
155 {
156 	struct ctlib_event_info *info = evthdl;
157 	if (info->event.ctev_cttype != CTT_PROCESS)
158 		return (EINVAL);
159 	if (info->event.ctev_type != CT_PR_EV_SIGNAL)
160 		return (EINVAL);
161 	if (info->nvl == NULL)
162 		return (ENOENT);
163 	return (nvlist_lookup_uint32(info->nvl, CTPE_SENDCT, (uint_t *)sendct));
164 }
165 
166 int
ct_pr_event_get_exitstatus(ct_evthdl_t evthdl,int * exitstatus)167 ct_pr_event_get_exitstatus(ct_evthdl_t evthdl, int *exitstatus)
168 {
169 	struct ctlib_event_info *info = evthdl;
170 	if (info->event.ctev_cttype != CTT_PROCESS)
171 		return (EINVAL);
172 	if (info->event.ctev_type != CT_PR_EV_EXIT)
173 		return (EINVAL);
174 	if (info->nvl == NULL)
175 		return (ENOENT);
176 	return (nvlist_lookup_int32(info->nvl, CTPE_EXITSTATUS, exitstatus));
177 }
178 
179 int
ct_pr_event_get_pcorefile(ct_evthdl_t evthdl,const char ** pcorefile)180 ct_pr_event_get_pcorefile(ct_evthdl_t evthdl, const char **pcorefile)
181 {
182 	struct ctlib_event_info *info = evthdl;
183 	if (info->event.ctev_cttype != CTT_PROCESS)
184 		return (EINVAL);
185 	if (info->event.ctev_type != CT_PR_EV_CORE)
186 		return (EINVAL);
187 	if (info->nvl == NULL)
188 		return (ENOENT);
189 	return (nvlist_lookup_string(info->nvl, CTPE_PCOREFILE,
190 	    (char **)pcorefile));
191 }
192 
193 int
ct_pr_event_get_gcorefile(ct_evthdl_t evthdl,const char ** gcorefile)194 ct_pr_event_get_gcorefile(ct_evthdl_t evthdl, const char **gcorefile)
195 {
196 	struct ctlib_event_info *info = evthdl;
197 	if (info->event.ctev_cttype != CTT_PROCESS)
198 		return (EINVAL);
199 	if (info->event.ctev_type != CT_PR_EV_CORE)
200 		return (EINVAL);
201 	if (info->nvl == NULL)
202 		return (ENOENT);
203 	return (nvlist_lookup_string(info->nvl, CTPE_GCOREFILE,
204 	    (char **)gcorefile));
205 }
206 
207 int
ct_pr_event_get_zcorefile(ct_evthdl_t evthdl,const char ** zcorefile)208 ct_pr_event_get_zcorefile(ct_evthdl_t evthdl, const char **zcorefile)
209 {
210 	struct ctlib_event_info *info = evthdl;
211 	if (info->event.ctev_cttype != CTT_PROCESS)
212 		return (EINVAL);
213 	if (info->event.ctev_type != CT_PR_EV_CORE)
214 		return (EINVAL);
215 	if (info->nvl == NULL)
216 		return (ENOENT);
217 	return (nvlist_lookup_string(info->nvl, CTPE_ZCOREFILE,
218 	    (char **)zcorefile));
219 }
220 
221 /*
222  * Process contract status routines
223  */
224 
225 int
ct_pr_status_get_param(ct_stathdl_t stathdl,uint_t * param)226 ct_pr_status_get_param(ct_stathdl_t stathdl, uint_t *param)
227 {
228 	struct ctlib_status_info *info = stathdl;
229 	if (info->status.ctst_type != CTT_PROCESS)
230 		return (EINVAL);
231 	if (info->nvl == NULL)
232 		return (ENOENT);
233 	return (nvlist_lookup_uint32(info->nvl, CTPS_PARAMS, param));
234 }
235 
236 int
ct_pr_status_get_fatal(ct_stathdl_t stathdl,uint_t * fatal)237 ct_pr_status_get_fatal(ct_stathdl_t stathdl, uint_t *fatal)
238 {
239 	struct ctlib_status_info *info = stathdl;
240 	if (info->status.ctst_type != CTT_PROCESS)
241 		return (EINVAL);
242 	if (info->nvl == NULL)
243 		return (ENOENT);
244 	return (nvlist_lookup_uint32(info->nvl, CTPS_EV_FATAL, fatal));
245 }
246 
247 int
ct_pr_status_get_members(ct_stathdl_t stathdl,pid_t ** members,uint_t * n)248 ct_pr_status_get_members(ct_stathdl_t stathdl, pid_t **members, uint_t *n)
249 {
250 	struct ctlib_status_info *info = stathdl;
251 	if (info->status.ctst_type != CTT_PROCESS)
252 		return (EINVAL);
253 	if (info->nvl == NULL)
254 		return (ENOENT);
255 	return (nvlist_lookup_uint32_array(info->nvl, CTPS_MEMBERS,
256 	    (uint_t **)members, n));
257 }
258 
259 int
ct_pr_status_get_contracts(ct_stathdl_t stathdl,ctid_t ** contracts,uint_t * n)260 ct_pr_status_get_contracts(ct_stathdl_t stathdl, ctid_t **contracts,
261     uint_t *n)
262 {
263 	struct ctlib_status_info *info = stathdl;
264 	if (info->status.ctst_type != CTT_PROCESS)
265 		return (EINVAL);
266 	if (info->nvl == NULL)
267 		return (ENOENT);
268 	return (nvlist_lookup_uint32_array(info->nvl, CTPS_CONTRACTS,
269 	    (uint_t **)contracts, n));
270 }
271 
272 int
ct_pr_status_get_svc_fmri(ct_stathdl_t stathdl,char ** svc_fmri)273 ct_pr_status_get_svc_fmri(ct_stathdl_t stathdl, char **svc_fmri)
274 {
275 	struct ctlib_status_info *info = stathdl;
276 	if (info->status.ctst_type != CTT_PROCESS)
277 		return (EINVAL);
278 	if (info->nvl == NULL)
279 		return (ENOENT);
280 	return (nvlist_lookup_string(info->nvl, CTPS_SVC_FMRI, svc_fmri));
281 }
282 
283 int
ct_pr_status_get_svc_aux(ct_stathdl_t stathdl,char ** svc_aux)284 ct_pr_status_get_svc_aux(ct_stathdl_t stathdl, char **svc_aux)
285 {
286 	struct ctlib_status_info *info = stathdl;
287 	if (info->status.ctst_type != CTT_PROCESS)
288 		return (EINVAL);
289 	if (info->nvl == NULL)
290 		return (ENOENT);
291 	return (nvlist_lookup_string(info->nvl, CTPS_CREATOR_AUX, svc_aux));
292 }
293 
294 int
ct_pr_status_get_svc_ctid(ct_stathdl_t stathdl,ctid_t * ctid)295 ct_pr_status_get_svc_ctid(ct_stathdl_t stathdl, ctid_t *ctid)
296 {
297 	struct ctlib_status_info *info = stathdl;
298 	if (info->status.ctst_type != CTT_PROCESS)
299 		return (EINVAL);
300 	if (info->nvl == NULL)
301 		return (ENOENT);
302 	return (nvlist_lookup_int32(info->nvl, CTPS_SVC_CTID,
303 	    (int32_t *)ctid));
304 }
305 
306 int
ct_pr_status_get_svc_creator(ct_stathdl_t stathdl,char ** svc_creator)307 ct_pr_status_get_svc_creator(ct_stathdl_t stathdl, char **svc_creator)
308 {
309 	struct ctlib_status_info *info = stathdl;
310 	if (info->status.ctst_type != CTT_PROCESS)
311 		return (EINVAL);
312 	if (info->nvl == NULL)
313 		return (ENOENT);
314 	return (nvlist_lookup_string(info->nvl, CTPS_SVC_CREATOR, svc_creator));
315 }
316