libvirtd.c 46.1 KB
Newer Older
D
Daniel P. Berrange 已提交
1
/*
D
Daniel P. Berrange 已提交
2
 * libvirtd.c: daemon start of day, guest process & i/o management
D
Daniel P. Berrange 已提交
3
 *
4
 * Copyright (C) 2006-2011 Red Hat, Inc.
D
Daniel P. Berrange 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * Copyright (C) 2006 Daniel P. Berrange
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

24
#include <config.h>
25

D
Daniel P. Berrange 已提交
26 27
#include <unistd.h>
#include <fcntl.h>
28 29
#include <sys/wait.h>
#include <sys/stat.h>
D
Daniel P. Berrange 已提交
30
#include <getopt.h>
31
#include <stdlib.h>
32
#include <grp.h>
E
Eric Blake 已提交
33
#include <locale.h>
34

35
#include "libvirt_internal.h"
36
#include "virterror_internal.h"
E
Eric Blake 已提交
37
#include "virfile.h"
38
#include "virpidfile.h"
39

40 41
#define VIR_FROM_THIS VIR_FROM_QEMU

D
Daniel P. Berrange 已提交
42
#include "libvirtd.h"
43

44
#include "util.h"
45
#include "uuid.h"
46
#include "remote_driver.h"
47
#include "conf.h"
48
#include "memory.h"
49 50 51 52 53
#include "conf.h"
#include "virnetserver.h"
#include "threads.h"
#include "remote.h"
#include "remote_driver.h"
54
#include "hooks.h"
55
#include "uuid.h"
56
#include "viraudit.h"
D
Daniel P. Berrange 已提交
57

58
#ifdef WITH_DRIVER_MODULES
59
# include "driver.h"
60
#else
61 62 63 64 65 66
# ifdef WITH_QEMU
#  include "qemu/qemu_driver.h"
# endif
# ifdef WITH_LXC
#  include "lxc/lxc_driver.h"
# endif
J
Jim Fehlig 已提交
67 68 69
# ifdef WITH_LIBXL
#  include "libxl/libxl_driver.h"
# endif
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
# ifdef WITH_UML
#  include "uml/uml_driver.h"
# endif
# ifdef WITH_NETWORK
#  include "network/bridge_driver.h"
# endif
# ifdef WITH_NETCF
#  include "interface/netcf_driver.h"
# endif
# ifdef WITH_STORAGE_DIR
#  include "storage/storage_driver.h"
# endif
# ifdef WITH_NODE_DEVICES
#  include "node_device/node_device_driver.h"
# endif
# ifdef WITH_SECRETS
#  include "secret/secret_driver.h"
# endif
88 89 90
# ifdef WITH_NWFILTER
#  include "nwfilter/nwfilter_driver.h"
# endif
91
#endif
92

93 94
#include "configmake.h"

95
#if HAVE_SASL
96
virNetSASLContextPtr saslCtxt = NULL;
97
#endif
98 99
virNetServerProgramPtr remoteProgram = NULL;
virNetServerProgramPtr qemuProgram = NULL;
100

101 102
struct daemonConfig {
    char *host_uuid;
103

104 105 106 107 108
    int listen_tls;
    int listen_tcp;
    char *listen_addr;
    char *tls_port;
    char *tcp_port;
109

110 111 112 113
    char *unix_sock_ro_perms;
    char *unix_sock_rw_perms;
    char *unix_sock_group;
    char *unix_sock_dir;
114

115 116 117 118
    int auth_unix_rw;
    int auth_unix_ro;
    int auth_tcp;
    int auth_tls;
119

120 121
    int mdns_adv;
    char *mdns_name;
122

123
    int tls_no_verify_certificate;
124
    int tls_no_sanity_certificate;
125 126
    char **tls_allowed_dn_list;
    char **sasl_allowed_username_list;
127

128 129 130 131
    char *key_file;
    char *cert_file;
    char *ca_file;
    char *crl_file;
132

133 134 135
    int min_workers;
    int max_workers;
    int max_clients;
136

137 138
    int prio_workers;

139 140
    int max_requests;
    int max_client_requests;
141

142 143 144 145
    int log_level;
    char *log_filters;
    char *log_outputs;
    int log_buffer_size;
146

147 148 149
    int audit_level;
    int audit_logging;
};
150

151 152 153 154 155 156 157 158 159
enum {
    VIR_DAEMON_ERR_NONE = 0,
    VIR_DAEMON_ERR_PIDFILE,
    VIR_DAEMON_ERR_RUNDIR,
    VIR_DAEMON_ERR_INIT,
    VIR_DAEMON_ERR_SIGNAL,
    VIR_DAEMON_ERR_PRIVS,
    VIR_DAEMON_ERR_NETWORK,
    VIR_DAEMON_ERR_CONFIG,
160
    VIR_DAEMON_ERR_HOOKS,
161
    VIR_DAEMON_ERR_AUDIT,
162 163 164 165 166 167 168 169 170 171 172 173 174

    VIR_DAEMON_ERR_LAST
};

VIR_ENUM_DECL(virDaemonErr)
VIR_ENUM_IMPL(virDaemonErr, VIR_DAEMON_ERR_LAST,
              "Initialization successful",
              "Unable to obtain pidfile",
              "Unable to create rundir",
              "Unable to initialize libvirt",
              "Unable to setup signal handlers",
              "Unable to drop privileges",
              "Unable to initialize network sockets",
175
              "Unable to load configuration file",
176 177
              "Unable to look for hook scripts",
              "Unable to initialize audit system")
178

179
static int daemonForkIntoBackground(const char *argv0)
180
{
181 182 183 184
    int statuspipe[2];
    if (pipe(statuspipe) < 0)
        return -1;

D
Daniel P. Berrange 已提交
185 186 187 188 189 190
    int pid = fork();
    switch (pid) {
    case 0:
        {
            int stdinfd = -1;
            int stdoutfd = -1;
191
            int nextpid;
D
Daniel P. Berrange 已提交
192

193
            VIR_FORCE_CLOSE(statuspipe[0]);
194

195
            if ((stdinfd = open("/dev/null", O_RDONLY)) < 0)
D
Daniel P. Berrange 已提交
196
                goto cleanup;
197
            if ((stdoutfd = open("/dev/null", O_WRONLY)) < 0)
D
Daniel P. Berrange 已提交
198 199 200 201 202 203 204
                goto cleanup;
            if (dup2(stdinfd, STDIN_FILENO) != STDIN_FILENO)
                goto cleanup;
            if (dup2(stdoutfd, STDOUT_FILENO) != STDOUT_FILENO)
                goto cleanup;
            if (dup2(stdoutfd, STDERR_FILENO) != STDERR_FILENO)
                goto cleanup;
205
            if (VIR_CLOSE(stdinfd) < 0)
D
Daniel P. Berrange 已提交
206
                goto cleanup;
207
            if (VIR_CLOSE(stdoutfd) < 0)
D
Daniel P. Berrange 已提交
208 209 210 211 212 213 214 215
                goto cleanup;

            if (setsid() < 0)
                goto cleanup;

            nextpid = fork();
            switch (nextpid) {
            case 0:
216
                return statuspipe[1];
D
Daniel P. Berrange 已提交
217 218 219
            case -1:
                return -1;
            default:
220
                _exit(0);
D
Daniel P. Berrange 已提交
221 222 223
            }

        cleanup:
224 225
            VIR_FORCE_CLOSE(stdoutfd);
            VIR_FORCE_CLOSE(stdinfd);
D
Daniel P. Berrange 已提交
226 227 228 229 230 231 232 233 234
            return -1;

        }

    case -1:
        return -1;

    default:
        {
235 236 237 238
            int got, exitstatus = 0;
            int ret;
            char status;

239
            VIR_FORCE_CLOSE(statuspipe[1]);
240 241 242

            /* We wait to make sure the first child forked successfully */
            if ((got = waitpid(pid, &exitstatus, 0)) < 0 ||
D
Daniel P. Berrange 已提交
243
                got != pid ||
244
                exitstatus != 0) {
D
Daniel P. Berrange 已提交
245 246
                return -1;
            }
247 248 249 250 251 252 253 254

            /* Now block until the second child initializes successfully */
        again:
            ret = read(statuspipe[0], &status, 1);
            if (ret == -1 && errno == EINTR)
                goto again;

            if (ret == 1 && status != 0) {
255
                fprintf(stderr,
256 257
                        _("%s: error: %s. Check /var/log/messages or run without "
                          "--daemon for more info.\n"), argv0,
258
                        virDaemonErrTypeToString(status));
259 260
            }
            _exit(ret == 1 && status == 0 ? 0 : 1);
D
Daniel P. Berrange 已提交
261 262 263 264
        }
    }
}

265 266

static int
267 268
daemonPidFilePath(bool privileged,
                  char **pidfile)
269
{
270 271 272 273 274
    if (privileged) {
        if (!(*pidfile = strdup(LOCALSTATEDIR "/run/libvirtd.pid")))
            goto no_memory;
    } else {
        char *userdir = NULL;
275

276 277
        if (!(userdir = virGetUserDirectory(geteuid())))
            goto error;
278

E
Eric Blake 已提交
279 280
        if (virAsprintf(pidfile, "%s/.libvirt/libvirtd.pid", userdir) < 0) {
            VIR_FREE(userdir);
281
            goto no_memory;
E
Eric Blake 已提交
282
        }
283

284
        VIR_FREE(userdir);
285 286 287
    }

    return 0;
288

289 290 291
no_memory:
    virReportOOMError();
error:
292
    return -1;
293 294
}

295 296 297 298 299
static int
daemonUnixSocketPaths(struct daemonConfig *config,
                      bool privileged,
                      char **sockfile,
                      char **rosockfile)
J
John Levon 已提交
300
{
301 302
    if (config->unix_sock_dir) {
        if (virAsprintf(sockfile, "%s/libvirt-sock", config->unix_sock_dir) < 0)
303
            goto no_memory;
304 305
        if (privileged &&
            virAsprintf(rosockfile, "%s/libvirt-sock-ro", config->unix_sock_dir) < 0)
306
            goto no_memory;
D
Daniel P. Berrange 已提交
307
    } else {
308 309
        if (privileged) {
            if (!(*sockfile = strdup(LOCALSTATEDIR "/run/libvirt/libvirt-sock")))
310
                goto no_memory;
311
            if (!(*rosockfile = strdup(LOCALSTATEDIR "/run/libvirt/libvirt-sock-ro")))
312
                goto no_memory;
313 314
        } else {
            char *userdir = NULL;
315

316 317
            if (!(userdir = virGetUserDirectory(geteuid())))
                goto error;
318

319 320 321 322
            if (virAsprintf(sockfile, "@%s/.libvirt/libvirt-sock", userdir) < 0) {
                VIR_FREE(userdir);
                goto no_memory;
            }
323

324 325 326 327
            VIR_FREE(userdir);
        }
    }
    return 0;
328

329
no_memory:
330 331 332
    virReportOOMError();
error:
    return -1;
D
Daniel P. Berrange 已提交
333 334
}

335 336 337

static void daemonErrorHandler(void *opaque ATTRIBUTE_UNUSED,
                               virErrorPtr err ATTRIBUTE_UNUSED)
338 339 340 341 342
{
    /* Don't do anything, since logging infrastructure already
     * took care of reporting the error */
}

343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
static int daemonErrorLogFilter(virErrorPtr err, int priority)
{
    /* These error codes don't really reflect real errors. They
     * are expected events that occur when an app tries to check
     * whether a particular guest already exists. This filters
     * them to a lower log level to prevent pollution of syslog
     */
    switch (err->code) {
    case VIR_ERR_NO_DOMAIN:
    case VIR_ERR_NO_NETWORK:
    case VIR_ERR_NO_STORAGE_POOL:
    case VIR_ERR_NO_STORAGE_VOL:
    case VIR_ERR_NO_NODE_DEVICE:
    case VIR_ERR_NO_INTERFACE:
    case VIR_ERR_NO_NWFILTER:
    case VIR_ERR_NO_SECRET:
    case VIR_ERR_NO_DOMAIN_SNAPSHOT:
        return VIR_LOG_DEBUG;
    }

    return priority;
}

366 367
static void daemonInitialize(void)
{
368 369 370 371 372 373 374
    /*
     * Note that the order is important: the first ones have a higher
     * priority when calling virStateInitialize. We must register
     * the network, storage and nodedev drivers before any domain
     * drivers, since their resources must be auto-started before
     * any domains can be auto-started.
     */
375 376 377
#ifdef WITH_DRIVER_MODULES
    /* We don't care if any of these fail, because the whole point
     * is to allow users to only install modules they want to use.
D
Dan Kenigsberg 已提交
378
     * If they try to open a connection for a module that
379 380 381 382
     * is not loaded they'll get a suitable error at that point
     */
    virDriverLoadModule("network");
    virDriverLoadModule("storage");
383
    virDriverLoadModule("nodedev");
384
    virDriverLoadModule("secret");
385 386 387
    virDriverLoadModule("qemu");
    virDriverLoadModule("lxc");
    virDriverLoadModule("uml");
388
    virDriverLoadModule("nwfilter");
389
#else
390
# ifdef WITH_NETWORK
391
    networkRegister();
392 393
# endif
# ifdef WITH_NETCF
394
    interfaceRegister();
395 396
# endif
# ifdef WITH_STORAGE_DIR
397
    storageRegister();
398 399
# endif
# if defined(WITH_NODE_DEVICES)
400
    nodedevRegister();
401 402
# endif
# ifdef WITH_SECRETS
403
    secretRegister();
404
# endif
405 406 407
# ifdef WITH_NWFILTER
    nwfilterRegister();
# endif
J
Jim Fehlig 已提交
408 409 410
# ifdef WITH_LIBXL
    libxlRegister();
# endif
411
# ifdef WITH_QEMU
412
    qemuRegister();
413 414
# endif
# ifdef WITH_LXC
415
    lxcRegister();
416 417
# endif
# ifdef WITH_UML
418
    umlRegister();
419
# endif
420
#endif
421 422 423
}


424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
static int daemonSetupNetworking(virNetServerPtr srv,
                                 struct daemonConfig *config,
                                 const char *sock_path,
                                 const char *sock_path_ro,
                                 bool ipsock,
                                 bool privileged)
{
    virNetServerServicePtr svc = NULL;
    virNetServerServicePtr svcRO = NULL;
    virNetServerServicePtr svcTCP = NULL;
    virNetServerServicePtr svcTLS = NULL;
    gid_t unix_sock_gid = 0;
    int unix_sock_ro_mask = 0;
    int unix_sock_rw_mask = 0;

    if (config->unix_sock_group) {
        if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0)
            return -1;
    }
443

444 445 446 447
    if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms);
        goto error;
    }
448

449 450 451 452
    if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms);
        goto error;
    }
453

454 455 456 457 458
    if (!(svc = virNetServerServiceNewUNIX(sock_path,
                                           unix_sock_rw_mask,
                                           unix_sock_gid,
                                           config->auth_unix_rw,
                                           false,
459
                                           config->max_client_requests,
460 461 462 463 464 465 466 467
                                           NULL)))
        goto error;
    if (sock_path_ro &&
        !(svcRO = virNetServerServiceNewUNIX(sock_path_ro,
                                             unix_sock_ro_mask,
                                             unix_sock_gid,
                                             config->auth_unix_ro,
                                             true,
468
                                             config->max_client_requests,
469 470
                                             NULL)))
        goto error;
471

472 473 474 475 476
    if (virNetServerAddService(srv, svc, NULL) < 0)
        goto error;
    if (svcRO &&
        virNetServerAddService(srv, svcRO, NULL) < 0)
        goto error;
477

478
    if (ipsock) {
479 480 481 482 483
        if (config->listen_tcp) {
            if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr,
                                                     config->tcp_port,
                                                     config->auth_tcp,
                                                     false,
484
                                                     config->max_client_requests,
485 486
                                                     NULL)))
                goto error;
487

488 489 490
            if (virNetServerAddService(srv, svcTCP,
                                       config->mdns_adv ? "_libvirt._tcp" : NULL) < 0)
                goto error;
491 492
        }

493 494
        if (config->listen_tls) {
            virNetTLSContextPtr ctxt = NULL;
495

496 497 498 499 500 501 502 503
            if (config->ca_file ||
                config->cert_file ||
                config->key_file) {
                if (!(ctxt = virNetTLSContextNewServer(config->ca_file,
                                                       config->crl_file,
                                                       config->cert_file,
                                                       config->key_file,
                                                       (const char *const*)config->tls_allowed_dn_list,
504
                                                       config->tls_no_sanity_certificate ? false : true,
505 506 507 508 509 510
                                                       config->tls_no_verify_certificate ? false : true)))
                    goto error;
            } else {
                if (!(ctxt = virNetTLSContextNewServerPath(NULL,
                                                           !privileged,
                                                           (const char *const*)config->tls_allowed_dn_list,
511
                                                           config->tls_no_sanity_certificate ? false : true,
512 513
                                                           config->tls_no_verify_certificate ? false : true)))
                    goto error;
514 515
            }

516 517 518 519 520
            if (!(svcTLS =
                  virNetServerServiceNewTCP(config->listen_addr,
                                            config->tls_port,
                                            config->auth_tls,
                                            false,
521
                                            config->max_client_requests,
522 523 524
                                            ctxt))) {
                virNetTLSContextFree(ctxt);
                goto error;
525
            }
526 527 528 529
            if (virNetServerAddService(srv, svcTLS,
                                       config->mdns_adv &&
                                       !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0)
                goto error;
530

531
            virNetTLSContextFree(ctxt);
532 533 534
        }
    }

535
#if HAVE_SASL
536 537 538 539 540 541 542
    if (config->auth_unix_rw == REMOTE_AUTH_SASL ||
        config->auth_unix_ro == REMOTE_AUTH_SASL ||
        config->auth_tcp == REMOTE_AUTH_SASL ||
        config->auth_tls == REMOTE_AUTH_SASL) {
        saslCtxt = virNetSASLContextNewServer(
            (const char *const*)config->sasl_allowed_username_list);
        if (!saslCtxt)
543
            goto error;
D
Daniel P. Berrange 已提交
544
    }
545
#endif
D
Daniel P. Berrange 已提交
546 547

    return 0;
548

549
error:
550 551 552 553
    virNetServerServiceFree(svcTLS);
    virNetServerServiceFree(svcTCP);
    virNetServerServiceFree(svc);
    virNetServerServiceFree(svcRO);
554
    return -1;
D
Daniel P. Berrange 已提交
555 556 557
}


558 559
static int daemonShutdownCheck(virNetServerPtr srv ATTRIBUTE_UNUSED,
                               void *opaque ATTRIBUTE_UNUSED)
E
Eric Blake 已提交
560
{
561 562
    if (virStateActive())
        return 0;
563

564
    return 1;
D
Daniel P. Berrange 已提交
565 566
}

567

568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
/* Allocate an array of malloc'd strings from the config file, filename
 * (used only in diagnostics), using handle "conf".  Upon error, return -1
 * and free any allocated memory.  Otherwise, save the array in *list_arg
 * and return 0.
 */
static int
remoteConfigGetStringList(virConfPtr conf, const char *key, char ***list_arg,
                          const char *filename)
{
    char **list;
    virConfValuePtr p = virConfGetValue (conf, key);
    if (!p)
        return 0;

    switch (p->type) {
    case VIR_CONF_STRING:
584
        if (VIR_ALLOC_N(list, 2) < 0) {
585
            VIR_ERROR(_("failed to allocate memory for %s config list"), key);
586 587 588 589 590
            return -1;
        }
        list[0] = strdup (p->str);
        list[1] = NULL;
        if (list[0] == NULL) {
591
            VIR_ERROR(_("failed to allocate memory for %s config list value"),
592
                      key);
593
            VIR_FREE(list);
594 595 596 597 598 599 600 601 602
            return -1;
        }
        break;

    case VIR_CONF_LIST: {
        int i, len = 0;
        virConfValuePtr pp;
        for (pp = p->list; pp; pp = pp->next)
            len++;
603
        if (VIR_ALLOC_N(list, 1+len) < 0) {
604
            VIR_ERROR(_("failed to allocate memory for %s config list"), key);
605 606 607 608
            return -1;
        }
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
            if (pp->type != VIR_CONF_STRING) {
609
                VIR_ERROR(_("remoteReadConfigFile: %s: %s:"
610
                            " must be a string or list of strings"),
611
                          filename, key);
612
                VIR_FREE(list);
613 614 615 616 617 618
                return -1;
            }
            list[i] = strdup (pp->str);
            if (list[i] == NULL) {
                int j;
                for (j = 0 ; j < i ; j++)
619 620
                    VIR_FREE(list[j]);
                VIR_FREE(list);
621 622
                VIR_ERROR(_("failed to allocate memory for %s config list value"),
                          key);
623 624 625 626 627 628 629 630 631
                return -1;
            }

        }
        list[i] = NULL;
        break;
    }

    default:
632
        VIR_ERROR(_("remoteReadConfigFile: %s: %s:"
633
                    " must be a string or list of strings"),
634 635 636 637 638 639 640 641 642 643 644 645 646 647
                  filename, key);
        return -1;
    }

    *list_arg = list;
    return 0;
}

/* A helper function used by each of the following macros.  */
static int
checkType (virConfValuePtr p, const char *filename,
           const char *key, virConfType required_type)
{
    if (p->type != required_type) {
648
        VIR_ERROR(_("remoteReadConfigFile: %s: %s: invalid type:"
649
                    " got %s; expected %s"), filename, key,
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
                  virConfTypeName (p->type),
                  virConfTypeName (required_type));
        return -1;
    }
    return 0;
}

/* If there is no config data for the key, #var_name, then do nothing.
   If there is valid data of type VIR_CONF_STRING, and strdup succeeds,
   store the result in var_name.  Otherwise, (i.e. invalid type, or strdup
   failure), give a diagnostic and "goto" the cleanup-and-fail label.  */
#define GET_CONF_STR(conf, filename, var_name)                          \
    do {                                                                \
        virConfValuePtr p = virConfGetValue (conf, #var_name);          \
        if (p) {                                                        \
            if (checkType (p, filename, #var_name, VIR_CONF_STRING) < 0) \
666 667 668 669 670
                goto error;                                             \
            VIR_FREE(data->var_name);                                   \
            if (!(data->var_name = strdup (p->str))) {                  \
                virReportOOMError();                                    \
                goto error;                                             \
671 672 673 674 675 676 677 678 679 680
            }                                                           \
        }                                                               \
    } while (0)

/* Like GET_CONF_STR, but for integral values.  */
#define GET_CONF_INT(conf, filename, var_name)                          \
    do {                                                                \
        virConfValuePtr p = virConfGetValue (conf, #var_name);          \
        if (p) {                                                        \
            if (checkType (p, filename, #var_name, VIR_CONF_LONG) < 0)  \
681 682
                goto error;                                             \
            data->var_name = p->l;                                      \
683 684 685
        }                                                               \
    } while (0)

686 687 688 689 690 691 692 693

static int remoteConfigGetAuth(virConfPtr conf, const char *key, int *auth, const char *filename) {
    virConfValuePtr p;

    p = virConfGetValue (conf, key);
    if (!p)
        return 0;

694
    if (checkType (p, filename, key, VIR_CONF_STRING) < 0)
695 696 697 698 699 700
        return -1;

    if (!p->str)
        return 0;

    if (STREQ(p->str, "none")) {
701
        *auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
702
#if HAVE_SASL
703
    } else if (STREQ(p->str, "sasl")) {
704
        *auth = VIR_NET_SERVER_SERVICE_AUTH_SASL;
705
#endif
706
    } else if (STREQ(p->str, "polkit")) {
707
        *auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT;
708
    } else {
709
        VIR_ERROR(_("remoteReadConfigFile: %s: %s: unsupported auth %s"),
710
                  filename, key, p->str);
711 712 713 714 715 716
        return -1;
    }

    return 0;
}

717 718
/*
 * Set up the logging environment
719 720
 * By default if daemonized all errors go to the logfile libvirtd.log,
 * but if verbose or error debugging is asked for then also output
721
 * informational and debug messages. Default size if 64 kB.
722
 */
723
static int
724 725 726 727
daemonSetupLogging(struct daemonConfig *config,
                   bool privileged,
                   bool verbose,
                   bool godaemon)
728
{
729 730
    virLogReset();

731
    /*
732 733 734 735 736 737 738 739 740 741 742 743
     * Libvirtd's order of precedence is:
     * cmdline > environment > config
     *
     * In order to achieve this, we must process configuration in
     * different order for the log level versus the filters and
     * outputs. Because filters and outputs append, we have to look at
     * the environment first and then only check the config file if
     * there was no result from the environment. The default output is
     * then applied only if there was no setting from either of the
     * first two. Because we don't have a way to determine if the log
     * level has been set, we must process variables in the opposite
     * order, each one overriding the previous.
744
     */
745 746
    if (config->log_level != 0)
        virLogSetDefaultPriority(config->log_level);
747

748
    virLogSetFromEnv();
749

750
    virLogSetBufferSize(config->log_buffer_size);
751

752 753 754 755 756
    if (virLogGetNbFilters() == 0)
        virLogParseFilters(config->log_filters);

    if (virLogGetNbOutputs() == 0)
        virLogParseOutputs(config->log_outputs);
757 758

    /*
759
     * If no defined outputs, then direct to libvirtd.log when running
760
     * as daemon. Otherwise the default output is stderr.
761
     */
762
    if (virLogGetNbOutputs() == 0) {
763
        char *tmp = NULL;
764

765
        if (godaemon) {
766
            if (privileged) {
767 768 769
                if (virAsprintf(&tmp, "%d:file:%s/log/libvirt/libvirtd.log",
                                virLogGetDefaultPriority(),
                                LOCALSTATEDIR) == -1)
770
                    goto no_memory;
771 772 773
            } else {
                char *userdir = virGetUserDirectory(geteuid());
                if (!userdir)
774
                    goto error;
775 776

                if (virAsprintf(&tmp, "%d:file:%s/.libvirt/libvirtd.log",
E
Eric Blake 已提交
777 778
                                virLogGetDefaultPriority(), userdir) == -1) {
                    VIR_FREE(userdir);
779
                    goto no_memory;
E
Eric Blake 已提交
780
                }
E
Eric Blake 已提交
781
                VIR_FREE(userdir);
782
            }
783
        } else {
784
            if (virAsprintf(&tmp, "%d:stderr", virLogGetDefaultPriority()) < 0)
785
                goto no_memory;
786
        }
787 788
        virLogParseOutputs(tmp);
        VIR_FREE(tmp);
789
    }
790 791 792 793 794 795 796

    /*
     * Command line override for --verbose
     */
    if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO))
        virLogSetDefaultPriority(VIR_LOG_INFO);

797 798 799 800 801 802 803 804
    return 0;

no_memory:
    virReportOOMError();
error:
    return -1;
}

805

806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
static int
daemonConfigFilePath(bool privileged, char **configfile)
{
    if (privileged) {
        if (!(*configfile = strdup(SYSCONFDIR "/libvirt/libvirtd.conf")))
            goto no_memory;
    } else {
        char *userdir = NULL;

        if (!(userdir = virGetUserDirectory(geteuid())))
            goto error;

        if (virAsprintf(configfile, "%s/.libvirt/libvirtd.conf", userdir) < 0) {
            VIR_FREE(userdir);
            goto no_memory;
        }
        VIR_FREE(userdir);
    }

    return 0;
826

827
no_memory:
828
    virReportOOMError();
829 830
error:
    return -1;
831 832 833
}

static void
834 835 836
daemonConfigFree(struct daemonConfig *data);

static struct daemonConfig*
J
Jiri Denemark 已提交
837
daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
838
{
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890
    struct daemonConfig *data;
    char *localhost;
    int ret;

    if (VIR_ALLOC(data) < 0) {
        virReportOOMError();
        return NULL;
    }

    data->listen_tls = 1;
    data->listen_tcp = 0;

    if (!(data->tls_port = strdup(LIBVIRTD_TLS_PORT)))
        goto no_memory;
    if (!(data->tcp_port = strdup(LIBVIRTD_TCP_PORT)))
        goto no_memory;

    /* Only default to PolicyKit if running as root */
#if HAVE_POLKIT
    if (privileged) {
        data->auth_unix_rw = REMOTE_AUTH_POLKIT;
        data->auth_unix_ro = REMOTE_AUTH_POLKIT;
    } else {
#endif
        data->auth_unix_rw = REMOTE_AUTH_NONE;
        data->auth_unix_ro = REMOTE_AUTH_NONE;
#if HAVE_POLKIT
    }
#endif

    if (data->auth_unix_rw == REMOTE_AUTH_POLKIT)
        data->unix_sock_rw_perms = strdup("0777"); /* Allow world */
    else
        data->unix_sock_rw_perms = strdup("0700"); /* Allow user only */
    data->unix_sock_ro_perms = strdup("0777"); /* Always allow world */
    if (!data->unix_sock_ro_perms ||
        !data->unix_sock_rw_perms)
        goto no_memory;

#if HAVE_SASL
    data->auth_tcp = REMOTE_AUTH_SASL;
#else
    data->auth_tcp = REMOTE_AUTH_NONE;
#endif
    data->auth_tls = REMOTE_AUTH_NONE;

    data->mdns_adv = 1;

    data->min_workers = 5;
    data->max_workers = 20;
    data->max_clients = 20;

891 892
    data->prio_workers = 5;

893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968
    data->max_requests = 20;
    data->max_client_requests = 5;

    data->log_buffer_size = 64;

    data->audit_level = 1;
    data->audit_logging = 0;

    localhost = virGetHostname(NULL);
    if (localhost == NULL) {
        /* we couldn't resolve the hostname; assume that we are
         * running in disconnected operation, and report a less
         * useful Avahi string
         */
        ret = virAsprintf(&data->mdns_name, "Virtualization Host");
    } else {
        char *tmp;
        /* Extract the host part of the potentially FQDN */
        if ((tmp = strchr(localhost, '.')))
            *tmp = '\0';
        ret = virAsprintf(&data->mdns_name, "Virtualization Host %s",
                          localhost);
    }
    VIR_FREE(localhost);
    if (ret < 0)
        goto no_memory;

    return data;

no_memory:
    virReportOOMError();
    daemonConfigFree(data);
    return NULL;
}

static void
daemonConfigFree(struct daemonConfig *data)
{
    char **tmp;

    if (!data)
        return;

    VIR_FREE(data->listen_addr);
    VIR_FREE(data->tls_port);
    VIR_FREE(data->tcp_port);

    VIR_FREE(data->unix_sock_ro_perms);
    VIR_FREE(data->unix_sock_rw_perms);
    VIR_FREE(data->unix_sock_group);
    VIR_FREE(data->unix_sock_dir);
    VIR_FREE(data->mdns_name);

    tmp = data->tls_allowed_dn_list;
    while (tmp && *tmp) {
        VIR_FREE(*tmp);
        tmp++;
    }
    VIR_FREE(data->tls_allowed_dn_list);

    tmp = data->sasl_allowed_username_list;
    while (tmp && *tmp) {
        VIR_FREE(*tmp);
        tmp++;
    }
    VIR_FREE(data->sasl_allowed_username_list);

    VIR_FREE(data->key_file);
    VIR_FREE(data->ca_file);
    VIR_FREE(data->cert_file);
    VIR_FREE(data->crl_file);

    VIR_FREE(data->log_filters);
    VIR_FREE(data->log_outputs);

    VIR_FREE(data);
969
}
970

971

972 973 974 975
/* Read the config file if it exists.
 * Only used in the remote case, hence the name.
 */
static int
976
daemonConfigLoad(struct daemonConfig *data,
977 978
                 const char *filename,
                 bool allow_missing)
979 980 981
{
    virConfPtr conf;

982 983
    if (allow_missing &&
        access(filename, R_OK) == -1 &&
984 985 986
        errno == ENOENT)
        return 0;

987
    conf = virConfReadFile (filename, 0);
988 989
    if (!conf)
        return -1;
990

991 992
    GET_CONF_INT (conf, filename, listen_tcp);
    GET_CONF_INT (conf, filename, listen_tls);
993 994
    GET_CONF_STR (conf, filename, tls_port);
    GET_CONF_STR (conf, filename, tcp_port);
995
    GET_CONF_STR (conf, filename, listen_addr);
J
Jim Meyering 已提交
996

997 998
    if (remoteConfigGetAuth(conf, "auth_unix_rw", &data->auth_unix_rw, filename) < 0)
        goto error;
999 1000 1001 1002
#if HAVE_POLKIT
    /* Change default perms to be wide-open if PolicyKit is enabled.
     * Admin can always override in config file
     */
1003 1004
    if (data->auth_unix_rw == REMOTE_AUTH_POLKIT) {
        VIR_FREE(data->unix_sock_rw_perms);
J
Jiri Denemark 已提交
1005 1006 1007 1008
        if (!(data->unix_sock_rw_perms = strdup("0777"))) {
            virReportOOMError();
            goto error;
        }
1009
    }
1010
#endif
1011 1012 1013 1014 1015 1016
    if (remoteConfigGetAuth(conf, "auth_unix_ro", &data->auth_unix_ro, filename) < 0)
        goto error;
    if (remoteConfigGetAuth(conf, "auth_tcp", &data->auth_tcp, filename) < 0)
        goto error;
    if (remoteConfigGetAuth(conf, "auth_tls", &data->auth_tls, filename) < 0)
        goto error;
1017

1018 1019 1020
    GET_CONF_STR (conf, filename, unix_sock_group);
    GET_CONF_STR (conf, filename, unix_sock_ro_perms);
    GET_CONF_STR (conf, filename, unix_sock_rw_perms);
1021

1022 1023
    GET_CONF_STR (conf, filename, unix_sock_dir);

1024 1025
    GET_CONF_INT (conf, filename, mdns_adv);
    GET_CONF_STR (conf, filename, mdns_name);
1026

1027
    GET_CONF_INT (conf, filename, tls_no_sanity_certificate);
1028
    GET_CONF_INT (conf, filename, tls_no_verify_certificate);
1029

1030 1031 1032 1033
    GET_CONF_STR (conf, filename, key_file);
    GET_CONF_STR (conf, filename, cert_file);
    GET_CONF_STR (conf, filename, ca_file);
    GET_CONF_STR (conf, filename, crl_file);
1034

1035 1036 1037 1038
    if (remoteConfigGetStringList(conf, "tls_allowed_dn_list",
                                  &data->tls_allowed_dn_list, filename) < 0)
        goto error;

1039

1040 1041 1042
    if (remoteConfigGetStringList(conf, "sasl_allowed_username_list",
                                  &data->sasl_allowed_username_list, filename) < 0)
        goto error;
1043

1044 1045 1046 1047 1048

    GET_CONF_INT (conf, filename, min_workers);
    GET_CONF_INT (conf, filename, max_workers);
    GET_CONF_INT (conf, filename, max_clients);

1049 1050
    GET_CONF_INT (conf, filename, prio_workers);

1051 1052 1053
    GET_CONF_INT (conf, filename, max_requests);
    GET_CONF_INT (conf, filename, max_client_requests);

1054 1055 1056
    GET_CONF_INT (conf, filename, audit_level);
    GET_CONF_INT (conf, filename, audit_logging);

1057 1058
    GET_CONF_STR (conf, filename, host_uuid);

1059 1060 1061 1062
    GET_CONF_INT (conf, filename, log_level);
    GET_CONF_STR (conf, filename, log_filters);
    GET_CONF_STR (conf, filename, log_outputs);
    GET_CONF_INT (conf, filename, log_buffer_size);
1063

1064 1065
    virConfFree (conf);
    return 0;
1066

1067
error:
1068 1069
    virConfFree (conf);
    return -1;
1070 1071
}

1072 1073
/* Display version information. */
static void
1074
daemonVersion(const char *argv0)
1075 1076 1077 1078
{
    printf ("%s (%s) %s\n", argv0, PACKAGE_NAME, PACKAGE_VERSION);
}

J
John Levon 已提交
1079 1080
#ifdef __sun
static int
1081
daemonSetupPrivs(void)
J
John Levon 已提交
1082 1083 1084 1085 1086
{
    chown ("/var/run/libvirt", SYSTEM_UID, SYSTEM_UID);

    if (__init_daemon_priv (PU_RESETGROUPS | PU_CLEARLIMITSET,
        SYSTEM_UID, SYSTEM_UID, PRIV_XVM_CONTROL, NULL)) {
1087
        VIR_ERROR(_("additional privileges are required"));
J
John Levon 已提交
1088 1089 1090 1091 1092
        return -1;
    }

    if (priv_set (PRIV_OFF, PRIV_ALLSETS, PRIV_FILE_LINK_ANY, PRIV_PROC_INFO,
        PRIV_PROC_SESSION, PRIV_PROC_EXEC, PRIV_PROC_FORK, NULL)) {
1093
        VIR_ERROR(_("failed to set reduced privileges"));
J
John Levon 已提交
1094 1095 1096 1097 1098 1099
        return -1;
    }

    return 0;
}
#else
1100
# define daemonSetupPrivs() 0
J
John Levon 已提交
1101 1102
#endif

1103

1104 1105 1106
static void daemonShutdownHandler(virNetServerPtr srv,
                                  siginfo_t *sig ATTRIBUTE_UNUSED,
                                  void *opaque ATTRIBUTE_UNUSED)
1107
{
1108 1109
    virNetServerQuit(srv);
}
1110

1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
static void daemonReloadHandler(virNetServerPtr srv ATTRIBUTE_UNUSED,
                                siginfo_t *sig ATTRIBUTE_UNUSED,
                                void *opaque ATTRIBUTE_UNUSED)
{
        VIR_INFO("Reloading configuration on SIGHUP");
        virHookCall(VIR_HOOK_DRIVER_DAEMON, "-",
                    VIR_HOOK_DAEMON_OP_RELOAD, SIGHUP, "SIGHUP", NULL);
        if (virStateReload() < 0)
            VIR_WARN("Error while reloading drivers");
}

1122 1123 1124
static int daemonSetupSignals(virNetServerPtr srv)
{
    if (virNetServerAddSignalHandler(srv, SIGINT, daemonShutdownHandler, NULL) < 0)
1125
        return -1;
1126 1127 1128 1129
    if (virNetServerAddSignalHandler(srv, SIGQUIT, daemonShutdownHandler, NULL) < 0)
        return -1;
    if (virNetServerAddSignalHandler(srv, SIGTERM, daemonShutdownHandler, NULL) < 0)
        return -1;
1130 1131
    if (virNetServerAddSignalHandler(srv, SIGHUP, daemonReloadHandler, NULL) < 0)
        return -1;
1132 1133
    return 0;
}
1134

1135 1136 1137
static void daemonRunStateInit(void *opaque)
{
    virNetServerPtr srv = opaque;
1138

1139
    /* Start the stateful HV drivers
E
Eric Blake 已提交
1140
     * This is deliberately done after telling the parent process
1141 1142 1143 1144
     * we're ready, since it can take a long time and this will
     * seriously delay OS bootup process */
    if (virStateInitialize(virNetServerIsPrivileged(srv)) < 0) {
        VIR_ERROR(_("Driver state initialization failed"));
1145 1146
        /* Ensure the main event loop quits */
        kill(getpid(), SIGTERM);
1147 1148
        virNetServerFree(srv);
        return;
1149 1150
    }

1151 1152 1153 1154
    /* Only now accept clients from network */
    virNetServerUpdateServices(srv, true);
    virNetServerFree(srv);
}
1155

1156 1157 1158 1159 1160 1161 1162 1163
static int daemonStateInit(virNetServerPtr srv)
{
    virThread thr;
    virNetServerRef(srv);
    if (virThreadCreate(&thr, false, daemonRunStateInit, srv) < 0) {
        virNetServerFree(srv);
        return -1;
    }
1164 1165 1166
    return 0;
}

1167 1168
/* Print command-line usage. */
static void
1169
daemonUsage(const char *argv0, bool privileged)
1170 1171
{
    fprintf (stderr,
1172
             _("\n\
1173 1174 1175 1176 1177 1178
Usage:\n\
  %s [options]\n\
\n\
Options:\n\
  -v | --verbose         Verbose messages.\n\
  -d | --daemon          Run as a daemon & write PID file.\n\
1179 1180
  -l | --listen          Listen for TCP/IP connections.\n\
  -t | --timeout <secs>  Exit after timeout period.\n\
1181
  -f | --config <file>   Configuration file.\n\
1182
     | --version         Display version information.\n\
1183 1184
  -p | --pid-file <file> Change name of PID file.\n\
\n\
1185 1186 1187 1188 1189
libvirt management daemon:\n"), argv0);

    if (privileged) {
        fprintf(stderr,
                _("\n\
1190 1191
  Default paths:\n\
\n\
W
Wolfgang Mauerer 已提交
1192
    Configuration file (unless overridden by -f):\n\
1193
      %s/libvirt/libvirtd.conf\n\
1194
\n\
1195
    Sockets:\n\
1196 1197
      %s/run/libvirt/libvirt-sock\n\
      %s/run/libvirt/libvirt-sock-ro\n\
1198
\n\
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222
    TLS:\n\
      CA certificate:     %s/pki/CA/caert.pem\n\
      Server certificate: %s/pki/libvirt/servercert.pem\n\
      Server private key: %s/pki/libvirt/private/serverkey.pem\n\
\n\
    PID file (unless overridden by -p):\n\
      %s/run/libvirtd.pid\n\
\n"),
                SYSCONFDIR,
                LOCALSTATEDIR,
                LOCALSTATEDIR,
                SYSCONFDIR,
                SYSCONFDIR,
                SYSCONFDIR,
                LOCALSTATEDIR);
    } else {
        fprintf(stderr,
                "%s", _("\n\
  Default paths:\n\
\n\
    Configuration file (unless overridden by -f):\n\
      $HOME/.libvirt/libvirtd.conf\n\
\n\
    Sockets:\n\
1223
      $HOME/.libvirt/libvirt-sock (in UNIX abstract namespace)\n\
1224 1225
\n\
    TLS:\n\
1226 1227 1228
      CA certificate:     $HOME/.pki/libvirt/cacert.pem\n\
      Server certificate: $HOME/.pki/libvirt/servercert.pem\n\
      Server private key: $HOME/.pki/libvirt/serverkey.pem\n\
1229
\n\
1230 1231 1232 1233
    PID file:\n\
      $HOME/.libvirt/libvirtd.pid\n\
\n"));
    }
1234 1235
}

1236 1237 1238 1239
enum {
    OPT_VERSION = 129
};

D
Daniel P. Berrange 已提交
1240 1241
#define MAX_LISTEN 5
int main(int argc, char **argv) {
1242 1243
    virNetServerPtr srv = NULL;
    char *remote_config_file = NULL;
1244
    int statuswrite = -1;
1245
    int ret = 1;
1246
    int pid_file_fd = -1;
1247 1248 1249 1250 1251 1252 1253 1254 1255
    char *pid_file = NULL;
    char *sock_file = NULL;
    char *sock_file_ro = NULL;
    int timeout = -1;        /* -t: Shutdown timeout */
    int verbose = 0;
    int godaemon = 0;
    int ipsock = 0;
    struct daemonConfig *config;
    bool privileged = geteuid() == 0 ? true : false;
1256
    bool implicit_conf = false;
J
Jim Fehlig 已提交
1257
    bool use_polkit_dbus;
1258 1259
    char *run_dir = NULL;
    mode_t old_umask;
D
Daniel P. Berrange 已提交
1260 1261 1262 1263

    struct option opts[] = {
        { "verbose", no_argument, &verbose, 1},
        { "daemon", no_argument, &godaemon, 1},
1264
        { "listen", no_argument, &ipsock, 1},
1265
        { "config", required_argument, NULL, 'f'},
1266 1267
        { "timeout", required_argument, NULL, 't'},
        { "pid-file", required_argument, NULL, 'p'},
1268
        { "version", no_argument, NULL, OPT_VERSION },
1269
        { "help", no_argument, NULL, '?' },
D
Daniel P. Berrange 已提交
1270 1271 1272
        {0, 0, 0, 0}
    };

E
Eric Blake 已提交
1273 1274 1275 1276
    if (setlocale (LC_ALL, "") == NULL ||
        bindtextdomain (PACKAGE, LOCALEDIR) == NULL ||
        textdomain(PACKAGE) == NULL ||
        virInitialize() < 0) {
1277
        fprintf(stderr, _("%s: initialization failed\n"), argv[0]);
E
Eric Blake 已提交
1278
        exit(EXIT_FAILURE);
1279
    }
D
Daniel P. Berrange 已提交
1280

1281 1282 1283
    /* initialize early logging */
    virLogSetFromEnv();

D
Daniel P. Berrange 已提交
1284 1285 1286 1287 1288
    while (1) {
        int optidx = 0;
        int c;
        char *tmp;

1289
        c = getopt_long(argc, argv, "ldf:p:t:v", opts, &optidx);
D
Daniel P. Berrange 已提交
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304

        if (c == -1) {
            break;
        }

        switch (c) {
        case 0:
            /* Got one of the flags */
            break;
        case 'v':
            verbose = 1;
            break;
        case 'd':
            godaemon = 1;
            break;
1305 1306
        case 'l':
            ipsock = 1;
D
Daniel P. Berrange 已提交
1307 1308 1309
            break;

        case 't':
1310
            if (virStrToLong_i(optarg, &tmp, 10, &timeout) != 0
1311 1312 1313
                || timeout <= 0
                /* Ensure that we can multiply by 1000 without overflowing.  */
                || timeout > INT_MAX / 1000)
D
Daniel P. Berrange 已提交
1314 1315
                timeout = -1;
            break;
1316 1317

        case 'p':
1318
            VIR_FREE(pid_file);
1319 1320
            if (!(pid_file = strdup(optarg))) {
                VIR_ERROR(_("Can't allocate memory"));
1321
                exit(EXIT_FAILURE);
1322
            }
1323 1324 1325
            break;

        case 'f':
1326
            VIR_FREE(remote_config_file);
1327 1328
            if (!(remote_config_file = strdup(optarg))) {
                VIR_ERROR(_("Can't allocate memory"));
1329
                exit(EXIT_FAILURE);
1330
            }
1331 1332
            break;

1333
        case OPT_VERSION:
1334
            daemonVersion(argv[0]);
1335 1336
            return 0;

D
Daniel P. Berrange 已提交
1337
        case '?':
1338
            daemonUsage(argv[0], privileged);
D
Daniel P. Berrange 已提交
1339 1340 1341
            return 2;

        default:
1342 1343
            VIR_ERROR(_("%s: internal error: unknown flag: %c"),
                      argv[0], c);
1344
            exit (EXIT_FAILURE);
D
Daniel P. Berrange 已提交
1345 1346 1347
        }
    }

1348 1349
    if (!(config = daemonConfigNew(privileged))) {
        VIR_ERROR(_("Can't create initial configuration"));
1350
        exit(EXIT_FAILURE);
1351
    }
1352 1353

    /* No explicit config, so try and find a default one */
1354 1355 1356
    if (remote_config_file == NULL) {
        implicit_conf = true;
        if (daemonConfigFilePath(privileged,
1357 1358
                                 &remote_config_file) < 0) {
            VIR_ERROR(_("Can't determine config path"));
1359
            exit(EXIT_FAILURE);
1360
        }
1361
    }
1362 1363 1364

    /* Read the config file if it exists*/
    if (remote_config_file &&
1365 1366
        daemonConfigLoad(config, remote_config_file, implicit_conf) < 0) {
        VIR_ERROR(_("Can't load config file '%s'"), remote_config_file);
1367
        exit(EXIT_FAILURE);
1368
    }
1369 1370 1371 1372 1373

    if (config->host_uuid &&
        virSetHostUUIDStr(config->host_uuid) < 0) {
        VIR_ERROR(_("invalid host UUID: %s"), config->host_uuid);
        exit(EXIT_FAILURE);
1374 1375
    }

1376 1377
    if (daemonSetupLogging(config, privileged, verbose, godaemon) < 0) {
        VIR_ERROR(_("Can't initialize logging"));
1378
        exit(EXIT_FAILURE);
1379
    }
1380

1381
    if (!pid_file &&
1382
        daemonPidFilePath(privileged,
1383 1384
                          &pid_file) < 0) {
        VIR_ERROR(_("Can't determine pid file path."));
1385
        exit(EXIT_FAILURE);
1386
    }
1387 1388 1389 1390

    if (daemonUnixSocketPaths(config,
                              privileged,
                              &sock_file,
1391 1392
                              &sock_file_ro) < 0) {
        VIR_ERROR(_("Can't determine socket paths"));
1393
        exit(EXIT_FAILURE);
1394
    }
1395

1396
    if (godaemon) {
1397
        char ebuf[1024];
1398 1399 1400 1401

        if (chdir("/") < 0) {
            VIR_ERROR(_("cannot change to root directory: %s"),
                      virStrerror(errno, ebuf, sizeof(ebuf)));
1402
            goto cleanup;
1403 1404
        }

1405
        if ((statuswrite = daemonForkIntoBackground(argv[0])) < 0) {
1406 1407
            VIR_ERROR(_("Failed to fork as daemon: %s"),
                      virStrerror(errno, ebuf, sizeof ebuf));
1408
            goto cleanup;
1409 1410 1411
        }
    }

J
John Levon 已提交
1412
    /* Ensure the rundir exists (on tmpfs on some systems) */
1413
    if (privileged) {
1414 1415 1416 1417 1418 1419 1420
        run_dir = strdup(LOCALSTATEDIR "/run/libvirt");
    } else {
        char *user_dir = virGetUserDirectory(geteuid());

        if (!user_dir) {
            VIR_ERROR(_("Can't determine user directory"));
            goto cleanup;
J
John Levon 已提交
1421
        }
1422 1423
        ignore_value(virAsprintf(&run_dir, "%s/.libvirt/", user_dir));
        VIR_FREE(user_dir);
J
John Levon 已提交
1424
    }
1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438
    if (!run_dir) {
        virReportOOMError();
        goto cleanup;
    }

    old_umask = umask(022);
    if (virFileMakePath(run_dir) < 0) {
        char ebuf[1024];
        VIR_ERROR(_("unable to create rundir %s: %s"), run_dir,
                  virStrerror(errno, ebuf, sizeof(ebuf)));
        ret = VIR_DAEMON_ERR_RUNDIR;
        goto cleanup;
    }
    umask(old_umask);
J
John Levon 已提交
1439

1440 1441 1442 1443 1444 1445
    /* Try to claim the pidfile, exiting if we can't */
    if ((pid_file_fd = virPidFileAcquirePath(pid_file, getpid())) < 0) {
        ret = VIR_DAEMON_ERR_PIDFILE;
        goto cleanup;
    }

J
Jim Fehlig 已提交
1446 1447
    use_polkit_dbus = config->auth_unix_rw == REMOTE_AUTH_POLKIT ||
            config->auth_unix_ro == REMOTE_AUTH_POLKIT;
1448 1449
    if (!(srv = virNetServerNew(config->min_workers,
                                config->max_workers,
1450
                                config->prio_workers,
1451 1452
                                config->max_clients,
                                config->mdns_adv ? config->mdns_name : NULL,
J
Jim Fehlig 已提交
1453
                                use_polkit_dbus,
1454 1455 1456 1457 1458
                                remoteClientInitHook))) {
        ret = VIR_DAEMON_ERR_INIT;
        goto cleanup;
    }

1459 1460 1461
    /* Beyond this point, nothing should rely on using
     * getuid/geteuid() == 0, for privilege level checks.
     */
1462
    if (daemonSetupPrivs() < 0) {
1463
        ret = VIR_DAEMON_ERR_PRIVS;
1464
        goto cleanup;
1465
    }
J
John Levon 已提交
1466

1467
    daemonInitialize();
1468

1469 1470 1471 1472 1473 1474 1475 1476 1477
    remoteProcs[REMOTE_PROC_AUTH_LIST].needAuth = false;
    remoteProcs[REMOTE_PROC_AUTH_SASL_INIT].needAuth = false;
    remoteProcs[REMOTE_PROC_AUTH_SASL_STEP].needAuth = false;
    remoteProcs[REMOTE_PROC_AUTH_SASL_START].needAuth = false;
    remoteProcs[REMOTE_PROC_AUTH_POLKIT].needAuth = false;
    if (!(remoteProgram = virNetServerProgramNew(REMOTE_PROGRAM,
                                                 REMOTE_PROTOCOL_VERSION,
                                                 remoteProcs,
                                                 remoteNProcs))) {
1478
        ret = VIR_DAEMON_ERR_INIT;
1479 1480 1481 1482 1483
        goto cleanup;
    }
    if (virNetServerAddProgram(srv, remoteProgram) < 0) {
        ret = VIR_DAEMON_ERR_INIT;
        goto cleanup;
1484
    }
1485

1486 1487 1488 1489 1490 1491 1492 1493 1494 1495
    if (!(qemuProgram = virNetServerProgramNew(QEMU_PROGRAM,
                                               QEMU_PROTOCOL_VERSION,
                                               qemuProcs,
                                               qemuNProcs))) {
        ret = VIR_DAEMON_ERR_INIT;
        goto cleanup;
    }
    if (virNetServerAddProgram(srv, qemuProgram) < 0) {
        ret = VIR_DAEMON_ERR_INIT;
        goto cleanup;
1496
    }
1497

1498 1499 1500 1501 1502 1503 1504 1505 1506
    if (timeout != -1)
        virNetServerAutoShutdown(srv,
                                 timeout,
                                 daemonShutdownCheck,
                                 NULL);

    if ((daemonSetupSignals(srv)) < 0) {
        ret = VIR_DAEMON_ERR_SIGNAL;
        goto cleanup;
1507
    }
D
Daniel P. Berrange 已提交
1508

1509
    if (config->audit_level) {
1510
        if (virAuditOpen() < 0) {
1511
            if (config->audit_level > 1) {
1512
                ret = VIR_DAEMON_ERR_AUDIT;
1513
                goto cleanup;
1514 1515 1516
            }
        }
    }
1517
    virAuditLog(config->audit_logging);
1518

1519
    /* setup the hooks if any */
1520
    if (virHookInitialize() < 0) {
1521
        ret = VIR_DAEMON_ERR_HOOKS;
1522
        goto cleanup;
1523 1524
    }

1525
    /* Disable error func, now logging is setup */
1526
    virSetErrorFunc(NULL, daemonErrorHandler);
1527
    virSetErrorLogPriorityFunc(daemonErrorLogFilter);
1528

1529 1530 1531 1532 1533 1534 1535 1536
    /*
     * Call the daemon startup hook
     * TODO: should we abort the daemon startup if the script returned
     *       an error ?
     */
    virHookCall(VIR_HOOK_DRIVER_DAEMON, "-", VIR_HOOK_DAEMON_OP_START,
                0, "start", NULL);

1537 1538 1539
    if (daemonSetupNetworking(srv, config,
                              sock_file, sock_file_ro,
                              ipsock, privileged) < 0) {
1540
        ret = VIR_DAEMON_ERR_NETWORK;
1541
        goto cleanup;
1542 1543
    }

1544 1545 1546 1547 1548 1549 1550 1551 1552
    /* Tell parent of daemon that basic initialization is complete
     * In particular we're ready to accept net connections & have
     * written the pidfile
     */
    if (statuswrite != -1) {
        char status = 0;
        while (write(statuswrite, &status, 1) == -1 &&
               errno == EINTR)
            ;
1553
        VIR_FORCE_CLOSE(statuswrite);
1554 1555
    }

1556 1557 1558 1559
    /* Initialize drivers & then start accepting new clients from network */
    if (daemonStateInit(srv) < 0) {
        ret = VIR_DAEMON_ERR_INIT;
        goto cleanup;
1560
    }
D
Daniel P. Berrange 已提交
1561

1562 1563
    /* Run event loop. */
    virNetServerRun(srv);
1564

1565 1566
    ret = 0;

1567 1568 1569
    virHookCall(VIR_HOOK_DRIVER_DAEMON, "-", VIR_HOOK_DAEMON_OP_SHUTDOWN,
                0, "shutdown", NULL);

1570 1571 1572
cleanup:
    virNetServerProgramFree(remoteProgram);
    virNetServerProgramFree(qemuProgram);
1573
    virNetServerClose(srv);
1574
    virNetServerFree(srv);
1575 1576 1577 1578 1579 1580 1581 1582
    if (statuswrite != -1) {
        if (ret != 0) {
            /* Tell parent of daemon what failed */
            char status = ret;
            while (write(statuswrite, &status, 1) == -1 &&
                   errno == EINTR)
                ;
        }
1583
        VIR_FORCE_CLOSE(statuswrite);
1584
    }
1585 1586
    if (pid_file_fd != -1)
        virPidFileReleasePath(pid_file, pid_file_fd);
1587 1588 1589 1590 1591

    VIR_FREE(sock_file);
    VIR_FREE(sock_file_ro);
    VIR_FREE(pid_file);
    VIR_FREE(remote_config_file);
1592 1593
    VIR_FREE(run_dir);

1594 1595 1596
    daemonConfigFree(config);
    virLogShutdown();

1597
    return ret;
D
Daniel P. Berrange 已提交
1598
}