+1848. [bug] Improve SMF integration. [RT #13238]
+
1847. [bug] isc_ondestroy_init() is called too late in
in dns_rbtdb_create()/dns_rbtdb_create().
[RT #13661]
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: control.c,v 1.22 2004/10/11 05:30:15 marka Exp $ */
+/* $Id: control.c,v 1.23 2005/04/05 00:58:14 marka Exp $ */
#include <config.h>
#include <named/log.h>
#include <named/os.h>
#include <named/server.h>
+#ifdef HAVE_LIBSCF
+#include <named/ns_smf_globals.h>
+#endif
static isc_boolean_t
command_compare(const char *text, const char *command) {
isccc_sexpr_t *data;
char *command;
isc_result_t result;
+#ifdef HAVE_LIBSCF
+ char *instance = NULL;
+#endif
data = isccc_alist_lookup(message, "_data");
if (data == NULL) {
} else if (command_compare(command, NS_COMMAND_RETRANSFER)) {
result = ns_server_retransfercommand(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_HALT)) {
+#ifdef HAVE_LIBSCF
+ /*
+ * If we are managed by smf(5), AND in chroot, then
+ * we cannot connect to the smf repository, so just
+ * return with an appropriate message back to rndc.
+ */
+ if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) {
+ result = ns_smf_add_message(text);
+ return (result);
+ }
+ /*
+ * If we are managed by smf(5) but not in chroot,
+ * try to disable ourselves the smf way.
+ */
+ if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) {
+ result = ns_smf_get_instance(&instance, 1, ns_g_mctx);
+ if (result == ISC_R_SUCCESS && instance != NULL) {
+ ns_server_flushonshutdown(ns_g_server,
+ ISC_FALSE);
+ result = ns_smf_disable(instance);
+ }
+ if (instance != NULL)
+ isc_mem_free(ns_g_mctx, instance);
+ return (result);
+ }
+ /*
+ * If ns_smf_got_instance = 0, ns_smf_chroot
+ * is not relevant and we fall through to
+ * isc_app_shutdown below.
+ */
+#endif
ns_server_flushonshutdown(ns_g_server, ISC_FALSE);
ns_os_shutdownmsg(command, text);
isc_app_shutdown();
result = ISC_R_SUCCESS;
} else if (command_compare(command, NS_COMMAND_STOP)) {
+#ifdef HAVE_LIBSCF
+ if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) {
+ result = ns_smf_add_message(text);
+ return (result);
+ }
+ if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) {
+ result = ns_smf_get_instance(&instance, 1, ns_g_mctx);
+ if (result == ISC_R_SUCCESS && instance != NULL) {
+ ns_server_flushonshutdown(ns_g_server,
+ ISC_TRUE);
+ result = ns_smf_disable(instance);
+ }
+ if (instance != NULL)
+ isc_mem_free(ns_g_mctx, instance);
+ return (result);
+ }
+#endif
ns_server_flushonshutdown(ns_g_server, ISC_TRUE);
ns_os_shutdownmsg(command, text);
isc_app_shutdown();
--- /dev/null
+/*
+ * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef NS_SMF_GLOBALS_H
+#define NS_SMF_GLOBALS_H 1
+
+#include <libscf.h>
+
+#undef EXTERN
+#undef INIT
+#ifdef NS_MAIN
+#define EXTERN
+#define INIT(v) = (v)
+#else
+#define EXTERN extern
+#define INIT(v)
+#endif
+
+EXTERN unsigned int ns_smf_got_instance INIT(0);
+EXTERN unsigned int ns_smf_chroot INIT(0);
+
+isc_result_t ns_smf_add_message(isc_buffer_t *text);
+isc_result_t ns_smf_get_instance(char **name, int debug, isc_mem_t *mctx);
+isc_result_t ns_smf_disable(const char *name);
+
+#undef EXTERN
+#undef INIT
+
+#endif /* NS_SMF_GLOBALS_H */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: main.c,v 1.140 2004/10/25 00:33:28 marka Exp $ */
+/* $Id: main.c,v 1.141 2005/04/05 00:58:14 marka Exp $ */
#include <config.h>
#include <dst/result.h>
-#ifdef HAVE_LIBSCF
-#include <libscf.h>
-#endif
-
/*
* Defining NS_MAIN provides storage declarations (rather than extern)
* for variables in named/globals.h.
#include <named/server.h>
#include <named/lwresd.h>
#include <named/main.h>
+#ifdef HAVE_LIBSCF
+#include <named/ns_smf_globals.h>
+#endif
/*
* Include header files for database drivers here.
static void
setup(void) {
isc_result_t result;
+#ifdef HAVE_LIBSCF
+ char *instance = NULL;
+#endif
/*
* Get the user and group information before changing the root
ns_os_opendevnull();
+#ifdef HAVE_LIBSCF
+ /* Check if named is under smf control, before chroot. */
+ result = ns_smf_get_instance(&instance, 0, ns_g_mctx);
+ /* We don't care about instance, just check if we got one. */
+ if (result == ISC_R_SUCCESS)
+ ns_smf_got_instance = 1;
+ else
+ ns_smf_got_instance = 0;
+ if (instance != NULL)
+ free(instance);
+#endif /* HAVE_LIBSCF */
+
#ifdef PATH_RANDOMDEV
/*
* Initialize system's random device as fallback entropy source
#ifdef HAVE_LIBSCF
/*
- * Get FMRI for the current named process
+ * Get FMRI for the named process.
*/
-static char *
-scf_get_ins_name(void) {
+isc_result_t
+ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) {
scf_handle_t *h = NULL;
int namelen;
- char *ins_name;
+ char *instance;
+
+ REQUIRE(ins_name != NULL && *ins_name == NULL);
if ((h = scf_handle_create(SCF_VERSION)) == NULL) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "scf_handle_create() failed: %s",
- scf_strerror(scf_error()));
- return (NULL);
+ if (debug)
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "scf_handle_create() failed: %s",
+ scf_strerror(scf_error()));
+ return (ISC_R_FAILURE);
}
if (scf_handle_bind(h) == -1) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "scf_handle_bind() failed: %s",
- scf_strerror(scf_error()));
+ if (debug)
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "scf_handle_bind() failed: %s",
+ scf_strerror(scf_error()));
scf_handle_destroy(h);
- return (NULL);
+ return (ISC_R_FAILURE);
}
if ((namelen = scf_myname(h, NULL, 0)) == -1) {
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_MAIN, ISC_LOG_INFO,
- "scf_myname() failed: %s",
- scf_strerror(scf_error()));
+ if (debug)
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "scf_myname() failed: %s",
+ scf_strerror(scf_error()));
scf_handle_destroy(h);
- return (NULL);
+ return (ISC_R_FAILURE);
}
- if ((ins_name = malloc(namelen + 1)) == NULL) {
+ if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
- "scf_get_ins_named() memory "
+ "ns_smf_get_instance memory "
"allocation failed: %s",
isc_result_totext(ISC_R_NOMEMORY));
scf_handle_destroy(h);
- return (NULL);
+ return (ISC_R_FAILURE);
}
- if (scf_myname(h, ins_name, namelen + 1) == -1) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "scf_myname() failed: %s",
- scf_strerror(scf_error()));
+ if (scf_myname(h, instance, namelen + 1) == -1) {
+ if (debug)
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "scf_myname() failed: %s",
+ scf_strerror(scf_error()));
scf_handle_destroy(h);
- free(ins_name);
- return (NULL);
+ isc_mem_free(mctx, instance);
+ return (ISC_R_FAILURE);
}
scf_handle_destroy(h);
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
- ISC_LOG_INFO, "instance name:%s", ins_name);
-
- return (ins_name);
-}
-
-static void
-scf_cleanup(void) {
- char *s;
- char *ins_name;
-
- if ((ins_name = scf_get_ins_name()) != NULL) {
- if ((s = smf_get_state(ins_name)) != NULL) {
- if ((strcmp(SCF_STATE_STRING_ONLINE, s) == 0) ||
- (strcmp(SCF_STATE_STRING_DEGRADED, s) == 0)) {
- if (smf_disable_instance(ins_name, 0) != 0) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "smf_disable_instance() failed: %s",
- scf_strerror(scf_error()));
- }
- }
- free(s);
- } else {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "smf_get_state() failed: %s",
- scf_strerror(scf_error()));
- }
- free(ins_name);
- }
+ *ins_name = instance;
+ return (ISC_R_SUCCESS);
}
-#endif
+#endif /* HAVE_LIBSCF */
int
main(int argc, char *argv[]) {
}
} while (result != ISC_R_SUCCESS);
-#ifdef HAVE_LIBSCF
- scf_cleanup();
-#endif
-
cleanup();
if (want_stats) {
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.439 2005/03/14 23:55:56 marka Exp $ */
+/* $Id: server.c,v 1.440 2005/04/05 00:58:15 marka Exp $ */
#include <config.h>
#include <named/tkeyconf.h>
#include <named/tsigconf.h>
#include <named/zoneconf.h>
+#ifdef HAVE_LIBSCF
+#include <named/ns_smf_globals.h>
+#include <stdlib.h>
+#endif
/*
* Check an operation for failure. Assumes that the function
dns_zone_detach(&zone);
return (result);
}
+
+#ifdef HAVE_LIBSCF
+/*
+ * This function adds a message for rndc to echo if named
+ * is managed by smf and is also running chroot.
+ */
+isc_result_t
+ns_smf_add_message(isc_buffer_t *text) {
+ unsigned int n;
+
+ n = snprintf((char *)isc_buffer_used(text),
+ isc_buffer_availablelength(text),
+ "use svcadm(1M) to manage named");
+ if (n >= isc_buffer_availablelength(text))
+ return (ISC_R_NOSPACE);
+ isc_buffer_add(text, n);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+ns_smf_disable(const char *ins_name) {
+
+ if (ins_name == NULL)
+ return (ISC_R_UNEXPECTED);
+ if (smf_disable_instance(ins_name, 0) != 0) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "smf_disable_instance() failed: %s",
+ scf_strerror(scf_error()));
+ return (ISC_R_FAILURE);
+ }
+ return (ISC_R_SUCCESS);
+}
+#endif /* HAVE_LIBSCF */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.c,v 1.71 2004/10/07 02:33:31 marka Exp $ */
+/* $Id: os.c,v 1.72 2005/04/05 00:58:16 marka Exp $ */
#include <config.h>
#include <stdarg.h>
#include <named/main.h>
#include <named/os.h>
+#ifdef HAVE_LIBSCF
+#include <named/ns_smf_globals.h>
+#endif
static char *pidfile = NULL;
static int devnullfd = -1;
void
ns_os_chroot(const char *root) {
char strbuf[ISC_STRERRORSIZE];
+#ifdef HAVE_LIBSCF
+ ns_smf_chroot = 0;
+#endif
if (root != NULL) {
if (chroot(root) < 0) {
isc__strerror(errno, strbuf, sizeof(strbuf));
isc__strerror(errno, strbuf, sizeof(strbuf));
ns_main_earlyfatal("chdir(/): %s", strbuf);
}
+#ifdef HAVE_LIBSCF
+ /* Set ns_smf_chroot flag on successful chroot. */
+ ns_smf_chroot = 1;
+#endif
}
}