diff options
| author | John Sonnenschein <johns@joyent.com> | 2011-03-16 16:53:19 -0700 |
|---|---|---|
| committer | John Sonnenschein <johns@joyent.com> | 2011-03-16 16:53:19 -0700 |
| commit | a5c2501f94a7811ea6f4fd115de2984115fe1949 (patch) | |
| tree | 2bfc29a4f6860dae4235086fa4f89e330bfe658a /usr/src | |
| parent | 7b66c860fc0e4f1476242b3828c10a4d18e8f82b (diff) | |
| download | illumos-joyent-a5c2501f94a7811ea6f4fd115de2984115fe1949.tar.gz | |
OS-275 smf behavior around going to maint causes problems.
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/cmd/svc/startd/method.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/usr/src/cmd/svc/startd/method.c b/usr/src/cmd/svc/startd/method.c index a615de643d..440ba348ee 100644 --- a/usr/src/cmd/svc/startd/method.c +++ b/usr/src/cmd/svc/startd/method.c @@ -24,6 +24,10 @@ */ /* + * Copyright 2011 Joyent Inc. + */ + +/* * method.c - method execution functions * * This file contains the routines needed to run a method: a fork(2)-exec(2) @@ -70,7 +74,7 @@ #include <unistd.h> #include <atomic.h> #include <poll.h> - +#include <libscf_priv.h> #include "startd.h" #define SBIN_SH "/sbin/sh" @@ -110,24 +114,44 @@ method_record_start(restarter_inst_t *inst) /* * method_rate_critical(restarter_inst_t *) * Return true if the average start interval is less than the permitted - * interval. Implicit success if insufficient measurements for an - * average exist. + * interval. The implicit interval defaults to RINST_FAILURE_RATE_NS and + * RINST_START_TIMES but is overridable with the + * startd/critical_failure_rate and startd/critical_start_times properties + * Implicit success if insufficient measurements for an average exist. */ static int method_rate_critical(restarter_inst_t *inst) { + hrtime_t critical_failure_rate = RINST_FAILURE_RATE_NS; + uint_t critical_start_times = RINST_START_TIMES; uint_t n = inst->ri_start_index; hrtime_t avg_ns = 0; - - if (inst->ri_start_index < RINST_START_TIMES) - return (0); + uint64_t scf_fr, scf_st; + scf_propvec_t *prop = NULL; + scf_propvec_t restart_critical[] = { + { "critical_failure_rate", NULL, SCF_TYPE_INTEGER, NULL, 0 }, + { "critical_start_times", NULL, SCF_TYPE_INTEGER, NULL, 0 }, + { NULL } + }; + + restart_critical[0].pv_ptr = &scf_fr; + restart_critical[1].pv_ptr = &scf_st; + + if (scf_read_propvec(inst->ri_i.i_fmri, "startd", + B_TRUE, restart_critical, &prop) != SCF_FAILED) { + /* failure rate is defined in 1s intervals, but implemented in ns */ + critical_failure_rate = (hrtime_t) scf_fr * 1000000000; + critical_start_times = (uint_t) scf_st; + } + if (inst->ri_start_index < critical_start_times) + return (0); avg_ns = - (inst->ri_start_time[(n - 1) % RINST_START_TIMES] - - inst->ri_start_time[n % RINST_START_TIMES]) / - (RINST_START_TIMES - 1); + (inst->ri_start_time[(n - 1) % critical_start_times] - + inst->ri_start_time[n % critical_start_times]) / + (critical_start_times - 1); - return (avg_ns < RINST_FAILURE_RATE_NS); + return (avg_ns < critical_failure_rate); } /* |
