chiark / gitweb /
bd3ee452c12e67e1696423cc5fd3bc84160de189
[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 int help(void) {
40
41         printf("%s [OPTIONS...]\n\n"
42                "Detect execution in a virtualized environment.\n\n"
43                "  -h --help             Show this help\n"
44                "     --version          Show package version\n"
45                "  -c --container        Only detect whether we are run in a container\n"
46                "  -v --vm               Only detect whether we are run in a VM\n"
47                "  -q --quiet            Don't output anything, just set return value\n",
48                program_invocation_short_name);
49
50         return 0;
51 }
52
53 static int parse_argv(int argc, char *argv[]) {
54
55         enum {
56                 ARG_VERSION = 0x100
57         };
58
59         static const struct option options[] = {
60                 { "help",      no_argument,       NULL, 'h'           },
61                 { "version",   no_argument,       NULL, ARG_VERSION   },
62                 { "container", no_argument,       NULL, 'c'           },
63                 { "vm",        optional_argument, NULL, 'v'           },
64                 { "quiet",     no_argument,       NULL, 'q'           },
65                 { NULL,        0,                 NULL, 0             }
66         };
67
68         int c;
69
70         assert(argc >= 0);
71         assert(argv);
72
73         while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0) {
74
75                 switch (c) {
76
77                 case 'h':
78                         help();
79                         return 0;
80
81                 case ARG_VERSION:
82                         puts(PACKAGE_STRING);
83                         puts(SYSTEMD_FEATURES);
84                         return 0;
85
86                 case 'q':
87                         arg_quiet = true;
88                         break;
89
90                 case 'c':
91                         arg_mode = ONLY_CONTAINER;
92                         break;
93
94                 case 'v':
95                         arg_mode = ONLY_VM;
96                         break;
97
98                 case '?':
99                         return -EINVAL;
100
101                 default:
102                         log_error("Unknown option code %c", c);
103                         return -EINVAL;
104                 }
105         }
106
107         if (optind < argc) {
108                 help();
109                 return -EINVAL;
110         }
111
112         return 1;
113 }
114
115 int main(int argc, char *argv[]) {
116         const char *id = NULL;
117         int r;
118         int retval = EXIT_SUCCESS;
119
120         /* This is mostly intended to be used for scripts which want
121          * to detect whether we are being run in a virtualized
122          * environment or not */
123
124         log_parse_environment();
125         log_open();
126
127         r = parse_argv(argc, argv);
128         if (r <= 0)
129                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
130
131         switch (arg_mode) {
132
133         case ANY_VIRTUALIZATION: {
134                 Virtualization v;
135
136                 v = detect_virtualization(&id);
137                 if (v < 0) {
138                         log_error("Failed to check for virtualization: %s", strerror(-v));
139                         return EXIT_FAILURE;
140                 }
141
142                 retval = v != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
143                 break;
144         }
145
146         case ONLY_CONTAINER:
147                 r = detect_container(&id);
148                 if (r < 0) {
149                         log_error("Failed to check for container: %s", strerror(-r));
150                         return EXIT_FAILURE;
151                 }
152
153                 retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
154                 break;
155
156         case ONLY_VM:
157                 r = detect_vm(&id);
158                 if (r < 0) {
159                         log_error("Failed to check for vm: %s", strerror(-r));
160                         return EXIT_FAILURE;
161                 }
162
163                 retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
164                 break;
165         }
166
167         if (!arg_quiet)
168                 puts(id ? id : "none");
169
170         return retval;
171 }