1
2#include <internal/lib.h>
3#include <subcmd/parse-options.h>
4#include <api/fd/array.h>
5#include <api/fs/fs.h>
6#include <linux/zalloc.h>
7#include <linux/string.h>
8#include <linux/limits.h>
9#include <string.h>
10#include <sys/file.h>
11#include <signal.h>
12#include <stdlib.h>
13#include <time.h>
14#include <stdio.h>
15#include <unistd.h>
16#include <errno.h>
17#include <sys/inotify.h>
18#include <libgen.h>
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <sys/un.h>
22#include <sys/stat.h>
23#include <sys/signalfd.h>
24#include <sys/wait.h>
25#include <poll.h>
26#include "builtin.h"
27#include "perf.h"
28#include "debug.h"
29#include "config.h"
30#include "util.h"
31
32#define SESSION_OUTPUT "output"
33#define SESSION_CONTROL "control"
34#define SESSION_ACK "ack"
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67enum daemon_session_state {
68 OK,
69 RECONFIG,
70 KILL,
71};
72
73struct daemon_session {
74 char *base;
75 char *name;
76 char *run;
77 char *control;
78 int pid;
79 struct list_head list;
80 enum daemon_session_state state;
81 time_t start;
82};
83
84struct daemon {
85 const char *config;
86 char *config_real;
87 char *config_base;
88 const char *csv_sep;
89 const char *base_user;
90 char *base;
91 struct list_head sessions;
92 FILE *out;
93 char perf[PATH_MAX];
94 int signal_fd;
95 time_t start;
96};
97
98static struct daemon __daemon = {
99 .sessions = LIST_HEAD_INIT(__daemon.sessions),
100};
101
102static const char * const daemon_usage[] = {
103 "perf daemon start [<options>]",
104 "perf daemon [<options>]",
105 NULL
106};
107
108static bool done;
109
110static void sig_handler(int sig __maybe_unused)
111{
112 done = true;
113}
114
115static struct daemon_session *daemon__add_session(struct daemon *config, char *name)
116{
117 struct daemon_session *session = zalloc(sizeof(*session));
118
119 if (!session)
120 return NULL;
121
122 session->name = strdup(name);
123 if (!session->name) {
124 free(session);
125 return NULL;
126 }
127
128 session->pid = -1;
129 list_add_tail(&session->list, &config->sessions);
130 return session;
131}
132
133static struct daemon_session *daemon__find_session(struct daemon *daemon, char *name)
134{
135 struct daemon_session *session;
136
137 list_for_each_entry(session, &daemon->sessions, list) {
138 if (!strcmp(session->name, name))
139 return session;
140 }
141
142 return NULL;
143}
144
145static int get_session_name(const char *var, char *session, int len)
146{
147 const char *p = var + sizeof("session-") - 1;
148
149 while (*p != '.' && *p != 0x0 && len--)
150 *session++ = *p++;
151
152 *session = 0;
153 return *p == '.' ? 0 : -EINVAL;
154}
155
156static int session_config(struct daemon *daemon, const char *var, const char *value)
157{
158 struct daemon_session *session;
159 char name[100];
160
161 if (get_session_name(var, name, sizeof(name) - 1))
162 return -EINVAL;
163
164 var = strchr(var, '.');
165 if (!var)
166 return -EINVAL;
167
168 var++;
169
170 session = daemon__find_session(daemon, name);
171
172 if (!session) {
173
174 session = daemon__add_session(daemon, name);
175 if (!session)
176 return -ENOMEM;
177
178 pr_debug("reconfig: found new session %s\n", name);
179
180
181 session->state = RECONFIG;
182 } else if (session->state == KILL) {
183
184 pr_debug("reconfig: found current session %s\n", name);
185 session->state = OK;
186 }
187
188 if (!strcmp(var, "run")) {
189 bool same = false;
190
191 if (session->run)
192 same = !strcmp(session->run, value);
193
194 if (!same) {
195 if (session->run) {
196 free(session->run);
197 pr_debug("reconfig: session %s is changed\n", name);
198 }
199
200 session->run = strdup(value);
201 if (!session->run)
202 return -ENOMEM;
203
204
205
206
207
208 session->state = RECONFIG;
209 }
210 }
211
212 return 0;
213}
214
215static int server_config(const char *var, const char *value, void *cb)
216{
217 struct daemon *daemon = cb;
218
219 if (strstarts(var, "session-")) {
220 return session_config(daemon, var, value);
221 } else if (!strcmp(var, "daemon.base") && !daemon->base_user) {
222 if (daemon->base && strcmp(daemon->base, value)) {
223 pr_err("failed: can't redefine base, bailing out\n");
224 return -EINVAL;
225 }
226 daemon->base = strdup(value);
227 if (!daemon->base)
228 return -ENOMEM;
229 }
230
231 return 0;
232}
233
234static int client_config(const char *var, const char *value, void *cb)
235{
236 struct daemon *daemon = cb;
237
238 if (!strcmp(var, "daemon.base") && !daemon->base_user) {
239 daemon->base = strdup(value);
240 if (!daemon->base)
241 return -ENOMEM;
242 }
243
244 return 0;
245}
246
247static int check_base(struct daemon *daemon)
248{
249 struct stat st;
250
251 if (!daemon->base) {
252 pr_err("failed: base not defined\n");
253 return -EINVAL;
254 }
255
256 if (stat(daemon->base, &st)) {
257 switch (errno) {
258 case EACCES:
259 pr_err("failed: permission denied for '%s' base\n",
260 daemon->base);
261 return -EACCES;
262 case ENOENT:
263 pr_err("failed: base '%s' does not exists\n",
264 daemon->base);
265 return -EACCES;
266 default:
267 pr_err("failed: can't access base '%s': %s\n",
268 daemon->base, strerror(errno));
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
282static 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
295static 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
305
306
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
320static 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
394static 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
404
405
406
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
443static 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
471static 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
483static 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
510static 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
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)
527 return -1;
528
529 if (do_ack) {
530
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) {
536 close(control);
537 return -1;
538 }
539 }
540
541
542 len = strlen(msg);
543
544 err = writen(control, msg, len);
545 if (err != len) {
546 pr_err("failed: write to control pipe: %d (%s)\n",
547 errno, control_path);
548 goto out;
549 }
550
551 if (!do_ack)
552 goto out;
553
554
555 pollfd.fd = ack;
556
557 if (!poll(&pollfd, 1, 2000)) {
558 pr_err("failed: control ack timeout\n");
559 goto out;
560 }
561
562 if (!(pollfd.revents & POLLIN)) {
563 pr_err("failed: did not received an ack\n");
564 goto out;
565 }
566
567 err = read(ack, buf, sizeof(buf));
568 if (err > 0)
569 ret = strcmp(buf, "ack\n");
570 else
571 perror("failed: read ack %d\n");
572
573out:
574 if (ack != -1)
575 close(ack);
576
577 close(control);
578 return ret;
579}
580
581static int setup_server_socket(struct daemon *daemon)
582{
583 struct sockaddr_un addr;
584 char path[PATH_MAX];
585 int fd = socket(AF_UNIX, SOCK_STREAM, 0);
586
587 if (fd < 0) {
588 fprintf(stderr, "socket: %s\n", strerror(errno));
589 return -1;
590 }
591
592 if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
593 perror("failed: fcntl FD_CLOEXEC");
594 close(fd);
595 return -1;
596 }
597
598 scnprintf(path, sizeof(path), "%s/control", daemon->base);
599
600 if (strlen(path) + 1 >= sizeof(addr.sun_path)) {
601 pr_err("failed: control path too long '%s'\n", path);
602 close(fd);
603 return -1;
604 }
605
606 memset(&addr, 0, sizeof(addr));
607 addr.sun_family = AF_UNIX;
608
609 strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
610 unlink(path);
611
612 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
613 perror("failed: bind");
614 close(fd);
615 return -1;
616 }
617
618 if (listen(fd, 1) == -1) {
619 perror("failed: listen");
620 close(fd);
621 return -1;
622 }
623
624 return fd;
625}
626
627enum {
628 CMD_LIST = 0,
629 CMD_SIGNAL = 1,
630 CMD_STOP = 2,
631 CMD_PING = 3,
632 CMD_MAX,
633};
634
635#define SESSION_MAX 64
636
637union cmd {
638 int cmd;
639
640
641 struct {
642 int cmd;
643 int verbose;
644 char csv_sep;
645 } list;
646
647
648 struct {
649 int cmd;
650 int sig;
651 char name[SESSION_MAX];
652 } signal;
653
654
655 struct {
656 int cmd;
657 char name[SESSION_MAX];
658 } ping;
659};
660
661enum {
662 PING_OK = 0,
663 PING_FAIL = 1,
664 PING_MAX,
665};
666
667static int daemon_session__ping(struct daemon_session *session)
668{
669 return daemon_session__control(session, "ping", true) ? PING_FAIL : PING_OK;
670}
671
672static int cmd_session_list(struct daemon *daemon, union cmd *cmd, FILE *out)
673{
674 char csv_sep = cmd->list.csv_sep;
675 struct daemon_session *session;
676 time_t curr = time(NULL);
677
678 if (csv_sep) {
679 fprintf(out, "%d%c%s%c%s%c%s/%s",
680
681 getpid(), csv_sep, "daemon",
682
683 csv_sep, daemon->base,
684
685 csv_sep, daemon->base, SESSION_OUTPUT);
686
687 fprintf(out, "%c%s/%s",
688
689 csv_sep, daemon->base, "lock");
690
691 fprintf(out, "%c%lu",
692
693 csv_sep, (curr - daemon->start) / 60);
694
695 fprintf(out, "\n");
696 } else {
697 fprintf(out, "[%d:daemon] base: %s\n", getpid(), daemon->base);
698 if (cmd->list.verbose) {
699 fprintf(out, " output: %s/%s\n",
700 daemon->base, SESSION_OUTPUT);
701 fprintf(out, " lock: %s/lock\n",
702 daemon->base);
703 fprintf(out, " up: %lu minutes\n",
704 (curr - daemon->start) / 60);
705 }
706 }
707
708 list_for_each_entry(session, &daemon->sessions, list) {
709 if (csv_sep) {
710 fprintf(out, "%d%c%s%c%s",
711
712 session->pid,
713
714 csv_sep, session->name,
715
716 csv_sep, session->run);
717
718 fprintf(out, "%c%s%c%s/%s",
719
720 csv_sep, session->base,
721
722 csv_sep, session->base, SESSION_OUTPUT);
723
724 fprintf(out, "%c%s/%s%c%s/%s",
725
726 csv_sep, session->base, SESSION_CONTROL,
727
728 csv_sep, session->base, SESSION_ACK);
729
730 fprintf(out, "%c%lu",
731
732 csv_sep, (curr - session->start) / 60);
733
734 fprintf(out, "\n");
735 } else {
736 fprintf(out, "[%d:%s] perf record %s\n",
737 session->pid, session->name, session->run);
738 if (!cmd->list.verbose)
739 continue;
740 fprintf(out, " base: %s\n",
741 session->base);
742 fprintf(out, " output: %s/%s\n",
743 session->base, SESSION_OUTPUT);
744 fprintf(out, " control: %s/%s\n",
745 session->base, SESSION_CONTROL);
746 fprintf(out, " ack: %s/%s\n",
747 session->base, SESSION_ACK);
748 fprintf(out, " up: %lu minutes\n",
749 (curr - session->start) / 60);
750 }
751 }
752
753 return 0;
754}
755
756static int daemon_session__signal(struct daemon_session *session, int sig)
757{
758 if (session->pid < 0)
759 return -1;
760 return kill(session->pid, sig);
761}
762
763static int cmd_session_kill(struct daemon *daemon, union cmd *cmd, FILE *out)
764{
765 struct daemon_session *session;
766 bool all = false;
767
768 all = !strcmp(cmd->signal.name, "all");
769
770 list_for_each_entry(session, &daemon->sessions, list) {
771 if (all || !strcmp(cmd->signal.name, session->name)) {
772 daemon_session__signal(session, cmd->signal.sig);
773 fprintf(out, "signal %d sent to session '%s [%d]'\n",
774 cmd->signal.sig, session->name, session->pid);
775 }
776 }
777
778 return 0;
779}
780
781static const char *ping_str[PING_MAX] = {
782 [PING_OK] = "OK",
783 [PING_FAIL] = "FAIL",
784};
785
786static int cmd_session_ping(struct daemon *daemon, union cmd *cmd, FILE *out)
787{
788 struct daemon_session *session;
789 bool all = false, found = false;
790
791 all = !strcmp(cmd->ping.name, "all");
792
793 list_for_each_entry(session, &daemon->sessions, list) {
794 if (all || !strcmp(cmd->ping.name, session->name)) {
795 int state = daemon_session__ping(session);
796
797 fprintf(out, "%-4s %s\n", ping_str[state], session->name);
798 found = true;
799 }
800 }
801
802 if (!found && !all) {
803 fprintf(out, "%-4s %s (not found)\n",
804 ping_str[PING_FAIL], cmd->ping.name);
805 }
806 return 0;
807}
808
809static int handle_server_socket(struct daemon *daemon, int sock_fd)
810{
811 int ret = -1, fd;
812 FILE *out = NULL;
813 union cmd cmd;
814
815 fd = accept(sock_fd, NULL, NULL);
816 if (fd < 0) {
817 perror("failed: accept");
818 return -1;
819 }
820
821 if (sizeof(cmd) != readn(fd, &cmd, sizeof(cmd))) {
822 perror("failed: read");
823 goto out;
824 }
825
826 out = fdopen(fd, "w");
827 if (!out) {
828 perror("failed: fdopen");
829 goto out;
830 }
831
832 switch (cmd.cmd) {
833 case CMD_LIST:
834 ret = cmd_session_list(daemon, &cmd, out);
835 break;
836 case CMD_SIGNAL:
837 ret = cmd_session_kill(daemon, &cmd, out);
838 break;
839 case CMD_STOP:
840 done = 1;
841 ret = 0;
842 pr_debug("perf daemon is exciting\n");
843 break;
844 case CMD_PING:
845 ret = cmd_session_ping(daemon, &cmd, out);
846 break;
847 default:
848 break;
849 }
850
851 fclose(out);
852out:
853
854 if (!out)
855 close(fd);
856 return ret;
857}
858
859static int setup_client_socket(struct daemon *daemon)
860{
861 struct sockaddr_un addr;
862 char path[PATH_MAX];
863 int fd = socket(AF_UNIX, SOCK_STREAM, 0);
864
865 if (fd == -1) {
866 perror("failed: socket");
867 return -1;
868 }
869
870 scnprintf(path, sizeof(path), "%s/control", daemon->base);
871
872 if (strlen(path) + 1 >= sizeof(addr.sun_path)) {
873 pr_err("failed: control path too long '%s'\n", path);
874 close(fd);
875 return -1;
876 }
877
878 memset(&addr, 0, sizeof(addr));
879 addr.sun_family = AF_UNIX;
880 strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
881
882 if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
883 perror("failed: connect");
884 close(fd);
885 return -1;
886 }
887
888 return fd;
889}
890
891static void daemon_session__kill(struct daemon_session *session,
892 struct daemon *daemon)
893{
894 int how = 0;
895
896 do {
897 switch (how) {
898 case 0:
899 daemon_session__control(session, "stop", false);
900 break;
901 case 1:
902 daemon_session__signal(session, SIGTERM);
903 break;
904 case 2:
905 daemon_session__signal(session, SIGKILL);
906 break;
907 default:
908 pr_err("failed to wait for session %s\n",
909 session->name);
910 return;
911 }
912 how++;
913
914 } while (daemon_session__wait(session, daemon, 10));
915}
916
917static void daemon__signal(struct daemon *daemon, int sig)
918{
919 struct daemon_session *session;
920
921 list_for_each_entry(session, &daemon->sessions, list)
922 daemon_session__signal(session, sig);
923}
924
925static void daemon_session__delete(struct daemon_session *session)
926{
927 free(session->base);
928 free(session->name);
929 free(session->run);
930 free(session);
931}
932
933static void daemon_session__remove(struct daemon_session *session)
934{
935 list_del(&session->list);
936 daemon_session__delete(session);
937}
938
939static void daemon__stop(struct daemon *daemon)
940{
941 struct daemon_session *session;
942
943 list_for_each_entry(session, &daemon->sessions, list)
944 daemon_session__control(session, "stop", false);
945}
946
947static void daemon__kill(struct daemon *daemon)
948{
949 int how = 0;
950
951 do {
952 switch (how) {
953 case 0:
954 daemon__stop(daemon);
955 break;
956 case 1:
957 daemon__signal(daemon, SIGTERM);
958 break;
959 case 2:
960 daemon__signal(daemon, SIGKILL);
961 break;
962 default:
963 pr_err("failed to wait for sessions\n");
964 return;
965 }
966 how++;
967
968 } while (daemon__wait(daemon, 10));
969}
970
971static void daemon__exit(struct daemon *daemon)
972{
973 struct daemon_session *session, *h;
974
975 list_for_each_entry_safe(session, h, &daemon->sessions, list)
976 daemon_session__remove(session);
977
978 free(daemon->config_real);
979 free(daemon->config_base);
980 free(daemon->base);
981}
982
983static int daemon__reconfig(struct daemon *daemon)
984{
985 struct daemon_session *session, *n;
986
987 list_for_each_entry_safe(session, n, &daemon->sessions, list) {
988
989 if (session->state == OK)
990 continue;
991
992
993 if (session->state == KILL) {
994 if (session->pid > 0) {
995 daemon_session__kill(session, daemon);
996 pr_info("reconfig: session '%s' killed\n", session->name);
997 }
998 daemon_session__remove(session);
999 continue;
1000 }
1001
1002
1003 if (session->pid > 0) {
1004 daemon_session__kill(session, daemon);
1005 pr_info("reconfig: session '%s' killed\n", session->name);
1006 }
1007 if (daemon_session__run(session, daemon))
1008 return -1;
1009
1010 session->state = OK;
1011 }
1012
1013 return 0;
1014}
1015
1016static int setup_config_changes(struct daemon *daemon)
1017{
1018 char *basen = strdup(daemon->config_real);
1019 char *dirn = strdup(daemon->config_real);
1020 char *base, *dir;
1021 int fd, wd = -1;
1022
1023 if (!dirn || !basen)
1024 goto out;
1025
1026 fd = inotify_init1(IN_NONBLOCK|O_CLOEXEC);
1027 if (fd < 0) {
1028 perror("failed: inotify_init");
1029 goto out;
1030 }
1031
1032 dir = dirname(dirn);
1033 base = basename(basen);
1034 pr_debug("config file: %s, dir: %s\n", base, dir);
1035
1036 wd = inotify_add_watch(fd, dir, IN_CLOSE_WRITE);
1037 if (wd >= 0) {
1038 daemon->config_base = strdup(base);
1039 if (!daemon->config_base) {
1040 close(fd);
1041 wd = -1;
1042 }
1043 } else {
1044 perror("failed: inotify_add_watch");
1045 }
1046
1047out:
1048 free(basen);
1049 free(dirn);
1050 return wd < 0 ? -1 : fd;
1051}
1052
1053static bool process_inotify_event(struct daemon *daemon, char *buf, ssize_t len)
1054{
1055 char *p = buf;
1056
1057 while (p < (buf + len)) {
1058 struct inotify_event *event = (struct inotify_event *) p;
1059
1060
1061
1062
1063
1064 if ((event->mask & IN_CLOSE_WRITE) &&
1065 !(event->mask & IN_ISDIR)) {
1066 if (!strcmp(event->name, daemon->config_base))
1067 return true;
1068 }
1069 p += sizeof(*event) + event->len;
1070 }
1071 return false;
1072}
1073
1074static int handle_config_changes(struct daemon *daemon, int conf_fd,
1075 bool *config_changed)
1076{
1077 char buf[4096];
1078 ssize_t len;
1079
1080 while (!(*config_changed)) {
1081 len = read(conf_fd, buf, sizeof(buf));
1082 if (len == -1) {
1083 if (errno != EAGAIN) {
1084 perror("failed: read");
1085 return -1;
1086 }
1087 return 0;
1088 }
1089 *config_changed = process_inotify_event(daemon, buf, len);
1090 }
1091 return 0;
1092}
1093
1094static int setup_config(struct daemon *daemon)
1095{
1096 if (daemon->base_user) {
1097 daemon->base = strdup(daemon->base_user);
1098 if (!daemon->base)
1099 return -ENOMEM;
1100 }
1101
1102 if (daemon->config) {
1103 char *real = realpath(daemon->config, NULL);
1104
1105 if (!real) {
1106 perror("failed: realpath");
1107 return -1;
1108 }
1109 daemon->config_real = real;
1110 return 0;
1111 }
1112
1113 if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK))
1114 daemon->config_real = strdup(perf_etc_perfconfig());
1115 else if (perf_config_global() && perf_home_perfconfig())
1116 daemon->config_real = strdup(perf_home_perfconfig());
1117
1118 return daemon->config_real ? 0 : -1;
1119}
1120
1121#ifndef F_TLOCK
1122#define F_TLOCK 2
1123
1124#include <sys/file.h>
1125
1126static int lockf(int fd, int cmd, off_t len)
1127{
1128 if (cmd != F_TLOCK || len != 0)
1129 return -1;
1130
1131 return flock(fd, LOCK_EX | LOCK_NB);
1132}
1133#endif
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143static int check_lock(struct daemon *daemon)
1144{
1145 char path[PATH_MAX];
1146 char buf[20];
1147 int fd, pid;
1148 ssize_t len;
1149
1150 scnprintf(path, sizeof(path), "%s/lock", daemon->base);
1151
1152 fd = open(path, O_RDWR|O_CREAT|O_CLOEXEC, 0640);
1153 if (fd < 0)
1154 return -1;
1155
1156 if (lockf(fd, F_TLOCK, 0) < 0) {
1157 filename__read_int(path, &pid);
1158 fprintf(stderr, "failed: another perf daemon (pid %d) owns %s\n",
1159 pid, daemon->base);
1160 close(fd);
1161 return -1;
1162 }
1163
1164 scnprintf(buf, sizeof(buf), "%d", getpid());
1165 len = strlen(buf);
1166
1167 if (write(fd, buf, len) != len) {
1168 perror("failed: write");
1169 close(fd);
1170 return -1;
1171 }
1172
1173 if (ftruncate(fd, len)) {
1174 perror("failed: ftruncate");
1175 close(fd);
1176 return -1;
1177 }
1178
1179 return 0;
1180}
1181
1182static int go_background(struct daemon *daemon)
1183{
1184 int pid, fd;
1185
1186 pid = fork();
1187 if (pid < 0)
1188 return -1;
1189
1190 if (pid > 0)
1191 return 1;
1192
1193 if (setsid() < 0)
1194 return -1;
1195
1196 if (check_lock(daemon))
1197 return -1;
1198
1199 umask(0);
1200
1201 if (chdir(daemon->base)) {
1202 perror("failed: chdir");
1203 return -1;
1204 }
1205
1206 fd = open("output", O_RDWR|O_CREAT|O_TRUNC, 0644);
1207 if (fd < 0) {
1208 perror("failed: open");
1209 return -1;
1210 }
1211
1212 if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
1213 perror("failed: fcntl FD_CLOEXEC");
1214 close(fd);
1215 return -1;
1216 }
1217
1218 close(0);
1219 dup2(fd, 1);
1220 dup2(fd, 2);
1221 close(fd);
1222
1223 daemon->out = fdopen(1, "w");
1224 if (!daemon->out) {
1225 close(1);
1226 close(2);
1227 return -1;
1228 }
1229
1230 setbuf(daemon->out, NULL);
1231 return 0;
1232}
1233
1234static int setup_signalfd(struct daemon *daemon)
1235{
1236 sigset_t mask;
1237
1238 sigemptyset(&mask);
1239 sigaddset(&mask, SIGCHLD);
1240
1241 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
1242 return -1;
1243
1244 daemon->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
1245 return daemon->signal_fd;
1246}
1247
1248static int __cmd_start(struct daemon *daemon, struct option parent_options[],
1249 int argc, const char **argv)
1250{
1251 bool foreground = false;
1252 struct option start_options[] = {
1253 OPT_BOOLEAN('f', "foreground", &foreground, "stay on console"),
1254 OPT_PARENT(parent_options),
1255 OPT_END()
1256 };
1257 int sock_fd = -1, conf_fd = -1, signal_fd = -1;
1258 int sock_pos, file_pos, signal_pos;
1259 struct fdarray fda;
1260 int err = 0;
1261
1262 argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1263 if (argc)
1264 usage_with_options(daemon_usage, start_options);
1265
1266 daemon->start = time(NULL);
1267
1268 if (setup_config(daemon)) {
1269 pr_err("failed: config not found\n");
1270 return -1;
1271 }
1272
1273 if (setup_server_config(daemon))
1274 return -1;
1275
1276 if (foreground && check_lock(daemon))
1277 return -1;
1278
1279 if (!foreground) {
1280 err = go_background(daemon);
1281 if (err) {
1282
1283 if (err == 1)
1284 err = 0;
1285 daemon__exit(daemon);
1286 return err;
1287 }
1288 }
1289
1290 debug_set_file(daemon->out);
1291 debug_set_display_time(true);
1292
1293 pr_info("daemon started (pid %d)\n", getpid());
1294
1295 fdarray__init(&fda, 3);
1296
1297 sock_fd = setup_server_socket(daemon);
1298 if (sock_fd < 0)
1299 goto out;
1300
1301 conf_fd = setup_config_changes(daemon);
1302 if (conf_fd < 0)
1303 goto out;
1304
1305 signal_fd = setup_signalfd(daemon);
1306 if (signal_fd < 0)
1307 goto out;
1308
1309 sock_pos = fdarray__add(&fda, sock_fd, POLLIN|POLLERR|POLLHUP, 0);
1310 if (sock_pos < 0)
1311 goto out;
1312
1313 file_pos = fdarray__add(&fda, conf_fd, POLLIN|POLLERR|POLLHUP, 0);
1314 if (file_pos < 0)
1315 goto out;
1316
1317 signal_pos = fdarray__add(&fda, signal_fd, POLLIN|POLLERR|POLLHUP, 0);
1318 if (signal_pos < 0)
1319 goto out;
1320
1321 signal(SIGINT, sig_handler);
1322 signal(SIGTERM, sig_handler);
1323 signal(SIGPIPE, SIG_IGN);
1324
1325 while (!done && !err) {
1326 err = daemon__reconfig(daemon);
1327
1328 if (!err && fdarray__poll(&fda, -1)) {
1329 bool reconfig = false;
1330
1331 if (fda.entries[sock_pos].revents & POLLIN)
1332 err = handle_server_socket(daemon, sock_fd);
1333 if (fda.entries[file_pos].revents & POLLIN)
1334 err = handle_config_changes(daemon, conf_fd, &reconfig);
1335 if (fda.entries[signal_pos].revents & POLLIN)
1336 err = handle_signalfd(daemon) < 0;
1337
1338 if (reconfig)
1339 err = setup_server_config(daemon);
1340 }
1341 }
1342
1343out:
1344 fdarray__exit(&fda);
1345
1346 daemon__kill(daemon);
1347 daemon__exit(daemon);
1348
1349 if (sock_fd != -1)
1350 close(sock_fd);
1351 if (conf_fd != -1)
1352 close(conf_fd);
1353 if (signal_fd != -1)
1354 close(signal_fd);
1355
1356 pr_info("daemon exited\n");
1357 fclose(daemon->out);
1358 return err;
1359}
1360
1361static int send_cmd(struct daemon *daemon, union cmd *cmd)
1362{
1363 int ret = -1, fd;
1364 char *line = NULL;
1365 size_t len = 0;
1366 ssize_t nread;
1367 FILE *in = NULL;
1368
1369 if (setup_client_config(daemon))
1370 return -1;
1371
1372 fd = setup_client_socket(daemon);
1373 if (fd < 0)
1374 return -1;
1375
1376 if (sizeof(*cmd) != writen(fd, cmd, sizeof(*cmd))) {
1377 perror("failed: write");
1378 goto out;
1379 }
1380
1381 in = fdopen(fd, "r");
1382 if (!in) {
1383 perror("failed: fdopen");
1384 goto out;
1385 }
1386
1387 while ((nread = getline(&line, &len, in)) != -1) {
1388 if (fwrite(line, nread, 1, stdout) != 1)
1389 goto out_fclose;
1390 fflush(stdout);
1391 }
1392
1393 ret = 0;
1394out_fclose:
1395 fclose(in);
1396 free(line);
1397out:
1398
1399 if (!in)
1400 close(fd);
1401 return ret;
1402}
1403
1404static int send_cmd_list(struct daemon *daemon)
1405{
1406 union cmd cmd = { .cmd = CMD_LIST, };
1407
1408 cmd.list.verbose = verbose;
1409 cmd.list.csv_sep = daemon->csv_sep ? *daemon->csv_sep : 0;
1410
1411 return send_cmd(daemon, &cmd);
1412}
1413
1414static int __cmd_signal(struct daemon *daemon, struct option parent_options[],
1415 int argc, const char **argv)
1416{
1417 const char *name = "all";
1418 struct option start_options[] = {
1419 OPT_STRING(0, "session", &name, "session",
1420 "Sent signal to specific session"),
1421 OPT_PARENT(parent_options),
1422 OPT_END()
1423 };
1424 union cmd cmd;
1425
1426 argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1427 if (argc)
1428 usage_with_options(daemon_usage, start_options);
1429
1430 if (setup_config(daemon)) {
1431 pr_err("failed: config not found\n");
1432 return -1;
1433 }
1434
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
1442static 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 = { .cmd = CMD_STOP, };
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 return send_cmd(daemon, &cmd);
1461}
1462
1463static int __cmd_ping(struct daemon *daemon, struct option parent_options[],
1464 int argc, const char **argv)
1465{
1466 const char *name = "all";
1467 struct option ping_options[] = {
1468 OPT_STRING(0, "session", &name, "session",
1469 "Ping to specific session"),
1470 OPT_PARENT(parent_options),
1471 OPT_END()
1472 };
1473 union cmd cmd = { .cmd = CMD_PING, };
1474
1475 argc = parse_options(argc, argv, ping_options, daemon_usage, 0);
1476 if (argc)
1477 usage_with_options(daemon_usage, ping_options);
1478
1479 if (setup_config(daemon)) {
1480 pr_err("failed: config not found\n");
1481 return -1;
1482 }
1483
1484 scnprintf(cmd.ping.name, sizeof(cmd.ping.name), "%s", name);
1485 return send_cmd(daemon, &cmd);
1486}
1487
1488int cmd_daemon(int argc, const char **argv)
1489{
1490 struct option daemon_options[] = {
1491 OPT_INCR('v', "verbose", &verbose, "be more verbose"),
1492 OPT_STRING(0, "config", &__daemon.config,
1493 "config file", "config file path"),
1494 OPT_STRING(0, "base", &__daemon.base_user,
1495 "directory", "base directory"),
1496 OPT_STRING_OPTARG('x', "field-separator", &__daemon.csv_sep,
1497 "field separator", "print counts with custom separator", ","),
1498 OPT_END()
1499 };
1500
1501 perf_exe(__daemon.perf, sizeof(__daemon.perf));
1502 __daemon.out = stdout;
1503
1504 argc = parse_options(argc, argv, daemon_options, daemon_usage,
1505 PARSE_OPT_STOP_AT_NON_OPTION);
1506
1507 if (argc) {
1508 if (!strcmp(argv[0], "start"))
1509 return __cmd_start(&__daemon, daemon_options, argc, argv);
1510 if (!strcmp(argv[0], "signal"))
1511 return __cmd_signal(&__daemon, daemon_options, argc, argv);
1512 else if (!strcmp(argv[0], "stop"))
1513 return __cmd_stop(&__daemon, daemon_options, argc, argv);
1514 else if (!strcmp(argv[0], "ping"))
1515 return __cmd_ping(&__daemon, daemon_options, argc, argv);
1516
1517 pr_err("failed: unknown command '%s'\n", argv[0]);
1518 return -1;
1519 }
1520
1521 if (setup_config(&__daemon)) {
1522 pr_err("failed: config not found\n");
1523 return -1;
1524 }
1525
1526 return send_cmd_list(&__daemon);
1527}
1528