mirror of
https://git.proxmox.com/git/mirror_corosync
synced 2026-02-04 21:11:14 +00:00
qdevice: Add support for daemonize
Also local unix socket is now created. In future this is going to be used for qdevice-tool, for now it's used only for handling SIGINT and SIGTERM. Signed-off-by: Jan Friesse <jfriesse@redhat.com>
This commit is contained in:
parent
1ec61e33cc
commit
ea7611a9dd
@ -53,7 +53,7 @@ corosync_qdevice_SOURCES = corosync-qdevice.c qdevice-cmap.c qdevice-instance.c
|
||||
qdevice-model.c \
|
||||
qdevice-model-net.c \
|
||||
qdevice-net-instance.c dynar.c send-buffer-list.c timer-list.c \
|
||||
msg.c msgio.c nss-sock.c tlv.c \
|
||||
msg.c msgio.c nss-sock.c tlv.c unix-socket.c qdevice-local-socket.c \
|
||||
qdevice-net-poll.c qdevice-net-send.c qdevice-net-votequorum.c \
|
||||
qdevice-net-socket.c qdevice-net-nss.c qdevice-net-msg-received.c \
|
||||
qdevice-net-cast-vote-timer.c qdevice-net-echo-request-timer.c \
|
||||
|
||||
@ -32,25 +32,126 @@
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "qdevice-config.h"
|
||||
#include "qdevice-cmap.h"
|
||||
#include "qdevice-log.h"
|
||||
#include "qdevice-model.h"
|
||||
#include "qdevice-votequorum.h"
|
||||
#include "qdevice-local-socket.h"
|
||||
#include "utils.h"
|
||||
|
||||
struct qdevice_instance *global_instance;
|
||||
|
||||
static void
|
||||
signal_int_handler(int sig)
|
||||
{
|
||||
qdevice_log(LOG_DEBUG, "SIGINT received - closing local unix socket");
|
||||
qdevice_local_socket_destroy(global_instance);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_term_handler(int sig)
|
||||
{
|
||||
qdevice_log(LOG_DEBUG, "SIGTERM received - closing server socket");
|
||||
qdevice_local_socket_destroy(global_instance);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_handlers_register(void)
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_handler = signal_int_handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = SA_RESTART;
|
||||
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
|
||||
act.sa_handler = signal_term_handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = SA_RESTART;
|
||||
|
||||
sigaction(SIGTERM, &act, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
printf("usage: %s [-dfh]\n", QDEVICE_PROGRAM_NAME);
|
||||
}
|
||||
|
||||
static void
|
||||
cli_parse(int argc, char * const argv[], int *foreground, int *force_debug)
|
||||
{
|
||||
int ch;
|
||||
|
||||
*foreground = 0;
|
||||
*force_debug = 0;
|
||||
|
||||
while ((ch = getopt(argc, argv, "dfh")) != -1) {
|
||||
switch (ch) {
|
||||
case 'd':
|
||||
*force_debug = 1;
|
||||
break;
|
||||
case 'f':
|
||||
*foreground = 1;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
usage();
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
main(int argc, char * const argv[])
|
||||
{
|
||||
struct qdevice_instance instance;
|
||||
int foreground;
|
||||
int force_debug;
|
||||
int lock_file;
|
||||
int another_instance_running;
|
||||
|
||||
cli_parse(argc, argv, &foreground, &force_debug);
|
||||
|
||||
qdevice_instance_init(&instance);
|
||||
global_instance = &instance;
|
||||
|
||||
qdevice_cmap_init(&instance);
|
||||
qdevice_log_init(&instance);
|
||||
qdevice_log_init(&instance, force_debug);
|
||||
|
||||
/*
|
||||
* Daemonize
|
||||
*/
|
||||
if (!foreground) {
|
||||
utils_tty_detach();
|
||||
}
|
||||
|
||||
if ((lock_file = utils_flock(QDEVICE_LOCK_FILE, getpid(), &another_instance_running)) == -1) {
|
||||
if (another_instance_running) {
|
||||
qdevice_log(LOG_ERR, "Another instance is running");
|
||||
} else {
|
||||
qdevice_log_err(LOG_ERR, "Can't aquire lock");
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
qdevice_log(LOG_DEBUG, "Initializing votequorum");
|
||||
qdevice_votequorum_init(&instance);
|
||||
|
||||
qdevice_log(LOG_DEBUG, "Initializing local socket");
|
||||
if (qdevice_local_socket_init(&instance) != 0) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
signal_handlers_register();
|
||||
|
||||
qdevice_log(LOG_DEBUG, "Registering qdevice models");
|
||||
qdevice_model_register_all();
|
||||
|
||||
@ -87,6 +188,7 @@ main(void)
|
||||
qdevice_log(LOG_DEBUG, "Destorying qdevice model");
|
||||
qdevice_model_destroy(&instance);
|
||||
|
||||
qdevice_local_socket_destroy(&instance);
|
||||
qdevice_votequorum_destroy(&instance);
|
||||
qdevice_cmap_destroy(&instance);
|
||||
qdevice_log_close(&instance);
|
||||
|
||||
@ -32,14 +32,14 @@
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "qnet-config.h"
|
||||
|
||||
#include "nss-sock.h"
|
||||
#include "qnetd-algorithm.h"
|
||||
#include "qnetd-instance.h"
|
||||
@ -224,7 +224,7 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
printf("usage: %s [-46df] [-l listen_addr] [-p listen_port] [-s tls]\n", QNETD_PROGRAM_NAME);
|
||||
printf("usage: %s [-46dfh] [-l listen_addr] [-p listen_port] [-s tls]\n", QNETD_PROGRAM_NAME);
|
||||
printf("%14s[-c client_cert_required] [-m max_clients]\n", "");
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ cli_parse(int argc, char * const argv[], char **host_addr, uint16_t *host_port,
|
||||
*max_clients = QNETD_DEFAULT_MAX_CLIENTS;
|
||||
*address_family = PR_AF_UNSPEC;
|
||||
|
||||
while ((ch = getopt(argc, argv, "46fdc:l:m:p:s:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "46dfhc:l:m:p:s:")) != -1) {
|
||||
switch (ch) {
|
||||
case '4':
|
||||
*address_family = PR_AF_INET;
|
||||
@ -298,6 +298,7 @@ cli_parse(int argc, char * const argv[], char **host_addr, uint16_t *host_port,
|
||||
errx(1, "tls must be one of on, off, req");
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
usage();
|
||||
exit(1);
|
||||
@ -307,7 +308,7 @@ cli_parse(int argc, char * const argv[], char **host_addr, uint16_t *host_port,
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
main(int argc, char * const argv[])
|
||||
{
|
||||
struct qnetd_instance instance;
|
||||
char *host_addr;
|
||||
@ -320,6 +321,7 @@ main(int argc, char *argv[])
|
||||
size_t max_clients;
|
||||
PRIntn address_family;
|
||||
int lock_file;
|
||||
int another_instance_running;
|
||||
|
||||
cli_parse(argc, argv, &host_addr, &host_port, &foreground, &debug_log, &bump_log_priority,
|
||||
&tls_supported, &client_cert_required, &max_clients, &address_family);
|
||||
@ -340,7 +342,13 @@ main(int argc, char *argv[])
|
||||
utils_tty_detach();
|
||||
}
|
||||
|
||||
if ((lock_file = utils_flock(QNETD_LOCK_FILE, getpid(), qnetd_log_printf)) == -1) {
|
||||
if ((lock_file = utils_flock(QNETD_LOCK_FILE, getpid(), &another_instance_running)) == -1) {
|
||||
if (another_instance_running) {
|
||||
qnetd_log(LOG_ERR, "Another instance is running");
|
||||
} else {
|
||||
qnetd_log_err(LOG_ERR, "Can't acquire lock");
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
#ifndef _QDEVICE_CONFIG_H_
|
||||
#define _QDEVICE_CONFIG_H_
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <qb/qbdefs.h>
|
||||
#include <qb/qblog.h>
|
||||
|
||||
@ -47,10 +49,12 @@ extern "C" {
|
||||
* idea to change them as long as you are not 100% sure what you are doing.
|
||||
*/
|
||||
#define QDEVICE_LOCK_FILE LOCALSTATEDIR"/run/corosync-qdevice.pid"
|
||||
#define QDEVICE_LOCAL_SOCKET_FILE LOCALSTATEDIR"/run/corosync-qdevice.sock"
|
||||
#define QDEVICE_LOCAL_SOCKET_BACKLOG 10
|
||||
|
||||
#define QDEVICE_MAX_CS_TRY_AGAIN 10
|
||||
|
||||
#define QDEVICE_PROGRAM_NAME "qdevice-net"
|
||||
#define QDEVICE_PROGRAM_NAME "corosync-qdevice"
|
||||
#define QDEVICE_LOG_SUBSYS "QDEVICE"
|
||||
#define QDEVICE_LOG_DEFAULT_TO_STDERR 1
|
||||
#define QDEVICE_LOG_DEFAULT_TO_SYSLOG 1
|
||||
|
||||
@ -61,6 +61,8 @@ struct qdevice_instance {
|
||||
votequorum_handle_t votequorum_handle;
|
||||
int votequorum_poll_fd;
|
||||
|
||||
int local_socket_fd;
|
||||
|
||||
enum qdevice_model_type model_type;
|
||||
|
||||
uint32_t node_id;
|
||||
|
||||
73
qdevices/qdevice-local-socket.c
Normal file
73
qdevices/qdevice-local-socket.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Red Hat, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Jan Friesse (jfriesse@redhat.com)
|
||||
*
|
||||
* This software licensed under BSD license, the text of which follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the Red Hat, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "qdevice-config.h"
|
||||
#include "qdevice-log.h"
|
||||
#include "qdevice-local-socket.h"
|
||||
#include "unix-socket.h"
|
||||
|
||||
int
|
||||
qdevice_local_socket_init(struct qdevice_instance *instance)
|
||||
{
|
||||
int local_socket;
|
||||
|
||||
local_socket = unix_socket_server_create(QDEVICE_LOCAL_SOCKET_FILE, 1,
|
||||
QDEVICE_LOCAL_SOCKET_BACKLOG);
|
||||
if (local_socket < 0) {
|
||||
qdevice_log_err(LOG_ERR, "Can't create unix socket");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
instance->local_socket_fd = local_socket;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
qdevice_local_socket_destroy(struct qdevice_instance *instance)
|
||||
{
|
||||
|
||||
if (instance->local_socket_fd < 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (close(instance->local_socket_fd) != 0) {
|
||||
qdevice_log_err(LOG_WARNING, "Can't close unix socket");
|
||||
}
|
||||
|
||||
instance->local_socket_fd = -1;
|
||||
if (unlink(QDEVICE_LOCAL_SOCKET_FILE) != 0) {
|
||||
qdevice_log_err(LOG_WARNING, "Can't unlink unix socket");
|
||||
}
|
||||
}
|
||||
55
qdevices/qdevice-local-socket.h
Normal file
55
qdevices/qdevice-local-socket.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Red Hat, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Jan Friesse (jfriesse@redhat.com)
|
||||
*
|
||||
* This software licensed under BSD license, the text of which follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the Red Hat, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _QDEVICE_LOCAL_SOCKET_H_
|
||||
#define _QDEVICE_LOCAL_SOCKET_H_
|
||||
|
||||
#include "qdevice-instance.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct qdevice_local_socket {
|
||||
};
|
||||
|
||||
extern int qdevice_local_socket_init(struct qdevice_instance *instance);
|
||||
|
||||
extern void qdevice_local_socket_destroy(struct qdevice_instance *instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _QDEVICE_LOCAL_SOCKET_H_ */
|
||||
@ -36,6 +36,8 @@
|
||||
#include "qdevice-config.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int qdevice_log_global_force_debug;
|
||||
|
||||
struct qdevice_log_syslog_names {
|
||||
const char *prio_name;
|
||||
int priority;
|
||||
@ -271,6 +273,10 @@ qdevice_log_configure(struct qdevice_instance *instance)
|
||||
}
|
||||
strcat(log_format_stderr, log_format_syslog);
|
||||
|
||||
if (qdevice_log_global_force_debug) {
|
||||
debug = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally reconfigure log system
|
||||
*/
|
||||
@ -289,8 +295,10 @@ qdevice_log_configure(struct qdevice_instance *instance)
|
||||
}
|
||||
|
||||
void
|
||||
qdevice_log_init(struct qdevice_instance *instance)
|
||||
qdevice_log_init(struct qdevice_instance *instance, int force_debug)
|
||||
{
|
||||
qdevice_log_global_force_debug = force_debug;
|
||||
|
||||
qb_log_init(QDEVICE_PROGRAM_NAME, QDEVICE_LOG_DEFAULT_SYSLOG_FACILITY,
|
||||
QDEVICE_LOG_DEFAULT_SYSLOG_PRIORITY);
|
||||
|
||||
|
||||
@ -49,7 +49,10 @@ extern "C" {
|
||||
#define qdevice_log_nss(priority, str) qdevice_log(priority, "%s (%d): %s", \
|
||||
str, PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
|
||||
|
||||
extern void qdevice_log_init(struct qdevice_instance *instance);
|
||||
#define qdevice_log_err(priority, str) qdevice_log(priority, "%s (%d): %s", \
|
||||
str, errno, strerror(errno));
|
||||
|
||||
extern void qdevice_log_init(struct qdevice_instance *instance, int force_debug);
|
||||
|
||||
extern void qdevice_log_configure(struct qdevice_instance *instance);
|
||||
|
||||
|
||||
@ -32,9 +32,6 @@
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
#include "qdevice-model.h"
|
||||
@ -225,8 +222,8 @@ qdevice_model_net_run(struct qdevice_instance *instance)
|
||||
" Can't update cast vote timer vote");
|
||||
}
|
||||
|
||||
if (net_instance->disconnect_reason ==
|
||||
QDEVICE_NET_DISCONNECT_REASON_COROSYNC_CONNECTION_CLOSED) {
|
||||
if (net_instance->disconnect_reason == QDEVICE_NET_DISCONNECT_REASON_COROSYNC_CONNECTION_CLOSED ||
|
||||
net_instance->disconnect_reason == QDEVICE_NET_DISCONNECT_REASON_LOCAL_SOCKET_CLOSED) {
|
||||
try_connect = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -85,6 +85,9 @@ enum qdevice_net_disconnect_reason {
|
||||
/* Can't dispatch cmap or votequroum. This cannot be overwritten and always means end of qdevice-net */
|
||||
QDEVICE_NET_DISCONNECT_REASON_COROSYNC_CONNECTION_CLOSED,
|
||||
|
||||
/* Local socket closed is reasult of sigint */
|
||||
QDEVICE_NET_DISCONNECT_REASON_LOCAL_SOCKET_CLOSED,
|
||||
|
||||
/* It was not possible to establish connection with qnetd */
|
||||
QDEVICE_NET_DISCONNECT_REASON_CANT_CONNECT_TO_THE_SERVER,
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ qdevice_net_instance_init(struct qdevice_net_instance *instance, size_t initial_
|
||||
uint32_t sync_heartbeat_interval, uint32_t cast_vote_timer_interval,
|
||||
const char *host_addr, uint16_t host_port, const char *cluster_name,
|
||||
const struct tlv_tie_breaker *tie_breaker, uint32_t connect_timeout,
|
||||
int force_ip_version, int cmap_fd, int votequorum_fd)
|
||||
int force_ip_version, int cmap_fd, int votequorum_fd, int local_socket_fd)
|
||||
{
|
||||
|
||||
memset(instance, 0, sizeof(*instance));
|
||||
@ -94,6 +94,11 @@ qdevice_net_instance_init(struct qdevice_net_instance *instance, size_t initial_
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((instance->local_socket_poll_fd = PR_CreateSocketPollFd(local_socket_fd)) == NULL) {
|
||||
qdevice_log_nss(LOG_CRIT, "Can't create NSPR local socket poll fd");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -136,6 +141,10 @@ qdevice_net_instance_destroy(struct qdevice_net_instance *instance)
|
||||
qdevice_log_nss(LOG_WARNING, "Unable to close votequorum connection fd");
|
||||
}
|
||||
|
||||
if (PR_DestroySocketPollFd(instance->local_socket_poll_fd) != PR_SUCCESS) {
|
||||
qdevice_log_nss(LOG_WARNING, "Unable to close local socket poll fd");
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -337,7 +346,8 @@ qdevice_net_instance_init_from_cmap(struct qdevice_instance *instance)
|
||||
heartbeat_interval, sync_heartbeat_interval, cast_vote_timer_interval,
|
||||
host_addr, host_port, cluster_name, &tie_breaker, connect_timeout,
|
||||
force_ip_version,
|
||||
instance->cmap_poll_fd, instance->votequorum_poll_fd) == -1) {
|
||||
instance->cmap_poll_fd, instance->votequorum_poll_fd,
|
||||
instance->local_socket_fd) == -1) {
|
||||
qdevice_log(LOG_ERR, "Can't initialize qdevice-net instance");
|
||||
goto error_free_instance;
|
||||
}
|
||||
|
||||
@ -94,6 +94,7 @@ struct qdevice_net_instance {
|
||||
int schedule_disconnect;
|
||||
PRFileDesc *votequorum_poll_fd;
|
||||
PRFileDesc *cmap_poll_fd;
|
||||
PRFileDesc *local_socket_poll_fd;
|
||||
struct tlv_ring_id last_sent_ring_id;
|
||||
struct tlv_tie_breaker tie_breaker;
|
||||
void *algorithm_data;
|
||||
@ -112,7 +113,7 @@ extern int qdevice_net_instance_init(struct qdevice_net_instance *instance,
|
||||
uint32_t sync_heartbeat_interval, uint32_t cast_vote_timer_interval,
|
||||
const char *host_addr, uint16_t host_port, const char *cluster_name,
|
||||
const struct tlv_tie_breaker *tie_breaker, uint32_t connect_timeout, int force_ip_version,
|
||||
int cmap_fd, int votequorum_fd);
|
||||
int cmap_fd, int votequorum_fd, int local_socket_fd);
|
||||
|
||||
extern void qdevice_net_instance_clean(struct qdevice_net_instance *instance);
|
||||
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
enum qdevice_net_poll_pfd {
|
||||
QDEVICE_NET_POLL_VOTEQUORUM,
|
||||
QDEVICE_NET_POLL_CMAP,
|
||||
QDEVICE_NET_POLL_LOCAL_SOCKET,
|
||||
QDEVICE_NET_POLL_SOCKET,
|
||||
QDEVICE_NET_POLL_MAX_PFDS
|
||||
};
|
||||
@ -142,6 +143,13 @@ qdevice_net_poll_err_socket(struct qdevice_net_instance *instance, const PRPollD
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qdevice_net_poll_read_local_socket(struct qdevice_net_instance *instance)
|
||||
{
|
||||
|
||||
// qdevice_log(LOG_DEBUG, "READ ON LOCAL SOCKET");
|
||||
}
|
||||
|
||||
int
|
||||
qdevice_net_poll(struct qdevice_net_instance *instance)
|
||||
{
|
||||
@ -160,6 +168,10 @@ qdevice_net_poll(struct qdevice_net_instance *instance)
|
||||
pfds[QDEVICE_NET_POLL_CMAP].in_flags = PR_POLL_READ;
|
||||
no_pfds++;
|
||||
|
||||
pfds[QDEVICE_NET_POLL_LOCAL_SOCKET].fd = instance->local_socket_poll_fd;
|
||||
pfds[QDEVICE_NET_POLL_LOCAL_SOCKET].in_flags = PR_POLL_READ;
|
||||
no_pfds++;
|
||||
|
||||
if (instance->state == QDEVICE_NET_INSTANCE_STATE_WAITING_CONNECT &&
|
||||
!instance->non_blocking_client.destroyed) {
|
||||
pfds[QDEVICE_NET_POLL_SOCKET].fd = instance->non_blocking_client.socket;
|
||||
@ -190,6 +202,9 @@ qdevice_net_poll(struct qdevice_net_instance *instance)
|
||||
case QDEVICE_NET_POLL_CMAP:
|
||||
qdevice_net_poll_read_cmap(instance);
|
||||
break;
|
||||
case QDEVICE_NET_POLL_LOCAL_SOCKET:
|
||||
qdevice_net_poll_read_local_socket(instance);
|
||||
break;
|
||||
default:
|
||||
qdevice_log(LOG_CRIT, "Unhandled read on poll descriptor %u", i);
|
||||
exit(1);
|
||||
@ -216,6 +231,18 @@ qdevice_net_poll(struct qdevice_net_instance *instance)
|
||||
case QDEVICE_NET_POLL_SOCKET:
|
||||
qdevice_net_poll_err_socket(instance, &pfds[i]);
|
||||
break;
|
||||
case QDEVICE_NET_POLL_LOCAL_SOCKET:
|
||||
if (pfds[i].out_flags != PR_POLL_NVAL) {
|
||||
qdevice_log(LOG_CRIT, "POLLERR (%u) on local socket",
|
||||
pfds[i].out_flags);
|
||||
exit(1);
|
||||
} else {
|
||||
qdevice_log(LOG_DEBUG, "Local socket is closed");
|
||||
instance->schedule_disconnect = 1;
|
||||
instance->disconnect_reason =
|
||||
QDEVICE_NET_DISCONNECT_REASON_LOCAL_SOCKET_CLOSED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
qdevice_log(LOG_CRIT, "Unhandled error on poll descriptor %u", i);
|
||||
exit(1);
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
#ifndef _QNET_CONFIG_H_
|
||||
#define _QNET_CONFIG_H_
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "tlv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -49,6 +49,9 @@ extern "C" {
|
||||
#define qnetd_log_nss(priority, str) qnetd_log_printf(priority, "%s (%d): %s", \
|
||||
str, PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
|
||||
|
||||
#define qnetd_log_err(priority, str) qnetd_log_printf(priority, "%s (%d): %s", \
|
||||
str, errno, strerror(errno))
|
||||
|
||||
extern void qnetd_log_init(int target);
|
||||
|
||||
extern void qnetd_log_printf(int priority, const char *format, ...)
|
||||
|
||||
104
qdevices/unix-socket.c
Normal file
104
qdevices/unix-socket.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Red Hat, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Jan Friesse (jfriesse@redhat.com)
|
||||
*
|
||||
* This software licensed under BSD license, the text of which follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the Red Hat, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "unix-socket.h"
|
||||
|
||||
static int
|
||||
unix_socket_set_non_blocking(int fd)
|
||||
{
|
||||
int flags;
|
||||
|
||||
flags = fcntl(fd, F_GETFL, NULL);
|
||||
|
||||
if (flags < 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
flags |= O_NONBLOCK;
|
||||
if (fcntl(fd, F_SETFL, flags) < 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
unix_socket_server_create(const char *path, int non_blocking, int backlog)
|
||||
{
|
||||
int s;
|
||||
struct sockaddr_un sun;
|
||||
|
||||
if (strlen(path) >= sizeof(sun.sun_path)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
memset(&sun, 0, sizeof(sun));
|
||||
sun.sun_family = AF_UNIX;
|
||||
|
||||
strncpy(sun.sun_path, path, sizeof(sun.sun_path));
|
||||
unlink(path);
|
||||
if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) != 0) {
|
||||
close(s);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (non_blocking) {
|
||||
if (unix_socket_set_non_blocking(s) != 0) {
|
||||
close(s);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (listen(s, backlog) != 0) {
|
||||
close(s);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (s);
|
||||
}
|
||||
51
qdevices/unix-socket.h
Normal file
51
qdevices/unix-socket.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Red Hat, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Jan Friesse (jfriesse@redhat.com)
|
||||
*
|
||||
* This software licensed under BSD license, the text of which follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the Red Hat, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _UNIX_SOCKET_H_
|
||||
#define _UNIX_SOCKET_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int unix_socket_server_create(const char *path, int non_blocking, int backlog);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _UNIX_SOCKET_H_ */
|
||||
@ -69,18 +69,17 @@ utils_parse_bool_str(const char *str)
|
||||
}
|
||||
|
||||
int
|
||||
utils_flock(const char *lockfile, pid_t pid,
|
||||
void (*log_printf)(int priority, const char *format, ...))
|
||||
utils_flock(const char *lockfile, pid_t pid, int *another_instance_running)
|
||||
{
|
||||
struct flock lock;
|
||||
char pid_s[17];
|
||||
int fd_flag;
|
||||
int lf;
|
||||
|
||||
*another_instance_running = 0;
|
||||
|
||||
lf = open(lockfile, O_WRONLY | O_CREAT, 0640);
|
||||
if (lf == -1) {
|
||||
log_printf(LOG_ERR, "Cannot create lock file. Error was %s", strerror(errno));
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -96,18 +95,16 @@ retry_fcntl:
|
||||
break;
|
||||
case EAGAIN:
|
||||
case EACCES:
|
||||
log_printf(LOG_ERR, "Another instance is already running.");
|
||||
*another_instance_running = 1;
|
||||
goto error_close;
|
||||
break;
|
||||
default:
|
||||
log_printf(LOG_ERR, "Cannot aquire lock. Error was %s", strerror(errno));
|
||||
goto error_close;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ftruncate(lf, 0) == -1) {
|
||||
log_printf(LOG_ERR, "Cannot truncate lock file. Error was %s", strerror(errno));
|
||||
goto error_close_unlink;
|
||||
}
|
||||
|
||||
@ -119,21 +116,15 @@ retry_write:
|
||||
if (errno == EINTR) {
|
||||
goto retry_write;
|
||||
} else {
|
||||
log_printf(LOG_ERR, "Cannot write pid to lock file. Error was %s",
|
||||
strerror(errno));
|
||||
goto error_close_unlink;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fd_flag = fcntl(lf, F_GETFD, 0)) == -1) {
|
||||
log_printf(LOG_ERR, "Cannot get close-on exec flag for lock file. Error was %s",
|
||||
strerror(errno));
|
||||
goto error_close_unlink;
|
||||
}
|
||||
fd_flag |= FD_CLOEXEC;
|
||||
if (fcntl(lf, F_SETFD, fd_flag) == -1) {
|
||||
log_printf(LOG_ERR, "Cannot set close-on-exec flag for lock file. Error was %s",
|
||||
strerror(errno));
|
||||
goto error_close_unlink;
|
||||
}
|
||||
|
||||
|
||||
@ -45,8 +45,7 @@ extern "C" {
|
||||
extern int utils_parse_bool_str(const char *str);
|
||||
|
||||
extern int utils_flock(const char *lockfile, pid_t pid,
|
||||
void (*log_printf)(int priority, const char *format, ...)
|
||||
__attribute__((__format__(__printf__, 2, 3))));
|
||||
int *another_instance_running);
|
||||
|
||||
extern void utils_tty_detach(void);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user