]> git.proxmox.com Git - mirror_qemu.git/blame - storage-daemon/qemu-storage-daemon.c
fuse: Implement hole detection through lseek
[mirror_qemu.git] / storage-daemon / qemu-storage-daemon.c
CommitLineData
f353415f
KW
1/*
2 * QEMU storage daemon
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 * Copyright (c) 2019 Kevin Wolf <kwolf@redhat.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26#include "qemu/osdep.h"
27
28#include <getopt.h>
29
30#include "block/block.h"
eed8b691 31#include "block/nbd.h"
5e6911cf 32#include "chardev/char.h"
f353415f 33#include "crypto/init.h"
2af282ec
KW
34#include "monitor/monitor.h"
35#include "monitor/monitor-internal.h"
f353415f
KW
36
37#include "qapi/error.h"
eed8b691 38#include "qapi/qapi-visit-block-core.h"
5daa6bfd 39#include "qapi/qapi-visit-block-export.h"
2af282ec 40#include "qapi/qapi-visit-control.h"
d6da78b5 41#include "qapi/qmp/qdict.h"
2af282ec 42#include "qapi/qmp/qstring.h"
14837c64
KW
43#include "qapi/qobject-input-visitor.h"
44
f353415f
KW
45#include "qemu-common.h"
46#include "qemu-version.h"
47#include "qemu/config-file.h"
48#include "qemu/error-report.h"
d6da78b5 49#include "qemu/help_option.h"
f353415f
KW
50#include "qemu/log.h"
51#include "qemu/main-loop.h"
52#include "qemu/module.h"
d6da78b5
KW
53#include "qemu/option.h"
54#include "qom/object_interfaces.h"
f353415f 55
2af282ec
KW
56#include "storage-daemon/qapi/qapi-commands.h"
57#include "storage-daemon/qapi/qapi-init-commands.h"
58
aa70683d 59#include "sysemu/runstate.h"
f353415f
KW
60#include "trace/control.h"
61
aa70683d
KW
62static volatile bool exit_requested = false;
63
64void qemu_system_killed(int signal, pid_t pid)
65{
66 exit_requested = true;
67}
68
2af282ec
KW
69void qmp_quit(Error **errp)
70{
71 exit_requested = true;
72}
73
f353415f
KW
74static void help(void)
75{
76 printf(
77"Usage: %s [options]\n"
78"QEMU storage daemon\n"
79"\n"
80" -h, --help display this help and exit\n"
81" -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
82" specify tracing options\n"
83" -V, --version output version information and exit\n"
84"\n"
14837c64
KW
85" --blockdev [driver=]<driver>[,node-name=<N>][,discard=ignore|unmap]\n"
86" [,cache.direct=on|off][,cache.no-flush=on|off]\n"
87" [,read-only=on|off][,auto-read-only=on|off]\n"
88" [,force-share=on|off][,detect-zeroes=on|off|unmap]\n"
89" [,driver specific parameters...]\n"
90" configure a block backend\n"
91"\n"
5e6911cf
KW
92" --chardev <options> configure a character device backend\n"
93" (see the qemu(1) man page for possible options)\n"
94"\n"
45db4bc1 95" --export [type=]nbd,id=<id>,node-name=<node-name>[,name=<export-name>]\n"
39411120
KW
96" [,writable=on|off][,bitmap=<name>]\n"
97" export the specified block node over NBD\n"
98" (requires --nbd-server)\n"
99"\n"
2af282ec
KW
100" --monitor [chardev=]name[,mode=control][,pretty[=on|off]]\n"
101" configure a QMP monitor\n"
102"\n"
eed8b691 103" --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>\n"
1c8222b0 104" [,tls-creds=<id>][,tls-authz=<id>][,max-connections=<n>]\n"
eed8b691 105" --nbd-server addr.type=unix,addr.path=<path>\n"
1c8222b0 106" [,tls-creds=<id>][,tls-authz=<id>][,max-connections=<n>]\n"
eed8b691
KW
107" start an NBD server for exporting block nodes\n"
108"\n"
d6da78b5
KW
109" --object help list object types that can be added\n"
110" --object <type>,help list properties for the given object type\n"
111" --object <type>[,<property>=<value>...]\n"
112" create a new object of type <type>, setting\n"
113" properties in the order they are specified. Note\n"
114" that the 'id' property must be set.\n"
115" See the qemu(1) man page for documentation of the\n"
116" objects that can be added.\n"
117"\n"
f353415f
KW
118QEMU_HELP_BOTTOM "\n",
119 error_get_progname());
120}
121
14837c64
KW
122enum {
123 OPTION_BLOCKDEV = 256,
5e6911cf 124 OPTION_CHARDEV,
39411120 125 OPTION_EXPORT,
2af282ec 126 OPTION_MONITOR,
eed8b691 127 OPTION_NBD_SERVER,
d6da78b5
KW
128 OPTION_OBJECT,
129};
130
5e6911cf
KW
131extern QemuOptsList qemu_chardev_opts;
132
d6da78b5
KW
133static QemuOptsList qemu_object_opts = {
134 .name = "object",
135 .implied_opt_name = "qom-type",
136 .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
137 .desc = {
138 { }
139 },
14837c64
KW
140};
141
2af282ec
KW
142static void init_qmp_commands(void)
143{
144 qmp_init_marshal(&qmp_commands);
145 qmp_register_command(&qmp_commands, "query-qmp-schema",
146 qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
147
148 QTAILQ_INIT(&qmp_cap_negotiation_commands);
149 qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
150 qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG);
151}
152
f353415f
KW
153static void process_options(int argc, char *argv[])
154{
155 int c;
156
157 static const struct option long_options[] = {
14837c64 158 {"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
5e6911cf 159 {"chardev", required_argument, NULL, OPTION_CHARDEV},
39411120 160 {"export", required_argument, NULL, OPTION_EXPORT},
f353415f 161 {"help", no_argument, NULL, 'h'},
2af282ec 162 {"monitor", required_argument, NULL, OPTION_MONITOR},
eed8b691 163 {"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
d6da78b5 164 {"object", required_argument, NULL, OPTION_OBJECT},
f353415f
KW
165 {"trace", required_argument, NULL, 'T'},
166 {"version", no_argument, NULL, 'V'},
167 {0, 0, 0, 0}
168 };
169
170 /*
171 * In contrast to the system emulator, options are processed in the order
172 * they are given on the command lines. This means that things must be
173 * defined first before they can be referenced in another option.
174 */
175 while ((c = getopt_long(argc, argv, "hT:V", long_options, NULL)) != -1) {
176 switch (c) {
177 case '?':
178 exit(EXIT_FAILURE);
179 case 'h':
180 help();
181 exit(EXIT_SUCCESS);
182 case 'T':
92eecfff
PB
183 trace_opt_parse(optarg);
184 trace_init_file();
185 break;
f353415f
KW
186 case 'V':
187 printf("qemu-storage-daemon version "
188 QEMU_FULL_VERSION "\n" QEMU_COPYRIGHT "\n");
189 exit(EXIT_SUCCESS);
14837c64
KW
190 case OPTION_BLOCKDEV:
191 {
192 Visitor *v;
193 BlockdevOptions *options;
194
195 v = qobject_input_visitor_new_str(optarg, "driver",
196 &error_fatal);
197
198 visit_type_BlockdevOptions(v, NULL, &options, &error_fatal);
199 visit_free(v);
200
201 qmp_blockdev_add(options, &error_fatal);
202 qapi_free_BlockdevOptions(options);
203 break;
204 }
5e6911cf
KW
205 case OPTION_CHARDEV:
206 {
207 /* TODO This interface is not stable until we QAPIfy it */
208 QemuOpts *opts = qemu_opts_parse_noisily(&qemu_chardev_opts,
209 optarg, true);
210 if (opts == NULL) {
211 exit(EXIT_FAILURE);
212 }
213
214 if (!qemu_chr_new_from_opts(opts, NULL, &error_fatal)) {
215 /* No error, but NULL returned means help was printed */
216 exit(EXIT_SUCCESS);
217 }
218 qemu_opts_del(opts);
219 break;
220 }
39411120
KW
221 case OPTION_EXPORT:
222 {
223 Visitor *v;
143ea767 224 BlockExportOptions *export;
39411120
KW
225
226 v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
143ea767 227 visit_type_BlockExportOptions(v, NULL, &export, &error_fatal);
39411120
KW
228 visit_free(v);
229
060102ad 230 qmp_block_export_add(export, &error_fatal);
143ea767 231 qapi_free_BlockExportOptions(export);
39411120
KW
232 break;
233 }
2af282ec
KW
234 case OPTION_MONITOR:
235 {
236 Visitor *v;
237 MonitorOptions *monitor;
238
239 v = qobject_input_visitor_new_str(optarg, "chardev",
240 &error_fatal);
241 visit_type_MonitorOptions(v, NULL, &monitor, &error_fatal);
242 visit_free(v);
243
244 /* TODO Catch duplicate monitor IDs */
245 monitor_init(monitor, false, &error_fatal);
246 qapi_free_MonitorOptions(monitor);
247 break;
248 }
eed8b691
KW
249 case OPTION_NBD_SERVER:
250 {
251 Visitor *v;
252 NbdServerOptions *options;
253
254 v = qobject_input_visitor_new_str(optarg, NULL, &error_fatal);
255 visit_type_NbdServerOptions(v, NULL, &options, &error_fatal);
256 visit_free(v);
257
258 nbd_server_start_options(options, &error_fatal);
259 qapi_free_NbdServerOptions(options);
260 break;
261 }
d6da78b5
KW
262 case OPTION_OBJECT:
263 {
d6da78b5 264 QDict *args;
8db1efd3 265 bool help;
d6da78b5 266
8db1efd3
KW
267 args = keyval_parse(optarg, "qom-type", &help, &error_fatal);
268 if (help) {
269 user_creatable_print_help_from_qdict(args);
d6da78b5
KW
270 exit(EXIT_SUCCESS);
271 }
eaae29ef 272 user_creatable_add_dict(args, true, &error_fatal);
d6da78b5 273 qobject_unref(args);
d6da78b5
KW
274 break;
275 }
f353415f
KW
276 default:
277 g_assert_not_reached();
278 }
279 }
280 if (optind != argc) {
281 error_report("Unexpected argument: %s", argv[optind]);
282 exit(EXIT_FAILURE);
283 }
284}
285
286int main(int argc, char *argv[])
287{
288#ifdef CONFIG_POSIX
289 signal(SIGPIPE, SIG_IGN);
290#endif
291
292 error_init(argv[0]);
293 qemu_init_exec_dir(argv[0]);
aa70683d 294 os_setup_signal_handling();
f353415f
KW
295
296 module_call_init(MODULE_INIT_QOM);
297 module_call_init(MODULE_INIT_TRACE);
5b99bdea 298 qemu_add_opts(&qemu_object_opts);
f353415f
KW
299 qemu_add_opts(&qemu_trace_opts);
300 qcrypto_init(&error_fatal);
301 bdrv_init();
2af282ec
KW
302 monitor_init_globals_core();
303 init_qmp_commands();
f353415f
KW
304
305 if (!trace_init_backends()) {
306 return EXIT_FAILURE;
307 }
308 qemu_set_log(LOG_TRACE);
309
310 qemu_init_main_loop(&error_fatal);
311 process_options(argc, argv);
312
aa70683d
KW
313 while (!exit_requested) {
314 main_loop_wait(false);
315 }
316
f10802d2
SH
317 monitor_cleanup();
318 qemu_chr_cleanup();
319 user_creatable_cleanup();
320
f353415f
KW
321 return EXIT_SUCCESS;
322}