esx_vi_methods.c 38.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

/*
 * esx_vi_methods.c: client for the VMware VI API 2.5 to manage ESX hosts
 *
 * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
 *
 * 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
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 */

#include <config.h>

#include "buf.h"
#include "memory.h"
#include "logging.h"
#include "uuid.h"
#include "virterror_internal.h"
#include "esx_vi_methods.h"
#include "esx_util.h"

#define VIR_FROM_THIS VIR_FROM_ESX

35 36
#define ESX_VI_ERROR(code, fmt...)                                            \
    virReportErrorHelper(NULL, VIR_FROM_ESX, code, __FILE__,  __FUNCTION__,   \
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
                         __LINE__, fmt)

#define ESX_VI__SOAP__REQUEST_HEADER                                          \
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"                            \
    "<soapenv:Envelope "                                                      \
      "xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "          \
      "xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" "          \
      "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "              \
      "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"                       \
    "<soapenv:Body>"

#define ESX_VI__SOAP__REQUEST_FOOTER                                          \
    "</soapenv:Body>"                                                         \
    "</soapenv:Envelope>"



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * VI Methods
 */

int
59
esxVI_RetrieveServiceContent(esxVI_Context *ctx,
60 61 62
                             esxVI_ServiceContent **serviceContent)
{
    int result = 0;
63 64 65 66 67 68 69 70 71 72
    const char *request = ESX_VI__SOAP__REQUEST_HEADER
                            "<RetrieveServiceContent xmlns=\"urn:vim25\">"
                              "<_this xmlns=\"urn:vim25\" "
                                     "xsi:type=\"ManagedObjectReference\" "
                                     "type=\"ServiceInstance\">"
                                "ServiceInstance"
                              "</_this>"
                            "</RetrieveServiceContent>"
                          ESX_VI__SOAP__REQUEST_FOOTER;
    esxVI_Response *response = NULL;
73 74

    if (serviceContent == NULL || *serviceContent != NULL) {
75
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
76 77 78
        return -1;
    }

79
    if (esxVI_Context_Execute(ctx, "RetrieveServiceContent", request,
80
                              &response, esxVI_Occurrence_RequiredItem) < 0 ||
81
        esxVI_ServiceContent_Deserialize(response->node, serviceContent) < 0) {
82 83 84 85
        goto failure;
    }

  cleanup:
86
    esxVI_Response_Free(&response);
87 88 89 90 91 92 93 94 95 96 97 98

    return result;

  failure:
    result = -1;

    goto cleanup;
}



int
99
esxVI_Login(esxVI_Context *ctx, const char *userName, const char *password,
100 101 102 103
            esxVI_UserSession **userSession)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
104 105
    char *request = NULL;
    esxVI_Response *response = NULL;
106 107

    if (ctx->service == NULL) {
108
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
109 110 111 112
        return -1;
    }

    if (userSession == NULL || *userSession != NULL) {
113
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
114 115 116 117 118 119
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<Login xmlns=\"urn:vim25\">");

120
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->sessionManager,
121 122
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
123
        esxVI_String_SerializeValue(userName, "userName", &buffer,
124
                                    esxVI_Boolean_True) < 0 ||
125
        esxVI_String_SerializeValue(password, "password", &buffer,
126 127 128 129 130 131 132 133
                                    esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</Login>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
134
        virReportOOMError(NULL);
135 136 137
        goto failure;
    }

138
    request = virBufferContentAndReset(&buffer);
139

140
    if (esxVI_Context_Execute(ctx, "Login", request, &response,
141
                              esxVI_Occurrence_RequiredItem) < 0 ||
142
        esxVI_UserSession_Deserialize(response->node, userSession) < 0) {
143 144 145 146
        goto failure;
    }

  cleanup:
147 148
    VIR_FREE(request);
    esxVI_Response_Free(&response);
149 150 151 152

    return result;

  failure:
153
    virBufferFreeAndReset(&buffer);
154 155 156 157 158 159 160 161 162

    result = -1;

    goto cleanup;
}



int
163
esxVI_Logout(esxVI_Context *ctx)
164 165 166
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
167 168
    char *request = NULL;
    esxVI_Response *response = NULL;
169 170

    if (ctx->service == NULL) {
171
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
172 173 174 175 176 177
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<Logout xmlns=\"urn:vim25\">");

178
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->sessionManager,
179 180 181 182 183 184 185 186 187
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</Logout>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
188
        virReportOOMError(NULL);
189 190 191
        goto failure;
    }

192
    request = virBufferContentAndReset(&buffer);
193

194
    if (esxVI_Context_Execute(ctx, "Logout", request, &response,
195
                              esxVI_Occurrence_None) < 0) {
196 197 198 199
        goto failure;
    }

  cleanup:
200 201
    VIR_FREE(request);
    esxVI_Response_Free(&response);
202 203 204 205

    return result;

  failure:
206
    virBufferFreeAndReset(&buffer);
207 208 209 210 211 212 213 214 215

    result = -1;

    goto cleanup;
}



int
216 217
esxVI_SessionIsActive(esxVI_Context *ctx, const char *sessionID,
                      const char *userName, esxVI_Boolean *active)
218 219 220
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
221 222
    char *request = NULL;
    esxVI_Response *response = NULL;
223 224

    if (ctx->service == NULL) {
225
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
226 227 228 229
        return -1;
    }

    if (active == NULL) {
230
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
231 232 233 234 235 236
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<SessionIsActive xmlns=\"urn:vim25\">");

237
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->sessionManager,
238 239
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
240
        esxVI_String_SerializeValue(sessionID, "sessionID", &buffer,
241
                                    esxVI_Boolean_True) < 0 ||
242
        esxVI_String_SerializeValue(userName, "userName", &buffer,
243 244 245 246 247 248 249 250
                                    esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</SessionIsActive>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
251
        virReportOOMError(NULL);
252 253 254
        goto failure;
    }

255
    request = virBufferContentAndReset(&buffer);
256

257 258 259
    if (esxVI_Context_Execute(ctx, "SessionIsActive", request, &response,
                              esxVI_Occurrence_RequiredItem) < 0 ||
        esxVI_Boolean_Deserialize(response->node, active) < 0) {
260 261 262 263
        goto failure;
    }

  cleanup:
264 265
    VIR_FREE(request);
    esxVI_Response_Free(&response);
266 267 268 269

    return result;

  failure:
270
    virBufferFreeAndReset(&buffer);
271 272 273 274 275 276 277 278 279

    result = -1;

    goto cleanup;
}



int
280
esxVI_RetrieveProperties(esxVI_Context *ctx,
281 282 283 284 285
                         esxVI_PropertyFilterSpec *propertyFilterSpecList,
                         esxVI_ObjectContent **objectContentList)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
286 287
    char *request = NULL;
    esxVI_Response *response = NULL;
288 289

    if (ctx->service == NULL) {
290
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
291 292 293 294
        return -1;
    }

    if (objectContentList == NULL || *objectContentList != NULL) {
295
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
296 297 298 299 300 301
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<RetrieveProperties xmlns=\"urn:vim25\">");

302
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->propertyCollector,
303 304
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
305
        esxVI_PropertyFilterSpec_SerializeList(propertyFilterSpecList,
306 307 308 309 310 311 312 313 314
                                               "specSet", &buffer,
                                               esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</RetrieveProperties>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
315
        virReportOOMError(NULL);
316 317 318
        goto failure;
    }

319
    request = virBufferContentAndReset(&buffer);
320

321 322 323
    if (esxVI_Context_Execute(ctx, "RetrieveProperties", request, &response,
                              esxVI_Occurrence_List) < 0 ||
        esxVI_ObjectContent_DeserializeList(response->node,
324
                                            objectContentList) < 0) {
325 326 327 328
        goto failure;
    }

  cleanup:
329 330
    VIR_FREE(request);
    esxVI_Response_Free(&response);
331 332 333 334

    return result;

  failure:
335
    virBufferFreeAndReset(&buffer);
336 337 338 339 340 341 342 343 344

    result = -1;

    goto cleanup;
}



int
345
esxVI_PowerOnVM_Task(esxVI_Context *ctx,
346 347 348
                     esxVI_ManagedObjectReference *virtualMachine,
                     esxVI_ManagedObjectReference **task)
{
349
    return esxVI_StartSimpleVirtualMachineTask(ctx, "PowerOnVM",
350 351 352 353 354 355
                                               virtualMachine, task);
}



int
356
esxVI_PowerOffVM_Task(esxVI_Context *ctx,
357 358 359
                      esxVI_ManagedObjectReference *virtualMachine,
                      esxVI_ManagedObjectReference **task)
{
360
    return esxVI_StartSimpleVirtualMachineTask(ctx, "PowerOffVM",
361 362 363 364 365 366
                                               virtualMachine, task);
}



int
367
esxVI_SuspendVM_Task(esxVI_Context *ctx,
368 369 370
                     esxVI_ManagedObjectReference *virtualMachine,
                     esxVI_ManagedObjectReference **task)
{
371
    return esxVI_StartSimpleVirtualMachineTask(ctx, "SuspendVM",
372 373 374 375 376 377
                                               virtualMachine, task);
}



int
378
esxVI_MigrateVM_Task(esxVI_Context *ctx,
379 380 381 382 383 384 385 386 387 388
                     esxVI_ManagedObjectReference *virtualMachine,
                     esxVI_ManagedObjectReference *resourcePool,
                     esxVI_ManagedObjectReference *hostSystem,
                     esxVI_ManagedObjectReference **task)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
    char *request = NULL;

    if (task == NULL || *task != NULL) {
389
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
390 391 392 393 394 395
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<MigrateVM_Task xmlns=\"urn:vim25\">");

396
    if (esxVI_ManagedObjectReference_Serialize(virtualMachine, "_this", &buffer,
397
                                               esxVI_Boolean_True) < 0 ||
398
        esxVI_ManagedObjectReference_Serialize(resourcePool, "pool", &buffer,
399
                                               esxVI_Boolean_True) < 0 ||
400
        esxVI_ManagedObjectReference_Serialize(hostSystem, "host", &buffer,
401 402
                                               esxVI_Boolean_True) < 0 ||
        esxVI_VirtualMachineMovePriority_Serialize
403 404
          (esxVI_VirtualMachineMovePriority_DefaultPriority, "priority",
           &buffer, esxVI_Boolean_True) < 0) {
405 406 407 408 409 410 411
        goto failure;
    }

    virBufferAddLit(&buffer, "</MigrateVM_Task>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
412
        virReportOOMError(NULL);
413 414 415 416 417
        goto failure;
    }

    request = virBufferContentAndReset(&buffer);

418
    if (esxVI_StartVirtualMachineTask(ctx, "MigrateVM", request, task) < 0) {
419 420 421 422 423 424 425 426 427
        goto failure;
    }

  cleanup:
    VIR_FREE(request);

    return result;

  failure:
428
    virBufferFreeAndReset(&buffer);
429 430 431 432 433 434 435 436 437

    result = -1;

    goto cleanup;
}



int
438
esxVI_ReconfigVM_Task(esxVI_Context *ctx,
439 440 441 442 443 444 445 446 447
                      esxVI_ManagedObjectReference *virtualMachine,
                      esxVI_VirtualMachineConfigSpec *spec,
                      esxVI_ManagedObjectReference **task)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
    char *request = NULL;

    if (task == NULL || *task != NULL) {
448
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
449 450 451 452 453 454
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<ReconfigVM_Task xmlns=\"urn:vim25\">");

455
    if (esxVI_ManagedObjectReference_Serialize(virtualMachine, "_this", &buffer,
456
                                               esxVI_Boolean_True) < 0 ||
457
        esxVI_VirtualMachineConfigSpec_Serialize(spec, "spec", &buffer,
458 459 460 461 462 463 464 465
                                                 esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</ReconfigVM_Task>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
466
        virReportOOMError(NULL);
467 468 469 470 471
        goto failure;
    }

    request = virBufferContentAndReset(&buffer);

472
    if (esxVI_StartVirtualMachineTask(ctx, "ReconfigVM", request, task) < 0) {
M
Matthias Bolte 已提交
473 474 475 476 477 478 479 480 481
        goto failure;
    }

  cleanup:
    VIR_FREE(request);

    return result;

  failure:
482
    virBufferFreeAndReset(&buffer);
M
Matthias Bolte 已提交
483 484 485 486 487 488 489 490 491

    result = -1;

    goto cleanup;
}



int
492
esxVI_RegisterVM_Task(esxVI_Context *ctx,
M
Matthias Bolte 已提交
493 494 495 496 497 498 499 500 501 502 503 504
                      esxVI_ManagedObjectReference *folder,
                      const char *path, const char *name,
                      esxVI_Boolean asTemplate,
                      esxVI_ManagedObjectReference *resourcePool,
                      esxVI_ManagedObjectReference *hostSystem,
                      esxVI_ManagedObjectReference **task)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
    char *request = NULL;

    if (task == NULL || *task != NULL) {
505
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
M
Matthias Bolte 已提交
506 507 508 509 510 511
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<RegisterVM_Task xmlns=\"urn:vim25\">");

512
    if (esxVI_ManagedObjectReference_Serialize(folder, "_this", &buffer,
M
Matthias Bolte 已提交
513
                                               esxVI_Boolean_True) < 0 ||
514
        esxVI_String_SerializeValue(path, "path", &buffer,
M
Matthias Bolte 已提交
515
                                    esxVI_Boolean_True) < 0 ||
516
        esxVI_String_SerializeValue(name, "name", &buffer,
M
Matthias Bolte 已提交
517
                                    esxVI_Boolean_False) < 0 ||
518
        esxVI_Boolean_Serialize(asTemplate, "asTemplate", &buffer,
M
Matthias Bolte 已提交
519
                                esxVI_Boolean_False) < 0 ||
520
        esxVI_ManagedObjectReference_Serialize(resourcePool, "pool", &buffer,
M
Matthias Bolte 已提交
521
                                               esxVI_Boolean_False) < 0 ||
522
        esxVI_ManagedObjectReference_Serialize(hostSystem, "host", &buffer,
M
Matthias Bolte 已提交
523 524 525 526 527 528 529 530
                                               esxVI_Boolean_False) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</RegisterVM_Task>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
531
        virReportOOMError(NULL);
M
Matthias Bolte 已提交
532 533 534 535 536
        goto failure;
    }

    request = virBufferContentAndReset(&buffer);

537
    if (esxVI_StartVirtualMachineTask(ctx, "RegisterVM", request, task) < 0) {
538 539 540 541 542 543 544 545 546
        goto failure;
    }

  cleanup:
    VIR_FREE(request);

    return result;

  failure:
547
    virBufferFreeAndReset(&buffer);
548 549 550 551 552 553 554 555

    result = -1;

    goto cleanup;
}



556
int
557
esxVI_CancelTask(esxVI_Context *ctx, esxVI_ManagedObjectReference *task)
558 559 560 561 562 563 564
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
    char *request = NULL;
    esxVI_Response *response = NULL;

    if (ctx->service == NULL) {
565
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
566 567 568 569 570 571
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<CancelTask xmlns=\"urn:vim25\">");

572
    if (esxVI_ManagedObjectReference_Serialize(task, "_this", &buffer,
573 574 575 576 577 578 579 580
                                               esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</CancelTask>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
581
        virReportOOMError(NULL);
582 583 584 585 586
        goto failure;
    }

    request = virBufferContentAndReset(&buffer);

587
    if (esxVI_Context_Execute(ctx, "CancelTask", request, &response,
588
                              esxVI_Occurrence_None) < 0) {
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
        goto failure;
    }

  cleanup:
    VIR_FREE(request);
    esxVI_Response_Free(&response);

    return result;

  failure:
    if (request == NULL) {
        request = virBufferContentAndReset(&buffer);
    }

    result = -1;

    goto cleanup;
}



610
int
611
esxVI_UnregisterVM(esxVI_Context *ctx,
612 613 614 615 616 617 618 619 620 621
                   esxVI_ManagedObjectReference *virtualMachine)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
    char *request = NULL;
    esxVI_Response *response = NULL;

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<UnregisterVM xmlns=\"urn:vim25\">");

622
    if (esxVI_ManagedObjectReference_Serialize(virtualMachine, "_this", &buffer,
623 624 625 626 627 628 629 630
                                               esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</UnregisterVM>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
631
        virReportOOMError(NULL);
632 633 634 635 636
        goto failure;
    }

    request = virBufferContentAndReset(&buffer);

637
    if (esxVI_Context_Execute(ctx, "UnregisterVM", request, &response,
638
                              esxVI_Occurrence_None) < 0) {
639 640 641 642 643 644 645 646 647 648
        goto failure;
    }

  cleanup:
    VIR_FREE(request);
    esxVI_Response_Free(&response);

    return result;

  failure:
649
    virBufferFreeAndReset(&buffer);
650 651 652 653 654 655 656 657

    result = -1;

    goto cleanup;
}



658
int
659
esxVI_AnswerVM(esxVI_Context *ctx,
660 661 662 663 664 665 666 667 668 669 670
               esxVI_ManagedObjectReference *virtualMachine,
               const char *questionId, const char *answerChoice)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
    char *request = NULL;
    esxVI_Response *response = NULL;

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<AnswerVM xmlns=\"urn:vim25\">");

671
    if (esxVI_ManagedObjectReference_Serialize(virtualMachine, "_this", &buffer,
672
                                               esxVI_Boolean_True) < 0 ||
673 674 675 676
        esxVI_String_SerializeValue(questionId, "questionId", &buffer,
                                    esxVI_Boolean_True) < 0 ||
        esxVI_String_SerializeValue(answerChoice, "answerChoice", &buffer,
                                    esxVI_Boolean_True) < 0) {
677 678 679 680 681 682 683
        goto failure;
    }

    virBufferAddLit(&buffer, "</AnswerVM>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
684
        virReportOOMError(NULL);
685 686 687 688 689
        goto failure;
    }

    request = virBufferContentAndReset(&buffer);

690
    if (esxVI_Context_Execute(ctx, request, NULL, &response,
691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
                              esxVI_Boolean_False) < 0) {
        goto failure;
    }

  cleanup:
    VIR_FREE(request);
    esxVI_Response_Free(&response);

    return result;

  failure:
    if (request == NULL) {
        request = virBufferContentAndReset(&buffer);
    }

    result = -1;

    goto cleanup;
}



713
int
714
esxVI_CreateFilter(esxVI_Context *ctx,
715 716 717 718 719 720
                   esxVI_PropertyFilterSpec *propertyFilterSpec,
                   esxVI_Boolean partialUpdates,
                   esxVI_ManagedObjectReference **propertyFilter)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
721 722
    char *request = NULL;
    esxVI_Response *response = NULL;
723 724

    if (ctx->service == NULL) {
725
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
726 727 728 729
        return -1;
    }

    if (propertyFilter == NULL || *propertyFilter != NULL) {
730
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
731 732 733 734 735 736
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<CreateFilter xmlns=\"urn:vim25\">");

737
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->propertyCollector,
738 739
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
740 741 742 743
        esxVI_PropertyFilterSpec_Serialize(propertyFilterSpec, "spec", &buffer,
                                           esxVI_Boolean_True) < 0 ||
        esxVI_Boolean_Serialize(partialUpdates, "partialUpdates", &buffer,
                                esxVI_Boolean_True) < 0) {
744 745 746 747 748 749 750
        goto failure;
    }

    virBufferAddLit(&buffer, "</CreateFilter>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
751
        virReportOOMError(NULL);
752 753 754
        goto failure;
    }

755
    request = virBufferContentAndReset(&buffer);
756

757
    if (esxVI_Context_Execute(ctx, "CreateFilter", request, &response,
758
                              esxVI_Occurrence_RequiredItem) < 0 ||
759
        esxVI_ManagedObjectReference_Deserialize(response->node, propertyFilter,
760
                                                 "PropertyFilter") < 0) {
761 762 763 764
        goto failure;
    }

  cleanup:
765 766
    VIR_FREE(request);
    esxVI_Response_Free(&response);
767 768 769 770

    return result;

  failure:
771
    virBufferFreeAndReset(&buffer);
772 773 774 775 776 777 778 779 780

    result = -1;

    goto cleanup;
}



int
781
esxVI_DestroyPropertyFilter(esxVI_Context *ctx,
782 783 784 785
                            esxVI_ManagedObjectReference *propertyFilter)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
786 787
    char *request = NULL;
    esxVI_Response *response = NULL;
788 789

    if (ctx->service == NULL) {
790
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
791 792 793 794 795 796
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<DestroyPropertyFilter xmlns=\"urn:vim25\">");

797
    if (esxVI_ManagedObjectReference_Serialize(propertyFilter, "_this", &buffer,
798 799 800 801 802 803 804 805
                                               esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</DestroyPropertyFilter>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
806
        virReportOOMError(NULL);
807 808 809
        goto failure;
    }

810
    request = virBufferContentAndReset(&buffer);
811

812
    if (esxVI_Context_Execute(ctx, "DestroyPropertyFilter", request,
813
                              &response, esxVI_Occurrence_None) < 0) {
814 815 816 817
        goto failure;
    }

  cleanup:
818 819
    VIR_FREE(request);
    esxVI_Response_Free(&response);
820 821 822 823

    return result;

  failure:
824
    virBufferFreeAndReset(&buffer);
825 826 827 828 829 830 831 832 833

    result = -1;

    goto cleanup;
}



int
834 835
esxVI_WaitForUpdates(esxVI_Context *ctx, const char *version,
                     esxVI_UpdateSet **updateSet)
836 837 838
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
839 840
    char *request = NULL;
    esxVI_Response *response = NULL;
841 842

    if (ctx->service == NULL) {
843
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
844 845 846 847
        return -1;
    }

    if (updateSet == NULL || *updateSet != NULL) {
848
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
849 850 851 852 853 854
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<WaitForUpdates xmlns=\"urn:vim25\">");

855
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->propertyCollector,
856 857
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
858
        esxVI_String_SerializeValue(version, "version", &buffer,
859 860 861 862 863 864 865 866
                                    esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</WaitForUpdates>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
867
        virReportOOMError(NULL);
868 869 870
        goto failure;
    }

871
    request = virBufferContentAndReset(&buffer);
872

873
    if (esxVI_Context_Execute(ctx, "WaitForUpdates", request,
874
                              &response, esxVI_Occurrence_RequiredItem) < 0 ||
875
        esxVI_UpdateSet_Deserialize(response->node, updateSet) < 0) {
876 877 878 879
        goto failure;
    }

  cleanup:
880 881
    VIR_FREE(request);
    esxVI_Response_Free(&response);
882 883 884 885

    return result;

  failure:
886
    virBufferFreeAndReset(&buffer);
887 888 889 890 891 892 893 894 895

    result = -1;

    goto cleanup;
}



int
896
esxVI_RebootGuest(esxVI_Context *ctx,
897 898
                  esxVI_ManagedObjectReference *virtualMachine)
{
899
    return esxVI_SimpleVirtualMachineMethod(ctx, "RebootGuest", virtualMachine);
900 901 902 903 904
}



int
905
esxVI_ShutdownGuest(esxVI_Context *ctx,
906 907
                    esxVI_ManagedObjectReference *virtualMachine)
{
908
    return esxVI_SimpleVirtualMachineMethod(ctx, "ShutdownGuest",
909 910 911 912 913 914
                                            virtualMachine);
}



int
915
esxVI_ValidateMigration(esxVI_Context *ctx,
916 917 918 919 920 921 922 923 924
                        esxVI_ManagedObjectReference *virtualMachineList,
                        esxVI_VirtualMachinePowerState powerState,
                        esxVI_String *testTypeList,
                        esxVI_ManagedObjectReference *resourcePool,
                        esxVI_ManagedObjectReference *hostSystem,
                        esxVI_Event **eventList)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
925 926
    char *request = NULL;
    esxVI_Response *response = NULL;
927 928

    if (ctx->service == NULL) {
929
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
930 931 932 933
        return -1;
    }

    if (eventList == NULL || *eventList != NULL) {
934
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
935 936 937 938 939 940 941 942 943 944 945
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<ValidateMigration xmlns=\"urn:vim25\">"
                             "<_this xmlns=\"urn:vim25\" "
                                    "xsi:type=\"ManagedObjectReference\" "
                                    "type=\"ServiceInstance\">"
                               "ServiceInstance"
                             "</_this>");

946 947
    if (esxVI_ManagedObjectReference_SerializeList(virtualMachineList, "vm",
                                                   &buffer,
948
                                                   esxVI_Boolean_True) < 0 ||
949
        esxVI_VirtualMachinePowerState_Serialize(powerState, "state", &buffer,
950
                                                 esxVI_Boolean_False) < 0 ||
951
        esxVI_String_SerializeList(testTypeList, "testType", &buffer,
952
                                   esxVI_Boolean_False) < 0 ||
953
        esxVI_ManagedObjectReference_Serialize(resourcePool, "pool", &buffer,
954
                                               esxVI_Boolean_True) < 0 ||
955
        esxVI_ManagedObjectReference_Serialize(hostSystem, "host", &buffer,
956 957 958 959 960 961 962 963
                                               esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</ValidateMigration>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
964
        virReportOOMError(NULL);
965 966 967
        goto failure;
    }

968
    request = virBufferContentAndReset(&buffer);
969

970 971 972
    if (esxVI_Context_Execute(ctx, "ValidateMigration", request, &response,
                              esxVI_Occurrence_List) < 0 ||
        esxVI_Event_DeserializeList(response->node, eventList) < 0) {
973 974 975 976
        goto failure;
    }

  cleanup:
977 978
    VIR_FREE(request);
    esxVI_Response_Free(&response);
979 980 981 982

    return result;

  failure:
983
    virBufferFreeAndReset(&buffer);
984 985 986 987 988 989 990 991 992

    result = -1;

    goto cleanup;
}



int
993
esxVI_FindByIp(esxVI_Context *ctx,
994 995 996 997 998 999
                 esxVI_ManagedObjectReference *datacenter,
                 const char *ip, esxVI_Boolean vmSearch,
                 esxVI_ManagedObjectReference **managedObjectReference)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
1000 1001
    char *request = NULL;
    esxVI_Response *response = NULL;
1002 1003

    if (ctx->service == NULL) {
1004
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
1005 1006 1007 1008
        return -1;
    }

    if (managedObjectReference == NULL || *managedObjectReference != NULL) {
1009
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
1010 1011 1012 1013 1014 1015
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<FindByIp xmlns=\"urn:vim25\">");

1016
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->searchIndex,
1017 1018
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
1019 1020
        esxVI_ManagedObjectReference_Serialize(datacenter, "datacenter",
                                               &buffer,
1021
                                               esxVI_Boolean_False) < 0 ||
1022
        esxVI_String_SerializeValue(ip, "ip", &buffer,
1023
                                    esxVI_Boolean_True) < 0 ||
1024
        esxVI_Boolean_Serialize(vmSearch, "vmSearch", &buffer,
1025 1026 1027 1028 1029 1030 1031 1032
                                esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</FindByIp>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
1033
        virReportOOMError(NULL);
1034 1035 1036
        goto failure;
    }

1037
    request = virBufferContentAndReset(&buffer);
1038

1039
    if (esxVI_Context_Execute(ctx, "FindByIp", request, &response,
1040
                              esxVI_Occurrence_OptionalItem) < 0 ||
1041
        esxVI_ManagedObjectReference_Deserialize
1042
          (response->node, managedObjectReference,
1043 1044 1045 1046 1047 1048
           vmSearch == esxVI_Boolean_True ? "VirtualMachine"
                                          : "HostSystem") < 0) {
        goto failure;
    }

  cleanup:
1049 1050
    VIR_FREE(request);
    esxVI_Response_Free(&response);
1051 1052 1053 1054

    return result;

  failure:
1055
    virBufferFreeAndReset(&buffer);
1056 1057 1058 1059 1060 1061 1062 1063 1064

    result = -1;

    goto cleanup;
}



int
1065
esxVI_FindByUuid(esxVI_Context *ctx,
1066 1067 1068 1069 1070 1071 1072
                 esxVI_ManagedObjectReference *datacenter,
                 const unsigned char *uuid, esxVI_Boolean vmSearch,
                 esxVI_ManagedObjectReference **managedObjectReference)
{
    int result = 0;
    char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
1073 1074
    char *request = NULL;
    esxVI_Response *response = NULL;
1075 1076

    if (ctx->service == NULL) {
1077
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
1078 1079 1080 1081
        return -1;
    }

    if (managedObjectReference == NULL || *managedObjectReference != NULL) {
1082
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
1083 1084 1085 1086 1087 1088 1089 1090
        return -1;
    }

    virUUIDFormat(uuid, uuid_string);

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<FindByUuid xmlns=\"urn:vim25\">");

1091
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->searchIndex,
1092 1093
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
1094 1095
        esxVI_ManagedObjectReference_Serialize(datacenter, "datacenter",
                                               &buffer,
1096
                                               esxVI_Boolean_False) < 0 ||
1097
        esxVI_String_SerializeValue(uuid_string, "uuid", &buffer,
1098
                                    esxVI_Boolean_True) < 0 ||
1099
        esxVI_Boolean_Serialize(vmSearch, "vmSearch", &buffer,
1100 1101 1102 1103 1104 1105 1106 1107
                                esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</FindByUuid>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
1108
        virReportOOMError(NULL);
1109 1110 1111
        goto failure;
    }

1112
    request = virBufferContentAndReset(&buffer);
1113

1114
    if (esxVI_Context_Execute(ctx, "FindByUuid", request, &response,
1115
                              esxVI_Occurrence_OptionalItem) < 0) {
1116 1117 1118 1119 1120 1121 1122 1123
        goto failure;
    }

    if (response->node == NULL) {
        goto cleanup;
    }

    if (esxVI_ManagedObjectReference_Deserialize
1124
          (response->node, managedObjectReference,
1125 1126 1127 1128 1129 1130
           vmSearch == esxVI_Boolean_True ? "VirtualMachine"
                                          : "HostSystem") < 0) {
        goto failure;
    }

  cleanup:
1131 1132
    VIR_FREE(request);
    esxVI_Response_Free(&response);
1133 1134 1135 1136

    return result;

  failure:
1137
    virBufferFreeAndReset(&buffer);
1138 1139 1140 1141 1142 1143 1144 1145 1146

    result = -1;

    goto cleanup;
}



int
1147
esxVI_QueryAvailablePerfMetric(esxVI_Context *ctx,
1148 1149 1150 1151 1152 1153 1154
                               esxVI_ManagedObjectReference *entity,
                               esxVI_DateTime *beginTime,
                               esxVI_DateTime *endTime, esxVI_Int *intervalId,
                               esxVI_PerfMetricId **perfMetricIdList)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
1155 1156
    char *request = NULL;
    esxVI_Response *response = NULL;
1157 1158

    if (ctx->service == NULL) {
1159
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
1160 1161 1162 1163
        return -1;
    }

    if (perfMetricIdList == NULL || *perfMetricIdList != NULL) {
1164
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
1165 1166 1167 1168 1169 1170
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<QueryAvailablePerfMetric xmlns=\"urn:vim25\">");

1171
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->perfManager,
1172 1173
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
1174
        esxVI_ManagedObjectReference_Serialize(entity, "entity", &buffer,
1175
                                               esxVI_Boolean_True) < 0 ||
1176
        esxVI_DateTime_Serialize(beginTime, "beginTime", &buffer,
1177
                                 esxVI_Boolean_False) < 0 ||
1178
        esxVI_DateTime_Serialize(endTime, "endTime", &buffer,
1179
                                 esxVI_Boolean_False) < 0 ||
1180
        esxVI_Int_Serialize(intervalId, "intervalId", &buffer,
1181 1182 1183 1184 1185 1186 1187 1188
                            esxVI_Boolean_False) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</QueryAvailablePerfMetric>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
1189
        virReportOOMError(NULL);
1190 1191 1192
        goto failure;
    }

1193
    request = virBufferContentAndReset(&buffer);
1194

1195
    if (esxVI_Context_Execute(ctx, "QueryAvailablePerfMetric", request,
1196
                              &response, esxVI_Occurrence_List) < 0 ||
1197
        esxVI_PerfMetricId_DeserializeList(response->node,
1198
                                           perfMetricIdList) < 0) {
1199 1200 1201 1202
        goto failure;
    }

  cleanup:
1203 1204
    VIR_FREE(request);
    esxVI_Response_Free(&response);
1205 1206 1207 1208

    return result;

  failure:
1209
    virBufferFreeAndReset(&buffer);
1210 1211 1212 1213 1214 1215 1216 1217 1218

    result = -1;

    goto cleanup;
}



int
1219
esxVI_QueryPerfCounter(esxVI_Context *ctx, esxVI_Int *counterIdList,
1220 1221 1222 1223
                       esxVI_PerfCounterInfo **perfCounterInfoList)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
1224 1225
    char *request = NULL;
    esxVI_Response *response = NULL;
1226 1227

    if (ctx->service == NULL) {
1228
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
1229 1230 1231 1232
        return -1;
    }

    if (perfCounterInfoList == NULL || *perfCounterInfoList != NULL) {
1233
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
1234 1235 1236 1237 1238 1239
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<QueryPerfCounter xmlns=\"urn:vim25\">");

1240
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->perfManager,
1241 1242
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
1243
        esxVI_Int_SerializeList(counterIdList, "counterId", &buffer,
1244 1245 1246 1247 1248 1249 1250 1251
                                esxVI_Boolean_True) < 0) {
        goto failure;
    }

    virBufferAddLit(&buffer, "</QueryPerfCounter>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
1252
        virReportOOMError(NULL);
1253 1254 1255
        goto failure;
    }

1256
    request = virBufferContentAndReset(&buffer);
1257

1258 1259 1260
    if (esxVI_Context_Execute(ctx, "QueryPerfCounter", request, &response,
                              esxVI_Occurrence_List) < 0 ||
        esxVI_PerfCounterInfo_DeserializeList(response->node,
1261
                                              perfCounterInfoList) < 0) {
1262 1263 1264 1265
        goto failure;
    }

  cleanup:
1266 1267
    VIR_FREE(request);
    esxVI_Response_Free(&response);
1268 1269 1270 1271

    return result;

  failure:
1272
    virBufferFreeAndReset(&buffer);
1273 1274 1275 1276 1277 1278 1279 1280 1281

    result = -1;

    goto cleanup;
}



int
1282
esxVI_QueryPerf(esxVI_Context *ctx, esxVI_PerfQuerySpec *querySpecList,
1283 1284 1285 1286
                esxVI_PerfEntityMetric **perfEntityMetricList)
{
    int result = 0;
    virBuffer buffer = VIR_BUFFER_INITIALIZER;
1287 1288
    char *request = NULL;
    esxVI_Response *response = NULL;
1289 1290

    if (ctx->service == NULL) {
1291
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid call");
1292 1293 1294 1295
        return -1;
    }

    if (perfEntityMetricList == NULL || *perfEntityMetricList != NULL) {
1296
        ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
1297 1298 1299 1300 1301 1302
        return -1;
    }

    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
    virBufferAddLit(&buffer, "<QueryPerf xmlns=\"urn:vim25\">");

1303
    if (esxVI_ManagedObjectReference_Serialize(ctx->service->perfManager,
1304 1305
                                               "_this", &buffer,
                                               esxVI_Boolean_True) < 0 ||
1306 1307
        esxVI_PerfQuerySpec_SerializeList(querySpecList, "querySpec", &buffer,
                                          esxVI_Boolean_True) < 0) {
1308 1309 1310 1311 1312 1313 1314
        goto failure;
    }

    virBufferAddLit(&buffer, "</QueryPerf>");
    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);

    if (virBufferError(&buffer)) {
1315
        virReportOOMError(NULL);
1316 1317 1318
        goto failure;
    }

1319
    request = virBufferContentAndReset(&buffer);
1320

1321
    if (esxVI_Context_Execute(ctx, "QueryPerf", request, &response,
1322
                              esxVI_Occurrence_List) < 0 ||
1323
        esxVI_PerfEntityMetric_DeserializeList(response->node,
1324
                                               perfEntityMetricList) < 0) {
1325 1326 1327 1328
        goto failure;
    }

  cleanup:
1329 1330
    VIR_FREE(request);
    esxVI_Response_Free(&response);
1331 1332 1333 1334

    return result;

  failure:
1335
    virBufferFreeAndReset(&buffer);
1336 1337 1338 1339 1340

    result = -1;

    goto cleanup;
}