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
1124static int lockf(int fd, int cmd, off_t len)
1125{
1126 if (cmd != F_TLOCK || len != 0)
1127 return -1;
1128
1129 return flock(fd, LOCK_EX | LOCK_NB);
1130}
1131#endif
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141static int check_lock(struct daemon *daemon)
1142{
1143 char path[PATH_MAX];
1144 char buf[20];
1145 int fd, pid;
1146 ssize_t len;
1147
1148 scnprintf(path, sizeof(path), "%s/lock", daemon->base);
1149
1150 fd = open(path, O_RDWR|O_CREAT|O_CLOEXEC, 0640);
1151 if (fd < 0)
1152 return -1;
1153
1154 if (lockf(fd, F_TLOCK, 0) < 0) {
1155 filename__read_int(path, &pid);
1156 fprintf(stderr, "failed: another perf daemon (pid %d) owns %s\n",
1157 pid, daemon->base);
1158 close(fd);
1159 return -1;
1160 }
1161
1162 scnprintf(buf, sizeof(buf), "%d", getpid());
1163 len = strlen(buf);
1164
1165 if (write(fd, buf, len) != len) {
1166 perror("failed: write");
1167 close(fd);
1168 return -1;
1169 }
1170
1171 if (ftruncate(fd, len)) {
1172 perror("failed: ftruncate");
1173 close(fd);
1174 return -1;
1175 }
1176
1177 return 0;
1178}
1179
1180static int go_background(struct daemon *daemon)
1181{
1182 int pid, fd;
1183
1184 pid = fork();
1185 if (pid < 0)
1186 return -1;
1187
1188 if (pid > 0)
1189 return 1;
1190
1191 if (setsid() < 0)
1192 return -1;
1193
1194 if (check_lock(daemon))
1195 return -1;
1196
1197 umask(0);
1198
1199 if (chdir(daemon->base)) {
1200 perror("failed: chdir");
1201 return -1;
1202 }
1203
1204 fd = open("output", O_RDWR|O_CREAT|O_TRUNC, 0644);
1205 if (fd < 0) {
1206 perror("failed: open");
1207 return -1;
1208 }
1209
1210 if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
1211 perror("failed: fcntl FD_CLOEXEC");
1212 close(fd);
1213 return -1;
1214 }
1215
1216 close(0);
1217 dup2(fd, 1);
1218 dup2(fd, 2);
1219 close(fd);
1220
1221 daemon->out = fdopen(1, "w");
1222 if (!daemon->out) {
1223 close(1);
1224 close(2);
1225 return -1;
1226 }
1227
1228 setbuf(daemon->out, NULL);
1229 return 0;
1230}
1231
1232static int setup_signalfd(struct daemon *daemon)
1233{
1234 sigset_t mask;
1235
1236 sigemptyset(&mask);
1237 sigaddset(&mask, SIGCHLD);
1238
1239 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
1240 return -1;
1241
1242 daemon->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
1243 return daemon->signal_fd;
1244}
1245
1246static int __cmd_start(struct daemon *daemon, struct option parent_options[],
1247 int argc, const char **argv)
1248{
1249 bool foreground = false;
1250 struct option start_options[] = {
1251 OPT_BOOLEAN('f', "foreground", &foreground, "stay on console"),
1252 OPT_PARENT(parent_options),
1253 OPT_END()
1254 };
1255 int sock_fd = -1, conf_fd = -1, signal_fd = -1;
1256 int sock_pos, file_pos, signal_pos;
1257 struct fdarray fda;
1258 int err = 0;
1259
1260 argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1261 if (argc)
1262 usage_with_options(daemon_usage, start_options);
1263
1264 daemon->start = time(NULL);
1265
1266 if (setup_config(daemon)) {
1267 pr_err("failed: config not found\n");
1268 return -1;
1269 }
1270
1271 if (setup_server_config(daemon))
1272 return -1;
1273
1274 if (foreground && check_lock(daemon))
1275 return -1;
1276
1277 if (!foreground) {
1278 err = go_background(daemon);
1279 if (err) {
1280
1281 if (err == 1)
1282 err = 0;
1283 daemon__exit(daemon);
1284 return err;
1285 }
1286 }
1287
1288 debug_set_file(daemon->out);
1289 debug_set_display_time(true);
1290
1291 pr_info("daemon started (pid %d)\n", getpid());
1292
1293 fdarray__init(&fda, 3);
1294
1295 sock_fd = setup_server_socket(daemon);
1296 if (sock_fd < 0)
1297 goto out;
1298
1299 conf_fd = setup_config_changes(daemon);
1300 if (conf_fd < 0)
1301 goto out;
1302
1303 signal_fd = setup_signalfd(daemon);
1304 if (signal_fd < 0)
1305 goto out;
1306
1307 sock_pos = fdarray__add(&fda, sock_fd, POLLIN|POLLERR|POLLHUP, 0);
1308 if (sock_pos < 0)
1309 goto out;
1310
1311 file_pos = fdarray__add(&fda, conf_fd, POLLIN|POLLERR|POLLHUP, 0);
1312 if (file_pos < 0)
1313 goto out;
1314
1315 signal_pos = fdarray__add(&fda, signal_fd, POLLIN|POLLERR|POLLHUP, 0);
1316 if (signal_pos < 0)
1317 goto out;
1318
1319 signal(SIGINT, sig_handler);
1320 signal(SIGTERM, sig_handler);
1321 signal(SIGPIPE, SIG_IGN);
1322
1323 while (!done && !err) {
1324 err = daemon__reconfig(daemon);
1325
1326 if (!err && fdarray__poll(&fda, -1)) {
1327 bool reconfig = false;
1328
1329 if (fda.entries[sock_pos].revents & POLLIN)
1330 err = handle_server_socket(daemon, sock_fd);
1331 if (fda.entries[file_pos].revents & POLLIN)
1332 err = handle_config_changes(daemon, conf_fd, &reconfig);
1333 if (fda.entries[signal_pos].revents & POLLIN)
1334 err = handle_signalfd(daemon) < 0;
1335
1336 if (reconfig)
1337 err = setup_server_config(daemon);
1338 }
1339 }
1340
1341out:
1342 fdarray__exit(&fda);
1343
1344 daemon__kill(daemon);
1345 daemon__exit(daemon);
1346
1347 if (sock_fd != -1)
1348 close(sock_fd);
1349 if (conf_fd != -1)
1350 close(conf_fd);
1351 if (signal_fd != -1)
1352 close(signal_fd);
1353
1354 pr_info("daemon exited\n");
1355 fclose(daemon->out);
1356 return err;
1357}
1358
1359static int send_cmd(struct daemon *daemon, union cmd *cmd)
1360{
1361 int ret = -1, fd;
1362 char *line = NULL;
1363 size_t len = 0;
1364 ssize_t nread;
1365 FILE *in = NULL;
1366
1367 if (setup_client_config(daemon))
1368 return -1;
1369
1370 fd = setup_client_socket(daemon);
1371 if (fd < 0)
1372 return -1;
1373
1374 if (sizeof(*cmd) != writen(fd, cmd, sizeof(*cmd))) {
1375 perror("failed: write");
1376 goto out;
1377 }
1378
1379 in = fdopen(fd, "r");
1380 if (!in) {
1381 perror("failed: fdopen");
1382 goto out;
1383 }
1384
1385 while ((nread = getline(&line, &len, in)) != -1) {
1386 if (fwrite(line, nread, 1, stdout) != 1)
1387 goto out_fclose;
1388 fflush(stdout);
1389 }
1390
1391 ret = 0;
1392out_fclose:
1393 fclose(in);
1394 free(line);
1395out:
1396
1397 if (!in)
1398 close(fd);
1399 return ret;
1400}
1401
1402static int send_cmd_list(struct daemon *daemon)
1403{
1404 union cmd cmd;
1405
1406 memset(&cmd, 0, sizeof(cmd));
1407 cmd.list.cmd = CMD_LIST;
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 memset(&cmd, 0, sizeof(cmd));
1436 cmd.signal.cmd = CMD_SIGNAL,
1437 cmd.signal.sig = SIGUSR2;
1438 strncpy(cmd.signal.name, name, sizeof(cmd.signal.name) - 1);
1439
1440 return send_cmd(daemon, &cmd);
1441}
1442
1443static int __cmd_stop(struct daemon *daemon, struct option parent_options[],
1444 int argc, const char **argv)
1445{
1446 struct option start_options[] = {
1447 OPT_PARENT(parent_options),
1448 OPT_END()
1449 };
1450 union cmd cmd;
1451
1452 argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1453 if (argc)
1454 usage_with_options(daemon_usage, start_options);
1455
1456 if (setup_config(daemon)) {
1457 pr_err("failed: config not found\n");
1458 return -1;
1459 }
1460
1461 memset(&cmd, 0, sizeof(cmd));
1462 cmd.cmd = CMD_STOP;
1463 return send_cmd(daemon, &cmd);
1464}
1465
1466static int __cmd_ping(struct daemon *daemon, struct option parent_options[],
1467 int argc, const char **argv)
1468{
1469 const char *name = "all";
1470 struct option ping_options[] = {
1471 OPT_STRING(0, "session", &name, "session",
1472 "Ping to specific session"),
1473 OPT_PARENT(parent_options),
1474 OPT_END()
1475 };
1476 union cmd cmd;
1477
1478 argc = parse_options(argc, argv, ping_options, daemon_usage, 0);
1479 if (argc)
1480 usage_with_options(daemon_usage, ping_options);
1481
1482 if (setup_config(daemon)) {
1483 pr_err("failed: config not found\n");
1484 return -1;
1485 }
1486
1487 memset(&cmd, 0, sizeof(cmd));
1488 cmd.cmd = CMD_PING;
1489 scnprintf(cmd.ping.name, sizeof(cmd.ping.name), "%s", name);
1490 return send_cmd(daemon, &cmd);
1491}
1492
1493int cmd_daemon(int argc, const char **argv)
1494{
1495 struct option daemon_options[] = {
1496 OPT_INCR('v', "verbose", &verbose, "be more verbose"),
1497 OPT_STRING(0, "config", &__daemon.config,
1498 "config file", "config file path"),
1499 OPT_STRING(0, "base", &__daemon.base_user,
1500 "directory", "base directory"),
1501 OPT_STRING_OPTARG('x', "field-separator", &__daemon.csv_sep,
1502 "field separator", "print counts with custom separator", ","),
1503 OPT_END()
1504 };
1505
1506 perf_exe(__daemon.perf, sizeof(__daemon.perf));
1507 __daemon.out = stdout;
1508
1509 argc = parse_options(argc, argv, daemon_options, daemon_usage,
1510 PARSE_OPT_STOP_AT_NON_OPTION);
1511
1512 if (argc) {
1513 if (!strcmp(argv[0], "start"))
1514 return __cmd_start(&__daemon, daemon_options, argc, argv);
1515 if (!strcmp(argv[0], "signal"))
1516 return __cmd_signal(&__daemon, daemon_options, argc, argv);
1517 else if (!strcmp(argv[0], "stop"))
1518 return __cmd_stop(&__daemon, daemon_options, argc, argv);
1519 else if (!strcmp(argv[0], "ping"))
1520 return __cmd_ping(&__daemon, daemon_options, argc, argv);
1521
1522 pr_err("failed: unknown command '%s'\n", argv[0]);
1523 return -1;
1524 }
1525
1526 if (setup_config(&__daemon)) {
1527 pr_err("failed: config not found\n");
1528 return -1;
1529 }
1530
1531 return send_cmd_list(&__daemon);
1532}
1533