lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 1 Mar 2017 18:05:58 -0300
From:   Arnaldo Carvalho de Melo <acme@...nel.org>
To:     Hari Bathini <hbathini@...ux.vnet.ibm.com>
Cc:     ast@...com, peterz@...radead.org,
        lkml <linux-kernel@...r.kernel.org>,
        alexander.shishkin@...ux.intel.com, mingo@...hat.com,
        daniel@...earbox.net, rostedt@...dmis.org,
        Ananth N Mavinakayanahalli <ananth@...ux.vnet.ibm.com>,
        ebiederm@...ssion.com, sargun@...gun.me,
        Aravinda Prasad <aravinda@...ux.vnet.ibm.com>,
        brendan.d.gregg@...il.com, jolsa@...hat.com
Subject: Re: [PATCH v7 4/8] perf tool: synthesize namespace events for
 current processes

Em Tue, Feb 21, 2017 at 07:31:44PM +0530, Hari Bathini escreveu:
> Synthesize PERF_RECORD_NAMESPACES events for processes that were
> running prior to invocation of perf record, the data for which is
> taken from /proc/$PID/ns. These changes make way for analyzing
> events with regard to namespaces.
> 
> Signed-off-by: Hari Bathini <hbathini@...ux.vnet.ibm.com>
> ---
>  tools/perf/builtin-record.c |   27 +++++++++--
>  tools/perf/util/event.c     |  107 +++++++++++++++++++++++++++++++++++++++++--
>  tools/perf/util/event.h     |    6 ++
>  3 files changed, 130 insertions(+), 10 deletions(-)
> 
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index a8b9a78..f4bf6a6 100644
> --- a/tools/perf/builtin-record.c
> +++ b/tools/perf/builtin-record.c
> @@ -986,6 +986,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
>  	 */
>  	if (forks) {
>  		union perf_event *event;
> +		pid_t tgid;
>  
>  		event = malloc(sizeof(event->comm) + machine->id_hdr_size);
>  		if (event == NULL) {
> @@ -999,10 +1000,28 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
>  		 * cannot see a correct process name for those events.
>  		 * Synthesize COMM event to prevent it.
>  		 */
> -		perf_event__synthesize_comm(tool, event,
> -					    rec->evlist->workload.pid,
> -					    process_synthesized_event,
> -					    machine);
> +		tgid = perf_event__synthesize_comm(tool, event,
> +						   rec->evlist->workload.pid,
> +						   process_synthesized_event,
> +						   machine);
> +		free(event);
> +
> +		if (tgid == -1)
> +			goto out_child;
> +
> +		event = malloc(sizeof(event->namespaces) + machine->id_hdr_size);
> +		if (event == NULL) {
> +			err = -ENOMEM;
> +			goto out_child;
> +		}
> +
> +		/*
> +		 * Synthesize NAMESPACES event for the command specified.
> +		 */
> +		perf_event__synthesize_namespaces(tool, event,
> +						  rec->evlist->workload.pid,
> +						  tgid, process_synthesized_event,
> +						  machine);
>  		free(event);
>  
>  		perf_evlist__start_workload(rec->evlist);
> diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
> index f118eac..c8c112a 100644
> --- a/tools/perf/util/event.c
> +++ b/tools/perf/util/event.c
> @@ -50,6 +50,16 @@ static const char *perf_event__names[] = {
>  	[PERF_RECORD_TIME_CONV]			= "TIME_CONV",
>  };
>  
> +static const char *perf_ns__names[] = {
> +	[NET_NS_INDEX]		= "net",
> +	[UTS_NS_INDEX]		= "uts",
> +	[IPC_NS_INDEX]		= "ipc",
> +	[PID_NS_INDEX]		= "pid",
> +	[USER_NS_INDEX]		= "user",
> +	[MNT_NS_INDEX]		= "mnt",
> +	[CGROUP_NS_INDEX]	= "cgroup",
> +};
> +
>  const char *perf_event__name(unsigned int id)
>  {
>  	if (id >= ARRAY_SIZE(perf_event__names))
> @@ -59,6 +69,13 @@ const char *perf_event__name(unsigned int id)
>  	return perf_event__names[id];
>  }
>  
> +static const char *perf_ns__name(unsigned int id)
> +{
> +	if (id >= ARRAY_SIZE(perf_ns__names))
> +		return "UNKNOWN";
> +	return perf_ns__names[id];
> +}
> +
>  static int perf_tool__process_synth_event(struct perf_tool *tool,
>  					  union perf_event *event,
>  					  struct machine *machine,
> @@ -204,6 +221,56 @@ pid_t perf_event__synthesize_comm(struct perf_tool *tool,
>  	return tgid;
>  }
>  
> +static void perf_event__get_ns_link_info(pid_t pid, const char *ns,
> +					 struct perf_ns_link_info *ns_link_info)
> +{
> +	struct stat64 st;
> +	char proc_ns[128];
> +
> +	sprintf(proc_ns, "/proc/%u/ns/%s", pid, ns);
> +	if (stat64(proc_ns, &st) == 0) {
> +		ns_link_info->dev = st.st_dev;
> +		ns_link_info->ino = st.st_ino;
> +	}
> +}
> +
> +int perf_event__synthesize_namespaces(struct perf_tool *tool,
> +				      union perf_event *event,
> +				      pid_t pid, pid_t tgid,
> +				      perf_event__handler_t process,
> +				      struct machine *machine)
> +{
> +	u32 idx;
> +	struct perf_ns_link_info *ns_link_info;
> +
> +	if (!tool->namespace_events)
> +		return 0;
> +
> +	memset(&event->namespaces, 0,
> +	       sizeof(event->namespaces) + machine->id_hdr_size);
> +
> +	event->namespaces.pid = tgid;
> +	event->namespaces.tid = pid;
> +
> +	event->namespaces.nr_namespaces = NR_NAMESPACES;

Huh? Don't you have to first figure out how many namespaces a process is
in to then set this field? 

> +	ns_link_info = event->namespaces.link_info;
> +
> +	for (idx = 0; idx < event->namespaces.nr_namespaces; idx++)
> +		perf_event__get_ns_link_info(pid, perf_ns__name(idx),
> +					     &ns_link_info[idx]);



> +
> +	event->namespaces.header.type = PERF_RECORD_NAMESPACES;
> +
> +	event->namespaces.header.size = (sizeof(event->namespaces) +
> +					 machine->id_hdr_size);
> +
> +	if (perf_tool__process_synth_event(tool, event, machine, process) != 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
>  static int perf_event__synthesize_fork(struct perf_tool *tool,
>  				       union perf_event *event,
>  				       pid_t pid, pid_t tgid, pid_t ppid,
> @@ -435,8 +502,9 @@ int perf_event__synthesize_modules(struct perf_tool *tool,
>  static int __event__synthesize_thread(union perf_event *comm_event,
>  				      union perf_event *mmap_event,
>  				      union perf_event *fork_event,
> +				      union perf_event *namespaces_event,
>  				      pid_t pid, int full,
> -					  perf_event__handler_t process,
> +				      perf_event__handler_t process,
>  				      struct perf_tool *tool,
>  				      struct machine *machine,
>  				      bool mmap_data,
> @@ -456,6 +524,11 @@ static int __event__synthesize_thread(union perf_event *comm_event,
>  		if (tgid == -1)
>  			return -1;
>  
> +		if (perf_event__synthesize_namespaces(tool, namespaces_event, pid,
> +						      tgid, process, machine) < 0)
> +			return -1;
> +
> +
>  		return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
>  							  process, machine, mmap_data,
>  							  proc_map_timeout);
> @@ -489,6 +562,11 @@ static int __event__synthesize_thread(union perf_event *comm_event,
>  		if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid,
>  						ppid, process, machine) < 0)
>  			break;
> +
> +		if (perf_event__synthesize_namespaces(tool, namespaces_event, _pid,
> +						      tgid, process, machine) < 0)
> +			break;
> +
>  		/*
>  		 * Send the prepared comm event
>  		 */
> @@ -517,6 +595,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
>  				      unsigned int proc_map_timeout)
>  {
>  	union perf_event *comm_event, *mmap_event, *fork_event;
> +	union perf_event *namespaces_event;
>  	int err = -1, thread, j;
>  
>  	comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
> @@ -531,10 +610,15 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
>  	if (fork_event == NULL)
>  		goto out_free_mmap;
>  
> +	namespaces_event = malloc(sizeof(namespaces_event->namespaces) +
> +				  machine->id_hdr_size);
> +	if (namespaces_event == NULL)
> +		goto out_free_fork;
> +
>  	err = 0;
>  	for (thread = 0; thread < threads->nr; ++thread) {
>  		if (__event__synthesize_thread(comm_event, mmap_event,
> -					       fork_event,
> +					       fork_event, namespaces_event,
>  					       thread_map__pid(threads, thread), 0,
>  					       process, tool, machine,
>  					       mmap_data, proc_map_timeout)) {
> @@ -560,7 +644,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
>  			/* if not, generate events for it */
>  			if (need_leader &&
>  			    __event__synthesize_thread(comm_event, mmap_event,
> -						       fork_event,
> +						       fork_event, namespaces_event,
>  						       comm_event->comm.pid, 0,
>  						       process, tool, machine,
>  						       mmap_data, proc_map_timeout)) {
> @@ -569,6 +653,8 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
>  			}
>  		}
>  	}
> +	free(namespaces_event);
> +out_free_fork:
>  	free(fork_event);
>  out_free_mmap:
>  	free(mmap_event);
> @@ -588,6 +674,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
>  	char proc_path[PATH_MAX];
>  	struct dirent *dirent;
>  	union perf_event *comm_event, *mmap_event, *fork_event;
> +	union perf_event *namespaces_event;
>  	int err = -1;
>  
>  	if (machine__is_default_guest(machine))
> @@ -605,11 +692,16 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
>  	if (fork_event == NULL)
>  		goto out_free_mmap;
>  
> +	namespaces_event = malloc(sizeof(namespaces_event->namespaces) +
> +				  machine->id_hdr_size);
> +	if (namespaces_event == NULL)
> +		goto out_free_fork;
> +
>  	snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
>  	proc = opendir(proc_path);
>  
>  	if (proc == NULL)
> -		goto out_free_fork;
> +		goto out_free_namespaces;
>  
>  	while ((dirent = readdir(proc)) != NULL) {
>  		char *end;
> @@ -621,13 +713,16 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
>   		 * We may race with exiting thread, so don't stop just because
>   		 * one thread couldn't be synthesized.
>   		 */
> -		__event__synthesize_thread(comm_event, mmap_event, fork_event, pid,
> -					   1, process, tool, machine, mmap_data,
> +		__event__synthesize_thread(comm_event, mmap_event, fork_event,
> +					   namespaces_event, pid, 1, process,
> +					   tool, machine, mmap_data,
>  					   proc_map_timeout);
>  	}
>  
>  	err = 0;
>  	closedir(proc);
> +out_free_namespaces:
> +	free(namespaces_event);
>  out_free_fork:
>  	free(fork_event);
>  out_free_mmap:
> diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
> index 4e90b09..c73ad47 100644
> --- a/tools/perf/util/event.h
> +++ b/tools/perf/util/event.h
> @@ -650,6 +650,12 @@ pid_t perf_event__synthesize_comm(struct perf_tool *tool,
>  				  perf_event__handler_t process,
>  				  struct machine *machine);
>  
> +int perf_event__synthesize_namespaces(struct perf_tool *tool,
> +				      union perf_event *event,
> +				      pid_t pid, pid_t tgid,
> +				      perf_event__handler_t process,
> +				      struct machine *machine);
> +
>  int perf_event__synthesize_mmap_events(struct perf_tool *tool,
>  				       union perf_event *event,
>  				       pid_t pid, pid_t tgid,

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ