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 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _LIBRESTART_H 28 #define _LIBRESTART_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <libcontract.h> 33 #include <libscf.h> 34 #include <limits.h> 35 #include <priv.h> 36 #include <pwd.h> 37 #include <sys/types.h> 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /* 44 * There are 3 parts to librestart. 45 * 1) The event protocol from the master restarter to its delegates. 46 * 2) A functional interface for updating the repository. 47 * 3) Convenience functions for common restarter tasks. 48 * 49 * Event protocol 50 * We need a reliable event protocol, as there's no way to define 51 * restarter events as idempotent. 52 * 53 * Currently using sysevent channels as the reliable event implementation. 54 * This could change if the implementation proves unsuitable, but 55 * the API defined here should abstract anything but a change in 56 * the fundamental event model. 57 * 58 * We offer functions to tease apart the event rather than generic 59 * nvpair interfaces. This is because each event type has a well- 60 * defined set of fields. 61 */ 62 63 typedef struct restarter_event_handle restarter_event_handle_t; 64 typedef struct restarter_event restarter_event_t; 65 66 typedef uint32_t restarter_event_type_t; 67 68 /* 69 * Define an event protocol version. In theory, we could use this in 70 * the future to support delegated restarters which use an older 71 * protocol. In practice, increment RESTARTER_EVENT_VERSION whenever the 72 * protocol might have changed. 73 */ 74 #define RESTARTER_EVENT_VERSION 4 75 76 #define RESTARTER_FLAG_DEBUG 1 77 78 /* 79 * Event types 80 * RESTARTER_EVENT_TYPE_ADD_INSTANCE 81 * responsible for a new (stopped) instance 82 * RESTARTER_EVENT_TYPE_REMOVE_INSTANCE 83 * no longer responsible for this instance; stop it and return 84 * RESTARTER_EVENT_TYPE_ENABLE 85 * no guarantee that dependencies are met; see 86 * RESTARTER_EVENT_TYPE_START 87 * RESTARTER_EVENT_TYPE_DISABLE 88 * no guarantee that instance was running 89 * RESTARTER_EVENT_TYPE_ADMIN_DEGRADED 90 * RESTARTER_EVENT_TYPE_ADMIN_REFRESH 91 * RESTARTER_EVENT_TYPE_ADMIN_RESTART 92 * RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF 93 * RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON 94 * RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE 95 * RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF 96 * RESTARTER_EVENT_TYPE_STOP 97 * dependencies are, or are becoming, unsatisfied 98 * RESTARTER_EVENT_TYPE_START 99 * dependencies have become satisfied 100 * RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE 101 * instance caused a dependency cycle 102 * RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY 103 * instance has an invalid dependency 104 */ 105 106 #define RESTARTER_EVENT_TYPE_INVALID 0 107 #define RESTARTER_EVENT_TYPE_ADD_INSTANCE 1 108 #define RESTARTER_EVENT_TYPE_REMOVE_INSTANCE 2 109 #define RESTARTER_EVENT_TYPE_ENABLE 3 110 #define RESTARTER_EVENT_TYPE_DISABLE 4 111 #define RESTARTER_EVENT_TYPE_ADMIN_DEGRADED 5 112 #define RESTARTER_EVENT_TYPE_ADMIN_REFRESH 6 113 #define RESTARTER_EVENT_TYPE_ADMIN_RESTART 7 114 #define RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF 8 115 #define RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON 9 116 #define RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE 10 117 #define RESTARTER_EVENT_TYPE_STOP 11 118 #define RESTARTER_EVENT_TYPE_START 12 119 #define RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE 13 120 #define RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY 14 121 #define RESTARTER_EVENT_TYPE_ADMIN_DISABLE 15 122 123 #define RESTARTER_EVENT_ERROR -1 124 125 #define RESTARTER_EVENT_INSTANCE_DISABLED 0 126 #define RESTARTER_EVENT_INSTANCE_ENABLED 1 127 128 typedef enum { 129 RESTARTER_STATE_NONE, 130 RESTARTER_STATE_UNINIT, 131 RESTARTER_STATE_MAINT, 132 RESTARTER_STATE_OFFLINE, 133 RESTARTER_STATE_DISABLED, 134 RESTARTER_STATE_ONLINE, 135 RESTARTER_STATE_DEGRADED 136 } restarter_instance_state_t; 137 138 /* 139 * These values are ordered by severity of required restart, as we use 140 * integer comparisons to determine error flow. 141 */ 142 typedef enum { 143 RERR_UNSUPPORTED = -1, 144 RERR_NONE = 0, /* no error, restart, refresh */ 145 RERR_FAULT, /* fault occurred */ 146 RERR_RESTART, /* transition due to restart */ 147 RERR_REFRESH /* transition due to refresh */ 148 } restarter_error_t; 149 150 /* 151 * restarter_store_contract() and restarter_remove_contract() types 152 */ 153 typedef enum { 154 RESTARTER_CONTRACT_PRIMARY, 155 RESTARTER_CONTRACT_TRANSIENT 156 } restarter_contract_type_t; 157 158 /* 159 * restarter_bind_handle() registers a delegate with svc.startd to 160 * begin consuming events. 161 * 162 * On initial bind, the delgated restarter receives an event for each 163 * instance it is responsible for, as if that instance was new. 164 * 165 * callers must have superuser privileges 166 * 167 * The event handler can return 0 for success, or EAGAIN to request 168 * retry of event delivery. EAGAIN may be returned 3 times before the 169 * event is discarded. 170 */ 171 int restarter_bind_handle(uint32_t, const char *, 172 int (*event_handler)(restarter_event_t *), int, 173 restarter_event_handle_t **); 174 175 restarter_event_type_t restarter_event_get_type(restarter_event_t *); 176 uint64_t restarter_event_get_seq(restarter_event_t *); 177 void restarter_event_get_time(restarter_event_t *, hrtime_t *); 178 ssize_t restarter_event_get_instance(restarter_event_t *, char *, size_t); 179 restarter_event_handle_t *restarter_event_get_handle(restarter_event_t *); 180 181 /* 182 * The following functions work only on certain types of events. 183 * They fail with a return of -1 if they're called on an inappropriate event. 184 */ 185 int restarter_event_get_enabled(restarter_event_t *); 186 int restarter_event_get_current_states(restarter_event_t *, 187 restarter_instance_state_t *, restarter_instance_state_t *); 188 189 /* 190 * Functions for updating the repository. 191 */ 192 int restarter_set_states(restarter_event_handle_t *, const char *, 193 restarter_instance_state_t, restarter_instance_state_t, 194 restarter_instance_state_t, restarter_instance_state_t, restarter_error_t, 195 const char *); 196 197 int restarter_store_contract(scf_instance_t *, ctid_t, 198 restarter_contract_type_t); 199 int restarter_remove_contract(scf_instance_t *, ctid_t, 200 restarter_contract_type_t); 201 202 ssize_t restarter_state_to_string(restarter_instance_state_t, char *, size_t); 203 restarter_instance_state_t restarter_string_to_state(char *); 204 205 #define RESTARTER_METHOD_CONTEXT_VERSION 6 206 207 struct method_context { 208 /* Stable */ 209 uid_t uid, euid; 210 gid_t gid, egid; 211 int ngroups; /* -1 means use initgroups(). */ 212 gid_t groups[NGROUPS_MAX-1]; 213 priv_set_t *lpriv_set, *priv_set; 214 char *corefile_pattern; /* Optional. */ 215 char *project; /* NULL for no change */ 216 char *resource_pool; /* NULL for project default */ 217 char *working_dir; /* NULL for :default */ 218 char **env; /* NULL for no env */ 219 size_t env_sz; /* size of env array */ 220 221 /* Private */ 222 char *vbuf; 223 ssize_t vbuf_sz; 224 struct passwd pwd; 225 char *pwbuf; 226 ssize_t pwbufsz; 227 }; 228 229 int restarter_rm_libs_loadable(void); 230 /* instance, restarter name, method name, command line, structure pointer */ 231 const char *restarter_get_method_context(uint_t, scf_instance_t *, 232 scf_snapshot_t *, const char *, const char *, struct method_context **); 233 int restarter_set_method_context(struct method_context *, const char **); 234 void restarter_free_method_context(struct method_context *); 235 236 237 int restarter_is_null_method(const char *); 238 int restarter_is_kill_method(const char *); 239 int restarter_is_kill_proc_method(const char *); 240 241 #ifdef __cplusplus 242 } 243 #endif 244 245 #endif /* _LIBRESTART_H */ 246