Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf daemon: Add daemon command

Add a daemon skeleton with a minimal base (non) functionality, covering
various setup in start command.

Add an initial perf-daemon.txt with basic info.

This is in response to pople asking for the possibility to be able run
record long running sessions on the background.

The patchset that starts with this adds support to configure and run
record sessions on background via new 'perf daemon' command.

This is useful for being able to use perf as a flight recorder that one
can interact with asking for events to be enabled or disabled, added or
removed, etc.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexei Budankov <abudankov@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: https://lore.kernel.org/r/20210208200908.1019149-2-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
d450bc50 8524711d

+130
+1
tools/perf/Build
··· 24 24 perf-y += builtin-data.o 25 25 perf-y += builtin-version.o 26 26 perf-y += builtin-c2c.o 27 + perf-y += builtin-daemon.o 27 28 28 29 perf-$(CONFIG_TRACE) += builtin-trace.o 29 30 perf-$(CONFIG_LIBELF) += builtin-probe.o
+40
tools/perf/Documentation/perf-daemon.txt
··· 1 + perf-daemon(1) 2 + ============== 3 + 4 + 5 + NAME 6 + ---- 7 + perf-daemon - Run record sessions on background 8 + 9 + 10 + SYNOPSIS 11 + -------- 12 + [verse] 13 + 'perf daemon' 14 + 'perf daemon' [<options>] 15 + 'perf daemon start' [<options>] 16 + 17 + 18 + DESCRIPTION 19 + ----------- 20 + This command allows to run simple daemon process that starts and 21 + monitors configured record sessions. 22 + 23 + 24 + OPTIONS 25 + ------- 26 + -v:: 27 + --verbose:: 28 + Be more verbose. 29 + 30 + All generic options are available also under commands. 31 + 32 + 33 + START COMMAND 34 + ------------- 35 + The start command creates the daemon process. 36 + 37 + 38 + SEE ALSO 39 + -------- 40 + linkperf:perf-record[1], linkperf:perf-config[1]
+86
tools/perf/builtin-daemon.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <subcmd/parse-options.h> 3 + #include <linux/limits.h> 4 + #include <string.h> 5 + #include <signal.h> 6 + #include <stdio.h> 7 + #include <unistd.h> 8 + #include "builtin.h" 9 + #include "perf.h" 10 + #include "debug.h" 11 + #include "util.h" 12 + 13 + struct daemon { 14 + char *base; 15 + FILE *out; 16 + char perf[PATH_MAX]; 17 + }; 18 + 19 + static struct daemon __daemon = { }; 20 + 21 + static const char * const daemon_usage[] = { 22 + "perf daemon start [<options>]", 23 + "perf daemon [<options>]", 24 + NULL 25 + }; 26 + 27 + static bool done; 28 + 29 + static void sig_handler(int sig __maybe_unused) 30 + { 31 + done = true; 32 + } 33 + 34 + static int __cmd_start(struct daemon *daemon, struct option parent_options[], 35 + int argc, const char **argv) 36 + { 37 + struct option start_options[] = { 38 + OPT_PARENT(parent_options), 39 + OPT_END() 40 + }; 41 + int err = 0; 42 + 43 + argc = parse_options(argc, argv, start_options, daemon_usage, 0); 44 + if (argc) 45 + usage_with_options(daemon_usage, start_options); 46 + 47 + debug_set_file(daemon->out); 48 + debug_set_display_time(true); 49 + 50 + pr_info("daemon started (pid %d)\n", getpid()); 51 + 52 + signal(SIGINT, sig_handler); 53 + signal(SIGTERM, sig_handler); 54 + 55 + while (!done && !err) { 56 + sleep(1); 57 + } 58 + 59 + pr_info("daemon exited\n"); 60 + fclose(daemon->out); 61 + return err; 62 + } 63 + 64 + int cmd_daemon(int argc, const char **argv) 65 + { 66 + struct option daemon_options[] = { 67 + OPT_INCR('v', "verbose", &verbose, "be more verbose"), 68 + OPT_END() 69 + }; 70 + 71 + perf_exe(__daemon.perf, sizeof(__daemon.perf)); 72 + __daemon.out = stdout; 73 + 74 + argc = parse_options(argc, argv, daemon_options, daemon_usage, 75 + PARSE_OPT_STOP_AT_NON_OPTION); 76 + 77 + if (argc) { 78 + if (!strcmp(argv[0], "start")) 79 + return __cmd_start(&__daemon, daemon_options, argc, argv); 80 + 81 + pr_err("failed: unknown command '%s'\n", argv[0]); 82 + return -1; 83 + } 84 + 85 + return -1; 86 + }
+1
tools/perf/builtin.h
··· 37 37 int cmd_mem(int argc, const char **argv); 38 38 int cmd_data(int argc, const char **argv); 39 39 int cmd_ftrace(int argc, const char **argv); 40 + int cmd_daemon(int argc, const char **argv); 40 41 41 42 int find_scripts(char **scripts_array, char **scripts_path_array, int num, 42 43 int pathlen);
+1
tools/perf/command-list.txt
··· 31 31 perf-top mainporcelain common 32 32 perf-trace mainporcelain audit 33 33 perf-version mainporcelain common 34 + perf-daemon mainporcelain common
+1
tools/perf/perf.c
··· 88 88 { "mem", cmd_mem, 0 }, 89 89 { "data", cmd_data, 0 }, 90 90 { "ftrace", cmd_ftrace, 0 }, 91 + { "daemon", cmd_daemon, 0 }, 91 92 }; 92 93 93 94 struct pager_config {