xref: /linux/tools/perf/util/namespaces.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f3b3614aSHari Bathini /*
3f3b3614aSHari Bathini  *
4f3b3614aSHari Bathini  * Copyright (C) 2017 Hari Bathini, IBM Corporation
5f3b3614aSHari Bathini  */
6f3b3614aSHari Bathini 
7f3b3614aSHari Bathini #include "namespaces.h"
8f3b3614aSHari Bathini #include "event.h"
9e5653eb8SArnaldo Carvalho de Melo #include "get_current_dir_name.h"
10843ff37bSKrister Johansen #include <sys/types.h>
11843ff37bSKrister Johansen #include <sys/stat.h>
12c23c2a0fSArnaldo Carvalho de Melo #include <fcntl.h>
13544abd44SKrister Johansen #include <limits.h>
14843ff37bSKrister Johansen #include <sched.h>
15f3b3614aSHari Bathini #include <stdlib.h>
16f3b3614aSHari Bathini #include <stdio.h>
1772f7c4d2SArnaldo Carvalho de Melo #include <string.h>
18843ff37bSKrister Johansen #include <unistd.h>
19b01c1f69SJiri Olsa #include <asm/bug.h>
20055c67edSArnaldo Carvalho de Melo #include <linux/kernel.h>
217f7c536fSArnaldo Carvalho de Melo #include <linux/zalloc.h>
22f3b3614aSHari Bathini 
23055c67edSArnaldo Carvalho de Melo static const char *perf_ns__names[] = {
24055c67edSArnaldo Carvalho de Melo 	[NET_NS_INDEX]		= "net",
25055c67edSArnaldo Carvalho de Melo 	[UTS_NS_INDEX]		= "uts",
26055c67edSArnaldo Carvalho de Melo 	[IPC_NS_INDEX]		= "ipc",
27055c67edSArnaldo Carvalho de Melo 	[PID_NS_INDEX]		= "pid",
28055c67edSArnaldo Carvalho de Melo 	[USER_NS_INDEX]		= "user",
29055c67edSArnaldo Carvalho de Melo 	[MNT_NS_INDEX]		= "mnt",
30055c67edSArnaldo Carvalho de Melo 	[CGROUP_NS_INDEX]	= "cgroup",
31055c67edSArnaldo Carvalho de Melo };
32055c67edSArnaldo Carvalho de Melo 
perf_ns__name(unsigned int id)33055c67edSArnaldo Carvalho de Melo const char *perf_ns__name(unsigned int id)
34055c67edSArnaldo Carvalho de Melo {
35055c67edSArnaldo Carvalho de Melo 	if (id >= ARRAY_SIZE(perf_ns__names))
36055c67edSArnaldo Carvalho de Melo 		return "UNKNOWN";
37055c67edSArnaldo Carvalho de Melo 	return perf_ns__names[id];
38055c67edSArnaldo Carvalho de Melo }
39055c67edSArnaldo Carvalho de Melo 
namespaces__new(struct perf_record_namespaces * event)4069d81f09SArnaldo Carvalho de Melo struct namespaces *namespaces__new(struct perf_record_namespaces *event)
41f3b3614aSHari Bathini {
42f3b3614aSHari Bathini 	struct namespaces *namespaces;
43f3b3614aSHari Bathini 	u64 link_info_size = ((event ? event->nr_namespaces : NR_NAMESPACES) *
44f3b3614aSHari Bathini 			      sizeof(struct perf_ns_link_info));
45f3b3614aSHari Bathini 
46f3b3614aSHari Bathini 	namespaces = zalloc(sizeof(struct namespaces) + link_info_size);
47f3b3614aSHari Bathini 	if (!namespaces)
48f3b3614aSHari Bathini 		return NULL;
49f3b3614aSHari Bathini 
50f3b3614aSHari Bathini 	namespaces->end_time = -1;
51f3b3614aSHari Bathini 
52f3b3614aSHari Bathini 	if (event)
53f3b3614aSHari Bathini 		memcpy(namespaces->link_info, event->link_info, link_info_size);
54f3b3614aSHari Bathini 
55f3b3614aSHari Bathini 	return namespaces;
56f3b3614aSHari Bathini }
57f3b3614aSHari Bathini 
namespaces__free(struct namespaces * namespaces)58f3b3614aSHari Bathini void namespaces__free(struct namespaces *namespaces)
59f3b3614aSHari Bathini {
60f3b3614aSHari Bathini 	free(namespaces);
61f3b3614aSHari Bathini }
62843ff37bSKrister Johansen 
nsinfo__get_nspid(pid_t * tgid,pid_t * nstgid,bool * in_pidns,const char * path)63c35ce1d9SIan Rogers static int nsinfo__get_nspid(pid_t *tgid, pid_t *nstgid, bool *in_pidns, const char *path)
645d28a17cSLeo Yan {
655d28a17cSLeo Yan 	FILE *f = NULL;
665d28a17cSLeo Yan 	char *statln = NULL;
675d28a17cSLeo Yan 	size_t linesz = 0;
685d28a17cSLeo Yan 	char *nspid;
695d28a17cSLeo Yan 
705d28a17cSLeo Yan 	f = fopen(path, "r");
715d28a17cSLeo Yan 	if (f == NULL)
725d28a17cSLeo Yan 		return -1;
735d28a17cSLeo Yan 
745d28a17cSLeo Yan 	while (getline(&statln, &linesz, f) != -1) {
755d28a17cSLeo Yan 		/* Use tgid if CONFIG_PID_NS is not defined. */
765d28a17cSLeo Yan 		if (strstr(statln, "Tgid:") != NULL) {
77c35ce1d9SIan Rogers 			*tgid = (pid_t)strtol(strrchr(statln, '\t'), NULL, 10);
78c35ce1d9SIan Rogers 			*nstgid = *tgid;
795d28a17cSLeo Yan 		}
805d28a17cSLeo Yan 
815d28a17cSLeo Yan 		if (strstr(statln, "NStgid:") != NULL) {
825d28a17cSLeo Yan 			nspid = strrchr(statln, '\t');
83c35ce1d9SIan Rogers 			*nstgid = (pid_t)strtol(nspid, NULL, 10);
845d28a17cSLeo Yan 			/*
855d28a17cSLeo Yan 			 * If innermost tgid is not the first, process is in a different
865d28a17cSLeo Yan 			 * PID namespace.
875d28a17cSLeo Yan 			 */
88c35ce1d9SIan Rogers 			*in_pidns = (statln + sizeof("NStgid:") - 1) != nspid;
895d28a17cSLeo Yan 			break;
905d28a17cSLeo Yan 		}
915d28a17cSLeo Yan 	}
925d28a17cSLeo Yan 
935d28a17cSLeo Yan 	fclose(f);
945d28a17cSLeo Yan 	free(statln);
955d28a17cSLeo Yan 	return 0;
965d28a17cSLeo Yan }
975d28a17cSLeo Yan 
nsinfo__init(struct nsinfo * nsi)98bf2e710bSKrister Johansen int nsinfo__init(struct nsinfo *nsi)
99843ff37bSKrister Johansen {
100843ff37bSKrister Johansen 	char oldns[PATH_MAX];
101bf2e710bSKrister Johansen 	char spath[PATH_MAX];
102843ff37bSKrister Johansen 	char *newns = NULL;
103843ff37bSKrister Johansen 	struct stat old_stat;
104843ff37bSKrister Johansen 	struct stat new_stat;
105bf2e710bSKrister Johansen 	int rv = -1;
106843ff37bSKrister Johansen 
107843ff37bSKrister Johansen 	if (snprintf(oldns, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX)
108bf2e710bSKrister Johansen 		return rv;
109843ff37bSKrister Johansen 
110bcaf0a97SIan Rogers 	if (asprintf(&newns, "/proc/%d/ns/mnt", nsinfo__pid(nsi)) == -1)
111bf2e710bSKrister Johansen 		return rv;
112843ff37bSKrister Johansen 
113843ff37bSKrister Johansen 	if (stat(oldns, &old_stat) < 0)
114843ff37bSKrister Johansen 		goto out;
115843ff37bSKrister Johansen 
116843ff37bSKrister Johansen 	if (stat(newns, &new_stat) < 0)
117843ff37bSKrister Johansen 		goto out;
118843ff37bSKrister Johansen 
119843ff37bSKrister Johansen 	/* Check if the mount namespaces differ, if so then indicate that we
120843ff37bSKrister Johansen 	 * want to switch as part of looking up dso/map data.
121843ff37bSKrister Johansen 	 */
122843ff37bSKrister Johansen 	if (old_stat.st_ino != new_stat.st_ino) {
123c35ce1d9SIan Rogers 		RC_CHK_ACCESS(nsi)->need_setns = true;
124c35ce1d9SIan Rogers 		RC_CHK_ACCESS(nsi)->mntns_path = newns;
125843ff37bSKrister Johansen 		newns = NULL;
126843ff37bSKrister Johansen 	}
127843ff37bSKrister Johansen 
128bf2e710bSKrister Johansen 	/* If we're dealing with a process that is in a different PID namespace,
129bf2e710bSKrister Johansen 	 * attempt to work out the innermost tgid for the process.
130bf2e710bSKrister Johansen 	 */
131bcaf0a97SIan Rogers 	if (snprintf(spath, PATH_MAX, "/proc/%d/status", nsinfo__pid(nsi)) >= PATH_MAX)
132bf2e710bSKrister Johansen 		goto out;
133bf2e710bSKrister Johansen 
134c35ce1d9SIan Rogers 	rv = nsinfo__get_nspid(&RC_CHK_ACCESS(nsi)->tgid, &RC_CHK_ACCESS(nsi)->nstgid,
135c35ce1d9SIan Rogers 			       &RC_CHK_ACCESS(nsi)->in_pidns, spath);
136bf2e710bSKrister Johansen 
137843ff37bSKrister Johansen out:
138843ff37bSKrister Johansen 	free(newns);
139bf2e710bSKrister Johansen 	return rv;
140843ff37bSKrister Johansen }
141843ff37bSKrister Johansen 
nsinfo__alloc(void)142c35ce1d9SIan Rogers static struct nsinfo *nsinfo__alloc(void)
143c35ce1d9SIan Rogers {
144c35ce1d9SIan Rogers 	struct nsinfo *res;
145c35ce1d9SIan Rogers 	RC_STRUCT(nsinfo) *nsi;
146c35ce1d9SIan Rogers 
147c35ce1d9SIan Rogers 	nsi = calloc(1, sizeof(*nsi));
148c35ce1d9SIan Rogers 	if (ADD_RC_CHK(res, nsi))
149c35ce1d9SIan Rogers 		refcount_set(&nsi->refcnt, 1);
150c35ce1d9SIan Rogers 
151c35ce1d9SIan Rogers 	return res;
152c35ce1d9SIan Rogers }
153c35ce1d9SIan Rogers 
nsinfo__new(pid_t pid)154843ff37bSKrister Johansen struct nsinfo *nsinfo__new(pid_t pid)
155843ff37bSKrister Johansen {
156bf2e710bSKrister Johansen 	struct nsinfo *nsi;
157843ff37bSKrister Johansen 
158bf2e710bSKrister Johansen 	if (pid == 0)
159bf2e710bSKrister Johansen 		return NULL;
160bf2e710bSKrister Johansen 
161c35ce1d9SIan Rogers 	nsi = nsinfo__alloc();
162c35ce1d9SIan Rogers 	if (!nsi)
163c35ce1d9SIan Rogers 		return NULL;
164c35ce1d9SIan Rogers 
165c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nsi)->pid = pid;
166c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nsi)->tgid = pid;
167c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nsi)->nstgid = pid;
1684d623903SArnaldo Carvalho de Melo 	nsinfo__clear_need_setns(nsi);
169c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nsi)->in_pidns = false;
170c35ce1d9SIan Rogers 	/* Init may fail if the process exits while we're trying to look at its
171c35ce1d9SIan Rogers 	 * proc information. In that case, save the pid but don't try to enter
172c35ce1d9SIan Rogers 	 * the namespace.
173bf2e710bSKrister Johansen 	 */
174bf2e710bSKrister Johansen 	if (nsinfo__init(nsi) == -1)
1754d623903SArnaldo Carvalho de Melo 		nsinfo__clear_need_setns(nsi);
176843ff37bSKrister Johansen 
177843ff37bSKrister Johansen 	return nsi;
178843ff37bSKrister Johansen }
179843ff37bSKrister Johansen 
nsinfo__mntns_path(const struct nsinfo * nsi)180*2d1acd3fSArnaldo Carvalho de Melo static const char *nsinfo__mntns_path(const struct nsinfo *nsi)
181*2d1acd3fSArnaldo Carvalho de Melo {
182*2d1acd3fSArnaldo Carvalho de Melo 	return RC_CHK_ACCESS(nsi)->mntns_path;
183*2d1acd3fSArnaldo Carvalho de Melo }
184*2d1acd3fSArnaldo Carvalho de Melo 
nsinfo__copy(const struct nsinfo * nsi)185bcaf0a97SIan Rogers struct nsinfo *nsinfo__copy(const struct nsinfo *nsi)
186bf2e710bSKrister Johansen {
187bf2e710bSKrister Johansen 	struct nsinfo *nnsi;
188bf2e710bSKrister Johansen 
1893f4417d6SBenno Evers 	if (nsi == NULL)
1903f4417d6SBenno Evers 		return NULL;
1913f4417d6SBenno Evers 
192c35ce1d9SIan Rogers 	nnsi = nsinfo__alloc();
193c35ce1d9SIan Rogers 	if (!nnsi)
194c35ce1d9SIan Rogers 		return NULL;
195c35ce1d9SIan Rogers 
196c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nnsi)->pid = nsinfo__pid(nsi);
197c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nnsi)->tgid = nsinfo__tgid(nsi);
198c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nnsi)->nstgid = nsinfo__nstgid(nsi);
199c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nnsi)->need_setns = nsinfo__need_setns(nsi);
200c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nnsi)->in_pidns = nsinfo__in_pidns(nsi);
201*2d1acd3fSArnaldo Carvalho de Melo 	if (nsinfo__mntns_path(nsi)) {
202*2d1acd3fSArnaldo Carvalho de Melo 		RC_CHK_ACCESS(nnsi)->mntns_path = strdup(nsinfo__mntns_path(nsi));
203c35ce1d9SIan Rogers 		if (!RC_CHK_ACCESS(nnsi)->mntns_path) {
204c35ce1d9SIan Rogers 			nsinfo__put(nnsi);
205bf2e710bSKrister Johansen 			return NULL;
206bf2e710bSKrister Johansen 		}
207bf2e710bSKrister Johansen 	}
208bf2e710bSKrister Johansen 
209bf2e710bSKrister Johansen 	return nnsi;
210bf2e710bSKrister Johansen }
211bf2e710bSKrister Johansen 
nsinfo__refcnt(struct nsinfo * nsi)212f94c21dfSArnaldo Carvalho de Melo static refcount_t *nsinfo__refcnt(struct nsinfo *nsi)
213f94c21dfSArnaldo Carvalho de Melo {
214f94c21dfSArnaldo Carvalho de Melo 	return &RC_CHK_ACCESS(nsi)->refcnt;
215f94c21dfSArnaldo Carvalho de Melo }
216f94c21dfSArnaldo Carvalho de Melo 
nsinfo__delete(struct nsinfo * nsi)217bcaf0a97SIan Rogers static void nsinfo__delete(struct nsinfo *nsi)
218843ff37bSKrister Johansen {
219c35ce1d9SIan Rogers 	if (nsi) {
220f94c21dfSArnaldo Carvalho de Melo 		WARN_ONCE(refcount_read(nsinfo__refcnt(nsi)) != 0, "nsinfo refcnt unbalanced\n");
221c35ce1d9SIan Rogers 		zfree(&RC_CHK_ACCESS(nsi)->mntns_path);
222c35ce1d9SIan Rogers 		RC_CHK_FREE(nsi);
223c35ce1d9SIan Rogers 	}
224843ff37bSKrister Johansen }
225843ff37bSKrister Johansen 
nsinfo__get(struct nsinfo * nsi)226843ff37bSKrister Johansen struct nsinfo *nsinfo__get(struct nsinfo *nsi)
227843ff37bSKrister Johansen {
228c35ce1d9SIan Rogers 	struct nsinfo *result;
229c35ce1d9SIan Rogers 
230c35ce1d9SIan Rogers 	if (RC_CHK_GET(result, nsi))
231f94c21dfSArnaldo Carvalho de Melo 		refcount_inc(nsinfo__refcnt(nsi));
232c35ce1d9SIan Rogers 
233c35ce1d9SIan Rogers 	return result;
234843ff37bSKrister Johansen }
235843ff37bSKrister Johansen 
nsinfo__put(struct nsinfo * nsi)236843ff37bSKrister Johansen void nsinfo__put(struct nsinfo *nsi)
237843ff37bSKrister Johansen {
238f94c21dfSArnaldo Carvalho de Melo 	if (nsi && refcount_dec_and_test(nsinfo__refcnt(nsi)))
239843ff37bSKrister Johansen 		nsinfo__delete(nsi);
240c35ce1d9SIan Rogers 	else
241c35ce1d9SIan Rogers 		RC_CHK_PUT(nsi);
242843ff37bSKrister Johansen }
243843ff37bSKrister Johansen 
nsinfo__need_setns(const struct nsinfo * nsi)244bcaf0a97SIan Rogers bool nsinfo__need_setns(const struct nsinfo *nsi)
245bcaf0a97SIan Rogers {
246c35ce1d9SIan Rogers 	return RC_CHK_ACCESS(nsi)->need_setns;
247bcaf0a97SIan Rogers }
248bcaf0a97SIan Rogers 
nsinfo__clear_need_setns(struct nsinfo * nsi)249bcaf0a97SIan Rogers void nsinfo__clear_need_setns(struct nsinfo *nsi)
250bcaf0a97SIan Rogers {
251c35ce1d9SIan Rogers 	RC_CHK_ACCESS(nsi)->need_setns = false;
252bcaf0a97SIan Rogers }
253bcaf0a97SIan Rogers 
nsinfo__tgid(const struct nsinfo * nsi)254bcaf0a97SIan Rogers pid_t nsinfo__tgid(const struct nsinfo  *nsi)
255bcaf0a97SIan Rogers {
256c35ce1d9SIan Rogers 	return RC_CHK_ACCESS(nsi)->tgid;
257bcaf0a97SIan Rogers }
258bcaf0a97SIan Rogers 
nsinfo__nstgid(const struct nsinfo * nsi)259bcaf0a97SIan Rogers pid_t nsinfo__nstgid(const struct nsinfo  *nsi)
260bcaf0a97SIan Rogers {
261c35ce1d9SIan Rogers 	return RC_CHK_ACCESS(nsi)->nstgid;
262bcaf0a97SIan Rogers }
263bcaf0a97SIan Rogers 
nsinfo__pid(const struct nsinfo * nsi)264bcaf0a97SIan Rogers pid_t nsinfo__pid(const struct nsinfo  *nsi)
265bcaf0a97SIan Rogers {
266c35ce1d9SIan Rogers 	return RC_CHK_ACCESS(nsi)->pid;
267bcaf0a97SIan Rogers }
268bcaf0a97SIan Rogers 
nsinfo__in_pidns(const struct nsinfo * nsi)269bcaf0a97SIan Rogers pid_t nsinfo__in_pidns(const struct nsinfo  *nsi)
270bcaf0a97SIan Rogers {
271c35ce1d9SIan Rogers 	return RC_CHK_ACCESS(nsi)->in_pidns;
272bcaf0a97SIan Rogers }
273bcaf0a97SIan Rogers 
nsinfo__mountns_enter(struct nsinfo * nsi,struct nscookie * nc)274bf2e710bSKrister Johansen void nsinfo__mountns_enter(struct nsinfo *nsi,
275bf2e710bSKrister Johansen 				  struct nscookie *nc)
276843ff37bSKrister Johansen {
277843ff37bSKrister Johansen 	char curpath[PATH_MAX];
278843ff37bSKrister Johansen 	int oldns = -1;
279843ff37bSKrister Johansen 	int newns = -1;
280b01c1f69SJiri Olsa 	char *oldcwd = NULL;
281843ff37bSKrister Johansen 
282843ff37bSKrister Johansen 	if (nc == NULL)
283843ff37bSKrister Johansen 		return;
284843ff37bSKrister Johansen 
285843ff37bSKrister Johansen 	nc->oldns = -1;
286843ff37bSKrister Johansen 	nc->newns = -1;
287843ff37bSKrister Johansen 
2884d623903SArnaldo Carvalho de Melo 	if (!nsi || !nsinfo__need_setns(nsi))
289843ff37bSKrister Johansen 		return;
290843ff37bSKrister Johansen 
291843ff37bSKrister Johansen 	if (snprintf(curpath, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX)
292843ff37bSKrister Johansen 		return;
293843ff37bSKrister Johansen 
294b01c1f69SJiri Olsa 	oldcwd = get_current_dir_name();
295b01c1f69SJiri Olsa 	if (!oldcwd)
296b01c1f69SJiri Olsa 		return;
297b01c1f69SJiri Olsa 
298843ff37bSKrister Johansen 	oldns = open(curpath, O_RDONLY);
299843ff37bSKrister Johansen 	if (oldns < 0)
300b01c1f69SJiri Olsa 		goto errout;
301843ff37bSKrister Johansen 
302*2d1acd3fSArnaldo Carvalho de Melo 	newns = open(nsinfo__mntns_path(nsi), O_RDONLY);
303843ff37bSKrister Johansen 	if (newns < 0)
304843ff37bSKrister Johansen 		goto errout;
305843ff37bSKrister Johansen 
306843ff37bSKrister Johansen 	if (setns(newns, CLONE_NEWNS) < 0)
307843ff37bSKrister Johansen 		goto errout;
308843ff37bSKrister Johansen 
309b01c1f69SJiri Olsa 	nc->oldcwd = oldcwd;
310843ff37bSKrister Johansen 	nc->oldns = oldns;
311843ff37bSKrister Johansen 	nc->newns = newns;
312843ff37bSKrister Johansen 	return;
313843ff37bSKrister Johansen 
314843ff37bSKrister Johansen errout:
315b01c1f69SJiri Olsa 	free(oldcwd);
316843ff37bSKrister Johansen 	if (oldns > -1)
317843ff37bSKrister Johansen 		close(oldns);
318843ff37bSKrister Johansen 	if (newns > -1)
319843ff37bSKrister Johansen 		close(newns);
320843ff37bSKrister Johansen }
321843ff37bSKrister Johansen 
nsinfo__mountns_exit(struct nscookie * nc)322843ff37bSKrister Johansen void nsinfo__mountns_exit(struct nscookie *nc)
323843ff37bSKrister Johansen {
324b01c1f69SJiri Olsa 	if (nc == NULL || nc->oldns == -1 || nc->newns == -1 || !nc->oldcwd)
325843ff37bSKrister Johansen 		return;
326843ff37bSKrister Johansen 
327843ff37bSKrister Johansen 	setns(nc->oldns, CLONE_NEWNS);
328843ff37bSKrister Johansen 
329b01c1f69SJiri Olsa 	if (nc->oldcwd) {
330b01c1f69SJiri Olsa 		WARN_ON_ONCE(chdir(nc->oldcwd));
331b01c1f69SJiri Olsa 		zfree(&nc->oldcwd);
332b01c1f69SJiri Olsa 	}
333b01c1f69SJiri Olsa 
334843ff37bSKrister Johansen 	if (nc->oldns > -1) {
335843ff37bSKrister Johansen 		close(nc->oldns);
336843ff37bSKrister Johansen 		nc->oldns = -1;
337843ff37bSKrister Johansen 	}
338843ff37bSKrister Johansen 
339843ff37bSKrister Johansen 	if (nc->newns > -1) {
340843ff37bSKrister Johansen 		close(nc->newns);
341843ff37bSKrister Johansen 		nc->newns = -1;
342843ff37bSKrister Johansen 	}
343843ff37bSKrister Johansen }
344544abd44SKrister Johansen 
nsinfo__realpath(const char * path,struct nsinfo * nsi)345544abd44SKrister Johansen char *nsinfo__realpath(const char *path, struct nsinfo *nsi)
346544abd44SKrister Johansen {
347544abd44SKrister Johansen 	char *rpath;
348544abd44SKrister Johansen 	struct nscookie nsc;
349544abd44SKrister Johansen 
350544abd44SKrister Johansen 	nsinfo__mountns_enter(nsi, &nsc);
351544abd44SKrister Johansen 	rpath = realpath(path, NULL);
352544abd44SKrister Johansen 	nsinfo__mountns_exit(&nsc);
353544abd44SKrister Johansen 
354544abd44SKrister Johansen 	return rpath;
355544abd44SKrister Johansen }
35667dec926SYonatan Goldschmidt 
nsinfo__stat(const char * filename,struct stat * st,struct nsinfo * nsi)35767dec926SYonatan Goldschmidt int nsinfo__stat(const char *filename, struct stat *st, struct nsinfo *nsi)
35867dec926SYonatan Goldschmidt {
35967dec926SYonatan Goldschmidt 	int ret;
36067dec926SYonatan Goldschmidt 	struct nscookie nsc;
36167dec926SYonatan Goldschmidt 
36267dec926SYonatan Goldschmidt 	nsinfo__mountns_enter(nsi, &nsc);
36367dec926SYonatan Goldschmidt 	ret = stat(filename, st);
36467dec926SYonatan Goldschmidt 	nsinfo__mountns_exit(&nsc);
36567dec926SYonatan Goldschmidt 
36667dec926SYonatan Goldschmidt 	return ret;
36767dec926SYonatan Goldschmidt }
3685d28a17cSLeo Yan 
nsinfo__is_in_root_namespace(void)3695d28a17cSLeo Yan bool nsinfo__is_in_root_namespace(void)
3705d28a17cSLeo Yan {
371c35ce1d9SIan Rogers 	pid_t tgid = 0, nstgid = 0;
372c35ce1d9SIan Rogers 	bool in_pidns = false;
3735d28a17cSLeo Yan 
374c35ce1d9SIan Rogers 	nsinfo__get_nspid(&tgid, &nstgid, &in_pidns, "/proc/self/status");
375c35ce1d9SIan Rogers 	return !in_pidns;
3765d28a17cSLeo Yan }
377