cgroup-network now uses its own spawn server (#18674)
* cgroup-network now uses custom spawn server * updated logs of cgroup-network; gettid_cached() needs to be updated after fork()
Costa Tsaousis committed
Oct 17, 2024 at 17:07 UTC
524f781b150bcbf1a5fe48ec568dfb328589badc
5 files changed
+156
-100
src/collectors/cgroups.plugin/cgroup-network.c
+134
-85
@@ -3,6 +3,8 @@
3
#include "libnetdata/libnetdata.h"
4
#include "libnetdata/required_dummies.h"
5
6
+SPAWN_SERVER *spawn_server = NULL;
7
+
8
char env_netdata_host_prefix[FILENAME_MAX + 50] = "";
9
char env_netdata_log_method[FILENAME_MAX + 50] = "";
10
char env_netdata_log_format[FILENAME_MAX + 50] = "";
@@ -42,7 +44,7 @@ unsigned int read_iface_iflink(const char *prefix, const char *iface) {
44
45
unsigned long long iflink = 0;
46
int ret = read_single_number_file(filename, &iflink);
45
- if(ret) collector_error("Cannot read '%s'.", filename);
47
+ if(ret) nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot read '%s'.", filename);
48
49
return (unsigned int)iflink;
50
}
@@ -55,7 +57,7 @@ unsigned int read_iface_ifindex(const char *prefix, const char *iface) {
57
58
unsigned long long ifindex = 0;
59
int ret = read_single_number_file(filename, &ifindex);
58
- if(ret) collector_error("Cannot read '%s'.", filename);
60
+ if(ret) nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot read '%s'.", filename);
61
62
return (unsigned int)ifindex;
63
}
@@ -68,19 +70,15 @@ struct iface *read_proc_net_dev(const char *scope __maybe_unused, const char *pr
70
71
snprintfz(filename, FILENAME_MAX, "%s%s", prefix, (*prefix)?"/proc/1/net/dev":"/proc/net/dev");
72
71
-#ifdef NETDATA_INTERNAL_CHECKS
72
- collector_info("parsing '%s'", filename);
73
-#endif
74
-
73
ff = procfile_open(filename, " \t,:|", PROCFILE_FLAG_DEFAULT);
74
if(unlikely(!ff)) {
77
- collector_error("Cannot open file '%s'", filename);
75
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot open file '%s'", filename);
76
return NULL;
77
}
78
79
ff = procfile_readall(ff);
80
if(unlikely(!ff)) {
83
- collector_error("Cannot read file '%s'", filename);
81
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot read file '%s'", filename);
82
return NULL;
83
}
84
@@ -97,9 +95,7 @@ struct iface *read_proc_net_dev(const char *scope __maybe_unused, const char *pr
95
t->next = root;
96
root = t;
97
100
-#ifdef NETDATA_INTERNAL_CHECKS
101
- collector_info("added %s interface '%s', ifindex %u, iflink %u", scope, t->device, t->ifindex, t->iflink);
102
-#endif
98
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "added %s interface '%s', ifindex %u, iflink %u", scope, t->device, t->ifindex, t->iflink);
99
}
100
101
procfile_close(ff);
@@ -143,12 +139,16 @@ static void continue_as_child(void) {
139
int status;
140
pid_t ret;
141
146
- if (child < 0)
147
- collector_error("fork() failed");
142
+ if (child < 0) {
143
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "fork() failed");
144
+ exit(1);
145
+ }
146
149
- if (child == 0)
147
+ if (child == 0) {
148
// the child returns
149
+ gettid_uncached();
150
return;
151
+ }
152
153
// here is the parent
154
for (;;) {
@@ -160,7 +160,6 @@ static void continue_as_child(void) {
160
} else {
161
break;
162
}
163
-
163
tinysleep();
164
}
165
@@ -187,6 +186,7 @@ static void continue_as_child(void) {
186
*
187
*/
188
189
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "sanitizers detected, killing myself to avoid lockup");
190
kill(getpid(), SIGKILL);
191
#endif
192
@@ -207,7 +207,7 @@ int proc_pid_fd(const char *prefix, const char *ns, pid_t pid) {
207
int fd = open(filename, O_RDONLY | O_CLOEXEC);
208
209
if(fd == -1)
210
- collector_error("Cannot open proc_pid_fd() file '%s'", filename);
210
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot open proc_pid_fd() file '%s'", filename);
211
212
return fd;
213
}
@@ -231,10 +231,8 @@ static struct ns {
231
{ .nstype = 0, .fd = -1, .status = -1, .name = NULL, .path = NULL }
232
};
233
234
-int switch_namespace(const char *prefix, pid_t pid) {
235
-
234
+static int switch_namespace(const char *prefix, pid_t pid) {
235
#ifdef HAVE_SETNS
237
-
236
int i;
237
for(i = 0; all_ns[i].name ; i++)
238
all_ns[i].fd = proc_pid_fd(prefix, all_ns[i].path, pid);
@@ -257,7 +255,9 @@ int switch_namespace(const char *prefix, pid_t pid) {
255
if(setns(all_ns[i].fd, all_ns[i].nstype) == -1) {
256
if(pass == 1) {
257
all_ns[i].status = 0;
260
- collector_error("Cannot switch to %s namespace of pid %d", all_ns[i].name, (int) pid);
258
+ nd_log(NDLS_COLLECTORS, NDLP_ERR,
259
+ "Cannot switch to %s namespace of pid %d",
260
+ all_ns[i].name, (int) pid);
261
}
262
}
263
else
@@ -266,21 +266,22 @@ int switch_namespace(const char *prefix, pid_t pid) {
266
}
267
}
268
269
+ gettid_uncached();
270
setgroups(0, NULL);
271
272
if(root_fd != -1) {
273
if(fchdir(root_fd) < 0)
273
- collector_error("Cannot fchdir() to pid %d root directory", (int)pid);
274
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot fchdir() to pid %d root directory", (int)pid);
275
276
if(chroot(".") < 0)
276
- collector_error("Cannot chroot() to pid %d root directory", (int)pid);
277
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot chroot() to pid %d root directory", (int)pid);
278
279
close(root_fd);
280
}
281
282
if(cwd_fd != -1) {
283
if(fchdir(cwd_fd) < 0)
283
- collector_error("Cannot fchdir() to pid %d current working directory", (int)pid);
284
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot fchdir() to pid %d current working directory", (int)pid);
285
286
close(cwd_fd);
287
}
@@ -304,9 +305,8 @@ int switch_namespace(const char *prefix, pid_t pid) {
305
#else
306
307
errno = ENOSYS;
307
- collector_error("setns() is missing on this system.");
308
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "setns() is missing on this system.");
309
return 1;
309
-
310
#endif
311
}
312
@@ -314,13 +314,13 @@ pid_t read_pid_from_cgroup_file(const char *filename) {
314
int fd = open(filename, procfile_open_flags);
315
if(fd == -1) {
316
if (errno != ENOENT)
317
- collector_error("Cannot open pid_from_cgroup() file '%s'.", filename);
317
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot open pid_from_cgroup() file '%s'.", filename);
318
return 0;
319
}
320
321
FILE *fp = fdopen(fd, "r");
322
if(!fp) {
323
- collector_error("Cannot upgrade fd to fp for file '%s'.", filename);
323
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot upgrade fd to fp for file '%s'.", filename);
324
return 0;
325
}
326
@@ -335,9 +335,8 @@ pid_t read_pid_from_cgroup_file(const char *filename) {
335
336
fclose(fp);
337
338
-#ifdef NETDATA_INTERNAL_CHECKS
339
- if(pid > 0) collector_info("found pid %d on file '%s'", pid, filename);
340
-#endif
338
+ if(pid > 0)
339
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "found pid %d on file '%s'", pid, filename);
340
341
return pid;
342
}
@@ -359,7 +358,7 @@ pid_t read_pid_from_cgroup(const char *path) {
358
359
DIR *dir = opendir(path);
360
if (!dir) {
362
- collector_error("cannot read directory '%s'", path);
361
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "cannot read directory '%s'", path);
362
return 0;
363
}
364
@@ -396,9 +395,8 @@ struct found_device {
395
} *detected_devices = NULL;
396
397
void add_device(const char *host, const char *guest) {
399
-#ifdef NETDATA_INTERNAL_CHECKS
400
- collector_info("adding device with host '%s', guest '%s'", host, guest);
401
-#endif
398
+ errno_clear();
399
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "adding device with host '%s', guest '%s'", host, guest);
400
401
uint32_t hash = simple_hash(host);
402
@@ -450,36 +448,34 @@ void detect_veth_interfaces(pid_t pid) {
448
host = read_proc_net_dev("host", netdata_configured_host_prefix);
449
if(!host) {
450
errno_clear();
453
- collector_error("cannot read host interface list.");
451
+ nd_log(NDLS_COLLECTORS, NDLP_WARNING, "no host interface list.");
452
goto cleanup;
453
}
454
455
if(!eligible_ifaces(host)) {
456
errno_clear();
459
- collector_info("there are no double-linked host interfaces available.");
457
+ nd_log(NDLS_COLLECTORS, NDLP_WARNING, "no double-linked host interfaces available.");
458
goto cleanup;
459
}
460
461
if(switch_namespace(netdata_configured_host_prefix, pid)) {
462
errno_clear();
465
- collector_error("cannot switch to the namespace of pid %u", (unsigned int) pid);
463
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "cannot switch to the namespace of pid %u", (unsigned int) pid);
464
goto cleanup;
465
}
466
469
-#ifdef NETDATA_INTERNAL_CHECKS
470
- collector_info("switched to namespaces of pid %d", pid);
471
-#endif
467
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "switched to namespaces of pid %d", pid);
468
469
cgroup = read_proc_net_dev("cgroup", NULL);
470
if(!cgroup) {
471
errno_clear();
476
- collector_error("cannot read cgroup interface list.");
472
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "cannot read cgroup interface list.");
473
goto cleanup;
474
}
475
476
if(!eligible_ifaces(cgroup)) {
477
errno_clear();
482
- collector_error("there are not double-linked cgroup interfaces available.");
478
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "there are not double-linked cgroup interfaces available.");
479
goto cleanup;
480
}
481
@@ -506,17 +502,73 @@ void detect_veth_interfaces(pid_t pid) {
502
if(iface_is_eligible(h)) {
503
for (c = cgroup; c; c = c->next) {
504
if(iface_is_eligible(c) && h->ifindex == c->iflink && h->iflink == c->ifindex) {
509
- add_device(h->device, c->device);
505
+ printf("%s %s\n", h->device, c->device);
506
+ // add_device(h->device, c->device);
507
}
508
}
509
}
510
}
511
512
+ printf("EXIT DONE\n");
513
+ fflush(stdout);
514
+
515
cleanup:
516
free_host_ifaces(cgroup);
517
free_host_ifaces(host);
518
}
519
520
+struct send_to_spawned_process {
521
+ pid_t pid;
522
+ char host_prefix[FILENAME_MAX];
523
+};
524
+
525
+
526
+static int spawn_callback(SPAWN_REQUEST *request) {
527
+ const struct send_to_spawned_process *d = request->data;
528
+ detect_veth_interfaces(d->pid);
529
+ return 0;
530
+}
531
+
532
+#define CGROUP_NETWORK_INTERFACE_MAX_LINE 2048
533
+static void read_from_spawned(SPAWN_INSTANCE *si, const char *name __maybe_unused) {
534
+ char buffer[CGROUP_NETWORK_INTERFACE_MAX_LINE + 1];
535
+ char *s;
536
+ FILE *fp = fdopen(spawn_server_instance_read_fd(si), "r");
537
+ while((s = fgets(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, fp))) {
538
+ trim(s);
539
+
540
+ if(*s && *s != '\n') {
541
+ char *t = s;
542
+ while(*t && *t != ' ') t++;
543
+ if(*t == ' ') {
544
+ *t = '\0';
545
+ t++;
546
+ }
547
+
548
+ if(strcmp(s, "EXIT") == 0)
549
+ break;
550
+
551
+ if(!*s || !*t) continue;
552
+ add_device(s, t);
553
+ }
554
+ }
555
+ fclose(fp);
556
+ spawn_server_instance_read_fd_unset(si);
557
+ spawn_server_exec_kill(spawn_server, si);
558
+}
559
+
560
+void detect_veth_interfaces_spawn(pid_t pid) {
561
+ struct send_to_spawned_process d = {
562
+ .pid = pid,
563
+ };
564
+ strncpyz(d.host_prefix, netdata_configured_host_prefix, sizeof(d.host_prefix) - 1);
565
+ SPAWN_INSTANCE *si = spawn_server_exec(spawn_server, STDERR_FILENO, 0, NULL, &d, sizeof(d), SPAWN_INSTANCE_TYPE_CALLBACK);
566
+ if(si)
567
+ read_from_spawned(si, "switch namespace callback");
568
+ else
569
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "cgroup-network cannot spawn switch namespace callback");
570
+}
571
+
572
// ----------------------------------------------------------------------------
573
// call the external helper
574
@@ -528,41 +580,35 @@ void call_the_helper(pid_t pid, const char *cgroup) {
580
else
581
snprintfz(command, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec " PLUGINS_DIR "/cgroup-network-helper.sh --pid %d", pid);
582
531
- collector_info("running: %s", command);
583
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "running: %s", command);
584
533
- POPEN_INSTANCE *pi;
585
+ SPAWN_INSTANCE *si;
586
535
- if(cgroup)
536
- pi = spawn_popen_run_variadic(PLUGINS_DIR "/cgroup-network-helper.sh", "--cgroup", cgroup, NULL);
587
+ if(cgroup) {
588
+ const char *argv[] = {
589
+ PLUGINS_DIR "/cgroup-network-helper.sh",
590
+ "--cgroup",
591
+ cgroup,
592
+ NULL,
593
+ };
594
+ si = spawn_server_exec(spawn_server, nd_log_collectors_fd(), 0, argv, NULL, 0, SPAWN_INSTANCE_TYPE_EXEC);
595
+ }
596
else {
597
char buffer[100];
598
snprintfz(buffer, sizeof(buffer) - 1, "%d", pid);
540
- pi = spawn_popen_run_variadic(PLUGINS_DIR "/cgroup-network-helper.sh", "--pid", buffer, NULL);
599
+ const char *argv[] = {
600
+ PLUGINS_DIR "/cgroup-network-helper.sh",
601
+ "--pid",
602
+ buffer,
603
+ NULL,
604
+ };
605
+ si = spawn_server_exec(spawn_server, nd_log_collectors_fd(), 0, argv, NULL, 0, SPAWN_INSTANCE_TYPE_EXEC);
606
}
607
543
- if(pi) {
544
- char buffer[CGROUP_NETWORK_INTERFACE_MAX_LINE + 1];
545
- char *s;
546
- while((s = fgets(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, spawn_popen_stdout(pi)))) {
547
- trim(s);
548
-
549
- if(*s && *s != '\n') {
550
- char *t = s;
551
- while(*t && *t != ' ') t++;
552
- if(*t == ' ') {
553
- *t = '\0';
554
- t++;
555
- }
556
-
557
- if(!*s || !*t) continue;
558
- add_device(s, t);
559
- }
560
- }
561
-
562
- spawn_popen_kill(pi);
563
- }
608
+ if(si)
609
+ read_from_spawned(si, command);
610
else
565
- collector_error("cannot execute cgroup-network helper script: %s", command);
611
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "cannot execute cgroup-network helper script: %s", command);
612
}
613
614
int is_valid_path_symbol(char c) {
@@ -593,33 +639,33 @@ int verify_path(const char *path) {
639
const char *s = path;
640
while((c = *s++)) {
641
if(!( isalnum(c) || is_valid_path_symbol(c) )) {
596
- collector_error("invalid character in path '%s'", path);
642
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "invalid character in path '%s'", path);
643
return -1;
644
}
645
}
646
647
if(strstr(path, "\\") && !strstr(path, "\\x")) {
602
- collector_error("invalid escape sequence in path '%s'", path);
648
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "invalid escape sequence in path '%s'", path);
649
return 1;
650
}
651
652
if(strstr(path, "/../")) {
607
- collector_error("invalid parent path sequence detected in '%s'", path);
653
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "invalid parent path sequence detected in '%s'", path);
654
return 1;
655
}
656
657
if(path[0] != '/') {
612
- collector_error("only absolute path names are supported - invalid path '%s'", path);
658
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "only absolute path names are supported - invalid path '%s'", path);
659
return -1;
660
}
661
662
if (stat(path, &sb) == -1) {
617
- collector_error("cannot stat() path '%s'", path);
663
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "cannot stat() path '%s'", path);
664
return -1;
665
}
666
667
if((sb.st_mode & S_IFMT) != S_IFDIR) {
622
- collector_error("path '%s' is not a directory", path);
668
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "path '%s' is not a directory", path);
669
return -1;
670
}
671
@@ -641,10 +687,10 @@ char *fix_path_variable(void) {
687
char *s = strsep(&ptr, ":");
688
if(s && *s) {
689
if(verify_path(s) == -1) {
644
- collector_error("the PATH variable includes an invalid path '%s' - removed it.", s);
690
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "the PATH variable includes an invalid path '%s' - removed it.", s);
691
}
692
else {
647
- collector_info("the PATH variable includes a valid path '%s'.", s);
693
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "the PATH variable includes a valid path '%s'.", s);
694
if(added) strcat(safe_path, ":");
695
strcat(safe_path, s);
696
added++;
@@ -652,8 +698,8 @@ char *fix_path_variable(void) {
698
}
699
}
700
655
- collector_info("unsafe PATH: '%s'.", path);
656
- collector_info(" safe PATH: '%s'.", safe_path);
701
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "unsafe PATH: '%s'.", path);
702
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, " safe PATH: '%s'.", safe_path);
703
704
freez(p);
705
return safe_path;
@@ -677,7 +723,7 @@ int main(int argc, const char **argv) {
723
collector_error("setresuid(0, 0, 0) failed.");
724
725
nd_log_initialize_for_external_plugins("cgroup-network");
680
- netdata_main_spawn_server_init(NULL, argc, argv);
726
+ spawn_server = spawn_server_create(SPAWN_SERVER_OPTION_EXEC | SPAWN_SERVER_OPTION_CALLBACK, NULL, spawn_callback, argc, argv);
727
728
// since cgroup-network runs as root, prevent it from opening symbolic links
729
procfile_open_flags = O_RDONLY|O_NOFOLLOW;
@@ -730,7 +776,7 @@ int main(int argc, const char **argv) {
776
777
if(pid <= 0) {
778
errno_clear();
733
- collector_error("Invalid pid %d given", (int) pid);
779
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Invalid pid %d given", (int) pid);
780
return 2;
781
}
782
@@ -739,7 +785,7 @@ int main(int argc, const char **argv) {
785
else if(!strcmp(argv[arg], "--cgroup")) {
786
const char *cgroup = argv[arg+1];
787
if(verify_path(cgroup) == -1) {
742
- collector_error("cgroup '%s' does not exist or is not valid.", cgroup);
788
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "cgroup '%s' does not exist or is not valid.", cgroup);
789
return 1;
790
}
791
@@ -748,16 +794,19 @@ int main(int argc, const char **argv) {
794
795
if(pid <= 0 && !detected_devices) {
796
errno_clear();
751
- collector_error("Cannot find a cgroup PID from cgroup '%s'", cgroup);
797
+ nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot find a cgroup PID from cgroup '%s'", cgroup);
798
}
799
}
800
else
801
usage();
802
803
if(pid > 0)
758
- detect_veth_interfaces(pid);
804
+ detect_veth_interfaces_spawn(pid);
805
806
int found = send_devices();
807
+
808
+ spawn_server_destroy(spawn_server);
809
+
810
if(found <= 0) return 1;
811
return 0;
812
}
src/daemon/daemon.c
+4
-6
@@ -432,9 +432,8 @@ int become_daemon(int dont_fork, const char *user)
432
perror("cannot fork");
433
exit(1);
434
}
435
- if(i != 0) {
436
- exit(0); // the parent
437
- }
435
+ if(i != 0) exit(0); // the parent
436
+ gettid_uncached();
437
438
// become session leader
439
if (setsid() < 0) {
@@ -448,9 +447,8 @@ int become_daemon(int dont_fork, const char *user)
447
perror("cannot fork");
448
exit(1);
449
}
451
- if(i != 0) {
452
- exit(0); // the parent
453
- }
450
+ if(i != 0) exit(0); // the parent
451
+ gettid_uncached();
452
}
453
454
// generate our pid file
src/libnetdata/spawn_server/spawn_server.h
+1
@@ -39,6 +39,7 @@ typedef struct spawn_server SPAWN_SERVER;
39
40
SPAWN_SERVER* spawn_server_create(SPAWN_SERVER_OPTIONS options, const char *name, spawn_request_callback_t child_callback, int argc, const char **argv);
41
void spawn_server_destroy(SPAWN_SERVER *server);
42
+pid_t spawn_server_pid(SPAWN_SERVER *server);
43
44
SPAWN_INSTANCE* spawn_server_exec(SPAWN_SERVER *server, int stderr_fd, int custom_fd, const char **argv, const void *data, size_t data_size, SPAWN_INSTANCE_TYPE type);
45
int spawn_server_exec_kill(SPAWN_SERVER *server, SPAWN_INSTANCE *si);
src/libnetdata/spawn_server/spawn_server_internals.h
+2
-2
@@ -70,8 +70,8 @@ struct spawn_server {
70
struct spawn_instance {
71
size_t request_id;
72
int sock;
73
- int write_fd;
74
- int read_fd;
73
+ int write_fd; // the child's input pipe, writing side
74
+ int read_fd; // the child's output pipe, reading side
75
int stderr_fd;
76
pid_t child_pid;
77
src/libnetdata/spawn_server/spawn_server_nofork.c
+15
-7
@@ -4,12 +4,18 @@
4
5
#if defined(SPAWN_SERVER_VERSION_NOFORK)
6
7
+// the child's output pipe, reading side
8
int spawn_server_instance_read_fd(SPAWN_INSTANCE *si) { return si->read_fd; }
9
+
10
+// the child's input pipe, writing side
11
int spawn_server_instance_write_fd(SPAWN_INSTANCE *si) { return si->write_fd; }
12
+
13
void spawn_server_instance_read_fd_unset(SPAWN_INSTANCE *si) { si->read_fd = -1; }
14
void spawn_server_instance_write_fd_unset(SPAWN_INSTANCE *si) { si->write_fd = -1; }
15
pid_t spawn_server_instance_pid(SPAWN_INSTANCE *si) { return si->child_pid; }
16
17
+pid_t spawn_server_pid(SPAWN_SERVER *server) { return server->server_pid; }
18
+
19
#ifdef __APPLE__
20
#include <crt_externs.h>
21
#define environ (*_NSGetEnviron())
@@ -773,36 +779,36 @@ static void spawn_server_process_sigchld(void) {
779
780
if(WIFEXITED(status)) {
781
if(WEXITSTATUS(status))
776
- nd_log(NDLS_COLLECTORS, NDLP_INFO,
782
+ nd_log(NDLS_COLLECTORS, NDLP_WARNING,
783
"SPAWN SERVER: child with pid %d (request %zu) exited with exit code %d: %s",
784
pid, request_id, WEXITSTATUS(status), rq ? rq->cmdline : "[request not found]");
785
send_report_remove_request = true;
786
}
787
else if(WIFSIGNALED(status)) {
788
if(WCOREDUMP(status))
783
- nd_log(NDLS_COLLECTORS, NDLP_INFO,
789
+ nd_log(NDLS_COLLECTORS, NDLP_WARNING,
790
"SPAWN SERVER: child with pid %d (request %zu) coredump'd due to signal %d: %s",
791
pid, request_id, WTERMSIG(status), rq ? rq->cmdline : "[request not found]");
792
else
787
- nd_log(NDLS_COLLECTORS, NDLP_INFO,
793
+ nd_log(NDLS_COLLECTORS, NDLP_WARNING,
794
"SPAWN SERVER: child with pid %d (request %zu) killed by signal %d: %s",
795
pid, request_id, WTERMSIG(status), rq ? rq->cmdline : "[request not found]");
796
send_report_remove_request = true;
797
}
798
else if(WIFSTOPPED(status)) {
793
- nd_log(NDLS_COLLECTORS, NDLP_INFO,
799
+ nd_log(NDLS_COLLECTORS, NDLP_WARNING,
800
"SPAWN SERVER: child with pid %d (request %zu) stopped due to signal %d: %s",
801
pid, request_id, WSTOPSIG(status), rq ? rq->cmdline : "[request not found]");
802
send_report_remove_request = false;
803
}
804
else if(WIFCONTINUED(status)) {
799
- nd_log(NDLS_COLLECTORS, NDLP_INFO,
805
+ nd_log(NDLS_COLLECTORS, NDLP_WARNING,
806
"SPAWN SERVER: child with pid %d (request %zu) continued due to signal %d: %s",
807
pid, request_id, SIGCONT, rq ? rq->cmdline : "[request not found]");
808
send_report_remove_request = false;
809
}
810
else {
805
- nd_log(NDLS_COLLECTORS, NDLP_INFO,
811
+ nd_log(NDLS_COLLECTORS, NDLP_WARNING,
812
"SPAWN SERVER: child with pid %d (request %zu) reports unhandled status: %s",
813
pid, request_id, rq ? rq->cmdline : "[request not found]");
814
send_report_remove_request = false;
@@ -882,7 +888,7 @@ static int spawn_server_event_loop(SPAWN_SERVER *server) {
888
889
if (fds[1].revents & (POLLHUP|POLLERR)) {
890
// Pipe has been closed (parent has exited)
885
- nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "SPAWN SERVER: Parent process has exited");
891
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "SPAWN SERVER: Parent process closed socket (exited?)");
892
break;
893
}
894
@@ -1096,6 +1102,8 @@ SPAWN_SERVER* spawn_server_create(SPAWN_SERVER_OPTIONS options, const char *name
1102
goto cleanup;
1103
}
1104
1105
+ nd_log(NDLS_COLLECTORS, NDLP_DEBUG, "SPAWN SERVER: server created on pid %d", server->server_pid);
1106
+
1107
return server;
1108
}
1109