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 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 package org.opensolaris.os.smf; 28 29 import java.util.*; 30 import org.opensolaris.os.scf.*; 31 import org.opensolaris.os.scf.common.*; 32 import org.opensolaris.os.smf.common.SmfState; 33 34 public class SmfInstance extends SmfDependent 35 { 36 private Instance instance_; 37 38 public SmfInstance(Instance instance) 39 { 40 instance_ = instance; 41 } 42 43 /** 44 * Returns the wrapped instance. 45 */ 46 public Instance getScfInstance() 47 { 48 return (instance_); 49 } 50 51 public FMRI getFMRI() 52 { 53 return (instance_.getFMRI()); 54 } 55 56 public String getName() 57 { 58 return (instance_.getName()); 59 } 60 61 public boolean isEnabled() throws ScfException 62 { 63 PropertyGroup pg; 64 pg = instance_.composed_pg( 65 SmfPropertyGroup.Name.GENERAL.literal()); 66 Property prop = 67 pg.property(SmfProperty.PropertyName.ENABLED.literal()); 68 /* XXX: Catch ClassCastException */ 69 return (((BooleanValue)prop.firstValue()).toBoolean()); 70 } 71 72 public SmfState getState() throws ScfException 73 { 74 return (SmfRestarterGroup.state(instance_)); 75 } 76 77 public SmfState getNextState() throws ScfException 78 { 79 return (SmfRestarterGroup.nextState(instance_)); 80 } 81 82 public SmfRestarterGroup getRestarterGroup() throws ScfException 83 { 84 PropertyGroup pg = instance_.composed_pg(SmfPropertyGroup. 85 Name.RESTARTER.literal()); 86 /* Should this be an exception? */ 87 if (pg == null) 88 return (null); 89 return (new SmfRestarterGroup(pg)); 90 } 91 92 public List<SmfDependencyGroup> getDependencies() throws ScfException 93 { 94 Snapshot snapshot; 95 snapshot = instance_.getSnapshot(ScfConstants.SCF_RUNNING); 96 String t = SmfPropertyGroup.Type.DEPENDENCY.literal(); 97 98 Iterator<PropertyGroup> groups; 99 groups = (snapshot != null) ? 100 snapshot.pgs(t) : instance_.composed_pgs(t); 101 102 return (dependencies(groups)); 103 } 104 105 public String toString() 106 { 107 return (instance_.getFMRI().toString()); 108 } 109 110 public boolean isSatisfied() 111 { 112 return (true); 113 } 114 115 public List<SmfInstance> getInstances() 116 { 117 Vector<SmfInstance> v = new Vector<SmfInstance>(1); 118 v.add(this); 119 return (v); 120 } 121 122 /* 123 * @throws ScfException BACKEND_ACCESS 124 * @throws ScfException BACKEND_READONLY 125 * @throws ScfException CONNECTION_BROKEN 126 * @throws ScfException DELETED - instance was deleted 127 * @throws ScfException NO_RESOURCES 128 * @throws ScfException PERMISSION_DENIED 129 */ 130 PropertyGroup get_or_create_pg(String name, String type, 131 EnumSet<PropertyGroup.Flag> flags) throws ScfException { 132 for (;;) { 133 try { 134 return (instance_.pg(name)); 135 } catch (ScfException e) { 136 switch (e.getError()) { 137 case CONNECTION_BROKEN: 138 case DELETED: 139 throw (e); 140 141 case NOT_FOUND: 142 break; 143 144 case HANDLE_MISMATCH: 145 case INVALID_ARGUMENT: 146 case NOT_BOUND: 147 case NOT_SET: 148 default: 149 throw (new AssertionError(e)); 150 } 151 } 152 153 try { 154 return (instance_.pg_create(name, type, flags)); 155 } catch (ScfException e) { 156 switch (e.getError()) { 157 case BACKEND_ACCESS: 158 case BACKEND_READONLY: 159 case CONNECTION_BROKEN: 160 case DELETED: 161 case NO_RESOURCES: 162 case PERMISSION_DENIED: 163 throw (e); 164 165 case EXISTS: 166 /* loop around */ 167 /* XXX throw write contention? */ 168 break; 169 170 case HANDLE_MISMATCH: 171 case INVALID_ARGUMENT: 172 case NOT_BOUND: 173 case NOT_SET: 174 default: 175 throw (new AssertionError(e)); 176 } 177 } 178 } 179 } 180 181 /** 182 * Enable or disable the instance, according to b. This currently 183 * only sets the persistent value, and does not delete a temporary 184 * override, if one exists. It should eventually take a {@code 185 * temporarily} argument, or we should have another function for 186 * temporary settings. 187 * 188 * @throws ScfException 189 * {@link 190 * org.opensolaris.os.scf.common.ScfException.Error#BACKEND_ACCESS 191 * BACKEND_ACCESS} 192 * 193 * @throws ScfException 194 * {@link 195 * org.opensolaris.os.scf.common.ScfException.Error#BACKEND_READONLY 196 * BACKEND_READONLY} 197 * 198 * @throws ScfException 199 * {@link 200 * org.opensolaris.os.scf.common.ScfException.Error#CONNECTION_BROKEN 201 * CONNECTION_BROKEN} 202 * 203 * @throws ScfException 204 * {@link org.opensolaris.os.scf.common.ScfException.Error#DELETED 205 * DELETED} 206 * 207 * @throws ScfException 208 * {@link org.opensolaris.os.scf.common.ScfException.Error#NO_RESOURCES 209 * NO_RESOURCES} 210 * 211 * @throws ScfException 212 * {@link 213 * org.opensolaris.os.scf.common.ScfException.Error#PERMISSION_DENIED 214 * PERMISSION_DENIED} 215 */ 216 public void setEnabled(boolean b) throws ScfException { 217 PropertyGroup pg; 218 219 try { 220 pg = get_or_create_pg("general", "framework", 221 EnumSet.noneOf(PropertyGroup.Flag.class)); 222 } catch (ScfException e) { 223 switch (e.getError()) { 224 case BACKEND_ACCESS: 225 case BACKEND_READONLY: 226 case CONNECTION_BROKEN: 227 case DELETED: 228 case NO_RESOURCES: 229 case PERMISSION_DENIED: 230 throw (e); 231 232 default: 233 throw (new AssertionError(e)); 234 } 235 } 236 237 for (;;) { 238 pg.remove_property("enabled"); 239 Property prop = pg.property_create( 240 PropertyType.BOOLEAN, "enabled"); 241 // XXX Should be able to add a boolean? 242 prop.addValue(Boolean.toString(b)); 243 try { 244 if (pg.commit()) 245 break; 246 } catch (ScfException e) { 247 switch (e.getError()) { 248 case BACKEND_ACCESS: 249 case BACKEND_READONLY: 250 case CONNECTION_BROKEN: 251 case DELETED: 252 case NO_RESOURCES: 253 case PERMISSION_DENIED: 254 throw (e); 255 256 case INVALID_ARGUMENT: 257 case NOT_BOUND: 258 case NOT_SET: 259 default: 260 throw (new AssertionError(e)); 261 } 262 } 263 pg.update(); 264 } 265 266 // XXX Should probably clear the override, if it exists 267 } 268 269 /** 270 * Request that the instance's restarter place the instance in the 271 * maintenance state. 272 * 273 * @throws ScfException 274 * {@link 275 * org.opensolaris.os.scf.common.ScfException.Error#CONNECTION_BROKEN 276 * CONNECTION_BROKEN} 277 * 278 * @throws ScfException 279 * {@link org.opensolaris.os.scf.common.ScfException.Error#DELETED 280 * DELETED} 281 * 282 * @throws ScfException 283 * {@link org.opensolaris.os.scf.common.ScfException.Error#NO_RESOURCES 284 * NO_RESOURCES} 285 */ 286 public void maintain(boolean immediate) throws ScfException { 287 instance_.maintain(immediate); 288 } 289 290 /** 291 * Request that the instance's restarter remove the instance from the 292 * maintenance state. 293 * 294 * @throws ScfException 295 * {@link 296 * org.opensolaris.os.scf.common.ScfException.Error#CONNECTION_BROKEN 297 * CONNECTION_BROKEN} 298 * 299 * @throws ScfException 300 * {@link 301 * org.opensolaris.os.scf.common.ScfException.Error#CONSTRAINT_VIOLATED 302 * CONSTRAINT_VIOLATED} (The instance is not in an appropriate state.) 303 * 304 * @throws ScfException 305 * {@link org.opensolaris.os.scf.common.ScfException.Error#DELETED 306 * DELETED} 307 * 308 * @throws ScfException 309 * {@link org.opensolaris.os.scf.common.ScfException.Error#NO_RESOURCES 310 * NO_RESOURCES} 311 */ 312 public void clear() throws ScfException { 313 instance_.restore(); 314 } 315 316 /** 317 * Request that the instance's restarter place the instance in the 318 * degraded state. 319 * 320 * @throws ScfException 321 * {@link 322 * org.opensolaris.os.scf.common.ScfException.Error#CONNECTION_BROKEN 323 * CONNECTION_BROKEN} 324 * @throws ScfException 325 * {@link 326 * org.opensolaris.os.scf.common.ScfException.Error#CONSTRAINT_VIOLATED 327 * CONSTRAINT_VIOLATED} (The instance is not in an appropriate state.) 328 * @throws ScfException 329 * {@link org.opensolaris.os.scf.common.ScfException.Error#DELETED 330 * DELETED} 331 * @throws ScfException 332 * {@link org.opensolaris.os.scf.common.ScfException.Error#NO_RESOURCES 333 * NO_RESOURCES} 334 */ 335 public void degrade(boolean immediate) throws ScfException { 336 instance_.degrade(immediate); 337 } 338 339 /** 340 * Request that the instance's restarter restart the instance. 341 * 342 * @throws ScfException 343 * {@link 344 * org.opensolaris.os.scf.common.ScfException.Error#CONNECTION_BROKEN 345 * CONNECTION_BROKEN} 346 * 347 * @throws ScfException 348 * {@link org.opensolaris.os.scf.common.ScfException.Error#DELETED 349 * DELETED} 350 * 351 * @throws ScfException 352 * {@link org.opensolaris.os.scf.common.ScfException.Error#NO_RESOURCES 353 * NO_RESOURCES} 354 */ 355 public void restart() throws ScfException { 356 instance_.restart(); 357 } 358 359 /** 360 * Request that the instance's configuration be refreshed. 361 * 362 * @throws ScfException 363 * {@link 364 * org.opensolaris.os.scf.common.ScfException.Error#CONNECTION_BROKEN 365 * CONNECTION_BROKEN} 366 * 367 * @throws ScfException 368 * {@link org.opensolaris.os.scf.common.ScfException.Error#DELETED 369 * DELETED} 370 * 371 * @throws ScfException 372 * {@link org.opensolaris.os.scf.common.ScfException.Error#NO_RESOURCES 373 * NO_RESOURCES} 374 */ 375 public void refresh() throws ScfException 376 { 377 instance_.refresh(); 378 } 379 } 380