Commit f754fa97 authored by Mark Andrews's avatar Mark Andrews
Browse files

1848. [bug] Improve SMF integration. [RT #13238]

parent 826363ff
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]
......
......@@ -15,7 +15,7 @@
* 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>
......@@ -37,6 +37,9 @@
#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) {
......@@ -58,6 +61,9 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
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) {
......@@ -92,11 +98,59 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
} 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();
......
/*
* 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 */
......@@ -15,7 +15,7 @@
* 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>
......@@ -47,10 +47,6 @@
#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.
......@@ -66,6 +62,9 @@
#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.
......@@ -540,6 +539,9 @@ destroy_managers(void) {
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
......@@ -555,6 +557,18 @@ setup(void) {
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
......@@ -699,88 +713,66 @@ ns_main_setmemstats(const char *filename) {
#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[]) {
......@@ -855,10 +847,6 @@ main(int argc, char *argv[]) {
}
} while (result != ISC_R_SUCCESS);
#ifdef HAVE_LIBSCF
scf_cleanup();
#endif
cleanup();
if (want_stats) {
......
......@@ -15,7 +15,7 @@
* 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>
......@@ -82,6 +82,10 @@
#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
......@@ -4215,3 +4219,36 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
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 */
......@@ -15,7 +15,7 @@
* 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>
......@@ -46,6 +46,9 @@
#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;
......@@ -417,6 +420,9 @@ all_digits(const char *s) {
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));
......@@ -426,6 +432,10 @@ ns_os_chroot(const char *root) {
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
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment