tools/perf/util/namespaces.c

Source file repositories/reference/linux-study-clean/tools/perf/util/namespaces.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/namespaces.c
Extension
.c
Size
7671 bytes
Lines
381
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (strstr(statln, "Tgid:") != NULL) {
			*tgid = (pid_t)strtol(strrchr(statln, '\t'), NULL, 10);
			*nstgid = *tgid;
		}

		if (strstr(statln, "NStgid:") != NULL) {
			nspid = strrchr(statln, '\t');
			*nstgid = (pid_t)strtol(nspid, NULL, 10);
			/*
			 * If innermost tgid is not the first, process is in a different
			 * PID namespace.
			 */
			*in_pidns = (statln + sizeof("NStgid:") - 1) != nspid;
			break;
		}
	}

	fclose(f);
	free(statln);
	return 0;
}

int nsinfo__init(struct nsinfo *nsi)
{
	char oldns[PATH_MAX];
	char spath[PATH_MAX];
	char *newns = NULL;
	struct stat old_stat;
	struct stat new_stat;
	int rv = -1;

	if (snprintf(oldns, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX)
		return rv;

	if (asprintf(&newns, "/proc/%d/ns/mnt", nsinfo__pid(nsi)) == -1)
		return rv;

	if (stat(oldns, &old_stat) < 0)
		goto out;

	if (stat(newns, &new_stat) < 0)
		goto out;

	/* Check if the mount namespaces differ, if so then indicate that we
	 * want to switch as part of looking up dso/map data.
	 */
	if (old_stat.st_ino != new_stat.st_ino) {
		RC_CHK_ACCESS(nsi)->need_setns = true;
		RC_CHK_ACCESS(nsi)->mntns_path = newns;
		newns = NULL;
	}

	/* If we're dealing with a process that is in a different PID namespace,
	 * attempt to work out the innermost tgid for the process.
	 */
	if (snprintf(spath, PATH_MAX, "/proc/%d/status", nsinfo__pid(nsi)) >= PATH_MAX)
		goto out;

	rv = nsinfo__get_nspid(&RC_CHK_ACCESS(nsi)->tgid, &RC_CHK_ACCESS(nsi)->nstgid,
			       &RC_CHK_ACCESS(nsi)->in_pidns, spath);

out:
	free(newns);
	return rv;
}

static struct nsinfo *nsinfo__alloc(void)
{
	struct nsinfo *res;
	RC_STRUCT(nsinfo) *nsi;

	nsi = calloc(1, sizeof(*nsi));
	if (ADD_RC_CHK(res, nsi))
		refcount_set(&nsi->refcnt, 1);

	return res;
}

struct nsinfo *nsinfo__new(pid_t pid)
{
	struct nsinfo *nsi;

	if (pid == 0)
		return NULL;

	nsi = nsinfo__alloc();
	if (!nsi)
		return NULL;

	RC_CHK_ACCESS(nsi)->pid = pid;

Annotation

Implementation Notes