chiark / gitweb /
install: make InstallContext::{will_install,have_installed} OrderedHashmaps
[elogind.git] / src / detect-virt / detect-virt.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <stdlib.h>
23 #include <stdbool.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <getopt.h>
27
28 #include "util.h"
29 #include "virt.h"
30 #include "build.h"
31
32 static bool arg_quiet = false;
33 static enum {
34         ANY_VIRTUALIZATION,
35         ONLY_VM,
36         ONLY_CONTAINER
37 } arg_mode = ANY_VIRTUALIZATION;
38
39 static void help(void) {
40         printf("%s [OPTIONS...]\n\n"
41                "Detect execution in a virtualized environment.\n\n"
42                "  -h --help             Show this help\n"
43                "     --version          Show package version\n"
44                "  -c --container        Only detect whether we are run in a container\n"
45                "  -v --vm               Only detect whether we are run in a VM\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         };
55
56         static const struct option options[] = {
57                 { "help",      no_argument,       NULL, 'h'           },
58                 { "version",   no_argument,       NULL, ARG_VERSION   },
59                 { "container", no_argument,       NULL, 'c'           },
60                 { "vm",        optional_argument, NULL, 'v'           },
61                 { "quiet",     no_argument,       NULL, 'q'           },
62                 {}
63         };
64
65         int c;
66
67         assert(argc >= 0);
68         assert(argv);
69
70         while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0)
71
72                 switch (c) {
73
74                 case 'h':
75                         help();
76                         return 0;
77
78                 case ARG_VERSION:
79                         puts(PACKAGE_STRING);
80                         puts(SYSTEMD_FEATURES);
81                         return 0;
82
83                 case 'q':
84                         arg_quiet = true;
85                         break;
86
87                 case 'c':
88                         arg_mode = ONLY_CONTAINER;
89                         break;
90
91                 case 'v':
92                         arg_mode = ONLY_VM;
93                         break;
94
95                 case '?':
96                         return -EINVAL;
97
98                 default:
99                         assert_not_reached("Unhandled option");
100                 }
101
102         if (optind < argc) {
103                 log_error("%s takes no arguments.",
104                           program_invocation_short_name);
105                 return -EINVAL;
106         }
107
108         return 1;
109 }
110
111 int main(int argc, char *argv[]) {
112         const char *id = NULL;
113         int retval = EXIT_SUCCESS;
114         int r;
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
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
129         case ANY_VIRTUALIZATION: {
130                 int v;
131
132                 v = detect_virtualization(&id);
133                 if (v < 0) {
134                         log_error("Failed to check for virtualization: %s", strerror(-v));
135                         return EXIT_FAILURE;
136                 }
137
138                 retval = v != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
139                 break;
140         }
141
142         case ONLY_CONTAINER:
143                 r = detect_container(&id);
144                 if (r < 0) {
145                         log_error("Failed to check for container: %s", strerror(-r));
146                         return EXIT_FAILURE;
147                 }
148
149                 retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
150                 break;
151
152         case ONLY_VM:
153                 r = detect_vm(&id);
154                 if (r < 0) {
155                         log_error("Failed to check for vm: %s", strerror(-r));
156                         return EXIT_FAILURE;
157                 }
158
159                 retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
160                 break;
161         }
162
163         if (!arg_quiet)
164                 puts(id ? id : "none");
165
166         return retval;
167 }