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 (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 #include "libscf_impl.h"
28
29 #include <assert.h>
30 #include <libuutil.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <sys/param.h>
35 #include <errno.h>
36 #include <libgen.h>
37 #include <assert.h>
38 #include "midlevel_impl.h"
39 #include "lowlevel_impl.h"
40
41 #ifndef NDEBUG
42 #define bad_error(func, err) { \
43 uu_warn("%s:%d: %s failed with unexpected error %d. Aborting.\n", \
44 __FILE__, __LINE__, func, err); \
1259 SCF_PROPERTY_STATE)) == NULL)
1260 return (SCF_FAILED);
1261
1262 if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) {
1263 scf_simple_prop_free(prop);
1264 return (SCF_FAILED);
1265 }
1266
1267 if (strcmp(state_str, SCF_STATE_STRING_MAINT) == 0) {
1268 ret = set_inst_action(instance, SCF_PROPERTY_MAINT_OFF);
1269 } else if (strcmp(state_str, SCF_STATE_STRING_DEGRADED) == 0) {
1270 ret = set_inst_action(instance, SCF_PROPERTY_RESTORE);
1271 } else {
1272 ret = scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED);
1273 }
1274
1275 scf_simple_prop_free(prop);
1276 return (ret);
1277 }
1278
1279 char *
1280 smf_get_state(const char *instance)
1281 {
1282 scf_simple_prop_t *prop;
1283 const char *state_str;
1284 char *ret;
1285
1286 if ((prop = scf_simple_prop_get(NULL, instance, SCF_PG_RESTARTER,
1287 SCF_PROPERTY_STATE)) == NULL)
1288 return (NULL);
1289
1290 if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) {
1291 scf_simple_prop_free(prop);
1292 return (NULL);
1293 }
1294
1295 if ((ret = strdup(state_str)) == NULL)
1296 (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1297
1298 scf_simple_prop_free(prop);
|
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 (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2017 RackTop Systems.
26 */
27
28 #include "libscf_impl.h"
29
30 #include <assert.h>
31 #include <libuutil.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <sys/param.h>
36 #include <errno.h>
37 #include <libgen.h>
38 #include <assert.h>
39 #include "midlevel_impl.h"
40 #include "lowlevel_impl.h"
41
42 #ifndef NDEBUG
43 #define bad_error(func, err) { \
44 uu_warn("%s:%d: %s failed with unexpected error %d. Aborting.\n", \
45 __FILE__, __LINE__, func, err); \
1260 SCF_PROPERTY_STATE)) == NULL)
1261 return (SCF_FAILED);
1262
1263 if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) {
1264 scf_simple_prop_free(prop);
1265 return (SCF_FAILED);
1266 }
1267
1268 if (strcmp(state_str, SCF_STATE_STRING_MAINT) == 0) {
1269 ret = set_inst_action(instance, SCF_PROPERTY_MAINT_OFF);
1270 } else if (strcmp(state_str, SCF_STATE_STRING_DEGRADED) == 0) {
1271 ret = set_inst_action(instance, SCF_PROPERTY_RESTORE);
1272 } else {
1273 ret = scf_set_error(SCF_ERROR_CONSTRAINT_VIOLATED);
1274 }
1275
1276 scf_simple_prop_free(prop);
1277 return (ret);
1278 }
1279
1280 /*
1281 * Wait for the given instance to finish transitioning. This can be gleamed
1282 * from looking at the restarter/next_state property, which settles to "none"
1283 * when the service has finished. This is true even in the case of failure.
1284 *
1285 * Some services take their sweet time so we don't bother with a timeout here.
1286 * Instead we let svc.startd deal with timing out the service, after which
1287 * restarter/next_state gets set to "none" and we return.
1288 */
1289 static int
1290 wait_for_transition(const char *instance, const char *state)
1291 {
1292 scf_simple_prop_t *prop;
1293 const char *state_str;
1294
1295 while (1) {
1296 if ((prop = scf_simple_prop_get(NULL, instance,
1297 SCF_PG_RESTARTER, SCF_PROPERTY_NEXT_STATE)) == NULL)
1298 return (SCF_FAILED);
1299
1300 if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) {
1301 scf_simple_prop_free(prop);
1302 return (SCF_FAILED);
1303 }
1304
1305 if (strcmp(state_str, SCF_STATE_STRING_NONE) == 0) {
1306 scf_simple_prop_free(prop);
1307 break;
1308 }
1309
1310 scf_simple_prop_free(prop);
1311 (void) sleep(1);
1312 }
1313
1314 if (state != NULL) {
1315 if ((prop = scf_simple_prop_get(NULL, instance,
1316 SCF_PG_RESTARTER, SCF_PROPERTY_STATE)) == NULL)
1317 return (SCF_FAILED);
1318
1319 if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) {
1320 scf_simple_prop_free(prop);
1321 return (SCF_FAILED);
1322 }
1323
1324 if (strcmp(state_str, state) != 0) {
1325 scf_simple_prop_free(prop);
1326 return (SCF_FAILED);
1327 }
1328
1329 scf_simple_prop_free(prop);
1330 }
1331
1332 return (SCF_SUCCESS);
1333 }
1334
1335 int
1336 smf_enable_instance_synchronous(const char *instance, int flags)
1337 {
1338 int ret;
1339
1340 if ((ret = smf_enable_instance(instance, flags)) != SCF_SUCCESS)
1341 return (ret);
1342
1343 return (wait_for_transition(instance, SCF_STATE_STRING_ONLINE));
1344 }
1345
1346 int
1347 smf_disable_instance_synchronous(const char *instance, int flags)
1348 {
1349 int ret;
1350
1351 if ((ret = smf_disable_instance(instance, flags)) != SCF_SUCCESS)
1352 return (ret);
1353
1354 return (wait_for_transition(instance, SCF_STATE_STRING_DISABLED));
1355 }
1356
1357 int
1358 smf_refresh_instance_synchronous(const char *instance)
1359 {
1360 int ret;
1361
1362 if ((ret = smf_refresh_instance(instance)) != SCF_SUCCESS)
1363 return (ret);
1364
1365 return (wait_for_transition(instance, NULL)); /* ignore state */
1366 }
1367
1368 int
1369 smf_restart_instance_synchronous(const char *instance)
1370 {
1371 int ret;
1372
1373 if ((ret = smf_restart_instance(instance)) != SCF_SUCCESS)
1374 return (ret);
1375
1376 return (wait_for_transition(instance, NULL)); /* ignore state */
1377 }
1378
1379 int
1380 smf_maintain_instance_synchronous(const char *instance, int flags)
1381 {
1382 int ret;
1383
1384 if ((ret = smf_maintain_instance(instance, flags)) != SCF_SUCCESS)
1385 return (ret);
1386
1387 return (wait_for_transition(instance, SCF_STATE_STRING_MAINT));
1388 }
1389
1390 int
1391 smf_degrade_instance_synchronous(const char *instance, int flags)
1392 {
1393 int ret;
1394
1395 if ((ret = smf_degrade_instance(instance, flags)) != SCF_SUCCESS)
1396 return (ret);
1397
1398 return (wait_for_transition(instance, SCF_STATE_STRING_DEGRADED));
1399 }
1400
1401 int
1402 smf_restore_instance_synchronous(const char *instance)
1403 {
1404 int ret;
1405
1406 if ((ret = smf_restore_instance(instance)) != SCF_SUCCESS)
1407 return (ret);
1408
1409 return (wait_for_transition(instance, SCF_STATE_STRING_ONLINE));
1410 }
1411
1412 char *
1413 smf_get_state(const char *instance)
1414 {
1415 scf_simple_prop_t *prop;
1416 const char *state_str;
1417 char *ret;
1418
1419 if ((prop = scf_simple_prop_get(NULL, instance, SCF_PG_RESTARTER,
1420 SCF_PROPERTY_STATE)) == NULL)
1421 return (NULL);
1422
1423 if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) {
1424 scf_simple_prop_free(prop);
1425 return (NULL);
1426 }
1427
1428 if ((ret = strdup(state_str)) == NULL)
1429 (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1430
1431 scf_simple_prop_free(prop);
|