Em Sun, Jan 31, 2021 at 12:48:37AM +0100, Jiri Olsa escreveu: > Adding support for client socket side that will be used > to send commands to daemon server socket. > > This patch adds only the core support, all commands using > this functionality are coming in following patches. > > Signed-off-by: Jiri Olsa <jo...@kernel.org> > --- > tools/perf/builtin-daemon.c | 105 ++++++++++++++++++++++++++++++++++++ > 1 file changed, 105 insertions(+) > > diff --git a/tools/perf/builtin-daemon.c b/tools/perf/builtin-daemon.c > index 756d60616d7d..eada3ceb9b0c 100644 > --- a/tools/perf/builtin-daemon.c > +++ b/tools/perf/builtin-daemon.c > @@ -11,6 +11,7 @@ > #include <sys/types.h> > #include <sys/socket.h> > #include <sys/un.h> > +#include <sys/stat.h> > #include <poll.h> > #include "builtin.h" > #include "perf.h" > @@ -42,6 +43,50 @@ static void sig_handler(int sig __maybe_unused) > done = true; > } > > +static int client_config(const char *var, const char *value, void *cb) > +{ > + struct daemon *daemon = cb; > + > + if (!strcmp(var, "daemon.base") && !daemon->base_user) { > + daemon->base = strdup(value); > + if (!daemon->base) > + return -ENOMEM; > + } > + > + return 0; > +} > + > +static int check_base(struct daemon *daemon) > +{ > + struct stat st; > + > + if (!daemon->base) { > + pr_err("failed: base not defined\n"); > + return -EINVAL; > + } > + > + if (stat(daemon->base, &st)) { > + pr_err("failed: base '%s' does not exists\n", daemon->base); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int setup_client_config(struct daemon *daemon) > +{ > + struct perf_config_set *set; > + int err = -ENOMEM; > + > + set = perf_config_set__load_file(daemon->config_real);
struct perf_config_set *set = perf_config_set__load_file(daemon->config_real); > + if (set) { > + err = perf_config_set(set, client_config, daemon); > + perf_config_set__delete(set); > + } > + > + return err ?: check_base(daemon); > +} > + > static int setup_server_socket(struct daemon *daemon) > { > struct sockaddr_un addr; > @@ -114,6 +159,32 @@ static int handle_server_socket(struct daemon *daemon > __maybe_unused, int sock_f > return ret; > } > > +static int setup_client_socket(struct daemon *daemon) > +{ > + struct sockaddr_un addr; > + char path[100]; > + int fd; > + > + fd = socket(AF_UNIX, SOCK_STREAM, 0); Ditto > + if (fd == -1) { > + perror("failed: socket"); > + return -1; > + } > + > + scnprintf(path, PATH_MAX, "%s/control", daemon->base); > + > + memset(&addr, 0, sizeof(addr)); > + addr.sun_family = AF_UNIX; > + strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); > + > + if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { > + perror("failed: connect"); close fd > + return -1; > + } > + > + return fd; > +} > + > static void daemon__free(struct daemon *daemon) > { > free(daemon->config_real); > @@ -211,6 +282,40 @@ static int __cmd_start(struct daemon *daemon, struct > option parent_options[], > return err; > } > > +__maybe_unused > +static int send_cmd(struct daemon *daemon, union cmd *cmd) > +{ > + char *line = NULL; > + size_t len = 0; > + ssize_t nread; > + FILE *in; > + int fd; > + > + if (setup_client_config(daemon)) > + return -1; > + > + fd = setup_client_socket(daemon); > + if (fd < 0) > + return -1; > + > + if (sizeof(*cmd) != write(fd, cmd, sizeof(*cmd))) close fd > + return -1; > + > + in = fdopen(fd, "r"); > + if (!in) { > + perror("failed: fdopen"); close fd > + return -1; > + } > + > + while ((nread = getline(&line, &len, in)) != -1) { > + fwrite(line, nread, 1, stdout); > + fflush(stdout); > + } > + > + fclose(in); > + return 0; > +} > + > int cmd_daemon(int argc, const char **argv) > { > struct option daemon_options[] = { > -- > 2.29.2 > -- - Arnaldo