mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +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
|
||||
|
||||
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)
|
||||
{
|
||||
if (unlink(file))
|
||||
@ -155,6 +202,7 @@ static void _daemonise(void)
|
||||
|
||||
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
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* NB. Past this point, exit is not allowed. You have to return to this
|
||||
* function at all costs. More or less.
|
||||
* NB. Take care to not keep stale locks around. Best not exit(...)
|
||||
* after this point.
|
||||
*/
|
||||
if (dm_create_lockfile(s.pidfile) == 0)
|
||||
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");
|
||||
#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. */
|
||||
if (!s.foreground)
|
||||
kill(getppid(), SIGTERM);
|
||||
|
||||
while (!_shutdown_requested) {
|
||||
while (!_shutdown_requested && !failed) {
|
||||
/* TODO: do work */
|
||||
}
|
||||
|
||||
syslog(LOG_NOTICE, "%s shutting down", s.name);
|
||||
closelog();
|
||||
remove_lockfile(s.pidfile);
|
||||
if (failed)
|
||||
exit(1);
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ typedef struct {
|
||||
unsigned foreground:1;
|
||||
const char *name;
|
||||
const char *pidfile;
|
||||
const char *socket_path;
|
||||
|
||||
/* Global runtime info maintained by the framework. */
|
||||
int socket_fd;
|
||||
|
||||
void *private; /* the global daemon state */
|
||||
} daemon_state;
|
||||
|
Loading…
x
Reference in New Issue
Block a user