~cmars/ubuntu/precise/haproxy/precise-dev-backports

« back to all changes in this revision

Viewing changes to src/haproxy-systemd-wrapper.c

  • Committer: Casey Marshall
  • Date: 2014-01-09 17:29:19 UTC
  • Revision ID: cmars@cmarstech.com-20140109172919-uocfag3820crkwtn
Updated to haproxy-1.5-dev21.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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 <stdio.h>
 
16
#include <stdlib.h>
 
17
#include <string.h>
 
18
#include <unistd.h>
 
19
#include <sys/wait.h>
 
20
 
 
21
static char *pid_file = "/run/haproxy.pid";
 
22
static int main_argc;
 
23
static char **main_argv;
 
24
 
 
25
static void locate_haproxy(char *buffer, size_t buffer_size)
 
26
{
 
27
        char* end = NULL;
 
28
        if (readlink("/proc/self/exe", buffer, buffer_size) > 0)
 
29
                end = strrchr(buffer, '/');
 
30
        if (end == NULL)
 
31
                strncpy(buffer, "/usr/sbin/haproxy", buffer_size);
 
32
        end[1] = '\0';
 
33
        strncat(buffer, "haproxy", buffer_size);
 
34
}
 
35
 
 
36
static void spawn_haproxy(char **pid_strv, int nb_pid)
 
37
{
 
38
        char haproxy_bin[512];
 
39
        pid_t pid;
 
40
 
 
41
        pid = fork();
 
42
        if (!pid) {
 
43
                /* 3 for "haproxy -Ds -sf" */
 
44
                char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
 
45
                int i;
 
46
                int argno = 0;
 
47
                locate_haproxy(haproxy_bin, 512);
 
48
                argv[argno++] = haproxy_bin;
 
49
                for (i = 0; i < main_argc; ++i)
 
50
                        argv[argno++] = main_argv[i];
 
51
                argv[argno++] = "-Ds";
 
52
                if (nb_pid > 0) {
 
53
                        argv[argno++] = "-sf";
 
54
                        for (i = 0; i < nb_pid; ++i)
 
55
                                argv[argno++] = pid_strv[i];
 
56
                }
 
57
                argv[argno] = NULL;
 
58
 
 
59
                printf("%s", "haproxy-systemd-wrapper: executing ");
 
60
                for (i = 0; argv[i]; ++i)
 
61
                        printf("%s ", argv[i]);
 
62
                puts("");
 
63
 
 
64
                execv(argv[0], argv);
 
65
                exit(0);
 
66
        }
 
67
}
 
68
 
 
69
static int read_pids(char ***pid_strv)
 
70
{
 
71
        FILE *f = fopen(pid_file, "r");
 
72
        int read = 0, allocated = 8;
 
73
        char pid_str[10];
 
74
 
 
75
        if (!f)
 
76
                return 0;
 
77
 
 
78
        *pid_strv = malloc(allocated * sizeof(char *));
 
79
        while (1 == fscanf(f, "%s\n", pid_str)) {
 
80
                if (read == allocated) {
 
81
                        allocated *= 2;
 
82
                        *pid_strv = realloc(*pid_strv, allocated * sizeof(char *));
 
83
                }
 
84
                (*pid_strv)[read++] = strdup(pid_str);
 
85
        }
 
86
 
 
87
        fclose(f);
 
88
 
 
89
        return read;
 
90
}
 
91
 
 
92
static void sigusr2_handler(int signum __attribute__((unused)))
 
93
{
 
94
        int i;
 
95
        char **pid_strv = NULL;
 
96
        int nb_pid = read_pids(&pid_strv);
 
97
 
 
98
        spawn_haproxy(pid_strv, nb_pid);
 
99
 
 
100
        for (i = 0; i < nb_pid; ++i)
 
101
                free(pid_strv[i]);
 
102
        free(pid_strv);
 
103
}
 
104
 
 
105
static void sigint_handler(int signum __attribute__((unused)))
 
106
{
 
107
        int i, pid;
 
108
        char **pid_strv = NULL;
 
109
        int nb_pid = read_pids(&pid_strv);
 
110
        for (i = 0; i < nb_pid; ++i) {
 
111
                pid = atoi(pid_strv[i]);
 
112
                if (pid > 0) {
 
113
                        printf("haproxy-systemd-wrapper: SIGINT -> %d\n", pid);
 
114
                        kill(pid, SIGINT);
 
115
                        free(pid_strv[i]);
 
116
                }
 
117
        }
 
118
        free(pid_strv);
 
119
}
 
120
 
 
121
static void init(int argc, char **argv)
 
122
{
 
123
        while (argc > 1) {
 
124
                if (**argv == '-') {
 
125
                        char *flag = *argv + 1;
 
126
                        --argc; ++argv;
 
127
                        if (*flag == 'p')
 
128
                                pid_file = *argv;
 
129
                }
 
130
                --argc; ++argv;
 
131
        }
 
132
}
 
133
 
 
134
int main(int argc, char **argv)
 
135
{
 
136
        int status;
 
137
 
 
138
        --argc; ++argv;
 
139
        main_argc = argc;
 
140
        main_argv = argv;
 
141
 
 
142
        init(argc, argv);
 
143
 
 
144
        signal(SIGINT, &sigint_handler);
 
145
        signal(SIGUSR2, &sigusr2_handler);
 
146
 
 
147
        spawn_haproxy(NULL, 0);
 
148
        status = -1;
 
149
        while (-1 != wait(&status) || errno == EINTR)
 
150
                ;
 
151
 
 
152
        printf("haproxy-systemd-wrapper: exit, haproxy RC=%d\n", status);
 
153
        return EXIT_SUCCESS;
 
154
}