Lines Matching +full:run +full:- +full:control

1 // SPDX-License-Identifier: GPL-2.0
4 #include <subcmd/parse-options.h>
34 #define SESSION_CONTROL "control"
40 * OK - session is up and running
41 * RECONFIG - session is pending for reconfiguration,
43 * KILL - session is pending to be killed
49 * - reads config file and setup session objects
52 * OK - no change needed
53 * RECONFIG - session needs to be changed
54 * (run variable changed)
55 * KILL - session needs to be killed
59 * - scans session objects and does following actions
62 * OK - skip
63 * RECONFIG - session is killed and re-run with new config
64 * KILL - session is killed
66 * - all sessions have OK state on the function exit
77 char *run; member
78 char *control; member
123 session->name = strdup(name); in daemon__add_session()
124 if (!session->name) { in daemon__add_session()
129 session->pid = -1; in daemon__add_session()
130 list_add_tail(&session->list, &config->sessions); in daemon__add_session()
138 list_for_each_entry(session, &daemon->sessions, list) { in daemon__find_session()
139 if (!strcmp(session->name, name)) in daemon__find_session()
148 const char *p = var + sizeof("session-") - 1; in get_session_name()
150 while (*p != '.' && *p != 0x0 && len--) in get_session_name()
154 return *p == '.' ? 0 : -EINVAL; in get_session_name()
162 if (get_session_name(var, name, sizeof(name) - 1)) in session_config()
163 return -EINVAL; in session_config()
167 return -EINVAL; in session_config()
177 return -ENOMEM; in session_config()
182 session->state = RECONFIG; in session_config()
183 } else if (session->state == KILL) { in session_config()
186 session->state = OK; in session_config()
189 if (!strcmp(var, "run")) { in session_config()
192 if (session->run) in session_config()
193 same = !strcmp(session->run, value); in session_config()
196 if (session->run) { in session_config()
197 zfree(&session->run); in session_config()
201 session->run = strdup(value); in session_config()
202 if (!session->run) in session_config()
203 return -ENOMEM; in session_config()
206 * Either new or changed run value is defined, in session_config()
209 session->state = RECONFIG; in session_config()
220 if (strstarts(var, "session-")) { in server_config()
222 } else if (!strcmp(var, "daemon.base") && !daemon->base_user) { in server_config()
223 if (daemon->base && strcmp(daemon->base, value)) { in server_config()
225 return -EINVAL; in server_config()
227 daemon->base = strdup(value); in server_config()
228 if (!daemon->base) in server_config()
229 return -ENOMEM; in server_config()
239 if (!strcmp(var, "daemon.base") && !daemon->base_user) { in client_config()
240 daemon->base = strdup(value); in client_config()
241 if (!daemon->base) in client_config()
242 return -ENOMEM; in client_config()
252 if (!daemon->base) { in check_base()
254 return -EINVAL; in check_base()
257 if (stat(daemon->base, &st)) { in check_base()
261 daemon->base); in check_base()
262 return -EACCES; in check_base()
265 daemon->base); in check_base()
266 return -EACCES; in check_base()
269 daemon->base, strerror(errno)); in check_base()
270 return -errno; in check_base()
276 daemon->base); in check_base()
277 return -EINVAL; in check_base()
285 struct perf_config_set *set = perf_config_set__load_file(daemon->config_real); in setup_client_config()
286 int err = -ENOMEM; in setup_client_config()
300 int err = -ENOMEM; in setup_server_config()
309 list_for_each_entry(session, &daemon->sessions, list) in setup_server_config()
310 session->state = KILL; in setup_server_config()
312 set = perf_config_set__load_file(daemon->config_real); in setup_server_config()
328 if (asprintf(&session->base, "%s/session-%s", in daemon_session__run()
329 daemon->base, session->name) < 0) { in daemon_session__run()
331 return -1; in daemon_session__run()
334 if (mkdir(session->base, 0755) && errno != EEXIST) { in daemon_session__run()
336 return -1; in daemon_session__run()
339 session->start = time(NULL); in daemon_session__run()
341 session->pid = fork(); in daemon_session__run()
342 if (session->pid < 0) in daemon_session__run()
343 return -1; in daemon_session__run()
344 if (session->pid > 0) { in daemon_session__run()
346 session->name, session->pid, session->run); in daemon_session__run()
350 if (chdir(session->base)) { in daemon_session__run()
352 return -1; in daemon_session__run()
358 return -1; in daemon_session__run()
367 return -1; in daemon_session__run()
375 perror("failed: create control fifo"); in daemon_session__run()
376 return -1; in daemon_session__run()
381 return -1; in daemon_session__run()
384 scnprintf(buf, sizeof(buf), "%s record --control=fifo:%s,%s %s", in daemon_session__run()
385 daemon->perf, SESSION_CONTROL, SESSION_ACK, session->run); in daemon_session__run()
389 exit(-1); in daemon_session__run()
391 exit(execve(daemon->perf, argv, NULL)); in daemon_session__run()
392 return -1; in daemon_session__run()
409 err = read(daemon->signal_fd, &si, sizeof(struct signalfd_siginfo)); in handle_signalfd()
412 return -1; in handle_signalfd()
415 list_for_each_entry(session, &daemon->sessions, list) { in handle_signalfd()
416 if (session->pid == -1) in handle_signalfd()
419 pid = waitpid(session->pid, &status, WNOHANG); in handle_signalfd()
425 session->name, WEXITSTATUS(status)); in handle_signalfd()
428 session->name, WTERMSIG(status)); in handle_signalfd()
431 session->name, WSTOPSIG(status)); in handle_signalfd()
434 session->name, status); in handle_signalfd()
437 session->state = KILL; in handle_signalfd()
438 session->pid = -1; in handle_signalfd()
448 .fd = daemon->signal_fd, in daemon_session__wait()
462 return -1; in daemon_session__wait()
466 return -1; in daemon_session__wait()
467 } while (session->pid != -1); in daemon_session__wait()
476 list_for_each_entry(session, &daemon->sessions, list) { in daemon__has_alive_session()
477 if (session->pid != -1) in daemon__has_alive_session()
487 .fd = daemon->signal_fd, in daemon__wait()
501 return -1; in daemon__wait()
505 return -1; in daemon__wait()
517 int control, ack = -1, len; in daemon_session__control() local
519 int ret = -1; in daemon_session__control()
522 /* open the control file */ in daemon_session__control()
524 session->base, SESSION_CONTROL); in daemon_session__control()
526 control = open(control_path, O_WRONLY|O_NONBLOCK); in daemon_session__control()
527 if (control < 0) in daemon_session__control()
528 return -1; in daemon_session__control()
533 session->base, SESSION_ACK); in daemon_session__control()
537 close(control); in daemon_session__control()
538 return -1; in daemon_session__control()
545 err = writen(control, msg, len); in daemon_session__control()
547 pr_err("failed: write to control pipe: %d (%s)\n", in daemon_session__control()
559 pr_err("failed: control ack timeout\n"); in daemon_session__control()
575 if (ack != -1) in daemon_session__control()
578 close(control); in daemon_session__control()
590 return -1; in setup_server_socket()
596 return -1; in setup_server_socket()
599 scnprintf(path, sizeof(path), "%s/control", daemon->base); in setup_server_socket()
602 pr_err("failed: control path too long '%s'\n", path); in setup_server_socket()
604 return -1; in setup_server_socket()
610 strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); in setup_server_socket()
613 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { in setup_server_socket()
616 return -1; in setup_server_socket()
619 if (listen(fd, 1) == -1) { in setup_server_socket()
622 return -1; in setup_server_socket()
675 char csv_sep = cmd->list.csv_sep; in cmd_session_list()
684 csv_sep, daemon->base, in cmd_session_list()
686 csv_sep, daemon->base, SESSION_OUTPUT); in cmd_session_list()
690 csv_sep, daemon->base, "lock"); in cmd_session_list()
694 csv_sep, (uint64_t)((curr - daemon->start) / 60)); in cmd_session_list()
698 fprintf(out, "[%d:daemon] base: %s\n", getpid(), daemon->base); in cmd_session_list()
699 if (cmd->list.verbose) { in cmd_session_list()
701 daemon->base, SESSION_OUTPUT); in cmd_session_list()
703 daemon->base); in cmd_session_list()
705 (uint64_t)((curr - daemon->start) / 60)); in cmd_session_list()
709 list_for_each_entry(session, &daemon->sessions, list) { in cmd_session_list()
713 session->pid, in cmd_session_list()
715 csv_sep, session->name, in cmd_session_list()
717 csv_sep, session->run); in cmd_session_list()
721 csv_sep, session->base, in cmd_session_list()
723 csv_sep, session->base, SESSION_OUTPUT); in cmd_session_list()
726 /* session control */ in cmd_session_list()
727 csv_sep, session->base, SESSION_CONTROL, in cmd_session_list()
729 csv_sep, session->base, SESSION_ACK); in cmd_session_list()
733 csv_sep, (uint64_t)((curr - session->start) / 60)); in cmd_session_list()
738 session->pid, session->name, session->run); in cmd_session_list()
739 if (!cmd->list.verbose) in cmd_session_list()
742 session->base); in cmd_session_list()
744 session->base, SESSION_OUTPUT); in cmd_session_list()
745 fprintf(out, " control: %s/%s\n", in cmd_session_list()
746 session->base, SESSION_CONTROL); in cmd_session_list()
748 session->base, SESSION_ACK); in cmd_session_list()
750 (uint64_t)((curr - session->start) / 60)); in cmd_session_list()
759 if (session->pid < 0) in daemon_session__signal()
760 return -1; in daemon_session__signal()
761 return kill(session->pid, sig); in daemon_session__signal()
769 all = !strcmp(cmd->signal.name, "all"); in cmd_session_kill()
771 list_for_each_entry(session, &daemon->sessions, list) { in cmd_session_kill()
772 if (all || !strcmp(cmd->signal.name, session->name)) { in cmd_session_kill()
773 daemon_session__signal(session, cmd->signal.sig); in cmd_session_kill()
775 cmd->signal.sig, session->name, session->pid); in cmd_session_kill()
792 all = !strcmp(cmd->ping.name, "all"); in cmd_session_ping()
794 list_for_each_entry(session, &daemon->sessions, list) { in cmd_session_ping()
795 if (all || !strcmp(cmd->ping.name, session->name)) { in cmd_session_ping()
798 fprintf(out, "%-4s %s\n", ping_str[state], session->name); in cmd_session_ping()
804 fprintf(out, "%-4s %s (not found)\n", in cmd_session_ping()
805 ping_str[PING_FAIL], cmd->ping.name); in cmd_session_ping()
812 int ret = -1, fd; in handle_server_socket()
819 return -1; in handle_server_socket()
866 if (fd == -1) { in setup_client_socket()
868 return -1; in setup_client_socket()
871 scnprintf(path, sizeof(path), "%s/control", daemon->base); in setup_client_socket()
874 pr_err("failed: control path too long '%s'\n", path); in setup_client_socket()
876 return -1; in setup_client_socket()
881 strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); in setup_client_socket()
883 if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { in setup_client_socket()
886 return -1; in setup_client_socket()
910 session->name); in daemon_session__kill()
922 list_for_each_entry(session, &daemon->sessions, list) in daemon__signal()
928 zfree(&session->base); in daemon_session__delete()
929 zfree(&session->name); in daemon_session__delete()
930 zfree(&session->run); in daemon_session__delete()
936 list_del(&session->list); in daemon_session__remove()
944 list_for_each_entry(session, &daemon->sessions, list) in daemon__stop()
976 list_for_each_entry_safe(session, h, &daemon->sessions, list) in daemon__exit()
979 zfree(&daemon->config_real); in daemon__exit()
980 zfree(&daemon->config_base); in daemon__exit()
981 zfree(&daemon->base); in daemon__exit()
988 list_for_each_entry_safe(session, n, &daemon->sessions, list) { in daemon__reconfig()
990 if (session->state == OK) in daemon__reconfig()
994 if (session->state == KILL) { in daemon__reconfig()
995 if (session->pid > 0) { in daemon__reconfig()
997 pr_info("reconfig: session '%s' killed\n", session->name); in daemon__reconfig()
1004 if (session->pid > 0) { in daemon__reconfig()
1006 pr_info("reconfig: session '%s' killed\n", session->name); in daemon__reconfig()
1009 return -1; in daemon__reconfig()
1011 session->state = OK; in daemon__reconfig()
1019 char *basen = strdup(daemon->config_real); in setup_config_changes()
1020 char *dirn = strdup(daemon->config_real); in setup_config_changes()
1022 int fd, wd = -1; in setup_config_changes()
1039 daemon->config_base = strdup(base); in setup_config_changes()
1040 if (!daemon->config_base) { in setup_config_changes()
1042 wd = -1; in setup_config_changes()
1051 return wd < 0 ? -1 : fd; in setup_config_changes()
1065 if ((event->mask & IN_CLOSE_WRITE) && in process_inotify_event()
1066 !(event->mask & IN_ISDIR)) { in process_inotify_event()
1067 if (!strcmp(event->name, daemon->config_base)) in process_inotify_event()
1070 p += sizeof(*event) + event->len; in process_inotify_event()
1083 if (len == -1) { in handle_config_changes()
1086 return -1; in handle_config_changes()
1097 if (daemon->base_user) { in setup_config()
1098 daemon->base = strdup(daemon->base_user); in setup_config()
1099 if (!daemon->base) in setup_config()
1100 return -ENOMEM; in setup_config()
1103 if (daemon->config) { in setup_config()
1104 char *real = realpath(daemon->config, NULL); in setup_config()
1108 return -1; in setup_config()
1110 daemon->config_real = real; in setup_config()
1115 daemon->config_real = strdup(perf_etc_perfconfig()); in setup_config()
1117 daemon->config_real = strdup(perf_home_perfconfig()); in setup_config()
1119 return daemon->config_real ? 0 : -1; in setup_config()
1128 return -1; in lockf()
1149 scnprintf(path, sizeof(path), "%s/lock", daemon->base); in check_lock()
1153 return -1; in check_lock()
1158 pid, daemon->base); in check_lock()
1160 return -1; in check_lock()
1169 return -1; in check_lock()
1175 return -1; in check_lock()
1187 return -1; in go_background()
1193 return -1; in go_background()
1196 return -1; in go_background()
1200 if (chdir(daemon->base)) { in go_background()
1202 return -1; in go_background()
1208 return -1; in go_background()
1214 return -1; in go_background()
1222 daemon->out = fdopen(1, "w"); in go_background()
1223 if (!daemon->out) { in go_background()
1226 return -1; in go_background()
1229 setbuf(daemon->out, NULL); in go_background()
1240 if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) in setup_signalfd()
1241 return -1; in setup_signalfd()
1243 daemon->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); in setup_signalfd()
1244 return daemon->signal_fd; in setup_signalfd()
1256 int sock_fd = -1, conf_fd = -1, signal_fd = -1; in __cmd_start()
1265 daemon->start = time(NULL); in __cmd_start()
1269 return -1; in __cmd_start()
1273 return -1; in __cmd_start()
1276 return -1; in __cmd_start()
1289 debug_set_file(daemon->out); in __cmd_start()
1327 if (!err && fdarray__poll(&fda, -1)) { in __cmd_start()
1348 if (sock_fd != -1) in __cmd_start()
1350 if (conf_fd != -1) in __cmd_start()
1352 if (signal_fd != -1) in __cmd_start()
1356 fclose(daemon->out); in __cmd_start()
1362 int ret = -1, fd; in send_cmd()
1369 return -1; in send_cmd()
1373 return -1; in send_cmd()
1386 while ((nread = getline(&line, &len, in)) != -1) { in send_cmd()
1410 cmd.list.csv_sep = daemon->csv_sep ? *daemon->csv_sep : 0; in send_cmd_list()
1433 return -1; in __cmd_signal()
1439 strncpy(cmd.signal.name, name, sizeof(cmd.signal.name) - 1); in __cmd_signal()
1459 return -1; in __cmd_stop()
1485 return -1; in __cmd_ping()
1510 OPT_STRING_OPTARG('x', "field-separator", &__daemon.csv_sep, in cmd_daemon()
1514 int ret = -1; in cmd_daemon()
1518 return -ENOMEM; in cmd_daemon()