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
41int
42ct_pr_tmpl_set_transfer(int fd, ctid_t ctid)
43{
44	return (ct_tmpl_set_internal(fd, CTPP_SUBSUME, ctid));
45}
46
47int
48ct_pr_tmpl_set_fatal(int fd, uint_t events)
49{
50	return (ct_tmpl_set_internal(fd, CTPP_EV_FATAL, events));
51}
52
53int
54ct_pr_tmpl_set_param(int fd, uint_t param)
55{
56	return (ct_tmpl_set_internal(fd, CTPP_PARAMS, param));
57}
58
59int
60ct_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
65int
66ct_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
71int
72ct_pr_tmpl_get_transfer(int fd, ctid_t *ctid)
73{
74	return (ct_tmpl_get_internal(fd, CTPP_SUBSUME, (uint_t *)ctid));
75}
76
77int
78ct_pr_tmpl_get_fatal(int fd, uint_t *events)
79{
80	return (ct_tmpl_get_internal(fd, CTPP_EV_FATAL, events));
81}
82
83int
84ct_pr_tmpl_get_param(int fd, uint_t *param)
85{
86	return (ct_tmpl_get_internal(fd, CTPP_PARAMS, param));
87}
88
89int
90ct_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
95int
96ct_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
105int
106ct_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
116int
117ct_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
129int
130ct_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
142int
143ct_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
155int
156ct_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
168int
169ct_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
181int
182ct_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
195int
196ct_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
209int
210ct_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
227int
228ct_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
238int
239ct_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
249int
250ct_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
261int
262ct_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
274int
275ct_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
285int
286ct_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
296int
297ct_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
308int
309ct_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