blob: fb1a7fd9272464a657242b523331b8ed1ca5dee6 [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>
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +010015#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <unistd.h>
19#include <sys/wait.h>
20
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +010021static char *pid_file = "/run/haproxy.pid";
22static int main_argc;
23static char **main_argv;
24
Marc-Antoine Perennou47f922d2013-04-02 13:53:21 +020025static void spawn_haproxy(char **pid_strv, int nb_pid)
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +010026{
27 pid_t pid = fork();
28 if (!pid) {
29 /* 3 for "haproxy -Ds -sf" */
30 char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
31 int i;
32 int argno = 0;
33 argv[argno++] = SBINDIR"/haproxy";
34 for (i = 0; i < main_argc; ++i)
35 argv[argno++] = main_argv[i];
36 argv[argno++] = "-Ds";
37 if (nb_pid > 0) {
38 argv[argno++] = "-sf";
39 for (i = 0; i < nb_pid; ++i)
40 argv[argno++] = pid_strv[i];
41 }
42 argv[argno] = NULL;
43 execv(argv[0], argv);
44 exit(0);
45 }
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +010046}
47
48static int read_pids(char ***pid_strv)
49{
50 FILE *f = fopen(pid_file, "r");
51 int read = 0, allocated = 8;
52 char pid_str[10];
53
54 if (!f)
55 return 0;
56
57 *pid_strv = malloc(allocated * sizeof(char *));
58 while (1 == fscanf(f, "%s\n", pid_str)) {
59 if (read == allocated) {
60 allocated *= 2;
61 *pid_strv = realloc(*pid_strv, allocated * sizeof(char *));
62 }
63 (*pid_strv)[read++] = strdup(pid_str);
64 }
65
66 fclose(f);
67
68 return read;
69}
70
71static void signal_handler(int signum __attribute__((unused)))
72{
73 int i;
74 char **pid_strv = NULL;
75 int nb_pid = read_pids(&pid_strv);
76
Marc-Antoine Perennou47f922d2013-04-02 13:53:21 +020077 spawn_haproxy(pid_strv, nb_pid);
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +010078
79 for (i = 0; i < nb_pid; ++i)
80 free(pid_strv[i]);
81 free(pid_strv);
82}
83
84static void init(int argc, char **argv)
85{
86 while (argc > 1) {
87 if (**argv == '-') {
88 char *flag = *argv + 1;
89 --argc; ++argv;
90 if (*flag == 'p')
91 pid_file = *argv;
92 }
93 --argc; ++argv;
94 }
95}
96
97int main(int argc, char **argv)
98{
99 --argc; ++argv;
100 main_argc = argc;
101 main_argv = argv;
102
103 init(argc, argv);
104
105 signal(SIGUSR2, &signal_handler);
106
Marc-Antoine Perennou47f922d2013-04-02 13:53:21 +0200107 spawn_haproxy(NULL, 0);
108 while (-1 != wait(NULL) || errno == EINTR);
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +0100109
110 return EXIT_SUCCESS;
111}