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;