libvirt.c 83.5 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
 *
E
Eric Blake 已提交
5
 * Copyright (C) 2005-2006, 2008-2014 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 "virconf.h"
56
#if WITH_GNUTLS
57 58 59
# if WITH_GNUTLS_GCRYPT
#  include <gcrypt.h>
# endif
60 61
# include "rpc/virnettlscontext.h"
#endif
62
#include "vircommand.h"
63
#include "virfile.h"
64
#include "virrandom.h"
M
Martin Kletzander 已提交
65
#include "viruri.h"
66
#include "virthread.h"
67
#include "virstring.h"
E
Eric Blake 已提交
68
#include "virutil.h"
69
#include "virtypedparam.h"
70

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
#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_ESX
# include "esx/esx_driver.h"
#endif
#ifdef WITH_HYPERV
# include "hyperv/hyperv_driver.h"
#endif
#ifdef WITH_XENAPI
# include "xenapi/xenapi_driver.h"
94
#endif
D
Dmitry Guryanov 已提交
95 96 97
#ifdef WITH_PARALLELS
# include "parallels/parallels_driver.h"
#endif
R
Roman Bogorodskiy 已提交
98 99 100
#ifdef WITH_BHYVE
# include "bhyve/bhyve_driver.h"
#endif
101

102 103
#define VIR_FROM_THIS VIR_FROM_NONE

104 105
VIR_LOG_INIT("libvirt");

D
Daniel Veillard 已提交
106 107 108
/*
 * TODO:
 * - use lock to protect against concurrent accesses ?
D
Daniel Veillard 已提交
109
 * - use reference counting to guarantee coherent pointer state ?
D
Daniel Veillard 已提交
110 111
 */

112
#define MAX_DRIVERS 20
113

114 115 116 117 118 119 120 121 122 123
#define virDriverCheckTabMaxReturn(count, ret)                          \
    do {                                                                \
        if ((count) >= MAX_DRIVERS) {                                   \
            virReportError(VIR_ERR_INTERNAL_ERROR,                      \
                           _("Too many drivers, cannot register %s"),   \
                           driver->name);                               \
            return ret;                                                 \
        }                                                               \
    } while (0)

124 125
static virHypervisorDriverPtr virHypervisorDriverTab[MAX_DRIVERS];
static int virHypervisorDriverTabCount = 0;
126
static virNetworkDriverPtr virNetworkDriverTab[MAX_DRIVERS];
127
static int virNetworkDriverTabCount = 0;
D
Daniel Veillard 已提交
128 129
static virInterfaceDriverPtr virInterfaceDriverTab[MAX_DRIVERS];
static int virInterfaceDriverTabCount = 0;
130 131
static virStorageDriverPtr virStorageDriverTab[MAX_DRIVERS];
static int virStorageDriverTabCount = 0;
132 133
static virNodeDeviceDriverPtr virNodeDeviceDriverTab[MAX_DRIVERS];
static int virNodeDeviceDriverTabCount = 0;
134 135
static virSecretDriverPtr virSecretDriverTab[MAX_DRIVERS];
static int virSecretDriverTabCount = 0;
S
Stefan Berger 已提交
136 137
static virNWFilterDriverPtr virNWFilterDriverTab[MAX_DRIVERS];
static int virNWFilterDriverTabCount = 0;
A
Atsushi SAKAI 已提交
138
#ifdef WITH_LIBVIRTD
139 140
static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
static int virStateDriverTabCount = 0;
A
Atsushi SAKAI 已提交
141
#endif
142

143

144
#if defined(POLKIT_AUTH)
145 146 147
static int
virConnectAuthGainPolkit(const char *privilege)
{
E
Eric Blake 已提交
148 149
    virCommandPtr cmd;
    int ret = -1;
150

151
    if (geteuid() == 0)
152 153
        return 0;

E
Eric Blake 已提交
154
    cmd = virCommandNewArgList(POLKIT_AUTH, "--obtain", privilege, NULL);
155
    if (virCommandRun(cmd, NULL) < 0)
E
Eric Blake 已提交
156
        goto cleanup;
157

E
Eric Blake 已提交
158
    ret = 0;
159
 cleanup:
E
Eric Blake 已提交
160 161
    virCommandFree(cmd);
    return ret;
162 163 164
}
#endif

165 166 167 168 169 170

static int
virConnectAuthCallbackDefault(virConnectCredentialPtr cred,
                              unsigned int ncred,
                              void *cbdata ATTRIBUTE_UNUSED)
{
171
    size_t i;
172

173
    for (i = 0; i < ncred; i++) {
174 175
        char buf[1024];
        char *bufptr = buf;
176
        size_t len;
177 178

        switch (cred[i].type) {
179 180 181 182
        case VIR_CRED_EXTERNAL: {
            if (STRNEQ(cred[i].challenge, "PolicyKit"))
                return -1;

183
#if defined(POLKIT_AUTH)
184
            if (virConnectAuthGainPolkit(cred[i].prompt) < 0)
185
                return -1;
186 187 188 189 190 191 192
#else
            /*
             * Ignore & carry on. Although we can't auth
             * directly, the user may have authenticated
             * themselves already outside context of libvirt
             */
#endif
193 194
            break;
        }
195

196 197 198 199
        case VIR_CRED_USERNAME:
        case VIR_CRED_AUTHNAME:
        case VIR_CRED_ECHOPROMPT:
        case VIR_CRED_REALM:
200
            if (printf("%s: ", cred[i].prompt) < 0)
201 202 203 204
                return -1;
            if (fflush(stdout) != 0)
                return -1;

205 206 207 208 209 210 211
            if (!fgets(buf, sizeof(buf), stdin)) {
                if (feof(stdin)) { /* Treat EOF as "" */
                    buf[0] = '\0';
                    break;
                }
                return -1;
            }
212 213 214
            len = strlen(buf);
            if (len != 0 && buf[len-1] == '\n')
                buf[len-1] = '\0';
215 216 217 218
            break;

        case VIR_CRED_PASSPHRASE:
        case VIR_CRED_NOECHOPROMPT:
219
            if (printf("%s: ", cred[i].prompt) < 0)
220 221 222 223
                return -1;
            if (fflush(stdout) != 0)
                return -1;

224 225 226 227
            bufptr = getpass("");
            if (!bufptr)
                return -1;
            break;
228 229 230

        default:
            return -1;
231 232
        }

D
Daniel P. Berrange 已提交
233
        if (cred[i].type != VIR_CRED_EXTERNAL) {
234 235 236
            if (VIR_STRDUP(cred[i].result,
                           STREQ(bufptr, "") && cred[i].defresult ?
                           cred[i].defresult : bufptr) < 0)
D
Daniel P. Berrange 已提交
237 238 239
                return -1;
            cred[i].resultlen = strlen(cred[i].result);
        }
240 241 242 243 244
    }

    return 0;
}

245

246 247 248 249 250 251 252 253 254 255
/* 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,
256
    VIR_CRED_EXTERNAL,
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
};

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;

278 279
#if HAVE_WINSOCK2_H
static int
280
winsock_init(void)
281 282 283 284 285 286 287
{
    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 已提交
288
    return err == 0 ? 0 : -1;
289 290 291
}
#endif

292

293
#ifdef WITH_GNUTLS_GCRYPT
294 295
static int
virTLSMutexInit(void **priv)
296
{
D
Daniel P. Berrange 已提交
297 298
    virMutexPtr lock = NULL;

299
    if (VIR_ALLOC_QUIET(lock) < 0)
D
Daniel P. Berrange 已提交
300 301 302 303 304 305 306 307 308 309 310
        return ENOMEM;

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

    *priv = lock;
    return 0;
}

311 312 313

static int
virTLSMutexDestroy(void **priv)
D
Daniel P. Berrange 已提交
314 315 316 317 318 319 320
{
    virMutexPtr lock = *priv;
    virMutexDestroy(lock);
    VIR_FREE(lock);
    return 0;
}

321 322 323

static int
virTLSMutexLock(void **priv)
D
Daniel P. Berrange 已提交
324 325 326 327 328 329
{
    virMutexPtr lock = *priv;
    virMutexLock(lock);
    return 0;
}

330 331 332

static int
virTLSMutexUnlock(void **priv)
D
Daniel P. Berrange 已提交
333 334 335 336 337 338
{
    virMutexPtr lock = *priv;
    virMutexUnlock(lock);
    return 0;
}

339

D
Daniel P. Berrange 已提交
340
static struct gcry_thread_cbs virTLSThreadImpl = {
341
    /* GCRY_THREAD_OPTION_VERSION was added in gcrypt 1.4.2 */
342
# ifdef GCRY_THREAD_OPTION_VERSION
D
Daniel P. Berrange 已提交
343
    (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)),
344
# else
345
    GCRY_THREAD_OPTION_PTHREAD,
346
# endif
D
Daniel P. Berrange 已提交
347 348 349 350 351 352 353
    NULL,
    virTLSMutexInit,
    virTLSMutexDestroy,
    virTLSMutexLock,
    virTLSMutexUnlock,
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
354
#endif /* WITH_GNUTLS_GCRYPT */
D
Daniel P. Berrange 已提交
355

356

357 358
static bool virGlobalError = false;
static virOnceControl virGlobalOnce = VIR_ONCE_CONTROL_INITIALIZER;
359

360 361 362
static void
virGlobalInit(void)
{
363 364 365 366 367
    /* It would be nice if we could trace the use of this call, to
     * help diagnose in log files if a user calls something other than
     * virConnectOpen first.  But we can't rely on VIR_DEBUG working
     * until after initialization is complete, and since this is
     * one-shot, we never get here again.  */
368
    if (virThreadInitialize() < 0 ||
369
        virErrorInitialize() < 0)
370
        goto error;
371

372
#ifndef LIBVIRT_SETUID_RPC_CLIENT
373 374 375 376 377 378 379
    if (virIsSUID()) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("libvirt.so is not safe to use from setuid programs"));
        goto error;
    }
#endif

380
#ifdef WITH_GNUTLS_GCRYPT
381 382 383 384 385 386 387 388 389 390 391 392 393
    /*
     * 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);
    }
394
#endif
D
Daniel P. Berrange 已提交
395

396
    virLogSetFromEnv();
397

398
#ifdef WITH_GNUTLS
399
    virNetTLSInit();
400
#endif
401

402
#if WITH_CURL
403 404 405
    curl_global_init(CURL_GLOBAL_DEFAULT);
#endif

406
    VIR_DEBUG("register drivers");
407

408
#if HAVE_WINSOCK2_H
409
    if (winsock_init() == -1)
410
        goto error;
411 412
#endif

413
    if (!bindtextdomain(PACKAGE, LOCALEDIR))
414
        goto error;
415

416 417 418 419 420
    /*
     * Note we must avoid everything except 'remote' driver
     * for virt-login-shell usage
     */
#ifndef LIBVIRT_SETUID_RPC_CLIENT
421
    /*
422 423
     * Note that the order is important: the first ones have a higher
     * priority when calling virConnectOpen.
424
     */
425
# ifdef WITH_TEST
426 427
    if (testRegister() == -1)
        goto error;
428 429
# endif
# ifdef WITH_OPENVZ
430 431
    if (openvzRegister() == -1)
        goto error;
432 433
# endif
# ifdef WITH_VMWARE
434 435
    if (vmwareRegister() == -1)
        goto error;
436 437
# endif
# ifdef WITH_PHYP
438 439
    if (phypRegister() == -1)
        goto error;
440 441
# endif
# ifdef WITH_ESX
442 443
    if (esxRegister() == -1)
        goto error;
444 445
# endif
# ifdef WITH_HYPERV
446 447
    if (hypervRegister() == -1)
        goto error;
448 449
# endif
# ifdef WITH_XENAPI
450 451
    if (xenapiRegister() == -1)
        goto error;
452 453
# endif
# ifdef WITH_PARALLELS
454 455
    if (parallelsRegister() == -1)
        goto error;
456
# endif
D
Dmitry Guryanov 已提交
457
#endif
458
#ifdef WITH_REMOTE
459
    if (remoteRegister() == -1)
460
        goto error;
461
#endif
D
Daniel P. Berrange 已提交
462

463 464
    return;

465
 error:
466 467 468
    virGlobalError = true;
}

469

470 471 472 473 474
/**
 * virInitialize:
 *
 * Initialize the library.
 *
475 476 477 478 479 480
 * This method is invoked automatically by any of the virConnectOpen() API
 * calls, and by virGetVersion(). 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; but applications
 * using an older version of the library should manually call this before
 * setting up competing threads that attempt virConnectOpen in parallel.
481
 *
482 483 484 485 486
 * The only other time it would be necessary to call virInitialize is if the
 * application did not invoke virConnectOpen as its first API call, such
 * as when calling virEventRegisterImpl() before setting up connections,
 * or when using virSetErrorFunc() to alter error reporting of the first
 * connection attempt.
487 488 489 490 491 492 493 494 495 496 497
 *
 * 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;
498
    return 0;
499 500
}

501

502 503
#ifdef WIN32
BOOL WINAPI
504
DllMain(HINSTANCE instance, DWORD reason, LPVOID ignore);
505 506

BOOL WINAPI
507 508 509
DllMain(HINSTANCE instance ATTRIBUTE_UNUSED,
        DWORD reason,
        LPVOID ignore ATTRIBUTE_UNUSED)
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
{
    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
535

536

537 538 539 540 541 542 543 544 545 546 547
/**
 * 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)
{
548
    virCheckNonNullArgReturn(driver, -1);
549
    virDriverCheckTabMaxReturn(virNetworkDriverTabCount, -1);
550

551
    VIR_DEBUG("registering %s as network driver %d",
552 553
           driver->name, virNetworkDriverTabCount);

554 555
    virNetworkDriverTab[virNetworkDriverTabCount] = driver;
    return virNetworkDriverTabCount++;
556 557
}

558

D
Daniel Veillard 已提交
559 560
/**
 * virRegisterInterfaceDriver:
L
Laine Stump 已提交
561
 * @driver: pointer to an interface driver block
D
Daniel Veillard 已提交
562
 *
L
Laine Stump 已提交
563
 * Register an interface virtualization driver
D
Daniel Veillard 已提交
564 565 566 567 568 569
 *
 * Returns the driver priority or -1 in case of error.
 */
int
virRegisterInterfaceDriver(virInterfaceDriverPtr driver)
{
570
    virCheckNonNullArgReturn(driver, -1);
571
    virDriverCheckTabMaxReturn(virInterfaceDriverTabCount, -1);
D
Daniel Veillard 已提交
572

573
    VIR_DEBUG("registering %s as interface driver %d",
D
Daniel Veillard 已提交
574 575 576 577 578 579
           driver->name, virInterfaceDriverTabCount);

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

580

581 582 583 584 585 586 587 588 589 590 591
/**
 * 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)
{
592
    virCheckNonNullArgReturn(driver, -1);
593
    virDriverCheckTabMaxReturn(virStorageDriverTabCount, -1);
594

595
    VIR_DEBUG("registering %s as storage driver %d",
596 597
           driver->name, virStorageDriverTabCount);

598 599 600 601
    virStorageDriverTab[virStorageDriverTabCount] = driver;
    return virStorageDriverTabCount++;
}

602

603
/**
604
 * virRegisterNodeDeviceDriver:
605 606 607 608 609 610 611
 * @driver: pointer to a device monitor block
 *
 * Register a device monitor
 *
 * Returns the driver priority or -1 in case of error.
 */
int
612
virRegisterNodeDeviceDriver(virNodeDeviceDriverPtr driver)
613
{
614
    virCheckNonNullArgReturn(driver, -1);
615
    virDriverCheckTabMaxReturn(virNodeDeviceDriverTabCount, -1);
616

617
    VIR_DEBUG("registering %s as device driver %d",
618
           driver->name, virNodeDeviceDriverTabCount);
619

620 621
    virNodeDeviceDriverTab[virNodeDeviceDriverTabCount] = driver;
    return virNodeDeviceDriverTabCount++;
622 623
}

624

625 626 627 628 629 630 631 632 633 634 635
/**
 * 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)
{
636
    virCheckNonNullArgReturn(driver, -1);
637
    virDriverCheckTabMaxReturn(virSecretDriverTabCount, -1);
638

639
    VIR_DEBUG("registering %s as secret driver %d",
640 641 642 643 644 645
           driver->name, virSecretDriverTabCount);

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

646

S
Stefan Berger 已提交
647 648 649 650 651 652 653 654 655 656 657
/**
 * 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)
{
658
    virCheckNonNullArgReturn(driver, -1);
659
    virDriverCheckTabMaxReturn(virNWFilterDriverTabCount, -1);
S
Stefan Berger 已提交
660

661
    VIR_DEBUG("registering %s as network filter driver %d",
S
Stefan Berger 已提交
662 663 664 665 666 667 668
           driver->name, virNWFilterDriverTabCount);

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


669
/**
670
 * virRegisterHypervisorDriver:
671 672 673 674 675 676 677
 * @driver: pointer to a driver block
 *
 * Register a virtualization driver
 *
 * Returns the driver priority or -1 in case of error.
 */
int
678
virRegisterHypervisorDriver(virHypervisorDriverPtr driver)
679
{
680 681
    VIR_DEBUG("driver=%p name=%s", driver,
              driver ? NULLSTR(driver->name) : "(null)");
682

683
    virCheckNonNullArgReturn(driver, -1);
684
    virDriverCheckTabMaxReturn(virHypervisorDriverTabCount, -1);
685

686
    VIR_DEBUG("registering %s as driver %d",
687
           driver->name, virHypervisorDriverTabCount);
688

689 690
    virHypervisorDriverTab[virHypervisorDriverTabCount] = driver;
    return virHypervisorDriverTabCount++;
691 692
}

693

A
Atsushi SAKAI 已提交
694
#ifdef WITH_LIBVIRTD
695 696 697 698 699 700 701 702 703 704 705
/**
 * 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)
{
706
    virCheckNonNullArgReturn(driver, -1);
707
    virDriverCheckTabMaxReturn(virStateDriverTabCount, -1);
708 709 710 711 712

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

713

714 715
/**
 * virStateInitialize:
716
 * @privileged: set to true if running with root privilege, false otherwise
717 718
 * @callback: callback to invoke to inhibit shutdown of the daemon
 * @opaque: data to pass to @callback
719
 *
720 721 722 723 724
 * Initialize all virtualization drivers. Accomplished in two phases,
 * the first being state and structure initialization followed by any
 * auto start supported by the driver.  This is done to ensure dependencies
 * that some drivers may have on another driver having been initialized
 * will exist, such as the storage driver's need to use the secret driver.
725
 *
726
 * Returns 0 if all succeed, -1 upon any failure.
727
 */
728 729 730 731
int
virStateInitialize(bool privileged,
                   virStateInhibitCallback callback,
                   void *opaque)
732
{
733
    size_t i;
734 735 736 737

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

738
    for (i = 0; i < virStateDriverTabCount; i++) {
739
        if (virStateDriverTab[i]->stateInitialize) {
740
            VIR_DEBUG("Running global init for %s state driver",
741
                      virStateDriverTab[i]->name);
742 743 744
            if (virStateDriverTab[i]->stateInitialize(privileged,
                                                      callback,
                                                      opaque) < 0) {
745 746 747 748
                virErrorPtr err = virGetLastError();
                VIR_ERROR(_("Initialization of %s state driver failed: %s"),
                          virStateDriverTab[i]->name,
                          err && err->message ? err->message : _("Unknown problem"));
749 750
                return -1;
            }
751
        }
752
    }
753 754 755 756 757 758 759 760

    for (i = 0; i < virStateDriverTabCount; i++) {
        if (virStateDriverTab[i]->stateAutoStart) {
            VIR_DEBUG("Running global auto start for %s state driver",
                      virStateDriverTab[i]->name);
            virStateDriverTab[i]->stateAutoStart();
        }
    }
761
    return 0;
762 763
}

764

765 766 767 768 769
/**
 * virStateCleanup:
 *
 * Run each virtualization driver's cleanup method.
 *
770
 * Returns 0 if all succeed, -1 upon any failure.
771
 */
772 773 774
int
virStateCleanup(void)
{
775 776
    size_t i;
    int ret = 0;
777

778
    for (i = 0; i < virStateDriverTabCount; i++) {
779 780
        if (virStateDriverTab[i]->stateCleanup &&
            virStateDriverTab[i]->stateCleanup() < 0)
781 782 783 784 785
            ret = -1;
    }
    return ret;
}

786

787 788 789 790 791
/**
 * virStateReload:
 *
 * Run each virtualization driver's reload method.
 *
792
 * Returns 0 if all succeed, -1 upon any failure.
793
 */
794 795 796
int
virStateReload(void)
{
797 798
    size_t i;
    int ret = 0;
799

800
    for (i = 0; i < virStateDriverTabCount; i++) {
801 802
        if (virStateDriverTab[i]->stateReload &&
            virStateDriverTab[i]->stateReload() < 0)
803 804 805 806 807
            ret = -1;
    }
    return ret;
}

808

809 810 811 812 813 814 815
/**
 * virStateStop:
 *
 * Run each virtualization driver's "stop" method.
 *
 * Returns 0 if successful, -1 on failure
 */
816 817 818
int
virStateStop(void)
{
819 820
    size_t i;
    int ret = 0;
821

822
    for (i = 0; i < virStateDriverTabCount; i++) {
823 824
        if (virStateDriverTab[i]->stateStop &&
            virStateDriverTab[i]->stateStop())
825 826 827 828
            ret = 1;
    }
    return ret;
}
829
#endif /* WITH_LIBVIRTD */
830 831


832 833 834
/**
 * virGetVersion:
 * @libVer: return value for the library version (OUT)
835 836 837 838 839 840 841 842 843 844
 * @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
845
 * get the version of the running hypervisor use the virConnectGetVersion()
846
 * function instead. To get the libvirt library version used by a
847 848 849
 * connection use the virConnectGetLibVersion() instead.
 *
 * This function includes a call to virInitialize() when necessary.
850 851 852 853 854
 *
 * 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
855
virGetVersion(unsigned long *libVer, const char *type ATTRIBUTE_UNUSED,
856 857
              unsigned long *typeVer)
{
858 859
    if (virInitialize() < 0)
        goto error;
860
    VIR_DEBUG("libVir=%p, type=%s, typeVer=%p", libVer, type, typeVer);
861

862
    virResetLastError();
863
    if (libVer == NULL)
864
        goto error;
865 866
    *libVer = LIBVIR_VERSION_NUMBER;

867
    if (typeVer != NULL)
868 869
        *typeVer = LIBVIR_VERSION_NUMBER;

870
    return 0;
871

872
 error:
873 874
    virDispatchError(NULL);
    return -1;
875 876
}

877

878
static char *
879
virConnectGetConfigFilePath(void)
880 881 882 883 884
{
    char *path;
    if (geteuid() == 0) {
        if (virAsprintf(&path, "%s/libvirt/libvirt.conf",
                        SYSCONFDIR) < 0)
885
            return NULL;
886
    } else {
887
        char *userdir = virGetUserConfigDirectory();
888
        if (!userdir)
889
            return NULL;
890

891
        if (virAsprintf(&path, "%s/libvirt.conf",
892 893
                        userdir) < 0) {
            VIR_FREE(userdir);
894
            return NULL;
895 896
        }
        VIR_FREE(userdir);
897 898 899 900 901
    }

    return path;
}

902

903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
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;

925
 cleanup:
926 927 928 929
    VIR_FREE(filename);
    return ret;
}

930 931
#define URI_ALIAS_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"

932

933
static int
934 935
virConnectOpenFindURIAliasMatch(virConfValuePtr value, const char *alias,
                                char **uri)
936 937
{
    virConfValuePtr entry;
W
Wen Ruo Lv 已提交
938 939
    size_t alias_len;

940
    if (value->type != VIR_CONF_LIST) {
941 942
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Expected a list for 'uri_aliases' config parameter"));
943 944 945 946
        return -1;
    }

    entry = value->list;
W
Wen Ruo Lv 已提交
947
    alias_len = strlen(alias);
948 949 950 951 952
    while (entry) {
        char *offset;
        size_t safe;

        if (entry->type != VIR_CONF_STRING) {
953 954
            virReportError(VIR_ERR_CONF_SYNTAX, "%s",
                           _("Expected a string for 'uri_aliases' config parameter list entry"));
955 956 957 958
            return -1;
        }

        if (!(offset = strchr(entry->str, '='))) {
959 960
            virReportError(VIR_ERR_CONF_SYNTAX,
                           _("Malformed 'uri_aliases' config entry '%s', expected 'alias=uri://host/path'"),
961 962 963 964 965 966
                            entry->str);
            return -1;
        }

        safe  = strspn(entry->str, URI_ALIAS_CHARS);
        if (safe < (offset - entry->str)) {
967 968
            virReportError(VIR_ERR_CONF_SYNTAX,
                           _("Malformed 'uri_aliases' config entry '%s', aliases may only contain 'a-Z, 0-9, _, -'"),
969 970 971 972
                            entry->str);
            return -1;
        }

W
Wen Ruo Lv 已提交
973 974
        if (alias_len == (offset - entry->str) &&
            STREQLEN(entry->str, alias, alias_len)) {
975 976
            VIR_DEBUG("Resolved alias '%s' to '%s'",
                      alias, offset+1);
977
            return VIR_STRDUP(*uri, offset+1);
978 979 980 981 982 983 984 985 986 987
        }

        entry = entry->next;
    }

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

988

989
static int
990 991
virConnectOpenResolveURIAlias(virConfPtr conf,
                              const char *alias, char **uri)
992 993 994 995 996 997
{
    int ret = -1;
    virConfValuePtr value = NULL;

    *uri = NULL;

998
    if ((value = virConfGetValue(conf, "uri_aliases")))
999 1000 1001 1002
        ret = virConnectOpenFindURIAliasMatch(value, alias, uri);
    else
        ret = 0;

1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
    return ret;
}


static int
virConnectGetDefaultURI(virConfPtr conf,
                        const char **name)
{
    int ret = -1;
    virConfValuePtr value = NULL;
1013
    const char *defname = virGetEnvBlockSUID("LIBVIRT_DEFAULT_URI");
1014 1015 1016 1017 1018
    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) {
1019 1020
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Expected a string for 'uri_default' config parameter"));
1021 1022 1023 1024 1025 1026 1027
            goto cleanup;
        }
        VIR_DEBUG("Using config file uri '%s'", value->str);
        *name = value->str;
    }

    ret = 0;
1028
 cleanup:
1029 1030 1031
    return ret;
}

1032

1033
static virConnectPtr
1034 1035 1036
do_open(const char *name,
        virConnectAuthPtr auth,
        unsigned int flags)
1037
{
1038 1039
    size_t i;
    int res;
1040
    virConnectPtr ret;
1041
    virConfPtr conf = NULL;
1042 1043 1044 1045

    ret = virGetConnect();
    if (ret == NULL)
        return NULL;
1046

1047 1048 1049 1050 1051 1052
    if (virConnectGetConfigFile(&conf) < 0)
        goto failed;

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

1053 1054 1055 1056 1057 1058
    if (!name && virIsSUID()) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("An explicit URI must be provided when setuid"));
        goto failed;
    }

1059
    /*
E
Eric Blake 已提交
1060 1061 1062
     * 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.
1063
     */
1064 1065 1066
    if (!name &&
        virConnectGetDefaultURI(conf, &name) < 0)
        goto failed;
1067

1068
    if (name) {
1069
        char *alias = NULL;
1070 1071 1072 1073 1074 1075 1076
        /* 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.
         */
1077
        if (STREQ(name, "xen://"))
1078 1079
            name = "xen:///";

1080
        if (!(flags & VIR_CONNECT_NO_ALIASES) &&
1081
            virConnectOpenResolveURIAlias(conf, name, &alias) < 0)
1082 1083
            goto failed;

1084
        if (!(ret->uri = virURIParse(alias ? alias : name))) {
1085
            VIR_FREE(alias);
1086 1087
            goto failed;
        }
1088

1089
        VIR_DEBUG("name \"%s\" to URI components:\n"
1090 1091 1092 1093 1094 1095
                  "  scheme %s\n"
                  "  server %s\n"
                  "  user %s\n"
                  "  port %d\n"
                  "  path %s\n",
                  alias ? alias : name,
1096
                  NULLSTR(ret->uri->scheme), NULLSTR(ret->uri->server),
1097 1098 1099 1100
                  NULLSTR(ret->uri->user), ret->uri->port,
                  NULLSTR(ret->uri->path));

        VIR_FREE(alias);
1101
    } else {
1102
        VIR_DEBUG("no name, allowing driver auto-select");
1103 1104
    }

1105 1106 1107
    /* Cleansing flags */
    ret->flags = flags & VIR_CONNECT_RO;

1108
    for (i = 0; i < virHypervisorDriverTabCount; i++) {
1109 1110 1111 1112 1113 1114 1115
        /* 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. */
1116
        if (virHypervisorDriverTab[i]->no == VIR_DRV_REMOTE &&
1117 1118 1119 1120 1121 1122
            ret->uri != NULL && ret->uri->scheme != NULL &&
            (
#ifndef WITH_PHYP
             STRCASEEQ(ret->uri->scheme, "phyp") ||
#endif
#ifndef WITH_ESX
1123
             STRCASEEQ(ret->uri->scheme, "vpx") ||
1124 1125
             STRCASEEQ(ret->uri->scheme, "esx") ||
             STRCASEEQ(ret->uri->scheme, "gsx") ||
M
Matthias Bolte 已提交
1126 1127 1128
#endif
#ifndef WITH_HYPERV
             STRCASEEQ(ret->uri->scheme, "hyperv") ||
1129 1130 1131
#endif
#ifndef WITH_XENAPI
             STRCASEEQ(ret->uri->scheme, "xenapi") ||
D
Dmitry Guryanov 已提交
1132 1133 1134
#endif
#ifndef WITH_PARALLELS
             STRCASEEQ(ret->uri->scheme, "parallels") ||
1135 1136
#endif
             false)) {
1137
            virReportErrorHelper(VIR_FROM_NONE, VIR_ERR_CONFIG_UNSUPPORTED,
1138 1139 1140 1141 1142 1143
                                 __FILE__, __FUNCTION__, __LINE__,
                                 _("libvirt was built without the '%s' driver"),
                                 ret->uri->scheme);
            goto failed;
        }

1144 1145 1146
        VIR_DEBUG("trying driver %zu (%s) ...", i, virHypervisorDriverTab[i]->name);
        ret->driver = virHypervisorDriverTab[i];
        res = virHypervisorDriverTab[i]->connectOpen(ret, auth, flags);
1147
        VIR_DEBUG("driver %zu %s returned %s",
1148
                  i, virHypervisorDriverTab[i]->name,
O
Osier Yang 已提交
1149 1150 1151 1152 1153
                  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) {
1154
            break;
O
Osier Yang 已提交
1155
        } else if (res == VIR_DRV_OPEN_ERROR) {
1156
            ret->driver = NULL;
O
Osier Yang 已提交
1157
            goto failed;
1158 1159
        } else {
            ret->driver = NULL;
1160
        }
1161 1162
    }

1163
    if (!ret->driver) {
1164
        /* If we reach here, then all drivers declined the connection. */
1165
        virReportError(VIR_ERR_NO_CONNECT, "%s", NULLSTR(name));
1166
        goto failed;
1167 1168
    }

1169
    for (i = 0; i < virNetworkDriverTabCount; i++) {
1170
        res = virNetworkDriverTab[i]->networkOpen(ret, auth, flags);
1171
        VIR_DEBUG("network driver %zu %s returned %s",
O
Osier Yang 已提交
1172 1173 1174 1175 1176 1177
                  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) {
1178 1179
            ret->networkDriver = virNetworkDriverTab[i];
            break;
O
Osier Yang 已提交
1180 1181
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
1182
        }
1183
    }
1184

D
Daniel Veillard 已提交
1185
    for (i = 0; i < virInterfaceDriverTabCount; i++) {
1186
        res = virInterfaceDriverTab[i]->interfaceOpen(ret, auth, flags);
1187
        VIR_DEBUG("interface driver %zu %s returned %s",
O
Osier Yang 已提交
1188 1189 1190 1191 1192 1193
                  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 已提交
1194 1195
            ret->interfaceDriver = virInterfaceDriverTab[i];
            break;
O
Osier Yang 已提交
1196 1197
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
D
Daniel Veillard 已提交
1198 1199
        }
    }
1200 1201 1202

    /* Secondary driver for storage. Optional */
    for (i = 0; i < virStorageDriverTabCount; i++) {
1203
        res = virStorageDriverTab[i]->storageOpen(ret, auth, flags);
1204
        VIR_DEBUG("storage driver %zu %s returned %s",
O
Osier Yang 已提交
1205 1206 1207 1208 1209 1210
                  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) {
1211 1212
            ret->storageDriver = virStorageDriverTab[i];
            break;
O
Osier Yang 已提交
1213 1214
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
1215 1216 1217
        }
    }

1218
    /* Node driver (optional) */
1219
    for (i = 0; i < virNodeDeviceDriverTabCount; i++) {
1220
        res = virNodeDeviceDriverTab[i]->nodeDeviceOpen(ret, auth, flags);
1221
        VIR_DEBUG("node driver %zu %s returned %s",
1222
                  i, virNodeDeviceDriverTab[i]->name,
O
Osier Yang 已提交
1223 1224 1225 1226 1227
                  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) {
1228
            ret->nodeDeviceDriver = virNodeDeviceDriverTab[i];
1229
            break;
O
Osier Yang 已提交
1230 1231
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
1232 1233 1234
        }
    }

1235 1236
    /* Secret manipulation driver. Optional */
    for (i = 0; i < virSecretDriverTabCount; i++) {
1237
        res = virSecretDriverTab[i]->secretOpen(ret, auth, flags);
1238
        VIR_DEBUG("secret driver %zu %s returned %s",
O
Osier Yang 已提交
1239 1240 1241 1242 1243 1244
                  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) {
1245 1246
            ret->secretDriver = virSecretDriverTab[i];
            break;
O
Osier Yang 已提交
1247 1248
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
1249 1250 1251
        }
    }

S
Stefan Berger 已提交
1252 1253
    /* Network filter driver. Optional */
    for (i = 0; i < virNWFilterDriverTabCount; i++) {
1254
        res = virNWFilterDriverTab[i]->nwfilterOpen(ret, auth, flags);
1255
        VIR_DEBUG("nwfilter driver %zu %s returned %s",
O
Osier Yang 已提交
1256 1257 1258 1259 1260 1261
                  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 已提交
1262 1263
            ret->nwfilterDriver = virNWFilterDriverTab[i];
            break;
O
Osier Yang 已提交
1264 1265
        } else if (res == VIR_DRV_OPEN_ERROR) {
            break;
S
Stefan Berger 已提交
1266 1267 1268
        }
    }

1269 1270
    virConfFree(conf);

1271
    return ret;
1272

1273
 failed:
1274
    virConfFree(conf);
1275
    virObjectUnref(ret);
1276

1277
    return NULL;
1278 1279
}

1280

1281 1282
/**
 * virConnectOpen:
1283
 * @name: (optional) URI of the hypervisor
1284
 *
1285
 * This function should be called first to get a connection to the
1286 1287
 * Hypervisor and xen store
 *
1288 1289 1290 1291 1292
 * 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.
1293 1294 1295 1296 1297 1298
 *
 * 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
 *
1299
 * URIs are documented at http://libvirt.org/uri.html
E
Eric Blake 已提交
1300
 *
1301 1302 1303
 * virConnectClose should be used to release the resources after the connection
 * is no longer needed.
 *
E
Eric Blake 已提交
1304
 * Returns a pointer to the hypervisor connection or NULL in case of error
1305 1306
 */
virConnectPtr
1307
virConnectOpen(const char *name)
1308
{
1309
    virConnectPtr ret = NULL;
1310 1311 1312

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

1314
    VIR_DEBUG("name=%s", NULLSTR(name));
1315
    virResetLastError();
1316
    ret = do_open(name, NULL, 0);
1317 1318 1319 1320
    if (!ret)
        goto error;
    return ret;

1321
 error:
1322 1323
    virDispatchError(NULL);
    return NULL;
1324 1325
}

1326

1327
/**
1328
 * virConnectOpenReadOnly:
1329
 * @name: (optional) URI of the hypervisor
1330
 *
1331
 * This function should be called first to get a restricted connection to the
D
Daniel Veillard 已提交
1332
 * library functionalities. The set of APIs usable are then restricted
1333
 * on the available methods to control the domains.
1334
 *
1335
 * See virConnectOpen for notes about environment variables which can
1336
 * have an effect on opening drivers and freeing the connection resources
1337
 *
1338
 * URIs are documented at http://libvirt.org/uri.html
E
Eric Blake 已提交
1339 1340
 *
 * Returns a pointer to the hypervisor connection or NULL in case of error
1341
 */
1342
virConnectPtr
1343 1344
virConnectOpenReadOnly(const char *name)
{
1345
    virConnectPtr ret = NULL;
1346 1347 1348

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

1350
    VIR_DEBUG("name=%s", NULLSTR(name));
1351
    virResetLastError();
1352
    ret = do_open(name, NULL, VIR_CONNECT_RO);
1353 1354 1355 1356
    if (!ret)
        goto error;
    return ret;

1357
 error:
1358 1359
    virDispatchError(NULL);
    return NULL;
1360 1361
}

1362

1363 1364
/**
 * virConnectOpenAuth:
1365
 * @name: (optional) URI of the hypervisor
1366
 * @auth: Authenticate callback parameters
1367
 * @flags: bitwise-OR of virConnectFlags
1368
 *
1369
 * This function should be called first to get a connection to the
1370
 * Hypervisor. If necessary, authentication will be performed fetching
1371 1372
 * credentials via the callback
 *
1373
 * See virConnectOpen for notes about environment variables which can
1374
 * have an effect on opening drivers and freeing the connection resources
1375
 *
1376
 * URIs are documented at http://libvirt.org/uri.html
E
Eric Blake 已提交
1377 1378
 *
 * Returns a pointer to the hypervisor connection or NULL in case of error
1379 1380 1381 1382
 */
virConnectPtr
virConnectOpenAuth(const char *name,
                   virConnectAuthPtr auth,
1383
                   unsigned int flags)
1384
{
1385
    virConnectPtr ret = NULL;
1386 1387 1388

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

1390
    VIR_DEBUG("name=%s, auth=%p, flags=%x", NULLSTR(name), auth, flags);
1391
    virResetLastError();
1392
    ret = do_open(name, auth, flags);
1393 1394 1395 1396
    if (!ret)
        goto error;
    return ret;

1397
 error:
1398 1399
    virDispatchError(NULL);
    return NULL;
D
Daniel Veillard 已提交
1400 1401
}

1402

D
Daniel Veillard 已提交
1403
/**
1404
 * virConnectClose:
D
Daniel Veillard 已提交
1405 1406 1407 1408 1409 1410 1411
 * @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.
 *
1412 1413 1414 1415 1416 1417 1418 1419
 * 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.
 *
1420 1421 1422 1423 1424 1425 1426 1427 1428 1429
 * 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 已提交
1430 1431
 */
int
1432 1433
virConnectClose(virConnectPtr conn)
{
1434
    VIR_DEBUG("conn=%p", conn);
1435

1436 1437
    virResetLastError();

1438
    virCheckConnectReturn(conn, -1);
1439

1440 1441 1442
    if (!virObjectUnref(conn))
        return 0;
    return 1;
D
Daniel Veillard 已提交
1443 1444
}

1445

1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459
/**
 * 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 已提交
1460 1461
 *
 * Returns 0 in case of success, -1 in case of failure
1462 1463 1464 1465
 */
int
virConnectRef(virConnectPtr conn)
{
1466 1467
    VIR_DEBUG("conn=%p refs=%d", conn, conn ? conn->object.u.s.refs : 0);

1468 1469
    virResetLastError();

1470
    virCheckConnectReturn(conn, -1);
1471
    virObjectRef(conn);
1472 1473 1474
    return 0;
}

1475

D
Daniel Veillard 已提交
1476 1477
/*
 * Not for public use.  This function is part of the internal
1478 1479 1480
 * implementation of driver features in the remote case.
 */
int
1481
virConnectSupportsFeature(virConnectPtr conn, int feature)
1482
{
1483
    int ret;
1484
    VIR_DEBUG("conn=%p, feature=%d", conn, feature);
1485

1486 1487
    virResetLastError();

1488
    virCheckConnectReturn(conn, -1);
1489

1490
    if (!conn->driver->connectSupportsFeature)
1491 1492
        ret = 0;
    else
1493
        ret = conn->driver->connectSupportsFeature(conn, feature);
1494 1495

    if (ret < 0)
1496
        virDispatchError(conn);
1497

1498
    return ret;
1499 1500
}

1501

1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543
/* Helper function called to validate incoming client array on any
 * interface that sets typed parameters in the hypervisor.  */
int
virTypedParameterValidateSet(virConnectPtr conn,
                             virTypedParameterPtr params,
                             int nparams)
{
    bool string_okay;
    size_t i;

    string_okay = VIR_DRV_SUPPORTS_FEATURE(conn->driver,
                                           conn,
                                           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) {
            virReportInvalidArg(params,
                                _("string parameter name '%.*s' too long"),
                                VIR_TYPED_PARAM_FIELD_LENGTH,
                                params[i].field);
            return -1;
        }
        if (params[i].type == VIR_TYPED_PARAM_STRING) {
            if (string_okay) {
                if (!params[i].value.s) {
                    virReportInvalidArg(params,
                                        _("NULL string parameter '%s'"),
                                        params[i].field);
                    return -1;
                }
            } else {
                virReportInvalidArg(params,
                                    _("string parameter '%s' unsupported"),
                                    params[i].field);
                return -1;
            }
        }
    }
    return 0;
}


1544 1545 1546 1547
/**
 * virConnectGetType:
 * @conn: pointer to the hypervisor connection
 *
1548 1549 1550 1551 1552
 * Get the name of the Hypervisor driver used. This is merely the driver
 * name; for example, both KVM and QEMU guests are serviced by the
 * driver for the qemu:// URI, so a return of "QEMU" does not indicate
 * whether KVM acceleration is present.  For more details about the
 * hypervisor, use virConnectGetCapabilities().
1553 1554
 *
 * Returns NULL in case of error, a static zero terminated string otherwise.
1555 1556 1557
 *
 * See also:
 * http://www.redhat.com/archives/libvir-list/2007-February/msg00096.html
1558 1559
 */
const char *
1560 1561
virConnectGetType(virConnectPtr conn)
{
1562
    const char *ret;
1563
    VIR_DEBUG("conn=%p", conn);
1564

1565 1566
    virResetLastError();

1567
    virCheckConnectReturn(conn, NULL);
1568

1569 1570
    if (conn->driver->connectGetType) {
        ret = conn->driver->connectGetType(conn);
1571
        if (ret) return ret;
1572
    }
1573
    return conn->driver->name;
1574 1575
}

1576

D
Daniel Veillard 已提交
1577
/**
1578
 * virConnectGetVersion:
D
Daniel Veillard 已提交
1579
 * @conn: pointer to the hypervisor connection
1580
 * @hvVer: return value for the version of the running hypervisor (OUT)
D
Daniel Veillard 已提交
1581
 *
1582
 * Get the version level of the Hypervisor running. This may work only with
1583
 * hypervisor call, i.e. with privileged access to the hypervisor, not
1584
 * with a Read-Only connection.
D
Daniel Veillard 已提交
1585
 *
1586 1587 1588
 * 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 已提交
1589
 */
1590
int
1591 1592
virConnectGetVersion(virConnectPtr conn, unsigned long *hvVer)
{
1593
    VIR_DEBUG("conn=%p, hvVer=%p", conn, hvVer);
1594

1595 1596
    virResetLastError();

1597
    virCheckConnectReturn(conn, -1);
1598
    virCheckNonNullArgGoto(hvVer, error);
1599

1600 1601
    if (conn->driver->connectGetVersion) {
        int ret = conn->driver->connectGetVersion(conn, hvVer);
1602 1603 1604 1605
        if (ret < 0)
            goto error;
        return ret;
    }
D
Daniel P. Berrange 已提交
1606

1607
    virReportUnsupportedError();
1608

1609
 error:
1610
    virDispatchError(conn);
1611
    return -1;
1612 1613
}

1614

1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629
/**
 * 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;
1630
    VIR_DEBUG("conn=%p, libVir=%p", conn, libVer);
1631 1632 1633

    virResetLastError();

1634
    virCheckConnectReturn(conn, -1);
1635
    virCheckNonNullArgGoto(libVer, error);
1636

1637 1638
    if (conn->driver->connectGetLibVersion) {
        ret = conn->driver->connectGetLibVersion(conn, libVer);
1639 1640 1641 1642 1643
        if (ret < 0)
            goto error;
        return ret;
    }

1644 1645 1646
    *libVer = LIBVIR_VERSION_NUMBER;
    return 0;

1647
 error:
1648
    virDispatchError(conn);
1649 1650 1651
    return ret;
}

1652

1653 1654 1655 1656
/**
 * virConnectGetHostname:
 * @conn: pointer to a hypervisor connection
 *
E
Eric Blake 已提交
1657 1658 1659 1660
 * This returns a system hostname on which the hypervisor is
 * running (based on the result of the gethostname system call, but
 * possibly expanded to a fully-qualified domain name via getaddrinfo).
 * If we are connected to a remote system, then this returns the
1661 1662 1663 1664 1665 1666
 * hostname of the remote system.
 *
 * Returns the hostname which must be freed by the caller, or
 * NULL if there was an error.
 */
char *
1667
virConnectGetHostname(virConnectPtr conn)
1668
{
1669
    VIR_DEBUG("conn=%p", conn);
1670

1671 1672
    virResetLastError();

1673
    virCheckConnectReturn(conn, NULL);
1674

1675 1676
    if (conn->driver->connectGetHostname) {
        char *ret = conn->driver->connectGetHostname(conn);
1677 1678 1679 1680
        if (!ret)
            goto error;
        return ret;
    }
1681

1682
    virReportUnsupportedError();
1683

1684
 error:
1685
    virDispatchError(conn);
1686 1687 1688
    return NULL;
}

1689

1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705
/**
 * 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 *
1706
virConnectGetURI(virConnectPtr conn)
1707
{
1708
    char *name;
1709
    VIR_DEBUG("conn=%p", conn);
1710

1711 1712
    virResetLastError();

1713
    virCheckConnectReturn(conn, NULL);
1714

1715
    if (!(name = virURIFormat(conn->uri)))
1716
        goto error;
1717

1718
    return name;
1719

1720
 error:
1721
    virDispatchError(conn);
1722
    return NULL;
1723 1724
}

1725

E
Eric Blake 已提交
1726 1727 1728
/**
 * virConnectGetSysinfo:
 * @conn: pointer to a hypervisor connection
1729
 * @flags: extra flags; not used yet, so callers should always pass 0
E
Eric Blake 已提交
1730 1731 1732 1733 1734 1735 1736 1737 1738 1739
 *
 * 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 *
1740
virConnectGetSysinfo(virConnectPtr conn, unsigned int flags)
E
Eric Blake 已提交
1741
{
E
Eric Blake 已提交
1742
    VIR_DEBUG("conn=%p, flags=%x", conn, flags);
E
Eric Blake 已提交
1743 1744 1745

    virResetLastError();

1746
    virCheckConnectReturn(conn, NULL);
E
Eric Blake 已提交
1747

1748 1749
    if (conn->driver->connectGetSysinfo) {
        char *ret = conn->driver->connectGetSysinfo(conn, flags);
E
Eric Blake 已提交
1750 1751 1752 1753 1754
        if (!ret)
            goto error;
        return ret;
    }

1755
    virReportUnsupportedError();
E
Eric Blake 已提交
1756

1757
 error:
E
Eric Blake 已提交
1758 1759 1760 1761
    virDispatchError(conn);
    return NULL;
}

1762

1763 1764 1765 1766 1767
/**
 * virConnectGetMaxVcpus:
 * @conn: pointer to the hypervisor connection
 * @type: value of the 'type' attribute in the <domain> element
 *
1768
 * Provides the maximum number of virtual CPUs supported for a guest VM of a
1769 1770 1771 1772 1773 1774 1775 1776 1777
 * 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)
{
1778
    VIR_DEBUG("conn=%p, type=%s", conn, type);
1779

1780 1781
    virResetLastError();

1782
    virCheckConnectReturn(conn, -1);
1783

1784 1785
    if (conn->driver->connectGetMaxVcpus) {
        int ret = conn->driver->connectGetMaxVcpus(conn, type);
1786 1787 1788 1789
        if (ret < 0)
            goto error;
        return ret;
    }
1790

1791
    virReportUnsupportedError();
1792
 error:
1793
    virDispatchError(conn);
1794
    return -1;
1795 1796
}

1797

1798
/**
1799
 * virNodeGetInfo:
1800
 * @conn: pointer to the hypervisor connection
1801
 * @info: pointer to a virNodeInfo structure allocated by the user
1802
 *
1803
 * Extract hardware information about the node.
1804
 *
1805
 * Returns 0 in case of success and -1 in case of failure.
1806 1807
 */
int
1808
virNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
1809
{
1810
    VIR_DEBUG("conn=%p, info=%p", conn, info);
1811

1812 1813
    virResetLastError();

1814
    virCheckConnectReturn(conn, -1);
1815
    virCheckNonNullArgGoto(info, error);
1816

1817 1818 1819
    if (conn->driver->nodeGetInfo) {
        int ret;
        ret = conn->driver->nodeGetInfo(conn, info);
1820 1821 1822 1823
        if (ret < 0)
            goto error;
        return ret;
    }
1824

1825
    virReportUnsupportedError();
1826

1827
 error:
1828
    virDispatchError(conn);
1829
    return -1;
D
Daniel Veillard 已提交
1830 1831
}

1832

K
 
Karel Zak 已提交
1833
/**
1834
 * virConnectGetCapabilities:
K
 
Karel Zak 已提交
1835 1836
 * @conn: pointer to the hypervisor connection
 *
1837
 * Provides capabilities of the hypervisor / driver.
1838
 *
1839 1840 1841
 * Returns NULL in case of error, or an XML string
 * defining the capabilities.
 * The client must free the returned string after use.
K
 
Karel Zak 已提交
1842
 */
1843 1844
char *
virConnectGetCapabilities(virConnectPtr conn)
1845
{
1846
    VIR_DEBUG("conn=%p", conn);
1847

1848 1849
    virResetLastError();

1850
    virCheckConnectReturn(conn, NULL);
K
Karel Zak 已提交
1851

1852 1853 1854 1855
    if (conn->driver->connectGetCapabilities) {
        char *ret;
        ret = conn->driver->connectGetCapabilities(conn);
        if (!ret)
1856
            goto error;
1857
        VIR_DEBUG("conn=%p ret=%s", conn, ret);
1858 1859
        return ret;
    }
1860

1861
    virReportUnsupportedError();
1862

1863
 error:
1864
    virDispatchError(conn);
1865
    return NULL;
K
 
Karel Zak 已提交
1866 1867
}

1868

1869
/**
1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900
 * virNodeGetCPUStats:
 * @conn: pointer to the hypervisor connection.
 * @cpuNum: number of node cpu. (VIR_NODE_CPU_STATS_ALL_CPUS means total cpu
 *          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)
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * This function provides individual cpu statistics of the node.
 * If you want to get total cpu statistics of the node, you must specify
 * VIR_NODE_CPU_STATS_ALL_CPUS to @cpuNum.
 * 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
 * array, i.e. (sizeof(@virNodeCPUStats) * @nparams) bytes and call
 * the API again.
 *
 * Here is a sample code snippet:
 *
 *   if (virNodeGetCPUStats(conn, cpuNum, NULL, &nparams, 0) == 0 &&
 *       nparams != 0) {
 *       if ((params = malloc(sizeof(virNodeCPUStats) * nparams)) == NULL)
 *           goto error;
 *       memset(params, 0, sizeof(virNodeCPUStats) * nparams);
 *       if (virNodeGetCPUStats(conn, cpuNum, params, &nparams, 0))
 *           goto error;
 *   }
1901
 *
1902 1903 1904 1905
 * This function doesn't require privileged access to the hypervisor.
 * This function expects the caller to allocate the @params.
 *
 * CPU time Statistics:
1906
 *
1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919
 * 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.
1920
 *
1921
 * Returns -1 in case of error, 0 in case of success.
1922
 */
1923 1924 1925 1926 1927
int
virNodeGetCPUStats(virConnectPtr conn,
                   int cpuNum,
                   virNodeCPUStatsPtr params,
                   int *nparams, unsigned int flags)
1928
{
1929 1930
    VIR_DEBUG("conn=%p, cpuNum=%d, params=%p, nparams=%d, flags=%x",
              conn, cpuNum, params, nparams ? *nparams : -1, flags);
1931

1932 1933
    virResetLastError();

1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952
    virCheckConnectReturn(conn, -1);
    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);
        goto error;
    }

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

1954 1955 1956
 error:
    virDispatchError(conn);
    return -1;
1957 1958
}

1959

D
Daniel Veillard 已提交
1960
/**
1961 1962 1963 1964 1965 1966 1967 1968
 * virNodeGetMemoryStats:
 * @conn: pointer to the hypervisor connection.
 * @cellNum: number of node cell. (VIR_NODE_MEMORY_STATS_ALL_CELLS means total
 *           cell statistics)
 * @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)
 * @flags: extra flags; not used yet, so callers should always pass 0
D
Daniel Veillard 已提交
1969
 *
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991
 * This function provides memory stats of the node.
 * If you want to get total memory statistics of the node, you must specify
 * VIR_NODE_MEMORY_STATS_ALL_CELLS to @cellNum.
 * 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
 * array, i.e. (sizeof(@virNodeMemoryStats) * @nparams) bytes and call
 * the API again.
 *
 * Here is the sample code snippet:
 *
 *   if (virNodeGetMemoryStats(conn, cellNum, NULL, &nparams, 0) == 0 &&
 *       nparams != 0) {
 *       if ((params = malloc(sizeof(virNodeMemoryStats) * nparams)) == NULL)
 *           goto error;
 *       memset(params, cellNum, 0, sizeof(virNodeMemoryStats) * nparams);
 *       if (virNodeGetMemoryStats(conn, params, &nparams, 0))
 *           goto error;
 *   }
1992
 *
1993 1994
 * This function doesn't require privileged access to the hypervisor.
 * This function expects the caller to allocate the @params.
1995
 *
1996
 * Memory Stats:
1997
 *
1998 1999 2000 2001 2002 2003 2004 2005 2006
 * VIR_NODE_MEMORY_STATS_TOTAL:
 *     The total memory usage.(KB)
 * VIR_NODE_MEMORY_STATS_FREE:
 *     The free memory usage.(KB)
 *     On linux, this usage includes buffers and cached.
 * VIR_NODE_MEMORY_STATS_BUFFERS:
 *     The buffers memory usage.(KB)
 * VIR_NODE_MEMORY_STATS_CACHED:
 *     The cached memory usage.(KB)
2007
 *
2008
 * Returns -1 in case of error, 0 in case of success.
D
Daniel Veillard 已提交
2009
 */
2010 2011 2012 2013 2014
int
virNodeGetMemoryStats(virConnectPtr conn,
                      int cellNum,
                      virNodeMemoryStatsPtr params,
                      int *nparams, unsigned int flags)
2015
{
2016 2017
    VIR_DEBUG("conn=%p, cellNum=%d, params=%p, nparams=%d, flags=%x",
              conn, cellNum, params, nparams ? *nparams : -1, flags);
2018

2019 2020
    virResetLastError();

2021 2022 2023 2024 2025 2026 2027 2028 2029 2030
    virCheckConnectReturn(conn, -1);
    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);
        goto error;
    }
D
Daniel Veillard 已提交
2031

2032 2033 2034 2035
    if (conn->driver->nodeGetMemoryStats) {
        int ret;
        ret = conn->driver->nodeGetMemoryStats(conn, cellNum, params, nparams, flags);
        if (ret < 0)
2036 2037 2038
            goto error;
        return ret;
    }
2039
    virReportUnsupportedError();
2040

2041
 error:
2042
    virDispatchError(conn);
2043
    return -1;
D
Daniel Veillard 已提交
2044 2045
}

2046

2047
/**
2048
 * virNodeGetFreeMemory:
2049 2050
 * @conn: pointer to the hypervisor connection
 *
2051 2052 2053 2054 2055
 * provides the free memory available on the Node
 * Note: most libvirt APIs provide memory sizes in kibibytes, but in this
 * function the returned value is in bytes. Divide by 1024 as necessary.
 *
 * Returns the available free memory in bytes or 0 in case of error
2056
 */
2057 2058
unsigned long long
virNodeGetFreeMemory(virConnectPtr conn)
2059
{
2060
    VIR_DEBUG("conn=%p", conn);
2061 2062 2063

    virResetLastError();

2064
    virCheckConnectReturn(conn, 0);
2065

2066 2067 2068 2069
    if (conn->driver->nodeGetFreeMemory) {
        unsigned long long ret;
        ret = conn->driver->nodeGetFreeMemory(conn);
        if (ret == 0)
2070 2071 2072 2073
            goto error;
        return ret;
    }

2074
    virReportUnsupportedError();
2075

2076
 error:
2077
    virDispatchError(conn);
2078
    return 0;
2079 2080
}

2081

2082
/**
2083
 * virNodeSuspendForDuration:
2084
 * @conn: pointer to the hypervisor connection
2085 2086 2087 2088 2089 2090 2091 2092
 * @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
 * @flags: extra flags; not used yet, so callers should always pass 0
2093
 *
2094 2095 2096 2097
 * 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.
2098
 *
2099 2100 2101
 * 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).
2102
 */
2103 2104 2105 2106 2107
int
virNodeSuspendForDuration(virConnectPtr conn,
                          unsigned int target,
                          unsigned long long duration,
                          unsigned int flags)
2108
{
2109 2110
    VIR_DEBUG("conn=%p, target=%d, duration=%lld, flags=%x",
              conn, target, duration, flags);
2111

2112 2113
    virResetLastError();

2114 2115
    virCheckConnectReturn(conn, -1);
    virCheckReadOnlyGoto(conn->flags, error);
2116

2117 2118 2119 2120 2121
    if (conn->driver->nodeSuspendForDuration) {
        int ret;
        ret = conn->driver->nodeSuspendForDuration(conn, target,
                                                   duration, flags);
        if (ret < 0)
2122 2123 2124
            goto error;
        return ret;
    }
2125

2126
    virReportUnsupportedError();
2127

2128
 error:
2129
    virDispatchError(conn);
2130
    return -1;
2131 2132
}

2133

2134 2135
/*
 * virNodeGetMemoryParameters:
2136
 * @conn: pointer to the hypervisor connection
2137 2138 2139 2140
 * @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
2141
 *
2142 2143 2144 2145
 * 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.
2146
 *
2147 2148 2149 2150 2151 2152
 * 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.
2153
 *
2154
 * Returns 0 in case of success, and -1 in case of failure.
2155
 */
2156 2157 2158 2159 2160
int
virNodeGetMemoryParameters(virConnectPtr conn,
                           virTypedParameterPtr params,
                           int *nparams,
                           unsigned int flags)
2161
{
2162 2163
    VIR_DEBUG("conn=%p, params=%p, nparams=%p, flags=%x",
              conn, params, nparams, flags);
2164

2165 2166
    virResetLastError();

2167 2168 2169 2170 2171
    virCheckConnectReturn(conn, -1);
    virCheckNonNullArgGoto(nparams, error);
    virCheckNonNegativeArgGoto(*nparams, error);
    if (*nparams != 0)
        virCheckNonNullArgGoto(params, error);
2172

2173 2174 2175 2176 2177 2178 2179 2180 2181
    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)
2182 2183 2184
            goto error;
        return ret;
    }
2185

2186
    virReportUnsupportedError();
2187

2188
 error:
2189
    virDispatchError(conn);
2190
    return -1;
2191 2192
}

2193

2194 2195
/*
 * virNodeSetMemoryParameters:
K
Karel Zak 已提交
2196
 * @conn: pointer to the hypervisor connection
2197 2198 2199 2200 2201 2202 2203 2204
 * @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
 *
 * Change all or a subset of the node memory tunables. The function
 * fails if not all of the tunables are supported.
K
Karel Zak 已提交
2205
 *
2206 2207 2208 2209
 * 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.
K
Karel Zak 已提交
2210
 *
2211
 * This function may require privileged access to the hypervisor.
2212
 *
2213
 * Returns 0 in case of success, -1 in case of failure.
K
Karel Zak 已提交
2214
 */
2215 2216 2217 2218 2219
int
virNodeSetMemoryParameters(virConnectPtr conn,
                           virTypedParameterPtr params,
                           int nparams,
                           unsigned int flags)
K
Karel Zak 已提交
2220
{
2221 2222 2223
    VIR_DEBUG("conn=%p, params=%p, nparams=%d, flags=%x",
              conn, params, nparams, flags);
    VIR_TYPED_PARAMS_DEBUG(params, nparams);
2224

2225 2226
    virResetLastError();

2227 2228 2229 2230
    virCheckConnectReturn(conn, -1);
    virCheckReadOnlyGoto(conn->flags, error);
    virCheckNonNullArgGoto(params, error);
    virCheckNonNegativeArgGoto(nparams, error);
2231

2232
    if (virTypedParameterValidateSet(conn, params, nparams) < 0)
2233
        goto error;
2234 2235 2236 2237 2238 2239 2240 2241

    if (conn->driver->nodeSetMemoryParameters) {
        int ret;
        ret = conn->driver->nodeSetMemoryParameters(conn, params,
                                                          nparams, flags);
        if (ret < 0)
            goto error;
        return ret;
K
Karel Zak 已提交
2242
    }
2243

2244
    virReportUnsupportedError();
2245

2246
 error:
2247
    virDispatchError(conn);
2248
    return -1;
K
Karel Zak 已提交
2249 2250
}

2251

2252
/**
2253 2254 2255
 * virNodeGetSecurityModel:
 * @conn: a connection object
 * @secmodel: pointer to a virSecurityModel structure
2256
 *
2257 2258 2259
 * 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.
2260
 *
2261
 * Returns 0 in case of success, -1 in case of failure
2262
 */
2263 2264
int
virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
2265
{
2266
    VIR_DEBUG("conn=%p secmodel=%p", conn, secmodel);
2267

2268 2269
    virResetLastError();

2270 2271
    virCheckConnectReturn(conn, -1);
    virCheckNonNullArgGoto(secmodel, error);
2272

2273 2274 2275 2276
    if (conn->driver->nodeGetSecurityModel) {
        int ret;
        ret = conn->driver->nodeGetSecurityModel(conn, secmodel);
        if (ret < 0)
2277
            goto error;
2278
        return ret;
2279
    }
2280

2281
    virReportUnsupportedError();
2282

2283
 error:
2284
    virDispatchError(conn);
2285
    return -1;
2286 2287
}

2288

D
Daniel Veillard 已提交
2289
/**
2290 2291 2292 2293 2294 2295
 * 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.
2296
 *
2297 2298 2299 2300 2301 2302 2303 2304
 * 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
 * with the amount of free memory in bytes for each cell requested,
 * 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.
2305
 */
D
Daniel Veillard 已提交
2306
int
2307 2308
virNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems,
                          int startCell, int maxCells)
2309
{
2310 2311
    VIR_DEBUG("conn=%p, freeMems=%p, startCell=%d, maxCells=%d",
          conn, freeMems, startCell, maxCells);
2312

2313 2314
    virResetLastError();

2315 2316 2317 2318
    virCheckConnectReturn(conn, -1);
    virCheckNonNullArgGoto(freeMems, error);
    virCheckPositiveArgGoto(maxCells, error);
    virCheckNonNegativeArgGoto(startCell, error);
2319

2320
    if (conn->driver->nodeGetCellsFreeMemory) {
2321
        int ret;
2322
        ret = conn->driver->nodeGetCellsFreeMemory(conn, freeMems, startCell, maxCells);
2323 2324 2325 2326
        if (ret < 0)
            goto error;
        return ret;
    }
2327

2328
    virReportUnsupportedError();
2329

2330
 error:
2331
    virDispatchError(conn);
2332
    return -1;
2333 2334
}

2335

2336
/**
2337 2338
 * virConnectIsEncrypted:
 * @conn: pointer to the connection object
2339
 *
2340
 * Determine if the connection to the hypervisor is encrypted
2341
 *
2342
 * Returns 1 if encrypted, 0 if not encrypted, -1 on error
2343 2344
 */
int
2345
virConnectIsEncrypted(virConnectPtr conn)
2346
{
2347
    VIR_DEBUG("conn=%p", conn);
2348 2349 2350

    virResetLastError();

2351 2352
    virCheckConnectReturn(conn, -1);
    if (conn->driver->connectIsEncrypted) {
2353
        int ret;
2354
        ret = conn->driver->connectIsEncrypted(conn);
2355 2356 2357 2358 2359
        if (ret < 0)
            goto error;
        return ret;
    }

2360
    virReportUnsupportedError();
2361
 error:
2362 2363 2364 2365
    virDispatchError(conn);
    return -1;
}

2366

2367
/**
2368 2369
 * virConnectIsSecure:
 * @conn: pointer to the connection object
2370
 *
2371
 * Determine if the connection to the hypervisor is secure
2372
 *
2373 2374 2375 2376 2377
 * 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)
 *
 * Returns 1 if secure, 0 if not secure, -1 on error
2378 2379
 */
int
2380
virConnectIsSecure(virConnectPtr conn)
2381
{
2382
    VIR_DEBUG("conn=%p", conn);
2383

2384 2385
    virResetLastError();

2386 2387 2388 2389 2390 2391 2392 2393
    virCheckConnectReturn(conn, -1);
    if (conn->driver->connectIsSecure) {
        int ret;
        ret = conn->driver->connectIsSecure(conn);
        if (ret < 0)
            goto error;
        return ret;
    }
2394

2395 2396 2397 2398
    virReportUnsupportedError();
 error:
    virDispatchError(conn);
    return -1;
D
Daniel Veillard 已提交
2399 2400
}

2401

2402
/**
2403 2404 2405 2406
 * virConnectCompareCPU:
 * @conn: virConnect connection
 * @xmlDesc: XML describing the CPU to compare with host CPU
 * @flags: bitwise-OR of virConnectCompareCPUFlags
2407
 *
2408
 * Compares the given CPU description with the host CPU
D
Daniel Veillard 已提交
2409
 *
2410 2411 2412 2413 2414 2415
 * Returns comparison result according to enum virCPUCompareResult. If
 * VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE is used and @xmlDesc CPU is
 * incompatible with host CPU, this function will return VIR_CPU_COMPARE_ERROR
 * (instead of VIR_CPU_COMPARE_INCOMPATIBLE) and the error will use the
 * VIR_ERR_CPU_INCOMPATIBLE code with a message providing more details about
 * the incompatibility.
2416 2417
 */
int
2418 2419 2420
virConnectCompareCPU(virConnectPtr conn,
                     const char *xmlDesc,
                     unsigned int flags)
2421
{
2422
    VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags);
2423

2424 2425
    virResetLastError();

2426 2427 2428 2429 2430
    virCheckConnectReturn(conn, VIR_CPU_COMPARE_ERROR);
    virCheckNonNullArgGoto(xmlDesc, error);

    if (conn->driver->connectCompareCPU) {
        int ret;
2431

2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442
        ret = conn->driver->connectCompareCPU(conn, xmlDesc, flags);
        if (ret == VIR_CPU_COMPARE_ERROR)
            goto error;
        return ret;
    }

    virReportUnsupportedError();

 error:
    virDispatchError(conn);
    return VIR_CPU_COMPARE_ERROR;
2443 2444 2445
}


D
Daniel Veillard 已提交
2446
/**
2447
 * virConnectGetCPUModelNames:
D
Daniel Veillard 已提交
2448
 *
2449 2450 2451 2452 2453 2454 2455
 * @conn: virConnect connection
 * @arch: Architecture
 * @models: Pointer to a variable to store the NULL-terminated array of the
 *          CPU models supported for the specified architecture.  Each element
 *          and the array itself must be freed by the caller with free.  Pass
 *          NULL if only the list length is needed.
 * @flags: extra flags; not used yet, so callers should always pass 0.
D
Daniel Veillard 已提交
2456
 *
2457
 * Get the list of supported CPU models for a specific architecture.
D
Daniel Veillard 已提交
2458
 *
2459
 * Returns -1 on error, number of elements in @models on success.
D
Daniel Veillard 已提交
2460 2461
 */
int
2462 2463
virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models,
                           unsigned int flags)
2464
{
2465 2466
    VIR_DEBUG("conn=%p, arch=%s, models=%p, flags=%x",
              conn, arch, models, flags);
2467 2468
    virResetLastError();

2469 2470
    if (models)
        *models = NULL;
2471

2472 2473
    virCheckConnectReturn(conn, -1);
    virCheckNonNullArgGoto(arch, error);
2474

2475
    if (conn->driver->connectGetCPUModelNames) {
2476
        int ret;
2477

2478
        ret = conn->driver->connectGetCPUModelNames(conn, arch, models, flags);
2479 2480
        if (ret < 0)
            goto error;
2481 2482 2483 2484

        return ret;
    }

2485
    virReportUnsupportedError();
2486

2487
 error:
2488 2489 2490 2491
    virDispatchError(conn);
    return -1;
}

2492

2493
/**
2494
 * virConnectBaselineCPU:
2495
 *
2496 2497 2498 2499
 * @conn: virConnect connection
 * @xmlCPUs: array of XML descriptions of host CPUs
 * @ncpus: number of CPUs in xmlCPUs
 * @flags: bitwise-OR of virConnectBaselineCPUFlags
2500
 *
2501 2502
 * Computes the most feature-rich CPU which is compatible with all given
 * host CPUs.
2503
 *
2504 2505 2506 2507
 * If @flags includes VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES then libvirt
 * will explicitly list all CPU features that are part of the host CPU,
 * without this flag features that are part of the CPU model will not be
 * listed.
E
Eric Blake 已提交
2508
 *
2509
 * Returns XML description of the computed CPU (caller frees) or NULL on error.
2510
 */
2511 2512 2513 2514 2515
char *
virConnectBaselineCPU(virConnectPtr conn,
                      const char **xmlCPUs,
                      unsigned int ncpus,
                      unsigned int flags)
2516
{
2517
    size_t i;
2518

2519 2520 2521 2522 2523
    VIR_DEBUG("conn=%p, xmlCPUs=%p, ncpus=%u, flags=%x",
              conn, xmlCPUs, ncpus, flags);
    if (xmlCPUs) {
        for (i = 0; i < ncpus; i++)
            VIR_DEBUG("xmlCPUs[%zu]=%s", i, NULLSTR(xmlCPUs[i]));
2524 2525
    }

2526 2527
    virResetLastError();

2528 2529
    virCheckConnectReturn(conn, NULL);
    virCheckNonNullArgGoto(xmlCPUs, error);
2530

2531 2532
    if (conn->driver->connectBaselineCPU) {
        char *cpu;
2533

2534 2535
        cpu = conn->driver->connectBaselineCPU(conn, xmlCPUs, ncpus, flags);
        if (!cpu)
2536
            goto error;
2537
        return cpu;
2538
    }
2539

2540
    virReportUnsupportedError();
2541

2542
 error:
2543
    virDispatchError(conn);
2544
    return NULL;
D
Daniel Veillard 已提交
2545 2546
}

2547

2548
/**
2549 2550 2551 2552
 * 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
2553
 *
2554 2555 2556 2557 2558 2559 2560
 * Start sending keepalive messages after @interval seconds 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.
2561
 *
2562 2563 2564 2565
 * Note: The client has to implement and run an event loop with
 * virEventRegisterImpl() or virEventRegisterDefaultImpl() to be able to
 * use keepalive messages.  Failure to do so may result in connections
 * being closed unexpectedly.
2566
 *
2567 2568 2569 2570 2571 2572
 * 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.
 *
 * Returns -1 on error, 0 on success, 1 when remote party doesn't support
 * keepalive messages.
2573 2574
 */
int
2575 2576 2577
virConnectSetKeepAlive(virConnectPtr conn,
                       int interval,
                       unsigned int count)
2578
{
2579 2580 2581
    int ret = -1;

    VIR_DEBUG("conn=%p, interval=%d, count=%u", conn, interval, count);
2582 2583 2584

    virResetLastError();

2585
    virCheckConnectReturn(conn, -1);
2586

2587 2588
    if (conn->driver->connectSetKeepAlive) {
        ret = conn->driver->connectSetKeepAlive(conn, interval, count);
2589 2590 2591 2592 2593
        if (ret < 0)
            goto error;
        return ret;
    }

2594
    virReportUnsupportedError();
2595

2596
 error:
2597
    virDispatchError(conn);
2598 2599
    return -1;
}
2600

2601

2602
/**
2603 2604 2605 2606
 * virConnectIsAlive:
 * @conn: pointer to the connection object
 *
 * Determine if the connection to the hypervisor is still alive
2607
 *
2608 2609
 * 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.
2610
 *
2611
 * Returns 1 if alive, 0 if dead, -1 on error
2612 2613
 */
int
2614
virConnectIsAlive(virConnectPtr conn)
2615
{
2616
    VIR_DEBUG("conn=%p", conn);
2617 2618 2619

    virResetLastError();

2620 2621 2622 2623
    virCheckConnectReturn(conn, -1);
    if (conn->driver->connectIsAlive) {
        int ret;
        ret = conn->driver->connectIsAlive(conn);
2624 2625 2626 2627 2628 2629 2630
        if (ret < 0)
            goto error;
        return ret;
    }

    virReportUnsupportedError();
 error:
2631
    virDispatchError(conn);
2632 2633 2634
    return -1;
}

2635

2636
/**
2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651
 * 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.
2652
 *
2653 2654 2655
 * The @freecb must not invoke any other libvirt public
 * APIs, since it is not called from a re-entrant safe
 * context.
2656
 *
2657
 * Returns 0 on success, -1 on error
2658 2659
 */
int
2660 2661 2662 2663
virConnectRegisterCloseCallback(virConnectPtr conn,
                                virConnectCloseFunc cb,
                                void *opaque,
                                virFreeCallback freecb)
2664
{
2665
    VIR_DEBUG("conn=%p", conn);
2666 2667 2668

    virResetLastError();

2669
    virCheckConnectReturn(conn, -1);
2670

2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681
    virObjectRef(conn);

    virMutexLock(&conn->lock);
    virObjectLock(conn->closeCallback);

    virCheckNonNullArgGoto(cb, error);

    if (conn->closeCallback->callback) {
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("A close callback is already registered"));
        goto error;
2682 2683
    }

2684 2685 2686 2687 2688 2689 2690 2691 2692
    conn->closeCallback->conn = conn;
    conn->closeCallback->callback = cb;
    conn->closeCallback->opaque = opaque;
    conn->closeCallback->freeCallback = freecb;

    virObjectUnlock(conn->closeCallback);
    virMutexUnlock(&conn->lock);

    return 0;
2693 2694

 error:
2695 2696 2697 2698
    virObjectUnlock(conn->closeCallback);
    virMutexUnlock(&conn->lock);
    virDispatchError(conn);
    virObjectUnref(conn);
2699 2700
    return -1;
}
2701

2702

2703
/**
2704 2705 2706
 * virConnectUnregisterCloseCallback:
 * @conn: pointer to connection object
 * @cb: pointer to the current registered callback
2707
 *
2708 2709 2710 2711 2712
 * 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
2713
 *
2714
 * Returns 0 on success, -1 on error
2715 2716
 */
int
2717 2718
virConnectUnregisterCloseCallback(virConnectPtr conn,
                                  virConnectCloseFunc cb)
2719
{
2720
    VIR_DEBUG("conn=%p", conn);
2721 2722 2723

    virResetLastError();

2724
    virCheckConnectReturn(conn, -1);
2725

2726 2727 2728 2729 2730 2731 2732 2733 2734
    virMutexLock(&conn->lock);
    virObjectLock(conn->closeCallback);

    virCheckNonNullArgGoto(cb, error);

    if (conn->closeCallback->callback != cb) {
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("A different callback was requested"));
        goto error;
2735 2736
    }

2737 2738 2739 2740 2741 2742 2743 2744 2745 2746
    conn->closeCallback->callback = NULL;
    if (conn->closeCallback->freeCallback)
        conn->closeCallback->freeCallback(conn->closeCallback->opaque);
    conn->closeCallback->freeCallback = NULL;

    virObjectUnref(conn);
    virObjectUnlock(conn->closeCallback);
    virMutexUnlock(&conn->lock);

    return 0;
2747 2748

 error:
2749 2750 2751
    virObjectUnlock(conn->closeCallback);
    virMutexUnlock(&conn->lock);
    virDispatchError(conn);
2752 2753 2754
    return -1;
}

2755

2756
/**
2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769
 * 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
2770
 *
2771
 * Get CPU map of host node CPUs.
2772
 *
2773 2774
 * Returns number of CPUs present on the host node,
 * or -1 if there was an error.
2775 2776
 */
int
2777 2778 2779
virNodeGetCPUMap(virConnectPtr conn,
                 unsigned char **cpumap,
                 unsigned int *online,
2780 2781
                 unsigned int flags)
{
2782 2783
    VIR_DEBUG("conn=%p, cpumap=%p, online=%p, flags=%x",
              conn, cpumap, online, flags);
2784 2785 2786

    virResetLastError();

2787
    virCheckConnectReturn(conn, -1);
2788

2789 2790
    if (conn->driver->nodeGetCPUMap) {
        int ret = conn->driver->nodeGetCPUMap(conn, cpumap, online, flags);
2791 2792 2793 2794 2795 2796 2797 2798
        if (ret < 0)
            goto error;
        return ret;
    }

    virReportUnsupportedError();

 error:
2799
    virDispatchError(conn);
2800 2801
    return -1;
}
M
Michal Privoznik 已提交
2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815


/**
 * virNodeGetFreePages:
 * @conn: pointer to the hypervisor connection
 * @npages: number of items in the @pages array
 * @pages: page sizes to query
 * @startCell: index of first cell to return free pages info on.
 * @cellCount: maximum number of cells for which free pages
 *             information can be returned.
 * @counts: returned counts of free pages
 * @flags: extra flags; not used yet, so callers should always pass 0
 *
 * This calls queries the host system on free pages of
2816
 * specified size. For the input, @pages is expected to be
M
Michal Privoznik 已提交
2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896
 * filled with pages that caller is interested in (the size
 * unit is kibibytes, so e.g. pass 2048 for 2MB), then @startcell
 * refers to the first NUMA node that info should be collected
 * from, and @cellcount tells how many consecutive nodes should
 * be queried. On the function output, @counts is filled with
 * desired information, where items are grouped by NUMA node.
 * So from @counts[0] till @counts[@npages - 1] you'll find count
 * for the first node (@startcell), then from @counts[@npages]
 * till @count[2 * @npages - 1] you'll find info for the
 * (@startcell + 1) node, and so on. It's callers responsibility
 * to allocate the @counts array.
 *
 * Example how to use this API:
 *
 *   unsigned int pages[] = { 4, 2048, 1048576}
 *   unsigned int npages = ARRAY_CARDINALITY(pages);
 *   int startcell = 0;
 *   unsigned int cellcount = 2;
 *
 *   unsigned long long counts = malloc(sizeof(long long) * npages * cellcount);
 *
 *   virNodeGetFreePages(conn, pages, npages,
 *                       startcell, cellcount, counts, 0);
 *
 *   for (i = 0 ; i < cellcount ; i++) {
 *       fprintf(stdout, "Cell %d\n", startcell + i);
 *       for (j = 0 ; j < npages ; j++) {
 *          fprintf(stdout, "  Page size=%d count=%d bytes=%llu\n",
 *                  pages[j], counts[(i * npages) +  j],
 *                  pages[j] * counts[(i * npages) +  j]);
 *       }
 *   }
 *
 *   This little code snippet will produce something like this:
 * Cell 0
 *    Page size=4096 count=300 bytes=1228800
 *    Page size=2097152 count=0 bytes=0
 *    Page size=1073741824 count=1 bytes=1073741824
 * Cell 1
 *    Page size=4096 count=0 bytes=0
 *    Page size=2097152 count=20 bytes=41943040
 *    Page size=1073741824 count=0 bytes=0
 *
 * Returns: the number of entries filled in @counts or -1 in case of error.
 */
int
virNodeGetFreePages(virConnectPtr conn,
                    unsigned int npages,
                    unsigned int *pages,
                    int startCell,
                    unsigned int cellCount,
                    unsigned long long *counts,
                    unsigned int flags)
{
    VIR_DEBUG("conn=%p, npages=%u, pages=%p, startCell=%u, "
              "cellCount=%u, counts=%p, flags=%x",
              conn, npages, pages, startCell, cellCount, counts, flags);

    virResetLastError();

    virCheckConnectReturn(conn, -1);
    virCheckNonZeroArgGoto(npages, error);
    virCheckNonNullArgGoto(pages, error);
    virCheckNonZeroArgGoto(cellCount, error);
    virCheckNonNullArgGoto(counts, error);

    if (conn->driver->nodeGetFreePages) {
        int ret;
        ret = conn->driver->nodeGetFreePages(conn, npages, pages, startCell,
                                             cellCount, counts, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

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

2898

M
Michal Privoznik 已提交
2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 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 2948
/**
 * virNodeAllocPages:
 * @conn: pointer to the hypervisor connection
 * @npages: number of items in the @pageSizes and
 *          @pageCounts arrays
 * @pageSizes: which huge page sizes to allocate
 * @pageCounts: how many pages should be allocated
 * @startCell: index of first cell to allocate pages on
 * @cellCount: number of consecutive cells to allocate pages on
 * @flags: extra flags; binary-OR of virNodeAllocPagesFlags
 *
 * Sometimes, when trying to start a new domain, it may be
 * necessary to reserve some huge pages in the system pool which
 * can be then allocated by the domain. This API serves that
 * purpose. On its input, @pageSizes and @pageCounts are arrays
 * of the same cardinality of @npages. The @pageSizes contains
 * page sizes which are to be allocated in the system (the size
 * unit is kibibytes), and @pageCounts then contains the number
 * of pages to reserve.  If @flags is 0
 * (VIR_NODE_ALLOC_PAGES_ADD), each pool corresponding to
 * @pageSizes grows by the number of pages specified in the
 * corresponding @pageCounts.  If @flags contains
 * VIR_NODE_ALLOC_PAGES_SET, each pool mentioned is resized to
 * the given number of pages.  The pages pool can be allocated
 * over several NUMA nodes at once, just point at @startCell and
 * tell how many subsequent NUMA nodes should be taken in. As a
 * special case, if @startCell is equal to negative one, then
 * kernel is instructed to allocate the pages over all NUMA nodes
 * proportionally.
 *
 * Returns: the number of nodes successfully adjusted or -1 in
 * case of an error.
 */
int
virNodeAllocPages(virConnectPtr conn,
                  unsigned int npages,
                  unsigned int *pageSizes,
                  unsigned long long *pageCounts,
                  int startCell,
                  unsigned int cellCount,
                  unsigned int flags)
{
    VIR_DEBUG("conn=%p npages=%u pageSizes=%p pageCounts=%p "
              "startCell=%d cellCount=%u flagx=%x",
              conn, npages, pageSizes, pageCounts, startCell,
              cellCount, flags);

    virResetLastError();

    virCheckConnectReturn(conn, -1);
2949
    virCheckReadOnlyGoto(conn->flags, error);
M
Michal Privoznik 已提交
2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969
    virCheckNonZeroArgGoto(npages, error);
    virCheckNonNullArgGoto(pageSizes, error);
    virCheckNonNullArgGoto(pageCounts, error);
    virCheckNonZeroArgGoto(cellCount, error);

    if (conn->driver->nodeAllocPages) {
        int ret;
        ret = conn->driver->nodeAllocPages(conn, npages, pageSizes,
                                           pageCounts, startCell,
                                           cellCount, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

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