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