Sfoglia il codice sorgente

log: Implement support for reopening log files

Feature depends on existence of libqb function qb_log_file_reopen.

New function call is added into CFG service API. This function is
used by corosync-cfgtool which now accepts -L parameter.

Finally, logrotate "postrotate" script is calling
corosync-cfgtool -L to notify corosync, instead of using
copytruncate option.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
Jan Friesse 7 anni fa
parent
commit
82f35f1720

+ 9 - 2
conf/logrotate/Makefile.am

@@ -32,11 +32,18 @@
 
 MAINTAINERCLEANFILES    = Makefile.in
 
-EXTRA_DIST		= corosync.in
+EXTRA_DIST		= corosync-reopen.in corosync-copytruncate.in
 
-corosync: corosync.in
+if HAVE_QB_LOG_FILE_REOPEN
+corosync: corosync-reopen.in
 	sed -e 's#@''LOGDIR@#${LOGDIR}#g' \
+	    -e 's#@''SBINDIR@#$(sbindir)#g' \
 	    $< > $@
+else
+corosync: corosync-copytruncate.in
+	sed -e 's#@''LOGDIR@#${LOGDIR}#g' \
+	    $< > $@
+endif
 
 logrotatecorosyncdir    = ${LOGROTATEDIR}
 logrotatecorosync_DATA  = corosync

+ 0 - 0
conf/logrotate/corosync.in → conf/logrotate/corosync-copytruncate.in


+ 12 - 0
conf/logrotate/corosync-reopen.in

@@ -0,0 +1,12 @@
+@LOGDIR@/corosync.log {
+	missingok
+	compress
+	daily
+	rotate 31
+	minsize 2048
+	notifempty
+	nocreate
+	postrotate
+		@SBINDIR@/corosync-cfgtool -L
+	endscript
+}

+ 8 - 0
configure.ac

@@ -162,6 +162,14 @@ AC_CHECK_LIB([qb], [qb_log_thread_priority_set], \
 if test "x${have_qb_log_thread_priority_set}" = xyes; then
 	AC_DEFINE_UNQUOTED([HAVE_QB_LOG_THREAD_PRIORITY_SET], 1, [have qb_log_thread_priority_set])
 fi
+AC_CHECK_LIB([qb], [qb_log_file_reopen], \
+	     have_qb_log_file_reopen="yes", \
+	     have_qb_log_file_reopen="no")
+if test "x${have_qb_log_file_reopen}" = xyes; then
+	AC_DEFINE_UNQUOTED([HAVE_QB_LOG_FILE_REOPEN], 1, [have qb_log_file_reopen])
+fi
+AM_CONDITIONAL(HAVE_QB_LOG_FILE_REOPEN, test x$have_qb_log_file_reopen = xyes)
+
 CPPFLAGS="$SAVE_CPPFLAGS"
 LIBS="$SAVE_LIBS"
 AC_CHECK_LIB([pthread], [pthread_create])

+ 30 - 1
exec/cfg.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2005-2006 MontaVista Software, Inc.
- * Copyright (c) 2006-2013 Red Hat, Inc.
+ * Copyright (c) 2006-2018 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -162,6 +162,10 @@ static void message_handler_req_lib_cfg_reload_config (
 	void *conn,
 	const void *msg);
 
+static void message_handler_req_lib_cfg_reopen_log_files (
+	void *conn,
+	const void *msg);
+
 /*
  * Service Handler Definition
  */
@@ -198,6 +202,10 @@ static struct corosync_lib_handler cfg_lib_engine[] =
 	{ /* 7 */
 		.lib_handler_fn		= message_handler_req_lib_cfg_reload_config,
 		.flow_control		= CS_LIB_FLOW_CONTROL_REQUIRED
+	},
+	{ /* 8 */
+		.lib_handler_fn		= message_handler_req_lib_cfg_reopen_log_files,
+		.flow_control		= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
 	}
 };
 
@@ -1080,3 +1088,24 @@ static void message_handler_req_lib_cfg_reload_config (void *conn, const void *m
 
 	LEAVE();
 }
+
+static void message_handler_req_lib_cfg_reopen_log_files (void *conn, const void *msg)
+{
+	struct res_lib_cfg_reopen_log_files res_lib_cfg_reopen_log_files;
+	cs_error_t res;
+
+	ENTER();
+
+	log_printf(LOGSYS_LEVEL_DEBUG, "Reopening logging files\n");
+
+	res = logsys_reopen_log_files();
+
+	res_lib_cfg_reopen_log_files.header.size = sizeof(res_lib_cfg_reopen_log_files);
+	res_lib_cfg_reopen_log_files.header.id = MESSAGE_RES_CFG_REOPEN_LOG_FILES;
+	res_lib_cfg_reopen_log_files.header.error = res;
+	api->ipc_response_send(conn,
+			       &res_lib_cfg_reopen_log_files,
+			       sizeof(res_lib_cfg_reopen_log_files));
+
+	LEAVE();
+}

+ 45 - 0
exec/logsys.c

@@ -877,3 +877,48 @@ void logsys_blackbox_postfork(void)
 
 	_logsys_config_apply_blackbox();
 }
+
+cs_error_t logsys_reopen_log_files(void)
+{
+	cs_error_t res;
+
+#ifdef HAVE_QB_LOG_FILE_REOPEN
+	int i, j;
+	int num_using_current;
+	int32_t rc;
+
+	res = CS_OK;
+
+	pthread_mutex_lock (&logsys_config_mutex);
+
+	for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+		if (logsys_loggers[i].target_id <= 0 || logsys_loggers[i].logfile == NULL) {
+			continue ;
+		}
+
+		num_using_current = 0;
+		for (j = 0; j <= i; j++) {
+			if (logsys_loggers[i].target_id == logsys_loggers[j].target_id) {
+				num_using_current++;
+			}
+		}
+		if (num_using_current == 1) {
+			/*
+			 * First instance of target file. Reopen it.
+			 */
+			rc = qb_log_file_reopen(logsys_loggers[i].target_id, NULL);
+			if (rc != 0) {
+				LOGSYS_PERROR (-rc, LOGSYS_LEVEL_WARNING,
+				    "Unable to reopen log file %s", logsys_loggers[i].logfile);
+				res = qb_to_cs_error(rc);
+			}
+		}
+	}
+
+	pthread_mutex_unlock (&logsys_config_mutex);
+#else
+	res = CS_ERR_NOT_SUPPORTED;
+#endif
+
+	return (res);
+}

+ 1 - 0
exec/main.c

@@ -1059,6 +1059,7 @@ static void main_service_ready (void)
 	corosync_totem_stats_init ();
 	corosync_fplay_control_init ();
 	corosync_force_gather_init ();
+
 	sync_init (
 		corosync_sync_callbacks_retrieve,
 		corosync_sync_completed);

+ 9 - 0
include/corosync/cfg.h

@@ -233,6 +233,15 @@ corosync_cfg_local_get (
 cs_error_t corosync_cfg_reload_config (
 	corosync_cfg_handle_t handle);
 
+/**
+ * @brief Reopen logging files
+ * @param handle CFG service handle
+ * @return CS_OK on success, CS_ERR_NOT_SUPPORTED if reopening of logging files is not available,
+ *         otherwise one of common errors.
+ */
+cs_error_t corosync_cfg_reopen_log_files (
+	corosync_cfg_handle_t handle);
+
 #ifdef __cplusplus
 }
 #endif

+ 17 - 3
include/corosync/ipc_cfg.h

@@ -59,7 +59,7 @@ enum req_lib_cfg_types {
 	MESSAGE_REQ_CFG_GET_NODE_ADDRS = 5,
 	MESSAGE_REQ_CFG_LOCAL_GET = 6,
 	MESSAGE_REQ_CFG_RELOAD_CONFIG = 7,
-	MESSAGE_REQ_CFG_CRYPTO_SET = 8
+	MESSAGE_REQ_CFG_REOPEN_LOG_FILES = 8
 };
 
 /**
@@ -80,8 +80,8 @@ enum res_lib_cfg_types {
 	MESSAGE_RES_CFG_GET_NODE_ADDRS = 11,
 	MESSAGE_RES_CFG_LOCAL_GET = 12,
 	MESSAGE_RES_CFG_REPLYTOSHUTDOWN = 13,
-	MESSAGE_RES_CFG_CRYPTO_SET = 14,
-	MESSAGE_RES_CFG_RELOAD_CONFIG = 15
+	MESSAGE_RES_CFG_RELOAD_CONFIG = 14,
+	MESSAGE_RES_CFG_REOPEN_LOG_FILES = 15
 };
 
 /**
@@ -217,6 +217,20 @@ struct res_lib_cfg_reload_config {
 	struct qb_ipc_response_header header __attribute__((aligned(8)));
 };
 
+/**
+ * @brief The req_lib_cfg_reopen_log_files struct
+ */
+struct req_lib_cfg_reopen_log_files {
+	struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cfg_reopen_log_files struct
+ */
+struct res_lib_cfg_reopen_log_files {
+	struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
 /**
  * @brief corosync_administrative_target_t enum
  */

+ 3 - 0
include/corosync/logsys.h

@@ -43,6 +43,8 @@
 #include <pthread.h>
 #include <limits.h>
 
+#include <corosync/corotypes.h>
+
 #include <qb/qbconfig.h>
 #include <qb/qblog.h>
 
@@ -262,6 +264,7 @@ extern void logsys_blackbox_prefork(void);
 
 extern void logsys_blackbox_postfork(void);
 
+extern cs_error_t logsys_reopen_log_files(void);
 
 /**
  * @brief logsys_subsys_id

+ 40 - 1
lib/cfg.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002-2005 MontaVista Software, Inc.
- * Copyright (c) 2006-2013 Red Hat, Inc.
+ * Copyright (c) 2006-2018 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -645,3 +645,42 @@ error_exit:
 
 	return (error);
 }
+
+cs_error_t corosync_cfg_reopen_log_files (
+	corosync_cfg_handle_t handle)
+{
+	cs_error_t error;
+	struct cfg_inst *cfg_inst;
+	struct iovec iov;
+	struct req_lib_cfg_reopen_log_files req_lib_cfg_reopen_log_files;
+	struct res_lib_cfg_reopen_log_files res_lib_cfg_reopen_log_files;
+
+	error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, handle, (void *)&cfg_inst));
+	if (error != CS_OK) {
+		return (error);
+	}
+
+	req_lib_cfg_reopen_log_files.header.size = sizeof (struct qb_ipc_request_header);
+	req_lib_cfg_reopen_log_files.header.id = MESSAGE_REQ_CFG_REOPEN_LOG_FILES;
+
+	iov.iov_base = (void *)&req_lib_cfg_reopen_log_files;
+	iov.iov_len = sizeof (struct req_lib_cfg_reopen_log_files);
+
+	error = qb_to_cs_error (qb_ipcc_sendv_recv (
+		cfg_inst->c,
+		&iov,
+		1,
+		&res_lib_cfg_reopen_log_files,
+		sizeof (struct res_lib_cfg_reopen_log_files), CS_IPC_TIMEOUT_MS));
+
+	if (error != CS_OK) {
+		goto error_exit;
+	}
+
+	error = res_lib_cfg_reopen_log_files.header.error;
+
+error_exit:
+	(void)hdb_handle_put (&cfg_hdb, handle);
+
+	return (error);
+}

+ 1 - 1
lib/libcfg.verso

@@ -1 +1 @@
-7.0.0
+7.1.0

+ 2 - 2
man/cmap_keys.8

@@ -1,5 +1,5 @@
 .\"/*
-.\" * Copyright (c) 2012-2017 Red Hat, Inc.
+.\" * Copyright (c) 2012-2018 Red Hat, Inc.
 .\" *
 .\" * All rights reserved.
 .\" *
@@ -31,7 +31,7 @@
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
 .\" */
-.TH "CMAP_KEYS" 8 "10/10/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.TH "CMAP_KEYS" 8 "2018-10-08" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
 
 .SH NAME
 .P

+ 11 - 7
man/corosync-cfgtool.8

@@ -1,5 +1,5 @@
 .\" 
-.\" * Copyright (C) 2010 Red Hat, Inc.
+.\" * Copyright (C) 2010-2018 Red Hat, Inc.
 .\" *
 .\" * All rights reserved.
 .\" *
@@ -31,11 +31,11 @@
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
 .\" */
-.TH "COROSYNC-CFGTOOL" "8" "2010-05-30" "" ""
+.TH "COROSYNC-CFGTOOL" "8" "2018-10-15" "" ""
 .SH "NAME"
 corosync-cfgtool \- An administrative tool for corosync.
 .SH "SYNOPSIS"
-.B corosync\-cfgtool [[\-i IP_address] [\-b] \-s] [\-R] [\-k nodeid] [\-a nodeid] [\-h] [\-H]
+.B corosync\-cfgtool [[\-i IP_address] [\-b] \-s] [\-R] [\-L] [\-k nodeid] [\-a nodeid] [\-h] [\-H]
 .SH "DESCRIPTION"
 .B corosync\-cfgtool
 A tool for displaying and configuring active parameters within corosync.
@@ -70,19 +70,23 @@ The output will be:
 LINK ID 0:
     id     = 192.168.100.80
     status = 333
-.TP 
+.TP
 .B -R
 Tell all instances of corosync in this cluster to reload corosync.conf.
-.TP 
+.TP
+.B -L
+Tell corosync to reopen all logging files. In contrast to other subcommands,
+nothing is displayed on terminal if call is successful.
+.TP
 .B -k
 Kill a node identified by node id.
-.TP 
+.TP
 .B -a
 Display the IP address(es) of a node.
 .TP
 .B -h
 Print basic usage.
-.TP 
+.TP
 .B -H
 Shutdown corosync cleanly on this node.
 .SH "SEE ALSO"

+ 35 - 2
tools/corosync-cfgtool.c

@@ -69,6 +69,7 @@ enum user_action {
 	ACTION_NOOP=0,
 	ACTION_LINKSTATUS_GET,
 	ACTION_RELOAD_CONFIG,
+	ACTION_REOPEN_LOG_FILES,
 	ACTION_SHUTDOW,
 	ACTION_SHOWADDR,
 	ACTION_KILL_NODE,
@@ -189,6 +190,31 @@ static int reload_config_do (void)
 	return (rc);
 }
 
+static int reopen_log_files_do (void)
+{
+	cs_error_t result;
+	corosync_cfg_handle_t handle;
+	int rc;
+
+	rc = 0;
+
+	result = corosync_cfg_initialize (&handle, NULL);
+	if (result != CS_OK) {
+		fprintf (stderr, "Could not initialize corosync configuration API error %s\n", cs_strerror(result));
+		exit (1);
+	}
+
+	result = corosync_cfg_reopen_log_files (handle);
+	if (result != CS_OK) {
+		fprintf (stderr, "Could not reopen corosync logging files. Error %s\n", cs_strerror(result));
+		rc = (int)result;
+	}
+
+	(void)corosync_cfg_finalize (handle);
+
+	return (rc);
+}
+
 static void shutdown_do(void)
 {
 	cs_error_t result;
@@ -280,13 +306,14 @@ static void killnode_do(unsigned int nodeid)
 
 static void usage_do (void)
 {
-	printf ("corosync-cfgtool [[-i <interface ip>] [-b] -s] [-R] [-k nodeid] [-a nodeid] [-h] [-H]\n\n");
+	printf ("corosync-cfgtool [[-i <interface ip>] [-b] -s] [-R] [-L] [-k nodeid] [-a nodeid] [-h] [-H]\n\n");
 	printf ("A tool for displaying and configuring active parameters within corosync.\n");
 	printf ("options:\n");
 	printf ("\t-i\tFinds only information about the specified interface IP address when used with -s..\n");
 	printf ("\t-s\tDisplays the status of the current links on this node(UDP/UDPU), while extended status for KNET.\n");
 	printf ("\t-b\tDisplays the brief status of the current links on this node when used with -s.(KNET only)\n");
 	printf ("\t-R\tTell all instances of corosync in this cluster to reload corosync.conf.\n");
+	printf ("\t-L\tTell corosync to reopen all logging files.\n");
 	printf ("\t-k\tKill a node identified by node id.\n");
 	printf ("\t-a\tDisplay the IP address(es) of a node\n");
 	printf ("\t-h\tPrint basic usage.\n");
@@ -294,7 +321,7 @@ static void usage_do (void)
 }
 
 int main (int argc, char *argv[]) {
-	const char *options = "i:sbrRk:a:hH";
+	const char *options = "i:sbrRLk:a:hH";
 	int opt;
 	unsigned int nodeid = 0;
 	char interface_name[128] = "";
@@ -317,6 +344,9 @@ int main (int argc, char *argv[]) {
 		case 'R':
 			action = ACTION_RELOAD_CONFIG;
 			break;
+		case 'L':
+			action = ACTION_REOPEN_LOG_FILES;
+			break;
 		case 'k':
 			nodeid = atoi (optarg);
 			action = ACTION_KILL_NODE;
@@ -343,6 +373,9 @@ int main (int argc, char *argv[]) {
 	case ACTION_RELOAD_CONFIG:
 		rc = reload_config_do();
 		break;
+	case ACTION_REOPEN_LOG_FILES:
+		rc = reopen_log_files_do();
+		break;
 	case ACTION_KILL_NODE:
 		killnode_do(nodeid);
 		break;