Home | History | Annotate | Download | only in smf
      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