chiark / gitweb /
test: allow deletion of temporary files from normal fs
[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(DISTRIBUTION);
84                         puts(SYSTEMD_FEATURES);
85                         return 0;
86
87                 case 'q':
88                         arg_quiet = true;
89                         break;
90
91                 case 'c':
92                         arg_mode = ONLY_CONTAINER;
93                         break;
94
95                 case 'v':
96                         arg_mode = ONLY_VM;
97                         break;
98
99                 case '?':
100                         return -EINVAL;
101
102                 default:
103                         log_error("Unknown option code %c", c);
104                         return -EINVAL;
105                 }
106         }
107
108         if (optind < argc) {
109                 help();
110                 return -EINVAL;
111         }
112
113         return 1;
114 }
115
116 int main(int argc, char *argv[]) {
117         const char *id = NULL;
118         int r;
119         int retval = EXIT_SUCCESS;
120
121         /* This is mostly intended to be used for scripts which want
122          * to detect whether we are being run in a virtualized
123          * environment or not */
124
125         log_parse_environment();
126         log_open();
127
128         r = parse_argv(argc, argv);
129         if (r <= 0)
130                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
131
132         switch (arg_mode) {
133
134         case ANY_VIRTUALIZATION: {
135                 Virtualization v;
136
137                 v = detect_virtualization(&id);
138                 if (v < 0) {
139                         log_error("Failed to check for virtualization: %s", strerror(-v));
140                         return EXIT_FAILURE;
141                 }
142
143                 retval = v != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
144                 break;
145         }
146
147         case ONLY_CONTAINER:
148                 r = detect_container(&id);
149                 if (r < 0) {
150                         log_error("Failed to check for container: %s", strerror(-r));
151                         return EXIT_FAILURE;
152                 }
153
154                 retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
155                 break;
156
157         case ONLY_VM:
158                 r = detect_vm(&id);
159                 if (r < 0) {
160                         log_error("Failed to check for vm: %s", strerror(-r));
161                         return EXIT_FAILURE;
162                 }
163
164                 retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
165                 break;
166         }
167
168         if (!arg_quiet)
169                 puts(id ? id : "none");
170
171         return retval;
172 }