1 // SPDX-License-Identifier: GPL-2.0
2 #include <internal/lib.h>
3 #include <inttypes.h>
4 #include <subcmd/parse-options.h>
5 #include <api/fd/array.h>
6 #include <api/fs/fs.h>
7 #include <linux/zalloc.h>
8 #include <linux/string.h>
9 #include <linux/limits.h>
10 #include <string.h>
11 #include <sys/file.h>
12 #include <signal.h>
13 #include <stdlib.h>
14 #include <time.h>
15 #include <stdio.h>
16 #include <unistd.h>
17 #include <errno.h>
18 #include <sys/inotify.h>
19 #include <libgen.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <sys/un.h>
23 #include <sys/stat.h>
24 #include <sys/signalfd.h>
25 #include <sys/wait.h>
26 #include <poll.h>
27 #include "builtin.h"
28 #include "perf.h"
29 #include "debug.h"
30 #include "config.h"
31 #include "util.h"
32
33 #define SESSION_OUTPUT "output"
34 #define SESSION_CONTROL "control"
35 #define SESSION_ACK "ack"
36
37 /*
38 * Session states:
39 *
40 * OK - session is up and running
41 * RECONFIG - session is pending for reconfiguration,
42 * new values are already loaded in session object
43 * KILL - session is pending to be killed
44 *
45 * Session object life and its state is maintained by
46 * following functions:
47 *
48 * setup_server_config
49 * - reads config file and setup session objects
50 * with following states:
51 *
52 * OK - no change needed
53 * RECONFIG - session needs to be changed
54 * (run variable changed)
55 * KILL - session needs to be killed
56 * (session is no longer in config file)
57 *
58 * daemon__reconfig
59 * - scans session objects and does following actions
60 * for states:
61 *
62 * OK - skip
63 * RECONFIG - session is killed and re-run with new config
64 * KILL - session is killed
65 *
66 * - all sessions have OK state on the function exit
67 */
68 enum daemon_session_state {
69 OK,
70 RECONFIG,
71 KILL,
72 };
73
74 struct daemon_session {
75 char *base;
76 char *name;
77 char *run;
78 char *control;
79 int pid;
80 struct list_head list;
81 enum daemon_session_state state;
82 time_t start;
83 };
84
85 struct daemon {
86 const char *config;
87 char *config_real;
88 char *config_base;
89 const char *csv_sep;
90 const char *base_user;
91 char *base;
92 struct list_head sessions;
93 FILE *out;
94 char *perf;
95 int signal_fd;
96 time_t start;
97 };
98
99 static struct daemon __daemon = {
100 .sessions = LIST_HEAD_INIT(__daemon.sessions),
101 };
102
103 static const char * const daemon_usage[] = {
104 "perf daemon {start|signal|stop|ping} [<options>]",
105 "perf daemon [<options>]",
106 NULL
107 };
108
109 static volatile sig_atomic_t done;
110
sig_handler(int sig __maybe_unused)111 static void sig_handler(int sig __maybe_unused)
112 {
113 done = true;
114 }
115
daemon__add_session(struct daemon * config,char * name)116 static struct daemon_session *daemon__add_session(struct daemon *config, char *name)
117 {
118 struct daemon_session *session = zalloc(sizeof(*session));
119
120 if (!session)
121 return NULL;
122
123 session->name = strdup(name);
124 if (!session->name) {
125 free(session);
126 return NULL;
127 }
128
129 session->pid = -1;
130 list_add_tail(&session->list, &config->sessions);
131 return session;
132 }
133
daemon__find_session(struct daemon * daemon,char * name)134 static struct daemon_session *daemon__find_session(struct daemon *daemon, char *name)
135 {
136 struct daemon_session *session;
137
138 list_for_each_entry(session, &daemon->sessions, list) {
139 if (!strcmp(session->name, name))
140 return session;
141 }
142
143 return NULL;
144 }
145
get_session_name(const char * var,char * session,int len)146 static int get_session_name(const char *var, char *session, int len)
147 {
148 const char *p = var + sizeof("session-") - 1;
149
150 while (*p != '.' && *p != 0x0 && len--)
151 *session++ = *p++;
152
153 *session = 0;
154 return *p == '.' ? 0 : -EINVAL;
155 }
156
session_config(struct daemon * daemon,const char * var,const char * value)157 static int session_config(struct daemon *daemon, const char *var, const char *value)
158 {
159 struct daemon_session *session;
160 char name[100];
161
162 if (get_session_name(var, name, sizeof(name) - 1))
163 return -EINVAL;
164
165 var = strchr(var, '.');
166 if (!var)
167 return -EINVAL;
168
169 var++;
170
171 session = daemon__find_session(daemon, name);
172
173 if (!session) {
174 /* New session is defined. */
175 session = daemon__add_session(daemon, name);
176 if (!session)
177 return -ENOMEM;
178
179 pr_debug("reconfig: found new session %s\n", name);
180
181 /* Trigger reconfig to start it. */
182 session->state = RECONFIG;
183 } else if (session->state == KILL) {
184 /* Current session is defined, no action needed. */
185 pr_debug("reconfig: found current session %s\n", name);
186 session->state = OK;
187 }
188
189 if (!strcmp(var, "run")) {
190 bool same = false;
191
192 if (session->run)
193 same = !strcmp(session->run, value);
194
195 if (!same) {
196 if (session->run) {
197 zfree(&session->run);
198 pr_debug("reconfig: session %s is changed\n", name);
199 }
200
201 session->run = strdup(value);
202 if (!session->run)
203 return -ENOMEM;
204
205 /*
206 * Either new or changed run value is defined,
207 * trigger reconfig for the session.
208 */
209 session->state = RECONFIG;
210 }
211 }
212
213 return 0;
214 }
215
server_config(const char * var,const char * value,void * cb)216 static int server_config(const char *var, const char *value, void *cb)
217 {
218 struct daemon *daemon = cb;
219
220 if (strstarts(var, "session-")) {
221 return session_config(daemon, var, value);
222 } else if (!strcmp(var, "daemon.base") && !daemon->base_user) {
223 if (daemon->base && strcmp(daemon->base, value)) {
224 pr_err("failed: can't redefine base, bailing out\n");
225 return -EINVAL;
226 }
227 daemon->base = strdup(value);
228 if (!daemon->base)
229 return -ENOMEM;
230 }
231
232 return 0;
233 }
234
client_config(const char * var,const char * value,void * cb)235 static int client_config(const char *var, const char *value, void *cb)
236 {
237 struct daemon *daemon = cb;
238
239 if (!strcmp(var, "daemon.base") && !daemon->base_user) {
240 daemon->base = strdup(value);
241 if (!daemon->base)
242 return -ENOMEM;
243 }
244
245 return 0;
246 }
247
check_base(struct daemon * daemon)248 static int check_base(struct daemon *daemon)
249 {
250 struct stat st;
251
252 if (!daemon->base) {
253 pr_err("failed: base not defined\n");
254 return -EINVAL;
255 }
256
257 if (stat(daemon->base, &st)) {
258 switch (errno) {
259 case EACCES:
260 pr_err("failed: permission denied for '%s' base\n",
261 daemon->base);
262 return -EACCES;
263 case ENOENT:
264 pr_err("failed: base '%s' does not exists\n",
265 daemon->base);
266 return -EACCES;
267 default:
268 pr_err("failed: can't access base '%s': %m\n", daemon->base);
269 return -errno;
270 }
271 }
272
273 if ((st.st_mode & S_IFMT) != S_IFDIR) {
274 pr_err("failed: base '%s' is not directory\n",
275 daemon->base);
276 return -EINVAL;
277 }
278
279 return 0;
280 }
281
setup_client_config(struct daemon * daemon)282 static int setup_client_config(struct daemon *daemon)
283 {
284 struct perf_config_set *set = perf_config_set__load_file(daemon->config_real);
285 int err = -ENOMEM;
286
287 if (set) {
288 err = perf_config_set(set, client_config, daemon);
289 perf_config_set__delete(set);
290 }
291
292 return err ?: check_base(daemon);
293 }
294
setup_server_config(struct daemon * daemon)295 static int setup_server_config(struct daemon *daemon)
296 {
297 struct perf_config_set *set;
298 struct daemon_session *session;
299 int err = -ENOMEM;
300
301 pr_debug("reconfig: started\n");
302
303 /*
304 * Mark all sessions for kill, the server config
305 * will set following states, see explanation at
306 * enum daemon_session_state declaration.
307 */
308 list_for_each_entry(session, &daemon->sessions, list)
309 session->state = KILL;
310
311 set = perf_config_set__load_file(daemon->config_real);
312 if (set) {
313 err = perf_config_set(set, server_config, daemon);
314 perf_config_set__delete(set);
315 }
316
317 return err ?: check_base(daemon);
318 }
319
daemon_session__run(struct daemon_session * session,struct daemon * daemon)320 static int daemon_session__run(struct daemon_session *session,
321 struct daemon *daemon)
322 {
323 char buf[PATH_MAX];
324 char **argv;
325 int argc, fd;
326
327 if (asprintf(&session->base, "%s/session-%s",
328 daemon->base, session->name) < 0) {
329 perror("failed: asprintf");
330 return -1;
331 }
332
333 if (mkdir(session->base, 0755) && errno != EEXIST) {
334 perror("failed: mkdir");
335 return -1;
336 }
337
338 session->start = time(NULL);
339
340 session->pid = fork();
341 if (session->pid < 0)
342 return -1;
343 if (session->pid > 0) {
344 pr_info("reconfig: ruining session [%s:%d]: %s\n",
345 session->name, session->pid, session->run);
346 return 0;
347 }
348
349 if (chdir(session->base)) {
350 perror("failed: chdir");
351 return -1;
352 }
353
354 fd = open("/dev/null", O_RDONLY);
355 if (fd < 0) {
356 perror("failed: open /dev/null");
357 return -1;
358 }
359
360 dup2(fd, 0);
361 close(fd);
362
363 fd = open(SESSION_OUTPUT, O_RDWR|O_CREAT|O_TRUNC, 0644);
364 if (fd < 0) {
365 perror("failed: open session output");
366 return -1;
367 }
368
369 dup2(fd, 1);
370 dup2(fd, 2);
371 close(fd);
372
373 if (mkfifo(SESSION_CONTROL, 0600) && errno != EEXIST) {
374 perror("failed: create control fifo");
375 return -1;
376 }
377
378 if (mkfifo(SESSION_ACK, 0600) && errno != EEXIST) {
379 perror("failed: create ack fifo");
380 return -1;
381 }
382
383 scnprintf(buf, sizeof(buf), "%s record --control=fifo:%s,%s %s",
384 daemon->perf, SESSION_CONTROL, SESSION_ACK, session->run);
385
386 argv = argv_split(buf, &argc);
387 if (!argv)
388 exit(-1);
389
390 exit(execve(daemon->perf, argv, NULL));
391 return -1;
392 }
393
handle_signalfd(struct daemon * daemon)394 static pid_t handle_signalfd(struct daemon *daemon)
395 {
396 struct daemon_session *session;
397 struct signalfd_siginfo si;
398 ssize_t err;
399 int status;
400 pid_t pid;
401
402 /*
403 * Take signal fd data as pure signal notification and check all
404 * the sessions state. The reason is that multiple signals can get
405 * coalesced in kernel and we can receive only single signal even
406 * if multiple SIGCHLD were generated.
407 */
408 err = read(daemon->signal_fd, &si, sizeof(struct signalfd_siginfo));
409 if (err != sizeof(struct signalfd_siginfo)) {
410 pr_err("failed to read signal fd\n");
411 return -1;
412 }
413
414 list_for_each_entry(session, &daemon->sessions, list) {
415 if (session->pid == -1)
416 continue;
417
418 pid = waitpid(session->pid, &status, WNOHANG);
419 if (pid <= 0)
420 continue;
421
422 if (WIFEXITED(status)) {
423 pr_info("session '%s' exited, status=%d\n",
424 session->name, WEXITSTATUS(status));
425 } else if (WIFSIGNALED(status)) {
426 pr_info("session '%s' killed (signal %d)\n",
427 session->name, WTERMSIG(status));
428 } else if (WIFSTOPPED(status)) {
429 pr_info("session '%s' stopped (signal %d)\n",
430 session->name, WSTOPSIG(status));
431 } else {
432 pr_info("session '%s' Unexpected status (0x%x)\n",
433 session->name, status);
434 }
435
436 session->state = KILL;
437 session->pid = -1;
438 }
439
440 return 0;
441 }
442
daemon_session__wait(struct daemon_session * session,struct daemon * daemon,int secs)443 static int daemon_session__wait(struct daemon_session *session, struct daemon *daemon,
444 int secs)
445 {
446 struct pollfd pollfd = {
447 .fd = daemon->signal_fd,
448 .events = POLLIN,
449 };
450 time_t start;
451
452 start = time(NULL);
453
454 do {
455 int err = poll(&pollfd, 1, 1000);
456
457 if (err > 0) {
458 handle_signalfd(daemon);
459 } else if (err < 0) {
460 perror("failed: poll\n");
461 return -1;
462 }
463
464 if (start + secs < time(NULL))
465 return -1;
466 } while (session->pid != -1);
467
468 return 0;
469 }
470
daemon__has_alive_session(struct daemon * daemon)471 static bool daemon__has_alive_session(struct daemon *daemon)
472 {
473 struct daemon_session *session;
474
475 list_for_each_entry(session, &daemon->sessions, list) {
476 if (session->pid != -1)
477 return true;
478 }
479
480 return false;
481 }
482
daemon__wait(struct daemon * daemon,int secs)483 static int daemon__wait(struct daemon *daemon, int secs)
484 {
485 struct pollfd pollfd = {
486 .fd = daemon->signal_fd,
487 .events = POLLIN,
488 };
489 time_t start;
490
491 start = time(NULL);
492
493 do {
494 int err = poll(&pollfd, 1, 1000);
495
496 if (err > 0) {
497 handle_signalfd(daemon);
498 } else if (err < 0) {
499 perror("failed: poll\n");
500 return -1;
501 }
502
503 if (start + secs < time(NULL))
504 return -1;
505 } while (daemon__has_alive_session(daemon));
506
507 return 0;
508 }
509
daemon_session__control(struct daemon_session * session,const char * msg,bool do_ack)510 static int daemon_session__control(struct daemon_session *session,
511 const char *msg, bool do_ack)
512 {
513 struct pollfd pollfd = { .events = POLLIN, };
514 char control_path[PATH_MAX];
515 char ack_path[PATH_MAX];
516 int control, ack = -1, len;
517 char buf[20];
518 int ret = -1;
519 ssize_t err;
520
521 /* open the control file */
522 scnprintf(control_path, sizeof(control_path), "%s/%s",
523 session->base, SESSION_CONTROL);
524
525 control = open(control_path, O_WRONLY|O_NONBLOCK);
526 if (control < 0)
527 return -1;
528
529 if (do_ack) {
530 /* open the ack file */
531 scnprintf(ack_path, sizeof(ack_path), "%s/%s",
532 session->base, SESSION_ACK);
533
534 ack = open(ack_path, O_RDONLY, O_NONBLOCK);
535 if (ack < 0) {
536 close(control);
537 return -1;
538 }
539 }
540
541 /* write the command */
542 len = strlen(msg);
543
544 err = writen(control, msg, len);
545 if (err != len) {
546 pr_err("failed: write to control pipe: %m (%s)\n", control_path);
547 goto out;
548 }
549
550 if (!do_ack)
551 goto out;
552
553 /* wait for an ack */
554 pollfd.fd = ack;
555
556 if (!poll(&pollfd, 1, 2000)) {
557 pr_err("failed: control ack timeout\n");
558 goto out;
559 }
560
561 if (!(pollfd.revents & POLLIN)) {
562 pr_err("failed: did not received an ack\n");
563 goto out;
564 }
565
566 err = read(ack, buf, sizeof(buf));
567 if (err > 0)
568 ret = strcmp(buf, "ack\n");
569 else
570 perror("failed: read ack %d\n");
571
572 out:
573 if (ack != -1)
574 close(ack);
575
576 close(control);
577 return ret;
578 }
579
setup_server_socket(struct daemon * daemon)580 static int setup_server_socket(struct daemon *daemon)
581 {
582 struct sockaddr_un addr;
583 char path[PATH_MAX];
584 int fd = socket(AF_UNIX, SOCK_STREAM, 0);
585
586 if (fd < 0) {
587 fprintf(stderr, "socket: %m\n");
588 return -1;
589 }
590
591 if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
592 perror("failed: fcntl FD_CLOEXEC");
593 close(fd);
594 return -1;
595 }
596
597 scnprintf(path, sizeof(path), "%s/control", daemon->base);
598
599 if (strlen(path) + 1 >= sizeof(addr.sun_path)) {
600 pr_err("failed: control path too long '%s'\n", path);
601 close(fd);
602 return -1;
603 }
604
605 memset(&addr, 0, sizeof(addr));
606 addr.sun_family = AF_UNIX;
607
608 strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
609 unlink(path);
610
611 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
612 perror("failed: bind");
613 close(fd);
614 return -1;
615 }
616
617 if (listen(fd, 1) == -1) {
618 perror("failed: listen");
619 close(fd);
620 return -1;
621 }
622
623 return fd;
624 }
625
626 enum {
627 CMD_LIST = 0,
628 CMD_SIGNAL = 1,
629 CMD_STOP = 2,
630 CMD_PING = 3,
631 CMD_MAX,
632 };
633
634 #define SESSION_MAX 64
635
636 union cmd {
637 int cmd;
638
639 /* CMD_LIST */
640 struct {
641 int cmd;
642 int verbose;
643 char csv_sep;
644 } list;
645
646 /* CMD_SIGNAL */
647 struct {
648 int cmd;
649 int sig;
650 char name[SESSION_MAX];
651 } signal;
652
653 /* CMD_PING */
654 struct {
655 int cmd;
656 char name[SESSION_MAX];
657 } ping;
658 };
659
660 enum {
661 PING_OK = 0,
662 PING_FAIL = 1,
663 PING_MAX,
664 };
665
daemon_session__ping(struct daemon_session * session)666 static int daemon_session__ping(struct daemon_session *session)
667 {
668 return daemon_session__control(session, "ping", true) ? PING_FAIL : PING_OK;
669 }
670
cmd_session_list(struct daemon * daemon,union cmd * cmd,FILE * out)671 static int cmd_session_list(struct daemon *daemon, union cmd *cmd, FILE *out)
672 {
673 char csv_sep = cmd->list.csv_sep;
674 struct daemon_session *session;
675 time_t curr = time(NULL);
676
677 if (csv_sep) {
678 fprintf(out, "%d%c%s%c%s%c%s/%s",
679 /* pid daemon */
680 getpid(), csv_sep, "daemon",
681 /* base */
682 csv_sep, daemon->base,
683 /* output */
684 csv_sep, daemon->base, SESSION_OUTPUT);
685
686 fprintf(out, "%c%s/%s",
687 /* lock */
688 csv_sep, daemon->base, "lock");
689
690 fprintf(out, "%c%" PRIu64,
691 /* session up time */
692 csv_sep, (uint64_t)((curr - daemon->start) / 60));
693
694 fprintf(out, "\n");
695 } else {
696 fprintf(out, "[%d:daemon] base: %s\n", getpid(), daemon->base);
697 if (cmd->list.verbose) {
698 fprintf(out, " output: %s/%s\n",
699 daemon->base, SESSION_OUTPUT);
700 fprintf(out, " lock: %s/lock\n",
701 daemon->base);
702 fprintf(out, " up: %" PRIu64 " minutes\n",
703 (uint64_t)((curr - daemon->start) / 60));
704 }
705 }
706
707 list_for_each_entry(session, &daemon->sessions, list) {
708 if (csv_sep) {
709 fprintf(out, "%d%c%s%c%s",
710 /* pid */
711 session->pid,
712 /* name */
713 csv_sep, session->name,
714 /* base */
715 csv_sep, session->run);
716
717 fprintf(out, "%c%s%c%s/%s",
718 /* session dir */
719 csv_sep, session->base,
720 /* session output */
721 csv_sep, session->base, SESSION_OUTPUT);
722
723 fprintf(out, "%c%s/%s%c%s/%s",
724 /* session control */
725 csv_sep, session->base, SESSION_CONTROL,
726 /* session ack */
727 csv_sep, session->base, SESSION_ACK);
728
729 fprintf(out, "%c%" PRIu64,
730 /* session up time */
731 csv_sep, (uint64_t)((curr - session->start) / 60));
732
733 fprintf(out, "\n");
734 } else {
735 fprintf(out, "[%d:%s] perf record %s\n",
736 session->pid, session->name, session->run);
737 if (!cmd->list.verbose)
738 continue;
739 fprintf(out, " base: %s\n",
740 session->base);
741 fprintf(out, " output: %s/%s\n",
742 session->base, SESSION_OUTPUT);
743 fprintf(out, " control: %s/%s\n",
744 session->base, SESSION_CONTROL);
745 fprintf(out, " ack: %s/%s\n",
746 session->base, SESSION_ACK);
747 fprintf(out, " up: %" PRIu64 " minutes\n",
748 (uint64_t)((curr - session->start) / 60));
749 }
750 }
751
752 return 0;
753 }
754
daemon_session__signal(struct daemon_session * session,int sig)755 static int daemon_session__signal(struct daemon_session *session, int sig)
756 {
757 if (session->pid < 0)
758 return -1;
759 return kill(session->pid, sig);
760 }
761
cmd_session_kill(struct daemon * daemon,union cmd * cmd,FILE * out)762 static int cmd_session_kill(struct daemon *daemon, union cmd *cmd, FILE *out)
763 {
764 struct daemon_session *session;
765 bool all = false;
766
767 all = !strcmp(cmd->signal.name, "all");
768
769 list_for_each_entry(session, &daemon->sessions, list) {
770 if (all || !strcmp(cmd->signal.name, session->name)) {
771 daemon_session__signal(session, cmd->signal.sig);
772 fprintf(out, "signal %d sent to session '%s [%d]'\n",
773 cmd->signal.sig, session->name, session->pid);
774 }
775 }
776
777 return 0;
778 }
779
780 static const char *ping_str[PING_MAX] = {
781 [PING_OK] = "OK",
782 [PING_FAIL] = "FAIL",
783 };
784
cmd_session_ping(struct daemon * daemon,union cmd * cmd,FILE * out)785 static int cmd_session_ping(struct daemon *daemon, union cmd *cmd, FILE *out)
786 {
787 struct daemon_session *session;
788 bool all = false, found = false;
789
790 all = !strcmp(cmd->ping.name, "all");
791
792 list_for_each_entry(session, &daemon->sessions, list) {
793 if (all || !strcmp(cmd->ping.name, session->name)) {
794 int state = daemon_session__ping(session);
795
796 fprintf(out, "%-4s %s\n", ping_str[state], session->name);
797 found = true;
798 }
799 }
800
801 if (!found && !all) {
802 fprintf(out, "%-4s %s (not found)\n",
803 ping_str[PING_FAIL], cmd->ping.name);
804 }
805 return 0;
806 }
807
handle_server_socket(struct daemon * daemon,int sock_fd)808 static int handle_server_socket(struct daemon *daemon, int sock_fd)
809 {
810 int ret = -1, fd;
811 FILE *out = NULL;
812 union cmd cmd;
813
814 fd = accept(sock_fd, NULL, NULL);
815 if (fd < 0) {
816 perror("failed: accept");
817 return -1;
818 }
819
820 if (sizeof(cmd) != readn(fd, &cmd, sizeof(cmd))) {
821 perror("failed: read");
822 goto out;
823 }
824
825 out = fdopen(fd, "w");
826 if (!out) {
827 perror("failed: fdopen");
828 goto out;
829 }
830
831 switch (cmd.cmd) {
832 case CMD_LIST:
833 ret = cmd_session_list(daemon, &cmd, out);
834 break;
835 case CMD_SIGNAL:
836 ret = cmd_session_kill(daemon, &cmd, out);
837 break;
838 case CMD_STOP:
839 done = 1;
840 ret = 0;
841 pr_debug("perf daemon is exciting\n");
842 break;
843 case CMD_PING:
844 ret = cmd_session_ping(daemon, &cmd, out);
845 break;
846 default:
847 break;
848 }
849
850 fclose(out);
851 out:
852 /* If out is defined, then fd is closed via fclose. */
853 if (!out)
854 close(fd);
855 return ret;
856 }
857
setup_client_socket(struct daemon * daemon)858 static int setup_client_socket(struct daemon *daemon)
859 {
860 struct sockaddr_un addr;
861 char path[PATH_MAX];
862 int fd = socket(AF_UNIX, SOCK_STREAM, 0);
863
864 if (fd == -1) {
865 perror("failed: socket");
866 return -1;
867 }
868
869 scnprintf(path, sizeof(path), "%s/control", daemon->base);
870
871 if (strlen(path) + 1 >= sizeof(addr.sun_path)) {
872 pr_err("failed: control path too long '%s'\n", path);
873 close(fd);
874 return -1;
875 }
876
877 memset(&addr, 0, sizeof(addr));
878 addr.sun_family = AF_UNIX;
879 strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
880
881 if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
882 perror("failed: connect");
883 close(fd);
884 return -1;
885 }
886
887 return fd;
888 }
889
daemon_session__kill(struct daemon_session * session,struct daemon * daemon)890 static void daemon_session__kill(struct daemon_session *session,
891 struct daemon *daemon)
892 {
893 int how = 0;
894
895 do {
896 switch (how) {
897 case 0:
898 daemon_session__control(session, "stop", false);
899 break;
900 case 1:
901 daemon_session__signal(session, SIGTERM);
902 break;
903 case 2:
904 daemon_session__signal(session, SIGKILL);
905 break;
906 default:
907 pr_err("failed to wait for session %s\n",
908 session->name);
909 return;
910 }
911 how++;
912
913 } while (daemon_session__wait(session, daemon, 10));
914 }
915
daemon__signal(struct daemon * daemon,int sig)916 static void daemon__signal(struct daemon *daemon, int sig)
917 {
918 struct daemon_session *session;
919
920 list_for_each_entry(session, &daemon->sessions, list)
921 daemon_session__signal(session, sig);
922 }
923
daemon_session__delete(struct daemon_session * session)924 static void daemon_session__delete(struct daemon_session *session)
925 {
926 zfree(&session->base);
927 zfree(&session->name);
928 zfree(&session->run);
929 free(session);
930 }
931
daemon_session__remove(struct daemon_session * session)932 static void daemon_session__remove(struct daemon_session *session)
933 {
934 list_del(&session->list);
935 daemon_session__delete(session);
936 }
937
daemon__stop(struct daemon * daemon)938 static void daemon__stop(struct daemon *daemon)
939 {
940 struct daemon_session *session;
941
942 list_for_each_entry(session, &daemon->sessions, list)
943 daemon_session__control(session, "stop", false);
944 }
945
daemon__kill(struct daemon * daemon)946 static void daemon__kill(struct daemon *daemon)
947 {
948 int how = 0;
949
950 do {
951 switch (how) {
952 case 0:
953 daemon__stop(daemon);
954 break;
955 case 1:
956 daemon__signal(daemon, SIGTERM);
957 break;
958 case 2:
959 daemon__signal(daemon, SIGKILL);
960 break;
961 default:
962 pr_err("failed to wait for sessions\n");
963 return;
964 }
965 how++;
966
967 } while (daemon__wait(daemon, 10));
968 }
969
daemon__exit(struct daemon * daemon)970 static void daemon__exit(struct daemon *daemon)
971 {
972 struct daemon_session *session, *h;
973
974 list_for_each_entry_safe(session, h, &daemon->sessions, list)
975 daemon_session__remove(session);
976
977 zfree(&daemon->config_real);
978 zfree(&daemon->config_base);
979 zfree(&daemon->base);
980 }
981
daemon__reconfig(struct daemon * daemon)982 static int daemon__reconfig(struct daemon *daemon)
983 {
984 struct daemon_session *session, *n;
985
986 list_for_each_entry_safe(session, n, &daemon->sessions, list) {
987 /* No change. */
988 if (session->state == OK)
989 continue;
990
991 /* Remove session. */
992 if (session->state == KILL) {
993 if (session->pid > 0) {
994 daemon_session__kill(session, daemon);
995 pr_info("reconfig: session '%s' killed\n", session->name);
996 }
997 daemon_session__remove(session);
998 continue;
999 }
1000
1001 /* Reconfig session. */
1002 if (session->pid > 0) {
1003 daemon_session__kill(session, daemon);
1004 pr_info("reconfig: session '%s' killed\n", session->name);
1005 }
1006 if (daemon_session__run(session, daemon))
1007 return -1;
1008
1009 session->state = OK;
1010 }
1011
1012 return 0;
1013 }
1014
setup_config_changes(struct daemon * daemon)1015 static int setup_config_changes(struct daemon *daemon)
1016 {
1017 char *basen = strdup(daemon->config_real);
1018 char *dirn = strdup(daemon->config_real);
1019 char *base, *dir;
1020 int fd, wd = -1;
1021
1022 if (!dirn || !basen)
1023 goto out;
1024
1025 fd = inotify_init1(IN_NONBLOCK|O_CLOEXEC);
1026 if (fd < 0) {
1027 perror("failed: inotify_init");
1028 goto out;
1029 }
1030
1031 dir = dirname(dirn);
1032 base = basename(basen);
1033 pr_debug("config file: %s, dir: %s\n", base, dir);
1034
1035 wd = inotify_add_watch(fd, dir, IN_CLOSE_WRITE);
1036 if (wd >= 0) {
1037 daemon->config_base = strdup(base);
1038 if (!daemon->config_base) {
1039 close(fd);
1040 wd = -1;
1041 }
1042 } else {
1043 perror("failed: inotify_add_watch");
1044 }
1045
1046 out:
1047 free(basen);
1048 free(dirn);
1049 return wd < 0 ? -1 : fd;
1050 }
1051
process_inotify_event(struct daemon * daemon,char * buf,ssize_t len)1052 static bool process_inotify_event(struct daemon *daemon, char *buf, ssize_t len)
1053 {
1054 char *p = buf;
1055
1056 while (p < (buf + len)) {
1057 struct inotify_event *event = (struct inotify_event *) p;
1058
1059 /*
1060 * We monitor config directory, check if our
1061 * config file was changes.
1062 */
1063 if ((event->mask & IN_CLOSE_WRITE) &&
1064 !(event->mask & IN_ISDIR)) {
1065 if (!strcmp(event->name, daemon->config_base))
1066 return true;
1067 }
1068 p += sizeof(*event) + event->len;
1069 }
1070 return false;
1071 }
1072
handle_config_changes(struct daemon * daemon,int conf_fd,bool * config_changed)1073 static int handle_config_changes(struct daemon *daemon, int conf_fd,
1074 bool *config_changed)
1075 {
1076 char buf[4096];
1077 ssize_t len;
1078
1079 while (!(*config_changed)) {
1080 len = read(conf_fd, buf, sizeof(buf));
1081 if (len == -1) {
1082 if (errno != EAGAIN) {
1083 perror("failed: read");
1084 return -1;
1085 }
1086 return 0;
1087 }
1088 *config_changed = process_inotify_event(daemon, buf, len);
1089 }
1090 return 0;
1091 }
1092
setup_config(struct daemon * daemon)1093 static int setup_config(struct daemon *daemon)
1094 {
1095 if (daemon->base_user) {
1096 daemon->base = strdup(daemon->base_user);
1097 if (!daemon->base)
1098 return -ENOMEM;
1099 }
1100
1101 if (daemon->config) {
1102 char *real = realpath(daemon->config, NULL);
1103
1104 if (!real) {
1105 perror("failed: realpath");
1106 return -1;
1107 }
1108 daemon->config_real = real;
1109 return 0;
1110 }
1111
1112 if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK))
1113 daemon->config_real = strdup(perf_etc_perfconfig());
1114 else if (perf_config_global() && perf_home_perfconfig())
1115 daemon->config_real = strdup(perf_home_perfconfig());
1116
1117 return daemon->config_real ? 0 : -1;
1118 }
1119
1120 #ifndef F_TLOCK
1121 #define F_TLOCK 2
1122
lockf(int fd,int cmd,off_t len)1123 static int lockf(int fd, int cmd, off_t len)
1124 {
1125 if (cmd != F_TLOCK || len != 0)
1126 return -1;
1127
1128 return flock(fd, LOCK_EX | LOCK_NB);
1129 }
1130 #endif // F_TLOCK
1131
1132 /*
1133 * Each daemon tries to create and lock BASE/lock file,
1134 * if it's successful we are sure we're the only daemon
1135 * running over the BASE.
1136 *
1137 * Once daemon is finished, file descriptor to lock file
1138 * is closed and lock is released.
1139 */
check_lock(struct daemon * daemon)1140 static int check_lock(struct daemon *daemon)
1141 {
1142 char path[PATH_MAX];
1143 char buf[20];
1144 int fd, pid;
1145 ssize_t len;
1146
1147 scnprintf(path, sizeof(path), "%s/lock", daemon->base);
1148
1149 fd = open(path, O_RDWR|O_CREAT|O_CLOEXEC, 0640);
1150 if (fd < 0)
1151 return -1;
1152
1153 if (lockf(fd, F_TLOCK, 0) < 0) {
1154 filename__read_int(path, &pid);
1155 fprintf(stderr, "failed: another perf daemon (pid %d) owns %s\n",
1156 pid, daemon->base);
1157 close(fd);
1158 return -1;
1159 }
1160
1161 scnprintf(buf, sizeof(buf), "%d", getpid());
1162 len = strlen(buf);
1163
1164 if (write(fd, buf, len) != len) {
1165 perror("failed: write");
1166 close(fd);
1167 return -1;
1168 }
1169
1170 if (ftruncate(fd, len)) {
1171 perror("failed: ftruncate");
1172 close(fd);
1173 return -1;
1174 }
1175
1176 return 0;
1177 }
1178
go_background(struct daemon * daemon)1179 static int go_background(struct daemon *daemon)
1180 {
1181 int pid, fd;
1182
1183 pid = fork();
1184 if (pid < 0)
1185 return -1;
1186
1187 if (pid > 0)
1188 return 1;
1189
1190 if (setsid() < 0)
1191 return -1;
1192
1193 if (check_lock(daemon))
1194 return -1;
1195
1196 umask(0);
1197
1198 if (chdir(daemon->base)) {
1199 perror("failed: chdir");
1200 return -1;
1201 }
1202
1203 fd = open("output", O_RDWR|O_CREAT|O_TRUNC, 0644);
1204 if (fd < 0) {
1205 perror("failed: open");
1206 return -1;
1207 }
1208
1209 if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
1210 perror("failed: fcntl FD_CLOEXEC");
1211 close(fd);
1212 return -1;
1213 }
1214
1215 close(0);
1216 dup2(fd, 1);
1217 dup2(fd, 2);
1218 close(fd);
1219
1220 daemon->out = fdopen(1, "w");
1221 if (!daemon->out) {
1222 close(1);
1223 close(2);
1224 return -1;
1225 }
1226
1227 setbuf(daemon->out, NULL);
1228 return 0;
1229 }
1230
setup_signalfd(struct daemon * daemon)1231 static int setup_signalfd(struct daemon *daemon)
1232 {
1233 sigset_t mask;
1234
1235 sigemptyset(&mask);
1236 sigaddset(&mask, SIGCHLD);
1237
1238 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
1239 return -1;
1240
1241 daemon->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
1242 return daemon->signal_fd;
1243 }
1244
__cmd_start(struct daemon * daemon,struct option parent_options[],int argc,const char ** argv)1245 static int __cmd_start(struct daemon *daemon, struct option parent_options[],
1246 int argc, const char **argv)
1247 {
1248 bool foreground = false;
1249 struct option start_options[] = {
1250 OPT_BOOLEAN('f', "foreground", &foreground, "stay on console"),
1251 OPT_PARENT(parent_options),
1252 OPT_END()
1253 };
1254 int sock_fd = -1, conf_fd = -1, signal_fd = -1;
1255 int sock_pos, file_pos, signal_pos;
1256 struct fdarray fda;
1257 int err = 0;
1258
1259 argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1260 if (argc)
1261 usage_with_options(daemon_usage, start_options);
1262
1263 daemon->start = time(NULL);
1264
1265 if (setup_config(daemon)) {
1266 pr_err("failed: config not found\n");
1267 return -1;
1268 }
1269
1270 if (setup_server_config(daemon))
1271 return -1;
1272
1273 if (foreground && check_lock(daemon))
1274 return -1;
1275
1276 if (!foreground) {
1277 err = go_background(daemon);
1278 if (err) {
1279 /* original process, exit normally */
1280 if (err == 1)
1281 err = 0;
1282 daemon__exit(daemon);
1283 return err;
1284 }
1285 }
1286
1287 debug_set_file(daemon->out);
1288 debug_set_display_time(true);
1289
1290 pr_info("daemon started (pid %d)\n", getpid());
1291
1292 fdarray__init(&fda, 3);
1293
1294 sock_fd = setup_server_socket(daemon);
1295 if (sock_fd < 0)
1296 goto out;
1297
1298 conf_fd = setup_config_changes(daemon);
1299 if (conf_fd < 0)
1300 goto out;
1301
1302 signal_fd = setup_signalfd(daemon);
1303 if (signal_fd < 0)
1304 goto out;
1305
1306 sock_pos = fdarray__add(&fda, sock_fd, POLLIN|POLLERR|POLLHUP, 0);
1307 if (sock_pos < 0)
1308 goto out;
1309
1310 file_pos = fdarray__add(&fda, conf_fd, POLLIN|POLLERR|POLLHUP, 0);
1311 if (file_pos < 0)
1312 goto out;
1313
1314 signal_pos = fdarray__add(&fda, signal_fd, POLLIN|POLLERR|POLLHUP, 0);
1315 if (signal_pos < 0)
1316 goto out;
1317
1318 signal(SIGINT, sig_handler);
1319 signal(SIGTERM, sig_handler);
1320 signal(SIGPIPE, SIG_IGN);
1321
1322 while (!done && !err) {
1323 err = daemon__reconfig(daemon);
1324
1325 if (!err && fdarray__poll(&fda, -1)) {
1326 bool reconfig = false;
1327
1328 if (fda.entries[sock_pos].revents & POLLIN)
1329 err = handle_server_socket(daemon, sock_fd);
1330 if (fda.entries[file_pos].revents & POLLIN)
1331 err = handle_config_changes(daemon, conf_fd, &reconfig);
1332 if (fda.entries[signal_pos].revents & POLLIN)
1333 err = handle_signalfd(daemon) < 0;
1334
1335 if (reconfig)
1336 err = setup_server_config(daemon);
1337 }
1338 }
1339
1340 out:
1341 fdarray__exit(&fda);
1342
1343 daemon__kill(daemon);
1344 daemon__exit(daemon);
1345
1346 if (sock_fd != -1)
1347 close(sock_fd);
1348 if (conf_fd != -1)
1349 close(conf_fd);
1350 if (signal_fd != -1)
1351 close(signal_fd);
1352
1353 pr_info("daemon exited\n");
1354 fclose(daemon->out);
1355 return err;
1356 }
1357
send_cmd(struct daemon * daemon,union cmd * cmd)1358 static int send_cmd(struct daemon *daemon, union cmd *cmd)
1359 {
1360 int ret = -1, fd;
1361 char *line = NULL;
1362 size_t len = 0;
1363 ssize_t nread;
1364 FILE *in = NULL;
1365
1366 if (setup_client_config(daemon))
1367 return -1;
1368
1369 fd = setup_client_socket(daemon);
1370 if (fd < 0)
1371 return -1;
1372
1373 if (sizeof(*cmd) != writen(fd, cmd, sizeof(*cmd))) {
1374 perror("failed: write");
1375 goto out;
1376 }
1377
1378 in = fdopen(fd, "r");
1379 if (!in) {
1380 perror("failed: fdopen");
1381 goto out;
1382 }
1383
1384 while ((nread = getline(&line, &len, in)) != -1) {
1385 if (fwrite(line, nread, 1, stdout) != 1)
1386 goto out_fclose;
1387 fflush(stdout);
1388 }
1389
1390 ret = 0;
1391 out_fclose:
1392 fclose(in);
1393 free(line);
1394 out:
1395 /* If in is defined, then fd is closed via fclose. */
1396 if (!in)
1397 close(fd);
1398 return ret;
1399 }
1400
send_cmd_list(struct daemon * daemon)1401 static int send_cmd_list(struct daemon *daemon)
1402 {
1403 union cmd cmd;
1404
1405 memset(&cmd, 0, sizeof(cmd));
1406 cmd.list.cmd = CMD_LIST;
1407 cmd.list.verbose = verbose;
1408 cmd.list.csv_sep = daemon->csv_sep ? *daemon->csv_sep : 0;
1409
1410 return send_cmd(daemon, &cmd);
1411 }
1412
__cmd_signal(struct daemon * daemon,struct option parent_options[],int argc,const char ** argv)1413 static int __cmd_signal(struct daemon *daemon, struct option parent_options[],
1414 int argc, const char **argv)
1415 {
1416 const char *name = "all";
1417 struct option start_options[] = {
1418 OPT_STRING(0, "session", &name, "session",
1419 "Sent signal to specific session"),
1420 OPT_PARENT(parent_options),
1421 OPT_END()
1422 };
1423 union cmd cmd;
1424
1425 argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1426 if (argc)
1427 usage_with_options(daemon_usage, start_options);
1428
1429 if (setup_config(daemon)) {
1430 pr_err("failed: config not found\n");
1431 return -1;
1432 }
1433
1434 memset(&cmd, 0, sizeof(cmd));
1435 cmd.signal.cmd = CMD_SIGNAL;
1436 cmd.signal.sig = SIGUSR2;
1437 strncpy(cmd.signal.name, name, sizeof(cmd.signal.name) - 1);
1438
1439 return send_cmd(daemon, &cmd);
1440 }
1441
__cmd_stop(struct daemon * daemon,struct option parent_options[],int argc,const char ** argv)1442 static int __cmd_stop(struct daemon *daemon, struct option parent_options[],
1443 int argc, const char **argv)
1444 {
1445 struct option start_options[] = {
1446 OPT_PARENT(parent_options),
1447 OPT_END()
1448 };
1449 union cmd cmd;
1450
1451 argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1452 if (argc)
1453 usage_with_options(daemon_usage, start_options);
1454
1455 if (setup_config(daemon)) {
1456 pr_err("failed: config not found\n");
1457 return -1;
1458 }
1459
1460 memset(&cmd, 0, sizeof(cmd));
1461 cmd.cmd = CMD_STOP;
1462 return send_cmd(daemon, &cmd);
1463 }
1464
__cmd_ping(struct daemon * daemon,struct option parent_options[],int argc,const char ** argv)1465 static int __cmd_ping(struct daemon *daemon, struct option parent_options[],
1466 int argc, const char **argv)
1467 {
1468 const char *name = "all";
1469 struct option ping_options[] = {
1470 OPT_STRING(0, "session", &name, "session",
1471 "Ping to specific session"),
1472 OPT_PARENT(parent_options),
1473 OPT_END()
1474 };
1475 union cmd cmd;
1476
1477 argc = parse_options(argc, argv, ping_options, daemon_usage, 0);
1478 if (argc)
1479 usage_with_options(daemon_usage, ping_options);
1480
1481 if (setup_config(daemon)) {
1482 pr_err("failed: config not found\n");
1483 return -1;
1484 }
1485
1486 memset(&cmd, 0, sizeof(cmd));
1487 cmd.cmd = CMD_PING;
1488 scnprintf(cmd.ping.name, sizeof(cmd.ping.name), "%s", name);
1489 return send_cmd(daemon, &cmd);
1490 }
1491
alloc_perf_exe_path(void)1492 static char *alloc_perf_exe_path(void)
1493 {
1494 char path[PATH_MAX];
1495
1496 perf_exe(path, sizeof(path));
1497 return strdup(path);
1498 }
1499
cmd_daemon(int argc,const char ** argv)1500 int cmd_daemon(int argc, const char **argv)
1501 {
1502 struct option daemon_options[] = {
1503 OPT_INCR('v', "verbose", &verbose, "be more verbose"),
1504 OPT_STRING(0, "config", &__daemon.config,
1505 "config file", "config file path"),
1506 OPT_STRING(0, "base", &__daemon.base_user,
1507 "directory", "base directory"),
1508 OPT_STRING_OPTARG('x', "field-separator", &__daemon.csv_sep,
1509 "field separator", "print counts with custom separator", ","),
1510 OPT_END()
1511 };
1512 int ret = -1;
1513
1514 __daemon.perf = alloc_perf_exe_path();
1515 if (!__daemon.perf)
1516 return -ENOMEM;
1517
1518 __daemon.out = stdout;
1519
1520 argc = parse_options(argc, argv, daemon_options, daemon_usage,
1521 PARSE_OPT_STOP_AT_NON_OPTION);
1522
1523 if (argc) {
1524 if (!strcmp(argv[0], "start"))
1525 ret = __cmd_start(&__daemon, daemon_options, argc, argv);
1526 else if (!strcmp(argv[0], "signal"))
1527 ret = __cmd_signal(&__daemon, daemon_options, argc, argv);
1528 else if (!strcmp(argv[0], "stop"))
1529 ret = __cmd_stop(&__daemon, daemon_options, argc, argv);
1530 else if (!strcmp(argv[0], "ping"))
1531 ret = __cmd_ping(&__daemon, daemon_options, argc, argv);
1532 else
1533 pr_err("failed: unknown command '%s'\n", argv[0]);
1534 } else {
1535 ret = setup_config(&__daemon);
1536 if (ret)
1537 pr_err("failed: config not found\n");
1538 else
1539 ret = send_cmd_list(&__daemon);
1540 }
1541 zfree(&__daemon.perf);
1542 return ret;
1543 }
1544