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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/ctfs.h> 30 #include <unistd.h> 31 #include <fcntl.h> 32 #include <errno.h> 33 #include <limits.h> 34 #include <stdio.h> 35 #include <assert.h> 36 #include <libuutil.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 44 45 contract_type_t types[CTT_MAXTYPE] = { 46 { "process", event_process } 47 }; 48 49 static int 50 close_on_exec(int fd) 51 { 52 int flags = fcntl(fd, F_GETFD, 0); 53 if ((flags != -1) && (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1)) 54 return (0); 55 return (-1); 56 } 57 58 int 59 contract_latest(ctid_t *id) 60 { 61 int cfd, r; 62 ct_stathdl_t st; 63 ctid_t result; 64 65 if ((cfd = open64(CTFS_ROOT "/process/latest", O_RDONLY)) == -1) 66 return (errno); 67 68 if ((r = ct_status_read(cfd, CTD_COMMON, &st)) != 0) { 69 (void) close(cfd); 70 return (r); 71 } 72 73 result = ct_status_get_id(st); 74 ct_status_free(st); 75 (void) close(cfd); 76 77 *id = result; 78 return (0); 79 } 80 81 int 82 contract_open(ctid_t ctid, const char *type, const char *file, int oflag) 83 { 84 char path[PATH_MAX]; 85 int n, fd; 86 87 assert((oflag & O_CREAT) == 0); 88 89 if (type == NULL) 90 type = "all"; 91 92 n = snprintf(path, PATH_MAX, CTFS_ROOT "/%s/%ld/%s", type, ctid, file); 93 if (n >= PATH_MAX) { 94 errno = ENAMETOOLONG; 95 return (-1); 96 } 97 98 fd = open64(path, oflag); 99 if (fd != -1) { 100 if (close_on_exec(fd) == -1) { 101 int err = errno; 102 (void) close(fd); 103 errno = err; 104 return (-1); 105 } 106 } 107 return (fd); 108 } 109 110 int 111 contract_abandon_id(ctid_t ctid) 112 { 113 int fd, err; 114 115 fd = contract_open(ctid, "all", "ctl", O_WRONLY); 116 if (fd == -1) 117 return (errno); 118 119 err = ct_ctl_abandon(fd); 120 (void) close(fd); 121 122 return (err); 123 } 124 125 ctid_t 126 getctid(void) 127 { 128 int fd; 129 psinfo_t ps; 130 131 if ((fd = open("/proc/self/psinfo", O_RDONLY)) == -1) 132 return (-1); 133 if (read(fd, &ps, sizeof (ps)) != sizeof (ps)) { 134 (void) close(fd); 135 return (-1); 136 } 137 (void) close(fd); 138 return (ps.pr_contract); 139 } 140 141 void 142 contract_event_dump(FILE *file, ct_evthdl_t hdl, int verbose) 143 { 144 ct_typeid_t type; 145 struct ctlib_event_info *info = hdl; 146 147 type = info->event.ctev_cttype; 148 types[type].type_event(file, hdl, verbose); 149 } 150