qemu_process.c 209.0 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
#include "qemu_security.h"
49

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

#define VIR_FROM_THIS VIR_FROM_QEMU

82 83
VIR_LOG_INIT("qemu.qemu_process");

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

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

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

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

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


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

D
Daniel P. Berrange 已提交
125 126 127 128 129 130 131
/*
 * 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
132
qemuProcessHandleAgentEOF(qemuAgentPtr agent,
D
Daniel P. Berrange 已提交
133 134 135 136 137 138
                          virDomainObjPtr vm)
{
    qemuDomainObjPrivatePtr priv;

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

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

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

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

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

157
    virObjectUnlock(vm);
158 159
    return;

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


/*
 * 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);

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

    priv = vm->privateData;

    priv->agentError = true;

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

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

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


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


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

    if (!config)
        return 0;

215 216 217 218 219 220 221 222 223
    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;
    }

224
    if (qemuSecuritySetDaemonSocketLabel(driver->securityManager, vm->def) < 0) {
D
Daniel P. Berrange 已提交
225 226 227 228 229 230 231
        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
    virObjectUnlock(vm);
D
Daniel P. Berrange 已提交
235 236

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

240
    virObjectLock(vm);
D
Daniel P. Berrange 已提交
241

242 243 244 245 246 247 248
    if (agent == NULL)
        virObjectUnref(vm);

    if (!virDomainObjIsActive(vm)) {
        qemuAgentClose(agent);
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("guest crashed while connecting to the guest agent"));
249
        return -1;
250 251
    }

252
    if (qemuSecurityClearSocketLabel(driver->securityManager, vm->def) < 0) {
D
Daniel P. Berrange 已提交
253 254
        VIR_ERROR(_("Failed to clear security context for agent for %s"),
                  vm->def->name);
255
        qemuAgentClose(agent);
D
Daniel P. Berrange 已提交
256 257 258 259
        goto cleanup;
    }

    priv->agent = agent;
260
    if (!priv->agent)
D
Daniel P. Berrange 已提交
261 262
        VIR_INFO("Failed to connect agent for %s", vm->def->name);

263
 cleanup:
264 265 266 267 268 269 270
    if (!priv->agent) {
        VIR_WARN("Cannot connect to QEMU guest agent for %s", vm->def->name);
        priv->agentError = true;
        virResetLastError();
    }

    return 0;
D
Daniel P. Berrange 已提交
271 272 273
}


274
/*
275
 * This is a callback registered with a qemuMonitorPtr instance,
276 277 278 279 280 281
 * 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,
282 283
                            virDomainObjPtr vm,
                            void *opaque)
284
{
285
    virQEMUDriverPtr driver = opaque;
286
    qemuDomainObjPrivatePtr priv;
287
    struct qemuProcessEvent *processEvent;
288

289
    virObjectLock(vm);
290

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

293
    priv = vm->privateData;
294 295
    if (priv->beingDestroyed) {
        VIR_DEBUG("Domain is being destroyed, EOF is expected");
296
        goto cleanup;
297 298
    }

299
    if (VIR_ALLOC(processEvent) < 0)
300
        goto cleanup;
301

302 303
    processEvent->eventType = QEMU_PROCESS_EVENT_MONITOR_EOF;
    processEvent->vm = vm;
304

305 306 307 308 309
    virObjectRef(vm);
    if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
        ignore_value(virObjectUnref(vm));
        VIR_FREE(processEvent);
        goto cleanup;
310
    }
311

312 313 314 315
    /* We don't want this EOF handler to be called over and over while the
     * thread is waiting for a job.
     */
    qemuMonitorUnregister(mon);
316

317 318 319 320
    /* We don't want any cleanup from EOF handler (or any other
     * thread) to enter qemu namespace. */
    qemuDomainDestroyNamespace(driver, vm);

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
                                         VIR_DOMAIN_EVENT_RESUMED,
                                         VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);

779
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
780 781 782 783 784
            VIR_WARN("Unable to save status on vm %s after state change",
                     vm->def->name);
        }
    }

785
 unlock:
786
    virObjectUnlock(vm);
787
    qemuDomainEventQueue(driver, event);
788
    virObjectUnref(cfg);
789 790 791
    return 0;
}

792 793 794
static int
qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                           virDomainObjPtr vm,
795 796
                           long long offset,
                           void *opaque)
797
{
798
    virQEMUDriverPtr driver = opaque;
799
    virObjectEventPtr event = NULL;
800
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
801

802
    virObjectLock(vm);
803

804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
    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;
821
        vm->def->clock.data.variable.adjustment = offset;
822

823
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
824 825 826 827
           VIR_WARN("unable to save domain status with RTC change");
    }

    event = virDomainEventRTCChangeNewFromObj(vm, offset);
828

829
    virObjectUnlock(vm);
830

831
    qemuDomainEventQueue(driver, event);
832
    virObjectUnref(cfg);
833 834 835 836 837 838 839
    return 0;
}


static int
qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                          virDomainObjPtr vm,
840 841
                          int action,
                          void *opaque)
842
{
843
    virQEMUDriverPtr driver = opaque;
844 845
    virObjectEventPtr watchdogEvent = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
846
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
847

848
    virObjectLock(vm);
849 850 851
    watchdogEvent = virDomainEventWatchdogNewFromObj(vm, action);

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

J
Jiri Denemark 已提交
856
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_WATCHDOG);
857
        lifecycleEvent = virDomainEventLifecycleNewFromObj(vm,
858 859 860
                                                  VIR_DOMAIN_EVENT_SUSPENDED,
                                                  VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG);

861 862 863 864 865
        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));

866
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
867 868 869
            VIR_WARN("Unable to save status on vm %s after watchdog event",
                     vm->def->name);
        }
870 871 872
    }

    if (vm->def->watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) {
C
Chen Fan 已提交
873 874 875 876 877
        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 已提交
878 879 880
            /* Hold an extra reference because we can't allow 'vm' to be
             * deleted before handling watchdog event is finished.
             */
881
            virObjectRef(vm);
C
Chen Fan 已提交
882
            if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
883
                if (!virObjectUnref(vm))
884
                    vm = NULL;
C
Chen Fan 已提交
885
                VIR_FREE(processEvent);
W
Wen Congyang 已提交
886
            }
887
        }
888 889
    }

890
    if (vm)
891
        virObjectUnlock(vm);
892 893
    qemuDomainEventQueue(driver, watchdogEvent);
    qemuDomainEventQueue(driver, lifecycleEvent);
894

895
    virObjectUnref(cfg);
896 897 898 899 900 901 902 903 904
    return 0;
}


static int
qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                         virDomainObjPtr vm,
                         const char *diskAlias,
                         int action,
905 906
                         const char *reason,
                         void *opaque)
907
{
908
    virQEMUDriverPtr driver = opaque;
909 910 911
    virObjectEventPtr ioErrorEvent = NULL;
    virObjectEventPtr ioErrorEvent2 = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
912 913 914
    const char *srcPath;
    const char *devAlias;
    virDomainDiskDefPtr disk;
915
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
916

917
    virObjectLock(vm);
918 919 920
    disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);

    if (disk) {
921
        srcPath = virDomainDiskGetSource(disk);
922 923 924 925 926 927 928 929 930 931
        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 已提交
932
        virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
933
        qemuDomainObjPrivatePtr priv = vm->privateData;
934 935
        VIR_DEBUG("Transitioned guest %s to paused state due to IO error", vm->def->name);

936 937 938
        if (priv->signalIOError)
            virDomainObjBroadcast(vm);

J
Jiri Denemark 已提交
939
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOERROR);
940
        lifecycleEvent = virDomainEventLifecycleNewFromObj(vm,
941 942 943
                                                  VIR_DOMAIN_EVENT_SUSPENDED,
                                                  VIR_DOMAIN_EVENT_SUSPENDED_IOERROR);

944 945 946 947 948
        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));

949
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
950 951
            VIR_WARN("Unable to save status on vm %s after IO error", vm->def->name);
    }
952
    virObjectUnlock(vm);
953

954 955 956
    qemuDomainEventQueue(driver, ioErrorEvent);
    qemuDomainEventQueue(driver, ioErrorEvent2);
    qemuDomainEventQueue(driver, lifecycleEvent);
957
    virObjectUnref(cfg);
958 959 960
    return 0;
}

961 962 963 964 965
static int
qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                          virDomainObjPtr vm,
                          const char *diskAlias,
                          int type,
966 967
                          int status,
                          void *opaque)
968
{
969
    virQEMUDriverPtr driver = opaque;
970
    struct qemuProcessEvent *processEvent = NULL;
971
    virDomainDiskDefPtr disk;
972
    qemuDomainDiskPrivatePtr diskPriv;
973
    char *data = NULL;
974

975
    virObjectLock(vm);
976

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

980
    if (!(disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias)))
981
        goto error;
982
    diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
983

984
    if (diskPriv->blockJobSync) {
985
        /* We have a SYNC API waiting for this event, dispatch it back */
986 987
        diskPriv->blockJobType = type;
        diskPriv->blockJobStatus = status;
988
        virDomainObjBroadcast(vm);
989 990 991 992 993 994 995 996 997 998 999 1000
    } 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;
1001

1002 1003 1004 1005 1006
        virObjectRef(vm);
        if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
            ignore_value(virObjectUnref(vm));
            goto error;
        }
1007 1008
    }

1009
 cleanup:
1010
    virObjectUnlock(vm);
1011
    return 0;
1012 1013 1014 1015 1016
 error:
    if (processEvent)
        VIR_FREE(processEvent->data);
    VIR_FREE(processEvent);
    goto cleanup;
1017
}
1018

1019

1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031
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,
1032 1033
                          const char *saslUsername,
                          void *opaque)
1034
{
1035
    virQEMUDriverPtr driver = opaque;
1036
    virObjectEventPtr event;
1037 1038 1039
    virDomainEventGraphicsAddressPtr localAddr = NULL;
    virDomainEventGraphicsAddressPtr remoteAddr = NULL;
    virDomainEventGraphicsSubjectPtr subject = NULL;
1040
    size_t i;
1041 1042

    if (VIR_ALLOC(localAddr) < 0)
1043
        goto error;
1044
    localAddr->family = localFamily;
1045 1046 1047
    if (VIR_STRDUP(localAddr->service, localService) < 0 ||
        VIR_STRDUP(localAddr->node, localNode) < 0)
        goto error;
1048 1049

    if (VIR_ALLOC(remoteAddr) < 0)
1050
        goto error;
1051
    remoteAddr->family = remoteFamily;
1052 1053 1054
    if (VIR_STRDUP(remoteAddr->service, remoteService) < 0 ||
        VIR_STRDUP(remoteAddr->node, remoteNode) < 0)
        goto error;
1055 1056

    if (VIR_ALLOC(subject) < 0)
1057
        goto error;
1058 1059
    if (x509dname) {
        if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
1060
            goto error;
1061
        subject->nidentity++;
1062 1063 1064
        if (VIR_STRDUP(subject->identities[subject->nidentity-1].type, "x509dname") < 0 ||
            VIR_STRDUP(subject->identities[subject->nidentity-1].name, x509dname) < 0)
            goto error;
1065 1066 1067
    }
    if (saslUsername) {
        if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
1068
            goto error;
1069
        subject->nidentity++;
1070 1071 1072
        if (VIR_STRDUP(subject->identities[subject->nidentity-1].type, "saslUsername") < 0 ||
            VIR_STRDUP(subject->identities[subject->nidentity-1].name, saslUsername) < 0)
            goto error;
1073 1074
    }

1075
    virObjectLock(vm);
1076
    event = virDomainEventGraphicsNewFromObj(vm, phase, localAddr, remoteAddr, authScheme, subject);
1077
    virObjectUnlock(vm);
1078

1079
    qemuDomainEventQueue(driver, event);
1080 1081 1082

    return 0;

1083
 error:
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
    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) {
1095
        for (i = 0; i < subject->nidentity; i++) {
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105
            VIR_FREE(subject->identities[i].type);
            VIR_FREE(subject->identities[i].name);
        }
        VIR_FREE(subject->identities);
        VIR_FREE(subject);
    }

    return -1;
}

1106 1107 1108 1109
static int
qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                            virDomainObjPtr vm,
                            const char *devAlias,
1110 1111
                            int reason,
                            void *opaque)
1112
{
1113
    virQEMUDriverPtr driver = opaque;
1114
    virObjectEventPtr event = NULL;
1115
    virDomainDiskDefPtr disk;
1116
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
1117

1118
    virObjectLock(vm);
1119 1120 1121 1122 1123 1124
    disk = qemuProcessFindDomainDiskByAlias(vm, devAlias);

    if (disk) {
        event = virDomainEventTrayChangeNewFromObj(vm,
                                                   devAlias,
                                                   reason);
1125 1126 1127 1128 1129 1130
        /* 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;

1131
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
1132 1133 1134
            VIR_WARN("Unable to save status on vm %s after tray moved event",
                     vm->def->name);
        }
1135 1136

        virDomainObjBroadcast(vm);
1137 1138
    }

1139
    virObjectUnlock(vm);
1140
    qemuDomainEventQueue(driver, event);
1141
    virObjectUnref(cfg);
1142 1143 1144
    return 0;
}

O
Osier Yang 已提交
1145 1146
static int
qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1147 1148
                          virDomainObjPtr vm,
                          void *opaque)
O
Osier Yang 已提交
1149
{
1150
    virQEMUDriverPtr driver = opaque;
1151 1152
    virObjectEventPtr event = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
1153
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
O
Osier Yang 已提交
1154

1155
    virObjectLock(vm);
O
Osier Yang 已提交
1156 1157
    event = virDomainEventPMWakeupNewFromObj(vm);

1158 1159 1160 1161 1162 1163 1164 1165 1166
    /* 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);
1167
        lifecycleEvent = virDomainEventLifecycleNewFromObj(vm,
1168 1169 1170
                                                  VIR_DOMAIN_EVENT_STARTED,
                                                  VIR_DOMAIN_EVENT_STARTED_WAKEUP);

1171
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
1172 1173 1174 1175 1176
            VIR_WARN("Unable to save status on vm %s after wakeup event",
                     vm->def->name);
        }
    }

1177
    virObjectUnlock(vm);
1178 1179
    qemuDomainEventQueue(driver, event);
    qemuDomainEventQueue(driver, lifecycleEvent);
1180
    virObjectUnref(cfg);
O
Osier Yang 已提交
1181 1182
    return 0;
}
1183

O
Osier Yang 已提交
1184 1185
static int
qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1186 1187
                           virDomainObjPtr vm,
                           void *opaque)
O
Osier Yang 已提交
1188
{
1189
    virQEMUDriverPtr driver = opaque;
1190 1191
    virObjectEventPtr event = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
1192
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
O
Osier Yang 已提交
1193

1194
    virObjectLock(vm);
O
Osier Yang 已提交
1195 1196
    event = virDomainEventPMSuspendNewFromObj(vm);

1197
    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
1198
        qemuDomainObjPrivatePtr priv = vm->privateData;
1199 1200 1201 1202 1203
        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 已提交
1204
        lifecycleEvent =
1205
            virDomainEventLifecycleNewFromObj(vm,
J
Jiri Denemark 已提交
1206 1207
                                     VIR_DOMAIN_EVENT_PMSUSPENDED,
                                     VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY);
1208

1209
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
1210 1211 1212
            VIR_WARN("Unable to save status on vm %s after suspend event",
                     vm->def->name);
        }
1213 1214 1215

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

1218
    virObjectUnlock(vm);
O
Osier Yang 已提交
1219

1220 1221
    qemuDomainEventQueue(driver, event);
    qemuDomainEventQueue(driver, lifecycleEvent);
1222
    virObjectUnref(cfg);
O
Osier Yang 已提交
1223 1224 1225
    return 0;
}

1226 1227 1228
static int
qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                               virDomainObjPtr vm,
1229 1230
                               unsigned long long actual,
                               void *opaque)
1231
{
1232
    virQEMUDriverPtr driver = opaque;
1233
    virObjectEventPtr event = NULL;
1234
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
1235

1236
    virObjectLock(vm);
1237 1238 1239 1240 1241 1242
    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;

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

1246
    virObjectUnlock(vm);
1247

1248
    qemuDomainEventQueue(driver, event);
1249
    virObjectUnref(cfg);
1250 1251 1252
    return 0;
}

1253 1254
static int
qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1255 1256
                               virDomainObjPtr vm,
                               void *opaque)
1257
{
1258
    virQEMUDriverPtr driver = opaque;
1259 1260
    virObjectEventPtr event = NULL;
    virObjectEventPtr lifecycleEvent = NULL;
1261
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
1262

1263
    virObjectLock(vm);
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
    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 =
1274
            virDomainEventLifecycleNewFromObj(vm,
1275 1276 1277
                                     VIR_DOMAIN_EVENT_PMSUSPENDED,
                                     VIR_DOMAIN_EVENT_PMSUSPENDED_DISK);

1278
        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
1279 1280 1281 1282 1283 1284 1285 1286
            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);
    }

1287
    virObjectUnlock(vm);
1288

1289 1290
    qemuDomainEventQueue(driver, event);
    qemuDomainEventQueue(driver, lifecycleEvent);
1291 1292
    virObjectUnref(cfg);

1293 1294 1295
    return 0;
}

1296

1297 1298
static int
qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
1299 1300
                            virDomainObjPtr vm,
                            void *opaque)
1301
{
1302
    virQEMUDriverPtr driver = opaque;
1303 1304 1305
    struct qemuProcessEvent *processEvent;

    virObjectLock(vm);
1306
    if (VIR_ALLOC(processEvent) < 0)
1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
        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);
    }

1322
 cleanup:
1323
    if (vm)
1324
        virObjectUnlock(vm);
1325 1326 1327 1328 1329

    return 0;
}


1330
int
1331 1332
qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                               virDomainObjPtr vm,
1333 1334
                               const char *devAlias,
                               void *opaque)
1335
{
1336
    virQEMUDriverPtr driver = opaque;
1337 1338
    struct qemuProcessEvent *processEvent = NULL;
    char *data;
1339 1340 1341 1342 1343 1344

    virObjectLock(vm);

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

1345 1346
    if (qemuDomainSignalDeviceRemoval(vm, devAlias,
                                      QEMU_DOMAIN_UNPLUGGING_DEVICE_STATUS_OK))
1347
        goto cleanup;
1348

1349 1350
    if (VIR_ALLOC(processEvent) < 0)
        goto error;
1351

1352 1353 1354 1355 1356
    processEvent->eventType = QEMU_PROCESS_EVENT_DEVICE_DELETED;
    if (VIR_STRDUP(data, devAlias) < 0)
        goto error;
    processEvent->data = data;
    processEvent->vm = vm;
1357

1358 1359 1360 1361 1362
    virObjectRef(vm);
    if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
        ignore_value(virObjectUnref(vm));
        goto error;
    }
1363

1364
 cleanup:
1365 1366
    virObjectUnlock(vm);
    return 0;
1367 1368 1369 1370 1371
 error:
    if (processEvent)
        VIR_FREE(processEvent->data);
    VIR_FREE(processEvent);
    goto cleanup;
1372 1373 1374
}


1375 1376 1377 1378 1379 1380 1381 1382 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
/**
 *
 * 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;
}


1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 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
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;
}


1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 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
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;
}


1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545
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;
1546
    virDomainObjBroadcast(vm);
1547 1548 1549 1550 1551 1552 1553

 cleanup:
    virObjectUnlock(vm);
    return 0;
}


1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
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;
1569
    if (priv->job.asyncJob == QEMU_ASYNC_JOB_NONE) {
1570 1571 1572 1573
        VIR_DEBUG("got MIGRATION event without a migration job");
        goto cleanup;
    }

1574
    priv->job.current->stats.status = status;
1575 1576 1577 1578 1579 1580 1581 1582
    virDomainObjBroadcast(vm);

 cleanup:
    virObjectUnlock(vm);
    return 0;
}


1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611
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;
}


1612 1613
static qemuMonitorCallbacks monitorCallbacks = {
    .eofNotify = qemuProcessHandleMonitorEOF,
1614
    .errorNotify = qemuProcessHandleMonitorError,
1615
    .diskSecretLookup = qemuProcessFindVolumeQcowPassphrase,
1616
    .domainEvent = qemuProcessHandleEvent,
1617 1618
    .domainShutdown = qemuProcessHandleShutdown,
    .domainStop = qemuProcessHandleStop,
1619
    .domainResume = qemuProcessHandleResume,
1620 1621 1622 1623 1624
    .domainReset = qemuProcessHandleReset,
    .domainRTCChange = qemuProcessHandleRTCChange,
    .domainWatchdog = qemuProcessHandleWatchdog,
    .domainIOError = qemuProcessHandleIOError,
    .domainGraphics = qemuProcessHandleGraphics,
1625
    .domainBlockJob = qemuProcessHandleBlockJob,
1626
    .domainTrayChange = qemuProcessHandleTrayChange,
O
Osier Yang 已提交
1627
    .domainPMWakeup = qemuProcessHandlePMWakeup,
O
Osier Yang 已提交
1628
    .domainPMSuspend = qemuProcessHandlePMSuspend,
1629
    .domainBalloonChange = qemuProcessHandleBalloonChange,
1630
    .domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
1631
    .domainGuestPanic = qemuProcessHandleGuestPanic,
1632
    .domainDeviceDeleted = qemuProcessHandleDeviceDeleted,
1633
    .domainNicRxFilterChanged = qemuProcessHandleNicRxFilterChanged,
1634
    .domainSerialChange = qemuProcessHandleSerialChanged,
1635
    .domainSpiceMigrated = qemuProcessHandleSpiceMigrated,
1636
    .domainMigrationStatus = qemuProcessHandleMigrationStatus,
1637
    .domainMigrationPass = qemuProcessHandleMigrationPass,
1638
    .domainAcpiOstInfo = qemuProcessHandleAcpiOstInfo,
1639 1640
};

1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653
static void
qemuProcessMonitorReportLogError(qemuMonitorPtr mon,
                                 const char *msg,
                                 void *opaque);


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

1654
static int
1655
qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob,
1656
                   qemuDomainLogContextPtr logCtxt)
1657 1658 1659
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int ret = -1;
1660
    qemuMonitorPtr mon = NULL;
1661
    unsigned long long timeout = 0;
1662

1663
    if (qemuSecuritySetDaemonSocketLabel(driver->securityManager, vm->def) < 0) {
1664 1665
        VIR_ERROR(_("Failed to set security context for monitor for %s"),
                  vm->def->name);
1666
        return -1;
1667 1668
    }

1669 1670 1671 1672 1673 1674
    /* When using hugepages, kernel zeroes them out before
     * handing them over to qemu. This can be very time
     * consuming. Therefore, add a second to timeout for each
     * 1GiB of guest RAM. */
    timeout = vm->def->mem.total_memory / (1024 * 1024);

1675
    /* Hold an extra reference because we can't allow 'vm' to be
C
Chen Hanxiao 已提交
1676
     * deleted until the monitor gets its own reference. */
1677
    virObjectRef(vm);
1678

1679
    ignore_value(virTimeMillisNow(&priv->monStart));
1680
    virObjectUnlock(vm);
1681 1682 1683 1684

    mon = qemuMonitorOpen(vm,
                          priv->monConfig,
                          priv->monJSON,
1685
                          timeout,
1686 1687
                          &monitorCallbacks,
                          driver);
1688

1689 1690 1691 1692 1693 1694 1695
    if (mon && logCtxt) {
        qemuDomainLogContextRef(logCtxt);
        qemuMonitorSetDomainLog(mon,
                                qemuProcessMonitorReportLogError,
                                logCtxt,
                                qemuProcessMonitorLogFree);
    }
1696

1697
    virObjectLock(vm);
M
Michal Privoznik 已提交
1698
    virObjectUnref(vm);
1699
    priv->monStart = 0;
1700

M
Michal Privoznik 已提交
1701
    if (!virDomainObjIsActive(vm)) {
1702
        qemuMonitorClose(mon);
1703
        mon = NULL;
1704 1705 1706
    }
    priv->mon = mon;

1707
    if (qemuSecurityClearSocketLabel(driver->securityManager, vm->def) < 0) {
1708 1709
        VIR_ERROR(_("Failed to clear security context for monitor for %s"),
                  vm->def->name);
1710
        return -1;
1711 1712 1713 1714
    }

    if (priv->mon == NULL) {
        VIR_INFO("Failed to connect monitor for %s", vm->def->name);
1715
        return -1;
1716 1717 1718
    }


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

1722 1723 1724 1725 1726 1727 1728 1729 1730 1731
    if (qemuMonitorSetCapabilities(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);
    }
1732

1733 1734 1735 1736 1737
    ret = 0;

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

1741 1742 1743

/**
 * qemuProcessReadLog: Read log file of a qemu VM
1744
 * @logCtxt: the domain log context
1745
 * @msg: pointer to buffer to store the read messages in
1746 1747
 *
 * Reads log of a qemu VM. Skips messages not produced by qemu or irrelevant
1748
 * messages. Returns returns 0 on success or -1 on error
1749
 */
1750
static int
1751
qemuProcessReadLog(qemuDomainLogContextPtr logCtxt, char **msg)
1752
{
1753 1754
    char *buf;
    ssize_t got;
1755
    char *eol;
1756
    char *filter_next;
1757

1758
    if ((got = qemuDomainLogContextRead(logCtxt, &buf)) < 0)
1759
        return -1;
1760

1761 1762 1763 1764 1765 1766 1767
    /* 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;
1768
            memmove(filter_next, eol + 1, buf + got - eol);
1769 1770 1771 1772
            got -= skip;
        } else {
            filter_next = eol + 1;
            *eol = '\n';
1773 1774
        }
    }
1775
    filter_next = NULL; /* silence false coverity warning */
1776

1777 1778
    if (got > 0 &&
        buf[got - 1] == '\n') {
1779 1780
        buf[got - 1] = '\0';
        got--;
1781
    }
1782
    ignore_value(VIR_REALLOC_N_QUIET(buf, got + 1));
1783 1784 1785
    *msg = buf;
    return 0;
}
1786 1787


1788 1789
static int
qemuProcessReportLogError(qemuDomainLogContextPtr logCtxt,
1790 1791 1792 1793
                          const char *msgprefix)
{
    char *logmsg = NULL;

1794
    if (qemuProcessReadLog(logCtxt, &logmsg) < 0)
1795 1796 1797
        return -1;

    virResetLastError();
1798 1799 1800 1801 1802
    if (virStringIsEmpty(logmsg))
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", msgprefix);
    else
        virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: %s"), msgprefix, logmsg);

1803 1804
    VIR_FREE(logmsg);
    return 0;
1805 1806 1807
}


1808 1809 1810 1811 1812 1813 1814 1815 1816 1817
static void
qemuProcessMonitorReportLogError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                 const char *msg,
                                 void *opaque)
{
    qemuDomainLogContextPtr logCtxt = opaque;
    qemuProcessReportLogError(logCtxt, msg);
}


1818
static int
1819 1820 1821
qemuProcessLookupPTYs(virDomainDefPtr def,
                      virQEMUCapsPtr qemuCaps,
                      virDomainChrDefPtr *devices,
1822
                      int count,
1823
                      virHashTablePtr info)
1824
{
1825
    size_t i;
1826

1827
    for (i = 0; i < count; i++) {
1828
        virDomainChrDefPtr chr = devices[i];
1829 1830
        bool chardevfmt = virQEMUCapsSupportsChardev(def, qemuCaps, chr);

1831
        if (chr->source->type == VIR_DOMAIN_CHR_TYPE_PTY) {
C
Cole Robinson 已提交
1832
            char id[32];
1833
            qemuMonitorChardevInfoPtr entry;
1834

C
Cole Robinson 已提交
1835
            if (snprintf(id, sizeof(id), "%s%s",
1836
                         chardevfmt ? "char" : "",
1837 1838 1839 1840
                         chr->info.alias) >= sizeof(id)) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("failed to format device alias "
                                 "for PTY retrieval"));
1841
                return -1;
1842
            }
1843

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

1861 1862
            VIR_FREE(chr->source->data.file.path);
            if (VIR_STRDUP(chr->source->data.file.path, entry->ptyPath) < 0)
1863 1864 1865 1866 1867 1868 1869
                return -1;
        }
    }

    return 0;
}

1870 1871
static int
qemuProcessFindCharDevicePTYsMonitor(virDomainObjPtr vm,
1872
                                     virQEMUCapsPtr qemuCaps,
1873
                                     virHashTablePtr info)
1874
{
1875
    size_t i = 0;
C
Cole Robinson 已提交
1876

1877 1878
    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
                              vm->def->serials, vm->def->nserials,
1879
                              info) < 0)
1880 1881
        return -1;

1882 1883
    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
                              vm->def->parallels, vm->def->nparallels,
1884
                              info) < 0)
1885
        return -1;
1886

1887 1888
    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
                              vm->def->channels, vm->def->nchannels,
1889
                              info) < 0)
1890
        return -1;
1891 1892 1893 1894
    /* 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];
1895

1896 1897 1898 1899 1900
        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;
1901 1902
            if (virDomainChrSourceDefCopy(chr->source,
                                          ((vm->def->serials[0])->source)) < 0)
1903 1904 1905 1906
                return -1;
        }
    }

1907 1908
    if (qemuProcessLookupPTYs(vm->def, qemuCaps,
                              vm->def->consoles + i, vm->def->nconsoles - i,
1909
                              info) < 0)
1910
        return -1;
1911 1912 1913 1914 1915

    return 0;
}


1916
static int
1917 1918 1919 1920
qemuProcessRefreshChannelVirtioState(virQEMUDriverPtr driver,
                                     virDomainObjPtr vm,
                                     virHashTablePtr info,
                                     int booted)
1921 1922
{
    size_t i;
1923
    int agentReason = VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL;
1924
    qemuMonitorChardevInfoPtr entry;
1925
    virObjectEventPtr event = NULL;
1926 1927
    char id[32];

1928 1929 1930
    if (booted)
        agentReason = VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED;

1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946
    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;

1947 1948 1949 1950 1951 1952
            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);

1953 1954 1955 1956 1957 1958 1959 1960
            chr->state = entry->state;
        }
    }

    return 0;
}


1961 1962
int
qemuRefreshVirtioChannelState(virQEMUDriverPtr driver,
1963 1964
                              virDomainObjPtr vm,
                              qemuDomainAsyncJob asyncJob)
1965 1966 1967 1968 1969
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virHashTablePtr info = NULL;
    int ret = -1;

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

1973
    ret = qemuMonitorGetChardevInfo(priv->mon, &info);
1974 1975
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;
1976 1977 1978 1979

    if (ret < 0)
        goto cleanup;

1980
    ret = qemuProcessRefreshChannelVirtioState(driver, vm, info, false);
1981 1982 1983 1984 1985 1986

 cleanup:
    virHashFree(info);
    return ret;
}

1987 1988 1989 1990 1991 1992 1993 1994 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
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;
}
2023

2024
int
2025 2026 2027 2028 2029 2030 2031 2032 2033
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 */
2034
    if (!virDomainDefHasMemballoon(vm->def)) {
2035
        vm->def->mem.cur_balloon = virDomainDefGetMemoryTotal(vm->def);
2036 2037 2038 2039 2040 2041 2042
        return 0;
    }

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

    rc = qemuMonitorGetBalloonInfo(qemuDomainGetMonitor(vm), &balloon);
2043
    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
2044 2045 2046 2047 2048 2049 2050 2051
        return -1;

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

    return 0;
}


2052
static int
2053
qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
C
Cole Robinson 已提交
2054
                          virDomainObjPtr vm,
2055
                          int asyncJob,
2056
                          virQEMUCapsPtr qemuCaps,
2057
                          qemuDomainLogContextPtr logCtxt)
2058 2059
{
    int ret = -1;
2060
    virHashTablePtr info = NULL;
2061
    qemuDomainObjPrivatePtr priv;
2062 2063

    VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name);
2064
    if (qemuConnectMonitor(driver, vm, asyncJob, logCtxt) < 0)
2065 2066 2067 2068 2069 2070
        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. */
2071
    priv = vm->privateData;
2072 2073
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto cleanup;
2074 2075
    ret = qemuMonitorGetChardevInfo(priv->mon, &info);
    VIR_DEBUG("qemuMonitorGetChardevInfo returned %i", ret);
2076 2077 2078
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;

2079 2080 2081 2082 2083
    if (ret == 0) {
        if ((ret = qemuProcessFindCharDevicePTYsMonitor(vm, qemuCaps,
                                                        info)) < 0)
            goto cleanup;

2084 2085
        if ((ret = qemuProcessRefreshChannelVirtioState(driver, vm, info,
                                                        true)) < 0)
2086 2087
            goto cleanup;
    }
2088

2089
 cleanup:
2090
    virHashFree(info);
2091

2092 2093
    if (logCtxt && kill(vm->pid, 0) == -1 && errno == ESRCH) {
        qemuProcessReportLogError(logCtxt,
2094
                                  _("process exited while connecting to monitor"));
2095 2096 2097 2098 2099 2100
        ret = -1;
    }

    return ret;
}

2101

2102 2103 2104 2105 2106 2107
static int
qemuProcessDetectIOThreadPIDs(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              int asyncJob)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
2108
    qemuMonitorIOThreadInfoPtr *iothreads = NULL;
2109 2110 2111 2112
    int niothreads = 0;
    int ret = -1;
    size_t i;

2113 2114 2115 2116 2117
    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) {
        ret = 0;
        goto cleanup;
    }

2118 2119 2120 2121
    /* Get the list of IOThreads from qemu */
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto cleanup;
    niothreads = qemuMonitorGetIOThreads(priv->mon, &iothreads);
2122 2123
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        goto cleanup;
J
John Ferlan 已提交
2124
    if (niothreads < 0)
2125 2126
        goto cleanup;

2127
    if (niothreads != vm->def->niothreadids) {
2128 2129
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("got wrong number of IOThread pids from QEMU monitor. "
2130 2131
                         "got %d, wanted %zu"),
                       niothreads, vm->def->niothreadids);
2132 2133 2134
        goto cleanup;
    }

2135 2136 2137 2138 2139 2140
    /* Nothing to do */
    if (niothreads == 0) {
        ret = 0;
        goto cleanup;
    }

2141 2142 2143
    for (i = 0; i < niothreads; i++) {
        virDomainIOThreadIDDefPtr iothrid;

2144 2145
        if (!(iothrid = virDomainIOThreadIDFind(vm->def,
                                                iothreads[i]->iothread_id))) {
2146
            virReportError(VIR_ERR_INTERNAL_ERROR,
2147 2148
                           _("iothread %d not found"),
                           iothreads[i]->iothread_id);
2149 2150 2151 2152
            goto cleanup;
        }
        iothrid->thread_id = iothreads[i]->thread_id;
    }
2153 2154 2155 2156 2157 2158

    ret = 0;

 cleanup:
    if (iothreads) {
        for (i = 0; i < niothreads; i++)
2159
            VIR_FREE(iothreads[i]);
2160 2161 2162 2163 2164
        VIR_FREE(iothreads);
    }
    return ret;
}

2165 2166 2167 2168 2169

/*
 * To be run between fork/exec of QEMU only
 */
static int
2170
qemuProcessInitCpuAffinity(virDomainObjPtr vm)
2171 2172 2173 2174
{
    int ret = -1;
    virBitmapPtr cpumap = NULL;
    virBitmapPtr cpumapToSet = NULL;
2175
    virBitmapPtr hostcpumap = NULL;
2176
    qemuDomainObjPrivatePtr priv = vm->privateData;
2177

2178 2179 2180 2181 2182 2183
    if (!vm->pid) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Cannot setup CPU affinity until process is started"));
        return -1;
    }

2184 2185
    if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
        VIR_DEBUG("Set CPU affinity with advisory nodeset from numad");
2186
        cpumapToSet = priv->autoCpuset;
2187
    } else {
2188
        VIR_DEBUG("Set CPU affinity with specified cpuset");
O
Osier Yang 已提交
2189
        if (vm->def->cpumask) {
H
Hu Tao 已提交
2190
            cpumapToSet = vm->def->cpumask;
O
Osier Yang 已提交
2191 2192 2193 2194 2195
        } 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 */
2196 2197
            int hostcpus;

2198 2199 2200 2201 2202 2203 2204 2205 2206 2207
            if (virHostCPUHasBitmap()) {
                hostcpumap = virHostCPUGetOnlineBitmap();
                cpumap = virProcessGetAffinity(vm->pid);
            }

            if (hostcpumap && cpumap && virBitmapEqual(hostcpumap, cpumap)) {
                /* we're using all available CPUs, no reason to set
                 * mask. If libvirtd is running without explicit
                 * affinity, we can use hotplugged CPUs for this VM */
                ret = 0;
2208
                goto cleanup;
2209 2210 2211 2212 2213
            } else {
                /* setaffinity fails if you set bits for CPUs which
                 * aren't present, so we have to limit ourselves */
                if ((hostcpus = virHostCPUGetCount()) < 0)
                    goto cleanup;
2214

2215 2216
                if (hostcpus > QEMUD_CPUMASK_LEN)
                    hostcpus = QEMUD_CPUMASK_LEN;
2217

2218 2219 2220
                virBitmapFree(cpumap);
                if (!(cpumap = virBitmapNew(hostcpus)))
                    goto cleanup;
2221

2222
                virBitmapSetAll(cpumap);
2223

2224 2225
                cpumapToSet = cpumap;
            }
O
Osier Yang 已提交
2226
        }
2227 2228
    }

2229
    if (virProcessSetAffinity(vm->pid, cpumapToSet) < 0)
2230
        goto cleanup;
2231

2232 2233
    ret = 0;

2234
 cleanup:
2235
    virBitmapFree(cpumap);
2236
    virBitmapFree(hostcpumap);
2237
    return ret;
2238 2239
}

2240 2241
/* set link states to down on interfaces at qemu start */
static int
2242 2243 2244
qemuProcessSetLinkStates(virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
                         qemuDomainAsyncJob asyncJob)
2245 2246 2247
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virDomainDefPtr def = vm->def;
2248
    size_t i;
2249 2250 2251 2252 2253
    int ret = -1;
    int rv;

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

    for (i = 0; i < def->nnets; i++) {
        if (def->nets[i]->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
2257 2258 2259
            if (!def->nets[i]->info.alias) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing alias for network device"));
2260
                goto cleanup;
2261 2262
            }

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

2265
            if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
2266
                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2267
                               _("Setting of link state is not supported by this qemu"));
2268
                goto cleanup;
2269 2270
            }

2271 2272 2273 2274
            rv = qemuMonitorSetLink(priv->mon,
                                    def->nets[i]->info.alias,
                                    VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN);
            if (rv < 0) {
2275
                virReportError(VIR_ERR_OPERATION_FAILED,
2276 2277 2278
                               _("Couldn't set link state on interface: %s"),
                               def->nets[i]->info.alias);
                goto cleanup;
2279 2280 2281 2282
            }
        }
    }

2283 2284 2285 2286 2287
    ret = 0;

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

2291

2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 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
/**
 * 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;
}


2400
static int
2401
qemuProcessSetupEmulator(virDomainObjPtr vm)
2402
{
2403 2404 2405 2406 2407
    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);
2408 2409
}

2410

2411 2412
static int
qemuProcessInitPasswords(virConnectPtr conn,
2413
                         virQEMUDriverPtr driver,
2414 2415
                         virDomainObjPtr vm,
                         int asyncJob)
2416 2417 2418
{
    int ret = 0;
    qemuDomainObjPrivatePtr priv = vm->privateData;
2419
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2420
    size_t i;
2421 2422
    char *alias = NULL;
    char *secret = NULL;
2423

2424
    for (i = 0; i < vm->def->ngraphics; ++i) {
2425 2426
        virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
2427 2428
            ret = qemuDomainChangeGraphicsPasswords(driver, vm,
                                                    VIR_DOMAIN_GRAPHICS_TYPE_VNC,
2429
                                                    &graphics->data.vnc.auth,
2430 2431
                                                    cfg->vncPassword,
                                                    asyncJob);
2432
        } else if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
2433 2434
            ret = qemuDomainChangeGraphicsPasswords(driver, vm,
                                                    VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
2435
                                                    &graphics->data.spice.auth,
2436 2437
                                                    cfg->spicePassword,
                                                    asyncJob);
2438 2439
        }

2440 2441 2442
        if (ret < 0)
            goto cleanup;
    }
2443

2444 2445
    for (i = 0; i < vm->def->ndisks; i++) {
        size_t secretLen;
2446

2447 2448 2449
        if (!vm->def->disks[i]->src->encryption ||
            !virDomainDiskGetSource(vm->def->disks[i]))
            continue;
2450

2451 2452 2453 2454 2455 2456
        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;

2457 2458 2459 2460 2461
        VIR_FREE(secret);
        if (qemuProcessGetVolumeQcowPassphrase(conn,
                                               vm->def->disks[i],
                                               &secret, &secretLen) < 0)
            goto cleanup;
2462

2463
        VIR_FREE(alias);
2464
        if (!(alias = qemuAliasFromDisk(vm->def->disks[i])))
2465 2466 2467 2468 2469 2470 2471 2472
            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;
2473 2474
    }

2475
 cleanup:
2476 2477
    VIR_FREE(alias);
    VIR_FREE(secret);
2478
    virObjectUnref(cfg);
2479 2480 2481 2482 2483 2484 2485 2486 2487 2488
    return ret;
}


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

2492
    if ((fd = open(dev->source->data.file.path,
2493 2494 2495
                   O_CREAT | O_APPEND, S_IRUSR|S_IWUSR)) < 0) {
        virReportSystemError(errno,
                             _("Unable to pre-create chardev file '%s'"),
2496
                             dev->source->data.file.path);
2497 2498 2499 2500 2501 2502 2503 2504 2505
        return -1;
    }

    VIR_FORCE_CLOSE(fd);

    return 0;
}


2506 2507 2508 2509 2510
static int
qemuProcessCleanupChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
                                virDomainChrDefPtr dev,
                                void *opaque ATTRIBUTE_UNUSED)
{
2511 2512 2513 2514
    if (dev->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
        dev->source->data.nix.listen &&
        dev->source->data.nix.path)
        unlink(dev->source->data.nix.path);
2515 2516 2517 2518 2519

    return 0;
}


2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555
/**
 * 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) {
2556
                if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VGAMEM) &&
2557 2558
                    qemuMonitorUpdateVideoMemorySize(priv->mon, video,
                                                     "qxl-vga") < 0)
2559
                        goto error;
2560

2561
                if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QXL_VRAM64) &&
2562 2563 2564
                    qemuMonitorUpdateVideoVram64Size(priv->mon, video,
                                                     "qxl-vga") < 0)
                    goto error;
2565
            } else {
2566 2567 2568 2569 2570 2571 2572 2573
                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)
2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592
                        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;
        }

    }

2593 2594
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        return -1;
2595 2596

    cfg = virQEMUDriverGetConfig(driver);
2597
    ret = virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps);
2598 2599 2600 2601 2602
    virObjectUnref(cfg);

    return ret;

 error:
2603
    ignore_value(qemuDomainObjExitMonitor(driver, vm));
2604 2605 2606 2607
    return -1;
}


2608 2609 2610
struct qemuProcessHookData {
    virConnectPtr conn;
    virDomainObjPtr vm;
2611
    virQEMUDriverPtr driver;
2612
    virQEMUDriverConfigPtr cfg;
2613 2614 2615 2616 2617
};

static int qemuProcessHook(void *data)
{
    struct qemuProcessHookData *h = data;
2618
    qemuDomainObjPrivatePtr priv = h->vm->privateData;
2619
    int ret = -1;
2620
    int fd;
2621 2622 2623
    virBitmapPtr nodeset = NULL;
    virDomainNumatuneMemMode mode;

2624 2625 2626 2627
    /* This method cannot use any mutexes, which are not
     * protected across fork()
     */

2628
    qemuSecurityPostFork(h->driver->securityManager);
2629 2630 2631 2632 2633

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

    VIR_DEBUG("Obtaining domain lock");
2634 2635 2636 2637 2638 2639 2640
    /*
     * 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.
     */
2641
    if (qemuSecuritySetSocketLabel(h->driver->securityManager, h->vm->def) < 0)
2642
        goto cleanup;
2643
    if (virDomainLockProcessStart(h->driver->lockManager,
2644
                                  h->cfg->uri,
2645
                                  h->vm,
J
Ján Tomko 已提交
2646
                                  /* QEMU is always paused initially */
2647 2648
                                  true,
                                  &fd) < 0)
2649
        goto cleanup;
2650
    if (qemuSecurityClearSocketLabel(h->driver->securityManager, h->vm->def) < 0)
2651
        goto cleanup;
2652

2653
    if (qemuDomainBuildNamespace(h->cfg, h->driver->securityManager, h->vm) < 0)
2654 2655
        goto cleanup;

2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666
    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);
2667

2668 2669 2670
            if (virNumaSetupMemoryPolicy(mode, nodeset) < 0)
                goto cleanup;
        }
2671
    }
2672

2673 2674
    ret = 0;

2675
 cleanup:
2676
    virObjectUnref(h->cfg);
2677 2678
    VIR_DEBUG("Hook complete ret=%d", ret);
    return ret;
2679 2680 2681
}

int
2682 2683
qemuProcessPrepareMonitorChr(virDomainChrSourceDefPtr monConfig,
                             const char *domainDir)
2684 2685 2686 2687
{
    monConfig->type = VIR_DOMAIN_CHR_TYPE_UNIX;
    monConfig->data.nix.listen = true;

2688 2689
    if (virAsprintf(&monConfig->data.nix.path, "%s/monitor.sock",
                    domainDir) < 0)
2690 2691
        return -1;
    return 0;
2692 2693 2694
}


2695
/*
2696 2697
 * Precondition: vm must be locked, and a job must be active.
 * This method will call {Enter,Exit}Monitor
2698
 */
E
Eric Blake 已提交
2699
int
2700
qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
2701
                     virConnectPtr conn, virDomainRunningReason reason,
2702
                     qemuDomainAsyncJob asyncJob)
2703
{
2704
    int ret = -1;
2705
    qemuDomainObjPrivatePtr priv = vm->privateData;
2706
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2707

2708
    /* Bring up netdevs before starting CPUs */
2709
    if (qemuInterfaceStartDevices(vm->def) < 0)
2710 2711
       goto cleanup;

2712
    VIR_DEBUG("Using lock state '%s'", NULLSTR(priv->lockState));
2713
    if (virDomainLockProcessResume(driver->lockManager, cfg->uri,
2714
                                   vm, priv->lockState) < 0) {
2715 2716 2717 2718
        /* 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
         */
2719
        goto cleanup;
2720 2721 2722
    }
    VIR_FREE(priv->lockState);

2723 2724
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto release;
J
Jiri Denemark 已提交
2725

2726
    ret = qemuMonitorStartCPUs(priv->mon, conn);
2727 2728
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;
2729 2730 2731 2732 2733

    if (ret < 0)
        goto release;

    virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
2734

2735
 cleanup:
2736
    virObjectUnref(cfg);
2737
    return ret;
2738 2739 2740 2741 2742 2743

 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;
2744 2745 2746
}


2747 2748
int qemuProcessStopCPUs(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
2749
                        virDomainPausedReason reason,
2750
                        qemuDomainAsyncJob asyncJob)
2751
{
2752
    int ret = -1;
2753 2754
    qemuDomainObjPrivatePtr priv = vm->privateData;

2755
    VIR_FREE(priv->lockState);
J
Jiri Denemark 已提交
2756

2757 2758
    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
        goto cleanup;
J
Jiri Denemark 已提交
2759

2760
    ret = qemuMonitorStopCPUs(priv->mon);
2761 2762
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        ret = -1;
2763 2764 2765 2766

    if (ret < 0)
        goto cleanup;

2767 2768 2769
    /* de-activate netdevs after stopping CPUs */
    ignore_value(qemuInterfaceStopDevices(vm->def));

2770 2771 2772
    if (priv->job.current)
        ignore_value(virTimeMillisNow(&priv->job.current->stopped));

2773 2774 2775 2776
    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 已提交
2777

2778
 cleanup:
2779 2780 2781 2782 2783
    return ret;
}



2784 2785 2786
static int
qemuProcessNotifyNets(virDomainDefPtr def)
{
2787
    size_t i;
2788

2789 2790
    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
2791 2792 2793 2794 2795 2796 2797 2798
        /* 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));

2799
        if (networkNotifyActualDevice(def, net) < 0)
2800 2801 2802 2803 2804
            return -1;
    }
    return 0;
}

2805
static int
2806
qemuProcessFiltersInstantiate(virDomainDefPtr def)
2807
{
2808
    size_t i;
2809

2810
    for (i = 0; i < def->nnets; i++) {
2811 2812
        virDomainNetDefPtr net = def->nets[i];
        if ((net->filter) && (net->ifname)) {
2813
            if (virDomainConfNWFilterInstantiate(def->uuid, net) < 0)
J
Ján Tomko 已提交
2814
                return 1;
2815 2816 2817
        }
    }

J
Ján Tomko 已提交
2818
    return 0;
2819 2820
}

2821
static int
2822
qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm)
2823 2824 2825
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virDomainState state;
2826
    virDomainPausedReason reason;
2827
    virDomainState newState = VIR_DOMAIN_NOSTATE;
2828
    int oldReason;
2829
    int newReason;
2830
    bool running;
2831
    char *msg = NULL;
2832 2833
    int ret;

2834
    qemuDomainObjEnterMonitor(driver, vm);
2835
    ret = qemuMonitorGetStatus(priv->mon, &running, &reason);
2836 2837
    if (qemuDomainObjExitMonitor(driver, vm) < 0)
        return -1;
2838

2839
    if (ret < 0)
2840 2841
        return -1;

2842
    state = virDomainObjGetState(vm, &oldReason);
2843

2844 2845 2846 2847 2848 2849 2850 2851
    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) {
2852 2853
        newState = VIR_DOMAIN_RUNNING;
        newReason = VIR_DOMAIN_RUNNING_UNPAUSED;
2854
        ignore_value(VIR_STRDUP_QUIET(msg, "was unpaused"));
2855
    } else if (state == VIR_DOMAIN_RUNNING && !running) {
2856 2857 2858
        if (reason == VIR_DOMAIN_PAUSED_SHUTTING_DOWN) {
            newState = VIR_DOMAIN_SHUTDOWN;
            newReason = VIR_DOMAIN_SHUTDOWN_UNKNOWN;
2859
            ignore_value(VIR_STRDUP_QUIET(msg, "shutdown"));
2860
        } else if (reason == VIR_DOMAIN_PAUSED_CRASHED) {
2861 2862 2863
            newState = VIR_DOMAIN_CRASHED;
            newReason = VIR_DOMAIN_CRASHED_PANICKED;
            ignore_value(VIR_STRDUP_QUIET(msg, "crashed"));
2864 2865 2866
        } else {
            newState = VIR_DOMAIN_PAUSED;
            newReason = reason;
S
Stefan Berger 已提交
2867 2868
            ignore_value(virAsprintf(&msg, "was paused (%s)",
                                 virDomainPausedReasonTypeToString(reason)));
2869 2870 2871 2872 2873 2874 2875
        }
    }

    if (newState != VIR_DOMAIN_NOSTATE) {
        VIR_DEBUG("Domain %s %s while its monitor was disconnected;"
                  " changing state to %s (%s)",
                  vm->def->name,
2876
                  NULLSTR(msg),
2877 2878 2879 2880
                  virDomainStateTypeToString(newState),
                  virDomainStateReasonToString(newState, newReason));
        VIR_FREE(msg);
        virDomainObjSetState(vm, newState, newReason);
2881 2882 2883 2884 2885
    }

    return 0;
}

2886
static int
2887 2888 2889 2890 2891
qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              virConnectPtr conn,
                              qemuMigrationJobPhase phase,
                              virDomainState state,
2892
                              int reason)
2893
{
2894 2895 2896 2897 2898
    bool postcopy = (state == VIR_DOMAIN_PAUSED &&
                     reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED) ||
                    (state == VIR_DOMAIN_RUNNING &&
                     reason == VIR_DOMAIN_RUNNING_POSTCOPY);

2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914
    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;
2915

2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930
    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
2931
         * we already started guest CPUs or we were in post-copy mode */
2932 2933 2934
        ignore_value(qemuMigrationResetTLS(driver, vm,
                                           QEMU_ASYNC_JOB_MIGRATION_IN,
                                           NULL, NULL));
2935 2936 2937
        if (postcopy) {
            qemuMigrationPostcopyFailed(driver, vm);
        } else if (state != VIR_DOMAIN_RUNNING) {
2938
            VIR_DEBUG("Killing migrated domain %s", vm->def->name);
2939
            return -1;
2940 2941 2942
        }
        break;
    }
2943

2944 2945
    return 0;
}
2946

2947 2948 2949 2950 2951 2952
static int
qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
                               virConnectPtr conn,
                               qemuMigrationJobPhase phase,
                               virDomainState state,
2953 2954
                               int reason,
                               unsigned int *stopFlags)
2955
{
2956 2957 2958 2959
    bool postcopy = state == VIR_DOMAIN_PAUSED &&
                    (reason == VIR_DOMAIN_PAUSED_POSTCOPY ||
                     reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED);

2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976
    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
2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989
         * 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;
2990
        }
2991
        break;
2992

2993 2994
    case QEMU_MIGRATION_PHASE_PERFORM3_DONE:
        /* migration finished but we didn't have a chance to get the result
2995 2996
         * 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
2997
         */
2998 2999
        if (postcopy)
            qemuMigrationPostcopyFailed(driver, vm);
3000
        break;
3001

3002
    case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED:
3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014
        /* 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;
3015

3016 3017
    case QEMU_MIGRATION_PHASE_CONFIRM3:
        /* migration completed, we need to kill the domain here */
3018
        *stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
3019 3020
        return -1;
    }
3021

3022
    return 0;
3023

3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034
 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);
3035 3036 3037 3038 3039
        }
    }
    return 0;
}

3040
static int
3041
qemuProcessRecoverJob(virQEMUDriverPtr driver,
3042 3043
                      virDomainObjPtr vm,
                      virConnectPtr conn,
3044 3045
                      const struct qemuDomainJobObj *job,
                      unsigned int *stopFlags)
3046
{
3047
    qemuDomainObjPrivatePtr priv = vm->privateData;
3048 3049 3050 3051 3052 3053 3054
    virDomainState state;
    int reason;

    state = virDomainObjGetState(vm, &reason);

    switch (job->asyncJob) {
    case QEMU_ASYNC_JOB_MIGRATION_OUT:
3055
        if (qemuProcessRecoverMigrationOut(driver, vm, conn, job->phase,
3056
                                           state, reason, stopFlags) < 0)
3057 3058 3059
            return -1;
        break;

3060
    case QEMU_ASYNC_JOB_MIGRATION_IN:
3061 3062
        if (qemuProcessRecoverMigrationIn(driver, vm, conn, job->phase,
                                          state, reason) < 0)
3063
            return -1;
3064 3065 3066 3067
        break;

    case QEMU_ASYNC_JOB_SAVE:
    case QEMU_ASYNC_JOB_DUMP:
3068
    case QEMU_ASYNC_JOB_SNAPSHOT:
3069
        qemuDomainObjEnterMonitor(driver, vm);
3070
        ignore_value(qemuMonitorMigrateCancel(priv->mon));
3071 3072
        if (qemuDomainObjExitMonitor(driver, vm) < 0)
            return -1;
3073
        /* resume the domain but only if it was paused as a result of
3074 3075 3076 3077 3078 3079 3080 3081 3082
         * 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 &&
3083 3084
               (reason == VIR_DOMAIN_PAUSED_SNAPSHOT ||
                reason == VIR_DOMAIN_PAUSED_MIGRATION)) ||
3085 3086 3087 3088 3089 3090
              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);
3091 3092 3093 3094
            }
        }
        break;

3095 3096 3097 3098
    case QEMU_ASYNC_JOB_START:
        /* Already handled in VIR_DOMAIN_PAUSED_STARTING_UP check. */
        break;

3099 3100 3101 3102 3103 3104 3105 3106
    case QEMU_ASYNC_JOB_NONE:
    case QEMU_ASYNC_JOB_LAST:
        break;
    }

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

3107 3108 3109 3110
    /* 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.
     */
3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130
    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;

3131
    case QEMU_JOB_MIGRATION_OP:
3132
    case QEMU_JOB_ABORT:
3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143
    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;
}

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

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

    old = priv->qemuDevices;
    priv->qemuDevices = NULL;
3160
    if (qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
3161 3162
        goto cleanup;

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

3176
 cleanup:
3177
    virStringListFree(old);
3178 3179 3180
    return ret;
}

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

3188
    if (!(priv->perf = virPerfNew()))
3189 3190 3191
        return -1;

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

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

    return 0;
}

3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226

static void
qemuProcessReconnectCheckMemAliasOrderMismatch(virDomainObjPtr vm)
{
    size_t i;
    int aliasidx;
    virDomainDefPtr def = vm->def;
    qemuDomainObjPrivatePtr priv = vm->privateData;

    if (!virDomainDefHasMemoryHotplug(def) || def->nmems == 0)
        return;

    for (i = 0; i < def->nmems; i++) {
        aliasidx = qemuDomainDeviceAliasIndex(&def->mems[i]->info, "dimm");

        if (def->mems[i]->info.addr.dimm.slot != aliasidx) {
            priv->memAliasOrderMismatch = true;
            break;
        }
    }
}


3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252
static int
qemuProcessBuildDestroyHugepagesPath(virQEMUDriverPtr driver,
                                     virDomainObjPtr vm,
                                     bool build)
{
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
    char *hugepagePath = NULL;
    size_t i;
    int ret = -1;

    if (vm->def->mem.nhugepages) {
        for (i = 0; i < cfg->nhugetlbfs; i++) {
            VIR_FREE(hugepagePath);
            hugepagePath = qemuGetDomainHugepagePath(vm->def, &cfg->hugetlbfs[i]);

            if (!hugepagePath)
                goto cleanup;

            if (build) {
                if (virFileMakePathWithMode(hugepagePath, 0700) < 0) {
                    virReportSystemError(errno,
                                         _("Unable to create %s"),
                                         hugepagePath);
                    goto cleanup;
                }

3253 3254
                if (qemuSecurityDomainSetPathLabel(driver->securityManager,
                                                   vm->def, hugepagePath) < 0) {
3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   "%s", _("Unable to set huge path in security driver"));
                    goto cleanup;
                }
            } else {
                if (rmdir(hugepagePath) < 0)
                    VIR_WARN("Unable to remove hugepage path: %s (errno=%d)",
                             hugepagePath, errno);
            }
        }
    }

    ret = 0;
 cleanup:
    VIR_FREE(hugepagePath);
    virObjectUnref(cfg);
    return ret;
}


3275 3276
struct qemuProcessReconnectData {
    virConnectPtr conn;
3277
    virQEMUDriverPtr driver;
3278
    virDomainObjPtr obj;
3279 3280 3281 3282
};
/*
 * Open an existing VM's monitor, re-detect VCPU threads
 * and re-reserve the security labels in use
S
Stefan Berger 已提交
3283 3284 3285 3286
 *
 * 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.
3287
 *
3288
 * This function also inherits a locked and ref'd domain object.
3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300
 *
 * 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.
3301 3302
 */
static void
3303
qemuProcessReconnect(void *opaque)
3304 3305
{
    struct qemuProcessReconnectData *data = opaque;
3306
    virQEMUDriverPtr driver = data->driver;
3307
    virDomainObjPtr obj = data->obj;
3308 3309
    qemuDomainObjPrivatePtr priv;
    virConnectPtr conn = data->conn;
3310
    struct qemuDomainJobObj oldjob;
3311 3312
    int state;
    int reason;
3313
    virQEMUDriverConfigPtr cfg;
3314
    size_t i;
3315
    unsigned int stopFlags = 0;
3316
    bool jobStarted = false;
3317
    virCapsPtr caps = NULL;
3318

3319 3320
    VIR_FREE(data);

3321
    qemuDomainObjRestoreJob(obj, &oldjob);
3322 3323
    if (oldjob.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
3324

3325 3326 3327
    cfg = virQEMUDriverGetConfig(driver);
    priv = obj->privateData;

3328 3329 3330
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto error;

3331 3332 3333 3334
    if (qemuDomainObjBeginJob(driver, obj, QEMU_JOB_MODIFY) < 0)
        goto error;
    jobStarted = true;

3335 3336 3337
    /* 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)))
3338
        goto error;
3339

J
John Ferlan 已提交
3340 3341 3342 3343
    /* Restore the masterKey */
    if (qemuDomainMasterKeyReadFile(priv) < 0)
        goto error;

3344
    virNWFilterReadLockFilterUpdates();
3345 3346 3347 3348

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

    /* XXX check PID liveliness & EXE path */
3349
    if (qemuConnectMonitor(driver, obj, QEMU_ASYNC_JOB_NONE, NULL) < 0)
3350 3351
        goto error;

3352
    if (qemuHostdevUpdateActiveDomainDevices(driver, obj->def) < 0)
3353 3354
        goto error;

3355
    if (qemuConnectCgroup(driver, obj) < 0)
3356 3357
        goto error;

3358 3359 3360
    if (qemuDomainPerfRestart(obj) < 0)
        goto error;

3361
    /* XXX: Need to change as long as lock is introduced for
3362
     * qemu_driver->sharedDevices.
3363 3364
     */
    for (i = 0; i < obj->def->ndisks; i++) {
3365 3366
        virDomainDeviceDef dev;

3367
        if (virStorageTranslateDiskSourcePool(conn, obj->def->disks[i]) < 0)
3368
            goto error;
3369

3370 3371 3372 3373 3374 3375
        /* 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)
3376 3377
            goto error;

3378 3379 3380
        dev.type = VIR_DOMAIN_DEVICE_DISK;
        dev.data.disk = obj->def->disks[i];
        if (qemuAddSharedDevice(driver, &dev, obj->def->name) < 0)
3381 3382 3383
            goto error;
    }

3384 3385 3386
    if (qemuProcessUpdateState(driver, obj) < 0)
        goto error;

3387
    state = virDomainObjGetState(obj, &reason);
3388 3389 3390
    if (state == VIR_DOMAIN_SHUTOFF ||
        (state == VIR_DOMAIN_PAUSED &&
         reason == VIR_DOMAIN_PAUSED_STARTING_UP)) {
3391 3392 3393 3394 3395
        VIR_DEBUG("Domain '%s' wasn't fully started yet, killing it",
                  obj->def->name);
        goto error;
    }

3396 3397 3398
    /* If upgrading from old libvirtd we won't have found any
     * caps in the domain status, so re-query them
     */
3399
    if (!priv->qemuCaps &&
3400 3401
        !(priv->qemuCaps = virQEMUCapsCacheLookupCopy(caps,
                                                      driver->qemuCapsCache,
3402 3403
                                                      obj->def->emulator,
                                                      obj->def->os.machine)))
3404 3405
        goto error;

3406
    /* In case the domain shutdown while we were not running,
3407
     * we need to finish the shutdown process. And we need to do it after
3408
     * we have virQEMUCaps filled in.
3409
     */
3410 3411 3412 3413 3414 3415
    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);
3416
        goto cleanup;
3417 3418
    }

3419 3420 3421
    if (qemuProcessBuildDestroyHugepagesPath(driver, obj, true) < 0)
        goto error;

3422 3423
    if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps,
                                   driver, obj, false)) < 0) {
3424
        goto error;
3425
    }
3426

3427 3428 3429
    /* if domain requests security driver we haven't loaded, report error, but
     * do not kill the domain
     */
3430 3431
    ignore_value(qemuSecurityCheckAllLabel(driver->securityManager,
                                           obj->def));
3432

3433 3434 3435
    if (qemuDomainRefreshVcpuInfo(driver, obj, QEMU_ASYNC_JOB_NONE, true) < 0)
        goto error;

3436
    if (qemuSecurityReserveLabel(driver->securityManager, obj->def, obj->pid) < 0)
3437 3438
        goto error;

3439 3440 3441
    if (qemuProcessNotifyNets(obj->def) < 0)
        goto error;

3442
    if (qemuProcessFiltersInstantiate(obj->def))
3443 3444
        goto error;

3445
    if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
3446 3447
        goto error;

3448
    if (qemuRefreshVirtioChannelState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
3449 3450
        goto error;

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

3454 3455 3456
    if (qemuProcessRefreshBalloonState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
        goto error;

3457
    if (qemuProcessRecoverJob(driver, obj, conn, &oldjob, &stopFlags) < 0)
3458 3459
        goto error;

3460 3461 3462
    if (qemuProcessUpdateDevices(driver, obj) < 0)
        goto error;

3463 3464
    qemuProcessReconnectCheckMemAliasOrderMismatch(obj);

3465 3466
    if (qemuConnectAgent(driver, obj) < 0)
        goto error;
3467

3468
    /* update domain state XML with possibly updated state in virDomainObj */
3469
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->caps) < 0)
3470 3471
        goto error;

3472 3473
    /* Run an hook to allow admins to do some magic */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
3474
        char *xml = qemuDomainDefFormatXML(driver, obj->def, 0);
3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488
        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;
    }

3489
    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
3490 3491
        driver->inhibitCallback(true, driver->inhibitOpaque);

3492 3493 3494 3495 3496 3497 3498 3499
 cleanup:
    if (jobStarted)
        qemuDomainObjEndJob(driver, obj);
    if (!virDomainObjIsActive(obj))
        qemuDomainRemoveInactive(driver, obj);
    virDomainObjEndAPI(&obj);
    virObjectUnref(conn);
    virObjectUnref(cfg);
3500
    virObjectUnref(caps);
3501 3502
    virNWFilterUnlockFilterUpdates();
    return;
3503

3504
 error:
3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518
    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;
3519
        }
3520 3521 3522 3523 3524
        /* 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);
3525
    }
3526
    goto cleanup;
3527 3528
}

3529 3530
static int
qemuProcessReconnectHelper(virDomainObjPtr obj,
3531 3532 3533 3534 3535 3536
                           void *opaque)
{
    virThread thread;
    struct qemuProcessReconnectData *src = opaque;
    struct qemuProcessReconnectData *data;

3537
    /* If the VM was inactive, we don't need to reconnect */
3538 3539 3540
    if (!obj->pid)
        return 0;

3541
    if (VIR_ALLOC(data) < 0)
3542
        return -1;
3543 3544

    memcpy(data, src, sizeof(*data));
3545
    data->obj = obj;
3546

3547 3548
    /* this lock and reference will be eventually transferred to the thread
     * that handles the reconnect */
3549
    virObjectLock(obj);
3550
    virObjectRef(obj);
3551

3552 3553 3554
    /* 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 已提交
3555
     */
3556
    virObjectRef(data->conn);
S
Stefan Berger 已提交
3557

3558
    if (virThreadCreate(&thread, false, qemuProcessReconnect, data) < 0) {
3559 3560 3561
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Could not create thread. QEMU initialization "
                         "might be incomplete"));
3562 3563 3564 3565 3566 3567 3568
        /* 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);
3569
        qemuDomainRemoveInactive(src->driver, obj);
3570

M
Michal Privoznik 已提交
3571
        virDomainObjEndAPI(&obj);
3572 3573 3574 3575
        virObjectUnref(data->conn);
        VIR_FREE(data);
        return -1;
    }
3576

3577
    return 0;
3578 3579 3580 3581 3582 3583 3584 3585 3586
}

/**
 * qemuProcessReconnectAll
 *
 * Try to re-open the resources for live VMs that we care
 * about.
 */
void
3587
qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver)
3588
{
3589
    struct qemuProcessReconnectData data = {.conn = conn, .driver = driver};
3590
    virDomainObjListForEach(driver->domains, qemuProcessReconnectHelper, &data);
3591 3592
}

3593
static int
3594
qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver,
3595 3596
                            virDomainGraphicsDefPtr graphics,
                            bool allocate)
3597 3598 3599
{
    unsigned short port;

3600 3601 3602 3603 3604 3605 3606
    if (!allocate) {
        if (graphics->data.vnc.autoport)
            graphics->data.vnc.port = 5900;

        return 0;
    }

3607 3608 3609 3610 3611 3612 3613 3614 3615 3616
    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;
3617
        graphics->data.vnc.websocketGenerated = true;
3618 3619 3620 3621
    }

    return 0;
}
3622

3623
static int
3624
qemuProcessSPICEAllocatePorts(virQEMUDriverPtr driver,
3625 3626
                              virDomainGraphicsDefPtr graphics,
                              bool allocate)
3627
{
3628
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
3629 3630
    unsigned short port = 0;
    unsigned short tlsPort;
3631
    size_t i;
3632
    int defaultMode = graphics->data.spice.defaultMode;
3633
    int ret = -1;
3634 3635 3636 3637 3638 3639

    bool needTLSPort = false;
    bool needPort = false;

    if (graphics->data.spice.autoport) {
        /* check if tlsPort or port need allocation */
3640
        for (i = 0; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST; i++) {
3641 3642 3643 3644 3645 3646 3647 3648 3649 3650
            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:
3651
                /* default mode will be used */
3652 3653 3654
                break;
            }
        }
3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669
        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;
        }
3670 3671
    }

3672 3673 3674 3675 3676 3677 3678
    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;

3679 3680
        ret = 0;
        goto cleanup;
3681 3682
    }

3683
    if (needPort || graphics->data.spice.port == -1) {
3684
        if (virPortAllocatorAcquire(driver->remotePorts, &port) < 0)
3685
            goto cleanup;
3686 3687

        graphics->data.spice.port = port;
3688 3689 3690

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

3693 3694
    if (needTLSPort || graphics->data.spice.tlsPort == -1) {
        if (!cfg->spiceTLS) {
3695 3696 3697
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Auto allocation of spice TLS port requested "
                             "but spice TLS is disabled in qemu.conf"));
3698
            goto cleanup;
3699
        }
3700 3701

        if (virPortAllocatorAcquire(driver->remotePorts, &tlsPort) < 0)
3702
            goto cleanup;
3703 3704

        graphics->data.spice.tlsPort = tlsPort;
3705 3706 3707

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

3710
    ret = 0;
3711

3712 3713 3714
 cleanup:
    virObjectUnref(cfg);
    return ret;
3715 3716 3717
}


3718 3719 3720
static int
qemuValidateCpuCount(virDomainDefPtr def,
                     virQEMUCapsPtr qemuCaps)
3721
{
3722
    unsigned int maxCpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, def->os.machine);
3723

3724 3725 3726 3727 3728 3729
    if (virDomainDefGetVcpus(def) == 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Domain requires at least 1 vCPU"));
        return -1;
    }

3730 3731 3732 3733
    if (maxCpus > 0 && virDomainDefGetVcpusMax(def) > maxCpus) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Maximum CPUs greater than specified machine type limit"));
        return -1;
3734 3735
    }

3736
    return 0;
3737 3738
}

3739

3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792
static int
qemuProcessVerifyHypervFeatures(virDomainDefPtr def,
                                virCPUDataPtr cpu)
{
    char *cpuFeature;
    size_t i;
    int rc;

    for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
        if (def->hyperv_features[i] != VIR_TRISTATE_SWITCH_ON)
            continue;

        if (virAsprintf(&cpuFeature, "__kvm_hv_%s",
                        virDomainHypervTypeToString(i)) < 0)
            return -1;

        rc = virCPUDataCheckFeature(cpu, cpuFeature);
        VIR_FREE(cpuFeature);

        if (rc < 0)
            return -1;
        else if (rc == 1)
            continue;

        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));
            return -1;

        /* coverity[dead_error_begin] */
        case VIR_DOMAIN_HYPERV_LAST:
            break;
        }
    }

    return 0;
}


3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814
static int
qemuProcessVerifyKVMFeatures(virDomainDefPtr def,
                             virCPUDataPtr cpu)
{
    int rc = 0;

    if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] != VIR_TRISTATE_SWITCH_ON)
        return 0;

    rc = virCPUDataCheckFeature(cpu, VIR_CPU_x86_KVM_PV_UNHALT);

    if (rc <= 0) {
        if (rc == 0)
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("host doesn't support paravirtual spinlocks"));
        return -1;
    }

    return 0;
}


3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839
static int
qemuProcessVerifyCPUFeatures(virDomainDefPtr def,
                             virCPUDataPtr cpu)
{
    int rc;

    rc = virCPUCheckFeature(def->os.arch, def->cpu, "invtsc");

    if (rc < 0) {
        return -1;
    } else if (rc == 1) {
        rc = virCPUDataCheckFeature(cpu, "invtsc");
        if (rc <= 0) {
            if (rc == 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("host doesn't support invariant TSC"));
            }
            return -1;
        }
    }

    return 0;
}


3840
static int
3841 3842 3843
qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              qemuDomainAsyncJob asyncJob)
3844 3845
{
    virDomainDefPtr def = vm->def;
3846
    virCPUDataPtr cpu = NULL;
3847
    virCPUDataPtr disabled = NULL;
3848
    qemuDomainObjPrivatePtr priv = vm->privateData;
3849
    int rc;
3850
    int ret = -1;
3851

3852
    if (ARCH_IS_X86(def->os.arch)) {
3853
        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
3854 3855
            goto cleanup;

3856
        rc = qemuMonitorGetGuestCPU(priv->mon, def->os.arch, &cpu, &disabled);
3857

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

3861 3862
        if (rc < 0) {
            if (rc == -2)
3863
                ret = 0;
3864
            goto cleanup;
3865
        }
3866

3867 3868
        if (qemuProcessVerifyKVMFeatures(def, cpu) < 0 ||
            qemuProcessVerifyHypervFeatures(def, cpu) < 0)
3869
            goto cleanup;
J
Ján Tomko 已提交
3870

3871 3872 3873 3874 3875 3876 3877
        if (!def->cpu ||
            (def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
             !def->cpu->model)) {
            ret = 0;
            goto cleanup;
        }

3878
        if (qemuProcessVerifyCPUFeatures(def, cpu) < 0)
3879
            goto cleanup;
3880 3881 3882 3883 3884

        if ((rc = virCPUUpdateLive(def->os.arch, def->cpu, cpu, disabled)) < 0)
            goto cleanup;
        else if (rc == 0)
            def->cpu->check = VIR_CPU_CHECK_FULL;
3885 3886
    }

3887
    ret = 0;
3888

3889
 cleanup:
3890
    virCPUDataFree(cpu);
3891
    virCPUDataFree(disabled);
3892 3893 3894 3895
    return ret;
}


3896 3897
static int
qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
3898
                 virDomainObjPtr vm)
3899 3900 3901 3902
{
    int ret = -1;
    int srcFD = -1;
    int dstFD = -1;
3903
    virDomainLoaderDefPtr loader = vm->def->os.loader;
3904
    bool created = false;
3905 3906
    const char *master_nvram_path;
    ssize_t r;
3907

3908
    if (!loader || !loader->nvram || virFileExists(loader->nvram))
3909 3910
        return 0;

3911 3912 3913
    master_nvram_path = loader->templt;
    if (!loader->templt) {
        size_t i;
3914 3915 3916
        for (i = 0; i < cfg->nfirmwares; i++) {
            if (STREQ(cfg->firmwares[i]->name, loader->path)) {
                master_nvram_path = cfg->firmwares[i]->nvram;
3917
                break;
3918 3919
            }
        }
3920
    }
3921

3922 3923 3924 3925 3926 3927
    if (!master_nvram_path) {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("unable to find any master var store for "
                         "loader: %s"), loader->path);
        goto cleanup;
    }
3928

3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945
    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;
3946

3947 3948
    do {
        char buf[1024];
3949

3950
        if ((r = saferead(srcFD, buf, sizeof(buf))) < 0) {
3951
            virReportSystemError(errno,
3952
                                 _("Unable to read from file '%s'"),
3953 3954 3955
                                 master_nvram_path);
            goto cleanup;
        }
3956 3957

        if (safewrite(dstFD, buf, r) < 0) {
3958
            virReportSystemError(errno,
3959
                                 _("Unable to write to file '%s'"),
3960 3961 3962
                                 loader->nvram);
            goto cleanup;
        }
3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975
    } 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;
3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992
    }

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


3993 3994 3995
static void
qemuLogOperation(virDomainObjPtr vm,
                 const char *msg,
3996 3997
                 virCommandPtr cmd,
                 qemuDomainLogContextPtr logCtxt)
3998 3999 4000 4001 4002
{
    char *timestamp;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    int qemuVersion = virQEMUCapsGetVersion(priv->qemuCaps);
    const char *package = virQEMUCapsGetPackage(priv->qemuCaps);
4003
    char *hostname = virGetHostname();
4004 4005

    if ((timestamp = virTimeStringNow()) == NULL)
4006
        goto cleanup;
4007

4008 4009
    if (qemuDomainLogContextWrite(logCtxt,
                                  "%s: %s %s, qemu version: %d.%d.%d%s, hostname: %s\n",
4010 4011 4012 4013
                                  timestamp, msg, VIR_LOG_VERSION_STRING,
                                  (qemuVersion / 1000000) % 1000,
                                  (qemuVersion / 1000) % 1000,
                                  qemuVersion % 1000,
4014 4015
                                  package ? package : "",
                                  hostname ? hostname : "") < 0)
4016
        goto cleanup;
4017

4018 4019 4020 4021 4022
    if (cmd) {
        char *args = virCommandToString(cmd);
        qemuDomainLogContextWrite(logCtxt, "%s\n", args);
        VIR_FREE(args);
    }
4023 4024

 cleanup:
4025
    VIR_FREE(hostname);
4026 4027 4028
    VIR_FREE(timestamp);
}

4029 4030 4031 4032 4033 4034 4035

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

4036
    VIR_FREE(inc->address);
4037
    VIR_FREE(inc->launchURI);
4038
    VIR_FREE(inc->deferredURI);
4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049
    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,
4050
                          const char *listenAddress,
4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062
                          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;

4063 4064 4065
    if (VIR_STRDUP(inc->address, listenAddress) < 0)
        goto error;

4066 4067 4068 4069
    inc->launchURI = qemuMigrationIncomingURI(migrateFrom, fd);
    if (!inc->launchURI)
        goto error;

4070 4071 4072 4073 4074 4075
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_INCOMING_DEFER)) {
        inc->deferredURI = inc->launchURI;
        if (VIR_STRDUP(inc->launchURI, "defer") < 0)
            goto error;
    }

4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086
    inc->fd = fd;
    inc->path = path;

    return inc;

 error:
    qemuProcessIncomingDefFree(inc);
    return NULL;
}


4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116
/*
 * 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);
}


4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139
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;
}


4140
static int
4141
qemuProcessGraphicsReservePorts(virQEMUDriverPtr driver,
4142
                                virDomainGraphicsDefPtr graphics)
4143
{
4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154
    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;

4155 4156 4157 4158 4159 4160 4161 4162 4163
    switch (graphics->type) {
    case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
        if (!graphics->data.vnc.autoport) {
            if (virPortAllocatorSetUsed(driver->remotePorts,
                                        graphics->data.vnc.port,
                                        true) < 0)
                return -1;
            graphics->data.vnc.portReserved = true;
        }
4164 4165 4166 4167 4168
        if (graphics->data.vnc.websocket > 0 &&
            virPortAllocatorSetUsed(driver->remotePorts,
                                    graphics->data.vnc.websocket,
                                    true) < 0)
            return -1;
4169 4170 4171 4172 4173
        break;

    case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
        if (graphics->data.spice.autoport)
            return 0;
4174

4175
        if (graphics->data.spice.port > 0) {
4176
            if (virPortAllocatorSetUsed(driver->remotePorts,
4177
                                        graphics->data.spice.port,
4178
                                        true) < 0)
4179
                return -1;
4180 4181
            graphics->data.spice.portReserved = true;
        }
4182

4183 4184 4185 4186 4187 4188
        if (graphics->data.spice.tlsPort > 0) {
            if (virPortAllocatorSetUsed(driver->remotePorts,
                                        graphics->data.spice.tlsPort,
                                        true) < 0)
                return -1;
            graphics->data.spice.tlsPortReserved = true;
4189
        }
4190 4191 4192 4193 4194 4195 4196
        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;
4197 4198
    }

4199 4200 4201 4202
    return 0;
}


4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240
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;
}


4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267
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;
}


4268
static int
4269
qemuProcessGraphicsSetupListen(virQEMUDriverPtr driver,
4270 4271
                               virDomainGraphicsDefPtr graphics,
                               virDomainObjPtr vm)
4272
{
4273
    qemuDomainObjPrivatePtr priv = vm->privateData;
4274
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4275
    const char *type = virDomainGraphicsTypeToString(graphics->type);
4276
    char *listenAddr = NULL;
4277
    bool useSocket = false;
4278
    size_t i;
4279
    int ret = -1;
4280 4281 4282

    switch (graphics->type) {
    case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
4283
        useSocket = cfg->vncAutoUnixSocket;
4284 4285 4286 4287
        listenAddr = cfg->vncListen;
        break;

    case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
4288
        useSocket = cfg->spiceAutoUnixSocket;
4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303
        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:
4304 4305 4306 4307 4308
            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) {
4309 4310
                    memset(glisten, 0, sizeof(virDomainGraphicsListenDef));
                    if (virAsprintf(&glisten->socket, "%s/%s.sock",
4311
                                    priv->libDir, type) < 0)
4312
                        goto cleanup;
4313 4314
                    glisten->fromConfig = true;
                    glisten->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET;
4315 4316
                } else if (listenAddr) {
                    if (VIR_STRDUP(glisten->address, listenAddr) < 0)
4317
                        goto cleanup;
4318 4319 4320
                    glisten->fromConfig = true;
                }
            }
4321 4322 4323 4324 4325 4326 4327 4328
            break;

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

            if (qemuProcessGraphicsSetupNetworkAddress(glisten,
                                                       listenAddr) < 0)
4329
                goto cleanup;
4330 4331
            break;

4332 4333 4334 4335
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
            if (!glisten->socket) {
                if (virAsprintf(&glisten->socket, "%s/%s.sock",
                                priv->libDir, type) < 0)
4336
                    goto cleanup;
4337 4338 4339 4340
                glisten->autoGenerated = true;
            }
            break;

4341 4342 4343 4344 4345 4346
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
            break;
        }
    }

4347 4348 4349 4350 4351
    ret = 0;

 cleanup:
    virObjectUnref(cfg);
    return ret;
4352 4353 4354
}


4355 4356
static int
qemuProcessSetupGraphics(virQEMUDriverPtr driver,
4357 4358
                         virDomainObjPtr vm,
                         unsigned int flags)
4359
{
4360
    virDomainGraphicsDefPtr graphics;
4361
    bool allocate = !(flags & VIR_QEMU_PROCESS_START_PRETEND);
4362
    size_t i;
4363 4364
    int ret = -1;

4365 4366 4367 4368 4369 4370 4371
    for (i = 0; i < vm->def->ngraphics; i++) {
        graphics = vm->def->graphics[i];

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

4372 4373 4374 4375 4376 4377 4378 4379
    if (allocate) {
        for (i = 0; i < vm->def->ngraphics; i++) {
            graphics = vm->def->graphics[i];

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

4381
    for (i = 0; i < vm->def->ngraphics; ++i) {
4382
        graphics = vm->def->graphics[i];
4383

4384 4385
        if (qemuProcessGraphicsAllocatePorts(driver, graphics, allocate) < 0)
            goto cleanup;
4386 4387 4388 4389 4390 4391 4392 4393 4394
    }

    ret = 0;

 cleanup:
    return ret;
}


4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427
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++) {
4428
            if (!virHostdevIsSCSIDevice(vm->def->hostdevs[i]))
4429 4430
                continue;

4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456
            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;
}


4457 4458 4459 4460 4461 4462 4463 4464 4465
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;

4466
    if (!virDomainDefHasMemballoon(vm->def))
4467 4468 4469 4470 4471
        return 0;

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

4472 4473 4474
    if (vm->def->memballoon->period)
        qemuMonitorSetMemoryStatsPeriod(priv->mon, vm->def->memballoon,
                                        vm->def->memballoon->period);
4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486
    if (qemuMonitorSetBalloon(priv->mon, balloon) < 0)
        goto cleanup;

    ret = 0;

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


J
Jiri Denemark 已提交
4487 4488 4489
static int
qemuProcessMakeDir(virQEMUDriverPtr driver,
                   virDomainObjPtr vm,
4490
                   const char *path)
J
Jiri Denemark 已提交
4491 4492 4493 4494 4495 4496 4497 4498
{
    int ret = -1;

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

4499 4500
    if (qemuSecurityDomainSetPathLabel(driver->securityManager,
                                       vm->def, path) < 0)
J
Jiri Denemark 已提交
4501 4502 4503 4504 4505 4506 4507 4508 4509
        goto cleanup;

    ret = 0;

 cleanup:
    return ret;
}


4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545
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) ==
4546
                VIR_DOMAIN_MEMORY_ACCESS_SHARED) {
4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558
                shmem = true;
                break;
            }
        }
    }

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

4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590

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


4591 4592 4593 4594 4595 4596 4597 4598 4599 4600
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];

4601 4602 4603 4604 4605 4606 4607 4608 4609 4610
        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))) {
4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632
            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;
}


4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663
static int
qemuProcessStartValidateIOThreads(virDomainObjPtr vm,
                                  virQEMUCapsPtr qemuCaps)
{
    size_t i;

    if (vm->def->niothreadids > 0 &&
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("IOThreads not supported for this QEMU"));
        return -1;
    }

    for (i = 0; i < vm->def->ncontrollers; i++) {
        virDomainControllerDefPtr cont = vm->def->controllers[i];

        if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
            cont->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI &&
            cont->iothread > 0 &&
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_SCSI_IOTHREAD)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("IOThreads for virtio-scsi not supported for "
                             "this QEMU"));
            return -1;
        }
    }

    return 0;
}


4664
static int
4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683
qemuProcessStartValidateShmem(virDomainObjPtr vm)
{
    size_t i;

    for (i = 0; i < vm->def->nshmems; i++) {
        virDomainShmemDefPtr shmem = vm->def->shmems[i];

        if (strchr(shmem->name, '/')) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("shmem name '%s' must not contain '/'"),
                           shmem->name);
            return -1;
        }
    }

    return 0;
}


4684
static int
4685 4686
qemuProcessStartValidateXML(virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
4687
                            virQEMUCapsPtr qemuCaps,
4688
                            virCapsPtr caps,
4689
                            unsigned int flags)
4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701
{
    /* 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;

4702 4703 4704
    /* 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 */
4705 4706 4707
    if ((flags & VIR_QEMU_PROCESS_START_NEW) &&
        virDomainDefValidate(vm->def, caps, 0, driver->xmlopt) < 0)
        return -1;
4708 4709 4710

    return 0;
}
4711

4712

4713 4714 4715 4716 4717 4718
/**
 * qemuProcessStartValidate:
 * @vm: domain object
 * @qemuCaps: emulator capabilities
 * @migration: restoration of existing state
 *
4719 4720 4721 4722 4723
 * 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.
4724
 */
4725
static int
4726 4727
qemuProcessStartValidate(virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
4728
                         virQEMUCapsPtr qemuCaps,
4729
                         virCapsPtr caps,
4730
                         unsigned int flags)
4731
{
4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745
    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");
4746
        if (qemuSecurityCheckAllLabel(driver->securityManager, vm->def) < 0)
4747 4748 4749 4750
            return -1;

    }

4751
    if (qemuProcessStartValidateXML(driver, vm, qemuCaps, caps, flags) < 0)
4752 4753
        return -1;

4754 4755 4756
    if (qemuProcessStartValidateGraphics(vm) < 0)
        return -1;

4757 4758 4759
    if (qemuProcessStartValidateVideo(vm, qemuCaps) < 0)
        return -1;

4760 4761 4762
    if (qemuProcessStartValidateIOThreads(vm, qemuCaps) < 0)
        return -1;

4763 4764 4765
    if (qemuProcessStartValidateShmem(vm) < 0)
        return -1;

4766 4767
    VIR_DEBUG("Checking for any possible (non-fatal) issues");

4768
    qemuProcessStartWarnShmem(vm);
4769

4770
    return 0;
4771 4772 4773
}


J
Jiri Denemark 已提交
4774 4775 4776 4777 4778 4779
/**
 * qemuProcessInit:
 *
 * Prepares the domain up to the point when priv->qemuCaps is initialized. The
 * function calls qemuProcessStop when needed.
 *
4780 4781 4782 4783
 * 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 已提交
4784 4785 4786 4787 4788
 * Returns 0 on success, -1 on error.
 */
int
qemuProcessInit(virQEMUDriverPtr driver,
                virDomainObjPtr vm,
4789
                qemuDomainAsyncJob asyncJob,
4790
                bool migration,
4791
                unsigned int flags)
J
Jiri Denemark 已提交
4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810
{
    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)))
4811 4812 4813 4814
        goto cleanup;

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

4821
    if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) < 0)
4822 4823
        goto cleanup;

J
Jiri Denemark 已提交
4824 4825 4826 4827 4828
    /* 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");
4829
    if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
4830
        goto cleanup;
J
Jiri Denemark 已提交
4831

4832
    if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
4833 4834 4835 4836
        if (qemuDomainSetPrivatePaths(driver, vm) < 0) {
            virDomainObjRemoveTransientDef(vm);
            goto cleanup;
        }
4837
    } else {
4838 4839 4840
        vm->def->id = qemuDriverAllocateID(driver);
        qemuDomainSetFakeReboot(driver, vm, false);
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_STARTING_UP);
J
Jiri Denemark 已提交
4841

4842 4843
        if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
            driver->inhibitCallback(true, driver->inhibitOpaque);
J
Jiri Denemark 已提交
4844

4845 4846 4847 4848 4849
        /* 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 已提交
4850

4851 4852 4853
        if (qemuDomainSetPrivatePaths(driver, vm) < 0)
            goto stop;
    }
4854

J
Jiri Denemark 已提交
4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865
    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;
4866
    qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, asyncJob, stopFlags);
J
Jiri Denemark 已提交
4867 4868 4869 4870
    goto cleanup;
}


4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881
/**
 * qemuProcessNetworkPrepareDevices
 */
static int
qemuProcessNetworkPrepareDevices(virDomainDefPtr def)
{
    int ret = -1;
    size_t i;

    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
4882
        virDomainNetType actualType;
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

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


4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939
/**
 * 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);
4940
    virDomainVcpuDefPtr vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
4941

4942 4943 4944 4945 4946
    return qemuProcessSetupPid(vm, vcpupid, VIR_CGROUP_THREAD_VCPU,
                               vcpuid, vcpu->cpumask,
                               vm->def->cputune.period,
                               vm->def->cputune.quota,
                               &vcpu->sched);
4947 4948 4949 4950 4951 4952
}


static int
qemuProcessSetupVcpus(virDomainObjPtr vm)
{
4953
    virDomainVcpuDefPtr vcpu;
4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998
    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;
}


4999 5000 5001 5002 5003
int
qemuProcessSetupIOThread(virDomainObjPtr vm,
                         virDomainIOThreadIDDefPtr iothread)
{

5004 5005
    return qemuProcessSetupPid(vm, iothread->thread_id,
                               VIR_CGROUP_THREAD_IOTHREAD,
5006
                               iothread->iothread_id,
5007
                               iothread->cpumask,
5008 5009
                               vm->def->cputune.iothread_period,
                               vm->def->cputune.iothread_quota,
5010
                               &iothread->sched);
5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029
}


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


5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041
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;

5042
    if (!(ordermap = virBitmapNew(maxvcpus + 1)))
5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058
        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) {
5059
            if (virBitmapIsBitSet(ordermap, vcpu->order)) {
5060
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5061
                               _("duplicate vcpu order '%u'"), vcpu->order);
5062 5063 5064
                goto cleanup;
            }

5065 5066 5067 5068 5069 5070
            if (virBitmapSetBit(ordermap, vcpu->order)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("vcpu order '%u' exceeds vcpu count"),
                               vcpu->order);
                goto cleanup;
            }
5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137
        }

        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);
5138 5139
    qemuDomainObjPrivatePtr priv = vm->privateData;
    qemuCgroupEmulatorAllNodesDataPtr emulatorCgroup = NULL;
5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171
    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);

5172 5173 5174
    if (qemuCgroupEmulatorAllNodesAllow(priv->cgroup, &emulatorCgroup) < 0)
        goto cleanup;

5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198
    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:
5199
    qemuCgroupEmulatorAllNodesRestore(emulatorCgroup);
5200 5201 5202 5203 5204 5205
    VIR_FREE(bootHotplug);
    virJSONValueFree(vcpuprops);
    return ret;
}


5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246
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;
    }

5247 5248 5249
    if (virCPUConvertLegacy(caps->host.arch, def->cpu) < 0)
        return -1;

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

5254 5255 5256 5257 5258
    if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
        virCPUCompare(caps->host.arch,
                      virQEMUCapsGetHostModel(qemuCaps, def->virtType),
                      def->cpu, true) < 0)
        return -1;
5259 5260

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

5264 5265
    if (virQEMUCapsGetCPUDefinitions(qemuCaps, def->virtType,
                                     &models, &nmodels) < 0 ||
5266 5267
        virCPUTranslate(def->os.arch, def->cpu,
                        (const char **) models, nmodels) < 0)
5268 5269 5270 5271 5272 5273
        goto cleanup;

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

 cleanup:
5274
    virStringListFreeCount(models, nmodels);
5275 5276 5277 5278
    return ret;
}


5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309
/**
 * 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;
    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)");
5310
        if (qemuSecurityGenLabel(driver->securityManager, vm->def) < 0) {
5311 5312 5313 5314 5315 5316 5317 5318 5319 5320
            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),
5321
                                                    virDomainDefGetMemoryTotal(vm->def));
5322 5323 5324 5325 5326
            if (!nodeset)
                goto cleanup;

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

5327
            if (virBitmapParse(nodeset, &priv->autoNodeset,
5328 5329 5330 5331 5332 5333 5334 5335 5336
                               VIR_DOMAIN_CPUMASK_LEN) < 0)
                goto cleanup;

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

5337 5338 5339 5340 5341 5342 5343
    /*
     * 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
     */
5344
    VIR_DEBUG("Assigning domain PCI addresses");
5345 5346
    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, driver, vm,
                                   !!(flags & VIR_QEMU_PROCESS_START_NEW))) < 0) {
5347
        goto cleanup;
5348
    }
5349

5350 5351 5352
    if (qemuAssignDeviceAliases(vm->def, priv->qemuCaps) < 0)
        goto cleanup;

5353
    VIR_DEBUG("Setting graphics devices");
5354 5355 5356
    if (qemuProcessSetupGraphics(driver, vm, flags) < 0)
        goto cleanup;

5357 5358 5359 5360 5361
    /* 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;
5362

5363 5364 5365 5366
    VIR_DEBUG("Create domain masterKey");
    if (qemuDomainMasterKeyCreate(vm) < 0)
        goto cleanup;

5367 5368 5369 5370 5371
    VIR_DEBUG("Prepare chardev source backends for TLS");
    qemuDomainPrepareChardevSource(vm->def, driver);

    VIR_DEBUG("Add secrets to disks, hostdevs, and chardevs");
    if (qemuDomainSecretPrepare(conn, driver, vm) < 0)
5372 5373
        goto cleanup;

5374 5375 5376 5377 5378 5379
    for (i = 0; i < vm->def->nchannels; i++) {
        if (qemuDomainPrepareChannel(vm->def->channels[i],
                                     priv->channelTargetDir) < 0)
            goto cleanup;
    }

5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391
    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;

5392 5393 5394 5395
    VIR_DEBUG("Updating guest CPU definition");
    if (qemuProcessUpdateGuestCPU(vm->def, priv->qemuCaps, caps, flags) < 0)
        goto cleanup;

5396 5397 5398 5399 5400 5401 5402 5403
    ret = 0;
 cleanup:
    VIR_FREE(nodeset);
    virObjectUnref(caps);
    return ret;
}


J
Jiri Denemark 已提交
5404
/**
5405
 * qemuProcessPrepareHost
J
Jiri Denemark 已提交
5406
 *
5407 5408 5409
 * 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 已提交
5410
 *
5411
 * TODO: move all host modification from qemuBuildCommandLine into this function
J
Jiri Denemark 已提交
5412 5413
 */
int
5414 5415 5416
qemuProcessPrepareHost(virQEMUDriverPtr driver,
                       virDomainObjPtr vm,
                       bool incoming)
5417
{
5418
    int ret = -1;
5419
    unsigned int hostdev_flags = 0;
5420 5421
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
5422

5423
    if (qemuPrepareNVRAM(cfg, vm) < 0)
J
Jiri Denemark 已提交
5424
        goto cleanup;
5425

5426 5427 5428 5429 5430
    /* 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");
5431
    if (qemuProcessNetworkPrepareDevices(vm->def) < 0)
J
Jiri Denemark 已提交
5432
        goto cleanup;
5433

5434
    /* Must be run before security labelling */
5435
    VIR_DEBUG("Preparing host devices");
5436 5437
    if (!cfg->relaxedACS)
        hostdev_flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
J
Jiri Denemark 已提交
5438
    if (!incoming)
5439
        hostdev_flags |= VIR_HOSTDEV_COLD_BOOT;
5440 5441
    if (qemuHostdevPrepareDomainDevices(driver, vm->def, priv->qemuCaps,
                                        hostdev_flags) < 0)
J
Jiri Denemark 已提交
5442
        goto cleanup;
5443

5444
    VIR_DEBUG("Preparing chr devices");
5445 5446 5447 5448
    if (virDomainChrDefForeach(vm->def,
                               true,
                               qemuProcessPrepareChardevDevice,
                               NULL) < 0)
J
Jiri Denemark 已提交
5449
        goto cleanup;
5450

5451 5452
    if (qemuProcessBuildDestroyHugepagesPath(driver, vm, true) < 0)
        goto cleanup;
5453

5454 5455
    /* Ensure no historical cgroup for this VM is lying around bogus
     * settings */
5456
    VIR_DEBUG("Ensuring no historical cgroup is lying around");
5457
    qemuRemoveCgroup(vm);
5458

5459
    if (virFileMakePath(cfg->logDir) < 0) {
5460 5461
        virReportSystemError(errno,
                             _("cannot create log directory %s"),
5462
                             cfg->logDir);
J
Jiri Denemark 已提交
5463
        goto cleanup;
5464 5465
    }

5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488
    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;

5489 5490
    VIR_DEBUG("Write domain masterKey");
    if (qemuDomainWriteMasterKeyFile(driver, vm) < 0)
J
John Ferlan 已提交
5491 5492
        goto cleanup;

5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533
    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 已提交
5534
    size_t i;
5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550

    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 |
5551 5552
                  VIR_QEMU_PROCESS_START_AUTODESTROY |
                  VIR_QEMU_PROCESS_START_NEW, -1);
5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564

    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;

5565
    VIR_DEBUG("Creating domain log file");
5566 5567
    if (!(logCtxt = qemuDomainLogContextNew(driver, vm,
                                            QEMU_DOMAIN_LOG_CONTEXT_MODE_START)))
J
Jiri Denemark 已提交
5568
        goto cleanup;
5569
    logfile = qemuDomainLogContextGetWriteFD(logCtxt);
5570

5571
    VIR_DEBUG("Building emulator command line");
5572
    if (!(cmd = qemuBuildCommandLine(driver,
5573 5574
                                     qemuDomainLogContextGetManager(logCtxt),
                                     vm->def, priv->monConfig,
E
Eric Blake 已提交
5575
                                     priv->monJSON, priv->qemuCaps,
5576 5577
                                     incoming ? incoming->launchURI : NULL,
                                     snapshot, vmop,
J
Ján Tomko 已提交
5578
                                     false,
5579
                                     qemuCheckFips(),
5580
                                     priv->autoNodeset,
5581
                                     &nnicindexes, &nicindexes,
5582
                                     priv->libDir)))
J
Jiri Denemark 已提交
5583
        goto cleanup;
5584

5585 5586
    if (incoming && incoming->fd != -1)
        virCommandPassFD(cmd, incoming->fd, 0);
5587

5588
    /* now that we know it is about to start call the hook if present */
5589 5590 5591
    if (qemuProcessStartHook(driver, vm,
                             VIR_HOOK_QEMU_OP_START,
                             VIR_HOOK_SUBOP_BEGIN) < 0)
J
Jiri Denemark 已提交
5592
        goto cleanup;
5593

5594
    qemuLogOperation(vm, "starting up", cmd, logCtxt);
5595

5596
    qemuDomainObjCheckTaint(driver, vm, logCtxt);
5597

5598
    qemuDomainLogContextMarkPosition(logCtxt);
5599

5600 5601 5602 5603 5604
    VIR_DEBUG("Building mount namespace");

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

5605
    VIR_DEBUG("Clear emulator capabilities: %d",
5606 5607
              cfg->clearEmulatorCapabilities);
    if (cfg->clearEmulatorCapabilities)
5608 5609
        virCommandClearCaps(cmd);

5610 5611
    VIR_DEBUG("Setting up raw IO");
    if (qemuProcessSetupRawIO(driver, vm, cmd) < 0)
J
Jiri Denemark 已提交
5612
        goto cleanup;
5613

5614
    virCommandSetPreExecHook(cmd, qemuProcessHook, &hookData);
5615 5616
    virCommandSetMaxProcesses(cmd, cfg->maxProcesses);
    virCommandSetMaxFiles(cmd, cfg->maxFiles);
5617
    virCommandSetMaxCoreSize(cmd, cfg->maxCore);
5618
    virCommandSetUmask(cmd, 0x002);
5619

5620
    VIR_DEBUG("Setting up security labelling");
5621 5622
    if (qemuSecuritySetChildProcessLabel(driver->securityManager,
                                         vm->def, cmd) < 0)
J
Jiri Denemark 已提交
5623
        goto cleanup;
5624

5625 5626 5627
    virCommandSetOutputFD(cmd, &logfile);
    virCommandSetErrorFD(cmd, &logfile);
    virCommandNonblockingFDs(cmd);
5628
    virCommandSetPidFile(cmd, priv->pidfile);
5629
    virCommandDaemonize(cmd);
5630
    virCommandRequireHandshake(cmd);
5631

5632
    if (qemuSecurityPreFork(driver->securityManager) < 0)
J
Jiri Denemark 已提交
5633
        goto cleanup;
5634
    rv = virCommandRun(cmd, NULL);
5635
    qemuSecurityPostFork(driver->securityManager);
5636

E
Eric Blake 已提交
5637
    /* wait for qemu process to show up */
5638
    if (rv == 0) {
5639
        if (virPidFileReadPath(priv->pidfile, &vm->pid) < 0) {
5640 5641
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Domain %s didn't show up"), vm->def->name);
5642
            rv = -1;
5643
        }
M
Michal Privoznik 已提交
5644 5645
        VIR_DEBUG("QEMU vm=%p name=%s running with pid=%lld",
                  vm, vm->def->name, (long long) vm->pid);
5646 5647 5648
    } else {
        VIR_DEBUG("QEMU vm=%p name=%s failed to spawn",
                  vm, vm->def->name);
5649 5650
    }

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

5655 5656
    VIR_DEBUG("Waiting for handshake from child");
    if (virCommandHandshakeWait(cmd) < 0) {
5657
        /* Read errors from child that occurred between fork and exec. */
5658 5659
        qemuProcessReportLogError(logCtxt,
                                  _("Process exited prior to exec"));
J
Jiri Denemark 已提交
5660
        goto cleanup;
5661 5662
    }

5663
    VIR_DEBUG("Setting up domain cgroup (if required)");
5664
    if (qemuSetupCgroup(driver, vm, nnicindexes, nicindexes) < 0)
J
Jiri Denemark 已提交
5665
        goto cleanup;
5666

5667 5668 5669 5670
    if (!(priv->perf = virPerfNew()))
        goto cleanup;

    for (i = 0; i < VIR_PERF_EVENT_LAST; i++) {
5671
        if (vm->def->perf.events[i] == VIR_TRISTATE_BOOL_YES &&
5672 5673
            virPerfEventEnable(priv->perf, i, vm->pid) < 0)
            goto cleanup;
Q
Qiaowei Ren 已提交
5674
    }
5675

5676 5677 5678 5679 5680 5681
    /* This must be done after cgroup placement to avoid resetting CPU
     * affinity */
    if (!vm->def->cputune.emulatorpin &&
        qemuProcessInitCpuAffinity(vm) < 0)
        goto cleanup;

5682 5683 5684 5685
    VIR_DEBUG("Setting emulator tuning/settings");
    if (qemuProcessSetupEmulator(vm) < 0)
        goto cleanup;

5686
    VIR_DEBUG("Setting domain security labels");
5687 5688 5689 5690
    if (qemuSecuritySetAllLabel(driver,
                                vm,
                                incoming ? incoming->path : NULL) < 0)
        goto cleanup;
5691

5692
    /* Security manager labeled all devices, therefore
J
Jiri Denemark 已提交
5693 5694 5695 5696
     * if any operation from now on fails, we need to ask the caller to
     * restore labels.
     */
    ret = -2;
5697

J
Jiri Denemark 已提交
5698
    if (incoming && incoming->fd != -1) {
5699 5700 5701 5702 5703 5704 5705
        /* 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 已提交
5706
        if (fstat(incoming->fd, &stdin_sb) < 0) {
5707
            virReportSystemError(errno,
J
Jiri Denemark 已提交
5708 5709
                                 _("cannot stat fd %d"), incoming->fd);
            goto cleanup;
5710 5711
        }
        if (S_ISFIFO(stdin_sb.st_mode) &&
5712 5713
            qemuSecuritySetImageFDLabel(driver->securityManager,
                                        vm->def, incoming->fd) < 0)
J
Jiri Denemark 已提交
5714
            goto cleanup;
5715 5716 5717
    }

    VIR_DEBUG("Labelling done, completing handshake to child");
5718
    if (virCommandHandshakeNotify(cmd) < 0)
J
Jiri Denemark 已提交
5719
        goto cleanup;
5720 5721
    VIR_DEBUG("Handshake complete, child running");

5722
    if (rv == -1) /* The VM failed to start; tear filters before taps */
5723 5724
        virDomainConfVMNWFilterTeardown(vm);

5725
    if (rv == -1) /* The VM failed to start */
J
Jiri Denemark 已提交
5726
        goto cleanup;
5727

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

5732 5733
    if (qemuConnectAgent(driver, vm) < 0)
        goto cleanup;
D
Daniel P. Berrange 已提交
5734

5735 5736
    VIR_DEBUG("Verifying and updating provided guest CPU");
    if (qemuProcessUpdateLiveGuestCPU(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5737
        goto cleanup;
5738

5739
    VIR_DEBUG("Setting up post-init cgroup restrictions");
5740
    if (qemuSetupCpusetMems(vm) < 0)
J
Jiri Denemark 已提交
5741
        goto cleanup;
5742

5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754
    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;
    }

5755
    VIR_DEBUG("Refreshing VCPU info");
5756
    if (qemuDomainRefreshVcpuInfo(driver, vm, asyncJob, false) < 0)
J
Jiri Denemark 已提交
5757
        goto cleanup;
5758

5759 5760 5761
    if (qemuDomainValidateVcpuInfo(vm) < 0)
        goto cleanup;

5762 5763
    qemuDomainVcpuPersistOrder(vm->def);

5764 5765
    VIR_DEBUG("Detecting IOThread PIDs");
    if (qemuProcessDetectIOThreadPIDs(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5766
        goto cleanup;
5767

5768 5769 5770 5771
    VIR_DEBUG("Setting global CPU cgroup (if required)");
    if (qemuSetupGlobalCpuCgroup(vm) < 0)
        goto cleanup;

5772 5773
    VIR_DEBUG("Setting vCPU tuning/settings");
    if (qemuProcessSetupVcpus(vm) < 0)
J
Jiri Denemark 已提交
5774
        goto cleanup;
5775

5776 5777
    VIR_DEBUG("Setting IOThread tuning/settings");
    if (qemuProcessSetupIOThreads(vm) < 0)
J
Jiri Denemark 已提交
5778
        goto cleanup;
5779

5780
    VIR_DEBUG("Setting any required VM passwords");
5781
    if (qemuProcessInitPasswords(conn, driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5782
        goto cleanup;
5783

5784 5785 5786 5787
    /* set default link states */
    /* qemu doesn't support setting this on the command line, so
     * enter the monitor */
    VIR_DEBUG("Setting network link states");
5788
    if (qemuProcessSetLinkStates(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5789
        goto cleanup;
5790

5791
    VIR_DEBUG("Fetching list of active devices");
5792
    if (qemuDomainUpdateDeviceList(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5793
        goto cleanup;
5794

5795 5796
    VIR_DEBUG("Updating info of memory devices");
    if (qemuDomainUpdateMemoryDeviceInfo(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5797
        goto cleanup;
5798

5799
    VIR_DEBUG("Setting initial memory amount");
5800
    if (qemuProcessSetupBalloon(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5801
        goto cleanup;
5802

5803
    /* Since CPUs were not started yet, the balloon could not return the memory
5804 5805
     * 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 */
5806
    if (!incoming && !snapshot &&
5807
        qemuProcessRefreshBalloonState(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5808
        goto cleanup;
5809

5810 5811
    VIR_DEBUG("Detecting actual memory size for video device");
    if (qemuProcessUpdateVideoRamSize(driver, vm, asyncJob) < 0)
J
Jiri Denemark 已提交
5812 5813
        goto cleanup;

5814 5815
    VIR_DEBUG("Updating disk data");
    if (qemuProcessRefreshDisks(driver, vm, asyncJob) < 0)
5816 5817
        goto cleanup;

J
Jiri Denemark 已提交
5818 5819 5820 5821 5822 5823 5824
    if (flags & VIR_QEMU_PROCESS_START_AUTODESTROY &&
        qemuProcessAutoDestroyAdd(driver, vm, conn) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
5825
    qemuDomainSecretDestroy(vm);
J
Jiri Denemark 已提交
5826
    virCommandFree(cmd);
5827
    qemuDomainLogContextFree(logCtxt);
J
Jiri Denemark 已提交
5828 5829 5830 5831 5832 5833 5834
    virObjectUnref(cfg);
    virObjectUnref(caps);
    VIR_FREE(nicindexes);
    return ret;
}


5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865
/**
 * 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");
5866
    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881
        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 已提交
5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912
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);

5913 5914 5915 5916
    if (!migrateFrom && !snapshot)
        flags |= VIR_QEMU_PROCESS_START_NEW;

    if (qemuProcessInit(driver, vm, asyncJob, !!migrateFrom, flags) < 0)
J
Jiri Denemark 已提交
5917 5918 5919
        goto cleanup;

    if (migrateFrom) {
5920
        incoming = qemuProcessIncomingDefNew(priv->qemuCaps, NULL, migrateFrom,
J
Jiri Denemark 已提交
5921 5922 5923 5924 5925
                                             migrateFd, migratePath);
        if (!incoming)
            goto stop;
    }

5926 5927 5928
    if (qemuProcessPrepareDomain(conn, driver, vm, flags) < 0)
        goto stop;

5929 5930 5931
    if (qemuProcessPrepareHost(driver, vm, !!incoming) < 0)
        goto stop;

J
Jiri Denemark 已提交
5932 5933
    if ((rv = qemuProcessLaunch(conn, driver, vm, asyncJob, incoming,
                                snapshot, vmop, flags)) < 0) {
5934
        if (rv == -2)
J
Jiri Denemark 已提交
5935 5936 5937 5938
            relabel = true;
        goto stop;
    }
    relabel = true;
5939

5940 5941 5942
    if (incoming &&
        incoming->deferredURI &&
        qemuMigrationRunIncoming(driver, vm, incoming->deferredURI, asyncJob) < 0)
J
Jiri Denemark 已提交
5943
        goto stop;
5944

5945 5946 5947 5948 5949
    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 已提交
5950
        goto stop;
5951

5952 5953
    /* Keep watching qemu log for errors during incoming migration, otherwise
     * unset reporting errors from qemu log. */
5954
    if (!incoming)
5955
        qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL);
5956

5957 5958 5959
    ret = 0;

 cleanup:
5960
    qemuProcessIncomingDefFree(incoming);
5961
    return ret;
5962

J
Jiri Denemark 已提交
5963 5964 5965 5966 5967 5968
 stop:
    stopFlags = 0;
    if (!relabel)
        stopFlags |= VIR_QEMU_PROCESS_STOP_NO_RELABEL;
    if (migrateFrom)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
5969
    if (priv->mon)
5970
        qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL);
5971
    qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, asyncJob, stopFlags);
5972
    goto cleanup;
5973 5974 5975
}


5976 5977 5978 5979 5980
virCommandPtr
qemuProcessCreatePretendCmd(virConnectPtr conn,
                            virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
                            const char *migrateURI,
5981
                            bool enableFips,
5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992
                            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;
5993
    flags |= VIR_QEMU_PROCESS_START_NEW;
5994

5995
    if (qemuProcessInit(driver, vm, QEMU_ASYNC_JOB_NONE, !!migrateURI, flags) < 0)
5996 5997 5998 5999 6000 6001
        goto cleanup;

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

    VIR_DEBUG("Building emulator command line");
6002
    cmd = qemuBuildCommandLine(driver,
6003 6004 6005 6006 6007 6008 6009 6010 6011
                               NULL,
                               vm->def,
                               priv->monConfig,
                               priv->monJSON,
                               priv->qemuCaps,
                               migrateURI,
                               NULL,
                               VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
                               standalone,
6012
                               enableFips,
6013 6014 6015
                               priv->autoNodeset,
                               NULL,
                               NULL,
6016
                               priv->libDir);
6017 6018 6019 6020 6021 6022

 cleanup:
    return cmd;
}


6023
int
6024
qemuProcessKill(virDomainObjPtr vm, unsigned int flags)
6025
{
6026
    int ret;
6027

M
Michal Privoznik 已提交
6028
    VIR_DEBUG("vm=%p name=%s pid=%lld flags=%x",
6029
              vm, vm->def->name,
M
Michal Privoznik 已提交
6030
              (long long) vm->pid, flags);
6031

6032 6033 6034 6035 6036
    if (!(flags & VIR_QEMU_PROCESS_KILL_NOCHECK)) {
        if (!virDomainObjIsActive(vm)) {
            VIR_DEBUG("VM '%s' not active", vm->def->name);
            return 0;
        }
6037 6038
    }

6039
    if (flags & VIR_QEMU_PROCESS_KILL_NOWAIT) {
6040 6041 6042 6043 6044
        virProcessKill(vm->pid,
                       (flags & VIR_QEMU_PROCESS_KILL_FORCE) ?
                       SIGKILL : SIGTERM);
        return 0;
    }
6045

6046 6047
    ret = virProcessKillPainfully(vm->pid,
                                  !!(flags & VIR_QEMU_PROCESS_KILL_FORCE));
6048

6049
    return ret;
6050 6051 6052
}


6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091
/**
 * 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;
}


6092
void qemuProcessStop(virQEMUDriverPtr driver,
6093
                     virDomainObjPtr vm,
6094
                     virDomainShutoffReason reason,
6095
                     qemuDomainAsyncJob asyncJob,
6096
                     unsigned int flags)
6097 6098 6099 6100 6101 6102
{
    int ret;
    int retries = 0;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    virErrorPtr orig_err;
    virDomainDefPtr def;
A
Ansis Atteka 已提交
6103
    virNetDevVPortProfilePtr vport = NULL;
6104
    size_t i;
6105
    char *timestamp;
6106
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
6107

M
Michal Privoznik 已提交
6108
    VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%lld, "
6109
              "reason=%s, asyncJob=%s, flags=%x",
6110
              vm, vm->def->name, vm->def->id,
M
Michal Privoznik 已提交
6111
              (long long) vm->pid,
6112 6113 6114
              virDomainShutoffReasonTypeToString(reason),
              qemuDomainAsyncJobTypeToString(asyncJob),
              flags);
6115

6116 6117 6118 6119
    /* This method is routinely used in clean up paths. Disable error
     * reporting so we don't squash a legit error. */
    orig_err = virSaveLastError();

6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134
    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;
    }

6135 6136
    qemuProcessBuildDestroyHugepagesPath(driver, vm, false);

6137 6138
    vm->def->id = -1;

6139
    if (virAtomicIntDecAndTest(&driver->nactive) && driver->inhibitCallback)
6140 6141
        driver->inhibitCallback(false, driver->inhibitOpaque);

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

6145
    if ((timestamp = virTimeStringNow()) != NULL) {
6146 6147 6148
        qemuDomainLogAppendMessage(driver, vm, "%s: shutting down, reason=%s\n",
                                   timestamp,
                                   virDomainShutoffReasonTypeToString(reason));
6149
        VIR_FREE(timestamp);
6150 6151
    }

6152 6153 6154
    /* Clear network bandwidth */
    virDomainClearNetBandwidth(vm);

6155 6156
    virDomainConfVMNWFilterTeardown(vm);

6157
    if (cfg->macFilter) {
6158
        def = vm->def;
6159
        for (i = 0; i < def->nnets; i++) {
6160 6161 6162
            virDomainNetDefPtr net = def->nets[i];
            if (net->ifname == NULL)
                continue;
6163 6164 6165
            ignore_value(ebtablesRemoveForwardAllowIn(driver->ebtables,
                                                      net->ifname,
                                                      &net->mac));
6166 6167 6168
        }
    }

6169
    virPortAllocatorRelease(driver->migrationPorts, priv->nbdPort);
6170
    priv->nbdPort = 0;
6171

D
Daniel P. Berrange 已提交
6172 6173 6174 6175
    if (priv->agent) {
        qemuAgentClose(priv->agent);
        priv->agent = NULL;
    }
6176
    priv->agentError = false;
D
Daniel P. Berrange 已提交
6177

6178
    if (priv->mon) {
6179
        qemuMonitorClose(priv->mon);
6180 6181
        priv->mon = NULL;
    }
6182 6183 6184 6185 6186 6187 6188 6189

    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 已提交
6190 6191 6192
    /* Remove the master key */
    qemuDomainMasterKeyRemove(priv);

6193 6194
    virFileDeleteTree(priv->libDir);
    virFileDeleteTree(priv->channelTargetDir);
6195

6196 6197
    qemuDomainClearPrivatePaths(vm);

6198 6199 6200 6201 6202 6203
    ignore_value(virDomainChrDefForeach(vm->def,
                                        false,
                                        qemuProcessCleanupChardevDevice,
                                        NULL));


6204
    /* shut it off for sure */
6205 6206 6207
    ignore_value(qemuProcessKill(vm,
                                 VIR_QEMU_PROCESS_KILL_FORCE|
                                 VIR_QEMU_PROCESS_KILL_NOCHECK));
6208

6209 6210
    qemuDomainCleanupRun(driver, vm);

6211
    /* Stop autodestroy in case guest is restarted */
6212
    qemuProcessAutoDestroyRemove(driver, vm);
6213

6214 6215
    /* now that we know it's stopped call the hook if present */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
6216
        char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
6217 6218

        /* we can't stop the operation even if the script raised an error */
6219 6220 6221
        ignore_value(virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
                                 VIR_HOOK_QEMU_OP_STOPPED, VIR_HOOK_SUBOP_END,
                                 NULL, xml, NULL));
6222 6223 6224
        VIR_FREE(xml);
    }

6225 6226
    /* Reset Security Labels unless caller don't want us to */
    if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL))
6227 6228 6229
        qemuSecurityRestoreAllLabel(driver, vm,
                                    !!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED));

6230
    qemuSecurityReleaseLabel(driver->securityManager, vm->def);
6231

6232
    for (i = 0; i < vm->def->ndisks; i++) {
6233
        virDomainDeviceDef dev;
6234
        virDomainDiskDefPtr disk = vm->def->disks[i];
6235 6236 6237 6238

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

6241
    /* Clear out dynamically assigned labels */
6242
    for (i = 0; i < vm->def->nseclabels; i++) {
6243
        if (vm->def->seclabels[i]->type == VIR_DOMAIN_SECLABEL_DYNAMIC)
6244 6245
            VIR_FREE(vm->def->seclabels[i]->label);
        VIR_FREE(vm->def->seclabels[i]->imagelabel);
6246 6247
    }

6248
    virStringListFree(priv->qemuDevices);
6249 6250
    priv->qemuDevices = NULL;

6251
    qemuHostdevReAttachDomainDevices(driver, vm->def);
6252 6253 6254 6255

    def = vm->def;
    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
6256 6257 6258 6259
        vport = virDomainNetGetActualVirtPortProfile(net);

        switch (virDomainNetGetActualType(net)) {
        case VIR_DOMAIN_NET_TYPE_DIRECT:
6260
            ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
6261
                             net->ifname, &net->mac,
6262 6263
                             virDomainNetGetActualDirectDev(net),
                             virDomainNetGetActualDirectMode(net),
6264
                             virDomainNetGetActualVirtPortProfile(net),
6265
                             cfg->stateDir));
6266
            break;
6267 6268 6269 6270 6271 6272
        case VIR_DOMAIN_NET_TYPE_ETHERNET:
            if (net->ifname) {
                ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
                VIR_FREE(net->ifname);
            }
            break;
6273 6274 6275 6276
        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))
6277
                ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
6278 6279
#endif
            break;
6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290
        case VIR_DOMAIN_NET_TYPE_USER:
        case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
        case VIR_DOMAIN_NET_TYPE_SERVER:
        case VIR_DOMAIN_NET_TYPE_CLIENT:
        case VIR_DOMAIN_NET_TYPE_MCAST:
        case VIR_DOMAIN_NET_TYPE_INTERNAL:
        case VIR_DOMAIN_NET_TYPE_HOSTDEV:
        case VIR_DOMAIN_NET_TYPE_UDP:
        case VIR_DOMAIN_NET_TYPE_LAST:
            /* No special cleanup procedure for these types. */
            break;
6291
        }
6292 6293 6294
        /* release the physical device (or any other resources used by
         * this interface in the network driver
         */
6295 6296 6297 6298 6299 6300 6301 6302 6303
        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 已提交
6304

6305 6306
        /* kick the device out of the hostdev list too */
        virDomainNetRemoveHostdev(def, net);
6307
        networkReleaseActualDevice(vm->def, net);
6308
    }
6309

6310
 retry:
6311
    if ((ret = qemuRemoveCgroup(vm)) < 0) {
6312 6313 6314 6315 6316 6317 6318
        if (ret == -EBUSY && (retries++ < 5)) {
            usleep(200*1000);
            goto retry;
        }
        VIR_WARN("Failed to remove cgroup for %s",
                 vm->def->name);
    }
6319
    virCgroupFree(&priv->cgroup);
6320

6321
    virPerfFree(priv->perf);
6322
    priv->perf = NULL;
6323

6324 6325
    qemuProcessRemoveDomainStatus(driver, vm);

6326 6327
    /* Remove VNC and Spice ports from port reservation bitmap, but only if
       they were reserved by the driver (autoport=yes)
6328
    */
6329
    for (i = 0; i < vm->def->ngraphics; ++i) {
6330
        virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
6331 6332
        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
            if (graphics->data.vnc.autoport) {
6333 6334
                virPortAllocatorRelease(driver->remotePorts,
                                        graphics->data.vnc.port);
6335
            } else if (graphics->data.vnc.portReserved) {
6336 6337 6338 6339 6340
                virPortAllocatorSetUsed(driver->remotePorts,
                                        graphics->data.spice.port,
                                        false);
                graphics->data.vnc.portReserved = false;
            }
6341 6342 6343 6344 6345 6346 6347 6348 6349 6350
            if (graphics->data.vnc.websocketGenerated) {
                virPortAllocatorRelease(driver->webSocketPorts,
                                        graphics->data.vnc.websocket);
                graphics->data.vnc.websocketGenerated = false;
                graphics->data.vnc.websocket = -1;
            } else if (graphics->data.vnc.websocket) {
                virPortAllocatorSetUsed(driver->remotePorts,
                                        graphics->data.vnc.websocket,
                                        false);
            }
6351
        }
6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372
        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;
                }
            }
6373
        }
6374 6375
    }

6376
    vm->taint = 0;
6377
    vm->pid = -1;
J
Jiri Denemark 已提交
6378
    virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
6379 6380
    for (i = 0; i < vm->def->niothreadids; i++)
        vm->def->iothreadids[i]->thread_id = 0;
6381 6382
    virObjectUnref(priv->qemuCaps);
    priv->qemuCaps = NULL;
6383
    VIR_FREE(priv->pidfile);
6384

6385
    /* The "release" hook cleans up additional resources */
6386
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
6387
        char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
6388 6389 6390

        /* we can't stop the operation even if the script raised an error */
        virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
6391 6392
                    VIR_HOOK_QEMU_OP_RELEASE, VIR_HOOK_SUBOP_END,
                    NULL, xml, NULL);
6393 6394 6395
        VIR_FREE(xml);
    }

6396
    virDomainObjRemoveTransientDef(vm);
6397

6398 6399 6400 6401 6402
 endjob:
    if (asyncJob != QEMU_ASYNC_JOB_NONE)
        qemuDomainObjEndJob(driver, vm);

 cleanup:
6403 6404 6405 6406
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
6407
    virObjectUnref(cfg);
6408
}
6409 6410


6411
int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
6412
                      virQEMUDriverPtr driver,
6413
                      virDomainObjPtr vm,
6414
                      pid_t pid,
6415 6416 6417 6418
                      const char *pidfile,
                      virDomainChrSourceDefPtr monConfig,
                      bool monJSON)
{
6419
    size_t i;
6420
    qemuDomainLogContextPtr logCtxt = NULL;
6421 6422 6423
    char *timestamp;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    bool running = true;
6424
    virDomainPausedReason reason;
6425
    virSecurityLabelPtr seclabel = NULL;
6426
    virSecurityLabelDefPtr seclabeldef = NULL;
6427
    bool seclabelgen = false;
6428 6429
    virSecurityManagerPtr* sec_managers = NULL;
    const char *model;
6430
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
6431
    virCapsPtr caps = NULL;
6432
    bool active = false;
6433 6434 6435 6436

    VIR_DEBUG("Beginning VM attach process");

    if (virDomainObjIsActive(vm)) {
6437 6438
        virReportError(VIR_ERR_OPERATION_INVALID,
                       "%s", _("VM is already active"));
6439
        virObjectUnref(cfg);
6440 6441 6442
        return -1;
    }

6443
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
6444
        goto error;
6445

6446 6447 6448 6449 6450
    /* 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");
6451
    if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
6452
        goto error;
6453

6454
    vm->def->id = qemuDriverAllocateID(driver);
6455

6456
    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
6457
        driver->inhibitCallback(true, driver->inhibitOpaque);
6458
    active = true;
6459

6460
    if (virFileMakePath(cfg->logDir) < 0) {
6461 6462
        virReportSystemError(errno,
                             _("cannot create log directory %s"),
6463
                             cfg->logDir);
6464
        goto error;
6465 6466 6467
    }

    VIR_FREE(priv->pidfile);
6468
    if (VIR_STRDUP(priv->pidfile, pidfile) < 0)
6469
        goto error;
6470

6471 6472
    vm->pid = pid;

6473
    VIR_DEBUG("Detect security driver config");
6474
    sec_managers = qemuSecurityGetNested(driver->securityManager);
6475 6476
    if (sec_managers == NULL)
        goto error;
6477 6478

    for (i = 0; sec_managers[i]; i++) {
6479
        seclabelgen = false;
6480
        model = qemuSecurityGetModel(sec_managers[i]);
6481
        seclabeldef = virDomainDefGetSecurityLabelDef(vm->def, model);
6482
        if (seclabeldef == NULL) {
6483
            if (!(seclabeldef = virSecurityLabelDefNew(model)))
6484 6485 6486
                goto error;
            seclabelgen = true;
        }
6487 6488
        seclabeldef->type = VIR_DOMAIN_SECLABEL_STATIC;
        if (VIR_ALLOC(seclabel) < 0)
6489
            goto error;
6490 6491
        if (qemuSecurityGetProcessLabel(sec_managers[i], vm->def,
                                        vm->pid, seclabel) < 0)
6492
            goto error;
6493

6494
        if (VIR_STRDUP(seclabeldef->model, model) < 0)
6495
            goto error;
6496

6497
        if (VIR_STRDUP(seclabeldef->label, seclabel->label) < 0)
6498
            goto error;
6499
        VIR_FREE(seclabel);
6500 6501 6502 6503 6504 6505

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

6508
    if (qemuSecurityCheckAllLabel(driver->securityManager, vm->def) < 0)
6509
        goto error;
6510
    if (qemuSecurityGenLabel(driver->securityManager, vm->def) < 0)
6511 6512
        goto error;

6513 6514 6515
    if (qemuDomainPerfRestart(vm) < 0)
        goto error;

6516
    VIR_DEBUG("Creating domain log file");
6517 6518
    if (!(logCtxt = qemuDomainLogContextNew(driver, vm,
                                            QEMU_DOMAIN_LOG_CONTEXT_MODE_ATTACH)))
6519
        goto error;
6520 6521

    VIR_DEBUG("Determining emulator version");
6522
    virObjectUnref(priv->qemuCaps);
6523 6524
    if (!(priv->qemuCaps = virQEMUCapsCacheLookupCopy(caps,
                                                      driver->qemuCapsCache,
6525 6526
                                                      vm->def->emulator,
                                                      vm->def->os.machine)))
6527
        goto error;
6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539

    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 已提交
6540
     * we also need to populate the PCI address set cache for later
6541 6542
     * use in hotplug
     */
6543
    VIR_DEBUG("Assigning domain PCI addresses");
6544 6545
    if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps,
                                   driver, vm, false)) < 0) {
6546
        goto error;
6547
    }
6548

6549
    if ((timestamp = virTimeStringNow()) == NULL)
6550
        goto error;
6551

6552
    qemuDomainLogContextWrite(logCtxt, "%s: attaching\n", timestamp);
6553
    VIR_FREE(timestamp);
6554

6555
    qemuDomainObjTaint(driver, vm, VIR_DOMAIN_TAINT_EXTERNAL_LAUNCH, logCtxt);
6556 6557

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

6561 6562
    if (qemuConnectAgent(driver, vm) < 0)
        goto error;
D
Daniel P. Berrange 已提交
6563

6564
    VIR_DEBUG("Detecting VCPU PIDs");
6565
    if (qemuDomainRefreshVcpuInfo(driver, vm, QEMU_ASYNC_JOB_NONE, false) < 0)
6566 6567
        goto error;

6568 6569 6570
    if (qemuDomainValidateVcpuInfo(vm) < 0)
        goto error;

6571 6572
    VIR_DEBUG("Detecting IOThread PIDs");
    if (qemuProcessDetectIOThreadPIDs(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
6573
        goto error;
6574 6575

    VIR_DEBUG("Getting initial memory amount");
6576
    qemuDomainObjEnterMonitor(driver, vm);
6577 6578 6579 6580 6581 6582 6583
    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)
6584
        goto error;
6585

6586
    if (running) {
6587 6588
        virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
                             VIR_DOMAIN_RUNNING_UNPAUSED);
6589 6590 6591
        if (vm->def->memballoon &&
            vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO &&
            vm->def->memballoon->period) {
6592
            qemuDomainObjEnterMonitor(driver, vm);
6593
            qemuMonitorSetMemoryStatsPeriod(priv->mon, vm->def->memballoon,
6594
                                            vm->def->memballoon->period);
6595 6596
            if (qemuDomainObjExitMonitor(driver, vm) < 0)
                goto error;
6597 6598
        }
    } else {
6599
        virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
6600
    }
6601 6602

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

6606 6607
    /* Run an hook to allow admins to do some magic */
    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
6608
        char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619
        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)
6620
            goto error;
6621 6622
    }

6623
    qemuDomainLogContextFree(logCtxt);
6624
    VIR_FREE(seclabel);
6625
    VIR_FREE(sec_managers);
6626
    virObjectUnref(cfg);
6627
    virObjectUnref(caps);
6628 6629 6630

    return 0;

6631 6632
 exit_monitor:
    ignore_value(qemuDomainObjExitMonitor(driver, vm));
6633
 error:
6634 6635 6636 6637 6638 6639
    /* 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);
6640 6641 6642

    qemuMonitorClose(priv->mon);
    priv->mon = NULL;
6643
    qemuDomainLogContextFree(logCtxt);
6644
    VIR_FREE(seclabel);
6645
    VIR_FREE(sec_managers);
6646 6647
    if (seclabelgen)
        virSecurityLabelDefFree(seclabeldef);
6648
    virDomainChrSourceDefFree(monConfig);
6649
    virObjectUnref(cfg);
6650
    virObjectUnref(caps);
6651 6652 6653 6654
    return -1;
}


6655
static virDomainObjPtr
6656 6657 6658
qemuProcessAutoDestroy(virDomainObjPtr dom,
                       virConnectPtr conn,
                       void *opaque)
6659
{
6660
    virQEMUDriverPtr driver = opaque;
6661
    qemuDomainObjPrivatePtr priv = dom->privateData;
6662
    virObjectEventPtr event = NULL;
6663
    unsigned int stopFlags = 0;
6664

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

6667 6668
    virObjectRef(dom);

6669 6670 6671
    if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;

6672 6673
    if (priv->job.asyncJob) {
        VIR_DEBUG("vm=%s has long-term job active, cancelling",
6674
                  dom->def->name);
6675
        qemuDomainObjDiscardAsyncJob(driver, dom);
6676 6677 6678
    }

    VIR_DEBUG("Killing domain");
6679

6680 6681 6682 6683 6684
    if (qemuProcessBeginStopJob(driver, dom, QEMU_JOB_DESTROY, true) < 0)
        goto cleanup;

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

6686
    virDomainAuditStop(dom, "destroyed");
6687
    event = virDomainEventLifecycleNewFromObj(dom,
6688 6689
                                     VIR_DOMAIN_EVENT_STOPPED,
                                     VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
6690

6691 6692
    qemuDomainObjEndJob(driver, dom);

6693
    qemuDomainRemoveInactive(driver, dom);
6694

6695
    qemuDomainEventQueue(driver, event);
6696

6697
 cleanup:
6698
    virDomainObjEndAPI(&dom);
6699
    return dom;
6700 6701
}

6702
int qemuProcessAutoDestroyAdd(virQEMUDriverPtr driver,
6703 6704 6705
                              virDomainObjPtr vm,
                              virConnectPtr conn)
{
6706
    VIR_DEBUG("vm=%s, conn=%p", vm->def->name, conn);
6707 6708
    return virCloseCallbacksSet(driver->closeCallbacks, vm, conn,
                                qemuProcessAutoDestroy);
6709 6710
}

6711
int qemuProcessAutoDestroyRemove(virQEMUDriverPtr driver,
6712 6713
                                 virDomainObjPtr vm)
{
6714
    int ret;
6715
    VIR_DEBUG("vm=%s", vm->def->name);
6716 6717 6718
    ret = virCloseCallbacksUnset(driver->closeCallbacks, vm,
                                 qemuProcessAutoDestroy);
    return ret;
6719
}
6720

6721
bool qemuProcessAutoDestroyActive(virQEMUDriverPtr driver,
6722 6723
                                  virDomainObjPtr vm)
{
6724
    virCloseCallback cb;
6725
    VIR_DEBUG("vm=%s", vm->def->name);
6726
    cb = virCloseCallbacksGet(driver->closeCallbacks, vm, NULL);
6727
    return cb == qemuProcessAutoDestroy;
6728
}
6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751


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];
6752
        qemuDomainDiskPrivatePtr diskpriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
6753 6754
        struct qemuDomainDiskInfo *info;

6755 6756
        if (!(info = virHashLookup(table, disk->info.alias)))
            continue;
6757

6758 6759
        if (info->removable) {
            if (info->empty)
6760 6761
                ignore_value(virDomainDiskSetSource(disk, NULL));

6762 6763 6764 6765 6766 6767
            if (info->tray) {
                if (info->tray_open)
                    disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
                else
                    disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
            }
6768
        }
6769 6770 6771 6772

        /* fill in additional data */
        diskpriv->removable = info->removable;
        diskpriv->tray = info->tray;
6773 6774 6775 6776 6777 6778 6779 6780
    }

    ret = 0;

 cleanup:
    virHashFree(table);
    return ret;
}