1/*
2 * Copyright (C) 2013 Linux Test Project, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it
13 * is free of the rightful claim of any third person regarding
14 * infringement or the like.  Any license provided herein, whether
15 * implied or otherwise, applies only to this software file.  Patent
16 * licenses, if any, provided herein do not apply to combinations of
17 * this program with other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301, USA.
23 */
24
25#define NS_MAX 5
26static int ns_types[NS_MAX];
27static int ns_fds[NS_MAX];
28static int ns_total;
29
30static int get_ns_fd(int pid, const char *ns)
31{
32	char tmp[PATH_MAX];
33	struct stat st;
34	int fd = -1;
35
36	sprintf(tmp, "/proc/%d/ns/%s", pid, ns);
37	if (stat(tmp, &st) == 0) {
38		fd = open(tmp, O_RDONLY);
39		if (fd == -1)
40			tst_brkm(TBROK|TERRNO, NULL, "failed to open %s", tmp);
41	} else {
42		if (errno != ENOENT)
43			tst_brkm(TBROK|TERRNO, NULL, "failed to stat %s", tmp);
44	}
45	return fd;
46}
47
48static void init_ns_type(int clone_type, const char *proc_name)
49{
50	int fd;
51
52	fd = get_ns_fd(getpid(), proc_name);
53	if (fd != -1) {
54		ns_types[ns_total] = clone_type;
55		ns_fds[ns_total] = fd;
56		tst_resm(TINFO, "ns_name=%s, ns_fds[%d]=%d, ns_types[%d]=0x%x",
57			 proc_name, ns_total, fd, ns_total, clone_type);
58		ns_total++;
59	}
60}
61
62static void init_available_ns(void)
63{
64#if defined(CLONE_NEWIPC)
65	init_ns_type(CLONE_NEWIPC, "ipc");
66#endif
67#if defined(CLONE_NEWNS)
68	init_ns_type(CLONE_NEWNS, "mnt");
69#endif
70#if defined(CLONE_NEWNET)
71	init_ns_type(CLONE_NEWNET, "net");
72#endif
73#if defined(CLONE_NEWPID)
74	init_ns_type(CLONE_NEWPID, "pid");
75#endif
76#if defined(CLONE_NEWUTS)
77	init_ns_type(CLONE_NEWUTS, "uts");
78#endif
79}
80
81static void close_ns_fds(void)
82{
83	int i;
84
85	for (i = 0; i < ns_total; i++)
86		if (ns_fds[i] != -1)
87			close(ns_fds[i]);
88}
89