Mercurial > hg
comparison contrib/chg/chg.c @ 28455:412ee35a8005
chg: do not write pidfile
Current pidfile logic will only keep the pid of the newest server, which is
not very useful if we want to kill all servers, and will become outdated if
the server auto exits after being idle for too long.
Besides, the server-side pidfile writing logic runs before chgserver gets
confighash so it's not trivial to append confighash to pidfile basename like
we did for socket file.
This patch removes --pidfile from the command starting chgserver and switches
to an alternative way (unlink socket file) to stop the server.
author | Jun Wu <quark@fb.com> |
---|---|
date | Thu, 10 Mar 2016 00:19:55 +0000 |
parents | 8062869860b8 |
children | 194a6cd873cd |
comparison
equal
deleted
inserted
replaced
28454:8062869860b8 | 28455:412ee35a8005 |
---|---|
31 | 31 |
32 struct cmdserveropts { | 32 struct cmdserveropts { |
33 char sockname[UNIX_PATH_MAX]; | 33 char sockname[UNIX_PATH_MAX]; |
34 char redirectsockname[UNIX_PATH_MAX]; | 34 char redirectsockname[UNIX_PATH_MAX]; |
35 char lockfile[UNIX_PATH_MAX]; | 35 char lockfile[UNIX_PATH_MAX]; |
36 char pidfile[UNIX_PATH_MAX]; | |
37 size_t argsize; | 36 size_t argsize; |
38 const char **args; | 37 const char **args; |
39 int lockfd; | 38 int lockfd; |
40 }; | 39 }; |
41 | 40 |
147 } | 146 } |
148 | 147 |
149 const char *basename = (envsockname) ? envsockname : sockdir; | 148 const char *basename = (envsockname) ? envsockname : sockdir; |
150 const char *sockfmt = (envsockname) ? "%s" : "%s/server"; | 149 const char *sockfmt = (envsockname) ? "%s" : "%s/server"; |
151 const char *lockfmt = (envsockname) ? "%s.lock" : "%s/lock"; | 150 const char *lockfmt = (envsockname) ? "%s.lock" : "%s/lock"; |
152 const char *pidfmt = (envsockname) ? "%s.pid" : "%s/pid"; | |
153 r = snprintf(opts->sockname, sizeof(opts->sockname), sockfmt, basename); | 151 r = snprintf(opts->sockname, sizeof(opts->sockname), sockfmt, basename); |
154 if (r < 0 || (size_t)r >= sizeof(opts->sockname)) | 152 if (r < 0 || (size_t)r >= sizeof(opts->sockname)) |
155 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); | 153 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); |
156 r = snprintf(opts->lockfile, sizeof(opts->lockfile), lockfmt, basename); | 154 r = snprintf(opts->lockfile, sizeof(opts->lockfile), lockfmt, basename); |
157 if (r < 0 || (size_t)r >= sizeof(opts->lockfile)) | 155 if (r < 0 || (size_t)r >= sizeof(opts->lockfile)) |
158 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); | |
159 r = snprintf(opts->pidfile, sizeof(opts->pidfile), pidfmt, basename); | |
160 if (r < 0 || (size_t)r >= sizeof(opts->pidfile)) | |
161 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); | 156 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); |
162 } | 157 } |
163 | 158 |
164 /* | 159 /* |
165 * Acquire a file lock that indicates a client is trying to start and connect | 160 * Acquire a file lock that indicates a client is trying to start and connect |
212 hgcmd, | 207 hgcmd, |
213 "serve", | 208 "serve", |
214 "--cmdserver", "chgunix", | 209 "--cmdserver", "chgunix", |
215 "--address", opts->sockname, | 210 "--address", opts->sockname, |
216 "--daemon-postexec", "chdir:/", | 211 "--daemon-postexec", "chdir:/", |
217 "--pid-file", opts->pidfile, | |
218 "--config", "extensions.chgserver=", | 212 "--config", "extensions.chgserver=", |
219 }; | 213 }; |
220 size_t baseargvsize = sizeof(baseargv) / sizeof(baseargv[0]); | 214 size_t baseargvsize = sizeof(baseargv) / sizeof(baseargv[0]); |
221 size_t argsize = baseargvsize + opts->argsize + 1; | 215 size_t argsize = baseargvsize + opts->argsize + 1; |
222 | 216 |
312 | 306 |
313 unlockcmdserver(opts); | 307 unlockcmdserver(opts); |
314 return hgc; | 308 return hgc; |
315 } | 309 } |
316 | 310 |
317 static void killcmdserver(const struct cmdserveropts *opts, int sig) | 311 static void killcmdserver(const struct cmdserveropts *opts) |
318 { | 312 { |
319 FILE *fp = fopen(opts->pidfile, "r"); | 313 /* resolve config hash */ |
320 if (!fp) | 314 char *resolvedpath = realpath(opts->sockname, NULL); |
321 abortmsg("cannot open %s (errno = %d)", opts->pidfile, errno); | 315 if (resolvedpath) { |
322 int pid = 0; | 316 unlink(resolvedpath); |
323 int n = fscanf(fp, "%d", &pid); | 317 free(resolvedpath); |
324 fclose(fp); | |
325 if (n != 1 || pid <= 0) | |
326 abortmsg("cannot read pid from %s", opts->pidfile); | |
327 | |
328 if (kill((pid_t)pid, sig) < 0) { | |
329 if (errno == ESRCH) | |
330 return; | |
331 abortmsg("cannot kill %d (errno = %d)", pid, errno); | |
332 } | 318 } |
333 } | 319 } |
334 | 320 |
335 static pid_t peerpid = 0; | 321 static pid_t peerpid = 0; |
336 | 322 |
534 initcmdserveropts(&opts); | 520 initcmdserveropts(&opts); |
535 setcmdserveropts(&opts); | 521 setcmdserveropts(&opts); |
536 setcmdserverargs(&opts, argc, argv); | 522 setcmdserverargs(&opts, argc, argv); |
537 | 523 |
538 if (argc == 2) { | 524 if (argc == 2) { |
539 int sig = 0; | 525 if (strcmp(argv[1], "--kill-chg-daemon") == 0) { |
540 if (strcmp(argv[1], "--kill-chg-daemon") == 0) | 526 killcmdserver(&opts); |
541 sig = SIGTERM; | |
542 if (sig > 0) { | |
543 killcmdserver(&opts, sig); | |
544 return 0; | 527 return 0; |
545 } | 528 } |
546 } | 529 } |
547 | 530 |
548 hgclient_t *hgc; | 531 hgclient_t *hgc; |