aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2013-08-21 22:42:56 +0200
committerLaurent Ghigonis <laurent@p1sec.com>2013-08-21 22:42:56 +0200
commit6485fb00d4291e24c63cbb95d816fb3550ff1c46 (patch)
tree735610a4f919648eea5768e4576e29773123a105
parentlogfile fix (diff)
downloadglouglou-6485fb00d4291e24c63cbb95d816fb3550ff1c46.tar.xz
glouglou-6485fb00d4291e24c63cbb95d816fb3550ff1c46.zip
v3 WIP
-rw-r--r--v3/glougloud/glougloud.c32
-rw-r--r--v3/glougloud/glougloud.h35
-rw-r--r--v3/glougloud/probes.c3
-rw-r--r--v3/glougloud/redis.c48
-rw-r--r--v3/glougloud/viz.c12
-rw-r--r--v3/libglouglou/libglouglou.h12
-rw-r--r--v3/libglouglou/tests/Makefile48
-rw-r--r--v3/libglouglou/tests/README.txt4
-rw-r--r--v3/libglouglou/tests/test_exec_pipe.c16
-rw-r--r--v3/libglouglou/utils.c71
10 files changed, 249 insertions, 32 deletions
diff --git a/v3/glougloud/glougloud.c b/v3/glougloud/glougloud.c
index b401ec3..b1e582d 100644
--- a/v3/glougloud/glougloud.c
+++ b/v3/glougloud/glougloud.c
@@ -5,7 +5,6 @@
#include <string.h>
#include <event.h>
-#include <dnet.h>
#include <libglouglou.h>
#include "glougloud.h"
@@ -29,7 +28,7 @@ usage(void)
static void
sig_handler(int sig, short why, void *data)
{
- log_info("glougloud: got signal %d", sig);
+ log_info("got signal %d", sig);
if (sig == SIGINT || sig == SIGTERM)
event_base_loopexit(ev_base, NULL);
}
@@ -38,17 +37,19 @@ int
main(int argc, char **argv)
{
struct event *ev_sigint, *ev_sigterm, *ev_sigchld, *ev_sighup;
- int pid, sr_pid, sp_pid, sv_pid;
- struct addr sp_ip, sv_ip;
- int sp_port = GLOUGLOU_PROBE_DEFAULT_PORT;
- int sv_port = GLOUGLOU_VIZ_DEFAULT_PORT;
- int daemonize = 1;
- char *logfile = GLOUGLOUD_LOGFILE;
- int loglevel = LOG_WARN;
+ struct glougloud *ggd;
int op;
- addr_aton("127.0.0.1", &sp_ip);
- addr_aton("127.0.0.1", &sv_ip);
+ ggd = xcalloc(1, struct glougloud);
+
+ addr_aton("127.0.0.1", &ggd->sp_ip);
+ addr_aton("127.0.0.1", &ggd->sv_ip);
+ ggd->sp_port = GLOUGLOU_PROBE_DEFAULT_PORT;
+ ggd->sv_port = GLOUGLOU_VIZ_DEFAULT_PORT;
+ ggd->daemonize = 1;
+ ggd->logfile = GLOUGLOUD_LOGFILE;
+ ggd->loglevel = LOG_WARN;
+
while ((op = getopt(argc, argv, "Dhl:L:p:P:v")) != -1) {
switch (op) {
case 'D':
@@ -97,14 +98,11 @@ main(int argc, char **argv)
evsignal_add(ev_sighup, NULL);
signal(SIGPIPE, SIG_IGN);
- sr_pid = redis_init();
- if (sr_pid < 0)
+ if (redis_init(ggd) < 0)
log_fatal("init redis failed");
- sp_pid = probes_init(&sp_ip, sp_port);
- if (sp_pid < 0)
+ if (probes_init(ggd, &sp_ip, sp_port) < 0)
log_fatal("init probes failed");
- sv_pid = viz_init(&sv_ip, sv_port);
- if (sv_pid < 0)
+ if (viz_init(ggd, &sv_ip, sv_port) < 0)
log_fatal("init viz failed");
if (daemonize) {
diff --git a/v3/glougloud/glougloud.h b/v3/glougloud/glougloud.h
index 3a91b19..2fc7c0d 100644
--- a/v3/glougloud/glougloud.h
+++ b/v3/glougloud/glougloud.h
@@ -1,18 +1,41 @@
/* glougloud internal */
+#include <dnet.h>
+
+#define GLOUGLOUD_USER_PROBES = "_glougloud_probe"
+#define GLOUGLOUD_USER_VIZ = "_glougloud_viz"
#define GLOUGLOUD_LOGFILE "/var/log/glougloud.log"
+#define GLOUGLOUD_MOD_PATH "/lib/glougloud/modules/"
+
+struct glougloud {
+ struct addr sp_ip, sv_ip;
+ int sp_port, sv_port;
+ int daemonize;
+ char *logfile;
+ int loglevel;
+ int pid;
+ struct redis {
+ int pid;
+ };
+ struct probes {
+
+ };
+ struct viz {
+
+ };
+};
/* redis.c */
-int redis_init();
-int redis_shutdown();
+int redis_init(struct glougloud *ggd);
+void redis_shutdown();
/* probes.c */
-int probes_init(struct addr *ip, int port);
-int probes_shutdown();
+int probes_init(struct glougloud *ggd, struct addr *ip, int port);
+void probes_shutdown();
/* viz.c */
-int viz_init(struct addr *ip, int port);
-int viz_shutdown();
+int viz_init(struct glougloud *ggd, struct addr *ip, int port);
+void viz_shutdown();
diff --git a/v3/glougloud/probes.c b/v3/glougloud/probes.c
index f6a7134..f8704b1 100644
--- a/v3/glougloud/probes.c
+++ b/v3/glougloud/probes.c
@@ -5,8 +5,7 @@ probes_init(struct addr *ip, int port) {
return -1;
}
-int
+void
probes_shutdown() {
- return -1;
}
diff --git a/v3/glougloud/redis.c b/v3/glougloud/redis.c
index 7df7b35..e694185 100644
--- a/v3/glougloud/redis.c
+++ b/v3/glougloud/redis.c
@@ -1,9 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <hiredis/hiredis.h>
+#include <hiredis/async.h>
+#include <hiredis/adapters/libevent.h>
+
int
-redis_init() {
- return -1;
+redis_init(struct glougloud *ggd) {
+ char redis_conf[4096];
+ char *echo_args[] = {"echo", redis_conf, NULL};
+ char *echo_env[] = {NULL};
+ char *redis_args[] = {"redis-server", "-", NULL};
+ char *redis_env[] = {NULL};
+
+ droppriv(GLOUGLOUD_USER_PROBES, 1);
+ ggd->redis.pid = fork();
+ if (ggd->redis.pid > 0)
+ return 0;
+
+ snprintf(redis_conf, sizeof(redis_conf),
+ "daemonize no\n"
+ "pidfile /var/run/glougloud/redis.pid\n"
+ "port 0\n"
+ "unixsocket /tmp/glougloud_redis.sock\n"
+ "unixsocketperm 750\n",
+ "timeout 0\n",
+ "loglevel notice\n",
+ "databases 16\n",
+ "save 900 1\n",
+ "save 300 10\n",
+ "save 60 10000\n",
+ "rdbcompression yes\n",
+ "dbfilename glougloud_dump.rdb\n",
+ "dir /var/lib/glougloud/\n",
+ "slowlog-log-slower-than 10000\n",
+ "slowlog-max-len 1024\n");
+ exec_pipe("echo", echo_args, echo_env,
+ "redis-server", redis_args, redis_env);
+
+ log_warn("error starting redis server");
+ exit(EXIT_FAILURE);
}
-int
+void
redis_shutdown() {
- return -1;
}
diff --git a/v3/glougloud/viz.c b/v3/glougloud/viz.c
index 7221642..fc12ba5 100644
--- a/v3/glougloud/viz.c
+++ b/v3/glougloud/viz.c
@@ -1,12 +1,20 @@
#include <dnet.h>
+#include "glougloud.h"
+
int
viz_init(struct addr *ip, int port) {
+ struct modules *mods;
+ droppriv(); // XXX
+ mods = modules_load(GLOUGLOUD_MOD_PATH);
+
+ redis_notification_cb; // XXX
+ socket(); // XXX
+
return -1;
}
-int
+void
viz_shutdown() {
- return -1;
}
diff --git a/v3/libglouglou/libglouglou.h b/v3/libglouglou/libglouglou.h
index 5a5fffd..687a34c 100644
--- a/v3/libglouglou/libglouglou.h
+++ b/v3/libglouglou/libglouglou.h
@@ -65,12 +65,22 @@ void log_fatal(const char *, ...);
/* utils.c */
+struct mod {
+ LIST_ENTRY(mod) entry;
+ void *handle;
+};
+struct modules {
+ LIST_HEAD(, mod) list;
+ int count;
+};
+
void *xmalloc(size_t);
void *xcalloc(size_t, size_t);
void fd_nonblock(int);
void addrcpy(struct sockaddr_in *, struct sockaddr_in *);
int addrcmp(struct sockaddr_in *, struct sockaddr_in *);
void droppriv(char *, int, char *);
-char *get_iface(char *);
+struct modules *modules_load(char *, char *);
+int exec_pipe(char *, char **, char **, char *, char **, char **);
#endif /* _LIBGLOUGLOU_H_ */
diff --git a/v3/libglouglou/tests/Makefile b/v3/libglouglou/tests/Makefile
new file mode 100644
index 0000000..75f195c
--- /dev/null
+++ b/v3/libglouglou/tests/Makefile
@@ -0,0 +1,48 @@
+CFLAGS += -Wall -g
+LDFLAGS=-L../ -levent -ldl -lglouglou
+
+SOURCES = $(shell echo *.c)
+OBJECTS = $(SOURCES:.c=.o)
+TARGETS = $(SOURCES:.c=)
+
+all: $(TARGETS)
+
+run: $(TARGETS)
+ @count=0 ;\
+ errors=0 ;\
+ for test in $(TARGETS); do \
+ echo =============================================================================== ;\
+ echo $$test ;\
+ LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:../ ./$$test ;\
+ if [ $$? -eq 0 ]; then \
+ echo OK ;\
+ else \
+ echo FAILED ;\
+ errors=$$(($$errors + 1)) ;\
+ fi ;\
+ count=$$(($$count + 1)) ;\
+ done ;\
+ echo =============================================================================== ;\
+ echo "$$count tests executed, $$errors errors" ;\
+ exit $$errors
+
+run_loop:
+ @loopcount=20 ;\
+ count=1 ;\
+ while [ $$count -lt $$loopcount ]; do \
+ echo "###############################################################################" ;\
+ make run ;\
+ if [ $$? -ne 0 ]; then \
+ echo ERROR ;\
+ echo "###############################################################################" ;\
+ echo "$$count / $$loopcount loops of tests executed, last one did ERROR" ;\
+ exit $$? ;\
+ fi ;\
+ count=$$(($$count + 1)) ;\
+ done ;\
+ echo "###############################################################################" ;\
+ echo "$$count / $$loopcount loops of tests executed, all OK" ;\
+ exit 0
+
+clean:
+ rm -f $(TARGETS) $(OBJECTS)
diff --git a/v3/libglouglou/tests/README.txt b/v3/libglouglou/tests/README.txt
new file mode 100644
index 0000000..fb19ae8
--- /dev/null
+++ b/v3/libglouglou/tests/README.txt
@@ -0,0 +1,4 @@
+libglouglou unit tests
+
+do "make run" to execute them
+returns the number of tests that failed
diff --git a/v3/libglouglou/tests/test_exec_pipe.c b/v3/libglouglou/tests/test_exec_pipe.c
new file mode 100644
index 0000000..f648bb2
--- /dev/null
+++ b/v3/libglouglou/tests/test_exec_pipe.c
@@ -0,0 +1,16 @@
+#include "../libglouglou.h"
+
+int
+main(int argc, char **argv)
+{
+ char *echo_args[] = {"echo", "toto", NULL};
+ char *echo_env[] = {NULL};
+ char *grep_args[] = {"grep", "-q", "toto", NULL};
+ char *grep_env[] = {NULL};
+
+ exec_pipe("/bin/echo", echo_args, echo_env,
+ "/bin/grep", grep_args, grep_env);
+
+ /* returns only on error */
+ return 1;
+}
diff --git a/v3/libglouglou/utils.c b/v3/libglouglou/utils.c
index 42b2789..4d22e88 100644
--- a/v3/libglouglou/utils.c
+++ b/v3/libglouglou/utils.c
@@ -15,6 +15,9 @@
#include <pwd.h>
#include <grp.h>
#include <string.h>
+#include <dlfcn.h>
+#include <dirent.h>
+#include <sys/wait.h>
#include "libglouglou.h"
@@ -98,3 +101,71 @@ droppriv(char *user, int do_chroot, char *chroot_path)
endpwent();
}
+/* Loads modules from path and returns a list of handles */
+struct modules *
+modules_load(char *path, char *check_sym) {
+ struct modules *modules;
+ struct mod *mod;
+ DIR *d;
+ struct dirent *ent;
+ int n;
+ void *handle, *sym;
+
+ modules = xcalloc(1, sizeof(struct modules));
+
+ d = opendir(path);
+ if (!d)
+ goto err;
+ while ((ent = readdir(d))) {
+ n = strnlen(ent->d_name, sizeof(ent->d_name));
+ if (!n)
+ continue;
+ handle = dlopen(ent->d_name, RTLD_LAZY);
+ if (!handle)
+ continue;
+ dlerror(); // clear errors
+ if (check_sym) {
+ sym = dlsym(handle, check_sym);
+ if (!sym)
+ continue;
+ dlerror(); // clear errors
+ }
+ mod = xcalloc(1, sizeof(struct mod));
+ mod->handle = handle;
+ LIST_INSERT_HEAD(&modules->list, mod, entry);
+ modules->count++;
+ }
+
+ closedir(d);
+ return modules;
+
+err:
+ free(modules);
+ return NULL;
+}
+
+/* pipe cmd1 stdout in cmd2 stdin
+ * return only on error (execve cmd2) */
+int
+exec_pipe(char *cmd1, char **cmd1_args, char **cmd1_env,
+ char *cmd2, char **cmd2_args, char **cmd2_env)
+{
+ int pfd[2];
+
+ pipe(pfd);
+ if(fork() == 0)
+ {
+ dup2(pfd[1], 1);
+ close(pfd[0]);
+ close(pfd[1]);
+ execve(cmd1, cmd1_args, cmd1_env);
+ perror("execve");
+ exit(0);
+ }
+ dup2(pfd[0], 0);
+ close(pfd[0]);
+ close(pfd[1]);
+ execve(cmd2, cmd2_args, cmd2_env);
+ perror("execve");
+ return -1;
+}