qemu_process.c 193.4 KB
Newer Older
1
/*
2
 * qemu_process.c: QEMU process management
3
 *
4
 * Copyright (C) 2006-2016 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16
 *
 * 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
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
19 20 21 22 23 24 25 26 27
 *
 */

#include <config.h>

#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
R
Roman Bogorodskiy 已提交
28 29 30 31 32 33
#if defined(__linux__)
# include <linux/capability.h>
#elif defined(__FreeBSD__)
# include <sys/param.h>
# include <sys/cpuset.h>
#endif
34 35

#include "qemu_process.h"
36
#include "qemu_processpriv.h"
37
#include "qemu_alias.h"
38
#include "qemu_domain.h"
39
#include "qemu_domain_address.h"
40 41 42 43 44 45
#include "qemu_cgroup.h"
#include "qemu_capabilities.h"
#include "qemu_monitor.h"
#include "qemu_command.h"
#include "qemu_hostdev.h"
#include "qemu_hotplug.h"
46
#include "qemu_migration.h"
47
#include "qemu_interface.h"
48

49
#include "cpu/cpu.h"
50
#include "datatypes.h"
51
#include "virlog.h"
52
#include "virerror.h"
53
#include "viralloc.h"
54
#include "virhook.h"
E
Eric Blake 已提交
55
#include "virfile.h"
56
#include "virpidfile.h"
57
#include "virhostcpu.h"
58
#include "domain_audit.h"
59
#include "domain_nwfilter.h"
60
#include "locking/domain_lock.h"
61
#include "network/bridge_driver.h"
62
#include "viruuid.h"
63
#include "virprocess.h"
64
#include "virtime.h"
A
Ansis Atteka 已提交
65
#include "virnetdevtap.h"
66
#include "virnetdevopenvswitch.h"
67
#include "virnetdevmidonet.h"
68
#include "virbitmap.h"
69
#include "viratomic.h"
70
#include "virnuma.h"
71
#include "virstring.h"
72
#include "virhostdev.h"
J
John Ferlan 已提交
73
#include "secret_util.h"
74
#include "storage/storage_driver.h"
75
#include "configmake.h"
76
#include "nwfilter_conf.h"
77
#include "netdev_bandwidth_conf.h"
78 79 80

#define VIR_FROM_THIS VIR_FROM_QEMU

81 82
VIR_LOG_INIT("qemu.qemu_process");

83
/**
84
 * qemuProcessRemoveDomainStatus
85 86 87 88 89 90
 *
 * remove all state files of a domain from statedir
 *
 * Returns 0 on success
 */
static int
91
qemuProcessRemoveDomainStatus(virQEMUDriverPtr driver,
92 93 94 95
                              virDomainObjPtr vm)
{
    char ebuf[1024];
    char *file = NULL;
96
    qemuDomainObjPrivatePtr priv = vm->privateData;
97 98
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
    int ret = -1;
99

100
    if (virAsprintf(&file, "%s/%s.xml", cfg->stateDir, vm->def->name) < 0)
101
        goto cleanup;
102 103 104 105 106 107

    if (unlink(file) < 0 && errno != ENOENT && errno != ENOTDIR)
        VIR_WARN("Failed to remove domain XML for %s: %s",
                 vm->def->name, virStrerror(errno, ebuf, sizeof(ebuf)));
    VIR_FREE(file);

108 109 110
    if (priv->pidfile &&
        unlink(priv->pidfile) < 0 &&
        errno != ENOENT)
111 112 113
        VIR_WARN("Failed to remove PID file for %s: %s",
                 vm->def->name, virStrerror(errno, ebuf, sizeof(ebuf)));

114
    ret = 0;
115
 cleanup:
116 117
    virObjectUnref(cfg);
    return ret;
118 119 120 121
}


/* XXX figure out how to remove this */
122
extern virQEMUDriverPtr qemu_driver;
123

D
Daniel P. Berrange 已提交
124 125 126 127 128 129 130
/*
 * This is a callback registered with a qemuAgentPtr instance,
 * and to be invoked when the agent console hits an end of file
 * condition, or error, thus indicating VM shutdown should be
 * performed
 */
static void
131
qemuProcessHandleAgentEOF(qemuAgentPtr agent,
D
Daniel P. Berrange 已提交
132 133 134 135 136 137
                          virDomainObjPtr vm)
{
    qemuDomainObjPrivatePtr priv;

    VIR_DEBUG("Received EOF from agent on %p '%s'", vm, vm->def->name);

138
    virObjectLock(vm);
D
Daniel P. Berrange 已提交
139 140

    priv = vm->privateData;
141 142 143 144 145 146 147 148 149 150 151

    if (!priv->agent) {
        VIR_DEBUG("Agent freed already");
        goto unlock;
    }

    if (priv->beingDestroyed) {
        VIR_DEBUG("Domain is being destroyed, agent EOF is expected");
        goto unlock;
    }

152
    qemuAgentClose(agent);
153
    priv->agent = NULL;
D
Daniel P. Berrange 已提交
154

155
    virObjectUnlock(vm);
156 157
    return;

158
 unlock:
159 160
    virObjectUnlock(vm);
    return;
D
Daniel P. Berrange 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
}


/*
 * This is invoked when there is some kind of error
 * parsing data to/from the agent. The VM can continue
 * to run, but no further agent commands will be
 * allowed
 */
static void
qemuProcessHandleAgentError(qemuAgentPtr agent ATTRIBUTE_UNUSED,
                            virDomainObjPtr vm)
{
    qemuDomainObjPrivatePtr priv;

    VIR_DEBUG("Received error from agent on %p '%s'", vm, vm->def->name);

178
    virObjectLock(vm);
D
Daniel P. Berrange 已提交
179 180 181 182 183

    priv = vm->privateData;

    priv->agentError = true;

184
    virObjectUnlock(vm);
D
Daniel P. Berrange 已提交
185 186 187 188 189
}

static void qemuProcessHandleAgentDestroy(qemuAgentPtr agent,
                                          virDomainObjPtr vm)
{
190 191
    VIR_DEBUG("Received destroy agent=%p vm=%p", agent, vm);

192
    virObjectUnref(vm);
D
Daniel P. Berrange 已提交
193 194 195 196 197 198 199 200 201 202
}


static qemuAgentCallbacks agentCallbacks = {
    .destroy = qemuProcessHandleAgentDestroy,
    .eofNotify = qemuProcessHandleAgentEOF,
    .errorNotify = qemuProcessHandleAgentError,
};


203
int
204
qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm)
D
Daniel P. Berrange 已提交
205 206 207 208
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int ret = -1;
    qemuAgentPtr agent = NULL;
209
    virDomainChrDefPtr config = qemuFindAgentConfig(vm->def);
D
Daniel P. Berrange 已提交
210 211 212 213

    if (!config)
        return 0;

214 215 216 217 218 219 220 221 222
    if (priv->agent)
        return 0;

    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VSERPORT_CHANGE) &&
        config->state != VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED) {
        VIR_DEBUG("Deferring connecting to guest agent");
        return 0;
    }

D
Daniel P. Berrange 已提交
223 224 225 226 227 228 229 230 231
    if (virSecurityManagerSetDaemonSocketLabel(driver->securityManager,
                                               vm->def) < 0) {
        VIR_ERROR(_("Failed to set security context for agent for %s"),
                  vm->def->name);
        goto cleanup;
    }

    /* Hold an extra reference because we can't allow 'vm' to be
     * deleted while the agent is active */
232
    virObjectRef(vm);
D
Daniel P. Berrange 已提交
233 234

    ignore_value(virTimeMillisNow(&priv->agentStart));
235
    virObjectUnlock(vm);
D
Daniel P. Berrange 已提交
236 237

    agent = qemuAgentOpen(vm,
238
                          &config->source,
D
Daniel P. Berrange 已提交
239 240
                          &agentCallbacks);

241
    virObjectLock(vm);
D
Daniel P. Berrange 已提交
242 243
    priv->agentStart = 0;

244 245 246 247 248 249 250 251 252 253 254
    if (agent == NULL)
        virObjectUnref(vm);

    if (!virDomainObjIsActive(vm)) {
        qemuAgentClose(agent);
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("guest crashed while connecting to the guest agent"));
        ret = -2;
        goto cleanup;
    }

D
Daniel P. Berrange 已提交
255 256 257 258
    if (virSecurityManagerClearSocketLabel(driver->securityManager,
                                           vm->def) < 0) {
        VIR_ERROR(_("Failed to clear security context for agent for %s"),
                  vm->def->name);
259
        qemuAgentClose(agent);
D
Daniel P. Berrange 已提交
260 261 262 263 264 265 266 267 268 269 270 271 272
        goto cleanup;
    }


    priv->agent = agent;

    if (priv->agent == NULL) {
        VIR_INFO("Failed to connect agent for %s", vm->def->name);
        goto cleanup;
    }

    ret = 0;

273
 cleanup:
D
Daniel P. Berrange 已提交
274 275 276 277
    return ret;
}


278
/*
279
 * This is a callback registered with a qemuMonitorPtr instance,
280 281 282 283 284 285
 * and to be invoked when the monitor console hits an end of file
 * condition, or error, thus indicating VM shutdown should be
 * performed
 */
static void
qemuProcessHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
286 287
                            virDomainObjPtr vm,
                            void *opaque)
288
{
289
    virQEMUDriverPtr driver = opaque;
290
    qemuDomainObjPrivatePtr priv;
291
    struct qemuProcessEvent *processEvent;
292

293
    virObjectLock(vm);
294

295
    VIR_DEBUG("Received EOF on %p '%s'", vm, vm->def->name);
296

297
    priv = vm->privateData;
298 299
    if (priv->beingDestroyed) {
        VIR_DEBUG("Domain is being destroyed, EOF is expected");
300
        goto cleanup;
301 302
    }

303
    if (VIR_ALLOC(processEvent) < 0)
304
        goto cleanup;
305

306 307
    processEvent->eventType = QEMU_PROCESS_EVENT_MONITOR_EOF;
    processEvent->vm = vm;
308

309 310 311 312 313
    virObjectRef(vm);
    if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
        ignore_value(virObjectUnref(vm));
        VIR_FREE(processEvent);
        goto cleanup;
314
    }
315

316 317 318 319
    /* We don't want this EOF handler to be called over and over while the
     * thread is waiting for a job.
     */
    qemuMonitorUnregister(mon);
320

321
 cleanup:
322
    virObjectUnlock(vm);
323 324 325 326 327 328 329 330 331 332 333
}


/*
 * This is invoked when there is some kind of error
 * parsing data to/from the monitor. The VM can continue
 * to run, but no further monitor commands will be
 * allowed
 */
static void
qemuProcessHandleMonitorError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
334 335
                              virDomainObjPtr vm,
                              void *opaque)
336
{
337
    virQEMUDriverPtr driver = opaque;
338
    virObjectEventPtr event = NULL;
339 340 341

    VIR_DEBUG("Received error on %p '%s'", vm, vm->def->name);

342
    virObjectLock(vm);
343

344
    ((qemuDomainObjPrivatePtr) vm->privateData)->monError = true;
345
    event = virDomainEventControlErrorNewFromObj(vm);
346
    qemuDomainEventQueue(driver, event);
347

348
    virObjectUnlock(vm);
349 350 351
}


352
virDomainDiskDefPtr
353 354 355
qemuProcessFindDomainDiskByAlias(virDomainObjPtr vm,
                                 const char *alias)
{
356
    size_t i;
357

358
    alias = qemuAliasDiskDriveSkipPrefix(alias);
359 360 361 362 363 364 365 366 367

    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk;

        disk = vm->def->disks[i];
        if (disk->info.alias != NULL && STREQ(disk->info.alias, alias))
            return disk;
    }

368 369 370
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("no disk found with alias %s"),
                   alias);
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
    return NULL;
}

static int
qemuProcessGetVolumeQcowPassphrase(virConnectPtr conn,
                                   virDomainDiskDefPtr disk,
                                   char **secretRet,
                                   size_t *secretLen)
{
    char *passphrase;
    unsigned char *data;
    size_t size;
    int ret = -1;
    virStorageEncryptionPtr enc;

386
    if (!disk->src->encryption) {
387 388
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("disk %s does not have any encryption information"),
389
                       disk->src->path);
390 391
        return -1;
    }
392
    enc = disk->src->encryption;
393 394

    if (!conn) {
395 396
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("cannot find secrets without a connection"));
397 398 399 400
        goto cleanup;
    }

    if (conn->secretDriver == NULL ||
401 402
        conn->secretDriver->secretLookupByUUID == NULL ||
        conn->secretDriver->secretGetValue == NULL) {
403 404
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("secret storage not supported"));
405 406 407 408 409 410 411
        goto cleanup;
    }

    if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_QCOW ||
        enc->nsecrets != 1 ||
        enc->secrets[0]->type !=
        VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE) {
412
        virReportError(VIR_ERR_XML_ERROR,
413 414
                       _("invalid <encryption> for volume %s"),
                       virDomainDiskGetSource(disk));
415 416 417
        goto cleanup;
    }

J
John Ferlan 已提交
418 419 420
    if (virSecretGetSecretString(conn, &enc->secrets[0]->seclookupdef,
                                 VIR_SECRET_USAGE_TYPE_VOLUME,
                                 &data, &size) < 0)
421 422 423 424 425
        goto cleanup;

    if (memchr(data, '\0', size) != NULL) {
        memset(data, 0, size);
        VIR_FREE(data);
426 427
        virReportError(VIR_ERR_XML_ERROR,
                       _("format='qcow' passphrase for %s must not contain a "
428
                         "'\\0'"), virDomainDiskGetSource(disk));
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
        goto cleanup;
    }

    if (VIR_ALLOC_N(passphrase, size + 1) < 0) {
        memset(data, 0, size);
        VIR_FREE(data);
        goto cleanup;
    }
    memcpy(passphrase, data, size);
    passphrase[size] = '\0';

    memset(data, 0, size);
    VIR_FREE(data);

    *secretRet = passphrase;
    *secretLen = size;

    ret = 0;

448
 cleanup:
449 450 451 452 453 454 455 456 457
    return ret;
}

static int
qemuProcessFindVolumeQcowPassphrase(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
                                    virDomainObjPtr vm,
                                    const char *path,
                                    char **secretRet,
458 459
                                    size_t *secretLen,
                                    void *opaque ATTRIBUTE_UNUSED)
460 461 462 463
{
    virDomainDiskDefPtr disk;
    int ret = -1;

464
    virObjectLock(vm);
465 466 467 468
    if (!(disk = virDomainDiskByName(vm->def, path, true))) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("no disk found with path %s"),
                       path);
469
        goto cleanup;
470
    }
471 472 473

    ret = qemuProcessGetVolumeQcowPassphrase(conn, disk, secretRet, secretLen);

474
 cleanup:
475
    virObjectUnlock(vm);
476 477 478 479 480 481
    return ret;
}


static int
qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
482 483
                       virDomainObjPtr vm,
                       void *opaque)
484
{
485
    virQEMUDriverPtr driver = opaque;
486
    virObjectEventPtr event;
487
    qemuDomainObjPrivatePtr priv;
488
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
489

490
    virObjectLock(vm);
491

492
    event = virDomainEventRebootNewFromObj(vm);
493 494 495
    priv = vm->privateData;
    if (priv->agent)
        qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_RESET);
496

497
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
498
        VIR_WARN("Failed to save status on vm %s", vm->def->name);
499

500
    virObjectUnlock(vm);
501

502
    qemuDomainEventQueue(driver, event);
503

504
    virObjectUnref(cfg);
505 506 507 508
    return 0;
}


509 510 511 512 513 514 515 516 517 518 519
/*
 * Since we have the '-no-shutdown' flag set, the
 * QEMU process will currently have guest OS shutdown
 * and the CPUS stopped. To fake the reboot, we thus
 * want todo a reset of the virtual hardware, followed
 * by restart of the CPUs. This should result in the
 * guest OS booting up again
 */
static void
qemuProcessFakeReboot(void *opaque)
{
520
    virQEMUDriverPtr driver = qemu_driver;
521 522
    virDomainObjPtr vm = opaque;
    qemuDomainObjPrivatePtr priv = vm->privateData;
523
    virObjectEventPtr event = NULL;
524
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
525
    virDomainRunningReason reason = VIR_DOMAIN_RUNNING_BOOTED;
526
    int ret = -1, rc;
527

528
    VIR_DEBUG("vm=%p", vm);
529
    virObjectLock(vm);
530
    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
531 532 533
        goto cleanup;

    if (!virDomainObjIsActive(vm)) {
534 535
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("guest unexpectedly quit"));
536 537 538
        goto endjob;
    }

539
    qemuDomainObjEnterMonitor(driver, vm);
540 541 542
    rc = qemuMonitorSystemReset(priv->mon);

    if (qemuDomainObjExitMonitor(driver, vm) < 0)
543 544
        goto endjob;

545
    if (rc < 0)
546 547
        goto endjob;

548 549 550
    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_CRASHED)
        reason = VIR_DOMAIN_RUNNING_CRASHED;

551
    if (qemuProcessStartCPUs(driver, vm, NULL,
552
                             reason,
553
                             QEMU_ASYNC_JOB_NONE) < 0) {
554
        if (virGetLastError() == NULL)
555 556
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("resume operation failed"));
557 558
        goto endjob;
    }
559
    priv->gotShutdown = false;
560
    event = virDomainEventLifecycleNewFromObj(vm,
561 562 563
                                     VIR_DOMAIN_EVENT_RESUMED,
                                     VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);

564
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
565 566 567 568
        VIR_WARN("Unable to save status on vm %s after state change",
                 vm->def->name);
    }

569 570
    ret = 0;

571
 endjob:
572
    qemuDomainObjEndJob(driver, vm);
573

574
 cleanup:
575 576
    if (ret == -1)
        ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE));
M
Michal Privoznik 已提交
577
    virDomainObjEndAPI(&vm);
578
    qemuDomainEventQueue(driver, event);
579
    virObjectUnref(cfg);
580 581 582
}


583
void
584
qemuProcessShutdownOrReboot(virQEMUDriverPtr driver,
585
                            virDomainObjPtr vm)
586
{
587 588 589
    qemuDomainObjPrivatePtr priv = vm->privateData;

    if (priv->fakeReboot) {
590
        qemuDomainSetFakeReboot(driver, vm, false);
591
        virObjectRef(vm);
592 593 594 595 596
        virThread th;
        if (virThreadCreate(&th,
                            false,
                            qemuProcessFakeReboot,
                            vm) < 0) {
597
            VIR_ERROR(_("Failed to create reboot thread, killing domain"));
598
            ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_NOWAIT));
599
            virObjectUnref(vm);
600 601
        }
    } else {
602
        ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_NOWAIT));
603
    }
604
}
605

606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626

static int
qemuProcessHandleEvent(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                       virDomainObjPtr vm,
                       const char *eventName,
                       long long seconds,
                       unsigned int micros,
                       const char *details,
                       void *opaque)
{
    virQEMUDriverPtr driver = opaque;
    virObjectEventPtr event = NULL;

    VIR_DEBUG("vm=%p", vm);

    virObjectLock(vm);
    event = virDomainQemuMonitorEventNew(vm->def->id, vm->def->name,
                                         vm->def->uuid, eventName,
                                         seconds, micros, details);

    virObjectUnlock(vm);
627
    qemuDomainEventQueue(driver, event);
628 629 630 631 632

    return 0;
}


633 634
static int
qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
635 636
                          virDomainObjPtr vm,
                          void *opaque)
637
{
638
    virQEMUDriverPtr driver = opaque;
639
    qemuDomainObjPrivatePtr priv;
640
    virObjectEventPtr event = NULL;
641
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
642

643 644
    VIR_DEBUG("vm=%p", vm);

645
    virObjectLock(vm);
646 647 648 649 650 651

    priv = vm->privateData;
    if (priv->gotShutdown) {
        VIR_DEBUG("Ignoring repeated SHUTDOWN event from domain %s",
                  vm->def->name);
        goto unlock;
652 653 654 655
    } else if (!virDomainObjIsActive(vm)) {
        VIR_DEBUG("Ignoring SHUTDOWN event from inactive domain %s",
                  vm->def->name);
        goto unlock;
656 657 658 659 660 661 662 663
    }
    priv->gotShutdown = true;

    VIR_DEBUG("Transitioned guest %s to shutdown state",
              vm->def->name);
    virDomainObjSetState(vm,
                         VIR_DOMAIN_SHUTDOWN,
                         VIR_DOMAIN_SHUTDOWN_UNKNOWN);
664
    event = virDomainEventLifecycleNewFromObj(vm,
665 666 667
                                     VIR_DOMAIN_EVENT_SHUTDOWN,
                                     VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED);

668
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
669 670 671 672
        VIR_WARN("Unable to save status on vm %s after state change",
                 vm->def->name);
    }

673 674 675
    if (priv->agent)
        qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SHUTDOWN);

676 677
    qemuProcessShutdownOrReboot(driver, vm);

678
 unlock:
679
    virObjectUnlock(vm);
680
    qemuDomainEventQueue(driver, event);
681
    virObjectUnref(cfg);
682

683 684 685 686 687 688
    return 0;
}


static int
qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
689 690
                      virDomainObjPtr vm,
                      void *opaque)
691
{
692
    virQEMUDriverPtr driver = opaque;
693
    virObjectEventPtr event = NULL;
694 695
    virDomainPausedReason reason = VIR_DOMAIN_PAUSED_UNKNOWN;
    virDomainEventSuspendedDetailType detail = VIR_DOMAIN_EVENT_SUSPENDED_PAUSED;
696
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
697

698
    virObjectLock(vm);
J
Jiri Denemark 已提交
699
    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
700
        qemuDomainObjPrivatePtr priv = vm->privateData;
701

702
        if (priv->gotShutdown) {
703 704
            VIR_DEBUG("Ignoring STOP event after SHUTDOWN");
            goto unlock;
705 706
        }

707
        if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) {
708 709 710 711 712 713 714 715
            if (priv->job.current->stats.status ==
                        QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY) {
                reason = VIR_DOMAIN_PAUSED_POSTCOPY;
                detail = VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY;
            } else {
                reason = VIR_DOMAIN_PAUSED_MIGRATION;
                detail = VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED;
            }
716 717 718 719
        }

        VIR_DEBUG("Transitioned guest %s to paused state, reason %s",
                  vm->def->name, virDomainPausedReasonTypeToString(reason));
720

721 722 723
        if (priv->job.current)
            ignore_value(virTimeMillisNow(&priv->job.current->stopped));

724 725 726 727
        if (priv->signalStop)
            virDomainObjBroadcast(vm);

        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
728
        event = virDomainEventLifecycleNewFromObj(vm,
729 730
                                                  VIR_DOMAIN_EVENT_SUSPENDED,
                                                  detail);
731

732 733 734 735 736
        VIR_FREE(priv->lockState);
        if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
            VIR_WARN("Unable to release lease on %s", vm->def->name);
        VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));

737
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
738 739 740
            VIR_WARN("Unable to save status on vm %s after state change",
                     vm->def->name);
        }
741
    }
742

743
 unlock:
744
    virObjectUnlock(vm);
745
    qemuDomainEventQueue(driver, event);
746
    virObjectUnref(cfg);
747 748 749 750 751

    return 0;
}


752 753
static int
qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
754 755
                        virDomainObjPtr vm,
                        void *opaque)
756
{
757
    virQEMUDriverPtr driver = opaque;
758
    virObjectEventPtr event = NULL;
759
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
760

761
    virObjectLock(vm);
762 763 764 765 766 767 768 769 770 771 772 773 774
    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
        qemuDomainObjPrivatePtr priv = vm->privateData;

        if (priv->gotShutdown) {
            VIR_DEBUG("Ignoring RESUME event after SHUTDOWN");
            goto unlock;
        }

        VIR_DEBUG("Transitioned guest %s out of paused into resumed state",
                  vm->def->name);

        virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
                                 VIR_DOMAIN_RUNNING_UNPAUSED);
775
        event = virDomainEventLifecycleNewFromObj(vm,
776 777 778 779
                                         VIR_DOMAIN_EVENT_RESUMED,
                                         VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);

        VIR_DEBUG("Using lock state '%s' on resume event", NULLSTR(priv->lockState));
780
        if (virDomainLockProcessResume(driver->lockManager, cfg->uri,
781 782 783 784 785 786 787 788 789
                                       vm, priv->lockState) < 0) {
            /* Don't free priv->lockState on error, because we need
             * to make sure we have state still present if the user
             * tries to resume again
             */
            goto unlock;
        }
        VIR_FREE(priv->lockState);

790
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
791 792 793 794 795
            VIR_WARN("Unable to save status on vm %s after state change",
                     vm->def->name);
        }
    }

796
 unlock:
797
    virObjectUnlock(vm);
798
    qemuDomainEventQueue(driver, event);
799
    virObjectUnref(cfg);
800 801 802
    return 0;
}

803 804 805
static int
qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                           virDomainObjPtr vm,
806 807
                           long long offset,
                           void *opaque)
808
{
809
    virQEMUDriverPtr driver = opaque;
810
    virObjectEventPtr event = NULL;
811
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
812

813
    virObjectLock(vm);
814

815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
    if (vm->def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) {
        /* when a basedate is manually given on the qemu commandline
         * rather than simply "-rtc base=utc", the offset sent by qemu
         * in this event is *not* the new offset from UTC, but is
         * instead the new offset from the *original basedate* +
         * uptime. For example, if the original offset was 3600 and
         * the guest clock has been advanced by 10 seconds, qemu will
         * send "10" in the event - this means that the new offset
         * from UTC is 3610, *not* 10. If the guest clock is advanced
         * by another 10 seconds, qemu will now send "20" - i.e. each
         * event is the sum of the most recent change and all previous
         * changes since the domain was started. Fortunately, we have
         * saved the initial offset in "adjustment0", so to arrive at
         * the proper new "adjustment", we just add the most recent
         * offset to adjustment0.
         */
        offset += vm->def->clock.data.variable.adjustment0;
832
        vm->def->clock.data.variable.adjustment = offset;
833

834
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
835 836 837 838
           VIR_WARN("unable to save domain status with RTC change");
    }

    event = virDomainEventRTCChangeNewFromObj(vm, offset);
839

840
    virObjectUnlock(vm);
841

842
    qemuDomainEventQueue(driver, event);
843
    virObjectUnref(cfg);
844 845 846 847 848 849 850
    return 0;
}


static int
qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                          virDomainObjPtr vm,
851 852
                          int action,
                          void *opaque)
853
{
854
    virQEMUDriverPtr driver = opaque;
855 856
    virObjectEventPtr watchdogEvent = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
857
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
858

859
    virObjectLock(vm);
860 861 862
    watchdogEvent = virDomainEventWatchdogNewFromObj(vm, action);

    if (action == VIR_DOMAIN_EVENT_WATCHDOG_PAUSE &&
J
Jiri Denemark 已提交
863
        virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
864
        qemuDomainObjPrivatePtr priv = vm->privateData;
865 866
        VIR_DEBUG("Transitioned guest %s to paused state due to watchdog", vm->def->name);

J
Jiri Denemark 已提交
867
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_WATCHDOG);
868
        lifecycleEvent = virDomainEventLifecycleNewFromObj(vm,
869 870 871
                                                  VIR_DOMAIN_EVENT_SUSPENDED,
                                                  VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG);

872 873 874 875 876
        VIR_FREE(priv->lockState);
        if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
            VIR_WARN("Unable to release lease on %s", vm->def->name);
        VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));

877
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
878 879 880
            VIR_WARN("Unable to save status on vm %s after watchdog event",
                     vm->def->name);
        }
881 882 883
    }

    if (vm->def->watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) {
C
Chen Fan 已提交
884 885 886 887 888
        struct qemuProcessEvent *processEvent;
        if (VIR_ALLOC(processEvent) == 0) {
            processEvent->eventType = QEMU_PROCESS_EVENT_WATCHDOG;
            processEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP;
            processEvent->vm = vm;
W
Wen Congyang 已提交
889 890 891
            /* Hold an extra reference because we can't allow 'vm' to be
             * deleted before handling watchdog event is finished.
             */
892
            virObjectRef(vm);
C
Chen Fan 已提交
893
            if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
894
                if (!virObjectUnref(vm))
895
                    vm = NULL;
C
Chen Fan 已提交
896
                VIR_FREE(processEvent);
W
Wen Congyang 已提交
897
            }
898
        }
899 900
    }

901
    if (vm)
902
        virObjectUnlock(vm);
903 904
    qemuDomainEventQueue(driver, watchdogEvent);
    qemuDomainEventQueue(driver, lifecycleEvent);
905

906
    virObjectUnref(cfg);
907 908 909 910 911 912 913 914 915
    return 0;
}


static int
qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                         virDomainObjPtr vm,
                         const char *diskAlias,
                         int action,
916 917
                         const char *reason,
                         void *opaque)
918
{
919
    virQEMUDriverPtr driver = opaque;
920 921 922
    virObjectEventPtr ioErrorEvent = NULL;
    virObjectEventPtr ioErrorEvent2 = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
923 924 925
    const char *srcPath;
    const char *devAlias;
    virDomainDiskDefPtr disk;
926
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
927

928
    virObjectLock(vm);
929 930 931
    disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);

    if (disk) {
932
        srcPath = virDomainDiskGetSource(disk);
933 934 935 936 937 938 939 940 941 942
        devAlias = disk->info.alias;
    } else {
        srcPath = "";
        devAlias = "";
    }

    ioErrorEvent = virDomainEventIOErrorNewFromObj(vm, srcPath, devAlias, action);
    ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, srcPath, devAlias, action, reason);

    if (action == VIR_DOMAIN_EVENT_IO_ERROR_PAUSE &&
J
Jiri Denemark 已提交
943
        virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
944
        qemuDomainObjPrivatePtr priv = vm->privateData;
945 946
        VIR_DEBUG("Transitioned guest %s to paused state due to IO error", vm->def->name);

947 948 949
        if (priv->signalIOError)
            virDomainObjBroadcast(vm);

J
Jiri Denemark 已提交
950
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOERROR);
951
        lifecycleEvent = virDomainEventLifecycleNewFromObj(vm,
952 953 954
                                                  VIR_DOMAIN_EVENT_SUSPENDED,
                                                  VIR_DOMAIN_EVENT_SUSPENDED_IOERROR);

955 956 957 958 959
        VIR_FREE(priv->lockState);
        if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
            VIR_WARN("Unable to release lease on %s", vm->def->name);
        VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));

960
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
961 962
            VIR_WARN("Unable to save status on vm %s after IO error", vm->def->name);
    }
963
    virObjectUnlock(vm);
964

965 966 967
    qemuDomainEventQueue(driver, ioErrorEvent);
    qemuDomainEventQueue(driver, ioErrorEvent2);
    qemuDomainEventQueue(driver, lifecycleEvent);
968
    virObjectUnref(cfg);
969 970 971
    return 0;
}

972 973 974 975 976
static int
qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                          virDomainObjPtr vm,
                          const char *diskAlias,
                          int type,
977 978
                          int status,
                          void *opaque)
979
{
980
    virQEMUDriverPtr driver = opaque;
981
    struct qemuProcessEvent *processEvent = NULL;
982
    virDomainDiskDefPtr disk;
983
    qemuDomainDiskPrivatePtr diskPriv;
984
    char *data = NULL;
985

986
    virObjectLock(vm);
987

988 989
    VIR_DEBUG("Block job for device %s (domain: %p,%s) type %d status %d",
              diskAlias, vm, vm->def->name, type, status);
990

991
    if (!(disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias)))
992
        goto error;
993
    diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
994

995
    if (diskPriv->blockJobSync) {
996
        /* We have a SYNC API waiting for this event, dispatch it back */
997 998
        diskPriv->blockJobType = type;
        diskPriv->blockJobStatus = status;
999
        virDomainObjBroadcast(vm);
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
    } else {
        /* there is no waiting SYNC API, dispatch the update to a thread */
        if (VIR_ALLOC(processEvent) < 0)
            goto error;

        processEvent->eventType = QEMU_PROCESS_EVENT_BLOCK_JOB;
        if (VIR_STRDUP(data, diskAlias) < 0)
            goto error;
        processEvent->data = data;
        processEvent->vm = vm;
        processEvent->action = type;
        processEvent->status = status;
1012

1013 1014 1015 1016 1017
        virObjectRef(vm);
        if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
            ignore_value(virObjectUnref(vm));
            goto error;
        }
1018 1019
    }

1020
 cleanup:
1021
    virObjectUnlock(vm);
1022
    return 0;
1023 1024 1025 1026 1027
 error:
    if (processEvent)
        VIR_FREE(processEvent->data);
    VIR_FREE(processEvent);
    goto cleanup;
1028
}
1029

1030

1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
static int
qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                          virDomainObjPtr vm,
                          int phase,
                          int localFamily,
                          const char *localNode,
                          const char *localService,
                          int remoteFamily,
                          const char *remoteNode,
                          const char *remoteService,
                          const char *authScheme,
                          const char *x509dname,
1043 1044
                          const char *saslUsername,
                          void *opaque)
1045
{
1046
    virQEMUDriverPtr driver = opaque;
1047
    virObjectEventPtr event;
1048 1049 1050
    virDomainEventGraphicsAddressPtr localAddr = NULL;
    virDomainEventGraphicsAddressPtr remoteAddr = NULL;
    virDomainEventGraphicsSubjectPtr subject = NULL;
1051
    size_t i;
1052 1053

    if (VIR_ALLOC(localAddr) < 0)
1054
        goto error;
1055
    localAddr->family = localFamily;
1056 1057 1058
    if (VIR_STRDUP(localAddr->service, localService) < 0 ||
        VIR_STRDUP(localAddr->node, localNode) < 0)
        goto error;
1059 1060

    if (VIR_ALLOC(remoteAddr) < 0)
1061
        goto error;
1062
    remoteAddr->family = remoteFamily;
1063 1064 1065
    if (VIR_STRDUP(remoteAddr->service, remoteService) < 0 ||
        VIR_STRDUP(remoteAddr->node, remoteNode) < 0)
        goto error;
1066 1067

    if (VIR_ALLOC(subject) < 0)
1068
        goto error;
1069 1070
    if (x509dname) {
        if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
1071
            goto error;
1072
        subject->nidentity++;
1073 1074 1075
        if (VIR_STRDUP(subject->identities[subject->nidentity-1].type, "x509dname") < 0 ||
            VIR_STRDUP(subject->identities[subject->nidentity-1].name, x509dname) < 0)
            goto error;
1076 1077 1078
    }
    if (saslUsername) {
        if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
1079
            goto error;
1080
        subject->nidentity++;
1081 1082 1083
        if (VIR_STRDUP(subject->identities[subject->nidentity-1].type, "saslUsername") < 0 ||
            VIR_STRDUP(subject->identities[subject->nidentity-1].name, saslUsername) < 0)
            goto error;
1084 1085
    }

1086
    virObjectLock(vm);
1087
    event = virDomainEventGraphicsNewFromObj(vm, phase, localAddr, remoteAddr, authScheme, subject);
1088
    virObjectUnlock(vm);
1089

1090
    qemuDomainEventQueue(driver, event);
1091 1092 1093

    return 0;

1094
 error:
1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105
    if (localAddr) {
        VIR_FREE(localAddr->service);
        VIR_FREE(localAddr->node);
        VIR_FREE(localAddr);
    }
    if (remoteAddr) {
        VIR_FREE(remoteAddr->service);
        VIR_FREE(remoteAddr->node);
        VIR_FREE(remoteAddr);
    }
    if (subject) {
1106
        for (i = 0; i < subject->nidentity; i++) {
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
            VIR_FREE(subject->identities[i].type);
            VIR_FREE(subject->identities[i].name);
        }
        VIR_FREE(subject->identities);
        VIR_FREE(subject);
    }

    return -1;
}

1117 1118 1119 1120
static int
qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                            virDomainObjPtr vm,
                            const char *devAlias,
1121 1122
                            int reason,
                            void *opaque)
1123
{
1124
    virQEMUDriverPtr driver = opaque;
1125
    virObjectEventPtr event = NULL;
1126
    virDomainDiskDefPtr disk;
1127
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
1128

1129
    virObjectLock(vm);
1130 1131 1132 1133 1134 1135
    disk = qemuProcessFindDomainDiskByAlias(vm, devAlias);

    if (disk) {
        event = virDomainEventTrayChangeNewFromObj(vm,
                                                   devAlias,
                                                   reason);
1136 1137 1138 1139 1140 1141
        /* Update disk tray status */
        if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN)
            disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
        else if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE)
            disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;

1142
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
1143 1144 1145
            VIR_WARN("Unable to save status on vm %s after tray moved event",
                     vm->def->name);
        }
1146 1147

        virDomainObjBroadcast(vm);
1148 1149
    }

1150
    virObjectUnlock(vm);
1151
    qemuDomainEventQueue(driver, event);
1152
    virObjectUnref(cfg);
1153 1154 1155
    return 0;
}

O
Osier Yang 已提交
1156 1157
static int
qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1158 1159
                          virDomainObjPtr vm,
                          void *opaque)
O
Osier Yang 已提交
1160
{
1161
    virQEMUDriverPtr driver = opaque;
1162 1163
    virObjectEventPtr event = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
1164
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
O
Osier Yang 已提交
1165

1166
    virObjectLock(vm);
O
Osier Yang 已提交
1167 1168
    event = virDomainEventPMWakeupNewFromObj(vm);

1169 1170 1171 1172 1173 1174 1175 1176 1177
    /* Don't set domain status back to running if it wasn't paused
     * from guest side, otherwise it can just cause confusion.
     */
    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PMSUSPENDED) {
        VIR_DEBUG("Transitioned guest %s from pmsuspended to running "
                  "state due to QMP wakeup event", vm->def->name);

        virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
                             VIR_DOMAIN_RUNNING_WAKEUP);
1178
        lifecycleEvent = virDomainEventLifecycleNewFromObj(vm,
1179 1180 1181
                                                  VIR_DOMAIN_EVENT_STARTED,
                                                  VIR_DOMAIN_EVENT_STARTED_WAKEUP);

1182
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
1183 1184 1185 1186 1187
            VIR_WARN("Unable to save status on vm %s after wakeup event",
                     vm->def->name);
        }
    }

1188
    virObjectUnlock(vm);
1189 1190
    qemuDomainEventQueue(driver, event);
    qemuDomainEventQueue(driver, lifecycleEvent);
1191
    virObjectUnref(cfg);
O
Osier Yang 已提交
1192 1193
    return 0;
}
1194

O
Osier Yang 已提交
1195 1196
static int
qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1197 1198
                           virDomainObjPtr vm,
                           void *opaque)
O
Osier Yang 已提交
1199
{
1200
    virQEMUDriverPtr driver = opaque;
1201 1202
    virObjectEventPtr event = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
1203
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
O
Osier Yang 已提交
1204

1205
    virObjectLock(vm);
O
Osier Yang 已提交
1206 1207
    event = virDomainEventPMSuspendNewFromObj(vm);

1208
    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
1209
        qemuDomainObjPrivatePtr priv = vm->privateData;
1210 1211 1212 1213 1214
        VIR_DEBUG("Transitioned guest %s to pmsuspended state due to "
                  "QMP suspend event", vm->def->name);

        virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED,
                             VIR_DOMAIN_PMSUSPENDED_UNKNOWN);
J
Jiri Denemark 已提交
1215
        lifecycleEvent =
1216
            virDomainEventLifecycleNewFromObj(vm,
J
Jiri Denemark 已提交
1217 1218
                                     VIR_DOMAIN_EVENT_PMSUSPENDED,
                                     VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY);
1219

1220
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
1221 1222 1223
            VIR_WARN("Unable to save status on vm %s after suspend event",
                     vm->def->name);
        }
1224 1225 1226

        if (priv->agent)
            qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND);
1227 1228
    }

1229
    virObjectUnlock(vm);
O
Osier Yang 已提交
1230

1231 1232
    qemuDomainEventQueue(driver, event);
    qemuDomainEventQueue(driver, lifecycleEvent);
1233
    virObjectUnref(cfg);
O
Osier Yang 已提交
1234 1235 1236
    return 0;
}

1237 1238 1239
static int
qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                               virDomainObjPtr vm,
1240 1241
                               unsigned long long actual,
                               void *opaque)
1242
{
1243
    virQEMUDriverPtr driver = opaque;
1244
    virObjectEventPtr event = NULL;
1245
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
1246

1247
    virObjectLock(vm);
1248 1249 1250 1251 1252 1253
    event = virDomainEventBalloonChangeNewFromObj(vm, actual);

    VIR_DEBUG("Updating balloon from %lld to %lld kb",
              vm->def->mem.cur_balloon, actual);
    vm->def->mem.cur_balloon = actual;

1254
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
1255 1256
        VIR_WARN("unable to save domain status with balloon change");

1257
    virObjectUnlock(vm);
1258

1259
    qemuDomainEventQueue(driver, event);
1260
    virObjectUnref(cfg);
1261 1262 1263
    return 0;
}

1264 1265
static int
qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1266 1267
                               virDomainObjPtr vm,
                               void *opaque)
1268
{
1269
    virQEMUDriverPtr driver = opaque;
1270 1271
    virObjectEventPtr event = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
1272
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
1273

1274
    virObjectLock(vm);
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284
    event = virDomainEventPMSuspendDiskNewFromObj(vm);

    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
        qemuDomainObjPrivatePtr priv = vm->privateData;
        VIR_DEBUG("Transitioned guest %s to pmsuspended state due to "
                  "QMP suspend_disk event", vm->def->name);

        virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED,
                             VIR_DOMAIN_PMSUSPENDED_UNKNOWN);
        lifecycleEvent =
1285
            virDomainEventLifecycleNewFromObj(vm,
1286 1287 1288
                                     VIR_DOMAIN_EVENT_PMSUSPENDED,
                                     VIR_DOMAIN_EVENT_PMSUSPENDED_DISK);

1289
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
1290 1291 1292 1293 1294 1295 1296 1297
            VIR_WARN("Unable to save status on vm %s after suspend event",
                     vm->def->name);
        }

        if (priv->agent)
            qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND);
    }

1298
    virObjectUnlock(vm);
1299

1300 1301
    qemuDomainEventQueue(driver, event);
    qemuDomainEventQueue(driver, lifecycleEvent);
1302 1303
    virObjectUnref(cfg);

1304 1305 1306
    return 0;
}

1307

1308 1309
static int
qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1310 1311
                            virDomainObjPtr vm,
                            void *opaque)
1312
{
1313
    virQEMUDriverPtr driver = opaque;
1314 1315 1316
    struct qemuProcessEvent *processEvent;

    virObjectLock(vm);
1317
    if (VIR_ALLOC(processEvent) < 0)
1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
        goto cleanup;

    processEvent->eventType = QEMU_PROCESS_EVENT_GUESTPANIC;
    processEvent->action = vm->def->onCrash;
    processEvent->vm = vm;
    /* Hold an extra reference because we can't allow 'vm' to be
     * deleted before handling guest panic event is finished.
     */
    virObjectRef(vm);
    if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
        if (!virObjectUnref(vm))
            vm = NULL;
        VIR_FREE(processEvent);
    }

1333
 cleanup:
1334
    if (vm)
1335
        virObjectUnlock(vm);
1336 1337 1338 1339 1340

    return 0;
}


1341
int
1342 1343
qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                               virDomainObjPtr vm,
1344 1345
                               const char *devAlias,
                               void *opaque)
1346
{
1347
    virQEMUDriverPtr driver = opaque;
1348 1349
    struct qemuProcessEvent *processEvent = NULL;
    char *data;
1350 1351 1352 1353 1354 1355

    virObjectLock(vm);

    VIR_DEBUG("Device %s removed from domain %p %s",
              devAlias, vm, vm->def->name);

1356 1357
    if (qemuDomainSignalDeviceRemoval(vm, devAlias,
                                      QEMU_DOMAIN_UNPLUGGING_DEVICE_STATUS_OK))
1358
        goto cleanup;
1359

1360 1361
    if (VIR_ALLOC(processEvent) < 0)
        goto error;
1362

1363 1364 1365 1366 1367
    processEvent->eventType = QEMU_PROCESS_EVENT_DEVICE_DELETED;
    if (VIR_STRDUP(data, devAlias) < 0)
        goto error;
    processEvent->data = data;
    processEvent->vm = vm;
1368

1369 1370 1371 1372 1373
    virObjectRef(vm);
    if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
        ignore_value(virObjectUnref(vm));
        goto error;
    }
1374

1375
 cleanup:
1376 1377
    virObjectUnlock(vm);
    return 0;
1378 1379 1380 1381 1382
 error:
    if (processEvent)
        VIR_FREE(processEvent->data);
    VIR_FREE(processEvent);
    goto cleanup;
1383 1384 1385
}


1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453
/**
 *
 * Meaning of fields reported by the event according to the ACPI standard:
 * @source:
 *  0x00 - 0xff: Notification values, as passed at the request time
 *  0x100: Operating System Shutdown Processing
 *  0x103: Ejection processing
 *  0x200: Insertion processing
 *  other values are reserved
 *
 * @status:
 *   general values
 *     0x00: success
 *     0x01: non-specific failure
 *     0x02: unrecognized notify code
 *     0x03 - 0x7f: reserved
 *     other values are specific to the notification type
 *
 *   for the 0x100 source the following additional codes are standardized
 *     0x80: OS Shutdown request denied
 *     0x81: OS Shutdown in progress
 *     0x82: OS Shutdown completed
 *     0x83: OS Graceful shutdown not supported
 *     other values are reserved
 *
 * Other fields and semantics are specific to the qemu handling of the event.
 *  - @alias may be NULL for successful unplug operations
 *  - @slotType describes the device type a bit more closely, currently the
 *    only known value is 'DIMM'
 *  - @slot describes the specific device
 *
 *  Note that qemu does not emit the event for all the documented sources or
 *  devices.
 */
static int
qemuProcessHandleAcpiOstInfo(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                             virDomainObjPtr vm,
                             const char *alias,
                             const char *slotType,
                             const char *slot,
                             unsigned int source,
                             unsigned int status,
                             void *opaque)
{
    virQEMUDriverPtr driver = opaque;
    virObjectEventPtr event = NULL;

    virObjectLock(vm);

    VIR_DEBUG("ACPI OST info for device %s domain %p %s. "
              "slotType='%s' slot='%s' source=%u status=%u",
              NULLSTR(alias), vm, vm->def->name, slotType, slot, source, status);

    /* handle memory unplug failure */
    if (STREQ(slotType, "DIMM") && alias && status == 1) {
        qemuDomainSignalDeviceRemoval(vm, alias,
                                      QEMU_DOMAIN_UNPLUGGING_DEVICE_STATUS_GUEST_REJECTED);

        event = virDomainEventDeviceRemovalFailedNewFromObj(vm, alias);
    }

    virObjectUnlock(vm);
    qemuDomainEventQueue(driver, event);

    return 0;
}


1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494
static int
qemuProcessHandleNicRxFilterChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                    virDomainObjPtr vm,
                                    const char *devAlias,
                                    void *opaque)
{
    virQEMUDriverPtr driver = opaque;
    struct qemuProcessEvent *processEvent = NULL;
    char *data;

    virObjectLock(vm);

    VIR_DEBUG("Device %s RX Filter changed in domain %p %s",
              devAlias, vm, vm->def->name);

    if (VIR_ALLOC(processEvent) < 0)
        goto error;

    processEvent->eventType = QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED;
    if (VIR_STRDUP(data, devAlias) < 0)
        goto error;
    processEvent->data = data;
    processEvent->vm = vm;

    virObjectRef(vm);
    if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
        ignore_value(virObjectUnref(vm));
        goto error;
    }

 cleanup:
    virObjectUnlock(vm);
    return 0;
 error:
    if (processEvent)
        VIR_FREE(processEvent->data);
    VIR_FREE(processEvent);
    goto cleanup;
}


1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537
static int
qemuProcessHandleSerialChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                               virDomainObjPtr vm,
                               const char *devAlias,
                               bool connected,
                               void *opaque)
{
    virQEMUDriverPtr driver = opaque;
    struct qemuProcessEvent *processEvent = NULL;
    char *data;

    virObjectLock(vm);

    VIR_DEBUG("Serial port %s state changed to '%d' in domain %p %s",
              devAlias, connected, vm, vm->def->name);

    if (VIR_ALLOC(processEvent) < 0)
        goto error;

    processEvent->eventType = QEMU_PROCESS_EVENT_SERIAL_CHANGED;
    if (VIR_STRDUP(data, devAlias) < 0)
        goto error;
    processEvent->data = data;
    processEvent->action = connected;
    processEvent->vm = vm;

    virObjectRef(vm);
    if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
        ignore_value(virObjectUnref(vm));
        goto error;
    }

 cleanup:
    virObjectUnlock(vm);
    return 0;
 error:
    if (processEvent)
        VIR_FREE(processEvent->data);
    VIR_FREE(processEvent);
    goto cleanup;
}


1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556
static int
qemuProcessHandleSpiceMigrated(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                               virDomainObjPtr vm,
                               void *opaque ATTRIBUTE_UNUSED)
{
    qemuDomainObjPrivatePtr priv;

    virObjectLock(vm);

    VIR_DEBUG("Spice migration completed for domain %p %s",
              vm, vm->def->name);

    priv = vm->privateData;
    if (priv->job.asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT) {
        VIR_DEBUG("got SPICE_MIGRATE_COMPLETED event without a migration job");
        goto cleanup;
    }

    priv->job.spiceMigrated = true;
1557
    virDomainObjBroadcast(vm);
1558 1559 1560 1561 1562 1563 1564

 cleanup:
    virObjectUnlock(vm);
    return 0;
}


1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579
static int
qemuProcessHandleMigrationStatus(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                 virDomainObjPtr vm,
                                 int status,
                                 void *opaque ATTRIBUTE_UNUSED)
{
    qemuDomainObjPrivatePtr priv;

    virObjectLock(vm);

    VIR_DEBUG("Migration of domain %p %s changed state to %s",
              vm, vm->def->name,
              qemuMonitorMigrationStatusTypeToString(status));

    priv = vm->privateData;
1580
    if (priv->job.asyncJob == QEMU_ASYNC_JOB_NONE) {
1581 1582 1583 1584
        VIR_DEBUG("got MIGRATION event without a migration job");
        goto cleanup;
    }

1585
    priv->job.current->stats.status = status;
1586 1587 1588 1589 1590 1591 1592 1593
    virDomainObjBroadcast(vm);

 cleanup:
    virObjectUnlock(vm);
    return 0;
}


1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622
static int
qemuProcessHandleMigrationPass(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                               virDomainObjPtr vm,
                               int pass,
                               void *opaque)
{
    virQEMUDriverPtr driver = opaque;
    qemuDomainObjPrivatePtr priv;

    virObjectLock(vm);

    VIR_DEBUG("Migrating domain %p %s, iteration %d",
              vm, vm->def->name, pass);

    priv = vm->privateData;
    if (priv->job.asyncJob == QEMU_ASYNC_JOB_NONE) {
        VIR_DEBUG("got MIGRATION_PASS event without a migration job");
        goto cleanup;
    }

    qemuDomainEventQueue(driver,
                         virDomainEventMigrationIterationNewFromObj(vm, pass));

 cleanup:
    virObjectUnlock(vm);
    return 0;
}


1623 1624
static qemuMonitorCallbacks monitorCallbacks = {
    .eofNotify = qemuProcessHandleMonitorEOF,
1625
    .errorNotify = qemuProcessHandleMonitorError,
1626
    .diskSecretLookup = qemuProcessFindVolumeQcowPassphrase,
1627
    .domainEvent = qemuProcessHandleEvent,
1628 1629
    .domainShutdown = qemuProcessHandleShutdown,
    .domainStop = qemuProcessHandleStop,
1630
    .domainResume = qemuProcessHandleResume,
1631 1632 1633 1634 1635
    .domainReset = qemuProcessHandleReset,
    .domainRTCChange = qemuProcessHandleRTCChange,
    .domainWatchdog = qemuProcessHandleWatchdog,
    .domainIOError = qemuProcessHandleIOError,
    .domainGraphics = qemuProcessHandleGraphics,
1636
    .domainBlockJob = qemuProcessHandleBlockJob,
1637
    .domainTrayChange = qemuProcessHandleTrayChange,
O
Osier Yang 已提交
1638
    .domainPMWakeup = qemuProcessHandlePMWakeup,
O
Osier Yang 已提交
1639
    .domainPMSuspend = qemuProcessHandlePMSuspend,
1640
    .domainBalloonChange = qemuProcessHandleBalloonChange,
1641
    .domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
1642
    .domainGuestPanic = qemuProcessHandleGuestPanic,
1643
    .domainDeviceDeleted = qemuProcessHandleDeviceDeleted,
1644
    .domainNicRxFilterChanged = qemuProcessHandleNicRxFilterChanged,
1645
    .domainSerialChange = qemuProcessHandleSerialChanged,
1646
    .domainSpiceMigrated = qemuProcessHandleSpiceMigrated,
1647
    .domainMigrationStatus = qemuProcessHandleMigrationStatus,
1648
    .domainMigrationPass = qemuProcessHandleMigrationPass,
1649
    .domainAcpiOstInfo = qemuProcessHandleAcpiOstInfo,
1650 1651
};

1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
static void
qemuProcessMonitorReportLogError(qemuMonitorPtr mon,
                                 const char *msg,
                                 void *opaque);


static void
qemuProcessMonitorLogFree(void *opaque)
{
    qemuDomainLogContextPtr logCtxt = opaque;
    qemuDomainLogContextFree(logCtxt);
}

1665
static int
1666
qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob,
1667
                   qemuDomainLogContextPtr logCtxt)
1668 1669 1670
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int ret = -1;
1671
    qemuMonitorPtr mon = NULL;
1672

1673
    if (virSecurityManagerSetDaemonSocketLabel(driver->securityManager,
1674
                                               vm->def) < 0) {
1675 1676
        VIR_ERROR(_("Failed to set security context for monitor for %s"),
                  vm->def->name);
1677
        return -1;
1678 1679 1680
    }

    /* Hold an extra reference because we can't allow 'vm' to be
M
Michal Privoznik 已提交
1681
     * deleted unitl the monitor gets its own reference. */
1682
    virObjectRef(vm);
1683

1684
    ignore_value(virTimeMillisNow(&priv->monStart));
1685
    virObjectUnlock(vm);
1686 1687 1688 1689

    mon = qemuMonitorOpen(vm,
                          priv->monConfig,
                          priv->monJSON,
1690 1691
                          &monitorCallbacks,
                          driver);
1692

1693 1694 1695 1696 1697 1698 1699
    if (mon && logCtxt) {
        qemuDomainLogContextRef(logCtxt);
        qemuMonitorSetDomainLog(mon,
                                qemuProcessMonitorReportLogError,
                                logCtxt,
                                qemuProcessMonitorLogFree);
    }
1700

1701
    virObjectLock(vm);
M
Michal Privoznik 已提交
1702
    virObjectUnref(vm);
1703
    priv->monStart = 0;
1704

M
Michal Privoznik 已提交
1705
    if (!virDomainObjIsActive(vm)) {
1706
        qemuMonitorClose(mon);
1707
        mon = NULL;
1708 1709 1710
    }
    priv->mon = mon;

1711
    if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) {
1712 1713
        VIR_ERROR(_("Failed to clear security context for monitor for %s"),
                  vm->def->name);
1714
        return -1;
1715 1716 1717 1718
    }

    if (priv->mon == NULL) {
        VIR_INFO("Failed to connect monitor for %s", vm->def->name);
1719
        return -1;
1720 1721 1722
    }


1723
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
1724
        return -1;
1725

1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739
    if (qemuMonitorSetCapabilities(priv->mon) < 0)
        goto cleanup;

    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON) &&
        virQEMUCapsProbeQMP(priv->qemuCaps, priv->mon) < 0)
        goto cleanup;

    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT) &&
        qemuMonitorSetMigrationCapability(priv->mon,
                                          QEMU_MONITOR_MIGRATION_CAPS_EVENTS,
                                          true) < 0) {
        VIR_DEBUG("Cannot enable migration events; clearing capability");
        virQEMUCapsClear(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
    }
1740

1741 1742 1743 1744 1745
    ret = 0;

 cleanup:
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;
1746 1747 1748
    return ret;
}

1749 1750 1751

/**
 * qemuProcessReadLog: Read log file of a qemu VM
1752
 * @logCtxt: the domain log context
1753
 * @msg: pointer to buffer to store the read messages in
1754 1755
 *
 * Reads log of a qemu VM. Skips messages not produced by qemu or irrelevant
1756
 * messages. Returns returns 0 on success or -1 on error
1757
 */
1758
static int
1759
qemuProcessReadLog(qemuDomainLogContextPtr logCtxt, char **msg)
1760
{
1761 1762
    char *buf;
    ssize_t got;
1763
    char *eol;
1764
    char *filter_next;
1765

1766
    if ((got = qemuDomainLogContextRead(logCtxt, &buf)) < 0)
1767
        return -1;
1768

1769 1770 1771 1772 1773 1774 1775
    /* Filter out debug messages from intermediate libvirt process */
    filter_next = buf;
    while ((eol = strchr(filter_next, '\n'))) {
        *eol = '\0';
        if (virLogProbablyLogMessage(filter_next) ||
            STRPREFIX(filter_next, "char device redirected to")) {
            size_t skip = (eol + 1) - filter_next;
1776
            memmove(filter_next, eol + 1, buf + got - eol);
1777 1778 1779 1780
            got -= skip;
        } else {
            filter_next = eol + 1;
            *eol = '\n';
1781 1782
        }
    }
1783
    filter_next = NULL; /* silence false coverity warning */
1784

1785 1786
    if (got > 0 &&
        buf[got - 1] == '\n') {
1787 1788
        buf[got - 1] = '\0';
        got--;
1789
    }
1790
    ignore_value(VIR_REALLOC_N_QUIET(buf, got + 1));
1791 1792 1793
    *msg = buf;
    return 0;
}
1794 1795


1796 1797
static int
qemuProcessReportLogError(qemuDomainLogContextPtr logCtxt,
1798 1799 1800 1801
                          const char *msgprefix)
{
    char *logmsg = NULL;

1802
    if (qemuProcessReadLog(logCtxt, &logmsg) < 0)
1803 1804 1805
        return -1;

    virResetLastError();
1806 1807 1808 1809 1810
    if (virStringIsEmpty(logmsg))
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", msgprefix);
    else
        virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: %s"), msgprefix, logmsg);

1811 1812
    VIR_FREE(logmsg);
    return 0;
1813 1814 1815
}


1816 1817 1818 1819 1820 1821 1822 1823 1824 1825
static void
qemuProcessMonitorReportLogError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                 const char *msg,
                                 void *opaque)
{
    qemuDomainLogContextPtr logCtxt = opaque;
    qemuProcessReportLogError(logCtxt, msg);
}


1826
static int
1827 1828 1829
qemuProcessLookupPTYs(virDomainDefPtr def,
                      virQEMUCapsPtr qemuCaps,
                      virDomainChrDefPtr *devices,
1830
                      int count,
1831
                      virHashTablePtr info)
1832
{
1833
    size_t i;
1834

1835
    for (i = 0; i < count; i++) {
1836
        virDomainChrDefPtr chr = devices[i];
1837 1838
        bool chardevfmt = virQEMUCapsSupportsChardev(def, qemuCaps, chr);

1839
        if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
C
Cole Robinson 已提交
1840
            char id[32];
1841
            qemuMonitorChardevInfoPtr entry;
1842

C
Cole Robinson 已提交
1843
            if (snprintf(id, sizeof(id), "%s%s",
1844
                         chardevfmt ? "char" : "",
1845 1846 1847 1848
                         chr->info.alias) >= sizeof(id)) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("failed to format device alias "
                                 "for PTY retrieval"));
1849
                return -1;
1850
            }
1851

1852 1853
            entry = virHashLookup(info, id);
            if (!entry || !entry->ptyPath) {
1854 1855 1856 1857
                if (chr->source.data.file.path == NULL) {
                    /* neither the log output nor 'info chardev' had a
                     * pty path for this chardev, report an error
                     */
1858 1859
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("no assigned pty for device %s"), id);
1860 1861 1862 1863 1864 1865 1866 1867 1868 1869
                    return -1;
                } else {
                    /* 'info chardev' had no pty path for this chardev,
                     * but the log output had, so we're fine
                     */
                    continue;
                }
            }

            VIR_FREE(chr->source.data.file.path);
1870
            if (VIR_STRDUP(chr->source.data.file.path, entry->ptyPath) < 0)
1871 1872 1873 1874 1875 1876 1877
                return -1;
        }
    }

    return 0;
}

1878 1879
static int
qemuProcessFindCharDevicePTYsMonitor(virDomainObjPtr vm,
1880
                                     virQEMUCapsPtr qemuCaps,
1881
                                     virHashTablePtr info)
1882
{
1883
    size_t i = 0;
C
Cole Robinson 已提交
1884

1885 1886
    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
                              vm->def->serials, vm->def->nserials,
1887
                              info) < 0)
1888 1889
        return -1;

1890 1891
    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
                              vm->def->parallels, vm->def->nparallels,
1892
                              info) < 0)
1893
        return -1;
1894

1895 1896
    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
                              vm->def->channels, vm->def->nchannels,
1897
                              info) < 0)
1898
        return -1;
1899 1900 1901 1902
    /* For historical reasons, console[0] can be just an alias
     * for serial[0]. That's why we need to update it as well. */
    if (vm->def->nconsoles) {
        virDomainChrDefPtr chr = vm->def->consoles[0];
1903

1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914
        if (vm->def->nserials &&
            chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
            chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
            /* yes, the first console is just an alias for serials[0] */
            i = 1;
            if (virDomainChrSourceDefCopy(&chr->source,
                                          &((vm->def->serials[0])->source)) < 0)
                return -1;
        }
    }

1915 1916
    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
                              vm->def->consoles + i, vm->def->nconsoles - i,
1917
                              info) < 0)
1918
        return -1;
1919 1920 1921 1922 1923

    return 0;
}


1924
static int
1925 1926 1927 1928
qemuProcessRefreshChannelVirtioState(virQEMUDriverPtr driver,
                                     virDomainObjPtr vm,
                                     virHashTablePtr info,
                                     int booted)
1929 1930
{
    size_t i;
1931
    int agentReason = VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL;
1932
    qemuMonitorChardevInfoPtr entry;
1933
    virObjectEventPtr event = NULL;
1934 1935
    char id[32];

1936 1937 1938
    if (booted)
        agentReason = VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED;

1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954
    for (i = 0; i < vm->def->nchannels; i++) {
        virDomainChrDefPtr chr = vm->def->channels[i];
        if (chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
            if (snprintf(id, sizeof(id), "char%s",
                         chr->info.alias) >= sizeof(id)) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("failed to format device alias "
                                 "for PTY retrieval"));
                return -1;
            }

            /* port state not reported */
            if (!(entry = virHashLookup(info, id)) ||
                !entry->state)
                continue;

1955 1956 1957 1958 1959 1960
            if (entry->state != VIR_DOMAIN_CHR_DEVICE_STATE_DEFAULT &&
                STREQ_NULLABLE(chr->target.name, "org.qemu.guest_agent.0") &&
                (event = virDomainEventAgentLifecycleNewFromObj(vm, entry->state,
                                                                agentReason)))
                qemuDomainEventQueue(driver, event);

1961 1962 1963 1964 1965 1966 1967 1968
            chr->state = entry->state;
        }
    }

    return 0;
}


1969 1970
int
qemuRefreshVirtioChannelState(virQEMUDriverPtr driver,
1971 1972
                              virDomainObjPtr vm,
                              qemuDomainAsyncJob asyncJob)
1973 1974 1975 1976 1977
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virHashTablePtr info = NULL;
    int ret = -1;

1978 1979 1980
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto cleanup;

1981
    ret = qemuMonitorGetChardevInfo(priv->mon, &info);
1982 1983
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;
1984 1985 1986 1987

    if (ret < 0)
        goto cleanup;

1988
    ret = qemuProcessRefreshChannelVirtioState(driver, vm, info, false);
1989 1990 1991 1992 1993 1994

 cleanup:
    virHashFree(info);
    return ret;
}

1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030
static void
qemuRefreshRTC(virQEMUDriverPtr driver,
               virDomainObjPtr vm)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    time_t now, then;
    struct tm thenbits;
    long localOffset;
    int rv;

    if (vm->def->clock.offset != VIR_DOMAIN_CLOCK_OFFSET_VARIABLE)
        return;

    memset(&thenbits, 0, sizeof(thenbits));
    qemuDomainObjEnterMonitor(driver, vm);
    now = time(NULL);
    rv = qemuMonitorGetRTCTime(priv->mon, &thenbits);
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        rv = -1;

    if (rv < 0)
        return;

    thenbits.tm_isdst = -1;
    if ((then = mktime(&thenbits)) == (time_t) -1) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Unable to convert time"));
        return;
    }

    /* Thing is, @now is in local TZ but @then in UTC. */
    if (virTimeLocalOffsetFromUTC(&localOffset) < 0)
        return;

    vm->def->clock.data.variable.adjustment = then - now + localOffset;
}
2031

2032
int
2033 2034 2035 2036 2037 2038 2039 2040 2041
qemuProcessRefreshBalloonState(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
                               int asyncJob)
{
    unsigned long long balloon;
    int rc;

    /* if no ballooning is available, the current size equals to the current
     * full memory size */
2042
    if (!virDomainDefHasMemballoon(vm->def)) {
2043
        vm->def->mem.cur_balloon = virDomainDefGetMemoryTotal(vm->def);
2044 2045 2046 2047 2048 2049 2050
        return 0;
    }

    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        return -1;

    rc = qemuMonitorGetBalloonInfo(qemuDomainGetMonitor(vm), &balloon);
2051
    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
2052 2053 2054 2055 2056 2057 2058 2059
        return -1;

    vm->def->mem.cur_balloon = balloon;

    return 0;
}


2060
static int
2061
qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
C
Cole Robinson 已提交
2062
                          virDomainObjPtr vm,
2063
                          int asyncJob,
2064
                          virQEMUCapsPtr qemuCaps,
2065
                          qemuDomainLogContextPtr logCtxt)
2066 2067
{
    int ret = -1;
2068
    virHashTablePtr info = NULL;
2069
    qemuDomainObjPrivatePtr priv;
2070 2071

    VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name);
2072
    if (qemuConnectMonitor(driver, vm, asyncJob, logCtxt) < 0)
2073 2074 2075 2076 2077 2078
        goto cleanup;

    /* Try to get the pty path mappings again via the monitor. This is much more
     * reliable if it's available.
     * Note that the monitor itself can be on a pty, so we still need to try the
     * log output method. */
2079
    priv = vm->privateData;
2080 2081
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto cleanup;
2082 2083
    ret = qemuMonitorGetChardevInfo(priv->mon, &info);
    VIR_DEBUG("qemuMonitorGetChardevInfo returned %i", ret);
2084 2085 2086
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;

2087 2088 2089 2090 2091
    if (ret == 0) {
        if ((ret = qemuProcessFindCharDevicePTYsMonitor(vm, qemuCaps,
                                                        info)) < 0)
            goto cleanup;

2092 2093
        if ((ret = qemuProcessRefreshChannelVirtioState(driver, vm, info,
                                                        true)) < 0)
2094 2095
            goto cleanup;
    }
2096

2097
 cleanup:
2098
    virHashFree(info);
2099

2100 2101
    if (logCtxt && kill(vm->pid, 0) == -1 && errno == ESRCH) {
        qemuProcessReportLogError(logCtxt,
2102
                                  _("process exited while connecting to monitor"));
2103 2104 2105 2106 2107 2108
        ret = -1;
    }

    return ret;
}

2109

2110 2111 2112 2113 2114 2115
static int
qemuProcessDetectIOThreadPIDs(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              int asyncJob)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
2116
    qemuMonitorIOThreadInfoPtr *iothreads = NULL;
2117 2118 2119 2120
    int niothreads = 0;
    int ret = -1;
    size_t i;

2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144
    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) {
        /* The following check is because at one time a domain could
         * define iothreadids and start the domain - only failing the
         * capability check when attempting to add a disk. Because the
         * iothreads and [n]iothreadids were left untouched other code
         * assumed it could use the ->thread_id value to make thread_id
         * based adjustments (e.g. pinning, scheduling) which while
         * succeeding would execute on the calling thread.
         */
        if (vm->def->niothreadids) {
            for (i = 0; i < vm->def->niothreadids; i++) {
                /* Check if the domain had defined any iothreadid elements
                 * and supply a VIR_INFO indicating that it's being removed.
                 */
                if (!vm->def->iothreadids[i]->autofill)
                    VIR_INFO("IOThreads not supported, remove iothread id '%u'",
                             vm->def->iothreadids[i]->iothread_id);
                virDomainIOThreadIDDefFree(vm->def->iothreadids[i]);
            }
            /* Remove any trace */
            VIR_FREE(vm->def->iothreadids);
            vm->def->niothreadids = 0;
            vm->def->iothreads = 0;
        }
2145
        return 0;
2146
    }
2147

2148 2149 2150 2151
    /* Get the list of IOThreads from qemu */
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto cleanup;
    niothreads = qemuMonitorGetIOThreads(priv->mon, &iothreads);
2152 2153
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        goto cleanup;
J
John Ferlan 已提交
2154
    if (niothreads < 0)
2155 2156
        goto cleanup;

2157
    if (niothreads != vm->def->niothreadids) {
2158 2159
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("got wrong number of IOThread pids from QEMU monitor. "
2160 2161
                         "got %d, wanted %zu"),
                       niothreads, vm->def->niothreadids);
2162 2163 2164
        goto cleanup;
    }

2165 2166 2167 2168 2169 2170
    /* Nothing to do */
    if (niothreads == 0) {
        ret = 0;
        goto cleanup;
    }

2171 2172 2173
    for (i = 0; i < niothreads; i++) {
        virDomainIOThreadIDDefPtr iothrid;

2174 2175
        if (!(iothrid = virDomainIOThreadIDFind(vm->def,
                                                iothreads[i]->iothread_id))) {
2176
            virReportError(VIR_ERR_INTERNAL_ERROR,
2177 2178
                           _("iothread %d not found"),
                           iothreads[i]->iothread_id);
2179 2180 2181 2182
            goto cleanup;
        }
        iothrid->thread_id = iothreads[i]->thread_id;
    }
2183 2184 2185 2186 2187 2188

    ret = 0;

 cleanup:
    if (iothreads) {
        for (i = 0; i < niothreads; i++)
2189
            VIR_FREE(iothreads[i]);
2190 2191 2192 2193 2194
        VIR_FREE(iothreads);
    }
    return ret;
}

2195 2196 2197 2198 2199

/*
 * To be run between fork/exec of QEMU only
 */
static int
2200
qemuProcessInitCpuAffinity(virDomainObjPtr vm)
2201 2202 2203 2204
{
    int ret = -1;
    virBitmapPtr cpumap = NULL;
    virBitmapPtr cpumapToSet = NULL;
2205
    qemuDomainObjPrivatePtr priv = vm->privateData;
2206

2207 2208 2209 2210 2211 2212
    if (!vm->pid) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Cannot setup CPU affinity until process is started"));
        return -1;
    }

2213 2214
    if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
        VIR_DEBUG("Set CPU affinity with advisory nodeset from numad");
2215
        cpumapToSet = priv->autoCpuset;
2216
    } else {
2217
        VIR_DEBUG("Set CPU affinity with specified cpuset");
O
Osier Yang 已提交
2218
        if (vm->def->cpumask) {
H
Hu Tao 已提交
2219
            cpumapToSet = vm->def->cpumask;
O
Osier Yang 已提交
2220 2221 2222 2223 2224
        } else {
            /* You may think this is redundant, but we can't assume libvirtd
             * itself is running on all pCPUs, so we need to explicitly set
             * the spawned QEMU instance to all pCPUs if no map is given in
             * its config file */
2225 2226 2227 2228
            int hostcpus;

            /* setaffinity fails if you set bits for CPUs which
             * aren't present, so we have to limit ourselves */
2229
            if ((hostcpus = virHostCPUGetCount()) < 0)
2230 2231 2232 2233 2234 2235 2236 2237
                goto cleanup;

            if (hostcpus > QEMUD_CPUMASK_LEN)
                hostcpus = QEMUD_CPUMASK_LEN;

            if (!(cpumap = virBitmapNew(hostcpus)))
                goto cleanup;

2238
            virBitmapSetAll(cpumap);
2239 2240

            cpumapToSet = cpumap;
O
Osier Yang 已提交
2241
        }
2242 2243
    }

2244
    if (virProcessSetAffinity(vm->pid, cpumapToSet) < 0)
2245
        goto cleanup;
2246

2247 2248
    ret = 0;

2249
 cleanup:
2250
    virBitmapFree(cpumap);
2251
    return ret;
2252 2253
}

2254 2255
/* set link states to down on interfaces at qemu start */
static int
2256 2257 2258
qemuProcessSetLinkStates(virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
                         qemuDomainAsyncJob asyncJob)
2259 2260 2261
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virDomainDefPtr def = vm->def;
2262
    size_t i;
2263 2264 2265 2266 2267
    int ret = -1;
    int rv;

    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        return -1;
2268 2269 2270

    for (i = 0; i < def->nnets; i++) {
        if (def->nets[i]->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
2271 2272 2273
            if (!def->nets[i]->info.alias) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing alias for network device"));
2274
                goto cleanup;
2275 2276
            }

2277 2278
            VIR_DEBUG("Setting link state: %s", def->nets[i]->info.alias);

2279
            if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
2280
                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2281
                               _("Setting of link state is not supported by this qemu"));
2282
                goto cleanup;
2283 2284
            }

2285 2286 2287 2288
            rv = qemuMonitorSetLink(priv->mon,
                                    def->nets[i]->info.alias,
                                    VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN);
            if (rv < 0) {
2289
                virReportError(VIR_ERR_OPERATION_FAILED,
2290 2291 2292
                               _("Couldn't set link state on interface: %s"),
                               def->nets[i]->info.alias);
                goto cleanup;
2293 2294 2295 2296
            }
        }
    }

2297 2298 2299 2300 2301
    ret = 0;

 cleanup:
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;
2302 2303 2304
    return ret;
}

2305

2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413
/**
 * qemuProcessSetupPid:
 *
 * This function sets resource properities (affinity, cgroups,
 * scheduler) for any PID associated with a domain.  It should be used
 * to set up emulator PIDs as well as vCPU and I/O thread pids to
 * ensure they are all handled the same way.
 *
 * Returns 0 on success, -1 on error.
 */
static int
qemuProcessSetupPid(virDomainObjPtr vm,
                    pid_t pid,
                    virCgroupThreadName nameval,
                    int id,
                    virBitmapPtr cpumask,
                    unsigned long long period,
                    long long quota,
                    virDomainThreadSchedParamPtr sched)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virDomainNumatuneMemMode mem_mode;
    virCgroupPtr cgroup = NULL;
    virBitmapPtr use_cpumask;
    char *mem_mask = NULL;
    int ret = -1;

    if ((period || quota) &&
        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("cgroup cpu is required for scheduler tuning"));
        goto cleanup;
    }

    /* Infer which cpumask shall be used. */
    if (cpumask)
        use_cpumask = cpumask;
    else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
        use_cpumask = priv->autoCpuset;
    else
        use_cpumask = vm->def->cpumask;

    /*
     * If CPU cgroup controller is not initialized here, then we need
     * neither period nor quota settings.  And if CPUSET controller is
     * not initialized either, then there's nothing to do anyway.
     */
    if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) ||
        virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {

        if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
            mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
            virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
                                                priv->autoNodeset,
                                                &mem_mask, -1) < 0)
            goto cleanup;

        if (virCgroupNewThread(priv->cgroup, nameval, id, true, &cgroup) < 0)
            goto cleanup;

        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
            if (use_cpumask &&
                qemuSetupCgroupCpusetCpus(cgroup, use_cpumask) < 0)
                goto cleanup;

            /*
             * Don't setup cpuset.mems for the emulator, they need to
             * be set up after initialization in order for kvm
             * allocations to succeed.
             */
            if (nameval != VIR_CGROUP_THREAD_EMULATOR &&
                mem_mask && virCgroupSetCpusetMems(cgroup, mem_mask) < 0)
                goto cleanup;

        }

        if ((period || quota) &&
            qemuSetupCgroupVcpuBW(cgroup, period, quota) < 0)
            goto cleanup;

        /* Move the thread to the sub dir */
        if (virCgroupAddTask(cgroup, pid) < 0)
            goto cleanup;

    }

    /* Setup legacy affinity. */
    if (use_cpumask && virProcessSetAffinity(pid, use_cpumask) < 0)
        goto cleanup;

    /* Set scheduler type and priority. */
    if (sched &&
        virProcessSetScheduler(pid, sched->policy, sched->priority) < 0)
        goto cleanup;

    ret = 0;
 cleanup:
    VIR_FREE(mem_mask);
    if (cgroup) {
        if (ret < 0)
            virCgroupRemove(cgroup);
        virCgroupFree(&cgroup);
    }

    return ret;
}


2414
static int
2415
qemuProcessSetupEmulator(virDomainObjPtr vm)
2416
{
2417 2418 2419 2420 2421
    return qemuProcessSetupPid(vm, vm->pid, VIR_CGROUP_THREAD_EMULATOR,
                               0, vm->def->cputune.emulatorpin,
                               vm->def->cputune.emulator_period,
                               vm->def->cputune.emulator_quota,
                               NULL);
2422 2423
}

2424

2425 2426
static int
qemuProcessInitPasswords(virConnectPtr conn,
2427
                         virQEMUDriverPtr driver,
2428 2429
                         virDomainObjPtr vm,
                         int asyncJob)
2430 2431 2432
{
    int ret = 0;
    qemuDomainObjPrivatePtr priv = vm->privateData;
2433
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2434
    size_t i;
2435 2436
    char *alias = NULL;
    char *secret = NULL;
2437

2438
    for (i = 0; i < vm->def->ngraphics; ++i) {
2439 2440
        virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
2441 2442
            ret = qemuDomainChangeGraphicsPasswords(driver, vm,
                                                    VIR_DOMAIN_GRAPHICS_TYPE_VNC,
2443
                                                    &graphics->data.vnc.auth,
2444 2445
                                                    cfg->vncPassword,
                                                    asyncJob);
2446
        } else if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
2447 2448
            ret = qemuDomainChangeGraphicsPasswords(driver, vm,
                                                    VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
2449
                                                    &graphics->data.spice.auth,
2450 2451
                                                    cfg->spicePassword,
                                                    asyncJob);
2452 2453
        }

2454 2455 2456
        if (ret < 0)
            goto cleanup;
    }
2457

2458 2459
    for (i = 0; i < vm->def->ndisks; i++) {
        size_t secretLen;
2460

2461 2462 2463
        if (!vm->def->disks[i]->src->encryption ||
            !virDomainDiskGetSource(vm->def->disks[i]))
            continue;
2464

2465 2466 2467 2468 2469 2470
        if (vm->def->disks[i]->src->encryption->format !=
            VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT &&
            vm->def->disks[i]->src->encryption->format !=
            VIR_STORAGE_ENCRYPTION_FORMAT_QCOW)
            continue;

2471 2472 2473 2474 2475
        VIR_FREE(secret);
        if (qemuProcessGetVolumeQcowPassphrase(conn,
                                               vm->def->disks[i],
                                               &secret, &secretLen) < 0)
            goto cleanup;
2476

2477
        VIR_FREE(alias);
2478
        if (!(alias = qemuAliasFromDisk(vm->def->disks[i])))
2479 2480 2481 2482 2483 2484 2485 2486
            goto cleanup;
        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
            goto cleanup;
        ret = qemuMonitorSetDrivePassphrase(priv->mon, alias, secret);
        if (qemuDomainObjExitMonitor(driver, vm) < 0)
            ret = -1;
        if (ret < 0)
            goto cleanup;
2487 2488
    }

2489
 cleanup:
2490 2491
    VIR_FREE(alias);
    VIR_FREE(secret);
2492
    virObjectUnref(cfg);
2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519
    return ret;
}


static int
qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
                                virDomainChrDefPtr dev,
                                void *opaque ATTRIBUTE_UNUSED)
{
    int fd;
    if (dev->source.type != VIR_DOMAIN_CHR_TYPE_FILE)
        return 0;

    if ((fd = open(dev->source.data.file.path,
                   O_CREAT | O_APPEND, S_IRUSR|S_IWUSR)) < 0) {
        virReportSystemError(errno,
                             _("Unable to pre-create chardev file '%s'"),
                             dev->source.data.file.path);
        return -1;
    }

    VIR_FORCE_CLOSE(fd);

    return 0;
}


2520 2521 2522 2523 2524 2525
static int
qemuProcessCleanupChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
                                virDomainChrDefPtr dev,
                                void *opaque ATTRIBUTE_UNUSED)
{
    if (dev->source.type == VIR_DOMAIN_CHR_TYPE_UNIX &&
2526 2527
        dev->source.data.nix.listen &&
        dev->source.data.nix.path)
2528 2529 2530 2531 2532 2533
        unlink(dev->source.data.nix.path);

    return 0;
}


2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569
/**
 * Loads and update video memory size for video devices according to QEMU
 * process as the QEMU will silently update the values that we pass to QEMU
 * through command line.  We need to load these updated values and store them
 * into the status XML.
 *
 * We will fail if for some reason the values cannot be loaded from QEMU because
 * its mandatory to get the correct video memory size to status XML to not break
 * migration.
 */
static int
qemuProcessUpdateVideoRamSize(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              int asyncJob)
{
    int ret = -1;
    ssize_t i;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virDomainVideoDefPtr video = NULL;
    virQEMUDriverConfigPtr cfg = NULL;

    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        return -1;

    for (i = 0; i < vm->def->nvideos; i++) {
        video = vm->def->videos[i];

        switch (video->type) {
        case VIR_DOMAIN_VIDEO_TYPE_VGA:
            if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VGA_VGAMEM)) {
                if (qemuMonitorUpdateVideoMemorySize(priv->mon, video, "VGA") < 0)
                    goto error;
            }
            break;
        case VIR_DOMAIN_VIDEO_TYPE_QXL:
            if (i == 0) {
2570 2571 2572
                if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM) &&
                    qemuMonitorUpdateVideoMemorySize(priv->mon, video,
                                                     "qxl-vga") < 0)
2573
                        goto error;
2574 2575 2576 2577 2578

                if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGA_VRAM64) &&
                    qemuMonitorUpdateVideoVram64Size(priv->mon, video,
                                                     "qxl-vga") < 0)
                    goto error;
2579
            } else {
2580 2581 2582 2583 2584 2585 2586 2587
                if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGAMEM) &&
                    qemuMonitorUpdateVideoMemorySize(priv->mon, video,
                                                     "qxl") < 0)
                        goto error;

                if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VRAM64) &&
                    qemuMonitorUpdateVideoVram64Size(priv->mon, video,
                                                     "qxl") < 0)
2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606
                        goto error;
            }
            break;
        case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
            if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VMWARE_SVGA_VGAMEM)) {
                if (qemuMonitorUpdateVideoMemorySize(priv->mon, video,
                                                     "vmware-svga") < 0)
                    goto error;
            }
            break;
        case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
        case VIR_DOMAIN_VIDEO_TYPE_XEN:
        case VIR_DOMAIN_VIDEO_TYPE_VBOX:
        case VIR_DOMAIN_VIDEO_TYPE_LAST:
            break;
        }

    }

2607 2608
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        return -1;
2609 2610

    cfg = virQEMUDriverGetConfig(driver);
2611
    ret = virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps);
2612 2613 2614 2615 2616
    virObjectUnref(cfg);

    return ret;

 error:
2617
    ignore_value(qemuDomainObjExitMonitor(driver, vm));
2618 2619 2620 2621
    return -1;
}


2622 2623 2624
struct qemuProcessHookData {
    virConnectPtr conn;
    virDomainObjPtr vm;
2625
    virQEMUDriverPtr driver;
2626
    virQEMUDriverConfigPtr cfg;
2627 2628 2629 2630 2631
};

static int qemuProcessHook(void *data)
{
    struct qemuProcessHookData *h = data;
2632
    qemuDomainObjPrivatePtr priv = h->vm->privateData;
2633
    int ret = -1;
2634
    int fd;
2635 2636 2637
    virBitmapPtr nodeset = NULL;
    virDomainNumatuneMemMode mode;

2638 2639 2640 2641 2642
    /* This method cannot use any mutexes, which are not
     * protected across fork()
     */

    virSecurityManagerPostFork(h->driver->securityManager);
2643 2644 2645 2646 2647

    /* Some later calls want pid present */
    h->vm->pid = getpid();

    VIR_DEBUG("Obtaining domain lock");
2648 2649 2650 2651 2652 2653 2654
    /*
     * Since we're going to leak the returned FD to QEMU,
     * we need to make sure it gets a sensible label.
     * This mildly sucks, because there could be other
     * sockets the lock driver opens that we don't want
     * labelled. So far we're ok though.
     */
2655
    if (virSecurityManagerSetSocketLabel(h->driver->securityManager, h->vm->def) < 0)
2656
        goto cleanup;
2657
    if (virDomainLockProcessStart(h->driver->lockManager,
2658
                                  h->cfg->uri,
2659
                                  h->vm,
J
Ján Tomko 已提交
2660
                                  /* QEMU is always paused initially */
2661 2662
                                  true,
                                  &fd) < 0)
2663
        goto cleanup;
2664
    if (virSecurityManagerClearSocketLabel(h->driver->securityManager, h->vm->def) < 0)
2665
        goto cleanup;
2666

2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677
    if (virDomainNumatuneGetMode(h->vm->def->numa, -1, &mode) == 0) {
        if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
            h->cfg->cgroupControllers & (1 << VIR_CGROUP_CONTROLLER_CPUSET) &&
            virCgroupControllerAvailable(VIR_CGROUP_CONTROLLER_CPUSET)) {
            /* Use virNuma* API iff necessary. Once set and child is exec()-ed,
             * there's no way for us to change it. Rely on cgroups (if available
             * and enabled in the config) rather than virNuma*. */
            VIR_DEBUG("Relying on CGroups for memory binding");
        } else {
            nodeset = virDomainNumatuneGetNodeset(h->vm->def->numa,
                                                  priv->autoNodeset, -1);
2678

2679 2680 2681
            if (virNumaSetupMemoryPolicy(mode, nodeset) < 0)
                goto cleanup;
        }
2682
    }
2683

2684 2685
    ret = 0;

2686
 cleanup:
2687
    virObjectUnref(h->cfg);
2688 2689
    VIR_DEBUG("Hook complete ret=%d", ret);
    return ret;
2690 2691 2692
}

int
2693 2694
qemuProcessPrepareMonitorChr(virDomainChrSourceDefPtr monConfig,
                             const char *domainDir)
2695 2696 2697 2698
{
    monConfig->type = VIR_DOMAIN_CHR_TYPE_UNIX;
    monConfig->data.nix.listen = true;

2699 2700
    if (virAsprintf(&monConfig->data.nix.path, "%s/monitor.sock",
                    domainDir) < 0)
2701 2702
        return -1;
    return 0;
2703 2704 2705
}


2706
/*
2707 2708
 * Precondition: vm must be locked, and a job must be active.
 * This method will call {Enter,Exit}Monitor
2709
 */
E
Eric Blake 已提交
2710
int
2711
qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
2712
                     virConnectPtr conn, virDomainRunningReason reason,
2713
                     qemuDomainAsyncJob asyncJob)
2714
{
2715
    int ret = -1;
2716
    qemuDomainObjPrivatePtr priv = vm->privateData;
2717
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2718

2719
    /* Bring up netdevs before starting CPUs */
2720
    if (qemuInterfaceStartDevices(vm->def) < 0)
2721 2722
       goto cleanup;

2723
    VIR_DEBUG("Using lock state '%s'", NULLSTR(priv->lockState));
2724
    if (virDomainLockProcessResume(driver->lockManager, cfg->uri,
2725
                                   vm, priv->lockState) < 0) {
2726 2727 2728 2729
        /* Don't free priv->lockState on error, because we need
         * to make sure we have state still present if the user
         * tries to resume again
         */
2730
        goto cleanup;
2731 2732 2733
    }
    VIR_FREE(priv->lockState);

2734 2735
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto release;
J
Jiri Denemark 已提交
2736

2737
    ret = qemuMonitorStartCPUs(priv->mon, conn);
2738 2739
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;
2740 2741 2742 2743 2744

    if (ret < 0)
        goto release;

    virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
2745

2746
 cleanup:
2747
    virObjectUnref(cfg);
2748
    return ret;
2749 2750 2751 2752 2753 2754

 release:
    if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
        VIR_WARN("Unable to release lease on %s", vm->def->name);
    VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
    goto cleanup;
2755 2756 2757
}


2758 2759
int qemuProcessStopCPUs(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
2760
                        virDomainPausedReason reason,
2761
                        qemuDomainAsyncJob asyncJob)
2762
{
2763
    int ret = -1;
2764 2765
    qemuDomainObjPrivatePtr priv = vm->privateData;

2766
    VIR_FREE(priv->lockState);
J
Jiri Denemark 已提交
2767

2768 2769
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto cleanup;
J
Jiri Denemark 已提交
2770

2771
    ret = qemuMonitorStopCPUs(priv->mon);
2772 2773
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;
2774 2775 2776 2777

    if (ret < 0)
        goto cleanup;

2778 2779 2780
    /* de-activate netdevs after stopping CPUs */
    ignore_value(qemuInterfaceStopDevices(vm->def));

2781 2782 2783
    if (priv->job.current)
        ignore_value(virTimeMillisNow(&priv->job.current->stopped));

2784 2785 2786 2787
    virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
    if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
        VIR_WARN("Unable to release lease on %s", vm->def->name);
    VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
J
Jiri Denemark 已提交
2788

2789
 cleanup:
2790 2791 2792 2793 2794
    return ret;
}



2795 2796 2797
static int
qemuProcessNotifyNets(virDomainDefPtr def)
{
2798
    size_t i;
2799

2800 2801
    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
2802 2803 2804 2805 2806 2807 2808 2809
        /* keep others from trying to use the macvtap device name, but
         * don't return error if this happens, since that causes the
         * domain to be unceremoniously killed, which would be *very*
         * impolite.
         */
        if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT)
           ignore_value(virNetDevMacVLanReserveName(net->ifname, false));

2810
        if (networkNotifyActualDevice(def, net) < 0)
2811 2812 2813 2814 2815
            return -1;
    }
    return 0;
}

2816
static int
2817
qemuProcessFiltersInstantiate(virDomainDefPtr def)
2818
{
2819
    size_t i;
2820

2821
    for (i = 0; i < def->nnets; i++) {
2822 2823
        virDomainNetDefPtr net = def->nets[i];
        if ((net->filter) && (net->ifname)) {
2824
            if (virDomainConfNWFilterInstantiate(def->uuid, net) < 0)
J
Ján Tomko 已提交
2825
                return 1;
2826 2827 2828
        }
    }

J
Ján Tomko 已提交
2829
    return 0;
2830 2831
}

2832
static int
2833
qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm)
2834 2835 2836
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virDomainState state;
2837
    virDomainPausedReason reason;
2838
    virDomainState newState = VIR_DOMAIN_NOSTATE;
2839
    int oldReason;
2840
    int newReason;
2841
    bool running;
2842
    char *msg = NULL;
2843 2844
    int ret;

2845
    qemuDomainObjEnterMonitor(driver, vm);
2846
    ret = qemuMonitorGetStatus(priv->mon, &running, &reason);
2847 2848
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        return -1;
2849

2850
    if (ret < 0)
2851 2852
        return -1;

2853
    state = virDomainObjGetState(vm, &oldReason);
2854

2855 2856 2857 2858 2859 2860 2861 2862
    if (running &&
        (state == VIR_DOMAIN_SHUTOFF ||
         (state == VIR_DOMAIN_PAUSED &&
          oldReason == VIR_DOMAIN_PAUSED_STARTING_UP))) {
        newState = VIR_DOMAIN_RUNNING;
        newReason = VIR_DOMAIN_RUNNING_BOOTED;
        ignore_value(VIR_STRDUP_QUIET(msg, "finished booting"));
    } else if (state == VIR_DOMAIN_PAUSED && running) {
2863 2864
        newState = VIR_DOMAIN_RUNNING;
        newReason = VIR_DOMAIN_RUNNING_UNPAUSED;
2865
        ignore_value(VIR_STRDUP_QUIET(msg, "was unpaused"));
2866
    } else if (state == VIR_DOMAIN_RUNNING && !running) {
2867 2868 2869
        if (reason == VIR_DOMAIN_PAUSED_SHUTTING_DOWN) {
            newState = VIR_DOMAIN_SHUTDOWN;
            newReason = VIR_DOMAIN_SHUTDOWN_UNKNOWN;
2870
            ignore_value(VIR_STRDUP_QUIET(msg, "shutdown"));
2871
        } else if (reason == VIR_DOMAIN_PAUSED_CRASHED) {
2872 2873 2874
            newState = VIR_DOMAIN_CRASHED;
            newReason = VIR_DOMAIN_CRASHED_PANICKED;
            ignore_value(VIR_STRDUP_QUIET(msg, "crashed"));
2875 2876 2877
        } else {
            newState = VIR_DOMAIN_PAUSED;
            newReason = reason;
S
Stefan Berger 已提交
2878 2879
            ignore_value(virAsprintf(&msg, "was paused (%s)",
                                 virDomainPausedReasonTypeToString(reason)));
2880 2881 2882 2883 2884 2885 2886
        }
    }

    if (newState != VIR_DOMAIN_NOSTATE) {
        VIR_DEBUG("Domain %s %s while its monitor was disconnected;"
                  " changing state to %s (%s)",
                  vm->def->name,
2887
                  NULLSTR(msg),
2888 2889 2890 2891
                  virDomainStateTypeToString(newState),
                  virDomainStateReasonToString(newState, newReason));
        VIR_FREE(msg);
        virDomainObjSetState(vm, newState, newReason);
2892 2893 2894 2895 2896
    }

    return 0;
}

2897
static int
2898 2899 2900 2901 2902
qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              virConnectPtr conn,
                              qemuMigrationJobPhase phase,
                              virDomainState state,
2903
                              int reason)
2904
{
2905 2906 2907 2908 2909
    bool postcopy = (state == VIR_DOMAIN_PAUSED &&
                     reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED) ||
                    (state == VIR_DOMAIN_RUNNING &&
                     reason == VIR_DOMAIN_RUNNING_POSTCOPY);

2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925
    switch (phase) {
    case QEMU_MIGRATION_PHASE_NONE:
    case QEMU_MIGRATION_PHASE_PERFORM2:
    case QEMU_MIGRATION_PHASE_BEGIN3:
    case QEMU_MIGRATION_PHASE_PERFORM3:
    case QEMU_MIGRATION_PHASE_PERFORM3_DONE:
    case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED:
    case QEMU_MIGRATION_PHASE_CONFIRM3:
    case QEMU_MIGRATION_PHASE_LAST:
        /* N/A for incoming migration */
        break;

    case QEMU_MIGRATION_PHASE_PREPARE:
        VIR_DEBUG("Killing unfinished incoming migration for domain %s",
                  vm->def->name);
        return -1;
2926

2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941
    case QEMU_MIGRATION_PHASE_FINISH2:
        /* source domain is already killed so let's just resume the domain
         * and hope we are all set */
        VIR_DEBUG("Incoming migration finished, resuming domain %s",
                  vm->def->name);
        if (qemuProcessStartCPUs(driver, vm, conn,
                                 VIR_DOMAIN_RUNNING_UNPAUSED,
                                 QEMU_ASYNC_JOB_NONE) < 0) {
            VIR_WARN("Could not resume domain %s", vm->def->name);
        }
        break;

    case QEMU_MIGRATION_PHASE_FINISH3:
        /* migration finished, we started resuming the domain but didn't
         * confirm success or failure yet; killing it seems safest unless
2942 2943 2944 2945
         * we already started guest CPUs or we were in post-copy mode */
        if (postcopy) {
            qemuMigrationPostcopyFailed(driver, vm);
        } else if (state != VIR_DOMAIN_RUNNING) {
2946
            VIR_DEBUG("Killing migrated domain %s", vm->def->name);
2947
            return -1;
2948 2949 2950
        }
        break;
    }
2951

2952 2953
    return 0;
}
2954

2955 2956 2957 2958 2959 2960 2961 2962
static int
qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
                               virConnectPtr conn,
                               qemuMigrationJobPhase phase,
                               virDomainState state,
                               int reason)
{
2963 2964 2965 2966
    bool postcopy = state == VIR_DOMAIN_PAUSED &&
                    (reason == VIR_DOMAIN_PAUSED_POSTCOPY ||
                     reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED);

2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983
    switch (phase) {
    case QEMU_MIGRATION_PHASE_NONE:
    case QEMU_MIGRATION_PHASE_PREPARE:
    case QEMU_MIGRATION_PHASE_FINISH2:
    case QEMU_MIGRATION_PHASE_FINISH3:
    case QEMU_MIGRATION_PHASE_LAST:
        /* N/A for outgoing migration */
        break;

    case QEMU_MIGRATION_PHASE_BEGIN3:
        /* nothing happened so far, just forget we were about to migrate the
         * domain */
        break;

    case QEMU_MIGRATION_PHASE_PERFORM2:
    case QEMU_MIGRATION_PHASE_PERFORM3:
        /* migration is still in progress, let's cancel it and resume the
2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996
         * domain; however we can only do that before migration enters
         * post-copy mode
         */
        if (postcopy) {
            qemuMigrationPostcopyFailed(driver, vm);
        } else {
            VIR_DEBUG("Cancelling unfinished migration of domain %s",
                      vm->def->name);
            if (qemuMigrationCancel(driver, vm) < 0) {
                VIR_WARN("Could not cancel ongoing migration of domain %s",
                         vm->def->name);
            }
            goto resume;
2997
        }
2998
        break;
2999

3000 3001
    case QEMU_MIGRATION_PHASE_PERFORM3_DONE:
        /* migration finished but we didn't have a chance to get the result
3002 3003
         * of Finish3 step; third party needs to check what to do next; in
         * post-copy mode we can use PAUSED_POSTCOPY_FAILED state for this
3004
         */
3005 3006
        if (postcopy)
            qemuMigrationPostcopyFailed(driver, vm);
3007
        break;
3008

3009
    case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED:
3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021
        /* Finish3 failed, we need to resume the domain, but once we enter
         * post-copy mode there's no way back, so let's just mark the domain
         * as broken in that case
         */
        if (postcopy) {
            qemuMigrationPostcopyFailed(driver, vm);
        } else {
            VIR_DEBUG("Resuming domain %s after failed migration",
                      vm->def->name);
            goto resume;
        }
        break;
3022

3023 3024 3025 3026
    case QEMU_MIGRATION_PHASE_CONFIRM3:
        /* migration completed, we need to kill the domain here */
        return -1;
    }
3027

3028
    return 0;
3029

3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040
 resume:
    /* resume the domain but only if it was paused as a result of
     * migration
     */
    if (state == VIR_DOMAIN_PAUSED &&
        (reason == VIR_DOMAIN_PAUSED_MIGRATION ||
         reason == VIR_DOMAIN_PAUSED_UNKNOWN)) {
        if (qemuProcessStartCPUs(driver, vm, conn,
                                 VIR_DOMAIN_RUNNING_UNPAUSED,
                                 QEMU_ASYNC_JOB_NONE) < 0) {
            VIR_WARN("Could not resume domain %s", vm->def->name);
3041 3042 3043 3044 3045
        }
    }
    return 0;
}

3046
static int
3047
qemuProcessRecoverJob(virQEMUDriverPtr driver,
3048 3049 3050 3051
                      virDomainObjPtr vm,
                      virConnectPtr conn,
                      const struct qemuDomainJobObj *job)
{
3052
    qemuDomainObjPrivatePtr priv = vm->privateData;
3053 3054 3055 3056 3057 3058 3059
    virDomainState state;
    int reason;

    state = virDomainObjGetState(vm, &reason);

    switch (job->asyncJob) {
    case QEMU_ASYNC_JOB_MIGRATION_OUT:
3060 3061 3062 3063 3064
        if (qemuProcessRecoverMigrationOut(driver, vm, conn, job->phase,
                                           state, reason) < 0)
            return -1;
        break;

3065
    case QEMU_ASYNC_JOB_MIGRATION_IN:
3066 3067
        if (qemuProcessRecoverMigrationIn(driver, vm, conn, job->phase,
                                          state, reason) < 0)
3068
            return -1;
3069 3070 3071 3072
        break;

    case QEMU_ASYNC_JOB_SAVE:
    case QEMU_ASYNC_JOB_DUMP:
3073
    case QEMU_ASYNC_JOB_SNAPSHOT:
3074
        qemuDomainObjEnterMonitor(driver, vm);
3075
        ignore_value(qemuMonitorMigrateCancel(priv->mon));
3076 3077
        if (qemuDomainObjExitMonitor(driver, vm) < 0)
            return -1;
3078
        /* resume the domain but only if it was paused as a result of
3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094
         * running a migration-to-file operation.  Although we are
         * recovering an async job, this function is run at startup
         * and must resume things using sync monitor connections.  */
         if (state == VIR_DOMAIN_PAUSED &&
             ((job->asyncJob == QEMU_ASYNC_JOB_DUMP &&
               reason == VIR_DOMAIN_PAUSED_DUMP) ||
              (job->asyncJob == QEMU_ASYNC_JOB_SAVE &&
               reason == VIR_DOMAIN_PAUSED_SAVE) ||
              (job->asyncJob == QEMU_ASYNC_JOB_SNAPSHOT &&
               reason == VIR_DOMAIN_PAUSED_SNAPSHOT) ||
              reason == VIR_DOMAIN_PAUSED_UNKNOWN)) {
             if (qemuProcessStartCPUs(driver, vm, conn,
                                      VIR_DOMAIN_RUNNING_UNPAUSED,
                                      QEMU_ASYNC_JOB_NONE) < 0) {
                 VIR_WARN("Could not resume domain '%s' after migration to file",
                          vm->def->name);
3095 3096 3097 3098
            }
        }
        break;

3099 3100 3101 3102
    case QEMU_ASYNC_JOB_START:
        /* Already handled in VIR_DOMAIN_PAUSED_STARTING_UP check. */
        break;

3103 3104 3105 3106 3107 3108 3109 3110
    case QEMU_ASYNC_JOB_NONE:
    case QEMU_ASYNC_JOB_LAST:
        break;
    }

    if (!virDomainObjIsActive(vm))
        return -1;

3111 3112 3113 3114
    /* In case any special handling is added for job type that has been ignored
     * before, QEMU_DOMAIN_TRACK_JOBS (from qemu_domain.h) needs to be updated
     * for the job to be properly tracked in domain state XML.
     */
3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134
    switch (job->active) {
    case QEMU_JOB_QUERY:
        /* harmless */
        break;

    case QEMU_JOB_DESTROY:
        VIR_DEBUG("Domain %s should have already been destroyed",
                  vm->def->name);
        return -1;

    case QEMU_JOB_SUSPEND:
        /* mostly harmless */
        break;

    case QEMU_JOB_MODIFY:
        /* XXX depending on the command we may be in an inconsistent state and
         * we should probably fall back to "monitor error" state and refuse to
         */
        break;

3135
    case QEMU_JOB_MIGRATION_OP:
3136
    case QEMU_JOB_ABORT:
3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147
    case QEMU_JOB_ASYNC:
    case QEMU_JOB_ASYNC_NESTED:
        /* async job was already handled above */
    case QEMU_JOB_NONE:
    case QEMU_JOB_LAST:
        break;
    }

    return 0;
}

3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162
static int
qemuProcessUpdateDevices(virQEMUDriverPtr driver,
                         virDomainObjPtr vm)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virDomainDeviceDef dev;
    char **old;
    char **tmp;
    int ret = -1;

    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
        return 0;

    old = priv->qemuDevices;
    priv->qemuDevices = NULL;
3163
    if (qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
3164 3165 3166 3167 3168
        goto cleanup;

    if ((tmp = old)) {
        while (*tmp) {
            if (!virStringArrayHasString(priv->qemuDevices, *tmp) &&
3169 3170 3171 3172
                virDomainDefFindDevice(vm->def, *tmp, &dev, false) == 0 &&
                qemuDomainRemoveDevice(driver, vm, &dev) < 0) {
                goto cleanup;
            }
3173 3174 3175 3176 3177
            tmp++;
        }
    }
    ret = 0;

3178
 cleanup:
3179 3180 3181 3182
    virStringFreeList(old);
    return ret;
}

3183 3184 3185 3186 3187 3188 3189
static int
qemuDomainPerfRestart(virDomainObjPtr vm)
{
    size_t i;
    virDomainDefPtr def = vm->def;
    qemuDomainObjPrivatePtr priv = vm->privateData;

3190
    if (!(priv->perf = virPerfNew()))
3191 3192 3193
        return -1;

    for (i = 0; i < VIR_PERF_EVENT_LAST; i++) {
3194 3195
        if (def->perf.events[i] &&
            def->perf.events[i] == VIR_TRISTATE_BOOL_YES) {
3196 3197 3198

            /* Failure to re-enable the perf event should not be fatal */
            if (virPerfEventEnable(priv->perf, i, vm->pid) < 0)
3199
                def->perf.events[i] = VIR_TRISTATE_BOOL_NO;
3200 3201 3202 3203 3204 3205
        }
    }

    return 0;
}

3206 3207
struct qemuProcessReconnectData {
    virConnectPtr conn;
3208
    virQEMUDriverPtr driver;
3209
    virDomainObjPtr obj;
3210 3211 3212 3213
};
/*
 * Open an existing VM's monitor, re-detect VCPU threads
 * and re-reserve the security labels in use
S
Stefan Berger 已提交
3214 3215 3216 3217
 *
 * We own the virConnectPtr we are passed here - whoever started
 * this thread function has increased the reference counter to it
 * so that we now have to close it.
3218
 *
3219
 * This function also inherits a locked and ref'd domain object.
3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231
 *
 * This function needs to:
 * 1. Enter job
 * 1. just before monitor reconnect do lightweight MonitorEnter
 *    (increase VM refcount and unlock VM)
 * 2. reconnect to monitor
 * 3. do lightweight MonitorExit (lock VM)
 * 4. continue reconnect process
 * 5. EndJob
 *
 * We can't do normal MonitorEnter & MonitorExit because these two lock the
 * monitor lock, which does not exists in this early phase.
3232 3233
 */
static void
3234
qemuProcessReconnect(void *opaque)
3235 3236
{
    struct qemuProcessReconnectData *data = opaque;
3237
    virQEMUDriverPtr driver = data->driver;
3238
    virDomainObjPtr obj = data->obj;
3239 3240
    qemuDomainObjPrivatePtr priv;
    virConnectPtr conn = data->conn;
3241
    struct qemuDomainJobObj oldjob;
3242 3243
    int state;
    int reason;
3244
    virQEMUDriverConfigPtr cfg;
3245
    size_t i;
3246
    int ret;
3247
    unsigned int stopFlags = 0;
3248
    bool jobStarted = false;
3249

3250 3251
    VIR_FREE(data);

3252
    qemuDomainObjRestoreJob(obj, &oldjob);
3253 3254
    if (oldjob.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
3255

3256 3257 3258
    cfg = virQEMUDriverGetConfig(driver);
    priv = obj->privateData;

3259 3260 3261 3262
    if (qemuDomainObjBeginJob(driver, obj, QEMU_JOB_MODIFY) < 0)
        goto error;
    jobStarted = true;

3263 3264 3265
    /* XXX If we ever gonna change pid file pattern, come up with
     * some intelligence here to deal with old paths. */
    if (!(priv->pidfile = virPidFileBuildPath(cfg->stateDir, obj->def->name)))
3266
        goto error;
3267

J
John Ferlan 已提交
3268 3269 3270 3271
    /* Restore the masterKey */
    if (qemuDomainMasterKeyReadFile(priv) < 0)
        goto error;

3272
    virNWFilterReadLockFilterUpdates();
3273 3274 3275 3276

    VIR_DEBUG("Reconnect monitor to %p '%s'", obj, obj->def->name);

    /* XXX check PID liveliness & EXE path */
3277
    if (qemuConnectMonitor(driver, obj, QEMU_ASYNC_JOB_NONE, NULL) < 0)
3278 3279
        goto error;

3280
    if (qemuHostdevUpdateActiveDomainDevices(driver, obj->def) < 0)
3281 3282
        goto error;

3283
    if (qemuConnectCgroup(driver, obj) < 0)
3284 3285
        goto error;

3286 3287 3288
    if (qemuDomainPerfRestart(obj) < 0)
        goto error;

3289
    /* XXX: Need to change as long as lock is introduced for
3290
     * qemu_driver->sharedDevices.
3291 3292
     */
    for (i = 0; i < obj->def->ndisks; i++) {
3293 3294
        virDomainDeviceDef dev;

3295
        if (virStorageTranslateDiskSourcePool(conn, obj->def->disks[i]) < 0)
3296
            goto error;
3297

3298 3299 3300 3301 3302 3303
        /* XXX we should be able to restore all data from XML in the future.
         * This should be the only place that calls qemuDomainDetermineDiskChain
         * with @report_broken == false to guarantee best-effort domain
         * reconnect */
        if (qemuDomainDetermineDiskChain(driver, obj, obj->def->disks[i],
                                         true, false) < 0)
3304 3305
            goto error;

3306 3307 3308
        dev.type = VIR_DOMAIN_DEVICE_DISK;
        dev.data.disk = obj->def->disks[i];
        if (qemuAddSharedDevice(driver, &dev, obj->def->name) < 0)
3309 3310 3311
            goto error;
    }

3312 3313 3314
    if (qemuProcessUpdateState(driver, obj) < 0)
        goto error;

3315
    state = virDomainObjGetState(obj, &reason);
3316 3317 3318
    if (state == VIR_DOMAIN_SHUTOFF ||
        (state == VIR_DOMAIN_PAUSED &&
         reason == VIR_DOMAIN_PAUSED_STARTING_UP)) {
3319 3320 3321 3322 3323
        VIR_DEBUG("Domain '%s' wasn't fully started yet, killing it",
                  obj->def->name);
        goto error;
    }

3324 3325 3326
    /* If upgrading from old libvirtd we won't have found any
     * caps in the domain status, so re-query them
     */
3327 3328
    if (!priv->qemuCaps &&
        !(priv->qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,
3329 3330
                                                      obj->def->emulator,
                                                      obj->def->os.machine)))
3331 3332
        goto error;

3333
    /* In case the domain shutdown while we were not running,
3334
     * we need to finish the shutdown process. And we need to do it after
3335
     * we have virQEMUCaps filled in.
3336
     */
3337 3338 3339 3340 3341 3342
    if (state == VIR_DOMAIN_SHUTDOWN ||
        (state == VIR_DOMAIN_PAUSED &&
         reason == VIR_DOMAIN_PAUSED_SHUTTING_DOWN)) {
        VIR_DEBUG("Finishing shutdown sequence for domain %s",
                  obj->def->name);
        qemuProcessShutdownOrReboot(driver, obj);
3343
        goto cleanup;
3344 3345
    }

3346
    if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps, obj, false)) < 0)
3347
        goto error;
3348

3349 3350 3351 3352 3353 3354
    /* if domain requests security driver we haven't loaded, report error, but
     * do not kill the domain
     */
    ignore_value(virSecurityManagerCheckAllLabel(driver->securityManager,
                                                 obj->def));

3355
    if (virSecurityManagerReserveLabel(driver->securityManager, obj->def, obj->pid) < 0)
3356 3357
        goto error;

3358 3359 3360
    if (qemuProcessNotifyNets(obj->def) < 0)
        goto error;

3361
    if (qemuProcessFiltersInstantiate(obj->def))
3362 3363
        goto error;

3364
    if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
3365 3366
        goto error;

3367
    if (qemuRefreshVirtioChannelState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
3368 3369
        goto error;

3370 3371 3372
    /* If querying of guest's RTC failed, report error, but do not kill the domain. */
    qemuRefreshRTC(driver, obj);

3373 3374 3375
    if (qemuProcessRefreshBalloonState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
        goto error;

3376 3377 3378
    if (qemuProcessRecoverJob(driver, obj, conn, &oldjob) < 0)
        goto error;

3379 3380 3381
    if (qemuProcessUpdateDevices(driver, obj) < 0)
        goto error;

3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392
    /* Failure to connect to agent shouldn't be fatal */
    if ((ret = qemuConnectAgent(driver, obj)) < 0) {
        if (ret == -2)
            goto error;

        VIR_WARN("Cannot connect to QEMU guest agent for %s",
                 obj->def->name);
        virResetLastError();
        priv->agentError = true;
    }

3393
    /* update domain state XML with possibly updated state in virDomainObj */
3394
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->caps) < 0)
3395 3396
        goto error;

3397 3398
    /* Run an hook to allow admins to do some magic */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
3399
        char *xml = qemuDomainDefFormatXML(driver, obj->def, 0);
3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413
        int hookret;

        hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, obj->def->name,
                              VIR_HOOK_QEMU_OP_RECONNECT, VIR_HOOK_SUBOP_BEGIN,
                              NULL, xml, NULL);
        VIR_FREE(xml);

        /*
         * If the script raised an error abort the launch
         */
        if (hookret < 0)
            goto error;
    }

3414
    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
3415 3416
        driver->inhibitCallback(true, driver->inhibitOpaque);

3417 3418 3419 3420 3421 3422 3423 3424 3425 3426
 cleanup:
    if (jobStarted)
        qemuDomainObjEndJob(driver, obj);
    if (!virDomainObjIsActive(obj))
        qemuDomainRemoveInactive(driver, obj);
    virDomainObjEndAPI(&obj);
    virObjectUnref(conn);
    virObjectUnref(cfg);
    virNWFilterUnlockFilterUpdates();
    return;
3427

3428
 error:
3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442
    if (virDomainObjIsActive(obj)) {
        /* We can't get the monitor back, so must kill the VM
         * to remove danger of it ending up running twice if
         * user tries to start it again later
         */
        if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
            /* If we couldn't get the monitor and qemu supports
             * no-shutdown, we can safely say that the domain
             * crashed ... */
            state = VIR_DOMAIN_SHUTOFF_CRASHED;
        } else {
            /* ... but if it doesn't we can't say what the state
             * really is and FAILED means "failed to start" */
            state = VIR_DOMAIN_SHUTOFF_UNKNOWN;
3443
        }
3444 3445 3446 3447 3448
        /* If BeginJob failed, we jumped here without a job, let's hope another
         * thread didn't have a chance to start playing with the domain yet
         * (it's all we can do anyway).
         */
        qemuProcessStop(driver, obj, state, QEMU_ASYNC_JOB_NONE, stopFlags);
3449
    }
3450
    goto cleanup;
3451 3452
}

3453 3454
static int
qemuProcessReconnectHelper(virDomainObjPtr obj,
3455 3456 3457 3458 3459 3460
                           void *opaque)
{
    virThread thread;
    struct qemuProcessReconnectData *src = opaque;
    struct qemuProcessReconnectData *data;

3461
    /* If the VM was inactive, we don't need to reconnect */
3462 3463 3464
    if (!obj->pid)
        return 0;

3465
    if (VIR_ALLOC(data) < 0)
3466
        return -1;
3467 3468

    memcpy(data, src, sizeof(*data));
3469
    data->obj = obj;
3470

3471 3472
    /* this lock and reference will be eventually transferred to the thread
     * that handles the reconnect */
3473
    virObjectLock(obj);
3474
    virObjectRef(obj);
3475

3476 3477 3478
    /* Since we close the connection later on, we have to make sure that the
     * threads we start see a valid connection throughout their lifetime. We
     * simply increase the reference counter here.
S
Stefan Berger 已提交
3479
     */
3480
    virObjectRef(data->conn);
S
Stefan Berger 已提交
3481

3482
    if (virThreadCreate(&thread, false, qemuProcessReconnect, data) < 0) {
3483 3484 3485
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Could not create thread. QEMU initialization "
                         "might be incomplete"));
3486 3487 3488 3489 3490 3491 3492
        /* We can't spawn a thread and thus connect to monitor. Kill qemu.
         * It's safe to call qemuProcessStop without a job here since there
         * is no thread that could be doing anything else with the same domain
         * object.
         */
        qemuProcessStop(src->driver, obj, VIR_DOMAIN_SHUTOFF_FAILED,
                        QEMU_ASYNC_JOB_NONE, 0);
3493
        qemuDomainRemoveInactive(src->driver, obj);
3494

M
Michal Privoznik 已提交
3495
        virDomainObjEndAPI(&obj);
3496 3497 3498 3499
        virObjectUnref(data->conn);
        VIR_FREE(data);
        return -1;
    }
3500

3501
    return 0;
3502 3503 3504 3505 3506 3507 3508 3509 3510
}

/**
 * qemuProcessReconnectAll
 *
 * Try to re-open the resources for live VMs that we care
 * about.
 */
void
3511
qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver)
3512
{
3513
    struct qemuProcessReconnectData data = {.conn = conn, .driver = driver};
3514
    virDomainObjListForEach(driver->domains, qemuProcessReconnectHelper, &data);
3515 3516
}

3517
static int
3518
qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver,
3519 3520
                            virDomainGraphicsDefPtr graphics,
                            bool allocate)
3521 3522 3523
{
    unsigned short port;

3524 3525 3526 3527 3528 3529 3530
    if (!allocate) {
        if (graphics->data.vnc.autoport)
            graphics->data.vnc.port = 5900;

        return 0;
    }

3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544
    if (graphics->data.vnc.autoport) {
        if (virPortAllocatorAcquire(driver->remotePorts, &port) < 0)
            return -1;
        graphics->data.vnc.port = port;
    }

    if (graphics->data.vnc.websocket == -1) {
        if (virPortAllocatorAcquire(driver->webSocketPorts, &port) < 0)
            return -1;
        graphics->data.vnc.websocket = port;
    }

    return 0;
}
3545

3546
static int
3547 3548
qemuProcessSPICEAllocatePorts(virQEMUDriverPtr driver,
                              virQEMUDriverConfigPtr cfg,
3549 3550
                              virDomainGraphicsDefPtr graphics,
                              bool allocate)
3551 3552 3553
{
    unsigned short port = 0;
    unsigned short tlsPort;
3554
    size_t i;
3555 3556 3557 3558 3559 3560 3561
    int defaultMode = graphics->data.spice.defaultMode;

    bool needTLSPort = false;
    bool needPort = false;

    if (graphics->data.spice.autoport) {
        /* check if tlsPort or port need allocation */
3562
        for (i = 0; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST; i++) {
3563 3564 3565 3566 3567 3568 3569 3570 3571 3572
            switch (graphics->data.spice.channels[i]) {
            case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
                needTLSPort = true;
                break;

            case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
                needPort = true;
                break;

            case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY:
3573
                /* default mode will be used */
3574 3575 3576
                break;
            }
        }
3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591
        switch (defaultMode) {
        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
            needTLSPort = true;
            break;

        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
            needPort = true;
            break;

        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY:
            if (cfg->spiceTLS)
                needTLSPort = true;
            needPort = true;
            break;
        }
3592 3593
    }

3594 3595 3596 3597 3598 3599 3600 3601 3602 3603
    if (!allocate) {
        if (needPort || graphics->data.spice.port == -1)
            graphics->data.spice.port = 5901;

        if (needTLSPort || graphics->data.spice.tlsPort == -1)
            graphics->data.spice.tlsPort = 5902;

        return 0;
    }

3604
    if (needPort || graphics->data.spice.port == -1) {
3605
        if (virPortAllocatorAcquire(driver->remotePorts, &port) < 0)
3606
            goto error;
3607 3608

        graphics->data.spice.port = port;
3609 3610 3611

        if (!graphics->data.spice.autoport)
            graphics->data.spice.portReserved = true;
3612 3613
    }

3614 3615
    if (needTLSPort || graphics->data.spice.tlsPort == -1) {
        if (!cfg->spiceTLS) {
3616 3617 3618 3619
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Auto allocation of spice TLS port requested "
                             "but spice TLS is disabled in qemu.conf"));
            goto error;
3620
        }
3621 3622 3623 3624 3625

        if (virPortAllocatorAcquire(driver->remotePorts, &tlsPort) < 0)
            goto error;

        graphics->data.spice.tlsPort = tlsPort;
3626 3627 3628

        if (!graphics->data.spice.autoport)
            graphics->data.spice.tlsPortReserved = true;
3629 3630
    }

3631
    return 0;
3632

3633
 error:
3634
    virPortAllocatorRelease(driver->remotePorts, port);
3635
    return -1;
3636 3637 3638
}


3639 3640 3641
static int
qemuValidateCpuCount(virDomainDefPtr def,
                     virQEMUCapsPtr qemuCaps)
3642
{
3643
    unsigned int maxCpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, def->os.machine);
3644

3645 3646 3647 3648 3649 3650
    if (virDomainDefGetVcpus(def) == 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Domain requires at least 1 vCPU"));
        return -1;
    }

3651 3652 3653 3654
    if (maxCpus > 0 && virDomainDefGetVcpusMax(def) > maxCpus) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Maximum CPUs greater than specified machine type limit"));
        return -1;
3655 3656
    }

3657
    return 0;
3658 3659
}

3660 3661

static bool
3662 3663 3664
qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver,
                          virDomainObjPtr vm,
                          int asyncJob)
3665 3666 3667 3668 3669
{
    virDomainDefPtr def = vm->def;
    virArch arch = def->os.arch;
    virCPUDataPtr guestcpu = NULL;
    qemuDomainObjPrivatePtr priv = vm->privateData;
3670
    int rc;
3671
    bool ret = false;
J
Ján Tomko 已提交
3672
    size_t i;
3673 3674 3675 3676

    switch (arch) {
    case VIR_ARCH_I686:
    case VIR_ARCH_X86_64:
3677 3678
        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
            return false;
3679
        rc = qemuMonitorGetGuestCPU(priv->mon, arch, &guestcpu);
3680 3681
        if (qemuDomainObjExitMonitor(driver, vm) < 0)
            return false;
3682

3683 3684 3685 3686
        if (rc < 0) {
            if (rc == -2)
                break;

3687
            goto cleanup;
3688
        }
3689

J
Ján Tomko 已提交
3690
        if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_TRISTATE_SWITCH_ON) {
3691 3692 3693 3694 3695 3696
            if (!cpuHasFeature(guestcpu, VIR_CPU_x86_KVM_PV_UNHALT)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("host doesn't support paravirtual spinlocks"));
                goto cleanup;
            }
        }
J
Ján Tomko 已提交
3697

3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722
        for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
            if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
                char *cpuFeature;
                if (virAsprintf(&cpuFeature, "__kvm_hv_%s",
                                virDomainHypervTypeToString(i)) < 0)
                    goto cleanup;
                if (!cpuHasFeature(guestcpu, cpuFeature)) {
                    switch ((virDomainHyperv) i) {
                    case VIR_DOMAIN_HYPERV_RELAXED:
                    case VIR_DOMAIN_HYPERV_VAPIC:
                    case VIR_DOMAIN_HYPERV_SPINLOCKS:
                        VIR_WARN("host doesn't support hyperv '%s' feature",
                                 virDomainHypervTypeToString(i));
                        break;
                    case VIR_DOMAIN_HYPERV_VPINDEX:
                    case VIR_DOMAIN_HYPERV_RUNTIME:
                    case VIR_DOMAIN_HYPERV_SYNIC:
                    case VIR_DOMAIN_HYPERV_STIMER:
                    case VIR_DOMAIN_HYPERV_RESET:
                    case VIR_DOMAIN_HYPERV_VENDOR_ID:
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                       _("host doesn't support hyperv '%s' feature"),
                                       virDomainHypervTypeToString(i));
                        goto cleanup;
                        break;
3723 3724

                    /* coverity[dead_error_begin] */
3725 3726 3727 3728 3729 3730
                    case VIR_DOMAIN_HYPERV_LAST:
                        break;
                    }
                }
            }
        }
J
Ján Tomko 已提交
3731

3732 3733 3734
        if (def->cpu && def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) {
            for (i = 0; i < def->cpu->nfeatures; i++) {
                virCPUFeatureDefPtr feature = &def->cpu->features[i];
J
Ján Tomko 已提交
3735

3736 3737 3738 3739 3740 3741 3742 3743 3744
                if (feature->policy != VIR_CPU_FEATURE_REQUIRE)
                    continue;

                if (STREQ(feature->name, "invtsc") &&
                    !cpuHasFeature(guestcpu, feature->name)) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("host doesn't support invariant TSC"));
                    goto cleanup;
                }
J
Ján Tomko 已提交
3745 3746
            }
        }
3747 3748 3749 3750 3751 3752 3753 3754
        break;

    default:
        break;
    }

    ret = true;

3755
 cleanup:
3756 3757 3758 3759 3760
    cpuDataFree(guestcpu);
    return ret;
}


3761 3762
static int
qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
3763
                 virDomainObjPtr vm)
3764 3765 3766 3767
{
    int ret = -1;
    int srcFD = -1;
    int dstFD = -1;
3768
    virDomainLoaderDefPtr loader = vm->def->os.loader;
3769
    bool created = false;
3770 3771
    const char *master_nvram_path;
    ssize_t r;
3772

3773
    if (!loader || !loader->nvram || virFileExists(loader->nvram))
3774 3775
        return 0;

3776 3777 3778
    master_nvram_path = loader->templt;
    if (!loader->templt) {
        size_t i;
3779 3780 3781
        for (i = 0; i < cfg->nfirmwares; i++) {
            if (STREQ(cfg->firmwares[i]->name, loader->path)) {
                master_nvram_path = cfg->firmwares[i]->nvram;
3782
                break;
3783 3784
            }
        }
3785
    }
3786

3787 3788 3789 3790 3791 3792
    if (!master_nvram_path) {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("unable to find any master var store for "
                         "loader: %s"), loader->path);
        goto cleanup;
    }
3793

3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810
    if ((srcFD = virFileOpenAs(master_nvram_path, O_RDONLY,
                               0, -1, -1, 0)) < 0) {
        virReportSystemError(-srcFD,
                             _("Failed to open file '%s'"),
                             master_nvram_path);
        goto cleanup;
    }
    if ((dstFD = virFileOpenAs(loader->nvram,
                               O_WRONLY | O_CREAT | O_EXCL,
                               S_IRUSR | S_IWUSR,
                               cfg->user, cfg->group, 0)) < 0) {
        virReportSystemError(-dstFD,
                             _("Failed to create file '%s'"),
                             loader->nvram);
        goto cleanup;
    }
    created = true;
3811

3812 3813
    do {
        char buf[1024];
3814

3815
        if ((r = saferead(srcFD, buf, sizeof(buf))) < 0) {
3816
            virReportSystemError(errno,
3817
                                 _("Unable to read from file '%s'"),
3818 3819 3820
                                 master_nvram_path);
            goto cleanup;
        }
3821 3822

        if (safewrite(dstFD, buf, r) < 0) {
3823
            virReportSystemError(errno,
3824
                                 _("Unable to write to file '%s'"),
3825 3826 3827
                                 loader->nvram);
            goto cleanup;
        }
3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840
    } while (r);

    if (VIR_CLOSE(srcFD) < 0) {
        virReportSystemError(errno,
                             _("Unable to close file '%s'"),
                             master_nvram_path);
        goto cleanup;
    }
    if (VIR_CLOSE(dstFD) < 0) {
        virReportSystemError(errno,
                             _("Unable to close file '%s'"),
                             loader->nvram);
        goto cleanup;
3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857
    }

    ret = 0;
 cleanup:
    /* We successfully generated the nvram path, but failed to
     * copy the file content. Roll back. */
    if (ret < 0) {
        if (created)
            unlink(loader->nvram);
    }

    VIR_FORCE_CLOSE(srcFD);
    VIR_FORCE_CLOSE(dstFD);
    return ret;
}


3858 3859 3860
static void
qemuLogOperation(virDomainObjPtr vm,
                 const char *msg,
3861 3862
                 virCommandPtr cmd,
                 qemuDomainLogContextPtr logCtxt)
3863 3864 3865 3866 3867
{
    char *timestamp;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int qemuVersion = virQEMUCapsGetVersion(priv->qemuCaps);
    const char *package = virQEMUCapsGetPackage(priv->qemuCaps);
3868
    char *hostname = virGetHostname();
3869 3870

    if ((timestamp = virTimeStringNow()) == NULL)
3871
        goto cleanup;
3872

3873 3874
    if (qemuDomainLogContextWrite(logCtxt,
                                  "%s: %s %s, qemu version: %d.%d.%d%s, hostname: %s\n",
3875 3876 3877 3878
                                  timestamp, msg, VIR_LOG_VERSION_STRING,
                                  (qemuVersion / 1000000) % 1000,
                                  (qemuVersion / 1000) % 1000,
                                  qemuVersion % 1000,
3879 3880
                                  package ? package : "",
                                  hostname ? hostname : "") < 0)
3881
        goto cleanup;
3882

3883 3884 3885 3886 3887
    if (cmd) {
        char *args = virCommandToString(cmd);
        qemuDomainLogContextWrite(logCtxt, "%s\n", args);
        VIR_FREE(args);
    }
3888 3889

 cleanup:
3890
    VIR_FREE(hostname);
3891 3892 3893
    VIR_FREE(timestamp);
}

3894 3895 3896 3897 3898 3899 3900

void
qemuProcessIncomingDefFree(qemuProcessIncomingDefPtr inc)
{
    if (!inc)
        return;

3901
    VIR_FREE(inc->address);
3902
    VIR_FREE(inc->launchURI);
3903
    VIR_FREE(inc->deferredURI);
3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914
    VIR_FREE(inc);
}


/*
 * This function does not copy @path, the caller is responsible for keeping
 * the @path pointer valid during the lifetime of the allocated
 * qemuProcessIncomingDef structure.
 */
qemuProcessIncomingDefPtr
qemuProcessIncomingDefNew(virQEMUCapsPtr qemuCaps,
3915
                          const char *listenAddress,
3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927
                          const char *migrateFrom,
                          int fd,
                          const char *path)
{
    qemuProcessIncomingDefPtr inc = NULL;

    if (qemuMigrationCheckIncoming(qemuCaps, migrateFrom) < 0)
        return NULL;

    if (VIR_ALLOC(inc) < 0)
        return NULL;

3928 3929 3930
    if (VIR_STRDUP(inc->address, listenAddress) < 0)
        goto error;

3931 3932 3933 3934
    inc->launchURI = qemuMigrationIncomingURI(migrateFrom, fd);
    if (!inc->launchURI)
        goto error;

3935 3936 3937 3938 3939 3940
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_INCOMING_DEFER)) {
        inc->deferredURI = inc->launchURI;
        if (VIR_STRDUP(inc->launchURI, "defer") < 0)
            goto error;
    }

3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951
    inc->fd = fd;
    inc->path = path;

    return inc;

 error:
    qemuProcessIncomingDefFree(inc);
    return NULL;
}


3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981
/*
 * This function starts a new QEMU_ASYNC_JOB_START async job. The user is
 * responsible for calling qemuProcessEndJob to stop this job and for passing
 * QEMU_ASYNC_JOB_START as @asyncJob argument to any function requiring this
 * parameter between qemuProcessBeginJob and qemuProcessEndJob.
 */
int
qemuProcessBeginJob(virQEMUDriverPtr driver,
                    virDomainObjPtr vm)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;

    if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_START) < 0)
        return -1;

    qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE);
    priv->job.current->type = VIR_DOMAIN_JOB_UNBOUNDED;

    return 0;
}


void
qemuProcessEndJob(virQEMUDriverPtr driver,
                  virDomainObjPtr vm)
{
    qemuDomainObjEndAsyncJob(driver, vm);
}


3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004
static int
qemuProcessStartHook(virQEMUDriverPtr driver,
                     virDomainObjPtr vm,
                     virHookQemuOpType op,
                     virHookSubopType subop)
{
    char *xml;
    int ret;

    if (!virHookPresent(VIR_HOOK_DRIVER_QEMU))
        return 0;

    if (!(xml = qemuDomainDefFormatXML(driver, vm->def, 0)))
        return -1;

    ret = virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name, op, subop,
                      NULL, xml, NULL);
    VIR_FREE(xml);

    return ret;
}


4005
static int
4006 4007
qemuProcessGraphicsReservePorts(virQEMUDriverPtr driver,
                                virDomainObjPtr vm)
4008 4009 4010 4011 4012 4013 4014 4015 4016 4017
{
    size_t i;

    for (i = 0; i < vm->def->ngraphics; ++i) {
        virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
            !graphics->data.vnc.autoport) {
            if (virPortAllocatorSetUsed(driver->remotePorts,
                                        graphics->data.vnc.port,
                                        true) < 0)
4018
                return -1;
4019 4020 4021 4022 4023 4024 4025 4026
            graphics->data.vnc.portReserved = true;

        } else if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
                   !graphics->data.spice.autoport) {
            if (graphics->data.spice.port > 0) {
                if (virPortAllocatorSetUsed(driver->remotePorts,
                                            graphics->data.spice.port,
                                            true) < 0)
4027
                    return -1;
4028 4029 4030 4031 4032 4033 4034
                graphics->data.spice.portReserved = true;
            }

            if (graphics->data.spice.tlsPort > 0) {
                if (virPortAllocatorSetUsed(driver->remotePorts,
                                            graphics->data.spice.tlsPort,
                                            true) < 0)
4035
                    return -1;
4036 4037 4038 4039 4040
                graphics->data.spice.tlsPortReserved = true;
            }
        }
    }

4041 4042 4043 4044
    return 0;
}


4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071
static int
qemuProcessGraphicsSetupNetworkAddress(virDomainGraphicsListenDefPtr glisten,
                                       const char *listenAddr)
{
    int rc;

    /* TODO: reject configuration without network specified for network listen */
    if (!glisten->network) {
        if (VIR_STRDUP(glisten->address, listenAddr) < 0)
            return -1;
        return 0;
    }

    rc = networkGetNetworkAddress(glisten->network, &glisten->address);
    if (rc <= -2) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("network-based listen isn't possible, "
                         "network driver isn't present"));
        return -1;
    }
    if (rc < 0)
        return -1;

    return 0;
}


4072 4073
static int
qemuProcessGraphicsSetupListen(virQEMUDriverConfigPtr cfg,
4074 4075
                               virDomainGraphicsDefPtr graphics,
                               virDomainObjPtr vm)
4076
{
4077 4078
    qemuDomainObjPrivatePtr priv = vm->privateData;
    const char *type = virDomainGraphicsTypeToString(graphics->type);
4079
    char *listenAddr = NULL;
4080
    bool useSocket = false;
4081 4082 4083 4084
    size_t i;

    switch (graphics->type) {
    case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
4085
        useSocket = cfg->vncAutoUnixSocket;
4086 4087 4088 4089
        listenAddr = cfg->vncListen;
        break;

    case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
4090
        useSocket = cfg->spiceAutoUnixSocket;
4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105
        listenAddr = cfg->spiceListen;
        break;

    case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
    case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
    case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
    case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
        break;
    }

    for (i = 0; i < graphics->nListens; i++) {
        virDomainGraphicsListenDefPtr glisten = &graphics->listens[i];

        switch (glisten->type) {
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
4106 4107 4108 4109 4110
            if (!glisten->address) {
                /* If there is no address specified and qemu.conf has
                 * *_auto_unix_socket set we should use unix socket as
                 * default instead of tcp listen. */
                if (useSocket) {
4111 4112
                    memset(glisten, 0, sizeof(virDomainGraphicsListenDef));
                    if (virAsprintf(&glisten->socket, "%s/%s.sock",
4113 4114
                                    priv->libDir, type) < 0)
                        return -1;
4115 4116
                    glisten->fromConfig = true;
                    glisten->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET;
4117 4118 4119 4120 4121 4122
                } else if (listenAddr) {
                    if (VIR_STRDUP(glisten->address, listenAddr) < 0)
                        return -1;
                    glisten->fromConfig = true;
                }
            }
4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133
            break;

        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
            if (glisten->address || !listenAddr)
                continue;

            if (qemuProcessGraphicsSetupNetworkAddress(glisten,
                                                       listenAddr) < 0)
                return -1;
            break;

4134 4135 4136 4137 4138 4139 4140 4141 4142
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
            if (!glisten->socket) {
                if (virAsprintf(&glisten->socket, "%s/%s.sock",
                                priv->libDir, type) < 0)
                    return -1;
                glisten->autoGenerated = true;
            }
            break;

4143 4144 4145 4146 4147 4148 4149 4150 4151 4152
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
            break;
        }
    }

    return 0;
}


4153 4154
static int
qemuProcessSetupGraphics(virQEMUDriverPtr driver,
4155 4156
                         virDomainObjPtr vm,
                         unsigned int flags)
4157 4158
{
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4159
    bool allocate = !(flags & VIR_QEMU_PROCESS_START_PRETEND);
4160
    size_t i;
4161 4162
    int ret = -1;

4163
    if (allocate && qemuProcessGraphicsReservePorts(driver, vm) < 0)
4164 4165
        goto cleanup;

4166 4167
    for (i = 0; i < vm->def->ngraphics; ++i) {
        virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
4168

4169 4170 4171 4172 4173 4174 4175 4176
        if (graphics->nListens > 0 &&
            (graphics->listens[0].type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS ||
             graphics->listens[0].type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK)) {
            switch (graphics->type) {
            case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
                if (qemuProcessVNCAllocatePorts(driver, graphics, allocate) < 0)
                    goto cleanup;
                break;
4177

4178 4179 4180 4181 4182
            case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
                if (qemuProcessSPICEAllocatePorts(driver, cfg, graphics,
                                                  allocate) < 0)
                    goto cleanup;
                break;
4183

4184 4185 4186 4187 4188 4189
            case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
            case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
            case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
            case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
                break;
            }
4190
        }
4191

4192
        if (qemuProcessGraphicsSetupListen(cfg, graphics, vm) < 0)
4193
            goto cleanup;
4194 4195 4196 4197 4198 4199 4200 4201 4202 4203
    }

    ret = 0;

 cleanup:
    virObjectUnref(cfg);
    return ret;
}


4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262
static int
qemuProcessSetupRawIO(virQEMUDriverPtr driver,
                      virDomainObjPtr vm,
                      virCommandPtr cmd ATTRIBUTE_UNUSED)
{
    bool rawio = false;
    size_t i;
    int ret = -1;

    /* in case a certain disk is desirous of CAP_SYS_RAWIO, add this */
    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDeviceDef dev;
        virDomainDiskDefPtr disk = vm->def->disks[i];

        if (disk->rawio == VIR_TRISTATE_BOOL_YES) {
            rawio = true;
#ifndef CAP_SYS_RAWIO
            break;
#endif
        }

        dev.type = VIR_DOMAIN_DEVICE_DISK;
        dev.data.disk = disk;
        if (qemuAddSharedDevice(driver, &dev, vm->def->name) < 0)
            goto cleanup;

        if (qemuSetUnprivSGIO(&dev) < 0)
            goto cleanup;
    }

    /* If rawio not already set, check hostdevs as well */
    if (!rawio) {
        for (i = 0; i < vm->def->nhostdevs; i++) {
            virDomainHostdevSubsysSCSIPtr scsisrc =
                &vm->def->hostdevs[i]->source.subsys.u.scsi;
            if (scsisrc->rawio == VIR_TRISTATE_BOOL_YES) {
                rawio = true;
                break;
            }
        }
    }

    ret = 0;

 cleanup:
    if (rawio) {
#ifdef CAP_SYS_RAWIO
        if (ret == 0)
            virCommandAllowCap(cmd, CAP_SYS_RAWIO);
#else
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Raw I/O is not supported on this platform"));
        ret = -1;
#endif
    }
    return ret;
}


4263 4264 4265 4266 4267 4268 4269 4270 4271
static int
qemuProcessSetupBalloon(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
                        qemuDomainAsyncJob asyncJob)
{
    unsigned long long balloon = vm->def->mem.cur_balloon;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int ret = -1;

4272
    if (!virDomainDefHasMemballoon(vm->def))
4273 4274 4275 4276 4277
        return 0;

    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto cleanup;

4278 4279 4280
    if (vm->def->memballoon->period)
        qemuMonitorSetMemoryStatsPeriod(priv->mon, vm->def->memballoon,
                                        vm->def->memballoon->period);
4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292
    if (qemuMonitorSetBalloon(priv->mon, balloon) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;
    return ret;
}


J
Jiri Denemark 已提交
4293 4294 4295
static int
qemuProcessMakeDir(virQEMUDriverPtr driver,
                   virDomainObjPtr vm,
4296
                   const char *path)
J
Jiri Denemark 已提交
4297 4298 4299 4300 4301 4302 4303 4304
{
    int ret = -1;

    if (virFileMakePathWithMode(path, 0750) < 0) {
        virReportSystemError(errno, _("Cannot create directory '%s'"), path);
        goto cleanup;
    }

4305 4306
    if (virSecurityManagerDomainSetPathLabel(driver->securityManager,
                                             vm->def, path) < 0)
J
Jiri Denemark 已提交
4307 4308 4309 4310 4311 4312 4313 4314 4315
        goto cleanup;

    ret = 0;

 cleanup:
    return ret;
}


4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364
static void
qemuProcessStartWarnShmem(virDomainObjPtr vm)
{
    size_t i;
    bool check_shmem = false;
    bool shmem = vm->def->nshmems;

    /*
     * For vhost-user to work, the domain has to have some type of
     * shared memory configured.  We're not the proper ones to judge
     * whether shared hugepages or shm are enough and will be in the
     * future, so we'll just warn in case neither is configured.
     * Moreover failing would give the false illusion that libvirt is
     * really checking that everything works before running the domain
     * and not only we are unable to do that, but it's also not our
     * aim to do so.
     */
    for (i = 0; i < vm->def->nnets; i++) {
        if (virDomainNetGetActualType(vm->def->nets[i]) ==
                                      VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
            check_shmem = true;
            break;
        }
    }

    if (!check_shmem)
        return;

    /*
     * This check is by no means complete.  We merely check
     * whether there are *some* hugepages enabled and *some* NUMA
     * nodes with shared memory access.
     */
    if (!shmem && vm->def->mem.nhugepages) {
        for (i = 0; i < virDomainNumaGetNodeCount(vm->def->numa); i++) {
            if (virDomainNumaGetNodeMemoryAccessMode(vm->def->numa, i) ==
                VIR_NUMA_MEM_ACCESS_SHARED) {
                shmem = true;
                break;
            }
        }
    }

    if (!shmem) {
        VIR_WARN("Detected vhost-user interface without any shared memory, "
                 "the interface might not be operational");
    }
}

4365
static int
4366 4367
qemuProcessStartValidateXML(virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
4368
                            virQEMUCapsPtr qemuCaps,
4369
                            virCapsPtr caps,
4370
                            unsigned int flags)
4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382
{
    /* The bits we validate here are XML configs that we previously
     * accepted. We reject them at VM startup time rather than parse
     * time so that pre-existing VMs aren't rejected and dropped from
     * the VM list when libvirt is updated.
     *
     * If back compat isn't a concern, XML validation should probably
     * be done at parse time.
     */
    if (qemuValidateCpuCount(vm->def, qemuCaps) < 0)
        return -1;

4383 4384 4385
    /* checks below should not be executed when starting a qemu process for a
     * VM that was running before (migration, snapshots, save). It's more
     * important to start such VM than keep the configuration clean */
4386 4387 4388
    if ((flags & VIR_QEMU_PROCESS_START_NEW) &&
        virDomainDefValidate(vm->def, caps, 0, driver->xmlopt) < 0)
        return -1;
4389 4390 4391

    return 0;
}
4392

4393 4394 4395 4396 4397 4398
/**
 * qemuProcessStartValidate:
 * @vm: domain object
 * @qemuCaps: emulator capabilities
 * @migration: restoration of existing state
 *
4399 4400 4401 4402 4403
 * This function aggregates checks done prior to start of a VM.
 *
 * Flag VIR_QEMU_PROCESS_START_PRETEND tells, that we don't want to actually
 * start the domain but create a valid qemu command.  If some code shouldn't be
 * executed in this case, make sure to check this flag.
4404
 */
4405
static int
4406 4407
qemuProcessStartValidate(virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
4408
                         virQEMUCapsPtr qemuCaps,
4409
                         virCapsPtr caps,
4410
                         unsigned int flags)
4411
{
4412 4413
    size_t i;

4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432
    if (!(flags & VIR_QEMU_PROCESS_START_PRETEND)) {
        if (vm->def->virtType == VIR_DOMAIN_VIRT_KVM) {
            VIR_DEBUG("Checking for KVM availability");
            if (!virFileExists("/dev/kvm")) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Domain requires KVM, but it is not available. "
                                 "Check that virtualization is enabled in the "
                                 "host BIOS, and host configuration is setup to "
                                 "load the kvm modules."));
                return -1;
            }
        }

        VIR_DEBUG("Checking domain and device security labels");
        if (virSecurityManagerCheckAllLabel(driver->securityManager, vm->def) < 0)
            return -1;

    }

4433
    if (qemuProcessStartValidateXML(driver, vm, qemuCaps, caps, flags) < 0)
4434 4435
        return -1;

4436 4437
    VIR_DEBUG("Checking for any possible (non-fatal) issues");

4438
    qemuProcessStartWarnShmem(vm);
4439

4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461
    for (i = 0; i < vm->def->ngraphics; i++) {
        virDomainGraphicsDefPtr graphics = vm->def->graphics[i];

        switch (graphics->type) {
        case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
        case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
            if (graphics->nListens > 1) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("QEMU does not support multiple listens for "
                                 "one graphics device."));
                return -1;
            }
            break;

        case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
        case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
        case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
        case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
            break;
        }
    }

4462 4463 4464 4465
    return 0;
}


J
Jiri Denemark 已提交
4466 4467 4468 4469 4470 4471
/**
 * qemuProcessInit:
 *
 * Prepares the domain up to the point when priv->qemuCaps is initialized. The
 * function calls qemuProcessStop when needed.
 *
4472 4473 4474 4475
 * Flag VIR_QEMU_PROCESS_START_PRETEND tells, that we don't want to actually
 * start the domain but create a valid qemu command.  If some code shouldn't be
 * executed in this case, make sure to check this flag.
 *
J
Jiri Denemark 已提交
4476 4477 4478 4479 4480
 * Returns 0 on success, -1 on error.
 */
int
qemuProcessInit(virQEMUDriverPtr driver,
                virDomainObjPtr vm,
4481
                qemuDomainAsyncJob asyncJob,
4482
                bool migration,
4483
                unsigned int flags)
J
Jiri Denemark 已提交
4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502
{
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
    virCapsPtr caps = NULL;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int stopFlags;
    int ret = -1;

    VIR_DEBUG("vm=%p name=%s id=%d migration=%d",
              vm, vm->def->name, vm->def->id, migration);

    VIR_DEBUG("Beginning VM startup process");

    if (virDomainObjIsActive(vm)) {
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("VM is already active"));
        goto cleanup;
    }

    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
4503 4504 4505 4506 4507 4508 4509 4510
        goto cleanup;

    VIR_DEBUG("Determining emulator version");
    virObjectUnref(priv->qemuCaps);
    if (!(priv->qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,
                                                      vm->def->emulator,
                                                      vm->def->os.machine)))
        goto cleanup;
J
Jiri Denemark 已提交
4511

4512
    if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) < 0)
4513 4514
        goto cleanup;

J
Jiri Denemark 已提交
4515 4516 4517 4518 4519
    /* Do this upfront, so any part of the startup process can add
     * runtime state to vm->def that won't be persisted. This let's us
     * report implicit runtime defaults in the XML, like vnc listen/socket
     */
    VIR_DEBUG("Setting current domain def as transient");
4520
    if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
J
Jiri Denemark 已提交
4521 4522
        goto stop;

4523 4524 4525 4526
    if (!(flags & VIR_QEMU_PROCESS_START_PRETEND)) {
        vm->def->id = qemuDriverAllocateID(driver);
        qemuDomainSetFakeReboot(driver, vm, false);
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_STARTING_UP);
J
Jiri Denemark 已提交
4527

4528 4529
        if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
            driver->inhibitCallback(true, driver->inhibitOpaque);
J
Jiri Denemark 已提交
4530

4531 4532 4533 4534 4535 4536
        /* Run an early hook to set-up missing devices */
        if (qemuProcessStartHook(driver, vm,
                                 VIR_HOOK_QEMU_OP_PREPARE,
                                 VIR_HOOK_SUBOP_BEGIN) < 0)
            goto stop;
    }
J
Jiri Denemark 已提交
4537

4538
    if (qemuDomainSetPrivatePaths(driver, vm) < 0)
4539 4540
        goto cleanup;

J
Jiri Denemark 已提交
4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551
    ret = 0;

 cleanup:
    virObjectUnref(cfg);
    virObjectUnref(caps);
    return ret;

 stop:
    stopFlags = VIR_QEMU_PROCESS_STOP_NO_RELABEL;
    if (migration)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
4552
    qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, asyncJob, stopFlags);
J
Jiri Denemark 已提交
4553 4554 4555 4556
    goto cleanup;
}


4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609
/**
 * qemuProcessNetworkPrepareDevices
 */
static int
qemuProcessNetworkPrepareDevices(virDomainDefPtr def)
{
    int ret = -1;
    size_t i;

    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
        int actualType;

        /* If appropriate, grab a physical device from the configured
         * network's pool of devices, or resolve bridge device name
         * to the one defined in the network definition.
         */
        if (networkAllocateActualDevice(def, net) < 0)
            goto cleanup;

        actualType = virDomainNetGetActualType(net);
        if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
            net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
            /* Each type='hostdev' network device must also have a
             * corresponding entry in the hostdevs array. For netdevs
             * that are hardcoded as type='hostdev', this is already
             * done by the parser, but for those allocated from a
             * network / determined at runtime, we need to do it
             * separately.
             */
            virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net);
            virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;

            if (virDomainHostdevFind(def, hostdev, NULL) >= 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("PCI device %04x:%02x:%02x.%x "
                                 "allocated from network %s is already "
                                 "in use by domain %s"),
                               pcisrc->addr.domain, pcisrc->addr.bus,
                               pcisrc->addr.slot, pcisrc->addr.function,
                               net->data.network.name, def->name);
                goto cleanup;
            }
            if (virDomainHostdevInsert(def, hostdev) < 0)
                goto cleanup;
        }
    }
    ret = 0;
 cleanup:
    return ret;
}


4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625
/**
 * qemuProcessSetupVcpu:
 * @vm: domain object
 * @vcpuid: id of VCPU to set defaults
 *
 * This function sets resource properties (cgroups, affinity, scheduler) for a
 * vCPU. This function expects that the vCPU is online and the vCPU pids were
 * correctly detected at the point when it's called.
 *
 * Returns 0 on success, -1 on error.
 */
int
qemuProcessSetupVcpu(virDomainObjPtr vm,
                     unsigned int vcpuid)
{
    pid_t vcpupid = qemuDomainGetVcpuPid(vm, vcpuid);
4626
    virDomainVcpuDefPtr vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
4627

4628 4629 4630 4631 4632
    return qemuProcessSetupPid(vm, vcpupid, VIR_CGROUP_THREAD_VCPU,
                               vcpuid, vcpu->cpumask,
                               vm->def->cputune.period,
                               vm->def->cputune.quota,
                               &vcpu->sched);
4633 4634 4635 4636 4637 4638
}


static int
qemuProcessSetupVcpus(virDomainObjPtr vm)
{
4639
    virDomainVcpuDefPtr vcpu;
4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684
    unsigned int maxvcpus = virDomainDefGetVcpusMax(vm->def);
    size_t i;

    if ((vm->def->cputune.period || vm->def->cputune.quota) &&
        !virCgroupHasController(((qemuDomainObjPrivatePtr) vm->privateData)->cgroup,
                                VIR_CGROUP_CONTROLLER_CPU)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("cgroup cpu is required for scheduler tuning"));
        return -1;
    }

    if (!qemuDomainHasVcpuPids(vm)) {
        /* If any CPU has custom affinity that differs from the
         * VM default affinity, we must reject it */
        for (i = 0; i < maxvcpus; i++) {
            vcpu = virDomainDefGetVcpu(vm->def, i);

            if (!vcpu->online)
                continue;

            if (vcpu->cpumask &&
                !virBitmapEqual(vm->def->cpumask, vcpu->cpumask)) {
                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                                _("cpu affinity is not supported"));
                return -1;
            }
        }

        return 0;
    }

    for (i = 0; i < maxvcpus; i++) {
        vcpu = virDomainDefGetVcpu(vm->def, i);

        if (!vcpu->online)
            continue;

        if (qemuProcessSetupVcpu(vm, i) < 0)
            return -1;
    }

    return 0;
}


4685 4686 4687 4688 4689
int
qemuProcessSetupIOThread(virDomainObjPtr vm,
                         virDomainIOThreadIDDefPtr iothread)
{

4690 4691
    return qemuProcessSetupPid(vm, iothread->thread_id,
                               VIR_CGROUP_THREAD_IOTHREAD,
4692
                               iothread->iothread_id,
4693
                               iothread->cpumask,
4694 4695
                               vm->def->cputune.iothread_period,
                               vm->def->cputune.iothread_quota,
4696
                               &iothread->sched);
4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715
}


static int
qemuProcessSetupIOThreads(virDomainObjPtr vm)
{
    size_t i;

    for (i = 0; i < vm->def->niothreadids; i++) {
        virDomainIOThreadIDDefPtr info = vm->def->iothreadids[i];

        if (qemuProcessSetupIOThread(vm, info) < 0)
            return -1;
    }

    return 0;
}


4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737
/**
 * qemuProcessPrepareDomain
 *
 * This function groups all code that modifies only live XML of a domain which
 * is about to start and it's the only place to do those modifications.
 *
 * Flag VIR_QEMU_PROCESS_START_PRETEND tells, that we don't want to actually
 * start the domain but create a valid qemu command.  If some code shouldn't be
 * executed in this case, make sure to check this flag.
 *
 * TODO: move all XML modification from qemuBuildCommandLine into this function
 */
int
qemuProcessPrepareDomain(virConnectPtr conn,
                         virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
                         unsigned int flags)
{
    int ret = -1;
    size_t i;
    char *nodeset = NULL;
    qemuDomainObjPrivatePtr priv = vm->privateData;
4738
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758
    virCapsPtr caps;

    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto cleanup;

    if (!(flags & VIR_QEMU_PROCESS_START_PRETEND)) {
        /* If you are using a SecurityDriver with dynamic labelling,
           then generate a security label for isolation */
        VIR_DEBUG("Generating domain security label (if required)");
        if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0) {
            virDomainAuditSecurityLabel(vm, false);
            goto cleanup;
        }
        virDomainAuditSecurityLabel(vm, true);

        /* Get the advisory nodeset from numad if 'placement' of
         * either <vcpu> or <numatune> is 'auto'.
         */
        if (virDomainDefNeedsPlacementAdvice(vm->def)) {
            nodeset = virNumaGetAutoPlacementAdvice(virDomainDefGetVcpus(vm->def),
4759
                                                    virDomainDefGetMemoryTotal(vm->def));
4760 4761 4762 4763 4764
            if (!nodeset)
                goto cleanup;

            VIR_DEBUG("Nodeset returned from numad: %s", nodeset);

4765
            if (virBitmapParse(nodeset, &priv->autoNodeset,
4766 4767 4768 4769 4770 4771 4772 4773 4774
                               VIR_DOMAIN_CPUMASK_LEN) < 0)
                goto cleanup;

            if (!(priv->autoCpuset = virCapabilitiesGetCpusForNodemask(caps,
                                                                       priv->autoNodeset)))
                goto cleanup;
        }
    }

4775 4776 4777 4778 4779 4780 4781
    /*
     * Normally PCI addresses are assigned in the virDomainCreate
     * or virDomainDefine methods. We might still need to assign
     * some here to cope with the question of upgrades. Regardless
     * we also need to populate the PCI address set cache for later
     * use in hotplug
     */
4782
    VIR_DEBUG("Assigning domain PCI addresses");
4783 4784
    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm,
                                   !!(flags & VIR_QEMU_PROCESS_START_NEW))) < 0)
4785
        goto cleanup;
4786

4787 4788 4789
    if (qemuAssignDeviceAliases(vm->def, priv->qemuCaps) < 0)
        goto cleanup;

4790
    VIR_DEBUG("Setting graphics devices");
4791 4792 4793
    if (qemuProcessSetupGraphics(driver, vm, flags) < 0)
        goto cleanup;

4794 4795 4796 4797 4798
    /* Drop possibly missing disks from the definition. This function
     * also resolves source pool/volume into a path and it needs to
     * happen after the def is copied and aliases are set. */
    if (qemuDomainCheckDiskPresence(conn, driver, vm, flags) < 0)
        goto cleanup;
4799

4800 4801 4802 4803
    VIR_DEBUG("Create domain masterKey");
    if (qemuDomainMasterKeyCreate(vm) < 0)
        goto cleanup;

4804 4805 4806 4807
    VIR_DEBUG("Add secrets to disks and hostdevs");
    if (qemuDomainSecretPrepare(conn, vm) < 0)
        goto cleanup;

4808 4809 4810 4811 4812 4813
    for (i = 0; i < vm->def->nchannels; i++) {
        if (qemuDomainPrepareChannel(vm->def->channels[i],
                                     priv->channelTargetDir) < 0)
            goto cleanup;
    }

4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829
    if (VIR_ALLOC(priv->monConfig) < 0)
        goto cleanup;

    VIR_DEBUG("Preparing monitor state");
    if (qemuProcessPrepareMonitorChr(priv->monConfig, priv->libDir) < 0)
        goto cleanup;

    priv->monJSON = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON);
    priv->monError = false;
    priv->monStart = 0;
    priv->gotShutdown = false;

    ret = 0;
 cleanup:
    VIR_FREE(nodeset);
    virObjectUnref(caps);
4830
    virObjectUnref(cfg);
4831 4832 4833 4834
    return ret;
}


J
Jiri Denemark 已提交
4835
/**
4836
 * qemuProcessPrepareHost
J
Jiri Denemark 已提交
4837
 *
4838 4839 4840
 * This function groups all code that modifies host system (which also may
 * update live XML) to prepare environment for a domain which is about to start
 * and it's the only place to do those modifications.
J
Jiri Denemark 已提交
4841
 *
4842
 * TODO: move all host modification from qemuBuildCommandLine into this function
J
Jiri Denemark 已提交
4843 4844
 */
int
4845 4846 4847
qemuProcessPrepareHost(virQEMUDriverPtr driver,
                       virDomainObjPtr vm,
                       bool incoming)
4848
{
4849
    int ret = -1;
4850
    unsigned int hostdev_flags = 0;
4851 4852 4853
    size_t i;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4854

4855
    if (qemuPrepareNVRAM(cfg, vm) < 0)
J
Jiri Denemark 已提交
4856
        goto cleanup;
4857

4858 4859 4860 4861 4862
    /* network devices must be "prepared" before hostdevs, because
     * setting up a network device might create a new hostdev that
     * will need to be setup.
     */
    VIR_DEBUG("Preparing network devices");
4863
    if (qemuProcessNetworkPrepareDevices(vm->def) < 0)
J
Jiri Denemark 已提交
4864
        goto cleanup;
4865

4866
    /* Must be run before security labelling */
4867
    VIR_DEBUG("Preparing host devices");
4868 4869
    if (!cfg->relaxedACS)
        hostdev_flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
J
Jiri Denemark 已提交
4870
    if (!incoming)
4871
        hostdev_flags |= VIR_HOSTDEV_COLD_BOOT;
4872 4873
    if (qemuHostdevPrepareDomainDevices(driver, vm->def, priv->qemuCaps,
                                        hostdev_flags) < 0)
J
Jiri Denemark 已提交
4874
        goto cleanup;
4875

4876
    VIR_DEBUG("Preparing chr devices");
4877 4878 4879 4880
    if (virDomainChrDefForeach(vm->def,
                               true,
                               qemuProcessPrepareChardevDevice,
                               NULL) < 0)
J
Jiri Denemark 已提交
4881
        goto cleanup;
4882

4883
    if (vm->def->mem.nhugepages) {
4884 4885 4886 4887
        for (i = 0; i < cfg->nhugetlbfs; i++) {
            char *hugepagePath = qemuGetHugepagePath(&cfg->hugetlbfs[i]);

            if (!hugepagePath)
J
Jiri Denemark 已提交
4888
                goto cleanup;
4889 4890 4891 4892 4893 4894

            if (virSecurityManagerSetHugepages(driver->securityManager,
                                               vm->def, hugepagePath) < 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("Unable to set huge path in security driver"));
                VIR_FREE(hugepagePath);
J
Jiri Denemark 已提交
4895
                goto cleanup;
4896 4897
            }
            VIR_FREE(hugepagePath);
4898 4899 4900
        }
    }

4901 4902
    /* Ensure no historical cgroup for this VM is lying around bogus
     * settings */
4903
    VIR_DEBUG("Ensuring no historical cgroup is lying around");
4904
    qemuRemoveCgroup(vm);
4905

4906
    if (virFileMakePath(cfg->logDir) < 0) {
4907 4908
        virReportSystemError(errno,
                             _("cannot create log directory %s"),
4909
                             cfg->logDir);
J
Jiri Denemark 已提交
4910
        goto cleanup;
4911 4912
    }

4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935
    VIR_FREE(priv->pidfile);
    if (!(priv->pidfile = virPidFileBuildPath(cfg->stateDir, vm->def->name))) {
        virReportSystemError(errno,
                             "%s", _("Failed to build pidfile path."));
        goto cleanup;
    }

    if (unlink(priv->pidfile) < 0 &&
        errno != ENOENT) {
        virReportSystemError(errno,
                             _("Cannot remove stale PID file %s"),
                             priv->pidfile);
        goto cleanup;
    }

    /*
     * Create all per-domain directories in order to make sure domain
     * with any possible seclabels can access it.
     */
    if (qemuProcessMakeDir(driver, vm, priv->libDir) < 0 ||
        qemuProcessMakeDir(driver, vm, priv->channelTargetDir) < 0)
        goto cleanup;

4936 4937
    VIR_DEBUG("Write domain masterKey");
    if (qemuDomainWriteMasterKeyFile(driver, vm) < 0)
J
John Ferlan 已提交
4938 4939
        goto cleanup;

4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980
    ret = 0;
 cleanup:
    virObjectUnref(cfg);
    return ret;
}


/**
 * qemuProcessLaunch:
 *
 * Launch a new QEMU process with stopped virtual CPUs.
 *
 * The caller is supposed to call qemuProcessStop with appropriate
 * flags in case of failure.
 *
 * Returns 0 on success,
 *        -1 on error which happened before devices were labeled and thus
 *           there is no need to restore them,
 *        -2 on error requesting security labels to be restored.
 */
int
qemuProcessLaunch(virConnectPtr conn,
                  virQEMUDriverPtr driver,
                  virDomainObjPtr vm,
                  qemuDomainAsyncJob asyncJob,
                  qemuProcessIncomingDefPtr incoming,
                  virDomainSnapshotObjPtr snapshot,
                  virNetDevVPortProfileOp vmop,
                  unsigned int flags)
{
    int ret = -1;
    int rv;
    int logfile = -1;
    qemuDomainLogContextPtr logCtxt = NULL;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virCommandPtr cmd = NULL;
    struct qemuProcessHookData hookData;
    virQEMUDriverConfigPtr cfg;
    virCapsPtr caps = NULL;
    size_t nnicindexes = 0;
    int *nicindexes = NULL;
Q
Qiaowei Ren 已提交
4981
    size_t i;
4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997

    VIR_DEBUG("vm=%p name=%s id=%d asyncJob=%d "
              "incoming.launchURI=%s incoming.deferredURI=%s "
              "incoming.fd=%d incoming.path=%s "
              "snapshot=%p vmop=%d flags=0x%x",
              vm, vm->def->name, vm->def->id, asyncJob,
              NULLSTR(incoming ? incoming->launchURI : NULL),
              NULLSTR(incoming ? incoming->deferredURI : NULL),
              incoming ? incoming->fd : -1,
              NULLSTR(incoming ? incoming->path : NULL),
              snapshot, vmop, flags);

    /* Okay, these are just internal flags,
     * but doesn't hurt to check */
    virCheckFlags(VIR_QEMU_PROCESS_START_COLD |
                  VIR_QEMU_PROCESS_START_PAUSED |
4998 4999
                  VIR_QEMU_PROCESS_START_AUTODESTROY |
                  VIR_QEMU_PROCESS_START_NEW, -1);
5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011

    cfg = virQEMUDriverGetConfig(driver);

    hookData.conn = conn;
    hookData.vm = vm;
    hookData.driver = driver;
    /* We don't increase cfg's reference counter here. */
    hookData.cfg = cfg;

    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto cleanup;

5012
    VIR_DEBUG("Creating domain log file");
5013 5014
    if (!(logCtxt = qemuDomainLogContextNew(driver, vm,
                                            QEMU_DOMAIN_LOG_CONTEXT_MODE_START)))
J
Jiri Denemark 已提交
5015
        goto cleanup;
5016
    logfile = qemuDomainLogContextGetWriteFD(logCtxt);
5017

5018
    VIR_DEBUG("Building emulator command line");
5019
    if (!(cmd = qemuBuildCommandLine(driver,
5020 5021
                                     qemuDomainLogContextGetManager(logCtxt),
                                     vm->def, priv->monConfig,
E
Eric Blake 已提交
5022
                                     priv->monJSON, priv->qemuCaps,
5023 5024
                                     incoming ? incoming->launchURI : NULL,
                                     snapshot, vmop,
J
Ján Tomko 已提交
5025
                                     false,
5026
                                     qemuCheckFips(),
5027
                                     priv->autoNodeset,
5028
                                     &nnicindexes, &nicindexes,
5029
                                     priv->libDir)))
J
Jiri Denemark 已提交
5030
        goto cleanup;
5031

5032 5033
    if (incoming && incoming->fd != -1)
        virCommandPassFD(cmd, incoming->fd, 0);
5034

5035
    /* now that we know it is about to start call the hook if present */
5036 5037 5038
    if (qemuProcessStartHook(driver, vm,
                             VIR_HOOK_QEMU_OP_START,
                             VIR_HOOK_SUBOP_BEGIN) < 0)
J
Jiri Denemark 已提交
5039
        goto cleanup;
5040

5041
    qemuLogOperation(vm, "starting up", cmd, logCtxt);
5042

5043
    qemuDomainObjCheckTaint(driver, vm, logCtxt);
5044

5045
    qemuDomainLogContextMarkPosition(logCtxt);
5046 5047

    VIR_DEBUG("Clear emulator capabilities: %d",
5048 5049
              cfg->clearEmulatorCapabilities);
    if (cfg->clearEmulatorCapabilities)
5050 5051
        virCommandClearCaps(cmd);

5052 5053
    VIR_DEBUG("Setting up raw IO");
    if (qemuProcessSetupRawIO(driver, vm, cmd) < 0)
J
Jiri Denemark 已提交
5054
        goto cleanup;
5055

5056
    virCommandSetPreExecHook(cmd, qemuProcessHook, &hookData);
5057 5058
    virCommandSetMaxProcesses(cmd, cfg->maxProcesses);
    virCommandSetMaxFiles(cmd, cfg->maxFiles);
5059
    virCommandSetUmask(cmd, 0x002);
5060

5061 5062
    VIR_DEBUG("Setting up security labelling");
    if (virSecurityManagerSetChildProcessLabel(driver->securityManager,
5063
                                               vm->def, cmd) < 0)
J
Jiri Denemark 已提交
5064
        goto cleanup;
5065

5066 5067 5068
    virCommandSetOutputFD(cmd, &logfile);
    virCommandSetErrorFD(cmd, &logfile);
    virCommandNonblockingFDs(cmd);
5069
    virCommandSetPidFile(cmd, priv->pidfile);
5070
    virCommandDaemonize(cmd);
5071
    virCommandRequireHandshake(cmd);
5072

5073
    if (virSecurityManagerPreFork(driver->securityManager) < 0)
J
Jiri Denemark 已提交
5074
        goto cleanup;
5075
    rv = virCommandRun(cmd, NULL);
5076
    virSecurityManagerPostFork(driver->securityManager);
5077

E
Eric Blake 已提交
5078
    /* wait for qemu process to show up */
5079
    if (rv == 0) {
5080
        if (virPidFileReadPath(priv->pidfile, &vm->pid) < 0) {
5081 5082
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Domain %s didn't show up"), vm->def->name);
5083
            rv = -1;
5084
        }
5085 5086 5087 5088 5089
        VIR_DEBUG("QEMU vm=%p name=%s running with pid=%llu",
                  vm, vm->def->name, (unsigned long long)vm->pid);
    } else {
        VIR_DEBUG("QEMU vm=%p name=%s failed to spawn",
                  vm, vm->def->name);
5090 5091
    }

5092
    VIR_DEBUG("Writing early domain status to disk");
5093
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
J
Jiri Denemark 已提交
5094
        goto cleanup;
5095

5096 5097
    VIR_DEBUG("Waiting for handshake from child");
    if (virCommandHandshakeWait(cmd) < 0) {
5098
        /* Read errors from child that occurred between fork and exec. */
5099 5100
        qemuProcessReportLogError(logCtxt,
                                  _("Process exited prior to exec"));
J
Jiri Denemark 已提交
5101
        goto cleanup;
5102 5103
    }

5104
    VIR_DEBUG("Setting up domain cgroup (if required)");
5105
    if (qemuSetupCgroup(driver, vm, nnicindexes, nicindexes) < 0)
J
Jiri Denemark 已提交
5106
        goto cleanup;
5107

5108 5109 5110 5111
    if (!(priv->perf = virPerfNew()))
        goto cleanup;

    for (i = 0; i < VIR_PERF_EVENT_LAST; i++) {
5112
        if (vm->def->perf.events[i] == VIR_TRISTATE_BOOL_YES &&
5113 5114
            virPerfEventEnable(priv->perf, i, vm->pid) < 0)
            goto cleanup;
Q
Qiaowei Ren 已提交
5115
    }
5116

5117 5118 5119 5120 5121 5122
    /* This must be done after cgroup placement to avoid resetting CPU
     * affinity */
    if (!vm->def->cputune.emulatorpin &&
        qemuProcessInitCpuAffinity(vm) < 0)
        goto cleanup;

5123 5124 5125 5126
    VIR_DEBUG("Setting emulator tuning/settings");
    if (qemuProcessSetupEmulator(vm) < 0)
        goto cleanup;

5127 5128
    VIR_DEBUG("Setting domain security labels");
    if (virSecurityManagerSetAllLabel(driver->securityManager,
J
Jiri Denemark 已提交
5129 5130 5131
                                      vm->def,
                                      incoming ? incoming->path : NULL) < 0)
        goto cleanup;
5132

5133
    /* Security manager labeled all devices, therefore
J
Jiri Denemark 已提交
5134 5135 5136 5137
     * if any operation from now on fails, we need to ask the caller to
     * restore labels.
     */
    ret = -2;
5138

J
Jiri Denemark 已提交
5139
    if (incoming && incoming->fd != -1) {
5140 5141 5142 5143 5144 5145 5146
        /* if there's an fd to migrate from, and it's a pipe, put the
         * proper security label on it
         */
        struct stat stdin_sb;

        VIR_DEBUG("setting security label on pipe used for migration");

J
Jiri Denemark 已提交
5147
        if (fstat(incoming->fd, &stdin_sb) < 0) {
5148
            virReportSystemError(errno,
J
Jiri Denemark 已提交
5149 5150
                                 _("cannot stat fd %d"), incoming->fd);
            goto cleanup;
5151 5152
        }
        if (S_ISFIFO(stdin_sb.st_mode) &&
J
Jiri Denemark 已提交
5153 5154 5155
            virSecurityManagerSetImageFDLabel(driver->securityManager,
                                              vm->def, incoming->fd) < 0)
            goto cleanup;
5156 5157 5158
    }

    VIR_DEBUG("Labelling done, completing handshake to child");
5159
    if (virCommandHandshakeNotify(cmd) < 0)
J
Jiri Denemark 已提交
5160
        goto cleanup;
5161 5162
    VIR_DEBUG("Handshake complete, child running");

5163
    if (rv == -1) /* The VM failed to start; tear filters before taps */
5164 5165
        virDomainConfVMNWFilterTeardown(vm);

5166
    if (rv == -1) /* The VM failed to start */
J
Jiri Denemark 已提交
5167
        goto cleanup;
5168

5169
    VIR_DEBUG("Waiting for monitor to show up");
5170
    if (qemuProcessWaitForMonitor(driver, vm, asyncJob, priv->qemuCaps, logCtxt) < 0)
J
Jiri Denemark 已提交
5171
        goto cleanup;
5172

D
Daniel P. Berrange 已提交
5173
    /* Failure to connect to agent shouldn't be fatal */
5174 5175
    if ((rv = qemuConnectAgent(driver, vm)) < 0) {
        if (rv == -2)
J
Jiri Denemark 已提交
5176
            goto cleanup;
5177

D
Daniel P. Berrange 已提交
5178 5179 5180 5181 5182 5183
        VIR_WARN("Cannot connect to QEMU guest agent for %s",
                 vm->def->name);
        virResetLastError();
        priv->agentError = true;
    }

5184
    VIR_DEBUG("Detecting if required emulator features are present");
5185
    if (!qemuProcessVerifyGuestCPU(driver, vm, asyncJob))
J
Jiri Denemark 已提交
5186
        goto cleanup;
5187

5188
    VIR_DEBUG("Setting up post-init cgroup restrictions");
5189
    if (qemuSetupCpusetMems(vm) < 0)
J
Jiri Denemark 已提交
5190
        goto cleanup;
5191

5192
    VIR_DEBUG("Detecting VCPU PIDs");
5193
    if (qemuDomainDetectVcpuPids(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5194
        goto cleanup;
5195

5196 5197
    VIR_DEBUG("Detecting IOThread PIDs");
    if (qemuProcessDetectIOThreadPIDs(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5198
        goto cleanup;
5199

5200 5201 5202 5203
    VIR_DEBUG("Setting global CPU cgroup (if required)");
    if (qemuSetupGlobalCpuCgroup(vm) < 0)
        goto cleanup;

5204 5205
    VIR_DEBUG("Setting vCPU tuning/settings");
    if (qemuProcessSetupVcpus(vm) < 0)
J
Jiri Denemark 已提交
5206
        goto cleanup;
5207

5208 5209
    VIR_DEBUG("Setting IOThread tuning/settings");
    if (qemuProcessSetupIOThreads(vm) < 0)
J
Jiri Denemark 已提交
5210
        goto cleanup;
5211

5212
    VIR_DEBUG("Setting any required VM passwords");
5213
    if (qemuProcessInitPasswords(conn, driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5214
        goto cleanup;
5215

5216 5217 5218 5219
    /* set default link states */
    /* qemu doesn't support setting this on the command line, so
     * enter the monitor */
    VIR_DEBUG("Setting network link states");
5220
    if (qemuProcessSetLinkStates(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5221
        goto cleanup;
5222

5223
    VIR_DEBUG("Fetching list of active devices");
5224
    if (qemuDomainUpdateDeviceList(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5225
        goto cleanup;
5226

5227 5228
    VIR_DEBUG("Updating info of memory devices");
    if (qemuDomainUpdateMemoryDeviceInfo(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5229
        goto cleanup;
5230

5231
    VIR_DEBUG("Setting initial memory amount");
5232
    if (qemuProcessSetupBalloon(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5233
        goto cleanup;
5234

5235
    /* Since CPUs were not started yet, the balloon could not return the memory
5236 5237
     * to the host and thus cur_balloon needs to be updated so that GetXMLdesc
     * and friends return the correct size in case they can't grab the job */
5238
    if (!incoming && !snapshot &&
5239
        qemuProcessRefreshBalloonState(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5240
        goto cleanup;
5241

5242 5243
    VIR_DEBUG("Detecting actual memory size for video device");
    if (qemuProcessUpdateVideoRamSize(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5244 5245
        goto cleanup;

5246 5247
    VIR_DEBUG("Updating disk data");
    if (qemuProcessRefreshDisks(driver, vm, asyncJob) < 0)
5248 5249
        goto cleanup;

J
Jiri Denemark 已提交
5250 5251 5252 5253 5254 5255 5256
    if (flags & VIR_QEMU_PROCESS_START_AUTODESTROY &&
        qemuProcessAutoDestroyAdd(driver, vm, conn) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
5257
    qemuDomainSecretDestroy(vm);
J
Jiri Denemark 已提交
5258
    virCommandFree(cmd);
5259
    qemuDomainLogContextFree(logCtxt);
J
Jiri Denemark 已提交
5260 5261 5262 5263 5264 5265 5266
    virObjectUnref(cfg);
    virObjectUnref(caps);
    VIR_FREE(nicindexes);
    return ret;
}


5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297
/**
 * qemuProcessFinishStartup:
 *
 * Finish starting a new domain.
 */
int
qemuProcessFinishStartup(virConnectPtr conn,
                         virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
                         qemuDomainAsyncJob asyncJob,
                         bool startCPUs,
                         virDomainPausedReason pausedReason)
{
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
    int ret = -1;

    if (startCPUs) {
        VIR_DEBUG("Starting domain CPUs");
        if (qemuProcessStartCPUs(driver, vm, conn,
                                 VIR_DOMAIN_RUNNING_BOOTED,
                                 asyncJob) < 0) {
            if (!virGetLastError())
                virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                               _("resume operation failed"));
            goto cleanup;
        }
    } else {
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, pausedReason);
    }

    VIR_DEBUG("Writing domain status to disk");
5298
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313
        goto cleanup;

    if (qemuProcessStartHook(driver, vm,
                             VIR_HOOK_QEMU_OP_STARTED,
                             VIR_HOOK_SUBOP_BEGIN) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    virObjectUnref(cfg);
    return ret;
}


J
Jiri Denemark 已提交
5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344
int
qemuProcessStart(virConnectPtr conn,
                 virQEMUDriverPtr driver,
                 virDomainObjPtr vm,
                 qemuDomainAsyncJob asyncJob,
                 const char *migrateFrom,
                 int migrateFd,
                 const char *migratePath,
                 virDomainSnapshotObjPtr snapshot,
                 virNetDevVPortProfileOp vmop,
                 unsigned int flags)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    qemuProcessIncomingDefPtr incoming = NULL;
    unsigned int stopFlags;
    bool relabel = false;
    int ret = -1;
    int rv;

    VIR_DEBUG("conn=%p driver=%p vm=%p name=%s id=%d asyncJob=%s "
              "migrateFrom=%s migrateFd=%d migratePath=%s "
              "snapshot=%p vmop=%d flags=0x%x",
              conn, driver, vm, vm->def->name, vm->def->id,
              qemuDomainAsyncJobTypeToString(asyncJob),
              NULLSTR(migrateFrom), migrateFd, NULLSTR(migratePath),
              snapshot, vmop, flags);

    virCheckFlagsGoto(VIR_QEMU_PROCESS_START_COLD |
                      VIR_QEMU_PROCESS_START_PAUSED |
                      VIR_QEMU_PROCESS_START_AUTODESTROY, cleanup);

5345 5346 5347 5348
    if (!migrateFrom && !snapshot)
        flags |= VIR_QEMU_PROCESS_START_NEW;

    if (qemuProcessInit(driver, vm, asyncJob, !!migrateFrom, flags) < 0)
J
Jiri Denemark 已提交
5349 5350 5351
        goto cleanup;

    if (migrateFrom) {
5352
        incoming = qemuProcessIncomingDefNew(priv->qemuCaps, NULL, migrateFrom,
J
Jiri Denemark 已提交
5353 5354 5355 5356 5357
                                             migrateFd, migratePath);
        if (!incoming)
            goto stop;
    }

5358 5359 5360
    if (qemuProcessPrepareDomain(conn, driver, vm, flags) < 0)
        goto stop;

5361 5362 5363
    if (qemuProcessPrepareHost(driver, vm, !!incoming) < 0)
        goto stop;

J
Jiri Denemark 已提交
5364 5365
    if ((rv = qemuProcessLaunch(conn, driver, vm, asyncJob, incoming,
                                snapshot, vmop, flags)) < 0) {
5366
        if (rv == -2)
J
Jiri Denemark 已提交
5367 5368 5369 5370
            relabel = true;
        goto stop;
    }
    relabel = true;
5371

5372 5373 5374
    if (incoming &&
        incoming->deferredURI &&
        qemuMigrationRunIncoming(driver, vm, incoming->deferredURI, asyncJob) < 0)
J
Jiri Denemark 已提交
5375
        goto stop;
5376

5377 5378 5379 5380 5381
    if (qemuProcessFinishStartup(conn, driver, vm, asyncJob,
                                 !(flags & VIR_QEMU_PROCESS_START_PAUSED),
                                 incoming ?
                                 VIR_DOMAIN_PAUSED_MIGRATION :
                                 VIR_DOMAIN_PAUSED_USER) < 0)
J
Jiri Denemark 已提交
5382
        goto stop;
5383

5384 5385
    /* Keep watching qemu log for errors during incoming migration, otherwise
     * unset reporting errors from qemu log. */
5386
    if (!incoming)
5387
        qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL);
5388

5389 5390 5391
    ret = 0;

 cleanup:
5392
    qemuProcessIncomingDefFree(incoming);
5393
    return ret;
5394

J
Jiri Denemark 已提交
5395 5396 5397 5398 5399 5400
 stop:
    stopFlags = 0;
    if (!relabel)
        stopFlags |= VIR_QEMU_PROCESS_STOP_NO_RELABEL;
    if (migrateFrom)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
5401
    if (priv->mon)
5402
        qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL);
5403
    qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, asyncJob, stopFlags);
5404
    goto cleanup;
5405 5406 5407
}


5408 5409 5410 5411 5412
virCommandPtr
qemuProcessCreatePretendCmd(virConnectPtr conn,
                            virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
                            const char *migrateURI,
5413
                            bool enableFips,
5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424
                            bool standalone,
                            unsigned int flags)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virCommandPtr cmd = NULL;

    virCheckFlagsGoto(VIR_QEMU_PROCESS_START_COLD |
                      VIR_QEMU_PROCESS_START_PAUSED |
                      VIR_QEMU_PROCESS_START_AUTODESTROY, cleanup);

    flags |= VIR_QEMU_PROCESS_START_PRETEND;
5425
    flags |= VIR_QEMU_PROCESS_START_NEW;
5426

5427
    if (qemuProcessInit(driver, vm, QEMU_ASYNC_JOB_NONE, !!migrateURI, flags) < 0)
5428 5429 5430 5431 5432 5433
        goto cleanup;

    if (qemuProcessPrepareDomain(conn, driver, vm, flags) < 0)
        goto cleanup;

    VIR_DEBUG("Building emulator command line");
5434
    cmd = qemuBuildCommandLine(driver,
5435 5436 5437 5438 5439 5440 5441 5442 5443
                               NULL,
                               vm->def,
                               priv->monConfig,
                               priv->monJSON,
                               priv->qemuCaps,
                               migrateURI,
                               NULL,
                               VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
                               standalone,
5444
                               enableFips,
5445 5446 5447
                               priv->autoNodeset,
                               NULL,
                               NULL,
5448
                               priv->libDir);
5449 5450 5451 5452 5453 5454

 cleanup:
    return cmd;
}


5455
int
5456
qemuProcessKill(virDomainObjPtr vm, unsigned int flags)
5457
{
5458
    int ret;
5459

5460 5461 5462
    VIR_DEBUG("vm=%p name=%s pid=%llu flags=%x",
              vm, vm->def->name,
              (unsigned long long)vm->pid, flags);
5463

5464 5465 5466 5467 5468
    if (!(flags & VIR_QEMU_PROCESS_KILL_NOCHECK)) {
        if (!virDomainObjIsActive(vm)) {
            VIR_DEBUG("VM '%s' not active", vm->def->name);
            return 0;
        }
5469 5470
    }

5471
    if (flags & VIR_QEMU_PROCESS_KILL_NOWAIT) {
5472 5473 5474 5475 5476
        virProcessKill(vm->pid,
                       (flags & VIR_QEMU_PROCESS_KILL_FORCE) ?
                       SIGKILL : SIGTERM);
        return 0;
    }
5477

5478 5479
    ret = virProcessKillPainfully(vm->pid,
                                  !!(flags & VIR_QEMU_PROCESS_KILL_FORCE));
5480

5481
    return ret;
5482 5483 5484
}


5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523
/**
 * qemuProcessBeginStopJob:
 *
 * Stop all current jobs by killing the domain and start a new one for
 * qemuProcessStop.
 */
int
qemuProcessBeginStopJob(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
                        qemuDomainJob job,
                        bool forceKill)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    unsigned int killFlags = forceKill ? VIR_QEMU_PROCESS_KILL_FORCE : 0;
    int ret = -1;

    /* We need to prevent monitor EOF callback from doing our work (and
     * sending misleading events) while the vm is unlocked inside
     * BeginJob/ProcessKill API
     */
    priv->beingDestroyed = true;

    if (qemuProcessKill(vm, killFlags) < 0)
        goto cleanup;

    /* Wake up anything waiting on domain condition */
    virDomainObjBroadcast(vm);

    if (qemuDomainObjBeginJob(driver, vm, job) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    priv->beingDestroyed = false;
    return ret;
}


5524
void qemuProcessStop(virQEMUDriverPtr driver,
5525
                     virDomainObjPtr vm,
5526
                     virDomainShutoffReason reason,
5527
                     qemuDomainAsyncJob asyncJob,
5528
                     unsigned int flags)
5529 5530 5531 5532 5533 5534
{
    int ret;
    int retries = 0;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virErrorPtr orig_err;
    virDomainDefPtr def;
A
Ansis Atteka 已提交
5535
    virNetDevVPortProfilePtr vport = NULL;
5536
    size_t i;
5537
    char *timestamp;
5538
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
5539

5540 5541
    VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%llu, "
              "reason=%s, asyncJob=%s, flags=%x",
5542
              vm, vm->def->name, vm->def->id,
5543 5544 5545 5546
              (unsigned long long)vm->pid,
              virDomainShutoffReasonTypeToString(reason),
              qemuDomainAsyncJobTypeToString(asyncJob),
              flags);
5547

5548 5549 5550 5551
    /* This method is routinely used in clean up paths. Disable error
     * reporting so we don't squash a legit error. */
    orig_err = virSaveLastError();

5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566
    if (asyncJob != QEMU_ASYNC_JOB_NONE) {
        if (qemuDomainObjBeginNestedJob(driver, vm, asyncJob) < 0)
            goto cleanup;
    } else if (priv->job.asyncJob != QEMU_ASYNC_JOB_NONE &&
               priv->job.asyncOwner == virThreadSelfID() &&
               priv->job.active != QEMU_JOB_ASYNC_NESTED) {
        VIR_WARN("qemuProcessStop called without a nested job (async=%s)",
                 qemuDomainAsyncJobTypeToString(asyncJob));
    }

    if (!virDomainObjIsActive(vm)) {
        VIR_DEBUG("VM '%s' not active", vm->def->name);
        goto endjob;
    }

5567 5568
    vm->def->id = -1;

5569
    if (virAtomicIntDecAndTest(&driver->nactive) && driver->inhibitCallback)
5570 5571
        driver->inhibitCallback(false, driver->inhibitOpaque);

5572 5573
    /* Wake up anything waiting on domain condition */
    virDomainObjBroadcast(vm);
5574

5575 5576 5577
    if ((timestamp = virTimeStringNow()) != NULL) {
        qemuDomainLogAppendMessage(driver, vm, "%s: shutting down\n", timestamp);
        VIR_FREE(timestamp);
5578 5579
    }

5580 5581 5582
    /* Clear network bandwidth */
    virDomainClearNetBandwidth(vm);

5583 5584
    virDomainConfVMNWFilterTeardown(vm);

5585
    if (cfg->macFilter) {
5586
        def = vm->def;
5587
        for (i = 0; i < def->nnets; i++) {
5588 5589 5590
            virDomainNetDefPtr net = def->nets[i];
            if (net->ifname == NULL)
                continue;
5591 5592 5593
            ignore_value(ebtablesRemoveForwardAllowIn(driver->ebtables,
                                                      net->ifname,
                                                      &net->mac));
5594 5595 5596
        }
    }

5597
    virPortAllocatorRelease(driver->migrationPorts, priv->nbdPort);
5598
    priv->nbdPort = 0;
5599

D
Daniel P. Berrange 已提交
5600 5601 5602 5603 5604 5605
    if (priv->agent) {
        qemuAgentClose(priv->agent);
        priv->agent = NULL;
        priv->agentError = false;
    }

5606
    if (priv->mon) {
5607
        qemuMonitorClose(priv->mon);
5608 5609
        priv->mon = NULL;
    }
5610 5611 5612 5613 5614 5615 5616 5617

    if (priv->monConfig) {
        if (priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX)
            unlink(priv->monConfig->data.nix.path);
        virDomainChrSourceDefFree(priv->monConfig);
        priv->monConfig = NULL;
    }

J
John Ferlan 已提交
5618 5619 5620
    /* Remove the master key */
    qemuDomainMasterKeyRemove(priv);

5621 5622
    virFileDeleteTree(priv->libDir);
    virFileDeleteTree(priv->channelTargetDir);
5623

5624 5625
    qemuDomainClearPrivatePaths(vm);

5626 5627 5628 5629 5630 5631
    ignore_value(virDomainChrDefForeach(vm->def,
                                        false,
                                        qemuProcessCleanupChardevDevice,
                                        NULL));


5632
    /* shut it off for sure */
5633 5634 5635
    ignore_value(qemuProcessKill(vm,
                                 VIR_QEMU_PROCESS_KILL_FORCE|
                                 VIR_QEMU_PROCESS_KILL_NOCHECK));
5636

5637 5638
    qemuDomainCleanupRun(driver, vm);

5639
    /* Stop autodestroy in case guest is restarted */
5640
    qemuProcessAutoDestroyRemove(driver, vm);
5641

5642 5643
    /* now that we know it's stopped call the hook if present */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
5644
        char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
5645 5646

        /* we can't stop the operation even if the script raised an error */
5647 5648 5649
        ignore_value(virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
                                 VIR_HOOK_QEMU_OP_STOPPED, VIR_HOOK_SUBOP_END,
                                 NULL, xml, NULL));
5650 5651 5652
        VIR_FREE(xml);
    }

5653 5654 5655 5656
    /* Reset Security Labels unless caller don't want us to */
    if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL))
        virSecurityManagerRestoreAllLabel(driver->securityManager,
                                          vm->def,
5657
                                          !!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED));
5658
    virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
5659

5660
    for (i = 0; i < vm->def->ndisks; i++) {
5661
        virDomainDeviceDef dev;
5662
        virDomainDiskDefPtr disk = vm->def->disks[i];
5663 5664 5665 5666

        dev.type = VIR_DOMAIN_DEVICE_DISK;
        dev.data.disk = disk;
        ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
5667 5668
    }

5669
    /* Clear out dynamically assigned labels */
5670
    for (i = 0; i < vm->def->nseclabels; i++) {
5671
        if (vm->def->seclabels[i]->type == VIR_DOMAIN_SECLABEL_DYNAMIC)
5672 5673
            VIR_FREE(vm->def->seclabels[i]->label);
        VIR_FREE(vm->def->seclabels[i]->imagelabel);
5674 5675
    }

5676 5677 5678
    virStringFreeList(priv->qemuDevices);
    priv->qemuDevices = NULL;

5679
    qemuHostdevReAttachDomainDevices(driver, vm->def);
5680 5681 5682 5683

    def = vm->def;
    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
5684 5685 5686 5687
        vport = virDomainNetGetActualVirtPortProfile(net);

        switch (virDomainNetGetActualType(net)) {
        case VIR_DOMAIN_NET_TYPE_DIRECT:
5688
            ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
5689
                             net->ifname, &net->mac,
5690 5691
                             virDomainNetGetActualDirectDev(net),
                             virDomainNetGetActualDirectMode(net),
5692
                             virDomainNetGetActualVirtPortProfile(net),
5693
                             cfg->stateDir));
5694
            break;
5695 5696 5697 5698 5699 5700
        case VIR_DOMAIN_NET_TYPE_ETHERNET:
            if (net->ifname) {
                ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
                VIR_FREE(net->ifname);
            }
            break;
5701 5702 5703 5704
        case VIR_DOMAIN_NET_TYPE_BRIDGE:
        case VIR_DOMAIN_NET_TYPE_NETWORK:
#ifdef VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP
            if (!(vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))
5705
                ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
5706 5707
#endif
            break;
5708
        }
5709 5710 5711
        /* release the physical device (or any other resources used by
         * this interface in the network driver
         */
5712 5713 5714 5715 5716 5717 5718 5719 5720
        if (vport) {
            if (vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_MIDONET) {
                ignore_value(virNetDevMidonetUnbindPort(vport));
            } else if (vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
                ignore_value(virNetDevOpenvswitchRemovePort(
                                 virDomainNetGetActualBridgeName(net),
                                 net->ifname));
            }
        }
A
Ansis Atteka 已提交
5721

5722 5723
        /* kick the device out of the hostdev list too */
        virDomainNetRemoveHostdev(def, net);
5724
        networkReleaseActualDevice(vm->def, net);
5725
    }
5726

5727
 retry:
5728
    if ((ret = qemuRemoveCgroup(vm)) < 0) {
5729 5730 5731 5732 5733 5734 5735
        if (ret == -EBUSY && (retries++ < 5)) {
            usleep(200*1000);
            goto retry;
        }
        VIR_WARN("Failed to remove cgroup for %s",
                 vm->def->name);
    }
5736
    virCgroupFree(&priv->cgroup);
5737

5738
    virPerfFree(priv->perf);
5739
    priv->perf = NULL;
5740

5741 5742
    qemuProcessRemoveDomainStatus(driver, vm);

5743 5744
    /* Remove VNC and Spice ports from port reservation bitmap, but only if
       they were reserved by the driver (autoport=yes)
5745
    */
5746
    for (i = 0; i < vm->def->ngraphics; ++i) {
5747
        virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
5748 5749
        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
            if (graphics->data.vnc.autoport) {
5750 5751
                virPortAllocatorRelease(driver->remotePorts,
                                        graphics->data.vnc.port);
5752
            } else if (graphics->data.vnc.portReserved) {
5753 5754 5755 5756 5757
                virPortAllocatorSetUsed(driver->remotePorts,
                                        graphics->data.spice.port,
                                        false);
                graphics->data.vnc.portReserved = false;
            }
5758 5759
            virPortAllocatorRelease(driver->webSocketPorts,
                                    graphics->data.vnc.websocket);
5760
        }
5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781
        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
            if (graphics->data.spice.autoport) {
                virPortAllocatorRelease(driver->remotePorts,
                                        graphics->data.spice.port);
                virPortAllocatorRelease(driver->remotePorts,
                                        graphics->data.spice.tlsPort);
            } else {
                if (graphics->data.spice.portReserved) {
                    virPortAllocatorSetUsed(driver->remotePorts,
                                            graphics->data.spice.port,
                                            false);
                    graphics->data.spice.portReserved = false;
                }

                if (graphics->data.spice.tlsPortReserved) {
                    virPortAllocatorSetUsed(driver->remotePorts,
                                            graphics->data.spice.tlsPort,
                                            false);
                    graphics->data.spice.tlsPortReserved = false;
                }
            }
5782
        }
5783 5784
    }

5785
    vm->taint = 0;
5786
    vm->pid = -1;
J
Jiri Denemark 已提交
5787
    virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
5788 5789
    for (i = 0; i < vm->def->niothreadids; i++)
        vm->def->iothreadids[i]->thread_id = 0;
5790 5791
    virObjectUnref(priv->qemuCaps);
    priv->qemuCaps = NULL;
5792
    VIR_FREE(priv->pidfile);
5793

5794
    /* The "release" hook cleans up additional resources */
5795
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
5796
        char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
5797 5798 5799

        /* we can't stop the operation even if the script raised an error */
        virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
5800 5801
                    VIR_HOOK_QEMU_OP_RELEASE, VIR_HOOK_SUBOP_END,
                    NULL, xml, NULL);
5802 5803 5804
        VIR_FREE(xml);
    }

5805 5806 5807 5808 5809 5810 5811
    if (vm->newDef) {
        virDomainDefFree(vm->def);
        vm->def = vm->newDef;
        vm->def->id = -1;
        vm->newDef = NULL;
    }

5812 5813 5814 5815 5816
 endjob:
    if (asyncJob != QEMU_ASYNC_JOB_NONE)
        qemuDomainObjEndJob(driver, vm);

 cleanup:
5817 5818 5819 5820
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
5821
    virObjectUnref(cfg);
5822
}
5823 5824


5825
int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
5826
                      virQEMUDriverPtr driver,
5827
                      virDomainObjPtr vm,
5828
                      pid_t pid,
5829 5830 5831 5832
                      const char *pidfile,
                      virDomainChrSourceDefPtr monConfig,
                      bool monJSON)
{
5833
    size_t i;
5834
    qemuDomainLogContextPtr logCtxt = NULL;
5835 5836 5837
    char *timestamp;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    bool running = true;
5838
    virDomainPausedReason reason;
5839
    virSecurityLabelPtr seclabel = NULL;
5840
    virSecurityLabelDefPtr seclabeldef = NULL;
5841
    bool seclabelgen = false;
5842 5843
    virSecurityManagerPtr* sec_managers = NULL;
    const char *model;
5844
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
5845
    virCapsPtr caps = NULL;
5846
    bool active = false;
5847
    int ret;
5848 5849 5850 5851

    VIR_DEBUG("Beginning VM attach process");

    if (virDomainObjIsActive(vm)) {
5852 5853
        virReportError(VIR_ERR_OPERATION_INVALID,
                       "%s", _("VM is already active"));
5854
        virObjectUnref(cfg);
5855 5856 5857
        return -1;
    }

5858
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
5859
        goto error;
5860

5861 5862 5863 5864 5865
    /* Do this upfront, so any part of the startup process can add
     * runtime state to vm->def that won't be persisted. This let's us
     * report implicit runtime defaults in the XML, like vnc listen/socket
     */
    VIR_DEBUG("Setting current domain def as transient");
5866
    if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
5867
        goto error;
5868

5869
    vm->def->id = qemuDriverAllocateID(driver);
5870

5871
    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
5872
        driver->inhibitCallback(true, driver->inhibitOpaque);
5873
    active = true;
5874

5875
    if (virFileMakePath(cfg->logDir) < 0) {
5876 5877
        virReportSystemError(errno,
                             _("cannot create log directory %s"),
5878
                             cfg->logDir);
5879
        goto error;
5880 5881 5882
    }

    VIR_FREE(priv->pidfile);
5883
    if (VIR_STRDUP(priv->pidfile, pidfile) < 0)
5884
        goto error;
5885

5886 5887
    vm->pid = pid;

5888
    VIR_DEBUG("Detect security driver config");
5889
    sec_managers = virSecurityManagerGetNested(driver->securityManager);
5890 5891
    if (sec_managers == NULL)
        goto error;
5892 5893

    for (i = 0; sec_managers[i]; i++) {
5894
        seclabelgen = false;
5895 5896
        model = virSecurityManagerGetModel(sec_managers[i]);
        seclabeldef = virDomainDefGetSecurityLabelDef(vm->def, model);
5897
        if (seclabeldef == NULL) {
5898
            if (!(seclabeldef = virSecurityLabelDefNew(model)))
5899 5900 5901
                goto error;
            seclabelgen = true;
        }
5902 5903
        seclabeldef->type = VIR_DOMAIN_SECLABEL_STATIC;
        if (VIR_ALLOC(seclabel) < 0)
5904
            goto error;
5905
        if (virSecurityManagerGetProcessLabel(sec_managers[i],
5906
                                              vm->def, vm->pid, seclabel) < 0)
5907
            goto error;
5908

5909
        if (VIR_STRDUP(seclabeldef->model, model) < 0)
5910
            goto error;
5911

5912
        if (VIR_STRDUP(seclabeldef->label, seclabel->label) < 0)
5913
            goto error;
5914
        VIR_FREE(seclabel);
5915 5916 5917 5918 5919 5920

        if (seclabelgen) {
            if (VIR_APPEND_ELEMENT(vm->def->seclabels, vm->def->nseclabels, seclabeldef) < 0)
                goto error;
            seclabelgen = false;
        }
5921
    }
5922

5923 5924
    if (virSecurityManagerCheckAllLabel(driver->securityManager, vm->def) < 0)
        goto error;
5925 5926 5927
    if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0)
        goto error;

5928 5929 5930
    if (qemuDomainPerfRestart(vm) < 0)
        goto error;

5931
    VIR_DEBUG("Creating domain log file");
5932 5933
    if (!(logCtxt = qemuDomainLogContextNew(driver, vm,
                                            QEMU_DOMAIN_LOG_CONTEXT_MODE_ATTACH)))
5934
        goto error;
5935 5936

    VIR_DEBUG("Determining emulator version");
5937 5938
    virObjectUnref(priv->qemuCaps);
    if (!(priv->qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,
5939 5940
                                                      vm->def->emulator,
                                                      vm->def->os.machine)))
5941
        goto error;
5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953

    VIR_DEBUG("Preparing monitor state");
    priv->monConfig = monConfig;
    monConfig = NULL;
    priv->monJSON = monJSON;

    priv->gotShutdown = false;

    /*
     * Normally PCI addresses are assigned in the virDomainCreate
     * or virDomainDefine methods. We might still need to assign
     * some here to cope with the question of upgrades. Regardless
M
Martin Kletzander 已提交
5954
     * we also need to populate the PCI address set cache for later
5955 5956
     * use in hotplug
     */
5957
    VIR_DEBUG("Assigning domain PCI addresses");
5958
    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm, false)) < 0)
5959
        goto error;
5960

5961
    if ((timestamp = virTimeStringNow()) == NULL)
5962
        goto error;
5963

5964
    qemuDomainLogContextWrite(logCtxt, "%s: attaching\n", timestamp);
5965
    VIR_FREE(timestamp);
5966

5967
    qemuDomainObjTaint(driver, vm, VIR_DOMAIN_TAINT_EXTERNAL_LAUNCH, logCtxt);
5968 5969

    VIR_DEBUG("Waiting for monitor to show up");
5970
    if (qemuProcessWaitForMonitor(driver, vm, QEMU_ASYNC_JOB_NONE, priv->qemuCaps, NULL) < 0)
5971
        goto error;
5972

D
Daniel P. Berrange 已提交
5973
    /* Failure to connect to agent shouldn't be fatal */
5974 5975 5976 5977
    if ((ret = qemuConnectAgent(driver, vm)) < 0) {
        if (ret == -2)
            goto error;

D
Daniel P. Berrange 已提交
5978 5979 5980 5981 5982 5983
        VIR_WARN("Cannot connect to QEMU guest agent for %s",
                 vm->def->name);
        virResetLastError();
        priv->agentError = true;
    }

5984
    VIR_DEBUG("Detecting VCPU PIDs");
5985
    if (qemuDomainDetectVcpuPids(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
5986 5987 5988 5989
        goto error;

    VIR_DEBUG("Detecting IOThread PIDs");
    if (qemuProcessDetectIOThreadPIDs(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
5990
        goto error;
5991 5992

    VIR_DEBUG("Getting initial memory amount");
5993
    qemuDomainObjEnterMonitor(driver, vm);
5994 5995 5996 5997 5998 5999 6000
    if (qemuMonitorGetBalloonInfo(priv->mon, &vm->def->mem.cur_balloon) < 0)
        goto exit_monitor;
    if (qemuMonitorGetStatus(priv->mon, &running, &reason) < 0)
        goto exit_monitor;
    if (qemuMonitorGetVirtType(priv->mon, &vm->def->virtType) < 0)
        goto exit_monitor;
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
6001
        goto error;
6002

6003
    if (running) {
6004 6005
        virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
                             VIR_DOMAIN_RUNNING_UNPAUSED);
6006 6007 6008
        if (vm->def->memballoon &&
            vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO &&
            vm->def->memballoon->period) {
6009
            qemuDomainObjEnterMonitor(driver, vm);
6010
            qemuMonitorSetMemoryStatsPeriod(priv->mon, vm->def->memballoon,
6011
                                            vm->def->memballoon->period);
6012 6013
            if (qemuDomainObjExitMonitor(driver, vm) < 0)
                goto error;
6014 6015
        }
    } else {
6016
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
6017
    }
6018 6019

    VIR_DEBUG("Writing domain status to disk");
6020
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
6021
        goto error;
6022

6023 6024
    /* Run an hook to allow admins to do some magic */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
6025
        char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036
        int hookret;

        hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
                              VIR_HOOK_QEMU_OP_ATTACH, VIR_HOOK_SUBOP_BEGIN,
                              NULL, xml, NULL);
        VIR_FREE(xml);

        /*
         * If the script raised an error abort the launch
         */
        if (hookret < 0)
6037
            goto error;
6038 6039
    }

6040
    qemuDomainLogContextFree(logCtxt);
6041
    VIR_FREE(seclabel);
6042
    VIR_FREE(sec_managers);
6043
    virObjectUnref(cfg);
6044
    virObjectUnref(caps);
6045 6046 6047

    return 0;

6048 6049
 exit_monitor:
    ignore_value(qemuDomainObjExitMonitor(driver, vm));
6050
 error:
6051 6052 6053 6054 6055 6056
    /* We jump here if we failed to attach to the VM for any reason.
     * Leave the domain running, but pretend we never attempted to
     * attach to it.  */
    if (active && virAtomicIntDecAndTest(&driver->nactive) &&
        driver->inhibitCallback)
        driver->inhibitCallback(false, driver->inhibitOpaque);
6057
    qemuDomainLogContextFree(logCtxt);
6058
    VIR_FREE(seclabel);
6059
    VIR_FREE(sec_managers);
6060 6061
    if (seclabelgen)
        virSecurityLabelDefFree(seclabeldef);
6062
    virDomainChrSourceDefFree(monConfig);
6063
    virObjectUnref(cfg);
6064
    virObjectUnref(caps);
6065 6066 6067 6068
    return -1;
}


6069
static virDomainObjPtr
6070 6071 6072
qemuProcessAutoDestroy(virDomainObjPtr dom,
                       virConnectPtr conn,
                       void *opaque)
6073
{
6074
    virQEMUDriverPtr driver = opaque;
6075
    qemuDomainObjPrivatePtr priv = dom->privateData;
6076
    virObjectEventPtr event = NULL;
6077
    unsigned int stopFlags = 0;
6078

6079
    VIR_DEBUG("vm=%s, conn=%p", dom->def->name, conn);
6080

6081 6082
    virObjectRef(dom);

6083 6084 6085
    if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;

6086 6087
    if (priv->job.asyncJob) {
        VIR_DEBUG("vm=%s has long-term job active, cancelling",
6088
                  dom->def->name);
6089
        qemuDomainObjDiscardAsyncJob(driver, dom);
6090 6091 6092
    }

    VIR_DEBUG("Killing domain");
6093

6094 6095 6096 6097 6098
    if (qemuProcessBeginStopJob(driver, dom, QEMU_JOB_DESTROY, true) < 0)
        goto cleanup;

    qemuProcessStop(driver, dom, VIR_DOMAIN_SHUTOFF_DESTROYED,
                    QEMU_ASYNC_JOB_NONE, stopFlags);
6099

6100
    virDomainAuditStop(dom, "destroyed");
6101
    event = virDomainEventLifecycleNewFromObj(dom,
6102 6103
                                     VIR_DOMAIN_EVENT_STOPPED,
                                     VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
6104

6105 6106
    qemuDomainObjEndJob(driver, dom);

6107
    qemuDomainRemoveInactive(driver, dom);
6108

6109
    qemuDomainEventQueue(driver, event);
6110

6111
 cleanup:
6112
    virDomainObjEndAPI(&dom);
6113
    return dom;
6114 6115
}

6116
int qemuProcessAutoDestroyAdd(virQEMUDriverPtr driver,
6117 6118 6119
                              virDomainObjPtr vm,
                              virConnectPtr conn)
{
6120
    VIR_DEBUG("vm=%s, conn=%p", vm->def->name, conn);
6121 6122
    return virCloseCallbacksSet(driver->closeCallbacks, vm, conn,
                                qemuProcessAutoDestroy);
6123 6124
}

6125
int qemuProcessAutoDestroyRemove(virQEMUDriverPtr driver,
6126 6127
                                 virDomainObjPtr vm)
{
6128
    int ret;
6129
    VIR_DEBUG("vm=%s", vm->def->name);
6130 6131 6132
    ret = virCloseCallbacksUnset(driver->closeCallbacks, vm,
                                 qemuProcessAutoDestroy);
    return ret;
6133
}
6134

6135
bool qemuProcessAutoDestroyActive(virQEMUDriverPtr driver,
6136 6137
                                  virDomainObjPtr vm)
{
6138
    virCloseCallback cb;
6139
    VIR_DEBUG("vm=%s", vm->def->name);
6140
    cb = virCloseCallbacksGet(driver->closeCallbacks, vm, NULL);
6141
    return cb == qemuProcessAutoDestroy;
6142
}
6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165


int
qemuProcessRefreshDisks(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
                        qemuDomainAsyncJob asyncJob)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virHashTablePtr table = NULL;
    int ret = -1;
    size_t i;

    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
        table = qemuMonitorGetBlockInfo(priv->mon);
        if (qemuDomainObjExitMonitor(driver, vm) < 0)
            goto cleanup;
    }

    if (!table)
        goto cleanup;

    for (i = 0; i < vm->def->ndisks; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
6166
        qemuDomainDiskPrivatePtr diskpriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
6167 6168
        struct qemuDomainDiskInfo *info;

6169 6170
        if (!(info = virHashLookup(table, disk->info.alias)))
            continue;
6171

6172 6173
        if (info->removable) {
            if (info->empty)
6174 6175
                ignore_value(virDomainDiskSetSource(disk, NULL));

6176 6177 6178 6179 6180 6181
            if (info->tray) {
                if (info->tray_open)
                    disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
                else
                    disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
            }
6182
        }
6183 6184 6185 6186

        /* fill in additional data */
        diskpriv->removable = info->removable;
        diskpriv->tray = info->tray;
6187 6188 6189 6190 6191 6192 6193 6194
    }

    ret = 0;

 cleanup:
    virHashFree(table);
    return ret;
}