1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-06 13:18:07 +03:00
samba-mirror/ctdb/common/sock_daemon.h
Amitay Isaacs b67cc00c93 ctdb-common: Move PID file creation to sock_daemon_run_send()
Only create PID file when actually starting the daemon, rather than
when setting up the context.  This will facilitate future changes.

Tweak test to confirm that PID file is no longer created during setup.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
2017-08-29 11:14:09 +02:00

219 lines
6.9 KiB
C

/*
A server based on unix domain socket
Copyright (C) Amitay Isaacs 2016
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CTDB_SOCK_DAEMON_H__
#define __CTDB_SOCK_DAEMON_H__
#include <talloc.h>
#include <tevent.h>
#include "common/logging.h"
/**
* @file sock_daemon.h
*
* @brief A framework for a server based on unix-domain sockets.
*
* This abstraction allows to build simple servers that communicate using
* unix-domain sockets. It takes care of the common boilerplate.
*/
/**
* @brief The abstract socket daemon context
*/
struct sock_daemon_context;
/**
* @brief The abstract socket client context
*/
struct sock_client_context;
/**
* @brief The callback routines called during daemon life cycle
*
* startup() is called when the daemon starts running
* either via sock_daemon_run() or via sock_daemon_run_send()
* reconfigure() is called when process receives SIGUSR1 or SIGHUP
* shutdown() is called when process receives SIGINT or SIGTERM or
* when wait computation has finished
*
* wait_send() starts the async computation to keep running the daemon
* wait_recv() ends the async computation to keep running the daemon
*
* If wait_send()/wait_recv() is NULL, then daemon will keep running forever.
* If wait_send() returns req, then when req is over, daemon will shutdown.
*/
struct sock_daemon_funcs {
void (*startup)(void *private_data);
void (*reconfigure)(void *private_data);
void (*shutdown)(void *private_data);
struct tevent_req * (*wait_send)(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
void *private_data);
bool (*wait_recv)(struct tevent_req *req, int *perr);
};
/**
* @brief The callback routines called for an unix-domain socket
*
* connect() is called when there is a new connection
*
* @param[in] client The new socket client context
* @param[in] private_data Private data set with the socket
* @retun true if connection should be accepted, false otherwise
*
*
* disconnect() is called when client closes connection
*
* @param[in] client The socket client context
* @param[in] private_data Private data associated with the socket
*
*
* read_send() starts the async computation to process data on the socket
*
* @param[in] mem_ctx Talloc memory context
* @param[in] ev Tevent context
* @param[in] client The socket client context
* @param[in] buf Data received from the client
* @param[in] buflen Length of the data
* @param[i] private_data Private data associatedwith the socket
* @return new tevent reques, or NULL on failure
*
*
* read_recv() ends the async computation to process data on the socket
*
* @param[in] req Tevent request
* @param[out] perr errno in case of failure
* @return true on success, false on failure
*
*/
struct sock_socket_funcs {
bool (*connect)(struct sock_client_context *client,
void *private_data);
void (*disconnect)(struct sock_client_context *client,
void *private_data);
struct tevent_req * (*read_send)(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sock_client_context *client,
uint8_t *buf, size_t buflen,
void *private_data);
bool (*read_recv)(struct tevent_req *req, int *perr);
};
/**
* @brief Async computation to send data to the client
*
* @param[in] mem_ctx Talloc memory context
* @param[in] ev Tevent context
* @param[in] client The socket client context
* @param[in] buf Data to be sent to the client
* @param[in] buflen Length of the data
* @return new tevent request, or NULL on failure
*/
struct tevent_req *sock_socket_write_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sock_client_context *client,
uint8_t *buf, size_t buflen);
/**
* @brief Async computation end to send data to client
*
* @param[in] req Tevent request
* @param[out] perr errno in case of failure
* @return true on success, false on failure
*/
bool sock_socket_write_recv(struct tevent_req *req, int *perr);
/**
* @brief Create a new socket daemon
*
* @param[in] mem_ctx Talloc memory context
* @param[in] daemon_name Name of the daemon, used for logging
* @param[in] logging Logging setup string
* @param[in] debug_level Debug level to log at
* @param[in] funcs Socket daemon callback routines
* @param[in] private_data Private data associated with callback routines
* @param[out] result New socket daemon context
* @return 0 on success, errno on failure
*/
int sock_daemon_setup(TALLOC_CTX *mem_ctx, const char *daemon_name,
const char *logging, const char *debug_level,
struct sock_daemon_funcs *funcs,
void *private_data,
struct sock_daemon_context **result);
/**
* @brief Create and listen to the unix domain socket
*
* @param[in] sockd Socket daemon context
* @param[in] sockpath Unix domain socket path
* @param[in] funcs socket callback routines
* @param[in] private_data Private data associated with callback routines
* @return 0 on success, errno on failure
*/
int sock_daemon_add_unix(struct sock_daemon_context *sockd,
const char *sockpath,
struct sock_socket_funcs *funcs,
void *private_data);
/**
* @brief Async computation start to run a socket daemon
*
* @param[in] mem_ctx Talloc memory context
* @param[in] ev Tevent context
* @param[in] sockd The socket daemon context
* @param[in] pidfile PID file to create, NULL if no PID file required
* @param[in] pid_watch PID to watch. If PID goes away, shutdown.
* @return new tevent request, NULL on failure
*/
struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sock_daemon_context *sockd,
const char *pidfile,
pid_t pid_watch);
/**
* @brief Async computation end to run a socket daemon
*
* @param[in] req Tevent request
* @param[out] perr errno in case of failure
* @return true on success, false on failure
*/
bool sock_daemon_run_recv(struct tevent_req *req, int *perr);
/**
* @brief Sync way to start a daemon
*
* @param[in] ev Tevent context
* @param[in] sockd The socket daemon context
* @param[in] pidfile PID file to create, NULL if no PID file required
* @param[in] pid_watch PID to watch. If PID goes away, shutdown.
* @return 0 on success, errno on failure
*
* This call will return only on shutdown of the daemon
*/
int sock_daemon_run(struct tevent_context *ev,
struct sock_daemon_context *sockd,
const char *pidfile,
pid_t pid_watch);
#endif /* __CTDB_SOCK_DAEMON_H__ */