summaryrefslogtreecommitdiff
path: root/usr/src/cmd/svc/startd/graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/svc/startd/graph.c')
-rw-r--r--usr/src/cmd/svc/startd/graph.c89
1 files changed, 87 insertions, 2 deletions
diff --git a/usr/src/cmd/svc/startd/graph.c b/usr/src/cmd/svc/startd/graph.c
index 57b04d33ae..e45faeb7dd 100644
--- a/usr/src/cmd/svc/startd/graph.c
+++ b/usr/src/cmd/svc/startd/graph.c
@@ -1504,8 +1504,16 @@ dependency_satisfied(graph_vertex_t *v, boolean_t satbility)
{
switch (v->gv_type) {
case GVT_INST:
- if ((v->gv_flags & GV_CONFIGURED) == 0)
+ if ((v->gv_flags & GV_CONFIGURED) == 0) {
+ if (v->gv_flags & GV_DEATHROW) {
+ /*
+ * A dependency on an instance with GV_DEATHROW
+ * flag is always considered as satisfied.
+ */
+ return (1);
+ }
return (-1);
+ }
switch (v->gv_state) {
case RESTARTER_STATE_ONLINE:
@@ -2869,6 +2877,7 @@ configure_vertex(graph_vertex_t *v, scf_instance_t *inst)
int enabled, enabled_ovr;
int err;
int *path;
+ int deathrow;
restarter_fmri[0] = '\0';
@@ -2880,11 +2889,86 @@ configure_vertex(graph_vertex_t *v, scf_instance_t *inst)
assert(should_be_in_subgraph(v) ==
((v->gv_flags & GV_INSUBGRAPH) != 0));
- log_framework(LOG_DEBUG, "Graph adding %s.\n", v->gv_name);
+ /*
+ * If the instance fmri is in the deathrow list then set the
+ * GV_DEATHROW flag on the vertex and create and set to true the
+ * SCF_PROPERTY_DEATHROW boolean property in the non-persistent
+ * repository for this instance fmri.
+ */
+ if ((v->gv_flags & GV_DEATHROW) ||
+ (is_fmri_in_deathrow(v->gv_name) == B_TRUE)) {
+ if ((v->gv_flags & GV_DEATHROW) == 0) {
+ /*
+ * Set flag GV_DEATHROW, create and set to true
+ * the SCF_PROPERTY_DEATHROW property in the
+ * non-persistent repository for this instance fmri.
+ */
+ v->gv_flags |= GV_DEATHROW;
+
+ switch (err = libscf_set_deathrow(inst, 1)) {
+ case 0:
+ break;
+
+ case ECONNABORTED:
+ case ECANCELED:
+ startd_free(restarter_fmri, max_scf_value_size);
+ return (err);
+
+ case EROFS:
+ log_error(LOG_WARNING, "Could not set %s/%s "
+ "for deathrow %s: %s.\n",
+ SCF_PG_DEATHROW, SCF_PROPERTY_DEATHROW,
+ v->gv_name, strerror(err));
+ break;
+
+ case EPERM:
+ uu_die("Permission denied.\n");
+ /* NOTREACHED */
+
+ default:
+ bad_error("libscf_set_deathrow", err);
+ }
+ log_framework(LOG_DEBUG, "Deathrow, graph set %s.\n",
+ v->gv_name);
+ }
+ startd_free(restarter_fmri, max_scf_value_size);
+ return (0);
+ }
h = scf_instance_handle(inst);
/*
+ * Using a temporary deathrow boolean property, set through
+ * libscf_set_deathrow(), only for fmris on deathrow, is necessary
+ * because deathrow_fini() may already have been called, and in case
+ * of a refresh, GV_DEATHROW may need to be set again.
+ * libscf_get_deathrow() sets deathrow to 1 only if this instance
+ * has a temporary boolean property named 'deathrow' valued true
+ * in a property group 'deathrow', -1 or 0 in all other cases.
+ */
+ err = libscf_get_deathrow(h, inst, &deathrow);
+ switch (err) {
+ case 0:
+ break;
+
+ case ECONNABORTED:
+ case ECANCELED:
+ startd_free(restarter_fmri, max_scf_value_size);
+ return (err);
+
+ default:
+ bad_error("libscf_get_deathrow", err);
+ }
+
+ if (deathrow == 1) {
+ v->gv_flags |= GV_DEATHROW;
+ startd_free(restarter_fmri, max_scf_value_size);
+ return (0);
+ }
+
+ log_framework(LOG_DEBUG, "Graph adding %s.\n", v->gv_name);
+
+ /*
* If the instance does not have a restarter property group,
* initialize its state to uninitialized/none, in case the restarter
* is not enabled.
@@ -4296,6 +4380,7 @@ dgraph_remove_instance(const char *fmri, scf_handle_t *h)
graph_walk_dependents(v, propagate_stop, (void *)RERR_RESTART);
v->gv_flags &= ~GV_CONFIGURED;
+ v->gv_flags &= ~GV_DEATHROW;
graph_walk_dependents(v, propagate_start, NULL);
propagate_satbility(v);