blob: 8499b35188c5c2931b931764cc8cce02690aa0cd [file] [log] [blame]
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +01001/*
2 * Wrapper to make haproxy systemd-compliant.
3 *
4 * Copyright 2013 Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <errno.h>
14#include <signal.h>
15#include <stdbool.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <unistd.h>
20#include <sys/wait.h>
21
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +010022static char *pid_file = "/run/haproxy.pid";
23static int main_argc;
24static char **main_argv;
25
Marc-Antoine Perennou47f922d2013-04-02 13:53:21 +020026static void spawn_haproxy(char **pid_strv, int nb_pid)
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +010027{
28 pid_t pid = fork();
29 if (!pid) {
30 /* 3 for "haproxy -Ds -sf" */
31 char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
32 int i;
33 int argno = 0;
34 argv[argno++] = SBINDIR"/haproxy";
35 for (i = 0; i < main_argc; ++i)
36 argv[argno++] = main_argv[i];
37 argv[argno++] = "-Ds";
38 if (nb_pid > 0) {
39 argv[argno++] = "-sf";
40 for (i = 0; i < nb_pid; ++i)
41 argv[argno++] = pid_strv[i];
42 }
43 argv[argno] = NULL;
44 execv(argv[0], argv);
45 exit(0);
46 }
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +010047}
48
49static int read_pids(char ***pid_strv)
50{
51 FILE *f = fopen(pid_file, "r");
52 int read = 0, allocated = 8;
53 char pid_str[10];
54
55 if (!f)
56 return 0;
57
58 *pid_strv = malloc(allocated * sizeof(char *));
59 while (1 == fscanf(f, "%s\n", pid_str)) {
60 if (read == allocated) {
61 allocated *= 2;
62 *pid_strv = realloc(*pid_strv, allocated * sizeof(char *));
63 }
64 (*pid_strv)[read++] = strdup(pid_str);
65 }
66
67 fclose(f);
68
69 return read;
70}
71
72static void signal_handler(int signum __attribute__((unused)))
73{
74 int i;
75 char **pid_strv = NULL;
76 int nb_pid = read_pids(&pid_strv);
77
Marc-Antoine Perennou47f922d2013-04-02 13:53:21 +020078 spawn_haproxy(pid_strv, nb_pid);
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +010079
80 for (i = 0; i < nb_pid; ++i)
81 free(pid_strv[i]);
82 free(pid_strv);
83}
84
85static void init(int argc, char **argv)
86{
87 while (argc > 1) {
88 if (**argv == '-') {
89 char *flag = *argv + 1;
90 --argc; ++argv;
91 if (*flag == 'p')
92 pid_file = *argv;
93 }
94 --argc; ++argv;
95 }
96}
97
98int main(int argc, char **argv)
99{
100 --argc; ++argv;
101 main_argc = argc;
102 main_argv = argv;
103
104 init(argc, argv);
105
106 signal(SIGUSR2, &signal_handler);
107
Marc-Antoine Perennou47f922d2013-04-02 13:53:21 +0200108 spawn_haproxy(NULL, 0);
109 while (-1 != wait(NULL) || errno == EINTR);
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +0100110
111 return EXIT_SUCCESS;
112}