Print this page
8225 passing invalid global pattern to coreadm wedges it nicely
@@ -20,10 +20,11 @@
*/
/*
* 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,10 +1275,142 @@
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;