public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2/daemons/common daemon-server.c
@ 2012-01-15 10:33 mornfall
0 siblings, 0 replies; 5+ messages in thread
From: mornfall @ 2012-01-15 10:33 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: mornfall@sourceware.org 2012-01-15 10:33:41
Modified files:
daemons/common : daemon-server.c
Log message:
Fix a couple of resource leaks in daemon-common server code -- filehandles and
unjoined threads were leaked for each connection.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.c.diff?cvsroot=lvm2&r1=1.14&r2=1.15
--- LVM2/daemons/common/daemon-server.c 2011/09/17 14:49:18 1.14
+++ LVM2/daemons/common/daemon-server.c 2012/01/15 10:33:41 1.15
@@ -251,9 +251,6 @@
if (!req.cft)
fprintf(stderr, "error parsing request:\n %s\n", req.buffer);
res = b->s.handler(b->s, b->client, req);
- if (req.cft)
- dm_config_destroy(req.cft);
- dm_free(req.buffer);
if (!res.buffer) {
dm_config_write_node(res.cft->root, buffer_line, &res);
@@ -261,12 +258,17 @@
dm_config_destroy(res.cft);
}
+ if (req.cft)
+ dm_config_destroy(req.cft);
+ dm_free(req.buffer);
+
write_buffer(b->client.socket_fd, res.buffer, strlen(res.buffer));
free(res.buffer);
}
fail:
/* TODO what should we really do here? */
+ close(b->client.socket_fd);
free(baton);
return NULL;
}
@@ -291,6 +293,8 @@
if (pthread_create(&baton->client.thread_id, NULL, client_thread, baton))
return 0;
+ pthread_detach(baton->client.thread_id);
+
return 1;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* LVM2/daemons/common daemon-server.c
@ 2012-02-28 14:25 zkabelac
0 siblings, 0 replies; 5+ messages in thread
From: zkabelac @ 2012-02-28 14:25 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: zkabelac@sourceware.org 2012-02-28 14:25:37
Modified files:
daemons/common : daemon-server.c
Log message:
Check for failing dm_asprintf
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.c.diff?cvsroot=lvm2&r1=1.18&r2=1.19
--- LVM2/daemons/common/daemon-server.c 2012/02/28 13:05:21 1.18
+++ LVM2/daemons/common/daemon-server.c 2012/02/28 14:25:37 1.19
@@ -339,18 +339,23 @@
static int buffer_rewrite(char **buf, const char *format, const char *string) {
char *old = *buf;
- dm_asprintf(buf, format, *buf, string);
+ int r = dm_asprintf(buf, format, *buf, string);
+
dm_free(old);
- return 0;
+
+ return (r < 0) ? 0 : 1;
}
static int buffer_line(const char *line, void *baton) {
response *r = baton;
- if (r->buffer)
- buffer_rewrite(&r->buffer, "%s\n%s", line);
- else
- dm_asprintf(&r->buffer, "%s\n", line);
- return 0;
+
+ if (r->buffer) {
+ if (!buffer_rewrite(&r->buffer, "%s\n%s", line))
+ return 0;
+ } else if (dm_asprintf(&r->buffer, "%s\n", line) < 0)
+ return 0;
+
+ return 1;
}
static response builtin_handler(daemon_state s, client_handle h, request r)
@@ -387,7 +392,8 @@
if (!res.buffer) {
dm_config_write_node(res.cft->root, buffer_line, &res);
- buffer_rewrite(&res.buffer, "%s\n\n", NULL);
+ if (!buffer_rewrite(&res.buffer, "%s\n\n", NULL))
+ goto fail;
dm_config_destroy(res.cft);
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* LVM2/daemons/common daemon-server.c
@ 2012-02-28 13:05 prajnoha
0 siblings, 0 replies; 5+ messages in thread
From: prajnoha @ 2012-02-28 13:05 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: prajnoha@sourceware.org 2012-02-28 13:05:21
Modified files:
daemons/common : daemon-server.c
Log message:
Add support for systemd socket handover for common daemon-server code and also add support for new OOM killer adjustment interface.
This code is already a part of dmeventd, but it's modified slightly to check
sockets instead of FIFOs.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.c.diff?cvsroot=lvm2&r1=1.17&r2=1.18
--- LVM2/daemons/common/daemon-server.c 2012/02/23 23:52:11 1.17
+++ LVM2/daemons/common/daemon-server.c 2012/02/28 13:05:21 1.18
@@ -43,6 +43,7 @@
#endif
static volatile sig_atomic_t _shutdown_requested = 0;
+static int _systemd_activation = 0;
static void _exit_handler(int sig __attribute__((unused)))
{
@@ -50,41 +51,148 @@
}
#ifdef linux
-# define OOM_ADJ_FILE "/proc/self/oom_adj"
-# include <stdio.h>
+
+#include <stddef.h>
+
+/*
+ * Kernel version 2.6.36 and higher has
+ * new OOM killer adjustment interface.
+ */
+# define OOM_ADJ_FILE_OLD "/proc/self/oom_adj"
+# define OOM_ADJ_FILE "/proc/self/oom_score_adj"
/* From linux/oom.h */
+/* Old interface */
# define OOM_DISABLE (-17)
# define OOM_ADJUST_MIN (-16)
+/* New interface */
+# define OOM_SCORE_ADJ_MIN (-1000)
+
+/* Systemd on-demand activation support */
+# define SD_LISTEN_PID_ENV_VAR_NAME "LISTEN_PID"
+# define SD_LISTEN_FDS_ENV_VAR_NAME "LISTEN_FDS"
+# define SD_LISTEN_FDS_START 3
+# define SD_FD_SOCKET_SERVER SD_LISTEN_FDS_START
+
+# include <stdio.h>
+
+static int _set_oom_adj(const char *oom_adj_path, int val)
+{
+ FILE *fp;
+
+ if (!(fp = fopen(oom_adj_path, "w"))) {
+ perror("oom_adj: fopen failed");
+ return 0;
+ }
+
+ fprintf(fp, "%i", val);
+
+ if (dm_fclose(fp))
+ perror("oom_adj: fclose failed");
+
+ return 1;
+}
/*
* Protection against OOM killer if kernel supports it
*/
-static int _set_oom_adj(int val)
+static int _protect_against_oom_killer(void)
{
- FILE *fp;
-
struct stat st;
if (stat(OOM_ADJ_FILE, &st) == -1) {
- if (errno == ENOENT)
- perror(OOM_ADJ_FILE " not found");
- else
+ if (errno != ENOENT)
perror(OOM_ADJ_FILE ": stat failed");
- return 1;
+
+ /* Try old oom_adj interface as a fallback */
+ if (stat(OOM_ADJ_FILE_OLD, &st) == -1) {
+ if (errno == ENOENT)
+ perror(OOM_ADJ_FILE_OLD " not found");
+ else
+ perror(OOM_ADJ_FILE_OLD ": stat failed");
+ return 1;
+ }
+
+ return _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_DISABLE) ||
+ _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_ADJUST_MIN);
}
- if (!(fp = fopen(OOM_ADJ_FILE, "w"))) {
- perror(OOM_ADJ_FILE ": fopen failed");
+ return _set_oom_adj(OOM_ADJ_FILE, OOM_SCORE_ADJ_MIN);
+}
+
+union sockaddr_union {
+ struct sockaddr sa;
+ struct sockaddr_un un;
+};
+
+static int _handle_preloaded_socket(int fd, const char *path)
+{
+ struct stat st_fd;
+ union sockaddr_union sockaddr;
+ int type = 0;
+ socklen_t len = sizeof(type);
+ size_t path_len = strlen(path);
+
+ if (fd < 0)
return 0;
- }
- fprintf(fp, "%i", val);
- if (fclose(fp))
- perror(OOM_ADJ_FILE ": fclose failed");
+ if (fstat(fd, &st_fd) < 0 || !S_ISSOCK(st_fd.st_mode))
+ return 0;
+
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len) < 0 ||
+ len != sizeof(type) || type != SOCK_STREAM)
+ return 0;
+
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ len = sizeof(sockaddr);
+ if (getsockname(fd, &sockaddr.sa, &len) < 0 ||
+ len < sizeof(sa_family_t) ||
+ sockaddr.sa.sa_family != PF_UNIX)
+ return 0;
+
+ if (!(len >= offsetof(struct sockaddr_un, sun_path) + path_len + 1 &&
+ memcmp(path, sockaddr.un.sun_path, path_len) == 0))
+ return 0;
return 1;
}
+
+static int _systemd_handover(struct daemon_state *ds)
+{
+ const char *e;
+ char *p;
+ unsigned long env_pid, env_listen_fds;
+ int r = 0;
+
+ /* LISTEN_PID must be equal to our PID! */
+ if (!(e = getenv(SD_LISTEN_PID_ENV_VAR_NAME)))
+ goto out;
+
+ errno = 0;
+ env_pid = strtoul(e, &p, 10);
+ if (errno || !p || *p || env_pid <= 0 ||
+ getpid() != (pid_t) env_pid)
+ ;
+
+ /* LISTEN_FDS must be 1 and the fd must be a socket! */
+ if (!(e = getenv(SD_LISTEN_FDS_ENV_VAR_NAME)))
+ goto out;
+
+ errno = 0;
+ env_listen_fds = strtoul(e, &p, 10);
+ if (errno || !p || *p || env_listen_fds != 1)
+ goto out;
+
+ /* Check and handle the socket passed in */
+ if ((r = _handle_preloaded_socket(SD_FD_SOCKET_SERVER, ds->socket_path)))
+ ds->socket_fd = SD_FD_SOCKET_SERVER;
+
+out:
+ unsetenv(SD_LISTEN_PID_ENV_VAR_NAME);
+ unsetenv(SD_LISTEN_FDS_ENV_VAR_NAME);
+ return r;
+}
+
#endif
static int _open_socket(daemon_state s)
@@ -192,8 +300,14 @@
else
fd = rlim.rlim_cur;
- for (--fd; fd >= 0; fd--)
+ for (--fd; fd >= 0; fd--) {
+#ifdef linux
+ /* Do not close fds preloaded by systemd! */
+ if (_systemd_activation && fd == SD_FD_SOCKET_SERVER)
+ continue;
+#endif
close(fd);
+ }
if ((open("/dev/null", O_RDONLY) < 0) ||
(open("/dev/null", O_WRONLY) < 0) ||
@@ -328,6 +442,10 @@
if (setenv("LANG", "C", 1))
perror("Cannot set LANG to C");
+#ifdef linux
+ _systemd_activation = _systemd_handover(&s);
+#endif
+
if (!s.foreground)
_daemonise();
@@ -354,11 +472,12 @@
signal(SIGPIPE, SIG_IGN);
#ifdef linux
- if (s.avoid_oom && !_set_oom_adj(OOM_DISABLE) && !_set_oom_adj(OOM_ADJUST_MIN))
- syslog(LOG_ERR, "Failed to set oom_adj to protect against OOM killer");
+ /* Systemd has adjusted oom killer for us already */
+ if (s.avoid_oom && !_systemd_activation && !_protect_against_oom_killer())
+ syslog(LOG_ERR, "Failed to protect against OOM killer");
#endif
- if (s.socket_path) {
+ if (!_systemd_activation && s.socket_path) {
s.socket_fd = _open_socket(s);
if (s.socket_fd < 0)
failed = 1;
^ permalink raw reply [flat|nested] 5+ messages in thread
* LVM2/daemons/common daemon-server.c
@ 2012-01-25 21:30 zkabelac
0 siblings, 0 replies; 5+ messages in thread
From: zkabelac @ 2012-01-25 21:30 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: zkabelac@sourceware.org 2012-01-25 21:30:28
Modified files:
daemons/common : daemon-server.c
Log message:
Check and print perror for syscalls
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.c.diff?cvsroot=lvm2&r1=1.15&r2=1.16
--- LVM2/daemons/common/daemon-server.c 2012/01/15 10:33:41 1.15
+++ LVM2/daemons/common/daemon-server.c 2012/01/25 21:30:27 1.16
@@ -129,8 +129,10 @@
error:
if (fd >= 0) {
- close(fd);
- unlink(s.socket_path);
+ if (close(fd))
+ perror("close failed");
+ if (unlink(s.socket_path))
+ perror("unlink failed");
fd = -1;
}
goto out;
@@ -364,7 +366,8 @@
}
if (s.socket_fd >= 0)
- unlink(s.socket_path);
+ if (unlink(s.socket_path))
+ perror("unlink error");
if (s.daemon_fini)
s.daemon_fini(&s);
^ permalink raw reply [flat|nested] 5+ messages in thread
* LVM2/daemons/common daemon-server.c
@ 2011-07-20 18:23 mornfall
0 siblings, 0 replies; 5+ messages in thread
From: mornfall @ 2011-07-20 18:23 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: mornfall@sourceware.org 2011-07-20 18:23:34
Modified files:
daemons/common : daemon-server.c
Log message:
Fix two small (but eventually unbounded) leaks in daemon-server.c.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.c.diff?cvsroot=lvm2&r1=1.8&r2=1.9
--- LVM2/daemons/common/daemon-server.c 2011/07/18 14:46:54 1.8
+++ LVM2/daemons/common/daemon-server.c 2011/07/20 18:23:33 1.9
@@ -253,6 +253,7 @@
if (!res.buffer) {
write_config_node(res.cft->root, buffer_line, &res);
buffer_rewrite(&res.buffer, "%s\n\n", NULL);
+ destroy_config_tree(res.cft);
}
write_buffer(b->client.socket_fd, res.buffer, strlen(res.buffer));
@@ -261,6 +262,7 @@
}
fail:
/* TODO what should we really do here? */
+ free(baton);
return NULL;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-02-28 14:25 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-15 10:33 LVM2/daemons/common daemon-server.c mornfall
-- strict thread matches above, loose matches on Subject: below --
2012-02-28 14:25 zkabelac
2012-02-28 13:05 prajnoha
2012-01-25 21:30 zkabelac
2011-07-20 18:23 mornfall
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).