qemu/storage-daemon/qemu-storage-daemon.c
<<
>>
Prefs
   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"
  31#include "block/nbd.h"
  32#include "chardev/char.h"
  33#include "crypto/init.h"
  34#include "monitor/monitor.h"
  35#include "monitor/monitor-internal.h"
  36
  37#include "qapi/error.h"
  38#include "qapi/qapi-visit-block-core.h"
  39#include "qapi/qapi-visit-block-export.h"
  40#include "qapi/qapi-visit-control.h"
  41#include "qapi/qmp/qdict.h"
  42#include "qapi/qmp/qstring.h"
  43#include "qapi/qobject-input-visitor.h"
  44
  45#include "qemu-common.h"
  46#include "qemu-version.h"
  47#include "qemu/config-file.h"
  48#include "qemu/error-report.h"
  49#include "qemu/help_option.h"
  50#include "qemu/log.h"
  51#include "qemu/main-loop.h"
  52#include "qemu/module.h"
  53#include "qemu/option.h"
  54#include "qom/object_interfaces.h"
  55
  56#include "storage-daemon/qapi/qapi-commands.h"
  57#include "storage-daemon/qapi/qapi-init-commands.h"
  58
  59#include "sysemu/runstate.h"
  60#include "trace/control.h"
  61
  62static const char *pid_file;
  63static volatile bool exit_requested = false;
  64
  65void qemu_system_killed(int signal, pid_t pid)
  66{
  67    exit_requested = true;
  68}
  69
  70void qmp_quit(Error **errp)
  71{
  72    exit_requested = true;
  73}
  74
  75static void help(void)
  76{
  77    printf(
  78"Usage: %s [options]\n"
  79"QEMU storage daemon\n"
  80"\n"
  81"  -h, --help             display this help and exit\n"
  82"  -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
  83"                         specify tracing options\n"
  84"  -V, --version          output version information and exit\n"
  85"\n"
  86"  --blockdev [driver=]<driver>[,node-name=<N>][,discard=ignore|unmap]\n"
  87"             [,cache.direct=on|off][,cache.no-flush=on|off]\n"
  88"             [,read-only=on|off][,auto-read-only=on|off]\n"
  89"             [,force-share=on|off][,detect-zeroes=on|off|unmap]\n"
  90"             [,driver specific parameters...]\n"
  91"                         configure a block backend\n"
  92"\n"
  93"  --chardev <options>    configure a character device backend\n"
  94"                         (see the qemu(1) man page for possible options)\n"
  95"\n"
  96"  --export [type=]nbd,id=<id>,node-name=<node-name>[,name=<export-name>]\n"
  97"           [,writable=on|off][,bitmap=<name>]\n"
  98"                         export the specified block node over NBD\n"
  99"                         (requires --nbd-server)\n"
 100"\n"
 101"  --export [type=]fuse,id=<id>,node-name=<node-name>,mountpoint=<file>\n"
 102"           [,growable=on|off][,writable=on|off]\n"
 103"                         export the specified block node over FUSE\n"
 104"\n"
 105"  --monitor [chardev=]name[,mode=control][,pretty[=on|off]]\n"
 106"                         configure a QMP monitor\n"
 107"\n"
 108"  --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>\n"
 109"               [,tls-creds=<id>][,tls-authz=<id>][,max-connections=<n>]\n"
 110"  --nbd-server addr.type=unix,addr.path=<path>\n"
 111"               [,tls-creds=<id>][,tls-authz=<id>][,max-connections=<n>]\n"
 112"                         start an NBD server for exporting block nodes\n"
 113"\n"
 114"  --object help          list object types that can be added\n"
 115"  --object <type>,help   list properties for the given object type\n"
 116"  --object <type>[,<property>=<value>...]\n"
 117"                         create a new object of type <type>, setting\n"
 118"                         properties in the order they are specified. Note\n"
 119"                         that the 'id' property must be set.\n"
 120"                         See the qemu(1) man page for documentation of the\n"
 121"                         objects that can be added.\n"
 122"\n"
 123"  --pidfile <path>       write process ID to a file after startup\n"
 124"\n"
 125QEMU_HELP_BOTTOM "\n",
 126    error_get_progname());
 127}
 128
 129enum {
 130    OPTION_BLOCKDEV = 256,
 131    OPTION_CHARDEV,
 132    OPTION_EXPORT,
 133    OPTION_MONITOR,
 134    OPTION_NBD_SERVER,
 135    OPTION_OBJECT,
 136    OPTION_PIDFILE,
 137};
 138
 139extern QemuOptsList qemu_chardev_opts;
 140
 141static void init_qmp_commands(void)
 142{
 143    qmp_init_marshal(&qmp_commands);
 144
 145    QTAILQ_INIT(&qmp_cap_negotiation_commands);
 146    qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
 147                         qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG);
 148}
 149
 150static int getopt_set_loc(int argc, char **argv, const char *optstring,
 151                          const struct option *longopts)
 152{
 153    int c, save_index;
 154
 155    optarg = NULL;
 156    save_index = optind;
 157    c = getopt_long(argc, argv, optstring, longopts, NULL);
 158    if (optarg) {
 159        loc_set_cmdline(argv, save_index, MAX(1, optind - save_index));
 160    }
 161    return c;
 162}
 163
 164static void process_options(int argc, char *argv[])
 165{
 166    int c;
 167
 168    static const struct option long_options[] = {
 169        {"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
 170        {"chardev", required_argument, NULL, OPTION_CHARDEV},
 171        {"export", required_argument, NULL, OPTION_EXPORT},
 172        {"help", no_argument, NULL, 'h'},
 173        {"monitor", required_argument, NULL, OPTION_MONITOR},
 174        {"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
 175        {"object", required_argument, NULL, OPTION_OBJECT},
 176        {"pidfile", required_argument, NULL, OPTION_PIDFILE},
 177        {"trace", required_argument, NULL, 'T'},
 178        {"version", no_argument, NULL, 'V'},
 179        {0, 0, 0, 0}
 180    };
 181
 182    /*
 183     * In contrast to the system emulator, options are processed in the order
 184     * they are given on the command lines. This means that things must be
 185     * defined first before they can be referenced in another option.
 186     */
 187    while ((c = getopt_set_loc(argc, argv, "-hT:V", long_options)) != -1) {
 188        switch (c) {
 189        case '?':
 190            exit(EXIT_FAILURE);
 191        case 'h':
 192            help();
 193            exit(EXIT_SUCCESS);
 194        case 'T':
 195            trace_opt_parse(optarg);
 196            trace_init_file();
 197            break;
 198        case 'V':
 199            printf("qemu-storage-daemon version "
 200                   QEMU_FULL_VERSION "\n" QEMU_COPYRIGHT "\n");
 201            exit(EXIT_SUCCESS);
 202        case OPTION_BLOCKDEV:
 203            {
 204                Visitor *v;
 205                BlockdevOptions *options;
 206
 207                v = qobject_input_visitor_new_str(optarg, "driver",
 208                                                  &error_fatal);
 209
 210                visit_type_BlockdevOptions(v, NULL, &options, &error_fatal);
 211                visit_free(v);
 212
 213                qmp_blockdev_add(options, &error_fatal);
 214                qapi_free_BlockdevOptions(options);
 215                break;
 216            }
 217        case OPTION_CHARDEV:
 218            {
 219                /* TODO This interface is not stable until we QAPIfy it */
 220                QemuOpts *opts = qemu_opts_parse_noisily(&qemu_chardev_opts,
 221                                                         optarg, true);
 222                if (opts == NULL) {
 223                    exit(EXIT_FAILURE);
 224                }
 225
 226                if (!qemu_chr_new_from_opts(opts, NULL, &error_fatal)) {
 227                    /* No error, but NULL returned means help was printed */
 228                    exit(EXIT_SUCCESS);
 229                }
 230                qemu_opts_del(opts);
 231                break;
 232            }
 233        case OPTION_EXPORT:
 234            {
 235                Visitor *v;
 236                BlockExportOptions *export;
 237
 238                v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
 239                visit_type_BlockExportOptions(v, NULL, &export, &error_fatal);
 240                visit_free(v);
 241
 242                qmp_block_export_add(export, &error_fatal);
 243                qapi_free_BlockExportOptions(export);
 244                break;
 245            }
 246        case OPTION_MONITOR:
 247            {
 248                Visitor *v;
 249                MonitorOptions *monitor;
 250
 251                v = qobject_input_visitor_new_str(optarg, "chardev",
 252                                                  &error_fatal);
 253                visit_type_MonitorOptions(v, NULL, &monitor, &error_fatal);
 254                visit_free(v);
 255
 256                /* TODO Catch duplicate monitor IDs */
 257                monitor_init(monitor, false, &error_fatal);
 258                qapi_free_MonitorOptions(monitor);
 259                break;
 260            }
 261        case OPTION_NBD_SERVER:
 262            {
 263                Visitor *v;
 264                NbdServerOptions *options;
 265
 266                v = qobject_input_visitor_new_str(optarg, NULL, &error_fatal);
 267                visit_type_NbdServerOptions(v, NULL, &options, &error_fatal);
 268                visit_free(v);
 269
 270                nbd_server_start_options(options, &error_fatal);
 271                qapi_free_NbdServerOptions(options);
 272                break;
 273            }
 274        case OPTION_OBJECT:
 275            user_creatable_process_cmdline(optarg);
 276            break;
 277        case OPTION_PIDFILE:
 278            pid_file = optarg;
 279            break;
 280        case 1:
 281            error_report("Unexpected argument");
 282            exit(EXIT_FAILURE);
 283        default:
 284            g_assert_not_reached();
 285        }
 286    }
 287    loc_set_none();
 288}
 289
 290static void pid_file_cleanup(void)
 291{
 292    unlink(pid_file);
 293}
 294
 295static void pid_file_init(void)
 296{
 297    Error *err = NULL;
 298
 299    if (!pid_file) {
 300        return;
 301    }
 302
 303    if (!qemu_write_pidfile(pid_file, &err)) {
 304        error_reportf_err(err, "cannot create PID file: ");
 305        exit(EXIT_FAILURE);
 306    }
 307
 308    atexit(pid_file_cleanup);
 309}
 310
 311int main(int argc, char *argv[])
 312{
 313#ifdef CONFIG_POSIX
 314    signal(SIGPIPE, SIG_IGN);
 315#endif
 316
 317    error_init(argv[0]);
 318    qemu_init_exec_dir(argv[0]);
 319    os_setup_signal_handling();
 320
 321    module_call_init(MODULE_INIT_QOM);
 322    module_call_init(MODULE_INIT_TRACE);
 323    qemu_add_opts(&qemu_trace_opts);
 324    qcrypto_init(&error_fatal);
 325    bdrv_init();
 326    monitor_init_globals_core();
 327    init_qmp_commands();
 328
 329    if (!trace_init_backends()) {
 330        return EXIT_FAILURE;
 331    }
 332    qemu_set_log(LOG_TRACE);
 333
 334    qemu_init_main_loop(&error_fatal);
 335    process_options(argc, argv);
 336
 337    /*
 338     * Write the pid file after creating chardevs, exports, and NBD servers but
 339     * before accepting connections. This ordering is documented. Do not change
 340     * it.
 341     */
 342    pid_file_init();
 343
 344    while (!exit_requested) {
 345        main_loop_wait(false);
 346    }
 347
 348    blk_exp_close_all();
 349    bdrv_drain_all_begin();
 350    job_cancel_sync_all();
 351    bdrv_close_all();
 352
 353    monitor_cleanup();
 354    qemu_chr_cleanup();
 355    user_creatable_cleanup();
 356
 357    return EXIT_SUCCESS;
 358}
 359