1
0
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:
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 #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);
} }

View File

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