]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/detect-virt/detect-virt.c
detect-virt: add --private-users switch to check if a userns is active
[thirdparty/systemd.git] / src / detect-virt / detect-virt.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <getopt.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24
25 #include "util.h"
26 #include "virt.h"
27
28 static bool arg_quiet = false;
29 static enum {
30 ANY_VIRTUALIZATION,
31 ONLY_VM,
32 ONLY_CONTAINER,
33 ONLY_CHROOT,
34 ONLY_PRIVATE_USERS,
35 } arg_mode = ANY_VIRTUALIZATION;
36
37 static void help(void) {
38 printf("%s [OPTIONS...]\n\n"
39 "Detect execution in a virtualized environment.\n\n"
40 " -h --help Show this help\n"
41 " --version Show package version\n"
42 " -c --container Only detect whether we are run in a container\n"
43 " -v --vm Only detect whether we are run in a VM\n"
44 " -r --chroot Detect whether we are run in a chroot() environment\n"
45 " --private-users Only detect whether we are running in a user namespace\n"
46 " -q --quiet Don't output anything, just set return value\n"
47 , program_invocation_short_name);
48 }
49
50 static int parse_argv(int argc, char *argv[]) {
51
52 enum {
53 ARG_VERSION = 0x100,
54 ARG_PRIVATE_USERS,
55 };
56
57 static const struct option options[] = {
58 { "help", no_argument, NULL, 'h' },
59 { "version", no_argument, NULL, ARG_VERSION },
60 { "container", no_argument, NULL, 'c' },
61 { "vm", no_argument, NULL, 'v' },
62 { "chroot", no_argument, NULL, 'r' },
63 { "private-users", no_argument, NULL, ARG_PRIVATE_USERS },
64 { "quiet", no_argument, NULL, 'q' },
65 {}
66 };
67
68 int c;
69
70 assert(argc >= 0);
71 assert(argv);
72
73 while ((c = getopt_long(argc, argv, "hqcvr", options, NULL)) >= 0)
74
75 switch (c) {
76
77 case 'h':
78 help();
79 return 0;
80
81 case ARG_VERSION:
82 return version();
83
84 case 'q':
85 arg_quiet = true;
86 break;
87
88 case 'c':
89 arg_mode = ONLY_CONTAINER;
90 break;
91
92 case ARG_PRIVATE_USERS:
93 arg_mode = ONLY_PRIVATE_USERS;
94 break;
95
96 case 'v':
97 arg_mode = ONLY_VM;
98 break;
99
100 case 'r':
101 arg_mode = ONLY_CHROOT;
102 break;
103
104 case '?':
105 return -EINVAL;
106
107 default:
108 assert_not_reached("Unhandled option");
109 }
110
111 if (optind < argc) {
112 log_error("%s takes no arguments.", program_invocation_short_name);
113 return -EINVAL;
114 }
115
116 return 1;
117 }
118
119 int main(int argc, char *argv[]) {
120 int r;
121
122 /* This is mostly intended to be used for scripts which want
123 * to detect whether we are being run in a virtualized
124 * environment or not */
125
126 log_parse_environment();
127 log_open();
128
129 r = parse_argv(argc, argv);
130 if (r <= 0)
131 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
132
133 switch (arg_mode) {
134
135 case ONLY_VM:
136 r = detect_vm();
137 if (r < 0) {
138 log_error_errno(r, "Failed to check for VM: %m");
139 return EXIT_FAILURE;
140 }
141
142 break;
143
144 case ONLY_CONTAINER:
145 r = detect_container();
146 if (r < 0) {
147 log_error_errno(r, "Failed to check for container: %m");
148 return EXIT_FAILURE;
149 }
150
151 break;
152
153 case ONLY_CHROOT:
154 r = running_in_chroot();
155 if (r < 0) {
156 log_error_errno(r, "Failed to check for chroot() environment: %m");
157 return EXIT_FAILURE;
158 }
159
160 return r ? EXIT_SUCCESS : EXIT_FAILURE;
161
162 case ONLY_PRIVATE_USERS:
163 r = running_in_userns();
164 if (r < 0) {
165 log_error_errno(r, "Failed to check for user namespace: %m");
166 return EXIT_FAILURE;
167 }
168
169 return r ? EXIT_SUCCESS : EXIT_FAILURE;
170
171 case ANY_VIRTUALIZATION:
172 default:
173 r = detect_virtualization();
174 if (r < 0) {
175 log_error_errno(r, "Failed to check for virtualization: %m");
176 return EXIT_FAILURE;
177 }
178
179 break;
180 }
181
182 if (!arg_quiet)
183 puts(virtualization_to_string(r));
184
185 return r != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
186 }