mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-25 06:02:08 +00:00
BUG/MEDIUM: workaround an eglibc bug which truncates the pidfiles when nbproc > 1
Thomas Heil reported that when using nbproc > 1, his pidfiles were regularly truncated. The issue could be tracked down to the presence of a call to lseek(pidfile, 0, SEEK_SET) just before the close() call in the children, resulting in the file being truncated by the children while the parent was feeding it. This unexpected lseek() is transparently performed by fclose(). Since there is no way to have the file automatically closed during the fork, the only solution is to bypass the libc and use open/write/close instead of fprintf() and fclose(). The issue was observed on eglibc 2.15.
This commit is contained in:
parent
ee2e3a4027
commit
269ab318ef
@ -1148,8 +1148,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int err, retry;
|
int err, retry;
|
||||||
struct rlimit limit;
|
struct rlimit limit;
|
||||||
FILE *pidfile = NULL;
|
|
||||||
char errmsg[100];
|
char errmsg[100];
|
||||||
|
int pidfd = -1;
|
||||||
|
|
||||||
init(argc, argv);
|
init(argc, argv);
|
||||||
signal_register_fct(SIGQUIT, dump, SIGQUIT);
|
signal_register_fct(SIGQUIT, dump, SIGQUIT);
|
||||||
@ -1264,7 +1264,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* open log & pid files before the chroot */
|
/* open log & pid files before the chroot */
|
||||||
if (global.mode & MODE_DAEMON && global.pidfile != NULL) {
|
if (global.mode & MODE_DAEMON && global.pidfile != NULL) {
|
||||||
int pidfd;
|
|
||||||
unlink(global.pidfile);
|
unlink(global.pidfile);
|
||||||
pidfd = open(global.pidfile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
|
pidfd = open(global.pidfile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
|
||||||
if (pidfd < 0) {
|
if (pidfd < 0) {
|
||||||
@ -1274,7 +1273,6 @@ int main(int argc, char **argv)
|
|||||||
protocol_unbind_all();
|
protocol_unbind_all();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
pidfile = fdopen(pidfd, "w");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HAP_CTTPROXY
|
#ifdef CONFIG_HAP_CTTPROXY
|
||||||
@ -1362,15 +1360,18 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else if (ret == 0) /* child breaks here */
|
else if (ret == 0) /* child breaks here */
|
||||||
break;
|
break;
|
||||||
if (pidfile != NULL) {
|
if (pidfd >= 0) {
|
||||||
fprintf(pidfile, "%d\n", ret);
|
char pidstr[100];
|
||||||
fflush(pidfile);
|
snprintf(pidstr, sizeof(pidstr), "%d\n", ret);
|
||||||
|
write(pidfd, pidstr, strlen(pidstr));
|
||||||
}
|
}
|
||||||
relative_pid++; /* each child will get a different one */
|
relative_pid++; /* each child will get a different one */
|
||||||
}
|
}
|
||||||
/* close the pidfile both in children and father */
|
/* close the pidfile both in children and father */
|
||||||
if (pidfile != NULL)
|
if (pidfd >= 0) {
|
||||||
fclose(pidfile);
|
//lseek(pidfd, 0, SEEK_SET); /* debug: emulate eglibc bug */
|
||||||
|
close(pidfd);
|
||||||
|
}
|
||||||
|
|
||||||
/* We won't ever use this anymore */
|
/* We won't ever use this anymore */
|
||||||
free(oldpids); oldpids = NULL;
|
free(oldpids); oldpids = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user