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.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include <sys/contract.h>
29 #include <libnvpair.h>
33 #include <libcontract.h>
34 #include "libcontract_impl.h"
37 * Common template routines
41 ct_tmpl_activate(int fd
)
43 if (ioctl(fd
, CT_TACTIVATE
) == -1)
51 if (ioctl(fd
, CT_TCLEAR
) == -1)
57 ct_tmpl_create(int fd
, ctid_t
*ctidp
)
59 ctid_t ctid
= ioctl(fd
, CT_TCREATE
);
67 ct_tmpl_set_internal(int fd
, uint_t id
, uintptr_t value
)
70 uint64_t param_value
= value
;
73 param
.ctpm_size
= sizeof (uint64_t);
74 param
.ctpm_value
= ¶m_value
;
75 if (ioctl(fd
, CT_TSET
, ¶m
) == -1)
82 ct_tmpl_set_internal_string(int fd
, uint_t id
, const char *value
)
89 param
.ctpm_size
= strlen(value
) + 1;
90 param
.ctpm_value
= (void *)value
;
91 if (ioctl(fd
, CT_TSET
, ¶m
) == -1)
98 ct_tmpl_set_critical(int fd
, uint_t events
)
100 return (ct_tmpl_set_internal(fd
, CTP_EV_CRITICAL
, events
));
104 ct_tmpl_set_informative(int fd
, uint_t events
)
106 return (ct_tmpl_set_internal(fd
, CTP_EV_INFO
, events
));
110 ct_tmpl_set_cookie(int fd
, uint64_t cookie
)
113 uint64_t param_value
= cookie
;
115 param
.ctpm_id
= CTP_COOKIE
;
116 param
.ctpm_size
= sizeof (uint64_t);
117 param
.ctpm_value
= ¶m_value
;
118 if (ioctl(fd
, CT_TSET
, ¶m
) == -1)
124 ct_tmpl_get_internal(int fd
, uint_t id
, uint_t
*value
)
127 uint64_t param_value
;
130 param
.ctpm_size
= sizeof (uint64_t);
131 param
.ctpm_value
= ¶m_value
;
132 if (ioctl(fd
, CT_TGET
, ¶m
) == -1)
134 *value
= param_value
;
139 ct_tmpl_get_internal_string(int fd
, uint32_t id
, char *buf
, size_t size
)
144 param
.ctpm_size
= size
;
145 param
.ctpm_value
= buf
;
146 if (ioctl(fd
, CT_TGET
, ¶m
) == -1)
148 return (param
.ctpm_size
);
152 ct_tmpl_get_critical(int fd
, uint_t
*events
)
154 return (ct_tmpl_get_internal(fd
, CTP_EV_CRITICAL
, events
));
158 ct_tmpl_get_informative(int fd
, uint_t
*events
)
160 return (ct_tmpl_get_internal(fd
, CTP_EV_INFO
, events
));
164 ct_tmpl_get_cookie(int fd
, uint64_t *cookie
)
168 param
.ctpm_id
= CTP_COOKIE
;
169 param
.ctpm_size
= sizeof (uint64_t);
170 param
.ctpm_value
= cookie
;
171 if (ioctl(fd
, CT_TGET
, ¶m
) == -1)
177 * Common ctl routines
183 if (ioctl(fd
, CT_CADOPT
) == -1)
189 ct_ctl_abandon(int fd
)
191 if (ioctl(fd
, CT_CABANDON
) == -1)
198 ct_ctl_newct(int cfd
, ctevid_t evid
, int tfd
)
200 if (ioctl(cfd
, CT_CNEWCT
, tfd
) == -1)
206 ct_ctl_ack(int fd
, ctevid_t event
)
208 if (ioctl(fd
, CT_CACK
, &event
) == -1)
214 ct_ctl_nack(int fd
, ctevid_t event
)
216 if (ioctl(fd
, CT_CNACK
, &event
) == -1)
222 ct_ctl_qack(int fd
, ctevid_t event
)
224 if (ioctl(fd
, CT_CQREQ
, &event
) == -1)
230 * Common status routines
234 ct_status_read(int fd
, int detail
, ct_stathdl_t
*stathdl
)
236 char *status_buffer
= NULL
;
237 int status_nbytes
= 0;
238 struct ctlib_status_info
*info
;
241 info
= malloc(sizeof (struct ctlib_status_info
));
245 info
->status
.ctst_detail
= detail
;
246 if (detail
!= CTD_COMMON
) {
248 info
->status
.ctst_nbytes
= status_nbytes
;
249 info
->status
.ctst_buffer
= status_buffer
;
251 error
= ioctl(fd
, CT_SSTATUS
, &info
->status
);
252 while (error
== -1 && errno
== EINTR
);
255 if (info
->status
.ctst_nbytes
<= status_nbytes
)
260 status_nbytes
= info
->status
.ctst_nbytes
;
261 status_buffer
= malloc(status_nbytes
);
262 if (status_buffer
== NULL
)
265 if ((errno
= nvlist_unpack(info
->status
.ctst_buffer
,
266 info
->status
.ctst_nbytes
, &info
->nvl
, 0)) != 0)
270 status_buffer
= NULL
;
273 info
->status
.ctst_nbytes
= 0;
275 if (ioctl(fd
, CT_SSTATUS
, &info
->status
) == -1)
292 ct_status_free(ct_stathdl_t stathdl
)
294 struct ctlib_status_info
*info
= stathdl
;
297 assert(info
->status
.ctst_detail
!= CTD_COMMON
);
298 nvlist_free(info
->nvl
);
305 ct_status_get_id(ct_stathdl_t stathdl
)
307 struct ctlib_status_info
*info
= stathdl
;
308 return (info
->status
.ctst_id
);
312 ct_status_get_zoneid(ct_stathdl_t stathdl
)
314 struct ctlib_status_info
*info
= stathdl
;
315 return (info
->status
.ctst_zoneid
);
319 ct_status_get_type(ct_stathdl_t stathdl
)
321 struct ctlib_status_info
*info
= stathdl
;
322 return (types
[info
->status
.ctst_type
].type_name
);
326 ct_status_get_holder(ct_stathdl_t stathdl
)
328 struct ctlib_status_info
*info
= stathdl
;
329 return (info
->status
.ctst_holder
);
333 ct_status_get_state(ct_stathdl_t stathdl
)
335 struct ctlib_status_info
*info
= stathdl
;
336 return (info
->status
.ctst_state
);
340 ct_status_get_nevents(ct_stathdl_t stathdl
)
342 struct ctlib_status_info
*info
= stathdl
;
343 return (info
->status
.ctst_nevents
);
347 ct_status_get_ntime(ct_stathdl_t stathdl
)
349 struct ctlib_status_info
*info
= stathdl
;
350 return (info
->status
.ctst_ntime
);
354 ct_status_get_qtime(ct_stathdl_t stathdl
)
356 struct ctlib_status_info
*info
= stathdl
;
357 return (info
->status
.ctst_qtime
);
361 ct_status_get_nevid(ct_stathdl_t stathdl
)
363 struct ctlib_status_info
*info
= stathdl
;
364 return (info
->status
.ctst_nevid
);
368 ct_status_get_informative(ct_stathdl_t stathdl
)
370 struct ctlib_status_info
*info
= stathdl
;
371 return (info
->status
.ctst_informative
);
375 ct_status_get_critical(ct_stathdl_t stathdl
)
377 struct ctlib_status_info
*info
= stathdl
;
378 return (info
->status
.ctst_critical
);
382 ct_status_get_cookie(ct_stathdl_t stathdl
)
384 struct ctlib_status_info
*info
= stathdl
;
385 return (info
->status
.ctst_cookie
);
389 * Common event routines
393 unpack_and_merge(nvlist_t
**nvl
, char *buffer
, size_t len
)
398 if ((error
= nvlist_unpack(buffer
, len
, &tmpnvl
, 0)) != 0)
406 error
= nvlist_merge(*nvl
, tmpnvl
, 0);
412 ct_event_read_internal(int fd
, int cmd
, ct_evthdl_t
*evt
)
414 char *event_buffer
= NULL
;
415 int event_nbytes
= 0;
416 struct ctlib_event_info
*info
;
420 info
= malloc(sizeof (struct ctlib_event_info
));
424 event
= &info
->event
;
427 event
->ctev_nbytes
= event_nbytes
;
428 event
->ctev_buffer
= event_buffer
;
430 error
= ioctl(fd
, cmd
, event
);
431 while (error
== -1 && errno
== EINTR
);
436 if (event
->ctev_nbytes
<= event_nbytes
)
441 event_nbytes
= event
->ctev_nbytes
;
442 event_buffer
= malloc(event_nbytes
);
443 if (event_buffer
== NULL
) {
449 if (event
->ctev_goffset
> 0 && (error
= unpack_and_merge(&info
->nvl
,
450 event
->ctev_buffer
, event
->ctev_goffset
)) != 0)
453 if (event
->ctev_goffset
< event
->ctev_nbytes
&&
454 (error
= unpack_and_merge(&info
->nvl
,
455 event
->ctev_buffer
+ event
->ctev_goffset
,
456 event
->ctev_nbytes
- event
->ctev_goffset
)) != 0)
468 nvlist_free(info
->nvl
);
475 ct_event_read(int fd
, ct_evthdl_t
*evthdl
)
477 return (ct_event_read_internal(fd
, CT_ERECV
, evthdl
));
481 ct_event_read_critical(int fd
, ct_evthdl_t
*evthdl
)
483 return (ct_event_read_internal(fd
, CT_ECRECV
, evthdl
));
487 ct_event_reset(int fd
)
489 if (ioctl(fd
, CT_ERESET
) == -1)
495 ct_event_reliable(int fd
)
497 if (ioctl(fd
, CT_ERELIABLE
) == -1)
503 ct_event_free(ct_evthdl_t evthdl
)
505 struct ctlib_event_info
*info
= evthdl
;
507 nvlist_free(info
->nvl
);
513 ct_event_get_flags(ct_evthdl_t evthdl
)
515 struct ctlib_event_info
*info
= evthdl
;
516 return (info
->event
.ctev_flags
);
520 ct_event_get_ctid(ct_evthdl_t evthdl
)
522 struct ctlib_event_info
*info
= evthdl
;
523 return (info
->event
.ctev_id
);
527 ct_event_get_evid(ct_evthdl_t evthdl
)
529 struct ctlib_event_info
*info
= evthdl
;
530 return (info
->event
.ctev_evid
);
534 ct_event_get_type(ct_evthdl_t evthdl
)
536 struct ctlib_event_info
*info
= evthdl
;
537 return (info
->event
.ctev_type
);
541 ct_event_get_nevid(ct_evthdl_t evthdl
, ctevid_t
*evidp
)
543 struct ctlib_event_info
*info
= evthdl
;
544 if (info
->nvl
== NULL
||
545 nvlist_lookup_uint64(info
->nvl
, CTS_NEVID
, evidp
))
551 ct_event_get_newct(ct_evthdl_t evthdl
, ctid_t
*ctidp
)
553 struct ctlib_event_info
*info
= evthdl
;
554 if (info
->nvl
== NULL
||
555 nvlist_lookup_int32(info
->nvl
, CTS_NEWCT
, (int *)ctidp
))