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 2007 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 <unistd.h> 30 #include <fcntl.h> 31 #include <errno.h> 32 #include <limits.h> 33 #include <stdio.h> 34 #include <assert.h> 35 #include <libuutil.h> 36 #include <libintl.h> 37 #include <string.h> 38 #include <procfs.h> 39 #include <libcontract.h> 40 #include <libcontract_priv.h> 41 #include "libcontract_impl.h" 42 #include "process_dump.h" 43 #include "device_dump.h" 44 45 46 contract_type_t types[CTT_MAXTYPE] = { 47 { "process", event_process }, 48 { "device", event_device } 49 }; 50 51 static int 52 close_on_exec(int fd) 53 { 54 int flags = fcntl(fd, F_GETFD, 0); 55 if ((flags != -1) && (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1)) 56 return (0); 57 return (-1); 58 } 59 60 int 61 contract_latest(ctid_t *id) 62 { 63 int cfd, r; 64 ct_stathdl_t st; 65 ctid_t result; 66 67 if ((cfd = open64(CTFS_ROOT "/process/latest", O_RDONLY)) == -1) 68 return (errno); 69 70 if ((r = ct_status_read(cfd, CTD_COMMON, &st)) != 0) { 71 (void) close(cfd); 72 return (r); 73 } 74 75 result = ct_status_get_id(st); 76 ct_status_free(st); 77 (void) close(cfd); 78 79 *id = result; 80 return (0); 81 } 82 83 int 84 contract_open(ctid_t ctid, const char *type, const char *file, int oflag) 85 { 86 char path[PATH_MAX]; 87 int n, fd; 88 89 assert((oflag & O_CREAT) == 0); 90 91 if (type == NULL) 92 type = "all"; 93 94 n = snprintf(path, PATH_MAX, CTFS_ROOT "/%s/%ld/%s", type, ctid, file); 95 if (n >= PATH_MAX) { 96 errno = ENAMETOOLONG; 97 return (-1); 98 } 99 100 fd = open64(path, oflag); 101 if (fd != -1) { 102 if (close_on_exec(fd) == -1) { 103 int err = errno; 104 (void) close(fd); 105 errno = err; 106 return (-1); 107 } 108 } 109 return (fd); 110 } 111 112 int 113 contract_abandon_id(ctid_t ctid) 114 { 115 int fd, err; 116 117 fd = contract_open(ctid, "all", "ctl", O_WRONLY); 118 if (fd == -1) 119 return (errno); 120 121 err = ct_ctl_abandon(fd); 122 (void) close(fd); 123 124 return (err); 125 } 126 127 ctid_t 128 getctid(void) 129 { 130 int fd; 131 psinfo_t ps; 132 133 if ((fd = open("/proc/self/psinfo", O_RDONLY)) == -1) 134 return (-1); 135 if (read(fd, &ps, sizeof (ps)) != sizeof (ps)) { 136 (void) close(fd); 137 return (-1); 138 } 139 (void) close(fd); 140 return (ps.pr_contract); 141 } 142 143 void 144 contract_event_dump(FILE *file, ct_evthdl_t hdl, int verbose) 145 { 146 ct_typeid_t type; 147 struct ctlib_event_info *info = hdl; 148 149 type = info->event.ctev_cttype; 150 types[type].type_event(file, hdl, verbose); 151 } 152 153 void 154 contract_negend_dump(FILE *file, ct_evthdl_t ev) 155 { 156 ctevid_t nevid = 0; 157 ctid_t my_ctid = ct_event_get_ctid(ev); 158 ctid_t new_ctid = 0; 159 char *s; 160 161 (void) ct_event_get_nevid(ev, &nevid); 162 (void) ct_event_get_newct(ev, &new_ctid); 163 164 if (new_ctid != my_ctid) { 165 s = dgettext(TEXT_DOMAIN, "negotiation %llu succeeded\n"); 166 } else { 167 s = dgettext(TEXT_DOMAIN, "negotiation %llu failed\n"); 168 } 169 /*LINTED*/ 170 (void) fprintf(file, s, (unsigned long long)nevid); 171 } 172