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