]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
07faed4f | 2 | /*** |
07faed4f | 3 | Copyright 2010 Lennart Poettering |
07faed4f LP |
4 | ***/ |
5 | ||
07faed4f | 6 | #include <errno.h> |
cac72f7a | 7 | #include <getopt.h> |
3f6fd1ba LP |
8 | #include <stdbool.h> |
9 | #include <stdlib.h> | |
07faed4f | 10 | |
39824629 | 11 | #include "string-table.h" |
07faed4f | 12 | #include "util.h" |
b52aae1d | 13 | #include "virt.h" |
cac72f7a LP |
14 | |
15 | static bool arg_quiet = false; | |
16 | static enum { | |
17 | ANY_VIRTUALIZATION, | |
18 | ONLY_VM, | |
d21be5ff LP |
19 | ONLY_CONTAINER, |
20 | ONLY_CHROOT, | |
299a34c1 | 21 | ONLY_PRIVATE_USERS, |
cac72f7a LP |
22 | } arg_mode = ANY_VIRTUALIZATION; |
23 | ||
601185b4 | 24 | static void help(void) { |
cac72f7a LP |
25 | printf("%s [OPTIONS...]\n\n" |
26 | "Detect execution in a virtualized environment.\n\n" | |
27 | " -h --help Show this help\n" | |
28 | " --version Show package version\n" | |
29 | " -c --container Only detect whether we are run in a container\n" | |
30 | " -v --vm Only detect whether we are run in a VM\n" | |
d21be5ff | 31 | " -r --chroot Detect whether we are run in a chroot() environment\n" |
299a34c1 | 32 | " --private-users Only detect whether we are running in a user namespace\n" |
601185b4 | 33 | " -q --quiet Don't output anything, just set return value\n" |
39824629 | 34 | " --list List all known and detectable types of virtualization\n" |
601185b4 | 35 | , program_invocation_short_name); |
cac72f7a LP |
36 | } |
37 | ||
38 | static int parse_argv(int argc, char *argv[]) { | |
39 | ||
40 | enum { | |
299a34c1 ZJS |
41 | ARG_VERSION = 0x100, |
42 | ARG_PRIVATE_USERS, | |
39824629 | 43 | ARG_LIST, |
cac72f7a LP |
44 | }; |
45 | ||
46 | static const struct option options[] = { | |
299a34c1 ZJS |
47 | { "help", no_argument, NULL, 'h' }, |
48 | { "version", no_argument, NULL, ARG_VERSION }, | |
49 | { "container", no_argument, NULL, 'c' }, | |
50 | { "vm", no_argument, NULL, 'v' }, | |
51 | { "chroot", no_argument, NULL, 'r' }, | |
52 | { "private-users", no_argument, NULL, ARG_PRIVATE_USERS }, | |
53 | { "quiet", no_argument, NULL, 'q' }, | |
39824629 | 54 | { "list", no_argument, NULL, ARG_LIST }, |
eb9da376 | 55 | {} |
cac72f7a LP |
56 | }; |
57 | ||
58 | int c; | |
59 | ||
60 | assert(argc >= 0); | |
61 | assert(argv); | |
62 | ||
d21be5ff | 63 | while ((c = getopt_long(argc, argv, "hqcvr", options, NULL)) >= 0) |
cac72f7a LP |
64 | |
65 | switch (c) { | |
66 | ||
67 | case 'h': | |
601185b4 ZJS |
68 | help(); |
69 | return 0; | |
cac72f7a LP |
70 | |
71 | case ARG_VERSION: | |
3f6fd1ba | 72 | return version(); |
cac72f7a LP |
73 | |
74 | case 'q': | |
75 | arg_quiet = true; | |
76 | break; | |
77 | ||
78 | case 'c': | |
79 | arg_mode = ONLY_CONTAINER; | |
80 | break; | |
81 | ||
299a34c1 ZJS |
82 | case ARG_PRIVATE_USERS: |
83 | arg_mode = ONLY_PRIVATE_USERS; | |
84 | break; | |
85 | ||
cac72f7a LP |
86 | case 'v': |
87 | arg_mode = ONLY_VM; | |
88 | break; | |
89 | ||
d21be5ff LP |
90 | case 'r': |
91 | arg_mode = ONLY_CHROOT; | |
92 | break; | |
93 | ||
39824629 LP |
94 | case ARG_LIST: |
95 | DUMP_STRING_TABLE(virtualization, int, _VIRTUALIZATION_MAX); | |
96 | return 0; | |
97 | ||
cac72f7a LP |
98 | case '?': |
99 | return -EINVAL; | |
100 | ||
101 | default: | |
eb9da376 | 102 | assert_not_reached("Unhandled option"); |
cac72f7a | 103 | } |
cac72f7a LP |
104 | |
105 | if (optind < argc) { | |
9e6a555a | 106 | log_error("%s takes no arguments.", program_invocation_short_name); |
cac72f7a LP |
107 | return -EINVAL; |
108 | } | |
109 | ||
110 | return 1; | |
111 | } | |
07faed4f LP |
112 | |
113 | int main(int argc, char *argv[]) { | |
9e6a555a | 114 | int r; |
07faed4f LP |
115 | |
116 | /* This is mostly intended to be used for scripts which want | |
117 | * to detect whether we are being run in a virtualized | |
118 | * environment or not */ | |
119 | ||
cac72f7a LP |
120 | log_parse_environment(); |
121 | log_open(); | |
122 | ||
123 | r = parse_argv(argc, argv); | |
124 | if (r <= 0) | |
125 | return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; | |
126 | ||
127 | switch (arg_mode) { | |
128 | ||
75f86906 LP |
129 | case ONLY_VM: |
130 | r = detect_vm(); | |
131 | if (r < 0) { | |
9e6a555a | 132 | log_error_errno(r, "Failed to check for VM: %m"); |
cac72f7a LP |
133 | return EXIT_FAILURE; |
134 | } | |
135 | ||
cac72f7a | 136 | break; |
cac72f7a LP |
137 | |
138 | case ONLY_CONTAINER: | |
75f86906 | 139 | r = detect_container(); |
cac72f7a | 140 | if (r < 0) { |
da927ba9 | 141 | log_error_errno(r, "Failed to check for container: %m"); |
cac72f7a LP |
142 | return EXIT_FAILURE; |
143 | } | |
144 | ||
cac72f7a LP |
145 | break; |
146 | ||
d21be5ff LP |
147 | case ONLY_CHROOT: |
148 | r = running_in_chroot(); | |
149 | if (r < 0) { | |
150 | log_error_errno(r, "Failed to check for chroot() environment: %m"); | |
151 | return EXIT_FAILURE; | |
152 | } | |
153 | ||
154 | return r ? EXIT_SUCCESS : EXIT_FAILURE; | |
155 | ||
299a34c1 ZJS |
156 | case ONLY_PRIVATE_USERS: |
157 | r = running_in_userns(); | |
158 | if (r < 0) { | |
159 | log_error_errno(r, "Failed to check for user namespace: %m"); | |
160 | return EXIT_FAILURE; | |
161 | } | |
162 | ||
163 | return r ? EXIT_SUCCESS : EXIT_FAILURE; | |
164 | ||
75f86906 LP |
165 | case ANY_VIRTUALIZATION: |
166 | default: | |
167 | r = detect_virtualization(); | |
cac72f7a | 168 | if (r < 0) { |
75f86906 | 169 | log_error_errno(r, "Failed to check for virtualization: %m"); |
cac72f7a LP |
170 | return EXIT_FAILURE; |
171 | } | |
172 | ||
cac72f7a | 173 | break; |
07faed4f LP |
174 | } |
175 | ||
ac0d6edf | 176 | if (!arg_quiet) |
75f86906 LP |
177 | puts(virtualization_to_string(r)); |
178 | ||
9e6a555a | 179 | return r != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE; |
07faed4f | 180 | } |