libvirt.c 623.8 KB
Newer Older
D
Daniel P. Berrange 已提交
1
/*
2
 * libvirt.c: Main interfaces for the libvirt library to handle virtualization
D
Daniel Veillard 已提交
3 4
 *           domains from a process running in domain 0
 *
5
 * Copyright (C) 2005-2006, 2008-2013 Red Hat, Inc.
D
Daniel Veillard 已提交
6
 *
O
Osier Yang 已提交
7 8 9 10 11 12 13 14 15 16 17
 * 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
18
 * License along with this library.  If not, see
O
Osier Yang 已提交
19
 * <http://www.gnu.org/licenses/>.
D
Daniel Veillard 已提交
20 21 22 23
 *
 * Daniel Veillard <veillard@redhat.com>
 */

24
#include <config.h>
D
Daniel Veillard 已提交
25

26
#include <stdio.h>
27
#include <stdlib.h>
28
#include <string.h>
29 30 31
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
E
Eric Blake 已提交
32
#include <sys/wait.h>
33
#include <time.h>
34

35 36
#include <libxml/parser.h>
#include <libxml/xpath.h>
37 38
#include "getpass.h"

39
#ifdef HAVE_WINSOCK2_H
40
# include <winsock2.h>
41
#endif
42

43
#ifdef WITH_CURL
44 45 46
# include <curl/curl.h>
#endif

47
#include "virerror.h"
48
#include "virlog.h"
49
#include "datatypes.h"
50
#include "driver.h"
51

52
#include "viruuid.h"
53
#include "viralloc.h"
54
#include "configmake.h"
55
#include "intprops.h"
56
#include "virconf.h"
57
#if WITH_GNUTLS
58
# include <gcrypt.h>
59 60
# include "rpc/virnettlscontext.h"
#endif
61
#include "vircommand.h"
62
#include "virfile.h"
63
#include "virrandom.h"
M
Martin Kletzander 已提交
64
#include "viruri.h"
65
#include "virthread.h"
66
#include "virstring.h"
E
Eric Blake 已提交
67
#include "virutil.h"
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
#ifdef WITH_TEST
# include "test/test_driver.h"
#endif
#ifdef WITH_REMOTE
# include "remote/remote_driver.h"
#endif
#ifdef WITH_OPENVZ
# include "openvz/openvz_driver.h"
#endif
#ifdef WITH_VMWARE
# include "vmware/vmware_driver.h"
#endif
#ifdef WITH_PHYP
# include "phyp/phyp_driver.h"
#endif
#ifdef WITH_VBOX
# include "vbox/vbox_driver.h"
#endif
#ifdef WITH_ESX
# include "esx/esx_driver.h"
#endif
#ifdef WITH_HYPERV
# include "hyperv/hyperv_driver.h"
#endif
#ifdef WITH_XENAPI
# include "xenapi/xenapi_driver.h"
95
#endif
D
Dmitry Guryanov 已提交
96 97 98
#ifdef WITH_PARALLELS
# include "parallels/parallels_driver.h"
#endif
99

100 101
#define VIR_FROM_THIS VIR_FROM_NONE

D
Daniel Veillard 已提交
102 103 104
/*
 * TODO:
 * - use lock to protect against concurrent accesses ?
D
Daniel Veillard 已提交
105
 * - use reference counting to guarantee coherent pointer state ?
D
Daniel Veillard 已提交
106 107
 */

108
#define MAX_DRIVERS 20
109

110
static virDriverPtr virDriverTab[MAX_DRIVERS];
111
static int virDriverTabCount = 0;
112
static virNetworkDriverPtr virNetworkDriverTab[MAX_DRIVERS];
113
static int virNetworkDriverTabCount = 0;
D
Daniel Veillard 已提交
114 115
static virInterfaceDriverPtr virInterfaceDriverTab[MAX_DRIVERS];
static int virInterfaceDriverTabCount = 0;
116 117
static virStorageDriverPtr virStorageDriverTab[MAX_DRIVERS];
static int virStorageDriverTabCount = 0;
118 119
static virNodeDeviceDriverPtr virNodeDeviceDriverTab[MAX_DRIVERS];
static int virNodeDeviceDriverTabCount = 0;
120 121
static virSecretDriverPtr virSecretDriverTab[MAX_DRIVERS];
static int virSecretDriverTabCount = 0;
S
Stefan Berger 已提交
122 123
static virNWFilterDriverPtr virNWFilterDriverTab[MAX_DRIVERS];
static int virNWFilterDriverTabCount = 0;
A
Atsushi SAKAI 已提交
124
#ifdef WITH_LIBVIRTD
125 126
static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
static int virStateDriverTabCount = 0;
A
Atsushi SAKAI 已提交
127
#endif
128

129

130 131
#if defined(POLKIT_AUTH)
static int virConnectAuthGainPolkit(const char *privilege) {
E
Eric Blake 已提交
132 133 134
    virCommandPtr cmd;
    int status;
    int ret = -1;
135 136 137 138

    if (getuid() == 0)
        return 0;

E
Eric Blake 已提交
139 140
    cmd = virCommandNewArgList(POLKIT_AUTH, "--obtain", privilege, NULL);
    if (virCommandRun(cmd, &status) < 0 ||
141
        status > 0)
E
Eric Blake 已提交
142
        goto cleanup;
143

E
Eric Blake 已提交
144 145 146 147
    ret = 0;
cleanup:
    virCommandFree(cmd);
    return ret;
148 149 150
}
#endif

151 152 153 154 155 156 157 158
static int virConnectAuthCallbackDefault(virConnectCredentialPtr cred,
                                         unsigned int ncred,
                                         void *cbdata ATTRIBUTE_UNUSED) {
    int i;

    for (i = 0 ; i < ncred ; i++) {
        char buf[1024];
        char *bufptr = buf;
159
        size_t len;
160 161

        switch (cred[i].type) {
162 163 164 165
        case VIR_CRED_EXTERNAL: {
            if (STRNEQ(cred[i].challenge, "PolicyKit"))
                return -1;

166
#if defined(POLKIT_AUTH)
167
            if (virConnectAuthGainPolkit(cred[i].prompt) < 0)
168
                return -1;
169 170 171 172 173 174 175
#else
            /*
             * Ignore & carry on. Although we can't auth
             * directly, the user may have authenticated
             * themselves already outside context of libvirt
             */
#endif
176 177
            break;
        }
178

179 180 181 182
        case VIR_CRED_USERNAME:
        case VIR_CRED_AUTHNAME:
        case VIR_CRED_ECHOPROMPT:
        case VIR_CRED_REALM:
183
            if (printf("%s: ", cred[i].prompt) < 0)
184 185 186 187
                return -1;
            if (fflush(stdout) != 0)
                return -1;

188 189 190 191 192 193 194
            if (!fgets(buf, sizeof(buf), stdin)) {
                if (feof(stdin)) { /* Treat EOF as "" */
                    buf[0] = '\0';
                    break;
                }
                return -1;
            }
195 196 197
            len = strlen(buf);
            if (len != 0 && buf[len-1] == '\n')
                buf[len-1] = '\0';
198 199 200 201
            break;

        case VIR_CRED_PASSPHRASE:
        case VIR_CRED_NOECHOPROMPT:
202
            if (printf("%s: ", cred[i].prompt) < 0)
203 204 205 206
                return -1;
            if (fflush(stdout) != 0)
                return -1;

207 208 209 210
            bufptr = getpass("");
            if (!bufptr)
                return -1;
            break;
211 212 213

        default:
            return -1;
214 215
        }

D
Daniel P. Berrange 已提交
216
        if (cred[i].type != VIR_CRED_EXTERNAL) {
217 218 219
            if (VIR_STRDUP(cred[i].result,
                           STREQ(bufptr, "") && cred[i].defresult ?
                           cred[i].defresult : bufptr) < 0)
D
Daniel P. Berrange 已提交
220 221 222
                return -1;
            cred[i].resultlen = strlen(cred[i].result);
        }
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    }

    return 0;
}

/* Don't typically want VIR_CRED_USERNAME. It enables you to authenticate
 * as one user, and act as another. It just results in annoying
 * prompts for the username twice & is very rarely what you want
 */
static int virConnectCredTypeDefault[] = {
    VIR_CRED_AUTHNAME,
    VIR_CRED_ECHOPROMPT,
    VIR_CRED_REALM,
    VIR_CRED_PASSPHRASE,
    VIR_CRED_NOECHOPROMPT,
238
    VIR_CRED_EXTERNAL,
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
};

static virConnectAuth virConnectAuthDefault = {
    virConnectCredTypeDefault,
    sizeof(virConnectCredTypeDefault)/sizeof(int),
    virConnectAuthCallbackDefault,
    NULL,
};

/*
 * virConnectAuthPtrDefault
 *
 * A default implementation of the authentication callbacks. This
 * implementation is suitable for command line based tools. It will
 * prompt for username, passwords, realm and one time keys as needed.
 * It will print on STDOUT, and read from STDIN. If this is not
 * suitable for the application's needs an alternative implementation
 * should be provided.
 */
virConnectAuthPtr virConnectAuthPtrDefault = &virConnectAuthDefault;

260 261
#if HAVE_WINSOCK2_H
static int
262
winsock_init(void)
263 264 265 266 267 268 269
{
    WORD winsock_version, err;
    WSADATA winsock_data;

    /* http://msdn2.microsoft.com/en-us/library/ms742213.aspx */
    winsock_version = MAKEWORD (2, 2);
    err = WSAStartup (winsock_version, &winsock_data);
J
Jim Meyering 已提交
270
    return err == 0 ? 0 : -1;
271 272 273
}
#endif

274

275
#ifdef WITH_GNUTLS
276 277
static int virTLSMutexInit(void **priv)
{
D
Daniel P. Berrange 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
    virMutexPtr lock = NULL;

    if (VIR_ALLOC(lock) < 0)
        return ENOMEM;

    if (virMutexInit(lock) < 0) {
        VIR_FREE(lock);
        return errno;
    }

    *priv = lock;
    return 0;
}

static int virTLSMutexDestroy(void **priv)
{
    virMutexPtr lock = *priv;
    virMutexDestroy(lock);
    VIR_FREE(lock);
    return 0;
}

static int virTLSMutexLock(void **priv)
{
    virMutexPtr lock = *priv;
    virMutexLock(lock);
    return 0;
}

static int virTLSMutexUnlock(void **priv)
{
    virMutexPtr lock = *priv;
    virMutexUnlock(lock);
    return 0;
}

static struct gcry_thread_cbs virTLSThreadImpl = {
315
    /* GCRY_THREAD_OPTION_VERSION was added in gcrypt 1.4.2 */
316
# ifdef GCRY_THREAD_OPTION_VERSION
D
Daniel P. Berrange 已提交
317
    (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)),
318
# else
319
    GCRY_THREAD_OPTION_PTHREAD,
320
# endif
D
Daniel P. Berrange 已提交
321 322 323 324 325 326 327
    NULL,
    virTLSMutexInit,
    virTLSMutexDestroy,
    virTLSMutexLock,
    virTLSMutexUnlock,
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
328
#endif
D
Daniel P. Berrange 已提交
329

330
/* Helper macros to implement VIR_DOMAIN_DEBUG using just C99.  This
331
 * assumes you pass fewer than 15 arguments to VIR_DOMAIN_DEBUG, but
332 333 334 335 336 337
 * can easily be expanded if needed.
 *
 * Note that gcc provides extensions of "define a(b...) b" or
 * "define a(b,...) b,##__VA_ARGS__" as a means of eliding a comma
 * when no var-args are present, but we don't want to require gcc.
 */
338 339
#define VIR_ARG15(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15
#define VIR_HAS_COMMA(...) VIR_ARG15(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
340 341 342 343 344 345 346 347 348 349 350

/* Form the name VIR_DOMAIN_DEBUG_[01], then call that macro,
 * according to how many arguments are present.  Two-phase due to
 * macro expansion rules.  */
#define VIR_DOMAIN_DEBUG_EXPAND(a, b, ...)      \
    VIR_DOMAIN_DEBUG_PASTE(a, b, __VA_ARGS__)
#define VIR_DOMAIN_DEBUG_PASTE(a, b, ...)       \
    a##b(__VA_ARGS__)

/* Internal use only, when VIR_DOMAIN_DEBUG has one argument.  */
#define VIR_DOMAIN_DEBUG_0(dom)                 \
E
Eric Blake 已提交
351
    VIR_DOMAIN_DEBUG_2(dom, "%s", "")
352 353

/* Internal use only, when VIR_DOMAIN_DEBUG has three or more arguments.  */
E
Eric Blake 已提交
354 355 356 357 358
#define VIR_DOMAIN_DEBUG_1(dom, fmt, ...)       \
    VIR_DOMAIN_DEBUG_2(dom, ", " fmt, __VA_ARGS__)

/* Internal use only, with final format.  */
#define VIR_DOMAIN_DEBUG_2(dom, fmt, ...)                               \
359 360 361 362 363 364 365 366 367 368 369
    do {                                                                \
        char _uuidstr[VIR_UUID_STRING_BUFLEN];                          \
        const char *_domname = NULL;                                    \
                                                                        \
        if (!VIR_IS_DOMAIN(dom)) {                                      \
            memset(_uuidstr, 0, sizeof(_uuidstr));                      \
        } else {                                                        \
            virUUIDFormat((dom)->uuid, _uuidstr);                       \
            _domname = (dom)->name;                                     \
        }                                                               \
                                                                        \
E
Eric Blake 已提交
370
        VIR_DEBUG("dom=%p, (VM: name=%s, uuid=%s)" fmt,                 \
371 372
                  dom, NULLSTR(_domname), _uuidstr, __VA_ARGS__);       \
    } while (0)
373

374 375 376 377 378 379 380 381 382 383
/**
 * VIR_DOMAIN_DEBUG:
 * @dom: domain
 * @fmt: optional format for additional information
 * @...: optional arguments corresponding to @fmt.
 */
#define VIR_DOMAIN_DEBUG(...)                           \
    VIR_DOMAIN_DEBUG_EXPAND(VIR_DOMAIN_DEBUG_,          \
                            VIR_HAS_COMMA(__VA_ARGS__), \
                            __VA_ARGS__)
D
Daniel P. Berrange 已提交
384

385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
/**
 * VIR_UUID_DEBUG:
 * @conn: connection
 * @uuid: possibly null UUID array
 */
#define VIR_UUID_DEBUG(conn, uuid)                              \
    do {                                                        \
        if (uuid) {                                             \
            char _uuidstr[VIR_UUID_STRING_BUFLEN];              \
            virUUIDFormat(uuid, _uuidstr);                      \
            VIR_DEBUG("conn=%p, uuid=%s", conn, _uuidstr);      \
        } else {                                                \
            VIR_DEBUG("conn=%p, uuid=(null)", conn);            \
        }                                                       \
    } while (0)

401

402 403
static bool virGlobalError = false;
static virOnceControl virGlobalOnce = VIR_ONCE_CONTROL_INITIALIZER;
404

405 406 407
static void
virGlobalInit(void)
{
408
    if (virThreadInitialize() < 0 ||
409
        virErrorInitialize() < 0)
410
        goto error;
411

412
#ifdef WITH_GNUTLS
413 414 415 416 417 418 419 420 421 422 423 424 425
    /*
     * This sequence of API calls it copied exactly from
     * gnutls 2.12.23 source lib/gcrypt/init.c, with
     * exception that GCRYCTL_ENABLE_QUICK_RANDOM, is
     * dropped
     */
    if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0) {
        gcry_control(GCRYCTL_SET_THREAD_CBS, &virTLSThreadImpl);
        gcry_check_version(NULL);

        gcry_control(GCRYCTL_DISABLE_SECMEM, NULL, 0);
        gcry_control(GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
    }
426
#endif
D
Daniel P. Berrange 已提交
427

428
    virLogSetFromEnv();
429

430
#ifdef WITH_GNUTLS
431
    virNetTLSInit();
432
#endif
433

434
#if WITH_CURL
435 436 437
    curl_global_init(CURL_GLOBAL_DEFAULT);
#endif

438
    VIR_DEBUG("register drivers");
439

440
#if HAVE_WINSOCK2_H
441
    if (winsock_init() == -1)
442
        goto error;
443 444
#endif

445
    if (!bindtextdomain(PACKAGE, LOCALEDIR))
446
        goto error;
447

448
    /*
449 450
     * Note that the order is important: the first ones have a higher
     * priority when calling virConnectOpen.
451
     */
452
#ifdef WITH_TEST
453 454
    if (testRegister() == -1)
        goto error;
455 456
#endif
#ifdef WITH_OPENVZ
457 458
    if (openvzRegister() == -1)
        goto error;
459 460
#endif
#ifdef WITH_VMWARE
461 462
    if (vmwareRegister() == -1)
        goto error;
463 464
#endif
#ifdef WITH_PHYP
465 466
    if (phypRegister() == -1)
        goto error;
467 468
#endif
#ifdef WITH_VBOX
469 470
    if (vboxRegister() == -1)
        goto error;
471 472
#endif
#ifdef WITH_ESX
473 474
    if (esxRegister() == -1)
        goto error;
475 476
#endif
#ifdef WITH_HYPERV
477 478
    if (hypervRegister() == -1)
        goto error;
479 480
#endif
#ifdef WITH_XENAPI
481 482
    if (xenapiRegister() == -1)
        goto error;
483
#endif
D
Dmitry Guryanov 已提交
484
#ifdef WITH_PARALLELS
485 486
    if (parallelsRegister() == -1)
        goto error;
D
Dmitry Guryanov 已提交
487
#endif
488
#ifdef WITH_REMOTE
489
    if (remoteRegister() == -1)
490
        goto error;
491
#endif
D
Daniel P. Berrange 已提交
492

493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
    return;

error:
    virGlobalError = true;
}

/**
 * virInitialize:
 *
 * Initialize the library.
 *
 * This method is invoked automatically by any of the virConnectOpen API
 * calls. Since release 1.0.0, there is no need to call this method even
 * in a multithreaded application, since initialization is performed in
 * a thread safe manner.
 *
 * The only time it would be necessary to call virInitialize is if the
 * application did not invoke virConnectOpen as its first API call.
 *
 * Returns 0 in case of success, -1 in case of error
 */
int
virInitialize(void)
{
    if (virOnce(&virGlobalOnce, virGlobalInit) < 0)
        return -1;

    if (virGlobalError)
        return -1;
522
    return 0;
523 524
}

525 526
#ifdef WIN32
BOOL WINAPI
527
DllMain(HINSTANCE instance, DWORD reason, LPVOID ignore);
528 529

BOOL WINAPI
530 531 532
DllMain(HINSTANCE instance ATTRIBUTE_UNUSED,
        DWORD reason,
        LPVOID ignore ATTRIBUTE_UNUSED)
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
{
    switch (reason) {
    case DLL_PROCESS_ATTACH:
        virInitialize();
        break;

    case DLL_THREAD_ATTACH:
        /* Nothing todo in libvirt yet */
        break;

    case DLL_THREAD_DETACH:
        /* Release per-thread local data */
        virThreadOnExit();
        break;

    case DLL_PROCESS_DETACH:
        /* Don't bother releasing per-thread data
           since (hopefully) windows cleans up
           everything on process exit */
        break;
    }

    return TRUE;
}
#endif
558

559
#define virLibConnError(code, ...)                                \
560
    virReportErrorHelper(VIR_FROM_NONE, code, __FILE__,           \
561 562
                         __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibDomainError(code, ...)                              \
563
    virReportErrorHelper(VIR_FROM_DOM, code, __FILE__,            \
564 565
                         __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibNetworkError(code, ...)                             \
566
    virReportErrorHelper(VIR_FROM_NETWORK, code, __FILE__,        \
567 568
                         __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibStoragePoolError(code, ...)                         \
569
    virReportErrorHelper(VIR_FROM_STORAGE, code, __FILE__,        \
570 571
                         __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibStorageVolError(code, ...)                          \
572
    virReportErrorHelper(VIR_FROM_STORAGE, code, __FILE__,        \
573 574
                         __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibInterfaceError(code, ...)                           \
575
    virReportErrorHelper(VIR_FROM_INTERFACE, code, __FILE__,      \
576 577
                         __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibNodeDeviceError(code, ...)                          \
578
    virReportErrorHelper(VIR_FROM_NODEDEV, code, __FILE__,        \
579 580
                         __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibSecretError(code, ...)                              \
581
    virReportErrorHelper(VIR_FROM_SECRET, code, __FILE__,         \
582 583
                         __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibStreamError(code, ...)                              \
584
    virReportErrorHelper(VIR_FROM_STREAMS, code, __FILE__,        \
585 586
                         __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibNWFilterError(code, ...)                            \
587
    virReportErrorHelper(VIR_FROM_NWFILTER, code, __FILE__,       \
588
                         __FUNCTION__, __LINE__, __VA_ARGS__)
589 590
#define virLibDomainSnapshotError(code, ...)                       \
    virReportErrorHelper(VIR_FROM_DOMAIN_SNAPSHOT, code, __FILE__, \
591
                         __FUNCTION__, __LINE__, __VA_ARGS__)
592

C
Chris Lalancette 已提交
593

594 595 596 597 598 599 600 601 602 603 604
/**
 * virRegisterNetworkDriver:
 * @driver: pointer to a network driver block
 *
 * Register a network virtualization driver
 *
 * Returns the driver priority or -1 in case of error.
 */
int
virRegisterNetworkDriver(virNetworkDriverPtr driver)
{
605
    virCheckNonNullArgReturn(driver, -1);
606 607

    if (virNetworkDriverTabCount >= MAX_DRIVERS) {
608 609 610
        virLibConnError(VIR_ERR_INTERNAL_ERROR,
                        _("Too many drivers, cannot register %s"),
                        driver->name);
611
        return -1;
612 613
    }

614
    VIR_DEBUG("registering %s as network driver %d",
615 616
           driver->name, virNetworkDriverTabCount);

617 618
    virNetworkDriverTab[virNetworkDriverTabCount] = driver;
    return virNetworkDriverTabCount++;
619 620
}

D
Daniel Veillard 已提交
621 622
/**
 * virRegisterInterfaceDriver:
L
Laine Stump 已提交
623
 * @driver: pointer to an interface driver block
D
Daniel Veillard 已提交
624
 *
L
Laine Stump 已提交
625
 * Register an interface virtualization driver
D
Daniel Veillard 已提交
626 627 628 629 630 631
 *
 * Returns the driver priority or -1 in case of error.
 */
int
virRegisterInterfaceDriver(virInterfaceDriverPtr driver)
{
632
    virCheckNonNullArgReturn(driver, -1);
D
Daniel Veillard 已提交
633 634

    if (virInterfaceDriverTabCount >= MAX_DRIVERS) {
635 636 637
        virLibConnError(VIR_ERR_INTERNAL_ERROR,
                        _("Too many drivers, cannot register %s"),
                        driver->name);
638
        return -1;
D
Daniel Veillard 已提交
639 640
    }

641
    VIR_DEBUG("registering %s as interface driver %d",
D
Daniel Veillard 已提交
642 643 644 645 646 647
           driver->name, virInterfaceDriverTabCount);

    virInterfaceDriverTab[virInterfaceDriverTabCount] = driver;
    return virInterfaceDriverTabCount++;
}

648 649 650 651 652 653 654 655 656 657 658
/**
 * virRegisterStorageDriver:
 * @driver: pointer to a storage driver block
 *
 * Register a storage virtualization driver
 *
 * Returns the driver priority or -1 in case of error.
 */
int
virRegisterStorageDriver(virStorageDriverPtr driver)
{
659
    virCheckNonNullArgReturn(driver, -1);
660 661

    if (virStorageDriverTabCount >= MAX_DRIVERS) {
662 663 664
        virLibConnError(VIR_ERR_INTERNAL_ERROR,
                        _("Too many drivers, cannot register %s"),
                        driver->name);
665
        return -1;
666 667
    }

668
    VIR_DEBUG("registering %s as storage driver %d",
669 670
           driver->name, virStorageDriverTabCount);

671 672 673 674
    virStorageDriverTab[virStorageDriverTabCount] = driver;
    return virStorageDriverTabCount++;
}

675
/**
676
 * virRegisterNodeDeviceDriver:
677 678 679 680 681 682 683
 * @driver: pointer to a device monitor block
 *
 * Register a device monitor
 *
 * Returns the driver priority or -1 in case of error.
 */
int
684
virRegisterNodeDeviceDriver(virNodeDeviceDriverPtr driver)
685
{
686
    virCheckNonNullArgReturn(driver, -1);
687

688
    if (virNodeDeviceDriverTabCount >= MAX_DRIVERS) {
689 690 691
        virLibConnError(VIR_ERR_INTERNAL_ERROR,
                        _("Too many drivers, cannot register %s"),
                        driver->name);
692
        return -1;
693 694
    }

695
    VIR_DEBUG("registering %s as device driver %d",
696
           driver->name, virNodeDeviceDriverTabCount);
697

698 699
    virNodeDeviceDriverTab[virNodeDeviceDriverTabCount] = driver;
    return virNodeDeviceDriverTabCount++;
700 701
}

702 703 704 705 706 707 708 709 710 711 712
/**
 * virRegisterSecretDriver:
 * @driver: pointer to a secret driver block
 *
 * Register a secret driver
 *
 * Returns the driver priority or -1 in case of error.
 */
int
virRegisterSecretDriver(virSecretDriverPtr driver)
{
713
    virCheckNonNullArgReturn(driver, -1);
714 715

    if (virSecretDriverTabCount >= MAX_DRIVERS) {
716 717 718
        virLibConnError(VIR_ERR_INTERNAL_ERROR,
                        _("Too many drivers, cannot register %s"),
                        driver->name);
719
        return -1;
720 721
    }

722
    VIR_DEBUG("registering %s as secret driver %d",
723 724 725 726 727 728
           driver->name, virSecretDriverTabCount);

    virSecretDriverTab[virSecretDriverTabCount] = driver;
    return virSecretDriverTabCount++;
}

S
Stefan Berger 已提交
729 730 731 732 733 734 735 736 737 738 739
/**
 * virRegisterNWFilterDriver:
 * @driver: pointer to a network filter driver block
 *
 * Register a network filter virtualization driver
 *
 * Returns the driver priority or -1 in case of error.
 */
int
virRegisterNWFilterDriver(virNWFilterDriverPtr driver)
{
740
    virCheckNonNullArgReturn(driver, -1);
S
Stefan Berger 已提交
741 742

    if (virNWFilterDriverTabCount >= MAX_DRIVERS) {
743 744 745
        virLibConnError(VIR_ERR_INTERNAL_ERROR,
                        _("Too many drivers, cannot register %s"),
                        driver->name);
S
Stefan Berger 已提交
746 747 748
        return -1;
    }

749
    VIR_DEBUG("registering %s as network filter driver %d",
S
Stefan Berger 已提交
750 751 752 753 754 755 756
           driver->name, virNWFilterDriverTabCount);

    virNWFilterDriverTab[virNWFilterDriverTabCount] = driver;
    return virNWFilterDriverTabCount++;
}


757 758 759 760 761 762 763 764 765 766 767
/**
 * virRegisterDriver:
 * @driver: pointer to a driver block
 *
 * Register a virtualization driver
 *
 * Returns the driver priority or -1 in case of error.
 */
int
virRegisterDriver(virDriverPtr driver)
{
768
    VIR_DEBUG("driver=%p name=%s", driver, driver ? NULLSTR(driver->name) : "(null)");
769

770
    virCheckNonNullArgReturn(driver, -1);
771 772

    if (virDriverTabCount >= MAX_DRIVERS) {
773 774 775
        virLibConnError(VIR_ERR_INTERNAL_ERROR,
                        _("Too many drivers, cannot register %s"),
                        driver->name);
776
        return -1;
777 778
    }

779
    VIR_DEBUG("registering %s as driver %d",
780 781
           driver->name, virDriverTabCount);

782 783
    virDriverTab[virDriverTabCount] = driver;
    return virDriverTabCount++;
784 785
}

A
Atsushi SAKAI 已提交
786
#ifdef WITH_LIBVIRTD
787 788 789 790 791 792 793 794 795 796 797
/**
 * virRegisterStateDriver:
 * @driver: pointer to a driver block
 *
 * Register a virtualization driver
 *
 * Returns the driver priority or -1 in case of error.
 */
int
virRegisterStateDriver(virStateDriverPtr driver)
{
798
    virCheckNonNullArgReturn(driver, -1);
799 800

    if (virStateDriverTabCount >= MAX_DRIVERS) {
801 802 803
        virLibConnError(VIR_ERR_INTERNAL_ERROR,
                        _("Too many drivers, cannot register %s"),
                        driver->name);
804
        return -1;
805 806 807 808 809 810
    }

    virStateDriverTab[virStateDriverTabCount] = driver;
    return virStateDriverTabCount++;
}

811 812
/**
 * virStateInitialize:
813
 * @privileged: set to true if running with root privilege, false otherwise
814 815
 * @callback: callback to invoke to inhibit shutdown of the daemon
 * @opaque: data to pass to @callback
816 817 818
 *
 * Initialize all virtualization drivers.
 *
819
 * Returns 0 if all succeed, -1 upon any failure.
820
 */
821 822 823 824
int virStateInitialize(bool privileged,
                       virStateInhibitCallback callback,
                       void *opaque)
{
825
    int i;
826 827 828 829 830

    if (virInitialize() < 0)
        return -1;

    for (i = 0 ; i < virStateDriverTabCount ; i++) {
831
        if (virStateDriverTab[i]->stateInitialize) {
832
            VIR_DEBUG("Running global init for %s state driver",
833
                      virStateDriverTab[i]->name);
834 835 836
            if (virStateDriverTab[i]->stateInitialize(privileged,
                                                      callback,
                                                      opaque) < 0) {
837 838 839 840
                VIR_ERROR(_("Initialization of %s state driver failed"),
                          virStateDriverTab[i]->name);
                return -1;
            }
841
        }
842
    }
843
    return 0;
844 845
}

846 847 848 849 850
/**
 * virStateCleanup:
 *
 * Run each virtualization driver's cleanup method.
 *
851
 * Returns 0 if all succeed, -1 upon any failure.
852
 */
D
Daniel P. Berrange 已提交
853
int virStateCleanup(void) {
854 855 856
    int i, ret = 0;

    for (i = 0 ; i < virStateDriverTabCount ; i++) {
857 858
        if (virStateDriverTab[i]->stateCleanup &&
            virStateDriverTab[i]->stateCleanup() < 0)
859 860 861 862 863
            ret = -1;
    }
    return ret;
}

864 865 866 867 868
/**
 * virStateReload:
 *
 * Run each virtualization driver's reload method.
 *
869
 * Returns 0 if all succeed, -1 upon any failure.
870
 */
D
Daniel P. Berrange 已提交
871
int virStateReload(void) {
872 873 874
    int i, ret = 0;

    for (i = 0 ; i < virStateDriverTabCount ; i++) {
875 876
        if (virStateDriverTab[i]->stateReload &&
            virStateDriverTab[i]->stateReload() < 0)
877 878 879 880 881
            ret = -1;
    }
    return ret;
}

882 883 884 885 886 887 888 889 890 891 892
/**
 * virStateStop:
 *
 * Run each virtualization driver's "stop" method.
 *
 * Returns 0 if successful, -1 on failure
 */
int virStateStop(void) {
    int i, ret = 0;

    for (i = 0 ; i < virStateDriverTabCount ; i++) {
893 894
        if (virStateDriverTab[i]->stateStop &&
            virStateDriverTab[i]->stateStop())
895 896 897 898 899
            ret = 1;
    }
    return ret;
}

A
Atsushi SAKAI 已提交
900
#endif
901

902 903


904 905 906
/**
 * virGetVersion:
 * @libVer: return value for the library version (OUT)
907 908 909 910 911 912 913 914 915 916 917 918 919
 * @type: ignored; pass NULL
 * @typeVer: pass NULL; for historical purposes duplicates @libVer if
 * non-NULL
 *
 * Provides version information. @libVer is the version of the
 * library and will always be set unless an error occurs, in which case
 * an error code will be returned. @typeVer exists for historical
 * compatibility; if it is not NULL it will duplicate @libVer (it was
 * originally intended to return hypervisor information based on @type,
 * but due to the design of remote clients this is not reliable). To
 * get the version of the running hypervisor use the virConnectGetVersion
 * function instead. To get the libvirt library version used by a
 * connection use the virConnectGetLibVersion instead.
920 921 922 923 924
 *
 * Returns -1 in case of failure, 0 otherwise, and values for @libVer and
 *       @typeVer have the format major * 1,000,000 + minor * 1,000 + release.
 */
int
925
virGetVersion(unsigned long *libVer, const char *type ATTRIBUTE_UNUSED,
926 927
              unsigned long *typeVer)
{
928
    VIR_DEBUG("libVir=%p, type=%s, typeVer=%p", libVer, type, typeVer);
929

930 931
    if (virInitialize() < 0)
        goto error;
932

933
    if (libVer == NULL)
934
        goto error;
935 936
    *libVer = LIBVIR_VERSION_NUMBER;

937
    if (typeVer != NULL)
938 939
        *typeVer = LIBVIR_VERSION_NUMBER;

940
    return 0;
941 942 943 944

error:
    virDispatchError(NULL);
    return -1;
945 946
}

947
static char *
948
virConnectGetConfigFilePath(void)
949 950 951 952 953 954 955
{
    char *path;
    if (geteuid() == 0) {
        if (virAsprintf(&path, "%s/libvirt/libvirt.conf",
                        SYSCONFDIR) < 0)
            goto no_memory;
    } else {
956
        char *userdir = virGetUserConfigDirectory();
957 958 959
        if (!userdir)
            goto error;

960
        if (virAsprintf(&path, "%s/libvirt.conf",
961 962
                        userdir) < 0) {
            VIR_FREE(userdir);
963
            goto no_memory;
964 965
        }
        VIR_FREE(userdir);
966 967 968 969 970 971 972 973 974 975
    }

    return path;

no_memory:
    virReportOOMError();
error:
    return NULL;
}

976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
static int
virConnectGetConfigFile(virConfPtr *conf)
{
    char *filename = NULL;
    int ret = -1;

    *conf = NULL;

    if (!(filename = virConnectGetConfigFilePath()))
        goto cleanup;

    if (!virFileExists(filename)) {
        ret = 0;
        goto cleanup;
    }

    VIR_DEBUG("Loading config file '%s'", filename);
    if (!(*conf = virConfReadFile(filename, 0)))
        goto cleanup;

    ret = 0;

cleanup:
    VIR_FREE(filename);
    return ret;
}

1003 1004 1005 1006 1007 1008
#define URI_ALIAS_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"

static int
virConnectOpenFindURIAliasMatch(virConfValuePtr value, const char *alias, char **uri)
{
    virConfValuePtr entry;
W
Wen Ruo Lv 已提交
1009 1010
    size_t alias_len;

1011 1012 1013 1014 1015 1016 1017
    if (value->type != VIR_CONF_LIST) {
        virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Expected a list for 'uri_aliases' config parameter"));
        return -1;
    }

    entry = value->list;
W
Wen Ruo Lv 已提交
1018
    alias_len = strlen(alias);
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
    while (entry) {
        char *offset;
        size_t safe;

        if (entry->type != VIR_CONF_STRING) {
            virLibConnError(VIR_ERR_CONF_SYNTAX, "%s",
                            _("Expected a string for 'uri_aliases' config parameter list entry"));
            return -1;
        }

        if (!(offset = strchr(entry->str, '='))) {
            virLibConnError(VIR_ERR_CONF_SYNTAX,
                            _("Malformed 'uri_aliases' config entry '%s', expected 'alias=uri://host/path'"),
                            entry->str);
            return -1;
        }

        safe  = strspn(entry->str, URI_ALIAS_CHARS);
        if (safe < (offset - entry->str)) {
            virLibConnError(VIR_ERR_CONF_SYNTAX,
Y
Yuri Chornoivan 已提交
1039
                            _("Malformed 'uri_aliases' config entry '%s', aliases may only contain 'a-Z, 0-9, _, -'"),
1040 1041 1042 1043
                            entry->str);
            return -1;
        }

W
Wen Ruo Lv 已提交
1044 1045
        if (alias_len == (offset - entry->str) &&
            STREQLEN(entry->str, alias, alias_len)) {
1046 1047
            VIR_DEBUG("Resolved alias '%s' to '%s'",
                      alias, offset+1);
1048
            return VIR_STRDUP(*uri, offset+1);
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
        }

        entry = entry->next;
    }

    VIR_DEBUG("No alias found for '%s', passing through to drivers",
              alias);
    return 0;
}

static int
1060 1061
virConnectOpenResolveURIAlias(virConfPtr conf,
                              const char *alias, char **uri)
1062 1063 1064 1065 1066 1067
{
    int ret = -1;
    virConfValuePtr value = NULL;

    *uri = NULL;

1068
    if ((value = virConfGetValue(conf, "uri_aliases")))
1069 1070 1071 1072
        ret = virConnectOpenFindURIAliasMatch(value, alias, uri);
    else
        ret = 0;

1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
    return ret;
}


static int
virConnectGetDefaultURI(virConfPtr conf,
                        const char **name)
{
    int ret = -1;
    virConfValuePtr value = NULL;
    char *defname = getenv("LIBVIRT_DEFAULT_URI");
    if (defname && *defname) {
        VIR_DEBUG("Using LIBVIRT_DEFAULT_URI '%s'", defname);
        *name = defname;
    } else if ((value = virConfGetValue(conf, "uri_default"))) {
        if (value->type != VIR_CONF_STRING) {
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Expected a string for 'uri_default' config parameter"));
            goto cleanup;
        }
        VIR_DEBUG("Using config file uri '%s'", value->str);
        *name = value->str;
    }

    ret = 0;
1098 1099 1100 1101
cleanup:
    return ret;
}

1102
static virConnectPtr
1103 1104 1105
do_open(const char *name,
        virConnectAuthPtr auth,
        unsigned int flags)
1106
{
1107
    int i, res;
1108
    virConnectPtr ret;
1109
    virConfPtr conf = NULL;
1110

1111 1112
    virResetLastError();

1113 1114 1115
    ret = virGetConnect();
    if (ret == NULL)
        return NULL;
1116

1117 1118 1119 1120 1121 1122
    if (virConnectGetConfigFile(&conf) < 0)
        goto failed;

    if (name && name[0] == '\0')
        name = NULL;

1123 1124 1125 1126 1127
    /*
     *  If no URI is passed, then check for an environment string if not
     *  available probe the compiled in drivers to find a default hypervisor
     *  if detectable.
     */
1128 1129 1130
    if (!name &&
        virConnectGetDefaultURI(conf, &name) < 0)
        goto failed;
1131

1132
    if (name) {
1133
        char *alias = NULL;
1134 1135 1136 1137 1138 1139 1140
        /* Convert xen -> xen:/// for back compat */
        if (STRCASEEQ(name, "xen"))
            name = "xen:///";

        /* Convert xen:// -> xen:/// because xmlParseURI cannot parse the
         * former.  This allows URIs such as xen://localhost to work.
         */
1141
        if (STREQ(name, "xen://"))
1142 1143
            name = "xen:///";

1144
        if (!(flags & VIR_CONNECT_NO_ALIASES) &&
1145
            virConnectOpenResolveURIAlias(conf, name, &alias) < 0)
1146 1147
            goto failed;

1148
        if (!(ret->uri = virURIParse(alias ? alias : name))) {
1149
            VIR_FREE(alias);
1150 1151
            goto failed;
        }
1152

1153
        VIR_DEBUG("name \"%s\" to URI components:\n"
1154 1155 1156 1157 1158 1159
                  "  scheme %s\n"
                  "  server %s\n"
                  "  user %s\n"
                  "  port %d\n"
                  "  path %s\n",
                  alias ? alias : name,
1160
                  NULLSTR(ret->uri->scheme), NULLSTR(ret->uri->server),
1161 1162 1163 1164
                  NULLSTR(ret->uri->user), ret->uri->port,
                  NULLSTR(ret->uri->path));

        VIR_FREE(alias);
1165
    } else {
1166
        VIR_DEBUG("no name, allowing driver auto-select");
1167 1168
    }

1169 1170 1171
    /* Cleansing flags */
    ret->flags = flags & VIR_CONNECT_RO;

1172
    for (i = 0; i < virDriverTabCount; i++) {
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
        /* We're going to probe the remote driver next. So we have already
         * probed all other client-side-only driver before, but none of them
         * accepted the URI.
         * If the scheme corresponds to a known but disabled client-side-only
         * driver then report a useful error, instead of a cryptic one about
         * not being able to connect to libvirtd or not being able to find
         * certificates. */
        if (virDriverTab[i]->no == VIR_DRV_REMOTE &&
            ret->uri != NULL && ret->uri->scheme != NULL &&
            (
#ifndef WITH_PHYP
             STRCASEEQ(ret->uri->scheme, "phyp") ||
#endif
#ifndef WITH_ESX
1187
             STRCASEEQ(ret->uri->scheme, "vpx") ||
1188 1189
             STRCASEEQ(ret->uri->scheme, "esx") ||
             STRCASEEQ(ret->uri->scheme, "gsx") ||
M
Matthias Bolte 已提交
1190 1191 1192
#endif
#ifndef WITH_HYPERV
             STRCASEEQ(ret->uri->scheme, "hyperv") ||
1193 1194 1195
#endif
#ifndef WITH_XENAPI
             STRCASEEQ(ret->uri->scheme, "xenapi") ||
D
Dmitry Guryanov 已提交
1196 1197 1198
#endif
#ifndef WITH_PARALLELS
             STRCASEEQ(ret->uri->scheme, "parallels") ||
1199 1200
#endif
             false)) {
1201
            virReportErrorHelper(VIR_FROM_NONE, VIR_ERR_CONFIG_UNSUPPORTED,
1202 1203 1204 1205 1206 1207
                                 __FILE__, __FUNCTION__, __LINE__,
                                 _("libvirt was built without the '%s' driver"),
                                 ret->uri->scheme);
            goto failed;
        }

O
Osier Yang 已提交
1208
        VIR_DEBUG("trying driver %d (%s) ...", i, virDriverTab[i]->name);
1209
        res = virDriverTab[i]->connectOpen(ret, auth, flags);
1210
        VIR_DEBUG("driver %d %s returned %s",
O
Osier Yang 已提交
1211 1212 1213 1214 1215 1216
                  i, virDriverTab[i]->name,
                  res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
                  (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
                  (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status")));

        if (res == VIR_DRV_OPEN_SUCCESS) {
1217 1218
            ret->driver = virDriverTab[i];
            break;
O
Osier Yang 已提交
1219 1220
        } else if (res == VIR_DRV_OPEN_ERROR) {
            goto failed;
1221
        }
1222 1223
    }

1224
    if (!ret->driver) {
1225
        /* If we reach here, then all drivers declined the connection. */
1226
        virLibConnError(VIR_ERR_NO_CONNECT,
1227
                        "%s",
1228
                        NULLSTR(name));
1229
        goto failed;
1230 1231
    }

1232
    for (i = 0; i < virNetworkDriverTabCount; i++) {
1233
        res = virNetworkDriverTab[i]->networkOpen(ret, auth, flags);
1234
        VIR_DEBUG("network driver %d %s returned %s",
O
Osier Yang 已提交
1235 1236 1237 1238 1239 1240
                  i, virNetworkDriverTab[i]->name,
                  res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
                  (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
                  (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status")));

        if (res == VIR_DRV_OPEN_SUCCESS) {
1241 1242
            ret->networkDriver = virNetworkDriverTab[i];
            break;
O
Osier Yang 已提交
1243 1244
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
1245
        }
1246
    }
1247

D
Daniel Veillard 已提交
1248
    for (i = 0; i < virInterfaceDriverTabCount; i++) {
1249
        res = virInterfaceDriverTab[i]->interfaceOpen(ret, auth, flags);
1250
        VIR_DEBUG("interface driver %d %s returned %s",
O
Osier Yang 已提交
1251 1252 1253 1254 1255 1256
                  i, virInterfaceDriverTab[i]->name,
                  res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
                  (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
                  (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status")));

        if (res == VIR_DRV_OPEN_SUCCESS) {
D
Daniel Veillard 已提交
1257 1258
            ret->interfaceDriver = virInterfaceDriverTab[i];
            break;
O
Osier Yang 已提交
1259 1260
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
D
Daniel Veillard 已提交
1261 1262
        }
    }
1263 1264 1265

    /* Secondary driver for storage. Optional */
    for (i = 0; i < virStorageDriverTabCount; i++) {
1266
        res = virStorageDriverTab[i]->storageOpen(ret, auth, flags);
1267
        VIR_DEBUG("storage driver %d %s returned %s",
O
Osier Yang 已提交
1268 1269 1270 1271 1272 1273
                  i, virStorageDriverTab[i]->name,
                  res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
                  (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
                  (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status")));

        if (res == VIR_DRV_OPEN_SUCCESS) {
1274 1275
            ret->storageDriver = virStorageDriverTab[i];
            break;
O
Osier Yang 已提交
1276 1277
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
1278 1279 1280
        }
    }

1281
    /* Node driver (optional) */
1282
    for (i = 0; i < virNodeDeviceDriverTabCount; i++) {
1283
        res = virNodeDeviceDriverTab[i]->nodeDeviceOpen(ret, auth, flags);
1284
        VIR_DEBUG("node driver %d %s returned %s",
1285
                  i, virNodeDeviceDriverTab[i]->name,
O
Osier Yang 已提交
1286 1287 1288 1289 1290
                  res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
                  (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
                  (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status")));

        if (res == VIR_DRV_OPEN_SUCCESS) {
1291
            ret->nodeDeviceDriver = virNodeDeviceDriverTab[i];
1292
            break;
O
Osier Yang 已提交
1293 1294
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
1295 1296 1297
        }
    }

1298 1299
    /* Secret manipulation driver. Optional */
    for (i = 0; i < virSecretDriverTabCount; i++) {
1300
        res = virSecretDriverTab[i]->secretOpen(ret, auth, flags);
1301
        VIR_DEBUG("secret driver %d %s returned %s",
O
Osier Yang 已提交
1302 1303 1304 1305 1306 1307
                  i, virSecretDriverTab[i]->name,
                  res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
                  (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
                  (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status")));

        if (res == VIR_DRV_OPEN_SUCCESS) {
1308 1309
            ret->secretDriver = virSecretDriverTab[i];
            break;
O
Osier Yang 已提交
1310 1311
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
1312 1313 1314
        }
    }

S
Stefan Berger 已提交
1315 1316
    /* Network filter driver. Optional */
    for (i = 0; i < virNWFilterDriverTabCount; i++) {
1317
        res = virNWFilterDriverTab[i]->nwfilterOpen(ret, auth, flags);
1318
        VIR_DEBUG("nwfilter driver %d %s returned %s",
O
Osier Yang 已提交
1319 1320 1321 1322 1323 1324
                  i, virNWFilterDriverTab[i]->name,
                  res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
                  (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
                  (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status")));

        if (res == VIR_DRV_OPEN_SUCCESS) {
S
Stefan Berger 已提交
1325 1326
            ret->nwfilterDriver = virNWFilterDriverTab[i];
            break;
O
Osier Yang 已提交
1327 1328
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
S
Stefan Berger 已提交
1329 1330 1331
        }
    }

1332 1333
    virConfFree(conf);

1334
    return ret;
1335 1336

failed:
1337
    virConfFree(conf);
1338
    virObjectUnref(ret);
1339

1340
    return NULL;
1341 1342
}

1343 1344
/**
 * virConnectOpen:
1345
 * @name: (optional) URI of the hypervisor
1346
 *
1347
 * This function should be called first to get a connection to the
1348 1349 1350
 * Hypervisor and xen store
 *
 * Returns a pointer to the hypervisor connection or NULL in case of error
1351
 *
1352 1353 1354 1355 1356
 * If @name is NULL, if the LIBVIRT_DEFAULT_URI environment variable is set,
 * then it will be used. Otherwise if the client configuration file
 * has the "uri_default" parameter set, then it will be used. Finally
 * probing will be done to determine a suitable default driver to activate.
 * This involves trying each hypervisor in turn until one successfully opens.
1357 1358 1359 1360 1361 1362
 *
 * If connecting to an unprivileged hypervisor driver which requires
 * the libvirtd daemon to be active, it will automatically be launched
 * if not already running. This can be prevented by setting the
 * environment variable LIBVIRT_AUTOSTART=0
 *
1363
 * URIs are documented at http://libvirt.org/uri.html
1364 1365
 */
virConnectPtr
1366
virConnectOpen(const char *name)
1367
{
1368
    virConnectPtr ret = NULL;
1369 1370 1371

    if (virInitialize() < 0)
        goto error;
1372

1373
    VIR_DEBUG("name=%s", NULLSTR(name));
1374
    virResetLastError();
1375
    ret = do_open(name, NULL, 0);
1376 1377 1378 1379 1380 1381 1382
    if (!ret)
        goto error;
    return ret;

error:
    virDispatchError(NULL);
    return NULL;
1383 1384
}

1385
/**
1386
 * virConnectOpenReadOnly:
1387
 * @name: (optional) URI of the hypervisor
1388
 *
1389
 * This function should be called first to get a restricted connection to the
D
Daniel Veillard 已提交
1390
 * library functionalities. The set of APIs usable are then restricted
1391
 * on the available methods to control the domains.
1392
 *
1393 1394 1395
 * See virConnectOpen for notes about environment variables which can
 * have an effect on opening drivers
 *
1396
 * Returns a pointer to the hypervisor connection or NULL in case of error
1397 1398
 *
 * URIs are documented at http://libvirt.org/uri.html
1399
 */
1400
virConnectPtr
1401 1402
virConnectOpenReadOnly(const char *name)
{
1403
    virConnectPtr ret = NULL;
1404 1405 1406

    if (virInitialize() < 0)
        goto error;
1407

1408
    VIR_DEBUG("name=%s", NULLSTR(name));
1409
    virResetLastError();
1410
    ret = do_open(name, NULL, VIR_CONNECT_RO);
1411 1412 1413 1414 1415 1416 1417
    if (!ret)
        goto error;
    return ret;

error:
    virDispatchError(NULL);
    return NULL;
1418 1419 1420 1421
}

/**
 * virConnectOpenAuth:
1422
 * @name: (optional) URI of the hypervisor
1423
 * @auth: Authenticate callback parameters
1424
 * @flags: bitwise-OR of virConnectFlags
1425
 *
1426
 * This function should be called first to get a connection to the
1427
 * Hypervisor. If necessary, authentication will be performed fetching
1428 1429
 * credentials via the callback
 *
1430 1431 1432
 * See virConnectOpen for notes about environment variables which can
 * have an effect on opening drivers
 *
1433 1434 1435 1436 1437 1438 1439
 * Returns a pointer to the hypervisor connection or NULL in case of error
 *
 * URIs are documented at http://libvirt.org/uri.html
 */
virConnectPtr
virConnectOpenAuth(const char *name,
                   virConnectAuthPtr auth,
1440
                   unsigned int flags)
1441
{
1442
    virConnectPtr ret = NULL;
1443 1444 1445

    if (virInitialize() < 0)
        goto error;
1446

1447
    VIR_DEBUG("name=%s, auth=%p, flags=%x", NULLSTR(name), auth, flags);
1448
    virResetLastError();
1449
    ret = do_open(name, auth, flags);
1450 1451 1452 1453 1454 1455 1456
    if (!ret)
        goto error;
    return ret;

error:
    virDispatchError(NULL);
    return NULL;
D
Daniel Veillard 已提交
1457 1458 1459
}

/**
1460
 * virConnectClose:
D
Daniel Veillard 已提交
1461 1462 1463 1464 1465 1466 1467
 * @conn: pointer to the hypervisor connection
 *
 * This function closes the connection to the Hypervisor. This should
 * not be called if further interaction with the Hypervisor are needed
 * especially if there is running domain which need further monitoring by
 * the application.
 *
1468 1469 1470 1471 1472 1473 1474 1475
 * Connections are reference counted; the count is explicitly
 * increased by the initial open (virConnectOpen, virConnectOpenAuth,
 * and the like) as well as virConnectRef; it is also temporarily
 * increased by other API that depend on the connection remaining
 * alive.  The open and every virConnectRef call should have a
 * matching virConnectClose, and all other references will be released
 * after the corresponding operation completes.
 *
1476 1477 1478 1479 1480 1481 1482 1483 1484 1485
 * Returns a positive number if at least 1 reference remains on
 * success. The returned value should not be assumed to be the total
 * reference count. A return of 0 implies no references remain and
 * the connection is closed and memory has been freed. A return of -1
 * implies a failure.
 *
 * It is possible for the last virConnectClose to return a positive
 * value if some other object still has a temporary reference to the
 * connection, but the application should not try to further use a
 * connection after the virConnectClose that matches the initial open.
D
Daniel Veillard 已提交
1486 1487
 */
int
1488 1489
virConnectClose(virConnectPtr conn)
{
1490
    int ret = -1;
1491
    VIR_DEBUG("conn=%p", conn);
1492

1493 1494 1495
    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
1496
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1497
        goto error;
1498
    }
1499

1500 1501 1502
    if (!virObjectUnref(conn))
        return 0;
    return 1;
1503 1504 1505 1506

error:
    virDispatchError(NULL);
    return ret;
D
Daniel Veillard 已提交
1507 1508
}

1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522
/**
 * virConnectRef:
 * @conn: the connection to hold a reference on
 *
 * Increment the reference count on the connection. For each
 * additional call to this method, there shall be a corresponding
 * call to virConnectClose to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * This method is typically useful for applications where multiple
 * threads are using a connection, and it is required that the
 * connection remain open until all threads have finished using
 * it. ie, each new thread using a connection would increment
 * the reference count.
D
Daniel Veillard 已提交
1523 1524
 *
 * Returns 0 in case of success, -1 in case of failure
1525 1526 1527 1528 1529
 */
int
virConnectRef(virConnectPtr conn)
{
    if ((!VIR_IS_CONNECT(conn))) {
1530
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1531
        virDispatchError(NULL);
1532
        return -1;
1533
    }
1534 1535
    VIR_DEBUG("conn=%p refs=%d", conn, conn->object.refs);
    virObjectRef(conn);
1536 1537 1538
    return 0;
}

D
Daniel Veillard 已提交
1539 1540
/*
 * Not for public use.  This function is part of the internal
1541 1542 1543
 * implementation of driver features in the remote case.
 */
int
1544
virConnectSupportsFeature(virConnectPtr conn, int feature)
1545
{
1546
    int ret;
1547
    VIR_DEBUG("conn=%p, feature=%d", conn, feature);
1548

1549 1550 1551
    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
1552
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1553
        virDispatchError(NULL);
1554
        return -1;
1555
    }
1556

1557
    if (!conn->driver->connectSupportsFeature)
1558 1559
        ret = 0;
    else
1560
        ret = conn->driver->connectSupportsFeature(conn, feature);
1561 1562

    if (ret < 0)
1563
        virDispatchError(conn);
1564

1565
    return ret;
1566 1567
}

1568 1569 1570 1571 1572 1573 1574
/**
 * virConnectGetType:
 * @conn: pointer to the hypervisor connection
 *
 * Get the name of the Hypervisor software used.
 *
 * Returns NULL in case of error, a static zero terminated string otherwise.
1575 1576 1577
 *
 * See also:
 * http://www.redhat.com/archives/libvir-list/2007-February/msg00096.html
1578 1579
 */
const char *
1580 1581
virConnectGetType(virConnectPtr conn)
{
1582
    const char *ret;
1583
    VIR_DEBUG("conn=%p", conn);
1584

1585 1586
    virResetLastError();

D
Daniel Veillard 已提交
1587
    if (!VIR_IS_CONNECT(conn)) {
1588
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1589
        virDispatchError(NULL);
1590
        return NULL;
D
Daniel Veillard 已提交
1591
    }
1592

1593 1594
    if (conn->driver->connectGetType) {
        ret = conn->driver->connectGetType(conn);
1595
        if (ret) return ret;
1596
    }
1597
    return conn->driver->name;
1598 1599
}

D
Daniel Veillard 已提交
1600
/**
1601
 * virConnectGetVersion:
D
Daniel Veillard 已提交
1602
 * @conn: pointer to the hypervisor connection
1603
 * @hvVer: return value for the version of the running hypervisor (OUT)
D
Daniel Veillard 已提交
1604
 *
1605
 * Get the version level of the Hypervisor running. This may work only with
1606
 * hypervisor call, i.e. with privileged access to the hypervisor, not
1607
 * with a Read-Only connection.
D
Daniel Veillard 已提交
1608
 *
1609 1610 1611
 * Returns -1 in case of error, 0 otherwise. if the version can't be
 *    extracted by lack of capacities returns 0 and @hvVer is 0, otherwise
 *    @hvVer value is major * 1,000,000 + minor * 1,000 + release
D
Daniel Veillard 已提交
1612
 */
1613
int
1614 1615
virConnectGetVersion(virConnectPtr conn, unsigned long *hvVer)
{
1616
    VIR_DEBUG("conn=%p, hvVer=%p", conn, hvVer);
1617

1618 1619
    virResetLastError();

D
Daniel Veillard 已提交
1620
    if (!VIR_IS_CONNECT(conn)) {
1621
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1622
        virDispatchError(NULL);
1623
        return -1;
D
Daniel Veillard 已提交
1624
    }
1625

1626
    virCheckNonNullArgGoto(hvVer, error);
1627

1628 1629
    if (conn->driver->connectGetVersion) {
        int ret = conn->driver->connectGetVersion(conn, hvVer);
1630 1631 1632 1633
        if (ret < 0)
            goto error;
        return ret;
    }
D
Daniel P. Berrange 已提交
1634

1635
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
1636 1637

error:
1638
    virDispatchError(conn);
1639
    return -1;
1640 1641
}

1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656
/**
 * virConnectGetLibVersion:
 * @conn: pointer to the hypervisor connection
 * @libVer: returns the libvirt library version used on the connection (OUT)
 *
 * Provides @libVer, which is the version of libvirt used by the
 *   daemon running on the @conn host
 *
 * Returns -1 in case of failure, 0 otherwise, and values for @libVer have
 *      the format major * 1,000,000 + minor * 1,000 + release.
 */
int
virConnectGetLibVersion(virConnectPtr conn, unsigned long *libVer)
{
    int ret = -1;
1657
    VIR_DEBUG("conn=%p, libVir=%p", conn, libVer);
1658 1659 1660 1661

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
1662
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1663
        virDispatchError(NULL);
1664 1665 1666
        return -1;
    }

1667
    virCheckNonNullArgGoto(libVer, error);
1668

1669 1670
    if (conn->driver->connectGetLibVersion) {
        ret = conn->driver->connectGetLibVersion(conn, libVer);
1671 1672 1673 1674 1675
        if (ret < 0)
            goto error;
        return ret;
    }

1676 1677 1678
    *libVer = LIBVIR_VERSION_NUMBER;
    return 0;

1679
error:
1680
    virDispatchError(conn);
1681 1682 1683
    return ret;
}

1684 1685 1686 1687 1688
/**
 * virConnectGetHostname:
 * @conn: pointer to a hypervisor connection
 *
 * This returns the system hostname on which the hypervisor is
1689
 * running (the result of the gethostname system call).  If
1690 1691 1692 1693 1694 1695 1696
 * we are connected to a remote system, then this returns the
 * hostname of the remote system.
 *
 * Returns the hostname which must be freed by the caller, or
 * NULL if there was an error.
 */
char *
1697
virConnectGetHostname(virConnectPtr conn)
1698
{
1699
    VIR_DEBUG("conn=%p", conn);
1700

1701 1702
    virResetLastError();

1703
    if (!VIR_IS_CONNECT(conn)) {
1704
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1705
        virDispatchError(NULL);
1706 1707 1708
        return NULL;
    }

1709 1710
    if (conn->driver->connectGetHostname) {
        char *ret = conn->driver->connectGetHostname(conn);
1711 1712 1713 1714
        if (!ret)
            goto error;
        return ret;
    }
1715

1716
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
1717 1718

error:
1719
    virDispatchError(conn);
1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738
    return NULL;
}

/**
 * virConnectGetURI:
 * @conn: pointer to a hypervisor connection
 *
 * This returns the URI (name) of the hypervisor connection.
 * Normally this is the same as or similar to the string passed
 * to the virConnectOpen/virConnectOpenReadOnly call, but
 * the driver may make the URI canonical.  If name == NULL
 * was passed to virConnectOpen, then the driver will return
 * a non-NULL URI which can be used to connect to the same
 * hypervisor later.
 *
 * Returns the URI string which must be freed by the caller, or
 * NULL if there was an error.
 */
char *
1739
virConnectGetURI(virConnectPtr conn)
1740
{
1741
    char *name;
1742
    VIR_DEBUG("conn=%p", conn);
1743

1744 1745
    virResetLastError();

1746
    if (!VIR_IS_CONNECT(conn)) {
1747
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1748
        virDispatchError(NULL);
1749 1750 1751
        return NULL;
    }

1752
    if (!(name = virURIFormat(conn->uri)))
1753
        goto error;
1754

1755
    return name;
1756 1757

error:
1758
    virDispatchError(conn);
1759
    return NULL;
1760 1761
}

E
Eric Blake 已提交
1762 1763 1764
/**
 * virConnectGetSysinfo:
 * @conn: pointer to a hypervisor connection
1765
 * @flags: extra flags; not used yet, so callers should always pass 0
E
Eric Blake 已提交
1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
 *
 * This returns the XML description of the sysinfo details for the
 * host on which the hypervisor is running, in the same format as the
 * <sysinfo> element of a domain XML.  This information is generally
 * available only for hypervisors running with root privileges.
 *
 * Returns the XML string which must be freed by the caller, or
 * NULL if there was an error.
 */
char *
1776
virConnectGetSysinfo(virConnectPtr conn, unsigned int flags)
E
Eric Blake 已提交
1777
{
E
Eric Blake 已提交
1778
    VIR_DEBUG("conn=%p, flags=%x", conn, flags);
E
Eric Blake 已提交
1779 1780 1781 1782 1783 1784 1785 1786 1787

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }

1788 1789
    if (conn->driver->connectGetSysinfo) {
        char *ret = conn->driver->connectGetSysinfo(conn, flags);
E
Eric Blake 已提交
1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801
        if (!ret)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return NULL;
}

1802 1803 1804 1805 1806
/**
 * virConnectGetMaxVcpus:
 * @conn: pointer to the hypervisor connection
 * @type: value of the 'type' attribute in the <domain> element
 *
1807
 * Provides the maximum number of virtual CPUs supported for a guest VM of a
1808 1809 1810 1811 1812 1813 1814 1815 1816
 * specific type. The 'type' parameter here corresponds to the 'type'
 * attribute in the <domain> element of the XML.
 *
 * Returns the maximum of virtual CPU or -1 in case of error.
 */
int
virConnectGetMaxVcpus(virConnectPtr conn,
                      const char *type)
{
1817
    VIR_DEBUG("conn=%p, type=%s", conn, type);
1818

1819 1820
    virResetLastError();

1821
    if (!VIR_IS_CONNECT(conn)) {
1822
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1823
        virDispatchError(NULL);
1824
        return -1;
1825 1826
    }

1827 1828
    if (conn->driver->connectGetMaxVcpus) {
        int ret = conn->driver->connectGetMaxVcpus(conn, type);
1829 1830 1831 1832
        if (ret < 0)
            goto error;
        return ret;
    }
1833

1834
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
1835
error:
1836
    virDispatchError(conn);
1837
    return -1;
1838 1839
}

1840
/**
1841
 * virConnectListDomains:
1842 1843 1844 1845
 * @conn: pointer to the hypervisor connection
 * @ids: array to collect the list of IDs of active domains
 * @maxids: size of @ids
 *
1846
 * Collect the list of active domains, and store their IDs in array @ids
1847
 *
1848 1849 1850 1851 1852 1853 1854 1855
 * For inactive domains, see virConnectListDefinedDomains().  For more
 * control over the results, see virConnectListAllDomains().
 *
 * Returns the number of domains found or -1 in case of error.  Note that
 * this command is inherently racy; a domain can be started between a
 * call to virConnectNumOfDomains() and this call; you are only guaranteed
 * that all currently active domains were listed if the return is less
 * than @maxids.
1856 1857
 */
int
1858 1859
virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
{
1860
    VIR_DEBUG("conn=%p, ids=%p, maxids=%d", conn, ids, maxids);
1861

1862 1863
    virResetLastError();

D
Daniel Veillard 已提交
1864
    if (!VIR_IS_CONNECT(conn)) {
1865
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1866
        virDispatchError(NULL);
1867
        return -1;
D
Daniel Veillard 已提交
1868
    }
1869

1870 1871
    virCheckNonNullArgGoto(ids, error);
    virCheckNonNegativeArgGoto(maxids, error);
1872

1873 1874
    if (conn->driver->connectListDomains) {
        int ret = conn->driver->connectListDomains(conn, ids, maxids);
1875 1876 1877 1878
        if (ret < 0)
            goto error;
        return ret;
    }
1879

1880
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
1881
error:
1882
    virDispatchError(conn);
1883
    return -1;
D
Daniel Veillard 已提交
1884 1885
}

K
 
Karel Zak 已提交
1886 1887 1888 1889
/**
 * virConnectNumOfDomains:
 * @conn: pointer to the hypervisor connection
 *
1890 1891
 * Provides the number of active domains.
 *
K
 
Karel Zak 已提交
1892 1893 1894
 * Returns the number of domain found or -1 in case of error
 */
int
1895 1896
virConnectNumOfDomains(virConnectPtr conn)
{
1897
    VIR_DEBUG("conn=%p", conn);
1898

1899 1900
    virResetLastError();

D
Daniel Veillard 已提交
1901
    if (!VIR_IS_CONNECT(conn)) {
1902
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1903
        virDispatchError(NULL);
1904
        return -1;
D
Daniel Veillard 已提交
1905
    }
K
Karel Zak 已提交
1906

1907 1908
    if (conn->driver->connectNumOfDomains) {
        int ret = conn->driver->connectNumOfDomains(conn);
1909 1910 1911 1912
        if (ret < 0)
            goto error;
        return ret;
    }
1913

1914
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
1915
error:
1916
    virDispatchError(conn);
1917
    return -1;
K
 
Karel Zak 已提交
1918 1919
}

1920 1921 1922 1923
/**
 * virDomainGetConnect:
 * @dom: pointer to a domain
 *
1924
 * Provides the connection pointer associated with a domain.  The
1925 1926 1927
 * reference counter on the connection is not increased by this
 * call.
 *
1928 1929 1930 1931
 * WARNING: When writing libvirt bindings in other languages, do
 * not use this function.  Instead, store the connection and
 * the domain object together.
 *
1932 1933 1934
 * Returns the virConnectPtr or NULL in case of failure.
 */
virConnectPtr
1935
virDomainGetConnect(virDomainPtr dom)
1936
{
1937
    VIR_DOMAIN_DEBUG(dom);
1938

1939 1940
    virResetLastError();

1941
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
1942
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
1943
        virDispatchError(NULL);
1944 1945 1946 1947 1948
        return NULL;
    }
    return dom->conn;
}

D
Daniel Veillard 已提交
1949
/**
1950
 * virDomainCreateXML:
D
Daniel Veillard 已提交
1951
 * @conn: pointer to the hypervisor connection
D
Daniel Veillard 已提交
1952
 * @xmlDesc: string containing an XML description of the domain
1953
 * @flags: bitwise-OR of supported virDomainCreateFlags
D
Daniel Veillard 已提交
1954
 *
1955
 * Launch a new guest domain, based on an XML description similar
1956
 * to the one returned by virDomainGetXMLDesc()
1957
 * This function may require privileged access to the hypervisor.
1958 1959 1960
 * The domain is not persistent, so its definition will disappear when it
 * is destroyed, or if the host is restarted (see virDomainDefineXML() to
 * define persistent domains).
1961
 *
1962 1963 1964 1965 1966 1967 1968
 * If the VIR_DOMAIN_START_PAUSED flag is set, the guest domain
 * will be started, but its CPUs will remain paused. The CPUs
 * can later be manually started using virDomainResume.
 *
 * If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest
 * domain will be automatically destroyed when the virConnectPtr
 * object is finally released. This will also happen if the
E
Eric Blake 已提交
1969
 * client application crashes / loses its connection to the
1970
 * libvirtd daemon. Any domains marked for auto destroy will
1971
 * block attempts at migration, save-to-file, or snapshots.
1972
 *
D
Daniel Veillard 已提交
1973 1974
 * Returns a new domain object or NULL in case of failure
 */
1975
virDomainPtr
1976 1977
virDomainCreateXML(virConnectPtr conn, const char *xmlDesc,
                   unsigned int flags)
1978
{
1979
    VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags);
1980

1981 1982
    virResetLastError();

D
Daniel Veillard 已提交
1983
    if (!VIR_IS_CONNECT(conn)) {
1984
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
1985
        virDispatchError(NULL);
1986
        return NULL;
D
Daniel Veillard 已提交
1987
    }
1988
    virCheckNonNullArgGoto(xmlDesc, error);
1989
    if (conn->flags & VIR_CONNECT_RO) {
1990
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
1991
        goto error;
1992
    }
D
Daniel Veillard 已提交
1993

1994 1995
    if (conn->driver->domainCreateXML) {
        virDomainPtr ret;
1996
        ret = conn->driver->domainCreateXML(conn, xmlDesc, flags);
1997 1998 1999 2000
        if (!ret)
            goto error;
        return ret;
    }
2001

2002
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2003
error:
2004
    virDispatchError(conn);
2005
    return NULL;
D
Daniel Veillard 已提交
2006 2007
}

2008 2009 2010 2011
/**
 * virDomainCreateLinux:
 * @conn: pointer to the hypervisor connection
 * @xmlDesc: string containing an XML description of the domain
2012
 * @flags: extra flags; not used yet, so callers should always pass 0
2013 2014 2015
 *
 * Deprecated after 0.4.6.
 * Renamed to virDomainCreateXML() providing identical functionality.
2016
 * This existing name will left indefinitely for API compatibility.
2017 2018 2019 2020 2021 2022 2023
 *
 * Returns a new domain object or NULL in case of failure
 */
virDomainPtr
virDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
                     unsigned int flags)
{
2024
    return virDomainCreateXML(conn, xmlDesc, flags);
2025
}
2026

2027
/**
2028
 * virDomainLookupByID:
2029 2030 2031 2032
 * @conn: pointer to the hypervisor connection
 * @id: the domain ID number
 *
 * Try to find a domain based on the hypervisor ID number
D
Daniel Veillard 已提交
2033 2034
 * Note that this won't work for inactive domains which have an ID of -1,
 * in that case a lookup based on the Name or UUId need to be done instead.
2035
 *
2036 2037
 * Returns a new domain object or NULL in case of failure.  If the
 * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
2038
 */
2039
virDomainPtr
2040 2041
virDomainLookupByID(virConnectPtr conn, int id)
{
2042
    VIR_DEBUG("conn=%p, id=%d", conn, id);
2043

2044 2045
    virResetLastError();

D
Daniel Veillard 已提交
2046
    if (!VIR_IS_CONNECT(conn)) {
2047
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
2048
        virDispatchError(NULL);
2049
        return NULL;
D
Daniel Veillard 已提交
2050
    }
2051
    virCheckNonNegativeArgGoto(id, error);
2052

2053 2054
    if (conn->driver->domainLookupByID) {
        virDomainPtr ret;
2055
        ret = conn->driver->domainLookupByID(conn, id);
2056 2057 2058 2059
        if (!ret)
            goto error;
        return ret;
    }
2060

2061
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2062 2063

error:
2064
    virDispatchError(conn);
2065
    return NULL;
2066 2067 2068 2069 2070
}

/**
 * virDomainLookupByUUID:
 * @conn: pointer to the hypervisor connection
K
Karel Zak 已提交
2071
 * @uuid: the raw UUID for the domain
2072 2073 2074
 *
 * Try to lookup a domain on the given hypervisor based on its UUID.
 *
2075 2076
 * Returns a new domain object or NULL in case of failure.  If the
 * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
2077 2078
 */
virDomainPtr
2079 2080
virDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
2081
    VIR_UUID_DEBUG(conn, uuid);
2082

2083 2084
    virResetLastError();

D
Daniel Veillard 已提交
2085
    if (!VIR_IS_CONNECT(conn)) {
2086
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
2087
        virDispatchError(NULL);
2088
        return NULL;
D
Daniel Veillard 已提交
2089
    }
2090
    virCheckNonNullArgGoto(uuid, error);
2091

2092 2093
    if (conn->driver->domainLookupByUUID) {
        virDomainPtr ret;
2094
        ret = conn->driver->domainLookupByUUID(conn, uuid);
2095 2096 2097 2098
        if (!ret)
            goto error;
        return ret;
    }
2099

2100
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2101 2102

error:
2103
    virDispatchError(conn);
2104
    return NULL;
2105 2106
}

K
Karel Zak 已提交
2107 2108 2109 2110 2111 2112 2113
/**
 * virDomainLookupByUUIDString:
 * @conn: pointer to the hypervisor connection
 * @uuidstr: the string UUID for the domain
 *
 * Try to lookup a domain on the given hypervisor based on its UUID.
 *
2114 2115
 * Returns a new domain object or NULL in case of failure.  If the
 * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
K
Karel Zak 已提交
2116 2117 2118 2119
 */
virDomainPtr
virDomainLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
{
2120
    unsigned char uuid[VIR_UUID_BUFLEN];
2121
    VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
2122

2123 2124
    virResetLastError();

K
Karel Zak 已提交
2125
    if (!VIR_IS_CONNECT(conn)) {
2126
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
2127
        virDispatchError(NULL);
2128
        return NULL;
K
Karel Zak 已提交
2129
    }
2130
    virCheckNonNullArgGoto(uuidstr, error);
2131 2132

    if (virUUIDParse(uuidstr, uuid) < 0) {
2133 2134 2135
        virReportInvalidArg(uuidstr,
                            _("uuidstr in %s must be a valid UUID"),
                            __FUNCTION__);
2136
        goto error;
K
Karel Zak 已提交
2137
    }
2138

K
Karel Zak 已提交
2139
    return virDomainLookupByUUID(conn, &uuid[0]);
2140 2141

error:
2142
    virDispatchError(conn);
2143
    return NULL;
K
Karel Zak 已提交
2144 2145
}

2146 2147 2148 2149 2150
/**
 * virDomainLookupByName:
 * @conn: pointer to the hypervisor connection
 * @name: name for the domain
 *
2151
 * Try to lookup a domain on the given hypervisor based on its name.
2152
 *
2153 2154
 * Returns a new domain object or NULL in case of failure.  If the
 * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
2155 2156
 */
virDomainPtr
2157 2158
virDomainLookupByName(virConnectPtr conn, const char *name)
{
2159
    VIR_DEBUG("conn=%p, name=%s", conn, name);
2160

2161 2162
    virResetLastError();

D
Daniel Veillard 已提交
2163
    if (!VIR_IS_CONNECT(conn)) {
2164
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
2165
        virDispatchError(NULL);
2166
        return NULL;
D
Daniel Veillard 已提交
2167
    }
2168
    virCheckNonNullArgGoto(name, error);
2169

2170 2171
    if (conn->driver->domainLookupByName) {
        virDomainPtr dom;
2172
        dom = conn->driver->domainLookupByName(conn, name);
2173 2174 2175 2176
        if (!dom)
            goto error;
        return dom;
    }
2177

2178
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2179 2180

error:
2181
    virDispatchError(conn);
2182
    return NULL;
2183 2184
}

D
Daniel Veillard 已提交
2185
/**
2186
 * virDomainDestroy:
D
Daniel Veillard 已提交
2187 2188 2189
 * @domain: a domain object
 *
 * Destroy the domain object. The running instance is shutdown if not down
2190 2191
 * already and all resources used by it are given back to the hypervisor. This
 * does not free the associated virDomainPtr object.
2192
 * This function may require privileged access.
D
Daniel Veillard 已提交
2193
 *
2194 2195
 * virDomainDestroy first requests that a guest terminate
 * (e.g. SIGTERM), then waits for it to comply. After a reasonable
2196
 * timeout, if the guest still exists, virDomainDestroy will
2197 2198 2199 2200 2201 2202
 * forcefully terminate the guest (e.g. SIGKILL) if necessary (which
 * may produce undesirable results, for example unflushed disk cache
 * in the guest). To avoid this possibility, it's recommended to
 * instead call virDomainDestroyFlags, sending the
 * VIR_DOMAIN_DESTROY_GRACEFUL flag.
 *
2203 2204 2205 2206
 * If the domain is transient and has any snapshot metadata (see
 * virDomainSnapshotNum()), then that metadata will automatically
 * be deleted when the domain quits.
 *
D
Daniel Veillard 已提交
2207
 * Returns 0 in case of success and -1 in case of failure.
2208
 */
D
Daniel Veillard 已提交
2209
int
2210 2211
virDomainDestroy(virDomainPtr domain)
{
2212
    virConnectPtr conn;
2213

2214
    VIR_DOMAIN_DEBUG(domain);
2215

2216 2217
    virResetLastError();

D
Daniel Veillard 已提交
2218
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
2219
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
2220
        virDispatchError(NULL);
2221
        return -1;
D
Daniel Veillard 已提交
2222
    }
2223

2224
    conn = domain->conn;
2225
    if (conn->flags & VIR_CONNECT_RO) {
2226
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
2227
        goto error;
2228
    }
2229

2230 2231
    if (conn->driver->domainDestroy) {
        int ret;
2232
        ret = conn->driver->domainDestroy(domain);
2233 2234 2235 2236
        if (ret < 0)
            goto error;
        return ret;
    }
2237

2238
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2239 2240

error:
2241
    virDispatchError(conn);
2242
    return -1;
2243 2244
}

2245 2246 2247
/**
 * virDomainDestroyFlags:
 * @domain: a domain object
2248
 * @flags: bitwise-OR of virDomainDestroyFlagsValues
2249 2250 2251 2252 2253 2254
 *
 * Destroy the domain object. The running instance is shutdown if not down
 * already and all resources used by it are given back to the hypervisor.
 * This does not free the associated virDomainPtr object.
 * This function may require privileged access.
 *
2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270
 * Calling this function with no @flags set (equal to zero) is
 * equivalent to calling virDomainDestroy, and after a reasonable
 * timeout will forcefully terminate the guest (e.g. SIGKILL) if
 * necessary (which may produce undesirable results, for example
 * unflushed disk cache in the guest). Including
 * VIR_DOMAIN_DESTROY_GRACEFUL in the flags will prevent the forceful
 * termination of the guest, and virDomainDestroyFlags will instead
 * return an error if the guest doesn't terminate by the end of the
 * timeout; at that time, the management application can decide if
 * calling again without VIR_DOMAIN_DESTROY_GRACEFUL is appropriate.
 *
 * Another alternative which may produce cleaner results for the
 * guest's disks is to use virDomainShutdown() instead, but that
 * depends on guest support (some hypervisor/guest combinations may
 * ignore the shutdown request).
 *
2271 2272 2273 2274 2275 2276 2277 2278 2279
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainDestroyFlags(virDomainPtr domain,
                      unsigned int flags)
{
    virConnectPtr conn;

E
Eric Blake 已提交
2280
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;
    if (conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainDestroyFlags) {
        int ret;
        ret = conn->driver->domainDestroyFlags(domain, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

2311 2312 2313 2314 2315 2316 2317 2318 2319 2320
/**
 * virDomainFree:
 * @domain: a domain object
 *
 * Free the domain object. The running instance is kept alive.
 * The data structure is freed and should not be used thereafter.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
2321 2322
virDomainFree(virDomainPtr domain)
{
2323
    VIR_DOMAIN_DEBUG(domain);
2324

2325 2326 2327
    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
2328
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
2329
        virDispatchError(NULL);
2330
        return -1;
D
Daniel Veillard 已提交
2331
    }
2332
    virObjectUnref(domain);
2333
    return 0;
D
Daniel Veillard 已提交
2334 2335
}

2336 2337
/**
 * virDomainRef:
D
Daniel Veillard 已提交
2338
 * @domain: the domain to hold a reference on
2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349
 *
 * Increment the reference count on the domain. For each
 * additional call to this method, there shall be a corresponding
 * call to virDomainFree to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * This method is typically useful for applications where multiple
 * threads are using a connection, and it is required that the
 * connection remain open until all threads have finished using
 * it. ie, each new thread using a domain would increment
 * the reference count.
D
Daniel Veillard 已提交
2350 2351
 *
 * Returns 0 in case of success and -1 in case of failure.
2352 2353 2354 2355 2356
 */
int
virDomainRef(virDomainPtr domain)
{
    if ((!VIR_IS_CONNECTED_DOMAIN(domain))) {
2357
        virLibConnError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
2358
        virDispatchError(NULL);
2359
        return -1;
2360
    }
2361 2362 2363

    VIR_DOMAIN_DEBUG(domain, "refs=%d", domain->object.refs);
    virObjectRef(domain);
2364 2365 2366 2367
    return 0;
}


D
Daniel Veillard 已提交
2368
/**
2369
 * virDomainSuspend:
D
Daniel Veillard 已提交
2370 2371 2372
 * @domain: a domain object
 *
 * Suspends an active domain, the process is frozen without further access
2373
 * to CPU resources and I/O but the memory used by the domain at the
2374
 * hypervisor level will stay allocated. Use virDomainResume() to reactivate
D
Daniel Veillard 已提交
2375
 * the domain.
2376
 * This function may require privileged access.
2377 2378
 * Moreover, suspend may not be supported if domain is in some
 * special state like VIR_DOMAIN_PMSUSPENDED.
D
Daniel Veillard 已提交
2379 2380 2381 2382
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
2383 2384
virDomainSuspend(virDomainPtr domain)
{
2385
    virConnectPtr conn;
2386

2387
    VIR_DOMAIN_DEBUG(domain);
2388

2389 2390
    virResetLastError();

D
Daniel Veillard 已提交
2391
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
2392
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
2393
        virDispatchError(NULL);
2394
        return -1;
D
Daniel Veillard 已提交
2395
    }
2396
    if (domain->conn->flags & VIR_CONNECT_RO) {
2397
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
2398
        goto error;
2399
    }
D
Daniel Veillard 已提交
2400

2401 2402
    conn = domain->conn;

2403 2404
    if (conn->driver->domainSuspend) {
        int ret;
2405
        ret = conn->driver->domainSuspend(domain);
2406 2407 2408 2409
        if (ret < 0)
            goto error;
        return ret;
    }
2410

2411
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2412 2413

error:
2414
    virDispatchError(domain->conn);
2415
    return -1;
D
Daniel Veillard 已提交
2416 2417 2418
}

/**
2419
 * virDomainResume:
D
Daniel Veillard 已提交
2420 2421
 * @domain: a domain object
 *
D
Dan Kenigsberg 已提交
2422
 * Resume a suspended domain, the process is restarted from the state where
2423
 * it was frozen by calling virDomainSuspend().
2424
 * This function may require privileged access
2425 2426
 * Moreover, resume may not be supported if domain is in some
 * special state like VIR_DOMAIN_PMSUSPENDED.
D
Daniel Veillard 已提交
2427 2428 2429 2430
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
2431 2432
virDomainResume(virDomainPtr domain)
{
2433
    virConnectPtr conn;
2434

2435
    VIR_DOMAIN_DEBUG(domain);
2436

2437 2438
    virResetLastError();

D
Daniel Veillard 已提交
2439
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
2440
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
2441
        virDispatchError(NULL);
2442
        return -1;
D
Daniel Veillard 已提交
2443
    }
2444
    if (domain->conn->flags & VIR_CONNECT_RO) {
2445
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
2446
        goto error;
2447
    }
D
Daniel Veillard 已提交
2448

2449 2450
    conn = domain->conn;

2451 2452
    if (conn->driver->domainResume) {
        int ret;
2453
        ret = conn->driver->domainResume(domain);
2454 2455 2456 2457
        if (ret < 0)
            goto error;
        return ret;
    }
2458

2459
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2460 2461

error:
2462
    virDispatchError(domain->conn);
2463
    return -1;
D
Daniel Veillard 已提交
2464 2465
}

2466 2467 2468
/**
 * virDomainPMSuspendForDuration:
 * @dom: a domain object
2469 2470 2471
 * @target: a value from virNodeSuspendTarget
 * @duration: duration in seconds to suspend, or 0 for indefinite
 * @flags: extra flags; not used yet, so callers should always pass 0
2472
 *
2473 2474 2475 2476 2477
 * Attempt to have the guest enter the given @target power management
 * suspension level.  If @duration is non-zero, also schedule the guest to
 * resume normal operation after that many seconds, if nothing else has
 * resumed it earlier.  Some hypervisors require that @duration be 0, for
 * an indefinite suspension.
2478
 *
2479
 * Dependent on hypervisor used, this may require a
2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520
 * guest agent to be available, e.g. QEMU.
 *
 * Returns: 0 on success,
 *          -1 on failure.
 */
int
virDomainPMSuspendForDuration(virDomainPtr dom,
                              unsigned int target,
                              unsigned long long duration,
                              unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(dom, "target=%u duration=%llu flags=%x",
                     target, duration, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = dom->conn;

    if (conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainPMSuspendForDuration) {
        int ret;
        ret = conn->driver->domainPMSuspendForDuration(dom, target,
                                                       duration, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
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 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570

error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainPMWakeup:
 * @dom: a domain object
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Inject a wakeup into the guest that previously used
 * virDomainPMSuspendForDuration, rather than waiting for the
 * previously requested duration (if any) to elapse.
 *
 * Returns: 0 on success,
 *          -1 on failure.
 */
int
virDomainPMWakeup(virDomainPtr dom,
                  unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = dom->conn;

    if (conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainPMWakeup) {
        int ret;
        ret = conn->driver->domainPMWakeup(dom, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2571 2572 2573 2574 2575 2576

error:
    virDispatchError(conn);
    return -1;
}

2577 2578 2579 2580 2581 2582
/**
 * virDomainSave:
 * @domain: a domain object
 * @to: path for the output file
 *
 * This method will suspend a domain and save its memory contents to
2583
 * a file on disk. After the call, if successful, the domain is not
2584
 * listed as running anymore (this ends the life of a transient domain).
2585
 * Use virDomainRestore() to restore a domain after saving.
2586
 *
2587 2588 2589
 * See virDomainSaveFlags() for more control.  Also, a save file can
 * be inspected or modified slightly with virDomainSaveImageGetXMLDesc()
 * and virDomainSaveImageDefineXML().
2590
 *
2591 2592 2593
 * Returns 0 in case of success and -1 in case of failure.
 */
int
2594 2595
virDomainSave(virDomainPtr domain, const char *to)
{
2596
    virConnectPtr conn;
2597 2598

    VIR_DOMAIN_DEBUG(domain, "to=%s", to);
2599

2600 2601
    virResetLastError();

D
Daniel Veillard 已提交
2602
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
2603
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
2604
        virDispatchError(NULL);
2605
        return -1;
D
Daniel Veillard 已提交
2606
    }
2607
    if (domain->conn->flags & VIR_CONNECT_RO) {
2608
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
2609
        goto error;
2610
    }
2611
    conn = domain->conn;
2612
    virCheckNonNullArgGoto(to, error);
2613

2614 2615 2616
    if (conn->driver->domainSave) {
        int ret;
        char *absolute_to;
2617

2618 2619
        /* We must absolutize the file path as the save is done out of process */
        if (virFileAbsPath(to, &absolute_to) < 0) {
2620
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
2621 2622 2623
                            _("could not build absolute output file path"));
            goto error;
        }
2624

2625 2626 2627
        ret = conn->driver->domainSave(domain, absolute_to);

        VIR_FREE(absolute_to);
2628

2629 2630 2631 2632
        if (ret < 0)
            goto error;
        return ret;
    }
2633

2634
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2635 2636

error:
2637
    virDispatchError(domain->conn);
2638
    return -1;
2639 2640
}

2641 2642 2643 2644 2645 2646 2647 2648 2649
/**
 * virDomainSaveFlags:
 * @domain: a domain object
 * @to: path for the output file
 * @dxml: (optional) XML config for adjusting guest xml used on restore
 * @flags: bitwise-OR of virDomainSaveRestoreFlags
 *
 * This method will suspend a domain and save its memory contents to
 * a file on disk. After the call, if successful, the domain is not
2650
 * listed as running anymore (this ends the life of a transient domain).
2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664
 * Use virDomainRestore() to restore a domain after saving.
 *
 * If the hypervisor supports it, @dxml can be used to alter
 * host-specific portions of the domain XML that will be used when
 * restoring an image.  For example, it is possible to alter the
 * backing filename that is associated with a disk device, in order to
 * prepare for file renaming done as part of backing up the disk
 * device while the domain is stopped.
 *
 * If @flags includes VIR_DOMAIN_SAVE_BYPASS_CACHE, then libvirt will
 * attempt to bypass the file system cache while creating the file, or
 * fail if it cannot do so for the given system; this can allow less
 * pressure on file system cache, but also risks slowing saves to NFS.
 *
2665 2666 2667 2668 2669 2670
 * Normally, the saved state file will remember whether the domain was
 * running or paused, and restore defaults to the same state.
 * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
 * @flags will override what state gets saved into the file.  These
 * two flags are mutually exclusive.
 *
2671 2672 2673
 * A save file can be inspected or modified slightly with
 * virDomainSaveImageGetXMLDesc() and virDomainSaveImageDefineXML().
 *
E
Eric Blake 已提交
2674 2675 2676 2677
 * Some hypervisors may prevent this operation if there is a current
 * block copy operation; in that case, use virDomainBlockJobAbort()
 * to stop the block copy first.
 *
2678 2679 2680 2681 2682 2683 2684 2685
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainSaveFlags(virDomainPtr domain, const char *to,
                   const char *dxml, unsigned int flags)
{
    virConnectPtr conn;

E
Eric Blake 已提交
2686
    VIR_DOMAIN_DEBUG(domain, "to=%s, dxml=%s, flags=%x",
2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700
                     to, NULLSTR(dxml), flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
    conn = domain->conn;
2701
    virCheckNonNullArgGoto(to, error);
2702

2703
    if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags & VIR_DOMAIN_SAVE_PAUSED)) {
2704 2705
        virReportInvalidArg(flags, "%s",
                            _("running and paused flags are mutually exclusive"));
2706 2707 2708
        goto error;
    }

2709 2710 2711 2712 2713 2714
    if (conn->driver->domainSaveFlags) {
        int ret;
        char *absolute_to;

        /* We must absolutize the file path as the save is done out of process */
        if (virFileAbsPath(to, &absolute_to) < 0) {
2715
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735
                            _("could not build absolute output file path"));
            goto error;
        }

        ret = conn->driver->domainSaveFlags(domain, absolute_to, dxml, flags);

        VIR_FREE(absolute_to);

        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

2736 2737
/**
 * virDomainRestore:
2738
 * @conn: pointer to the hypervisor connection
2739
 * @from: path to the input file
2740 2741 2742
 *
 * This method will restore a domain saved to disk by virDomainSave().
 *
2743 2744
 * See virDomainRestoreFlags() for more control.
 *
2745 2746 2747
 * Returns 0 in case of success and -1 in case of failure.
 */
int
2748 2749
virDomainRestore(virConnectPtr conn, const char *from)
{
2750
    VIR_DEBUG("conn=%p, from=%s", conn, from);
2751

2752 2753
    virResetLastError();

D
Daniel Veillard 已提交
2754
    if (!VIR_IS_CONNECT(conn)) {
2755
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
2756
        virDispatchError(NULL);
2757
        return -1;
D
Daniel Veillard 已提交
2758
    }
2759
    if (conn->flags & VIR_CONNECT_RO) {
2760
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
2761
        goto error;
2762
    }
2763
    virCheckNonNullArgGoto(from, error);
D
Daniel Veillard 已提交
2764

2765 2766 2767
    if (conn->driver->domainRestore) {
        int ret;
        char *absolute_from;
2768

2769 2770
        /* We must absolutize the file path as the restore is done out of process */
        if (virFileAbsPath(from, &absolute_from) < 0) {
2771
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
2772
                            _("could not build absolute input file path"));
2773 2774
            goto error;
        }
2775

2776 2777 2778 2779
        ret = conn->driver->domainRestore(conn, absolute_from);

        VIR_FREE(absolute_from);

2780 2781 2782 2783
        if (ret < 0)
            goto error;
        return ret;
    }
2784

2785
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
2786 2787

error:
2788
    virDispatchError(conn);
2789
    return -1;
D
Daniel Veillard 已提交
2790 2791
}

2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812
/**
 * virDomainRestoreFlags:
 * @conn: pointer to the hypervisor connection
 * @from: path to the input file
 * @dxml: (optional) XML config for adjusting guest xml used on restore
 * @flags: bitwise-OR of virDomainSaveRestoreFlags
 *
 * This method will restore a domain saved to disk by virDomainSave().
 *
 * If the hypervisor supports it, @dxml can be used to alter
 * host-specific portions of the domain XML that will be used when
 * restoring an image.  For example, it is possible to alter the
 * backing filename that is associated with a disk device, in order to
 * prepare for file renaming done as part of backing up the disk
 * device while the domain is stopped.
 *
 * If @flags includes VIR_DOMAIN_SAVE_BYPASS_CACHE, then libvirt will
 * attempt to bypass the file system cache while restoring the file, or
 * fail if it cannot do so for the given system; this can allow less
 * pressure on file system cache, but also risks slowing saves to NFS.
 *
2813 2814 2815 2816 2817 2818
 * Normally, the saved state file will remember whether the domain was
 * running or paused, and restore defaults to the same state.
 * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
 * @flags will override the default read from the file.  These two
 * flags are mutually exclusive.
 *
2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainRestoreFlags(virConnectPtr conn, const char *from, const char *dxml,
    unsigned int flags)
{
    VIR_DEBUG("conn=%p, from=%s, dxml=%s, flags=%x",
              conn, from, NULLSTR(dxml), flags);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
2839
    virCheckNonNullArgGoto(from, error);
2840

2841
    if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags & VIR_DOMAIN_SAVE_PAUSED)) {
2842 2843
        virReportInvalidArg(flags, "%s",
                            _("running and paused flags are mutually exclusive"));
2844 2845 2846
        goto error;
    }

2847 2848 2849 2850 2851 2852
    if (conn->driver->domainRestoreFlags) {
        int ret;
        char *absolute_from;

        /* We must absolutize the file path as the restore is done out of process */
        if (virFileAbsPath(from, &absolute_from) < 0) {
2853
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874
                            _("could not build absolute input file path"));
            goto error;
        }

        ret = conn->driver->domainRestoreFlags(conn, absolute_from, dxml,
                                               flags);

        VIR_FREE(absolute_from);

        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906
/**
 * virDomainSaveImageGetXMLDesc:
 * @conn: pointer to the hypervisor connection
 * @file: path to saved state file
 * @flags: bitwise-OR of subset of virDomainXMLFlags
 *
 * This method will extract the XML describing the domain at the time
 * a saved state file was created.  @file must be a file created
 * previously by virDomainSave() or virDomainSaveFlags().
 *
 * No security-sensitive data will be included unless @flags contains
 * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
 * connections.  For this API, @flags should not contain either
 * VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU.
 *
 * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of
 * error.  The caller must free() the returned value.
 */
char *
virDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *file,
                             unsigned int flags)
{
    VIR_DEBUG("conn=%p, file=%s, flags=%x",
              conn, file, flags);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }
2907
    virCheckNonNullArgGoto(file, error);
2908 2909

    if ((conn->flags & VIR_CONNECT_RO) && (flags & VIR_DOMAIN_XML_SECURE)) {
2910
        virLibConnError(VIR_ERR_OPERATION_DENIED, "%s",
2911 2912 2913 2914 2915 2916 2917 2918 2919 2920
                        _("virDomainSaveImageGetXMLDesc with secure flag"));
        goto error;
    }

    if (conn->driver->domainSaveImageGetXMLDesc) {
        char *ret;
        char *absolute_file;

        /* We must absolutize the file path as the read is done out of process */
        if (virFileAbsPath(file, &absolute_file) < 0) {
2921
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947
                            _("could not build absolute input file path"));
            goto error;
        }

        ret = conn->driver->domainSaveImageGetXMLDesc(conn, absolute_file,
                                                      flags);

        VIR_FREE(absolute_file);

        if (!ret)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return NULL;
}

/**
 * virDomainSaveImageDefineXML:
 * @conn: pointer to the hypervisor connection
 * @file: path to saved state file
 * @dxml: XML config for adjusting guest xml used on restore
2948
 * @flags: bitwise-OR of virDomainSaveRestoreFlags
2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959
 *
 * This updates the definition of a domain stored in a saved state
 * file.  @file must be a file created previously by virDomainSave()
 * or virDomainSaveFlags().
 *
 * @dxml can be used to alter host-specific portions of the domain XML
 * that will be used when restoring an image.  For example, it is
 * possible to alter the backing filename that is associated with a
 * disk device, to match renaming done as part of backing up the disk
 * device while the domain is stopped.
 *
2960 2961 2962 2963 2964 2965 2966
 * Normally, the saved state file will remember whether the domain was
 * running or paused, and restore defaults to the same state.
 * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
 * @flags will override the default saved into the file; omitting both
 * leaves the file's default unchanged.  These two flags are mutually
 * exclusive.
 *
2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainSaveImageDefineXML(virConnectPtr conn, const char *file,
                            const char *dxml, unsigned int flags)
{
    VIR_DEBUG("conn=%p, file=%s, dxml=%s, flags=%x",
              conn, file, dxml, flags);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
2987 2988
    virCheckNonNullArgGoto(file, error);
    virCheckNonNullArgGoto(dxml, error);
2989

2990
    if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags & VIR_DOMAIN_SAVE_PAUSED)) {
2991 2992
        virReportInvalidArg(flags, "%s",
                            _("running and paused flags are mutually exclusive"));
2993 2994 2995
        goto error;
    }

2996 2997 2998 2999 3000 3001
    if (conn->driver->domainSaveImageDefineXML) {
        int ret;
        char *absolute_file;

        /* We must absolutize the file path as the read is done out of process */
        if (virFileAbsPath(file, &absolute_file) < 0) {
3002
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023
                            _("could not build absolute input file path"));
            goto error;
        }

        ret = conn->driver->domainSaveImageDefineXML(conn, absolute_file,
                                                     dxml, flags);

        VIR_FREE(absolute_file);

        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

D
Daniel Veillard 已提交
3024 3025 3026 3027
/**
 * virDomainCoreDump:
 * @domain: a domain object
 * @to: path for the core file
3028
 * @flags: bitwise-OR of virDomainCoreDumpFlags
D
Daniel Veillard 已提交
3029 3030 3031
 *
 * This method will dump the core of a domain on a given file for analysis.
 * Note that for remote Xen Daemon the file path will be interpreted in
3032 3033
 * the remote host. Hypervisors may require  the user to manually ensure
 * proper permissions on the file named by @to.
D
Daniel Veillard 已提交
3034
 *
3035 3036 3037 3038
 * If @flags includes VIR_DUMP_CRASH, then leave the guest shut off with
 * a crashed state after the dump completes.  If @flags includes
 * VIR_DUMP_LIVE, then make the core dump while continuing to allow
 * the guest to run; otherwise, the guest is suspended during the dump.
3039 3040
 * VIR_DUMP_RESET flag forces reset of the quest after dump.
 * The above three flags are mutually exclusive.
3041 3042 3043 3044 3045 3046
 *
 * Additionally, if @flags includes VIR_DUMP_BYPASS_CACHE, then libvirt
 * will attempt to bypass the file system cache while creating the file,
 * or fail if it cannot do so for the given system; this can allow less
 * pressure on file system cache, but also risks slowing saves to NFS.
 *
D
Daniel Veillard 已提交
3047 3048 3049
 * Returns 0 in case of success and -1 in case of failure.
 */
int
3050
virDomainCoreDump(virDomainPtr domain, const char *to, unsigned int flags)
D
Daniel Veillard 已提交
3051 3052
{
    virConnectPtr conn;
3053

3054
    VIR_DOMAIN_DEBUG(domain, "to=%s, flags=%x", to, flags);
D
Daniel Veillard 已提交
3055

3056 3057
    virResetLastError();

D
Daniel Veillard 已提交
3058
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
3059
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3060
        virDispatchError(NULL);
3061
        return -1;
D
Daniel Veillard 已提交
3062 3063
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
3064
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
3065
        goto error;
D
Daniel Veillard 已提交
3066 3067
    }
    conn = domain->conn;
3068
    virCheckNonNullArgGoto(to, error);
D
Daniel Veillard 已提交
3069

3070
    if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_LIVE)) {
3071 3072
        virReportInvalidArg(flags, "%s",
                            _("crash and live flags are mutually exclusive"));
3073 3074 3075
        goto error;
    }

3076
    if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_RESET)) {
3077
        virReportInvalidArg(flags, "%s",
3078 3079 3080 3081 3082
                         _("crash and reset flags are mutually exclusive"));
        goto error;
    }

    if ((flags & VIR_DUMP_LIVE) && (flags & VIR_DUMP_RESET)) {
3083 3084
        virReportInvalidArg(flags, "%s",
                            _("live and reset flags are mutually exclusive"));
3085 3086 3087
        goto error;
    }

3088 3089 3090
    if (conn->driver->domainCoreDump) {
        int ret;
        char *absolute_to;
D
Daniel Veillard 已提交
3091

3092 3093
        /* We must absolutize the file path as the save is done out of process */
        if (virFileAbsPath(to, &absolute_to) < 0) {
3094
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
3095
                            _("could not build absolute core file path"));
3096 3097
            goto error;
        }
D
Daniel Veillard 已提交
3098

3099 3100 3101
        ret = conn->driver->domainCoreDump(domain, absolute_to, flags);

        VIR_FREE(absolute_to);
D
Daniel Veillard 已提交
3102

3103 3104 3105 3106
        if (ret < 0)
            goto error;
        return ret;
    }
3107

3108
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
3109 3110

error:
3111
    virDispatchError(domain->conn);
3112
    return -1;
3113 3114
}

3115 3116 3117 3118 3119
/**
 * virDomainScreenshot:
 * @domain: a domain object
 * @stream: stream to use as output
 * @screen: monitor ID to take screenshot from
3120
 * @flags: extra flags; not used yet, so callers should always pass 0
3121 3122 3123 3124 3125 3126 3127
 *
 * Take a screenshot of current domain console as a stream. The image format
 * is hypervisor specific. Moreover, some hypervisors supports multiple
 * displays per domain. These can be distinguished by @screen argument.
 *
 * This call sets up a stream; subsequent use of stream API is necessary
 * to transfer actual data, determine how much data is successfully
J
Ján Tomko 已提交
3128
 * transferred, and detect any errors.
3129 3130 3131 3132
 *
 * The screen ID is the sequential number of screen. In case of multiple
 * graphics cards, heads are enumerated before devices, e.g. having
 * two graphics cards, both with four heads, screen ID 5 addresses
3133
 * the second head on the second card.
3134 3135 3136 3137 3138 3139 3140 3141 3142 3143
 *
 * Returns a string representing the mime-type of the image format, or
 * NULL upon error. The caller must free() the returned value.
 */
char *
virDomainScreenshot(virDomainPtr domain,
                    virStreamPtr stream,
                    unsigned int screen,
                    unsigned int flags)
{
E
Eric Blake 已提交
3144
    VIR_DOMAIN_DEBUG(domain, "stream=%p, flags=%x", stream, flags);
3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }
    if (!VIR_IS_STREAM(stream)) {
        virLibConnError(VIR_ERR_INVALID_STREAM, __FUNCTION__);
        return NULL;
    }
    if (domain->conn->flags & VIR_CONNECT_RO ||
        stream->conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (domain->conn->driver->domainScreenshot) {
        char * ret;
        ret = domain->conn->driver->domainScreenshot(domain, stream,
                                                     screen, flags);

        if (ret == NULL)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return NULL;
}

3180 3181 3182 3183
/**
 * virDomainShutdown:
 * @domain: a domain object
 *
3184
 * Shutdown a domain, the domain object is still usable thereafter but
3185
 * the domain OS is being stopped. Note that the guest OS may ignore the
3186 3187 3188 3189 3190
 * request.  For guests that react to a shutdown request, the differences
 * from virDomainDestroy() are that the guests disk storage will be in a
 * stable state rather than having the (virtual) power cord pulled, and
 * this command returns as soon as the shutdown request is issued rather
 * than blocking until the guest is no longer running.
3191
 *
3192 3193 3194
 * If the domain is transient and has any snapshot metadata (see
 * virDomainSnapshotNum()), then that metadata will automatically
 * be deleted when the domain quits.
3195 3196 3197 3198
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
3199 3200
virDomainShutdown(virDomainPtr domain)
{
3201
    virConnectPtr conn;
3202

3203
    VIR_DOMAIN_DEBUG(domain);
3204

3205 3206
    virResetLastError();

D
Daniel Veillard 已提交
3207
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
3208
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3209
        virDispatchError(NULL);
3210
        return -1;
D
Daniel Veillard 已提交
3211
    }
3212
    if (domain->conn->flags & VIR_CONNECT_RO) {
3213
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
3214
        goto error;
3215
    }
3216

3217 3218
    conn = domain->conn;

3219 3220
    if (conn->driver->domainShutdown) {
        int ret;
3221
        ret = conn->driver->domainShutdown(domain);
3222 3223 3224 3225
        if (ret < 0)
            goto error;
        return ret;
    }
3226

3227
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
3228 3229

error:
3230
    virDispatchError(domain->conn);
3231
    return -1;
3232 3233
}

3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252
/**
 * virDomainShutdownFlags:
 * @domain: a domain object
 * @flags: bitwise-OR of virDomainShutdownFlagValues
 *
 * Shutdown a domain, the domain object is still usable thereafter but
 * the domain OS is being stopped. Note that the guest OS may ignore the
 * request.  For guests that react to a shutdown request, the differences
 * from virDomainDestroy() are that the guest's disk storage will be in a
 * stable state rather than having the (virtual) power cord pulled, and
 * this command returns as soon as the shutdown request is issued rather
 * than blocking until the guest is no longer running.
 *
 * If the domain is transient and has any snapshot metadata (see
 * virDomainSnapshotNum()), then that metadata will automatically
 * be deleted when the domain quits.
 *
 * If @flags is set to zero, then the hypervisor will choose the
 * method of shutdown it considers best. To have greater control
3253 3254 3255
 * pass one or more of the virDomainShutdownFlagValues. The order
 * in which the hypervisor tries each shutdown method is undefined,
 * and a hypervisor is not required to support all methods.
3256 3257 3258 3259 3260 3261 3262 3263
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
{
    virConnectPtr conn;

3264
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    conn = domain->conn;

    if (conn->driver->domainShutdownFlags) {
        int ret;
        ret = conn->driver->domainShutdownFlags(domain, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

3295 3296 3297
/**
 * virDomainReboot:
 * @domain: a domain object
3298
 * @flags: bitwise-OR of virDomainRebootFlagValues
3299 3300 3301 3302 3303
 *
 * Reboot a domain, the domain object is still usable there after but
 * the domain OS is being stopped for a restart.
 * Note that the guest OS may ignore the request.
 *
3304 3305
 * If @flags is set to zero, then the hypervisor will choose the
 * method of shutdown it considers best. To have greater control
3306 3307 3308
 * pass one or more of the virDomainShutdownFlagValues. The order
 * in which the hypervisor tries each shutdown method is undefined,
 * and a hypervisor is not required to support all methods.
3309 3310 3311 3312
 *
 * To use guest agent (VIR_DOMAIN_REBOOT_GUEST_AGENT) the domain XML
 * must have <channel> configured.
 *
3313 3314 3315 3316 3317
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainReboot(virDomainPtr domain, unsigned int flags)
{
3318
    virConnectPtr conn;
3319

3320
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
3321

3322 3323
    virResetLastError();

3324
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
3325
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3326
        virDispatchError(NULL);
3327
        return -1;
3328
    }
3329
    if (domain->conn->flags & VIR_CONNECT_RO) {
3330
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
3331
        goto error;
3332
    }
3333

3334 3335
    conn = domain->conn;

3336 3337
    if (conn->driver->domainReboot) {
        int ret;
3338
        ret = conn->driver->domainReboot(domain, flags);
3339 3340 3341 3342
        if (ret < 0)
            goto error;
        return ret;
    }
3343

3344
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
X
Xu He Jie 已提交
3345 3346 3347 3348 3349 3350 3351 3352 3353

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainReset:
 * @domain: a domain object
3354
 * @flags: extra flags; not used yet, so callers should always pass 0
X
Xu He Jie 已提交
3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387
 *
 * Reset a domain immediately without any guest OS shutdown.
 * Reset emulates the power reset button on a machine, where all
 * hardware sees the RST line set and reinitializes internal state.
 *
 * Note that there is a risk of data loss caused by reset without any
 * guest OS shutdown.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainReset(virDomainPtr domain, unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    conn = domain->conn;

    if (conn->driver->domainReset) {
        int ret;
3388
        ret = conn->driver->domainReset(domain, flags);
X
Xu He Jie 已提交
3389 3390 3391 3392 3393 3394
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
3395 3396

error:
3397
    virDispatchError(domain->conn);
3398
    return -1;
3399 3400
}

3401
/**
3402
 * virDomainGetName:
3403 3404 3405 3406 3407 3408 3409 3410
 * @domain: a domain object
 *
 * Get the public name for that domain
 *
 * Returns a pointer to the name or NULL, the string need not be deallocated
 * its lifetime will be the same as the domain object.
 */
const char *
3411 3412
virDomainGetName(virDomainPtr domain)
{
3413
    VIR_DEBUG("domain=%p", domain);
3414

3415 3416
    virResetLastError();

D
Daniel Veillard 已提交
3417
    if (!VIR_IS_DOMAIN(domain)) {
3418
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3419
        virDispatchError(NULL);
3420
        return NULL;
D
Daniel Veillard 已提交
3421
    }
3422
    return domain->name;
3423 3424
}

3425 3426 3427
/**
 * virDomainGetUUID:
 * @domain: a domain object
3428
 * @uuid: pointer to a VIR_UUID_BUFLEN bytes array
3429 3430 3431 3432 3433 3434
 *
 * Get the UUID for a domain
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
3435 3436
virDomainGetUUID(virDomainPtr domain, unsigned char *uuid)
{
3437
    VIR_DOMAIN_DEBUG(domain, "uuid=%p", uuid);
3438

3439 3440
    virResetLastError();

D
Daniel Veillard 已提交
3441
    if (!VIR_IS_DOMAIN(domain)) {
3442
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3443
        virDispatchError(NULL);
3444
        return -1;
D
Daniel Veillard 已提交
3445
    }
3446
    virCheckNonNullArgReturn(uuid, -1);
D
Daniel Veillard 已提交
3447

3448 3449
    memcpy(uuid, &domain->uuid[0], VIR_UUID_BUFLEN);

3450
    return 0;
3451 3452
}

K
Karel Zak 已提交
3453 3454 3455
/**
 * virDomainGetUUIDString:
 * @domain: a domain object
3456
 * @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
K
Karel Zak 已提交
3457
 *
3458
 * Get the UUID for a domain as string. For more information about
K
Karel Zak 已提交
3459 3460 3461 3462 3463 3464 3465
 * UUID see RFC4122.
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virDomainGetUUIDString(virDomainPtr domain, char *buf)
{
3466
    unsigned char uuid[VIR_UUID_BUFLEN];
3467 3468

    VIR_DOMAIN_DEBUG(domain, "buf=%p", buf);
3469

3470 3471
    virResetLastError();

K
Karel Zak 已提交
3472
    if (!VIR_IS_DOMAIN(domain)) {
3473
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3474
        virDispatchError(NULL);
3475
        return -1;
K
Karel Zak 已提交
3476
    }
3477
    virCheckNonNullArgGoto(buf, error);
3478

K
Karel Zak 已提交
3479
    if (virDomainGetUUID(domain, &uuid[0]))
3480
        goto error;
K
Karel Zak 已提交
3481

3482
    virUUIDFormat(uuid, buf);
3483
    return 0;
3484 3485

error:
3486
    virDispatchError(domain->conn);
3487
    return -1;
K
Karel Zak 已提交
3488 3489
}

3490
/**
3491
 * virDomainGetID:
3492 3493 3494 3495 3496 3497 3498
 * @domain: a domain object
 *
 * Get the hypervisor ID number for the domain
 *
 * Returns the domain ID number or (unsigned int) -1 in case of error
 */
unsigned int
3499 3500
virDomainGetID(virDomainPtr domain)
{
3501
    VIR_DOMAIN_DEBUG(domain);
3502

3503 3504
    virResetLastError();

D
Daniel Veillard 已提交
3505
    if (!VIR_IS_DOMAIN(domain)) {
3506
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3507
        virDispatchError(NULL);
3508
        return (unsigned int)-1;
D
Daniel Veillard 已提交
3509
    }
3510
    return domain->id;
3511 3512
}

3513 3514 3515 3516 3517 3518
/**
 * virDomainGetOSType:
 * @domain: a domain object
 *
 * Get the type of domain operation system.
 *
3519 3520
 * Returns the new string or NULL in case of error, the string must be
 *         freed by the caller.
3521 3522
 */
char *
3523 3524
virDomainGetOSType(virDomainPtr domain)
{
3525
    virConnectPtr conn;
3526

3527
    VIR_DOMAIN_DEBUG(domain);
3528

3529 3530 3531
    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
3532
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3533
        virDispatchError(NULL);
3534
        return NULL;
D
Daniel Veillard 已提交
3535
    }
3536

3537 3538
    conn = domain->conn;

3539 3540
    if (conn->driver->domainGetOSType) {
        char *ret;
3541
        ret = conn->driver->domainGetOSType(domain);
3542 3543 3544 3545
        if (!ret)
            goto error;
        return ret;
    }
3546

3547
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
3548 3549

error:
3550
    virDispatchError(domain->conn);
3551
    return NULL;
3552 3553
}

3554
/**
3555
 * virDomainGetMaxMemory:
3556
 * @domain: a domain object or NULL
3557
 *
3558 3559 3560 3561
 * Retrieve the maximum amount of physical memory allocated to a
 * domain. If domain is NULL, then this get the amount of memory reserved
 * to Domain0 i.e. the domain where the application runs.
 *
3562 3563
 * Returns the memory size in kibibytes (blocks of 1024 bytes), or 0 in
 * case of error.
3564 3565
 */
unsigned long
3566 3567
virDomainGetMaxMemory(virDomainPtr domain)
{
3568
    virConnectPtr conn;
3569

3570
    VIR_DOMAIN_DEBUG(domain);
3571

3572 3573
    virResetLastError();

D
Daniel Veillard 已提交
3574
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
3575
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3576
        virDispatchError(NULL);
3577
        return 0;
D
Daniel Veillard 已提交
3578
    }
3579

3580 3581
    conn = domain->conn;

3582
    if (conn->driver->domainGetMaxMemory) {
3583
        unsigned long long ret;
3584
        ret = conn->driver->domainGetMaxMemory(domain);
3585 3586
        if (ret == 0)
            goto error;
3587 3588 3589 3590 3591
        if ((unsigned long) ret != ret) {
            virLibDomainError(VIR_ERR_OVERFLOW, _("result too large: %llu"),
                              ret);
            goto error;
        }
3592 3593
        return ret;
    }
3594

3595
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
3596 3597

error:
3598
    virDispatchError(domain->conn);
3599
    return 0;
3600 3601
}

D
Daniel Veillard 已提交
3602
/**
3603
 * virDomainSetMaxMemory:
D
Daniel Veillard 已提交
3604
 * @domain: a domain object or NULL
3605
 * @memory: the memory size in kibibytes (blocks of 1024 bytes)
3606
 *
D
Daniel Veillard 已提交
3607 3608 3609
 * Dynamically change the maximum amount of physical memory allocated to a
 * domain. If domain is NULL, then this change the amount of memory reserved
 * to Domain0 i.e. the domain where the application runs.
3610
 * This function may require privileged access to the hypervisor.
D
Daniel Veillard 已提交
3611
 *
3612 3613 3614
 * This command is hypervisor-specific for whether active, persistent,
 * or both configurations are changed; for more control, use
 * virDomainSetMemoryFlags().
3615
 *
D
Daniel Veillard 已提交
3616 3617 3618
 * Returns 0 in case of success and -1 in case of failure.
 */
int
3619 3620
virDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
{
3621
    virConnectPtr conn;
3622 3623

    VIR_DOMAIN_DEBUG(domain, "memory=%lu", memory);
3624

3625 3626
    virResetLastError();

3627
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
3628
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3629
        virDispatchError(NULL);
3630
        return -1;
3631
    }
3632
    if (domain->conn->flags & VIR_CONNECT_RO) {
3633
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
3634
        goto error;
3635
    }
3636 3637
    virCheckNonZeroArgGoto(memory, error);

3638
    conn = domain->conn;
3639

3640 3641
    if (conn->driver->domainSetMaxMemory) {
        int ret;
3642
        ret = conn->driver->domainSetMaxMemory(domain, memory);
3643 3644 3645 3646
        if (ret < 0)
            goto error;
        return ret;
    }
3647

3648
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
3649 3650

error:
3651
    virDispatchError(domain->conn);
3652
    return -1;
3653
}
3654

3655 3656 3657
/**
 * virDomainSetMemory:
 * @domain: a domain object or NULL
3658
 * @memory: the memory size in kibibytes (blocks of 1024 bytes)
3659
 *
3660 3661 3662
 * Dynamically change the target amount of physical memory allocated to a
 * domain. If domain is NULL, then this change the amount of memory reserved
 * to Domain0 i.e. the domain where the application runs.
3663
 * This function may require privileged access to the hypervisor.
3664
 *
3665 3666 3667
 * This command only changes the runtime configuration of the domain,
 * so can only be called on an active domain.
 *
3668 3669 3670 3671 3672 3673
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainSetMemory(virDomainPtr domain, unsigned long memory)
{
    virConnectPtr conn;
3674 3675

    VIR_DOMAIN_DEBUG(domain, "memory=%lu", memory);
3676

3677 3678
    virResetLastError();

3679
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
3680
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3681
        virDispatchError(NULL);
3682
        return -1;
3683
    }
3684
    if (domain->conn->flags & VIR_CONNECT_RO) {
3685
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
3686
        goto error;
3687
    }
3688
    virCheckNonZeroArgGoto(memory, error);
3689 3690

    conn = domain->conn;
3691

3692 3693
    if (conn->driver->domainSetMemory) {
        int ret;
3694
        ret = conn->driver->domainSetMemory(domain, memory);
3695 3696 3697 3698
        if (ret < 0)
            goto error;
        return ret;
    }
3699

3700
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
3701 3702

error:
3703
    virDispatchError(domain->conn);
3704
    return -1;
D
Daniel Veillard 已提交
3705 3706
}

3707
/**
3708
 * virDomainSetMemoryFlags:
3709
 * @domain: a domain object or NULL
3710
 * @memory: the memory size in kibibytes (blocks of 1024 bytes)
3711
 * @flags: bitwise-OR of virDomainMemoryModFlags
3712 3713 3714 3715
 *
 * Dynamically change the target amount of physical memory allocated to a
 * domain. If domain is NULL, then this change the amount of memory reserved
 * to Domain0 i.e. the domain where the application runs.
3716
 * This function may require privileged access to the hypervisor.
3717
 *
3718 3719
 * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
 * Both flags may be set. If VIR_DOMAIN_AFFECT_LIVE is set, the change affects
3720
 * a running domain and will fail if domain is not active.
3721
 * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
3722
 * and will fail for transient domains. If neither flag is specified
3723
 * (that is, @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain
3724 3725
 * modifies persistent setup, while an active domain is hypervisor-dependent
 * on whether just live or both live and persistent state is changed.
3726 3727
 * If VIR_DOMAIN_MEM_MAXIMUM is set, the change affects domain's maximum memory
 * size rather than current memory size.
3728
 * Not all hypervisors can support all flag combinations.
3729 3730 3731 3732 3733 3734 3735 3736 3737 3738
 *
 * Returns 0 in case of success, -1 in case of failure.
 */

int
virDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory,
                        unsigned int flags)
{
    virConnectPtr conn;

E
Eric Blake 已提交
3739
    VIR_DOMAIN_DEBUG(domain, "memory=%lu, flags=%x", memory, flags);
3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
3753
    virCheckNonZeroArgGoto(memory, error);
3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764

    conn = domain->conn;

    if (conn->driver->domainSetMemoryFlags) {
        int ret;
        ret = conn->driver->domainSetMemoryFlags(domain, memory, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

3765 3766
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

3767 3768 3769 3770 3771
error:
    virDispatchError(domain->conn);
    return -1;
}

E
Eric Blake 已提交
3772 3773 3774
/* Helper function called to validate incoming client array on any
 * interface that sets typed parameters in the hypervisor.  */
static int
3775
virTypedParameterValidateSet(virConnectPtr conn,
E
Eric Blake 已提交
3776 3777 3778 3779 3780 3781
                             virTypedParameterPtr params,
                             int nparams)
{
    bool string_okay;
    int i;

3782 3783
    string_okay = VIR_DRV_SUPPORTS_FEATURE(conn->driver,
                                           conn,
E
Eric Blake 已提交
3784 3785 3786 3787
                                           VIR_DRV_FEATURE_TYPED_PARAM_STRING);
    for (i = 0; i < nparams; i++) {
        if (strnlen(params[i].field, VIR_TYPED_PARAM_FIELD_LENGTH) ==
            VIR_TYPED_PARAM_FIELD_LENGTH) {
3788 3789 3790 3791
            virReportInvalidArg(params,
                                _("string parameter name '%.*s' too long"),
                                VIR_TYPED_PARAM_FIELD_LENGTH,
                                params[i].field);
E
Eric Blake 已提交
3792 3793 3794 3795 3796
            return -1;
        }
        if (params[i].type == VIR_TYPED_PARAM_STRING) {
            if (string_okay) {
                if (!params[i].value.s) {
3797 3798 3799
                    virReportInvalidArg(params,
                                        _("NULL string parameter '%s'"),
                                        params[i].field);
E
Eric Blake 已提交
3800 3801 3802
                    return -1;
                }
            } else {
3803 3804 3805
                virReportInvalidArg(params,
                                    _("string parameter '%s' unsupported"),
                                    params[i].field);
E
Eric Blake 已提交
3806 3807 3808 3809 3810 3811 3812
                return -1;
            }
        }
    }
    return 0;
}

3813 3814 3815 3816
/**
 * virDomainSetMemoryParameters:
 * @domain: pointer to domain object
 * @params: pointer to memory parameter objects
3817
 * @nparams: number of memory parameter (this value can be the same or
3818
 *          less than the number of parameters supported)
3819
 * @flags: bitwise-OR of virDomainModificationImpact
3820
 *
3821
 * Change all or a subset of the memory tunables.
3822
 * This function may require privileged access to the hypervisor.
3823 3824 3825 3826 3827
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int
virDomainSetMemoryParameters(virDomainPtr domain,
3828
                             virTypedParameterPtr params,
3829 3830 3831
                             int nparams, unsigned int flags)
{
    virConnectPtr conn;
3832

3833
    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
3834
                     params, nparams, flags);
3835 3836 3837 3838

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
3839
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3840 3841 3842 3843
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
3844
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
3845 3846
        goto error;
    }
3847 3848 3849
    virCheckNonNullArgGoto(params, error);
    virCheckPositiveArgGoto(nparams, error);

3850
    if (virTypedParameterValidateSet(domain->conn, params, nparams) < 0)
3851
        goto error;
E
Eric Blake 已提交
3852

3853 3854 3855 3856
    conn = domain->conn;

    if (conn->driver->domainSetMemoryParameters) {
        int ret;
3857
        ret = conn->driver->domainSetMemoryParameters(domain, params, nparams, flags);
3858 3859 3860 3861 3862
        if (ret < 0)
            goto error;
        return ret;
    }

3863
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainGetMemoryParameters:
 * @domain: pointer to domain object
 * @params: pointer to memory parameter object
 *          (return value, allocated by the caller)
3875
 * @nparams: pointer to number of memory parameters; input and output
E
Eric Blake 已提交
3876
 * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
3877
 *
3878 3879 3880 3881
 * Get all memory parameters.  On input, @nparams gives the size of the
 * @params array; on output, @nparams gives how many slots were filled
 * with parameter information, which might be less but will not exceed
 * the input value.
3882
 *
3883 3884 3885
 * As a special case, calling with @params as NULL and @nparams as 0 on
 * input will cause @nparams on output to contain the number of parameters
 * supported by the hypervisor. The caller should then allocate @params
3886
 * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
3887 3888
 * again.
 *
3889
 * Here is a sample code snippet:
3890 3891 3892
 *
 * if ((virDomainGetMemoryParameters(dom, NULL, &nparams, 0) == 0) &&
 *     (nparams != 0)) {
3893 3894
 *     if ((params = malloc(sizeof(*params) * nparams)) == NULL)
 *         goto error;
3895
 *     memset(params, 0, sizeof(*params) * nparams);
3896
 *     if (virDomainGetMemoryParameters(dom, params, &nparams, 0))
3897 3898
 *         goto error;
 * }
3899
 *
3900
 * This function may require privileged access to the hypervisor. This function
3901
 * expects the caller to allocate the @params.
3902 3903 3904 3905 3906
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int
virDomainGetMemoryParameters(virDomainPtr domain,
3907
                             virTypedParameterPtr params,
3908 3909 3910
                             int *nparams, unsigned int flags)
{
    virConnectPtr conn;
3911

3912
    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
3913
                     params, (nparams) ? *nparams : -1, flags);
3914 3915 3916 3917

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
3918
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
3919 3920 3921
        virDispatchError(NULL);
        return -1;
    }
3922 3923 3924 3925 3926
    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (*nparams != 0)
        virCheckNonNullArgGoto(params, error);

E
Eric Blake 已提交
3927 3928 3929
    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_TYPED_PARAM_STRING))
        flags |= VIR_TYPED_PARAM_STRING_OKAY;
3930 3931 3932 3933

    /* At most one of these two flags should be set.  */
    if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
        (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
3934 3935 3936
        virReportInvalidArg(flags,
                            _("flags 'affect live' and 'affect config' in %s are mutually exclusive"),
                            __FUNCTION__);
3937 3938
        goto error;
    }
3939 3940 3941 3942
    conn = domain->conn;

    if (conn->driver->domainGetMemoryParameters) {
        int ret;
3943
        ret = conn->driver->domainGetMemoryParameters(domain, params, nparams, flags);
3944 3945 3946 3947
        if (ret < 0)
            goto error;
        return ret;
    }
3948
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
3949 3950 3951 3952 3953 3954

error:
    virDispatchError(domain->conn);
    return -1;
}

3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988
/**
 * virDomainSetNumaParameters:
 * @domain: pointer to domain object
 * @params: pointer to numa parameter objects
 * @nparams: number of numa parameters (this value can be the same or
 *          less than the number of parameters supported)
 * @flags: bitwise-OR of virDomainModificationImpact
 *
 * Change all or a subset of the numa tunables.
 * This function may require privileged access to the hypervisor.
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int
virDomainSetNumaParameters(virDomainPtr domain,
                           virTypedParameterPtr params,
                           int nparams, unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
                     params, nparams, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
3989 3990
    virCheckNonNullArgGoto(params, error);
    virCheckPositiveArgGoto(nparams, error);
3991
    if (virTypedParameterValidateSet(domain->conn, params, nparams) < 0)
3992
        goto error;
3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055

    conn = domain->conn;

    if (conn->driver->domainSetNumaParameters) {
        int ret;
        ret = conn->driver->domainSetNumaParameters(domain, params, nparams,
                                                    flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainGetNumaParameters:
 * @domain: pointer to domain object
 * @params: pointer to numa parameter object
 *          (return value, allocated by the caller)
 * @nparams: pointer to number of numa parameters
 * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
 *
 * Get all numa parameters.  On input, @nparams gives the size of the
 * @params array; on output, @nparams gives how many slots were filled
 * with parameter information, which might be less but will not exceed
 * the input value.
 *
 * As a special case, calling with @params as NULL and @nparams as 0 on
 * input will cause @nparams on output to contain the number of parameters
 * supported by the hypervisor. The caller should then allocate @params
 * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
 * again.
 *
 * See virDomainGetMemoryParameters() for an equivalent usage example.
 *
 * This function may require privileged access to the hypervisor. This function
 * expects the caller to allocate the @params.
 *
 * Returns -1 in case of error, 0 in case of success.
 */

int
virDomainGetNumaParameters(virDomainPtr domain,
                           virTypedParameterPtr params,
                           int *nparams, unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
                     params, (nparams) ? *nparams : -1, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
4056 4057 4058 4059 4060
    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (*nparams != 0)
        virCheckNonNullArgGoto(params, error);

4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081
    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_TYPED_PARAM_STRING))
        flags |= VIR_TYPED_PARAM_STRING_OKAY;

    conn = domain->conn;

    if (conn->driver->domainGetNumaParameters) {
        int ret;
        ret = conn->driver->domainGetNumaParameters(domain, params, nparams,
                                                    flags);
        if (ret < 0)
            goto error;
        return ret;
    }
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

4082 4083 4084 4085
/**
 * virDomainSetBlkioParameters:
 * @domain: pointer to domain object
 * @params: pointer to blkio parameter objects
4086
 * @nparams: number of blkio parameters (this value can be the same or
4087
 *          less than the number of parameters supported)
E
Eric Blake 已提交
4088
 * @flags: bitwise-OR of virDomainModificationImpact
4089
 *
4090
 * Change all or a subset of the blkio tunables.
4091
 * This function may require privileged access to the hypervisor.
4092 4093 4094 4095 4096
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int
virDomainSetBlkioParameters(virDomainPtr domain,
4097
                             virTypedParameterPtr params,
4098 4099 4100 4101
                             int nparams, unsigned int flags)
{
    virConnectPtr conn;

4102
    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115
                     params, nparams, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
4116 4117 4118
    virCheckNonNullArgGoto(params, error);
    virCheckNonNegativeArgGoto(nparams, error);

4119
    if (virTypedParameterValidateSet(domain->conn, params, nparams) < 0)
4120
        goto error;
E
Eric Blake 已提交
4121

4122 4123 4124 4125
    conn = domain->conn;

    if (conn->driver->domainSetBlkioParameters) {
        int ret;
4126
        ret = conn->driver->domainSetBlkioParameters(domain, params, nparams, flags);
4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainGetBlkioParameters:
 * @domain: pointer to domain object
 * @params: pointer to blkio parameter object
 *          (return value, allocated by the caller)
4144
 * @nparams: pointer to number of blkio parameters; input and output
E
Eric Blake 已提交
4145
 * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
4146
 *
4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158
 * Get all blkio parameters.  On input, @nparams gives the size of the
 * @params array; on output, @nparams gives how many slots were filled
 * with parameter information, which might be less but will not exceed
 * the input value.
 *
 * As a special case, calling with @params as NULL and @nparams as 0 on
 * input will cause @nparams on output to contain the number of parameters
 * supported by the hypervisor. The caller should then allocate @params
 * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
 * again.
 *
 * See virDomainGetMemoryParameters() for an equivalent usage example.
4159
 *
4160
 * This function may require privileged access to the hypervisor. This function
4161 4162 4163 4164 4165 4166
 * expects the caller to allocate the @params.
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int
virDomainGetBlkioParameters(virDomainPtr domain,
4167
                             virTypedParameterPtr params,
4168 4169 4170 4171
                             int *nparams, unsigned int flags)
{
    virConnectPtr conn;

4172
    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
4173 4174 4175 4176 4177 4178 4179 4180 4181
                     params, (nparams) ? *nparams : -1, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
4182 4183 4184 4185 4186
    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (*nparams != 0)
        virCheckNonNullArgGoto(params, error);

E
Eric Blake 已提交
4187 4188 4189
    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_TYPED_PARAM_STRING))
        flags |= VIR_TYPED_PARAM_STRING_OKAY;
4190 4191 4192 4193

    /* At most one of these two flags should be set.  */
    if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
        (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
4194 4195 4196
        virReportInvalidArg(flags,
                            _("flags 'affect live' and 'affect config' in %s are mutually exclusive"),
                            __FUNCTION__);
4197 4198
        goto error;
    }
4199 4200 4201 4202
    conn = domain->conn;

    if (conn->driver->domainGetBlkioParameters) {
        int ret;
4203
        ret = conn->driver->domainGetBlkioParameters(domain, params, nparams, flags);
4204 4205 4206 4207
        if (ret < 0)
            goto error;
        return ret;
    }
4208
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
4209 4210 4211 4212 4213 4214

error:
    virDispatchError(domain->conn);
    return -1;
}

4215 4216
/**
 * virDomainGetInfo:
4217
 * @domain: a domain object
4218
 * @info: pointer to a virDomainInfo structure allocated by the user
4219
 *
4220
 * Extract information about a domain. Note that if the connection
4221
 * used to get the domain is limited only a partial set of the information
4222 4223 4224 4225 4226
 * can be extracted.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
4227 4228
virDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
{
4229
    virConnectPtr conn;
4230 4231

    VIR_DOMAIN_DEBUG(domain, "info=%p", info);
4232

4233 4234
    virResetLastError();

D
Daniel Veillard 已提交
4235
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
4236
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
4237
        virDispatchError(NULL);
4238
        return -1;
D
Daniel Veillard 已提交
4239
    }
4240
    virCheckNonNullArgGoto(info, error);
4241

4242
    memset(info, 0, sizeof(virDomainInfo));
4243

4244 4245
    conn = domain->conn;

4246 4247
    if (conn->driver->domainGetInfo) {
        int ret;
4248
        ret = conn->driver->domainGetInfo(domain, info);
4249 4250 4251 4252
        if (ret < 0)
            goto error;
        return ret;
    }
4253

4254
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
4255 4256

error:
4257
    virDispatchError(domain->conn);
4258
    return -1;
4259
}
4260

4261 4262 4263 4264 4265 4266
/**
 * virDomainGetState:
 * @domain: a domain object
 * @state: returned state of the domain (one of virDomainState)
 * @reason: returned reason which led to @state (one of virDomain*Reason
 * corresponding to the current state); it is allowed to be NULL
4267
 * @flags: extra flags; not used yet, so callers should always pass 0
4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281
 *
 * Extract domain state. Each state can be accompanied with a reason (if known)
 * which led to the state.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainGetState(virDomainPtr domain,
                  int *state,
                  int *reason,
                  unsigned int flags)
{
    virConnectPtr conn;

E
Eric Blake 已提交
4282 4283
    VIR_DOMAIN_DEBUG(domain, "state=%p, reason=%p, flags=%x",
                     state, reason, flags);
4284 4285 4286 4287 4288 4289 4290 4291

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
4292
    virCheckNonNullArgGoto(state, error);
4293 4294 4295 4296 4297 4298

    conn = domain->conn;
    if (conn->driver->domainGetState) {
        int ret;
        ret = conn->driver->domainGetState(domain, state, reason, flags);
        if (ret < 0)
4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainGetControlInfo:
 * @domain: a domain object
 * @info: pointer to a virDomainControlInfo structure allocated by the user
4314
 * @flags: extra flags; not used yet, so callers should always pass 0
4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326
 *
 * Extract details about current state of control interface to a domain.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainGetControlInfo(virDomainPtr domain,
                        virDomainControlInfoPtr info,
                        unsigned int flags)
{
    virConnectPtr conn;

E
Eric Blake 已提交
4327
    VIR_DOMAIN_DEBUG(domain, "info=%p, flags=%x", info, flags);
4328 4329 4330 4331 4332 4333 4334 4335 4336

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

4337
    virCheckNonNullArgGoto(info, error);
4338 4339 4340 4341 4342 4343

    conn = domain->conn;
    if (conn->driver->domainGetControlInfo) {
        int ret;
        ret = conn->driver->domainGetControlInfo(domain, info, flags);
        if (ret < 0)
4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

4355 4356 4357
/**
 * virDomainGetXMLDesc:
 * @domain: a domain object
4358
 * @flags: bitwise-OR of virDomainXMLFlags
4359 4360
 *
 * Provide an XML description of the domain. The description may be reused
4361
 * later to relaunch the domain with virDomainCreateXML().
4362
 *
4363 4364 4365 4366 4367 4368 4369 4370 4371 4372
 * No security-sensitive data will be included unless @flags contains
 * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
 * connections.  If @flags includes VIR_DOMAIN_XML_INACTIVE, then the
 * XML represents the configuration that will be used on the next boot
 * of a persistent domain; otherwise, the configuration represents the
 * currently running domain.  If @flags contains
 * VIR_DOMAIN_XML_UPDATE_CPU, then the portion of the domain XML
 * describing CPU capabilities is modified to match actual
 * capabilities of the host.
 *
4373 4374 4375 4376
 * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
 *         the caller must free() the returned value.
 */
char *
4377
virDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
4378
{
4379
    virConnectPtr conn;
4380

4381
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
4382

4383 4384 4385
    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
4386
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
4387
        virDispatchError(NULL);
4388
        return NULL;
D
Daniel Veillard 已提交
4389
    }
4390

4391 4392
    conn = domain->conn;

4393
    if ((conn->flags & VIR_CONNECT_RO) && (flags & VIR_DOMAIN_XML_SECURE)) {
4394
        virLibConnError(VIR_ERR_OPERATION_DENIED, "%s",
4395 4396 4397 4398
                        _("virDomainGetXMLDesc with secure flag"));
        goto error;
    }

4399
    if (conn->driver->domainGetXMLDesc) {
4400
        char *ret;
4401
        ret = conn->driver->domainGetXMLDesc(domain, flags);
4402 4403 4404 4405
        if (!ret)
            goto error;
        return ret;
    }
4406

4407
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
4408 4409

error:
4410
    virDispatchError(domain->conn);
4411
    return NULL;
4412
}
4413

4414 4415 4416 4417 4418
/**
 * virConnectDomainXMLFromNative:
 * @conn: a connection object
 * @nativeFormat: configuration format importing from
 * @nativeConfig: the configuration data to import
4419
 * @flags: extra flags; not used yet, so callers should always pass 0
4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432
 *
 * Reads native configuration data  describing a domain, and
 * generates libvirt domain XML. The format of the native
 * data is hypervisor dependant.
 *
 * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
 *         the caller must free() the returned value.
 */
char *virConnectDomainXMLFromNative(virConnectPtr conn,
                                    const char *nativeFormat,
                                    const char *nativeConfig,
                                    unsigned int flags)
{
E
Eric Blake 已提交
4433
    VIR_DEBUG("conn=%p, format=%s, config=%s, flags=%x",
4434
              conn, nativeFormat, nativeConfig, flags);
4435 4436 4437 4438

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
4439
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
4440
        virDispatchError(NULL);
4441
        return NULL;
4442 4443
    }

4444 4445
    virCheckNonNullArgGoto(nativeFormat, error);
    virCheckNonNullArgGoto(nativeConfig, error);
4446

4447
    if (conn->driver->connectDomainXMLFromNative) {
4448
        char *ret;
4449 4450 4451 4452
        ret = conn->driver->connectDomainXMLFromNative(conn,
                                                       nativeFormat,
                                                       nativeConfig,
                                                       flags);
4453 4454 4455 4456 4457
        if (!ret)
            goto error;
        return ret;
    }

4458
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
4459 4460

error:
4461
    virDispatchError(conn);
4462 4463 4464 4465 4466 4467 4468 4469
    return NULL;
}

/**
 * virConnectDomainXMLToNative:
 * @conn: a connection object
 * @nativeFormat: configuration format exporting to
 * @domainXml: the domain configuration to export
4470
 * @flags: extra flags; not used yet, so callers should always pass 0
4471 4472
 *
 * Reads a domain XML configuration document, and generates
E
Eric Blake 已提交
4473
 * a native configuration file describing the domain.
4474 4475 4476 4477 4478 4479 4480 4481 4482 4483
 * The format of the native data is hypervisor dependant.
 *
 * Returns a 0 terminated UTF-8 encoded native config datafile, or NULL in case of error.
 *         the caller must free() the returned value.
 */
char *virConnectDomainXMLToNative(virConnectPtr conn,
                                  const char *nativeFormat,
                                  const char *domainXml,
                                  unsigned int flags)
{
E
Eric Blake 已提交
4484
    VIR_DEBUG("conn=%p, format=%s, xml=%s, flags=%x",
4485
              conn, nativeFormat, domainXml, flags);
4486 4487 4488 4489

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
4490
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
4491
        virDispatchError(NULL);
4492
        return NULL;
4493
    }
4494 4495 4496 4497
    if (conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
4498

4499 4500
    virCheckNonNullArgGoto(nativeFormat, error);
    virCheckNonNullArgGoto(domainXml, error);
4501

4502
    if (conn->driver->connectDomainXMLToNative) {
4503
        char *ret;
4504 4505 4506 4507
        ret = conn->driver->connectDomainXMLToNative(conn,
                                                     nativeFormat,
                                                     domainXml,
                                                     flags);
4508 4509 4510 4511 4512
        if (!ret)
            goto error;
        return ret;
    }

4513
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
4514 4515

error:
4516
    virDispatchError(conn);
4517 4518 4519 4520
    return NULL;
}


4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536
/*
 * Sequence v1:
 *
 *  Dst: Prepare
 *        - Get ready to accept incoming VM
 *        - Generate optional cookie to pass to src
 *
 *  Src: Perform
 *        - Start migration and wait for send completion
 *        - Kill off VM if successful, resume if failed
 *
 *  Dst: Finish
 *        - Wait for recv completion and check status
 *        - Kill off VM if unsuccessful
 *
 */
4537
static virDomainPtr
4538 4539 4540 4541 4542 4543
virDomainMigrateVersion1(virDomainPtr domain,
                         virConnectPtr dconn,
                         unsigned long flags,
                         const char *dname,
                         const char *uri,
                         unsigned long bandwidth)
4544 4545 4546 4547
{
    virDomainPtr ddomain = NULL;
    char *uri_out = NULL;
    char *cookie = NULL;
4548 4549
    int cookielen = 0, ret;
    virDomainInfo info;
4550
    VIR_DOMAIN_DEBUG(domain,
E
Eric Blake 已提交
4551
                     "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
4552
                     dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
4553

4554
    ret = virDomainGetInfo(domain, &info);
4555 4556 4557
    if (ret == 0 && info.state == VIR_DOMAIN_PAUSED) {
        flags |= VIR_MIGRATE_PAUSED;
    }
4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575

    /* Prepare the migration.
     *
     * The destination host may return a cookie, or leave cookie as
     * NULL.
     *
     * The destination host MUST set uri_out if uri_in is NULL.
     *
     * If uri_in is non-NULL, then the destination host may modify
     * the URI by setting uri_out.  If it does not wish to modify
     * the URI, it should leave uri_out as NULL.
     */
    if (dconn->driver->domainMigratePrepare
        (dconn, &cookie, &cookielen, uri, &uri_out, flags, dname,
         bandwidth) == -1)
        goto done;

    if (uri == NULL && uri_out == NULL) {
4576
        virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599
                         _("domainMigratePrepare did not set uri"));
        goto done;
    }
    if (uri_out)
        uri = uri_out; /* Did domainMigratePrepare change URI? */

    /* Perform the migration.  The driver isn't supposed to return
     * until the migration is complete.
     */
    if (domain->conn->driver->domainMigratePerform
        (domain, cookie, cookielen, uri, flags, dname, bandwidth) == -1)
        goto done;

    /* Get the destination domain and return it or error.
     * 'domain' no longer actually exists at this point
     * (or so we hope), but we still use the object in memory
     * in order to get the name.
     */
    dname = dname ? dname : domain->name;
    if (dconn->driver->domainMigrateFinish)
        ddomain = dconn->driver->domainMigrateFinish
            (dconn, dname, cookie, cookielen, uri, flags);
    else
4600
        ddomain = virDomainLookupByName(dconn, dname);
4601 4602

 done:
4603 4604
    VIR_FREE(uri_out);
    VIR_FREE(cookie);
4605 4606 4607
    return ddomain;
}

4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626
/*
 * Sequence v2:
 *
 *  Src: DumpXML
 *        - Generate XML to pass to dst
 *
 *  Dst: Prepare
 *        - Get ready to accept incoming VM
 *        - Generate optional cookie to pass to src
 *
 *  Src: Perform
 *        - Start migration and wait for send completion
 *        - Kill off VM if successful, resume if failed
 *
 *  Dst: Finish
 *        - Wait for recv completion and check status
 *        - Kill off VM if unsuccessful
 *
 */
4627
static virDomainPtr
4628 4629 4630 4631 4632 4633
virDomainMigrateVersion2(virDomainPtr domain,
                         virConnectPtr dconn,
                         unsigned long flags,
                         const char *dname,
                         const char *uri,
                         unsigned long bandwidth)
4634 4635 4636 4637 4638 4639
{
    virDomainPtr ddomain = NULL;
    char *uri_out = NULL;
    char *cookie = NULL;
    char *dom_xml = NULL;
    int cookielen = 0, ret;
4640
    virDomainInfo info;
4641
    virErrorPtr orig_err = NULL;
4642
    unsigned int getxml_flags = 0;
4643
    int cancelled;
4644
    VIR_DOMAIN_DEBUG(domain,
E
Eric Blake 已提交
4645
                     "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
4646
                     dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663

    /* Prepare the migration.
     *
     * The destination host may return a cookie, or leave cookie as
     * NULL.
     *
     * The destination host MUST set uri_out if uri_in is NULL.
     *
     * If uri_in is non-NULL, then the destination host may modify
     * the URI by setting uri_out.  If it does not wish to modify
     * the URI, it should leave uri_out as NULL.
     */

    /* In version 2 of the protocol, the prepare step is slightly
     * different.  We fetch the domain XML of the source domain
     * and pass it to Prepare2.
     */
4664
    if (!domain->conn->driver->domainGetXMLDesc) {
4665
        virLibConnError(VIR_ERR_INTERNAL_ERROR, __FUNCTION__);
4666
        virDispatchError(domain->conn);
4667 4668
        return NULL;
    }
4669 4670 4671 4672 4673 4674 4675 4676 4677

    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_XML_MIGRATABLE)) {
        getxml_flags |= VIR_DOMAIN_XML_MIGRATABLE;
    } else {
        getxml_flags |= VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_UPDATE_CPU;
    }

    dom_xml = domain->conn->driver->domainGetXMLDesc(domain, getxml_flags);
4678 4679 4680
    if (!dom_xml)
        return NULL;

4681
    ret = virDomainGetInfo(domain, &info);
4682 4683 4684 4685
    if (ret == 0 && info.state == VIR_DOMAIN_PAUSED) {
        flags |= VIR_MIGRATE_PAUSED;
    }

4686
    VIR_DEBUG("Prepare2 %p flags=%lx", dconn, flags);
4687 4688 4689
    ret = dconn->driver->domainMigratePrepare2
        (dconn, &cookie, &cookielen, uri, &uri_out, flags, dname,
         bandwidth, dom_xml);
4690
    VIR_FREE(dom_xml);
4691 4692 4693 4694
    if (ret == -1)
        goto done;

    if (uri == NULL && uri_out == NULL) {
4695
        virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
4696
                         _("domainMigratePrepare2 did not set uri"));
4697
        virDispatchError(domain->conn);
4698 4699
        cancelled = 1;
        goto finish;
4700 4701 4702 4703 4704 4705 4706
    }
    if (uri_out)
        uri = uri_out; /* Did domainMigratePrepare2 change URI? */

    /* Perform the migration.  The driver isn't supposed to return
     * until the migration is complete.
     */
4707
    VIR_DEBUG("Perform %p", domain->conn);
4708 4709 4710
    ret = domain->conn->driver->domainMigratePerform
        (domain, cookie, cookielen, uri, flags, dname, bandwidth);

4711 4712 4713 4714
    /* Perform failed. Make sure Finish doesn't overwrite the error */
    if (ret < 0)
        orig_err = virSaveLastError();

4715 4716 4717 4718 4719 4720
    /* If Perform returns < 0, then we need to cancel the VM
     * startup on the destination
     */
    cancelled = ret < 0 ? 1 : 0;

finish:
4721 4722 4723 4724 4725
    /* In version 2 of the migration protocol, we pass the
     * status code from the sender to the destination host,
     * so it can do any cleanup if the migration failed.
     */
    dname = dname ? dname : domain->name;
4726
    VIR_DEBUG("Finish2 %p ret=%d", dconn, ret);
4727
    ddomain = dconn->driver->domainMigrateFinish2
4728
        (dconn, dname, cookie, cookielen, uri, flags, cancelled);
4729 4730

 done:
4731 4732 4733 4734
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
4735 4736
    VIR_FREE(uri_out);
    VIR_FREE(cookie);
4737 4738 4739
    return ddomain;
}

4740

4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767
/*
 * Sequence v3:
 *
 *  Src: Begin
 *        - Generate XML to pass to dst
 *        - Generate optional cookie to pass to dst
 *
 *  Dst: Prepare
 *        - Get ready to accept incoming VM
 *        - Generate optional cookie to pass to src
 *
 *  Src: Perform
 *        - Start migration and wait for send completion
 *        - Generate optional cookie to pass to dst
 *
 *  Dst: Finish
 *        - Wait for recv completion and check status
 *        - Kill off VM if failed, resume if success
 *        - Generate optional cookie to pass to src
 *
 *  Src: Confirm
 *        - Kill off VM if success, resume if failed
 *
 */
static virDomainPtr
virDomainMigrateVersion3(virDomainPtr domain,
                         virConnectPtr dconn,
4768
                         const char *xmlin,
4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783
                         unsigned long flags,
                         const char *dname,
                         const char *uri,
                         unsigned long bandwidth)
{
    virDomainPtr ddomain = NULL;
    char *uri_out = NULL;
    char *cookiein = NULL;
    char *cookieout = NULL;
    char *dom_xml = NULL;
    int cookieinlen = 0;
    int cookieoutlen = 0;
    int ret;
    virDomainInfo info;
    virErrorPtr orig_err = NULL;
4784 4785
    int cancelled = 1;
    unsigned long protection = 0;
4786
    bool notify_source = true;
4787

4788
    VIR_DOMAIN_DEBUG(domain, "dconn=%p xmlin=%s, flags=%lx, "
4789 4790 4791
                     "dname=%s, uri=%s, bandwidth=%lu",
                     dconn, NULLSTR(xmlin), flags,
                     NULLSTR(dname), NULLSTR(uri), bandwidth);
4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802

    if (!domain->conn->driver->domainMigrateBegin3 ||
        !domain->conn->driver->domainMigratePerform3 ||
        !domain->conn->driver->domainMigrateConfirm3 ||
        !dconn->driver->domainMigratePrepare3 ||
        !dconn->driver->domainMigrateFinish3) {
        virLibConnError(VIR_ERR_INTERNAL_ERROR, __FUNCTION__);
        virDispatchError(domain->conn);
        return NULL;
    }

4803 4804 4805 4806
    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION))
        protection = VIR_MIGRATE_CHANGE_PROTECTION;

4807 4808
    VIR_DEBUG("Begin3 %p", domain->conn);
    dom_xml = domain->conn->driver->domainMigrateBegin3
4809
        (domain, xmlin, &cookieout, &cookieoutlen,
4810
         flags | protection, dname, bandwidth);
4811 4812 4813
    if (!dom_xml)
        goto done;

4814
    ret = virDomainGetInfo(domain, &info);
4815 4816 4817 4818
    if (ret == 0 && info.state == VIR_DOMAIN_PAUSED) {
        flags |= VIR_MIGRATE_PAUSED;
    }

4819
    VIR_DEBUG("Prepare3 %p flags=%lx", dconn, flags);
4820 4821 4822 4823 4824 4825 4826
    cookiein = cookieout;
    cookieinlen = cookieoutlen;
    cookieout = NULL;
    cookieoutlen = 0;
    ret = dconn->driver->domainMigratePrepare3
        (dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
         uri, &uri_out, flags, dname, bandwidth, dom_xml);
4827
    VIR_FREE(dom_xml);
4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838
    if (ret == -1) {
        if (protection) {
            /* Begin already started a migration job so we need to cancel it by
             * calling Confirm while making sure it doesn't overwrite the error
             */
            orig_err = virSaveLastError();
            goto confirm;
        } else {
            goto done;
        }
    }
4839 4840

    if (uri == NULL && uri_out == NULL) {
4841
        virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
4842 4843
                        _("domainMigratePrepare3 did not set uri"));
        virDispatchError(domain->conn);
4844
        goto finish;
4845 4846 4847 4848
    }
    if (uri_out)
        uri = uri_out; /* Did domainMigratePrepare3 change URI? */

L
liguang 已提交
4849 4850 4851 4852 4853 4854 4855 4856
    if (flags & VIR_MIGRATE_OFFLINE) {
        VIR_DEBUG("Offline migration, skipping Perform phase");
        VIR_FREE(cookieout);
        cookieoutlen = 0;
        cancelled = 0;
        goto finish;
    }

4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867
    /* Perform the migration.  The driver isn't supposed to return
     * until the migration is complete. The src VM should remain
     * running, but in paused state until the destination can
     * confirm migration completion.
     */
    VIR_DEBUG("Perform3 %p uri=%s", domain->conn, uri);
    VIR_FREE(cookiein);
    cookiein = cookieout;
    cookieinlen = cookieoutlen;
    cookieout = NULL;
    cookieoutlen = 0;
4868
    /* dconnuri not relevant in non-P2P modes, so left NULL here */
4869
    ret = domain->conn->driver->domainMigratePerform3
4870
        (domain, NULL, cookiein, cookieinlen,
4871
         &cookieout, &cookieoutlen, NULL,
4872
         uri, flags | protection, dname, bandwidth);
4873 4874

    /* Perform failed. Make sure Finish doesn't overwrite the error */
4875
    if (ret < 0) {
4876
        orig_err = virSaveLastError();
4877 4878 4879 4880 4881
        /* Perform failed so we don't need to call confirm to let source know
         * about the failure.
         */
        notify_source = false;
    }
4882 4883 4884 4885 4886 4887

    /* If Perform returns < 0, then we need to cancel the VM
     * startup on the destination
     */
    cancelled = ret < 0 ? 1 : 0;

4888
finish:
4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901
    /*
     * The status code from the source is passed to the destination.
     * The dest can cleanup if the source indicated it failed to
     * send all migration data. Returns NULL for ddomain if
     * the dest was unable to complete migration.
     */
    VIR_DEBUG("Finish3 %p ret=%d", dconn, ret);
    VIR_FREE(cookiein);
    cookiein = cookieout;
    cookieinlen = cookieoutlen;
    cookieout = NULL;
    cookieoutlen = 0;
    dname = dname ? dname : domain->name;
4902
    ddomain = dconn->driver->domainMigrateFinish3
4903
        (dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
4904 4905 4906 4907 4908 4909 4910 4911 4912
         NULL, uri, flags, cancelled);

    /* If ddomain is NULL, then we were unable to start
     * the guest on the target, and must restart on the
     * source. There is a small chance that the ddomain
     * is NULL due to an RPC failure, in which case
     * ddomain could in fact be running on the dest.
     * The lock manager plugins should take care of
     * safety in this scenario.
4913
     */
4914
    cancelled = ddomain == NULL ? 1 : 0;
4915

4916 4917 4918 4919 4920 4921
    /* If finish3 set an error, and we don't have an earlier
     * one we need to preserve it in case confirm3 overwrites
     */
    if (!orig_err)
        orig_err = virSaveLastError();

4922
confirm:
4923
    /*
4924 4925 4926
     * If cancelled, then src VM will be restarted, else it will be killed.
     * Don't do this if migration failed on source and thus it was already
     * cancelled there.
4927
     */
4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946
    if (notify_source) {
        VIR_DEBUG("Confirm3 %p ret=%d domain=%p", domain->conn, ret, domain);
        VIR_FREE(cookiein);
        cookiein = cookieout;
        cookieinlen = cookieoutlen;
        cookieout = NULL;
        cookieoutlen = 0;
        ret = domain->conn->driver->domainMigrateConfirm3
            (domain, cookiein, cookieinlen,
             flags | protection, cancelled);
        /* If Confirm3 returns -1, there's nothing more we can
         * do, but fortunately worst case is that there is a
         * domain left in 'paused' state on source.
         */
        if (ret < 0) {
            VIR_WARN("Guest %s probably left in 'paused' state on source",
                     domain->name);
        }
    }
4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959

 done:
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
    VIR_FREE(uri_out);
    VIR_FREE(cookiein);
    VIR_FREE(cookieout);
    return ddomain;
}


4960
 /*
4961
  * In normal migration, the libvirt client co-ordinates communication
4962
  * between the 2 libvirtd instances on source & dest hosts.
4963
  *
4964 4965 4966 4967
  * In this peer-2-peer migration alternative, the libvirt client
  * only talks to the source libvirtd instance. The source libvirtd
  * then opens its own connection to the destination and co-ordinates
  * migration itself.
4968 4969
  */
static int
4970 4971 4972 4973 4974 4975 4976
virDomainMigratePeer2Peer(virDomainPtr domain,
                          const char *xmlin,
                          unsigned long flags,
                          const char *dname,
                          const char *dconnuri,
                          const char *uri,
                          unsigned long bandwidth)
4977
{
M
Martin Kletzander 已提交
4978
    virURIPtr tempuri = NULL;
4979
    VIR_DOMAIN_DEBUG(domain, "xmlin=%s, flags=%lx, dname=%s, "
4980 4981 4982
                     "dconnuri=%s, uri=%s, bandwidth=%lu",
                     NULLSTR(xmlin), flags, NULLSTR(dname),
                     NULLSTR(dconnuri), NULLSTR(uri), bandwidth);
4983

4984
    if (!domain->conn->driver->domainMigratePerform) {
4985
        virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
4986
        virDispatchError(domain->conn);
4987 4988 4989
        return -1;
    }

4990
    if (!(tempuri = virURIParse(dconnuri))) {
4991 4992 4993 4994
        virDispatchError(domain->conn);
        return -1;
    }

4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006
    if (!tempuri->server) {
        virReportInvalidArg(dconnuri,
                            _("unable to parse server from dconnuri in %s"),
                            __FUNCTION__);
        virDispatchError(domain->conn);
        virURIFree(tempuri);
        return -1;
    }
    if (STRPREFIX(tempuri->server, "localhost")) {
        virReportInvalidArg(dconnuri,
                            _("unable to parse server from dconnuri in %s"),
                            __FUNCTION__);
5007
        virDispatchError(domain->conn);
5008
        virURIFree(tempuri);
5009 5010
        return -1;
    }
5011
    virURIFree(tempuri);
5012

5013 5014 5015
    /* Perform the migration.  The driver isn't supposed to return
     * until the migration is complete.
     */
5016 5017 5018 5019
    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_MIGRATION_V3)) {
        VIR_DEBUG("Using migration protocol 3");
        return domain->conn->driver->domainMigratePerform3(domain,
5020
                                                           xmlin,
5021 5022 5023 5024
                                                           NULL, /* cookiein */
                                                           0,    /* cookieinlen */
                                                           NULL, /* cookieoutlen */
                                                           NULL, /* cookieoutlen */
5025
                                                           dconnuri,
5026 5027 5028 5029 5030 5031
                                                           uri,
                                                           flags,
                                                           dname,
                                                           bandwidth);
    } else {
        VIR_DEBUG("Using migration protocol 2");
5032 5033 5034 5035 5036
        if (xmlin) {
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Unable to change target guest XML during migration"));
            return -1;
        }
5037 5038 5039 5040 5041
        if (uri) {
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Unable to override peer2peer migration URI"));
            return -1;
        }
5042 5043 5044
        return domain->conn->driver->domainMigratePerform(domain,
                                                          NULL, /* cookie */
                                                          0,    /* cookielen */
5045
                                                          dconnuri,
5046 5047 5048 5049
                                                          flags,
                                                          dname,
                                                          bandwidth);
    }
5050 5051 5052
}


C
Chris Lalancette 已提交
5053
/*
5054
 * In normal migration, the libvirt client co-ordinates communication
5055
 * between the 2 libvirtd instances on source & dest hosts.
C
Chris Lalancette 已提交
5056
 *
5057 5058 5059
 * Some hypervisors support an alternative, direct migration where
 * there is no requirement for a libvirtd instance on the dest host.
 * In this case
5060
 *
5061 5062
 * eg, XenD can talk direct to XenD, so libvirtd on dest does not
 * need to be involved at all, or even running
C
Chris Lalancette 已提交
5063
 */
5064
static int
5065 5066 5067 5068 5069 5070
virDomainMigrateDirect(virDomainPtr domain,
                       const char *xmlin,
                       unsigned long flags,
                       const char *dname,
                       const char *uri,
                       unsigned long bandwidth)
5071
{
5072 5073 5074 5075
    VIR_DOMAIN_DEBUG(domain,
                     "xmlin=%s, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
                     NULLSTR(xmlin), flags, NULLSTR(dname), NULLSTR(uri),
                     bandwidth);
5076

5077
    if (!domain->conn->driver->domainMigratePerform) {
5078
        virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
5079
        virDispatchError(domain->conn);
5080 5081 5082
        return -1;
    }

C
Chris Lalancette 已提交
5083 5084 5085
    /* Perform the migration.  The driver isn't supposed to return
     * until the migration is complete.
     */
5086 5087 5088
    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_MIGRATION_V3)) {
        VIR_DEBUG("Using migration protocol 3");
5089 5090
        /* dconn URI not relevant in direct migration, since no
         * target libvirtd is involved */
5091
        return domain->conn->driver->domainMigratePerform3(domain,
5092
                                                           xmlin,
5093 5094 5095 5096
                                                           NULL, /* cookiein */
                                                           0,    /* cookieinlen */
                                                           NULL, /* cookieoutlen */
                                                           NULL, /* cookieoutlen */
5097
                                                           NULL, /* dconnuri */
5098 5099 5100 5101 5102 5103
                                                           uri,
                                                           flags,
                                                           dname,
                                                           bandwidth);
    } else {
        VIR_DEBUG("Using migration protocol 2");
5104 5105 5106 5107 5108
        if (xmlin) {
            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Unable to change target guest XML during migration"));
            return -1;
        }
5109 5110 5111 5112 5113 5114 5115 5116
        return domain->conn->driver->domainMigratePerform(domain,
                                                          NULL, /* cookie */
                                                          0,    /* cookielen */
                                                          uri,
                                                          flags,
                                                          dname,
                                                          bandwidth);
    }
C
Chris Lalancette 已提交
5117 5118
}

5119

5120 5121 5122 5123
/**
 * virDomainMigrate:
 * @domain: a domain object
 * @dconn: destination host (a connection object)
5124
 * @flags: bitwise-OR of virDomainMigrateFlags
5125 5126
 * @dname: (optional) rename domain to this at destination
 * @uri: (optional) dest hostname/URI as seen from the source host
5127
 * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
5128 5129 5130 5131 5132
 *
 * Migrate the domain object from its current host to the destination
 * host given by dconn (a connection to the destination host).
 *
 * Flags may be one of more of the following:
5133 5134 5135
 *   VIR_MIGRATE_LIVE      Do not pause the VM during migration
 *   VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
 *   VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
C
Chris Lalancette 已提交
5136 5137 5138 5139
 *   VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
 *                            on the destination host.
 *   VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
 *                               domain on the source host.
5140
 *   VIR_MIGRATE_PAUSED    Leave the domain suspended on the remote side.
5141 5142 5143 5144
 *   VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
 *                               disk copy
 *   VIR_MIGRATE_NON_SHARED_INC  Migration with non-shared storage with
 *                               incremental disk copy
5145 5146 5147
 *   VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
 *                                 changes during the migration process (set
 *                                 automatically when supported).
J
Jiri Denemark 已提交
5148
 *   VIR_MIGRATE_UNSAFE    Force migration even if it is considered unsafe.
5149
 *   VIR_MIGRATE_OFFLINE Migrate offline
5150 5151 5152 5153 5154
 *
 * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
 * Applications using the VIR_MIGRATE_PEER2PEER flag will probably
 * prefer to invoke virDomainMigrateToURI, avoiding the need to
 * open connection to the destination host themselves.
5155 5156 5157 5158 5159 5160
 *
 * If a hypervisor supports renaming domains during migration,
 * then you may set the dname parameter to the new name (otherwise
 * it keeps the same name).  If this is not supported by the
 * hypervisor, dname must be NULL or else you will get an error.
 *
5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171
 * If the VIR_MIGRATE_PEER2PEER flag is set, the uri parameter
 * must be a valid libvirt connection URI, by which the source
 * libvirt driver can connect to the destination libvirt. If
 * omitted, the dconn connection object will be queried for its
 * current URI.
 *
 * If the VIR_MIGRATE_PEER2PEER flag is NOT set, the URI parameter
 * takes a hypervisor specific format. The hypervisor capabilities
 * XML includes details of the support URI schemes. If omitted
 * the dconn will be asked for a default URI.
 *
5172 5173 5174 5175
 * If you want to copy non-shared storage within migration you
 * can use either VIR_MIGRATE_NON_SHARED_DISK or
 * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
 *
5176
 * In either case it is typically only necessary to specify a
5177 5178
 * URI if the destination host has multiple interfaces and a
 * specific interface is required to transmit migration data.
5179
 *
5180
 * The maximum bandwidth (in MiB/s) that will be used to do migration
5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198
 * can be specified with the bandwidth parameter.  If set to 0,
 * libvirt will choose a suitable default.  Some hypervisors do
 * not support this feature and will return an error if bandwidth
 * is not 0.
 *
 * To see which features are supported by the current hypervisor,
 * see virConnectGetCapabilities, /capabilities/host/migration_features.
 *
 * There are many limitations on migration imposed by the underlying
 * technology - for example it may not be possible to migrate between
 * different processors even with the same architecture, or between
 * different types of hypervisor.
 *
 * Returns the new domain object if the migration was successful,
 *   or NULL in case of error.  Note that the new domain object
 *   exists in the scope of the destination connection (dconn).
 */
virDomainPtr
5199 5200 5201 5202 5203 5204
virDomainMigrate(virDomainPtr domain,
                 virConnectPtr dconn,
                 unsigned long flags,
                 const char *dname,
                 const char *uri,
                 unsigned long bandwidth)
5205 5206
{
    virDomainPtr ddomain = NULL;
5207

5208 5209
    VIR_DOMAIN_DEBUG(domain,
                     "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
5210
                     dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
5211

5212 5213
    virResetLastError();

5214
    /* First checkout the source */
5215
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
5216
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
5217
        virDispatchError(NULL);
5218 5219
        return NULL;
    }
5220
    if (domain->conn->flags & VIR_CONNECT_RO) {
5221
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
5222
        goto error;
5223 5224
    }

5225 5226
    /* Now checkout the destination */
    if (!VIR_IS_CONNECT(dconn)) {
5227
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
5228 5229 5230 5231
        goto error;
    }
    if (dconn->flags & VIR_CONNECT_RO) {
        /* NB, deliberately report error against source object, not dest */
5232
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
5233 5234 5235
        goto error;
    }

5236 5237 5238 5239 5240 5241 5242 5243 5244
    if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
        flags & VIR_MIGRATE_NON_SHARED_INC) {
        virReportInvalidArg(flags,
                            _("flags 'shared disk' and 'shared incremental' "
                              "in %s are mutually exclusive"),
                            __FUNCTION__);
        goto error;
    }

L
liguang 已提交
5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261
    if (flags & VIR_MIGRATE_OFFLINE) {
        if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                      VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
            virLibConnError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                            _("offline migration is not supported by "
                              "the source host"));
            goto error;
        }
        if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                      VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
            virLibConnError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                            _("offline migration is not supported by "
                              "the destination host"));
            goto error;
        }
    }

5262
    if (flags & VIR_MIGRATE_PEER2PEER) {
5263 5264
        if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                     VIR_DRV_FEATURE_MIGRATION_P2P)) {
5265 5266 5267
            char *dstURI = NULL;
            if (uri == NULL) {
                dstURI = virConnectGetURI(dconn);
5268
                if (!dstURI)
5269 5270
                    return NULL;
            }
5271

5272
            VIR_DEBUG("Using peer2peer migration");
5273
            if (virDomainMigratePeer2Peer(domain, NULL, flags, dname,
5274
                                          uri ? uri : dstURI, NULL, bandwidth) < 0) {
5275 5276 5277 5278
                VIR_FREE(dstURI);
                goto error;
            }
            VIR_FREE(dstURI);
C
Chris Lalancette 已提交
5279

5280
            ddomain = virDomainLookupByName(dconn, dname ? dname : domain->name);
5281 5282
        } else {
            /* This driver does not support peer to peer migration */
5283
            virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
5284 5285
            goto error;
        }
5286
    } else {
5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299
        /* Change protection requires support only on source side, and
         * is only needed in v3 migration, which automatically re-adds
         * the flag for just the source side.  We mask it out for
         * non-peer2peer to allow migration from newer source to an
         * older destination that rejects the flag.  */
        if (flags & VIR_MIGRATE_CHANGE_PROTECTION &&
            !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                      VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION)) {
            virLibConnError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                            _("cannot enforce change protection"));
            goto error;
        }
        flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
5300
        if (flags & VIR_MIGRATE_TUNNELLED) {
5301
            virLibConnError(VIR_ERR_OPERATION_INVALID, "%s",
5302 5303 5304 5305
                            _("cannot perform tunnelled migration without using peer2peer flag"));
            goto error;
        }

C
Chris Lalancette 已提交
5306 5307
        /* Check that migration is supported by both drivers. */
        if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
5308
                                     VIR_DRV_FEATURE_MIGRATION_V3) &&
C
Chris Lalancette 已提交
5309
            VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
5310 5311
                                     VIR_DRV_FEATURE_MIGRATION_V3)) {
            VIR_DEBUG("Using migration protocol 3");
5312 5313
            ddomain = virDomainMigrateVersion3(domain, dconn, NULL,
                                               flags, dname, uri, bandwidth);
5314 5315 5316 5317 5318
        } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                            VIR_DRV_FEATURE_MIGRATION_V2) &&
                   VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                          VIR_DRV_FEATURE_MIGRATION_V2)) {
            VIR_DEBUG("Using migration protocol 2");
5319 5320
            ddomain = virDomainMigrateVersion2(domain, dconn, flags,
                                               dname, uri, bandwidth);
5321 5322 5323 5324 5325
        } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                            VIR_DRV_FEATURE_MIGRATION_V1) &&
                   VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                            VIR_DRV_FEATURE_MIGRATION_V1)) {
            VIR_DEBUG("Using migration protocol 1");
5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349
            ddomain = virDomainMigrateVersion1(domain, dconn, flags,
                                               dname, uri, bandwidth);
        } else {
            /* This driver does not support any migration method */
            virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
            goto error;
        }
    }

    if (ddomain == NULL)
        goto error;

    return ddomain;

error:
    virDispatchError(domain->conn);
    return NULL;
}


/**
 * virDomainMigrate2:
 * @domain: a domain object
 * @dconn: destination host (a connection object)
5350
 * @flags: bitwise-OR of virDomainMigrateFlags
5351 5352 5353
 * @dxml: (optional) XML config for launching guest on target
 * @dname: (optional) rename domain to this at destination
 * @uri: (optional) dest hostname/URI as seen from the source host
5354
 * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367
 *
 * Migrate the domain object from its current host to the destination
 * host given by dconn (a connection to the destination host).
 *
 * Flags may be one of more of the following:
 *   VIR_MIGRATE_LIVE      Do not pause the VM during migration
 *   VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
 *   VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
 *   VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
 *                            on the destination host.
 *   VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
 *                               domain on the source host.
 *   VIR_MIGRATE_PAUSED    Leave the domain suspended on the remote side.
5368 5369 5370 5371
 *   VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
 *                               disk copy
 *   VIR_MIGRATE_NON_SHARED_INC  Migration with non-shared storage with
 *                               incremental disk copy
5372 5373 5374
 *   VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
 *                                 changes during the migration process (set
 *                                 automatically when supported).
J
Jiri Denemark 已提交
5375
 *   VIR_MIGRATE_UNSAFE    Force migration even if it is considered unsafe.
5376
 *   VIR_MIGRATE_OFFLINE Migrate offline
5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398
 *
 * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
 * Applications using the VIR_MIGRATE_PEER2PEER flag will probably
 * prefer to invoke virDomainMigrateToURI, avoiding the need to
 * open connection to the destination host themselves.
 *
 * If a hypervisor supports renaming domains during migration,
 * then you may set the dname parameter to the new name (otherwise
 * it keeps the same name).  If this is not supported by the
 * hypervisor, dname must be NULL or else you will get an error.
 *
 * If the VIR_MIGRATE_PEER2PEER flag is set, the uri parameter
 * must be a valid libvirt connection URI, by which the source
 * libvirt driver can connect to the destination libvirt. If
 * omitted, the dconn connection object will be queried for its
 * current URI.
 *
 * If the VIR_MIGRATE_PEER2PEER flag is NOT set, the URI parameter
 * takes a hypervisor specific format. The hypervisor capabilities
 * XML includes details of the support URI schemes. If omitted
 * the dconn will be asked for a default URI.
 *
5399 5400 5401 5402
 * If you want to copy non-shared storage within migration you
 * can use either VIR_MIGRATE_NON_SHARED_DISK or
 * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
 *
5403 5404 5405 5406
 * In either case it is typically only necessary to specify a
 * URI if the destination host has multiple interfaces and a
 * specific interface is required to transmit migration data.
 *
5407
 * The maximum bandwidth (in MiB/s) that will be used to do migration
5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420
 * can be specified with the bandwidth parameter.  If set to 0,
 * libvirt will choose a suitable default.  Some hypervisors do
 * not support this feature and will return an error if bandwidth
 * is not 0.
 *
 * To see which features are supported by the current hypervisor,
 * see virConnectGetCapabilities, /capabilities/host/migration_features.
 *
 * There are many limitations on migration imposed by the underlying
 * technology - for example it may not be possible to migrate between
 * different processors even with the same architecture, or between
 * different types of hypervisor.
 *
5421 5422 5423 5424 5425 5426 5427 5428
 * If the hypervisor supports it, @dxml can be used to alter
 * host-specific portions of the domain XML that will be used on
 * the destination.  For example, it is possible to alter the
 * backing filename that is associated with a disk device, in order
 * to account for naming differences between source and destination
 * in accessing the underlying storage.  The migration will fail
 * if @dxml would cause any guest-visible changes.  Pass NULL
 * if no changes are needed to the XML between source and destination.
5429
 * @dxml cannot be used to rename the domain during migration (use
5430 5431
 * @dname for that purpose).  Domain name in @dxml must match the
 * original domain name.
5432
 *
5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447
 * Returns the new domain object if the migration was successful,
 *   or NULL in case of error.  Note that the new domain object
 *   exists in the scope of the destination connection (dconn).
 */
virDomainPtr
virDomainMigrate2(virDomainPtr domain,
                  virConnectPtr dconn,
                  const char *dxml,
                  unsigned long flags,
                  const char *dname,
                  const char *uri,
                  unsigned long bandwidth)
{
    virDomainPtr ddomain = NULL;

5448 5449
    VIR_DOMAIN_DEBUG(domain,
                     "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
5450 5451 5452 5453 5454
                     dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);

    virResetLastError();

    /* First checkout the source */
5455
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    /* Now checkout the destination */
    if (!VIR_IS_CONNECT(dconn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        goto error;
    }
    if (dconn->flags & VIR_CONNECT_RO) {
        /* NB, deliberately report error against source object, not dest */
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

5476 5477 5478 5479 5480 5481 5482 5483 5484
    if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
        flags & VIR_MIGRATE_NON_SHARED_INC) {
        virReportInvalidArg(flags,
                            _("flags 'shared disk' and 'shared incremental' "
                              "in %s are mutually exclusive"),
                            __FUNCTION__);
        goto error;
    }

L
liguang 已提交
5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501
    if (flags & VIR_MIGRATE_OFFLINE) {
        if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                      VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
            virLibConnError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                            _("offline migration is not supported by "
                              "the source host"));
            goto error;
        }
        if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                      VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
            virLibConnError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                            _("offline migration is not supported by "
                              "the destination host"));
            goto error;
        }
    }

5502
    if (flags & VIR_MIGRATE_PEER2PEER) {
5503 5504
        if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                     VIR_DRV_FEATURE_MIGRATION_P2P)) {
5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516
            char *dstURI = virConnectGetURI(dconn);
            if (!dstURI)
                return NULL;

            VIR_DEBUG("Using peer2peer migration");
            if (virDomainMigratePeer2Peer(domain, dxml, flags, dname,
                                          dstURI, uri, bandwidth) < 0) {
                VIR_FREE(dstURI);
                goto error;
            }
            VIR_FREE(dstURI);

5517
            ddomain = virDomainLookupByName(dconn, dname ? dname : domain->name);
5518 5519 5520 5521 5522 5523
        } else {
            /* This driver does not support peer to peer migration */
            virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
            goto error;
        }
    } else {
5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536
        /* Change protection requires support only on source side, and
         * is only needed in v3 migration, which automatically re-adds
         * the flag for just the source side.  We mask it out for
         * non-peer2peer to allow migration from newer source to an
         * older destination that rejects the flag.  */
        if (flags & VIR_MIGRATE_CHANGE_PROTECTION &&
            !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                      VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION)) {
            virLibConnError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                            _("cannot enforce change protection"));
            goto error;
        }
        flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
5537
        if (flags & VIR_MIGRATE_TUNNELLED) {
5538
            virLibConnError(VIR_ERR_OPERATION_INVALID, "%s",
5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574
                            _("cannot perform tunnelled migration without using peer2peer flag"));
            goto error;
        }

        /* Check that migration is supported by both drivers. */
        if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                     VIR_DRV_FEATURE_MIGRATION_V3) &&
            VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                     VIR_DRV_FEATURE_MIGRATION_V3)) {
            VIR_DEBUG("Using migration protocol 3");
            ddomain = virDomainMigrateVersion3(domain, dconn, dxml,
                                               flags, dname, uri, bandwidth);
        } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                            VIR_DRV_FEATURE_MIGRATION_V2) &&
                   VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                          VIR_DRV_FEATURE_MIGRATION_V2)) {
            VIR_DEBUG("Using migration protocol 2");
            if (dxml) {
                virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("Unable to change target guest XML during migration"));
                goto error;
            }
            ddomain = virDomainMigrateVersion2(domain, dconn, flags,
                                               dname, uri, bandwidth);
        } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                            VIR_DRV_FEATURE_MIGRATION_V1) &&
                   VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                            VIR_DRV_FEATURE_MIGRATION_V1)) {
            VIR_DEBUG("Using migration protocol 1");
            if (dxml) {
                virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("Unable to change target guest XML during migration"));
                goto error;
            }
            ddomain = virDomainMigrateVersion1(domain, dconn, flags,
                                               dname, uri, bandwidth);
5575
        } else {
5576
            /* This driver does not support any migration method */
5577
            virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
5578 5579
            goto error;
        }
5580 5581
    }

5582 5583
    if (ddomain == NULL)
        goto error;
D
Daniel Veillard 已提交
5584

5585
    return ddomain;
5586 5587

error:
5588
    virDispatchError(domain->conn);
5589
    return NULL;
5590 5591
}

5592 5593 5594 5595 5596

/**
 * virDomainMigrateToURI:
 * @domain: a domain object
 * @duri: mandatory URI for the destination host
5597
 * @flags: bitwise-OR of virDomainMigrateFlags
5598
 * @dname: (optional) rename domain to this at destination
5599
 * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
5600 5601
 *
 * Migrate the domain object from its current host to the destination
D
Dan Kenigsberg 已提交
5602
 * host given by duri.
5603 5604 5605 5606 5607
 *
 * Flags may be one of more of the following:
 *   VIR_MIGRATE_LIVE      Do not pause the VM during migration
 *   VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
 *   VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
5608 5609 5610 5611
 *   VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
 *                            on the destination host.
 *   VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
 *                               domain on the source host.
5612 5613 5614 5615 5616
 *   VIR_MIGRATE_PAUSED    Leave the domain suspended on the remote side.
 *   VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
 *                               disk copy
 *   VIR_MIGRATE_NON_SHARED_INC  Migration with non-shared storage with
 *                               incremental disk copy
5617 5618 5619
 *   VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
 *                                 changes during the migration process (set
 *                                 automatically when supported).
J
Jiri Denemark 已提交
5620
 *   VIR_MIGRATE_UNSAFE    Force migration even if it is considered unsafe.
5621
 *   VIR_MIGRATE_OFFLINE Migrate offline
5622
 *
5623 5624 5625 5626 5627 5628 5629 5630 5631 5632
 * The operation of this API hinges on the VIR_MIGRATE_PEER2PEER flag.
 * If the VIR_MIGRATE_PEER2PEER flag is NOT set, the duri parameter
 * takes a hypervisor specific format. The uri_transports element of the
 * hypervisor capabilities XML includes details of the supported URI
 * schemes. Not all hypervisors will support this mode of migration, so
 * if the VIR_MIGRATE_PEER2PEER flag is not set, then it may be necessary
 * to use the alternative virDomainMigrate API providing and explicit
 * virConnectPtr for the destination host.
 *
 * If the VIR_MIGRATE_PEER2PEER flag IS set, the duri parameter
5633
 * must be a valid libvirt connection URI, by which the source
D
Dan Kenigsberg 已提交
5634
 * libvirt driver can connect to the destination libvirt.
5635
 *
5636 5637
 * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
 *
5638 5639 5640 5641
 * If you want to copy non-shared storage within migration you
 * can use either VIR_MIGRATE_NON_SHARED_DISK or
 * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
 *
5642 5643 5644 5645 5646
 * If a hypervisor supports renaming domains during migration,
 * the dname parameter specifies the new name for the domain.
 * Setting dname to NULL keeps the domain name the same.  If domain
 * renaming is not supported by the hypervisor, dname must be NULL or
 * else an error will be returned.
5647
 *
5648
 * The maximum bandwidth (in MiB/s) that will be used to do migration
5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664
 * can be specified with the bandwidth parameter.  If set to 0,
 * libvirt will choose a suitable default.  Some hypervisors do
 * not support this feature and will return an error if bandwidth
 * is not 0.
 *
 * To see which features are supported by the current hypervisor,
 * see virConnectGetCapabilities, /capabilities/host/migration_features.
 *
 * There are many limitations on migration imposed by the underlying
 * technology - for example it may not be possible to migrate between
 * different processors even with the same architecture, or between
 * different types of hypervisor.
 *
 * Returns 0 if the migration succeeded, -1 upon error.
 */
int
5665 5666 5667 5668 5669
virDomainMigrateToURI(virDomainPtr domain,
                      const char *duri,
                      unsigned long flags,
                      const char *dname,
                      unsigned long bandwidth)
5670
{
5671
    VIR_DOMAIN_DEBUG(domain, "duri=%p, flags=%lx, dname=%s, bandwidth=%lu",
5672
                     NULLSTR(duri), flags, NULLSTR(dname), bandwidth);
5673 5674 5675 5676

    virResetLastError();

    /* First checkout the source */
5677
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
5678
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
5679
        virDispatchError(NULL);
5680 5681 5682
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
5683
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
5684 5685 5686
        goto error;
    }

5687
    virCheckNonNullArgGoto(duri, error);
5688

5689 5690 5691 5692 5693 5694 5695 5696 5697
    if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
        flags & VIR_MIGRATE_NON_SHARED_INC) {
        virReportInvalidArg(flags,
                            _("flags 'shared disk' and 'shared incremental' "
                              "in %s are mutually exclusive"),
                            __FUNCTION__);
        goto error;
    }

L
liguang 已提交
5698 5699 5700 5701 5702 5703 5704 5705 5706
    if (flags & VIR_MIGRATE_OFFLINE &&
        !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                  VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
        virLibConnError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                        _("offline migration is not supported by "
                          "the source host"));
        goto error;
    }

5707
    if (flags & VIR_MIGRATE_PEER2PEER) {
5708 5709
        if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                     VIR_DRV_FEATURE_MIGRATION_P2P)) {
5710
            VIR_DEBUG("Using peer2peer migration");
5711
            if (virDomainMigratePeer2Peer(domain, NULL, flags,
5712
                                          dname, duri, NULL, bandwidth) < 0)
5713 5714 5715
                goto error;
        } else {
            /* No peer to peer migration supported */
5716
            virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
5717 5718 5719
            goto error;
        }
    } else {
5720 5721
        if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                     VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
5722
            VIR_DEBUG("Using direct migration");
5723 5724
            if (virDomainMigrateDirect(domain, NULL, flags,
                                       dname, duri, bandwidth) < 0)
5725 5726 5727
                goto error;
        } else {
            /* Cannot do a migration with only the perform step */
J
Jiri Denemark 已提交
5728 5729 5730
            virLibConnError(VIR_ERR_OPERATION_INVALID, "%s",
                            _("direct migration is not supported by the"
                              " connection driver"));
5731 5732 5733 5734 5735 5736 5737
            goto error;
        }
    }

    return 0;

error:
5738
    virDispatchError(domain->conn);
5739 5740 5741 5742
    return -1;
}


5743 5744 5745 5746 5747 5748
/**
 * virDomainMigrateToURI2:
 * @domain: a domain object
 * @dconnuri: (optional) URI for target libvirtd if @flags includes VIR_MIGRATE_PEER2PEER
 * @miguri: (optional) URI for invoking the migration, not if @flags includs VIR_MIGRATE_TUNNELLED
 * @dxml: (optional) XML config for launching guest on target
5749
 * @flags: bitwise-OR of virDomainMigrateFlags
5750
 * @dname: (optional) rename domain to this at destination
5751
 * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763
 *
 * Migrate the domain object from its current host to the destination
 * host given by duri.
 *
 * Flags may be one of more of the following:
 *   VIR_MIGRATE_LIVE      Do not pause the VM during migration
 *   VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
 *   VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
 *   VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
 *                            on the destination host.
 *   VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
 *                               domain on the source host.
5764 5765 5766 5767 5768
 *   VIR_MIGRATE_PAUSED    Leave the domain suspended on the remote side.
 *   VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
 *                               disk copy
 *   VIR_MIGRATE_NON_SHARED_INC  Migration with non-shared storage with
 *                               incremental disk copy
5769 5770 5771
 *   VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
 *                                 changes during the migration process (set
 *                                 automatically when supported).
J
Jiri Denemark 已提交
5772
 *   VIR_MIGRATE_UNSAFE    Force migration even if it is considered unsafe.
5773
 *   VIR_MIGRATE_OFFLINE Migrate offline
5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790
 *
 * The operation of this API hinges on the VIR_MIGRATE_PEER2PEER flag.
 *
 * If the VIR_MIGRATE_PEER2PEER flag is set, the @dconnuri parameter
 * must be a valid libvirt connection URI, by which the source
 * libvirt driver can connect to the destination libvirt. If the
 * VIR_MIGRATE_PEER2PEER flag is NOT set, then @dconnuri must be
 * NULL.
 *
 * If the VIR_MIGRATE_TUNNELLED flag is NOT set, then the @miguri
 * parameter allows specification of a URI to use to initiate the
 * VM migration. It takes a hypervisor specific format. The uri_transports
 * element of the hypervisor capabilities XML includes details of the
 * supported URI schemes.
 *
 * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
 *
5791 5792 5793 5794
 * If you want to copy non-shared storage within migration you
 * can use either VIR_MIGRATE_NON_SHARED_DISK or
 * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
 *
5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809
 * If a hypervisor supports changing the configuration of the guest
 * during migration, the @dxml parameter specifies the new config
 * for the guest. The configuration must include an identical set
 * of virtual devices, to ensure a stable guest ABI across migration.
 * Only parameters related to host side configuration can be
 * changed in the XML. Hypervisors will validate this and refuse to
 * allow migration if the provided XML would cause a change in the
 * guest ABI,
 *
 * If a hypervisor supports renaming domains during migration,
 * the dname parameter specifies the new name for the domain.
 * Setting dname to NULL keeps the domain name the same.  If domain
 * renaming is not supported by the hypervisor, dname must be NULL or
 * else an error will be returned.
 *
5810
 * The maximum bandwidth (in MiB/s) that will be used to do migration
5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835
 * can be specified with the bandwidth parameter.  If set to 0,
 * libvirt will choose a suitable default.  Some hypervisors do
 * not support this feature and will return an error if bandwidth
 * is not 0.
 *
 * To see which features are supported by the current hypervisor,
 * see virConnectGetCapabilities, /capabilities/host/migration_features.
 *
 * There are many limitations on migration imposed by the underlying
 * technology - for example it may not be possible to migrate between
 * different processors even with the same architecture, or between
 * different types of hypervisor.
 *
 * Returns 0 if the migration succeeded, -1 upon error.
 */
int
virDomainMigrateToURI2(virDomainPtr domain,
                       const char *dconnuri,
                       const char *miguri,
                       const char *dxml,
                       unsigned long flags,
                       const char *dname,
                       unsigned long bandwidth)
{
    VIR_DOMAIN_DEBUG(domain, "dconnuri=%s, miguri=%s, dxml=%s, "
5836
                     "flags=%lx, dname=%s, bandwidth=%lu",
5837 5838 5839 5840 5841 5842
                     NULLSTR(dconnuri), NULLSTR(miguri), NULLSTR(dxml),
                     flags, NULLSTR(dname), bandwidth);

    virResetLastError();

    /* First checkout the source */
5843
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
5844 5845 5846 5847 5848 5849 5850 5851 5852
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

5853 5854 5855 5856 5857 5858 5859 5860 5861
    if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
        flags & VIR_MIGRATE_NON_SHARED_INC) {
        virReportInvalidArg(flags,
                            _("flags 'shared disk' and 'shared incremental' "
                              "in %s are mutually exclusive"),
                            __FUNCTION__);
        goto error;
    }

5862
    if (flags & VIR_MIGRATE_PEER2PEER) {
5863 5864
        if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                     VIR_DRV_FEATURE_MIGRATION_P2P)) {
5865 5866 5867 5868 5869 5870 5871 5872 5873 5874
            VIR_DEBUG("Using peer2peer migration");
            if (virDomainMigratePeer2Peer(domain, dxml, flags,
                                          dname, dconnuri, miguri, bandwidth) < 0)
                goto error;
        } else {
            /* No peer to peer migration supported */
            virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
            goto error;
        }
    } else {
5875 5876
        if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                     VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
5877 5878 5879 5880 5881 5882
            VIR_DEBUG("Using direct migration");
            if (virDomainMigrateDirect(domain, dxml, flags,
                                       dname, miguri, bandwidth) < 0)
                goto error;
        } else {
            /* Cannot do a migration with only the perform step */
J
Jiri Denemark 已提交
5883 5884 5885
            virLibConnError(VIR_ERR_OPERATION_INVALID, "%s",
                            _("direct migration is not supported by the"
                              " connection driver"));
5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897
            goto error;
        }
    }

    return 0;

error:
    virDispatchError(domain->conn);
    return -1;
}


D
Daniel Veillard 已提交
5898 5899
/*
 * Not for public use.  This function is part of the internal
5900 5901 5902
 * implementation of migration in the remote case.
 */
int
5903 5904 5905 5906 5907 5908 5909 5910
virDomainMigratePrepare(virConnectPtr dconn,
                        char **cookie,
                        int *cookielen,
                        const char *uri_in,
                        char **uri_out,
                        unsigned long flags,
                        const char *dname,
                        unsigned long bandwidth)
5911
{
J
John Levon 已提交
5912
    VIR_DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p, "
5913
              "flags=%lx, dname=%s, bandwidth=%lu", dconn, cookie, cookielen,
J
John Levon 已提交
5914
              NULLSTR(uri_in), uri_out, flags, NULLSTR(dname), bandwidth);
5915

5916 5917
    virResetLastError();

5918
    if (!VIR_IS_CONNECT(dconn)) {
5919
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
5920
        virDispatchError(NULL);
5921 5922 5923
        return -1;
    }

5924
    if (dconn->flags & VIR_CONNECT_RO) {
5925
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
5926
        goto error;
5927 5928
    }

5929 5930
    if (dconn->driver->domainMigratePrepare) {
        int ret;
5931 5932 5933
        ret = dconn->driver->domainMigratePrepare(dconn, cookie, cookielen,
                                                  uri_in, uri_out,
                                                  flags, dname, bandwidth);
5934 5935 5936 5937
        if (ret < 0)
            goto error;
        return ret;
    }
5938

5939
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
5940 5941

error:
5942
    virDispatchError(dconn);
5943 5944 5945
    return -1;
}

D
Daniel Veillard 已提交
5946 5947
/*
 * Not for public use.  This function is part of the internal
5948 5949 5950
 * implementation of migration in the remote case.
 */
int
5951 5952 5953 5954 5955 5956 5957
virDomainMigratePerform(virDomainPtr domain,
                        const char *cookie,
                        int cookielen,
                        const char *uri,
                        unsigned long flags,
                        const char *dname,
                        unsigned long bandwidth)
5958 5959
{
    virConnectPtr conn;
5960

5961
    VIR_DOMAIN_DEBUG(domain, "cookie=%p, cookielen=%d, uri=%s, flags=%lx, "
5962 5963
                     "dname=%s, bandwidth=%lu", cookie, cookielen, uri, flags,
                     NULLSTR(dname), bandwidth);
5964

5965 5966
    virResetLastError();

5967
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
5968
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
5969
        virDispatchError(NULL);
5970 5971 5972 5973
        return -1;
    }
    conn = domain->conn;

5974
    if (domain->conn->flags & VIR_CONNECT_RO) {
5975
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
5976
        goto error;
5977 5978
    }

5979 5980
    if (conn->driver->domainMigratePerform) {
        int ret;
5981 5982 5983
        ret = conn->driver->domainMigratePerform(domain, cookie, cookielen,
                                                 uri,
                                                 flags, dname, bandwidth);
5984 5985 5986 5987
        if (ret < 0)
            goto error;
        return ret;
    }
5988

5989
    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
5990 5991

error:
5992
    virDispatchError(domain->conn);
5993 5994 5995
    return -1;
}

D
Daniel Veillard 已提交
5996 5997
/*
 * Not for public use.  This function is part of the internal
5998 5999 6000
 * implementation of migration in the remote case.
 */
virDomainPtr
6001 6002 6003 6004 6005 6006
virDomainMigrateFinish(virConnectPtr dconn,
                       const char *dname,
                       const char *cookie,
                       int cookielen,
                       const char *uri,
                       unsigned long flags)
6007
{
J
John Levon 已提交
6008
    VIR_DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, "
6009
              "flags=%lx", dconn, NULLSTR(dname), cookie, cookielen,
J
John Levon 已提交
6010
              uri, flags);
6011

6012 6013
    virResetLastError();

6014
    if (!VIR_IS_CONNECT(dconn)) {
6015
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
6016
        virDispatchError(NULL);
6017 6018 6019
        return NULL;
    }

6020
    if (dconn->flags & VIR_CONNECT_RO) {
6021
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
6022
        goto error;
6023 6024
    }

6025 6026
    if (dconn->driver->domainMigrateFinish) {
        virDomainPtr ret;
6027 6028 6029
        ret = dconn->driver->domainMigrateFinish(dconn, dname,
                                                 cookie, cookielen,
                                                 uri, flags);
6030 6031 6032 6033
        if (!ret)
            goto error;
        return ret;
    }
6034

6035
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
6036 6037

error:
6038
    virDispatchError(dconn);
6039
    return NULL;
D
Daniel Veillard 已提交
6040 6041 6042
}


D
Daniel Veillard 已提交
6043 6044
/*
 * Not for public use.  This function is part of the internal
D
Daniel Veillard 已提交
6045 6046 6047
 * implementation of migration in the remote case.
 */
int
6048 6049 6050 6051 6052 6053 6054 6055 6056
virDomainMigratePrepare2(virConnectPtr dconn,
                         char **cookie,
                         int *cookielen,
                         const char *uri_in,
                         char **uri_out,
                         unsigned long flags,
                         const char *dname,
                         unsigned long bandwidth,
                         const char *dom_xml)
D
Daniel Veillard 已提交
6057
{
J
John Levon 已提交
6058
    VIR_DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p,"
6059
              "flags=%lx, dname=%s, bandwidth=%lu, dom_xml=%s", dconn,
J
John Levon 已提交
6060 6061
              cookie, cookielen, uri_in, uri_out, flags, NULLSTR(dname),
              bandwidth, dom_xml);
D
Daniel Veillard 已提交
6062

6063 6064
    virResetLastError();

6065
    if (!VIR_IS_CONNECT(dconn)) {
6066
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
6067
        virDispatchError(NULL);
D
Daniel Veillard 已提交
6068 6069 6070
        return -1;
    }

6071
    if (dconn->flags & VIR_CONNECT_RO) {
6072
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
6073
        goto error;
6074 6075
    }

6076 6077
    if (dconn->driver->domainMigratePrepare2) {
        int ret;
6078 6079 6080 6081
        ret = dconn->driver->domainMigratePrepare2(dconn, cookie, cookielen,
                                                   uri_in, uri_out,
                                                   flags, dname, bandwidth,
                                                   dom_xml);
6082 6083 6084 6085
        if (ret < 0)
            goto error;
        return ret;
    }
D
Daniel Veillard 已提交
6086

6087
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
6088 6089

error:
6090
    virDispatchError(dconn);
D
Daniel Veillard 已提交
6091 6092 6093
    return -1;
}

D
Daniel Veillard 已提交
6094 6095
/*
 * Not for public use.  This function is part of the internal
D
Daniel Veillard 已提交
6096 6097 6098
 * implementation of migration in the remote case.
 */
virDomainPtr
6099 6100 6101 6102 6103 6104 6105
virDomainMigrateFinish2(virConnectPtr dconn,
                        const char *dname,
                        const char *cookie,
                        int cookielen,
                        const char *uri,
                        unsigned long flags,
                        int retcode)
D
Daniel Veillard 已提交
6106
{
J
John Levon 已提交
6107
    VIR_DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, "
6108
              "flags=%lx, retcode=%d", dconn, NULLSTR(dname), cookie,
J
John Levon 已提交
6109
              cookielen, uri, flags, retcode);
D
Daniel Veillard 已提交
6110

6111 6112
    virResetLastError();

6113
    if (!VIR_IS_CONNECT(dconn)) {
6114
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
6115
        virDispatchError(NULL);
D
Daniel Veillard 已提交
6116 6117 6118
        return NULL;
    }

6119
    if (dconn->flags & VIR_CONNECT_RO) {
6120
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
6121
        goto error;
6122 6123
    }

6124 6125
    if (dconn->driver->domainMigrateFinish2) {
        virDomainPtr ret;
6126 6127 6128 6129
        ret = dconn->driver->domainMigrateFinish2(dconn, dname,
                                                  cookie, cookielen,
                                                  uri, flags,
                                                  retcode);
6130 6131 6132 6133
        if (!ret)
            goto error;
        return ret;
    }
D
Daniel Veillard 已提交
6134

6135
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
6136 6137

error:
6138
    virDispatchError(dconn);
D
Daniel Veillard 已提交
6139
    return NULL;
6140 6141 6142
}


C
Chris Lalancette 已提交
6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154
/*
 * Not for public use.  This function is part of the internal
 * implementation of migration in the remote case.
 */
int
virDomainMigratePrepareTunnel(virConnectPtr conn,
                              virStreamPtr st,
                              unsigned long flags,
                              const char *dname,
                              unsigned long bandwidth,
                              const char *dom_xml)
{
6155
    VIR_DEBUG("conn=%p, stream=%p, flags=%lx, dname=%s, "
6156
              "bandwidth=%lu, dom_xml=%s", conn, st, flags,
C
Chris Lalancette 已提交
6157 6158 6159 6160 6161
              NULLSTR(dname), bandwidth, dom_xml);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
6162
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
6163
        virDispatchError(NULL);
C
Chris Lalancette 已提交
6164 6165 6166 6167
        return -1;
    }

    if (conn->flags & VIR_CONNECT_RO) {
6168
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
C
Chris Lalancette 已提交
6169 6170 6171 6172
        goto error;
    }

    if (conn != st->conn) {
6173 6174 6175
        virReportInvalidArg(conn,
                            _("conn in %s must match stream connection"),
                            __FUNCTION__);
C
Chris Lalancette 已提交
6176 6177 6178 6179
        goto error;
    }

    if (conn->driver->domainMigratePrepareTunnel) {
6180
        int rv = conn->driver->domainMigratePrepareTunnel(conn, st,
C
Chris Lalancette 已提交
6181 6182 6183 6184 6185 6186 6187
                                                          flags, dname,
                                                          bandwidth, dom_xml);
        if (rv < 0)
            goto error;
        return rv;
    }

6188
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
6189 6190

error:
6191
    virDispatchError(conn);
C
Chris Lalancette 已提交
6192 6193 6194
    return -1;
}

6195 6196 6197 6198 6199 6200
/*
 * Not for public use.  This function is part of the internal
 * implementation of migration in the remote case.
 */
char *
virDomainMigrateBegin3(virDomainPtr domain,
6201
                       const char *xmlin,
6202 6203 6204 6205 6206 6207 6208 6209
                       char **cookieout,
                       int *cookieoutlen,
                       unsigned long flags,
                       const char *dname,
                       unsigned long bandwidth)
{
    virConnectPtr conn;

6210
    VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookieout=%p, cookieoutlen=%p, "
6211
                     "flags=%lx, dname=%s, bandwidth=%lu",
6212
                     NULLSTR(xmlin), cookieout, cookieoutlen, flags,
6213 6214 6215 6216
                     NULLSTR(dname), bandwidth);

    virResetLastError();

6217
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }
    conn = domain->conn;

    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainMigrateBegin3) {
        char *xml;
6231
        xml = conn->driver->domainMigrateBegin3(domain, xmlin,
6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264
                                                cookieout, cookieoutlen,
                                                flags, dname, bandwidth);
        VIR_DEBUG("xml %s", NULLSTR(xml));
        if (!xml)
            goto error;
        return xml;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return NULL;
}


/*
 * Not for public use.  This function is part of the internal
 * implementation of migration in the remote case.
 */
int
virDomainMigratePrepare3(virConnectPtr dconn,
                         const char *cookiein,
                         int cookieinlen,
                         char **cookieout,
                         int *cookieoutlen,
                         const char *uri_in,
                         char **uri_out,
                         unsigned long flags,
                         const char *dname,
                         unsigned long bandwidth,
                         const char *dom_xml)
{
6265 6266 6267 6268 6269
    VIR_DEBUG("dconn=%p, cookiein=%p, cookieinlen=%d, cookieout=%p, "
              "cookieoutlen=%p, uri_in=%s, uri_out=%p, flags=%lx, dname=%s, "
              "bandwidth=%lu, dom_xml=%s",
              dconn, cookiein, cookieinlen, cookieout, cookieoutlen, uri_in,
              uri_out, flags, NULLSTR(dname), bandwidth, dom_xml);
6270 6271 6272

    virResetLastError();

6273
    if (!VIR_IS_CONNECT(dconn)) {
6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (dconn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (dconn->driver->domainMigratePrepare3) {
        int ret;
        ret = dconn->driver->domainMigratePrepare3(dconn,
                                                   cookiein, cookieinlen,
                                                   cookieout, cookieoutlen,
                                                   uri_in, uri_out,
                                                   flags, dname, bandwidth,
                                                   dom_xml);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dconn);
    return -1;
}

/*
 * Not for public use.  This function is part of the internal
 * implementation of migration in the remote case.
 */
int
virDomainMigratePrepareTunnel3(virConnectPtr conn,
                               virStreamPtr st,
                               const char *cookiein,
                               int cookieinlen,
                               char **cookieout,
                               int *cookieoutlen,
                               unsigned long flags,
                               const char *dname,
                               unsigned long bandwidth,
                               const char *dom_xml)

{
6321 6322 6323
    VIR_DEBUG("conn=%p, stream=%p, cookiein=%p, cookieinlen=%d, cookieout=%p, "
              "cookieoutlen=%p, flags=%lx, dname=%s, bandwidth=%lu, "
              "dom_xml=%s",
6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340
              conn, st, cookiein, cookieinlen, cookieout, cookieoutlen, flags,
              NULLSTR(dname), bandwidth, dom_xml);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn != st->conn) {
6341 6342 6343
        virReportInvalidArg(conn,
                            _("conn in %s must match stream connection"),
                            __FUNCTION__);
6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371
        goto error;
    }

    if (conn->driver->domainMigratePrepareTunnel3) {
        int rv = conn->driver->domainMigratePrepareTunnel3(conn, st,
                                                           cookiein, cookieinlen,
                                                           cookieout, cookieoutlen,
                                                           flags, dname,
                                                           bandwidth, dom_xml);
        if (rv < 0)
            goto error;
        return rv;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}


/*
 * Not for public use.  This function is part of the internal
 * implementation of migration in the remote case.
 */
int
virDomainMigratePerform3(virDomainPtr domain,
6372
                         const char *xmlin,
6373 6374 6375 6376
                         const char *cookiein,
                         int cookieinlen,
                         char **cookieout,
                         int *cookieoutlen,
6377
                         const char *dconnuri,
6378 6379 6380 6381 6382 6383 6384
                         const char *uri,
                         unsigned long flags,
                         const char *dname,
                         unsigned long bandwidth)
{
    virConnectPtr conn;

6385
    VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookiein=%p, cookieinlen=%d, "
6386
                     "cookieout=%p, cookieoutlen=%p, dconnuri=%s, "
6387
                     "uri=%s, flags=%lx, dname=%s, bandwidth=%lu",
6388
                     NULLSTR(xmlin), cookiein, cookieinlen,
6389 6390
                     cookieout, cookieoutlen, NULLSTR(dconnuri),
                     NULLSTR(uri), flags, NULLSTR(dname), bandwidth);
6391 6392 6393

    virResetLastError();

6394
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = domain->conn;

    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainMigratePerform3) {
        int ret;
6408
        ret = conn->driver->domainMigratePerform3(domain, xmlin,
6409 6410
                                                  cookiein, cookieinlen,
                                                  cookieout, cookieoutlen,
6411
                                                  dconnuri, uri,
6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429
                                                  flags, dname, bandwidth);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}


/*
 * Not for public use.  This function is part of the internal
 * implementation of migration in the remote case.
 */
6430
virDomainPtr
6431 6432 6433 6434 6435 6436
virDomainMigrateFinish3(virConnectPtr dconn,
                        const char *dname,
                        const char *cookiein,
                        int cookieinlen,
                        char **cookieout,
                        int *cookieoutlen,
6437
                        const char *dconnuri,
6438 6439
                        const char *uri,
                        unsigned long flags,
6440
                        int cancelled)
6441 6442
{
    VIR_DEBUG("dconn=%p, dname=%s, cookiein=%p, cookieinlen=%d, cookieout=%p,"
6443
              "cookieoutlen=%p, dconnuri=%s, uri=%s, flags=%lx, retcode=%d",
6444
              dconn, NULLSTR(dname), cookiein, cookieinlen, cookieout,
6445
              cookieoutlen, NULLSTR(dconnuri), NULLSTR(uri), flags, cancelled);
6446 6447 6448

    virResetLastError();

6449
    if (!VIR_IS_CONNECT(dconn)) {
6450 6451
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
6452
        return NULL;
6453 6454 6455 6456 6457 6458 6459 6460
    }

    if (dconn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (dconn->driver->domainMigrateFinish3) {
6461
        virDomainPtr ret;
6462 6463 6464
        ret = dconn->driver->domainMigrateFinish3(dconn, dname,
                                                  cookiein, cookieinlen,
                                                  cookieout, cookieoutlen,
6465
                                                  dconnuri, uri, flags,
6466 6467
                                                  cancelled);
        if (!ret)
6468 6469 6470 6471 6472 6473 6474 6475
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dconn);
6476
    return NULL;
6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492
}


/*
 * Not for public use.  This function is part of the internal
 * implementation of migration in the remote case.
 */
int
virDomainMigrateConfirm3(virDomainPtr domain,
                         const char *cookiein,
                         int cookieinlen,
                         unsigned long flags,
                         int cancelled)
{
    virConnectPtr conn;

6493 6494
    VIR_DOMAIN_DEBUG(domain,
                     "cookiein=%p, cookieinlen=%d, flags=%lx, cancelled=%d",
6495 6496 6497 6498
                     cookiein, cookieinlen, flags, cancelled);

    virResetLastError();

6499
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = domain->conn;

    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainMigrateConfirm3) {
        int ret;
        ret = conn->driver->domainMigrateConfirm3(domain,
                                                  cookiein, cookieinlen,
                                                  flags, cancelled);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

C
Chris Lalancette 已提交
6528

6529 6530 6531 6532
/**
 * virNodeGetInfo:
 * @conn: pointer to the hypervisor connection
 * @info: pointer to a virNodeInfo structure allocated by the user
6533
 *
6534 6535 6536 6537 6538
 * Extract hardware information about the node.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
6539 6540
virNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
{
6541
    VIR_DEBUG("conn=%p, info=%p", conn, info);
6542

6543 6544
    virResetLastError();

6545
    if (!VIR_IS_CONNECT(conn)) {
6546
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
6547
        virDispatchError(NULL);
6548
        return -1;
6549
    }
6550
    virCheckNonNullArgGoto(info, error);
6551

6552 6553
    if (conn->driver->nodeGetInfo) {
        int ret;
6554
        ret = conn->driver->nodeGetInfo(conn, info);
6555 6556 6557 6558
        if (ret < 0)
            goto error;
        return ret;
    }
6559

6560
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
6561 6562

error:
6563
    virDispatchError(conn);
6564
    return -1;
6565
}
6566

6567 6568 6569 6570 6571 6572
/**
 * virConnectGetCapabilities:
 * @conn: pointer to the hypervisor connection
 *
 * Provides capabilities of the hypervisor / driver.
 *
6573 6574
 * Returns NULL in case of error, or an XML string
 * defining the capabilities.
6575 6576 6577
 * The client must free the returned string after use.
 */
char *
6578
virConnectGetCapabilities(virConnectPtr conn)
6579
{
6580
    VIR_DEBUG("conn=%p", conn);
6581

6582 6583
    virResetLastError();

6584
    if (!VIR_IS_CONNECT(conn)) {
6585
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
6586
        virDispatchError(NULL);
6587 6588 6589
        return NULL;
    }

6590
    if (conn->driver->connectGetCapabilities) {
6591
        char *ret;
6592
        ret = conn->driver->connectGetCapabilities(conn);
6593 6594
        if (!ret)
            goto error;
6595
        VIR_DEBUG("conn=%p ret=%s", conn, ret);
6596 6597
        return ret;
    }
6598

6599
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
6600 6601

error:
6602
    virDispatchError(conn);
6603 6604 6605
    return NULL;
}

6606 6607 6608
/**
 * virNodeGetCPUStats:
 * @conn: pointer to the hypervisor connection.
6609
 * @cpuNum: number of node cpu. (VIR_NODE_CPU_STATS_ALL_CPUS means total cpu
6610 6611 6612 6613
 *          statistics)
 * @params: pointer to node cpu time parameter objects
 * @nparams: number of node cpu time parameter (this value should be same or
 *          less than the number of parameters supported)
6614
 * @flags: extra flags; not used yet, so callers should always pass 0
6615 6616 6617
 *
 * This function provides individual cpu statistics of the node.
 * If you want to get total cpu statistics of the node, you must specify
6618
 * VIR_NODE_CPU_STATS_ALL_CPUS to @cpuNum.
6619 6620 6621 6622 6623 6624
 * The @params array will be filled with the values equal to the number of
 * parameters suggested by @nparams
 *
 * As the value of @nparams is dynamic, call the API setting @nparams to 0 and
 * @params as NULL, the API returns the number of parameters supported by the
 * HV by updating @nparams on SUCCESS. The caller should then allocate @params
6625
 * array, i.e. (sizeof(@virNodeCPUStats) * @nparams) bytes and call
6626 6627 6628 6629 6630 6631
 * the API again.
 *
 * Here is a sample code snippet:
 *
 * if ((virNodeGetCPUStats(conn, cpuNum, NULL, &nparams, 0) == 0) &&
 *     (nparams != 0)) {
6632
 *     if ((params = malloc(sizeof(virNodeCPUStats) * nparams)) == NULL)
6633
 *         goto error;
6634
 *     memset(params, 0, sizeof(virNodeCPUStats) * nparams);
6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659
 *     if (virNodeGetCPUStats(conn, cpuNum, params, &nparams, 0))
 *         goto error;
 * }
 *
 * This function doesn't require privileged access to the hypervisor.
 * This function expects the caller to allocate the @params.
 *
 * CPU time Statistics:
 *
 * VIR_NODE_CPU_STATS_KERNEL:
 *     The cumulative CPU time which spends by kernel,
 *     when the node booting up.(nanoseconds)
 * VIR_NODE_CPU_STATS_USER:
 *     The cumulative CPU time which spends by user processes,
 *     when the node booting up.(nanoseconds)
 * VIR_NODE_CPU_STATS_IDLE:
 *     The cumulative idle CPU time, when the node booting up.(nanoseconds)
 * VIR_NODE_CPU_STATS_IOWAIT:
 *     The cumulative I/O wait CPU time, when the node booting up.(nanoseconds)
 * VIR_NODE_CPU_STATS_UTILIZATION:
 *     The CPU utilization. The usage value is in percent and 100%
 *     represents all CPUs on the server.
 *
 * Returns -1 in case of error, 0 in case of success.
 */
6660 6661 6662 6663
int virNodeGetCPUStats(virConnectPtr conn,
                       int cpuNum,
                       virNodeCPUStatsPtr params,
                       int *nparams, unsigned int flags)
6664
{
6665
    VIR_DEBUG("conn=%p, cpuNum=%d, params=%p, nparams=%d, flags=%x",
6666 6667 6668 6669 6670 6671 6672 6673 6674 6675
              conn, cpuNum, params, nparams ? *nparams : -1, flags);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

6676 6677 6678 6679 6680 6681
    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (((cpuNum < 0) && (cpuNum != VIR_NODE_CPU_STATS_ALL_CPUS))) {
        virReportInvalidArg(cpuNum,
                            _("cpuNum in %s only accepts %d as a negative value"),
                            __FUNCTION__, VIR_NODE_CPU_STATS_ALL_CPUS);
6682 6683 6684 6685 6686
        goto error;
    }

    if (conn->driver->nodeGetCPUStats) {
        int ret;
6687
        ret = conn->driver->nodeGetCPUStats(conn, cpuNum, params, nparams, flags);
6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698
        if (ret < 0)
            goto error;
        return ret;
    }
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

6699 6700 6701
/**
 * virNodeGetMemoryStats:
 * @conn: pointer to the hypervisor connection.
6702 6703
 * @cellNum: number of node cell. (VIR_NODE_MEMORY_STATS_ALL_CELLS means total
 *           cell statistics)
6704 6705 6706
 * @params: pointer to node memory stats objects
 * @nparams: number of node memory stats (this value should be same or
 *          less than the number of stats supported)
6707
 * @flags: extra flags; not used yet, so callers should always pass 0
6708 6709 6710
 *
 * This function provides memory stats of the node.
 * If you want to get total cpu statistics of the node, you must specify
6711
 * VIR_NODE_MEMORY_STATS_ALL_CELLS to @cellNum.
6712 6713 6714 6715 6716 6717
 * The @params array will be filled with the values equal to the number of
 * stats suggested by @nparams
 *
 * As the value of @nparams is dynamic, call the API setting @nparams to 0 and
 * @params as NULL, the API returns the number of parameters supported by the
 * HV by updating @nparams on SUCCESS. The caller should then allocate @params
6718
 * array, i.e. (sizeof(@virNodeMemoryStats) * @nparams) bytes and call
6719 6720 6721 6722 6723 6724
 * the API again.
 *
 * Here is the sample code snippet:
 *
 * if ((virNodeGetMemoryStats(conn, cellNum, NULL, &nparams, 0) == 0) &&
 *     (nparams != 0)) {
6725
 *     if ((params = malloc(sizeof(virNodeMemoryStats) * nparams)) == NULL)
6726
 *         goto error;
6727
 *     memset(params, cellNum, 0, sizeof(virNodeMemoryStats) * nparams);
6728 6729 6730 6731 6732 6733 6734 6735 6736
 *     if (virNodeGetMemoryStats(conn, params, &nparams, 0))
 *         goto error;
 * }
 *
 * This function doesn't require privileged access to the hypervisor.
 * This function expects the caller to allocate the @params.
 *
 * Memory Stats:
 *
6737
 * VIR_NODE_MEMORY_STATS_TOTAL:
6738
 *     The total memory usage.(KB)
6739
 * VIR_NODE_MEMORY_STATS_FREE:
6740 6741
 *     The free memory usage.(KB)
 *     On linux, this usage includes buffers and cached.
6742
 * VIR_NODE_MEMORY_STATS_BUFFERS:
6743
 *     The buffers memory usage.(KB)
6744
 * VIR_NODE_MEMORY_STATS_CACHED:
6745 6746 6747 6748
 *     The cached memory usage.(KB)
 *
 * Returns -1 in case of error, 0 in case of success.
 */
6749 6750 6751 6752
int virNodeGetMemoryStats(virConnectPtr conn,
                          int cellNum,
                          virNodeMemoryStatsPtr params,
                          int *nparams, unsigned int flags)
6753
{
6754
    VIR_DEBUG("conn=%p, cellNum=%d, params=%p, nparams=%d, flags=%x",
6755 6756 6757 6758 6759 6760 6761 6762 6763 6764
              conn, cellNum, params, nparams ? *nparams : -1, flags);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

6765 6766 6767 6768 6769 6770
    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (((cellNum < 0) && (cellNum != VIR_NODE_MEMORY_STATS_ALL_CELLS))) {
        virReportInvalidArg(cpuNum,
                            _("cellNum in %s only accepts %d as a negative value"),
                            __FUNCTION__, VIR_NODE_MEMORY_STATS_ALL_CELLS);
6771 6772 6773 6774 6775
        goto error;
    }

    if (conn->driver->nodeGetMemoryStats) {
        int ret;
6776
        ret = conn->driver->nodeGetMemoryStats(conn, cellNum, params, nparams, flags);
6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787
        if (ret < 0)
            goto error;
        return ret;
    }
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

6788 6789 6790
/**
 * virNodeGetFreeMemory:
 * @conn: pointer to the hypervisor connection
6791
 *
D
Daniel Veillard 已提交
6792
 * provides the free memory available on the Node
6793
 * Note: most libvirt APIs provide memory sizes in kibibytes, but in this
D
Daniel Veillard 已提交
6794
 * function the returned value is in bytes. Divide by 1024 as necessary.
6795
 *
D
Daniel Veillard 已提交
6796
 * Returns the available free memory in bytes or 0 in case of error
6797 6798 6799 6800
 */
unsigned long long
virNodeGetFreeMemory(virConnectPtr conn)
{
6801
    VIR_DEBUG("conn=%p", conn);
6802

6803 6804
    virResetLastError();

6805
    if (!VIR_IS_CONNECT(conn)) {
6806
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
6807
        virDispatchError(NULL);
6808 6809 6810
        return 0;
    }

6811
    if (conn->driver->nodeGetFreeMemory) {
6812
        unsigned long long ret;
6813
        ret = conn->driver->nodeGetFreeMemory(conn);
6814 6815 6816 6817
        if (ret == 0)
            goto error;
        return ret;
    }
6818

6819
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
6820 6821

error:
6822
    virDispatchError(conn);
6823 6824 6825
    return 0;
}

6826 6827 6828 6829 6830 6831 6832 6833 6834 6835
/**
 * virNodeSuspendForDuration:
 * @conn: pointer to the hypervisor connection
 * @target: the state to which the host must be suspended to,
 *         such as: VIR_NODE_SUSPEND_TARGET_MEM (Suspend-to-RAM)
 *                  VIR_NODE_SUSPEND_TARGET_DISK (Suspend-to-Disk)
 *                  VIR_NODE_SUSPEND_TARGET_HYBRID (Hybrid-Suspend,
 *                  which is a combination of the former modes).
 * @duration: the time duration in seconds for which the host
 *            has to be suspended
6836
 * @flags: extra flags; not used yet, so callers should always pass 0
6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853
 *
 * Attempt to suspend the node (host machine) for the given duration of
 * time in the specified state (Suspend-to-RAM, Suspend-to-Disk or
 * Hybrid-Suspend). Schedule the node's Real-Time-Clock interrupt to
 * resume the node after the duration is complete.
 *
 * Returns 0 on success (i.e., the node will be suspended after a short
 * delay), -1 on failure (the operation is not supported, or an attempted
 * suspend is already underway).
 */
int
virNodeSuspendForDuration(virConnectPtr conn,
                          unsigned int target,
                          unsigned long long duration,
                          unsigned int flags)
{

6854 6855
    VIR_DEBUG("conn=%p, target=%d, duration=%lld, flags=%x",
              conn, target, duration, flags);
6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->nodeSuspendForDuration) {
        int ret;
        ret = conn->driver->nodeSuspendForDuration(conn, target,
                                                   duration, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

6886 6887 6888 6889 6890 6891 6892 6893
/*
 * virNodeGetMemoryParameters:
 * @conn: pointer to the hypervisor connection
 * @params: pointer to memory parameter object
 *          (return value, allocated by the caller)
 * @nparams: pointer to number of memory parameters; input and output
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
6894 6895 6896 6897
 * Get all node memory parameters (parameters unsupported by OS will be
 * omitted).  On input, @nparams gives the size of the @params array;
 * on output, @nparams gives how many slots were filled with parameter
 * information, which might be less but will not exceed the input value.
6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958
 *
 * As a special case, calling with @params as NULL and @nparams as 0 on
 * input will cause @nparams on output to contain the number of parameters
 * supported by the hypervisor. The caller should then allocate @params
 * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
 * again.  See virDomainGetMemoryParameters() for an equivalent usage
 * example.
 *
 * Returns 0 in case of success, and -1 in case of failure.
 */
int
virNodeGetMemoryParameters(virConnectPtr conn,
                           virTypedParameterPtr params,
                           int *nparams,
                           unsigned int flags)
{
    VIR_DEBUG("conn=%p, params=%p, nparams=%p, flags=%x",
              conn, params, nparams, flags);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (*nparams != 0)
        virCheckNonNullArgGoto(params, error);

    if (VIR_DRV_SUPPORTS_FEATURE(conn->driver, conn,
                                 VIR_DRV_FEATURE_TYPED_PARAM_STRING))
        flags |= VIR_TYPED_PARAM_STRING_OKAY;

    if (conn->driver->nodeGetMemoryParameters) {
        int ret;
        ret = conn->driver->nodeGetMemoryParameters(conn, params,
                                                    nparams, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

/*
 * virNodeSetMemoryParameters:
 * @conn: pointer to the hypervisor connection
 * @params: pointer to scheduler parameter objects
 * @nparams: number of scheduler parameter objects
 *          (this value can be the same or less than the returned
 *           value nparams of virDomainGetSchedulerType)
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
6959 6960
 * Change all or a subset of the node memory tunables. The function
 * fails if not all of the tunables are supported.
O
Osier Yang 已提交
6961 6962 6963 6964 6965 6966
 *
 * Note that it's not recommended to use this function while the
 * outside tuning program is running (such as ksmtuned under Linux),
 * as they could change the tunables in parallel, which could cause
 * conflicts.
 *
6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013
 * This function may require privileged access to the hypervisor.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virNodeSetMemoryParameters(virConnectPtr conn,
                           virTypedParameterPtr params,
                           int nparams,
                           unsigned int flags)
{
    VIR_DEBUG("conn=%p, params=%p, nparams=%d, flags=%x",
              conn, params, nparams, flags);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    virCheckNonNullArgGoto(params, error);
    virCheckNonNegativeArgGoto(nparams, error);

    if (virTypedParameterValidateSet(conn, params, nparams) < 0)
        goto error;

    if (conn->driver->nodeSetMemoryParameters) {
        int ret;
        ret = conn->driver->nodeSetMemoryParameters(conn, params,
                                                          nparams, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}
7014

7015 7016 7017
/**
 * virDomainGetSchedulerType:
 * @domain: pointer to domain object
7018 7019
 * @nparams: pointer to number of scheduler parameters, can be NULL
 *           (return value)
7020
 *
7021
 * Get the scheduler type and the number of scheduler parameters.
7022 7023 7024 7025 7026 7027 7028 7029
 *
 * Returns NULL in case of error. The caller must free the returned string.
 */
char *
virDomainGetSchedulerType(virDomainPtr domain, int *nparams)
{
    virConnectPtr conn;
    char *schedtype;
7030 7031

    VIR_DOMAIN_DEBUG(domain, "nparams=%p", nparams);
7032

7033 7034
    virResetLastError();

7035
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
7036
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
7037
        virDispatchError(NULL);
7038 7039 7040 7041 7042
        return NULL;
    }
    conn = domain->conn;

    if (conn->driver->domainGetSchedulerType){
7043
        schedtype = conn->driver->domainGetSchedulerType(domain, nparams);
7044 7045
        if (!schedtype)
            goto error;
7046 7047 7048
        return schedtype;
    }

7049
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
7050 7051

error:
7052
    virDispatchError(domain->conn);
7053 7054 7055 7056 7057 7058 7059
    return NULL;
}


/**
 * virDomainGetSchedulerParameters:
 * @domain: pointer to domain object
7060
 * @params: pointer to scheduler parameter objects
7061
 *          (return value)
7062
 * @nparams: pointer to number of scheduler parameter objects
7063 7064 7065 7066 7067 7068 7069
 *          (this value should generally be as large as the returned value
 *           nparams of virDomainGetSchedulerType()); input and output
 *
 * Get all scheduler parameters.  On input, @nparams gives the size of the
 * @params array; on output, @nparams gives how many slots were filled
 * with parameter information, which might be less but will not exceed
 * the input value.  @nparams cannot be 0.
7070
 *
7071
 * It is hypervisor specific whether this returns the live or
7072
 * persistent state; for more control, use
7073
 * virDomainGetSchedulerParametersFlags().
7074 7075 7076 7077 7078
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int
virDomainGetSchedulerParameters(virDomainPtr domain,
7079
                                virTypedParameterPtr params, int *nparams)
7080 7081
{
    virConnectPtr conn;
7082 7083

    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%p", params, nparams);
7084

7085 7086
    virResetLastError();

7087
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
7088
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
7089
        virDispatchError(NULL);
7090 7091
        return -1;
    }
7092

7093 7094 7095
    virCheckNonNullArgGoto(params, error);
    virCheckNonNullArgGoto(nparams, error);
    virCheckPositiveArgGoto(*nparams, error);
7096

7097 7098
    conn = domain->conn;

7099 7100
    if (conn->driver->domainGetSchedulerParameters) {
        int ret;
7101
        ret = conn->driver->domainGetSchedulerParameters(domain, params, nparams);
7102 7103 7104 7105
        if (ret < 0)
            goto error;
        return ret;
    }
7106

7107
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
7108 7109

error:
7110
    virDispatchError(domain->conn);
7111 7112 7113
    return -1;
}

7114 7115 7116 7117 7118 7119 7120
/**
 * virDomainGetSchedulerParametersFlags:
 * @domain: pointer to domain object
 * @params: pointer to scheduler parameter object
 *          (return value)
 * @nparams: pointer to number of scheduler parameter
 *          (this value should be same than the returned value
7121
 *           nparams of virDomainGetSchedulerType()); input and output
E
Eric Blake 已提交
7122
 * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
7123
 *
7124 7125 7126 7127
 * Get all scheduler parameters.  On input, @nparams gives the size of the
 * @params array; on output, @nparams gives how many slots were filled
 * with parameter information, which might be less but will not exceed
 * the input value.  @nparams cannot be 0.
7128
 *
7129 7130
 * The value of @flags can be exactly VIR_DOMAIN_AFFECT_CURRENT,
 * VIR_DOMAIN_AFFECT_LIVE, or VIR_DOMAIN_AFFECT_CONFIG.
7131
 *
7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142
 * Here is a sample code snippet:
 *
 * char *ret = virDomainGetSchedulerType(dom, &nparams);
 * if (ret && nparams != 0) {
 *     if ((params = malloc(sizeof(*params) * nparams)) == NULL)
 *         goto error;
 *     memset(params, 0, sizeof(*params) * nparams);
 *     if (virDomainGetSchedulerParametersFlags(dom, params, &nparams, 0))
 *         goto error;
 * }
 *
7143 7144 7145 7146 7147 7148 7149 7150 7151
 * Returns -1 in case of error, 0 in case of success.
 */
int
virDomainGetSchedulerParametersFlags(virDomainPtr domain,
                                     virTypedParameterPtr params, int *nparams,
                                     unsigned int flags)
{
    virConnectPtr conn;

7152
    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%p, flags=%x",
7153 7154 7155 7156 7157 7158 7159 7160 7161 7162
                     params, nparams, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

7163 7164 7165
    virCheckNonNullArgGoto(params, error);
    virCheckNonNullArgGoto(nparams, error);
    virCheckPositiveArgGoto(*nparams, error);
7166

E
Eric Blake 已提交
7167 7168 7169
    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_TYPED_PARAM_STRING))
        flags |= VIR_TYPED_PARAM_STRING_OKAY;
7170 7171 7172 7173

    /* At most one of these two flags should be set.  */
    if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
        (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
7174 7175 7176
        virReportInvalidArg(flags,
                            _("flags 'affect live' and 'affect config' in %s are mutually exclusive"),
                            __FUNCTION__);
7177 7178
        goto error;
    }
7179 7180 7181 7182
    conn = domain->conn;

    if (conn->driver->domainGetSchedulerParametersFlags) {
        int ret;
7183 7184
        ret = conn->driver->domainGetSchedulerParametersFlags(domain, params,
                                                              nparams, flags);
7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

7197 7198 7199 7200
/**
 * virDomainSetSchedulerParameters:
 * @domain: pointer to domain object
 * @params: pointer to scheduler parameter objects
7201 7202
 * @nparams: number of scheduler parameter objects
 *          (this value can be the same or less than the returned value
7203 7204
 *           nparams of virDomainGetSchedulerType)
 *
7205 7206 7207 7208
 * Change all or a subset or the scheduler parameters.  It is
 * hypervisor-specific whether this sets live, persistent, or both
 * settings; for more control, use
 * virDomainSetSchedulerParametersFlags.
7209 7210 7211 7212
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int
7213
virDomainSetSchedulerParameters(virDomainPtr domain,
7214
                                virTypedParameterPtr params, int nparams)
7215 7216
{
    virConnectPtr conn;
7217 7218

    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d", params, nparams);
7219

7220 7221
    virResetLastError();

7222
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
7223
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
7224
        virDispatchError(NULL);
7225 7226
        return -1;
    }
7227

E
Eric Blake 已提交
7228 7229 7230 7231
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
7232 7233 7234
    virCheckNonNullArgGoto(params, error);
    virCheckNonNegativeArgGoto(nparams, error);

7235
    if (virTypedParameterValidateSet(domain->conn, params, nparams) < 0)
7236
        goto error;
7237

7238 7239
    conn = domain->conn;

7240 7241
    if (conn->driver->domainSetSchedulerParameters) {
        int ret;
7242
        ret = conn->driver->domainSetSchedulerParameters(domain, params, nparams);
7243 7244 7245 7246
        if (ret < 0)
            goto error;
        return ret;
    }
7247

7248
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259

error:
    virDispatchError(domain->conn);
    return -1;
}


/**
 * virDomainSetSchedulerParametersFlags:
 * @domain: pointer to domain object
 * @params: pointer to scheduler parameter objects
7260 7261
 * @nparams: number of scheduler parameter objects
 *          (this value can be the same or less than the returned value
7262
 *           nparams of virDomainGetSchedulerType)
7263
 * @flags: bitwise-OR of virDomainModificationImpact
7264
 *
7265
 * Change a subset or all scheduler parameters.  The value of @flags
7266 7267 7268
 * should be either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of
 * values from VIR_DOMAIN_AFFECT_LIVE and
 * VIR_DOMAIN_AFFECT_CURRENT, although hypervisors vary in which
7269
 * flags are supported.
7270 7271 7272 7273 7274
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int
virDomainSetSchedulerParametersFlags(virDomainPtr domain,
7275
                                     virTypedParameterPtr params,
7276 7277 7278 7279 7280
                                     int nparams,
                                     unsigned int flags)
{
    virConnectPtr conn;

7281
    VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
7282 7283 7284 7285 7286 7287 7288 7289 7290
                     params, nparams, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
7291

E
Eric Blake 已提交
7292 7293 7294 7295
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
7296 7297 7298
    virCheckNonNullArgGoto(params, error);
    virCheckNonNegativeArgGoto(nparams, error);

7299
    if (virTypedParameterValidateSet(domain->conn, params, nparams) < 0)
7300
        goto error;
7301

7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315
    conn = domain->conn;

    if (conn->driver->domainSetSchedulerParametersFlags) {
        int ret;
        ret = conn->driver->domainSetSchedulerParametersFlags(domain,
                                                              params,
                                                              nparams,
                                                              flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
7316 7317

error:
7318
    virDispatchError(domain->conn);
7319 7320 7321 7322
    return -1;
}


7323
/**
7324
 * virDomainBlockStats:
7325
 * @dom: pointer to the domain object
7326
 * @disk: path to the block device, or device shorthand
7327 7328 7329 7330 7331 7332
 * @stats: block device stats (returned)
 * @size: size of stats structure
 *
 * This function returns block device (disk) stats for block
 * devices attached to the domain.
 *
7333
 * The @disk parameter is either the device target shorthand (the
7334 7335 7336 7337 7338
 * <target dev='...'/> sub-element, such as "xvda"), or (since 0.9.8)
 * an unambiguous source name of the block device (the <source
 * file='...'/> sub-element, such as "/path/to/image").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349
 *
 * Domains may have more than one block device.  To get stats for
 * each you should make multiple calls to this function.
 *
 * Individual fields within the stats structure may be returned
 * as -1, which indicates that the hypervisor does not support
 * that particular statistic.
 *
 * Returns: 0 in case of success or -1 in case of failure.
 */
int
7350 7351
virDomainBlockStats(virDomainPtr dom, const char *disk,
                    virDomainBlockStatsPtr stats, size_t size)
7352 7353 7354
{
    virConnectPtr conn;
    struct _virDomainBlockStats stats2 = { -1, -1, -1, -1, -1 };
7355

7356
    VIR_DOMAIN_DEBUG(dom, "disk=%s, stats=%p, size=%zi", disk, stats, size);
7357

7358 7359
    virResetLastError();

7360
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
7361
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
7362
        virDispatchError(NULL);
7363 7364
        return -1;
    }
7365 7366 7367 7368 7369 7370
    virCheckNonNullArgGoto(disk, error);
    virCheckNonNullArgGoto(stats, error);
    if (size > sizeof(stats2)) {
        virReportInvalidArg(size,
                            _("size in %s must not exceed %zu"),
                            __FUNCTION__, sizeof(stats2));
7371 7372
        goto error;
    }
7373 7374 7375
    conn = dom->conn;

    if (conn->driver->domainBlockStats) {
7376
        if (conn->driver->domainBlockStats(dom, disk, &stats2) == -1)
7377
            goto error;
7378

7379
        memcpy(stats, &stats2, size);
7380 7381 7382
        return 0;
    }

7383
    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
7384 7385

error:
7386
    virDispatchError(dom->conn);
7387 7388 7389
    return -1;
}

O
Osier Yang 已提交
7390 7391 7392
/**
 * virDomainBlockStatsFlags:
 * @dom: pointer to domain object
7393
 * @disk: path to the block device, or device shorthand
O
Osier Yang 已提交
7394 7395
 * @params: pointer to block stats parameter object
 *          (return value)
7396
 * @nparams: pointer to number of block stats; input and output
E
Eric Blake 已提交
7397
 * @flags: bitwise-OR of virTypedParameterFlags
O
Osier Yang 已提交
7398 7399 7400 7401
 *
 * This function is to get block stats parameters for block
 * devices attached to the domain.
 *
7402
 * The @disk parameter is either the device target shorthand (the
7403 7404 7405 7406 7407
 * <target dev='...'/> sub-element, such as "xvda"), or (since 0.9.8)
 * an unambiguous source name of the block device (the <source
 * file='...'/> sub-element, such as "/path/to/image").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
O
Osier Yang 已提交
7408 7409 7410 7411
 *
 * Domains may have more than one block device.  To get stats for
 * each you should make multiple calls to this function.
 *
7412 7413 7414 7415
 * On input, @nparams gives the size of the @params array; on output,
 * @nparams gives how many slots were filled with parameter
 * information, which might be less but will not exceed the input
 * value.
O
Osier Yang 已提交
7416
 *
7417 7418 7419 7420 7421
 * As a special case, calling with @params as NULL and @nparams as 0 on
 * input will cause @nparams on output to contain the number of parameters
 * supported by the hypervisor. (Note that block devices of different types
 * might support different parameters, so it might be necessary to compute
 * @nparams for each block device). The caller should then allocate @params
O
Osier Yang 已提交
7422
 * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
7423
 * again. See virDomainGetMemoryParameters() for more details.
O
Osier Yang 已提交
7424 7425 7426
 *
 * Returns -1 in case of error, 0 in case of success.
 */
7427
int virDomainBlockStatsFlags(virDomainPtr dom,
7428
                             const char *disk,
7429 7430 7431
                             virTypedParameterPtr params,
                             int *nparams,
                             unsigned int flags)
O
Osier Yang 已提交
7432 7433 7434
{
    virConnectPtr conn;

7435 7436
    VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
                     disk, params, nparams ? *nparams : -1, flags);
O
Osier Yang 已提交
7437 7438 7439

    virResetLastError();

7440
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
O
Osier Yang 已提交
7441 7442 7443 7444
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
7445 7446 7447 7448 7449 7450
    virCheckNonNullArgGoto(disk, error);
    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (*nparams != 0)
        virCheckNonNullArgGoto(params, error);

E
Eric Blake 已提交
7451 7452 7453
    if (VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
                                 VIR_DRV_FEATURE_TYPED_PARAM_STRING))
        flags |= VIR_TYPED_PARAM_STRING_OKAY;
O
Osier Yang 已提交
7454 7455 7456 7457
    conn = dom->conn;

    if (conn->driver->domainBlockStatsFlags) {
        int ret;
7458
        ret = conn->driver->domainBlockStatsFlags(dom, disk, params, nparams, flags);
O
Osier Yang 已提交
7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470
        if (ret < 0)
            goto error;
        return ret;
    }
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}


7471
/**
7472
 * virDomainInterfaceStats:
7473 7474 7475 7476 7477 7478 7479 7480 7481 7482
 * @dom: pointer to the domain object
 * @path: path to the interface
 * @stats: network interface stats (returned)
 * @size: size of stats structure
 *
 * This function returns network interface stats for interfaces
 * attached to the domain.
 *
 * The path parameter is the name of the network interface.
 *
D
Dan Kenigsberg 已提交
7483
 * Domains may have more than one network interface.  To get stats for
7484 7485 7486 7487 7488 7489 7490 7491 7492
 * each you should make multiple calls to this function.
 *
 * Individual fields within the stats structure may be returned
 * as -1, which indicates that the hypervisor does not support
 * that particular statistic.
 *
 * Returns: 0 in case of success or -1 in case of failure.
 */
int
7493 7494
virDomainInterfaceStats(virDomainPtr dom, const char *path,
                        virDomainInterfaceStatsPtr stats, size_t size)
7495 7496 7497 7498
{
    virConnectPtr conn;
    struct _virDomainInterfaceStats stats2 = { -1, -1, -1, -1,
                                               -1, -1, -1, -1 };
7499 7500 7501

    VIR_DOMAIN_DEBUG(dom, "path=%s, stats=%p, size=%zi",
                     path, stats, size);
7502

7503 7504
    virResetLastError();

7505
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
7506
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
7507
        virDispatchError(NULL);
7508 7509
        return -1;
    }
7510 7511 7512 7513 7514 7515
    virCheckNonNullArgGoto(path, error);
    virCheckNonNullArgGoto(stats, error);
    if (size > sizeof(stats2)) {
        virReportInvalidArg(size,
                            _("size in %s must not exceed %zu"),
                            __FUNCTION__, sizeof(stats2));
7516 7517
        goto error;
    }
7518

7519 7520 7521
    conn = dom->conn;

    if (conn->driver->domainInterfaceStats) {
7522
        if (conn->driver->domainInterfaceStats(dom, path, &stats2) == -1)
7523
            goto error;
7524

7525
        memcpy(stats, &stats2, size);
7526 7527 7528
        return 0;
    }

7529
    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
7530 7531

error:
7532
    virDispatchError(dom->conn);
7533 7534 7535
    return -1;
}

7536 7537 7538 7539 7540 7541 7542 7543 7544
 /**
 * virDomainSetInterfaceParameters:
 * @domain: pointer to domain object
 * @device: the interface name or mac address
 * @params: pointer to interface parameter objects
 * @nparams: number of interface parameter (this value can be the same or
 *          less than the number of parameters supported)
 * @flags: bitwise-OR of virDomainModificationImpact
 *
7545 7546
 * Change a subset or all parameters of interface; currently this
 * includes bandwidth parameters.  The value of @flags should be
7547 7548
 * either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of values
 * VIR_DOMAIN_AFFECT_LIVE and VIR_DOMAIN_AFFECT_CONFIG, although
7549 7550
 * hypervisors vary in which flags are supported.
 *
7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576
 * This function may require privileged access to the hypervisor.
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int
virDomainSetInterfaceParameters(virDomainPtr domain,
                                const char *device,
                                virTypedParameterPtr params,
                                int nparams, unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "device=%s, params=%p, nparams=%d, flags=%x",
                     device, params, nparams, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
7577 7578 7579
    virCheckNonNullArgGoto(params, error);
    virCheckPositiveArgGoto(nparams, error);

7580
    if (virTypedParameterValidateSet(domain->conn, params, nparams) < 0)
7581
        goto error;
7582 7583 7584 7585 7586

    conn = domain->conn;

    if (conn->driver->domainSetInterfaceParameters) {
        int ret;
7587 7588 7589
        ret = conn->driver->domainSetInterfaceParameters(domain, device,
                                                         params, nparams,
                                                         flags);
7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

 /**
 * virDomainGetInterfaceParameters:
 * @domain: pointer to domain object
 * @device: the interface name or mac address
 * @params: pointer to interface parameter objects
 *          (return value, allocated by the caller)
7608 7609
 * @nparams: pointer to number of interface parameter; input and output
 * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646
 *
 * Get all interface parameters. On input, @nparams gives the size of
 * the @params array; on output, @nparams gives how many slots were
 * filled with parameter information, which might be less but will not
 * exceed the input value.
 *
 * As a special case, calling with @params as NULL and @nparams as 0 on
 * input will cause @nparams on output to contain the number of parameters
 * supported by the hypervisor. The caller should then allocate @params
 * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the
 * API again. See virDomainGetMemoryParameters() for an equivalent usage
 * example.
 *
 * This function may require privileged access to the hypervisor. This function
 * expects the caller to allocate the @params.
 *
 * Returns -1 in case of error, 0 in case of success.
 */

int
virDomainGetInterfaceParameters(virDomainPtr domain,
                                const char *device,
                                virTypedParameterPtr params,
                                int *nparams, unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "device=%s, params=%p, nparams=%d, flags=%x",
                     device, params, (nparams) ? *nparams : -1, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
7647 7648 7649 7650 7651
    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (*nparams != 0)
        virCheckNonNullArgGoto(params, error);

7652 7653 7654 7655 7656 7657 7658 7659
    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_TYPED_PARAM_STRING))
        flags |= VIR_TYPED_PARAM_STRING_OKAY;

    conn = domain->conn;

    if (conn->driver->domainGetInterfaceParameters) {
        int ret;
7660 7661 7662
        ret = conn->driver->domainGetInterfaceParameters(domain, device,
                                                         params, nparams,
                                                         flags);
7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673
        if (ret < 0)
            goto error;
        return ret;
    }
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

7674 7675 7676 7677 7678
/**
 * virDomainMemoryStats:
 * @dom: pointer to the domain object
 * @stats: nr_stats-sized array of stat structures (returned)
 * @nr_stats: number of memory statistics requested
7679
 * @flags: extra flags; not used yet, so callers should always pass 0
7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700
 *
 * This function provides memory statistics for the domain.
 *
 * Up to 'nr_stats' elements of 'stats' will be populated with memory statistics
 * from the domain.  Only statistics supported by the domain, the driver, and
 * this version of libvirt will be returned.
 *
 * Memory Statistics:
 *
 * VIR_DOMAIN_MEMORY_STAT_SWAP_IN:
 *     The total amount of data read from swap space (in kb).
 * VIR_DOMAIN_MEMORY_STAT_SWAP_OUT:
 *     The total amount of memory written out to swap space (in kb).
 * VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT:
 *     The number of page faults that required disk IO to service.
 * VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT:
 *     The number of page faults serviced without disk IO.
 * VIR_DOMAIN_MEMORY_STAT_UNUSED:
 *     The amount of memory which is not being used for any purpose (in kb).
 * VIR_DOMAIN_MEMORY_STAT_AVAILABLE:
 *     The total amount of memory available to the domain's OS (in kb).
7701 7702
 * VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON:
 *     Current balloon value (in kb).
7703 7704 7705
 *
 * Returns: The number of stats provided or -1 in case of failure.
 */
7706 7707
int virDomainMemoryStats(virDomainPtr dom, virDomainMemoryStatPtr stats,
                         unsigned int nr_stats, unsigned int flags)
7708 7709 7710
{
    virConnectPtr conn;
    unsigned long nr_stats_ret = 0;
7711

E
Eric Blake 已提交
7712 7713
    VIR_DOMAIN_DEBUG(dom, "stats=%p, nr_stats=%u, flags=%x",
                     stats, nr_stats, flags);
7714 7715 7716

    virResetLastError();

7717
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
7718
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
7719
        virDispatchError(NULL);
7720 7721
        return -1;
    }
7722

7723 7724 7725 7726 7727 7728 7729 7730
    if (!stats || nr_stats == 0)
        return 0;

    if (nr_stats > VIR_DOMAIN_MEMORY_STAT_NR)
        nr_stats = VIR_DOMAIN_MEMORY_STAT_NR;

    conn = dom->conn;
    if (conn->driver->domainMemoryStats) {
7731 7732
        nr_stats_ret = conn->driver->domainMemoryStats(dom, stats, nr_stats,
                                                       flags);
7733 7734 7735 7736 7737
        if (nr_stats_ret == -1)
            goto error;
        return nr_stats_ret;
    }

7738
    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
7739 7740

error:
7741
    virDispatchError(dom->conn);
7742 7743 7744
    return -1;
}

R
Richard W.M. Jones 已提交
7745 7746 7747
/**
 * virDomainBlockPeek:
 * @dom: pointer to the domain object
7748
 * @disk: path to the block device, or device shorthand
R
Richard W.M. Jones 已提交
7749 7750 7751
 * @offset: offset within block device
 * @size: size to read
 * @buffer: return buffer (must be at least size bytes)
7752
 * @flags: extra flags; not used yet, so callers should always pass 0
R
Richard W.M. Jones 已提交
7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766
 *
 * This function allows you to read the contents of a domain's
 * disk device.
 *
 * Typical uses for this are to determine if the domain has
 * written a Master Boot Record (indicating that the domain
 * has completed installation), or to try to work out the state
 * of the domain's filesystems.
 *
 * (Note that in the local case you might try to open the
 * block device or file directly, but that won't work in the
 * remote case, nor if you don't have sufficient permission.
 * Hence the need for this call).
 *
7767
 * The @disk parameter is either an unambiguous source name of the
7768 7769 7770 7771 7772
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or (since 0.9.5) the device target shorthand
 * (the <target dev='...'/> sub-element, such as "xvda").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
R
Richard W.M. Jones 已提交
7773 7774 7775 7776 7777 7778 7779
 *
 * 'offset' and 'size' represent an area which must lie entirely
 * within the device or file.  'size' may be 0 to test if the
 * call would succeed.
 *
 * 'buffer' is the return buffer and must be at least 'size' bytes.
 *
R
Richard W.M. Jones 已提交
7780 7781 7782
 * NB. The remote driver imposes a 64K byte limit on 'size'.
 * For your program to be able to work reliably over a remote
 * connection you should split large requests to <= 65536 bytes.
M
Michal Privoznik 已提交
7783
 * However, with 0.9.13 this RPC limit has been raised to 1M byte.
7784 7785
 * Starting with version 1.0.6 the RPC limit has been raised again.
 * Now large requests up to 16M byte are supported.
R
Richard W.M. Jones 已提交
7786
 *
R
Richard W.M. Jones 已提交
7787 7788 7789
 * Returns: 0 in case of success or -1 in case of failure.
 */
int
7790 7791 7792 7793 7794 7795
virDomainBlockPeek(virDomainPtr dom,
                   const char *disk,
                   unsigned long long offset /* really 64 bits */,
                   size_t size,
                   void *buffer,
                   unsigned int flags)
R
Richard W.M. Jones 已提交
7796 7797
{
    virConnectPtr conn;
7798

7799 7800
    VIR_DOMAIN_DEBUG(dom, "disk=%s, offset=%lld, size=%zi, buffer=%p, flags=%x",
                     disk, offset, size, buffer, flags);
R
Richard W.M. Jones 已提交
7801

7802 7803
    virResetLastError();

7804
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
7805
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
7806
        virDispatchError(NULL);
R
Richard W.M. Jones 已提交
7807 7808 7809
        return -1;
    }
    conn = dom->conn;
7810

7811
    if (dom->conn->flags & VIR_CONNECT_RO) {
7812
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
7813
        goto error;
7814 7815
    }

7816
    virCheckNonNullArgGoto(disk, error);
R
Richard W.M. Jones 已提交
7817 7818

    /* Allow size == 0 as an access test. */
7819 7820
    if (size > 0)
        virCheckNonNullArgGoto(buffer, error);
R
Richard W.M. Jones 已提交
7821

7822 7823
    if (conn->driver->domainBlockPeek) {
        int ret;
7824
        ret = conn->driver->domainBlockPeek(dom, disk, offset, size,
7825 7826 7827 7828 7829
                                            buffer, flags);
        if (ret < 0)
            goto error;
        return ret;
    }
R
Richard W.M. Jones 已提交
7830

7831
    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
7832 7833

error:
7834
    virDispatchError(dom->conn);
R
Richard W.M. Jones 已提交
7835 7836
    return -1;
}
7837

O
Osier Yang 已提交
7838 7839 7840 7841
/**
 * virDomainBlockResize:
 * @dom: pointer to the domain object
 * @disk: path to the block image, or shorthand
E
Eric Blake 已提交
7842 7843
 * @size: new size of the block image, see below for unit
 * @flags: bitwise-OR of virDomainBlockResizeFlags
O
Osier Yang 已提交
7844
 *
E
Eric Blake 已提交
7845
 * Resize a block device of domain while the domain is running.  If
7846 7847 7848 7849 7850
 * @flags is 0, then @size is in kibibytes (blocks of 1024 bytes);
 * since 0.9.11, if @flags includes VIR_DOMAIN_BLOCK_RESIZE_BYTES,
 * @size is in bytes instead.  @size is taken directly as the new
 * size.  Depending on the file format, the hypervisor may round up
 * to the next alignment boundary.
O
Osier Yang 已提交
7851 7852 7853 7854 7855 7856 7857 7858
 *
 * The @disk parameter is either an unambiguous source name of the
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or (since 0.9.5) the device target shorthand
 * (the <target dev='...'/> sub-element, such as "xvda").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
 *
E
Eric Blake 已提交
7859 7860 7861
 * Note that this call may fail if the underlying virtualization hypervisor
 * does not support it; this call requires privileged access to the
 * hypervisor.
O
Osier Yang 已提交
7862 7863 7864 7865 7866
 *
 * Returns: 0 in case of success or -1 in case of failure.
 */

int
7867 7868 7869 7870
virDomainBlockResize(virDomainPtr dom,
                     const char *disk,
                     unsigned long long size,
                     unsigned int flags)
O
Osier Yang 已提交
7871 7872 7873 7874 7875 7876 7877
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(dom, "disk=%s, size=%llu, flags=%x", disk, size, flags);

    virResetLastError();

7878
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
O
Osier Yang 已提交
7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = dom->conn;

    if (dom->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

7890
    virCheckNonNullArgGoto(disk, error);
O
Osier Yang 已提交
7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906

    if (conn->driver->domainBlockResize) {
        int ret;
        ret =conn->driver->domainBlockResize(dom, disk, size, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}

R
Richard W.M. Jones 已提交
7907 7908 7909 7910 7911 7912
/**
 * virDomainMemoryPeek:
 * @dom: pointer to the domain object
 * @start: start of memory to peek
 * @size: size of memory to peek
 * @buffer: return buffer (must be at least size bytes)
7913
 * @flags: bitwise-OR of virDomainMemoryFlags
R
Richard W.M. Jones 已提交
7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934
 *
 * This function allows you to read the contents of a domain's
 * memory.
 *
 * The memory which is read is controlled by the 'start', 'size'
 * and 'flags' parameters.
 *
 * If 'flags' is VIR_MEMORY_VIRTUAL then the 'start' and 'size'
 * parameters are interpreted as virtual memory addresses for
 * whichever task happens to be running on the domain at the
 * moment.  Although this sounds haphazard it is in fact what
 * you want in order to read Linux kernel state, because it
 * ensures that pointers in the kernel image can be interpreted
 * coherently.
 *
 * 'buffer' is the return buffer and must be at least 'size' bytes.
 * 'size' may be 0 to test if the call would succeed.
 *
 * NB. The remote driver imposes a 64K byte limit on 'size'.
 * For your program to be able to work reliably over a remote
 * connection you should split large requests to <= 65536 bytes.
M
Michal Privoznik 已提交
7935
 * However, with 0.9.13 this RPC limit has been raised to 1M byte.
7936 7937
 * Starting with version 1.0.6 the RPC limit has been raised again.
 * Now large requests up to 16M byte are supported.
R
Richard W.M. Jones 已提交
7938 7939 7940 7941
 *
 * Returns: 0 in case of success or -1 in case of failure.
 */
int
7942 7943 7944 7945 7946
virDomainMemoryPeek(virDomainPtr dom,
                    unsigned long long start /* really 64 bits */,
                    size_t size,
                    void *buffer,
                    unsigned int flags)
R
Richard W.M. Jones 已提交
7947 7948
{
    virConnectPtr conn;
7949

7950
    VIR_DOMAIN_DEBUG(dom, "start=%lld, size=%zi, buffer=%p, flags=%x",
7951
                     start, size, buffer, flags);
R
Richard W.M. Jones 已提交
7952

7953 7954
    virResetLastError();

7955
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
7956
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
7957
        virDispatchError(NULL);
R
Richard W.M. Jones 已提交
7958 7959 7960 7961
        return -1;
    }
    conn = dom->conn;

7962
    if (dom->conn->flags & VIR_CONNECT_RO) {
7963
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
7964
        goto error;
7965 7966
    }

7967
    /* Note on access to physical memory: A VIR_MEMORY_PHYSICAL flag is
R
Richard W.M. Jones 已提交
7968 7969 7970 7971 7972 7973
     * a possibility.  However it isn't really useful unless the caller
     * can also access registers, particularly CR3 on x86 in order to
     * get the Page Table Directory.  Since registers are different on
     * every architecture, that would imply another call to get the
     * machine registers.
     *
7974
     * The QEMU driver handles VIR_MEMORY_VIRTUAL, mapping it
R
Richard W.M. Jones 已提交
7975 7976 7977
     * to the qemu 'memsave' command which does the virtual to physical
     * mapping inside qemu.
     *
7978 7979 7980
     * The QEMU driver also handles VIR_MEMORY_PHYSICAL, mapping it
     * to the qemu 'pmemsave' command.
     *
R
Richard W.M. Jones 已提交
7981 7982 7983 7984 7985 7986 7987 7988
     * At time of writing there is no Xen driver.  However the Xen
     * hypervisor only lets you map physical pages from other domains,
     * and so the Xen driver would have to do the virtual to physical
     * mapping by chasing 2, 3 or 4-level page tables from the PTD.
     * There is example code in libxc (xc_translate_foreign_address)
     * which does this, although we cannot copy this code directly
     * because of incompatible licensing.
     */
7989

7990 7991
    /* Exactly one of these two flags must be set.  */
    if (!(flags & VIR_MEMORY_VIRTUAL) == !(flags & VIR_MEMORY_PHYSICAL)) {
7992 7993 7994
        virReportInvalidArg(flags,
                            _("flags in %s must include VIR_MEMORY_VIRTUAL or VIR_MEMORY_PHYSICAL"),
                            __FUNCTION__);
7995
        goto error;
R
Richard W.M. Jones 已提交
7996 7997 7998
    }

    /* Allow size == 0 as an access test. */
7999 8000
    if (size > 0)
        virCheckNonNullArgGoto(buffer, error);
R
Richard W.M. Jones 已提交
8001

8002 8003
    if (conn->driver->domainMemoryPeek) {
        int ret;
8004 8005
        ret = conn->driver->domainMemoryPeek(dom, start, size,
                                             buffer, flags);
8006 8007 8008 8009
        if (ret < 0)
            goto error;
        return ret;
    }
R
Richard W.M. Jones 已提交
8010

8011
    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8012 8013

error:
8014
    virDispatchError(dom->conn);
R
Richard W.M. Jones 已提交
8015 8016 8017
    return -1;
}

8018

8019 8020 8021
/**
 * virDomainGetBlockInfo:
 * @domain: a domain object
8022
 * @disk: path to the block device, or device shorthand
8023
 * @info: pointer to a virDomainBlockInfo structure allocated by the user
8024
 * @flags: extra flags; not used yet, so callers should always pass 0
8025 8026 8027
 *
 * Extract information about a domain's block device.
 *
8028
 * The @disk parameter is either an unambiguous source name of the
8029 8030 8031 8032 8033 8034
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or (since 0.9.5) the device target shorthand
 * (the <target dev='...'/> sub-element, such as "xvda").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
 *
8035 8036 8037
 * Returns 0 in case of success and -1 in case of failure.
 */
int
8038
virDomainGetBlockInfo(virDomainPtr domain, const char *disk,
8039
                      virDomainBlockInfoPtr info, unsigned int flags)
8040 8041
{
    virConnectPtr conn;
8042

E
Eric Blake 已提交
8043
    VIR_DOMAIN_DEBUG(domain, "info=%p, flags=%x", info, flags);
8044 8045 8046 8047

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
8048
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
8049
        virDispatchError(NULL);
8050
        return -1;
8051
    }
8052 8053
    virCheckNonNullArgGoto(disk, error);
    virCheckNonNullArgGoto(info, error);
8054 8055 8056 8057 8058 8059 8060

    memset(info, 0, sizeof(virDomainBlockInfo));

    conn = domain->conn;

    if (conn->driver->domainGetBlockInfo) {
        int ret;
8061
        ret = conn->driver->domainGetBlockInfo(domain, disk, info, flags);
8062 8063 8064 8065 8066
        if (ret < 0)
            goto error;
        return ret;
    }

8067
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8068 8069 8070 8071 8072 8073 8074

error:
    virDispatchError(domain->conn);
    return -1;
}


8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085
/************************************************************************
 *									*
 *		Handling of defined but not running domains		*
 *									*
 ************************************************************************/

/**
 * virDomainDefineXML:
 * @conn: pointer to the hypervisor connection
 * @xml: the XML description for the domain, preferably in UTF-8
 *
8086 8087
 * Define a domain, but does not start it.
 * This definition is persistent, until explicitly undefined with
8088 8089
 * virDomainUndefine(). A previous definition for this domain would be
 * overriden if it already exists.
8090
 *
E
Eric Blake 已提交
8091 8092 8093 8094 8095
 * Some hypervisors may prevent this operation if there is a current
 * block copy operation on a transient domain with the same id as the
 * domain being defined; in that case, use virDomainBlockJobAbort() to
 * stop the block copy first.
 *
8096 8097 8098 8099
 * Returns NULL in case of error, a pointer to the domain otherwise
 */
virDomainPtr
virDomainDefineXML(virConnectPtr conn, const char *xml) {
8100
    VIR_DEBUG("conn=%p, xml=%s", conn, xml);
8101

8102 8103
    virResetLastError();

8104
    if (!VIR_IS_CONNECT(conn)) {
8105
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
8106
        virDispatchError(NULL);
8107
        return NULL;
8108
    }
8109
    if (conn->flags & VIR_CONNECT_RO) {
8110
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
8111
        goto error;
8112
    }
8113
    virCheckNonNullArgGoto(xml, error);
8114

8115 8116
    if (conn->driver->domainDefineXML) {
        virDomainPtr ret;
8117
        ret = conn->driver->domainDefineXML(conn, xml);
8118 8119 8120 8121
        if (!ret)
            goto error;
        return ret;
    }
8122

8123
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8124 8125

error:
8126
    virDispatchError(conn);
8127
    return NULL;
8128 8129 8130 8131 8132 8133
}

/**
 * virDomainUndefine:
 * @domain: pointer to a defined domain
 *
O
Osier Yang 已提交
8134 8135 8136 8137 8138
 * Undefine a domain. If the domain is running, it's converted to
 * transient domain, without stopping it. If the domain is inactive,
 * the domain configuration is removed.
 *
 * If the domain has a managed save image (see
8139 8140 8141
 * virDomainHasManagedSaveImage()), or if it is inactive and has any
 * snapshot metadata (see virDomainSnapshotNum()), then the undefine will
 * fail. See virDomainUndefineFlags() for more control.
8142 8143 8144 8145 8146
 *
 * Returns 0 in case of success, -1 in case of error
 */
int
virDomainUndefine(virDomainPtr domain) {
8147
    virConnectPtr conn;
8148

8149
    VIR_DOMAIN_DEBUG(domain);
8150

8151 8152
    virResetLastError();

8153
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
8154
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
8155
        virDispatchError(NULL);
8156
        return -1;
8157
    }
8158 8159
    conn = domain->conn;
    if (conn->flags & VIR_CONNECT_RO) {
8160
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
8161
        goto error;
8162 8163
    }

8164 8165
    if (conn->driver->domainUndefine) {
        int ret;
8166
        ret = conn->driver->domainUndefine(domain);
8167 8168 8169 8170
        if (ret < 0)
            goto error;
        return ret;
    }
8171

8172
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8173 8174

error:
8175
    virDispatchError(domain->conn);
8176
    return -1;
8177 8178
}

O
Osier Yang 已提交
8179 8180 8181
/**
 * virDomainUndefineFlags:
 * @domain: pointer to a defined domain
8182
 * @flags: bitwise-OR of supported virDomainUndefineFlagsValues
O
Osier Yang 已提交
8183 8184 8185 8186 8187 8188 8189 8190 8191
 *
 * Undefine a domain. If the domain is running, it's converted to
 * transient domain, without stopping it. If the domain is inactive,
 * the domain configuration is removed.
 *
 * If the domain has a managed save image (see virDomainHasManagedSaveImage()),
 * then including VIR_DOMAIN_UNDEFINE_MANAGED_SAVE in @flags will also remove
 * that file, and omitting the flag will cause the undefine process to fail.
 *
8192 8193 8194 8195 8196 8197 8198 8199 8200
 * If the domain is inactive and has any snapshot metadata (see
 * virDomainSnapshotNum()), then including
 * VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA in @flags will also remove
 * that metadata.  Omitting the flag will cause the undefine of an
 * inactive domain to fail.  Active snapshots will retain snapshot
 * metadata until the (now-transient) domain halts, regardless of
 * whether this flag is present.  On hypervisors where snapshots do
 * not use libvirt metadata, this flag has no effect.
 *
O
Osier Yang 已提交
8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225
 * Returns 0 in case of success, -1 in case of error
 */
int
virDomainUndefineFlags(virDomainPtr domain,
                       unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = domain->conn;
    if (conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainUndefineFlags) {
        int ret;
8226
        ret = conn->driver->domainUndefineFlags(domain, flags);
O
Osier Yang 已提交
8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}


8240 8241 8242 8243
/**
 * virConnectNumOfDefinedDomains:
 * @conn: pointer to the hypervisor connection
 *
8244
 * Provides the number of defined but inactive domains.
8245 8246 8247 8248 8249 8250
 *
 * Returns the number of domain found or -1 in case of error
 */
int
virConnectNumOfDefinedDomains(virConnectPtr conn)
{
8251
    VIR_DEBUG("conn=%p", conn);
8252

8253 8254
    virResetLastError();

8255
    if (!VIR_IS_CONNECT(conn)) {
8256
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
8257
        virDispatchError(NULL);
8258
        return -1;
8259 8260
    }

8261
    if (conn->driver->connectNumOfDefinedDomains) {
8262
        int ret;
8263
        ret = conn->driver->connectNumOfDefinedDomains(conn);
8264 8265 8266 8267
        if (ret < 0)
            goto error;
        return ret;
    }
8268

8269
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8270 8271

error:
8272
    virDispatchError(conn);
8273
    return -1;
8274 8275 8276 8277 8278 8279 8280 8281
}

/**
 * virConnectListDefinedDomains:
 * @conn: pointer to the hypervisor connection
 * @names: pointer to an array to store the names
 * @maxnames: size of the array
 *
8282 8283
 * list the defined but inactive domains, stores the pointers to the names
 * in @names
8284
 *
8285 8286 8287 8288 8289 8290 8291 8292
 * For active domains, see virConnectListDomains().  For more control over
 * the results, see virConnectListAllDomains().
 *
 * Returns the number of names provided in the array or -1 in case of error.
 * Note that this command is inherently racy; a domain can be defined between
 * a call to virConnectNumOfDefinedDomains() and this call; you are only
 * guaranteed that all currently defined domains were listed if the return
 * is less than @maxids.  The client must call free() on each returned name.
8293 8294
 */
int
8295
virConnectListDefinedDomains(virConnectPtr conn, char **const names,
8296
                             int maxnames) {
8297
    VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
8298

8299 8300
    virResetLastError();

8301
    if (!VIR_IS_CONNECT(conn)) {
8302
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
8303
        virDispatchError(NULL);
8304
        return -1;
8305 8306
    }

8307 8308
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
8309

8310
    if (conn->driver->connectListDefinedDomains) {
8311
        int ret;
8312
        ret = conn->driver->connectListDefinedDomains(conn, names, maxnames);
8313 8314 8315 8316
        if (ret < 0)
            goto error;
        return ret;
    }
8317

8318
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8319 8320

error:
8321
    virDispatchError(conn);
8322
    return -1;
8323 8324
}

8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370
/**
 * virConnectListAllDomains:
 * @conn: Pointer to the hypervisor connection.
 * @domains: Pointer to a variable to store the array containing domain objects
 *           or NULL if the list is not required (just returns number of guests).
 * @flags: bitwise-OR of virConnectListAllDomainsFlags
 *
 * Collect a possibly-filtered list of all domains, and return an allocated
 * array of information for each.  This API solves the race inherent in
 * virConnectListDomains() and virConnectListDefinedDomains().
 *
 * Normally, all domains are returned; however, @flags can be used to
 * filter the results for a smaller list of targeted domains.  The valid
 * flags are divided into groups, where each group contains bits that
 * describe mutually exclusive attributes of a domain, and where all bits
 * within a group describe all possible domains.  Some hypervisors might
 * reject explicit bits from a group where the hypervisor cannot make a
 * distinction (for example, not all hypervisors can tell whether domains
 * have snapshots).  For a group supported by a given hypervisor, the
 * behavior when no bits of a group are set is identical to the behavior
 * when all bits in that group are set.  When setting bits from more than
 * one group, it is possible to select an impossible combination (such
 * as an inactive transient domain), in that case a hypervisor may return
 * either 0 or an error.
 *
 * The first group of @flags is VIR_CONNECT_LIST_DOMAINS_ACTIVE (online
 * domains) and VIR_CONNECT_LIST_DOMAINS_INACTIVE (offline domains).
 *
 * The next group of @flags is VIR_CONNECT_LIST_DOMAINS_PERSISTENT (defined
 * domains) and VIR_CONNECT_LIST_DOMAINS_TRANSIENT (running but not defined).
 *
 * The next group of @flags covers various domain states:
 * VIR_CONNECT_LIST_DOMAINS_RUNNING, VIR_CONNECT_LIST_DOMAINS_PAUSED,
 * VIR_CONNECT_LIST_DOMAINS_SHUTOFF, and a catch-all for all other states
 * (such as crashed, this catch-all covers the possibility of adding new
 * states).
 *
 * The remaining groups cover boolean attributes commonly asked about
 * domains; they include VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE and
 * VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE, for filtering based on whether
 * a managed save image exists; VIR_CONNECT_LIST_DOMAINS_AUTOSTART and
 * VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART, for filtering based on autostart;
 * VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT and
 * VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT, for filtering based on whether
 * a domain has snapshots.
 *
J
John Ferlan 已提交
8371 8372
 * Returns the number of domains found or -1 and sets domains to NULL in case of
 * error.  On success, the array stored into @domains is guaranteed to have an
8373 8374
 * extra allocated element set to NULL but not included in the return count, to
 * make iteration easier. The caller is responsible for calling virDomainFree()
J
John Ferlan 已提交
8375
 * on each array element, then calling free() on @domains.
8376 8377 8378 8379 8380
 *
 * Example of usage:
 * virDomainPtr *domains;
 * int i;
 * int ret;
J
John Ferlan 已提交
8381 8382
 * unsigned int flags = VIR_CONNECT_LIST_DOMAINS_RUNNING |
 *                      VIR_CONNECT_LIST_DOMAINS_PERSISTENT;
8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414
 *
 * ret = virConnectListAllDomains(conn, &domains, flags);
 * if (ret < 0)
 *     error();
 *
 * for (i = 0; i < ret; i++) {
 *      do_something_with_domain(domains[i]);
 *
 *      //here or in a separate loop if needed
 *      virDomainFree(domains[i]);
 * }
 *
 * free(domains);
 */
int
virConnectListAllDomains(virConnectPtr conn,
                         virDomainPtr **domains,
                         unsigned int flags)
{
    VIR_DEBUG("conn=%p, domains=%p, flags=%x", conn, domains, flags);

    virResetLastError();

    if (domains)
        *domains = NULL;

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

8415
    if (conn->driver->connectListAllDomains) {
8416
        int ret;
8417
        ret = conn->driver->connectListAllDomains(conn, domains, flags);
8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

8430 8431 8432 8433
/**
 * virDomainCreate:
 * @domain: pointer to a defined domain
 *
8434
 * Launch a defined domain. If the call succeeds the domain moves from the
8435 8436 8437
 * defined to the running domains pools.  The domain will be paused only
 * if restoring from managed state created from a paused domain.  For more
 * control, see virDomainCreateWithFlags().
8438 8439 8440 8441 8442
 *
 * Returns 0 in case of success, -1 in case of error
 */
int
virDomainCreate(virDomainPtr domain) {
8443
    virConnectPtr conn;
8444

8445
    VIR_DOMAIN_DEBUG(domain);
8446

8447 8448
    virResetLastError();

8449
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
8450
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
8451
        virDispatchError(NULL);
8452
        return -1;
8453
    }
8454 8455
    conn = domain->conn;
    if (conn->flags & VIR_CONNECT_RO) {
8456
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
8457
        goto error;
8458
    }
8459

8460 8461
    if (conn->driver->domainCreate) {
        int ret;
8462
        ret = conn->driver->domainCreate(domain);
8463 8464 8465 8466
        if (ret < 0)
            goto error;
        return ret;
    }
8467

8468
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8469 8470

error:
8471
    virDispatchError(domain->conn);
8472
    return -1;
8473 8474
}

8475 8476 8477
/**
 * virDomainCreateWithFlags:
 * @domain: pointer to a defined domain
8478
 * @flags: bitwise-OR of supported virDomainCreateFlags
8479 8480 8481 8482
 *
 * Launch a defined domain. If the call succeeds the domain moves from the
 * defined to the running domains pools.
 *
8483 8484 8485 8486 8487 8488
 * If the VIR_DOMAIN_START_PAUSED flag is set, or if the guest domain
 * has a managed save image that requested paused state (see
 * virDomainManagedSave()) the guest domain will be started, but its
 * CPUs will remain paused. The CPUs can later be manually started
 * using virDomainResume().  In all other cases, the guest domain will
 * be running.
8489 8490 8491 8492
 *
 * If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest
 * domain will be automatically destroyed when the virConnectPtr
 * object is finally released. This will also happen if the
E
Eric Blake 已提交
8493
 * client application crashes / loses its connection to the
8494
 * libvirtd daemon. Any domains marked for auto destroy will
8495
 * block attempts at migration, save-to-file, or snapshots.
8496
 *
8497 8498 8499 8500 8501 8502
 * If the VIR_DOMAIN_START_BYPASS_CACHE flag is set, and there is a
 * managed save file for this domain (created by virDomainManagedSave()),
 * then libvirt will attempt to bypass the file system cache while restoring
 * the file, or fail if it cannot do so for the given system; this can allow
 * less pressure on file system cache, but also risks slowing loads from NFS.
 *
8503 8504 8505
 * If the VIR_DOMAIN_START_FORCE_BOOT flag is set, then any managed save
 * file for this domain is discarded, and the domain boots from scratch.
 *
8506 8507 8508 8509 8510
 * Returns 0 in case of success, -1 in case of error
 */
int
virDomainCreateWithFlags(virDomainPtr domain, unsigned int flags) {
    virConnectPtr conn;
8511

8512
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
8513 8514 8515 8516

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
8517
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
8518
        virDispatchError(NULL);
8519
        return -1;
8520 8521 8522
    }
    conn = domain->conn;
    if (conn->flags & VIR_CONNECT_RO) {
8523
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
8524 8525 8526 8527 8528
        goto error;
    }

    if (conn->driver->domainCreateWithFlags) {
        int ret;
8529
        ret = conn->driver->domainCreateWithFlags(domain, flags);
8530 8531 8532 8533 8534
        if (ret < 0)
            goto error;
        return ret;
    }

8535
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8536 8537 8538 8539 8540 8541

error:
    virDispatchError(domain->conn);
    return -1;
}

8542 8543 8544
/**
 * virDomainGetAutostart:
 * @domain: a domain object
8545
 * @autostart: the value returned
8546
 *
8547
 * Provides a boolean value indicating whether the domain
8548 8549 8550 8551 8552 8553 8554
 * configured to be automatically started when the host
 * machine boots.
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virDomainGetAutostart(virDomainPtr domain,
8555 8556 8557
                      int *autostart)
{
    virConnectPtr conn;
8558 8559

    VIR_DOMAIN_DEBUG(domain, "autostart=%p", autostart);
8560

8561 8562 8563
    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
8564
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
8565
        virDispatchError(NULL);
8566
        return -1;
8567
    }
8568
    virCheckNonNullArgGoto(autostart, error);
8569

8570 8571
    conn = domain->conn;

8572 8573
    if (conn->driver->domainGetAutostart) {
        int ret;
8574
        ret = conn->driver->domainGetAutostart(domain, autostart);
8575 8576 8577 8578
        if (ret < 0)
            goto error;
        return ret;
    }
8579

8580
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8581 8582

error:
8583
    virDispatchError(domain->conn);
8584
    return -1;
8585 8586 8587 8588 8589
}

/**
 * virDomainSetAutostart:
 * @domain: a domain object
8590
 * @autostart: whether the domain should be automatically started 0 or 1
8591 8592 8593 8594 8595 8596 8597 8598
 *
 * Configure the domain to be automatically started
 * when the host machine boots.
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virDomainSetAutostart(virDomainPtr domain,
8599 8600 8601
                      int autostart)
{
    virConnectPtr conn;
8602 8603

    VIR_DOMAIN_DEBUG(domain, "autostart=%d", autostart);
8604

8605 8606 8607
    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
8608
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
8609
        virDispatchError(NULL);
8610
        return -1;
8611 8612
    }

8613 8614
    conn = domain->conn;

8615
    if (domain->conn->flags & VIR_CONNECT_RO) {
8616
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
8617
        goto error;
8618 8619
    }

8620 8621
    if (conn->driver->domainSetAutostart) {
        int ret;
8622
        ret = conn->driver->domainSetAutostart(domain, autostart);
8623 8624 8625 8626
        if (ret < 0)
            goto error;
        return ret;
    }
8627

8628
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8629 8630

error:
8631
    virDispatchError(domain->conn);
8632
    return -1;
8633 8634
}

8635 8636 8637
/**
 * virDomainInjectNMI:
 * @domain: pointer to domain object, or NULL for Domain0
8638
 * @flags: extra flags; not used yet, so callers should always pass 0
8639 8640 8641 8642 8643 8644 8645 8646 8647
 *
 * Send NMI to the guest
 *
 * Returns 0 in case of success, -1 in case of failure.
 */

int virDomainInjectNMI(virDomainPtr domain, unsigned int flags)
{
    virConnectPtr conn;
8648
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
8649 8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    conn = domain->conn;

    if (conn->driver->domainInjectNMI) {
        int ret;
        ret = conn->driver->domainInjectNMI(domain, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

8672
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8673 8674 8675 8676 8677 8678

error:
    virDispatchError(domain->conn);
    return -1;
}

8679 8680 8681 8682 8683 8684 8685
/**
 * virDomainSendKey:
 * @domain:    pointer to domain object, or NULL for Domain0
 * @codeset:   the code set of keycodes, from virKeycodeSet
 * @holdtime:  the duration (in milliseconds) that the keys will be held
 * @keycodes:  array of keycodes
 * @nkeycodes: number of keycodes, up to VIR_DOMAIN_SEND_KEY_MAX_KEYS
8686
 * @flags: extra flags; not used yet, so callers should always pass 0
8687 8688 8689 8690 8691 8692 8693 8694 8695 8696
 *
 * Send key(s) to the guest.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */

int virDomainSendKey(virDomainPtr domain,
                     unsigned int codeset,
                     unsigned int holdtime,
                     unsigned int *keycodes,
8697
                     int nkeycodes,
8698 8699 8700
                     unsigned int flags)
{
    virConnectPtr conn;
8701
    VIR_DOMAIN_DEBUG(domain, "codeset=%u, holdtime=%u, nkeycodes=%u, flags=%x",
8702 8703 8704 8705 8706
                     codeset, holdtime, nkeycodes, flags);

    virResetLastError();

    if (keycodes == NULL ||
8707
        nkeycodes <= 0 || nkeycodes > VIR_DOMAIN_SEND_KEY_MAX_KEYS) {
8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733
        virLibDomainError(VIR_ERR_OPERATION_INVALID, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    conn = domain->conn;

    if (conn->driver->domainSendKey) {
        int ret;
        ret = conn->driver->domainSendKey(domain, codeset, holdtime,
                                          keycodes, nkeycodes, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

8734
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8735 8736 8737 8738 8739 8740

error:
    virDispatchError(domain->conn);
    return -1;
}

8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819

/**
 * virDomainSendProcessSignal:
 * @domain: pointer to domain object
 * @pid_value: a positive integer process ID, or negative integer process group ID
 * @signum: a signal from the virDomainProcessSignal enum
 * @flags: one of the virDomainProcessSignalFlag values
 *
 * Send a signal to the designated process in the guest
 *
 * The signal numbers must be taken from the virDomainProcessSignal
 * enum. These will be translated to the corresponding signal
 * number for the guest OS, by the guest agent delivering the
 * signal. If there is no mapping from virDomainProcessSignal to
 * the native OS signals, this API will report an error.
 *
 * If @pid_value is an integer greater than zero, it is
 * treated as a process ID. If @pid_value is an integer
 * less than zero, it is treated as a process group ID.
 * All the @pid_value numbers are from the container/guest
 * namespace. The value zero is not valid.
 *
 * Not all hypervisors will support sending signals to
 * arbitrary processes or process groups. If this API is
 * implemented the minimum requirement is to be able to
 * use @pid_value==1 (i.e. kill init). No other value is
 * required to be supported.
 *
 * If the @signum is VIR_DOMAIN_PROCESS_SIGNAL_NOP then this
 * API will simply report whether the process is running in
 * the container/guest.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int virDomainSendProcessSignal(virDomainPtr domain,
                               long long pid_value,
                               unsigned int signum,
                               unsigned int flags)
{
    virConnectPtr conn;
    VIR_DOMAIN_DEBUG(domain, "pid=%lld, signum=%u flags=%x",
                     pid_value, signum, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    virCheckNonZeroArgGoto(pid_value, error);

    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    conn = domain->conn;

    if (conn->driver->domainSendProcessSignal) {
        int ret;
        ret = conn->driver->domainSendProcessSignal(domain,
                                                    pid_value,
                                                    signum,
                                                    flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}


8820 8821 8822 8823 8824 8825 8826 8827
/**
 * virDomainSetVcpus:
 * @domain: pointer to domain object, or NULL for Domain0
 * @nvcpus: the new number of virtual CPUs for this domain
 *
 * Dynamically change the number of virtual CPUs used by the domain.
 * Note that this call may fail if the underlying virtualization hypervisor
 * does not support it or if growing the number is arbitrary limited.
8828
 * This function may require privileged access to the hypervisor.
8829
 *
8830
 * This command only changes the runtime configuration of the domain,
E
Eric Blake 已提交
8831 8832 8833
 * so can only be called on an active domain.  It is hypervisor-dependent
 * whether it also affects persistent configuration; for more control,
 * use virDomainSetVcpusFlags().
8834
 *
8835 8836 8837 8838 8839 8840
 * Returns 0 in case of success, -1 in case of failure.
 */

int
virDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
{
8841
    virConnectPtr conn;
8842 8843

    VIR_DOMAIN_DEBUG(domain, "nvcpus=%u", nvcpus);
8844

8845 8846
    virResetLastError();

8847
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
8848
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
8849
        virDispatchError(NULL);
8850
        return -1;
8851
    }
8852
    if (domain->conn->flags & VIR_CONNECT_RO) {
8853
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
8854
        goto error;
8855
    }
8856

8857 8858
    virCheckNonZeroArgGoto(nvcpus, error);

8859
    conn = domain->conn;
8860

8861 8862
    if (conn->driver->domainSetVcpus) {
        int ret;
8863
        ret = conn->driver->domainSetVcpus(domain, nvcpus);
8864 8865 8866 8867
        if (ret < 0)
            goto error;
        return ret;
    }
8868

8869
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
8870 8871

error:
8872
    virDispatchError(domain->conn);
8873
    return -1;
8874 8875
}

E
Eric Blake 已提交
8876 8877 8878 8879
/**
 * virDomainSetVcpusFlags:
 * @domain: pointer to domain object, or NULL for Domain0
 * @nvcpus: the new number of virtual CPUs for this domain, must be at least 1
8880
 * @flags: bitwise-OR of virDomainVcpuFlags
E
Eric Blake 已提交
8881 8882 8883 8884
 *
 * Dynamically change the number of virtual CPUs used by the domain.
 * Note that this call may fail if the underlying virtualization hypervisor
 * does not support it or if growing the number is arbitrary limited.
8885
 * This function may require privileged access to the hypervisor.
E
Eric Blake 已提交
8886
 *
8887
 * @flags may include VIR_DOMAIN_AFFECT_LIVE to affect a running
E
Eric Blake 已提交
8888
 * domain (which may fail if domain is not active), or
8889
 * VIR_DOMAIN_AFFECT_CONFIG to affect the next boot via the XML
E
Eric Blake 已提交
8890
 * description of the domain.  Both flags may be set.
8891 8892 8893 8894
 * If neither flag is specified (that is, @flags is VIR_DOMAIN_AFFECT_CURRENT),
 * then an inactive domain modifies persistent setup, while an active domain
 * is hypervisor-dependent on whether just live or both live and persistent
 * state is changed.
E
Eric Blake 已提交
8895 8896
 *
 * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then
8897
 * VIR_DOMAIN_AFFECT_LIVE must be clear, and only the maximum virtual
E
Eric Blake 已提交
8898 8899 8900 8901
 * CPU limit is altered; generally, this value must be less than or
 * equal to virConnectGetMaxVcpus().  Otherwise, this call affects the
 * current virtual CPU limit, which must be less than or equal to the
 * maximum limit.
8902
 * Not all hypervisors can support all flag combinations.
E
Eric Blake 已提交
8903 8904 8905 8906 8907 8908 8909 8910 8911
 *
 * Returns 0 in case of success, -1 in case of failure.
 */

int
virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
                       unsigned int flags)
{
    virConnectPtr conn;
8912

8913
    VIR_DOMAIN_DEBUG(domain, "nvcpus=%u, flags=%x", nvcpus, flags);
E
Eric Blake 已提交
8914 8915 8916 8917

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
8918
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
E
Eric Blake 已提交
8919
        virDispatchError(NULL);
8920
        return -1;
E
Eric Blake 已提交
8921 8922
    }
    if (domain->conn->flags & VIR_CONNECT_RO) {
8923
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
E
Eric Blake 已提交
8924 8925 8926
        goto error;
    }

8927 8928
    virCheckNonZeroArgGoto(nvcpus, error);

E
Eric Blake 已提交
8929 8930 8931 8932
    if ((unsigned short) nvcpus != nvcpus) {
        virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %u"), nvcpus);
        goto error;
    }
E
Eric Blake 已提交
8933 8934 8935 8936
    conn = domain->conn;

    if (conn->driver->domainSetVcpusFlags) {
        int ret;
8937
        ret = conn->driver->domainSetVcpusFlags(domain, nvcpus, flags);
E
Eric Blake 已提交
8938 8939 8940 8941 8942
        if (ret < 0)
            goto error;
        return ret;
    }

8943
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
E
Eric Blake 已提交
8944 8945 8946 8947 8948 8949 8950 8951 8952

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainGetVcpusFlags:
 * @domain: pointer to domain object, or NULL for Domain0
8953
 * @flags: bitwise-OR of virDomainVcpuFlags
E
Eric Blake 已提交
8954 8955 8956
 *
 * Query the number of virtual CPUs used by the domain.  Note that
 * this call may fail if the underlying virtualization hypervisor does
8957
 * not support it.  This function may require privileged access to the
E
Eric Blake 已提交
8958 8959
 * hypervisor.
 *
8960 8961 8962 8963 8964 8965 8966
 * If @flags includes VIR_DOMAIN_AFFECT_LIVE, this will query a
 * running domain (which will fail if domain is not active); if
 * it includes VIR_DOMAIN_AFFECT_CONFIG, this will query the XML
 * description of the domain.  It is an error to set both flags.
 * If neither flag is set (that is, VIR_DOMAIN_AFFECT_CURRENT),
 * then the configuration queried depends on whether the domain
 * is currently running.
E
Eric Blake 已提交
8967 8968 8969 8970 8971
 *
 * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum
 * virtual CPU limit is queried.  Otherwise, this call queries the
 * current virtual CPU limit.
 *
8972
 * Returns the number of vCPUs in case of success, -1 in case of failure.
E
Eric Blake 已提交
8973 8974 8975 8976 8977 8978
 */

int
virDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
{
    virConnectPtr conn;
8979

8980
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
E
Eric Blake 已提交
8981 8982 8983 8984

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
8985
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
E
Eric Blake 已提交
8986
        virDispatchError(NULL);
8987
        return -1;
E
Eric Blake 已提交
8988 8989
    }

8990
    /* At most one of these two flags should be set.  */
8991 8992
    if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
        (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
8993 8994 8995
        virReportInvalidArg(flags,
                            _("flags 'affect live' and 'affect config' in %s are mutually exclusive"),
                            __FUNCTION__);
E
Eric Blake 已提交
8996 8997 8998 8999 9000 9001
        goto error;
    }
    conn = domain->conn;

    if (conn->driver->domainGetVcpusFlags) {
        int ret;
9002
        ret = conn->driver->domainGetVcpusFlags(domain, flags);
E
Eric Blake 已提交
9003 9004 9005 9006 9007
        if (ret < 0)
            goto error;
        return ret;
    }

9008
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
E
Eric Blake 已提交
9009 9010 9011 9012 9013 9014

error:
    virDispatchError(domain->conn);
    return -1;
}

9015 9016 9017 9018 9019
/**
 * virDomainPinVcpu:
 * @domain: pointer to domain object, or NULL for Domain0
 * @vcpu: virtual CPU number
 * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
E
Eric Blake 已提交
9020 9021 9022
 *      Each bit set to 1 means that corresponding CPU is usable.
 *      Bytes are stored in little-endian order: CPU0-7, 8-15...
 *      In each byte, lowest CPU number is least significant bit.
9023
 * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
O
Osier Yang 已提交
9024 9025 9026
 *      underlying virtualization system (Xen...).
 *      If maplen < size, missing bytes are set to zero.
 *      If maplen > size, failure code is returned.
9027
 *
9028
 * Dynamically change the real CPUs which can be allocated to a virtual CPU.
9029
 * This function may require privileged access to the hypervisor.
9030
 *
9031 9032 9033
 * This command only changes the runtime configuration of the domain,
 * so can only be called on an active domain.
 *
9034 9035 9036 9037 9038 9039
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
                 unsigned char *cpumap, int maplen)
{
9040
    virConnectPtr conn;
9041 9042 9043

    VIR_DOMAIN_DEBUG(domain, "vcpu=%u, cpumap=%p, maplen=%d",
                     vcpu, cpumap, maplen);
9044

9045 9046
    virResetLastError();

9047
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
9048
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
9049
        virDispatchError(NULL);
9050
        return -1;
9051
    }
9052
    if (domain->conn->flags & VIR_CONNECT_RO) {
9053
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
9054
        goto error;
9055
    }
9056

9057 9058 9059 9060 9061 9062
    virCheckNonNullArgGoto(cpumap, error);
    virCheckPositiveArgGoto(maplen, error);

    if ((unsigned short) vcpu != vcpu) {
        virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %u"), vcpu);
        goto error;
9063
    }
9064

9065 9066
    conn = domain->conn;

9067 9068
    if (conn->driver->domainPinVcpu) {
        int ret;
9069
        ret = conn->driver->domainPinVcpu(domain, vcpu, cpumap, maplen);
9070 9071 9072 9073
        if (ret < 0)
            goto error;
        return ret;
    }
9074

9075
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
9076 9077

error:
9078
    virDispatchError(domain->conn);
9079
    return -1;
9080 9081
}

9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093
/**
 * virDomainPinVcpuFlags:
 * @domain: pointer to domain object, or NULL for Domain0
 * @vcpu: virtual CPU number
 * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
 *      Each bit set to 1 means that corresponding CPU is usable.
 *      Bytes are stored in little-endian order: CPU0-7, 8-15...
 *      In each byte, lowest CPU number is least significant bit.
 * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
 *      underlying virtualization system (Xen...).
 *      If maplen < size, missing bytes are set to zero.
 *      If maplen > size, failure code is returned.
9094
 * @flags: bitwise-OR of virDomainModificationImpact
9095 9096
 *
 * Dynamically change the real CPUs which can be allocated to a virtual CPU.
9097
 * This function may require privileged access to the hypervisor.
9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109
 *
 * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
 * Both flags may be set.
 * If VIR_DOMAIN_AFFECT_LIVE is set, the change affects a running domain
 * and may fail if domain is not alive.
 * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
 * and will fail for transient domains. If neither flag is specified (that is,
 * @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain modifies
 * persistent setup, while an active domain is hypervisor-dependent on whether
 * just live or both live and persistent state is changed.
 * Not all hypervisors can support all flag combinations.
 *
E
Eric Blake 已提交
9110
 * See also virDomainGetVcpuPinInfo for querying this information.
9111
 *
9112 9113 9114 9115 9116 9117 9118 9119 9120
 * Returns 0 in case of success, -1 in case of failure.
 *
 */
int
virDomainPinVcpuFlags(virDomainPtr domain, unsigned int vcpu,
                      unsigned char *cpumap, int maplen, unsigned int flags)
{
    virConnectPtr conn;

9121
    VIR_DOMAIN_DEBUG(domain, "vcpu=%u, cpumap=%p, maplen=%d, flags=%x",
9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136
                     vcpu, cpumap, maplen, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

9137 9138 9139 9140 9141
    virCheckNonNullArgGoto(cpumap, error);
    virCheckPositiveArgGoto(maplen, error);

    if ((unsigned short) vcpu != vcpu) {
        virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %u"), vcpu);
9142 9143 9144 9145 9146 9147 9148
        goto error;
    }

    conn = domain->conn;

    if (conn->driver->domainPinVcpuFlags) {
        int ret;
9149
        ret = conn->driver->domainPinVcpuFlags(domain, vcpu, cpumap, maplen, flags);
9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;

}

9163
/**
E
Eric Blake 已提交
9164
 * virDomainGetVcpuPinInfo:
9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176
 * @domain: pointer to domain object, or NULL for Domain0
 * @ncpumaps: the number of cpumap (listed first to match virDomainGetVcpus)
 * @cpumaps: pointer to a bit map of real CPUs for all vcpus of this
 *     domain (in 8-bit bytes) (OUT)
 *     It's assumed there is <ncpumaps> cpumap in cpumaps array.
 *     The memory allocated to cpumaps must be (ncpumaps * maplen) bytes
 *     (ie: calloc(ncpumaps, maplen)).
 *     One cpumap inside cpumaps has the format described in
 *     virDomainPinVcpu() API.
 *     Must not be NULL.
 * @maplen: the number of bytes in one cpumap, from 1 up to size of CPU map.
 *     Must be positive.
9177
 * @flags: bitwise-OR of virDomainModificationImpact
9178 9179 9180 9181 9182 9183 9184 9185 9186 9187
 *     Must not be VIR_DOMAIN_AFFECT_LIVE and
 *     VIR_DOMAIN_AFFECT_CONFIG concurrently.
 *
 * Query the CPU affinity setting of all virtual CPUs of domain, store it
 * in cpumaps.
 *
 * Returns the number of virtual CPUs in case of success,
 * -1 in case of failure.
 */
int
9188 9189
virDomainGetVcpuPinInfo(virDomainPtr domain, int ncpumaps,
                        unsigned char *cpumaps, int maplen, unsigned int flags)
9190 9191 9192
{
    virConnectPtr conn;

9193
    VIR_DOMAIN_DEBUG(domain, "ncpumaps=%d, cpumaps=%p, maplen=%d, flags=%x",
9194 9195 9196 9197 9198 9199 9200 9201 9202 9203
                     ncpumaps, cpumaps, maplen, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

9204 9205 9206 9207
    virCheckNonNullArgGoto(cpumaps, error);
    virCheckPositiveArgGoto(ncpumaps, error);
    virCheckPositiveArgGoto(maplen, error);

E
Eric Blake 已提交
9208 9209 9210 9211 9212
    if (INT_MULTIPLY_OVERFLOW(ncpumaps, maplen)) {
        virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %d * %d"),
                          ncpumaps, maplen);
        goto error;
    }
9213

9214 9215 9216
    /* At most one of these two flags should be set.  */
    if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
        (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
9217 9218 9219
        virReportInvalidArg(flags,
                            _("flags 'affect live' and 'affect config' in %s are mutually exclusive"),
                            __FUNCTION__);
9220 9221
        goto error;
    }
9222 9223
    conn = domain->conn;

E
Eric Blake 已提交
9224
    if (conn->driver->domainGetVcpuPinInfo) {
9225
        int ret;
9226 9227
        ret = conn->driver->domainGetVcpuPinInfo(domain, ncpumaps,
                                                 cpumaps, maplen, flags);
9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302
/**
 * virDomainPinEmulator:
 * @domain: pointer to domain object, or NULL for Domain0
 * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
 *      Each bit set to 1 means that corresponding CPU is usable.
 *      Bytes are stored in little-endian order: CPU0-7, 8-15...
 *      In each byte, lowest CPU number is least significant bit.
 * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
 *      underlying virtualization system (Xen...).
 *      If maplen < size, missing bytes are set to zero.
 *      If maplen > size, failure code is returned.
 * @flags: bitwise-OR of virDomainModificationImpact
 *
 * Dynamically change the real CPUs which can be allocated to all emulator
 * threads. This function may require privileged access to the hypervisor.
 *
 * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
 * Both flags may be set.
 * If VIR_DOMAIN_AFFECT_LIVE is set, the change affects a running domain
 * and may fail if domain is not alive.
 * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
 * and will fail for transient domains. If neither flag is specified (that is,
 * @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain modifies
 * persistent setup, while an active domain is hypervisor-dependent on whether
 * just live or both live and persistent state is changed.
 * Not all hypervisors can support all flag combinations.
 *
 * See also virDomainGetEmulatorPinInfo for querying this information.
 *
 * Returns 0 in case of success, -1 in case of failure.
 *
 */
int
virDomainPinEmulator(virDomainPtr domain, unsigned char *cpumap,
                     int maplen, unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "cpumap=%p, maplen=%d, flags=%x",
                     cpumap, maplen, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (domain->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if ((cpumap == NULL) || (maplen < 1)) {
        virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
        goto error;
    }

    conn = domain->conn;

    if (conn->driver->domainPinEmulator) {
        int ret;
9303
        ret = conn->driver->domainPinEmulator(domain, cpumap, maplen, flags);
9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainGetEmulatorPinInfo:
 * @domain: pointer to domain object, or NULL for Domain0
 * @cpumap: pointer to a bit map of real CPUs for all emulator threads of
 *     this domain (in 8-bit bytes) (OUT)
 *     There is only one cpumap for all emulator threads.
 *     Must not be NULL.
 * @maplen: the number of bytes in one cpumap, from 1 up to size of CPU map.
 *     Must be positive.
 * @flags: bitwise-OR of virDomainModificationImpact
 *     Must not be VIR_DOMAIN_AFFECT_LIVE and
 *     VIR_DOMAIN_AFFECT_CONFIG concurrently.
 *
 * Query the CPU affinity setting of all emulator threads of domain, store
 * it in cpumap.
 *
 * Returns 1 in case of success,
 * 0 in case of no emulator threads are pined to pcpus,
 * -1 in case of failure.
 */
int
virDomainGetEmulatorPinInfo(virDomainPtr domain, unsigned char *cpumap,
                            int maplen, unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "cpumap=%p, maplen=%d, flags=%x",
                     cpumap, maplen, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (!cpumap || maplen <= 0) {
        virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
        goto error;
    }

    /* At most one of these two flags should be set.  */
    if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
        (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
        virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
        goto error;
    }
    conn = domain->conn;

    if (conn->driver->domainGetEmulatorPinInfo) {
        int ret;
        ret = conn->driver->domainGetEmulatorPinInfo(domain, cpumap,
                                                     maplen, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

9382 9383 9384 9385 9386
/**
 * virDomainGetVcpus:
 * @domain: pointer to domain object, or NULL for Domain0
 * @info: pointer to an array of virVcpuInfo structures (OUT)
 * @maxinfo: number of structures in info array
D
Dan Kenigsberg 已提交
9387
 * @cpumaps: pointer to a bit map of real CPUs for all vcpus of this
9388
 *      domain (in 8-bit bytes) (OUT)
O
Osier Yang 已提交
9389 9390 9391 9392 9393
 *      If cpumaps is NULL, then no cpumap information is returned by the API.
 *      It's assumed there is <maxinfo> cpumap in cpumaps array.
 *      The memory allocated to cpumaps must be (maxinfo * maplen) bytes
 *      (ie: calloc(maxinfo, maplen)).
 *      One cpumap inside cpumaps has the format described in
9394 9395
 *      virDomainPinVcpu() API.
 * @maplen: number of bytes in one cpumap, from 1 up to size of CPU map in
O
Osier Yang 已提交
9396 9397
 *      underlying virtualization system (Xen...).
 *      Must be zero when cpumaps is NULL and positive when it is non-NULL.
9398
 *
9399
 * Extract information about virtual CPUs of domain, store it in info array
9400 9401 9402
 * and also in cpumaps if this pointer isn't NULL.  This call may fail
 * on an inactive domain.
 *
E
Eric Blake 已提交
9403
 * See also virDomainGetVcpuPinInfo for querying just cpumaps, including on
9404
 * an inactive domain.
9405 9406 9407 9408 9409
 *
 * Returns the number of info filled in case of success, -1 in case of failure.
 */
int
virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
9410
                  unsigned char *cpumaps, int maplen)
9411
{
9412
    virConnectPtr conn;
9413 9414 9415

    VIR_DOMAIN_DEBUG(domain, "info=%p, maxinfo=%d, cpumaps=%p, maplen=%d",
                     info, maxinfo, cpumaps, maplen);
9416

9417 9418
    virResetLastError();

9419
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
9420
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
9421
        virDispatchError(NULL);
9422
        return -1;
9423
    }
9424 9425
    virCheckNonNullArgGoto(info, error);
    virCheckPositiveArgGoto(maxinfo, error);
9426 9427 9428

    /* Ensure that domainGetVcpus (aka remoteDomainGetVcpus) does not
       try to memcpy anything into a NULL pointer.  */
9429 9430 9431 9432 9433
    if (cpumaps)
        virCheckPositiveArgGoto(maplen, error);
    else
        virCheckZeroArgGoto(maplen, error);

E
Eric Blake 已提交
9434 9435 9436 9437 9438
    if (cpumaps && INT_MULTIPLY_OVERFLOW(maxinfo, maplen)) {
        virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %d * %d"),
                          maxinfo, maplen);
        goto error;
    }
9439

9440 9441
    conn = domain->conn;

9442 9443
    if (conn->driver->domainGetVcpus) {
        int ret;
9444 9445
        ret = conn->driver->domainGetVcpus(domain, info, maxinfo,
                                           cpumaps, maplen);
9446 9447 9448 9449
        if (ret < 0)
            goto error;
        return ret;
    }
9450

9451
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
9452 9453

error:
9454
    virDispatchError(domain->conn);
9455
    return -1;
9456
}
9457

9458 9459 9460
/**
 * virDomainGetMaxVcpus:
 * @domain: pointer to domain object
9461
 *
9462 9463
 * Provides the maximum number of virtual CPUs supported for
 * the guest VM. If the guest is inactive, this is basically
E
Eric Blake 已提交
9464
 * the same as virConnectGetMaxVcpus(). If the guest is running
9465
 * this will reflect the maximum number of virtual CPUs the
E
Eric Blake 已提交
9466
 * guest was booted with.  For more details, see virDomainGetVcpusFlags().
9467 9468 9469 9470
 *
 * Returns the maximum of virtual CPU or -1 in case of error.
 */
int
9471 9472
virDomainGetMaxVcpus(virDomainPtr domain)
{
9473
    virConnectPtr conn;
9474

9475
    VIR_DOMAIN_DEBUG(domain);
9476

9477 9478
    virResetLastError();

9479
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
9480
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
9481
        virDispatchError(NULL);
9482
        return -1;
9483 9484 9485 9486
    }

    conn = domain->conn;

9487 9488
    if (conn->driver->domainGetMaxVcpus) {
        int ret;
9489
        ret = conn->driver->domainGetMaxVcpus(domain);
9490 9491 9492 9493
        if (ret < 0)
            goto error;
        return ret;
    }
9494

9495
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
9496 9497

error:
9498
    virDispatchError(domain->conn);
9499
    return -1;
9500 9501
}

9502 9503 9504 9505 9506
/**
 * virDomainGetSecurityLabel:
 * @domain: a domain object
 * @seclabel: pointer to a virSecurityLabel structure
 *
9507 9508 9509
 * Extract security label of an active domain. The 'label' field
 * in the @seclabel argument will be initialized to the empty
 * string if the domain is not running under a security model.
9510
 *
9511
 * Returns 0 in case of success, -1 in case of failure
9512 9513 9514 9515 9516 9517
 */
int
virDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr seclabel)
{
    virConnectPtr conn;

9518 9519
    VIR_DOMAIN_DEBUG(domain, "seclabel=%p", seclabel);

9520
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
9521
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
9522
        virDispatchError(NULL);
9523 9524 9525
        return -1;
    }

9526
    virCheckNonNullArgGoto(seclabel, error);
9527 9528 9529

    conn = domain->conn;

9530 9531 9532 9533 9534 9535 9536 9537
    if (conn->driver->domainGetSecurityLabel) {
        int ret;
        ret = conn->driver->domainGetSecurityLabel(domain, seclabel);
        if (ret < 0)
            goto error;
        return ret;
    }

9538
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
9539

9540
error:
9541
    virDispatchError(domain->conn);
9542
    return -1;
9543 9544
}

M
Marcelo Cerri 已提交
9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 9581 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591
/**
 * virDomainGetSecurityLabelList:
 * @domain: a domain object
 * @seclabels: will be auto-allocated and filled with domains' security labels.
 * Caller must free memory on return.
 *
 * Extract the security labels of an active domain. The 'label' field
 * in the @seclabels argument will be initialized to the empty
 * string if the domain is not running under a security model.
 *
 * Returns number of elemnets in @seclabels on success, -1 in case of failure.
 */
int
virDomainGetSecurityLabelList(virDomainPtr domain,
                              virSecurityLabelPtr* seclabels)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "seclabels=%p", seclabels);

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (seclabels == NULL) {
        virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
        goto error;
    }

    conn = domain->conn;

    if (conn->driver->domainGetSecurityLabelList) {
        int ret;
        ret = conn->driver->domainGetSecurityLabelList(domain, seclabels);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}
9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617 9618 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 9646 9647 9648 9649 9650 9651
/**
 * virDomainSetMetadata:
 * @domain: a domain object
 * @type: type of description, from virDomainMetadataType
 * @metadata: new metadata text
 * @key: XML namespace key, or NULL
 * @uri: XML namespace URI, or NULL
 * @flags: bitwise-OR of virDomainModificationImpact
 *
 * Sets the appropriate domain element given by @type to the
 * value of @description.  A @type of VIR_DOMAIN_METADATA_DESCRIPTION
 * is free-form text; VIR_DOMAIN_METADATA_TITLE is free-form, but no
 * newlines are permitted, and should be short (although the length is
 * not enforced). For these two options @key and @uri are irrelevant and
 * must be set to NULL.
 *
 * For type VIR_DOMAIN_METADATA_ELEMENT @metadata  must be well-formed
 * XML belonging to namespace defined by @uri with local name @key.
 *
 * Passing NULL for @metadata says to remove that element from the
 * domain XML (passing the empty string leaves the element present).
 *
 * The resulting metadata will be present in virDomainGetXMLDesc(),
 * as well as quick access through virDomainGetMetadata().
 *
 * @flags controls whether the live domain, persistent configuration,
 * or both will be modified.
 *
 * Returns 0 on success, -1 in case of failure.
 */
int
virDomainSetMetadata(virDomainPtr domain,
                     int type,
                     const char *metadata,
                     const char *key,
                     const char *uri,
                     unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain,
                     "type=%d, metadata='%s', key='%s', uri='%s', flags=%x",
                     type, NULLSTR(metadata), NULLSTR(key), NULLSTR(uri),
                     flags);

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        goto error;
    }

    conn = domain->conn;

    if (conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    switch (type) {
    case VIR_DOMAIN_METADATA_TITLE:
        if (metadata && strchr(metadata, '\n')) {
9652 9653 9654 9655
            virReportInvalidArg(metadata,
                                _("metadata title in %s can't contain newlines"),
                                __FUNCTION__);
            goto error;
9656 9657 9658
        }
        /* fallthrough */
    case VIR_DOMAIN_METADATA_DESCRIPTION:
9659 9660
        virCheckNullArgGoto(uri, error);
        virCheckNullArgGoto(key, error);
9661 9662
        break;
    case VIR_DOMAIN_METADATA_ELEMENT:
9663 9664
        virCheckNonNullArgGoto(uri, error);
        virCheckNonNullArgGoto(key, error);
9665 9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727
        break;
    default:
        /* For future expansion */
        break;
    }

    if (conn->driver->domainSetMetadata) {
        int ret;
        ret = conn->driver->domainSetMetadata(domain, type, metadata, key, uri,
                                              flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainGetMetadata:
 * @domain: a domain object
 * @type: type of description, from virDomainMetadataType
 * @uri: XML namespace identifier
 * @flags: bitwise-OR of virDomainModificationImpact
 *
 * Retrieves the appropriate domain element given by @type.
 * If VIR_DOMAIN_METADATA_ELEMENT is requested parameter @uri
 * must be set to the name of the namespace the requested elements
 * belong to, otherwise must be NULL.
 *
 * If an element of the domain XML is not present, the resulting
 * error will be VIR_ERR_NO_DOMAIN_METADATA.  This method forms
 * a shortcut for seeing information from virDomainSetMetadata()
 * without having to go through virDomainGetXMLDesc().
 *
 * @flags controls whether the live domain or persistent
 * configuration will be queried.
 *
 * Returns the metadata string on success (caller must free),
 * or NULL in case of failure.
 */
char *
virDomainGetMetadata(virDomainPtr domain,
                     int type,
                     const char *uri,
                     unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "type=%d, uri='%s', flags=%x",
                     type, NULLSTR(uri), flags);

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        goto error;
    }

    if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
        (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
9728 9729 9730
        virReportInvalidArg(flags,
                            _("flags 'affect live' and 'affect config' in %s are mutually exclusive"),
                            __FUNCTION__);
9731 9732 9733 9734 9735 9736
        goto error;
    }

    switch (type) {
    case VIR_DOMAIN_METADATA_TITLE:
    case VIR_DOMAIN_METADATA_DESCRIPTION:
9737
        virCheckNullArgGoto(uri, error);
9738 9739
        break;
    case VIR_DOMAIN_METADATA_ELEMENT:
9740
        virCheckNonNullArgGoto(uri, error);
9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762
        break;
    default:
        /* For future expansion */
        break;
    }

    conn = domain->conn;

    if (conn->driver->domainGetMetadata) {
        char *ret;
        if (!(ret = conn->driver->domainGetMetadata(domain, type, uri, flags)))
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return NULL;
}

9763 9764 9765 9766 9767
/**
 * virNodeGetSecurityModel:
 * @conn: a connection object
 * @secmodel: pointer to a virSecurityModel structure
 *
9768 9769 9770
 * Extract the security model of a hypervisor. The 'model' field
 * in the @secmodel argument may be initialized to the empty
 * string if the driver has not activated a security model.
9771
 *
9772
 * Returns 0 in case of success, -1 in case of failure
9773 9774 9775 9776
 */
int
virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
{
9777
    VIR_DEBUG("conn=%p secmodel=%p", conn, secmodel);
9778

9779
    if (!VIR_IS_CONNECT(conn)) {
9780
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
9781
        virDispatchError(NULL);
9782 9783 9784
        return -1;
    }

9785
    virCheckNonNullArgGoto(secmodel, error);
9786 9787 9788 9789 9790 9791 9792

    if (conn->driver->nodeGetSecurityModel) {
        int ret;
        ret = conn->driver->nodeGetSecurityModel(conn, secmodel);
        if (ret < 0)
            goto error;
        return ret;
9793 9794
    }

9795
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
9796

9797
error:
9798
    virDispatchError(conn);
9799
    return -1;
9800
}
9801

9802 9803 9804 9805
/**
 * virDomainAttachDevice:
 * @domain: pointer to domain object
 * @xml: pointer to XML description of one device
9806
 *
9807 9808
 * Create a virtual device attachment to backend.  This function,
 * having hotplug semantics, is only allowed on an active domain.
9809
 *
9810 9811 9812 9813
 * For compatibility, this method can also be used to change the media
 * in an existing CDROM/Floppy device, however, applications are
 * recommended to use the virDomainUpdateDeviceFlag method instead.
 *
9814 9815 9816
 * Returns 0 in case of success, -1 in case of failure.
 */
int
9817
virDomainAttachDevice(virDomainPtr domain, const char *xml)
9818 9819
{
    virConnectPtr conn;
9820 9821

    VIR_DOMAIN_DEBUG(domain, "xml=%s", xml);
9822

9823 9824
    virResetLastError();

9825
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
9826
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
9827
        virDispatchError(NULL);
9828
        return -1;
9829
    }
9830

9831
    virCheckNonNullArgGoto(xml, error);
9832

9833
    if (domain->conn->flags & VIR_CONNECT_RO) {
9834
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
9835
        goto error;
9836 9837 9838
    }
    conn = domain->conn;

9839
    if (conn->driver->domainAttachDevice) {
J
Jim Fehlig 已提交
9840
       int ret;
9841
       ret = conn->driver->domainAttachDevice(domain, xml);
J
Jim Fehlig 已提交
9842 9843 9844 9845 9846
       if (ret < 0)
          goto error;
       return ret;
    }

9847
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
J
Jim Fehlig 已提交
9848 9849 9850 9851 9852 9853 9854 9855 9856 9857

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainAttachDeviceFlags:
 * @domain: pointer to domain object
 * @xml: pointer to XML description of one device
9858
 * @flags: bitwise-OR of virDomainDeviceModifyFlags
J
Jim Fehlig 已提交
9859 9860
 *
 * Attach a virtual device to a domain, using the flags parameter
9861
 * to control how the device is attached.  VIR_DOMAIN_AFFECT_CURRENT
J
Jim Fehlig 已提交
9862
 * specifies that the device allocation is made based on current domain
9863
 * state.  VIR_DOMAIN_AFFECT_LIVE specifies that the device shall be
J
Jim Fehlig 已提交
9864
 * allocated to the active domain instance only and is not added to the
9865
 * persisted domain configuration.  VIR_DOMAIN_AFFECT_CONFIG
J
Jim Fehlig 已提交
9866 9867 9868 9869 9870 9871
 * specifies that the device shall be allocated to the persisted domain
 * configuration only.  Note that the target hypervisor must return an
 * error if unable to satisfy flags.  E.g. the hypervisor driver will
 * return failure if LIVE is specified but it only supports modifying the
 * persisted device allocation.
 *
9872 9873 9874 9875
 * For compatibility, this method can also be used to change the media
 * in an existing CDROM/Floppy device, however, applications are
 * recommended to use the virDomainUpdateDeviceFlag method instead.
 *
J
Jim Fehlig 已提交
9876 9877 9878 9879 9880 9881 9882
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virDomainAttachDeviceFlags(virDomainPtr domain,
                           const char *xml, unsigned int flags)
{
    virConnectPtr conn;
9883

9884
    VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%x", xml, flags);
J
Jim Fehlig 已提交
9885 9886 9887 9888

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
9889
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
W
Wen Congyang 已提交
9890
        virDispatchError(NULL);
9891
        return -1;
J
Jim Fehlig 已提交
9892
    }
9893

9894
    virCheckNonNullArgGoto(xml, error);
9895

J
Jim Fehlig 已提交
9896
    if (domain->conn->flags & VIR_CONNECT_RO) {
9897
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
J
Jim Fehlig 已提交
9898 9899 9900 9901 9902
        goto error;
    }
    conn = domain->conn;

    if (conn->driver->domainAttachDeviceFlags) {
9903
        int ret;
J
Jim Fehlig 已提交
9904
        ret = conn->driver->domainAttachDeviceFlags(domain, xml, flags);
9905 9906 9907 9908
        if (ret < 0)
            goto error;
        return ret;
    }
9909

9910
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
9911 9912

error:
9913
    virDispatchError(domain->conn);
9914
    return -1;
9915 9916 9917 9918 9919 9920
}

/**
 * virDomainDetachDevice:
 * @domain: pointer to domain object
 * @xml: pointer to XML description of one device
9921
 *
9922 9923
 * Destroy a virtual device attachment to backend.  This function,
 * having hot-unplug semantics, is only allowed on an active domain.
9924 9925 9926 9927
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
9928
virDomainDetachDevice(virDomainPtr domain, const char *xml)
9929 9930
{
    virConnectPtr conn;
9931 9932

    VIR_DOMAIN_DEBUG(domain, "xml=%s", xml);
9933

9934 9935
    virResetLastError();

9936
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
9937
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
9938
        virDispatchError(NULL);
9939
        return -1;
9940
    }
9941

9942
    virCheckNonNullArgGoto(xml, error);
9943

9944
    if (domain->conn->flags & VIR_CONNECT_RO) {
9945
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
9946
        goto error;
9947 9948 9949
    }
    conn = domain->conn;

9950 9951
    if (conn->driver->domainDetachDevice) {
        int ret;
9952
        ret = conn->driver->domainDetachDevice(domain, xml);
J
Jim Fehlig 已提交
9953 9954 9955 9956 9957
         if (ret < 0)
             goto error;
         return ret;
     }

9958
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
J
Jim Fehlig 已提交
9959 9960 9961 9962 9963 9964 9965 9966 9967 9968

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainDetachDeviceFlags:
 * @domain: pointer to domain object
 * @xml: pointer to XML description of one device
9969
 * @flags: bitwise-OR of virDomainDeviceModifyFlags
J
Jim Fehlig 已提交
9970 9971
 *
 * Detach a virtual device from a domain, using the flags parameter
9972
 * to control how the device is detached.  VIR_DOMAIN_AFFECT_CURRENT
J
Jim Fehlig 已提交
9973
 * specifies that the device allocation is removed based on current domain
9974
 * state.  VIR_DOMAIN_AFFECT_LIVE specifies that the device shall be
J
Jim Fehlig 已提交
9975
 * deallocated from the active domain instance only and is not from the
9976
 * persisted domain configuration.  VIR_DOMAIN_AFFECT_CONFIG
J
Jim Fehlig 已提交
9977 9978 9979 9980 9981 9982
 * specifies that the device shall be deallocated from the persisted domain
 * configuration only.  Note that the target hypervisor must return an
 * error if unable to satisfy flags.  E.g. the hypervisor driver will
 * return failure if LIVE is specified but it only supports removing the
 * persisted device allocation.
 *
E
Eric Blake 已提交
9983 9984 9985 9986
 * Some hypervisors may prevent this operation if there is a current
 * block copy operation on the device being detached; in that case,
 * use virDomainBlockJobAbort() to stop the block copy first.
 *
J
Jim Fehlig 已提交
9987 9988 9989 9990 9991 9992 9993
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virDomainDetachDeviceFlags(virDomainPtr domain,
                           const char *xml, unsigned int flags)
{
    virConnectPtr conn;
9994

9995
    VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%x", xml, flags);
J
Jim Fehlig 已提交
9996 9997 9998 9999

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
10000
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
W
Wen Congyang 已提交
10001
        virDispatchError(NULL);
10002
        return -1;
J
Jim Fehlig 已提交
10003
    }
10004

10005
    virCheckNonNullArgGoto(xml, error);
10006

J
Jim Fehlig 已提交
10007
    if (domain->conn->flags & VIR_CONNECT_RO) {
10008
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
J
Jim Fehlig 已提交
10009 10010 10011 10012 10013 10014 10015
        goto error;
    }
    conn = domain->conn;

    if (conn->driver->domainDetachDeviceFlags) {
        int ret;
        ret = conn->driver->domainDetachDeviceFlags(domain, xml, flags);
10016 10017 10018 10019 10020
        if (ret < 0)
            goto error;
        return ret;
    }

10021
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10022 10023 10024 10025 10026 10027 10028 10029 10030 10031

error:
    virDispatchError(domain->conn);
    return -1;
}

/**
 * virDomainUpdateDeviceFlags:
 * @domain: pointer to domain object
 * @xml: pointer to XML description of one device
10032
 * @flags: bitwise-OR of virDomainDeviceModifyFlags
10033 10034
 *
 * Change a virtual device on a domain, using the flags parameter
10035
 * to control how the device is changed.  VIR_DOMAIN_AFFECT_CURRENT
10036
 * specifies that the device change is made based on current domain
10037
 * state.  VIR_DOMAIN_AFFECT_LIVE specifies that the device shall be
10038
 * changed on the active domain instance only and is not added to the
10039
 * persisted domain configuration. VIR_DOMAIN_AFFECT_CONFIG
10040 10041 10042 10043 10044 10045 10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056
 * specifies that the device shall be changed on the persisted domain
 * configuration only.  Note that the target hypervisor must return an
 * error if unable to satisfy flags.  E.g. the hypervisor driver will
 * return failure if LIVE is specified but it only supports modifying the
 * persisted device allocation.
 *
 * This method is used for actions such changing CDROM/Floppy device
 * media, altering the graphics configuration such as password,
 * reconfiguring the NIC device backend connectivity, etc.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virDomainUpdateDeviceFlags(virDomainPtr domain,
                           const char *xml, unsigned int flags)
{
    virConnectPtr conn;
10057

10058
    VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%x", xml, flags);
10059 10060 10061 10062

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
10063
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
W
Wen Congyang 已提交
10064
        virDispatchError(NULL);
10065
        return -1;
10066
    }
10067

10068
    virCheckNonNullArgGoto(xml, error);
10069

10070
    if (domain->conn->flags & VIR_CONNECT_RO) {
10071
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
10072 10073 10074 10075 10076 10077 10078
        goto error;
    }
    conn = domain->conn;

    if (conn->driver->domainUpdateDeviceFlags) {
        int ret;
        ret = conn->driver->domainUpdateDeviceFlags(domain, xml, flags);
10079 10080 10081 10082
        if (ret < 0)
            goto error;
        return ret;
    }
10083

10084
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10085 10086

error:
10087
    virDispatchError(domain->conn);
10088
    return -1;
10089
}
10090

10091 10092 10093 10094 10095 10096 10097 10098 10099 10100
/**
 * virNodeGetCellsFreeMemory:
 * @conn: pointer to the hypervisor connection
 * @freeMems: pointer to the array of unsigned long long
 * @startCell: index of first cell to return freeMems info on.
 * @maxCells: Maximum number of cells for which freeMems information can
 *            be returned.
 *
 * This call returns the amount of free memory in one or more NUMA cells.
 * The @freeMems array must be allocated by the caller and will be filled
10101
 * with the amount of free memory in bytes for each cell requested,
10102 10103 10104 10105 10106 10107 10108 10109 10110 10111 10112
 * starting with startCell (in freeMems[0]), up to either
 * (startCell + maxCells), or the number of additional cells in the node,
 * whichever is smaller.
 *
 * Returns the number of entries filled in freeMems, or -1 in case of error.
 */

int
virNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems,
                          int startCell, int maxCells)
{
10113
    VIR_DEBUG("conn=%p, freeMems=%p, startCell=%d, maxCells=%d",
10114 10115
          conn, freeMems, startCell, maxCells);

10116 10117
    virResetLastError();

10118
    if (!VIR_IS_CONNECT(conn)) {
10119
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10120
        virDispatchError(NULL);
10121
        return -1;
10122 10123
    }

10124 10125 10126
    virCheckNonNullArgGoto(freeMems, error);
    virCheckPositiveArgGoto(maxCells, error);
    virCheckNonNegativeArgGoto(startCell, error);
10127

10128 10129
    if (conn->driver->nodeGetCellsFreeMemory) {
        int ret;
10130
        ret = conn->driver->nodeGetCellsFreeMemory(conn, freeMems, startCell, maxCells);
10131 10132 10133 10134
        if (ret < 0)
            goto error;
        return ret;
    }
10135

10136
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10137 10138

error:
10139
    virDispatchError(conn);
10140 10141 10142
    return -1;
}

10143 10144 10145 10146
/**
 * virNetworkGetConnect:
 * @net: pointer to a network
 *
10147
 * Provides the connection pointer associated with a network.  The
10148 10149 10150
 * reference counter on the connection is not increased by this
 * call.
 *
10151 10152 10153 10154
 * WARNING: When writing libvirt bindings in other languages, do
 * not use this function.  Instead, store the connection and
 * the network object together.
 *
10155 10156 10157
 * Returns the virConnectPtr or NULL in case of failure.
 */
virConnectPtr
10158
virNetworkGetConnect(virNetworkPtr net)
10159
{
10160
    VIR_DEBUG("net=%p", net);
10161

10162 10163
    virResetLastError();

10164
    if (!VIR_IS_CONNECTED_NETWORK(net)) {
10165
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10166
        virDispatchError(NULL);
10167 10168 10169 10170 10171
        return NULL;
    }
    return net->conn;
}

10172 10173 10174 10175 10176 10177 10178 10179 10180 10181 10182 10183 10184 10185 10186 10187 10188 10189 10190 10191 10192 10193 10194 10195 10196 10197 10198 10199 10200 10201 10202 10203 10204 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225
/**
 * virConnectListAllNetworks:
 * @conn: Pointer to the hypervisor connection.
 * @nets: Pointer to a variable to store the array containing the network
 *        objects or NULL if the list is not required (just returns number
 *        of networks).
 * @flags: bitwise-OR of virConnectListAllNetworksFlags.
 *
 * Collect the list of networks, and allocate an array to store those
 * objects. This API solves the race inherent between virConnectListNetworks
 * and virConnectListDefinedNetworks.
 *
 * Normally, all networks are returned; however, @flags can be used to
 * filter the results for a smaller list of targeted networks.  The valid
 * flags are divided into groups, where each group contains bits that
 * describe mutually exclusive attributes of a network, and where all bits
 * within a group describe all possible networks.
 *
 * The first group of @flags is VIR_CONNECT_LIST_NETWORKS_ACTIVE (up) and
 * VIR_CONNECT_LIST_NETWORKS_INACTIVE (down) to filter the networks by state.
 *
 * The second group of @flags is VIR_CONNECT_LIST_NETWORKS_PERSISTENT (defined)
 * and VIR_CONNECT_LIST_NETWORKS_TRANSIENT (running but not defined), to filter
 * the networks by whether they have persistent config or not.
 *
 * The third group of @flags is VIR_CONNECT_LIST_NETWORKS_AUTOSTART
 * and VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART, to filter the networks by
 * whether they are marked as autostart or not.
 *
 * Returns the number of networks found or -1 and sets @nets to  NULL in case
 * of error.  On success, the array stored into @nets is guaranteed to have an
 * extra allocated element set to NULL but not included in the return count,
 * to make iteration easier.  The caller is responsible for calling
 * virNetworkFree() on each array element, then calling free() on @nets.
 */
int
virConnectListAllNetworks(virConnectPtr conn,
                          virNetworkPtr **nets,
                          unsigned int flags)
{
    VIR_DEBUG("conn=%p, nets=%p, flags=%x", conn, nets, flags);

    virResetLastError();

    if (nets)
        *nets = NULL;

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->networkDriver &&
10226
        conn->networkDriver->connectListAllNetworks) {
10227
        int ret;
10228
        ret = conn->networkDriver->connectListAllNetworks(conn, nets, flags);
10229 10230 10231 10232 10233 10234 10235 10236 10237 10238 10239 10240 10241
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}


10242 10243 10244 10245 10246 10247 10248 10249 10250 10251 10252
/**
 * virConnectNumOfNetworks:
 * @conn: pointer to the hypervisor connection
 *
 * Provides the number of active networks.
 *
 * Returns the number of network found or -1 in case of error
 */
int
virConnectNumOfNetworks(virConnectPtr conn)
{
10253
    VIR_DEBUG("conn=%p", conn);
10254

10255 10256
    virResetLastError();

10257
    if (!VIR_IS_CONNECT(conn)) {
10258
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10259
        virDispatchError(NULL);
10260
        return -1;
10261 10262
    }

10263
    if (conn->networkDriver && conn->networkDriver->connectNumOfNetworks) {
10264
        int ret;
10265
        ret = conn->networkDriver->connectNumOfNetworks(conn);
10266 10267 10268 10269
        if (ret < 0)
            goto error;
        return ret;
    }
10270

10271
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10272 10273

error:
10274
    virDispatchError(conn);
10275
    return -1;
10276 10277 10278 10279 10280 10281 10282 10283 10284 10285
}

/**
 * virConnectListNetworks:
 * @conn: pointer to the hypervisor connection
 * @names: array to collect the list of names of active networks
 * @maxnames: size of @names
 *
 * Collect the list of active networks, and store their names in @names
 *
10286 10287 10288 10289 10290 10291
 * For more control over the results, see virConnectListAllNetworks().
 *
 * Returns the number of networks found or -1 in case of error.  Note that
 * this command is inherently racy; a network can be started between a call
 * to virConnectNumOfNetworks() and this call; you are only guaranteed that
 * all currently active networks were listed if the return is less than
J
John Ferlan 已提交
10292
 * @maxnames. The client must call free() on each returned name.
10293 10294
 */
int
10295
virConnectListNetworks(virConnectPtr conn, char **const names, int maxnames)
10296
{
10297
    VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
10298

10299 10300
    virResetLastError();

10301
    if (!VIR_IS_CONNECT(conn)) {
10302
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10303
        virDispatchError(NULL);
10304
        return -1;
10305 10306
    }

10307 10308
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
10309

10310
    if (conn->networkDriver && conn->networkDriver->connectListNetworks) {
10311
        int ret;
10312
        ret = conn->networkDriver->connectListNetworks(conn, names, maxnames);
10313 10314 10315 10316
        if (ret < 0)
            goto error;
        return ret;
    }
10317

10318
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10319 10320

error:
10321
    virDispatchError(conn);
10322
    return -1;
10323 10324 10325 10326 10327 10328 10329 10330 10331 10332 10333 10334 10335
}

/**
 * virConnectNumOfDefinedNetworks:
 * @conn: pointer to the hypervisor connection
 *
 * Provides the number of inactive networks.
 *
 * Returns the number of networks found or -1 in case of error
 */
int
virConnectNumOfDefinedNetworks(virConnectPtr conn)
{
10336
    VIR_DEBUG("conn=%p", conn);
10337

10338 10339
    virResetLastError();

10340
    if (!VIR_IS_CONNECT(conn)) {
10341
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10342
        virDispatchError(NULL);
10343
        return -1;
10344 10345
    }

10346
    if (conn->networkDriver && conn->networkDriver->connectNumOfDefinedNetworks) {
10347
        int ret;
10348
        ret = conn->networkDriver->connectNumOfDefinedNetworks(conn);
10349 10350 10351 10352
        if (ret < 0)
            goto error;
        return ret;
    }
10353

10354
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10355 10356

error:
10357
    virDispatchError(conn);
10358
    return -1;
10359 10360 10361 10362 10363 10364 10365 10366 10367 10368
}

/**
 * virConnectListDefinedNetworks:
 * @conn: pointer to the hypervisor connection
 * @names: pointer to an array to store the names
 * @maxnames: size of the array
 *
 * list the inactive networks, stores the pointers to the names in @names
 *
10369 10370 10371 10372 10373 10374 10375
 * For more control over the results, see virConnectListAllNetworks().
 *
 * Returns the number of names provided in the array or -1 in case of error.
 * Note that this command is inherently racy; a network can be defined between
 * a call to virConnectNumOfDefinedNetworks() and this call; you are only
 * guaranteed that all currently defined networks were listed if the return
 * is less than @maxnames.  The client must call free() on each returned name.
10376 10377
 */
int
10378
virConnectListDefinedNetworks(virConnectPtr conn, char **const names,
10379 10380
                              int maxnames)
{
10381
    VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
10382

10383 10384
    virResetLastError();

10385
    if (!VIR_IS_CONNECT(conn)) {
10386
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10387
        virDispatchError(NULL);
10388
        return -1;
10389 10390
    }

10391 10392
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
10393

10394
    if (conn->networkDriver && conn->networkDriver->connectListDefinedNetworks) {
10395
        int ret;
10396
        ret = conn->networkDriver->connectListDefinedNetworks(conn, names, maxnames);
10397 10398 10399 10400
        if (ret < 0)
            goto error;
        return ret;
    }
10401

10402
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10403 10404

error:
10405
    virDispatchError(conn);
10406
    return -1;
10407 10408 10409 10410 10411 10412 10413 10414 10415
}

/**
 * virNetworkLookupByName:
 * @conn: pointer to the hypervisor connection
 * @name: name for the network
 *
 * Try to lookup a network on the given hypervisor based on its name.
 *
10416 10417
 * Returns a new network object or NULL in case of failure.  If the
 * network cannot be found, then VIR_ERR_NO_NETWORK error is raised.
10418 10419 10420 10421
 */
virNetworkPtr
virNetworkLookupByName(virConnectPtr conn, const char *name)
{
10422
    VIR_DEBUG("conn=%p, name=%s", conn, name);
10423

10424 10425
    virResetLastError();

10426
    if (!VIR_IS_CONNECT(conn)) {
10427
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10428
        virDispatchError(NULL);
10429
        return NULL;
10430
    }
10431
    virCheckNonNullArgGoto(name, error);
10432

10433 10434
    if (conn->networkDriver && conn->networkDriver->networkLookupByName) {
        virNetworkPtr ret;
10435
        ret = conn->networkDriver->networkLookupByName(conn, name);
10436 10437 10438 10439
        if (!ret)
            goto error;
        return ret;
    }
10440

10441
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10442 10443

error:
10444
    virDispatchError(conn);
10445
    return NULL;
10446 10447 10448 10449 10450 10451 10452 10453 10454
}

/**
 * virNetworkLookupByUUID:
 * @conn: pointer to the hypervisor connection
 * @uuid: the raw UUID for the network
 *
 * Try to lookup a network on the given hypervisor based on its UUID.
 *
10455 10456
 * Returns a new network object or NULL in case of failure.  If the
 * network cannot be found, then VIR_ERR_NO_NETWORK error is raised.
10457 10458 10459 10460
 */
virNetworkPtr
virNetworkLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
10461
    VIR_UUID_DEBUG(conn, uuid);
10462

10463 10464
    virResetLastError();

10465
    if (!VIR_IS_CONNECT(conn)) {
10466
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10467
        virDispatchError(NULL);
10468
        return NULL;
10469
    }
10470 10471

    virCheckNonNullArgGoto(uuid, error);
10472

10473 10474
    if (conn->networkDriver && conn->networkDriver->networkLookupByUUID){
        virNetworkPtr ret;
10475
        ret = conn->networkDriver->networkLookupByUUID(conn, uuid);
10476 10477 10478 10479
        if (!ret)
            goto error;
        return ret;
    }
10480

10481
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10482 10483

error:
10484
    virDispatchError(conn);
10485
    return NULL;
10486 10487 10488 10489 10490 10491 10492 10493 10494
}

/**
 * virNetworkLookupByUUIDString:
 * @conn: pointer to the hypervisor connection
 * @uuidstr: the string UUID for the network
 *
 * Try to lookup a network on the given hypervisor based on its UUID.
 *
10495 10496
 * Returns a new network object or NULL in case of failure.  If the
 * network cannot be found, then VIR_ERR_NO_NETWORK error is raised.
10497 10498 10499 10500 10501
 */
virNetworkPtr
virNetworkLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
{
    unsigned char uuid[VIR_UUID_BUFLEN];
10502
    VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
10503

10504 10505
    virResetLastError();

10506
    if (!VIR_IS_CONNECT(conn)) {
10507
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10508
        virDispatchError(NULL);
10509
        return NULL;
10510
    }
10511 10512

    virCheckNonNullArgGoto(uuidstr, error);
10513

10514
    if (virUUIDParse(uuidstr, uuid) < 0) {
10515 10516 10517
        virReportInvalidArg(uuidstr,
                            _("uuidstr in %s must be a valid UUID"),
                            __FUNCTION__);
10518
        goto error;
10519 10520 10521
    }

    return virNetworkLookupByUUID(conn, &uuid[0]);
10522 10523

error:
10524
    virDispatchError(conn);
10525
    return NULL;
10526 10527 10528 10529 10530 10531 10532 10533 10534 10535 10536 10537 10538 10539 10540
}

/**
 * virNetworkCreateXML:
 * @conn: pointer to the hypervisor connection
 * @xmlDesc: an XML description of the network
 *
 * Create and start a new virtual network, based on an XML description
 * similar to the one returned by virNetworkGetXMLDesc()
 *
 * Returns a new network object or NULL in case of failure
 */
virNetworkPtr
virNetworkCreateXML(virConnectPtr conn, const char *xmlDesc)
{
10541
    VIR_DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc);
10542

10543 10544
    virResetLastError();

10545
    if (!VIR_IS_CONNECT(conn)) {
10546
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10547
        virDispatchError(NULL);
10548
        return NULL;
10549
    }
10550 10551
    virCheckNonNullArgGoto(xmlDesc, error);

10552
    if (conn->flags & VIR_CONNECT_RO) {
10553
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
10554
        goto error;
10555 10556
    }

10557 10558
    if (conn->networkDriver && conn->networkDriver->networkCreateXML) {
        virNetworkPtr ret;
10559
        ret = conn->networkDriver->networkCreateXML(conn, xmlDesc);
10560 10561 10562 10563
        if (!ret)
            goto error;
        return ret;
    }
10564

10565
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10566 10567

error:
10568
    virDispatchError(conn);
10569
    return NULL;
10570 10571 10572 10573 10574 10575 10576 10577 10578 10579 10580 10581
}

/**
 * virNetworkDefineXML:
 * @conn: pointer to the hypervisor connection
 * @xml: the XML description for the network, preferably in UTF-8
 *
 * Define a network, but does not create it
 *
 * Returns NULL in case of error, a pointer to the network otherwise
 */
virNetworkPtr
10582 10583
virNetworkDefineXML(virConnectPtr conn, const char *xml)
{
10584
    VIR_DEBUG("conn=%p, xml=%s", conn, xml);
10585

10586 10587
    virResetLastError();

10588
    if (!VIR_IS_CONNECT(conn)) {
10589
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
10590
        virDispatchError(NULL);
10591
        return NULL;
10592 10593
    }
    if (conn->flags & VIR_CONNECT_RO) {
10594
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
10595
        goto error;
10596
    }
10597
    virCheckNonNullArgGoto(xml, error);
10598

10599 10600
    if (conn->networkDriver && conn->networkDriver->networkDefineXML) {
        virNetworkPtr ret;
10601
        ret = conn->networkDriver->networkDefineXML(conn, xml);
10602 10603 10604 10605
        if (!ret)
            goto error;
        return ret;
    }
10606

10607
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10608 10609

error:
10610
    virDispatchError(conn);
10611
    return NULL;
10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624
}

/**
 * virNetworkUndefine:
 * @network: pointer to a defined network
 *
 * Undefine a network but does not stop it if it is running
 *
 * Returns 0 in case of success, -1 in case of error
 */
int
virNetworkUndefine(virNetworkPtr network) {
    virConnectPtr conn;
10625
    VIR_DEBUG("network=%p", network);
10626

10627 10628
    virResetLastError();

10629
    if (!VIR_IS_CONNECTED_NETWORK(network)) {
10630
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10631
        virDispatchError(NULL);
10632
        return -1;
10633 10634 10635
    }
    conn = network->conn;
    if (conn->flags & VIR_CONNECT_RO) {
10636
        virLibNetworkError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
10637
        goto error;
10638 10639
    }

10640 10641
    if (conn->networkDriver && conn->networkDriver->networkUndefine) {
        int ret;
10642
        ret = conn->networkDriver->networkUndefine(network);
10643 10644 10645 10646
        if (ret < 0)
            goto error;
        return ret;
    }
10647

10648
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10649 10650 10651 10652 10653 10654 10655 10656 10657 10658 10659 10660 10661 10662 10663 10664 10665 10666 10667 10668 10669 10670 10671 10672 10673 10674 10675 10676 10677 10678 10679 10680 10681 10682 10683 10684 10685 10686 10687 10688 10689 10690 10691 10692 10693 10694 10695 10696 10697 10698 10699 10700 10701 10702 10703 10704 10705 10706 10707 10708 10709 10710

error:
    virDispatchError(network->conn);
    return -1;
}

/**
 * virNetworkUpdate:
 * @network: pointer to a defined network
 * @section: which section of the network to update
 *           (see virNetworkUpdateSection for descriptions)
 * @command: what action to perform (add/delete/modify)
 *           (see virNetworkUpdateCommand for descriptions)
 * @parentIndex: which parent element, if there are multiple parents
 *           of the same type (e.g. which <ip> element when modifying
 *           a <dhcp>/<host> element), or "-1" for "don't care" or
 *           "automatically find appropriate one".
 * @xml: the XML description for the network, preferably in UTF-8
 * @flags: bitwise OR of virNetworkUpdateFlags.
 *
 * Update the definition of an existing network, either its live
 * running state, its persistent configuration, or both.
 *
 * Returns 0 in case of success, -1 in case of error
 */
int
virNetworkUpdate(virNetworkPtr network,
                 unsigned int command, /* virNetworkUpdateCommand */
                 unsigned int section, /* virNetworkUpdateSection */
                 int parentIndex,
                 const char *xml,
                 unsigned int flags)
{
    virConnectPtr conn;
    VIR_DEBUG("network=%p, section=%d, parentIndex=%d, xml=%s, flags=0x%x",
              network, section, parentIndex, xml, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_NETWORK(network)) {
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = network->conn;
    if (conn->flags & VIR_CONNECT_RO) {
        virLibNetworkError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    virCheckNonNullArgGoto(xml, error);

    if (conn->networkDriver && conn->networkDriver->networkUpdate) {
        int ret;
        ret = conn->networkDriver->networkUpdate(network, section, command,
                                                 parentIndex, xml, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10711 10712

error:
10713
    virDispatchError(network->conn);
10714
    return -1;
10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726
}

/**
 * virNetworkCreate:
 * @network: pointer to a defined network
 *
 * Create and start a defined network. If the call succeed the network
 * moves from the defined to the running networks pools.
 *
 * Returns 0 in case of success, -1 in case of error
 */
int
10727 10728
virNetworkCreate(virNetworkPtr network)
{
10729
    virConnectPtr conn;
10730
    VIR_DEBUG("network=%p", network);
10731

10732 10733
    virResetLastError();

10734
    if (!VIR_IS_CONNECTED_NETWORK(network)) {
10735
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10736
        virDispatchError(NULL);
10737
        return -1;
10738 10739 10740
    }
    conn = network->conn;
    if (conn->flags & VIR_CONNECT_RO) {
10741
        virLibNetworkError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
10742
        goto error;
10743 10744
    }

10745 10746
    if (conn->networkDriver && conn->networkDriver->networkCreate) {
        int ret;
10747
        ret = conn->networkDriver->networkCreate(network);
10748 10749 10750 10751
        if (ret < 0)
            goto error;
        return ret;
    }
10752

10753
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10754 10755

error:
10756
    virDispatchError(network->conn);
10757
    return -1;
10758 10759 10760 10761 10762 10763 10764
}

/**
 * virNetworkDestroy:
 * @network: a network object
 *
 * Destroy the network object. The running instance is shutdown if not down
10765 10766 10767
 * already and all resources used by it are given back to the hypervisor. This
 * does not free the associated virNetworkPtr object.
 * This function may require privileged access
10768 10769 10770 10771 10772 10773 10774
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virNetworkDestroy(virNetworkPtr network)
{
    virConnectPtr conn;
10775
    VIR_DEBUG("network=%p", network);
10776

10777 10778
    virResetLastError();

10779
    if (!VIR_IS_CONNECTED_NETWORK(network)) {
10780
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10781
        virDispatchError(NULL);
10782
        return -1;
10783 10784 10785 10786
    }

    conn = network->conn;
    if (conn->flags & VIR_CONNECT_RO) {
10787
        virLibNetworkError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
10788
        goto error;
10789 10790
    }

10791 10792
    if (conn->networkDriver && conn->networkDriver->networkDestroy) {
        int ret;
10793
        ret = conn->networkDriver->networkDestroy(network);
10794 10795 10796 10797
        if (ret < 0)
            goto error;
        return ret;
    }
10798

10799
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10800 10801

error:
10802
    virDispatchError(network->conn);
10803
    return -1;
10804 10805 10806 10807 10808 10809 10810 10811 10812 10813 10814 10815 10816 10817
}

/**
 * virNetworkFree:
 * @network: a network object
 *
 * Free the network object. The running instance is kept alive.
 * The data structure is freed and should not be used thereafter.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virNetworkFree(virNetworkPtr network)
{
10818
    VIR_DEBUG("network=%p", network);
10819

10820 10821 10822
    virResetLastError();

    if (!VIR_IS_CONNECTED_NETWORK(network)) {
10823
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10824
        virDispatchError(NULL);
10825
        return -1;
10826
    }
10827
    virObjectUnref(network);
10828
    return 0;
10829 10830
}

10831 10832
/**
 * virNetworkRef:
D
Daniel Veillard 已提交
10833
 * @network: the network to hold a reference on
10834 10835 10836 10837 10838 10839 10840 10841 10842 10843 10844
 *
 * Increment the reference count on the network. For each
 * additional call to this method, there shall be a corresponding
 * call to virNetworkFree to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * This method is typically useful for applications where multiple
 * threads are using a connection, and it is required that the
 * connection remain open until all threads have finished using
 * it. ie, each new thread using a network would increment
 * the reference count.
D
Daniel Veillard 已提交
10845 10846
 *
 * Returns 0 in case of success, -1 in case of failure.
10847 10848 10849 10850 10851
 */
int
virNetworkRef(virNetworkPtr network)
{
    if ((!VIR_IS_CONNECTED_NETWORK(network))) {
10852
        virLibConnError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10853
        virDispatchError(NULL);
10854
        return -1;
10855
    }
10856 10857
    VIR_DEBUG("network=%p refs=%d", network, network->object.refs);
    virObjectRef(network);
10858 10859 10860
    return 0;
}

10861 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872
/**
 * virNetworkGetName:
 * @network: a network object
 *
 * Get the public name for that network
 *
 * Returns a pointer to the name or NULL, the string need not be deallocated
 * its lifetime will be the same as the network object.
 */
const char *
virNetworkGetName(virNetworkPtr network)
{
10873
    VIR_DEBUG("network=%p", network);
10874

10875 10876
    virResetLastError();

10877
    if (!VIR_IS_NETWORK(network)) {
10878
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10879
        virDispatchError(NULL);
10880
        return NULL;
10881
    }
10882
    return network->name;
10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896
}

/**
 * virNetworkGetUUID:
 * @network: a network object
 * @uuid: pointer to a VIR_UUID_BUFLEN bytes array
 *
 * Get the UUID for a network
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virNetworkGetUUID(virNetworkPtr network, unsigned char *uuid)
{
10897
    VIR_DEBUG("network=%p, uuid=%p", network, uuid);
10898

10899 10900
    virResetLastError();

10901
    if (!VIR_IS_NETWORK(network)) {
10902
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10903
        virDispatchError(NULL);
10904
        return -1;
10905
    }
10906
    virCheckNonNullArgGoto(uuid, error);
10907 10908 10909

    memcpy(uuid, &network->uuid[0], VIR_UUID_BUFLEN);

10910
    return 0;
10911 10912

error:
10913
    virDispatchError(network->conn);
10914
    return -1;
10915 10916 10917 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930
}

/**
 * virNetworkGetUUIDString:
 * @network: a network object
 * @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
 *
 * Get the UUID for a network as string. For more information about
 * UUID see RFC4122.
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virNetworkGetUUIDString(virNetworkPtr network, char *buf)
{
    unsigned char uuid[VIR_UUID_BUFLEN];
10931
    VIR_DEBUG("network=%p, buf=%p", network, buf);
10932

10933 10934
    virResetLastError();

10935
    if (!VIR_IS_NETWORK(network)) {
10936
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10937
        virDispatchError(NULL);
10938
        return -1;
10939
    }
10940
    virCheckNonNullArgGoto(buf, error);
10941 10942

    if (virNetworkGetUUID(network, &uuid[0]))
10943
        goto error;
10944

10945
    virUUIDFormat(uuid, buf);
10946
    return 0;
10947 10948

error:
10949
    virDispatchError(network->conn);
10950
    return -1;
10951 10952 10953 10954 10955
}

/**
 * virNetworkGetXMLDesc:
 * @network: a network object
10956
 * @flags: bitwise-OR of virNetworkXMLFlags
10957 10958 10959 10960
 *
 * Provide an XML description of the network. The description may be reused
 * later to relaunch the network with virNetworkCreateXML().
 *
10961 10962 10963 10964 10965
 * Normally, if a network included a physical function, the output includes
 * all virtual functions tied to that physical interface.  If @flags includes
 * VIR_NETWORK_XML_INACTIVE, then the expansion of virtual interfaces is
 * not performed.
 *
10966 10967 10968 10969
 * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
 *         the caller must free() the returned value.
 */
char *
10970
virNetworkGetXMLDesc(virNetworkPtr network, unsigned int flags)
10971
{
10972
    virConnectPtr conn;
10973
    VIR_DEBUG("network=%p, flags=%x", network, flags);
10974

10975 10976 10977
    virResetLastError();

    if (!VIR_IS_CONNECTED_NETWORK(network)) {
10978
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
10979
        virDispatchError(NULL);
10980
        return NULL;
10981 10982
    }

10983 10984
    conn = network->conn;

10985
    if (conn->networkDriver && conn->networkDriver->networkGetXMLDesc) {
10986
        char *ret;
10987
        ret = conn->networkDriver->networkGetXMLDesc(network, flags);
10988 10989 10990 10991
        if (!ret)
            goto error;
        return ret;
    }
10992

10993
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
10994 10995

error:
10996
    virDispatchError(network->conn);
10997
    return NULL;
10998
}
10999 11000 11001 11002 11003

/**
 * virNetworkGetBridgeName:
 * @network: a network object
 *
11004
 * Provides a bridge interface name to which a domain may connect
11005 11006 11007 11008 11009 11010 11011 11012
 * a network interface in order to join the network.
 *
 * Returns a 0 terminated interface name, or NULL in case of error.
 *         the caller must free() the returned value.
 */
char *
virNetworkGetBridgeName(virNetworkPtr network)
{
11013
    virConnectPtr conn;
11014
    VIR_DEBUG("network=%p", network);
11015

11016 11017 11018
    virResetLastError();

    if (!VIR_IS_CONNECTED_NETWORK(network)) {
11019
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
11020
        virDispatchError(NULL);
11021
        return NULL;
11022 11023
    }

11024 11025
    conn = network->conn;

11026 11027
    if (conn->networkDriver && conn->networkDriver->networkGetBridgeName) {
        char *ret;
11028
        ret = conn->networkDriver->networkGetBridgeName(network);
11029 11030 11031 11032
        if (!ret)
            goto error;
        return ret;
    }
11033

11034
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
11035 11036

error:
11037
    virDispatchError(network->conn);
11038
    return NULL;
11039
}
11040 11041 11042 11043

/**
 * virNetworkGetAutostart:
 * @network: a network object
11044
 * @autostart: the value returned
11045
 *
11046
 * Provides a boolean value indicating whether the network
11047 11048 11049 11050 11051 11052 11053
 * configured to be automatically started when the host
 * machine boots.
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virNetworkGetAutostart(virNetworkPtr network,
11054 11055 11056
                       int *autostart)
{
    virConnectPtr conn;
11057
    VIR_DEBUG("network=%p, autostart=%p", network, autostart);
11058

11059 11060 11061
    virResetLastError();

    if (!VIR_IS_CONNECTED_NETWORK(network)) {
11062
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
11063
        virDispatchError(NULL);
11064
        return -1;
11065
    }
11066
    virCheckNonNullArgGoto(autostart, error);
11067

11068 11069
    conn = network->conn;

11070 11071
    if (conn->networkDriver && conn->networkDriver->networkGetAutostart) {
        int ret;
11072
        ret = conn->networkDriver->networkGetAutostart(network, autostart);
11073 11074 11075 11076
        if (ret < 0)
            goto error;
        return ret;
    }
11077

11078
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
11079 11080

error:
11081
    virDispatchError(network->conn);
11082
    return -1;
11083 11084 11085 11086 11087
}

/**
 * virNetworkSetAutostart:
 * @network: a network object
11088
 * @autostart: whether the network should be automatically started 0 or 1
11089 11090 11091 11092 11093 11094 11095 11096
 *
 * Configure the network to be automatically started
 * when the host machine boots.
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virNetworkSetAutostart(virNetworkPtr network,
11097 11098 11099
                       int autostart)
{
    virConnectPtr conn;
11100
    VIR_DEBUG("network=%p, autostart=%d", network, autostart);
11101

11102 11103 11104
    virResetLastError();

    if (!VIR_IS_CONNECTED_NETWORK(network)) {
11105
        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
11106
        virDispatchError(NULL);
11107
        return -1;
11108 11109
    }

11110
    if (network->conn->flags & VIR_CONNECT_RO) {
11111
        virLibNetworkError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
11112
        goto error;
11113 11114
    }

11115 11116
    conn = network->conn;

11117 11118
    if (conn->networkDriver && conn->networkDriver->networkSetAutostart) {
        int ret;
11119
        ret = conn->networkDriver->networkSetAutostart(network, autostart);
11120 11121 11122 11123
        if (ret < 0)
            goto error;
        return ret;
    }
11124

11125
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
11126 11127

error:
11128
    virDispatchError(network->conn);
11129
    return -1;
11130
}
11131

D
Daniel Veillard 已提交
11132 11133
/**
 * virInterfaceGetConnect:
L
Laine Stump 已提交
11134
 * @iface: pointer to an interface
D
Daniel Veillard 已提交
11135 11136 11137 11138 11139 11140 11141 11142 11143 11144 11145 11146
 *
 * Provides the connection pointer associated with an interface.  The
 * reference counter on the connection is not increased by this
 * call.
 *
 * WARNING: When writing libvirt bindings in other languages, do
 * not use this function.  Instead, store the connection and
 * the interface object together.
 *
 * Returns the virConnectPtr or NULL in case of failure.
 */
virConnectPtr
11147
virInterfaceGetConnect(virInterfacePtr iface)
D
Daniel Veillard 已提交
11148
{
11149
    VIR_DEBUG("iface=%p", iface);
D
Daniel Veillard 已提交
11150 11151 11152

    virResetLastError();

11153
    if (!VIR_IS_CONNECTED_INTERFACE(iface)) {
11154
        virLibInterfaceError(VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
11155
        virDispatchError(NULL);
D
Daniel Veillard 已提交
11156 11157
        return NULL;
    }
11158
    return iface->conn;
D
Daniel Veillard 已提交
11159 11160
}

11161 11162 11163 11164 11165 11166 11167 11168 11169 11170 11171 11172 11173 11174 11175 11176 11177 11178 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 11194 11195 11196 11197 11198 11199 11200 11201 11202 11203 11204 11205 11206
/**
 * virConnectListAllInterfaces:
 * @conn: Pointer to the hypervisor connection.
 * @ifaces: Pointer to a variable to store the array containing the interface
 *          objects or NULL if the list is not required (just returns number
 *          of interfaces).
 * @flags: bitwise-OR of virConnectListAllInterfacesFlags.
 *
 * Collect the list of interfaces, and allocate an array to store those
 * objects. This API solves the race inherent between virConnectListInterfaces
 * and virConnectListDefinedInterfaces.
 *
 * Normally, all interfaces are returned; however, @flags can be used to
 * filter the results for a smaller list of targeted interfaces.  The valid
 * flags are divided into groups, where each group contains bits that
 * describe mutually exclusive attributes of a interface, and where all bits
 * within a group describe all possible interfaces.
 *
 * The only group of @flags is VIR_CONNECT_LIST_INTERFACES_ACTIVE (up) and
 * VIR_CONNECT_LIST_INTERFACES_INACTIVE (down) to filter the interfaces by state.
 *
 * Returns the number of interfaces found or -1 and sets @ifaces to  NULL in case
 * of error.  On success, the array stored into @ifaces is guaranteed to have an
 * extra allocated element set to NULL but not included in the return count,
 * to make iteration easier.  The caller is responsible for calling
 * virStorageInterfaceFree() on each array element, then calling free() on @ifaces.
 */
int
virConnectListAllInterfaces(virConnectPtr conn,
                            virInterfacePtr **ifaces,
                            unsigned int flags)
{
    VIR_DEBUG("conn=%p, ifaces=%p, flags=%x", conn, ifaces, flags);

    virResetLastError();

    if (ifaces)
        *ifaces = NULL;

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->interfaceDriver &&
11207
        conn->interfaceDriver->connectListAllInterfaces) {
11208
        int ret;
11209
        ret = conn->interfaceDriver->connectListAllInterfaces(conn, ifaces, flags);
11210 11211 11212 11213 11214 11215 11216 11217 11218 11219 11220 11221
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

D
Daniel Veillard 已提交
11222 11223 11224 11225
/**
 * virConnectNumOfInterfaces:
 * @conn: pointer to the hypervisor connection
 *
11226
 * Provides the number of active interfaces on the physical host.
D
Daniel Veillard 已提交
11227
 *
11228
 * Returns the number of active interfaces found or -1 in case of error
D
Daniel Veillard 已提交
11229 11230 11231 11232
 */
int
virConnectNumOfInterfaces(virConnectPtr conn)
{
11233
    VIR_DEBUG("conn=%p", conn);
D
Daniel Veillard 已提交
11234 11235 11236 11237

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
11238
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
11239
        virDispatchError(NULL);
11240
        return -1;
D
Daniel Veillard 已提交
11241 11242
    }

11243
    if (conn->interfaceDriver && conn->interfaceDriver->connectNumOfInterfaces) {
D
Daniel Veillard 已提交
11244
        int ret;
11245
        ret = conn->interfaceDriver->connectNumOfInterfaces(conn);
D
Daniel Veillard 已提交
11246 11247 11248 11249 11250
        if (ret < 0)
            goto error;
        return ret;
    }

11251
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
D
Daniel Veillard 已提交
11252 11253

error:
11254
    virDispatchError(conn);
D
Daniel Veillard 已提交
11255 11256 11257 11258 11259 11260 11261 11262 11263
    return -1;
}

/**
 * virConnectListInterfaces:
 * @conn: pointer to the hypervisor connection
 * @names: array to collect the list of names of interfaces
 * @maxnames: size of @names
 *
11264 11265
 * Collect the list of active physical host interfaces,
 * and store their names in @names
D
Daniel Veillard 已提交
11266
 *
11267 11268 11269 11270 11271 11272
 * For more control over the results, see virConnectListAllInterfaces().
 *
 * Returns the number of interfaces found or -1 in case of error.  Note that
 * this command is inherently racy; a interface can be started between a call
 * to virConnectNumOfInterfaces() and this call; you are only guaranteed that
 * all currently active interfaces were listed if the return is less than
J
John Ferlan 已提交
11273
 * @maxnames. The client must call free() on each returned name.
D
Daniel Veillard 已提交
11274 11275 11276 11277
 */
int
virConnectListInterfaces(virConnectPtr conn, char **const names, int maxnames)
{
11278
    VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
D
Daniel Veillard 已提交
11279 11280 11281 11282

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
11283
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
11284
        virDispatchError(NULL);
11285
        return -1;
D
Daniel Veillard 已提交
11286 11287
    }

11288 11289
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
D
Daniel Veillard 已提交
11290

11291
    if (conn->interfaceDriver && conn->interfaceDriver->connectListInterfaces) {
D
Daniel Veillard 已提交
11292
        int ret;
11293
        ret = conn->interfaceDriver->connectListInterfaces(conn, names, maxnames);
D
Daniel Veillard 已提交
11294 11295 11296 11297 11298
        if (ret < 0)
            goto error;
        return ret;
    }

11299
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
D
Daniel Veillard 已提交
11300 11301

error:
11302
    virDispatchError(conn);
D
Daniel Veillard 已提交
11303 11304 11305
    return -1;
}

11306 11307 11308 11309 11310 11311 11312 11313 11314 11315 11316
/**
 * virConnectNumOfDefinedInterfaces:
 * @conn: pointer to the hypervisor connection
 *
 * Provides the number of defined (inactive) interfaces on the physical host.
 *
 * Returns the number of defined interface found or -1 in case of error
 */
int
virConnectNumOfDefinedInterfaces(virConnectPtr conn)
{
11317
    VIR_DEBUG("conn=%p", conn);
11318 11319 11320 11321

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
11322
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
11323
        virDispatchError(NULL);
11324
        return -1;
11325 11326
    }

11327
    if (conn->interfaceDriver && conn->interfaceDriver->connectNumOfDefinedInterfaces) {
11328
        int ret;
11329
        ret = conn->interfaceDriver->connectNumOfDefinedInterfaces(conn);
11330 11331 11332 11333 11334
        if (ret < 0)
            goto error;
        return ret;
    }

11335
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
11336 11337

error:
11338
    virDispatchError(conn);
11339 11340 11341 11342 11343 11344 11345 11346 11347 11348 11349 11350
    return -1;
}

/**
 * virConnectListDefinedInterfaces:
 * @conn: pointer to the hypervisor connection
 * @names: array to collect the list of names of interfaces
 * @maxnames: size of @names
 *
 * Collect the list of defined (inactive) physical host interfaces,
 * and store their names in @names.
 *
11351 11352 11353 11354 11355 11356 11357
 * For more control over the results, see virConnectListAllInterfaces().
 *
 * Returns the number of names provided in the array or -1 in case of error.
 * Note that this command is inherently racy; a interface can be defined between
 * a call to virConnectNumOfDefinedInterfaces() and this call; you are only
 * guaranteed that all currently defined interfaces were listed if the return
 * is less than @maxnames.  The client must call free() on each returned name.
11358 11359 11360 11361 11362 11363
 */
int
virConnectListDefinedInterfaces(virConnectPtr conn,
                                char **const names,
                                int maxnames)
{
11364
    VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
11365 11366 11367 11368

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
11369
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
11370
        virDispatchError(NULL);
11371
        return -1;
11372 11373
    }

11374 11375
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
11376

11377
    if (conn->interfaceDriver && conn->interfaceDriver->connectListDefinedInterfaces) {
11378
        int ret;
11379
        ret = conn->interfaceDriver->connectListDefinedInterfaces(conn, names, maxnames);
11380 11381 11382 11383 11384
        if (ret < 0)
            goto error;
        return ret;
    }

11385
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
11386 11387

error:
11388
    virDispatchError(conn);
11389 11390 11391
    return -1;
}

D
Daniel Veillard 已提交
11392 11393 11394 11395 11396 11397 11398 11399 11400 11401 11402 11403 11404
/**
 * virInterfaceLookupByName:
 * @conn: pointer to the hypervisor connection
 * @name: name for the interface
 *
 * Try to lookup an interface on the given hypervisor based on its name.
 *
 * Returns a new interface object or NULL in case of failure.  If the
 * interface cannot be found, then VIR_ERR_NO_INTERFACE error is raised.
 */
virInterfacePtr
virInterfaceLookupByName(virConnectPtr conn, const char *name)
{
11405
    VIR_DEBUG("conn=%p, name=%s", conn, name);
D
Daniel Veillard 已提交
11406 11407 11408 11409

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
11410
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
11411
        virDispatchError(NULL);
11412
        return NULL;
D
Daniel Veillard 已提交
11413
    }
11414
    virCheckNonNullArgGoto(name, error);
D
Daniel Veillard 已提交
11415 11416 11417

    if (conn->interfaceDriver && conn->interfaceDriver->interfaceLookupByName) {
        virInterfacePtr ret;
11418
        ret = conn->interfaceDriver->interfaceLookupByName(conn, name);
D
Daniel Veillard 已提交
11419 11420 11421 11422 11423
        if (!ret)
            goto error;
        return ret;
    }

11424
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
D
Daniel Veillard 已提交
11425 11426

error:
11427
    virDispatchError(conn);
D
Daniel Veillard 已提交
11428 11429 11430 11431 11432 11433 11434 11435 11436 11437 11438 11439 11440 11441 11442 11443
    return NULL;
}

/**
 * virInterfaceLookupByMACString:
 * @conn: pointer to the hypervisor connection
 * @macstr: the MAC for the interface (null-terminated ASCII format)
 *
 * Try to lookup an interface on the given hypervisor based on its MAC.
 *
 * Returns a new interface object or NULL in case of failure.  If the
 * interface cannot be found, then VIR_ERR_NO_INTERFACE error is raised.
 */
virInterfacePtr
virInterfaceLookupByMACString(virConnectPtr conn, const char *macstr)
{
11444
    VIR_DEBUG("conn=%p, macstr=%s", conn, macstr);
D
Daniel Veillard 已提交
11445 11446 11447 11448

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
11449
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
11450
        virDispatchError(NULL);
11451
        return NULL;
D
Daniel Veillard 已提交
11452
    }
11453
    virCheckNonNullArgGoto(macstr, error);
D
Daniel Veillard 已提交
11454 11455 11456

    if (conn->interfaceDriver && conn->interfaceDriver->interfaceLookupByMACString) {
        virInterfacePtr ret;
11457
        ret = conn->interfaceDriver->interfaceLookupByMACString(conn, macstr);
D
Daniel Veillard 已提交
11458 11459 11460 11461 11462
        if (!ret)
            goto error;
        return ret;
    }

11463
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
D
Daniel Veillard 已提交
11464 11465

error:
11466
    virDispatchError(conn);
D
Daniel Veillard 已提交
11467 11468 11469 11470 11471
    return NULL;
}

/**
 * virInterfaceGetName:
L
Laine Stump 已提交
11472
 * @iface: an interface object
D
Daniel Veillard 已提交
11473 11474 11475 11476 11477 11478 11479
 *
 * Get the public name for that interface
 *
 * Returns a pointer to the name or NULL, the string need not be deallocated
 * its lifetime will be the same as the interface object.
 */
const char *
11480
virInterfaceGetName(virInterfacePtr iface)
D
Daniel Veillard 已提交
11481
{
11482
    VIR_DEBUG("iface=%p", iface);
D
Daniel Veillard 已提交
11483 11484 11485

    virResetLastError();

11486
    if (!VIR_IS_INTERFACE(iface)) {
11487
        virLibInterfaceError(VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
11488
        virDispatchError(NULL);
11489
        return NULL;
D
Daniel Veillard 已提交
11490
    }
11491
    return iface->name;
D
Daniel Veillard 已提交
11492 11493 11494 11495
}

/**
 * virInterfaceGetMACString:
L
Laine Stump 已提交
11496
 * @iface: an interface object
D
Daniel Veillard 已提交
11497
 *
L
Laine Stump 已提交
11498
 * Get the MAC for an interface as string. For more information about
D
Daniel Veillard 已提交
11499 11500 11501 11502 11503 11504 11505
 * MAC see RFC4122.
 *
 * Returns a pointer to the MAC address (in null-terminated ASCII
 * format) or NULL, the string need not be deallocated its lifetime
 * will be the same as the interface object.
 */
const char *
11506
virInterfaceGetMACString(virInterfacePtr iface)
D
Daniel Veillard 已提交
11507
{
11508
    VIR_DEBUG("iface=%p", iface);
D
Daniel Veillard 已提交
11509 11510 11511

    virResetLastError();

11512
    if (!VIR_IS_INTERFACE(iface)) {
11513
        virLibInterfaceError(VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
11514
        virDispatchError(NULL);
11515
        return NULL;
D
Daniel Veillard 已提交
11516
    }
11517
    return iface->mac;
D
Daniel Veillard 已提交
11518 11519 11520 11521
}

/**
 * virInterfaceGetXMLDesc:
L
Laine Stump 已提交
11522
 * @iface: an interface object
11523
 * @flags: bitwise-OR of extraction flags. Current valid bits:
11524 11525 11526 11527
 *
 *      VIR_INTERFACE_XML_INACTIVE - return the static configuration,
 *                                   suitable for use redefining the
 *                                   interface via virInterfaceDefineXML()
D
Daniel Veillard 已提交
11528
 *
11529 11530 11531 11532 11533
 * Provide an XML description of the interface. If
 * VIR_INTERFACE_XML_INACTIVE is set, the description may be reused
 * later to redefine the interface with virInterfaceDefineXML(). If it
 * is not set, the ip address and netmask will be the current live
 * setting of the interface, not the settings from the config files.
D
Daniel Veillard 已提交
11534 11535 11536 11537 11538
 *
 * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
 *         the caller must free() the returned value.
 */
char *
11539
virInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags)
D
Daniel Veillard 已提交
11540 11541
{
    virConnectPtr conn;
11542
    VIR_DEBUG("iface=%p, flags=%x", iface, flags);
D
Daniel Veillard 已提交
11543 11544 11545

    virResetLastError();

11546
    if (!VIR_IS_CONNECTED_INTERFACE(iface)) {
11547
        virLibInterfaceError(VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
11548
        virDispatchError(NULL);
11549
        return NULL;
D
Daniel Veillard 已提交
11550 11551
    }

11552
    conn = iface->conn;
D
Daniel Veillard 已提交
11553 11554 11555

    if (conn->interfaceDriver && conn->interfaceDriver->interfaceGetXMLDesc) {
        char *ret;
11556
        ret = conn->interfaceDriver->interfaceGetXMLDesc(iface, flags);
D
Daniel Veillard 已提交
11557 11558 11559 11560 11561
        if (!ret)
            goto error;
        return ret;
    }

11562
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
D
Daniel Veillard 已提交
11563 11564

error:
11565
    virDispatchError(iface->conn);
D
Daniel Veillard 已提交
11566 11567 11568 11569 11570 11571 11572
    return NULL;
}

/**
 * virInterfaceDefineXML:
 * @conn: pointer to the hypervisor connection
 * @xml: the XML description for the interface, preferably in UTF-8
11573
 * @flags: extra flags; not used yet, so callers should always pass 0
D
Daniel Veillard 已提交
11574
 *
11575 11576 11577 11578 11579 11580 11581 11582 11583 11584 11585
 * Define an interface (or modify existing interface configuration).
 *
 * Normally this change in the interface configuration is immediately
 * permanent/persistent, but if virInterfaceChangeBegin() has been
 * previously called (i.e. if an interface config transaction is
 * open), the new interface definition will only become permanent if
 * virInterfaceChangeCommit() is called prior to the next reboot of
 * the system running libvirtd. Prior to that time, it can be
 * explicitly removed using virInterfaceChangeRollback(), or will be
 * automatically removed during the next reboot of the system running
 * libvirtd.
D
Daniel Veillard 已提交
11586 11587 11588 11589 11590 11591
 *
 * Returns NULL in case of error, a pointer to the interface otherwise
 */
virInterfacePtr
virInterfaceDefineXML(virConnectPtr conn, const char *xml, unsigned int flags)
{
11592
    VIR_DEBUG("conn=%p, xml=%s, flags=%x", conn, xml, flags);
D
Daniel Veillard 已提交
11593 11594 11595 11596

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
11597
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
11598
        virDispatchError(NULL);
11599
        return NULL;
D
Daniel Veillard 已提交
11600 11601
    }
    if (conn->flags & VIR_CONNECT_RO) {
11602
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
D
Daniel Veillard 已提交
11603 11604
        goto error;
    }
11605
    virCheckNonNullArgGoto(xml, error);
D
Daniel Veillard 已提交
11606 11607 11608

    if (conn->interfaceDriver && conn->interfaceDriver->interfaceDefineXML) {
        virInterfacePtr ret;
11609
        ret = conn->interfaceDriver->interfaceDefineXML(conn, xml, flags);
D
Daniel Veillard 已提交
11610 11611 11612 11613 11614
        if (!ret)
            goto error;
        return ret;
    }

11615
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
D
Daniel Veillard 已提交
11616 11617

error:
11618
    virDispatchError(conn);
D
Daniel Veillard 已提交
11619 11620 11621 11622 11623
    return NULL;
}

/**
 * virInterfaceUndefine:
11624
 * @iface: pointer to a defined interface
D
Daniel Veillard 已提交
11625 11626 11627 11628
 *
 * Undefine an interface, ie remove it from the config.
 * This does not free the associated virInterfacePtr object.
 *
11629 11630 11631 11632 11633 11634 11635 11636 11637 11638
 * Normally this change in the interface configuration is
 * permanent/persistent, but if virInterfaceChangeBegin() has been
 * previously called (i.e. if an interface config transaction is
 * open), the removal of the interface definition will only become
 * permanent if virInterfaceChangeCommit() is called prior to the next
 * reboot of the system running libvirtd. Prior to that time, the
 * definition can be explicitly restored using
 * virInterfaceChangeRollback(), or will be automatically restored
 * during the next reboot of the system running libvirtd.
 *
D
Daniel Veillard 已提交
11639 11640 11641
 * Returns 0 in case of success, -1 in case of error
 */
int
11642
virInterfaceUndefine(virInterfacePtr iface) {
D
Daniel Veillard 已提交
11643
    virConnectPtr conn;
11644
    VIR_DEBUG("iface=%p", iface);
D
Daniel Veillard 已提交
11645 11646 11647

    virResetLastError();

11648
    if (!VIR_IS_CONNECTED_INTERFACE(iface)) {
11649
        virLibInterfaceError(VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
11650
        virDispatchError(NULL);
11651
        return -1;
D
Daniel Veillard 已提交
11652
    }
11653
    conn = iface->conn;
D
Daniel Veillard 已提交
11654
    if (conn->flags & VIR_CONNECT_RO) {
11655
        virLibInterfaceError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
D
Daniel Veillard 已提交
11656 11657 11658 11659 11660
        goto error;
    }

    if (conn->interfaceDriver && conn->interfaceDriver->interfaceUndefine) {
        int ret;
11661
        ret = conn->interfaceDriver->interfaceUndefine(iface);
D
Daniel Veillard 已提交
11662 11663 11664 11665 11666
        if (ret < 0)
            goto error;
        return ret;
    }

11667
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
D
Daniel Veillard 已提交
11668 11669

error:
11670
    virDispatchError(iface->conn);
D
Daniel Veillard 已提交
11671 11672 11673 11674 11675
    return -1;
}

/**
 * virInterfaceCreate:
11676
 * @iface: pointer to a defined interface
11677
 * @flags: extra flags; not used yet, so callers should always pass 0
D
Daniel Veillard 已提交
11678
 *
11679
 * Activate an interface (i.e. call "ifup").
D
Daniel Veillard 已提交
11680
 *
11681 11682 11683 11684 11685
 * If there was an open network config transaction at the time this
 * interface was defined (that is, if virInterfaceChangeBegin() had
 * been called), the interface will be brought back down (and then
 * undefined) if virInterfaceChangeRollback() is called.
p *
D
Daniel Veillard 已提交
11686 11687 11688
 * Returns 0 in case of success, -1 in case of error
 */
int
11689
virInterfaceCreate(virInterfacePtr iface, unsigned int flags)
D
Daniel Veillard 已提交
11690 11691
{
    virConnectPtr conn;
11692
    VIR_DEBUG("iface=%p, flags=%x", iface, flags);
D
Daniel Veillard 已提交
11693 11694 11695

    virResetLastError();

11696
    if (!VIR_IS_CONNECTED_INTERFACE(iface)) {
11697
        virLibInterfaceError(VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
11698
        virDispatchError(NULL);
11699
        return -1;
D
Daniel Veillard 已提交
11700
    }
11701
    conn = iface->conn;
D
Daniel Veillard 已提交
11702
    if (conn->flags & VIR_CONNECT_RO) {
11703
        virLibInterfaceError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
D
Daniel Veillard 已提交
11704 11705 11706 11707 11708
        goto error;
    }

    if (conn->interfaceDriver && conn->interfaceDriver->interfaceCreate) {
        int ret;
11709
        ret = conn->interfaceDriver->interfaceCreate(iface, flags);
D
Daniel Veillard 已提交
11710 11711 11712 11713 11714
        if (ret < 0)
            goto error;
        return ret;
    }

11715
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
D
Daniel Veillard 已提交
11716 11717

error:
11718
    virDispatchError(iface->conn);
D
Daniel Veillard 已提交
11719 11720 11721 11722 11723
    return -1;
}

/**
 * virInterfaceDestroy:
11724
 * @iface: an interface object
11725
 * @flags: extra flags; not used yet, so callers should always pass 0
D
Daniel Veillard 已提交
11726 11727 11728 11729 11730
 *
 * deactivate an interface (ie call "ifdown")
 * This does not remove the interface from the config, and
 * does not free the associated virInterfacePtr object.
 *
11731 11732 11733 11734 11735 11736 11737

 * If there is an open network config transaction at the time this
 * interface is destroyed (that is, if virInterfaceChangeBegin() had
 * been called), and if the interface is later undefined and then
 * virInterfaceChangeRollback() is called, the restoral of the
 * interface definition will also bring the interface back up.
 *
D
Daniel Veillard 已提交
11738 11739 11740
 * Returns 0 in case of success and -1 in case of failure.
 */
int
11741
virInterfaceDestroy(virInterfacePtr iface, unsigned int flags)
D
Daniel Veillard 已提交
11742 11743
{
    virConnectPtr conn;
11744
    VIR_DEBUG("iface=%p, flags=%x", iface, flags);
D
Daniel Veillard 已提交
11745 11746 11747

    virResetLastError();

11748
    if (!VIR_IS_CONNECTED_INTERFACE(iface)) {
11749
        virLibInterfaceError(VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
11750
        virDispatchError(NULL);
11751
        return -1;
D
Daniel Veillard 已提交
11752 11753
    }

11754
    conn = iface->conn;
D
Daniel Veillard 已提交
11755
    if (conn->flags & VIR_CONNECT_RO) {
11756
        virLibInterfaceError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
D
Daniel Veillard 已提交
11757 11758 11759 11760 11761
        goto error;
    }

    if (conn->interfaceDriver && conn->interfaceDriver->interfaceDestroy) {
        int ret;
11762
        ret = conn->interfaceDriver->interfaceDestroy(iface, flags);
D
Daniel Veillard 已提交
11763 11764 11765 11766 11767
        if (ret < 0)
            goto error;
        return ret;
    }

11768
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
D
Daniel Veillard 已提交
11769 11770

error:
11771
    virDispatchError(iface->conn);
D
Daniel Veillard 已提交
11772 11773 11774 11775 11776
    return -1;
}

/**
 * virInterfaceRef:
11777
 * @iface: the interface to hold a reference on
D
Daniel Veillard 已提交
11778 11779 11780 11781 11782 11783 11784 11785 11786
 *
 * Increment the reference count on the interface. For each
 * additional call to this method, there shall be a corresponding
 * call to virInterfaceFree to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * This method is typically useful for applications where multiple
 * threads are using a connection, and it is required that the
 * connection remain open until all threads have finished using
L
Laine Stump 已提交
11787
 * it. ie, each new thread using an interface would increment
D
Daniel Veillard 已提交
11788 11789 11790 11791 11792
 * the reference count.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
11793
virInterfaceRef(virInterfacePtr iface)
D
Daniel Veillard 已提交
11794
{
11795
    if ((!VIR_IS_CONNECTED_INTERFACE(iface))) {
11796
        virLibConnError(VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
11797
        virDispatchError(NULL);
11798
        return -1;
D
Daniel Veillard 已提交
11799
    }
11800 11801
    VIR_DEBUG("iface=%p refs=%d", iface, iface->object.refs);
    virObjectRef(iface);
D
Daniel Veillard 已提交
11802 11803 11804 11805 11806
    return 0;
}

/**
 * virInterfaceFree:
L
Laine Stump 已提交
11807
 * @iface: an interface object
D
Daniel Veillard 已提交
11808 11809 11810 11811 11812 11813 11814
 *
 * Free the interface object. The interface itself is unaltered.
 * The data structure is freed and should not be used thereafter.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
11815
virInterfaceFree(virInterfacePtr iface)
D
Daniel Veillard 已提交
11816
{
11817
    VIR_DEBUG("iface=%p", iface);
D
Daniel Veillard 已提交
11818 11819 11820

    virResetLastError();

11821
    if (!VIR_IS_CONNECTED_INTERFACE(iface)) {
11822
        virLibInterfaceError(VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
11823
        virDispatchError(NULL);
11824
        return -1;
D
Daniel Veillard 已提交
11825
    }
11826
    virObjectUnref(iface);
11827
    return 0;
D
Daniel Veillard 已提交
11828 11829
}

11830 11831 11832
/**
 * virInterfaceChangeBegin:
 * @conn: pointer to hypervisor connection
11833
 * @flags: extra flags; not used yet, so callers should always pass 0
11834
 *
Y
Yuri Chornoivan 已提交
11835
 * This function creates a restore point to which one can return
11836 11837
 * later by calling virInterfaceChangeRollback(). This function should
 * be called before any transaction with interface configuration.
Y
Yuri Chornoivan 已提交
11838
 * Once it is known that a new configuration works, it can be committed via
11839 11840 11841 11842 11843 11844 11845 11846 11847 11848 11849
 * virInterfaceChangeCommit(), which frees the restore point.
 *
 * If virInterfaceChangeBegin() is called when a transaction is
 * already opened, this function will fail, and a
 * VIR_ERR_INVALID_OPERATION will be logged.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virInterfaceChangeBegin(virConnectPtr conn, unsigned int flags)
{
11850
    VIR_DEBUG("conn=%p, flags=%x", conn, flags);
11851 11852 11853 11854 11855 11856 11857 11858 11859 11860 11861 11862 11863 11864 11865 11866 11867 11868 11869 11870 11871 11872 11873 11874 11875 11876 11877 11878 11879 11880 11881 11882

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->flags & VIR_CONNECT_RO) {
        virLibInterfaceError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->interfaceDriver && conn->interfaceDriver->interfaceChangeBegin) {
        int ret;
        ret = conn->interfaceDriver->interfaceChangeBegin(conn, flags);
        if (ret < 0)
           goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

/**
 * virInterfaceChangeCommit:
 * @conn: pointer to hypervisor connection
11883
 * @flags: extra flags; not used yet, so callers should always pass 0
11884 11885 11886 11887 11888 11889 11890 11891 11892 11893 11894 11895 11896
 *
 * This commits the changes made to interfaces and frees the restore point
 * created by virInterfaceChangeBegin().
 *
 * If virInterfaceChangeCommit() is called when a transaction is not
 * opened, this function will fail, and a VIR_ERR_INVALID_OPERATION
 * will be logged.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virInterfaceChangeCommit(virConnectPtr conn, unsigned int flags)
{
11897
    VIR_DEBUG("conn=%p, flags=%x", conn, flags);
11898 11899 11900 11901 11902 11903 11904 11905 11906 11907 11908 11909 11910 11911 11912 11913 11914 11915 11916 11917 11918 11919 11920 11921 11922 11923 11924 11925 11926 11927 11928 11929

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->flags & VIR_CONNECT_RO) {
        virLibInterfaceError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->interfaceDriver && conn->interfaceDriver->interfaceChangeCommit) {
        int ret;
        ret = conn->interfaceDriver->interfaceChangeCommit(conn, flags);
        if (ret < 0)
           goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

/**
 * virInterfaceChangeRollback:
 * @conn: pointer to hypervisor connection
11930
 * @flags: extra flags; not used yet, so callers should always pass 0
11931 11932 11933 11934 11935 11936 11937 11938 11939 11940 11941 11942 11943
 *
 * This cancels changes made to interfaces settings by restoring previous
 * state created by virInterfaceChangeBegin().
 *
 * If virInterfaceChangeRollback() is called when a transaction is not
 * opened, this function will fail, and a VIR_ERR_INVALID_OPERATION
 * will be logged.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virInterfaceChangeRollback(virConnectPtr conn, unsigned int flags)
{
11944
    VIR_DEBUG("conn=%p, flags=%x", conn, flags);
11945 11946 11947 11948 11949 11950 11951 11952 11953 11954 11955 11956 11957 11958 11959 11960 11961 11962 11963 11964 11965 11966 11967 11968 11969 11970 11971 11972 11973 11974

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->flags & VIR_CONNECT_RO) {
        virLibInterfaceError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->interfaceDriver &&
        conn->interfaceDriver->interfaceChangeRollback) {
        int ret;
        ret = conn->interfaceDriver->interfaceChangeRollback(conn, flags);
        if (ret < 0)
           goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

11975 11976 11977

/**
 * virStoragePoolGetConnect:
11978
 * @pool: pointer to a pool
11979 11980 11981 11982 11983 11984 11985 11986 11987 11988 11989 11990
 *
 * Provides the connection pointer associated with a storage pool.  The
 * reference counter on the connection is not increased by this
 * call.
 *
 * WARNING: When writing libvirt bindings in other languages, do
 * not use this function.  Instead, store the connection and
 * the pool object together.
 *
 * Returns the virConnectPtr or NULL in case of failure.
 */
virConnectPtr
11991
virStoragePoolGetConnect(virStoragePoolPtr pool)
11992
{
11993
    VIR_DEBUG("pool=%p", pool);
11994

11995 11996
    virResetLastError();

11997
    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
11998
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
11999
        virDispatchError(NULL);
12000 12001 12002 12003 12004
        return NULL;
    }
    return pool->conn;
}

12005 12006 12007 12008 12009 12010 12011 12012 12013 12014 12015 12016 12017 12018 12019 12020 12021 12022 12023 12024 12025 12026 12027 12028 12029 12030 12031 12032 12033 12034 12035 12036 12037 12038 12039 12040 12041 12042 12043 12044 12045 12046 12047 12048 12049 12050 12051 12052 12053 12054 12055 12056 12057 12058 12059 12060 12061 12062 12063 12064 12065 12066 12067 12068 12069 12070 12071 12072 12073
/**
 * virConnectListAllStoragePools:
 * @conn: Pointer to the hypervisor connection.
 * @pools: Pointer to a variable to store the array containing storage pool
 *         objects or NULL if the list is not required (just returns number
 *         of pools).
 * @flags: bitwise-OR of virConnectListAllStoragePoolsFlags.
 *
 * Collect the list of storage pools, and allocate an array to store those
 * objects. This API solves the race inherent between
 * virConnectListStoragePools and virConnectListDefinedStoragePools.
 *
 * Normally, all storage pools are returned; however, @flags can be used to
 * filter the results for a smaller list of targeted pools.  The valid
 * flags are divided into groups, where each group contains bits that
 * describe mutually exclusive attributes of a pool, and where all bits
 * within a group describe all possible pools.
 *
 * The first group of @flags is VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE (online)
 * and VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE (offline) to filter the pools
 * by state.
 *
 * The second group of @flags is VIR_CONNECT_LIST_STORAGE_POOLS_PERSITENT
 * (defined) and VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT (running but not
 * defined), to filter the pools by whether they have persistent config or not.
 *
 * The third group of @flags is VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART
 * and VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART, to filter the pools by
 * whether they are marked as autostart or not.
 *
 * The last group of @flags is provided to filter the pools by the types,
 * the flags include:
 * VIR_CONNECT_LIST_STORAGE_POOLS_DIR
 * VIR_CONNECT_LIST_STORAGE_POOLS_FS
 * VIR_CONNECT_LIST_STORAGE_POOLS_NETFS
 * VIR_CONNECT_LIST_STORAGE_POOLS_LOGICAL
 * VIR_CONNECT_LIST_STORAGE_POOLS_DISK
 * VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI
 * VIR_CONNECT_LIST_STORAGE_POOLS_SCSI
 * VIR_CONNECT_LIST_STORAGE_POOLS_MPATH
 * VIR_CONNECT_LIST_STORAGE_POOLS_RBD
 * VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG
 *
 * Returns the number of storage pools found or -1 and sets @pools to
 * NULL in case of error.  On success, the array stored into @pools is
 * guaranteed to have an extra allocated element set to NULL but not included
 * in the return count, to make iteration easier.  The caller is responsible
 * for calling virStoragePoolFree() on each array element, then calling
 * free() on @pools.
 */
int
virConnectListAllStoragePools(virConnectPtr conn,
                              virStoragePoolPtr **pools,
                              unsigned int flags)
{
    VIR_DEBUG("conn=%p, pools=%p, flags=%x", conn, pools, flags);

    virResetLastError();

    if (pools)
        *pools = NULL;

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->storageDriver &&
12074
        conn->storageDriver->connectListAllStoragePools) {
12075
        int ret;
12076
        ret = conn->storageDriver->connectListAllStoragePools(conn, pools, flags);
12077 12078 12079 12080 12081 12082 12083 12084 12085 12086 12087 12088
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

12089 12090 12091 12092 12093 12094 12095 12096 12097
/**
 * virConnectNumOfStoragePools:
 * @conn: pointer to hypervisor connection
 *
 * Provides the number of active storage pools
 *
 * Returns the number of pools found, or -1 on error
 */
int
O
Osier Yang 已提交
12098
virConnectNumOfStoragePools(virConnectPtr conn)
12099
{
12100
    VIR_DEBUG("conn=%p", conn);
12101

12102 12103
    virResetLastError();

12104
    if (!VIR_IS_CONNECT(conn)) {
12105
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12106
        virDispatchError(NULL);
12107
        return -1;
12108 12109
    }

12110
    if (conn->storageDriver && conn->storageDriver->connectNumOfStoragePools) {
12111
        int ret;
12112
        ret = conn->storageDriver->connectNumOfStoragePools(conn);
12113 12114 12115 12116
        if (ret < 0)
            goto error;
        return ret;
    }
12117

12118
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12119 12120

error:
12121
    virDispatchError(conn);
12122 12123 12124 12125 12126 12127 12128 12129 12130
    return -1;
}

/**
 * virConnectListStoragePools:
 * @conn: pointer to hypervisor connection
 * @names: array of char * to fill with pool names (allocated by caller)
 * @maxnames: size of the names array
 *
12131 12132 12133 12134 12135
 * Provides the list of names of active storage pools up to maxnames.
 * If there are more than maxnames, the remaining names will be silently
 * ignored.
 *
 * For more control over the results, see virConnectListAllStoragePools().
12136
 *
12137 12138 12139 12140
 * Returns the number of pools found or -1 in case of error.  Note that
 * this command is inherently racy; a pool can be started between a call to
 * virConnectNumOfStoragePools() and this call; you are only guaranteed
 * that all currently active pools were listed if the return is less than
J
John Ferlan 已提交
12141
 * @maxnames. The client must call free() on each returned name.
12142 12143
 */
int
O
Osier Yang 已提交
12144 12145 12146
virConnectListStoragePools(virConnectPtr conn,
                           char **const names,
                           int maxnames)
12147
{
12148
    VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
12149

12150 12151
    virResetLastError();

12152
    if (!VIR_IS_CONNECT(conn)) {
12153
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12154
        virDispatchError(NULL);
12155
        return -1;
12156 12157
    }

12158 12159
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
12160

12161
    if (conn->storageDriver && conn->storageDriver->connectListStoragePools) {
12162
        int ret;
12163
        ret = conn->storageDriver->connectListStoragePools(conn, names, maxnames);
12164 12165 12166 12167
        if (ret < 0)
            goto error;
        return ret;
    }
12168

12169
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12170

12171
error:
12172
    virDispatchError(conn);
12173
    return -1;
12174 12175 12176 12177 12178 12179 12180 12181 12182 12183 12184 12185 12186 12187
}


/**
 * virConnectNumOfDefinedStoragePools:
 * @conn: pointer to hypervisor connection
 *
 * Provides the number of inactive storage pools
 *
 * Returns the number of pools found, or -1 on error
 */
int
virConnectNumOfDefinedStoragePools(virConnectPtr conn)
{
12188
    VIR_DEBUG("conn=%p", conn);
12189

12190 12191
    virResetLastError();

12192
    if (!VIR_IS_CONNECT(conn)) {
12193
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12194
        virDispatchError(NULL);
12195
        return -1;
12196 12197
    }

12198
    if (conn->storageDriver && conn->storageDriver->connectNumOfDefinedStoragePools) {
12199
        int ret;
12200
        ret = conn->storageDriver->connectNumOfDefinedStoragePools(conn);
12201 12202 12203 12204
        if (ret < 0)
            goto error;
        return ret;
    }
12205

12206
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12207 12208

error:
12209
    virDispatchError(conn);
12210 12211 12212 12213 12214 12215 12216 12217 12218 12219
    return -1;
}


/**
 * virConnectListDefinedStoragePools:
 * @conn: pointer to hypervisor connection
 * @names: array of char * to fill with pool names (allocated by caller)
 * @maxnames: size of the names array
 *
12220 12221 12222
 * Provides the list of names of inactive storage pools up to maxnames.
 * If there are more than maxnames, the remaining names will be silently
 * ignored.
12223
 *
12224 12225 12226 12227 12228 12229 12230
 * For more control over the results, see virConnectListAllStoragePools().
 *
 * Returns the number of names provided in the array or -1 in case of error.
 * Note that this command is inherently racy; a pool can be defined between
 * a call to virConnectNumOfDefinedStoragePools() and this call; you are only
 * guaranteed that all currently defined pools were listed if the return
 * is less than @maxnames.  The client must call free() on each returned name.
12231 12232 12233 12234 12235 12236
 */
int
virConnectListDefinedStoragePools(virConnectPtr conn,
                                  char **const names,
                                  int maxnames)
{
12237
    VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
12238

12239 12240
    virResetLastError();

12241
    if (!VIR_IS_CONNECT(conn)) {
12242
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12243
        virDispatchError(NULL);
12244
        return -1;
12245 12246
    }

12247 12248
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
12249

12250
    if (conn->storageDriver && conn->storageDriver->connectListDefinedStoragePools) {
12251
        int ret;
12252
        ret = conn->storageDriver->connectListDefinedStoragePools(conn, names, maxnames);
12253 12254 12255 12256
        if (ret < 0)
            goto error;
        return ret;
    }
12257

12258
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12259 12260

error:
12261
    virDispatchError(conn);
12262 12263 12264 12265
    return -1;
}


12266 12267 12268 12269 12270
/**
 * virConnectFindStoragePoolSources:
 * @conn: pointer to hypervisor connection
 * @type: type of storage pool sources to discover
 * @srcSpec: XML document specifying discovery source
12271
 * @flags: extra flags; not used yet, so callers should always pass 0
12272 12273 12274 12275 12276 12277 12278 12279 12280 12281 12282 12283 12284 12285 12286 12287 12288 12289 12290 12291 12292
 *
 * Talks to a storage backend and attempts to auto-discover the set of
 * available storage pool sources. e.g. For iSCSI this would be a set of
 * iSCSI targets. For NFS this would be a list of exported paths.  The
 * srcSpec (optional for some storage pool types, e.g. local ones) is
 * an instance of the storage pool's source element specifying where
 * to look for the pools.
 *
 * srcSpec is not required for some types (e.g., those querying
 * local storage resources only)
 *
 * Returns an xml document consisting of a SourceList element
 * containing a source document appropriate to the given pool
 * type for each discovered source.
 */
char *
virConnectFindStoragePoolSources(virConnectPtr conn,
                                 const char *type,
                                 const char *srcSpec,
                                 unsigned int flags)
{
12293
    VIR_DEBUG("conn=%p, type=%s, src=%s, flags=%x",
O
Osier Yang 已提交
12294
              conn, NULLSTR(type), NULLSTR(srcSpec), flags);
12295 12296 12297

    virResetLastError();

12298
    if (!VIR_IS_CONNECT(conn)) {
12299
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12300
        virDispatchError(NULL);
12301
        return NULL;
12302
    }
12303
    virCheckNonNullArgGoto(type, error);
12304

12305
    if (conn->flags & VIR_CONNECT_RO) {
12306
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
12307
        goto error;
12308 12309
    }

12310
    if (conn->storageDriver && conn->storageDriver->connectFindStoragePoolSources) {
12311
        char *ret;
12312
        ret = conn->storageDriver->connectFindStoragePoolSources(conn, type, srcSpec, flags);
12313 12314 12315 12316
        if (!ret)
            goto error;
        return ret;
    }
12317

12318
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12319 12320

error:
12321
    virDispatchError(conn);
12322 12323 12324 12325
    return NULL;
}


12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338
/**
 * virStoragePoolLookupByName:
 * @conn: pointer to hypervisor connection
 * @name: name of pool to fetch
 *
 * Fetch a storage pool based on its unique name
 *
 * Returns a virStoragePoolPtr object, or NULL if no matching pool is found
 */
virStoragePoolPtr
virStoragePoolLookupByName(virConnectPtr conn,
                           const char *name)
{
12339
    VIR_DEBUG("conn=%p, name=%s", conn, name);
12340

12341 12342
    virResetLastError();

12343
    if (!VIR_IS_CONNECT(conn)) {
12344
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12345
        virDispatchError(NULL);
12346
        return NULL;
12347
    }
12348
    virCheckNonNullArgGoto(name, error);
12349

12350
    if (conn->storageDriver && conn->storageDriver->storagePoolLookupByName) {
12351
        virStoragePoolPtr ret;
12352
        ret = conn->storageDriver->storagePoolLookupByName(conn, name);
12353 12354 12355 12356
        if (!ret)
            goto error;
        return ret;
    }
12357

12358
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12359 12360

error:
12361
    virDispatchError(conn);
12362 12363 12364 12365 12366 12367 12368 12369 12370 12371 12372 12373 12374 12375 12376 12377 12378
    return NULL;
}


/**
 * virStoragePoolLookupByUUID:
 * @conn: pointer to hypervisor connection
 * @uuid: globally unique id of pool to fetch
 *
 * Fetch a storage pool based on its globally unique id
 *
 * Returns a virStoragePoolPtr object, or NULL if no matching pool is found
 */
virStoragePoolPtr
virStoragePoolLookupByUUID(virConnectPtr conn,
                           const unsigned char *uuid)
{
12379
    VIR_UUID_DEBUG(conn, uuid);
12380

12381 12382
    virResetLastError();

12383
    if (!VIR_IS_CONNECT(conn)) {
12384
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12385
        virDispatchError(NULL);
12386
        return NULL;
12387
    }
12388
    virCheckNonNullArgGoto(uuid, error);
12389

12390
    if (conn->storageDriver && conn->storageDriver->storagePoolLookupByUUID) {
12391
        virStoragePoolPtr ret;
12392
        ret = conn->storageDriver->storagePoolLookupByUUID(conn, uuid);
12393 12394 12395 12396
        if (!ret)
            goto error;
        return ret;
    }
12397

12398
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12399

12400
error:
12401
    virDispatchError(conn);
12402
    return NULL;
12403 12404 12405 12406 12407 12408 12409 12410 12411 12412 12413 12414 12415 12416
}


/**
 * virStoragePoolLookupByUUIDString:
 * @conn: pointer to hypervisor connection
 * @uuidstr: globally unique id of pool to fetch
 *
 * Fetch a storage pool based on its globally unique id
 *
 * Returns a virStoragePoolPtr object, or NULL if no matching pool is found
 */
virStoragePoolPtr
virStoragePoolLookupByUUIDString(virConnectPtr conn,
12417
                                 const char *uuidstr)
12418 12419
{
    unsigned char uuid[VIR_UUID_BUFLEN];
12420
    VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
12421

12422 12423
    virResetLastError();

12424
    if (!VIR_IS_CONNECT(conn)) {
12425
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12426
        virDispatchError(NULL);
12427
        return NULL;
12428
    }
12429
    virCheckNonNullArgGoto(uuidstr, error);
12430 12431

    if (virUUIDParse(uuidstr, uuid) < 0) {
12432 12433 12434
        virReportInvalidArg(uuidstr,
                            _("uuidstr in %s must be a valid UUID"),
                            __FUNCTION__);
12435
        goto error;
12436 12437 12438
    }

    return virStoragePoolLookupByUUID(conn, uuid);
12439 12440

error:
12441
    virDispatchError(conn);
12442
    return NULL;
12443 12444 12445 12446 12447 12448 12449 12450 12451 12452 12453 12454 12455 12456
}


/**
 * virStoragePoolLookupByVolume:
 * @vol: pointer to storage volume
 *
 * Fetch a storage pool which contains a particular volume
 *
 * Returns a virStoragePoolPtr object, or NULL if no matching pool is found
 */
virStoragePoolPtr
virStoragePoolLookupByVolume(virStorageVolPtr vol)
{
12457
    VIR_DEBUG("vol=%p", vol);
12458

12459 12460 12461
    virResetLastError();

    if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
12462
        virLibConnError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
12463
        virDispatchError(NULL);
12464
        return NULL;
12465 12466
    }

12467
    if (vol->conn->storageDriver && vol->conn->storageDriver->storagePoolLookupByVolume) {
12468
        virStoragePoolPtr ret;
12469
        ret = vol->conn->storageDriver->storagePoolLookupByVolume(vol);
12470 12471 12472 12473
        if (!ret)
            goto error;
        return ret;
    }
12474

12475
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12476

12477
error:
12478
    virDispatchError(vol->conn);
12479
    return NULL;
12480 12481 12482 12483 12484 12485
}

/**
 * virStoragePoolCreateXML:
 * @conn: pointer to hypervisor connection
 * @xmlDesc: XML description for new pool
12486
 * @flags: extra flags; not used yet, so callers should always pass 0
12487 12488
 *
 * Create a new storage based on its XML description. The
D
Daniel Veillard 已提交
12489
 * pool is not persistent, so its definition will disappear
12490 12491 12492 12493 12494 12495 12496 12497 12498
 * when it is destroyed, or if the host is restarted
 *
 * Returns a virStoragePoolPtr object, or NULL if creation failed
 */
virStoragePoolPtr
virStoragePoolCreateXML(virConnectPtr conn,
                        const char *xmlDesc,
                        unsigned int flags)
{
E
Eric Blake 已提交
12499
    VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags);
12500

12501 12502
    virResetLastError();

12503
    if (!VIR_IS_CONNECT(conn)) {
12504
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12505
        virDispatchError(NULL);
12506
        return NULL;
12507
    }
12508 12509
    virCheckNonNullArgGoto(xmlDesc, error);

12510
    if (conn->flags & VIR_CONNECT_RO) {
12511
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
12512
        goto error;
12513 12514
    }

12515
    if (conn->storageDriver && conn->storageDriver->storagePoolCreateXML) {
12516
        virStoragePoolPtr ret;
12517
        ret = conn->storageDriver->storagePoolCreateXML(conn, xmlDesc, flags);
12518 12519 12520 12521
        if (!ret)
            goto error;
        return ret;
    }
12522

12523
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12524 12525

error:
12526
    virDispatchError(conn);
12527 12528 12529 12530 12531 12532 12533
    return NULL;
}

/**
 * virStoragePoolDefineXML:
 * @conn: pointer to hypervisor connection
 * @xml: XML description for new pool
12534
 * @flags: extra flags; not used yet, so callers should always pass 0
12535 12536
 *
 * Define a new inactive storage pool based on its XML description. The
D
Daniel Veillard 已提交
12537
 * pool is persistent, until explicitly undefined.
12538 12539 12540 12541 12542 12543 12544 12545
 *
 * Returns a virStoragePoolPtr object, or NULL if creation failed
 */
virStoragePoolPtr
virStoragePoolDefineXML(virConnectPtr conn,
                        const char *xml,
                        unsigned int flags)
{
E
Eric Blake 已提交
12546
    VIR_DEBUG("conn=%p, xml=%s, flags=%x", conn, xml, flags);
12547

12548 12549
    virResetLastError();

12550
    if (!VIR_IS_CONNECT(conn)) {
12551
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
12552
        virDispatchError(NULL);
12553
        return NULL;
12554 12555
    }
    if (conn->flags & VIR_CONNECT_RO) {
12556
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
12557
        goto error;
12558
    }
12559
    virCheckNonNullArgGoto(xml, error);
12560

12561
    if (conn->storageDriver && conn->storageDriver->storagePoolDefineXML) {
12562
        virStoragePoolPtr ret;
12563
        ret = conn->storageDriver->storagePoolDefineXML(conn, xml, flags);
12564 12565 12566 12567
        if (!ret)
            goto error;
        return ret;
    }
12568

12569
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12570

12571
error:
12572
    virDispatchError(conn);
12573
    return NULL;
12574 12575 12576 12577 12578
}

/**
 * virStoragePoolBuild:
 * @pool: pointer to storage pool
12579
 * @flags: bitwise-OR of virStoragePoolBuildFlags
O
Osier Yang 已提交
12580 12581 12582
 *
 * Currently only filesystem pool accepts flags VIR_STORAGE_POOL_BUILD_OVERWRITE
 * and VIR_STORAGE_POOL_BUILD_NO_OVERWRITE.
12583 12584 12585 12586 12587 12588 12589 12590 12591 12592
 *
 * Build the underlying storage pool
 *
 * Returns 0 on success, or -1 upon failure
 */
int
virStoragePoolBuild(virStoragePoolPtr pool,
                    unsigned int flags)
{
    virConnectPtr conn;
12593
    VIR_DEBUG("pool=%p, flags=%x", pool, flags);
12594

12595 12596
    virResetLastError();

12597
    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
12598
        virLibStoragePoolError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
12599
        virDispatchError(NULL);
12600
        return -1;
12601 12602 12603
    }
    conn = pool->conn;
    if (conn->flags & VIR_CONNECT_RO) {
12604
        virLibStoragePoolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
12605
        goto error;
12606 12607
    }

12608
    if (conn->storageDriver && conn->storageDriver->storagePoolBuild) {
12609
        int ret;
12610
        ret = conn->storageDriver->storagePoolBuild(pool, flags);
12611 12612 12613 12614
        if (ret < 0)
            goto error;
        return ret;
    }
12615

12616
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12617

12618
error:
12619
    virDispatchError(pool->conn);
12620
    return -1;
12621 12622 12623 12624 12625 12626 12627 12628 12629
}


/**
 * virStoragePoolUndefine:
 * @pool: pointer to storage pool
 *
 * Undefine an inactive storage pool
 *
12630
 * Returns 0 on success, -1 on failure
12631 12632 12633 12634 12635
 */
int
virStoragePoolUndefine(virStoragePoolPtr pool)
{
    virConnectPtr conn;
12636
    VIR_DEBUG("pool=%p", pool);
12637

12638 12639
    virResetLastError();

12640
    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
12641
        virLibStoragePoolError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
12642
        virDispatchError(NULL);
12643
        return -1;
12644 12645 12646
    }
    conn = pool->conn;
    if (conn->flags & VIR_CONNECT_RO) {
12647
        virLibStoragePoolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
12648
        goto error;
12649 12650
    }

12651
    if (conn->storageDriver && conn->storageDriver->storagePoolUndefine) {
12652
        int ret;
12653
        ret = conn->storageDriver->storagePoolUndefine(pool);
12654 12655 12656 12657
        if (ret < 0)
            goto error;
        return ret;
    }
12658

12659
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12660

12661
error:
12662
    virDispatchError(pool->conn);
12663
    return -1;
12664 12665 12666 12667 12668 12669
}


/**
 * virStoragePoolCreate:
 * @pool: pointer to storage pool
12670
 * @flags: extra flags; not used yet, so callers should always pass 0
12671 12672 12673 12674 12675 12676 12677 12678 12679 12680
 *
 * Starts an inactive storage pool
 *
 * Returns 0 on success, or -1 if it could not be started
 */
int
virStoragePoolCreate(virStoragePoolPtr pool,
                     unsigned int flags)
{
    virConnectPtr conn;
E
Eric Blake 已提交
12681
    VIR_DEBUG("pool=%p, flags=%x", pool, flags);
12682

12683 12684
    virResetLastError();

12685
    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
12686
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
12687
        virDispatchError(NULL);
12688
        return -1;
12689 12690 12691
    }
    conn = pool->conn;
    if (conn->flags & VIR_CONNECT_RO) {
12692
        virLibStoragePoolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
12693
        goto error;
12694 12695
    }

12696
    if (conn->storageDriver && conn->storageDriver->storagePoolCreate) {
12697
        int ret;
12698
        ret = conn->storageDriver->storagePoolCreate(pool, flags);
12699 12700 12701 12702
        if (ret < 0)
            goto error;
        return ret;
    }
12703

12704
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12705

12706
error:
12707
    virDispatchError(pool->conn);
12708
    return -1;
12709 12710 12711 12712 12713 12714 12715 12716 12717 12718 12719 12720 12721 12722 12723 12724 12725 12726 12727
}


/**
 * virStoragePoolDestroy:
 * @pool: pointer to storage pool
 *
 * Destroy an active storage pool. This will deactivate the
 * pool on the host, but keep any persistent config associated
 * with it. If it has a persistent config it can later be
 * restarted with virStoragePoolCreate(). This does not free
 * the associated virStoragePoolPtr object.
 *
 * Returns 0 on success, or -1 if it could not be destroyed
 */
int
virStoragePoolDestroy(virStoragePoolPtr pool)
{
    virConnectPtr conn;
12728
    VIR_DEBUG("pool=%p", pool);
12729

12730 12731
    virResetLastError();

12732
    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
12733
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
12734
        virDispatchError(NULL);
12735
        return -1;
12736 12737 12738 12739
    }

    conn = pool->conn;
    if (conn->flags & VIR_CONNECT_RO) {
12740
        virLibStoragePoolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
12741
        goto error;
12742 12743
    }

12744
    if (conn->storageDriver && conn->storageDriver->storagePoolDestroy) {
12745
        int ret;
12746
        ret = conn->storageDriver->storagePoolDestroy(pool);
12747 12748 12749 12750
        if (ret < 0)
            goto error;
        return ret;
    }
12751

12752
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12753 12754

error:
12755
    virDispatchError(pool->conn);
12756 12757 12758 12759 12760 12761
    return -1;
}

/**
 * virStoragePoolDelete:
 * @pool: pointer to storage pool
12762
 * @flags: bitwise-OR of virStoragePoolDeleteFlags
12763 12764 12765 12766 12767 12768 12769 12770 12771 12772 12773 12774
 *
 * Delete the underlying pool resources. This is
 * a non-recoverable operation. The virStoragePoolPtr object
 * itself is not free'd.
 *
 * Returns 0 on success, or -1 if it could not be obliterate
 */
int
virStoragePoolDelete(virStoragePoolPtr pool,
                     unsigned int flags)
{
    virConnectPtr conn;
12775
    VIR_DEBUG("pool=%p, flags=%x", pool, flags);
12776

12777 12778
    virResetLastError();

12779
    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
12780
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
12781
        virDispatchError(NULL);
12782
        return -1;
12783 12784 12785 12786
    }

    conn = pool->conn;
    if (conn->flags & VIR_CONNECT_RO) {
12787
        virLibStoragePoolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
12788
        goto error;
12789 12790
    }

12791
    if (conn->storageDriver && conn->storageDriver->storagePoolDelete) {
12792
        int ret;
12793
        ret = conn->storageDriver->storagePoolDelete(pool, flags);
12794 12795 12796 12797
        if (ret < 0)
            goto error;
        return ret;
    }
12798

12799
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12800 12801

error:
12802
    virDispatchError(pool->conn);
12803 12804 12805 12806 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817 12818
    return -1;
}


/**
 * virStoragePoolFree:
 * @pool: pointer to storage pool
 *
 * Free a storage pool object, releasing all memory associated with
 * it. Does not change the state of the pool on the host.
 *
 * Returns 0 on success, or -1 if it could not be free'd.
 */
int
virStoragePoolFree(virStoragePoolPtr pool)
{
12819
    VIR_DEBUG("pool=%p", pool);
12820

12821 12822 12823
    virResetLastError();

    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
12824
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
12825
        virDispatchError(NULL);
12826
        return -1;
12827
    }
12828
    virObjectUnref(pool);
12829
    return 0;
12830 12831 12832 12833

}


12834 12835
/**
 * virStoragePoolRef:
D
Daniel Veillard 已提交
12836
 * @pool: the pool to hold a reference on
12837 12838 12839 12840 12841 12842 12843 12844 12845 12846 12847
 *
 * Increment the reference count on the pool. For each
 * additional call to this method, there shall be a corresponding
 * call to virStoragePoolFree to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * This method is typically useful for applications where multiple
 * threads are using a connection, and it is required that the
 * connection remain open until all threads have finished using
 * it. ie, each new thread using a pool would increment
 * the reference count.
D
Daniel Veillard 已提交
12848 12849
 *
 * Returns 0 in case of success, -1 in case of failure.
12850 12851 12852 12853 12854
 */
int
virStoragePoolRef(virStoragePoolPtr pool)
{
    if ((!VIR_IS_CONNECTED_STORAGE_POOL(pool))) {
12855
        virLibConnError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
12856
        virDispatchError(NULL);
12857
        return -1;
12858
    }
12859 12860
    VIR_DEBUG("pool=%p refs=%d", pool, pool->object.refs);
    virObjectRef(pool);
12861 12862 12863
    return 0;
}

12864 12865 12866
/**
 * virStoragePoolRefresh:
 * @pool: pointer to storage pool
12867
 * @flags: extra flags; not used yet, so callers should always pass 0
12868 12869 12870 12871 12872
 *
 * Request that the pool refresh its list of volumes. This may
 * involve communicating with a remote server, and/or initializing
 * new devices at the OS layer
 *
12873
 * Returns 0 if the volume list was refreshed, -1 on failure
12874 12875 12876 12877 12878 12879
 */
int
virStoragePoolRefresh(virStoragePoolPtr pool,
                      unsigned int flags)
{
    virConnectPtr conn;
E
Eric Blake 已提交
12880
    VIR_DEBUG("pool=%p, flags=%x", pool, flags);
12881

12882 12883
    virResetLastError();

12884
    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
12885
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
12886
        virDispatchError(NULL);
12887
        return -1;
12888 12889 12890 12891
    }

    conn = pool->conn;
    if (conn->flags & VIR_CONNECT_RO) {
12892
        virLibStoragePoolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
12893
        goto error;
12894 12895
    }

12896
    if (conn->storageDriver && conn->storageDriver->storagePoolRefresh) {
12897
        int ret;
12898
        ret = conn->storageDriver->storagePoolRefresh(pool, flags);
12899 12900 12901 12902
        if (ret < 0)
            goto error;
        return ret;
    }
12903

12904
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
12905 12906

error:
12907
    virDispatchError(pool->conn);
12908 12909 12910 12911 12912 12913 12914 12915 12916 12917
    return -1;
}


/**
 * virStoragePoolGetName:
 * @pool: pointer to storage pool
 *
 * Fetch the locally unique name of the storage pool
 *
12918
 * Returns the name of the pool, or NULL on error
12919 12920 12921 12922
 */
const char*
virStoragePoolGetName(virStoragePoolPtr pool)
{
12923
    VIR_DEBUG("pool=%p", pool);
12924

12925 12926
    virResetLastError();

12927
    if (!VIR_IS_STORAGE_POOL(pool)) {
12928
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
12929
        virDispatchError(NULL);
12930
        return NULL;
12931
    }
12932
    return pool->name;
12933 12934 12935 12936 12937 12938 12939 12940 12941 12942
}


/**
 * virStoragePoolGetUUID:
 * @pool: pointer to storage pool
 * @uuid: buffer of VIR_UUID_BUFLEN bytes in size
 *
 * Fetch the globally unique ID of the storage pool
 *
12943
 * Returns 0 on success, or -1 on error;
12944 12945 12946 12947 12948
 */
int
virStoragePoolGetUUID(virStoragePoolPtr pool,
                      unsigned char *uuid)
{
12949
    VIR_DEBUG("pool=%p, uuid=%p", pool, uuid);
12950

12951 12952
    virResetLastError();

12953
    if (!VIR_IS_STORAGE_POOL(pool)) {
12954
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
12955
        virDispatchError(NULL);
12956
        return -1;
12957
    }
12958
    virCheckNonNullArgGoto(uuid, error);
12959 12960 12961

    memcpy(uuid, &pool->uuid[0], VIR_UUID_BUFLEN);

12962
    return 0;
12963

12964
error:
12965
    virDispatchError(pool->conn);
12966
    return -1;
12967 12968 12969 12970 12971 12972 12973 12974 12975
}

/**
 * virStoragePoolGetUUIDString:
 * @pool: pointer to storage pool
 * @buf: buffer of VIR_UUID_STRING_BUFLEN bytes in size
 *
 * Fetch the globally unique ID of the storage pool as a string
 *
12976
 * Returns 0 on success, or -1 on error;
12977 12978 12979 12980 12981 12982
 */
int
virStoragePoolGetUUIDString(virStoragePoolPtr pool,
                            char *buf)
{
    unsigned char uuid[VIR_UUID_BUFLEN];
12983
    VIR_DEBUG("pool=%p, buf=%p", pool, buf);
12984

12985 12986
    virResetLastError();

12987
    if (!VIR_IS_STORAGE_POOL(pool)) {
12988
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
12989
        virDispatchError(NULL);
12990
        return -1;
12991
    }
12992
    virCheckNonNullArgGoto(buf, error);
12993 12994

    if (virStoragePoolGetUUID(pool, &uuid[0]))
12995
        goto error;
12996 12997

    virUUIDFormat(uuid, buf);
12998
    return 0;
12999

13000
error:
13001
    virDispatchError(pool->conn);
13002
    return -1;
13003 13004 13005 13006 13007 13008 13009 13010 13011 13012 13013
}


/**
 * virStoragePoolGetInfo:
 * @pool: pointer to storage pool
 * @info: pointer at which to store info
 *
 * Get volatile information about the storage pool
 * such as free space / usage summary
 *
13014
 * Returns 0 on success, or -1 on failure.
13015 13016 13017 13018 13019 13020
 */
int
virStoragePoolGetInfo(virStoragePoolPtr pool,
                      virStoragePoolInfoPtr info)
{
    virConnectPtr conn;
13021
    VIR_DEBUG("pool=%p, info=%p", pool, info);
13022

13023 13024
    virResetLastError();

13025
    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
13026
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
13027
        virDispatchError(NULL);
13028
        return -1;
13029
    }
13030
    virCheckNonNullArgGoto(info, error);
13031 13032 13033 13034 13035

    memset(info, 0, sizeof(virStoragePoolInfo));

    conn = pool->conn;

13036
    if (conn->storageDriver->storagePoolGetInfo) {
13037
        int ret;
13038
        ret = conn->storageDriver->storagePoolGetInfo(pool, info);
13039 13040 13041 13042
        if (ret < 0)
            goto error;
        return ret;
    }
13043

13044
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13045

13046
error:
13047
    virDispatchError(pool->conn);
13048
    return -1;
13049 13050 13051 13052 13053 13054
}


/**
 * virStoragePoolGetXMLDesc:
 * @pool: pointer to storage pool
13055
 * @flags: bitwise-OR of virStorageXMLFlags
13056 13057 13058 13059 13060
 *
 * Fetch an XML document describing all aspects of the
 * storage pool. This is suitable for later feeding back
 * into the virStoragePoolCreateXML method.
 *
13061
 * Returns a XML document, or NULL on error
13062 13063 13064 13065 13066 13067
 */
char *
virStoragePoolGetXMLDesc(virStoragePoolPtr pool,
                         unsigned int flags)
{
    virConnectPtr conn;
13068
    VIR_DEBUG("pool=%p, flags=%x", pool, flags);
13069

13070 13071 13072
    virResetLastError();

    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
13073
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
13074
        virDispatchError(NULL);
13075
        return NULL;
13076 13077 13078 13079
    }

    conn = pool->conn;

13080
    if (conn->storageDriver && conn->storageDriver->storagePoolGetXMLDesc) {
13081
        char *ret;
13082
        ret = conn->storageDriver->storagePoolGetXMLDesc(pool, flags);
13083 13084 13085 13086
        if (!ret)
            goto error;
        return ret;
    }
13087

13088
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13089

13090
error:
13091
    virDispatchError(pool->conn);
13092
    return NULL;
13093 13094 13095 13096 13097 13098 13099 13100 13101 13102 13103
}


/**
 * virStoragePoolGetAutostart:
 * @pool: pointer to storage pool
 * @autostart: location in which to store autostart flag
 *
 * Fetches the value of the autostart flag, which determines
 * whether the pool is automatically started at boot time
 *
13104
 * Returns 0 on success, -1 on failure
13105 13106 13107 13108 13109 13110
 */
int
virStoragePoolGetAutostart(virStoragePoolPtr pool,
                           int *autostart)
{
    virConnectPtr conn;
13111
    VIR_DEBUG("pool=%p, autostart=%p", pool, autostart);
13112

13113 13114 13115
    virResetLastError();

    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
13116
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
13117
        virDispatchError(NULL);
13118
        return -1;
13119
    }
13120
    virCheckNonNullArgGoto(autostart, error);
13121 13122 13123

    conn = pool->conn;

13124
    if (conn->storageDriver && conn->storageDriver->storagePoolGetAutostart) {
13125
        int ret;
13126
        ret = conn->storageDriver->storagePoolGetAutostart(pool, autostart);
13127 13128 13129 13130
        if (ret < 0)
            goto error;
        return ret;
    }
13131

13132
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13133 13134

error:
13135
    virDispatchError(pool->conn);
13136 13137 13138 13139 13140 13141 13142 13143 13144 13145 13146
    return -1;
}


/**
 * virStoragePoolSetAutostart:
 * @pool: pointer to storage pool
 * @autostart: new flag setting
 *
 * Sets the autostart flag
 *
13147
 * Returns 0 on success, -1 on failure
13148 13149 13150 13151 13152 13153
 */
int
virStoragePoolSetAutostart(virStoragePoolPtr pool,
                           int autostart)
{
    virConnectPtr conn;
13154
    VIR_DEBUG("pool=%p, autostart=%d", pool, autostart);
13155

13156 13157 13158
    virResetLastError();

    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
13159
        virLibStoragePoolError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
13160
        virDispatchError(NULL);
13161
        return -1;
13162 13163
    }

13164
    if (pool->conn->flags & VIR_CONNECT_RO) {
13165
        virLibStoragePoolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
13166
        goto error;
13167 13168
    }

13169 13170
    conn = pool->conn;

13171
    if (conn->storageDriver && conn->storageDriver->storagePoolSetAutostart) {
13172
        int ret;
13173
        ret = conn->storageDriver->storagePoolSetAutostart(pool, autostart);
13174 13175 13176 13177
        if (ret < 0)
            goto error;
        return ret;
    }
13178

13179
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13180 13181

error:
13182
    virDispatchError(pool->conn);
13183 13184 13185
    return -1;
}

13186 13187 13188 13189 13190 13191 13192 13193 13194 13195 13196 13197 13198 13199 13200 13201 13202 13203 13204 13205 13206 13207 13208 13209 13210 13211 13212 13213 13214 13215 13216 13217 13218 13219
/**
 * virStoragePoolListAllVolumes:
 * @pool: Pointer to storage pool
 * @vols: Pointer to a variable to store the array containing storage volume
 *        objects or NULL if the list is not required (just returns number
 *        of volumes).
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Collect the list of storage volumes, and allocate an array to store those
 * objects.
 *
 * Returns the number of storage volumes found or -1 and sets @vols to
 * NULL in case of error.  On success, the array stored into @vols is
 * guaranteed to have an extra allocated element set to NULL but not included
 * in the return count, to make iteration easier.  The caller is responsible
 * for calling virStorageVolFree() on each array element, then calling
 * free() on @vols.
 */
int
virStoragePoolListAllVolumes(virStoragePoolPtr pool,
                             virStorageVolPtr **vols,
                             unsigned int flags)
{
    VIR_DEBUG("pool=%p, vols=%p, flags=%x", pool, vols, flags);

    virResetLastError();

    if (!VIR_IS_STORAGE_POOL(pool)) {
        virLibConnError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (pool->conn->storageDriver &&
13220
        pool->conn->storageDriver->storagePoolListAllVolumes) {
13221
        int ret;
13222
        ret = pool->conn->storageDriver->storagePoolListAllVolumes(pool, vols, flags);
13223 13224 13225 13226 13227 13228 13229 13230 13231 13232 13233
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(pool->conn);
    return -1;
}
13234 13235 13236 13237 13238 13239 13240 13241 13242 13243 13244 13245

/**
 * virStoragePoolNumOfVolumes:
 * @pool: pointer to storage pool
 *
 * Fetch the number of storage volumes within a pool
 *
 * Returns the number of storage pools, or -1 on failure
 */
int
virStoragePoolNumOfVolumes(virStoragePoolPtr pool)
{
13246
    VIR_DEBUG("pool=%p", pool);
13247

13248 13249
    virResetLastError();

13250
    if (!VIR_IS_STORAGE_POOL(pool)) {
13251
        virLibConnError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
13252
        virDispatchError(NULL);
13253
        return -1;
13254 13255
    }

13256
    if (pool->conn->storageDriver && pool->conn->storageDriver->storagePoolNumOfVolumes) {
13257
        int ret;
13258
        ret = pool->conn->storageDriver->storagePoolNumOfVolumes(pool);
13259 13260 13261 13262
        if (ret < 0)
            goto error;
        return ret;
    }
13263

13264
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13265 13266

error:
13267
    virDispatchError(pool->conn);
13268 13269 13270 13271 13272 13273 13274 13275 13276 13277 13278 13279 13280
    return -1;
}


/**
 * virStoragePoolListVolumes:
 * @pool: pointer to storage pool
 * @names: array in which to storage volume names
 * @maxnames: size of names array
 *
 * Fetch list of storage volume names, limiting to
 * at most maxnames.
 *
13281 13282
 * To list the volume objects directly, see virStoragePoolListAllVolumes().
 *
13283 13284 13285 13286 13287 13288 13289
 * Returns the number of names fetched, or -1 on error
 */
int
virStoragePoolListVolumes(virStoragePoolPtr pool,
                          char **const names,
                          int maxnames)
{
13290
    VIR_DEBUG("pool=%p, names=%p, maxnames=%d", pool, names, maxnames);
13291

13292 13293
    virResetLastError();

13294
    if (!VIR_IS_STORAGE_POOL(pool)) {
13295
        virLibConnError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
13296
        virDispatchError(NULL);
13297
        return -1;
13298 13299
    }

13300 13301
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
13302

13303
    if (pool->conn->storageDriver && pool->conn->storageDriver->storagePoolListVolumes) {
13304
        int ret;
13305
        ret = pool->conn->storageDriver->storagePoolListVolumes(pool, names, maxnames);
13306 13307 13308 13309
        if (ret < 0)
            goto error;
        return ret;
    }
13310

13311
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13312 13313

error:
13314
    virDispatchError(pool->conn);
13315 13316 13317 13318 13319 13320
    return -1;
}


/**
 * virStorageVolGetConnect:
13321
 * @vol: pointer to a pool
13322 13323 13324 13325 13326 13327 13328 13329 13330 13331 13332 13333
 *
 * Provides the connection pointer associated with a storage volume.  The
 * reference counter on the connection is not increased by this
 * call.
 *
 * WARNING: When writing libvirt bindings in other languages, do
 * not use this function.  Instead, store the connection and
 * the volume object together.
 *
 * Returns the virConnectPtr or NULL in case of failure.
 */
virConnectPtr
13334
virStorageVolGetConnect(virStorageVolPtr vol)
13335
{
13336
    VIR_DEBUG("vol=%p", vol);
13337

13338 13339
    virResetLastError();

13340
    if (!VIR_IS_STORAGE_VOL(vol)) {
13341
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
13342
        virDispatchError(NULL);
13343 13344 13345 13346 13347 13348 13349 13350 13351 13352 13353 13354 13355 13356
        return NULL;
    }
    return vol->conn;
}


/**
 * virStorageVolLookupByName:
 * @pool: pointer to storage pool
 * @name: name of storage volume
 *
 * Fetch a pointer to a storage volume based on its name
 * within a pool
 *
13357
 * Returns a storage volume, or NULL if not found / error
13358 13359 13360 13361 13362
 */
virStorageVolPtr
virStorageVolLookupByName(virStoragePoolPtr pool,
                          const char *name)
{
13363
    VIR_DEBUG("pool=%p, name=%s", pool, name);
13364

13365 13366
    virResetLastError();

13367
    if (!VIR_IS_STORAGE_POOL(pool)) {
13368
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
13369
        virDispatchError(NULL);
13370
        return NULL;
13371
    }
13372 13373

    virCheckNonNullArgGoto(name, error);
13374

13375
    if (pool->conn->storageDriver && pool->conn->storageDriver->storageVolLookupByName) {
13376
        virStorageVolPtr ret;
13377
        ret = pool->conn->storageDriver->storageVolLookupByName(pool, name);
13378 13379 13380 13381
        if (!ret)
            goto error;
        return ret;
    }
13382

13383
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13384 13385

error:
13386
    virDispatchError(pool->conn);
13387 13388 13389 13390 13391 13392 13393 13394 13395 13396 13397 13398 13399
    return NULL;
}



/**
 * virStorageVolLookupByKey:
 * @conn: pointer to hypervisor connection
 * @key: globally unique key
 *
 * Fetch a pointer to a storage volume based on its
 * globally unique key
 *
13400
 * Returns a storage volume, or NULL if not found / error
13401 13402 13403 13404 13405
 */
virStorageVolPtr
virStorageVolLookupByKey(virConnectPtr conn,
                         const char *key)
{
13406
    VIR_DEBUG("conn=%p, key=%s", conn, key);
13407

13408 13409
    virResetLastError();

13410
    if (!VIR_IS_CONNECT(conn)) {
13411
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
13412
        virDispatchError(NULL);
13413
        return NULL;
13414
    }
13415 13416

    virCheckNonNullArgGoto(key, error);
13417

13418
    if (conn->storageDriver && conn->storageDriver->storageVolLookupByKey) {
13419
        virStorageVolPtr ret;
13420
        ret = conn->storageDriver->storageVolLookupByKey(conn, key);
13421 13422 13423 13424
        if (!ret)
            goto error;
        return ret;
    }
13425

13426
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13427 13428

error:
13429
    virDispatchError(conn);
13430 13431 13432 13433 13434 13435 13436 13437 13438 13439 13440
    return NULL;
}

/**
 * virStorageVolLookupByPath:
 * @conn: pointer to hypervisor connection
 * @path: locally unique path
 *
 * Fetch a pointer to a storage volume based on its
 * locally (host) unique path
 *
13441
 * Returns a storage volume, or NULL if not found / error
13442 13443 13444 13445 13446
 */
virStorageVolPtr
virStorageVolLookupByPath(virConnectPtr conn,
                          const char *path)
{
13447
    VIR_DEBUG("conn=%p, path=%s", conn, path);
13448

13449 13450
    virResetLastError();

13451
    if (!VIR_IS_CONNECT(conn)) {
13452
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
13453
        virDispatchError(NULL);
13454
        return NULL;
13455
    }
13456
    virCheckNonNullArgGoto(path, error);
13457

13458
    if (conn->storageDriver && conn->storageDriver->storageVolLookupByPath) {
13459
        virStorageVolPtr ret;
13460
        ret = conn->storageDriver->storageVolLookupByPath(conn, path);
13461 13462 13463 13464
        if (!ret)
            goto error;
        return ret;
    }
13465

13466
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13467 13468

error:
13469
    virDispatchError(conn);
13470 13471 13472 13473 13474 13475 13476 13477 13478 13479 13480
    return NULL;
}


/**
 * virStorageVolGetName:
 * @vol: pointer to storage volume
 *
 * Fetch the storage volume name. This is unique
 * within the scope of a pool
 *
13481
 * Returns the volume name, or NULL on error
13482 13483 13484 13485
 */
const char*
virStorageVolGetName(virStorageVolPtr vol)
{
13486
    VIR_DEBUG("vol=%p", vol);
13487

13488 13489
    virResetLastError();

13490
    if (!VIR_IS_STORAGE_VOL(vol)) {
13491
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
13492
        virDispatchError(NULL);
13493
        return NULL;
13494
    }
13495
    return vol->name;
13496 13497 13498 13499 13500 13501 13502 13503
}


/**
 * virStorageVolGetKey:
 * @vol: pointer to storage volume
 *
 * Fetch the storage volume key. This is globally
13504
 * unique, so the same volume will have the same
13505 13506
 * key no matter what host it is accessed from
 *
13507
 * Returns the volume key, or NULL on error
13508 13509 13510 13511
 */
const char*
virStorageVolGetKey(virStorageVolPtr vol)
{
13512
    VIR_DEBUG("vol=%p", vol);
13513

13514 13515
    virResetLastError();

13516
    if (!VIR_IS_STORAGE_VOL(vol)) {
13517
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
13518
        virDispatchError(NULL);
13519
        return NULL;
13520
    }
13521
    return vol->key;
13522 13523 13524 13525 13526 13527
}


/**
 * virStorageVolCreateXML:
 * @pool: pointer to storage pool
E
Eric Blake 已提交
13528
 * @xmlDesc: description of volume to create
13529
 * @flags: bitwise-OR of virStorageVolCreateFlags
13530 13531 13532
 *
 * Create a storage volume within a pool based
 * on an XML description. Not all pools support
13533 13534 13535 13536 13537 13538
 * creation of volumes.
 *
 * Since 1.0.1 VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA
 * in flags can be used to get higher performance with
 * qcow2 image files which don't support full preallocation,
 * by creating a sparse image file with metadata.
13539
 *
13540
 * Returns the storage volume, or NULL on error
13541 13542 13543
 */
virStorageVolPtr
virStorageVolCreateXML(virStoragePoolPtr pool,
E
Eric Blake 已提交
13544
                       const char *xmlDesc,
13545 13546
                       unsigned int flags)
{
E
Eric Blake 已提交
13547
    VIR_DEBUG("pool=%p, xmlDesc=%s, flags=%x", pool, xmlDesc, flags);
13548

13549 13550
    virResetLastError();

13551
    if (!VIR_IS_STORAGE_POOL(pool)) {
13552
        virLibConnError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
13553
        virDispatchError(NULL);
13554
        return NULL;
13555 13556
    }

E
Eric Blake 已提交
13557
    virCheckNonNullArgGoto(xmlDesc, error);
13558

13559
    if (pool->conn->flags & VIR_CONNECT_RO) {
13560
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
13561
        goto error;
13562 13563
    }

13564
    if (pool->conn->storageDriver && pool->conn->storageDriver->storageVolCreateXML) {
13565
        virStorageVolPtr ret;
13566
        ret = pool->conn->storageDriver->storageVolCreateXML(pool, xmlDesc, flags);
13567 13568 13569 13570
        if (!ret)
            goto error;
        return ret;
    }
13571

13572
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13573 13574

error:
13575
    virDispatchError(pool->conn);
13576 13577 13578 13579
    return NULL;
}


13580 13581 13582
/**
 * virStorageVolCreateXMLFrom:
 * @pool: pointer to parent pool for the new volume
E
Eric Blake 已提交
13583
 * @xmlDesc: description of volume to create
13584
 * @clonevol: storage volume to use as input
13585
 * @flags: bitwise-OR of virStorageVolCreateFlags
13586 13587 13588 13589 13590 13591
 *
 * Create a storage volume in the parent pool, using the
 * 'clonevol' volume as input. Information for the new
 * volume (name, perms)  are passed via a typical volume
 * XML description.
 *
13592 13593 13594 13595 13596
 * Since 1.0.1 VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA
 * in flags can be used to get higher performance with
 * qcow2 image files which don't support full preallocation,
 * by creating a sparse image file with metadata.
 *
13597
 * Returns the storage volume, or NULL on error
13598 13599 13600
 */
virStorageVolPtr
virStorageVolCreateXMLFrom(virStoragePoolPtr pool,
E
Eric Blake 已提交
13601
                           const char *xmlDesc,
13602 13603 13604
                           virStorageVolPtr clonevol,
                           unsigned int flags)
{
E
Eric Blake 已提交
13605 13606
    VIR_DEBUG("pool=%p, xmlDesc=%s, clonevol=%p, flags=%x",
              pool, xmlDesc, clonevol, flags);
13607 13608 13609 13610

    virResetLastError();

    if (!VIR_IS_STORAGE_POOL(pool)) {
13611
        virLibConnError(VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
13612
        virDispatchError(NULL);
13613
        return NULL;
13614 13615 13616
    }

    if (!VIR_IS_STORAGE_VOL(clonevol)) {
13617
        virLibConnError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
13618
        goto error;
13619 13620
    }

E
Eric Blake 已提交
13621
    virCheckNonNullArgGoto(xmlDesc, error);
13622

13623 13624
    if (pool->conn->flags & VIR_CONNECT_RO ||
        clonevol->conn->flags & VIR_CONNECT_RO) {
13625
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
13626 13627 13628 13629
        goto error;
    }

    if (pool->conn->storageDriver &&
13630
        pool->conn->storageDriver->storageVolCreateXMLFrom) {
13631
        virStorageVolPtr ret;
13632
        ret = pool->conn->storageDriver->storageVolCreateXMLFrom(pool, xmlDesc,
13633
                                                          clonevol, flags);
13634 13635 13636 13637 13638
        if (!ret)
            goto error;
        return ret;
    }

13639
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13640 13641

error:
13642
    virDispatchError(pool->conn);
13643 13644 13645 13646
    return NULL;
}


13647 13648 13649 13650 13651 13652
/**
 * virStorageVolDownload:
 * @vol: pointer to volume to download from
 * @stream: stream to use as output
 * @offset: position in @vol to start reading from
 * @length: limit on amount of data to download
13653
 * @flags: extra flags; not used yet, so callers should always pass 0
13654 13655 13656 13657 13658 13659 13660 13661 13662 13663 13664 13665 13666 13667 13668 13669 13670 13671 13672 13673
 *
 * Download the content of the volume as a stream. If @length
 * is zero, then the remaining contents of the volume after
 * @offset will be downloaded.
 *
 * This call sets up an asynchronous stream; subsequent use of
 * stream APIs is necessary to transfer the actual data,
 * determine how much data is successfully transferred, and
 * detect any errors. The results will be unpredictable if
 * another active stream is writing to the storage volume.
 *
 * Returns 0, or -1 upon error.
 */
int
virStorageVolDownload(virStorageVolPtr vol,
                      virStreamPtr stream,
                      unsigned long long offset,
                      unsigned long long length,
                      unsigned int flags)
{
E
Eric Blake 已提交
13674
    VIR_DEBUG("vol=%p, stream=%p, offset=%llu, length=%llu, flags=%x",
13675 13676 13677 13678 13679 13680 13681 13682 13683 13684 13685 13686 13687 13688 13689 13690 13691 13692 13693 13694 13695
              vol, stream, offset, length, flags);

    virResetLastError();

    if (!VIR_IS_STORAGE_VOL(vol)) {
        virLibConnError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
        return -1;
    }

    if (!VIR_IS_STREAM(stream)) {
        virLibConnError(VIR_ERR_INVALID_STREAM, __FUNCTION__);
        return -1;
    }

    if (vol->conn->flags & VIR_CONNECT_RO ||
        stream->conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (vol->conn->storageDriver &&
13696
        vol->conn->storageDriver->storageVolDownload) {
13697
        int ret;
13698
        ret = vol->conn->storageDriver->storageVolDownload(vol,
O
Osier Yang 已提交
13699 13700 13701 13702
                                                           stream,
                                                           offset,
                                                           length,
                                                           flags);
13703 13704 13705 13706 13707 13708 13709 13710 13711 13712 13713 13714 13715 13716 13717 13718 13719 13720 13721
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(vol->conn);
    return -1;
}


/**
 * virStorageVolUpload:
 * @vol: pointer to volume to upload
 * @stream: stream to use as input
 * @offset: position to start writing to
 * @length: limit on amount of data to upload
13722
 * @flags: extra flags; not used yet, so callers should always pass 0
13723 13724 13725 13726 13727 13728 13729 13730 13731 13732 13733 13734 13735 13736 13737 13738 13739 13740 13741 13742 13743 13744
 *
 * Upload new content to the volume from a stream. This call
 * will fail if @offset + @length exceeds the size of the
 * volume. Otherwise, if @length is non-zero, an error
 * will be raised if an attempt is made to upload greater
 * than @length bytes of data.
 *
 * This call sets up an asynchronous stream; subsequent use of
 * stream APIs is necessary to transfer the actual data,
 * determine how much data is successfully transferred, and
 * detect any errors. The results will be unpredictable if
 * another active stream is writing to the storage volume.
 *
 * Returns 0, or -1 upon error.
 */
int
virStorageVolUpload(virStorageVolPtr vol,
                    virStreamPtr stream,
                    unsigned long long offset,
                    unsigned long long length,
                    unsigned int flags)
{
E
Eric Blake 已提交
13745
    VIR_DEBUG("vol=%p, stream=%p, offset=%llu, length=%llu, flags=%x",
13746 13747 13748 13749 13750 13751 13752 13753 13754 13755 13756 13757 13758 13759 13760 13761 13762 13763 13764 13765 13766
              vol, stream, offset, length, flags);

    virResetLastError();

    if (!VIR_IS_STORAGE_VOL(vol)) {
        virLibConnError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
        return -1;
    }

    if (!VIR_IS_STREAM(stream)) {
        virLibConnError(VIR_ERR_INVALID_STREAM, __FUNCTION__);
        return -1;
    }

    if (vol->conn->flags & VIR_CONNECT_RO ||
        stream->conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (vol->conn->storageDriver &&
13767
        vol->conn->storageDriver->storageVolUpload) {
13768
        int ret;
13769
        ret = vol->conn->storageDriver->storageVolUpload(vol,
13770 13771 13772 13773 13774 13775 13776 13777 13778 13779 13780 13781 13782 13783 13784 13785 13786
                                                  stream,
                                                  offset,
                                                  length,
                                                  flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(vol->conn);
    return -1;
}


13787 13788 13789
/**
 * virStorageVolDelete:
 * @vol: pointer to storage volume
13790
 * @flags: extra flags; not used yet, so callers should always pass 0
13791 13792 13793
 *
 * Delete the storage volume from the pool
 *
13794
 * Returns 0 on success, or -1 on error
13795 13796 13797 13798 13799 13800
 */
int
virStorageVolDelete(virStorageVolPtr vol,
                    unsigned int flags)
{
    virConnectPtr conn;
13801
    VIR_DEBUG("vol=%p, flags=%x", vol, flags);
13802

13803 13804
    virResetLastError();

13805
    if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
13806
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
13807
        virDispatchError(NULL);
13808
        return -1;
13809 13810 13811 13812
    }

    conn = vol->conn;
    if (conn->flags & VIR_CONNECT_RO) {
13813
        virLibStorageVolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
13814
        goto error;
13815 13816
    }

13817
    if (conn->storageDriver && conn->storageDriver->storageVolDelete) {
13818
        int ret;
13819
        ret = conn->storageDriver->storageVolDelete(vol, flags);
13820 13821 13822 13823
        if (ret < 0)
            goto error;
        return ret;
    }
13824

13825
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13826 13827

error:
13828
    virDispatchError(vol->conn);
13829 13830 13831 13832
    return -1;
}


13833 13834 13835
/**
 * virStorageVolWipe:
 * @vol: pointer to storage volume
13836
 * @flags: extra flags; not used yet, so callers should always pass 0
13837 13838 13839 13840 13841 13842 13843 13844 13845 13846
 *
 * Ensure data previously on a volume is not accessible to future reads
 *
 * Returns 0 on success, or -1 on error
 */
int
virStorageVolWipe(virStorageVolPtr vol,
                  unsigned int flags)
{
    virConnectPtr conn;
13847
    VIR_DEBUG("vol=%p, flags=%x", vol, flags);
13848 13849 13850 13851

    virResetLastError();

    if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
13852
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
13853
        virDispatchError(NULL);
13854
        return -1;
13855 13856 13857 13858
    }

    conn = vol->conn;
    if (conn->flags & VIR_CONNECT_RO) {
13859
        virLibStorageVolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
13860 13861 13862
        goto error;
    }

13863
    if (conn->storageDriver && conn->storageDriver->storageVolWipe) {
13864
        int ret;
13865
        ret = conn->storageDriver->storageVolWipe(vol, flags);
13866 13867 13868 13869 13870 13871
        if (ret < 0) {
            goto error;
        }
        return ret;
    }

13872
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
13873 13874 13875 13876 13877 13878 13879

error:
    virDispatchError(vol->conn);
    return -1;
}


13880 13881 13882 13883 13884 13885 13886 13887 13888 13889 13890 13891 13892 13893 13894 13895 13896 13897 13898 13899 13900 13901 13902 13903 13904 13905 13906 13907 13908 13909 13910 13911 13912
/**
 * virStorageVolWipePattern:
 * @vol: pointer to storage volume
 * @algorithm: one of virStorageVolWipeAlgorithm
 * @flags: future flags, use 0 for now
 *
 * Similar to virStorageVolWipe, but one can choose
 * between different wiping algorithms.
 *
 * Returns 0 on success, or -1 on error.
 */
int
virStorageVolWipePattern(virStorageVolPtr vol,
                         unsigned int algorithm,
                         unsigned int flags)
{
    virConnectPtr conn;
    VIR_DEBUG("vol=%p, algorithm=%u, flags=%x", vol, algorithm, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = vol->conn;
    if (conn->flags & VIR_CONNECT_RO) {
        virLibStorageVolError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

13913
    if (conn->storageDriver && conn->storageDriver->storageVolWipePattern) {
13914
        int ret;
13915
        ret = conn->storageDriver->storageVolWipePattern(vol, algorithm, flags);
13916 13917 13918 13919 13920 13921 13922 13923 13924 13925 13926 13927 13928
        if (ret < 0) {
            goto error;
        }
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(vol->conn);
    return -1;
}

13929 13930 13931 13932 13933
/**
 * virStorageVolFree:
 * @vol: pointer to storage volume
 *
 * Release the storage volume handle. The underlying
13934
 * storage volume continues to exist.
13935
 *
13936
 * Returns 0 on success, or -1 on error
13937 13938 13939 13940
 */
int
virStorageVolFree(virStorageVolPtr vol)
{
13941
    VIR_DEBUG("vol=%p", vol);
13942

13943 13944
    virResetLastError();

13945
    if (!VIR_IS_STORAGE_VOL(vol)) {
13946
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
13947
        virDispatchError(NULL);
13948
        return -1;
13949
    }
13950
    virObjectUnref(vol);
13951
    return 0;
13952 13953 13954
}


13955 13956
/**
 * virStorageVolRef:
D
Daniel Veillard 已提交
13957
 * @vol: the vol to hold a reference on
13958 13959 13960 13961 13962 13963 13964 13965 13966 13967 13968
 *
 * Increment the reference count on the vol. For each
 * additional call to this method, there shall be a corresponding
 * call to virStorageVolFree to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * This method is typically useful for applications where multiple
 * threads are using a connection, and it is required that the
 * connection remain open until all threads have finished using
 * it. ie, each new thread using a vol would increment
 * the reference count.
D
Daniel Veillard 已提交
13969 13970
 *
 * Returns 0 in case of success, -1 in case of failure.
13971 13972 13973 13974 13975
 */
int
virStorageVolRef(virStorageVolPtr vol)
{
    if ((!VIR_IS_CONNECTED_STORAGE_VOL(vol))) {
13976
        virLibConnError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
13977
        virDispatchError(NULL);
13978
        return -1;
13979
    }
13980 13981
    VIR_DEBUG("vol=%p refs=%d", vol, vol->object.refs);
    virObjectRef(vol);
13982 13983 13984
    return 0;
}

13985 13986 13987 13988 13989 13990 13991 13992
/**
 * virStorageVolGetInfo:
 * @vol: pointer to storage volume
 * @info: pointer at which to store info
 *
 * Fetches volatile information about the storage
 * volume such as its current allocation
 *
13993
 * Returns 0 on success, or -1 on failure
13994 13995 13996 13997 13998 13999
 */
int
virStorageVolGetInfo(virStorageVolPtr vol,
                     virStorageVolInfoPtr info)
{
    virConnectPtr conn;
14000
    VIR_DEBUG("vol=%p, info=%p", vol, info);
14001

14002 14003
    virResetLastError();

14004
    if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
14005
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
14006
        virDispatchError(NULL);
14007
        return -1;
14008
    }
14009
    virCheckNonNullArgGoto(info, error);
14010 14011 14012 14013 14014

    memset(info, 0, sizeof(virStorageVolInfo));

    conn = vol->conn;

14015
    if (conn->storageDriver->storageVolGetInfo){
14016
        int ret;
14017
        ret = conn->storageDriver->storageVolGetInfo(vol, info);
14018 14019 14020 14021
        if (ret < 0)
            goto error;
        return ret;
    }
14022

14023
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14024 14025

error:
14026
    virDispatchError(vol->conn);
14027 14028 14029 14030 14031 14032 14033
    return -1;
}


/**
 * virStorageVolGetXMLDesc:
 * @vol: pointer to storage volume
14034
 * @flags: extra flags; not used yet, so callers should always pass 0
14035 14036 14037 14038
 *
 * Fetch an XML document describing all aspects of
 * the storage volume
 *
14039
 * Returns the XML document, or NULL on error
14040 14041 14042 14043 14044 14045
 */
char *
virStorageVolGetXMLDesc(virStorageVolPtr vol,
                        unsigned int flags)
{
    virConnectPtr conn;
14046
    VIR_DEBUG("vol=%p, flags=%x", vol, flags);
14047

14048 14049
    virResetLastError();

14050
    if (!VIR_IS_STORAGE_VOL(vol)) {
14051
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
14052
        virDispatchError(NULL);
14053
        return NULL;
14054 14055 14056 14057
    }

    conn = vol->conn;

14058
    if (conn->storageDriver && conn->storageDriver->storageVolGetXMLDesc) {
14059
        char *ret;
14060
        ret = conn->storageDriver->storageVolGetXMLDesc(vol, flags);
14061 14062 14063 14064
        if (!ret)
            goto error;
        return ret;
    }
14065

14066
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14067

14068
error:
14069
    virDispatchError(vol->conn);
14070
    return NULL;
14071 14072 14073 14074 14075 14076 14077 14078 14079 14080 14081 14082 14083
}


/**
 * virStorageVolGetPath:
 * @vol: pointer to storage volume
 *
 * Fetch the storage volume path. Depending on the pool
 * configuration this is either persistent across hosts,
 * or dynamically assigned at pool startup. Consult
 * pool documentation for information on getting the
 * persistent naming
 *
14084 14085
 * Returns the storage volume path, or NULL on error. The
 * caller must free() the returned path after use.
14086 14087 14088 14089 14090
 */
char *
virStorageVolGetPath(virStorageVolPtr vol)
{
    virConnectPtr conn;
14091
    VIR_DEBUG("vol=%p", vol);
14092

14093 14094
    virResetLastError();

14095
    if (!VIR_IS_STORAGE_VOL(vol)) {
14096
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
14097
        virDispatchError(NULL);
14098
        return NULL;
14099 14100 14101 14102
    }

    conn = vol->conn;

14103
    if (conn->storageDriver && conn->storageDriver->storageVolGetPath) {
14104
        char *ret;
14105
        ret = conn->storageDriver->storageVolGetPath(vol);
14106 14107 14108 14109
        if (!ret)
            goto error;
        return ret;
    }
14110

14111
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14112 14113

error:
14114
    virDispatchError(vol->conn);
14115 14116
    return NULL;
}
14117

14118 14119 14120 14121 14122 14123 14124 14125 14126 14127 14128 14129 14130 14131 14132 14133 14134 14135
/**
 * virStorageVolResize:
 * @vol: pointer to storage volume
 * @capacity: new capacity, in bytes
 * @flags: bitwise-OR of virStorageVolResizeFlags
 *
 * Changes the capacity of the storage volume @vol to @capacity. The
 * operation will fail if the new capacity requires allocation that would
 * exceed the remaining free space in the parent pool.  The contents of
 * the new capacity will appear as all zero bytes.
 *
 * Normally, the operation will attempt to affect capacity with a minimum
 * impact on allocation (that is, the default operation favors a sparse
 * resize).  If @flags contains VIR_STORAGE_VOL_RESIZE_ALLOCATE, then the
 * operation will ensure that allocation is sufficient for the new
 * capacity; this may make the operation take noticeably longer.
 *
 * Normally, the operation treats @capacity as the new size in bytes;
A
Alex Jia 已提交
14136
 * but if @flags contains VIR_STORAGE_VOL_RESIZE_DELTA, then @capacity
14137 14138 14139 14140 14141
 * represents the size difference to add to the current size.  It is
 * up to the storage pool implementation whether unaligned requests are
 * rounded up to the next valid boundary, or rejected.
 *
 * Normally, this operation should only be used to enlarge capacity;
A
Alex Jia 已提交
14142
 * but if @flags contains VIR_STORAGE_VOL_RESIZE_SHRINK, it is possible to
14143
 * attempt a reduction in capacity even though it might cause data loss.
A
Alex Jia 已提交
14144
 * If VIR_STORAGE_VOL_RESIZE_DELTA is also present, then @capacity is
E
Eric Blake 已提交
14145 14146 14147
 * subtracted from the current size; without it, @capacity represents
 * the absolute new size regardless of whether it is larger or smaller
 * than the current size.
14148 14149 14150 14151 14152
 *
 * Returns 0 on success, or -1 on error.
 */
int
virStorageVolResize(virStorageVolPtr vol,
E
Eric Blake 已提交
14153
                    unsigned long long capacity,
14154 14155 14156
                    unsigned int flags)
{
    virConnectPtr conn;
E
Eric Blake 已提交
14157
    VIR_DEBUG("vol=%p capacity=%llu flags=%x", vol, capacity, flags);
14158 14159 14160 14161 14162 14163 14164 14165 14166 14167 14168 14169 14170 14171 14172 14173

    virResetLastError();

    if (!VIR_IS_STORAGE_VOL(vol)) {
        virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = vol->conn;

    if (conn->flags & VIR_CONNECT_RO) {
       virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
       goto error;
    }

E
Eric Blake 已提交
14174 14175 14176
    /* Zero capacity is only valid with either delta or shrink.  */
    if (capacity == 0 && !((flags & VIR_STORAGE_VOL_RESIZE_DELTA) ||
                           (flags & VIR_STORAGE_VOL_RESIZE_SHRINK))) {
14177 14178 14179
        virReportInvalidArg(capacity,
                            _("capacity in %s cannot be zero without 'delta' or 'shrink' flags set"),
                            __FUNCTION__);
14180 14181 14182
        goto error;
    }

14183
    if (conn->storageDriver && conn->storageDriver->storageVolResize) {
14184
        int ret;
14185
        ret = conn->storageDriver->storageVolResize(vol, capacity, flags);
14186 14187 14188 14189 14190 14191 14192 14193 14194 14195 14196
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(vol->conn);
    return -1;
}
14197

14198 14199 14200 14201
/**
 * virNodeNumOfDevices:
 * @conn: pointer to the hypervisor connection
 * @cap: capability name
14202
 * @flags: extra flags; not used yet, so callers should always pass 0
14203 14204 14205 14206 14207 14208 14209 14210 14211 14212 14213
 *
 * Provides the number of node devices.
 *
 * If the optional 'cap'  argument is non-NULL, then the count
 * will be restricted to devices with the specified capability
 *
 * Returns the number of node devices or -1 in case of error
 */
int
virNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags)
{
14214
    VIR_DEBUG("conn=%p, cap=%s, flags=%x", conn, NULLSTR(cap), flags);
14215

14216 14217
    virResetLastError();

14218
    if (!VIR_IS_CONNECT(conn)) {
14219
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
14220
        virDispatchError(NULL);
14221
        return -1;
14222 14223
    }

14224
    if (conn->nodeDeviceDriver && conn->nodeDeviceDriver->nodeNumOfDevices) {
14225
        int ret;
14226
        ret = conn->nodeDeviceDriver->nodeNumOfDevices(conn, cap, flags);
14227 14228 14229 14230
        if (ret < 0)
            goto error;
        return ret;
    }
14231

14232
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14233 14234

error:
14235
    virDispatchError(conn);
14236 14237 14238
    return -1;
}

14239 14240 14241 14242 14243 14244 14245 14246 14247 14248 14249 14250 14251 14252 14253 14254 14255 14256 14257 14258 14259 14260 14261 14262 14263 14264 14265 14266
/**
 * virConnectListAllNodeDevices:
 * @conn: Pointer to the hypervisor connection.
 * @devices: Pointer to a variable to store the array containing the node
 *           device objects or NULL if the list is not required (just returns
 *           number of node devices).
 * @flags: bitwise-OR of virConnectListAllNodeDevices.
 *
 * Collect the list of node devices, and allocate an array to store those
 * objects.
 *
 * Normally, all node devices are returned; however, @flags can be used to
 * filter the results for a smaller list of targeted node devices.  The valid
 * flags are divided into groups, where each group contains bits that
 * describe mutually exclusive attributes of a node device, and where all bits
 * within a group describe all possible node devices.
 *
 * Only one group of the @flags is provided to filter the node devices by
 * capability type, flags include:
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_SYSTEM
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_TARGET
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE
14267 14268
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST
 *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS
14269 14270 14271 14272 14273 14274 14275 14276 14277 14278 14279 14280 14281 14282 14283 14284 14285 14286 14287 14288 14289 14290 14291 14292 14293 14294
 *
 * Returns the number of node devices found or -1 and sets @devices to NULL in
 * case of error.  On success, the array stored into @devices is guaranteed to
 * have an extra allocated element set to NULL but not included in the return
 * count, to make iteration easier.  The caller is responsible for calling
 * virNodeDeviceFree() on each array element, then calling free() on
 * @devices.
 */
int
virConnectListAllNodeDevices(virConnectPtr conn,
                             virNodeDevicePtr **devices,
                             unsigned int flags)
{
    VIR_DEBUG("conn=%p, devices=%p, flags=%x", conn, devices, flags);

    virResetLastError();

    if (devices)
        *devices = NULL;

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

14295 14296
    if (conn->nodeDeviceDriver &&
        conn->nodeDeviceDriver->connectListAllNodeDevices) {
14297
        int ret;
14298
        ret = conn->nodeDeviceDriver->connectListAllNodeDevices(conn, devices, flags);
14299 14300 14301 14302 14303 14304 14305 14306 14307 14308 14309
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}
14310 14311 14312 14313 14314 14315 14316

/**
 * virNodeListDevices:
 * @conn: pointer to the hypervisor connection
 * @cap: capability name
 * @names: array to collect the list of node device names
 * @maxnames: size of @names
14317
 * @flags: extra flags; not used yet, so callers should always pass 0
14318 14319 14320
 *
 * Collect the list of node devices, and store their names in @names
 *
14321 14322
 * For more control over the results, see virConnectListAllNodeDevices().
 *
14323 14324 14325 14326 14327 14328 14329 14330 14331 14332 14333
 * If the optional 'cap'  argument is non-NULL, then the count
 * will be restricted to devices with the specified capability
 *
 * Returns the number of node devices found or -1 in case of error
 */
int
virNodeListDevices(virConnectPtr conn,
                   const char *cap,
                   char **const names, int maxnames,
                   unsigned int flags)
{
14334
    VIR_DEBUG("conn=%p, cap=%s, names=%p, maxnames=%d, flags=%x",
14335 14336
          conn, cap, names, maxnames, flags);

14337 14338
    virResetLastError();

14339
    if (!VIR_IS_CONNECT(conn)) {
14340
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
14341
        virDispatchError(NULL);
14342
        return -1;
14343
    }
14344 14345
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
14346

14347
    if (conn->nodeDeviceDriver && conn->nodeDeviceDriver->nodeListDevices) {
14348
        int ret;
14349
        ret = conn->nodeDeviceDriver->nodeListDevices(conn, cap, names, maxnames, flags);
14350 14351 14352 14353
        if (ret < 0)
            goto error;
        return ret;
    }
14354

14355
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14356 14357

error:
14358
    virDispatchError(conn);
14359 14360 14361 14362 14363 14364 14365 14366 14367 14368 14369 14370 14371 14372 14373
    return -1;
}


/**
 * virNodeDeviceLookupByName:
 * @conn: pointer to the hypervisor connection
 * @name: unique device name
 *
 * Lookup a node device by its name.
 *
 * Returns a virNodeDevicePtr if found, NULL otherwise.
 */
virNodeDevicePtr virNodeDeviceLookupByName(virConnectPtr conn, const char *name)
{
14374
    VIR_DEBUG("conn=%p, name=%p", conn, name);
14375

14376 14377
    virResetLastError();

14378
    if (!VIR_IS_CONNECT(conn)) {
14379
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
14380
        virDispatchError(NULL);
14381 14382 14383
        return NULL;
    }

14384
    virCheckNonNullArgGoto(name, error);
14385

14386
    if (conn->nodeDeviceDriver && conn->nodeDeviceDriver->nodeDeviceLookupByName) {
14387
        virNodeDevicePtr ret;
14388
        ret = conn->nodeDeviceDriver->nodeDeviceLookupByName(conn, name);
14389 14390 14391 14392
        if (!ret)
            goto error;
        return ret;
    }
14393

14394
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14395 14396

error:
14397
    virDispatchError(conn);
14398 14399 14400
    return NULL;
}

14401 14402 14403 14404 14405 14406 14407 14408 14409 14410 14411 14412 14413 14414 14415 14416 14417 14418 14419 14420 14421 14422 14423 14424 14425 14426 14427 14428 14429 14430
/**
 * virNodeDeviceLookupSCSIHostByWWN:
 * @conn: pointer to the hypervisor connection
 * @wwnn: WWNN of the SCSI Host.
 * @wwpn: WWPN of the SCSI Host.
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Lookup SCSI Host which is capable with 'fc_host' by its WWNN and WWPN.
 *
 * Returns a virNodeDevicePtr if found, NULL otherwise.
 */
virNodeDevicePtr
virNodeDeviceLookupSCSIHostByWWN(virConnectPtr conn,
                                 const char *wwnn,
                                 const char *wwpn,
                                 unsigned int flags)
{
    VIR_DEBUG("conn=%p, wwnn=%p, wwpn=%p, flags=%x", conn, wwnn, wwpn, flags);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }

    virCheckNonNullArgGoto(wwnn, error);
    virCheckNonNullArgGoto(wwpn, error);

14431 14432
    if (conn->nodeDeviceDriver &&
        conn->nodeDeviceDriver->nodeDeviceLookupSCSIHostByWWN) {
14433
        virNodeDevicePtr ret;
14434
        ret = conn->nodeDeviceDriver->nodeDeviceLookupSCSIHostByWWN(conn, wwnn,
14435 14436 14437 14438 14439 14440 14441 14442 14443 14444 14445 14446
                                                             wwpn, flags);
        if (!ret)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return NULL;
}
14447 14448 14449 14450

/**
 * virNodeDeviceGetXMLDesc:
 * @dev: pointer to the node device
14451
 * @flags: extra flags; not used yet, so callers should always pass 0
14452 14453 14454 14455
 *
 * Fetch an XML document describing all aspects of
 * the device.
 *
14456
 * Returns the XML document, or NULL on error
14457 14458 14459
 */
char *virNodeDeviceGetXMLDesc(virNodeDevicePtr dev, unsigned int flags)
{
E
Eric Blake 已提交
14460
    VIR_DEBUG("dev=%p, conn=%p, flags=%x", dev, dev ? dev->conn : NULL, flags);
14461

14462 14463
    virResetLastError();

14464
    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14465
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14466
        virDispatchError(NULL);
14467 14468 14469
        return NULL;
    }

14470
    if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceGetXMLDesc) {
14471
        char *ret;
14472
        ret = dev->conn->nodeDeviceDriver->nodeDeviceGetXMLDesc(dev, flags);
14473 14474 14475 14476
        if (!ret)
            goto error;
        return ret;
    }
14477

14478
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14479 14480

error:
14481
    virDispatchError(dev->conn);
14482 14483 14484 14485 14486 14487 14488 14489
    return NULL;
}


/**
 * virNodeDeviceGetName:
 * @dev: the device
 *
D
Daniel Veillard 已提交
14490 14491 14492
 * Just return the device name
 *
 * Returns the device name or NULL in case of error
14493 14494 14495
 */
const char *virNodeDeviceGetName(virNodeDevicePtr dev)
{
14496
    VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
14497 14498

    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14499
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14500
        virDispatchError(NULL);
14501 14502 14503 14504 14505 14506 14507 14508 14509 14510
        return NULL;
    }

    return dev->name;
}

/**
 * virNodeDeviceGetParent:
 * @dev: the device
 *
D
Daniel Veillard 已提交
14511 14512
 * Accessor for the parent of the device
 *
14513 14514 14515 14516 14517
 * Returns the name of the device's parent, or NULL if the
 * device has no parent.
 */
const char *virNodeDeviceGetParent(virNodeDevicePtr dev)
{
14518
    VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
14519

14520 14521
    virResetLastError();

14522
    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14523
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14524
        virDispatchError(NULL);
14525 14526 14527
        return NULL;
    }

14528
    if (!dev->parent) {
14529 14530
        if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceGetParent) {
            dev->parent = dev->conn->nodeDeviceDriver->nodeDeviceGetParent(dev);
14531
        } else {
14532
            virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14533
            virDispatchError(dev->conn);
14534 14535 14536 14537
            return NULL;
        }
    }
    return dev->parent;
14538 14539 14540 14541 14542 14543
}

/**
 * virNodeDeviceNumOfCaps:
 * @dev: the device
 *
D
Daniel Veillard 已提交
14544 14545
 * Accessor for the number of capabilities supported by the device.
 *
14546 14547 14548 14549
 * Returns the number of capabilities supported by the device.
 */
int virNodeDeviceNumOfCaps(virNodeDevicePtr dev)
{
14550
    VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
14551

14552 14553
    virResetLastError();

14554
    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14555
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14556
        virDispatchError(NULL);
14557 14558 14559
        return -1;
    }

14560
    if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceNumOfCaps) {
14561
        int ret;
14562
        ret = dev->conn->nodeDeviceDriver->nodeDeviceNumOfCaps(dev);
14563 14564 14565 14566
        if (ret < 0)
            goto error;
        return ret;
    }
14567

14568
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14569 14570

error:
14571
    virDispatchError(dev->conn);
14572 14573 14574 14575 14576 14577 14578 14579 14580 14581 14582 14583 14584 14585 14586 14587 14588
    return -1;
}

/**
 * virNodeDeviceListCaps:
 * @dev: the device
 * @names: array to collect the list of capability names
 * @maxnames: size of @names
 *
 * Lists the names of the capabilities supported by the device.
 *
 * Returns the number of capability names listed in @names.
 */
int virNodeDeviceListCaps(virNodeDevicePtr dev,
                          char **const names,
                          int maxnames)
{
14589
    VIR_DEBUG("dev=%p, conn=%p, names=%p, maxnames=%d",
14590 14591
          dev, dev ? dev->conn : NULL, names, maxnames);

14592 14593
    virResetLastError();

14594
    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14595
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14596
        virDispatchError(NULL);
14597 14598 14599
        return -1;
    }

14600 14601
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
14602

14603
    if (dev->conn->nodeDeviceDriver && dev->conn->nodeDeviceDriver->nodeDeviceListCaps) {
14604
        int ret;
14605
        ret = dev->conn->nodeDeviceDriver->nodeDeviceListCaps(dev, names, maxnames);
14606 14607 14608 14609
        if (ret < 0)
            goto error;
        return ret;
    }
14610

14611
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14612 14613

error:
14614
    virDispatchError(dev->conn);
14615 14616 14617 14618 14619 14620 14621 14622 14623 14624 14625 14626 14627 14628 14629
    return -1;
}


/**
 * virNodeDeviceFree:
 * @dev: pointer to the node device
 *
 * Drops a reference to the node device, freeing it if
 * this was the last reference.
 *
 * Returns the 0 for success, -1 for error.
 */
int virNodeDeviceFree(virNodeDevicePtr dev)
{
14630
    VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
14631

14632 14633
    virResetLastError();

14634
    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14635
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14636
        virDispatchError(NULL);
14637
        return -1;
14638
    }
14639
    virObjectUnref(dev);
14640
    return 0;
14641 14642 14643
}


14644 14645
/**
 * virNodeDeviceRef:
D
Daniel Veillard 已提交
14646
 * @dev: the dev to hold a reference on
14647 14648 14649 14650 14651 14652 14653 14654 14655 14656 14657
 *
 * Increment the reference count on the dev. For each
 * additional call to this method, there shall be a corresponding
 * call to virNodeDeviceFree to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * This method is typically useful for applications where multiple
 * threads are using a connection, and it is required that the
 * connection remain open until all threads have finished using
 * it. ie, each new thread using a dev would increment
 * the reference count.
D
Daniel Veillard 已提交
14658 14659
 *
 * Returns 0 in case of success, -1 in case of failure.
14660 14661 14662 14663 14664
 */
int
virNodeDeviceRef(virNodeDevicePtr dev)
{
    if ((!VIR_IS_CONNECTED_NODE_DEVICE(dev))) {
14665
        virLibConnError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14666
        virDispatchError(NULL);
14667
        return -1;
14668
    }
14669 14670
    VIR_DEBUG("dev=%p refs=%d", dev, dev->object.refs);
    virObjectRef(dev);
14671 14672 14673
    return 0;
}

14674
/**
D
Daniel Veillard 已提交
14675
 * virNodeDeviceDettach:
14676 14677 14678 14679 14680 14681 14682 14683 14684 14685 14686 14687 14688 14689
 * @dev: pointer to the node device
 *
 * Dettach the node device from the node itself so that it may be
 * assigned to a guest domain.
 *
 * Depending on the hypervisor, this may involve operations such
 * as unbinding any device drivers from the device, binding the
 * device to a dummy device driver and resetting the device.
 *
 * If the device is currently in use by the node, this method may
 * fail.
 *
 * Once the device is not assigned to any guest, it may be re-attached
 * to the node using the virNodeDeviceReattach() method.
D
Daniel Veillard 已提交
14690
 *
14691 14692 14693 14694 14695
 * If the caller needs control over which backend driver will be used
 * during PCI device assignment (to use something other than the
 * default, for example VFIO), the newer virNodeDeviceDetachFlags()
 * API should be used instead.
 *
D
Daniel Veillard 已提交
14696
 * Returns 0 in case of success, -1 in case of failure.
14697 14698 14699 14700
 */
int
virNodeDeviceDettach(virNodeDevicePtr dev)
{
14701
    VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
14702 14703 14704 14705

    virResetLastError();

    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14706
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14707
        virDispatchError(NULL);
14708
        return -1;
14709 14710
    }

14711 14712 14713 14714 14715
    if (dev->conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

14716 14717
    if (dev->conn->driver->nodeDeviceDettach) {
        int ret;
14718
        ret = dev->conn->driver->nodeDeviceDettach(dev);
14719 14720 14721 14722 14723
        if (ret < 0)
            goto error;
        return ret;
    }

14724
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14725 14726

error:
14727
    virDispatchError(dev->conn);
14728
    return -1;
14729 14730
}

14731 14732 14733 14734 14735 14736 14737 14738 14739 14740 14741 14742 14743 14744 14745 14746 14747 14748 14749 14750 14751 14752 14753 14754 14755 14756 14757 14758 14759 14760 14761 14762 14763 14764 14765 14766 14767 14768 14769 14770 14771 14772 14773 14774 14775 14776 14777 14778 14779 14780 14781 14782 14783 14784 14785 14786 14787 14788 14789 14790 14791 14792 14793 14794
/**
 * virNodeDeviceDetachFlags:
 * @dev: pointer to the node device
 * @driverName: name of backend driver that will be used
 *              for later device assignment to a domain. NULL
 *              means "use the hypervisor default driver"
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Detach the node device from the node itself so that it may be
 * assigned to a guest domain.
 *
 * Depending on the hypervisor, this may involve operations such as
 * unbinding any device drivers from the device, binding the device to
 * a dummy device driver and resetting the device. Different backend
 * drivers expect the device to be bound to different dummy
 * devices. For example, QEMU's "kvm" backend driver (the default)
 * expects the device to be bound to "pci-stub", but its "vfio"
 * backend driver expects the device to be bound to "vfio-pci".
 *
 * If the device is currently in use by the node, this method may
 * fail.
 *
 * Once the device is not assigned to any guest, it may be re-attached
 * to the node using the virNodeDeviceReAttach() method.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virNodeDeviceDetachFlags(virNodeDevicePtr dev,
                         const char *driverName,
                         unsigned int flags)
{
    VIR_DEBUG("dev=%p, conn=%p driverName=%s flags=%x",
              dev, dev ? dev->conn : NULL,
              driverName ? driverName : "(default)", flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (dev->conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (dev->conn->driver->nodeDeviceDetachFlags) {
        int ret;
        ret = dev->conn->driver->nodeDeviceDetachFlags(dev, driverName, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dev->conn);
    return -1;
}

14795 14796 14797 14798 14799 14800 14801 14802 14803 14804 14805 14806
/**
 * virNodeDeviceReAttach:
 * @dev: pointer to the node device
 *
 * Re-attach a previously dettached node device to the node so that it
 * may be used by the node again.
 *
 * Depending on the hypervisor, this may involve operations such
 * as resetting the device, unbinding it from a dummy device driver
 * and binding it to its appropriate driver.
 *
 * If the device is currently in use by a guest, this method may fail.
D
Daniel Veillard 已提交
14807 14808
 *
 * Returns 0 in case of success, -1 in case of failure.
14809 14810 14811 14812
 */
int
virNodeDeviceReAttach(virNodeDevicePtr dev)
{
14813
    VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
14814 14815 14816 14817

    virResetLastError();

    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14818
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14819
        virDispatchError(NULL);
14820
        return -1;
14821 14822
    }

14823 14824 14825 14826 14827
    if (dev->conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

14828 14829
    if (dev->conn->driver->nodeDeviceReAttach) {
        int ret;
14830
        ret = dev->conn->driver->nodeDeviceReAttach(dev);
14831 14832 14833 14834 14835
        if (ret < 0)
            goto error;
        return ret;
    }

14836
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14837 14838

error:
14839
    virDispatchError(dev->conn);
14840
    return -1;
14841 14842 14843 14844 14845 14846 14847 14848 14849 14850 14851 14852 14853 14854 14855 14856
}

/**
 * virNodeDeviceReset:
 * @dev: pointer to the node device
 *
 * Reset a previously dettached node device to the node before or
 * after assigning it to a guest.
 *
 * The exact reset semantics depends on the hypervisor and device
 * type but, for example, KVM will attempt to reset PCI devices with
 * a Function Level Reset, Secondary Bus Reset or a Power Management
 * D-State reset.
 *
 * If the reset will affect other devices which are currently in use,
 * this function may fail.
D
Daniel Veillard 已提交
14857 14858
 *
 * Returns 0 in case of success, -1 in case of failure.
14859 14860 14861 14862
 */
int
virNodeDeviceReset(virNodeDevicePtr dev)
{
14863
    VIR_DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
14864 14865 14866 14867

    virResetLastError();

    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14868
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14869
        virDispatchError(NULL);
14870
        return -1;
14871 14872
    }

14873 14874 14875 14876 14877
    if (dev->conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

14878 14879
    if (dev->conn->driver->nodeDeviceReset) {
        int ret;
14880
        ret = dev->conn->driver->nodeDeviceReset(dev);
14881 14882 14883 14884 14885
        if (ret < 0)
            goto error;
        return ret;
    }

14886
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14887 14888

error:
14889
    virDispatchError(dev->conn);
14890
    return -1;
14891 14892
}

14893

14894 14895 14896 14897
/**
 * virNodeDeviceCreateXML:
 * @conn: pointer to the hypervisor connection
 * @xmlDesc: string containing an XML description of the device to be created
14898
 * @flags: extra flags; not used yet, so callers should always pass 0
14899 14900 14901 14902 14903 14904 14905 14906 14907 14908 14909
 *
 * Create a new device on the VM host machine, for example, virtual
 * HBAs created using vport_create.
 *
 * Returns a node device object if successful, NULL in case of failure
 */
virNodeDevicePtr
virNodeDeviceCreateXML(virConnectPtr conn,
                       const char *xmlDesc,
                       unsigned int flags)
{
14910
    VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags);
14911 14912 14913 14914

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
14915
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
14916
        virDispatchError(NULL);
14917 14918 14919 14920
        return NULL;
    }

    if (conn->flags & VIR_CONNECT_RO) {
14921
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
14922 14923 14924
        goto error;
    }

14925
    virCheckNonNullArgGoto(xmlDesc, error);
14926

14927 14928 14929
    if (conn->nodeDeviceDriver &&
        conn->nodeDeviceDriver->nodeDeviceCreateXML) {
        virNodeDevicePtr dev = conn->nodeDeviceDriver->nodeDeviceCreateXML(conn, xmlDesc, flags);
14930 14931 14932 14933 14934
        if (dev == NULL)
            goto error;
        return dev;
    }

14935
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14936 14937

error:
14938
    virDispatchError(conn);
14939 14940 14941 14942 14943 14944 14945 14946 14947 14948 14949 14950 14951 14952 14953 14954
    return NULL;
}


/**
 * virNodeDeviceDestroy:
 * @dev: a device object
 *
 * Destroy the device object. The virtual device is removed from the host operating system.
 * This function may require privileged access
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virNodeDeviceDestroy(virNodeDevicePtr dev)
{
14955
    VIR_DEBUG("dev=%p", dev);
14956 14957 14958 14959

    virResetLastError();

    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
14960
        virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
14961
        virDispatchError(NULL);
14962
        return -1;
14963 14964 14965
    }

    if (dev->conn->flags & VIR_CONNECT_RO) {
14966
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
14967 14968 14969
        goto error;
    }

14970 14971 14972
    if (dev->conn->nodeDeviceDriver &&
        dev->conn->nodeDeviceDriver->nodeDeviceDestroy) {
        int retval = dev->conn->nodeDeviceDriver->nodeDeviceDestroy(dev);
14973 14974 14975 14976 14977 14978 14979
        if (retval < 0) {
            goto error;
        }

        return 0;
    }

14980
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
14981 14982

error:
14983
    virDispatchError(dev->conn);
14984 14985 14986 14987
    return -1;
}


14988 14989 14990 14991 14992 14993 14994 14995 14996
/*
 * Domain Event Notification
 */

/**
 * virConnectDomainEventRegister:
 * @conn: pointer to the connection
 * @cb: callback to the function handling domain events
 * @opaque: opaque data to pass on to the callback
D
Daniel Veillard 已提交
14997
 * @freecb: optional function to deallocate opaque when not used anymore
14998
 *
14999 15000 15001 15002 15003 15004
 * Adds a callback to receive notifications of domain lifecycle events
 * occurring on a connection
 *
 * Use of this method is no longer recommended. Instead applications
 * should try virConnectDomainEventRegisterAny which has a more flexible
 * API contract
15005
 *
15006 15007
 * The virDomainPtr object handle passed into the callback upon delivery
 * of an event is only valid for the duration of execution of the callback.
15008 15009
 * If the callback wishes to keep the domain object after the callback returns,
 * it shall take a reference to it, by calling virDomainRef.
15010 15011 15012
 * The reference can be released once the object is no longer required
 * by calling virDomainFree.
 *
15013 15014 15015 15016 15017
 * Returns 0 on success, -1 on failure
 */
int
virConnectDomainEventRegister(virConnectPtr conn,
                              virConnectDomainEventCallback cb,
15018 15019
                              void *opaque,
                              virFreeCallback freecb)
15020
{
15021
    VIR_DEBUG("conn=%p, cb=%p, opaque=%p, freecb=%p", conn, cb, opaque, freecb);
15022
    virResetLastError();
15023 15024

    if (!VIR_IS_CONNECT(conn)) {
15025
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15026
        virDispatchError(NULL);
15027
        return -1;
15028
    }
15029
    virCheckNonNullArgGoto(cb, error);
15030

15031
    if ((conn->driver) && (conn->driver->connectDomainEventRegister)) {
15032
        int ret;
15033
        ret = conn->driver->connectDomainEventRegister(conn, cb, opaque, freecb);
15034 15035 15036 15037 15038
        if (ret < 0)
            goto error;
        return ret;
    }

15039
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15040
error:
15041
    virDispatchError(conn);
15042 15043 15044 15045 15046 15047 15048 15049
    return -1;
}

/**
 * virConnectDomainEventDeregister:
 * @conn: pointer to the connection
 * @cb: callback to the function handling domain events
 *
15050
 * Removes a callback previously registered with the virConnectDomainEventRegister
J
Ján Tomko 已提交
15051
 * function.
15052 15053 15054 15055
 *
 * Use of this method is no longer recommended. Instead applications
 * should try virConnectDomainEventUnregisterAny which has a more flexible
 * API contract
15056 15057 15058 15059 15060 15061 15062
 *
 * Returns 0 on success, -1 on failure
 */
int
virConnectDomainEventDeregister(virConnectPtr conn,
                                virConnectDomainEventCallback cb)
{
15063
    VIR_DEBUG("conn=%p, cb=%p", conn, cb);
15064 15065

    virResetLastError();
15066 15067

    if (!VIR_IS_CONNECT(conn)) {
15068
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15069
        virDispatchError(NULL);
15070
        return -1;
15071
    }
15072 15073
    virCheckNonNullArgGoto(cb, error);

15074
    if ((conn->driver) && (conn->driver->connectDomainEventDeregister)) {
15075
        int ret;
15076
        ret = conn->driver->connectDomainEventDeregister(conn, cb);
15077 15078 15079
        if (ret < 0)
            goto error;
        return ret;
15080 15081
    }

15082
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15083
error:
15084
    virDispatchError(conn);
15085 15086
    return -1;
}
15087 15088 15089 15090 15091 15092 15093 15094 15095 15096 15097 15098 15099 15100

/**
 * virSecretGetConnect:
 * @secret: A virSecret secret
 *
 * Provides the connection pointer associated with a secret.  The reference
 * counter on the connection is not increased by this call.
 *
 * WARNING: When writing libvirt bindings in other languages, do not use this
 * function.  Instead, store the connection and the secret object together.
 *
 * Returns the virConnectPtr or NULL in case of failure.
 */
virConnectPtr
15101
virSecretGetConnect(virSecretPtr secret)
15102
{
15103
    VIR_DEBUG("secret=%p", secret);
15104 15105 15106

    virResetLastError();

15107
    if (!VIR_IS_CONNECTED_SECRET(secret)) {
15108
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15109
        virDispatchError(NULL);
15110 15111 15112 15113 15114 15115 15116 15117 15118 15119 15120 15121 15122 15123 15124 15125 15126 15127 15128 15129 15130
        return NULL;
    }
    return secret->conn;
}

/**
 * virConnectNumOfSecrets:
 * @conn: virConnect connection
 *
 * Fetch number of currently defined secrets.
 *
 * Returns the number currently defined secrets.
 */
int
virConnectNumOfSecrets(virConnectPtr conn)
{
    VIR_DEBUG("conn=%p", conn);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
15131
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15132
        virDispatchError(NULL);
15133 15134 15135 15136
        return -1;
    }

    if (conn->secretDriver != NULL &&
15137
        conn->secretDriver->connectNumOfSecrets != NULL) {
15138 15139
        int ret;

15140
        ret = conn->secretDriver->connectNumOfSecrets(conn);
15141 15142 15143 15144 15145
        if (ret < 0)
            goto error;
        return ret;
    }

15146
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15147 15148

error:
15149
    virDispatchError(conn);
15150 15151 15152
    return -1;
}

15153 15154 15155 15156 15157 15158 15159 15160 15161 15162 15163 15164 15165 15166 15167 15168 15169 15170 15171 15172 15173 15174 15175 15176 15177 15178 15179 15180 15181 15182 15183 15184 15185 15186 15187 15188 15189 15190 15191 15192 15193 15194 15195 15196 15197 15198 15199 15200 15201 15202 15203 15204
/**
 * virConnectListAllSecrets:
 * @conn: Pointer to the hypervisor connection.
 * @secrets: Pointer to a variable to store the array containing the secret
 *           objects or NULL if the list is not required (just returns the
 *           number of secrets).
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Collect the list of secrets, and allocate an array to store those
 * objects.
 *
 * Normally, all secrets are returned; however, @flags can be used to
 * filter the results for a smaller list of targeted secrets. The valid
 * flags are divided into groups, where each group contains bits that
 * describe mutually exclusive attributes of a secret, and where all bits
 * within a group describe all possible secrets.
 *
 * The first group of @flags is used to filter secrets by its storage
 * location. Flag VIR_CONNECT_LIST_SECRETS_EPHEMERAL selects secrets that
 * are kept only in memory. Flag VIR_CONNECT_LIST_SECRETS_NO_EPHEMERAL
 * selects secrets that are kept in persistent storage.
 *
 * The second group of @flags is used to filter secrets by privacy. Flag
 * VIR_CONNECT_LIST_SECRETS_PRIVATE seclets secrets that are never revealed
 * to any caller of libvirt nor to any other node. Flag
 * VIR_CONNECT_LIST_SECRETS_NO_PRIVATE selects non-private secrets.
 *
 * Returns the number of secrets found or -1 and sets @secrets to NULL in case
 * of error.  On success, the array stored into @secrets is guaranteed to
 * have an extra allocated element set to NULL but not included in the return count,
 * to make iteration easier.  The caller is responsible for calling
 * virSecretFree() on each array element, then calling free() on @secrets.
 */
int
virConnectListAllSecrets(virConnectPtr conn,
                         virSecretPtr **secrets,
                         unsigned int flags)
{
    VIR_DEBUG("conn=%p, secrets=%p, flags=%x", conn, secrets, flags);

    virResetLastError();

    if (secrets)
        *secrets = NULL;

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->secretDriver &&
15205
        conn->secretDriver->connectListAllSecrets) {
15206
        int ret;
15207
        ret = conn->secretDriver->connectListAllSecrets(conn, secrets, flags);
15208 15209 15210 15211 15212 15213 15214 15215 15216 15217 15218 15219
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

15220 15221 15222 15223 15224 15225 15226 15227 15228 15229 15230 15231 15232 15233 15234 15235 15236 15237
/**
 * virConnectListSecrets:
 * @conn: virConnect connection
 * @uuids: Pointer to an array to store the UUIDs
 * @maxuuids: size of the array.
 *
 * List UUIDs of defined secrets, store pointers to names in uuids.
 *
 * Returns the number of UUIDs provided in the array, or -1 on failure.
 */
int
virConnectListSecrets(virConnectPtr conn, char **uuids, int maxuuids)
{
    VIR_DEBUG("conn=%p, uuids=%p, maxuuids=%d", conn, uuids, maxuuids);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
15238
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15239
        virDispatchError(NULL);
15240 15241
        return -1;
    }
15242 15243
    virCheckNonNullArgGoto(uuids, error);
    virCheckNonNegativeArgGoto(maxuuids, error);
15244

15245
    if (conn->secretDriver != NULL && conn->secretDriver->connectListSecrets != NULL) {
15246 15247
        int ret;

15248
        ret = conn->secretDriver->connectListSecrets(conn, uuids, maxuuids);
15249 15250 15251 15252 15253
        if (ret < 0)
            goto error;
        return ret;
    }

15254
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15255 15256

error:
15257
    virDispatchError(conn);
15258 15259 15260 15261
    return -1;
}

/**
15262 15263 15264
 * virSecretLookupByUUID:
 * @conn: pointer to the hypervisor connection
 * @uuid: the raw UUID for the secret
15265
 *
15266 15267
 * Try to lookup a secret on the given hypervisor based on its UUID.
 * Uses the 16 bytes of raw data to describe the UUID
15268
 *
15269 15270
 * Returns a new secret object or NULL in case of failure.  If the
 * secret cannot be found, then VIR_ERR_NO_SECRET error is raised.
15271 15272
 */
virSecretPtr
15273
virSecretLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
15274
{
15275
    VIR_UUID_DEBUG(conn, uuid);
15276 15277 15278 15279

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
15280
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15281
        virDispatchError(NULL);
15282
        return NULL;
15283
    }
15284
    virCheckNonNullArgGoto(uuid, error);
15285

15286
    if (conn->secretDriver &&
15287
        conn->secretDriver->secretLookupByUUID) {
15288
        virSecretPtr ret;
15289
        ret = conn->secretDriver->secretLookupByUUID(conn, uuid);
15290
        if (!ret)
15291 15292 15293 15294
            goto error;
        return ret;
    }

15295
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15296 15297

error:
15298
    virDispatchError(conn);
15299 15300 15301
    return NULL;
}

15302 15303 15304 15305 15306 15307 15308 15309 15310 15311 15312 15313 15314 15315 15316
/**
 * virSecretLookupByUUIDString:
 * @conn: pointer to the hypervisor connection
 * @uuidstr: the string UUID for the secret
 *
 * Try to lookup a secret on the given hypervisor based on its UUID.
 * Uses the printable string value to describe the UUID
 *
 * Returns a new secret object or NULL in case of failure.  If the
 * secret cannot be found, then VIR_ERR_NO_SECRET error is raised.
 */
virSecretPtr
virSecretLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
{
    unsigned char uuid[VIR_UUID_BUFLEN];
15317
    VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
15318 15319 15320 15321

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
15322
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15323
        virDispatchError(NULL);
15324
        return NULL;
15325
    }
15326
    virCheckNonNullArgGoto(uuidstr, error);
15327 15328

    if (virUUIDParse(uuidstr, uuid) < 0) {
15329 15330 15331
        virReportInvalidArg(uuidstr,
                            _("uuidstr in %s must be a valid UUID"),
                            __FUNCTION__);
15332 15333 15334 15335 15336 15337
        goto error;
    }

    return virSecretLookupByUUID(conn, &uuid[0]);

error:
15338
    virDispatchError(conn);
15339 15340 15341 15342
    return NULL;
}


15343 15344 15345 15346 15347 15348 15349 15350 15351 15352 15353 15354 15355 15356 15357 15358 15359 15360
/**
 * virSecretLookupByUsage:
 * @conn: pointer to the hypervisor connection
 * @usageType: the type of secret usage
 * @usageID: identifier of the object using the secret
 *
 * Try to lookup a secret on the given hypervisor based on its usage
 * The usageID is unique within the set of secrets sharing the
 * same usageType value.
 *
 * Returns a new secret object or NULL in case of failure.  If the
 * secret cannot be found, then VIR_ERR_NO_SECRET error is raised.
 */
virSecretPtr
virSecretLookupByUsage(virConnectPtr conn,
                       int usageType,
                       const char *usageID)
{
15361
    VIR_DEBUG("conn=%p, usageType=%d usageID=%s", conn, usageType, NULLSTR(usageID));
15362 15363 15364 15365

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
15366
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15367
        virDispatchError(NULL);
15368
        return NULL;
15369
    }
15370
    virCheckNonNullArgGoto(usageID, error);
15371 15372

    if (conn->secretDriver &&
15373
        conn->secretDriver->secretLookupByUsage) {
15374
        virSecretPtr ret;
15375
        ret = conn->secretDriver->secretLookupByUsage(conn, usageType, usageID);
15376 15377 15378 15379 15380
        if (!ret)
            goto error;
        return ret;
    }

15381
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15382 15383

error:
15384
    virDispatchError(conn);
15385 15386 15387 15388
    return NULL;
}


15389 15390 15391 15392
/**
 * virSecretDefineXML:
 * @conn: virConnect connection
 * @xml: XML describing the secret.
15393
 * @flags: extra flags; not used yet, so callers should always pass 0
15394
 *
D
Dan Kenigsberg 已提交
15395
 * If XML specifies a UUID, locates the specified secret and replaces all
15396 15397 15398 15399 15400 15401 15402 15403 15404 15405 15406
 * attributes of the secret specified by UUID by attributes specified in xml
 * (any attributes not specified in xml are discarded).
 *
 * Otherwise, creates a new secret with an automatically chosen UUID, and
 * initializes its attributes from xml.
 *
 * Returns a the secret on success, NULL on failure.
 */
virSecretPtr
virSecretDefineXML(virConnectPtr conn, const char *xml, unsigned int flags)
{
15407
    VIR_DEBUG("conn=%p, xml=%s, flags=%x", conn, xml, flags);
15408 15409 15410 15411

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
15412
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15413
        virDispatchError(NULL);
15414 15415 15416
        return NULL;
    }
    if (conn->flags & VIR_CONNECT_RO) {
15417
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
15418 15419
        goto error;
    }
15420
    virCheckNonNullArgGoto(xml, error);
15421

15422
    if (conn->secretDriver != NULL && conn->secretDriver->secretDefineXML != NULL) {
15423 15424
        virSecretPtr ret;

15425
        ret = conn->secretDriver->secretDefineXML(conn, xml, flags);
15426 15427 15428 15429 15430
        if (ret == NULL)
            goto error;
        return ret;
    }

15431
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15432 15433

error:
15434
    virDispatchError(conn);
15435 15436 15437 15438
    return NULL;
}

/**
15439
 * virSecretGetUUID:
15440
 * @secret: A virSecret secret
15441
 * @uuid: buffer of VIR_UUID_BUFLEN bytes in size
15442 15443 15444
 *
 * Fetches the UUID of the secret.
 *
15445 15446
 * Returns 0 on success with the uuid buffer being filled, or
 * -1 upon failure.
15447
 */
15448 15449
int
virSecretGetUUID(virSecretPtr secret, unsigned char *uuid)
15450 15451 15452 15453 15454 15455
{
    VIR_DEBUG("secret=%p", secret);

    virResetLastError();

    if (!VIR_IS_CONNECTED_SECRET(secret)) {
15456
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15457
        virDispatchError(NULL);
15458 15459
        return -1;
    }
15460
    virCheckNonNullArgGoto(uuid, error);
15461

15462 15463 15464
    memcpy(uuid, &secret->uuid[0], VIR_UUID_BUFLEN);

    return 0;
15465 15466 15467 15468

error:
    virDispatchError(secret->conn);
    return -1;
15469 15470 15471 15472 15473 15474 15475 15476 15477 15478 15479 15480 15481 15482 15483 15484
}

/**
 * virSecretGetUUIDString:
 * @secret: a secret object
 * @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
 *
 * Get the UUID for a secret as string. For more information about
 * UUID see RFC4122.
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virSecretGetUUIDString(virSecretPtr secret, char *buf)
{
    unsigned char uuid[VIR_UUID_BUFLEN];
15485
    VIR_DEBUG("secret=%p, buf=%p", secret, buf);
15486 15487

    virResetLastError();
15488

15489
    if (!VIR_IS_SECRET(secret)) {
15490
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15491
        virDispatchError(NULL);
15492
        return -1;
15493
    }
15494
    virCheckNonNullArgGoto(buf, error);
15495 15496 15497 15498 15499

    if (virSecretGetUUID(secret, &uuid[0]))
        goto error;

    virUUIDFormat(uuid, buf);
15500
    return 0;
15501 15502

error:
15503
    virDispatchError(secret->conn);
15504
    return -1;
15505 15506
}

15507 15508 15509 15510 15511 15512 15513 15514 15515 15516 15517 15518 15519 15520 15521 15522
/**
 * virSecretGetUsageType:
 * @secret: a secret object
 *
 * Get the type of object which uses this secret. The returned
 * value is one of the constants defined in the virSecretUsageType
 * enumeration. More values may be added to this enumeration in
 * the future, so callers should expect to see usage types they
 * do not explicitly know about.
 *
 * Returns a positive integer identifying the type of object,
 * or -1 upon error.
 */
int
virSecretGetUsageType(virSecretPtr secret)
{
15523
    VIR_DEBUG("secret=%p", secret);
15524 15525 15526 15527

    virResetLastError();

    if (!VIR_IS_SECRET(secret)) {
15528
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15529
        virDispatchError(NULL);
15530
        return -1;
15531
    }
15532
    return secret->usageType;
15533 15534 15535 15536 15537 15538 15539 15540 15541 15542 15543 15544 15545 15546 15547 15548 15549 15550 15551 15552 15553
}

/**
 * virSecretGetUsageID:
 * @secret: a secret object
 *
 * Get the unique identifier of the object with which this
 * secret is to be used. The format of the identifier is
 * dependant on the usage type of the secret. For a secret
 * with a usage type of VIR_SECRET_USAGE_TYPE_VOLUME the
 * identifier will be a fully qualfied path name. The
 * identifiers are intended to be unique within the set of
 * all secrets sharing the same usage type. ie, there shall
 * only ever be one secret for each volume path.
 *
 * Returns a string identifying the object using the secret,
 * or NULL upon error
 */
const char *
virSecretGetUsageID(virSecretPtr secret)
{
15554
    VIR_DEBUG("secret=%p", secret);
15555 15556 15557 15558

    virResetLastError();

    if (!VIR_IS_SECRET(secret)) {
15559
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15560
        virDispatchError(NULL);
15561
        return NULL;
15562
    }
15563
    return secret->usageID;
15564 15565
}

15566

15567 15568 15569
/**
 * virSecretGetXMLDesc:
 * @secret: A virSecret secret
15570
 * @flags: extra flags; not used yet, so callers should always pass 0
15571 15572 15573 15574 15575 15576 15577 15578 15579 15580 15581
 *
 * Fetches an XML document describing attributes of the secret.
 *
 * Returns the XML document on success, NULL on failure.  The caller must
 * free() the XML.
 */
char *
virSecretGetXMLDesc(virSecretPtr secret, unsigned int flags)
{
    virConnectPtr conn;

15582
    VIR_DEBUG("secret=%p, flags=%x", secret, flags);
15583 15584 15585 15586

    virResetLastError();

    if (!VIR_IS_CONNECTED_SECRET(secret)) {
15587
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15588
        virDispatchError(NULL);
15589 15590 15591 15592
        return NULL;
    }

    conn = secret->conn;
15593
    if (conn->secretDriver != NULL && conn->secretDriver->secretGetXMLDesc != NULL) {
15594 15595
        char *ret;

15596
        ret = conn->secretDriver->secretGetXMLDesc(secret, flags);
15597 15598 15599 15600 15601
        if (ret == NULL)
            goto error;
        return ret;
    }

15602
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15603 15604

error:
15605
    virDispatchError(conn);
15606 15607 15608 15609 15610 15611 15612 15613
    return NULL;
}

/**
 * virSecretSetValue:
 * @secret: A virSecret secret
 * @value: Value of the secret
 * @value_size: Size of the value
15614
 * @flags: extra flags; not used yet, so callers should always pass 0
15615 15616 15617 15618 15619 15620 15621 15622 15623 15624 15625
 *
 * Sets the value of a secret.
 *
 * Returns 0 on success, -1 on failure.
 */
int
virSecretSetValue(virSecretPtr secret, const unsigned char *value,
                  size_t value_size, unsigned int flags)
{
    virConnectPtr conn;

15626
    VIR_DEBUG("secret=%p, value=%p, value_size=%zu, flags=%x", secret, value,
15627 15628 15629 15630 15631
              value_size, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_SECRET(secret)) {
15632
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15633
        virDispatchError(NULL);
15634 15635 15636 15637
        return -1;
    }
    conn = secret->conn;
    if (conn->flags & VIR_CONNECT_RO) {
15638
        virLibSecretError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
15639 15640
        goto error;
    }
15641
    virCheckNonNullArgGoto(value, error);
15642

15643
    if (conn->secretDriver != NULL && conn->secretDriver->secretSetValue != NULL) {
15644 15645
        int ret;

15646
        ret = conn->secretDriver->secretSetValue(secret, value, value_size, flags);
15647 15648 15649 15650 15651
        if (ret < 0)
            goto error;
        return ret;
    }

15652
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15653 15654

error:
15655
    virDispatchError(conn);
15656 15657 15658 15659 15660 15661 15662
    return -1;
}

/**
 * virSecretGetValue:
 * @secret: A virSecret connection
 * @value_size: Place for storing size of the secret value
15663
 * @flags: extra flags; not used yet, so callers should always pass 0
15664 15665 15666 15667 15668 15669 15670 15671 15672 15673 15674
 *
 * Fetches the value of a secret.
 *
 * Returns the secret value on success, NULL on failure.  The caller must
 * free() the secret value.
 */
unsigned char *
virSecretGetValue(virSecretPtr secret, size_t *value_size, unsigned int flags)
{
    virConnectPtr conn;

15675
    VIR_DEBUG("secret=%p, value_size=%p, flags=%x", secret, value_size, flags);
15676 15677 15678 15679

    virResetLastError();

    if (!VIR_IS_CONNECTED_SECRET(secret)) {
15680
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15681
        virDispatchError(NULL);
15682 15683 15684 15685
        return NULL;
    }
    conn = secret->conn;
    if (conn->flags & VIR_CONNECT_RO) {
15686
        virLibSecretError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
15687 15688
        goto error;
    }
15689
    virCheckNonNullArgGoto(value_size, error);
15690

15691
    if (conn->secretDriver != NULL && conn->secretDriver->secretGetValue != NULL) {
15692 15693
        unsigned char *ret;

15694
        ret = conn->secretDriver->secretGetValue(secret, value_size, flags, 0);
15695 15696 15697 15698 15699
        if (ret == NULL)
            goto error;
        return ret;
    }

15700
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15701 15702

error:
15703
    virDispatchError(conn);
15704 15705 15706 15707 15708 15709 15710 15711 15712 15713 15714 15715 15716 15717 15718 15719 15720 15721 15722 15723 15724 15725
    return NULL;
}

/**
 * virSecretUndefine:
 * @secret: A virSecret secret
 *
 * Deletes the specified secret.  This does not free the associated
 * virSecretPtr object.
 *
 * Returns 0 on success, -1 on failure.
 */
int
virSecretUndefine(virSecretPtr secret)
{
    virConnectPtr conn;

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

    virResetLastError();

    if (!VIR_IS_CONNECTED_SECRET(secret)) {
15726
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15727
        virDispatchError(NULL);
15728 15729 15730 15731
        return -1;
    }
    conn = secret->conn;
    if (conn->flags & VIR_CONNECT_RO) {
15732
        virLibSecretError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
15733 15734 15735
        goto error;
    }

15736
    if (conn->secretDriver != NULL && conn->secretDriver->secretUndefine != NULL) {
15737 15738
        int ret;

15739
        ret = conn->secretDriver->secretUndefine(secret);
15740 15741 15742 15743 15744
        if (ret < 0)
            goto error;
        return ret;
    }

15745
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15746 15747

error:
15748
    virDispatchError(conn);
15749 15750 15751 15752 15753 15754 15755 15756 15757 15758 15759 15760 15761 15762 15763 15764 15765 15766 15767 15768 15769 15770 15771
    return -1;
}

/**
 * virSecretRef:
 * @secret: the secret to hold a reference on
 *
 * Increment the reference count on the secret. For each additional call to
 * this method, there shall be a corresponding call to virSecretFree to release
 * the reference count, once the caller no longer needs the reference to this
 * object.
 *
 * This method is typically useful for applications where multiple threads are
 * using a connection, and it is required that the connection remain open until
 * all threads have finished using it. ie, each new thread using a secret would
 * increment the reference count.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virSecretRef(virSecretPtr secret)
{
    if (!VIR_IS_CONNECTED_SECRET(secret)) {
15772
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15773
        virDispatchError(NULL);
15774 15775
        return -1;
    }
15776 15777
    VIR_DEBUG("secret=%p refs=%d", secret, secret->object.refs);
    virObjectRef(secret);
15778 15779 15780 15781 15782 15783 15784 15785 15786
    return 0;
}

/**
 * virSecretFree:
 * @secret: pointer to a secret
 *
 * Release the secret handle. The underlying secret continues to exist.
 *
15787
 * Returns 0 on success, or -1 on error
15788 15789 15790 15791
 */
int
virSecretFree(virSecretPtr secret)
{
15792
    VIR_DEBUG("secret=%p", secret);
15793 15794 15795 15796

    virResetLastError();

    if (!VIR_IS_CONNECTED_SECRET(secret)) {
15797
        virLibSecretError(VIR_ERR_INVALID_SECRET, __FUNCTION__);
15798
        virDispatchError(NULL);
15799 15800
        return -1;
    }
15801
    virObjectUnref(secret);
15802 15803
    return 0;
}
15804 15805 15806 15807 15808


/**
 * virStreamNew:
 * @conn: pointer to the connection
15809
 * @flags: bitwise-OR of virStreamFlags
15810 15811 15812 15813 15814 15815 15816 15817 15818 15819 15820 15821 15822 15823 15824 15825 15826 15827 15828 15829 15830
 *
 * Creates a new stream object which can be used to perform
 * streamed I/O with other public API function.
 *
 * When no longer needed, a stream object must be released
 * with virStreamFree. If a data stream has been used,
 * then the application must call virStreamFinish or
 * virStreamAbort before free'ing to, in order to notify
 * the driver of termination.
 *
 * If a non-blocking data stream is required passed
 * VIR_STREAM_NONBLOCK for flags, otherwise pass 0.
 *
 * Returns the new stream, or NULL upon error
 */
virStreamPtr
virStreamNew(virConnectPtr conn,
             unsigned int flags)
{
    virStreamPtr st;

15831
    VIR_DEBUG("conn=%p, flags=%x", conn, flags);
15832 15833 15834 15835

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
15836
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15837
        virDispatchError(NULL);
15838
        return NULL;
15839 15840 15841 15842 15843
    }

    st = virGetStream(conn);
    if (st)
        st->flags = flags;
15844 15845
    else
        virDispatchError(conn);
15846 15847 15848 15849 15850 15851 15852 15853 15854 15855 15856 15857 15858 15859 15860 15861 15862 15863 15864 15865

    return st;
}


/**
 * virStreamRef:
 * @stream: pointer to the stream
 *
 * Increment the reference count on the stream. For each
 * additional call to this method, there shall be a corresponding
 * call to virStreamFree to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * Returns 0 in case of success, -1 in case of failure
 */
int
virStreamRef(virStreamPtr stream)
{
    if ((!VIR_IS_CONNECTED_STREAM(stream))) {
15866
        virLibConnError(VIR_ERR_INVALID_STREAM, __FUNCTION__);
15867
        virDispatchError(NULL);
15868
        return -1;
15869
    }
15870 15871
    VIR_DEBUG("stream=%p refs=%d", stream, stream->object.refs);
    virObjectRef(stream);
15872 15873 15874 15875 15876 15877 15878 15879 15880 15881 15882 15883 15884
    return 0;
}


/**
 * virStreamSend:
 * @stream: pointer to the stream object
 * @data: buffer to write to stream
 * @nbytes: size of @data buffer
 *
 * Write a series of bytes to the stream. This method may
 * block the calling application for an arbitrary amount
 * of time. Once an application has finished sending data
15885
 * it should call virStreamFinish to wait for successful
15886
 * confirmation from the driver, or detect any error.
15887 15888
 *
 * This method may not be used if a stream source has been
15889
 * registered.
15890 15891 15892 15893 15894
 *
 * Errors are not guaranteed to be reported synchronously
 * with the call, but may instead be delayed until a
 * subsequent call.
 *
D
Dan Kenigsberg 已提交
15895
 * An example using this with a hypothetical file upload
15896 15897 15898 15899 15900 15901 15902 15903 15904 15905 15906 15907 15908 15909 15910 15911 15912 15913 15914 15915 15916 15917 15918 15919 15920 15921 15922 15923 15924 15925 15926 15927 15928 15929 15930 15931 15932 15933 15934 15935 15936 15937 15938 15939 15940 15941 15942 15943
 * API looks like
 *
 *   virStreamPtr st = virStreamNew(conn, 0);
 *   int fd = open("demo.iso", O_RDONLY)
 *
 *   virConnectUploadFile(conn, "demo.iso", st);
 *
 *   while (1) {
 *       char buf[1024];
 *       int got = read(fd, buf, 1024);
 *       if (got < 0) {
 *          virStreamAbort(st);
 *          break;
 *       }
 *       if (got == 0) {
 *          virStreamFinish(st);
 *          break;
 *       }
 *       int offset = 0;
 *       while (offset < got) {
 *          int sent = virStreamSend(st, buf+offset, got-offset)
 *          if (sent < 0) {
 *             virStreamAbort(st);
 *             goto done;
 *          }
 *          offset += sent;
 *       }
 *   }
 *   if (virStreamFinish(st) < 0)
 *      ... report an error ....
 * done:
 *   virStreamFree(st);
 *   close(fd);
 *
 * Returns the number of bytes written, which may be less
 * than requested.
 *
 * Returns -1 upon error, at which time the stream will
 * be marked as aborted, and the caller should now release
 * the stream with virStreamFree.
 *
 * Returns -2 if the outgoing transmit buffers are full &
 * the stream is marked as non-blocking.
 */
int virStreamSend(virStreamPtr stream,
                  const char *data,
                  size_t nbytes)
{
15944
    VIR_DEBUG("stream=%p, data=%p, nbytes=%zi", stream, data, nbytes);
15945 15946 15947 15948

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
15949
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
15950
        virDispatchError(NULL);
15951
        return -1;
15952 15953
    }

15954
    virCheckNonNullArgGoto(data, error);
15955

15956 15957 15958 15959 15960 15961 15962 15963 15964 15965 15966
    if (stream->driver &&
        stream->driver->streamSend) {
        int ret;
        ret = (stream->driver->streamSend)(stream, data, nbytes);
        if (ret == -2)
            return -2;
        if (ret < 0)
            goto error;
        return ret;
    }

15967
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
15968 15969

error:
15970
    virDispatchError(stream->conn);
15971 15972 15973 15974 15975 15976 15977
    return -1;
}


/**
 * virStreamRecv:
 * @stream: pointer to the stream object
15978
 * @data: buffer to read into from stream
15979 15980
 * @nbytes: size of @data buffer
 *
15981
 * Reads a series of bytes from the stream. This method may
15982 15983 15984 15985 15986 15987 15988
 * block the calling application for an arbitrary amount
 * of time.
 *
 * Errors are not guaranteed to be reported synchronously
 * with the call, but may instead be delayed until a
 * subsequent call.
 *
D
Dan Kenigsberg 已提交
15989
 * An example using this with a hypothetical file download
15990 15991 15992 15993 15994 15995 15996 15997 15998 15999 16000 16001 16002 16003 16004 16005 16006 16007 16008 16009 16010 16011 16012 16013 16014 16015 16016 16017 16018 16019 16020 16021 16022 16023 16024 16025 16026 16027 16028 16029 16030 16031 16032 16033 16034 16035 16036 16037 16038 16039 16040
 * API looks like
 *
 *   virStreamPtr st = virStreamNew(conn, 0);
 *   int fd = open("demo.iso", O_WRONLY, 0600)
 *
 *   virConnectDownloadFile(conn, "demo.iso", st);
 *
 *   while (1) {
 *       char buf[1024];
 *       int got = virStreamRecv(st, buf, 1024);
 *       if (got < 0)
 *          break;
 *       if (got == 0) {
 *          virStreamFinish(st);
 *          break;
 *       }
 *       int offset = 0;
 *       while (offset < got) {
 *          int sent = write(fd, buf+offset, got-offset)
 *          if (sent < 0) {
 *             virStreamAbort(st);
 *             goto done;
 *          }
 *          offset += sent;
 *       }
 *   }
 *   if (virStreamFinish(st) < 0)
 *      ... report an error ....
 * done:
 *   virStreamFree(st);
 *   close(fd);
 *
 *
 * Returns the number of bytes read, which may be less
 * than requested.
 *
 * Returns 0 when the end of the stream is reached, at
 * which time the caller should invoke virStreamFinish()
 * to get confirmation of stream completion.
 *
 * Returns -1 upon error, at which time the stream will
 * be marked as aborted, and the caller should now release
 * the stream with virStreamFree.
 *
 * Returns -2 if there is no data pending to be read & the
 * stream is marked as non-blocking.
 */
int virStreamRecv(virStreamPtr stream,
                  char *data,
                  size_t nbytes)
{
16041
    VIR_DEBUG("stream=%p, data=%p, nbytes=%zi", stream, data, nbytes);
16042 16043 16044 16045

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
16046
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16047
        virDispatchError(NULL);
16048
        return -1;
16049 16050
    }

16051
    virCheckNonNullArgGoto(data, error);
16052

16053 16054 16055 16056 16057 16058 16059 16060 16061 16062 16063
    if (stream->driver &&
        stream->driver->streamRecv) {
        int ret;
        ret = (stream->driver->streamRecv)(stream, data, nbytes);
        if (ret == -2)
            return -2;
        if (ret < 0)
            goto error;
        return ret;
    }

16064
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16065 16066

error:
16067
    virDispatchError(stream->conn);
16068 16069 16070 16071 16072 16073 16074 16075 16076 16077 16078 16079 16080 16081
    return -1;
}


/**
 * virStreamSendAll:
 * @stream: pointer to the stream object
 * @handler: source callback for reading data from application
 * @opaque: application defined data
 *
 * Send the entire data stream, reading the data from the
 * requested data source. This is simply a convenient alternative
 * to virStreamSend, for apps that do blocking-I/o.
 *
D
Dan Kenigsberg 已提交
16082
 * An example using this with a hypothetical file upload
16083 16084 16085 16086 16087 16088 16089 16090 16091 16092 16093 16094 16095 16096 16097 16098 16099 16100 16101 16102 16103
 * API looks like
 *
 *   int mysource(virStreamPtr st, char *buf, int nbytes, void *opaque) {
 *       int *fd = opaque;
 *
 *       return read(*fd, buf, nbytes);
 *   }
 *
 *   virStreamPtr st = virStreamNew(conn, 0);
 *   int fd = open("demo.iso", O_RDONLY)
 *
 *   virConnectUploadFile(conn, st);
 *   if (virStreamSendAll(st, mysource, &fd) < 0) {
 *      ...report an error ...
 *      goto done;
 *   }
 *   if (virStreamFinish(st) < 0)
 *      ...report an error...
 *   virStreamFree(st);
 *   close(fd);
 *
16104
 * Returns 0 if all the data was successfully sent. The caller
16105 16106 16107 16108 16109 16110 16111 16112 16113 16114 16115 16116 16117 16118
 * should invoke virStreamFinish(st) to flush the stream upon
 * success and then virStreamFree
 *
 * Returns -1 upon any error, with virStreamAbort() already
 * having been called,  so the caller need only call
 * virStreamFree()
 */
int virStreamSendAll(virStreamPtr stream,
                     virStreamSourceFunc handler,
                     void *opaque)
{
    char *bytes = NULL;
    int want = 1024*64;
    int ret = -1;
16119
    VIR_DEBUG("stream=%p, handler=%p, opaque=%p", stream, handler, opaque);
16120 16121 16122 16123

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
16124
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16125
        virDispatchError(NULL);
16126
        return -1;
16127 16128
    }

16129
    virCheckNonNullArgGoto(handler, cleanup);
16130

16131
    if (stream->flags & VIR_STREAM_NONBLOCK) {
16132
        virLibConnError(VIR_ERR_OPERATION_INVALID, "%s",
16133 16134 16135 16136 16137
                        _("data sources cannot be used for non-blocking streams"));
        goto cleanup;
    }

    if (VIR_ALLOC_N(bytes, want) < 0) {
16138
        virReportOOMError();
16139 16140 16141 16142 16143 16144 16145 16146 16147 16148 16149 16150 16151 16152 16153 16154 16155 16156 16157 16158 16159 16160 16161 16162 16163 16164
        goto cleanup;
    }

    for (;;) {
        int got, offset = 0;
        got = (handler)(stream, bytes, want, opaque);
        if (got < 0) {
            virStreamAbort(stream);
            goto cleanup;
        }
        if (got == 0)
            break;
        while (offset < got) {
            int done;
            done = virStreamSend(stream, bytes + offset, got - offset);
            if (done < 0)
                goto cleanup;
            offset += done;
        }
    }
    ret = 0;

cleanup:
    VIR_FREE(bytes);

    if (ret != 0)
16165
        virDispatchError(stream->conn);
16166 16167 16168 16169 16170 16171 16172 16173 16174 16175 16176 16177 16178 16179 16180

    return ret;
}


/**
 * virStreamRecvAll:
 * @stream: pointer to the stream object
 * @handler: sink callback for writing data to application
 * @opaque: application defined data
 *
 * Receive the entire data stream, sending the data to the
 * requested data sink. This is simply a convenient alternative
 * to virStreamRecv, for apps that do blocking-I/o.
 *
D
Dan Kenigsberg 已提交
16181
 * An example using this with a hypothetical file download
16182 16183 16184 16185 16186 16187 16188 16189 16190 16191 16192 16193 16194 16195 16196 16197 16198 16199 16200 16201 16202
 * API looks like
 *
 *   int mysink(virStreamPtr st, const char *buf, int nbytes, void *opaque) {
 *       int *fd = opaque;
 *
 *       return write(*fd, buf, nbytes);
 *   }
 *
 *   virStreamPtr st = virStreamNew(conn, 0);
 *   int fd = open("demo.iso", O_WRONLY)
 *
 *   virConnectUploadFile(conn, st);
 *   if (virStreamRecvAll(st, mysink, &fd) < 0) {
 *      ...report an error ...
 *      goto done;
 *   }
 *   if (virStreamFinish(st) < 0)
 *      ...report an error...
 *   virStreamFree(st);
 *   close(fd);
 *
16203
 * Returns 0 if all the data was successfully received. The caller
16204 16205 16206 16207 16208 16209 16210 16211 16212 16213 16214 16215 16216 16217
 * should invoke virStreamFinish(st) to flush the stream upon
 * success and then virStreamFree
 *
 * Returns -1 upon any error, with virStreamAbort() already
 * having been called,  so the caller need only call
 * virStreamFree()
 */
int virStreamRecvAll(virStreamPtr stream,
                     virStreamSinkFunc handler,
                     void *opaque)
{
    char *bytes = NULL;
    int want = 1024*64;
    int ret = -1;
16218
    VIR_DEBUG("stream=%p, handler=%p, opaque=%p", stream, handler, opaque);
16219 16220 16221 16222

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
16223
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16224
        virDispatchError(NULL);
16225
        return -1;
16226 16227
    }

16228
    virCheckNonNullArgGoto(handler, cleanup);
16229

16230
    if (stream->flags & VIR_STREAM_NONBLOCK) {
16231
        virLibConnError(VIR_ERR_OPERATION_INVALID, "%s",
16232 16233 16234 16235 16236 16237
                        _("data sinks cannot be used for non-blocking streams"));
        goto cleanup;
    }


    if (VIR_ALLOC_N(bytes, want) < 0) {
16238
        virReportOOMError();
16239 16240 16241 16242 16243 16244 16245 16246 16247 16248 16249 16250 16251 16252 16253 16254 16255 16256 16257 16258 16259 16260 16261 16262 16263 16264
        goto cleanup;
    }

    for (;;) {
        int got, offset = 0;
        got = virStreamRecv(stream, bytes, want);
        if (got < 0)
            goto cleanup;
        if (got == 0)
            break;
        while (offset < got) {
            int done;
            done = (handler)(stream, bytes + offset, got - offset, opaque);
            if (done < 0) {
                virStreamAbort(stream);
                goto cleanup;
            }
            offset += done;
        }
    }
    ret = 0;

cleanup:
    VIR_FREE(bytes);

    if (ret != 0)
16265
        virDispatchError(stream->conn);
16266 16267 16268 16269 16270 16271

    return ret;
}


/**
M
Matthias Bolte 已提交
16272
 * virStreamEventAddCallback:
16273 16274 16275 16276 16277 16278 16279 16280 16281 16282 16283 16284 16285 16286 16287 16288 16289 16290 16291
 * @stream: pointer to the stream object
 * @events: set of events to monitor
 * @cb: callback to invoke when an event occurs
 * @opaque: application defined data
 * @ff: callback to free @opaque data
 *
 * Register a callback to be notified when a stream
 * becomes writable, or readable. This is most commonly
 * used in conjunction with non-blocking data streams
 * to integrate into an event loop
 *
 * Returns 0 on success, -1 upon error
 */
int virStreamEventAddCallback(virStreamPtr stream,
                              int events,
                              virStreamEventCallback cb,
                              void *opaque,
                              virFreeCallback ff)
{
16292
    VIR_DEBUG("stream=%p, events=%d, cb=%p, opaque=%p, ff=%p", stream, events, cb, opaque, ff);
16293 16294 16295 16296

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
16297
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16298
        virDispatchError(NULL);
16299
        return -1;
16300 16301 16302
    }

    if (stream->driver &&
16303
        stream->driver->streamEventAddCallback) {
16304
        int ret;
16305
        ret = (stream->driver->streamEventAddCallback)(stream, events, cb, opaque, ff);
16306 16307 16308 16309 16310
        if (ret < 0)
            goto error;
        return ret;
    }

16311
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16312 16313

error:
16314
    virDispatchError(stream->conn);
16315 16316 16317 16318 16319
    return -1;
}


/**
M
Matthias Bolte 已提交
16320
 * virStreamEventUpdateCallback:
16321 16322 16323 16324 16325 16326
 * @stream: pointer to the stream object
 * @events: set of events to monitor
 *
 * Changes the set of events to monitor for a stream. This allows
 * for event notification to be changed without having to
 * unregister & register the callback completely. This method
E
Eric Blake 已提交
16327
 * is guaranteed to succeed if a callback is already registered
16328 16329 16330 16331 16332 16333
 *
 * Returns 0 on success, -1 if no callback is registered
 */
int virStreamEventUpdateCallback(virStreamPtr stream,
                                 int events)
{
16334
    VIR_DEBUG("stream=%p, events=%d", stream, events);
16335 16336 16337 16338

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
16339
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16340
        virDispatchError(NULL);
16341
        return -1;
16342 16343 16344
    }

    if (stream->driver &&
16345
        stream->driver->streamEventUpdateCallback) {
16346
        int ret;
16347
        ret = (stream->driver->streamEventUpdateCallback)(stream, events);
16348 16349 16350 16351 16352
        if (ret < 0)
            goto error;
        return ret;
    }

16353
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16354 16355

error:
16356
    virDispatchError(stream->conn);
16357 16358 16359 16360
    return -1;
}

/**
M
Matthias Bolte 已提交
16361
 * virStreamEventRemoveCallback:
16362 16363
 * @stream: pointer to the stream object
 *
D
Dan Kenigsberg 已提交
16364
 * Remove an event callback from the stream
16365 16366 16367 16368 16369
 *
 * Returns 0 on success, -1 on error
 */
int virStreamEventRemoveCallback(virStreamPtr stream)
{
16370
    VIR_DEBUG("stream=%p", stream);
16371 16372 16373 16374

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
16375
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16376
        virDispatchError(NULL);
16377
        return -1;
16378 16379 16380
    }

    if (stream->driver &&
16381
        stream->driver->streamEventRemoveCallback) {
16382
        int ret;
16383
        ret = (stream->driver->streamEventRemoveCallback)(stream);
16384 16385 16386 16387 16388
        if (ret < 0)
            goto error;
        return ret;
    }

16389
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16390 16391

error:
16392
    virDispatchError(stream->conn);
16393 16394 16395 16396 16397 16398 16399 16400 16401 16402 16403 16404 16405 16406 16407 16408 16409 16410 16411 16412
    return -1;
}

/**
 * virStreamFinish:
 * @stream: pointer to the stream object
 *
 * Indicate that there is no further data is to be transmitted
 * on the stream. For output streams this should be called once
 * all data has been written. For input streams this should be
 * called once virStreamRecv returns end-of-file.
 *
 * This method is a synchronization point for all asynchronous
 * errors, so if this returns a success code the application can
 * be sure that all data has been successfully processed.
 *
 * Returns 0 on success, -1 upon error
 */
int virStreamFinish(virStreamPtr stream)
{
16413
    VIR_DEBUG("stream=%p", stream);
16414 16415 16416 16417

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
16418
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16419
        virDispatchError(NULL);
16420
        return -1;
16421 16422 16423 16424 16425 16426 16427 16428 16429 16430 16431
    }

    if (stream->driver &&
        stream->driver->streamFinish) {
        int ret;
        ret = (stream->driver->streamFinish)(stream);
        if (ret < 0)
            goto error;
        return ret;
    }

16432
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16433 16434

error:
16435
    virDispatchError(stream->conn);
16436 16437 16438 16439 16440 16441 16442 16443 16444 16445 16446 16447 16448 16449 16450 16451 16452 16453
    return -1;
}

/**
 * virStreamAbort:
 * @stream: pointer to the stream object
 *
 * Request that the in progress data transfer be cancelled
 * abnormally before the end of the stream has been reached.
 * For output streams this can be used to inform the driver
 * that the stream is being terminated early. For input
 * streams this can be used to inform the driver that it
 * should stop sending data.
 *
 * Returns 0 on success, -1 upon error
 */
int virStreamAbort(virStreamPtr stream)
{
16454
    VIR_DEBUG("stream=%p", stream);
16455 16456 16457 16458

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
16459
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16460
        virDispatchError(NULL);
16461
        return -1;
16462 16463
    }

16464 16465 16466 16467 16468 16469
    if (!stream->driver) {
        VIR_DEBUG("aborting unused stream");
        return 0;
    }

    if (stream->driver->streamAbort) {
16470 16471 16472 16473 16474 16475 16476
        int ret;
        ret = (stream->driver->streamAbort)(stream);
        if (ret < 0)
            goto error;
        return ret;
    }

16477
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16478 16479

error:
16480
    virDispatchError(stream->conn);
16481 16482 16483 16484 16485 16486 16487 16488 16489 16490
    return -1;
}

/**
 * virStreamFree:
 * @stream: pointer to the stream object
 *
 * Decrement the reference count on a stream, releasing
 * the stream object if the reference count has hit zero.
 *
D
Dan Kenigsberg 已提交
16491
 * There must not be an active data transfer in progress
16492 16493 16494 16495 16496 16497 16498 16499
 * when releasing the stream. If a stream needs to be
 * disposed of prior to end of stream being reached, then
 * the virStreamAbort function should be called first.
 *
 * Returns 0 upon success, or -1 on error
 */
int virStreamFree(virStreamPtr stream)
{
16500
    VIR_DEBUG("stream=%p", stream);
16501 16502 16503 16504

    virResetLastError();

    if (!VIR_IS_CONNECTED_STREAM(stream)) {
16505
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16506
        virDispatchError(NULL);
16507
        return -1;
16508 16509 16510 16511
    }

    /* XXX Enforce shutdown before free'ing resources ? */

16512
    virObjectUnref(stream);
16513
    return 0;
16514
}
16515 16516 16517 16518 16519 16520 16521 16522 16523 16524 16525 16526


/**
 * virDomainIsActive:
 * @dom: pointer to the domain object
 *
 * Determine if the domain is currently running
 *
 * Returns 1 if running, 0 if inactive, -1 on error
 */
int virDomainIsActive(virDomainPtr dom)
{
16527
    VIR_DEBUG("dom=%p", dom);
16528 16529 16530 16531

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
16532
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16533
        virDispatchError(NULL);
16534
        return -1;
16535 16536 16537 16538 16539 16540 16541 16542 16543
    }
    if (dom->conn->driver->domainIsActive) {
        int ret;
        ret = dom->conn->driver->domainIsActive(dom);
        if (ret < 0)
            goto error;
        return ret;
    }

16544
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16545
error:
16546
    virDispatchError(dom->conn);
16547 16548 16549 16550 16551 16552 16553 16554 16555 16556 16557 16558 16559 16560
    return -1;
}

/**
 * virDomainIsPersistent:
 * @dom: pointer to the domain object
 *
 * Determine if the domain has a persistent configuration
 * which means it will still exist after shutting down
 *
 * Returns 1 if persistent, 0 if transient, -1 on error
 */
int virDomainIsPersistent(virDomainPtr dom)
{
16561
    VIR_DOMAIN_DEBUG(dom);
16562 16563 16564 16565

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
16566
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16567
        virDispatchError(NULL);
16568
        return -1;
16569 16570 16571 16572 16573 16574 16575 16576 16577
    }
    if (dom->conn->driver->domainIsPersistent) {
        int ret;
        ret = dom->conn->driver->domainIsPersistent(dom);
        if (ret < 0)
            goto error;
        return ret;
    }

16578
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16579
error:
16580
    virDispatchError(dom->conn);
16581 16582 16583
    return -1;
}

16584 16585 16586 16587 16588 16589 16590 16591 16592 16593
/**
 * virDomainIsUpdated:
 * @dom: pointer to the domain object
 *
 * Determine if the domain has been updated.
 *
 * Returns 1 if updated, 0 if not, -1 on error
 */
int virDomainIsUpdated(virDomainPtr dom)
{
16594
    VIR_DOMAIN_DEBUG(dom);
16595 16596 16597 16598

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
16599
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16600
        virDispatchError(NULL);
16601
        return -1;
16602 16603 16604 16605 16606 16607 16608 16609 16610
    }
    if (dom->conn->driver->domainIsUpdated) {
        int ret;
        ret = dom->conn->driver->domainIsUpdated(dom);
        if (ret < 0)
            goto error;
        return ret;
    }

16611
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16612 16613 16614 16615 16616
error:
    virDispatchError(dom->conn);
    return -1;
}

16617 16618 16619 16620 16621 16622 16623 16624 16625 16626
/**
 * virNetworkIsActive:
 * @net: pointer to the network object
 *
 * Determine if the network is currently running
 *
 * Returns 1 if running, 0 if inactive, -1 on error
 */
int virNetworkIsActive(virNetworkPtr net)
{
16627
    VIR_DEBUG("net=%p", net);
16628 16629 16630 16631

    virResetLastError();

    if (!VIR_IS_CONNECTED_NETWORK(net)) {
16632
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16633
        virDispatchError(NULL);
16634
        return -1;
16635 16636 16637 16638 16639 16640 16641 16642 16643
    }
    if (net->conn->networkDriver->networkIsActive) {
        int ret;
        ret = net->conn->networkDriver->networkIsActive(net);
        if (ret < 0)
            goto error;
        return ret;
    }

16644
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16645
error:
16646
    virDispatchError(net->conn);
16647 16648 16649 16650 16651 16652 16653 16654 16655 16656 16657 16658 16659 16660 16661
    return -1;
}


/**
 * virNetworkIsPersistent:
 * @net: pointer to the network object
 *
 * Determine if the network has a persistent configuration
 * which means it will still exist after shutting down
 *
 * Returns 1 if persistent, 0 if transient, -1 on error
 */
int virNetworkIsPersistent(virNetworkPtr net)
{
16662
    VIR_DEBUG("net=%p", net);
16663 16664 16665 16666

    virResetLastError();

    if (!VIR_IS_CONNECTED_NETWORK(net)) {
16667
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16668
        virDispatchError(NULL);
16669
        return -1;
16670 16671 16672 16673 16674 16675 16676 16677 16678
    }
    if (net->conn->networkDriver->networkIsPersistent) {
        int ret;
        ret = net->conn->networkDriver->networkIsPersistent(net);
        if (ret < 0)
            goto error;
        return ret;
    }

16679
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16680
error:
16681
    virDispatchError(net->conn);
16682 16683 16684 16685 16686 16687 16688 16689 16690 16691 16692 16693 16694 16695
    return -1;
}


/**
 * virStoragePoolIsActive:
 * @pool: pointer to the storage pool object
 *
 * Determine if the storage pool is currently running
 *
 * Returns 1 if running, 0 if inactive, -1 on error
 */
int virStoragePoolIsActive(virStoragePoolPtr pool)
{
16696
    VIR_DEBUG("pool=%p", pool);
16697 16698 16699 16700

    virResetLastError();

    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
16701
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16702
        virDispatchError(NULL);
16703
        return -1;
16704
    }
16705
    if (pool->conn->storageDriver->storagePoolIsActive) {
16706
        int ret;
16707
        ret = pool->conn->storageDriver->storagePoolIsActive(pool);
16708 16709 16710 16711 16712
        if (ret < 0)
            goto error;
        return ret;
    }

16713
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16714
error:
16715
    virDispatchError(pool->conn);
16716 16717 16718 16719 16720 16721 16722 16723 16724 16725 16726 16727 16728 16729 16730
    return -1;
}


/**
 * virStoragePoolIsPersistent:
 * @pool: pointer to the storage pool object
 *
 * Determine if the storage pool has a persistent configuration
 * which means it will still exist after shutting down
 *
 * Returns 1 if persistent, 0 if transient, -1 on error
 */
int virStoragePoolIsPersistent(virStoragePoolPtr pool)
{
16731
    VIR_DEBUG("pool=%p", pool);
16732 16733 16734 16735

    virResetLastError();

    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
16736
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
16737
        virDispatchError(NULL);
16738
        return -1;
16739
    }
16740
    if (pool->conn->storageDriver->storagePoolIsPersistent) {
16741
        int ret;
16742
        ret = pool->conn->storageDriver->storagePoolIsPersistent(pool);
16743 16744 16745 16746 16747
        if (ret < 0)
            goto error;
        return ret;
    }

16748
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
16749
error:
16750
    virDispatchError(pool->conn);
16751 16752 16753 16754
    return -1;
}


S
Stefan Berger 已提交
16755 16756 16757 16758 16759 16760 16761 16762 16763 16764 16765 16766

/**
 * virConnectNumOfNWFilters:
 * @conn: pointer to the hypervisor connection
 *
 * Provides the number of nwfilters.
 *
 * Returns the number of nwfilters found or -1 in case of error
 */
int
virConnectNumOfNWFilters(virConnectPtr conn)
{
16767
    VIR_DEBUG("conn=%p", conn);
S
Stefan Berger 已提交
16768 16769 16770 16771

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
16772
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
S
Stefan Berger 已提交
16773 16774 16775 16776
        virDispatchError(NULL);
        return -1;
    }

16777
    if (conn->nwfilterDriver && conn->nwfilterDriver->connectNumOfNWFilters) {
S
Stefan Berger 已提交
16778
        int ret;
16779
        ret = conn->nwfilterDriver->connectNumOfNWFilters(conn);
S
Stefan Berger 已提交
16780 16781 16782 16783 16784
        if (ret < 0)
            goto error;
        return ret;
    }

16785
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
S
Stefan Berger 已提交
16786 16787 16788 16789 16790 16791

error:
    virDispatchError(conn);
    return -1;
}

16792 16793 16794 16795 16796 16797 16798 16799 16800 16801 16802 16803 16804 16805 16806 16807 16808 16809 16810 16811 16812 16813 16814 16815 16816 16817 16818 16819 16820 16821 16822 16823 16824 16825 16826 16827
/**
 * virConnectListAllNWFilters:
 * @conn: Pointer to the hypervisor connection.
 * @filters: Pointer to a variable to store the array containing the network
 *           filter objects or NULL if the list is not required (just returns
 *           number of network filters).
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Collect the list of network filters, and allocate an array to store those
 * objects.
 *
 * Returns the number of network filters found or -1 and sets @filters to  NULL
 * in case of error.  On success, the array stored into @filters is guaranteed to
 * have an extra allocated element set to NULL but not included in the return count,
 * to make iteration easier.  The caller is responsible for calling
 * virNWFilterFree() on each array element, then calling free() on @filters.
 */
int
virConnectListAllNWFilters(virConnectPtr conn,
                           virNWFilterPtr **filters,
                           unsigned int flags)
{
    VIR_DEBUG("conn=%p, filters=%p, flags=%x", conn, filters, flags);

    virResetLastError();

    if (filters)
        *filters = NULL;

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->nwfilterDriver &&
16828
        conn->nwfilterDriver->connectListAllNWFilters) {
16829
        int ret;
16830
        ret = conn->nwfilterDriver->connectListAllNWFilters(conn, filters, flags);
16831 16832 16833 16834 16835 16836 16837 16838 16839 16840 16841
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}
S
Stefan Berger 已提交
16842 16843 16844 16845 16846 16847 16848 16849 16850 16851 16852 16853 16854 16855

/**
 * virConnectListNWFilters:
 * @conn: pointer to the hypervisor connection
 * @names: array to collect the list of names of network filters
 * @maxnames: size of @names
 *
 * Collect the list of network filters, and store their names in @names
 *
 * Returns the number of network filters found or -1 in case of error
 */
int
virConnectListNWFilters(virConnectPtr conn, char **const names, int maxnames)
{
16856
    VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
S
Stefan Berger 已提交
16857 16858 16859 16860

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
16861
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
S
Stefan Berger 已提交
16862 16863 16864 16865
        virDispatchError(NULL);
        return -1;
    }

16866 16867
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(maxnames, error);
S
Stefan Berger 已提交
16868

16869
    if (conn->nwfilterDriver && conn->nwfilterDriver->connectListNWFilters) {
S
Stefan Berger 已提交
16870
        int ret;
16871
        ret = conn->nwfilterDriver->connectListNWFilters(conn, names, maxnames);
S
Stefan Berger 已提交
16872 16873 16874 16875 16876
        if (ret < 0)
            goto error;
        return ret;
    }

16877
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
S
Stefan Berger 已提交
16878 16879 16880 16881 16882 16883 16884 16885 16886 16887 16888 16889 16890 16891 16892 16893 16894 16895 16896 16897

error:
    virDispatchError(conn);
    return -1;
}


/**
 * virNWFilterLookupByName:
 * @conn: pointer to the hypervisor connection
 * @name: name for the network filter
 *
 * Try to lookup a network filter on the given hypervisor based on its name.
 *
 * Returns a new nwfilter object or NULL in case of failure.  If the
 * network filter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
 */
virNWFilterPtr
virNWFilterLookupByName(virConnectPtr conn, const char *name)
{
16898
    VIR_DEBUG("conn=%p, name=%s", conn, name);
S
Stefan Berger 已提交
16899 16900 16901 16902

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
16903
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
S
Stefan Berger 已提交
16904
        virDispatchError(NULL);
16905
        return NULL;
S
Stefan Berger 已提交
16906
    }
16907
    virCheckNonNullArgGoto(name, error);
S
Stefan Berger 已提交
16908 16909 16910

    if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByName) {
        virNWFilterPtr ret;
16911
        ret = conn->nwfilterDriver->nwfilterLookupByName(conn, name);
S
Stefan Berger 已提交
16912 16913 16914 16915 16916
        if (!ret)
            goto error;
        return ret;
    }

16917
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
S
Stefan Berger 已提交
16918 16919 16920 16921 16922 16923 16924 16925 16926 16927 16928 16929 16930 16931 16932 16933 16934 16935 16936

error:
    virDispatchError(conn);
    return NULL;
}

/**
 * virNWFilterLookupByUUID:
 * @conn: pointer to the hypervisor connection
 * @uuid: the raw UUID for the network filter
 *
 * Try to lookup a network filter on the given hypervisor based on its UUID.
 *
 * Returns a new nwfilter object or NULL in case of failure.  If the
 * nwfdilter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
 */
virNWFilterPtr
virNWFilterLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
16937
    VIR_UUID_DEBUG(conn, uuid);
S
Stefan Berger 已提交
16938 16939 16940 16941

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
16942
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
S
Stefan Berger 已提交
16943
        virDispatchError(NULL);
16944
        return NULL;
S
Stefan Berger 已提交
16945
    }
16946
    virCheckNonNullArgGoto(uuid, error);
S
Stefan Berger 已提交
16947 16948 16949

    if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByUUID){
        virNWFilterPtr ret;
16950
        ret = conn->nwfilterDriver->nwfilterLookupByUUID(conn, uuid);
S
Stefan Berger 已提交
16951 16952 16953 16954 16955
        if (!ret)
            goto error;
        return ret;
    }

16956
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
S
Stefan Berger 已提交
16957 16958 16959 16960 16961 16962 16963

error:
    virDispatchError(conn);
    return NULL;
}

/**
16964
 * virNWFilterLookupByUUIDString:
S
Stefan Berger 已提交
16965 16966 16967 16968 16969 16970 16971 16972 16973 16974 16975 16976
 * @conn: pointer to the hypervisor connection
 * @uuidstr: the string UUID for the nwfilter
 *
 * Try to lookup an nwfilter on the given hypervisor based on its UUID.
 *
 * Returns a new nwfilter object or NULL in case of failure.  If the
 * nwfilter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
 */
virNWFilterPtr
virNWFilterLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
{
    unsigned char uuid[VIR_UUID_BUFLEN];
16977
    VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
S
Stefan Berger 已提交
16978 16979 16980 16981

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
16982
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
S
Stefan Berger 已提交
16983
        virDispatchError(NULL);
16984
        return NULL;
S
Stefan Berger 已提交
16985
    }
16986
    virCheckNonNullArgGoto(uuidstr, error);
S
Stefan Berger 已提交
16987 16988

    if (virUUIDParse(uuidstr, uuid) < 0) {
16989 16990 16991
        virReportInvalidArg(uuidstr,
                            _("uuidstr in %s must be a valid UUID"),
                            __FUNCTION__);
S
Stefan Berger 已提交
16992 16993 16994 16995 16996 16997 16998 16999 17000 17001 17002 17003 17004 17005 17006 17007 17008 17009 17010 17011 17012 17013
        goto error;
    }

    return virNWFilterLookupByUUID(conn, &uuid[0]);

error:
    virDispatchError(conn);
    return NULL;
}

/**
 * virNWFilterFree:
 * @nwfilter: a nwfilter object
 *
 * Free the nwfilter object. The running instance is kept alive.
 * The data structure is freed and should not be used thereafter.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virNWFilterFree(virNWFilterPtr nwfilter)
{
17014
    VIR_DEBUG("nwfilter=%p", nwfilter);
S
Stefan Berger 已提交
17015 17016 17017 17018

    virResetLastError();

    if (!VIR_IS_CONNECTED_NWFILTER(nwfilter)) {
17019
        virLibNWFilterError(VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
S
Stefan Berger 已提交
17020 17021 17022
        virDispatchError(NULL);
        return -1;
    }
17023 17024

    virObjectUnref(nwfilter);
S
Stefan Berger 已提交
17025 17026 17027 17028 17029 17030 17031 17032 17033 17034 17035 17036 17037 17038 17039
    return 0;
}

/**
 * virNWFilterGetName:
 * @nwfilter: a nwfilter object
 *
 * Get the public name for the network filter
 *
 * Returns a pointer to the name or NULL, the string need not be deallocated
 * its lifetime will be the same as the nwfilter object.
 */
const char *
virNWFilterGetName(virNWFilterPtr nwfilter)
{
17040
    VIR_DEBUG("nwfilter=%p", nwfilter);
S
Stefan Berger 已提交
17041 17042 17043 17044

    virResetLastError();

    if (!VIR_IS_NWFILTER(nwfilter)) {
17045
        virLibNWFilterError(VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
S
Stefan Berger 已提交
17046
        virDispatchError(NULL);
17047
        return NULL;
S
Stefan Berger 已提交
17048
    }
17049
    return nwfilter->name;
S
Stefan Berger 已提交
17050 17051 17052 17053 17054 17055 17056 17057 17058 17059 17060 17061 17062 17063
}

/**
 * virNWFilterGetUUID:
 * @nwfilter: a nwfilter object
 * @uuid: pointer to a VIR_UUID_BUFLEN bytes array
 *
 * Get the UUID for a network filter
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virNWFilterGetUUID(virNWFilterPtr nwfilter, unsigned char *uuid)
{
17064
    VIR_DEBUG("nwfilter=%p, uuid=%p", nwfilter, uuid);
S
Stefan Berger 已提交
17065 17066 17067 17068

    virResetLastError();

    if (!VIR_IS_NWFILTER(nwfilter)) {
17069
        virLibNWFilterError(VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
S
Stefan Berger 已提交
17070 17071 17072
        virDispatchError(NULL);
        return -1;
    }
17073
    virCheckNonNullArgGoto(uuid, error);
S
Stefan Berger 已提交
17074 17075 17076 17077 17078 17079 17080 17081 17082 17083 17084 17085 17086 17087 17088 17089 17090 17091 17092 17093 17094 17095 17096 17097

    memcpy(uuid, &nwfilter->uuid[0], VIR_UUID_BUFLEN);

    return 0;

error:
    virDispatchError(nwfilter->conn);
    return -1;
}

/**
 * virNWFilterGetUUIDString:
 * @nwfilter: a nwfilter object
 * @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
 *
 * Get the UUID for a network filter as string. For more information about
 * UUID see RFC4122.
 *
 * Returns -1 in case of error, 0 in case of success
 */
int
virNWFilterGetUUIDString(virNWFilterPtr nwfilter, char *buf)
{
    unsigned char uuid[VIR_UUID_BUFLEN];
17098
    VIR_DEBUG("nwfilter=%p, buf=%p", nwfilter, buf);
S
Stefan Berger 已提交
17099 17100 17101 17102

    virResetLastError();

    if (!VIR_IS_NWFILTER(nwfilter)) {
17103
        virLibNWFilterError(VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
S
Stefan Berger 已提交
17104 17105 17106
        virDispatchError(NULL);
        return -1;
    }
17107
    virCheckNonNullArgGoto(buf, error);
S
Stefan Berger 已提交
17108 17109 17110 17111 17112 17113 17114 17115 17116 17117 17118 17119 17120 17121 17122 17123 17124 17125 17126 17127 17128 17129 17130 17131 17132 17133

    if (virNWFilterGetUUID(nwfilter, &uuid[0]))
        goto error;

    virUUIDFormat(uuid, buf);
    return 0;

error:
    virDispatchError(nwfilter->conn);
    return -1;
}


/**
 * virNWFilterDefineXML:
 * @conn: pointer to the hypervisor connection
 * @xmlDesc: an XML description of the nwfilter
 *
 * Define a new network filter, based on an XML description
 * similar to the one returned by virNWFilterGetXMLDesc()
 *
 * Returns a new nwfilter object or NULL in case of failure
 */
virNWFilterPtr
virNWFilterDefineXML(virConnectPtr conn, const char *xmlDesc)
{
17134
    VIR_DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc);
S
Stefan Berger 已提交
17135 17136 17137 17138

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
17139
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
S
Stefan Berger 已提交
17140
        virDispatchError(NULL);
17141
        return NULL;
S
Stefan Berger 已提交
17142
    }
17143 17144
    virCheckNonNullArgGoto(xmlDesc, error);

S
Stefan Berger 已提交
17145
    if (conn->flags & VIR_CONNECT_RO) {
17146
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
S
Stefan Berger 已提交
17147 17148 17149
        goto error;
    }

17150
    if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterDefineXML) {
S
Stefan Berger 已提交
17151
        virNWFilterPtr ret;
17152
        ret = conn->nwfilterDriver->nwfilterDefineXML(conn, xmlDesc);
S
Stefan Berger 已提交
17153 17154 17155 17156 17157
        if (!ret)
            goto error;
        return ret;
    }

17158
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
S
Stefan Berger 已提交
17159 17160 17161 17162 17163 17164 17165 17166 17167 17168 17169 17170 17171 17172 17173 17174 17175 17176 17177 17178 17179

error:
    virDispatchError(conn);
    return NULL;
}


/**
 * virNWFilterUndefine:
 * @nwfilter: a nwfilter object
 *
 * Undefine the nwfilter object. This call will not succeed if
 * a running VM is referencing the filter. This does not free the
 * associated virNWFilterPtr object.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virNWFilterUndefine(virNWFilterPtr nwfilter)
{
    virConnectPtr conn;
17180
    VIR_DEBUG("nwfilter=%p", nwfilter);
S
Stefan Berger 已提交
17181 17182 17183 17184

    virResetLastError();

    if (!VIR_IS_CONNECTED_NWFILTER(nwfilter)) {
17185
        virLibNWFilterError(VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
S
Stefan Berger 已提交
17186 17187 17188 17189 17190 17191
        virDispatchError(NULL);
        return -1;
    }

    conn = nwfilter->conn;
    if (conn->flags & VIR_CONNECT_RO) {
17192
        virLibNWFilterError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
S
Stefan Berger 已提交
17193 17194 17195
        goto error;
    }

17196
    if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterUndefine) {
S
Stefan Berger 已提交
17197
        int ret;
17198
        ret = conn->nwfilterDriver->nwfilterUndefine(nwfilter);
S
Stefan Berger 已提交
17199 17200 17201 17202 17203
        if (ret < 0)
            goto error;
        return ret;
    }

17204
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
S
Stefan Berger 已提交
17205 17206 17207 17208 17209 17210 17211 17212 17213 17214

error:
    virDispatchError(nwfilter->conn);
    return -1;
}


/**
 * virNWFilterGetXMLDesc:
 * @nwfilter: a nwfilter object
17215
 * @flags: extra flags; not used yet, so callers should always pass 0
S
Stefan Berger 已提交
17216 17217 17218 17219 17220 17221 17222 17223
 *
 * Provide an XML description of the network filter. The description may be
 * reused later to redefine the network filter with virNWFilterCreateXML().
 *
 * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
 *         the caller must free() the returned value.
 */
char *
17224
virNWFilterGetXMLDesc(virNWFilterPtr nwfilter, unsigned int flags)
S
Stefan Berger 已提交
17225 17226
{
    virConnectPtr conn;
17227
    VIR_DEBUG("nwfilter=%p, flags=%x", nwfilter, flags);
S
Stefan Berger 已提交
17228 17229 17230 17231

    virResetLastError();

    if (!VIR_IS_CONNECTED_NWFILTER(nwfilter)) {
17232
        virLibNWFilterError(VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
S
Stefan Berger 已提交
17233
        virDispatchError(NULL);
17234
        return NULL;
S
Stefan Berger 已提交
17235 17236 17237 17238
    }

    conn = nwfilter->conn;

17239
    if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterGetXMLDesc) {
S
Stefan Berger 已提交
17240
        char *ret;
17241
        ret = conn->nwfilterDriver->nwfilterGetXMLDesc(nwfilter, flags);
S
Stefan Berger 已提交
17242 17243 17244 17245 17246
        if (!ret)
            goto error;
        return ret;
    }

17247
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
S
Stefan Berger 已提交
17248 17249 17250 17251 17252 17253 17254 17255 17256 17257 17258 17259 17260 17261 17262 17263 17264 17265 17266 17267 17268 17269 17270 17271 17272 17273 17274 17275

error:
    virDispatchError(nwfilter->conn);
    return NULL;
}


/**
 * virNWFilterRef:
 * @nwfilter: the nwfilter to hold a reference on
 *
 * Increment the reference count on the nwfilter. For each
 * additional call to this method, there shall be a corresponding
 * call to virNWFilterFree to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * This method is typically useful for applications where multiple
 * threads are using a connection, and it is required that the
 * connection remain open until all threads have finished using
 * it. ie, each new thread using an nwfilter would increment
 * the reference count.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virNWFilterRef(virNWFilterPtr nwfilter)
{
    if ((!VIR_IS_CONNECTED_NWFILTER(nwfilter))) {
17276
        virLibConnError(VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
S
Stefan Berger 已提交
17277 17278 17279
        virDispatchError(NULL);
        return -1;
    }
17280 17281
    VIR_DEBUG("nwfilter=%p refs=%d", nwfilter, nwfilter->object.refs);
    virObjectRef(nwfilter);
S
Stefan Berger 已提交
17282 17283 17284 17285
    return 0;
}


17286 17287 17288 17289 17290 17291 17292 17293 17294 17295
/**
 * virInterfaceIsActive:
 * @iface: pointer to the interface object
 *
 * Determine if the interface is currently running
 *
 * Returns 1 if running, 0 if inactive, -1 on error
 */
int virInterfaceIsActive(virInterfacePtr iface)
{
17296
    VIR_DEBUG("iface=%p", iface);
17297 17298 17299 17300

    virResetLastError();

    if (!VIR_IS_CONNECTED_INTERFACE(iface)) {
17301
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
17302
        virDispatchError(NULL);
17303
        return -1;
17304 17305 17306 17307 17308 17309 17310 17311 17312
    }
    if (iface->conn->interfaceDriver->interfaceIsActive) {
        int ret;
        ret = iface->conn->interfaceDriver->interfaceIsActive(iface);
        if (ret < 0)
            goto error;
        return ret;
    }

17313
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
17314
error:
17315
    virDispatchError(iface->conn);
17316 17317 17318 17319 17320 17321 17322 17323 17324 17325 17326 17327 17328 17329
    return -1;
}


/**
 * virConnectIsEncrypted:
 * @conn: pointer to the connection object
 *
 * Determine if the connection to the hypervisor is encrypted
 *
 * Returns 1 if encrypted, 0 if not encrypted, -1 on error
 */
int virConnectIsEncrypted(virConnectPtr conn)
{
17330
    VIR_DEBUG("conn=%p", conn);
17331 17332 17333 17334

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
17335
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
17336
        virDispatchError(NULL);
17337
        return -1;
17338
    }
17339
    if (conn->driver->connectIsEncrypted) {
17340
        int ret;
17341
        ret = conn->driver->connectIsEncrypted(conn);
17342 17343 17344 17345 17346
        if (ret < 0)
            goto error;
        return ret;
    }

17347
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
17348
error:
17349
    virDispatchError(conn);
17350 17351 17352 17353 17354 17355 17356 17357 17358 17359 17360 17361 17362
    return -1;
}

/**
 * virConnectIsSecure:
 * @conn: pointer to the connection object
 *
 * Determine if the connection to the hypervisor is secure
 *
 * A connection will be classed as secure if it is either
 * encrypted, or running over a channel which is not exposed
 * to eavesdropping (eg a UNIX domain socket, or pipe)
 *
C
Claudio Bley 已提交
17363
 * Returns 1 if secure, 0 if not secure, -1 on error
17364 17365 17366
 */
int virConnectIsSecure(virConnectPtr conn)
{
17367
    VIR_DEBUG("conn=%p", conn);
17368 17369 17370 17371

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
17372
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
17373
        virDispatchError(NULL);
17374
        return -1;
17375
    }
17376
    if (conn->driver->connectIsSecure) {
17377
        int ret;
17378
        ret = conn->driver->connectIsSecure(conn);
17379 17380 17381 17382 17383
        if (ret < 0)
            goto error;
        return ret;
    }

17384
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
17385
error:
17386
    virDispatchError(conn);
17387 17388
    return -1;
}
J
Jiri Denemark 已提交
17389 17390 17391 17392 17393


/**
 * virConnectCompareCPU:
 * @conn: virConnect connection
17394
 * @xmlDesc: XML describing the CPU to compare with host CPU
17395
 * @flags: extra flags; not used yet, so callers should always pass 0
17396 17397
 *
 * Compares the given CPU description with the host CPU
J
Jiri Denemark 已提交
17398 17399 17400 17401 17402 17403 17404 17405
 *
 * Returns comparison result according to enum virCPUCompareResult
 */
int
virConnectCompareCPU(virConnectPtr conn,
                     const char *xmlDesc,
                     unsigned int flags)
{
17406
    VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags);
J
Jiri Denemark 已提交
17407 17408 17409 17410

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
17411
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
17412
        virDispatchError(NULL);
J
Jiri Denemark 已提交
17413 17414
        return VIR_CPU_COMPARE_ERROR;
    }
17415
    virCheckNonNullArgGoto(xmlDesc, error);
J
Jiri Denemark 已提交
17416

17417
    if (conn->driver->connectCompareCPU) {
J
Jiri Denemark 已提交
17418 17419
        int ret;

17420
        ret = conn->driver->connectCompareCPU(conn, xmlDesc, flags);
J
Jiri Denemark 已提交
17421 17422 17423 17424 17425
        if (ret == VIR_CPU_COMPARE_ERROR)
            goto error;
        return ret;
    }

17426
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
J
Jiri Denemark 已提交
17427 17428

error:
17429
    virDispatchError(conn);
J
Jiri Denemark 已提交
17430 17431
    return VIR_CPU_COMPARE_ERROR;
}
17432 17433 17434 17435 17436 17437 17438 17439


/**
 * virConnectBaselineCPU:
 *
 * @conn: virConnect connection
 * @xmlCPUs: array of XML descriptions of host CPUs
 * @ncpus: number of CPUs in xmlCPUs
17440
 * @flags: extra flags; not used yet, so callers should always pass 0
17441 17442 17443 17444 17445 17446 17447 17448 17449 17450 17451 17452 17453 17454
 *
 * Computes the most feature-rich CPU which is compatible with all given
 * host CPUs.
 *
 * Returns XML description of the computed CPU or NULL on error.
 */
char *
virConnectBaselineCPU(virConnectPtr conn,
                      const char **xmlCPUs,
                      unsigned int ncpus,
                      unsigned int flags)
{
    unsigned int i;

17455
    VIR_DEBUG("conn=%p, xmlCPUs=%p, ncpus=%u, flags=%x",
17456 17457 17458 17459 17460 17461 17462 17463 17464
              conn, xmlCPUs, ncpus, flags);
    if (xmlCPUs) {
        for (i = 0; i < ncpus; i++)
            VIR_DEBUG("xmlCPUs[%u]=%s", i, NULLSTR(xmlCPUs[i]));
    }

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
17465
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
17466 17467 17468
        virDispatchError(NULL);
        return NULL;
    }
17469
    virCheckNonNullArgGoto(xmlCPUs, error);
17470

17471
    if (conn->driver->connectBaselineCPU) {
17472 17473
        char *cpu;

17474
        cpu = conn->driver->connectBaselineCPU(conn, xmlCPUs, ncpus, flags);
17475 17476 17477 17478 17479
        if (!cpu)
            goto error;
        return cpu;
    }

17480
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
17481 17482 17483 17484 17485

error:
    virDispatchError(conn);
    return NULL;
}
17486 17487 17488 17489 17490 17491 17492 17493 17494 17495 17496 17497 17498 17499 17500 17501


/**
 * virDomainGetJobInfo:
 * @domain: a domain object
 * @info: pointer to a virDomainJobInfo structure allocated by the user
 *
 * Extract information about progress of a background job on a domain.
 * Will return an error if the domain is not active.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
{
    virConnectPtr conn;
17502 17503

    VIR_DOMAIN_DEBUG(domain, "info=%p", info);
17504 17505 17506 17507

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
17508
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
17509
        virDispatchError(NULL);
17510
        return -1;
17511
    }
17512
    virCheckNonNullArgGoto(info, error);
17513 17514 17515 17516 17517 17518 17519

    memset(info, 0, sizeof(virDomainJobInfo));

    conn = domain->conn;

    if (conn->driver->domainGetJobInfo) {
        int ret;
17520
        ret = conn->driver->domainGetJobInfo(domain, info);
17521 17522 17523 17524 17525
        if (ret < 0)
            goto error;
        return ret;
    }

17526
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
17527 17528 17529 17530

error:
    virDispatchError(domain->conn);
    return -1;
17531 17532 17533 17534 17535 17536 17537 17538 17539 17540 17541 17542 17543 17544 17545 17546 17547 17548 17549 17550 17551 17552 17553 17554 17555 17556 17557 17558 17559 17560 17561 17562 17563 17564 17565 17566 17567 17568 17569 17570 17571 17572 17573 17574 17575 17576 17577 17578 17579 17580 17581 17582 17583 17584 17585 17586 17587 17588 17589 17590
}


/**
 * virDomainGetJobStats:
 * @domain: a domain object
 * @type: where to store the job type (one of virDomainJobType)
 * @params: where to store job statistics
 * @nparams: number of items in @params
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Extract information about progress of a background job on a domain.
 * Will return an error if the domain is not active. The function returns
 * a superset of progress information provided by virDomainGetJobInfo.
 * Possible fields returned in @params are defined by VIR_DOMAIN_JOB_*
 * macros and new fields will likely be introduced in the future so callers
 * may receive fields that they do not understand in case they talk to a
 * newer server.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainGetJobStats(virDomainPtr domain,
                     int *type,
                     virTypedParameterPtr *params,
                     int *nparams,
                     unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "type=%p, params=%p, nparams=%p, flags=%x",
                     type, params, nparams, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    virCheckNonNullArgGoto(type, error);
    virCheckNonNullArgGoto(params, error);
    virCheckNonNullArgGoto(nparams, error);

    conn = domain->conn;

    if (conn->driver->domainGetJobStats) {
        int ret;
        ret = conn->driver->domainGetJobStats(domain, type, params,
                                              nparams, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
17591
}
17592 17593 17594 17595 17596 17597 17598


/**
 * virDomainAbortJob:
 * @domain: a domain object
 *
 * Requests that the current background job be aborted at the
M
Michal Privoznik 已提交
17599
 * soonest opportunity.
17600 17601 17602 17603 17604 17605 17606 17607
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainAbortJob(virDomainPtr domain)
{
    virConnectPtr conn;

17608
    VIR_DOMAIN_DEBUG(domain);
17609 17610 17611 17612

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
17613
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
17614
        virDispatchError(NULL);
17615
        return -1;
17616 17617 17618 17619
    }

    conn = domain->conn;
    if (conn->flags & VIR_CONNECT_RO) {
17620
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
17621 17622 17623 17624 17625 17626 17627 17628 17629 17630 17631
        goto error;
    }

    if (conn->driver->domainAbortJob) {
        int ret;
        ret = conn->driver->domainAbortJob(domain);
        if (ret < 0)
            goto error;
        return ret;
    }

17632
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
17633 17634 17635 17636 17637

error:
    virDispatchError(conn);
    return -1;
}
17638 17639 17640 17641 17642 17643


/**
 * virDomainMigrateSetMaxDowntime:
 * @domain: a domain object
 * @downtime: maximum tolerable downtime for live migration, in milliseconds
17644
 * @flags: extra flags; not used yet, so callers should always pass 0
17645 17646 17647 17648 17649 17650 17651 17652 17653 17654 17655 17656 17657 17658
 *
 * Sets maximum tolerable time for which the domain is allowed to be paused
 * at the end of live migration. It's supposed to be called while the domain is
 * being live-migrated as a reaction to migration progress.
 *
 * Returns 0 in case of success, -1 otherwise.
 */
int
virDomainMigrateSetMaxDowntime(virDomainPtr domain,
                               unsigned long long downtime,
                               unsigned int flags)
{
    virConnectPtr conn;

17659
    VIR_DOMAIN_DEBUG(domain, "downtime=%llu, flags=%x", downtime, flags);
17660 17661 17662 17663

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
17664
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
17665 17666 17667 17668 17669 17670
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;
    if (conn->flags & VIR_CONNECT_RO) {
17671
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
17672 17673 17674 17675 17676 17677 17678 17679 17680
        goto error;
    }

    if (conn->driver->domainMigrateSetMaxDowntime) {
        if (conn->driver->domainMigrateSetMaxDowntime(domain, downtime, flags) < 0)
            goto error;
        return 0;
    }

17681
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
17682 17683 17684 17685 17686
error:
    virDispatchError(conn);
    return -1;
}

17687 17688 17689 17690 17691 17692 17693 17694 17695 17696 17697 17698 17699 17700 17701 17702 17703 17704 17705 17706 17707 17708 17709 17710 17711 17712 17713 17714 17715 17716 17717 17718 17719 17720 17721 17722 17723 17724 17725 17726 17727 17728 17729 17730 17731 17732 17733 17734 17735 17736 17737 17738 17739 17740 17741 17742 17743 17744 17745 17746 17747 17748 17749 17750 17751 17752 17753 17754 17755 17756 17757 17758 17759 17760 17761 17762 17763 17764 17765 17766 17767 17768 17769 17770 17771 17772 17773 17774 17775 17776 17777 17778 17779 17780 17781
/**
 * virDomainMigrateGetCompressionCache:
 * @domain: a domain object
 * @cacheSize: return value of current size of the cache (in bytes)
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Gets current size of the cache (in bytes) used for compressing repeatedly
 * transferred memory pages during live migration.
 *
 * Returns 0 in case of success, -1 otherwise.
 */
int
virDomainMigrateGetCompressionCache(virDomainPtr domain,
                                    unsigned long long *cacheSize,
                                    unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "cacheSize=%p, flags=%x", cacheSize, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;

    virCheckNonNullArgGoto(cacheSize, error);

    if (conn->driver->domainMigrateGetCompressionCache) {
        if (conn->driver->domainMigrateGetCompressionCache(domain, cacheSize,
                                                           flags) < 0)
            goto error;
        return 0;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainMigrateSetCompressionCache:
 * @domain: a domain object
 * @cacheSize: size of the cache (in bytes) used for compression
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Sets size of the cache (in bytes) used for compressing repeatedly
 * transferred memory pages during live migration. It's supposed to be called
 * while the domain is being live-migrated as a reaction to migration progress
 * and increasing number of compression cache misses obtained from
 * virDomainGetJobStats.
 *
 * Returns 0 in case of success, -1 otherwise.
 */
int
virDomainMigrateSetCompressionCache(virDomainPtr domain,
                                    unsigned long long cacheSize,
                                    unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "cacheSize=%llu, flags=%x", cacheSize, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;
    if (conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainMigrateSetCompressionCache) {
        if (conn->driver->domainMigrateSetCompressionCache(domain, cacheSize,
                                                           flags) < 0)
            goto error;
        return 0;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

17782 17783 17784
/**
 * virDomainMigrateSetMaxSpeed:
 * @domain: a domain object
17785
 * @bandwidth: migration bandwidth limit in MiB/s
17786
 * @flags: extra flags; not used yet, so callers should always pass 0
17787
 *
17788
 * The maximum bandwidth (in MiB/s) that will be used to do migration
17789 17790 17791 17792 17793 17794 17795 17796 17797 17798 17799 17800
 * can be specified with the bandwidth parameter. Not all hypervisors
 * will support a bandwidth cap
 *
 * Returns 0 in case of success, -1 otherwise.
 */
int
virDomainMigrateSetMaxSpeed(virDomainPtr domain,
                            unsigned long bandwidth,
                            unsigned int flags)
{
    virConnectPtr conn;

17801
    VIR_DOMAIN_DEBUG(domain, "bandwidth=%lu, flags=%x", bandwidth, flags);
17802 17803 17804 17805 17806 17807 17808 17809 17810 17811 17812 17813 17814 17815 17816 17817 17818 17819 17820 17821 17822

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;
    if (conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainMigrateSetMaxSpeed) {
        if (conn->driver->domainMigrateSetMaxSpeed(domain, bandwidth, flags) < 0)
            goto error;
        return 0;
    }

17823 17824 17825 17826 17827 17828 17829 17830 17831
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainMigrateGetMaxSpeed:
 * @domain: a domain object
17832
 * @bandwidth: return value of current migration bandwidth limit in MiB/s
17833
 * @flags: extra flags; not used yet, so callers should always pass 0
17834
 *
17835
 * Get the current maximum bandwidth (in MiB/s) that will be used if the
17836 17837 17838 17839 17840 17841 17842 17843 17844 17845 17846 17847 17848 17849 17850 17851 17852 17853 17854 17855 17856
 * domain is migrated.  Not all hypervisors will support a bandwidth limit.
 *
 * Returns 0 in case of success, -1 otherwise.
 */
int
virDomainMigrateGetMaxSpeed(virDomainPtr domain,
                            unsigned long *bandwidth,
                            unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "bandwidth = %p, flags=%x", bandwidth, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

17857 17858
    conn = domain->conn;

17859
    virCheckNonNullArgGoto(bandwidth, error);
17860 17861 17862 17863 17864 17865 17866 17867 17868 17869 17870 17871

    if (conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainMigrateGetMaxSpeed) {
        if (conn->driver->domainMigrateGetMaxSpeed(domain, bandwidth, flags) < 0)
            goto error;
        return 0;
    }

17872 17873 17874 17875 17876 17877
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

17878 17879 17880 17881 17882 17883 17884 17885 17886 17887 17888 17889 17890 17891 17892 17893
/**
 * virConnectDomainEventRegisterAny:
 * @conn: pointer to the connection
 * @dom: pointer to the domain
 * @eventID: the event type to receive
 * @cb: callback to the function handling domain events
 * @opaque: opaque data to pass on to the callback
 * @freecb: optional function to deallocate opaque when not used anymore
 *
 * Adds a callback to receive notifications of arbitrary domain events
 * occurring on a domain.
 *
 * If dom is NULL, then events will be monitored for any domain. If dom
 * is non-NULL, then only the specific domain will be monitored
 *
 * Most types of event have a callback providing a custom set of parameters
17894
 * for the event. When registering an event, it is thus necessary to use
17895 17896 17897 17898 17899
 * the VIR_DOMAIN_EVENT_CALLBACK() macro to cast the supplied function pointer
 * to match the signature of this method.
 *
 * The virDomainPtr object handle passed into the callback upon delivery
 * of an event is only valid for the duration of execution of the callback.
17900 17901
 * If the callback wishes to keep the domain object after the callback returns,
 * it shall take a reference to it, by calling virDomainRef.
17902 17903 17904 17905 17906 17907 17908 17909 17910 17911 17912 17913 17914 17915 17916 17917 17918
 * The reference can be released once the object is no longer required
 * by calling virDomainFree.
 *
 * The return value from this method is a positive integer identifier
 * for the callback. To unregister a callback, this callback ID should
 * be passed to the virDomainEventUnregisterAny method
 *
 * Returns a callback identifier on success, -1 on failure
 */
int
virConnectDomainEventRegisterAny(virConnectPtr conn,
                                 virDomainPtr dom,
                                 int eventID,
                                 virConnectDomainEventGenericCallback cb,
                                 void *opaque,
                                 virFreeCallback freecb)
{
17919 17920 17921
    VIR_DOMAIN_DEBUG(dom, "conn=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
                     conn, eventID, cb, opaque, freecb);

17922 17923 17924
    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
17925
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
17926
        virDispatchError(NULL);
17927
        return -1;
17928 17929 17930
    }
    if (dom != NULL &&
        !(VIR_IS_CONNECTED_DOMAIN(dom) && dom->conn == conn)) {
17931
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
17932
        virDispatchError(conn);
17933
        return -1;
17934
    }
17935 17936 17937 17938 17939 17940
    virCheckNonNullArgGoto(cb, error);
    virCheckNonNegativeArgGoto(eventID, error);
    if (eventID >= VIR_DOMAIN_EVENT_ID_LAST) {
        virReportInvalidArg(eventID,
                            _("eventID in %s must be less than %d"),
                            __FUNCTION__, VIR_DOMAIN_EVENT_ID_LAST);
17941 17942 17943
        goto error;
    }

17944
    if ((conn->driver) && (conn->driver->connectDomainEventRegisterAny)) {
17945
        int ret;
17946
        ret = conn->driver->connectDomainEventRegisterAny(conn, dom, eventID, cb, opaque, freecb);
17947 17948 17949 17950 17951
        if (ret < 0)
            goto error;
        return ret;
    }

17952
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
17953 17954 17955 17956
error:
    virDispatchError(conn);
    return -1;
}
17957

17958 17959 17960 17961 17962 17963 17964 17965 17966 17967 17968 17969 17970 17971
/**
 * virConnectDomainEventDeregisterAny:
 * @conn: pointer to the connection
 * @callbackID: the callback identifier
 *
 * Removes an event callback. The callbackID parameter should be the
 * vaule obtained from a previous virDomainEventRegisterAny method.
 *
 * Returns 0 on success, -1 on failure
 */
int
virConnectDomainEventDeregisterAny(virConnectPtr conn,
                                   int callbackID)
{
17972
    VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
17973 17974 17975 17976

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
17977
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
17978
        virDispatchError(NULL);
17979
        return -1;
17980
    }
17981 17982
    virCheckNonNegativeArgGoto(callbackID, error);

17983
    if ((conn->driver) && (conn->driver->connectDomainEventDeregisterAny)) {
17984
        int ret;
17985
        ret = conn->driver->connectDomainEventDeregisterAny(conn, callbackID);
17986 17987 17988 17989 17990
        if (ret < 0)
            goto error;
        return ret;
    }

17991
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
17992 17993 17994 17995
error:
    virDispatchError(conn);
    return -1;
}
17996 17997 17998 17999

/**
 * virDomainManagedSave:
 * @dom: pointer to the domain
18000
 * @flags: bitwise-OR of virDomainSaveRestoreFlags
18001 18002 18003 18004 18005 18006 18007 18008
 *
 * This method will suspend a domain and save its memory contents to
 * a file on disk. After the call, if successful, the domain is not
 * listed as running anymore.
 * The difference from virDomainSave() is that libvirt is keeping track of
 * the saved state itself, and will reuse it once the domain is being
 * restarted (automatically or via an explicit libvirt call).
 * As a result any running domain is sure to not have a managed saved image.
18009 18010 18011
 * This also implies that managed save only works on persistent domains,
 * since the domain must still exist in order to use virDomainCreate() to
 * restart it.
18012
 *
18013 18014 18015 18016 18017
 * If @flags includes VIR_DOMAIN_SAVE_BYPASS_CACHE, then libvirt will
 * attempt to bypass the file system cache while creating the file, or
 * fail if it cannot do so for the given system; this can allow less
 * pressure on file system cache, but also risks slowing saves to NFS.
 *
18018 18019 18020 18021 18022 18023
 * Normally, the managed saved state will remember whether the domain
 * was running or paused, and start will resume to the same state.
 * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
 * @flags will override the default saved into the file.  These two
 * flags are mutually exclusive.
 *
18024 18025 18026 18027 18028 18029
 * Returns 0 in case of success or -1 in case of failure
 */
int virDomainManagedSave(virDomainPtr dom, unsigned int flags)
{
    virConnectPtr conn;

18030
    VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
18031 18032 18033 18034

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
18035
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
18036 18037 18038 18039 18040 18041
        virDispatchError(NULL);
        return -1;
    }

    conn = dom->conn;
    if (conn->flags & VIR_CONNECT_RO) {
18042
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
18043 18044 18045
        goto error;
    }

18046
    if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags & VIR_DOMAIN_SAVE_PAUSED)) {
18047 18048 18049
        virReportInvalidArg(flags,
                            _("running and paused flags in %s are mutually exclusive"),
                            __FUNCTION__);
18050 18051 18052
        goto error;
    }

18053 18054 18055 18056 18057 18058 18059 18060 18061
    if (conn->driver->domainManagedSave) {
        int ret;

        ret = conn->driver->domainManagedSave(dom, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

18062
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
18063 18064 18065 18066 18067 18068 18069 18070 18071

error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainHasManagedSaveImage:
 * @dom: pointer to the domain
18072
 * @flags: extra flags; not used yet, so callers should always pass 0
18073 18074 18075 18076 18077 18078 18079 18080 18081 18082 18083 18084
 *
 * Check if a domain has a managed save image as created by
 * virDomainManagedSave(). Note that any running domain should not have
 * such an image, as it should have been removed on restart.
 *
 * Returns 0 if no image is present, 1 if an image is present, and
 *         -1 in case of error
 */
int virDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
{
    virConnectPtr conn;

18085
    VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
18086 18087 18088 18089

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
18090
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
18091 18092 18093 18094 18095 18096 18097 18098 18099 18100 18101 18102 18103 18104 18105
        virDispatchError(NULL);
        return -1;
    }

    conn = dom->conn;

    if (conn->driver->domainHasManagedSaveImage) {
        int ret;

        ret = conn->driver->domainHasManagedSaveImage(dom, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

18106
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
18107 18108 18109 18110 18111 18112 18113 18114 18115

error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainManagedSaveRemove:
 * @dom: pointer to the domain
18116
 * @flags: extra flags; not used yet, so callers should always pass 0
18117
 *
D
Daniel Veillard 已提交
18118
 * Remove any managed save image for this domain.
18119 18120 18121 18122 18123 18124 18125
 *
 * Returns 0 in case of success, and -1 in case of error
 */
int virDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
{
    virConnectPtr conn;

18126
    VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
18127 18128 18129 18130

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
18131
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
18132 18133 18134 18135 18136 18137
        virDispatchError(NULL);
        return -1;
    }

    conn = dom->conn;
    if (conn->flags & VIR_CONNECT_RO) {
18138
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
18139 18140 18141 18142 18143 18144 18145 18146 18147 18148 18149 18150
        goto error;
    }

    if (conn->driver->domainManagedSaveRemove) {
        int ret;

        ret = conn->driver->domainManagedSaveRemove(dom, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

18151
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
18152 18153 18154 18155 18156

error:
    virDispatchError(conn);
    return -1;
}
C
Chris Lalancette 已提交
18157

18158 18159 18160 18161 18162 18163 18164 18165 18166 18167 18168 18169 18170 18171 18172 18173 18174 18175 18176 18177 18178 18179 18180 18181 18182 18183 18184 18185 18186
/**
 * virDomainSnapshotGetName:
 * @snapshot: a snapshot object
 *
 * Get the public name for that snapshot
 *
 * Returns a pointer to the name or NULL, the string need not be deallocated
 * as its lifetime will be the same as the snapshot object.
 */
const char *
virDomainSnapshotGetName(virDomainSnapshotPtr snapshot)
{
    VIR_DEBUG("snapshot=%p", snapshot);

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }
    return snapshot->name;
}

/**
 * virDomainSnapshotGetDomain:
 * @snapshot: a snapshot object
 *
18187 18188 18189 18190 18191 18192
 * Provides the domain pointer associated with a snapshot.  The
 * reference counter on the domain is not increased by this
 * call.
 *
 * WARNING: When writing libvirt bindings in other languages, do not use this
 * function.  Instead, store the domain and the snapshot object together.
18193 18194 18195 18196 18197 18198 18199 18200 18201 18202 18203 18204 18205 18206 18207 18208 18209 18210 18211 18212 18213 18214 18215
 *
 * Returns the domain or NULL.
 */
virDomainPtr
virDomainSnapshotGetDomain(virDomainSnapshotPtr snapshot)
{
    VIR_DEBUG("snapshot=%p", snapshot);

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }
    return snapshot->domain;
}

/**
 * virDomainSnapshotGetConnect:
 * @snapshot: a snapshot object
 *
18216 18217 18218 18219 18220 18221
 * Provides the connection pointer associated with a snapshot.  The
 * reference counter on the connection is not increased by this
 * call.
 *
 * WARNING: When writing libvirt bindings in other languages, do not use this
 * function.  Instead, store the connection and the snapshot object together.
18222 18223 18224 18225 18226 18227 18228 18229 18230 18231 18232 18233 18234 18235 18236 18237 18238 18239 18240
 *
 * Returns the connection or NULL.
 */
virConnectPtr
virDomainSnapshotGetConnect(virDomainSnapshotPtr snapshot)
{
    VIR_DEBUG("snapshot=%p", snapshot);

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }
    return snapshot->domain->conn;
}

C
Chris Lalancette 已提交
18241 18242 18243 18244
/**
 * virDomainSnapshotCreateXML:
 * @domain: a domain object
 * @xmlDesc: string containing an XML description of the domain
18245
 * @flags: bitwise-OR of virDomainSnapshotCreateFlags
C
Chris Lalancette 已提交
18246 18247 18248 18249
 *
 * Creates a new snapshot of a domain based on the snapshot xml
 * contained in xmlDesc.
 *
18250 18251 18252 18253 18254 18255 18256 18257 18258 18259 18260 18261 18262 18263 18264 18265 18266 18267 18268 18269 18270 18271 18272 18273 18274 18275 18276 18277 18278 18279 18280 18281 18282 18283 18284
 * If @flags is 0, the domain can be active, in which case the
 * snapshot will be a system checkpoint (both disk state and runtime
 * VM state such as RAM contents), where reverting to the snapshot is
 * the same as resuming from hibernation (TCP connections may have
 * timed out, but everything else picks up where it left off); or
 * the domain can be inactive, in which case the snapshot includes
 * just the disk state prior to booting.  The newly created snapshot
 * becomes current (see virDomainSnapshotCurrent()), and is a child
 * of any previous current snapshot.
 *
 * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE, then this
 * is a request to reinstate snapshot metadata that was previously
 * discarded, rather than creating a new snapshot.  This can be used
 * to recreate a snapshot hierarchy on a destination, then remove it
 * on the source, in order to allow migration (since migration
 * normally fails if snapshot metadata still remains on the source
 * machine).  When redefining snapshot metadata, the current snapshot
 * will not be altered unless the VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
 * flag is also present.  It is an error to request the
 * VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT flag without
 * VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE.  On some hypervisors,
 * redefining an existing snapshot can be used to alter host-specific
 * portions of the domain XML to be used during revert (such as
 * backing filenames associated with disk devices), but must not alter
 * guest-visible layout.  When redefining a snapshot name that does
 * not exist, the hypervisor may validate that reverting to the
 * snapshot appears to be possible (for example, disk images have
 * snapshot contents by the requested name).  Not all hypervisors
 * support these flags.
 *
 * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA, then the
 * domain's disk images are modified according to @xmlDesc, but then
 * the just-created snapshot has its metadata deleted.  This flag is
 * incompatible with VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE.
 *
18285 18286 18287 18288 18289 18290
 * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_HALT, then the domain
 * will be inactive after the snapshot completes, regardless of whether
 * it was active before; otherwise, a running domain will still be
 * running after the snapshot.  This flag is invalid on transient domains,
 * and is incompatible with VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE.
 *
18291 18292 18293 18294 18295 18296
 * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_LIVE, then the domain
 * is not paused while creating the snapshot. This increases the size
 * of the memory dump file, but reduces downtime of the guest while
 * taking the snapshot. Some hypervisors only support this flag during
 * external checkpoints.
 *
18297 18298 18299 18300 18301 18302
 * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY, then the
 * snapshot will be limited to the disks described in @xmlDesc, and no
 * VM state will be saved.  For an active guest, the disk image may be
 * inconsistent (as if power had been pulled), and specifying this
 * with the VIR_DOMAIN_SNAPSHOT_CREATE_HALT flag risks data loss.
 *
18303 18304 18305 18306 18307 18308
 * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE, then the
 * libvirt will attempt to use guest agent to freeze and thaw all
 * file systems in use within domain OS. However, if the guest agent
 * is not present, an error is thrown. Moreover, this flag requires
 * VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY to be passed as well.
 *
18309
 * By default, if the snapshot involves external files, and any of the
18310 18311 18312 18313 18314 18315 18316
 * destination files already exist as a non-empty regular file, the
 * snapshot is rejected to avoid losing contents of those files.
 * However, if @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT,
 * then the destination files must already exist and contain content
 * identical to the source files (this allows a management app to
 * pre-create files with relative backing file names, rather than the
 * default of creating with absolute backing file names).
18317 18318
 *
 * Be aware that although libvirt prefers to report errors up front with
E
Eric Blake 已提交
18319 18320 18321 18322 18323 18324 18325 18326 18327 18328 18329 18330 18331
 * no other effect, some hypervisors have certain types of failures where
 * the overall command can easily fail even though the guest configuration
 * was partially altered (for example, if a disk snapshot request for two
 * disks fails on the second disk, but the first disk alteration cannot be
 * rolled back).  If this API call fails, it is therefore normally
 * necessary to follow up with virDomainGetXMLDesc() and check each disk
 * to determine if any partial changes occurred.  However, if @flags
 * contains VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC, then libvirt guarantees
 * that this command will not alter any disks unless the entire set of
 * changes can be done atomically, making failure recovery simpler (note
 * that it is still possible to fail after disks have changed, but only
 * in the much rarer cases of running out of memory or disk space).
 *
E
Eric Blake 已提交
18332 18333 18334 18335
 * Some hypervisors may prevent this operation if there is a current
 * block copy operation; in that case, use virDomainBlockJobAbort()
 * to stop the block copy first.
 *
E
Eric Blake 已提交
18336
 * Returns an (opaque) virDomainSnapshotPtr on success, NULL on failure.
C
Chris Lalancette 已提交
18337 18338 18339 18340 18341 18342 18343 18344
 */
virDomainSnapshotPtr
virDomainSnapshotCreateXML(virDomainPtr domain,
                           const char *xmlDesc,
                           unsigned int flags)
{
    virConnectPtr conn;

18345
    VIR_DOMAIN_DEBUG(domain, "xmlDesc=%s, flags=%x", xmlDesc, flags);
C
Chris Lalancette 已提交
18346 18347 18348 18349

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
18350
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
C
Chris Lalancette 已提交
18351 18352 18353 18354 18355
        virDispatchError(NULL);
        return NULL;
    }

    conn = domain->conn;
18356

18357
    virCheckNonNullArgGoto(xmlDesc, error);
18358

C
Chris Lalancette 已提交
18359
    if (conn->flags & VIR_CONNECT_RO) {
18360
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
C
Chris Lalancette 已提交
18361 18362 18363
        goto error;
    }

18364 18365
    if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT) &&
        !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)) {
18366 18367 18368
        virReportInvalidArg(flags,
                            _("use of 'current' flag in %s requires 'redefine' flag"),
                            __FUNCTION__);
18369 18370 18371 18372
        goto error;
    }
    if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) &&
        (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
18373 18374 18375
        virReportInvalidArg(flags,
                            _("'redefine' and 'no metadata' flags in %s are mutually exclusive"),
                            __FUNCTION__);
18376 18377
        goto error;
    }
18378 18379
    if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) &&
        (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT)) {
18380 18381 18382
        virReportInvalidArg(flags,
                            _("'redefine' and 'halt' flags in %s are mutually exclusive"),
                            __FUNCTION__);
18383 18384
        goto error;
    }
18385

C
Chris Lalancette 已提交
18386 18387 18388 18389 18390 18391 18392 18393
    if (conn->driver->domainSnapshotCreateXML) {
        virDomainSnapshotPtr ret;
        ret = conn->driver->domainSnapshotCreateXML(domain, xmlDesc, flags);
        if (!ret)
            goto error;
        return ret;
    }

18394
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
18395 18396 18397 18398 18399 18400 18401 18402
error:
    virDispatchError(conn);
    return NULL;
}

/**
 * virDomainSnapshotGetXMLDesc:
 * @snapshot: a domain snapshot object
18403
 * @flags: bitwise-OR of subset of virDomainXMLFlags
C
Chris Lalancette 已提交
18404 18405 18406
 *
 * Provide an XML description of the domain snapshot.
 *
18407 18408 18409 18410 18411
 * No security-sensitive data will be included unless @flags contains
 * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
 * connections.  For this API, @flags should not contain either
 * VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU.
 *
C
Chris Lalancette 已提交
18412 18413 18414 18415 18416 18417 18418 18419
 * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
 *         the caller must free() the returned value.
 */
char *
virDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
                            unsigned int flags)
{
    virConnectPtr conn;
18420
    VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
C
Chris Lalancette 已提交
18421 18422 18423 18424

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
18425
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
C
Chris Lalancette 已提交
18426 18427
                                  __FUNCTION__);
        virDispatchError(NULL);
18428
        return NULL;
C
Chris Lalancette 已提交
18429 18430 18431 18432 18433
    }

    conn = snapshot->domain->conn;

    if ((conn->flags & VIR_CONNECT_RO) && (flags & VIR_DOMAIN_XML_SECURE)) {
18434
        virLibConnError(VIR_ERR_OPERATION_DENIED, "%s",
C
Chris Lalancette 已提交
18435 18436 18437 18438
                        _("virDomainSnapshotGetXMLDesc with secure flag"));
        goto error;
    }

18439
    if (conn->driver->domainSnapshotGetXMLDesc) {
C
Chris Lalancette 已提交
18440
        char *ret;
18441
        ret = conn->driver->domainSnapshotGetXMLDesc(snapshot, flags);
C
Chris Lalancette 已提交
18442 18443 18444 18445 18446
        if (!ret)
            goto error;
        return ret;
    }

18447
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
18448 18449 18450 18451 18452 18453 18454 18455
error:
    virDispatchError(conn);
    return NULL;
}

/**
 * virDomainSnapshotNum:
 * @domain: a domain object
18456
 * @flags: bitwise-OR of supported virDomainSnapshotListFlags
18457 18458
 *
 * Provides the number of domain snapshots for this domain.
C
Chris Lalancette 已提交
18459
 *
18460 18461 18462 18463 18464 18465 18466 18467 18468 18469 18470 18471 18472 18473 18474 18475
 * By default, this command covers all snapshots; it is also possible to
 * limit things to just snapshots with no parents, when @flags includes
 * VIR_DOMAIN_SNAPSHOT_LIST_ROOTS.  Additional filters are provided in
 * groups, where each group contains bits that describe mutually exclusive
 * attributes of a snapshot, and where all bits within a group describe
 * all possible snapshots.  Some hypervisors might reject explicit bits
 * from a group where the hypervisor cannot make a distinction.  For a
 * group supported by a given hypervisor, the behavior when no bits of a
 * group are set is identical to the behavior when all bits in that group
 * are set.  When setting bits from more than one group, it is possible to
 * select an impossible combination, in that case a hypervisor may return
 * either 0 or an error.
 *
 * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
 * have no further children (a leaf snapshot).
C
Chris Lalancette 已提交
18476
 *
18477 18478 18479 18480
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
 * whether they have metadata that would prevent the removal of the last
 * reference to a domain.
18481
 *
18482 18483 18484 18485 18486 18487 18488 18489 18490 18491
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
 * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
 * for filtering snapshots based on what domain state is tracked by the
 * snapshot.
 *
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
 * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
 * whether the snapshot is stored inside the disk images or as
 * additional files.
 *
18492
 * Returns the number of domain snapshots found or -1 in case of error.
C
Chris Lalancette 已提交
18493 18494 18495 18496 18497
 */
int
virDomainSnapshotNum(virDomainPtr domain, unsigned int flags)
{
    virConnectPtr conn;
18498

E
Eric Blake 已提交
18499
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
C
Chris Lalancette 已提交
18500 18501 18502 18503

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
18504
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
C
Chris Lalancette 已提交
18505 18506 18507 18508 18509 18510 18511 18512 18513 18514 18515 18516
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;
    if (conn->driver->domainSnapshotNum) {
        int ret = conn->driver->domainSnapshotNum(domain, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

18517
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
18518 18519 18520 18521 18522 18523 18524 18525 18526 18527
error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainSnapshotListNames:
 * @domain: a domain object
 * @names: array to collect the list of names of snapshots
 * @nameslen: size of @names
18528
 * @flags: bitwise-OR of supported virDomainSnapshotListFlags
C
Chris Lalancette 已提交
18529 18530
 *
 * Collect the list of domain snapshots for the given domain, and store
18531 18532
 * their names in @names.  The value to use for @nameslen can be determined
 * by virDomainSnapshotNum() with the same @flags.
18533
 *
18534 18535 18536 18537 18538 18539 18540 18541 18542 18543 18544 18545 18546 18547 18548 18549
 * By default, this command covers all snapshots; it is also possible to
 * limit things to just snapshots with no parents, when @flags includes
 * VIR_DOMAIN_SNAPSHOT_LIST_ROOTS.  Additional filters are provided in
 * groups, where each group contains bits that describe mutually exclusive
 * attributes of a snapshot, and where all bits within a group describe
 * all possible snapshots.  Some hypervisors might reject explicit bits
 * from a group where the hypervisor cannot make a distinction.  For a
 * group supported by a given hypervisor, the behavior when no bits of a
 * group are set is identical to the behavior when all bits in that group
 * are set.  When setting bits from more than one group, it is possible to
 * select an impossible combination, in that case a hypervisor may return
 * either 0 or an error.
 *
 * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
 * have no further children (a leaf snapshot).
18550
 *
18551 18552 18553 18554
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
 * whether they have metadata that would prevent the removal of the last
 * reference to a domain.
C
Chris Lalancette 已提交
18555
 *
18556 18557 18558 18559 18560 18561 18562 18563 18564 18565
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
 * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
 * for filtering snapshots based on what domain state is tracked by the
 * snapshot.
 *
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
 * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
 * whether the snapshot is stored inside the disk images or as
 * additional files.
 *
18566 18567 18568 18569 18570 18571
 * Note that this command is inherently racy: another connection can
 * define a new snapshot between a call to virDomainSnapshotNum() and
 * this call.  You are only guaranteed that all currently defined
 * snapshots were listed if the return is less than @nameslen.  Likewise,
 * you should be prepared for virDomainSnapshotLookupByName() to fail when
 * converting a name from this call into a snapshot object, if another
18572 18573 18574 18575
 * connection deletes the snapshot in the meantime.  For more control over
 * the results, see virDomainListAllSnapshots().
 *
 * Returns the number of domain snapshots found or -1 in case of error.
J
John Ferlan 已提交
18576
 * The caller is responsible to call free() for each member of the array.
C
Chris Lalancette 已提交
18577 18578 18579 18580 18581 18582 18583
 */
int
virDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
                           unsigned int flags)
{
    virConnectPtr conn;

18584
    VIR_DOMAIN_DEBUG(domain, "names=%p, nameslen=%d, flags=%x",
18585
                     names, nameslen, flags);
C
Chris Lalancette 已提交
18586 18587 18588 18589

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
18590
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
C
Chris Lalancette 已提交
18591 18592 18593 18594 18595 18596
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;

18597 18598
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(nameslen, error);
C
Chris Lalancette 已提交
18599 18600 18601 18602 18603 18604 18605 18606 18607

    if (conn->driver->domainSnapshotListNames) {
        int ret = conn->driver->domainSnapshotListNames(domain, names,
                                                        nameslen, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

18608
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
18609 18610 18611 18612 18613
error:
    virDispatchError(conn);
    return -1;
}

18614 18615 18616 18617 18618 18619 18620 18621 18622 18623 18624 18625 18626 18627 18628 18629 18630 18631 18632 18633 18634 18635 18636 18637 18638 18639 18640 18641 18642 18643 18644 18645 18646 18647
/**
 * virDomainListAllSnapshots:
 * @domain: a domain object
 * @snaps: pointer to variable to store the array containing snapshot objects,
 *         or NULL if the list is not required (just returns number of
 *         snapshots)
 * @flags: bitwise-OR of supported virDomainSnapshotListFlags
 *
 * Collect the list of domain snapshots for the given domain, and allocate
 * an array to store those objects.  This API solves the race inherent in
 * virDomainSnapshotListNames().
 *
 * By default, this command covers all snapshots; it is also possible to
 * limit things to just snapshots with no parents, when @flags includes
 * VIR_DOMAIN_SNAPSHOT_LIST_ROOTS.  Additional filters are provided in
 * groups, where each group contains bits that describe mutually exclusive
 * attributes of a snapshot, and where all bits within a group describe
 * all possible snapshots.  Some hypervisors might reject explicit bits
 * from a group where the hypervisor cannot make a distinction.  For a
 * group supported by a given hypervisor, the behavior when no bits of a
 * group are set is identical to the behavior when all bits in that group
 * are set.  When setting bits from more than one group, it is possible to
 * select an impossible combination, in that case a hypervisor may return
 * either 0 or an error.
 *
 * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
 * have no further children (a leaf snapshot).
 *
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
 * whether they have metadata that would prevent the removal of the last
 * reference to a domain.
 *
18648 18649 18650 18651 18652 18653 18654 18655 18656 18657
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
 * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
 * for filtering snapshots based on what domain state is tracked by the
 * snapshot.
 *
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
 * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
 * whether the snapshot is stored inside the disk images or as
 * additional files.
 *
18658 18659 18660 18661 18662 18663 18664 18665 18666 18667 18668 18669 18670 18671 18672 18673 18674 18675 18676 18677 18678 18679 18680 18681 18682 18683 18684 18685 18686 18687 18688 18689 18690 18691 18692 18693 18694 18695 18696 18697 18698
 * Returns the number of domain snapshots found or -1 and sets @snaps to
 * NULL in case of error.  On success, the array stored into @snaps is
 * guaranteed to have an extra allocated element set to NULL but not included
 * in the return count, to make iteration easier.  The caller is responsible
 * for calling virDomainSnapshotFree() on each array element, then calling
 * free() on @snaps.
 */
int
virDomainListAllSnapshots(virDomainPtr domain, virDomainSnapshotPtr **snaps,
                          unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "snaps=%p, flags=%x", snaps, flags);

    virResetLastError();

    if (snaps)
        *snaps = NULL;

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;

    if (conn->driver->domainListAllSnapshots) {
        int ret = conn->driver->domainListAllSnapshots(domain, snaps, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

18699 18700 18701
/**
 * virDomainSnapshotNumChildren:
 * @snapshot: a domain snapshot object
18702
 * @flags: bitwise-OR of supported virDomainSnapshotListFlags
18703 18704 18705
 *
 * Provides the number of child snapshots for this domain snapshot.
 *
18706 18707 18708 18709 18710 18711 18712 18713 18714 18715 18716 18717
 * By default, this command covers only direct children; it is also possible
 * to expand things to cover all descendants, when @flags includes
 * VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS.  Also, some filters are provided in
 * groups, where each group contains bits that describe mutually exclusive
 * attributes of a snapshot, and where all bits within a group describe
 * all possible snapshots.  Some hypervisors might reject explicit bits
 * from a group where the hypervisor cannot make a distinction.  For a
 * group supported by a given hypervisor, the behavior when no bits of a
 * group are set is identical to the behavior when all bits in that group
 * are set.  When setting bits from more than one group, it is possible to
 * select an impossible combination, in that case a hypervisor may return
 * either 0 or an error.
18718
 *
18719 18720 18721
 * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
 * have no further children (a leaf snapshot).
18722
 *
18723 18724 18725 18726
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
 * whether they have metadata that would prevent the removal of the last
 * reference to a domain.
18727
 *
18728 18729 18730 18731 18732 18733 18734 18735 18736 18737
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
 * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
 * for filtering snapshots based on what domain state is tracked by the
 * snapshot.
 *
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
 * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
 * whether the snapshot is stored inside the disk images or as
 * additional files.
 *
18738 18739 18740 18741 18742 18743 18744 18745 18746 18747 18748 18749 18750 18751 18752 18753 18754 18755 18756 18757 18758 18759 18760 18761 18762 18763 18764 18765 18766 18767 18768 18769 18770 18771 18772 18773 18774
 * Returns the number of domain snapshots found or -1 in case of error.
 */
int
virDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags)
{
    virConnectPtr conn;

    VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = snapshot->domain->conn;
    if (conn->driver->domainSnapshotNumChildren) {
        int ret = conn->driver->domainSnapshotNumChildren(snapshot, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainSnapshotListChildrenNames:
 * @snapshot: a domain snapshot object
 * @names: array to collect the list of names of snapshots
 * @nameslen: size of @names
18775
 * @flags: bitwise-OR of supported virDomainSnapshotListFlags
18776 18777
 *
 * Collect the list of domain snapshots that are children of the given
18778 18779 18780
 * snapshot, and store their names in @names.  The value to use for
 * @nameslen can be determined by virDomainSnapshotNumChildren() with
 * the same @flags.
18781
 *
18782 18783 18784 18785 18786 18787 18788 18789 18790 18791 18792 18793
 * By default, this command covers only direct children; it is also possible
 * to expand things to cover all descendants, when @flags includes
 * VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS.  Also, some filters are provided in
 * groups, where each group contains bits that describe mutually exclusive
 * attributes of a snapshot, and where all bits within a group describe
 * all possible snapshots.  Some hypervisors might reject explicit bits
 * from a group where the hypervisor cannot make a distinction.  For a
 * group supported by a given hypervisor, the behavior when no bits of a
 * group are set is identical to the behavior when all bits in that group
 * are set.  When setting bits from more than one group, it is possible to
 * select an impossible combination, in that case a hypervisor may return
 * either 0 or an error.
18794
 *
18795 18796 18797
 * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
 * have no further children (a leaf snapshot).
18798
 *
18799 18800 18801 18802
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
 * whether they have metadata that would prevent the removal of the last
 * reference to a domain.
18803
 *
18804 18805 18806 18807 18808 18809 18810 18811 18812 18813
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
 * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
 * for filtering snapshots based on what domain state is tracked by the
 * snapshot.
 *
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
 * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
 * whether the snapshot is stored inside the disk images or as
 * additional files.
 *
18814
 * Returns the number of domain snapshots found or -1 in case of error.
18815 18816 18817 18818 18819 18820
 * Note that this command is inherently racy: another connection can
 * define a new snapshot between a call to virDomainSnapshotNumChildren()
 * and this call.  You are only guaranteed that all currently defined
 * snapshots were listed if the return is less than @nameslen.  Likewise,
 * you should be prepared for virDomainSnapshotLookupByName() to fail when
 * converting a name from this call into a snapshot object, if another
18821 18822 18823 18824
 * connection deletes the snapshot in the meantime.  For more control over
 * the results, see virDomainSnapshotListAllChildren().
 *
 * Returns the number of domain snapshots found or -1 in case of error.
J
John Ferlan 已提交
18825
 * The caller is responsible to call free() for each member of the array.
18826 18827 18828 18829 18830 18831 18832 18833 18834 18835 18836 18837 18838 18839 18840 18841 18842 18843 18844 18845 18846 18847
 */
int
virDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
                                   char **names, int nameslen,
                                   unsigned int flags)
{
    virConnectPtr conn;

    VIR_DEBUG("snapshot=%p, names=%p, nameslen=%d, flags=%x",
              snapshot, names, nameslen, flags);

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = snapshot->domain->conn;

18848 18849
    virCheckNonNullArgGoto(names, error);
    virCheckNonNegativeArgGoto(nameslen, error);
18850 18851 18852 18853 18854 18855

    if (conn->driver->domainSnapshotListChildrenNames) {
        int ret = conn->driver->domainSnapshotListChildrenNames(snapshot,
                                                                names,
                                                                nameslen,
                                                                flags);
18856 18857 18858 18859 18860 18861 18862 18863 18864 18865 18866 18867 18868 18869 18870 18871 18872 18873 18874 18875 18876 18877 18878 18879 18880 18881 18882 18883 18884 18885 18886 18887 18888 18889 18890 18891 18892 18893 18894 18895 18896 18897 18898 18899 18900
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainSnapshotListAllChildren:
 * @snapshot: a domain snapshot object
 * @snaps: pointer to variable to store the array containing snapshot objects,
 *         or NULL if the list is not required (just returns number of
 *         snapshots)
 * @flags: bitwise-OR of supported virDomainSnapshotListFlags
 *
 * Collect the list of domain snapshots that are children of the given
 * snapshot, and allocate an array to store those objects.  This API solves
 * the race inherent in virDomainSnapshotListChildrenNames().
 *
 * By default, this command covers only direct children; it is also possible
 * to expand things to cover all descendants, when @flags includes
 * VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS.  Also, some filters are provided in
 * groups, where each group contains bits that describe mutually exclusive
 * attributes of a snapshot, and where all bits within a group describe
 * all possible snapshots.  Some hypervisors might reject explicit bits
 * from a group where the hypervisor cannot make a distinction.  For a
 * group supported by a given hypervisor, the behavior when no bits of a
 * group are set is identical to the behavior when all bits in that group
 * are set.  When setting bits from more than one group, it is possible to
 * select an impossible combination, in that case a hypervisor may return
 * either 0 or an error.
 *
 * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
 * have no further children (a leaf snapshot).
 *
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
 * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
 * whether they have metadata that would prevent the removal of the last
 * reference to a domain.
 *
18901 18902 18903 18904 18905 18906 18907 18908 18909 18910
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
 * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
 * for filtering snapshots based on what domain state is tracked by the
 * snapshot.
 *
 * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
 * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
 * whether the snapshot is stored inside the disk images or as
 * additional files.
 *
18911 18912 18913 18914 18915 18916 18917 18918 18919 18920 18921 18922 18923 18924 18925 18926 18927 18928 18929 18930 18931 18932 18933 18934 18935 18936 18937 18938 18939 18940 18941 18942 18943
 * Returns the number of domain snapshots found or -1 and sets @snaps to
 * NULL in case of error.  On success, the array stored into @snaps is
 * guaranteed to have an extra allocated element set to NULL but not included
 * in the return count, to make iteration easier.  The caller is responsible
 * for calling virDomainSnapshotFree() on each array element, then calling
 * free() on @snaps.
 */
int
virDomainSnapshotListAllChildren(virDomainSnapshotPtr snapshot,
                                 virDomainSnapshotPtr **snaps,
                                 unsigned int flags)
{
    virConnectPtr conn;

    VIR_DEBUG("snapshot=%p, snaps=%p, flags=%x", snapshot, snaps, flags);

    virResetLastError();

    if (snaps)
        *snaps = NULL;

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = snapshot->domain->conn;

    if (conn->driver->domainSnapshotListAllChildren) {
        int ret = conn->driver->domainSnapshotListAllChildren(snapshot, snaps,
                                                              flags);
18944 18945 18946 18947 18948 18949 18950 18951 18952 18953 18954
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

C
Chris Lalancette 已提交
18955 18956 18957 18958
/**
 * virDomainSnapshotLookupByName:
 * @domain: a domain object
 * @name: name for the domain snapshot
18959
 * @flags: extra flags; not used yet, so callers should always pass 0
C
Chris Lalancette 已提交
18960 18961 18962 18963 18964 18965 18966 18967 18968 18969 18970 18971 18972
 *
 * Try to lookup a domain snapshot based on its name.
 *
 * Returns a domain snapshot object or NULL in case of failure.  If the
 * domain snapshot cannot be found, then the VIR_ERR_NO_DOMAIN_SNAPSHOT
 * error is raised.
 */
virDomainSnapshotPtr
virDomainSnapshotLookupByName(virDomainPtr domain,
                              const char *name,
                              unsigned int flags)
{
    virConnectPtr conn;
18973

18974
    VIR_DOMAIN_DEBUG(domain, "name=%s, flags=%x", name, flags);
C
Chris Lalancette 已提交
18975 18976 18977 18978

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
18979
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
C
Chris Lalancette 已提交
18980
        virDispatchError(NULL);
18981
        return NULL;
C
Chris Lalancette 已提交
18982 18983 18984 18985
    }

    conn = domain->conn;

18986
    virCheckNonNullArgGoto(name, error);
C
Chris Lalancette 已提交
18987 18988 18989 18990 18991 18992 18993 18994 18995

    if (conn->driver->domainSnapshotLookupByName) {
        virDomainSnapshotPtr dom;
        dom = conn->driver->domainSnapshotLookupByName(domain, name, flags);
        if (!dom)
            goto error;
        return dom;
    }

18996
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
18997 18998 18999 19000 19001 19002 19003 19004
error:
    virDispatchError(conn);
    return NULL;
}

/**
 * virDomainHasCurrentSnapshot:
 * @domain: pointer to the domain object
19005
 * @flags: extra flags; not used yet, so callers should always pass 0
C
Chris Lalancette 已提交
19006 19007 19008 19009 19010 19011 19012 19013 19014
 *
 * Determine if the domain has a current snapshot.
 *
 * Returns 1 if such snapshot exists, 0 if it doesn't, -1 on error.
 */
int
virDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags)
{
    virConnectPtr conn;
19015

19016
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
C
Chris Lalancette 已提交
19017 19018 19019 19020

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
19021
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
C
Chris Lalancette 已提交
19022 19023 19024 19025 19026 19027 19028 19029 19030 19031 19032 19033 19034
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;

    if (conn->driver->domainHasCurrentSnapshot) {
        int ret = conn->driver->domainHasCurrentSnapshot(domain, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

19035
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
19036 19037 19038 19039 19040 19041 19042 19043
error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainSnapshotCurrent:
 * @domain: a domain object
19044
 * @flags: extra flags; not used yet, so callers should always pass 0
C
Chris Lalancette 已提交
19045 19046 19047 19048 19049 19050 19051 19052 19053 19054 19055 19056
 *
 * Get the current snapshot for a domain, if any.
 *
 * Returns a domain snapshot object or NULL in case of failure.  If the
 * current domain snapshot cannot be found, then the VIR_ERR_NO_DOMAIN_SNAPSHOT
 * error is raised.
 */
virDomainSnapshotPtr
virDomainSnapshotCurrent(virDomainPtr domain,
                         unsigned int flags)
{
    virConnectPtr conn;
19057

19058
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
C
Chris Lalancette 已提交
19059 19060 19061 19062

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
19063
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
C
Chris Lalancette 已提交
19064
        virDispatchError(NULL);
19065
        return NULL;
C
Chris Lalancette 已提交
19066 19067 19068 19069 19070 19071 19072 19073 19074 19075 19076 19077
    }

    conn = domain->conn;

    if (conn->driver->domainSnapshotCurrent) {
        virDomainSnapshotPtr snap;
        snap = conn->driver->domainSnapshotCurrent(domain, flags);
        if (!snap)
            goto error;
        return snap;
    }

19078
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
19079 19080 19081 19082 19083
error:
    virDispatchError(conn);
    return NULL;
}

19084 19085 19086
/**
 * virDomainSnapshotGetParent:
 * @snapshot: a snapshot object
19087
 * @flags: extra flags; not used yet, so callers should always pass 0
19088 19089 19090 19091 19092 19093 19094 19095 19096 19097 19098 19099 19100 19101 19102 19103 19104 19105 19106 19107 19108 19109 19110 19111 19112 19113 19114 19115 19116 19117 19118 19119 19120 19121 19122 19123 19124 19125 19126 19127
 *
 * Get the parent snapshot for @snapshot, if any.
 *
 * Returns a domain snapshot object or NULL in case of failure.  If the
 * given snapshot is a root (no parent), then the VIR_ERR_NO_DOMAIN_SNAPSHOT
 * error is raised.
 */
virDomainSnapshotPtr
virDomainSnapshotGetParent(virDomainSnapshotPtr snapshot,
                           unsigned int flags)
{
    virConnectPtr conn;

    VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }

    conn = snapshot->domain->conn;

    if (conn->driver->domainSnapshotGetParent) {
        virDomainSnapshotPtr snap;
        snap = conn->driver->domainSnapshotGetParent(snapshot, flags);
        if (!snap)
            goto error;
        return snap;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return NULL;
}

E
Eric Blake 已提交
19128 19129 19130 19131 19132 19133 19134 19135 19136 19137 19138 19139 19140 19141 19142 19143 19144 19145 19146 19147 19148 19149 19150 19151 19152 19153 19154 19155 19156 19157 19158 19159 19160 19161 19162 19163 19164 19165 19166 19167 19168 19169 19170 19171 19172 19173 19174 19175 19176 19177 19178 19179 19180 19181 19182 19183 19184 19185 19186 19187 19188 19189 19190 19191 19192 19193 19194 19195 19196 19197 19198 19199 19200 19201 19202 19203 19204 19205 19206 19207 19208 19209 19210 19211 19212
/**
 * virDomainSnapshotIsCurrent:
 * @snapshot: a snapshot object
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Determine if the given snapshot is the domain's current snapshot.  See
 * also virDomainHasCurrentSnapshot().
 *
 * Returns 1 if current, 0 if not current, or -1 on error.
 */
int virDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot,
                               unsigned int flags)
{
    virConnectPtr conn;

    VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = snapshot->domain->conn;

    if (conn->driver->domainSnapshotIsCurrent) {
        int ret;
        ret = conn->driver->domainSnapshotIsCurrent(snapshot, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

/**
 * virDomainSnapshotHasMetadata:
 * @snapshot: a snapshot object
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Determine if the given snapshot is associated with libvirt metadata
 * that would prevent the deletion of the domain.
 *
 * Returns 1 if the snapshot has metadata, 0 if the snapshot exists without
 * help from libvirt, or -1 on error.
 */
int virDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot,
                                 unsigned int flags)
{
    virConnectPtr conn;

    VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = snapshot->domain->conn;

    if (conn->driver->domainSnapshotHasMetadata) {
        int ret;
        ret = conn->driver->domainSnapshotHasMetadata(snapshot, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}

C
Chris Lalancette 已提交
19213
/**
19214
 * virDomainRevertToSnapshot:
C
Chris Lalancette 已提交
19215
 * @snapshot: a domain snapshot object
19216
 * @flags: bitwise-OR of virDomainSnapshotRevertFlags
C
Chris Lalancette 已提交
19217 19218 19219
 *
 * Revert the domain to a given snapshot.
 *
19220 19221 19222 19223 19224 19225 19226 19227 19228 19229 19230 19231
 * Normally, the domain will revert to the same state the domain was
 * in while the snapshot was taken (whether inactive, running, or
 * paused), except that disk snapshots default to reverting to
 * inactive state.  Including VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING in
 * @flags overrides the snapshot state to guarantee a running domain
 * after the revert; or including VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED in
 * @flags guarantees a paused domain after the revert.  These two
 * flags are mutually exclusive.  While a persistent domain does not
 * need either flag, it is not possible to revert a transient domain
 * into an inactive state, so transient domains require the use of one
 * of these two flags.
 *
E
Eric Blake 已提交
19232 19233 19234 19235 19236 19237 19238 19239 19240 19241 19242 19243 19244 19245 19246 19247 19248 19249 19250 19251 19252 19253
 * Reverting to any snapshot discards all configuration changes made since
 * the last snapshot.  Additionally, reverting to a snapshot from a running
 * domain is a form of data loss, since it discards whatever is in the
 * guest's RAM at the time.  Since the very nature of keeping snapshots
 * implies the intent to roll back state, no additional confirmation is
 * normally required for these lossy effects.
 *
 * However, there are two particular situations where reverting will
 * be refused by default, and where @flags must include
 * VIR_DOMAIN_SNAPSHOT_REVERT_FORCE to acknowledge the risks.  1) Any
 * attempt to revert to a snapshot that lacks the metadata to perform
 * ABI compatibility checks (generally the case for snapshots that
 * lack a full <domain> when listed by virDomainSnapshotGetXMLDesc(),
 * such as those created prior to libvirt 0.9.5).  2) Any attempt to
 * revert a running domain to an active state that requires starting a
 * new hypervisor instance rather than reusing the existing hypervisor
 * (since this would terminate all connections to the domain, such as
 * such as VNC or Spice graphics) - this condition arises from active
 * snapshots that are provably ABI incomaptible, as well as from
 * inactive snapshots with a @flags request to start the domain after
 * the revert.
 *
C
Chris Lalancette 已提交
19254 19255 19256 19257 19258 19259 19260 19261
 * Returns 0 if the creation is successful, -1 on error.
 */
int
virDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
                          unsigned int flags)
{
    virConnectPtr conn;

19262
    VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
C
Chris Lalancette 已提交
19263 19264 19265 19266

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
19267
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
C
Chris Lalancette 已提交
19268 19269 19270 19271 19272 19273
                                  __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = snapshot->domain->conn;
19274 19275 19276 19277
    if (conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
C
Chris Lalancette 已提交
19278

19279 19280
    if ((flags & VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING) &&
        (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
19281 19282 19283
        virReportInvalidArg(flags,
                            _("running and paused flags in %s are mutually exclusive"),
                            __FUNCTION__);
19284 19285 19286
        goto error;
    }

C
Chris Lalancette 已提交
19287 19288 19289 19290 19291 19292 19293
    if (conn->driver->domainRevertToSnapshot) {
        int ret = conn->driver->domainRevertToSnapshot(snapshot, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

19294
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
19295 19296 19297 19298 19299 19300
error:
    virDispatchError(conn);
    return -1;
}

/**
19301
 * virDomainSnapshotDelete:
C
Chris Lalancette 已提交
19302
 * @snapshot: a domain snapshot object
19303
 * @flags: bitwise-OR of supported virDomainSnapshotDeleteFlags
C
Chris Lalancette 已提交
19304 19305 19306
 *
 * Delete the snapshot.
 *
19307 19308 19309 19310 19311 19312 19313 19314 19315 19316 19317 19318 19319
 * If @flags is 0, then just this snapshot is deleted, and changes
 * from this snapshot are automatically merged into children
 * snapshots.  If @flags includes VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN,
 * then this snapshot and any descendant snapshots are deleted.  If
 * @flags includes VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY, then any
 * descendant snapshots are deleted, but this snapshot remains.  These
 * two flags are mutually exclusive.
 *
 * If @flags includes VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY, then
 * any snapshot metadata tracked by libvirt is removed while keeping
 * the snapshot contents intact; if a hypervisor does not require any
 * libvirt metadata to track snapshots, then this flag is silently
 * ignored.
C
Chris Lalancette 已提交
19320
 *
19321 19322
 * Returns 0 if the selected snapshot(s) were successfully deleted,
 * -1 on error.
C
Chris Lalancette 已提交
19323 19324 19325 19326 19327 19328 19329
 */
int
virDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
                        unsigned int flags)
{
    virConnectPtr conn;

19330
    VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
C
Chris Lalancette 已提交
19331 19332 19333 19334

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
19335
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
C
Chris Lalancette 已提交
19336 19337 19338 19339 19340 19341
                                  __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = snapshot->domain->conn;
19342 19343 19344 19345
    if (conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }
C
Chris Lalancette 已提交
19346

19347 19348
    if ((flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) &&
        (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
19349 19350 19351 19352
        virReportInvalidArg(flags,
                            _("children and children_only flags in %s are "
                              "mutually exclusive"),
                            __FUNCTION__);
19353 19354 19355
        goto error;
    }

C
Chris Lalancette 已提交
19356 19357 19358 19359 19360 19361 19362
    if (conn->driver->domainSnapshotDelete) {
        int ret = conn->driver->domainSnapshotDelete(snapshot, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

19363
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
C
Chris Lalancette 已提交
19364 19365 19366 19367 19368
error:
    virDispatchError(conn);
    return -1;
}

19369 19370 19371 19372 19373 19374 19375 19376 19377 19378 19379 19380 19381 19382 19383 19384 19385 19386 19387 19388 19389 19390 19391 19392 19393 19394
/**
 * virDomainSnapshotRef:
 * @snapshot: the snapshot to hold a reference on
 *
 * Increment the reference count on the snapshot. For each
 * additional call to this method, there shall be a corresponding
 * call to virDomainSnapshotFree to release the reference count, once
 * the caller no longer needs the reference to this object.
 *
 * This method is typically useful for applications where multiple
 * threads are using a connection, and it is required that the
 * connection and domain remain open until all threads have finished
 * using the snapshot. ie, each new thread using a snapshot would
 * increment the reference count.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainSnapshotRef(virDomainSnapshotPtr snapshot)
{
    if ((!VIR_IS_DOMAIN_SNAPSHOT(snapshot))) {
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
                                  __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
19395 19396
    VIR_DEBUG("snapshot=%p, refs=%d", snapshot, snapshot->object.refs);
    virObjectRef(snapshot);
19397 19398 19399
    return 0;
}

C
Chris Lalancette 已提交
19400 19401 19402 19403 19404 19405 19406 19407 19408 19409 19410 19411
/**
 * virDomainSnapshotFree:
 * @snapshot: a domain snapshot object
 *
 * Free the domain snapshot object.  The snapshot itself is not modified.
 * The data structure is freed and should not be used thereafter.
 *
 * Returns 0 in case of success and -1 in case of failure.
 */
int
virDomainSnapshotFree(virDomainSnapshotPtr snapshot)
{
19412
    VIR_DEBUG("snapshot=%p", snapshot);
C
Chris Lalancette 已提交
19413 19414 19415 19416

    virResetLastError();

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
19417
        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
C
Chris Lalancette 已提交
19418 19419 19420 19421
                                  __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
19422
    virObjectUnref(snapshot);
C
Chris Lalancette 已提交
19423 19424
    return 0;
}
19425 19426 19427 19428

/**
 * virDomainOpenConsole:
 * @dom: a domain object
19429
 * @dev_name: the console, serial or parallel port device alias, or NULL
19430
 * @st: a stream to associate with the console
19431
 * @flags: bitwise-OR of virDomainConsoleFlags
19432 19433 19434
 *
 * This opens the backend associated with a console, serial or
 * parallel port device on a guest, if the backend is supported.
19435
 * If the @dev_name is omitted, then the first console or serial
19436 19437 19438 19439
 * device is opened. The console is associated with the passed
 * in @st stream, which should have been opened in non-blocking
 * mode for bi-directional I/O.
 *
19440 19441 19442 19443 19444 19445 19446 19447 19448 19449 19450 19451 19452 19453 19454
 * By default, when @flags is 0, the open will fail if libvirt
 * detects that the console is already in use by another client;
 * passing VIR_DOMAIN_CONSOLE_FORCE will cause libvirt to forcefully
 * remove the other client prior to opening this console.
 *
 * If flag VIR_DOMAIN_CONSOLE_SAFE the console is opened only in the
 * case where the hypervisor driver supports safe (mutually exclusive)
 * console handling.
 *
 * Older servers did not support either flag, and also did not forbid
 * simultaneous clients on a console, with potentially confusing results.
 * When passing @flags of 0 in order to support a wider range of server
 * versions, it is up to the client to ensure mutual exclusion.
 *
 * Returns 0 if the console was opened, -1 on error
19455 19456
 */
int virDomainOpenConsole(virDomainPtr dom,
19457
                         const char *dev_name,
19458 19459 19460 19461
                         virStreamPtr st,
                         unsigned int flags)
{
    virConnectPtr conn;
19462

19463 19464
    VIR_DOMAIN_DEBUG(dom, "dev_name=%s, st=%p, flags=%x",
                     NULLSTR(dev_name), st, flags);
19465 19466 19467 19468

    virResetLastError();

    if (!VIR_IS_DOMAIN(dom)) {
19469
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
19470 19471 19472 19473 19474 19475
        virDispatchError(NULL);
        return -1;
    }

    conn = dom->conn;
    if (conn->flags & VIR_CONNECT_RO) {
19476
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
19477 19478 19479 19480 19481
        goto error;
    }

    if (conn->driver->domainOpenConsole) {
        int ret;
19482
        ret = conn->driver->domainOpenConsole(dom, dev_name, st, flags);
19483 19484 19485 19486 19487
        if (ret < 0)
            goto error;
        return ret;
    }

19488
    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
19489 19490 19491 19492 19493

error:
    virDispatchError(conn);
    return -1;
}
19494

19495 19496 19497 19498 19499 19500 19501 19502 19503 19504 19505 19506 19507 19508 19509 19510 19511 19512 19513 19514 19515 19516 19517 19518 19519 19520 19521 19522 19523 19524 19525 19526 19527 19528 19529 19530 19531 19532 19533 19534 19535 19536 19537 19538 19539 19540 19541 19542 19543 19544 19545 19546 19547 19548 19549 19550 19551 19552 19553 19554 19555
/**
 * virDomainOpenChannel:
 * @dom: a domain object
 * @name: the channel name, or NULL
 * @st: a stream to associate with the channel
 * @flags: bitwise-OR of virDomainChannelFlags
 *
 * This opens the host interface associated with a channel device on a
 * guest, if the host interface is supported.  If @name is given, it
 * can match either the device alias (e.g. "channel0"), or the virtio
 * target name (e.g. "org.qemu.guest_agent.0").  If @name is omitted,
 * then the first channel is opened. The channel is associated with
 * the passed in @st stream, which should have been opened in
 * non-blocking mode for bi-directional I/O.
 *
 * By default, when @flags is 0, the open will fail if libvirt detects
 * that the channel is already in use by another client; passing
 * VIR_DOMAIN_CHANNEL_FORCE will cause libvirt to forcefully remove the
 * other client prior to opening this channel.
 *
 * Returns 0 if the channel was opened, -1 on error
 */
int virDomainOpenChannel(virDomainPtr dom,
                         const char *name,
                         virStreamPtr st,
                         unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(dom, "name=%s, st=%p, flags=%x",
                     NULLSTR(name), st, flags);

    virResetLastError();

    if (!VIR_IS_DOMAIN(dom)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = dom->conn;
    if (conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (conn->driver->domainOpenChannel) {
        int ret;
        ret = conn->driver->domainOpenChannel(dom, name, st, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}

19556 19557 19558
/**
 * virDomainBlockJobAbort:
 * @dom: pointer to domain object
19559
 * @disk: path to the block device, or device shorthand
19560
 * @flags: bitwise-OR of virDomainBlockJobAbortFlags
19561 19562 19563
 *
 * Cancel the active block job on the given disk.
 *
19564
 * The @disk parameter is either an unambiguous source name of the
19565 19566 19567 19568 19569 19570
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or (since 0.9.5) the device target shorthand
 * (the <target dev='...'/> sub-element, such as "xvda").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
 *
E
Eric Blake 已提交
19571 19572
 * If the current block job for @disk is VIR_DOMAIN_BLOCK_JOB_TYPE_PULL, then
 * by default, this function performs a synchronous operation and the caller
19573 19574 19575 19576 19577 19578 19579 19580
 * may assume that the operation has completed when 0 is returned.  However,
 * BlockJob operations may take a long time to cancel, and during this time
 * further domain interactions may be unresponsive.  To avoid this problem,
 * pass VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC in the @flags argument to enable
 * asynchronous behavior, returning as soon as possible.  When the job has
 * been canceled, a BlockJob event will be emitted, with status
 * VIR_DOMAIN_BLOCK_JOB_CANCELED (even if the ABORT_ASYNC flag was not
 * used); it is also possible to poll virDomainBlockJobInfo() to see if
E
Eric Blake 已提交
19581 19582 19583 19584 19585 19586 19587 19588 19589 19590 19591 19592
 * the job cancellation is still pending.  This type of job can be restarted
 * to pick up from where it left off.
 *
 * If the current block job for @disk is VIR_DOMAIN_BLOCK_JOB_TYPE_COPY, then
 * the default is to abort the mirroring and revert to the source disk;
 * adding @flags of VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT causes this call to
 * fail with VIR_ERR_BLOCK_COPY_ACTIVE if the copy is not fully populated,
 * otherwise it will swap the disk over to the copy to end the mirroring.  An
 * event will be issued when the job is ended, and it is possible to use
 * VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC to control whether this command waits
 * for the completion of the job.  Restarting this job requires starting
 * over from the beginning of the first phase.
19593
 *
19594 19595
 * Returns -1 in case of failure, 0 when successful.
 */
19596
int virDomainBlockJobAbort(virDomainPtr dom, const char *disk,
19597 19598 19599 19600
                           unsigned int flags)
{
    virConnectPtr conn;

19601
    VIR_DOMAIN_DEBUG(dom, "disk=%s, flags=%x", disk, flags);
19602 19603 19604

    virResetLastError();

19605
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
19606 19607 19608 19609 19610 19611 19612 19613 19614 19615 19616
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = dom->conn;

    if (dom->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

19617
    virCheckNonNullArgGoto(disk, error);
19618 19619 19620

    if (conn->driver->domainBlockJobAbort) {
        int ret;
19621
        ret = conn->driver->domainBlockJobAbort(dom, disk, flags);
19622 19623 19624 19625 19626 19627 19628 19629 19630 19631 19632 19633 19634 19635 19636
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}

/**
 * virDomainGetBlockJobInfo:
 * @dom: pointer to domain object
19637
 * @disk: path to the block device, or device shorthand
19638
 * @info: pointer to a virDomainBlockJobInfo structure
19639
 * @flags: extra flags; not used yet, so callers should always pass 0
19640 19641 19642 19643
 *
 * Request block job information for the given disk.  If an operation is active
 * @info will be updated with the current progress.
 *
19644
 * The @disk parameter is either an unambiguous source name of the
19645 19646 19647 19648 19649 19650
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or (since 0.9.5) the device target shorthand
 * (the <target dev='...'/> sub-element, such as "xvda").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
 *
19651 19652
 * Returns -1 in case of failure, 0 when nothing found, 1 when info was found.
 */
19653
int virDomainGetBlockJobInfo(virDomainPtr dom, const char *disk,
19654 19655 19656 19657
                             virDomainBlockJobInfoPtr info, unsigned int flags)
{
    virConnectPtr conn;

19658
    VIR_DOMAIN_DEBUG(dom, "disk=%s, info=%p, flags=%x", disk, info, flags);
19659 19660 19661

    virResetLastError();

19662
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
19663 19664 19665 19666 19667 19668
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = dom->conn;

19669 19670
    virCheckNonNullArgGoto(disk, error);
    virCheckNonNullArgGoto(info, error);
19671 19672 19673

    if (conn->driver->domainGetBlockJobInfo) {
        int ret;
19674
        ret = conn->driver->domainGetBlockJobInfo(dom, disk, info, flags);
19675 19676 19677 19678 19679 19680 19681 19682 19683 19684 19685 19686 19687 19688 19689
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}

/**
 * virDomainBlockJobSetSpeed:
 * @dom: pointer to domain object
19690
 * @disk: path to the block device, or device shorthand
19691
 * @bandwidth: specify bandwidth limit in MiB/s
19692
 * @flags: extra flags; not used yet, so callers should always pass 0
19693 19694 19695 19696
 *
 * Set the maximimum allowable bandwidth that a block job may consume.  If
 * bandwidth is 0, the limit will revert to the hypervisor default.
 *
19697
 * The @disk parameter is either an unambiguous source name of the
19698 19699 19700 19701 19702 19703
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or (since 0.9.5) the device target shorthand
 * (the <target dev='...'/> sub-element, such as "xvda").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
 *
19704 19705
 * Returns -1 in case of failure, 0 when successful.
 */
19706
int virDomainBlockJobSetSpeed(virDomainPtr dom, const char *disk,
19707 19708 19709 19710
                              unsigned long bandwidth, unsigned int flags)
{
    virConnectPtr conn;

19711
    VIR_DOMAIN_DEBUG(dom, "disk=%s, bandwidth=%lu, flags=%x",
19712
                     disk, bandwidth, flags);
19713 19714 19715

    virResetLastError();

19716
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
19717 19718 19719 19720 19721 19722 19723 19724 19725 19726 19727
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = dom->conn;

    if (dom->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

19728
    virCheckNonNullArgGoto(disk, error);
19729 19730 19731

    if (conn->driver->domainBlockJobSetSpeed) {
        int ret;
19732
        ret = conn->driver->domainBlockJobSetSpeed(dom, disk, bandwidth, flags);
19733 19734 19735 19736 19737 19738 19739 19740 19741 19742 19743 19744 19745 19746 19747
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}

/**
 * virDomainBlockPull:
 * @dom: pointer to domain object
19748
 * @disk: path to the block device, or device shorthand
19749
 * @bandwidth: (optional) specify copy bandwidth limit in MiB/s
19750
 * @flags: extra flags; not used yet, so callers should always pass 0
19751 19752 19753 19754 19755 19756
 *
 * Populate a disk image with data from its backing image.  Once all data from
 * its backing image has been pulled, the disk no longer depends on a backing
 * image.  This function pulls data for the entire device in the background.
 * Progress of the operation can be checked with virDomainGetBlockJobInfo() and
 * the operation can be aborted with virDomainBlockJobAbort().  When finished,
E
Eric Blake 已提交
19757 19758
 * an asynchronous event is raised to indicate the final status.  To move
 * data in the opposite direction, see virDomainBlockCommit().
19759
 *
19760
 * The @disk parameter is either an unambiguous source name of the
19761 19762 19763 19764 19765 19766
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or (since 0.9.5) the device target shorthand
 * (the <target dev='...'/> sub-element, such as "xvda").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
 *
19767
 * The maximum bandwidth (in MiB/s) that will be used to do the copy can be
19768 19769
 * specified with the bandwidth parameter.  If set to 0, libvirt will choose a
 * suitable default.  Some hypervisors do not support this feature and will
19770 19771 19772
 * return an error if bandwidth is not 0; in this case, it might still be
 * possible for a later call to virDomainBlockJobSetSpeed() to succeed.
 * The actual speed can be determined with virDomainGetBlockJobInfo().
19773
 *
19774 19775
 * This is shorthand for virDomainBlockRebase() with a NULL base.
 *
19776 19777
 * Returns 0 if the operation has started, -1 on failure.
 */
19778
int virDomainBlockPull(virDomainPtr dom, const char *disk,
19779 19780 19781 19782
                       unsigned long bandwidth, unsigned int flags)
{
    virConnectPtr conn;

19783
    VIR_DOMAIN_DEBUG(dom, "disk=%s, bandwidth=%lu, flags=%x",
19784
                     disk, bandwidth, flags);
19785 19786 19787

    virResetLastError();

19788
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
19789 19790 19791 19792 19793 19794 19795 19796 19797 19798 19799
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = dom->conn;

    if (dom->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

19800
    virCheckNonNullArgGoto(disk, error);
19801 19802 19803

    if (conn->driver->domainBlockPull) {
        int ret;
19804
        ret = conn->driver->domainBlockPull(dom, disk, bandwidth, flags);
19805 19806 19807 19808 19809 19810 19811 19812 19813 19814 19815
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}
19816 19817


19818 19819 19820 19821 19822
/**
 * virDomainBlockRebase:
 * @dom: pointer to domain object
 * @disk: path to the block device, or device shorthand
 * @base: path to backing file to keep, or NULL for no backing file
19823
 * @bandwidth: (optional) specify copy bandwidth limit in MiB/s
E
Eric Blake 已提交
19824
 * @flags: bitwise-OR of virDomainBlockRebaseFlags
19825 19826
 *
 * Populate a disk image with data from its backing image chain, and
E
Eric Blake 已提交
19827 19828 19829 19830
 * setting the backing image to @base, or alternatively copy an entire
 * backing chain to a new file @base.
 *
 * When @flags is 0, this starts a pull, where @base must be the absolute
19831 19832 19833 19834 19835
 * path of one of the backing images further up the chain, or NULL to
 * convert the disk image so that it has no backing image.  Once all
 * data from its backing image chain has been pulled, the disk no
 * longer depends on those intermediate backing images.  This function
 * pulls data for the entire device in the background.  Progress of
E
Eric Blake 已提交
19836 19837 19838 19839 19840 19841 19842 19843 19844 19845 19846 19847 19848 19849 19850 19851 19852 19853 19854 19855 19856 19857 19858 19859 19860 19861 19862 19863 19864 19865 19866 19867
 * the operation can be checked with virDomainGetBlockJobInfo() with a
 * job type of VIR_DOMAIN_BLOCK_JOB_TYPE_PULL, and the operation can be
 * aborted with virDomainBlockJobAbort().  When finished, an asynchronous
 * event is raised to indicate the final status, and the job no longer
 * exists.  If the job is aborted, a new one can be started later to
 * resume from the same point.
 *
 * When @flags includes VIR_DOMAIN_BLOCK_REBASE_COPY, this starts a copy,
 * where @base must be the name of a new file to copy the chain to.  By
 * default, the copy will pull the entire source chain into the destination
 * file, but if @flags also contains VIR_DOMAIN_BLOCK_REBASE_SHALLOW, then
 * only the top of the source chain will be copied (the source and
 * destination have a common backing file).  By default, @base will be
 * created with the same file format as the source, but this can be altered
 * by adding VIR_DOMAIN_BLOCK_REBASE_COPY_RAW to force the copy to be raw
 * (does not make sense with the shallow flag unless the source is also raw),
 * or by using VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT to reuse an existing file
 * with initial contents identical to the backing file of the source (this
 * allows a management app to pre-create files with relative backing file
 * names, rather than the default of absolute backing file names; as a
 * security precaution, you should generally only use reuse_ext with the
 * shallow flag and a non-raw destination file).
 *
 * A copy job has two parts; in the first phase, the @bandwidth parameter
 * affects how fast the source is pulled into the destination, and the job
 * can only be canceled by reverting to the source file; progress in this
 * phase can be tracked via the virDomainBlockJobInfo() command, with a
 * job type of VIR_DOMAIN_BLOCK_JOB_TYPE_COPY.  The job transitions to the
 * second phase when the job info states cur == end, and remains alive to
 * mirror all further changes to both source and destination.  The user
 * must call virDomainBlockJobAbort() to end the mirroring while choosing
 * whether to revert to source or pivot to the destination.  An event is
19868 19869 19870 19871
 * issued when the job ends, and depending on the hypervisor, an event may
 * also be issued when the job transitions from pulling to mirroring.  If
 * the job is aborted, a new job will have to start over from the beginning
 * of the first phase.
E
Eric Blake 已提交
19872 19873 19874 19875
 *
 * Some hypervisors will restrict certain actions, such as virDomainSave()
 * or virDomainDetachDevice(), while a copy job is active; they may
 * also restrict a copy job to transient domains.
19876 19877 19878 19879 19880 19881 19882 19883
 *
 * The @disk parameter is either an unambiguous source name of the
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or the device target shorthand (the
 * <target dev='...'/> sub-element, such as "xvda").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
 *
19884
 * The maximum bandwidth (in MiB/s) that will be used to do the copy can be
19885 19886
 * specified with the bandwidth parameter.  If set to 0, libvirt will choose a
 * suitable default.  Some hypervisors do not support this feature and will
19887 19888 19889
 * return an error if bandwidth is not 0; in this case, it might still be
 * possible for a later call to virDomainBlockJobSetSpeed() to succeed.
 * The actual speed can be determined with virDomainGetBlockJobInfo().
19890
 *
E
Eric Blake 已提交
19891 19892
 * When @base is NULL and @flags is 0, this is identical to
 * virDomainBlockPull().
19893 19894 19895 19896 19897 19898 19899 19900 19901
 *
 * Returns 0 if the operation has started, -1 on failure.
 */
int virDomainBlockRebase(virDomainPtr dom, const char *disk,
                         const char *base, unsigned long bandwidth,
                         unsigned int flags)
{
    virConnectPtr conn;

E
Eric Blake 已提交
19902
    VIR_DOMAIN_DEBUG(dom, "disk=%s, base=%s, bandwidth=%lu, flags=%x",
19903 19904 19905 19906
                     disk, NULLSTR(base), bandwidth, flags);

    virResetLastError();

19907
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
19908 19909 19910 19911 19912 19913 19914 19915 19916 19917 19918
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = dom->conn;

    if (dom->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

19919
    virCheckNonNullArgGoto(disk, error);
19920

E
Eric Blake 已提交
19921
    if (flags & VIR_DOMAIN_BLOCK_REBASE_COPY) {
19922
        virCheckNonNullArgGoto(base, error);
E
Eric Blake 已提交
19923 19924 19925
    } else if (flags & (VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
                        VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
                        VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)) {
19926 19927 19928
        virReportInvalidArg(flags,
                            _("use of flags in %s requires a copy job"),
                            __FUNCTION__);
E
Eric Blake 已提交
19929 19930 19931
        goto error;
    }

19932 19933 19934 19935 19936 19937 19938 19939 19940 19941 19942 19943 19944 19945 19946 19947 19948
    if (conn->driver->domainBlockRebase) {
        int ret;
        ret = conn->driver->domainBlockRebase(dom, disk, base, bandwidth,
                                              flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}


E
Eric Blake 已提交
19949 19950 19951 19952 19953 19954 19955 19956 19957 19958 19959 19960 19961 19962 19963 19964 19965 19966 19967 19968 19969 19970 19971 19972 19973 19974 19975 19976 19977 19978 19979 19980 19981 19982 19983 19984 19985 19986 19987 19988 19989 19990 19991 19992 19993 19994 19995 19996 19997 19998 19999 20000 20001 20002 20003 20004 20005 20006 20007 20008 20009 20010 20011 20012 20013 20014 20015 20016 20017 20018 20019 20020 20021 20022 20023 20024 20025 20026 20027 20028 20029 20030 20031 20032 20033 20034 20035 20036 20037 20038 20039 20040 20041 20042 20043 20044 20045 20046 20047 20048 20049 20050 20051 20052 20053 20054 20055
/**
 * virDomainBlockCommit:
 * @dom: pointer to domain object
 * @disk: path to the block device, or device shorthand
 * @base: path to backing file to merge into, or NULL for default
 * @top: path to file within backing chain that contains data to be merged,
 *       or NULL to merge all possible data
 * @bandwidth: (optional) specify commit bandwidth limit in MiB/s
 * @flags: bitwise-OR of virDomainBlockCommitFlags
 *
 * Commit changes that were made to temporary top-level files within a disk
 * image backing file chain into a lower-level base file.  In other words,
 * take all the difference between @base and @top, and update @base to contain
 * that difference; after the commit, any portion of the chain that previously
 * depended on @top will now depend on @base, and all files after @base up
 * to and including @top will now be invalidated.  A typical use of this
 * command is to reduce the length of a backing file chain after taking an
 * external disk snapshot.  To move data in the opposite direction, see
 * virDomainBlockPull().
 *
 * This command starts a long-running commit block job, whose status may
 * be tracked by virDomainBlockJobInfo() with a job type of
 * VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT, and the operation can be aborted with
 * virDomainBlockJobAbort().  When finished, an asynchronous event is
 * raised to indicate the final status, and the job no longer exists.  If
 * the job is aborted, it is up to the hypervisor whether starting a new
 * job will resume from the same point, or start over.
 *
 * Be aware that this command may invalidate files even if it is aborted;
 * the user is cautioned against relying on the contents of invalidated
 * intermediate files such as @top without manually rebasing those files
 * to use a backing file of a read-only copy of @base prior to the point
 * where the commit operation was started (although such a rebase cannot
 * be safely done until the commit has successfully completed).  However,
 * the domain itself will not have any issues; the active layer remains
 * valid throughout the entire commit operation.  As a convenience,
 * if @flags contains VIR_DOMAIN_BLOCK_COMMIT_DELETE, this command will
 * unlink all files that were invalidated, after the commit successfully
 * completes.
 *
 * By default, if @base is NULL, the commit target will be the bottom of
 * the backing chain; if @flags contains VIR_DOMAIN_BLOCK_COMMIT_SHALLOW,
 * then the immediate backing file of @top will be used instead.  If @top
 * is NULL, the active image at the top of the chain will be used.  Some
 * hypervisors place restrictions on how much can be committed, and might
 * fail if @base is not the immediate backing file of @top, or if @top is
 * the active layer in use by a running domain, or if @top is not the
 * top-most file; restrictions may differ for online vs. offline domains.
 *
 * The @disk parameter is either an unambiguous source name of the
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or the device target shorthand (the
 * <target dev='...'/> sub-element, such as "xvda").  Valid names
 * can be found by calling virDomainGetXMLDesc() and inspecting
 * elements within //domain/devices/disk.
 *
 * The maximum bandwidth (in MiB/s) that will be used to do the commit can be
 * specified with the bandwidth parameter.  If set to 0, libvirt will choose a
 * suitable default.  Some hypervisors do not support this feature and will
 * return an error if bandwidth is not 0; in this case, it might still be
 * possible for a later call to virDomainBlockJobSetSpeed() to succeed.
 * The actual speed can be determined with virDomainGetBlockJobInfo().
 *
 * Returns 0 if the operation has started, -1 on failure.
 */
int virDomainBlockCommit(virDomainPtr dom, const char *disk,
                         const char *base, const char *top,
                         unsigned long bandwidth, unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(dom, "disk=%s, base=%s, top=%s, bandwidth=%lu, flags=%x",
                     disk, NULLSTR(base), NULLSTR(top), bandwidth, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
    conn = dom->conn;

    if (dom->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    virCheckNonNullArgGoto(disk, error);

    if (conn->driver->domainBlockCommit) {
        int ret;
        ret = conn->driver->domainBlockCommit(dom, disk, base, top, bandwidth,
                                              flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}


20056 20057 20058 20059 20060
/**
 * virDomainOpenGraphics:
 * @dom: pointer to domain object
 * @idx: index of graphics config to open
 * @fd: file descriptor to attach graphics to
20061
 * @flags: bitwise-OR of virDomainOpenGraphicsFlags
20062 20063 20064 20065 20066 20067 20068 20069 20070 20071 20072 20073 20074 20075 20076 20077 20078 20079 20080 20081 20082 20083 20084 20085 20086 20087 20088 20089 20090 20091 20092 20093 20094 20095 20096
 *
 * This will attempt to connect the file descriptor @fd, to
 * the graphics backend of @dom. If @dom has multiple graphics
 * backends configured, then @idx will determine which one is
 * opened, starting from @idx 0.
 *
 * To disable any authentication, pass the VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
 * constant for @flags.
 *
 * The caller should use an anonymous socketpair to open
 * @fd before invocation.
 *
 * This method can only be used when connected to a local
 * libvirt hypervisor, over a UNIX domain socket. Attempts
 * to use this method over a TCP connection will always fail
 *
 * Returns 0 on success, -1 on failure
 */
int virDomainOpenGraphics(virDomainPtr dom,
                          unsigned int idx,
                          int fd,
                          unsigned int flags)
{
    struct stat sb;
    VIR_DOMAIN_DEBUG(dom, "idx=%u, fd=%d, flags=%x",
                     idx, fd, flags);

    virResetLastError();

    if (!VIR_IS_DOMAIN(dom)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

20097
    virCheckNonNegativeArgGoto(fd, error);
20098 20099 20100 20101 20102 20103 20104 20105

    if (fstat(fd, &sb) < 0) {
        virReportSystemError(errno,
                             _("Unable to access file descriptor %d"), fd);
        goto error;
    }

    if (!S_ISSOCK(sb.st_mode)) {
20106 20107 20108
        virReportInvalidArg(fd,
                          _("fd %d in %s must be a socket"),
                            fd, __FUNCTION__);
20109 20110 20111 20112 20113 20114 20115 20116 20117 20118 20119 20120 20121 20122 20123 20124 20125 20126 20127 20128 20129 20130 20131 20132 20133 20134 20135 20136
        goto error;
    }

    if (dom->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (!VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
                                  VIR_DRV_FEATURE_FD_PASSING)) {
        virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
        goto error;
    }

    if (dom->conn->driver->domainOpenGraphics) {
        int ret;
        ret = dom->conn->driver->domainOpenGraphics(dom, idx, fd, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}
J
Jiri Denemark 已提交
20137 20138 20139 20140 20141 20142 20143 20144 20145 20146 20147 20148 20149 20150 20151 20152 20153 20154 20155 20156


/**
 * virConnectSetKeepAlive:
 * @conn: pointer to a hypervisor connection
 * @interval: number of seconds of inactivity before a keepalive message is sent
 * @count: number of messages that can be sent in a row
 *
 * Start sending keepalive messages after interval second of inactivity and
 * consider the connection to be broken when no response is received after
 * count keepalive messages sent in a row.  In other words, sending count + 1
 * keepalive message results in closing the connection.  When interval is <= 0,
 * no keepalive messages will be sent.  When count is 0, the connection will be
 * automatically closed after interval seconds of inactivity without sending
 * any keepalive messages.
 *
 * Note: client has to implement and run event loop to be able to use keepalive
 * messages.  Failure to do so may result in connections being closed
 * unexpectedly.
 *
20157 20158 20159 20160
 * Note: This API function controls only keepalive messages sent by the client.
 * If the server is configured to use keepalive you still need to run the event
 * loop to respond to them, even if you disable keepalives by this function.
 *
J
Jiri Denemark 已提交
20161 20162 20163 20164 20165 20166 20167 20168 20169 20170 20171 20172 20173 20174 20175 20176 20177 20178 20179
 * Returns -1 on error, 0 on success, 1 when remote party doesn't support
 * keepalive messages.
 */
int virConnectSetKeepAlive(virConnectPtr conn,
                           int interval,
                           unsigned int count)
{
    int ret = -1;

    VIR_DEBUG("conn=%p, interval=%d, count=%u", conn, interval, count);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

20180 20181
    if (conn->driver->connectSetKeepAlive) {
        ret = conn->driver->connectSetKeepAlive(conn, interval, count);
J
Jiri Denemark 已提交
20182 20183 20184 20185 20186 20187 20188 20189 20190 20191 20192
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}
J
Jiri Denemark 已提交
20193 20194 20195 20196 20197 20198 20199 20200 20201 20202 20203 20204 20205 20206 20207 20208 20209 20210 20211 20212 20213 20214 20215

/**
 * virConnectIsAlive:
 * @conn: pointer to the connection object
 *
 * Determine if the connection to the hypervisor is still alive
 *
 * A connection will be classed as alive if it is either local, or running
 * over a channel (TCP or UNIX socket) which is not closed.
 *
 * Returns 1 if alive, 0 if dead, -1 on error
 */
int virConnectIsAlive(virConnectPtr conn)
{
    VIR_DEBUG("conn=%p", conn);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }
20216
    if (conn->driver->connectIsAlive) {
J
Jiri Denemark 已提交
20217
        int ret;
20218
        ret = conn->driver->connectIsAlive(conn);
J
Jiri Denemark 已提交
20219 20220 20221 20222 20223 20224 20225 20226 20227 20228
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
    virDispatchError(conn);
    return -1;
}
20229 20230


20231 20232 20233 20234 20235 20236 20237 20238 20239 20240 20241 20242 20243 20244 20245 20246 20247 20248 20249 20250 20251 20252 20253 20254 20255 20256 20257 20258 20259 20260 20261 20262 20263 20264 20265 20266 20267 20268
/**
 * virConnectRegisterCloseCallback:
 * @conn: pointer to connection object
 * @cb: callback to invoke upon close
 * @opaque: user data to pass to @cb
 * @freecb: callback to free @opaque
 *
 * Registers a callback to be invoked when the connection
 * is closed. This callback is invoked when there is any
 * condition that causes the socket connection to the
 * hypervisor to be closed.
 *
 * This function is only applicable to hypervisor drivers
 * which maintain a persistent open connection. Drivers
 * which open a new connection for every operation will
 * not invoke this.
 *
 * The @freecb must not invoke any other libvirt public
 * APIs, since it is not called from a re-entrant safe
 * context.
 *
 * Returns 0 on success, -1 on error
 */
int virConnectRegisterCloseCallback(virConnectPtr conn,
                                    virConnectCloseFunc cb,
                                    void *opaque,
                                    virFreeCallback freecb)
{
    VIR_DEBUG("conn=%p", conn);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

20269 20270
    virObjectRef(conn);

20271
    virMutexLock(&conn->lock);
20272
    virObjectLock(conn->closeCallback);
20273 20274 20275

    virCheckNonNullArgGoto(cb, error);

20276
    if (conn->closeCallback->callback) {
20277 20278 20279 20280 20281
        virLibConnError(VIR_ERR_OPERATION_INVALID, "%s",
                        _("A close callback is already registered"));
        goto error;
    }

20282 20283 20284
    conn->closeCallback->callback = cb;
    conn->closeCallback->opaque = opaque;
    conn->closeCallback->freeCallback = freecb;
20285

20286
    virObjectUnlock(conn->closeCallback);
20287 20288 20289 20290 20291
    virMutexUnlock(&conn->lock);

    return 0;

error:
20292
    virObjectUnlock(conn->closeCallback);
20293
    virMutexUnlock(&conn->lock);
20294
    virObjectUnref(conn);
20295 20296 20297 20298 20299 20300 20301 20302 20303 20304 20305 20306 20307 20308 20309 20310 20311 20312 20313 20314 20315 20316 20317 20318 20319 20320 20321 20322 20323 20324 20325
    virDispatchError(NULL);
    return -1;
}

/**
 * virConnectUnregisterCloseCallback:
 * @conn: pointer to connection object
 * @cb: pointer to the current registered callback
 *
 * Unregisters the callback previously set with the
 * virConnectRegisterCloseCallback method. The callback
 * will no longer receive notifications when the connection
 * closes. If a virFreeCallback was provided at time of
 * registration, it will be invoked
 *
 * Returns 0 on success, -1 on error
 */
int virConnectUnregisterCloseCallback(virConnectPtr conn,
                                      virConnectCloseFunc cb)
{
    VIR_DEBUG("conn=%p", conn);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    virMutexLock(&conn->lock);
20326
    virObjectLock(conn->closeCallback);
20327 20328 20329

    virCheckNonNullArgGoto(cb, error);

20330
    if (conn->closeCallback->callback != cb) {
20331 20332 20333 20334 20335
        virLibConnError(VIR_ERR_OPERATION_INVALID, "%s",
                        _("A different callback was requested"));
        goto error;
    }

20336 20337 20338 20339
    conn->closeCallback->callback = NULL;
    if (conn->closeCallback->freeCallback)
        conn->closeCallback->freeCallback(conn->closeCallback->opaque);
    conn->closeCallback->freeCallback = NULL;
20340

20341
    virObjectUnref(conn);
20342 20343
    virObjectUnlock(conn->closeCallback);
    virMutexUnlock(&conn->lock);
20344

20345 20346 20347
    return 0;

error:
20348
    virObjectUnlock(conn->closeCallback);
20349 20350 20351 20352 20353
    virMutexUnlock(&conn->lock);
    virDispatchError(NULL);
    return -1;
}

20354 20355 20356 20357 20358 20359 20360
/**
 * virDomainSetBlockIoTune:
 * @dom: pointer to domain object
 * @disk: path to the block device, or device shorthand
 * @params: Pointer to blkio parameter objects
 * @nparams: Number of blkio parameters (this value can be the same or
 *           less than the number of parameters supported)
20361
 * @flags: bitwise-OR of virDomainModificationImpact
20362 20363 20364 20365 20366 20367 20368 20369 20370 20371 20372 20373 20374 20375 20376 20377 20378 20379 20380 20381
 *
 * Change all or a subset of the per-device block IO tunables.
 *
 * The @disk parameter is either an unambiguous source name of the
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or the device target shorthand (the <target
 * dev='...'/> sub-element, such as "xvda").  Valid names can be found
 * by calling virDomainGetXMLDesc() and inspecting elements
 * within //domain/devices/disk.
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int virDomainSetBlockIoTune(virDomainPtr dom,
                            const char *disk,
                            virTypedParameterPtr params,
                            int nparams,
                            unsigned int flags)
{
    virConnectPtr conn;

20382
    VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
20383 20384 20385 20386 20387 20388 20389 20390 20391 20392 20393 20394 20395 20396 20397
                     disk, params, nparams, flags);

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (dom->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

20398 20399 20400
    virCheckNonNullArgGoto(disk, error);
    virCheckPositiveArgGoto(nparams, error);
    virCheckNonNullArgGoto(params, error);
20401

20402
    if (virTypedParameterValidateSet(dom->conn, params, nparams) < 0)
20403
        goto error;
20404 20405 20406 20407 20408 20409 20410 20411 20412 20413 20414 20415 20416 20417 20418 20419 20420 20421 20422 20423 20424 20425 20426 20427 20428

    conn = dom->conn;

    if (conn->driver->domainSetBlockIoTune) {
        int ret;
        ret = conn->driver->domainSetBlockIoTune(dom, disk, params, nparams, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}

/**
 * virDomainGetBlockIoTune:
 * @dom: pointer to domain object
 * @disk: path to the block device, or device shorthand
 * @params: Pointer to blkio parameter object
 *          (return value, allocated by the caller)
 * @nparams: Pointer to number of blkio parameters
20429
 * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
20430 20431 20432 20433 20434 20435 20436 20437 20438 20439 20440 20441 20442 20443 20444 20445 20446 20447 20448 20449 20450 20451 20452 20453 20454 20455 20456 20457 20458 20459 20460 20461 20462
 *
 * Get all block IO tunable parameters for a given device.  On input,
 * @nparams gives the size of the @params array; on output, @nparams
 * gives how many slots were filled with parameter information, which
 * might be less but will not exceed the input value.
 *
 * As a special case, calling with @params as NULL and @nparams as 0
 * on input will cause @nparams on output to contain the number of
 * parameters supported by the hypervisor, either for the given @disk
 * (note that block devices of different types might support different
 * parameters), or if @disk is NULL, for all possible disks. The
 * caller should then allocate @params array,
 * i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
 * again.  See virDomainGetMemoryParameters() for more details.
 *
 * The @disk parameter is either an unambiguous source name of the
 * block device (the <source file='...'/> sub-element, such as
 * "/path/to/image"), or the device target shorthand (the <target
 * dev='...'/> sub-element, such as "xvda").  Valid names can be found
 * by calling virDomainGetXMLDesc() and inspecting elements
 * within //domain/devices/disk.  This parameter cannot be NULL
 * unless @nparams is 0 on input.
 *
 * Returns -1 in case of error, 0 in case of success.
 */
int virDomainGetBlockIoTune(virDomainPtr dom,
                            const char *disk,
                            virTypedParameterPtr params,
                            int *nparams,
                            unsigned int flags)
{
    virConnectPtr conn;

20463
    VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
20464 20465 20466 20467
                     NULLSTR(disk), params, (nparams) ? *nparams : -1, flags);

    virResetLastError();

20468
    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
20469 20470 20471 20472 20473
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

20474 20475 20476 20477 20478
    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (*nparams != 0) {
        virCheckNonNullArgGoto(params, error);
        virCheckNonNullArgGoto(disk, error);
20479 20480 20481 20482 20483 20484 20485 20486 20487
    }

    if (VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
                                 VIR_DRV_FEATURE_TYPED_PARAM_STRING))
        flags |= VIR_TYPED_PARAM_STRING_OKAY;

    /* At most one of these two flags should be set.  */
    if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
        (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
20488 20489 20490
        virReportInvalidArg(flags,
                            _("flags 'affect live' and 'affect config' in %s are mutually exclusive"),
                            __FUNCTION__);
20491 20492 20493 20494 20495 20496 20497 20498 20499 20500 20501 20502 20503 20504 20505 20506 20507 20508
        goto error;
    }
    conn = dom->conn;

    if (conn->driver->domainGetBlockIoTune) {
        int ret;
        ret = conn->driver->domainGetBlockIoTune(dom, disk, params, nparams, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}
20509 20510 20511 20512 20513 20514 20515 20516

/**
 * virDomainGetCPUStats:
 * @domain: domain to query
 * @params: array to populate on output
 * @nparams: number of parameters per cpu
 * @start_cpu: which cpu to start with, or -1 for summary
 * @ncpus: how many cpus to query
20517
 * @flags: bitwise-OR of virTypedParameterFlags
20518 20519 20520 20521 20522 20523 20524 20525 20526 20527 20528 20529 20530 20531
 *
 * Get statistics relating to CPU usage attributable to a single
 * domain (in contrast to the statistics returned by
 * virNodeGetCPUStats() for all processes on the host).  @dom
 * must be running (an inactive domain has no attributable cpu
 * usage).  On input, @params must contain at least @nparams * @ncpus
 * entries, allocated by the caller.
 *
 * If @start_cpu is -1, then @ncpus must be 1, and the returned
 * results reflect the statistics attributable to the entire
 * domain (such as user and system time for the process as a
 * whole).  Otherwise, @start_cpu represents which cpu to start
 * with, and @ncpus represents how many consecutive processors to
 * query, with statistics attributable per processor (such as
20532 20533 20534
 * per-cpu usage).  If @ncpus is larger than the number of cpus
 * available to query, then the trailing part of the array will
 * be unpopulated.
20535 20536 20537 20538 20539 20540 20541 20542 20543 20544 20545 20546 20547 20548 20549 20550 20551 20552 20553 20554 20555 20556 20557 20558 20559 20560 20561 20562 20563 20564
 *
 * The remote driver imposes a limit of 128 @ncpus and 16 @nparams;
 * the number of parameters per cpu should not exceed 16, but if you
 * have a host with more than 128 CPUs, your program should split
 * the request into multiple calls.
 *
 * As special cases, if @params is NULL and @nparams is 0 and
 * @ncpus is 1, and the return value will be how many
 * statistics are available for the given @start_cpu.  This number
 * may be different for @start_cpu of -1 than for any non-negative
 * value, but will be the same for all non-negative @start_cpu.
 * Likewise, if @params is NULL and @nparams is 0 and @ncpus is 0,
 * the number of cpus available to query is returned.  From the
 * host perspective, this would typically match the cpus member
 * of virNodeGetInfo(), but might be less due to host cpu hotplug.
 *
 * For now, @flags is unused, and the statistics all relate to the
 * usage from the host perspective.  It is possible that a future
 * version will support a flag that queries the cpu usage from the
 * guest's perspective, where the maximum cpu to query would be
 * related to virDomainGetVcpusFlags() rather than virNodeGetInfo().
 * An individual guest vcpu cannot be reliably mapped back to a
 * specific host cpu unless a single-processor vcpu pinning was used,
 * but when @start_cpu is -1, any difference in usage between a host
 * and guest perspective would serve as a measure of hypervisor overhead.
 *
 * Typical use sequence is below.
 *
 * getting total stats: set start_cpu as -1, ncpus 1
 * virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0) => nparams
20565
 * params = calloc(nparams, sizeof(virTypedParameter))
20566 20567 20568 20569 20570
 * virDomainGetCPUStats(dom, params, nparams, -1, 1, 0) => total stats.
 *
 * getting per-cpu stats:
 * virDomainGetCPUStats(dom, NULL, 0, 0, 0, 0) => ncpus
 * virDomainGetCPUStats(dom, NULL, 0, 0, 1, 0) => nparams
20571
 * params = calloc(ncpus * nparams, sizeof(virTypedParameter))
20572 20573 20574 20575 20576 20577 20578
 * virDomainGetCPUStats(dom, params, nparams, 0, ncpus, 0) => per-cpu stats
 *
 * Returns -1 on failure, or the number of statistics that were
 * populated per cpu on success (this will be less than the total
 * number of populated @params, unless @ncpus was 1; and may be
 * less than @nparams).  The populated parameters start at each
 * stride of @nparams, which means the results may be discontiguous;
20579 20580 20581 20582
 * any unpopulated parameters will be zeroed on success (this includes
 * skipped elements if @nparams is too large, and tail elements if
 * @ncpus is too large).  The caller is responsible for freeing any
 * returned string parameters.
20583 20584 20585 20586 20587 20588 20589 20590 20591 20592 20593 20594 20595 20596 20597 20598 20599 20600 20601 20602 20603 20604 20605 20606 20607 20608 20609
 */
int virDomainGetCPUStats(virDomainPtr domain,
                         virTypedParameterPtr params,
                         unsigned int nparams,
                         int start_cpu,
                         unsigned int ncpus,
                         unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain,
                     "params=%p, nparams=%d, start_cpu=%d, ncpus=%u, flags=%x",
                     params, nparams, start_cpu, ncpus, flags);
    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;
    /* Special cases:
     * start_cpu must be non-negative, or else -1
     * if start_cpu is -1, ncpus must be 1
     * params == NULL must match nparams == 0
     * ncpus must be non-zero unless params == NULL
20610
     * nparams * ncpus must not overflow (RPC may restrict it even more)
20611
     */
20612 20613 20614 20615 20616 20617 20618 20619 20620
    if (start_cpu == -1) {
        if (ncpus != 1) {
            virReportInvalidArg(start_cpu,
                                _("ncpus in %s must be 1 when start_cpu is -1"),
                                __FUNCTION__);
            goto error;
        }
    } else {
        virCheckNonNegativeArgGoto(start_cpu, error);
20621
    }
20622 20623 20624 20625 20626 20627 20628
    if (nparams)
        virCheckNonNullArgGoto(params, error);
    else
        virCheckNullArgGoto(params, error);
    if (ncpus == 0)
        virCheckNullArgGoto(params, error);

E
Eric Blake 已提交
20629 20630 20631 20632 20633
    if (nparams && ncpus > UINT_MAX / nparams) {
        virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %u * %u"),
                          nparams, ncpus);
        goto error;
    }
20634 20635 20636
    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_TYPED_PARAM_STRING))
        flags |= VIR_TYPED_PARAM_STRING_OKAY;
20637 20638 20639 20640 20641 20642 20643 20644 20645 20646 20647 20648 20649 20650 20651 20652 20653

    if (conn->driver->domainGetCPUStats) {
        int ret;

        ret = conn->driver->domainGetCPUStats(domain, params, nparams,
                                              start_cpu, ncpus, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return -1;
}
20654 20655 20656 20657 20658 20659 20660 20661 20662 20663 20664 20665 20666 20667 20668 20669 20670 20671 20672 20673 20674 20675 20676 20677 20678 20679 20680 20681 20682 20683 20684 20685 20686 20687 20688 20689 20690 20691 20692 20693 20694 20695 20696 20697 20698 20699 20700 20701 20702 20703 20704 20705 20706 20707 20708 20709 20710 20711 20712 20713 20714 20715 20716 20717 20718

/**
 * virDomainGetDiskErrors:
 * @dom: a domain object
 * @errors: array to populate on output
 * @maxerrors: size of @errors array
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * The function populates @errors array with all disks that encountered an
 * I/O error.  Disks with no error will not be returned in the @errors array.
 * Each disk is identified by its target (the dev attribute of target
 * subelement in domain XML), such as "vda", and accompanied with the error
 * that was seen on it.  The caller is also responsible for calling free()
 * on each disk name returned.
 *
 * In a special case when @errors is NULL and @maxerrors is 0, the function
 * returns preferred size of @errors that the caller should use to get all
 * disk errors.
 *
 * Since calling virDomainGetDiskErrors(dom, NULL, 0, 0) to get preferred size
 * of @errors array and getting the errors are two separate operations, new
 * disks may be hotplugged to the domain and new errors may be encountered
 * between the two calls.  Thus, this function may not return all disk errors
 * because the supplied array is not large enough.  Such errors may, however,
 * be detected by listening to domain events.
 *
 * Returns number of disks with errors filled in the @errors array or -1 on
 * error.
 */
int
virDomainGetDiskErrors(virDomainPtr dom,
                       virDomainDiskErrorPtr errors,
                       unsigned int maxerrors,
                       unsigned int flags)
{
    VIR_DOMAIN_DEBUG(dom, "errors=%p, maxerrors=%u, flags=%x",
                     errors, maxerrors, flags);

    virResetLastError();

    if (!VIR_IS_DOMAIN(dom)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if ((!errors && maxerrors) || (errors && !maxerrors)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        goto error;
    }

    if (dom->conn->driver->domainGetDiskErrors) {
        int ret = dom->conn->driver->domainGetDiskErrors(dom, errors,
                                                         maxerrors, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}
G
Guido Günther 已提交
20719 20720 20721 20722 20723 20724 20725 20726 20727 20728 20729 20730 20731 20732 20733 20734 20735 20736 20737

/**
 * virDomainGetHostname:
 * @domain: a domain object
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Get the hostname for that domain.
 *
 * Dependent on hypervisor used, this may require a guest agent to be
 * available.
 *
 * Returns the hostname which must be freed by the caller, or
 * NULL if there was an error.
 */
char *
virDomainGetHostname(virDomainPtr domain, unsigned int flags)
{
    virConnectPtr conn;

20738
    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
G
Guido Günther 已提交
20739 20740 20741 20742 20743 20744 20745 20746 20747 20748 20749 20750 20751

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }

    conn = domain->conn;

    if (conn->driver->domainGetHostname) {
        char *ret;
20752
        ret = conn->driver->domainGetHostname(domain, flags);
G
Guido Günther 已提交
20753 20754 20755 20756 20757 20758 20759 20760 20761 20762 20763
        if (!ret)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(domain->conn);
    return NULL;
}
20764 20765 20766 20767 20768 20769 20770 20771 20772 20773 20774 20775 20776 20777 20778 20779 20780 20781 20782 20783 20784 20785 20786 20787 20788 20789 20790 20791 20792 20793 20794 20795 20796 20797 20798 20799 20800 20801 20802 20803 20804 20805 20806 20807 20808 20809 20810 20811 20812 20813 20814

/**
 * virNodeGetCPUMap:
 * @conn: pointer to the hypervisor connection
 * @cpumap: optional pointer to a bit map of real CPUs on the host node
 *      (in 8-bit bytes) (OUT)
 *      In case of success each bit set to 1 means that corresponding
 *      CPU is online.
 *      Bytes are stored in little-endian order: CPU0-7, 8-15...
 *      In each byte, lowest CPU number is least significant bit.
 *      The bit map is allocated by virNodeGetCPUMap and needs
 *      to be released using free() by the caller.
 * @online: optional number of online CPUs in cpumap (OUT)
 *      Contains the number of online CPUs if the call was successful.
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * Get CPU map of host node CPUs.
 *
 * Returns number of CPUs present on the host node,
 * or -1 if there was an error.
 */
int
virNodeGetCPUMap(virConnectPtr conn,
                 unsigned char **cpumap,
                 unsigned int *online,
                 unsigned int flags)
{
    VIR_DEBUG("conn=%p, cpumap=%p, online=%p, flags=%x",
              conn, cpumap, online, flags);

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (conn->driver->nodeGetCPUMap) {
        int ret = conn->driver->nodeGetCPUMap(conn, cpumap, online, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(conn);
    return -1;
}
20815 20816 20817 20818

/**
 * virDomainFSTrim:
 * @dom: a domain object
20819
 * @mountPoint: which mount point to trim
20820 20821 20822 20823 20824 20825
 * @minimum: Minimum contiguous free range to discard in bytes
 * @flags: extra flags, not used yet, so callers should always pass 0
 *
 * Calls FITRIM within the guest (hence guest agent may be
 * required depending on hypervisor used). Either call it on each
 * mounted filesystem (@mountPoint is NULL) or just on specified
20826
 * @mountPoint. @minimum hints that free ranges smaller than this
20827 20828 20829 20830
 * may be ignored (this is a hint and the guest may not respect
 * it).  By increasing this value, the fstrim operation will
 * complete more quickly for filesystems with badly fragmented
 * free space, although not all blocks will be discarded.
20831
 * If @minimum is not zero, the command may fail.
20832 20833 20834 20835 20836 20837 20838 20839 20840 20841 20842 20843 20844 20845 20846 20847 20848 20849 20850 20851 20852 20853 20854 20855 20856 20857 20858 20859 20860 20861 20862 20863 20864 20865 20866 20867 20868 20869 20870
 *
 * Returns 0 on success, -1 otherwise.
 */
int
virDomainFSTrim(virDomainPtr dom,
                const char *mountPoint,
                unsigned long long minimum,
                unsigned int flags)
{
    VIR_DOMAIN_DEBUG(dom, "mountPoint=%s, minimum=%llu, flags=%x",
                     mountPoint, minimum, flags);

    virResetLastError();

    if (!VIR_IS_DOMAIN(dom)) {
        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    if (dom->conn->flags & VIR_CONNECT_RO) {
        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

    if (dom->conn->driver->domainFSTrim) {
        int ret = dom->conn->driver->domainFSTrim(dom, mountPoint,
                                                  minimum, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);

error:
    virDispatchError(dom->conn);
    return -1;
}