summaryrefslogtreecommitdiff
path: root/usr/src/lib/libscf
diff options
context:
space:
mode:
authorBryan Cantrill <bryan@joyent.com>2011-01-28 00:48:09 -0800
committerBryan Cantrill <bryan@joyent.com>2011-01-28 00:48:09 -0800
commit048b02791572fec28722a0c06dec096503552ca7 (patch)
tree8c8c455ff35ec95eab4ab787d939d3cc4a080c05 /usr/src/lib/libscf
parent877f730dbb1e7275a86015a8ac16fca4a36a1ec7 (diff)
downloadillumos-joyent-048b02791572fec28722a0c06dec096503552ca7.tar.gz
946 want ability to list services in a zone from the GZ
Reviewed by: Eric Schrock <eric.schrock@delphix.com> Reviewed by: Albert Lee <trisk@opensolaris.org> Reviewed by: Garrett D'Amore <garrett@nexenta.com> Approved by: Garrett D'Amore <garrett@nexenta.com>
Diffstat (limited to 'usr/src/lib/libscf')
-rw-r--r--usr/src/lib/libscf/common/lowlevel.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/usr/src/lib/libscf/common/lowlevel.c b/usr/src/lib/libscf/common/lowlevel.c
index 7363c7fc9c..3bf4d31372 100644
--- a/usr/src/lib/libscf/common/lowlevel.c
+++ b/usr/src/lib/libscf/common/lowlevel.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
*/
/*
@@ -49,7 +50,9 @@
#include <string.h>
#include <sys/mman.h>
#include <sys/sysmacros.h>
+#include <libzonecfg.h>
#include <unistd.h>
+#include <dlfcn.h>
#define ENV_SCF_DEBUG "LIBSCF_DEBUG"
#define ENV_SCF_DOORPATH "LIBSCF_DOORPATH"
@@ -879,6 +882,67 @@ scf_handle_decorate(scf_handle_t *handle, const char *name, scf_value_t *v)
}
return (0);
}
+
+ if (strcmp(name, "zone") == 0) {
+ char zone[MAXPATHLEN], root[MAXPATHLEN], door[MAXPATHLEN];
+ static int (*zone_get_rootpath)(char *, char *, size_t);
+ ssize_t len;
+
+ /*
+ * In order to be able to set the zone on a handle, we want
+ * to determine the zone's path, which requires us to call into
+ * libzonecfg -- but libzonecfg.so links against libscf.so so
+ * we must not explicitly link to it. To circumvent the
+ * circular dependency, we will pull it in here via dlopen().
+ */
+ if (zone_get_rootpath == NULL) {
+ void *dl = dlopen("libzonecfg.so.1", RTLD_LAZY), *sym;
+
+ if (dl == NULL)
+ return (scf_set_error(SCF_ERROR_NOT_FOUND));
+
+ if ((sym = dlsym(dl, "zone_get_rootpath")) == NULL) {
+ (void) dlclose(dl);
+ return (scf_set_error(SCF_ERROR_INTERNAL));
+ }
+
+ zone_get_rootpath = (int(*)(char *, char *, size_t))sym;
+ }
+
+ if (v == SCF_DECORATE_CLEAR) {
+ (void) pthread_mutex_lock(&handle->rh_lock);
+ handle->rh_doorpath[0] = 0;
+ (void) pthread_mutex_unlock(&handle->rh_lock);
+
+ return (0);
+ }
+
+ if ((len = scf_value_get_astring(v, zone, sizeof (zone))) < 0)
+ return (-1);
+
+ if (len == 0 || len >= sizeof (zone))
+ return (scf_set_error(SCF_ERROR_INVALID_ARGUMENT));
+
+ if (zone_get_rootpath(zone, root, sizeof (root)) != Z_OK) {
+ if (strcmp(zone, GLOBAL_ZONENAME) == 0) {
+ root[0] = '\0';
+ } else {
+ return (scf_set_error(SCF_ERROR_NOT_FOUND));
+ }
+ }
+
+ if (snprintf(door, sizeof (door), "%s/%s", root,
+ default_door_path) >= sizeof (door))
+ return (scf_set_error(SCF_ERROR_INTERNAL));
+
+ (void) pthread_mutex_lock(&handle->rh_lock);
+ (void) strlcpy(handle->rh_doorpath, door,
+ sizeof (handle->rh_doorpath));
+ (void) pthread_mutex_unlock(&handle->rh_lock);
+
+ return (0);
+ }
+
return (scf_set_error(SCF_ERROR_INVALID_ARGUMENT));
}