1
0
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:
Petr Rockai 2011-05-13 09:34:12 +00:00
parent d7448a721b
commit 73ffd6e748
2 changed files with 63 additions and 3 deletions

View File

@ -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);
}

View File

@ -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;