qemu_process.c 204.6 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
C
Chen Hanxiao 已提交
1681
     * deleted until 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
                if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGAMEM) &&
2571 2572
                    qemuMonitorUpdateVideoMemorySize(priv->mon, video,
                                                     "qxl-vga") < 0)
2573
                        goto error;
2574

2575
                if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VRAM64) &&
2576 2577 2578
                    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
static int
qemuProcessUpdateDevices(virQEMUDriverPtr driver,
                         virDomainObjPtr vm)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virDomainDeviceDef dev;
3154
    const char **qemuDevices;
3155 3156 3157 3158 3159 3160 3161 3162 3163
    char **old;
    char **tmp;
    int ret = -1;

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

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

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

3180
 cleanup:
3181 3182 3183 3184
    virStringFreeList(old);
    return ret;
}

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

3192
    if (!(priv->perf = virPerfNew()))
3193 3194 3195
        return -1;

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

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

    return 0;
}

3208 3209
struct qemuProcessReconnectData {
    virConnectPtr conn;
3210
    virQEMUDriverPtr driver;
3211
    virDomainObjPtr obj;
3212 3213 3214 3215
};
/*
 * Open an existing VM's monitor, re-detect VCPU threads
 * and re-reserve the security labels in use
S
Stefan Berger 已提交
3216 3217 3218 3219
 *
 * 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.
3220
 *
3221
 * This function also inherits a locked and ref'd domain object.
3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233
 *
 * 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.
3234 3235
 */
static void
3236
qemuProcessReconnect(void *opaque)
3237 3238
{
    struct qemuProcessReconnectData *data = opaque;
3239
    virQEMUDriverPtr driver = data->driver;
3240
    virDomainObjPtr obj = data->obj;
3241 3242
    qemuDomainObjPrivatePtr priv;
    virConnectPtr conn = data->conn;
3243
    struct qemuDomainJobObj oldjob;
3244 3245
    int state;
    int reason;
3246
    virQEMUDriverConfigPtr cfg;
3247
    size_t i;
3248
    int ret;
3249
    unsigned int stopFlags = 0;
3250
    bool jobStarted = false;
3251
    virCapsPtr caps = NULL;
3252

3253 3254
    VIR_FREE(data);

3255
    qemuDomainObjRestoreJob(obj, &oldjob);
3256 3257
    if (oldjob.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
3258

3259 3260 3261
    cfg = virQEMUDriverGetConfig(driver);
    priv = obj->privateData;

3262 3263 3264
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto error;

3265 3266 3267 3268
    if (qemuDomainObjBeginJob(driver, obj, QEMU_JOB_MODIFY) < 0)
        goto error;
    jobStarted = true;

3269 3270 3271
    /* 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)))
3272
        goto error;
3273

J
John Ferlan 已提交
3274 3275 3276 3277
    /* Restore the masterKey */
    if (qemuDomainMasterKeyReadFile(priv) < 0)
        goto error;

3278
    virNWFilterReadLockFilterUpdates();
3279 3280 3281 3282

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

    /* XXX check PID liveliness & EXE path */
3283
    if (qemuConnectMonitor(driver, obj, QEMU_ASYNC_JOB_NONE, NULL) < 0)
3284 3285
        goto error;

3286
    if (qemuHostdevUpdateActiveDomainDevices(driver, obj->def) < 0)
3287 3288
        goto error;

3289
    if (qemuConnectCgroup(driver, obj) < 0)
3290 3291
        goto error;

3292 3293 3294
    if (qemuDomainPerfRestart(obj) < 0)
        goto error;

3295
    /* XXX: Need to change as long as lock is introduced for
3296
     * qemu_driver->sharedDevices.
3297 3298
     */
    for (i = 0; i < obj->def->ndisks; i++) {
3299 3300
        virDomainDeviceDef dev;

3301
        if (virStorageTranslateDiskSourcePool(conn, obj->def->disks[i]) < 0)
3302
            goto error;
3303

3304 3305 3306 3307 3308 3309
        /* 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)
3310 3311
            goto error;

3312 3313 3314
        dev.type = VIR_DOMAIN_DEVICE_DISK;
        dev.data.disk = obj->def->disks[i];
        if (qemuAddSharedDevice(driver, &dev, obj->def->name) < 0)
3315 3316 3317
            goto error;
    }

3318 3319 3320
    if (qemuProcessUpdateState(driver, obj) < 0)
        goto error;

3321
    state = virDomainObjGetState(obj, &reason);
3322 3323 3324
    if (state == VIR_DOMAIN_SHUTOFF ||
        (state == VIR_DOMAIN_PAUSED &&
         reason == VIR_DOMAIN_PAUSED_STARTING_UP)) {
3325 3326 3327 3328 3329
        VIR_DEBUG("Domain '%s' wasn't fully started yet, killing it",
                  obj->def->name);
        goto error;
    }

3330 3331 3332
    /* If upgrading from old libvirtd we won't have found any
     * caps in the domain status, so re-query them
     */
3333
    if (!priv->qemuCaps &&
3334 3335
        !(priv->qemuCaps = virQEMUCapsCacheLookupCopy(caps,
                                                      driver->qemuCapsCache,
3336 3337
                                                      obj->def->emulator,
                                                      obj->def->os.machine)))
3338 3339
        goto error;

3340
    /* In case the domain shutdown while we were not running,
3341
     * we need to finish the shutdown process. And we need to do it after
3342
     * we have virQEMUCaps filled in.
3343
     */
3344 3345 3346 3347 3348 3349
    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);
3350
        goto cleanup;
3351 3352
    }

3353
    if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps, obj, false)) < 0)
3354
        goto error;
3355

3356 3357 3358 3359 3360 3361
    /* if domain requests security driver we haven't loaded, report error, but
     * do not kill the domain
     */
    ignore_value(virSecurityManagerCheckAllLabel(driver->securityManager,
                                                 obj->def));

3362 3363 3364
    if (qemuDomainRefreshVcpuInfo(driver, obj, QEMU_ASYNC_JOB_NONE, true) < 0)
        goto error;

3365
    if (virSecurityManagerReserveLabel(driver->securityManager, obj->def, obj->pid) < 0)
3366 3367
        goto error;

3368 3369 3370
    if (qemuProcessNotifyNets(obj->def) < 0)
        goto error;

3371
    if (qemuProcessFiltersInstantiate(obj->def))
3372 3373
        goto error;

3374
    if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
3375 3376
        goto error;

3377
    if (qemuRefreshVirtioChannelState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
3378 3379
        goto error;

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

3383 3384 3385
    if (qemuProcessRefreshBalloonState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
        goto error;

3386 3387 3388
    if (qemuProcessRecoverJob(driver, obj, conn, &oldjob) < 0)
        goto error;

3389 3390 3391
    if (qemuProcessUpdateDevices(driver, obj) < 0)
        goto error;

3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402
    /* 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;
    }

3403
    /* update domain state XML with possibly updated state in virDomainObj */
3404
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->caps) < 0)
3405 3406
        goto error;

3407 3408
    /* Run an hook to allow admins to do some magic */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
3409
        char *xml = qemuDomainDefFormatXML(driver, obj->def, 0);
3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423
        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;
    }

3424
    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
3425 3426
        driver->inhibitCallback(true, driver->inhibitOpaque);

3427 3428 3429 3430 3431 3432 3433 3434
 cleanup:
    if (jobStarted)
        qemuDomainObjEndJob(driver, obj);
    if (!virDomainObjIsActive(obj))
        qemuDomainRemoveInactive(driver, obj);
    virDomainObjEndAPI(&obj);
    virObjectUnref(conn);
    virObjectUnref(cfg);
3435
    virObjectUnref(caps);
3436 3437
    virNWFilterUnlockFilterUpdates();
    return;
3438

3439
 error:
3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453
    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;
3454
        }
3455 3456 3457 3458 3459
        /* 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);
3460
    }
3461
    goto cleanup;
3462 3463
}

3464 3465
static int
qemuProcessReconnectHelper(virDomainObjPtr obj,
3466 3467 3468 3469 3470 3471
                           void *opaque)
{
    virThread thread;
    struct qemuProcessReconnectData *src = opaque;
    struct qemuProcessReconnectData *data;

3472
    /* If the VM was inactive, we don't need to reconnect */
3473 3474 3475
    if (!obj->pid)
        return 0;

3476
    if (VIR_ALLOC(data) < 0)
3477
        return -1;
3478 3479

    memcpy(data, src, sizeof(*data));
3480
    data->obj = obj;
3481

3482 3483
    /* this lock and reference will be eventually transferred to the thread
     * that handles the reconnect */
3484
    virObjectLock(obj);
3485
    virObjectRef(obj);
3486

3487 3488 3489
    /* 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 已提交
3490
     */
3491
    virObjectRef(data->conn);
S
Stefan Berger 已提交
3492

3493
    if (virThreadCreate(&thread, false, qemuProcessReconnect, data) < 0) {
3494 3495 3496
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Could not create thread. QEMU initialization "
                         "might be incomplete"));
3497 3498 3499 3500 3501 3502 3503
        /* 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);
3504
        qemuDomainRemoveInactive(src->driver, obj);
3505

M
Michal Privoznik 已提交
3506
        virDomainObjEndAPI(&obj);
3507 3508 3509 3510
        virObjectUnref(data->conn);
        VIR_FREE(data);
        return -1;
    }
3511

3512
    return 0;
3513 3514 3515 3516 3517 3518 3519 3520 3521
}

/**
 * qemuProcessReconnectAll
 *
 * Try to re-open the resources for live VMs that we care
 * about.
 */
void
3522
qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver)
3523
{
3524
    struct qemuProcessReconnectData data = {.conn = conn, .driver = driver};
3525
    virDomainObjListForEach(driver->domains, qemuProcessReconnectHelper, &data);
3526 3527
}

3528
static int
3529
qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver,
3530 3531
                            virDomainGraphicsDefPtr graphics,
                            bool allocate)
3532 3533 3534
{
    unsigned short port;

3535 3536 3537 3538 3539 3540 3541
    if (!allocate) {
        if (graphics->data.vnc.autoport)
            graphics->data.vnc.port = 5900;

        return 0;
    }

3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555
    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;
}
3556

3557
static int
3558
qemuProcessSPICEAllocatePorts(virQEMUDriverPtr driver,
3559 3560
                              virDomainGraphicsDefPtr graphics,
                              bool allocate)
3561
{
3562
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
3563 3564
    unsigned short port = 0;
    unsigned short tlsPort;
3565
    size_t i;
3566
    int defaultMode = graphics->data.spice.defaultMode;
3567
    int ret = -1;
3568 3569 3570 3571 3572 3573

    bool needTLSPort = false;
    bool needPort = false;

    if (graphics->data.spice.autoport) {
        /* check if tlsPort or port need allocation */
3574
        for (i = 0; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST; i++) {
3575 3576 3577 3578 3579 3580 3581 3582 3583 3584
            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:
3585
                /* default mode will be used */
3586 3587 3588
                break;
            }
        }
3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603
        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;
        }
3604 3605
    }

3606 3607 3608 3609 3610 3611 3612
    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;

3613 3614
        ret = 0;
        goto cleanup;
3615 3616
    }

3617
    if (needPort || graphics->data.spice.port == -1) {
3618
        if (virPortAllocatorAcquire(driver->remotePorts, &port) < 0)
3619
            goto cleanup;
3620 3621

        graphics->data.spice.port = port;
3622 3623 3624

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

3627 3628
    if (needTLSPort || graphics->data.spice.tlsPort == -1) {
        if (!cfg->spiceTLS) {
3629 3630 3631
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Auto allocation of spice TLS port requested "
                             "but spice TLS is disabled in qemu.conf"));
3632
            goto cleanup;
3633
        }
3634 3635

        if (virPortAllocatorAcquire(driver->remotePorts, &tlsPort) < 0)
3636
            goto cleanup;
3637 3638

        graphics->data.spice.tlsPort = tlsPort;
3639 3640 3641

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

3644
    ret = 0;
3645

3646
 cleanup:
3647
    virPortAllocatorRelease(driver->remotePorts, port);
3648 3649
    virObjectUnref(cfg);
    return ret;
3650 3651 3652
}


3653 3654 3655
static int
qemuValidateCpuCount(virDomainDefPtr def,
                     virQEMUCapsPtr qemuCaps)
3656
{
3657
    unsigned int maxCpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, def->os.machine);
3658

3659 3660 3661 3662 3663 3664
    if (virDomainDefGetVcpus(def) == 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Domain requires at least 1 vCPU"));
        return -1;
    }

3665 3666 3667 3668
    if (maxCpus > 0 && virDomainDefGetVcpusMax(def) > maxCpus) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Maximum CPUs greater than specified machine type limit"));
        return -1;
3669 3670
    }

3671
    return 0;
3672 3673
}

3674 3675

static bool
3676 3677 3678
qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver,
                          virDomainObjPtr vm,
                          int asyncJob)
3679 3680 3681 3682 3683
{
    virDomainDefPtr def = vm->def;
    virArch arch = def->os.arch;
    virCPUDataPtr guestcpu = NULL;
    qemuDomainObjPrivatePtr priv = vm->privateData;
3684
    int rc;
3685
    bool ret = false;
J
Ján Tomko 已提交
3686
    size_t i;
3687 3688 3689 3690

    switch (arch) {
    case VIR_ARCH_I686:
    case VIR_ARCH_X86_64:
3691 3692
        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
            return false;
3693
        rc = qemuMonitorGetGuestCPU(priv->mon, arch, &guestcpu);
3694 3695
        if (qemuDomainObjExitMonitor(driver, vm) < 0)
            return false;
3696

3697 3698 3699 3700
        if (rc < 0) {
            if (rc == -2)
                break;

3701
            goto cleanup;
3702
        }
3703

J
Ján Tomko 已提交
3704
        if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_TRISTATE_SWITCH_ON) {
3705
            if (!virCPUDataCheckFeature(guestcpu, VIR_CPU_x86_KVM_PV_UNHALT)) {
3706 3707 3708 3709 3710
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("host doesn't support paravirtual spinlocks"));
                goto cleanup;
            }
        }
J
Ján Tomko 已提交
3711

3712 3713 3714 3715 3716 3717
        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;
3718
                if (!virCPUDataCheckFeature(guestcpu, cpuFeature)) {
3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736
                    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;
3737 3738

                    /* coverity[dead_error_begin] */
3739 3740 3741 3742 3743 3744
                    case VIR_DOMAIN_HYPERV_LAST:
                        break;
                    }
                }
            }
        }
J
Ján Tomko 已提交
3745

3746 3747 3748
        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 已提交
3749

3750 3751 3752 3753
                if (feature->policy != VIR_CPU_FEATURE_REQUIRE)
                    continue;

                if (STREQ(feature->name, "invtsc") &&
3754
                    !virCPUDataCheckFeature(guestcpu, feature->name)) {
3755 3756 3757 3758
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("host doesn't support invariant TSC"));
                    goto cleanup;
                }
J
Ján Tomko 已提交
3759 3760
            }
        }
3761 3762 3763 3764 3765 3766 3767 3768
        break;

    default:
        break;
    }

    ret = true;

3769
 cleanup:
3770 3771 3772 3773 3774
    cpuDataFree(guestcpu);
    return ret;
}


3775 3776
static int
qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
3777
                 virDomainObjPtr vm)
3778 3779 3780 3781
{
    int ret = -1;
    int srcFD = -1;
    int dstFD = -1;
3782
    virDomainLoaderDefPtr loader = vm->def->os.loader;
3783
    bool created = false;
3784 3785
    const char *master_nvram_path;
    ssize_t r;
3786

3787
    if (!loader || !loader->nvram || virFileExists(loader->nvram))
3788 3789
        return 0;

3790 3791 3792
    master_nvram_path = loader->templt;
    if (!loader->templt) {
        size_t i;
3793 3794 3795
        for (i = 0; i < cfg->nfirmwares; i++) {
            if (STREQ(cfg->firmwares[i]->name, loader->path)) {
                master_nvram_path = cfg->firmwares[i]->nvram;
3796
                break;
3797 3798
            }
        }
3799
    }
3800

3801 3802 3803 3804 3805 3806
    if (!master_nvram_path) {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("unable to find any master var store for "
                         "loader: %s"), loader->path);
        goto cleanup;
    }
3807

3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824
    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;
3825

3826 3827
    do {
        char buf[1024];
3828

3829
        if ((r = saferead(srcFD, buf, sizeof(buf))) < 0) {
3830
            virReportSystemError(errno,
3831
                                 _("Unable to read from file '%s'"),
3832 3833 3834
                                 master_nvram_path);
            goto cleanup;
        }
3835 3836

        if (safewrite(dstFD, buf, r) < 0) {
3837
            virReportSystemError(errno,
3838
                                 _("Unable to write to file '%s'"),
3839 3840 3841
                                 loader->nvram);
            goto cleanup;
        }
3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854
    } 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;
3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871
    }

    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;
}


3872 3873 3874
static void
qemuLogOperation(virDomainObjPtr vm,
                 const char *msg,
3875 3876
                 virCommandPtr cmd,
                 qemuDomainLogContextPtr logCtxt)
3877 3878 3879 3880 3881
{
    char *timestamp;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int qemuVersion = virQEMUCapsGetVersion(priv->qemuCaps);
    const char *package = virQEMUCapsGetPackage(priv->qemuCaps);
3882
    char *hostname = virGetHostname();
3883 3884

    if ((timestamp = virTimeStringNow()) == NULL)
3885
        goto cleanup;
3886

3887 3888
    if (qemuDomainLogContextWrite(logCtxt,
                                  "%s: %s %s, qemu version: %d.%d.%d%s, hostname: %s\n",
3889 3890 3891 3892
                                  timestamp, msg, VIR_LOG_VERSION_STRING,
                                  (qemuVersion / 1000000) % 1000,
                                  (qemuVersion / 1000) % 1000,
                                  qemuVersion % 1000,
3893 3894
                                  package ? package : "",
                                  hostname ? hostname : "") < 0)
3895
        goto cleanup;
3896

3897 3898 3899 3900 3901
    if (cmd) {
        char *args = virCommandToString(cmd);
        qemuDomainLogContextWrite(logCtxt, "%s\n", args);
        VIR_FREE(args);
    }
3902 3903

 cleanup:
3904
    VIR_FREE(hostname);
3905 3906 3907
    VIR_FREE(timestamp);
}

3908 3909 3910 3911 3912 3913 3914

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

3915
    VIR_FREE(inc->address);
3916
    VIR_FREE(inc->launchURI);
3917
    VIR_FREE(inc->deferredURI);
3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928
    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,
3929
                          const char *listenAddress,
3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941
                          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;

3942 3943 3944
    if (VIR_STRDUP(inc->address, listenAddress) < 0)
        goto error;

3945 3946 3947 3948
    inc->launchURI = qemuMigrationIncomingURI(migrateFrom, fd);
    if (!inc->launchURI)
        goto error;

3949 3950 3951 3952 3953 3954
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_INCOMING_DEFER)) {
        inc->deferredURI = inc->launchURI;
        if (VIR_STRDUP(inc->launchURI, "defer") < 0)
            goto error;
    }

3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965
    inc->fd = fd;
    inc->path = path;

    return inc;

 error:
    qemuProcessIncomingDefFree(inc);
    return NULL;
}


3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995
/*
 * 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);
}


3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018
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;
}


4019
static int
4020
qemuProcessGraphicsReservePorts(virQEMUDriverPtr driver,
4021
                                virDomainGraphicsDefPtr graphics)
4022
{
4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033
    virDomainGraphicsListenDefPtr glisten;

    if (graphics->nListens <= 0)
        return 0;

    glisten = &graphics->listens[0];

    if (glisten->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS &&
        glisten->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK)
        return 0;

4034 4035 4036 4037 4038 4039 4040
    if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
        !graphics->data.vnc.autoport) {
        if (virPortAllocatorSetUsed(driver->remotePorts,
                                    graphics->data.vnc.port,
                                    true) < 0)
            return -1;
        graphics->data.vnc.portReserved = true;
4041

4042 4043 4044
    } else if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
               !graphics->data.spice.autoport) {
        if (graphics->data.spice.port > 0) {
4045
            if (virPortAllocatorSetUsed(driver->remotePorts,
4046
                                        graphics->data.spice.port,
4047
                                        true) < 0)
4048
                return -1;
4049 4050
            graphics->data.spice.portReserved = true;
        }
4051

4052 4053 4054 4055 4056 4057
        if (graphics->data.spice.tlsPort > 0) {
            if (virPortAllocatorSetUsed(driver->remotePorts,
                                        graphics->data.spice.tlsPort,
                                        true) < 0)
                return -1;
            graphics->data.spice.tlsPortReserved = true;
4058 4059 4060
        }
    }

4061 4062 4063 4064
    return 0;
}


4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102
static int
qemuProcessGraphicsAllocatePorts(virQEMUDriverPtr driver,
                                 virDomainGraphicsDefPtr graphics,
                                 bool allocate)
{
    virDomainGraphicsListenDefPtr glisten;

    if (graphics->nListens <= 0)
        return 0;

    glisten = &graphics->listens[0];

    if (glisten->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS &&
        glisten->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK)
        return 0;

    switch (graphics->type) {
    case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
        if (qemuProcessVNCAllocatePorts(driver, graphics, allocate) < 0)
            return -1;
        break;

    case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
        if (qemuProcessSPICEAllocatePorts(driver, graphics, allocate) < 0)
            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;
    }

    return 0;
}


4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129
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;
}


4130
static int
4131
qemuProcessGraphicsSetupListen(virQEMUDriverPtr driver,
4132 4133
                               virDomainGraphicsDefPtr graphics,
                               virDomainObjPtr vm)
4134
{
4135
    qemuDomainObjPrivatePtr priv = vm->privateData;
4136
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4137
    const char *type = virDomainGraphicsTypeToString(graphics->type);
4138
    char *listenAddr = NULL;
4139
    bool useSocket = false;
4140
    size_t i;
4141
    int ret = -1;
4142 4143 4144

    switch (graphics->type) {
    case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
4145
        useSocket = cfg->vncAutoUnixSocket;
4146 4147 4148 4149
        listenAddr = cfg->vncListen;
        break;

    case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
4150
        useSocket = cfg->spiceAutoUnixSocket;
4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165
        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:
4166 4167 4168 4169 4170
            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) {
4171 4172
                    memset(glisten, 0, sizeof(virDomainGraphicsListenDef));
                    if (virAsprintf(&glisten->socket, "%s/%s.sock",
4173
                                    priv->libDir, type) < 0)
4174
                        goto cleanup;
4175 4176
                    glisten->fromConfig = true;
                    glisten->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET;
4177 4178
                } else if (listenAddr) {
                    if (VIR_STRDUP(glisten->address, listenAddr) < 0)
4179
                        goto cleanup;
4180 4181 4182
                    glisten->fromConfig = true;
                }
            }
4183 4184 4185 4186 4187 4188 4189 4190
            break;

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

            if (qemuProcessGraphicsSetupNetworkAddress(glisten,
                                                       listenAddr) < 0)
4191
                goto cleanup;
4192 4193
            break;

4194 4195 4196 4197
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
            if (!glisten->socket) {
                if (virAsprintf(&glisten->socket, "%s/%s.sock",
                                priv->libDir, type) < 0)
4198
                    goto cleanup;
4199 4200 4201 4202
                glisten->autoGenerated = true;
            }
            break;

4203 4204 4205 4206 4207 4208
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
            break;
        }
    }

4209 4210 4211 4212 4213
    ret = 0;

 cleanup:
    virObjectUnref(cfg);
    return ret;
4214 4215 4216
}


4217 4218
static int
qemuProcessSetupGraphics(virQEMUDriverPtr driver,
4219 4220
                         virDomainObjPtr vm,
                         unsigned int flags)
4221
{
4222
    virDomainGraphicsDefPtr graphics;
4223
    bool allocate = !(flags & VIR_QEMU_PROCESS_START_PRETEND);
4224
    size_t i;
4225 4226
    int ret = -1;

4227 4228 4229 4230 4231 4232 4233
    for (i = 0; i < vm->def->ngraphics; i++) {
        graphics = vm->def->graphics[i];

        if (qemuProcessGraphicsSetupListen(driver, graphics, vm) < 0)
            goto cleanup;
    }

4234 4235 4236 4237 4238 4239 4240 4241
    if (allocate) {
        for (i = 0; i < vm->def->ngraphics; i++) {
            graphics = vm->def->graphics[i];

            if (qemuProcessGraphicsReservePorts(driver, graphics) < 0)
                goto cleanup;
        }
    }
4242

4243
    for (i = 0; i < vm->def->ngraphics; ++i) {
4244
        graphics = vm->def->graphics[i];
4245

4246 4247
        if (qemuProcessGraphicsAllocatePorts(driver, graphics, allocate) < 0)
            goto cleanup;
4248 4249 4250 4251 4252 4253 4254 4255 4256
    }

    ret = 0;

 cleanup:
    return ret;
}


4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315
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;
}


4316 4317 4318 4319 4320 4321 4322 4323 4324
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;

4325
    if (!virDomainDefHasMemballoon(vm->def))
4326 4327 4328 4329 4330
        return 0;

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

4331 4332 4333
    if (vm->def->memballoon->period)
        qemuMonitorSetMemoryStatsPeriod(priv->mon, vm->def->memballoon,
                                        vm->def->memballoon->period);
4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345
    if (qemuMonitorSetBalloon(priv->mon, balloon) < 0)
        goto cleanup;

    ret = 0;

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


J
Jiri Denemark 已提交
4346 4347 4348
static int
qemuProcessMakeDir(virQEMUDriverPtr driver,
                   virDomainObjPtr vm,
4349
                   const char *path)
J
Jiri Denemark 已提交
4350 4351 4352 4353 4354 4355 4356 4357
{
    int ret = -1;

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

4358 4359
    if (virSecurityManagerDomainSetPathLabel(driver->securityManager,
                                             vm->def, path) < 0)
J
Jiri Denemark 已提交
4360 4361 4362 4363 4364 4365 4366 4367 4368
        goto cleanup;

    ret = 0;

 cleanup:
    return ret;
}


4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417
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");
    }
}

4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449

static int
qemuProcessStartValidateGraphics(virDomainObjPtr vm)
{
    size_t i;

    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;
        }
    }

    return 0;
}


4450 4451 4452 4453 4454 4455 4456 4457 4458 4459
static int
qemuProcessStartValidateVideo(virDomainObjPtr vm,
                              virQEMUCapsPtr qemuCaps)
{
    size_t i;
    virDomainVideoDefPtr video;

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

4460 4461 4462 4463 4464 4465 4466 4467 4468 4469
        if ((video->type == VIR_DOMAIN_VIDEO_TYPE_VGA &&
             !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VGA)) ||
            (video->type == VIR_DOMAIN_VIDEO_TYPE_CIRRUS &&
             !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA)) ||
            (video->type == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
             !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA)) ||
            (video->type == VIR_DOMAIN_VIDEO_TYPE_QXL &&
             !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL)) ||
            (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO &&
             !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU))) {
4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("this QEMU does not support '%s' video device"),
                           virDomainVideoTypeToString(video->type));
            return -1;
        }

        if (video->accel) {
            if (video->accel->accel3d == VIR_TRISTATE_SWITCH_ON &&
                (video->type != VIR_DOMAIN_VIDEO_TYPE_VIRTIO ||
                 !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_VIRGL))) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("%s 3d acceleration is not supported"),
                               virDomainVideoTypeToString(video->type));
                return -1;
            }
        }
    }

    return 0;
}


4492
static int
4493 4494
qemuProcessStartValidateXML(virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
4495
                            virQEMUCapsPtr qemuCaps,
4496
                            virCapsPtr caps,
4497
                            unsigned int flags)
4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509
{
    /* 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;

4510 4511 4512
    /* 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 */
4513 4514 4515
    if ((flags & VIR_QEMU_PROCESS_START_NEW) &&
        virDomainDefValidate(vm->def, caps, 0, driver->xmlopt) < 0)
        return -1;
4516 4517 4518

    return 0;
}
4519

4520

4521 4522 4523 4524 4525 4526
/**
 * qemuProcessStartValidate:
 * @vm: domain object
 * @qemuCaps: emulator capabilities
 * @migration: restoration of existing state
 *
4527 4528 4529 4530 4531
 * 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.
4532
 */
4533
static int
4534 4535
qemuProcessStartValidate(virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
4536
                         virQEMUCapsPtr qemuCaps,
4537
                         virCapsPtr caps,
4538
                         unsigned int flags)
4539
{
4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558
    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;

    }

4559
    if (qemuProcessStartValidateXML(driver, vm, qemuCaps, caps, flags) < 0)
4560 4561
        return -1;

4562 4563 4564
    if (qemuProcessStartValidateGraphics(vm) < 0)
        return -1;

4565 4566 4567
    if (qemuProcessStartValidateVideo(vm, qemuCaps) < 0)
        return -1;

4568 4569
    VIR_DEBUG("Checking for any possible (non-fatal) issues");

4570
    qemuProcessStartWarnShmem(vm);
4571

4572
    return 0;
4573 4574 4575
}


J
Jiri Denemark 已提交
4576 4577 4578 4579 4580 4581
/**
 * qemuProcessInit:
 *
 * Prepares the domain up to the point when priv->qemuCaps is initialized. The
 * function calls qemuProcessStop when needed.
 *
4582 4583 4584 4585
 * 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 已提交
4586 4587 4588 4589 4590
 * Returns 0 on success, -1 on error.
 */
int
qemuProcessInit(virQEMUDriverPtr driver,
                virDomainObjPtr vm,
4591
                qemuDomainAsyncJob asyncJob,
4592
                bool migration,
4593
                unsigned int flags)
J
Jiri Denemark 已提交
4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612
{
    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)))
4613 4614 4615 4616
        goto cleanup;

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

4623
    if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) < 0)
4624 4625
        goto cleanup;

J
Jiri Denemark 已提交
4626 4627 4628 4629 4630
    /* 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");
4631
    if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
J
Jiri Denemark 已提交
4632 4633
        goto stop;

4634 4635 4636 4637
    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 已提交
4638

4639 4640
        if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
            driver->inhibitCallback(true, driver->inhibitOpaque);
J
Jiri Denemark 已提交
4641

4642 4643 4644 4645 4646 4647
        /* 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 已提交
4648

4649
    if (qemuDomainSetPrivatePaths(driver, vm) < 0)
4650 4651
        goto cleanup;

J
Jiri Denemark 已提交
4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662
    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;
4663
    qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, asyncJob, stopFlags);
J
Jiri Denemark 已提交
4664 4665 4666 4667
    goto cleanup;
}


4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720
/**
 * 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;
}


4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736
/**
 * 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);
4737
    virDomainVcpuDefPtr vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
4738

4739 4740 4741 4742 4743
    return qemuProcessSetupPid(vm, vcpupid, VIR_CGROUP_THREAD_VCPU,
                               vcpuid, vcpu->cpumask,
                               vm->def->cputune.period,
                               vm->def->cputune.quota,
                               &vcpu->sched);
4744 4745 4746 4747 4748 4749
}


static int
qemuProcessSetupVcpus(virDomainObjPtr vm)
{
4750
    virDomainVcpuDefPtr vcpu;
4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795
    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;
}


4796 4797 4798 4799 4800
int
qemuProcessSetupIOThread(virDomainObjPtr vm,
                         virDomainIOThreadIDDefPtr iothread)
{

4801 4802
    return qemuProcessSetupPid(vm, iothread->thread_id,
                               VIR_CGROUP_THREAD_IOTHREAD,
4803
                               iothread->iothread_id,
4804
                               iothread->cpumask,
4805 4806
                               vm->def->cputune.iothread_period,
                               vm->def->cputune.iothread_quota,
4807
                               &iothread->sched);
4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826
}


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;
}


4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838
static int
qemuProcessValidateHotpluggableVcpus(virDomainDefPtr def)
{
    virDomainVcpuDefPtr vcpu;
    virDomainVcpuDefPtr subvcpu;
    qemuDomainVcpuPrivatePtr vcpupriv;
    unsigned int maxvcpus = virDomainDefGetVcpusMax(def);
    size_t i = 0;
    size_t j;
    virBitmapPtr ordermap = NULL;
    int ret = -1;

4839
    if (!(ordermap = virBitmapNew(maxvcpus + 1)))
4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855
        goto cleanup;

    /* validate:
     * - all hotpluggable entities to be hotplugged have the correct data
     * - vcpus belonging to a hotpluggable entity share configuration
     * - order of the hotpluggable entities is unique
     */
    for (i = 0; i < maxvcpus; i++) {
        vcpu = virDomainDefGetVcpu(def, i);
        vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);

        /* skip over hotpluggable entities  */
        if (vcpupriv->vcpus == 0)
            continue;

        if (vcpu->order != 0) {
4856
            if (virBitmapIsBitSet(ordermap, vcpu->order)) {
4857
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
4858
                               _("duplicate vcpu order '%u'"), vcpu->order);
4859 4860 4861
                goto cleanup;
            }

4862 4863 4864 4865 4866 4867
            if (virBitmapSetBit(ordermap, vcpu->order)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("vcpu order '%u' exceeds vcpu count"),
                               vcpu->order);
                goto cleanup;
            }
4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934
        }

        for (j = i + 1; j < (i + vcpupriv->vcpus); j++) {
            subvcpu = virDomainDefGetVcpu(def, j);
            if (subvcpu->hotpluggable != vcpu->hotpluggable ||
                subvcpu->online != vcpu->online ||
                subvcpu->order != vcpu->order) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("vcpus '%zu' and '%zu' are in the same hotplug "
                                 "group but differ in configuration"), i, j);
                goto cleanup;
            }
        }

        if (vcpu->online && vcpu->hotpluggable == VIR_TRISTATE_BOOL_YES) {
            if ((vcpupriv->socket_id == -1 && vcpupriv->core_id == -1 &&
                 vcpupriv->thread_id == -1) ||
                !vcpupriv->type) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("vcpu '%zu' is missing hotplug data"), i);
                goto cleanup;
            }
        }
    }

    ret = 0;
 cleanup:
    virBitmapFree(ordermap);
    return ret;
}


static int
qemuDomainHasHotpluggableStartupVcpus(virDomainDefPtr def)
{
    size_t maxvcpus = virDomainDefGetVcpusMax(def);
    virDomainVcpuDefPtr vcpu;
    size_t i;

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

        if (vcpu->online && vcpu->hotpluggable == VIR_TRISTATE_BOOL_YES)
            return true;
    }

    return false;
}


static int
qemuProcessVcpusSortOrder(const void *a,
                          const void *b)
{
    virDomainVcpuDefPtr vcpua = *((virDomainVcpuDefPtr *)a);
    virDomainVcpuDefPtr vcpub = *((virDomainVcpuDefPtr *)b);

    return vcpua->order - vcpub->order;
}


static int
qemuProcessSetupHotpluggableVcpus(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
                                  qemuDomainAsyncJob asyncJob)
{
    unsigned int maxvcpus = virDomainDefGetVcpusMax(vm->def);
4935 4936
    qemuDomainObjPrivatePtr priv = vm->privateData;
    qemuCgroupEmulatorAllNodesDataPtr emulatorCgroup = NULL;
4937 4938 4939 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
    virDomainVcpuDefPtr vcpu;
    qemuDomainVcpuPrivatePtr vcpupriv;
    virJSONValuePtr vcpuprops = NULL;
    size_t i;
    int ret = -1;
    int rc;

    virDomainVcpuDefPtr *bootHotplug = NULL;
    size_t nbootHotplug = 0;

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

        if (vcpu->hotpluggable == VIR_TRISTATE_BOOL_YES && vcpu->online &&
            vcpupriv->vcpus != 0) {
            if (virAsprintf(&vcpupriv->alias, "vcpu%zu", i) < 0)
                goto cleanup;

            if (VIR_APPEND_ELEMENT(bootHotplug, nbootHotplug, vcpu) < 0)
                goto cleanup;
        }
    }

    if (nbootHotplug == 0) {
        ret = 0;
        goto cleanup;
    }

    qsort(bootHotplug, nbootHotplug, sizeof(*bootHotplug),
          qemuProcessVcpusSortOrder);

4969 4970 4971
    if (qemuCgroupEmulatorAllNodesAllow(priv->cgroup, &emulatorCgroup) < 0)
        goto cleanup;

4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995
    for (i = 0; i < nbootHotplug; i++) {
        vcpu = bootHotplug[i];

        if (!(vcpuprops = qemuBuildHotpluggableCPUProps(vcpu)))
            goto cleanup;

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

        rc = qemuMonitorAddDeviceArgs(qemuDomainGetMonitor(vm), vcpuprops);
        vcpuprops = NULL;

        if (qemuDomainObjExitMonitor(driver, vm) < 0)
            goto cleanup;

        if (rc < 0)
            goto cleanup;

        virJSONValueFree(vcpuprops);
    }

    ret = 0;

 cleanup:
4996
    qemuCgroupEmulatorAllNodesRestore(emulatorCgroup);
4997 4998 4999 5000 5001 5002
    VIR_FREE(bootHotplug);
    virJSONValueFree(vcpuprops);
    return ret;
}


5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072
static int
qemuProcessUpdateGuestCPU(virDomainDefPtr def,
                          virQEMUCapsPtr qemuCaps,
                          virCapsPtr caps,
                          unsigned int flags)
{
    int ret = -1;
    size_t nmodels = 0;
    char **models = NULL;

    if (!def->cpu)
        return 0;

    /* nothing to do if only topology part of CPU def is used */
    if (def->cpu->mode == VIR_CPU_MODE_CUSTOM && !def->cpu->model)
        return 0;

    /* Old libvirt added host CPU model to host-model CPUs for migrations,
     * while new libvirt just turns host-model into custom mode. We need
     * to fix the mode to maintain backward compatibility and to avoid
     * the CPU model to be replaced in virCPUUpdate.
     */
    if (!(flags & VIR_QEMU_PROCESS_START_NEW) &&
        ARCH_IS_X86(def->os.arch) &&
        def->cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
        def->cpu->model) {
        def->cpu->mode = VIR_CPU_MODE_CUSTOM;
    }

    if (!virQEMUCapsIsCPUModeSupported(qemuCaps, caps, def->virtType,
                                       def->cpu->mode)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("CPU mode '%s' for %s %s domain on %s host is not "
                         "supported by hypervisor"),
                       virCPUModeTypeToString(def->cpu->mode),
                       virArchToString(def->os.arch),
                       virDomainVirtTypeToString(def->virtType),
                       virArchToString(caps->host.arch));
        return -1;
    }

    /* nothing to update for host-passthrough */
    if (def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
        return 0;

    /* custom CPUs in TCG mode don't need to be compared to host CPU */
    if (def->virtType != VIR_DOMAIN_VIRT_QEMU ||
        def->cpu->mode != VIR_CPU_MODE_CUSTOM) {
        if (virCPUCompare(caps->host.arch, virQEMUCapsGetHostModel(qemuCaps),
                          def->cpu, true) < 0)
            return -1;
    }

    if (virCPUUpdate(def->os.arch, def->cpu,
                     virQEMUCapsGetHostModel(qemuCaps)) < 0)
        goto cleanup;

    if (virQEMUCapsGetCPUDefinitions(qemuCaps, &models, &nmodels) < 0 ||
        virCPUTranslate(def->os.arch, def->cpu, models, nmodels) < 0)
        goto cleanup;

    def->cpu->fallback = VIR_CPU_FALLBACK_FORBID;
    ret = 0;

 cleanup:
    virStringFreeListCount(models, nmodels);
    return ret;
}


5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094
/**
 * 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;
5095
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115
    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),
5116
                                                    virDomainDefGetMemoryTotal(vm->def));
5117 5118 5119 5120 5121
            if (!nodeset)
                goto cleanup;

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

5122
            if (virBitmapParse(nodeset, &priv->autoNodeset,
5123 5124 5125 5126 5127 5128 5129 5130 5131
                               VIR_DOMAIN_CPUMASK_LEN) < 0)
                goto cleanup;

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

5132 5133 5134 5135 5136 5137 5138
    /*
     * 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
     */
5139
    VIR_DEBUG("Assigning domain PCI addresses");
5140 5141
    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm,
                                   !!(flags & VIR_QEMU_PROCESS_START_NEW))) < 0)
5142
        goto cleanup;
5143

5144 5145 5146
    if (qemuAssignDeviceAliases(vm->def, priv->qemuCaps) < 0)
        goto cleanup;

5147
    VIR_DEBUG("Setting graphics devices");
5148 5149 5150
    if (qemuProcessSetupGraphics(driver, vm, flags) < 0)
        goto cleanup;

5151 5152 5153 5154 5155
    /* 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;
5156

5157 5158 5159 5160
    VIR_DEBUG("Create domain masterKey");
    if (qemuDomainMasterKeyCreate(vm) < 0)
        goto cleanup;

5161 5162 5163 5164
    VIR_DEBUG("Add secrets to disks and hostdevs");
    if (qemuDomainSecretPrepare(conn, vm) < 0)
        goto cleanup;

5165 5166 5167 5168 5169 5170
    for (i = 0; i < vm->def->nchannels; i++) {
        if (qemuDomainPrepareChannel(vm->def->channels[i],
                                     priv->channelTargetDir) < 0)
            goto cleanup;
    }

5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182
    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;

5183 5184 5185 5186
    VIR_DEBUG("Updating guest CPU definition");
    if (qemuProcessUpdateGuestCPU(vm->def, priv->qemuCaps, caps, flags) < 0)
        goto cleanup;

5187 5188 5189 5190
    ret = 0;
 cleanup:
    VIR_FREE(nodeset);
    virObjectUnref(caps);
5191
    virObjectUnref(cfg);
5192 5193 5194 5195
    return ret;
}


J
Jiri Denemark 已提交
5196
/**
5197
 * qemuProcessPrepareHost
J
Jiri Denemark 已提交
5198
 *
5199 5200 5201
 * 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 已提交
5202
 *
5203
 * TODO: move all host modification from qemuBuildCommandLine into this function
J
Jiri Denemark 已提交
5204 5205
 */
int
5206 5207 5208
qemuProcessPrepareHost(virQEMUDriverPtr driver,
                       virDomainObjPtr vm,
                       bool incoming)
5209
{
5210
    int ret = -1;
5211
    unsigned int hostdev_flags = 0;
5212 5213 5214
    size_t i;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
5215

5216
    if (qemuPrepareNVRAM(cfg, vm) < 0)
J
Jiri Denemark 已提交
5217
        goto cleanup;
5218

5219 5220 5221 5222 5223
    /* 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");
5224
    if (qemuProcessNetworkPrepareDevices(vm->def) < 0)
J
Jiri Denemark 已提交
5225
        goto cleanup;
5226

5227
    /* Must be run before security labelling */
5228
    VIR_DEBUG("Preparing host devices");
5229 5230
    if (!cfg->relaxedACS)
        hostdev_flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
J
Jiri Denemark 已提交
5231
    if (!incoming)
5232
        hostdev_flags |= VIR_HOSTDEV_COLD_BOOT;
5233 5234
    if (qemuHostdevPrepareDomainDevices(driver, vm->def, priv->qemuCaps,
                                        hostdev_flags) < 0)
J
Jiri Denemark 已提交
5235
        goto cleanup;
5236

5237
    VIR_DEBUG("Preparing chr devices");
5238 5239 5240 5241
    if (virDomainChrDefForeach(vm->def,
                               true,
                               qemuProcessPrepareChardevDevice,
                               NULL) < 0)
J
Jiri Denemark 已提交
5242
        goto cleanup;
5243

5244
    if (vm->def->mem.nhugepages) {
5245 5246 5247 5248
        for (i = 0; i < cfg->nhugetlbfs; i++) {
            char *hugepagePath = qemuGetHugepagePath(&cfg->hugetlbfs[i]);

            if (!hugepagePath)
J
Jiri Denemark 已提交
5249
                goto cleanup;
5250 5251 5252 5253 5254 5255

            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 已提交
5256
                goto cleanup;
5257 5258
            }
            VIR_FREE(hugepagePath);
5259 5260 5261
        }
    }

5262 5263
    /* Ensure no historical cgroup for this VM is lying around bogus
     * settings */
5264
    VIR_DEBUG("Ensuring no historical cgroup is lying around");
5265
    qemuRemoveCgroup(vm);
5266

5267
    if (virFileMakePath(cfg->logDir) < 0) {
5268 5269
        virReportSystemError(errno,
                             _("cannot create log directory %s"),
5270
                             cfg->logDir);
J
Jiri Denemark 已提交
5271
        goto cleanup;
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
    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;

5297 5298
    VIR_DEBUG("Write domain masterKey");
    if (qemuDomainWriteMasterKeyFile(driver, vm) < 0)
J
John Ferlan 已提交
5299 5300
        goto cleanup;

5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 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
    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 已提交
5342
    size_t i;
5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358

    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 |
5359 5360
                  VIR_QEMU_PROCESS_START_AUTODESTROY |
                  VIR_QEMU_PROCESS_START_NEW, -1);
5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372

    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;

5373
    VIR_DEBUG("Creating domain log file");
5374 5375
    if (!(logCtxt = qemuDomainLogContextNew(driver, vm,
                                            QEMU_DOMAIN_LOG_CONTEXT_MODE_START)))
J
Jiri Denemark 已提交
5376
        goto cleanup;
5377
    logfile = qemuDomainLogContextGetWriteFD(logCtxt);
5378

5379
    VIR_DEBUG("Building emulator command line");
5380
    if (!(cmd = qemuBuildCommandLine(driver,
5381 5382
                                     qemuDomainLogContextGetManager(logCtxt),
                                     vm->def, priv->monConfig,
E
Eric Blake 已提交
5383
                                     priv->monJSON, priv->qemuCaps,
5384 5385
                                     incoming ? incoming->launchURI : NULL,
                                     snapshot, vmop,
J
Ján Tomko 已提交
5386
                                     false,
5387
                                     qemuCheckFips(),
5388
                                     priv->autoNodeset,
5389
                                     &nnicindexes, &nicindexes,
5390
                                     priv->libDir)))
J
Jiri Denemark 已提交
5391
        goto cleanup;
5392

5393 5394
    if (incoming && incoming->fd != -1)
        virCommandPassFD(cmd, incoming->fd, 0);
5395

5396
    /* now that we know it is about to start call the hook if present */
5397 5398 5399
    if (qemuProcessStartHook(driver, vm,
                             VIR_HOOK_QEMU_OP_START,
                             VIR_HOOK_SUBOP_BEGIN) < 0)
J
Jiri Denemark 已提交
5400
        goto cleanup;
5401

5402
    qemuLogOperation(vm, "starting up", cmd, logCtxt);
5403

5404
    qemuDomainObjCheckTaint(driver, vm, logCtxt);
5405

5406
    qemuDomainLogContextMarkPosition(logCtxt);
5407 5408

    VIR_DEBUG("Clear emulator capabilities: %d",
5409 5410
              cfg->clearEmulatorCapabilities);
    if (cfg->clearEmulatorCapabilities)
5411 5412
        virCommandClearCaps(cmd);

5413 5414
    VIR_DEBUG("Setting up raw IO");
    if (qemuProcessSetupRawIO(driver, vm, cmd) < 0)
J
Jiri Denemark 已提交
5415
        goto cleanup;
5416

5417
    virCommandSetPreExecHook(cmd, qemuProcessHook, &hookData);
5418 5419
    virCommandSetMaxProcesses(cmd, cfg->maxProcesses);
    virCommandSetMaxFiles(cmd, cfg->maxFiles);
5420
    virCommandSetMaxCoreSize(cmd, cfg->maxCore);
5421
    virCommandSetUmask(cmd, 0x002);
5422

5423 5424
    VIR_DEBUG("Setting up security labelling");
    if (virSecurityManagerSetChildProcessLabel(driver->securityManager,
5425
                                               vm->def, cmd) < 0)
J
Jiri Denemark 已提交
5426
        goto cleanup;
5427

5428 5429 5430
    virCommandSetOutputFD(cmd, &logfile);
    virCommandSetErrorFD(cmd, &logfile);
    virCommandNonblockingFDs(cmd);
5431
    virCommandSetPidFile(cmd, priv->pidfile);
5432
    virCommandDaemonize(cmd);
5433
    virCommandRequireHandshake(cmd);
5434

5435
    if (virSecurityManagerPreFork(driver->securityManager) < 0)
J
Jiri Denemark 已提交
5436
        goto cleanup;
5437
    rv = virCommandRun(cmd, NULL);
5438
    virSecurityManagerPostFork(driver->securityManager);
5439

E
Eric Blake 已提交
5440
    /* wait for qemu process to show up */
5441
    if (rv == 0) {
5442
        if (virPidFileReadPath(priv->pidfile, &vm->pid) < 0) {
5443 5444
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Domain %s didn't show up"), vm->def->name);
5445
            rv = -1;
5446
        }
5447 5448 5449 5450 5451
        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);
5452 5453
    }

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

5458 5459
    VIR_DEBUG("Waiting for handshake from child");
    if (virCommandHandshakeWait(cmd) < 0) {
5460
        /* Read errors from child that occurred between fork and exec. */
5461 5462
        qemuProcessReportLogError(logCtxt,
                                  _("Process exited prior to exec"));
J
Jiri Denemark 已提交
5463
        goto cleanup;
5464 5465
    }

5466
    VIR_DEBUG("Setting up domain cgroup (if required)");
5467
    if (qemuSetupCgroup(driver, vm, nnicindexes, nicindexes) < 0)
J
Jiri Denemark 已提交
5468
        goto cleanup;
5469

5470 5471 5472 5473
    if (!(priv->perf = virPerfNew()))
        goto cleanup;

    for (i = 0; i < VIR_PERF_EVENT_LAST; i++) {
5474
        if (vm->def->perf.events[i] == VIR_TRISTATE_BOOL_YES &&
5475 5476
            virPerfEventEnable(priv->perf, i, vm->pid) < 0)
            goto cleanup;
Q
Qiaowei Ren 已提交
5477
    }
5478

5479 5480 5481 5482 5483 5484
    /* This must be done after cgroup placement to avoid resetting CPU
     * affinity */
    if (!vm->def->cputune.emulatorpin &&
        qemuProcessInitCpuAffinity(vm) < 0)
        goto cleanup;

5485 5486 5487 5488
    VIR_DEBUG("Setting emulator tuning/settings");
    if (qemuProcessSetupEmulator(vm) < 0)
        goto cleanup;

5489 5490
    VIR_DEBUG("Setting domain security labels");
    if (virSecurityManagerSetAllLabel(driver->securityManager,
J
Jiri Denemark 已提交
5491 5492 5493
                                      vm->def,
                                      incoming ? incoming->path : NULL) < 0)
        goto cleanup;
5494

5495
    /* Security manager labeled all devices, therefore
J
Jiri Denemark 已提交
5496 5497 5498 5499
     * if any operation from now on fails, we need to ask the caller to
     * restore labels.
     */
    ret = -2;
5500

J
Jiri Denemark 已提交
5501
    if (incoming && incoming->fd != -1) {
5502 5503 5504 5505 5506 5507 5508
        /* 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 已提交
5509
        if (fstat(incoming->fd, &stdin_sb) < 0) {
5510
            virReportSystemError(errno,
J
Jiri Denemark 已提交
5511 5512
                                 _("cannot stat fd %d"), incoming->fd);
            goto cleanup;
5513 5514
        }
        if (S_ISFIFO(stdin_sb.st_mode) &&
J
Jiri Denemark 已提交
5515 5516 5517
            virSecurityManagerSetImageFDLabel(driver->securityManager,
                                              vm->def, incoming->fd) < 0)
            goto cleanup;
5518 5519 5520
    }

    VIR_DEBUG("Labelling done, completing handshake to child");
5521
    if (virCommandHandshakeNotify(cmd) < 0)
J
Jiri Denemark 已提交
5522
        goto cleanup;
5523 5524
    VIR_DEBUG("Handshake complete, child running");

5525
    if (rv == -1) /* The VM failed to start; tear filters before taps */
5526 5527
        virDomainConfVMNWFilterTeardown(vm);

5528
    if (rv == -1) /* The VM failed to start */
J
Jiri Denemark 已提交
5529
        goto cleanup;
5530

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

D
Daniel P. Berrange 已提交
5535
    /* Failure to connect to agent shouldn't be fatal */
5536 5537
    if ((rv = qemuConnectAgent(driver, vm)) < 0) {
        if (rv == -2)
J
Jiri Denemark 已提交
5538
            goto cleanup;
5539

D
Daniel P. Berrange 已提交
5540 5541 5542 5543 5544 5545
        VIR_WARN("Cannot connect to QEMU guest agent for %s",
                 vm->def->name);
        virResetLastError();
        priv->agentError = true;
    }

5546
    VIR_DEBUG("Detecting if required emulator features are present");
5547
    if (!qemuProcessVerifyGuestCPU(driver, vm, asyncJob))
J
Jiri Denemark 已提交
5548
        goto cleanup;
5549

5550
    VIR_DEBUG("Setting up post-init cgroup restrictions");
5551
    if (qemuSetupCpusetMems(vm) < 0)
J
Jiri Denemark 已提交
5552
        goto cleanup;
5553

5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565
    VIR_DEBUG("setting up hotpluggable cpus");
    if (qemuDomainHasHotpluggableStartupVcpus(vm->def)) {
        if (qemuDomainRefreshVcpuInfo(driver, vm, asyncJob, false) < 0)
            goto cleanup;

        if (qemuProcessValidateHotpluggableVcpus(vm->def) < 0)
            goto cleanup;

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

5566
    VIR_DEBUG("Refreshing VCPU info");
5567
    if (qemuDomainRefreshVcpuInfo(driver, vm, asyncJob, false) < 0)
J
Jiri Denemark 已提交
5568
        goto cleanup;
5569

5570 5571 5572
    if (qemuDomainValidateVcpuInfo(vm) < 0)
        goto cleanup;

5573 5574
    qemuDomainVcpuPersistOrder(vm->def);

5575 5576
    VIR_DEBUG("Detecting IOThread PIDs");
    if (qemuProcessDetectIOThreadPIDs(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5577
        goto cleanup;
5578

5579 5580 5581 5582
    VIR_DEBUG("Setting global CPU cgroup (if required)");
    if (qemuSetupGlobalCpuCgroup(vm) < 0)
        goto cleanup;

5583 5584
    VIR_DEBUG("Setting vCPU tuning/settings");
    if (qemuProcessSetupVcpus(vm) < 0)
J
Jiri Denemark 已提交
5585
        goto cleanup;
5586

5587 5588
    VIR_DEBUG("Setting IOThread tuning/settings");
    if (qemuProcessSetupIOThreads(vm) < 0)
J
Jiri Denemark 已提交
5589
        goto cleanup;
5590

5591
    VIR_DEBUG("Setting any required VM passwords");
5592
    if (qemuProcessInitPasswords(conn, driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5593
        goto cleanup;
5594

5595 5596 5597 5598
    /* set default link states */
    /* qemu doesn't support setting this on the command line, so
     * enter the monitor */
    VIR_DEBUG("Setting network link states");
5599
    if (qemuProcessSetLinkStates(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5600
        goto cleanup;
5601

5602
    VIR_DEBUG("Fetching list of active devices");
5603
    if (qemuDomainUpdateDeviceList(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5604
        goto cleanup;
5605

5606 5607
    VIR_DEBUG("Updating info of memory devices");
    if (qemuDomainUpdateMemoryDeviceInfo(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5608
        goto cleanup;
5609

5610
    VIR_DEBUG("Setting initial memory amount");
5611
    if (qemuProcessSetupBalloon(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5612
        goto cleanup;
5613

5614
    /* Since CPUs were not started yet, the balloon could not return the memory
5615 5616
     * 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 */
5617
    if (!incoming && !snapshot &&
5618
        qemuProcessRefreshBalloonState(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5619
        goto cleanup;
5620

5621 5622
    VIR_DEBUG("Detecting actual memory size for video device");
    if (qemuProcessUpdateVideoRamSize(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5623 5624
        goto cleanup;

5625 5626
    VIR_DEBUG("Updating disk data");
    if (qemuProcessRefreshDisks(driver, vm, asyncJob) < 0)
5627 5628
        goto cleanup;

J
Jiri Denemark 已提交
5629 5630 5631 5632 5633 5634 5635
    if (flags & VIR_QEMU_PROCESS_START_AUTODESTROY &&
        qemuProcessAutoDestroyAdd(driver, vm, conn) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
5636
    qemuDomainSecretDestroy(vm);
J
Jiri Denemark 已提交
5637
    virCommandFree(cmd);
5638
    qemuDomainLogContextFree(logCtxt);
J
Jiri Denemark 已提交
5639 5640 5641 5642 5643 5644 5645
    virObjectUnref(cfg);
    virObjectUnref(caps);
    VIR_FREE(nicindexes);
    return ret;
}


5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676
/**
 * 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");
5677
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692
        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 已提交
5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723
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);

5724 5725 5726 5727
    if (!migrateFrom && !snapshot)
        flags |= VIR_QEMU_PROCESS_START_NEW;

    if (qemuProcessInit(driver, vm, asyncJob, !!migrateFrom, flags) < 0)
J
Jiri Denemark 已提交
5728 5729 5730
        goto cleanup;

    if (migrateFrom) {
5731
        incoming = qemuProcessIncomingDefNew(priv->qemuCaps, NULL, migrateFrom,
J
Jiri Denemark 已提交
5732 5733 5734 5735 5736
                                             migrateFd, migratePath);
        if (!incoming)
            goto stop;
    }

5737 5738 5739
    if (qemuProcessPrepareDomain(conn, driver, vm, flags) < 0)
        goto stop;

5740 5741 5742
    if (qemuProcessPrepareHost(driver, vm, !!incoming) < 0)
        goto stop;

J
Jiri Denemark 已提交
5743 5744
    if ((rv = qemuProcessLaunch(conn, driver, vm, asyncJob, incoming,
                                snapshot, vmop, flags)) < 0) {
5745
        if (rv == -2)
J
Jiri Denemark 已提交
5746 5747 5748 5749
            relabel = true;
        goto stop;
    }
    relabel = true;
5750

5751 5752 5753
    if (incoming &&
        incoming->deferredURI &&
        qemuMigrationRunIncoming(driver, vm, incoming->deferredURI, asyncJob) < 0)
J
Jiri Denemark 已提交
5754
        goto stop;
5755

5756 5757 5758 5759 5760
    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 已提交
5761
        goto stop;
5762

5763 5764
    /* Keep watching qemu log for errors during incoming migration, otherwise
     * unset reporting errors from qemu log. */
5765
    if (!incoming)
5766
        qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL);
5767

5768 5769 5770
    ret = 0;

 cleanup:
5771
    qemuProcessIncomingDefFree(incoming);
5772
    return ret;
5773

J
Jiri Denemark 已提交
5774 5775 5776 5777 5778 5779
 stop:
    stopFlags = 0;
    if (!relabel)
        stopFlags |= VIR_QEMU_PROCESS_STOP_NO_RELABEL;
    if (migrateFrom)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
5780
    if (priv->mon)
5781
        qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL);
5782
    qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, asyncJob, stopFlags);
5783
    goto cleanup;
5784 5785 5786
}


5787 5788 5789 5790 5791
virCommandPtr
qemuProcessCreatePretendCmd(virConnectPtr conn,
                            virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
                            const char *migrateURI,
5792
                            bool enableFips,
5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803
                            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;
5804
    flags |= VIR_QEMU_PROCESS_START_NEW;
5805

5806
    if (qemuProcessInit(driver, vm, QEMU_ASYNC_JOB_NONE, !!migrateURI, flags) < 0)
5807 5808 5809 5810 5811 5812
        goto cleanup;

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

    VIR_DEBUG("Building emulator command line");
5813
    cmd = qemuBuildCommandLine(driver,
5814 5815 5816 5817 5818 5819 5820 5821 5822
                               NULL,
                               vm->def,
                               priv->monConfig,
                               priv->monJSON,
                               priv->qemuCaps,
                               migrateURI,
                               NULL,
                               VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
                               standalone,
5823
                               enableFips,
5824 5825 5826
                               priv->autoNodeset,
                               NULL,
                               NULL,
5827
                               priv->libDir);
5828 5829 5830 5831 5832 5833

 cleanup:
    return cmd;
}


5834
int
5835
qemuProcessKill(virDomainObjPtr vm, unsigned int flags)
5836
{
5837
    int ret;
5838

5839 5840 5841
    VIR_DEBUG("vm=%p name=%s pid=%llu flags=%x",
              vm, vm->def->name,
              (unsigned long long)vm->pid, flags);
5842

5843 5844 5845 5846 5847
    if (!(flags & VIR_QEMU_PROCESS_KILL_NOCHECK)) {
        if (!virDomainObjIsActive(vm)) {
            VIR_DEBUG("VM '%s' not active", vm->def->name);
            return 0;
        }
5848 5849
    }

5850
    if (flags & VIR_QEMU_PROCESS_KILL_NOWAIT) {
5851 5852 5853 5854 5855
        virProcessKill(vm->pid,
                       (flags & VIR_QEMU_PROCESS_KILL_FORCE) ?
                       SIGKILL : SIGTERM);
        return 0;
    }
5856

5857 5858
    ret = virProcessKillPainfully(vm->pid,
                                  !!(flags & VIR_QEMU_PROCESS_KILL_FORCE));
5859

5860
    return ret;
5861 5862 5863
}


5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902
/**
 * 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;
}


5903
void qemuProcessStop(virQEMUDriverPtr driver,
5904
                     virDomainObjPtr vm,
5905
                     virDomainShutoffReason reason,
5906
                     qemuDomainAsyncJob asyncJob,
5907
                     unsigned int flags)
5908 5909 5910 5911 5912 5913
{
    int ret;
    int retries = 0;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virErrorPtr orig_err;
    virDomainDefPtr def;
A
Ansis Atteka 已提交
5914
    virNetDevVPortProfilePtr vport = NULL;
5915
    size_t i;
5916
    char *timestamp;
5917
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
5918

5919 5920
    VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%llu, "
              "reason=%s, asyncJob=%s, flags=%x",
5921
              vm, vm->def->name, vm->def->id,
5922 5923 5924 5925
              (unsigned long long)vm->pid,
              virDomainShutoffReasonTypeToString(reason),
              qemuDomainAsyncJobTypeToString(asyncJob),
              flags);
5926

5927 5928 5929 5930
    /* This method is routinely used in clean up paths. Disable error
     * reporting so we don't squash a legit error. */
    orig_err = virSaveLastError();

5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945
    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;
    }

5946 5947
    vm->def->id = -1;

5948
    if (virAtomicIntDecAndTest(&driver->nactive) && driver->inhibitCallback)
5949 5950
        driver->inhibitCallback(false, driver->inhibitOpaque);

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

5954
    if ((timestamp = virTimeStringNow()) != NULL) {
5955 5956 5957
        qemuDomainLogAppendMessage(driver, vm, "%s: shutting down, reason=%s\n",
                                   timestamp,
                                   virDomainShutoffReasonTypeToString(reason));
5958
        VIR_FREE(timestamp);
5959 5960
    }

5961 5962 5963
    /* Clear network bandwidth */
    virDomainClearNetBandwidth(vm);

5964 5965
    virDomainConfVMNWFilterTeardown(vm);

5966
    if (cfg->macFilter) {
5967
        def = vm->def;
5968
        for (i = 0; i < def->nnets; i++) {
5969 5970 5971
            virDomainNetDefPtr net = def->nets[i];
            if (net->ifname == NULL)
                continue;
5972 5973 5974
            ignore_value(ebtablesRemoveForwardAllowIn(driver->ebtables,
                                                      net->ifname,
                                                      &net->mac));
5975 5976 5977
        }
    }

5978
    virPortAllocatorRelease(driver->migrationPorts, priv->nbdPort);
5979
    priv->nbdPort = 0;
5980

D
Daniel P. Berrange 已提交
5981 5982 5983 5984 5985 5986
    if (priv->agent) {
        qemuAgentClose(priv->agent);
        priv->agent = NULL;
        priv->agentError = false;
    }

5987
    if (priv->mon) {
5988
        qemuMonitorClose(priv->mon);
5989 5990
        priv->mon = NULL;
    }
5991 5992 5993 5994 5995 5996 5997 5998

    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 已提交
5999 6000 6001
    /* Remove the master key */
    qemuDomainMasterKeyRemove(priv);

6002 6003
    virFileDeleteTree(priv->libDir);
    virFileDeleteTree(priv->channelTargetDir);
6004

6005 6006
    qemuDomainClearPrivatePaths(vm);

6007 6008 6009 6010 6011 6012
    ignore_value(virDomainChrDefForeach(vm->def,
                                        false,
                                        qemuProcessCleanupChardevDevice,
                                        NULL));


6013
    /* shut it off for sure */
6014 6015 6016
    ignore_value(qemuProcessKill(vm,
                                 VIR_QEMU_PROCESS_KILL_FORCE|
                                 VIR_QEMU_PROCESS_KILL_NOCHECK));
6017

6018 6019
    qemuDomainCleanupRun(driver, vm);

6020
    /* Stop autodestroy in case guest is restarted */
6021
    qemuProcessAutoDestroyRemove(driver, vm);
6022

6023 6024
    /* now that we know it's stopped call the hook if present */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
6025
        char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
6026 6027

        /* we can't stop the operation even if the script raised an error */
6028 6029 6030
        ignore_value(virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
                                 VIR_HOOK_QEMU_OP_STOPPED, VIR_HOOK_SUBOP_END,
                                 NULL, xml, NULL));
6031 6032 6033
        VIR_FREE(xml);
    }

6034 6035 6036 6037
    /* Reset Security Labels unless caller don't want us to */
    if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL))
        virSecurityManagerRestoreAllLabel(driver->securityManager,
                                          vm->def,
6038
                                          !!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED));
6039
    virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
6040

6041
    for (i = 0; i < vm->def->ndisks; i++) {
6042
        virDomainDeviceDef dev;
6043
        virDomainDiskDefPtr disk = vm->def->disks[i];
6044 6045 6046 6047

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

6050
    /* Clear out dynamically assigned labels */
6051
    for (i = 0; i < vm->def->nseclabels; i++) {
6052
        if (vm->def->seclabels[i]->type == VIR_DOMAIN_SECLABEL_DYNAMIC)
6053 6054
            VIR_FREE(vm->def->seclabels[i]->label);
        VIR_FREE(vm->def->seclabels[i]->imagelabel);
6055 6056
    }

6057 6058 6059
    virStringFreeList(priv->qemuDevices);
    priv->qemuDevices = NULL;

6060
    qemuHostdevReAttachDomainDevices(driver, vm->def);
6061 6062 6063 6064

    def = vm->def;
    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
6065 6066 6067 6068
        vport = virDomainNetGetActualVirtPortProfile(net);

        switch (virDomainNetGetActualType(net)) {
        case VIR_DOMAIN_NET_TYPE_DIRECT:
6069
            ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
6070
                             net->ifname, &net->mac,
6071 6072
                             virDomainNetGetActualDirectDev(net),
                             virDomainNetGetActualDirectMode(net),
6073
                             virDomainNetGetActualVirtPortProfile(net),
6074
                             cfg->stateDir));
6075
            break;
6076 6077 6078 6079 6080 6081
        case VIR_DOMAIN_NET_TYPE_ETHERNET:
            if (net->ifname) {
                ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
                VIR_FREE(net->ifname);
            }
            break;
6082 6083 6084 6085
        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))
6086
                ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
6087 6088
#endif
            break;
6089
        }
6090 6091 6092
        /* release the physical device (or any other resources used by
         * this interface in the network driver
         */
6093 6094 6095 6096 6097 6098 6099 6100 6101
        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 已提交
6102

6103 6104
        /* kick the device out of the hostdev list too */
        virDomainNetRemoveHostdev(def, net);
6105
        networkReleaseActualDevice(vm->def, net);
6106
    }
6107

6108
 retry:
6109
    if ((ret = qemuRemoveCgroup(vm)) < 0) {
6110 6111 6112 6113 6114 6115 6116
        if (ret == -EBUSY && (retries++ < 5)) {
            usleep(200*1000);
            goto retry;
        }
        VIR_WARN("Failed to remove cgroup for %s",
                 vm->def->name);
    }
6117
    virCgroupFree(&priv->cgroup);
6118

6119
    virPerfFree(priv->perf);
6120
    priv->perf = NULL;
6121

6122 6123
    qemuProcessRemoveDomainStatus(driver, vm);

6124 6125
    /* Remove VNC and Spice ports from port reservation bitmap, but only if
       they were reserved by the driver (autoport=yes)
6126
    */
6127
    for (i = 0; i < vm->def->ngraphics; ++i) {
6128
        virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
6129 6130
        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
            if (graphics->data.vnc.autoport) {
6131 6132
                virPortAllocatorRelease(driver->remotePorts,
                                        graphics->data.vnc.port);
6133
            } else if (graphics->data.vnc.portReserved) {
6134 6135 6136 6137 6138
                virPortAllocatorSetUsed(driver->remotePorts,
                                        graphics->data.spice.port,
                                        false);
                graphics->data.vnc.portReserved = false;
            }
6139 6140
            virPortAllocatorRelease(driver->webSocketPorts,
                                    graphics->data.vnc.websocket);
6141
        }
6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162
        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;
                }
            }
6163
        }
6164 6165
    }

6166
    vm->taint = 0;
6167
    vm->pid = -1;
J
Jiri Denemark 已提交
6168
    virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
6169 6170
    for (i = 0; i < vm->def->niothreadids; i++)
        vm->def->iothreadids[i]->thread_id = 0;
6171 6172
    virObjectUnref(priv->qemuCaps);
    priv->qemuCaps = NULL;
6173
    VIR_FREE(priv->pidfile);
6174

6175
    /* The "release" hook cleans up additional resources */
6176
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
6177
        char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
6178 6179 6180

        /* we can't stop the operation even if the script raised an error */
        virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
6181 6182
                    VIR_HOOK_QEMU_OP_RELEASE, VIR_HOOK_SUBOP_END,
                    NULL, xml, NULL);
6183 6184 6185
        VIR_FREE(xml);
    }

6186
    virDomainObjRemoveTransientDef(vm);
6187

6188 6189 6190 6191 6192
 endjob:
    if (asyncJob != QEMU_ASYNC_JOB_NONE)
        qemuDomainObjEndJob(driver, vm);

 cleanup:
6193 6194 6195 6196
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
6197
    virObjectUnref(cfg);
6198
}
6199 6200


6201
int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
6202
                      virQEMUDriverPtr driver,
6203
                      virDomainObjPtr vm,
6204
                      pid_t pid,
6205 6206 6207 6208
                      const char *pidfile,
                      virDomainChrSourceDefPtr monConfig,
                      bool monJSON)
{
6209
    size_t i;
6210
    qemuDomainLogContextPtr logCtxt = NULL;
6211 6212 6213
    char *timestamp;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    bool running = true;
6214
    virDomainPausedReason reason;
6215
    virSecurityLabelPtr seclabel = NULL;
6216
    virSecurityLabelDefPtr seclabeldef = NULL;
6217
    bool seclabelgen = false;
6218 6219
    virSecurityManagerPtr* sec_managers = NULL;
    const char *model;
6220
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
6221
    virCapsPtr caps = NULL;
6222
    bool active = false;
6223
    int ret;
6224 6225 6226 6227

    VIR_DEBUG("Beginning VM attach process");

    if (virDomainObjIsActive(vm)) {
6228 6229
        virReportError(VIR_ERR_OPERATION_INVALID,
                       "%s", _("VM is already active"));
6230
        virObjectUnref(cfg);
6231 6232 6233
        return -1;
    }

6234
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
6235
        goto error;
6236

6237 6238 6239 6240 6241
    /* 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");
6242
    if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
6243
        goto error;
6244

6245
    vm->def->id = qemuDriverAllocateID(driver);
6246

6247
    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
6248
        driver->inhibitCallback(true, driver->inhibitOpaque);
6249
    active = true;
6250

6251
    if (virFileMakePath(cfg->logDir) < 0) {
6252 6253
        virReportSystemError(errno,
                             _("cannot create log directory %s"),
6254
                             cfg->logDir);
6255
        goto error;
6256 6257 6258
    }

    VIR_FREE(priv->pidfile);
6259
    if (VIR_STRDUP(priv->pidfile, pidfile) < 0)
6260
        goto error;
6261

6262 6263
    vm->pid = pid;

6264
    VIR_DEBUG("Detect security driver config");
6265
    sec_managers = virSecurityManagerGetNested(driver->securityManager);
6266 6267
    if (sec_managers == NULL)
        goto error;
6268 6269

    for (i = 0; sec_managers[i]; i++) {
6270
        seclabelgen = false;
6271 6272
        model = virSecurityManagerGetModel(sec_managers[i]);
        seclabeldef = virDomainDefGetSecurityLabelDef(vm->def, model);
6273
        if (seclabeldef == NULL) {
6274
            if (!(seclabeldef = virSecurityLabelDefNew(model)))
6275 6276 6277
                goto error;
            seclabelgen = true;
        }
6278 6279
        seclabeldef->type = VIR_DOMAIN_SECLABEL_STATIC;
        if (VIR_ALLOC(seclabel) < 0)
6280
            goto error;
6281
        if (virSecurityManagerGetProcessLabel(sec_managers[i],
6282
                                              vm->def, vm->pid, seclabel) < 0)
6283
            goto error;
6284

6285
        if (VIR_STRDUP(seclabeldef->model, model) < 0)
6286
            goto error;
6287

6288
        if (VIR_STRDUP(seclabeldef->label, seclabel->label) < 0)
6289
            goto error;
6290
        VIR_FREE(seclabel);
6291 6292 6293 6294 6295 6296

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

6299 6300
    if (virSecurityManagerCheckAllLabel(driver->securityManager, vm->def) < 0)
        goto error;
6301 6302 6303
    if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0)
        goto error;

6304 6305 6306
    if (qemuDomainPerfRestart(vm) < 0)
        goto error;

6307
    VIR_DEBUG("Creating domain log file");
6308 6309
    if (!(logCtxt = qemuDomainLogContextNew(driver, vm,
                                            QEMU_DOMAIN_LOG_CONTEXT_MODE_ATTACH)))
6310
        goto error;
6311 6312

    VIR_DEBUG("Determining emulator version");
6313
    virObjectUnref(priv->qemuCaps);
6314 6315
    if (!(priv->qemuCaps = virQEMUCapsCacheLookupCopy(caps,
                                                      driver->qemuCapsCache,
6316 6317
                                                      vm->def->emulator,
                                                      vm->def->os.machine)))
6318
        goto error;
6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330

    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 已提交
6331
     * we also need to populate the PCI address set cache for later
6332 6333
     * use in hotplug
     */
6334
    VIR_DEBUG("Assigning domain PCI addresses");
6335
    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm, false)) < 0)
6336
        goto error;
6337

6338
    if ((timestamp = virTimeStringNow()) == NULL)
6339
        goto error;
6340

6341
    qemuDomainLogContextWrite(logCtxt, "%s: attaching\n", timestamp);
6342
    VIR_FREE(timestamp);
6343

6344
    qemuDomainObjTaint(driver, vm, VIR_DOMAIN_TAINT_EXTERNAL_LAUNCH, logCtxt);
6345 6346

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

D
Daniel P. Berrange 已提交
6350
    /* Failure to connect to agent shouldn't be fatal */
6351 6352 6353 6354
    if ((ret = qemuConnectAgent(driver, vm)) < 0) {
        if (ret == -2)
            goto error;

D
Daniel P. Berrange 已提交
6355 6356 6357 6358 6359 6360
        VIR_WARN("Cannot connect to QEMU guest agent for %s",
                 vm->def->name);
        virResetLastError();
        priv->agentError = true;
    }

6361
    VIR_DEBUG("Detecting VCPU PIDs");
6362
    if (qemuDomainRefreshVcpuInfo(driver, vm, QEMU_ASYNC_JOB_NONE, false) < 0)
6363 6364
        goto error;

6365 6366 6367
    if (qemuDomainValidateVcpuInfo(vm) < 0)
        goto error;

6368 6369
    VIR_DEBUG("Detecting IOThread PIDs");
    if (qemuProcessDetectIOThreadPIDs(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
6370
        goto error;
6371 6372

    VIR_DEBUG("Getting initial memory amount");
6373
    qemuDomainObjEnterMonitor(driver, vm);
6374 6375 6376 6377 6378 6379 6380
    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)
6381
        goto error;
6382

6383
    if (running) {
6384 6385
        virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
                             VIR_DOMAIN_RUNNING_UNPAUSED);
6386 6387 6388
        if (vm->def->memballoon &&
            vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO &&
            vm->def->memballoon->period) {
6389
            qemuDomainObjEnterMonitor(driver, vm);
6390
            qemuMonitorSetMemoryStatsPeriod(priv->mon, vm->def->memballoon,
6391
                                            vm->def->memballoon->period);
6392 6393
            if (qemuDomainObjExitMonitor(driver, vm) < 0)
                goto error;
6394 6395
        }
    } else {
6396
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
6397
    }
6398 6399

    VIR_DEBUG("Writing domain status to disk");
6400
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
6401
        goto error;
6402

6403 6404
    /* Run an hook to allow admins to do some magic */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
6405
        char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416
        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)
6417
            goto error;
6418 6419
    }

6420
    qemuDomainLogContextFree(logCtxt);
6421
    VIR_FREE(seclabel);
6422
    VIR_FREE(sec_managers);
6423
    virObjectUnref(cfg);
6424
    virObjectUnref(caps);
6425 6426 6427

    return 0;

6428 6429
 exit_monitor:
    ignore_value(qemuDomainObjExitMonitor(driver, vm));
6430
 error:
6431 6432 6433 6434 6435 6436
    /* 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);
6437 6438 6439

    qemuMonitorClose(priv->mon);
    priv->mon = NULL;
6440
    qemuDomainLogContextFree(logCtxt);
6441
    VIR_FREE(seclabel);
6442
    VIR_FREE(sec_managers);
6443 6444
    if (seclabelgen)
        virSecurityLabelDefFree(seclabeldef);
6445
    virDomainChrSourceDefFree(monConfig);
6446
    virObjectUnref(cfg);
6447
    virObjectUnref(caps);
6448 6449 6450 6451
    return -1;
}


6452
static virDomainObjPtr
6453 6454 6455
qemuProcessAutoDestroy(virDomainObjPtr dom,
                       virConnectPtr conn,
                       void *opaque)
6456
{
6457
    virQEMUDriverPtr driver = opaque;
6458
    qemuDomainObjPrivatePtr priv = dom->privateData;
6459
    virObjectEventPtr event = NULL;
6460
    unsigned int stopFlags = 0;
6461

6462
    VIR_DEBUG("vm=%s, conn=%p", dom->def->name, conn);
6463

6464 6465
    virObjectRef(dom);

6466 6467 6468
    if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;

6469 6470
    if (priv->job.asyncJob) {
        VIR_DEBUG("vm=%s has long-term job active, cancelling",
6471
                  dom->def->name);
6472
        qemuDomainObjDiscardAsyncJob(driver, dom);
6473 6474 6475
    }

    VIR_DEBUG("Killing domain");
6476

6477 6478 6479 6480 6481
    if (qemuProcessBeginStopJob(driver, dom, QEMU_JOB_DESTROY, true) < 0)
        goto cleanup;

    qemuProcessStop(driver, dom, VIR_DOMAIN_SHUTOFF_DESTROYED,
                    QEMU_ASYNC_JOB_NONE, stopFlags);
6482

6483
    virDomainAuditStop(dom, "destroyed");
6484
    event = virDomainEventLifecycleNewFromObj(dom,
6485 6486
                                     VIR_DOMAIN_EVENT_STOPPED,
                                     VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
6487

6488 6489
    qemuDomainObjEndJob(driver, dom);

6490
    qemuDomainRemoveInactive(driver, dom);
6491

6492
    qemuDomainEventQueue(driver, event);
6493

6494
 cleanup:
6495
    virDomainObjEndAPI(&dom);
6496
    return dom;
6497 6498
}

6499
int qemuProcessAutoDestroyAdd(virQEMUDriverPtr driver,
6500 6501 6502
                              virDomainObjPtr vm,
                              virConnectPtr conn)
{
6503
    VIR_DEBUG("vm=%s, conn=%p", vm->def->name, conn);
6504 6505
    return virCloseCallbacksSet(driver->closeCallbacks, vm, conn,
                                qemuProcessAutoDestroy);
6506 6507
}

6508
int qemuProcessAutoDestroyRemove(virQEMUDriverPtr driver,
6509 6510
                                 virDomainObjPtr vm)
{
6511
    int ret;
6512
    VIR_DEBUG("vm=%s", vm->def->name);
6513 6514 6515
    ret = virCloseCallbacksUnset(driver->closeCallbacks, vm,
                                 qemuProcessAutoDestroy);
    return ret;
6516
}
6517

6518
bool qemuProcessAutoDestroyActive(virQEMUDriverPtr driver,
6519 6520
                                  virDomainObjPtr vm)
{
6521
    virCloseCallback cb;
6522
    VIR_DEBUG("vm=%s", vm->def->name);
6523
    cb = virCloseCallbacksGet(driver->closeCallbacks, vm, NULL);
6524
    return cb == qemuProcessAutoDestroy;
6525
}
6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548


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];
6549
        qemuDomainDiskPrivatePtr diskpriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
6550 6551
        struct qemuDomainDiskInfo *info;

6552 6553
        if (!(info = virHashLookup(table, disk->info.alias)))
            continue;
6554

6555 6556
        if (info->removable) {
            if (info->empty)
6557 6558
                ignore_value(virDomainDiskSetSource(disk, NULL));

6559 6560 6561 6562 6563 6564
            if (info->tray) {
                if (info->tray_open)
                    disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
                else
                    disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
            }
6565
        }
6566 6567 6568 6569

        /* fill in additional data */
        diskpriv->removable = info->removable;
        diskpriv->tray = info->tray;
6570 6571 6572 6573 6574 6575 6576 6577
    }

    ret = 0;

 cleanup:
    virHashFree(table);
    return ret;
}