Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Feb 10-13, 2025
Register
Loading...
v6.13.7
   1// SPDX-License-Identifier: GPL-2.0
   2#include <internal/lib.h>
   3#include <inttypes.h>
   4#include <subcmd/parse-options.h>
   5#include <api/fd/array.h>
   6#include <api/fs/fs.h>
   7#include <linux/zalloc.h>
   8#include <linux/string.h>
   9#include <linux/limits.h>
  10#include <string.h>
  11#include <sys/file.h>
  12#include <signal.h>
  13#include <stdlib.h>
  14#include <time.h>
  15#include <stdio.h>
  16#include <unistd.h>
  17#include <errno.h>
  18#include <sys/inotify.h>
  19#include <libgen.h>
  20#include <sys/types.h>
  21#include <sys/socket.h>
  22#include <sys/un.h>
  23#include <sys/stat.h>
  24#include <sys/signalfd.h>
  25#include <sys/wait.h>
  26#include <poll.h>
  27#include "builtin.h"
  28#include "perf.h"
  29#include "debug.h"
  30#include "config.h"
  31#include "util.h"
  32
  33#define SESSION_OUTPUT  "output"
  34#define SESSION_CONTROL "control"
  35#define SESSION_ACK     "ack"
  36
  37/*
  38 * Session states:
  39 *
  40 *   OK       - session is up and running
  41 *   RECONFIG - session is pending for reconfiguration,
  42 *              new values are already loaded in session object
  43 *   KILL     - session is pending to be killed
  44 *
  45 * Session object life and its state is maintained by
  46 * following functions:
  47 *
  48 *  setup_server_config
  49 *    - reads config file and setup session objects
  50 *      with following states:
  51 *
  52 *      OK       - no change needed
  53 *      RECONFIG - session needs to be changed
  54 *                 (run variable changed)
  55 *      KILL     - session needs to be killed
  56 *                 (session is no longer in config file)
  57 *
  58 *  daemon__reconfig
  59 *    - scans session objects and does following actions
  60 *      for states:
  61 *
  62 *      OK       - skip
  63 *      RECONFIG - session is killed and re-run with new config
  64 *      KILL     - session is killed
  65 *
  66 *    - all sessions have OK state on the function exit
  67 */
  68enum daemon_session_state {
  69	OK,
  70	RECONFIG,
  71	KILL,
  72};
  73
  74struct daemon_session {
  75	char				*base;
  76	char				*name;
  77	char				*run;
  78	char				*control;
  79	int				 pid;
  80	struct list_head		 list;
  81	enum daemon_session_state	 state;
  82	time_t				 start;
  83};
  84
  85struct daemon {
  86	const char		*config;
  87	char			*config_real;
  88	char			*config_base;
  89	const char		*csv_sep;
  90	const char		*base_user;
  91	char			*base;
  92	struct list_head	 sessions;
  93	FILE			*out;
  94	char			*perf;
  95	int			 signal_fd;
  96	time_t			 start;
  97};
  98
  99static struct daemon __daemon = {
 100	.sessions = LIST_HEAD_INIT(__daemon.sessions),
 101};
 102
 103static const char * const daemon_usage[] = {
 104	"perf daemon {start|signal|stop|ping} [<options>]",
 105	"perf daemon [<options>]",
 106	NULL
 107};
 108
 109static volatile sig_atomic_t done;
 110
 111static void sig_handler(int sig __maybe_unused)
 112{
 113	done = true;
 114}
 115
 116static struct daemon_session *daemon__add_session(struct daemon *config, char *name)
 117{
 118	struct daemon_session *session = zalloc(sizeof(*session));
 119
 120	if (!session)
 121		return NULL;
 122
 123	session->name = strdup(name);
 124	if (!session->name) {
 125		free(session);
 126		return NULL;
 127	}
 128
 129	session->pid = -1;
 130	list_add_tail(&session->list, &config->sessions);
 131	return session;
 132}
 133
 134static struct daemon_session *daemon__find_session(struct daemon *daemon, char *name)
 135{
 136	struct daemon_session *session;
 137
 138	list_for_each_entry(session, &daemon->sessions, list) {
 139		if (!strcmp(session->name, name))
 140			return session;
 141	}
 142
 143	return NULL;
 144}
 145
 146static int get_session_name(const char *var, char *session, int len)
 147{
 148	const char *p = var + sizeof("session-") - 1;
 149
 150	while (*p != '.' && *p != 0x0 && len--)
 151		*session++ = *p++;
 152
 153	*session = 0;
 154	return *p == '.' ? 0 : -EINVAL;
 155}
 156
 157static int session_config(struct daemon *daemon, const char *var, const char *value)
 158{
 159	struct daemon_session *session;
 160	char name[100];
 161
 162	if (get_session_name(var, name, sizeof(name) - 1))
 163		return -EINVAL;
 164
 165	var = strchr(var, '.');
 166	if (!var)
 167		return -EINVAL;
 168
 169	var++;
 170
 171	session = daemon__find_session(daemon, name);
 172
 173	if (!session) {
 174		/* New session is defined. */
 175		session = daemon__add_session(daemon, name);
 176		if (!session)
 177			return -ENOMEM;
 178
 179		pr_debug("reconfig: found new session %s\n", name);
 180
 181		/* Trigger reconfig to start it. */
 182		session->state = RECONFIG;
 183	} else if (session->state == KILL) {
 184		/* Current session is defined, no action needed. */
 185		pr_debug("reconfig: found current session %s\n", name);
 186		session->state = OK;
 187	}
 188
 189	if (!strcmp(var, "run")) {
 190		bool same = false;
 191
 192		if (session->run)
 193			same = !strcmp(session->run, value);
 194
 195		if (!same) {
 196			if (session->run) {
 197				zfree(&session->run);
 198				pr_debug("reconfig: session %s is changed\n", name);
 199			}
 200
 201			session->run = strdup(value);
 202			if (!session->run)
 203				return -ENOMEM;
 204
 205			/*
 206			 * Either new or changed run value is defined,
 207			 * trigger reconfig for the session.
 208			 */
 209			session->state = RECONFIG;
 210		}
 211	}
 212
 213	return 0;
 214}
 215
 216static int server_config(const char *var, const char *value, void *cb)
 217{
 218	struct daemon *daemon = cb;
 219
 220	if (strstarts(var, "session-")) {
 221		return session_config(daemon, var, value);
 222	} else if (!strcmp(var, "daemon.base") && !daemon->base_user) {
 223		if (daemon->base && strcmp(daemon->base, value)) {
 224			pr_err("failed: can't redefine base, bailing out\n");
 225			return -EINVAL;
 226		}
 227		daemon->base = strdup(value);
 228		if (!daemon->base)
 229			return -ENOMEM;
 230	}
 231
 232	return 0;
 233}
 234
 235static int client_config(const char *var, const char *value, void *cb)
 236{
 237	struct daemon *daemon = cb;
 238
 239	if (!strcmp(var, "daemon.base") && !daemon->base_user) {
 240		daemon->base = strdup(value);
 241		if (!daemon->base)
 242			return -ENOMEM;
 243	}
 244
 245	return 0;
 246}
 247
 248static int check_base(struct daemon *daemon)
 249{
 250	struct stat st;
 251
 252	if (!daemon->base) {
 253		pr_err("failed: base not defined\n");
 254		return -EINVAL;
 255	}
 256
 257	if (stat(daemon->base, &st)) {
 258		switch (errno) {
 259		case EACCES:
 260			pr_err("failed: permission denied for '%s' base\n",
 261			       daemon->base);
 262			return -EACCES;
 263		case ENOENT:
 264			pr_err("failed: base '%s' does not exists\n",
 265			       daemon->base);
 266			return -EACCES;
 267		default:
 268			pr_err("failed: can't access base '%s': %s\n",
 269			       daemon->base, strerror(errno));
 270			return -errno;
 271		}
 272	}
 273
 274	if ((st.st_mode & S_IFMT) != S_IFDIR) {
 275		pr_err("failed: base '%s' is not directory\n",
 276		       daemon->base);
 277		return -EINVAL;
 278	}
 279
 280	return 0;
 281}
 282
 283static int setup_client_config(struct daemon *daemon)
 284{
 285	struct perf_config_set *set = perf_config_set__load_file(daemon->config_real);
 286	int err = -ENOMEM;
 287
 288	if (set) {
 289		err = perf_config_set(set, client_config, daemon);
 290		perf_config_set__delete(set);
 291	}
 292
 293	return err ?: check_base(daemon);
 294}
 295
 296static int setup_server_config(struct daemon *daemon)
 297{
 298	struct perf_config_set *set;
 299	struct daemon_session *session;
 300	int err = -ENOMEM;
 301
 302	pr_debug("reconfig: started\n");
 303
 304	/*
 305	 * Mark all sessions for kill, the server config
 306	 * will set following states, see explanation at
 307	 * enum daemon_session_state declaration.
 308	 */
 309	list_for_each_entry(session, &daemon->sessions, list)
 310		session->state = KILL;
 311
 312	set = perf_config_set__load_file(daemon->config_real);
 313	if (set) {
 314		err = perf_config_set(set, server_config, daemon);
 315		perf_config_set__delete(set);
 316	}
 317
 318	return err ?: check_base(daemon);
 319}
 320
 321static int daemon_session__run(struct daemon_session *session,
 322			       struct daemon *daemon)
 323{
 324	char buf[PATH_MAX];
 325	char **argv;
 326	int argc, fd;
 327
 328	if (asprintf(&session->base, "%s/session-%s",
 329		     daemon->base, session->name) < 0) {
 330		perror("failed: asprintf");
 331		return -1;
 332	}
 333
 334	if (mkdir(session->base, 0755) && errno != EEXIST) {
 335		perror("failed: mkdir");
 336		return -1;
 337	}
 338
 339	session->start = time(NULL);
 340
 341	session->pid = fork();
 342	if (session->pid < 0)
 343		return -1;
 344	if (session->pid > 0) {
 345		pr_info("reconfig: ruining session [%s:%d]: %s\n",
 346			session->name, session->pid, session->run);
 347		return 0;
 348	}
 349
 350	if (chdir(session->base)) {
 351		perror("failed: chdir");
 352		return -1;
 353	}
 354
 355	fd = open("/dev/null", O_RDONLY);
 356	if (fd < 0) {
 357		perror("failed: open /dev/null");
 358		return -1;
 359	}
 360
 361	dup2(fd, 0);
 362	close(fd);
 363
 364	fd = open(SESSION_OUTPUT, O_RDWR|O_CREAT|O_TRUNC, 0644);
 365	if (fd < 0) {
 366		perror("failed: open session output");
 367		return -1;
 368	}
 369
 370	dup2(fd, 1);
 371	dup2(fd, 2);
 372	close(fd);
 373
 374	if (mkfifo(SESSION_CONTROL, 0600) && errno != EEXIST) {
 375		perror("failed: create control fifo");
 376		return -1;
 377	}
 378
 379	if (mkfifo(SESSION_ACK, 0600) && errno != EEXIST) {
 380		perror("failed: create ack fifo");
 381		return -1;
 382	}
 383
 384	scnprintf(buf, sizeof(buf), "%s record --control=fifo:%s,%s %s",
 385		  daemon->perf, SESSION_CONTROL, SESSION_ACK, session->run);
 386
 387	argv = argv_split(buf, &argc);
 388	if (!argv)
 389		exit(-1);
 390
 391	exit(execve(daemon->perf, argv, NULL));
 392	return -1;
 393}
 394
 395static pid_t handle_signalfd(struct daemon *daemon)
 396{
 397	struct daemon_session *session;
 398	struct signalfd_siginfo si;
 399	ssize_t err;
 400	int status;
 401	pid_t pid;
 402
 403	/*
 404	 * Take signal fd data as pure signal notification and check all
 405	 * the sessions state. The reason is that multiple signals can get
 406	 * coalesced in kernel and we can receive only single signal even
 407	 * if multiple SIGCHLD were generated.
 408	 */
 409	err = read(daemon->signal_fd, &si, sizeof(struct signalfd_siginfo));
 410	if (err != sizeof(struct signalfd_siginfo)) {
 411		pr_err("failed to read signal fd\n");
 412		return -1;
 413	}
 414
 415	list_for_each_entry(session, &daemon->sessions, list) {
 416		if (session->pid == -1)
 417			continue;
 418
 419		pid = waitpid(session->pid, &status, WNOHANG);
 420		if (pid <= 0)
 421			continue;
 422
 423		if (WIFEXITED(status)) {
 424			pr_info("session '%s' exited, status=%d\n",
 425				session->name, WEXITSTATUS(status));
 426		} else if (WIFSIGNALED(status)) {
 427			pr_info("session '%s' killed (signal %d)\n",
 428				session->name, WTERMSIG(status));
 429		} else if (WIFSTOPPED(status)) {
 430			pr_info("session '%s' stopped (signal %d)\n",
 431				session->name, WSTOPSIG(status));
 432		} else {
 433			pr_info("session '%s' Unexpected status (0x%x)\n",
 434				session->name, status);
 435		}
 436
 437		session->state = KILL;
 438		session->pid = -1;
 439	}
 440
 441	return 0;
 442}
 443
 444static int daemon_session__wait(struct daemon_session *session, struct daemon *daemon,
 445				int secs)
 446{
 447	struct pollfd pollfd = {
 448		.fd	= daemon->signal_fd,
 449		.events	= POLLIN,
 450	};
 451	time_t start;
 452
 453	start = time(NULL);
 454
 455	do {
 456		int err = poll(&pollfd, 1, 1000);
 457
 458		if (err > 0) {
 459			handle_signalfd(daemon);
 460		} else if (err < 0) {
 461			perror("failed: poll\n");
 462			return -1;
 463		}
 464
 465		if (start + secs < time(NULL))
 466			return -1;
 467	} while (session->pid != -1);
 468
 469	return 0;
 470}
 471
 472static bool daemon__has_alive_session(struct daemon *daemon)
 473{
 474	struct daemon_session *session;
 475
 476	list_for_each_entry(session, &daemon->sessions, list) {
 477		if (session->pid != -1)
 478			return true;
 479	}
 480
 481	return false;
 482}
 483
 484static int daemon__wait(struct daemon *daemon, int secs)
 485{
 486	struct pollfd pollfd = {
 487		.fd	= daemon->signal_fd,
 488		.events	= POLLIN,
 489	};
 490	time_t start;
 491
 492	start = time(NULL);
 493
 494	do {
 495		int err = poll(&pollfd, 1, 1000);
 496
 497		if (err > 0) {
 498			handle_signalfd(daemon);
 499		} else if (err < 0) {
 500			perror("failed: poll\n");
 501			return -1;
 502		}
 503
 504		if (start + secs < time(NULL))
 505			return -1;
 506	} while (daemon__has_alive_session(daemon));
 507
 508	return 0;
 509}
 510
 511static int daemon_session__control(struct daemon_session *session,
 512				   const char *msg, bool do_ack)
 513{
 514	struct pollfd pollfd = { .events = POLLIN, };
 515	char control_path[PATH_MAX];
 516	char ack_path[PATH_MAX];
 517	int control, ack = -1, len;
 518	char buf[20];
 519	int ret = -1;
 520	ssize_t err;
 521
 522	/* open the control file */
 523	scnprintf(control_path, sizeof(control_path), "%s/%s",
 524		  session->base, SESSION_CONTROL);
 525
 526	control = open(control_path, O_WRONLY|O_NONBLOCK);
 527	if (control < 0)
 528		return -1;
 529
 530	if (do_ack) {
 531		/* open the ack file */
 532		scnprintf(ack_path, sizeof(ack_path), "%s/%s",
 533			  session->base, SESSION_ACK);
 534
 535		ack = open(ack_path, O_RDONLY, O_NONBLOCK);
 536		if (ack < 0) {
 537			close(control);
 538			return -1;
 539		}
 540	}
 541
 542	/* write the command */
 543	len = strlen(msg);
 544
 545	err = writen(control, msg, len);
 546	if (err != len) {
 547		pr_err("failed: write to control pipe: %d (%s)\n",
 548		       errno, control_path);
 549		goto out;
 550	}
 551
 552	if (!do_ack)
 553		goto out;
 554
 555	/* wait for an ack */
 556	pollfd.fd = ack;
 557
 558	if (!poll(&pollfd, 1, 2000)) {
 559		pr_err("failed: control ack timeout\n");
 560		goto out;
 561	}
 562
 563	if (!(pollfd.revents & POLLIN)) {
 564		pr_err("failed: did not received an ack\n");
 565		goto out;
 566	}
 567
 568	err = read(ack, buf, sizeof(buf));
 569	if (err > 0)
 570		ret = strcmp(buf, "ack\n");
 571	else
 572		perror("failed: read ack %d\n");
 573
 574out:
 575	if (ack != -1)
 576		close(ack);
 577
 578	close(control);
 579	return ret;
 580}
 581
 582static int setup_server_socket(struct daemon *daemon)
 583{
 584	struct sockaddr_un addr;
 585	char path[PATH_MAX];
 586	int fd = socket(AF_UNIX, SOCK_STREAM, 0);
 587
 588	if (fd < 0) {
 589		fprintf(stderr, "socket: %s\n", strerror(errno));
 590		return -1;
 591	}
 592
 593	if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
 594		perror("failed: fcntl FD_CLOEXEC");
 595		close(fd);
 596		return -1;
 597	}
 598
 599	scnprintf(path, sizeof(path), "%s/control", daemon->base);
 600
 601	if (strlen(path) + 1 >= sizeof(addr.sun_path)) {
 602		pr_err("failed: control path too long '%s'\n", path);
 603		close(fd);
 604		return -1;
 605	}
 606
 607	memset(&addr, 0, sizeof(addr));
 608	addr.sun_family = AF_UNIX;
 609
 610	strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
 611	unlink(path);
 612
 613	if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
 614		perror("failed: bind");
 615		close(fd);
 616		return -1;
 617	}
 618
 619	if (listen(fd, 1) == -1) {
 620		perror("failed: listen");
 621		close(fd);
 622		return -1;
 623	}
 624
 625	return fd;
 626}
 627
 628enum {
 629	CMD_LIST   = 0,
 630	CMD_SIGNAL = 1,
 631	CMD_STOP   = 2,
 632	CMD_PING   = 3,
 633	CMD_MAX,
 634};
 635
 636#define SESSION_MAX 64
 637
 638union cmd {
 639	int cmd;
 640
 641	/* CMD_LIST */
 642	struct {
 643		int	cmd;
 644		int	verbose;
 645		char	csv_sep;
 646	} list;
 647
 648	/* CMD_SIGNAL */
 649	struct {
 650		int	cmd;
 651		int	sig;
 652		char	name[SESSION_MAX];
 653	} signal;
 654
 655	/* CMD_PING */
 656	struct {
 657		int	cmd;
 658		char	name[SESSION_MAX];
 659	} ping;
 660};
 661
 662enum {
 663	PING_OK	  = 0,
 664	PING_FAIL = 1,
 665	PING_MAX,
 666};
 667
 668static int daemon_session__ping(struct daemon_session *session)
 669{
 670	return daemon_session__control(session, "ping", true) ?  PING_FAIL : PING_OK;
 671}
 672
 673static int cmd_session_list(struct daemon *daemon, union cmd *cmd, FILE *out)
 674{
 675	char csv_sep = cmd->list.csv_sep;
 676	struct daemon_session *session;
 677	time_t curr = time(NULL);
 678
 679	if (csv_sep) {
 680		fprintf(out, "%d%c%s%c%s%c%s/%s",
 681			/* pid daemon  */
 682			getpid(), csv_sep, "daemon",
 683			/* base */
 684			csv_sep, daemon->base,
 685			/* output */
 686			csv_sep, daemon->base, SESSION_OUTPUT);
 687
 688		fprintf(out, "%c%s/%s",
 689			/* lock */
 690			csv_sep, daemon->base, "lock");
 691
 692		fprintf(out, "%c%" PRIu64,
 693			/* session up time */
 694			csv_sep, (uint64_t)((curr - daemon->start) / 60));
 695
 696		fprintf(out, "\n");
 697	} else {
 698		fprintf(out, "[%d:daemon] base: %s\n", getpid(), daemon->base);
 699		if (cmd->list.verbose) {
 700			fprintf(out, "  output:  %s/%s\n",
 701				daemon->base, SESSION_OUTPUT);
 702			fprintf(out, "  lock:    %s/lock\n",
 703				daemon->base);
 704			fprintf(out, "  up:      %" PRIu64 " minutes\n",
 705				(uint64_t)((curr - daemon->start) / 60));
 706		}
 707	}
 708
 709	list_for_each_entry(session, &daemon->sessions, list) {
 710		if (csv_sep) {
 711			fprintf(out, "%d%c%s%c%s",
 712				/* pid */
 713				session->pid,
 714				/* name */
 715				csv_sep, session->name,
 716				/* base */
 717				csv_sep, session->run);
 718
 719			fprintf(out, "%c%s%c%s/%s",
 720				/* session dir */
 721				csv_sep, session->base,
 722				/* session output */
 723				csv_sep, session->base, SESSION_OUTPUT);
 724
 725			fprintf(out, "%c%s/%s%c%s/%s",
 726				/* session control */
 727				csv_sep, session->base, SESSION_CONTROL,
 728				/* session ack */
 729				csv_sep, session->base, SESSION_ACK);
 730
 731			fprintf(out, "%c%" PRIu64,
 732				/* session up time */
 733				csv_sep, (uint64_t)((curr - session->start) / 60));
 734
 735			fprintf(out, "\n");
 736		} else {
 737			fprintf(out, "[%d:%s] perf record %s\n",
 738				session->pid, session->name, session->run);
 739			if (!cmd->list.verbose)
 740				continue;
 741			fprintf(out, "  base:    %s\n",
 742				session->base);
 743			fprintf(out, "  output:  %s/%s\n",
 744				session->base, SESSION_OUTPUT);
 745			fprintf(out, "  control: %s/%s\n",
 746				session->base, SESSION_CONTROL);
 747			fprintf(out, "  ack:     %s/%s\n",
 748				session->base, SESSION_ACK);
 749			fprintf(out, "  up:      %" PRIu64 " minutes\n",
 750				(uint64_t)((curr - session->start) / 60));
 751		}
 752	}
 753
 754	return 0;
 755}
 756
 757static int daemon_session__signal(struct daemon_session *session, int sig)
 758{
 759	if (session->pid < 0)
 760		return -1;
 761	return kill(session->pid, sig);
 762}
 763
 764static int cmd_session_kill(struct daemon *daemon, union cmd *cmd, FILE *out)
 765{
 766	struct daemon_session *session;
 767	bool all = false;
 768
 769	all = !strcmp(cmd->signal.name, "all");
 770
 771	list_for_each_entry(session, &daemon->sessions, list) {
 772		if (all || !strcmp(cmd->signal.name, session->name)) {
 773			daemon_session__signal(session, cmd->signal.sig);
 774			fprintf(out, "signal %d sent to session '%s [%d]'\n",
 775				cmd->signal.sig, session->name, session->pid);
 776		}
 777	}
 778
 779	return 0;
 780}
 781
 782static const char *ping_str[PING_MAX] = {
 783	[PING_OK]   = "OK",
 784	[PING_FAIL] = "FAIL",
 785};
 786
 787static int cmd_session_ping(struct daemon *daemon, union cmd *cmd, FILE *out)
 788{
 789	struct daemon_session *session;
 790	bool all = false, found = false;
 791
 792	all = !strcmp(cmd->ping.name, "all");
 793
 794	list_for_each_entry(session, &daemon->sessions, list) {
 795		if (all || !strcmp(cmd->ping.name, session->name)) {
 796			int state = daemon_session__ping(session);
 797
 798			fprintf(out, "%-4s %s\n", ping_str[state], session->name);
 799			found = true;
 800		}
 801	}
 802
 803	if (!found && !all) {
 804		fprintf(out, "%-4s %s (not found)\n",
 805			ping_str[PING_FAIL], cmd->ping.name);
 806	}
 807	return 0;
 808}
 809
 810static int handle_server_socket(struct daemon *daemon, int sock_fd)
 811{
 812	int ret = -1, fd;
 813	FILE *out = NULL;
 814	union cmd cmd;
 815
 816	fd = accept(sock_fd, NULL, NULL);
 817	if (fd < 0) {
 818		perror("failed: accept");
 819		return -1;
 820	}
 821
 822	if (sizeof(cmd) != readn(fd, &cmd, sizeof(cmd))) {
 823		perror("failed: read");
 824		goto out;
 825	}
 826
 827	out = fdopen(fd, "w");
 828	if (!out) {
 829		perror("failed: fdopen");
 830		goto out;
 831	}
 832
 833	switch (cmd.cmd) {
 834	case CMD_LIST:
 835		ret = cmd_session_list(daemon, &cmd, out);
 836		break;
 837	case CMD_SIGNAL:
 838		ret = cmd_session_kill(daemon, &cmd, out);
 839		break;
 840	case CMD_STOP:
 841		done = 1;
 842		ret = 0;
 843		pr_debug("perf daemon is exciting\n");
 844		break;
 845	case CMD_PING:
 846		ret = cmd_session_ping(daemon, &cmd, out);
 847		break;
 848	default:
 849		break;
 850	}
 851
 852	fclose(out);
 853out:
 854	/* If out is defined, then fd is closed via fclose. */
 855	if (!out)
 856		close(fd);
 857	return ret;
 858}
 859
 860static int setup_client_socket(struct daemon *daemon)
 861{
 862	struct sockaddr_un addr;
 863	char path[PATH_MAX];
 864	int fd = socket(AF_UNIX, SOCK_STREAM, 0);
 865
 866	if (fd == -1) {
 867		perror("failed: socket");
 868		return -1;
 869	}
 870
 871	scnprintf(path, sizeof(path), "%s/control", daemon->base);
 872
 873	if (strlen(path) + 1 >= sizeof(addr.sun_path)) {
 874		pr_err("failed: control path too long '%s'\n", path);
 875		close(fd);
 876		return -1;
 877	}
 878
 879	memset(&addr, 0, sizeof(addr));
 880	addr.sun_family = AF_UNIX;
 881	strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
 882
 883	if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
 884		perror("failed: connect");
 885		close(fd);
 886		return -1;
 887	}
 888
 889	return fd;
 890}
 891
 892static void daemon_session__kill(struct daemon_session *session,
 893				 struct daemon *daemon)
 894{
 895	int how = 0;
 896
 897	do {
 898		switch (how) {
 899		case 0:
 900			daemon_session__control(session, "stop", false);
 901			break;
 902		case 1:
 903			daemon_session__signal(session, SIGTERM);
 904			break;
 905		case 2:
 906			daemon_session__signal(session, SIGKILL);
 907			break;
 908		default:
 909			pr_err("failed to wait for session %s\n",
 910			       session->name);
 911			return;
 912		}
 913		how++;
 914
 915	} while (daemon_session__wait(session, daemon, 10));
 916}
 917
 918static void daemon__signal(struct daemon *daemon, int sig)
 919{
 920	struct daemon_session *session;
 921
 922	list_for_each_entry(session, &daemon->sessions, list)
 923		daemon_session__signal(session, sig);
 924}
 925
 926static void daemon_session__delete(struct daemon_session *session)
 927{
 928	zfree(&session->base);
 929	zfree(&session->name);
 930	zfree(&session->run);
 931	free(session);
 932}
 933
 934static void daemon_session__remove(struct daemon_session *session)
 935{
 936	list_del(&session->list);
 937	daemon_session__delete(session);
 938}
 939
 940static void daemon__stop(struct daemon *daemon)
 941{
 942	struct daemon_session *session;
 943
 944	list_for_each_entry(session, &daemon->sessions, list)
 945		daemon_session__control(session, "stop", false);
 946}
 947
 948static void daemon__kill(struct daemon *daemon)
 949{
 950	int how = 0;
 951
 952	do {
 953		switch (how) {
 954		case 0:
 955			daemon__stop(daemon);
 956			break;
 957		case 1:
 958			daemon__signal(daemon, SIGTERM);
 959			break;
 960		case 2:
 961			daemon__signal(daemon, SIGKILL);
 962			break;
 963		default:
 964			pr_err("failed to wait for sessions\n");
 965			return;
 966		}
 967		how++;
 968
 969	} while (daemon__wait(daemon, 10));
 970}
 971
 972static void daemon__exit(struct daemon *daemon)
 973{
 974	struct daemon_session *session, *h;
 975
 976	list_for_each_entry_safe(session, h, &daemon->sessions, list)
 977		daemon_session__remove(session);
 978
 979	zfree(&daemon->config_real);
 980	zfree(&daemon->config_base);
 981	zfree(&daemon->base);
 982}
 983
 984static int daemon__reconfig(struct daemon *daemon)
 985{
 986	struct daemon_session *session, *n;
 987
 988	list_for_each_entry_safe(session, n, &daemon->sessions, list) {
 989		/* No change. */
 990		if (session->state == OK)
 991			continue;
 992
 993		/* Remove session. */
 994		if (session->state == KILL) {
 995			if (session->pid > 0) {
 996				daemon_session__kill(session, daemon);
 997				pr_info("reconfig: session '%s' killed\n", session->name);
 998			}
 999			daemon_session__remove(session);
1000			continue;
1001		}
1002
1003		/* Reconfig session. */
1004		if (session->pid > 0) {
1005			daemon_session__kill(session, daemon);
1006			pr_info("reconfig: session '%s' killed\n", session->name);
1007		}
1008		if (daemon_session__run(session, daemon))
1009			return -1;
1010
1011		session->state = OK;
1012	}
1013
1014	return 0;
1015}
1016
1017static int setup_config_changes(struct daemon *daemon)
1018{
1019	char *basen = strdup(daemon->config_real);
1020	char *dirn  = strdup(daemon->config_real);
1021	char *base, *dir;
1022	int fd, wd = -1;
1023
1024	if (!dirn || !basen)
1025		goto out;
1026
1027	fd = inotify_init1(IN_NONBLOCK|O_CLOEXEC);
1028	if (fd < 0) {
1029		perror("failed: inotify_init");
1030		goto out;
1031	}
1032
1033	dir = dirname(dirn);
1034	base = basename(basen);
1035	pr_debug("config file: %s, dir: %s\n", base, dir);
1036
1037	wd = inotify_add_watch(fd, dir, IN_CLOSE_WRITE);
1038	if (wd >= 0) {
1039		daemon->config_base = strdup(base);
1040		if (!daemon->config_base) {
1041			close(fd);
1042			wd = -1;
1043		}
1044	} else {
1045		perror("failed: inotify_add_watch");
1046	}
1047
1048out:
1049	free(basen);
1050	free(dirn);
1051	return wd < 0 ? -1 : fd;
1052}
1053
1054static bool process_inotify_event(struct daemon *daemon, char *buf, ssize_t len)
1055{
1056	char *p = buf;
1057
1058	while (p < (buf + len)) {
1059		struct inotify_event *event = (struct inotify_event *) p;
1060
1061		/*
1062		 * We monitor config directory, check if our
1063		 * config file was changes.
1064		 */
1065		if ((event->mask & IN_CLOSE_WRITE) &&
1066		    !(event->mask & IN_ISDIR)) {
1067			if (!strcmp(event->name, daemon->config_base))
1068				return true;
1069		}
1070		p += sizeof(*event) + event->len;
1071	}
1072	return false;
1073}
1074
1075static int handle_config_changes(struct daemon *daemon, int conf_fd,
1076				 bool *config_changed)
1077{
1078	char buf[4096];
1079	ssize_t len;
1080
1081	while (!(*config_changed)) {
1082		len = read(conf_fd, buf, sizeof(buf));
1083		if (len == -1) {
1084			if (errno != EAGAIN) {
1085				perror("failed: read");
1086				return -1;
1087			}
1088			return 0;
1089		}
1090		*config_changed = process_inotify_event(daemon, buf, len);
1091	}
1092	return 0;
1093}
1094
1095static int setup_config(struct daemon *daemon)
1096{
1097	if (daemon->base_user) {
1098		daemon->base = strdup(daemon->base_user);
1099		if (!daemon->base)
1100			return -ENOMEM;
1101	}
1102
1103	if (daemon->config) {
1104		char *real = realpath(daemon->config, NULL);
1105
1106		if (!real) {
1107			perror("failed: realpath");
1108			return -1;
1109		}
1110		daemon->config_real = real;
1111		return 0;
1112	}
1113
1114	if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK))
1115		daemon->config_real = strdup(perf_etc_perfconfig());
1116	else if (perf_config_global() && perf_home_perfconfig())
1117		daemon->config_real = strdup(perf_home_perfconfig());
1118
1119	return daemon->config_real ? 0 : -1;
1120}
1121
1122#ifndef F_TLOCK
1123#define F_TLOCK 2
1124
1125static int lockf(int fd, int cmd, off_t len)
1126{
1127	if (cmd != F_TLOCK || len != 0)
1128		return -1;
1129
1130	return flock(fd, LOCK_EX | LOCK_NB);
1131}
1132#endif // F_TLOCK
1133
1134/*
1135 * Each daemon tries to create and lock BASE/lock file,
1136 * if it's successful we are sure we're the only daemon
1137 * running over the BASE.
1138 *
1139 * Once daemon is finished, file descriptor to lock file
1140 * is closed and lock is released.
1141 */
1142static int check_lock(struct daemon *daemon)
1143{
1144	char path[PATH_MAX];
1145	char buf[20];
1146	int fd, pid;
1147	ssize_t len;
1148
1149	scnprintf(path, sizeof(path), "%s/lock", daemon->base);
1150
1151	fd = open(path, O_RDWR|O_CREAT|O_CLOEXEC, 0640);
1152	if (fd < 0)
1153		return -1;
1154
1155	if (lockf(fd, F_TLOCK, 0) < 0) {
1156		filename__read_int(path, &pid);
1157		fprintf(stderr, "failed: another perf daemon (pid %d) owns %s\n",
1158			pid, daemon->base);
1159		close(fd);
1160		return -1;
1161	}
1162
1163	scnprintf(buf, sizeof(buf), "%d", getpid());
1164	len = strlen(buf);
1165
1166	if (write(fd, buf, len) != len) {
1167		perror("failed: write");
1168		close(fd);
1169		return -1;
1170	}
1171
1172	if (ftruncate(fd, len)) {
1173		perror("failed: ftruncate");
1174		close(fd);
1175		return -1;
1176	}
1177
1178	return 0;
1179}
1180
1181static int go_background(struct daemon *daemon)
1182{
1183	int pid, fd;
1184
1185	pid = fork();
1186	if (pid < 0)
1187		return -1;
1188
1189	if (pid > 0)
1190		return 1;
1191
1192	if (setsid() < 0)
1193		return -1;
1194
1195	if (check_lock(daemon))
1196		return -1;
1197
1198	umask(0);
1199
1200	if (chdir(daemon->base)) {
1201		perror("failed: chdir");
1202		return -1;
1203	}
1204
1205	fd = open("output", O_RDWR|O_CREAT|O_TRUNC, 0644);
1206	if (fd < 0) {
1207		perror("failed: open");
1208		return -1;
1209	}
1210
1211	if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
1212		perror("failed: fcntl FD_CLOEXEC");
1213		close(fd);
1214		return -1;
1215	}
1216
1217	close(0);
1218	dup2(fd, 1);
1219	dup2(fd, 2);
1220	close(fd);
1221
1222	daemon->out = fdopen(1, "w");
1223	if (!daemon->out) {
1224		close(1);
1225		close(2);
1226		return -1;
1227	}
1228
1229	setbuf(daemon->out, NULL);
1230	return 0;
1231}
1232
1233static int setup_signalfd(struct daemon *daemon)
1234{
1235	sigset_t mask;
1236
1237	sigemptyset(&mask);
1238	sigaddset(&mask, SIGCHLD);
1239
1240	if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
1241		return -1;
1242
1243	daemon->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
1244	return daemon->signal_fd;
1245}
1246
1247static int __cmd_start(struct daemon *daemon, struct option parent_options[],
1248		       int argc, const char **argv)
1249{
1250	bool foreground = false;
1251	struct option start_options[] = {
1252		OPT_BOOLEAN('f', "foreground", &foreground, "stay on console"),
1253		OPT_PARENT(parent_options),
1254		OPT_END()
1255	};
1256	int sock_fd = -1, conf_fd = -1, signal_fd = -1;
1257	int sock_pos, file_pos, signal_pos;
1258	struct fdarray fda;
1259	int err = 0;
1260
1261	argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1262	if (argc)
1263		usage_with_options(daemon_usage, start_options);
1264
1265	daemon->start = time(NULL);
1266
1267	if (setup_config(daemon)) {
1268		pr_err("failed: config not found\n");
1269		return -1;
1270	}
1271
1272	if (setup_server_config(daemon))
1273		return -1;
1274
1275	if (foreground && check_lock(daemon))
1276		return -1;
1277
1278	if (!foreground) {
1279		err = go_background(daemon);
1280		if (err) {
1281			/* original process, exit normally */
1282			if (err == 1)
1283				err = 0;
1284			daemon__exit(daemon);
1285			return err;
1286		}
1287	}
1288
1289	debug_set_file(daemon->out);
1290	debug_set_display_time(true);
1291
1292	pr_info("daemon started (pid %d)\n", getpid());
1293
1294	fdarray__init(&fda, 3);
1295
1296	sock_fd = setup_server_socket(daemon);
1297	if (sock_fd < 0)
1298		goto out;
1299
1300	conf_fd = setup_config_changes(daemon);
1301	if (conf_fd < 0)
1302		goto out;
1303
1304	signal_fd = setup_signalfd(daemon);
1305	if (signal_fd < 0)
1306		goto out;
1307
1308	sock_pos = fdarray__add(&fda, sock_fd, POLLIN|POLLERR|POLLHUP, 0);
1309	if (sock_pos < 0)
1310		goto out;
1311
1312	file_pos = fdarray__add(&fda, conf_fd, POLLIN|POLLERR|POLLHUP, 0);
1313	if (file_pos < 0)
1314		goto out;
1315
1316	signal_pos = fdarray__add(&fda, signal_fd, POLLIN|POLLERR|POLLHUP, 0);
1317	if (signal_pos < 0)
1318		goto out;
1319
1320	signal(SIGINT, sig_handler);
1321	signal(SIGTERM, sig_handler);
1322	signal(SIGPIPE, SIG_IGN);
1323
1324	while (!done && !err) {
1325		err = daemon__reconfig(daemon);
1326
1327		if (!err && fdarray__poll(&fda, -1)) {
1328			bool reconfig = false;
1329
1330			if (fda.entries[sock_pos].revents & POLLIN)
1331				err = handle_server_socket(daemon, sock_fd);
1332			if (fda.entries[file_pos].revents & POLLIN)
1333				err = handle_config_changes(daemon, conf_fd, &reconfig);
1334			if (fda.entries[signal_pos].revents & POLLIN)
1335				err = handle_signalfd(daemon) < 0;
1336
1337			if (reconfig)
1338				err = setup_server_config(daemon);
1339		}
1340	}
1341
1342out:
1343	fdarray__exit(&fda);
1344
1345	daemon__kill(daemon);
1346	daemon__exit(daemon);
1347
1348	if (sock_fd != -1)
1349		close(sock_fd);
1350	if (conf_fd != -1)
1351		close(conf_fd);
1352	if (signal_fd != -1)
1353		close(signal_fd);
1354
1355	pr_info("daemon exited\n");
1356	fclose(daemon->out);
1357	return err;
1358}
1359
1360static int send_cmd(struct daemon *daemon, union cmd *cmd)
1361{
1362	int ret = -1, fd;
1363	char *line = NULL;
1364	size_t len = 0;
1365	ssize_t nread;
1366	FILE *in = NULL;
1367
1368	if (setup_client_config(daemon))
1369		return -1;
1370
1371	fd = setup_client_socket(daemon);
1372	if (fd < 0)
1373		return -1;
1374
1375	if (sizeof(*cmd) != writen(fd, cmd, sizeof(*cmd))) {
1376		perror("failed: write");
1377		goto out;
1378	}
1379
1380	in = fdopen(fd, "r");
1381	if (!in) {
1382		perror("failed: fdopen");
1383		goto out;
1384	}
1385
1386	while ((nread = getline(&line, &len, in)) != -1) {
1387		if (fwrite(line, nread, 1, stdout) != 1)
1388			goto out_fclose;
1389		fflush(stdout);
1390	}
1391
1392	ret = 0;
1393out_fclose:
1394	fclose(in);
1395	free(line);
1396out:
1397	/* If in is defined, then fd is closed via fclose. */
1398	if (!in)
1399		close(fd);
1400	return ret;
1401}
1402
1403static int send_cmd_list(struct daemon *daemon)
1404{
1405	union cmd cmd;
1406
1407	memset(&cmd, 0, sizeof(cmd));
1408	cmd.list.cmd = CMD_LIST;
1409	cmd.list.verbose = verbose;
1410	cmd.list.csv_sep = daemon->csv_sep ? *daemon->csv_sep : 0;
1411
1412	return send_cmd(daemon, &cmd);
1413}
1414
1415static int __cmd_signal(struct daemon *daemon, struct option parent_options[],
1416			int argc, const char **argv)
1417{
1418	const char *name = "all";
1419	struct option start_options[] = {
1420		OPT_STRING(0, "session", &name, "session",
1421			"Sent signal to specific session"),
1422		OPT_PARENT(parent_options),
1423		OPT_END()
1424	};
1425	union cmd cmd;
1426
1427	argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1428	if (argc)
1429		usage_with_options(daemon_usage, start_options);
1430
1431	if (setup_config(daemon)) {
1432		pr_err("failed: config not found\n");
1433		return -1;
1434	}
1435
1436	memset(&cmd, 0, sizeof(cmd));
1437	cmd.signal.cmd = CMD_SIGNAL;
1438	cmd.signal.sig = SIGUSR2;
1439	strncpy(cmd.signal.name, name, sizeof(cmd.signal.name) - 1);
1440
1441	return send_cmd(daemon, &cmd);
1442}
1443
1444static int __cmd_stop(struct daemon *daemon, struct option parent_options[],
1445			int argc, const char **argv)
1446{
1447	struct option start_options[] = {
1448		OPT_PARENT(parent_options),
1449		OPT_END()
1450	};
1451	union cmd cmd;
1452
1453	argc = parse_options(argc, argv, start_options, daemon_usage, 0);
1454	if (argc)
1455		usage_with_options(daemon_usage, start_options);
1456
1457	if (setup_config(daemon)) {
1458		pr_err("failed: config not found\n");
1459		return -1;
1460	}
1461
1462	memset(&cmd, 0, sizeof(cmd));
1463	cmd.cmd = CMD_STOP;
1464	return send_cmd(daemon, &cmd);
1465}
1466
1467static int __cmd_ping(struct daemon *daemon, struct option parent_options[],
1468		      int argc, const char **argv)
1469{
1470	const char *name = "all";
1471	struct option ping_options[] = {
1472		OPT_STRING(0, "session", &name, "session",
1473			"Ping to specific session"),
1474		OPT_PARENT(parent_options),
1475		OPT_END()
1476	};
1477	union cmd cmd;
1478
1479	argc = parse_options(argc, argv, ping_options, daemon_usage, 0);
1480	if (argc)
1481		usage_with_options(daemon_usage, ping_options);
1482
1483	if (setup_config(daemon)) {
1484		pr_err("failed: config not found\n");
1485		return -1;
1486	}
1487
1488	memset(&cmd, 0, sizeof(cmd));
1489	cmd.cmd = CMD_PING;
1490	scnprintf(cmd.ping.name, sizeof(cmd.ping.name), "%s", name);
1491	return send_cmd(daemon, &cmd);
1492}
1493
1494static char *alloc_perf_exe_path(void)
1495{
1496	char path[PATH_MAX];
1497
1498	perf_exe(path, sizeof(path));
1499	return strdup(path);
1500}
1501
1502int cmd_daemon(int argc, const char **argv)
1503{
1504	struct option daemon_options[] = {
1505		OPT_INCR('v', "verbose", &verbose, "be more verbose"),
1506		OPT_STRING(0, "config", &__daemon.config,
1507			"config file", "config file path"),
1508		OPT_STRING(0, "base", &__daemon.base_user,
1509			"directory", "base directory"),
1510		OPT_STRING_OPTARG('x', "field-separator", &__daemon.csv_sep,
1511			"field separator", "print counts with custom separator", ","),
1512		OPT_END()
1513	};
1514	int ret = -1;
1515
1516	__daemon.perf = alloc_perf_exe_path();
1517	if (!__daemon.perf)
1518		return -ENOMEM;
1519
 
1520	__daemon.out = stdout;
1521
1522	argc = parse_options(argc, argv, daemon_options, daemon_usage,
1523			     PARSE_OPT_STOP_AT_NON_OPTION);
1524
1525	if (argc) {
1526		if (!strcmp(argv[0], "start"))
1527			ret = __cmd_start(&__daemon, daemon_options, argc, argv);
1528		else if (!strcmp(argv[0], "signal"))
1529			ret = __cmd_signal(&__daemon, daemon_options, argc, argv);
1530		else if (!strcmp(argv[0], "stop"))
1531			ret = __cmd_stop(&__daemon, daemon_options, argc, argv);
1532		else if (!strcmp(argv[0], "ping"))
1533			ret = __cmd_ping(&__daemon, daemon_options, argc, argv);
1534		else
1535			pr_err("failed: unknown command '%s'\n", argv[0]);
1536	} else {
1537		ret = setup_config(&__daemon);
1538		if (ret)
1539			pr_err("failed: config not found\n");
1540		else
1541			ret = send_cmd_list(&__daemon);
1542	}
1543	zfree(&__daemon.perf);
1544	return ret;
 
 
 
 
 
1545}
v6.2
   1// SPDX-License-Identifier: GPL-2.0
   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 * Session states:
  38 *
  39 *   OK       - session is up and running
  40 *   RECONFIG - session is pending for reconfiguration,
  41 *              new values are already loaded in session object
  42 *   KILL     - session is pending to be killed
  43 *
  44 * Session object life and its state is maintained by
  45 * following functions:
  46 *
  47 *  setup_server_config
  48 *    - reads config file and setup session objects
  49 *      with following states:
  50 *
  51 *      OK       - no change needed
  52 *      RECONFIG - session needs to be changed
  53 *                 (run variable changed)
  54 *      KILL     - session needs to be killed
  55 *                 (session is no longer in config file)
  56 *
  57 *  daemon__reconfig
  58 *    - scans session objects and does following actions
  59 *      for states:
  60 *
  61 *      OK       - skip
  62 *      RECONFIG - session is killed and re-run with new config
  63 *      KILL     - session is killed
  64 *
  65 *    - all sessions have OK state on the function exit
  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|signal|stop|ping} [<options>]",
 104	"perf daemon [<options>]",
 105	NULL
 106};
 107
 108static volatile sig_atomic_t 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		/* New session is defined. */
 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		/* Trigger reconfig to start it. */
 181		session->state = RECONFIG;
 182	} else if (session->state == KILL) {
 183		/* Current session is defined, no action needed. */
 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			 * Either new or changed run value is defined,
 206			 * trigger reconfig for the session.
 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	 * Mark all sessions for kill, the server config
 305	 * will set following states, see explanation at
 306	 * enum daemon_session_state declaration.
 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	 * Take signal fd data as pure signal notification and check all
 404	 * the sessions state. The reason is that multiple signals can get
 405	 * coalesced in kernel and we can receive only single signal even
 406	 * if multiple SIGCHLD were generated.
 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	/* open the control file */
 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		/* open the ack file */
 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	/* write the command */
 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	/* wait for an ack */
 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	/* CMD_LIST */
 641	struct {
 642		int	cmd;
 643		int	verbose;
 644		char	csv_sep;
 645	} list;
 646
 647	/* CMD_SIGNAL */
 648	struct {
 649		int	cmd;
 650		int	sig;
 651		char	name[SESSION_MAX];
 652	} signal;
 653
 654	/* CMD_PING */
 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			/* pid daemon  */
 681			getpid(), csv_sep, "daemon",
 682			/* base */
 683			csv_sep, daemon->base,
 684			/* output */
 685			csv_sep, daemon->base, SESSION_OUTPUT);
 686
 687		fprintf(out, "%c%s/%s",
 688			/* lock */
 689			csv_sep, daemon->base, "lock");
 690
 691		fprintf(out, "%c%lu",
 692			/* session up time */
 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				/* pid */
 712				session->pid,
 713				/* name */
 714				csv_sep, session->name,
 715				/* base */
 716				csv_sep, session->run);
 717
 718			fprintf(out, "%c%s%c%s/%s",
 719				/* session dir */
 720				csv_sep, session->base,
 721				/* session output */
 722				csv_sep, session->base, SESSION_OUTPUT);
 723
 724			fprintf(out, "%c%s/%s%c%s/%s",
 725				/* session control */
 726				csv_sep, session->base, SESSION_CONTROL,
 727				/* session ack */
 728				csv_sep, session->base, SESSION_ACK);
 729
 730			fprintf(out, "%c%lu",
 731				/* session up time */
 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	/* If out is defined, then fd is closed via fclose. */
 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		/* No change. */
 989		if (session->state == OK)
 990			continue;
 991
 992		/* Remove session. */
 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		/* Reconfig session. */
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		 * We monitor config directory, check if our
1062		 * config file was changes.
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 // F_TLOCK
1132
1133/*
1134 * Each daemon tries to create and lock BASE/lock file,
1135 * if it's successful we are sure we're the only daemon
1136 * running over the BASE.
1137 *
1138 * Once daemon is finished, file descriptor to lock file
1139 * is closed and lock is released.
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			/* original process, exit normally */
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	/* If in is defined, then fd is closed via fclose. */
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}