mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
1848. [bug] Improve SMF integration. [RT #13238]
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -1,3 +1,5 @@
|
||||
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();
|
||||
|
42
bin/named/include/named/ns_smf_globals.h
Normal file
42
bin/named/include/named/ns_smf_globals.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 */
|
118
bin/named/main.c
118
bin/named/main.c
@@ -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);
|
||||
*ins_name = instance;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
#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
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user