Print this page
8225 passing invalid global pattern to coreadm wedges it nicely
*** 20,29 ****
--- 20,30 ----
*/
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 RackTop Systems.
*/
#include "libscf_impl.h"
#include <assert.h>
*** 1274,1283 ****
--- 1275,1416 ----
scf_simple_prop_free(prop);
return (ret);
}
+ /*
+ * Wait for the given instance to finish transitioning. This can be gleamed
+ * from looking at the restarter/next_state property, which settles to "none"
+ * when the service has finished. This is true even in the case of failure.
+ *
+ * Some services take their sweet time so we don't bother with a timeout here.
+ * Instead we let svc.startd deal with timing out the service, after which
+ * restarter/next_state gets set to "none" and we return.
+ */
+ static int
+ wait_for_transition(const char *instance, const char *state)
+ {
+ scf_simple_prop_t *prop;
+ const char *state_str;
+
+ while (1) {
+ if ((prop = scf_simple_prop_get(NULL, instance,
+ SCF_PG_RESTARTER, SCF_PROPERTY_NEXT_STATE)) == NULL)
+ return (SCF_FAILED);
+
+ if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) {
+ scf_simple_prop_free(prop);
+ return (SCF_FAILED);
+ }
+
+ if (strcmp(state_str, SCF_STATE_STRING_NONE) == 0) {
+ scf_simple_prop_free(prop);
+ break;
+ }
+
+ scf_simple_prop_free(prop);
+ (void) sleep(1);
+ }
+
+ if (state != NULL) {
+ if ((prop = scf_simple_prop_get(NULL, instance,
+ SCF_PG_RESTARTER, SCF_PROPERTY_STATE)) == NULL)
+ return (SCF_FAILED);
+
+ if ((state_str = scf_simple_prop_next_astring(prop)) == NULL) {
+ scf_simple_prop_free(prop);
+ return (SCF_FAILED);
+ }
+
+ if (strcmp(state_str, state) != 0) {
+ scf_simple_prop_free(prop);
+ return (SCF_FAILED);
+ }
+
+ scf_simple_prop_free(prop);
+ }
+
+ return (SCF_SUCCESS);
+ }
+
+ int
+ smf_enable_instance_synchronous(const char *instance, int flags)
+ {
+ int ret;
+
+ if ((ret = smf_enable_instance(instance, flags)) != SCF_SUCCESS)
+ return (ret);
+
+ return (wait_for_transition(instance, SCF_STATE_STRING_ONLINE));
+ }
+
+ int
+ smf_disable_instance_synchronous(const char *instance, int flags)
+ {
+ int ret;
+
+ if ((ret = smf_disable_instance(instance, flags)) != SCF_SUCCESS)
+ return (ret);
+
+ return (wait_for_transition(instance, SCF_STATE_STRING_DISABLED));
+ }
+
+ int
+ smf_refresh_instance_synchronous(const char *instance)
+ {
+ int ret;
+
+ if ((ret = smf_refresh_instance(instance)) != SCF_SUCCESS)
+ return (ret);
+
+ return (wait_for_transition(instance, NULL)); /* ignore state */
+ }
+
+ int
+ smf_restart_instance_synchronous(const char *instance)
+ {
+ int ret;
+
+ if ((ret = smf_restart_instance(instance)) != SCF_SUCCESS)
+ return (ret);
+
+ return (wait_for_transition(instance, NULL)); /* ignore state */
+ }
+
+ int
+ smf_maintain_instance_synchronous(const char *instance, int flags)
+ {
+ int ret;
+
+ if ((ret = smf_maintain_instance(instance, flags)) != SCF_SUCCESS)
+ return (ret);
+
+ return (wait_for_transition(instance, SCF_STATE_STRING_MAINT));
+ }
+
+ int
+ smf_degrade_instance_synchronous(const char *instance, int flags)
+ {
+ int ret;
+
+ if ((ret = smf_degrade_instance(instance, flags)) != SCF_SUCCESS)
+ return (ret);
+
+ return (wait_for_transition(instance, SCF_STATE_STRING_DEGRADED));
+ }
+
+ int
+ smf_restore_instance_synchronous(const char *instance)
+ {
+ int ret;
+
+ if ((ret = smf_restore_instance(instance)) != SCF_SUCCESS)
+ return (ret);
+
+ return (wait_for_transition(instance, SCF_STATE_STRING_ONLINE));
+ }
+
char *
smf_get_state(const char *instance)
{
scf_simple_prop_t *prop;
const char *state_str;