summaryrefslogtreecommitdiff
path: root/usr/src/cmd/svc
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/svc')
-rw-r--r--usr/src/cmd/svc/configd/rc_node.c3
-rw-r--r--usr/src/cmd/svc/milestone/net-routing-setup23
-rw-r--r--usr/src/cmd/svc/milestone/network-location.xml2
-rw-r--r--usr/src/cmd/svc/milestone/network-routing-setup.xml14
-rw-r--r--usr/src/cmd/svc/milestone/network.xml8
-rw-r--r--usr/src/cmd/svc/milestone/single-user.xml2
-rw-r--r--usr/src/cmd/svc/shell/smf_include.sh6
-rw-r--r--usr/src/cmd/svc/startd/graph.c26
-rw-r--r--usr/src/cmd/svc/startd/method.c96
-rw-r--r--usr/src/cmd/svc/startd/startd.h4
-rw-r--r--usr/src/cmd/svc/svcadm/Makefile7
-rw-r--r--usr/src/cmd/svc/svcs/Makefile2
-rw-r--r--usr/src/cmd/svc/svcs/explain.c4
-rw-r--r--usr/src/cmd/svc/svcs/svcs.c94
14 files changed, 234 insertions, 57 deletions
diff --git a/usr/src/cmd/svc/configd/rc_node.c b/usr/src/cmd/svc/configd/rc_node.c
index 3cc30e3e67..149f2a6cb5 100644
--- a/usr/src/cmd/svc/configd/rc_node.c
+++ b/usr/src/cmd/svc/configd/rc_node.c
@@ -23,6 +23,9 @@
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
/*
* rc_node.c - In-memory SCF object management
diff --git a/usr/src/cmd/svc/milestone/net-routing-setup b/usr/src/cmd/svc/milestone/net-routing-setup
index 6ab1a6c7f0..b4ee7d39ac 100644
--- a/usr/src/cmd/svc/milestone/net-routing-setup
+++ b/usr/src/cmd/svc/milestone/net-routing-setup
@@ -21,11 +21,15 @@
#
#
# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# Copyright (c) 2012 Joyent, Inc. All rights reserved.
# This script configures IP routing.
. /lib/svc/share/smf_include.sh
+set -o xtrace
+
#
# In a shared-IP zone we need this service to be up, but all of the work
# it tries to do is irrelevant (and will actually lead to the service
@@ -156,7 +160,8 @@ fi
# however, as persistent daemon state is now controlled by SMF.
#
ipv4_routing_set=`/usr/bin/svcprop -p routeadm/ipv4-routing-set $SMF_FMRI`
-if [ -z "$defrouters" ]; then
+smartos_param=`/usr/bin/bootparams | grep "^smartos"`
+if [ -z "$defrouters" ] && [ "$smartos_param" != "" ]; then
#
# Set default value for ipv4-routing to enabled. If routeadm -e/-d
# has not yet been run by the administrator, we apply this default.
@@ -210,5 +215,21 @@ if [ -f /etc/inet/static_routes ]; then
done
fi
+#
+# Read /etc/inet/static_routes.vmadm and add each route.
+#
+if [ -f /etc/inet/static_routes.vmadm ]; then
+ echo "Adding vmadm persistent routes:"
+ /usr/bin/egrep -v "^(#|$)" /etc/inet/static_routes.vmadm | while read line; do
+ /usr/sbin/route add $line
+ done
+fi
+
+#
+# Log the result
+#
+echo "Routing setup complete:"
+/usr/bin/netstat -rn
+
# Clear exit status.
exit $SMF_EXIT_OK
diff --git a/usr/src/cmd/svc/milestone/network-location.xml b/usr/src/cmd/svc/milestone/network-location.xml
index aad337f42f..709e9df8f3 100644
--- a/usr/src/cmd/svc/milestone/network-location.xml
+++ b/usr/src/cmd/svc/milestone/network-location.xml
@@ -106,7 +106,7 @@
-->
<dependency
name='manifest-import'
- grouping='require_all'
+ grouping='optional_all'
restart_on='none'
type='service'>
<service_fmri value='svc:/system/manifest-import:default' />
diff --git a/usr/src/cmd/svc/milestone/network-routing-setup.xml b/usr/src/cmd/svc/milestone/network-routing-setup.xml
index b34d578e2a..85a74756da 100644
--- a/usr/src/cmd/svc/milestone/network-routing-setup.xml
+++ b/usr/src/cmd/svc/milestone/network-routing-setup.xml
@@ -40,11 +40,19 @@
<!-- loopback/physical network configuration is required -->
<dependency
- name='network'
- grouping='optional_all'
+ name='loopback'
+ grouping='require_all'
+ restart_on='none'
+ type='service'>
+ <service_fmri value='svc:/network/loopback' />
+ </dependency>
+
+ <dependency
+ name='physical'
+ grouping='require_all'
restart_on='none'
type='service'>
- <service_fmri value='svc:/milestone/network' />
+ <service_fmri value='svc:/network/physical' />
</dependency>
<!-- usr filesystem required to run routing-related commands -->
diff --git a/usr/src/cmd/svc/milestone/network.xml b/usr/src/cmd/svc/milestone/network.xml
index 75b5578f44..48386ebf73 100644
--- a/usr/src/cmd/svc/milestone/network.xml
+++ b/usr/src/cmd/svc/milestone/network.xml
@@ -54,6 +54,14 @@
<service_fmri value='svc:/network/physical' />
</dependency>
+ <dependency
+ name='routing-setup'
+ grouping='require_all'
+ restart_on='none'
+ type='service'>
+ <service_fmri value='svc:/network/routing-setup' />
+ </dependency>
+
<exec_method
type='method'
name='start'
diff --git a/usr/src/cmd/svc/milestone/single-user.xml b/usr/src/cmd/svc/milestone/single-user.xml
index 8797f13c47..579ecb5ddd 100644
--- a/usr/src/cmd/svc/milestone/single-user.xml
+++ b/usr/src/cmd/svc/milestone/single-user.xml
@@ -68,7 +68,7 @@
<dependency
name='manifests'
- grouping='require_all'
+ grouping='optional_all'
restart_on='none'
type='service'>
<service_fmri value='svc:/system/manifest-import' />
diff --git a/usr/src/cmd/svc/shell/smf_include.sh b/usr/src/cmd/svc/shell/smf_include.sh
index d0dc387246..02c9532763 100644
--- a/usr/src/cmd/svc/shell/smf_include.sh
+++ b/usr/src/cmd/svc/shell/smf_include.sh
@@ -22,6 +22,7 @@
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2012 Joyent, Inc. All rights reserved.
#
smf_present () {
@@ -234,7 +235,12 @@ smf_kill_contract() {
# SMF_EXIT_ERR_OTHER, although not defined, encompasses all non-zero
# exit status values.
#
+# The SMF_EXIT_NODAEMON exit status should be used when a method does not
+# need to run any persistent process. This indicates success, abandons the
+# contract, and allows dependencies to be met.
+#
SMF_EXIT_OK=0
+SMF_EXIT_NODAEMON=94
SMF_EXIT_ERR_FATAL=95
SMF_EXIT_ERR_CONFIG=96
SMF_EXIT_MON_DEGRADE=97
diff --git a/usr/src/cmd/svc/startd/graph.c b/usr/src/cmd/svc/startd/graph.c
index c831c99301..5a4e933220 100644
--- a/usr/src/cmd/svc/startd/graph.c
+++ b/usr/src/cmd/svc/startd/graph.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2015, Syneto S.R.L. All rights reserved.
*/
@@ -142,6 +143,8 @@
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <fm/libfmevent.h>
#include <libscf.h>
#include <libscf_priv.h>
@@ -4876,6 +4879,20 @@ vertex_subgraph_dependencies_shutdown(scf_handle_t *h, graph_vertex_t *v,
was_up = up_state(old_state);
now_up = up_state(v->gv_state);
+ if (halting != -1 && old_state == RESTARTER_STATE_DISABLED &&
+ v->gv_state != RESTARTER_STATE_DISABLED) {
+ /*
+ * We're halting and we have a svc which is transitioning to
+ * offline in parallel. This leads to a race condition where
+ * gt_enter_offline might re-enable the svc after we disabled
+ * it. Since we're halting, we want to ensure no svc ever
+ * transitions out of the disabled state. In this case, modify
+ * the flags to keep us on the halting path.
+ */
+ was_up = 0;
+ now_up = 0;
+ }
+
if (!was_up && now_up) {
++non_subgraph_svcs;
} else if (was_up && !now_up) {
@@ -6828,6 +6845,7 @@ repository_event_thread(void *unused)
char *fmri = startd_alloc(max_scf_fmri_size);
char *pg_name = startd_alloc(max_scf_value_size);
int r;
+ int fd;
h = libscf_handle_create_bound_loop();
@@ -6850,6 +6868,14 @@ retry:
goto retry;
}
+ if ((fd = open("/etc/svc/volatile/startd.ready", O_RDONLY | O_CREAT,
+ S_IRUSR)) < 0) {
+ log_error(LOG_WARNING, "Couldn't create startd.ready file\n",
+ SCF_GROUP_FRAMEWORK, scf_strerror(scf_error()));
+ } else {
+ (void) close(fd);
+ }
+
/*CONSTCOND*/
while (1) {
ssize_t res;
diff --git a/usr/src/cmd/svc/startd/method.c b/usr/src/cmd/svc/startd/method.c
index cc9ce6768c..c3cd0144c1 100644
--- a/usr/src/cmd/svc/startd/method.c
+++ b/usr/src/cmd/svc/startd/method.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2011 Joyent Inc.
+ * Copyright 2012 Joyent, Inc. All rights reserved.
*/
/*
@@ -100,34 +100,18 @@ static uint_t method_events[] = {
* method_record_start(restarter_inst_t *)
* Record a service start for rate limiting. Place the current time
* in the circular array of instance starts.
+ *
+ * Save the critical_failure_period and critical_failure_allowed with either
+ * the defaults or the svc properties startd/critical_failure_count and
+ * startd/critical_failure_period.
+ * ri_crit_fail_allowed is capped at RINST_START_TIMES.
*/
static void
method_record_start(restarter_inst_t *inst)
{
- int index = inst->ri_start_index++ % RINST_START_TIMES;
-
- inst->ri_start_time[index] = gethrtime();
-}
-
-/*
- * method_rate_critical(restarter_inst_t *)
- * Return true if the average start interval is less than the permitted
- * interval. The implicit interval defaults to RINST_FAILURE_RATE_NS and
- * RINST_START_TIMES but may be overridden with the svc properties
- * startd/critical_failure_count and startd/critical_failure_period
- * which represent the number of failures to consider and the amount of
- * time in seconds in which that number may occur, respectively. Note that
- * this time is measured as of the transition to 'enabled' rather than wall
- * clock time.
- * Implicit success if insufficient measurements for an average exist.
- */
-int
-method_rate_critical(restarter_inst_t *inst)
-{
+ int index;
+ uint_t critical_failure_allowed = RINST_START_TIMES;
hrtime_t critical_failure_period;
- uint_t critical_failure_count = RINST_START_TIMES;
- uint_t n = inst->ri_start_index;
- hrtime_t avg_ns = 0;
uint64_t scf_fr, scf_st;
scf_propvec_t *prop = NULL;
scf_propvec_t restart_critical[] = {
@@ -151,17 +135,48 @@ method_rate_critical(restarter_inst_t *inst)
* in seconds but tracked in ns
*/
critical_failure_period = (hrtime_t)scf_fr * NANOSEC;
- critical_failure_count = (uint_t)scf_st;
+ critical_failure_allowed = (uint_t)scf_st;
+
+ if (critical_failure_allowed > RINST_START_TIMES)
+ critical_failure_allowed = RINST_START_TIMES;
+ if (critical_failure_allowed < 1)
+ critical_failure_allowed = 1;
+
}
- if (inst->ri_start_index < critical_failure_count)
+
+ inst->ri_crit_fail_allowed = critical_failure_allowed;
+ inst->ri_crit_fail_period = critical_failure_period;
+
+ index = inst->ri_start_index++ % critical_failure_allowed;
+ inst->ri_start_time[index] = gethrtime();
+}
+
+/*
+ * method_rate_critical(restarter_inst_t *)
+ * Return true if the number of failures within the interval
+ * ri_crit_fail_period exceeds ri_crit_fail_allowed. The allowed failure
+ * count defaults to RINST_START_TIMES and the implicit interval defaults
+ * to RINST_FAILURE_RATE_NS but may be overridden with the svc properties
+ * startd/critical_failure_count and startd/critical_failure_period which
+ * represent the acceptable number of failures and the amount of time in
+ * seconds in which that number may occur, respectively. Note that this time
+ * is measured as of the transition to 'enabled' rather than wall clock
+ * time. Implicitly not critical if insufficient failures have occured.
+ */
+int
+method_rate_critical(restarter_inst_t *inst)
+{
+ uint_t n = inst->ri_start_index;
+ uint_t fail_allowed = inst->ri_crit_fail_allowed;
+ hrtime_t diff_ns;
+
+ if (n < fail_allowed)
return (0);
- avg_ns =
- (inst->ri_start_time[(n - 1) % critical_failure_count] -
- inst->ri_start_time[n % critical_failure_count]) /
- (critical_failure_count - 1);
+ diff_ns = inst->ri_start_time[(n - 1) % fail_allowed] -
+ inst->ri_start_time[n % fail_allowed];
- return (avg_ns < critical_failure_period);
+ return (diff_ns < inst->ri_crit_fail_period);
}
/*
@@ -989,7 +1004,8 @@ method_run(restarter_inst_t **instp, int type, int *exit_code)
goto contract_out;
}
- if (!WIFEXITED(ret_status)) {
+ if (!WIFEXITED(ret_status) &&
+ WEXITSTATUS(ret_status) != SMF_EXIT_NODAEMON) {
/*
* If method didn't exit itself (it was killed by an
* external entity, etc.), consider the entire
@@ -1018,7 +1034,7 @@ method_run(restarter_inst_t **instp, int type, int *exit_code)
}
*exit_code = WEXITSTATUS(ret_status);
- if (*exit_code != 0) {
+ if (*exit_code != 0 && *exit_code != SMF_EXIT_NODAEMON) {
log_error(LOG_WARNING,
"%s: Method \"%s\" failed with exit status %d.\n",
inst->ri_i.i_fmri, method, WEXITSTATUS(ret_status));
@@ -1027,6 +1043,7 @@ method_run(restarter_inst_t **instp, int type, int *exit_code)
log_instance(inst, B_TRUE, "Method \"%s\" exited with status "
"%d.", mname, *exit_code);
+ /* Note: we will take this path for SMF_EXIT_NODAEMON */
if (*exit_code != 0)
goto contract_out;
@@ -1073,7 +1090,10 @@ assured_kill:
}
contract_out:
- /* Abandon contracts for transient methods & methods that fail. */
+ /*
+ * Abandon contracts for transient methods, methods that exit with
+ * SMF_EXIT_NODAEMON & methods that fail.
+ */
transient = method_is_transient(inst, type);
if ((transient || *exit_code != 0 || result != 0) &&
(restarter_is_kill_method(method) < 0))
@@ -1169,7 +1189,7 @@ retry:
r = method_run(&inst, info->sf_method_type, &exit_code);
- if (r == 0 && exit_code == 0) {
+ if (r == 0 && (exit_code == 0 || exit_code == SMF_EXIT_NODAEMON)) {
/* Success! */
assert(inst->ri_i.i_next_state != RESTARTER_STATE_NONE);
@@ -1187,6 +1207,12 @@ retry:
else
method_remove_contract(inst, B_TRUE, B_TRUE);
}
+
+ /*
+ * For methods that exit with SMF_EXIT_NODAEMON, we already
+ * called method_remove_contract in method_run.
+ */
+
/*
* We don't care whether the handle was rebound because this is
* the last thing we do with it.
diff --git a/usr/src/cmd/svc/startd/startd.h b/usr/src/cmd/svc/startd/startd.h
index c1062e45e0..e204fb829f 100644
--- a/usr/src/cmd/svc/startd/startd.h
+++ b/usr/src/cmd/svc/startd/startd.h
@@ -405,7 +405,7 @@ typedef enum {
#define RINST_RETAKE_MASK 0x0f000000
-#define RINST_START_TIMES 5 /* failures to consider */
+#define RINST_START_TIMES 10 /* up to 10 fails to consider */
#define RINST_FAILURE_RATE_NS 600000000000LL /* 1 failure/10 minutes */
#define RINST_WT_SVC_FAILURE_RATE_NS NANOSEC /* 1 failure/second */
@@ -427,6 +427,8 @@ typedef struct restarter_inst {
hrtime_t ri_start_time[RINST_START_TIMES];
uint_t ri_start_index; /* times started */
+ uint_t ri_crit_fail_allowed;
+ hrtime_t ri_crit_fail_period;
uu_list_node_t ri_link;
pthread_mutex_t ri_lock;
diff --git a/usr/src/cmd/svc/svcadm/Makefile b/usr/src/cmd/svc/svcadm/Makefile
index cc0cc160bf..1a6a0dd35c 100644
--- a/usr/src/cmd/svc/svcadm/Makefile
+++ b/usr/src/cmd/svc/svcadm/Makefile
@@ -21,6 +21,7 @@
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2012, Joyent, Inc. All rights reserved.
#
PROG = svcadm
@@ -49,7 +50,11 @@ $(PROG): $(OBJS)
$(POFILE): $(POFILES)
cat $(POFILES) > $(POFILE)
-install: all $(ROOTUSRSBINPROG)
+install: all $(ROOTSBINPROG) $(ROOTUSRSBINPROG)
+
+$(ROOTUSRSBINPROG):
+ -$(RM) $@
+ -$(SYMLINK) ../../sbin/$(PROG) $@
clean:
$(RM) $(OBJS)
diff --git a/usr/src/cmd/svc/svcs/Makefile b/usr/src/cmd/svc/svcs/Makefile
index 0e9fc52652..2ea89818c0 100644
--- a/usr/src/cmd/svc/svcs/Makefile
+++ b/usr/src/cmd/svc/svcs/Makefile
@@ -34,7 +34,7 @@ include ../../Makefile.cmd
include ../../Makefile.ctf
POFILE = $(PROG)_all.po
-LDLIBS += -lcontract -lscf -luutil -lumem -lnvpair -lzonecfg
+LDLIBS += -lcontract -lscf -luutil -lumem -lnvpair -lzonecfg -lsasl
CPPFLAGS += -I ../common
lint := LINTFLAGS = -mux
diff --git a/usr/src/cmd/svc/svcs/explain.c b/usr/src/cmd/svc/svcs/explain.c
index 42fca80172..eed9733abc 100644
--- a/usr/src/cmd/svc/svcs/explain.c
+++ b/usr/src/cmd/svc/svcs/explain.c
@@ -200,6 +200,7 @@ static char *emsg_invalid_dep;
extern scf_handle_t *h;
extern char *g_zonename;
+extern char *g_zonealias;
/* ARGSUSED */
static int
@@ -2000,6 +2001,9 @@ print_service(inst_t *svcp, int verbose)
if (g_zonename != NULL)
(void) printf(gettext(" Zone: %s\n"), g_zonename);
+ if (g_zonealias != NULL)
+ (void) printf(gettext(" Alias: %s\n"), g_zonealias);
+
stime = svcp->stime.tv_sec;
tmp = localtime(&stime);
diff --git a/usr/src/cmd/svc/svcs/svcs.c b/usr/src/cmd/svc/svcs/svcs.c
index c54f4bd12d..b4882d1776 100644
--- a/usr/src/cmd/svc/svcs/svcs.c
+++ b/usr/src/cmd/svc/svcs/svcs.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
/*
@@ -59,6 +59,7 @@
#include <sys/ctfs.h>
#include <sys/stat.h>
+#include <sasl/saslutil.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
@@ -134,6 +135,9 @@ static int first_paragraph = 1; /* For -l mode. */
static char *common_name_buf; /* Sized for maximal length value. */
char *locale; /* Current locale. */
char *g_zonename; /* zone being operated upon */
+char *g_zonealias; /* alias for zone, if any */
+static char g_aliasdec[MAXPATHLEN / 4 * 3]; /* decoded zone alias buffer */
+static char g_aliasbuf[MAXPATHLEN]; /* base64 encoded zone alias buffer */
/*
* Pathname storage for path generated from the fmri.
@@ -240,7 +244,25 @@ ht_free(void)
static void
ht_init(void)
{
- assert(ht_buckets == NULL);
+ if (ht_buckets != NULL) {
+ /*
+ * If we already have a hash table (e.g., because we are
+ * processing multiple zones), destroy it before creating
+ * a new one.
+ */
+ struct ht_elem *elem, *next;
+ int i;
+
+ for (i = 0; i < ht_buckets_num; i++) {
+ for (elem = ht_buckets[i]; elem != NULL; elem = next) {
+ next = elem->next;
+ free((char *)elem->fmri);
+ free(elem);
+ }
+ }
+
+ free(ht_buckets);
+ }
ht_buckets_num = 8;
ht_buckets = safe_malloc(sizeof (*ht_buckets) * ht_buckets_num);
@@ -553,7 +575,7 @@ get_restarter_time_prop(scf_instance_t *inst, const char *pname,
int r;
r = inst_get_single_val(inst, SCF_PG_RESTARTER, pname, SCF_TYPE_TIME,
- tvp, NULL, ok_if_empty ? EMPTY_OK : 0, 0, 1);
+ tvp, 0, ok_if_empty ? EMPTY_OK : 0, 0, 1);
return (r == 0 ? 0 : -1);
}
@@ -1650,7 +1672,7 @@ sprint_stime(char **buf, scf_walkinfo_t *wip)
SCF_PROPERTY_STATE_TIMESTAMP, &tv, 0);
} else {
r = pg_get_single_val(wip->pg, SCF_PROPERTY_STATE_TIMESTAMP,
- SCF_TYPE_TIME, &tv, NULL, 0);
+ SCF_TYPE_TIME, &tv, 0, 0);
}
if (r != 0) {
@@ -1702,7 +1724,7 @@ sortkey_stime(char *buf, int reverse, scf_walkinfo_t *wip)
SCF_PROPERTY_STATE_TIMESTAMP, &tv, 0);
else
r = pg_get_single_val(wip->pg, SCF_PROPERTY_STATE_TIMESTAMP,
- SCF_TYPE_TIME, &tv, NULL, 0);
+ SCF_TYPE_TIME, &tv, 0, 0);
if (r == 0) {
int64_t sec;
@@ -2514,7 +2536,7 @@ print_detailed(void *unused, scf_walkinfo_t *wip)
gettext("next_state"), buf);
if (pg_get_single_val(rpg, SCF_PROPERTY_STATE_TIMESTAMP,
- SCF_TYPE_TIME, &tv, NULL, 0) == 0) {
+ SCF_TYPE_TIME, &tv, 0, 0) == 0) {
stime = tv.tv_sec;
tmp = localtime(&stime);
for (tbsz = 50; ; tbsz *= 2) {
@@ -3663,6 +3685,24 @@ again:
assert(opt_zone == NULL || zids == NULL);
if (opt_zone == NULL) {
+ zone_status_t status;
+
+ if (zone_getattr(zids[zent], ZONE_ATTR_STATUS,
+ &status, sizeof (status)) < 0 ||
+ status != ZONE_IS_RUNNING) {
+ /*
+ * If this zone is not running or we cannot
+ * get its status, we do not want to attempt
+ * to bind an SCF handle to it, lest we
+ * accidentally interfere with a zone that
+ * is not yet running by looking up a door
+ * to its svc.configd (which could potentially
+ * block a mount with an EBUSY).
+ */
+ zent++;
+ goto nextzone;
+ }
+
if (getzonenamebyid(zids[zent++],
zonename, sizeof (zonename)) < 0) {
uu_warn(gettext("could not get name for "
@@ -3685,18 +3725,46 @@ again:
uu_die(gettext("invalid zone '%s'\n"), g_zonename);
scf_value_destroy(zone);
+
+ /*
+ * On SmartOS, there may be a base64-encoded string attribute
+ * named 'alias' associated with this zone. This alias is
+ * useful, so we attempt to make it available when we are
+ * displaying -xZ output. If it's not available or not
+ * decodable, we just ignore it.
+ */
+ if (g_zonename != NULL) {
+ unsigned len;
+ struct zone_attrtab zattrs;
+ zone_dochandle_t zhdl = zonecfg_init_handle();
+
+ bzero(&zattrs, sizeof (zattrs));
+ (void) strcpy(zattrs.zone_attr_name, "alias");
+
+ if (zhdl != NULL &&
+ zonecfg_get_handle(g_zonename, zhdl) == Z_OK &&
+ zonecfg_lookup_attr(zhdl, &zattrs) == Z_OK &&
+ zonecfg_get_attr_string(&zattrs, g_aliasbuf,
+ sizeof (g_aliasbuf)) == Z_OK &&
+ sasl_decode64(g_aliasbuf, strlen(g_aliasbuf),
+ g_aliasdec, sizeof (g_aliasdec), &len) == SASL_OK) {
+ g_aliasdec[len] = '\0';
+ g_zonealias = g_aliasdec;
+ } else {
+ g_zonealias = NULL;
+ }
+ zonecfg_fini_handle(zhdl);
+ }
}
if (scf_handle_bind(h) == -1) {
if (g_zonename != NULL) {
- uu_warn(gettext("Could not bind to repository "
+ if (show_zones)
+ goto nextzone;
+
+ uu_die(gettext("Could not bind to repository "
"server for zone %s: %s\n"), g_zonename,
scf_strerror(scf_error()));
-
- if (!show_zones)
- return (UU_EXIT_FATAL);
-
- goto nextzone;
}
uu_die(gettext("Could not bind to repository server: %s. "
@@ -3755,7 +3823,7 @@ again:
if (opt_mode == 'L') {
if ((err = scf_walk_fmri(h, argc, argv, SCF_WALK_MULTIPLE,
- print_log, NULL, &exit_status, uu_warn)) != 0) {
+ print_log, NULL, errarg, errfunc)) != 0) {
uu_warn(gettext("failed to iterate over "
"instances: %s\n"), scf_strerror(err));
exit_status = UU_EXIT_FATAL;