mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-11 20:58:50 +03:00
More scavenging of common daemon code, this time the clvmd local socket setup
sequence.
This commit is contained in:
parent
d7448a721b
commit
73ffd6e748
@ -79,6 +79,53 @@ static int _set_oom_adj(int val)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int _open_socket(daemon_state s)
|
||||||
|
{
|
||||||
|
int fd = -1;
|
||||||
|
struct sockaddr_un sockaddr;
|
||||||
|
mode_t old_mask;
|
||||||
|
|
||||||
|
(void) dm_prepare_selinux_context(s.socket_path, S_IFSOCK);
|
||||||
|
old_mask = umask(0077);
|
||||||
|
|
||||||
|
/* Open local socket */
|
||||||
|
fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
log_error("Can't create local socket: %m");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Close-on-exec & non-blocking */
|
||||||
|
if (fcntl(fd, F_SETFD, 1))
|
||||||
|
DEBUGLOG("setting CLOEXEC on socket fd %d failed: %s\n", fd, strerror(errno));
|
||||||
|
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
|
||||||
|
|
||||||
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
|
memcpy(sockaddr.sun_path, s.socket_path, strlen(s.socket_path));
|
||||||
|
sockaddr.sun_family = AF_UNIX;
|
||||||
|
|
||||||
|
if (bind(fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
|
||||||
|
log_error("can't bind local socket: %m");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (listen(fd, 1) != 0) {
|
||||||
|
log_error("listen local: %m");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
umask(old_mask);
|
||||||
|
(void) dm_prepare_selinux_context(NULL, 0);
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (fd >= 0) {
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
static void remove_lockfile(const char *file)
|
static void remove_lockfile(const char *file)
|
||||||
{
|
{
|
||||||
if (unlink(file))
|
if (unlink(file))
|
||||||
@ -155,6 +202,7 @@ static void _daemonise(void)
|
|||||||
|
|
||||||
void daemon_start(daemon_state s, handle_request r)
|
void daemon_start(daemon_state s, handle_request r)
|
||||||
{
|
{
|
||||||
|
int failed = 0;
|
||||||
/*
|
/*
|
||||||
* Switch to C locale to avoid reading large locale-archive file used by
|
* Switch to C locale to avoid reading large locale-archive file used by
|
||||||
* some glibc (on some distributions it takes over 100MB). Some daemons
|
* some glibc (on some distributions it takes over 100MB). Some daemons
|
||||||
@ -172,8 +220,8 @@ void daemon_start(daemon_state s, handle_request r)
|
|||||||
(void) dm_prepare_selinux_context(s.pidfile, S_IFREG);
|
(void) dm_prepare_selinux_context(s.pidfile, S_IFREG);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NB. Past this point, exit is not allowed. You have to return to this
|
* NB. Take care to not keep stale locks around. Best not exit(...)
|
||||||
* function at all costs. More or less.
|
* after this point.
|
||||||
*/
|
*/
|
||||||
if (dm_create_lockfile(s.pidfile) == 0)
|
if (dm_create_lockfile(s.pidfile) == 0)
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -190,15 +238,23 @@ void daemon_start(daemon_state s, handle_request r)
|
|||||||
syslog(LOG_ERR, "Failed to set oom_adj to protect against OOM killer");
|
syslog(LOG_ERR, "Failed to set oom_adj to protect against OOM killer");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (s.socket_path) {
|
||||||
|
s.socket_fd = _open_socket(s);
|
||||||
|
if (s.socket_fd < 0)
|
||||||
|
failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Signal parent, letting them know we are ready to go. */
|
/* Signal parent, letting them know we are ready to go. */
|
||||||
if (!s.foreground)
|
if (!s.foreground)
|
||||||
kill(getppid(), SIGTERM);
|
kill(getppid(), SIGTERM);
|
||||||
|
|
||||||
while (!_shutdown_requested) {
|
while (!_shutdown_requested && !failed) {
|
||||||
/* TODO: do work */
|
/* TODO: do work */
|
||||||
}
|
}
|
||||||
|
|
||||||
syslog(LOG_NOTICE, "%s shutting down", s.name);
|
syslog(LOG_NOTICE, "%s shutting down", s.name);
|
||||||
closelog();
|
closelog();
|
||||||
remove_lockfile(s.pidfile);
|
remove_lockfile(s.pidfile);
|
||||||
|
if (failed)
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,10 @@ typedef struct {
|
|||||||
unsigned foreground:1;
|
unsigned foreground:1;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *pidfile;
|
const char *pidfile;
|
||||||
|
const char *socket_path;
|
||||||
|
|
||||||
|
/* Global runtime info maintained by the framework. */
|
||||||
|
int socket_fd;
|
||||||
|
|
||||||
void *private; /* the global daemon state */
|
void *private; /* the global daemon state */
|
||||||
} daemon_state;
|
} daemon_state;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user