virsh.c 28.1 KB
Newer Older
1
/*
2
 * virsh.c: a shell to exercise the libvirt API
3
 *
4
 * Copyright (C) 2005, 2007-2015 Red Hat, Inc.
5
 *
O
Osier Yang 已提交
6 7 8 9 10 11 12 13 14 15 16
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
19 20
 *
 * Daniel Veillard <veillard@redhat.com>
K
Karel Zak 已提交
21
 * Karel Zak <kzak@redhat.com>
K
Karel Zak 已提交
22
 * Daniel P. Berrange <berrange@redhat.com>
23 24
 */

25
#include <config.h>
E
Eric Blake 已提交
26
#include "virsh.h"
27

28
#include <stdio.h>
K
Karel Zak 已提交
29 30 31
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
32
#include <unistd.h>
33
#include <errno.h>
K
Karel Zak 已提交
34
#include <getopt.h>
K
Karel Zak 已提交
35
#include <sys/time.h>
36
#include <fcntl.h>
37
#include <locale.h>
38
#include <time.h>
39
#include <limits.h>
40
#include <sys/stat.h>
41
#include <inttypes.h>
42
#include <signal.h>
K
Karel Zak 已提交
43

44
#if WITH_READLINE
45 46
# include <readline/readline.h>
# include <readline/history.h>
47
#endif
K
Karel Zak 已提交
48

49
#include "internal.h"
50
#include "virerror.h"
51
#include "virbuffer.h"
52
#include "viralloc.h"
53 54
#include <libvirt/libvirt-qemu.h>
#include <libvirt/libvirt-lxc.h>
E
Eric Blake 已提交
55
#include "virfile.h"
56
#include "configmake.h"
57
#include "virthread.h"
58
#include "vircommand.h"
H
Hu Tao 已提交
59
#include "conf/domain_conf.h"
60
#include "virtypedparam.h"
61
#include "virstring.h"
K
Karel Zak 已提交
62

63
#include "virsh-console.h"
E
Eric Blake 已提交
64
#include "virsh-domain.h"
65
#include "virsh-domain-monitor.h"
E
Eric Blake 已提交
66
#include "virsh-host.h"
E
Eric Blake 已提交
67
#include "virsh-interface.h"
E
Eric Blake 已提交
68
#include "virsh-network.h"
E
Eric Blake 已提交
69
#include "virsh-nodedev.h"
E
Eric Blake 已提交
70
#include "virsh-nwfilter.h"
E
Eric Blake 已提交
71
#include "virsh-pool.h"
E
Eric Blake 已提交
72
#include "virsh-secret.h"
E
Eric Blake 已提交
73
#include "virsh-snapshot.h"
E
Eric Blake 已提交
74
#include "virsh-volume.h"
E
Eric Blake 已提交
75

76 77 78 79 80
/* Gnulib doesn't guarantee SA_SIGINFO support.  */
#ifndef SA_SIGINFO
# define SA_SIGINFO 0
#endif

K
Karel Zak 已提交
81 82
static char *progname;

83
static const vshCmdGrp cmdGroups[];
84
static const vshClientHooks hooks;
J
John Levon 已提交
85

86 87 88
/*
 * Detection of disconnections and automatic reconnection support
 */
89
static int disconnected; /* we may have been disconnected */
90 91

/*
92
 * virshCatchDisconnect:
93
 *
94 95
 * We get here when the connection was closed.  We can't do much in the
 * handler, just save the fact it was raised.
96
 */
L
Laine Stump 已提交
97
static void
98
virshCatchDisconnect(virConnectPtr conn,
99
                     int reason,
100
                     void *opaque)
101
{
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
    if (reason != VIR_CONNECT_CLOSE_REASON_CLIENT) {
        vshControl *ctl = opaque;
        const char *str = "unknown reason";
        virErrorPtr error;
        char *uri;

        error = virSaveLastError();
        uri = virConnectGetURI(conn);

        switch ((virConnectCloseReason) reason) {
        case VIR_CONNECT_CLOSE_REASON_ERROR:
            str = N_("Disconnected from %s due to I/O error");
            break;
        case VIR_CONNECT_CLOSE_REASON_EOF:
            str = N_("Disconnected from %s due to end of file");
            break;
        case VIR_CONNECT_CLOSE_REASON_KEEPALIVE:
            str = N_("Disconnected from %s due to keepalive timeout");
            break;
J
John Ferlan 已提交
121
        /* coverity[dead_error_condition] */
122 123 124 125 126
        case VIR_CONNECT_CLOSE_REASON_CLIENT:
        case VIR_CONNECT_CLOSE_REASON_LAST:
            break;
        }
        vshError(ctl, _(str), NULLSTR(uri));
127
        VIR_FREE(uri);
128 129 130 131 132

        if (error) {
            virSetError(error);
            virFreeError(error);
        }
133
        disconnected++;
134
        vshEventDone(ctl);
135
    }
136 137
}

138 139 140
/* Main Function which should be used for connecting.
 * This function properly handles keepalive settings. */
virConnectPtr
141
virshConnect(vshControl *ctl, const char *uri, bool readonly)
142 143 144 145 146
{
    virConnectPtr c = NULL;
    int interval = 5; /* Default */
    int count = 6;    /* Default */
    bool keepalive_forced = false;
147 148
    virPolkitAgentPtr pkagent = NULL;
    int authfail = 0;
149 150 151 152 153 154 155 156 157 158

    if (ctl->keepalive_interval >= 0) {
        interval = ctl->keepalive_interval;
        keepalive_forced = true;
    }
    if (ctl->keepalive_count >= 0) {
        count = ctl->keepalive_count;
        keepalive_forced = true;
    }

159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
    do {
        virErrorPtr err;

        if ((c = virConnectOpenAuth(uri, virConnectAuthPtrDefault,
                                    readonly ? VIR_CONNECT_RO : 0)))
            break;

        if (readonly)
            goto cleanup;

        err = virGetLastError();
        if (err && err->domain == VIR_FROM_POLKIT &&
            err->code == VIR_ERR_AUTH_UNAVAILABLE) {
            if (!(pkagent = virPolkitAgentCreate()))
                goto cleanup;
        } else if (err && err->domain == VIR_FROM_POLKIT &&
                   err->code == VIR_ERR_AUTH_FAILED) {
            authfail++;
        } else {
            goto cleanup;
        }
        virResetLastError();
        /* Failure to authenticate 5 times should be enough.
         * No sense prolonging the agony.
         */
    } while (authfail < 5);

186
    if (!c)
187
        goto cleanup;
188 189 190 191 192 193 194 195

    if (interval > 0 &&
        virConnectSetKeepAlive(c, interval, count) != 0) {
        if (keepalive_forced) {
            vshError(ctl, "%s",
                     _("Cannot setup keepalive on connection "
                       "as requested, disconnecting"));
            virConnectClose(c);
196 197
            c = NULL;
            goto cleanup;
198 199 200 201 202
        }
        vshDebug(ctl, VSH_ERR_INFO, "%s",
                 _("Failed to setup keepalive on connection\n"));
    }

203 204
 cleanup:
    virPolkitAgentDestroy(pkagent);
205 206 207
    return c;
}

208
/*
209
 * virshReconnect:
210
 *
L
Laine Stump 已提交
211
 * Reconnect after a disconnect from libvirtd
212 213
 *
 */
L
Laine Stump 已提交
214
static void
215
virshReconnect(vshControl *ctl)
216 217
{
    bool connected = false;
218
    virshControlPtr priv = ctl->privData;
219

220
    if (priv->conn) {
221
        int ret;
222
        connected = true;
223

224 225
        virConnectUnregisterCloseCallback(priv->conn, virshCatchDisconnect);
        ret = virConnectClose(priv->conn);
226 227 228 229 230
        if (ret < 0)
            vshError(ctl, "%s", _("Failed to disconnect from the hypervisor"));
        else if (ret > 0)
            vshError(ctl, "%s", _("One or more references were leaked after "
                                  "disconnect from the hypervisor"));
231
    }
232

233
    priv->conn = virshConnect(ctl, ctl->connname, priv->readonly);
234

235
    if (!priv->conn) {
236 237 238 239
        if (disconnected)
            vshError(ctl, "%s", _("Failed to reconnect to the hypervisor"));
        else
            vshError(ctl, "%s", _("failed to connect to the hypervisor"));
240
    } else {
241
        if (virConnectRegisterCloseCallback(priv->conn, virshCatchDisconnect,
242
                                            ctl, NULL) < 0)
243 244 245 246
            vshError(ctl, "%s", _("Unable to register disconnect callback"));
        if (connected)
            vshError(ctl, "%s", _("Reconnected to the hypervisor"));
    }
247
    disconnected = 0;
248 249 250
    priv->useGetInfo = false;
    priv->useSnapshotOld = false;
    priv->blockJobNoBytes = false;
251
}
252

253 254 255 256 257 258 259
int virshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED,
                    const char *bytes, size_t nbytes, void *opaque)
{
    int *fd = opaque;

    return safewrite(*fd, bytes, nbytes);
}
260

261 262 263
/* ---------------
 * Command Connect
 * ---------------
264 265 266 267
 */

static const vshCmdOptDef opts_connect[] = {
    {.name = "name",
268
     .type = VSH_OT_STRING,
269 270 271 272 273 274 275 276 277 278
     .flags = VSH_OFLAG_EMPTY_OK,
     .help = N_("hypervisor connection URI")
    },
    {.name = "readonly",
     .type = VSH_OT_BOOL,
     .help = N_("read-only connection")
    },
    {.name = NULL}
};

279
static const vshCmdInfo info_connect[] = {
280
    {.name = "help",
281
     .data = N_("(re)connect to hypervisor")
282 283
    },
    {.name = "desc",
284 285
     .data = N_("Connect to local hypervisor. This is built-in "
                "command after shell start up.")
286 287
    },
    {.name = NULL}
P
Paolo Bonzini 已提交
288 289
};

E
Eric Blake 已提交
290
static bool
291
cmdConnect(vshControl *ctl, const vshCmd *cmd)
P
Paolo Bonzini 已提交
292
{
293 294 295
    bool ro = vshCommandOptBool(cmd, "readonly");
    const char *name = NULL;
    virshControlPtr priv = ctl->privData;
P
Paolo Bonzini 已提交
296

297 298
    if (priv->conn) {
        int ret;
299

300 301 302 303 304 305 306 307
        virConnectUnregisterCloseCallback(priv->conn, virshCatchDisconnect);
        ret = virConnectClose(priv->conn);
        if (ret < 0)
            vshError(ctl, "%s", _("Failed to disconnect from the hypervisor"));
        else if (ret > 0)
            vshError(ctl, "%s", _("One or more references were leaked after "
                                  "disconnect from the hypervisor"));
        priv->conn = NULL;
J
Jiri Denemark 已提交
308 309
    }

310
    VIR_FREE(ctl->connname);
311 312
    if (vshCommandOptStringReq(ctl, cmd, "name", &name) < 0)
        return false;
313

314
    ctl->connname = vshStrdup(ctl, name);
315

316 317 318 319
    priv->useGetInfo = false;
    priv->useSnapshotOld = false;
    priv->blockJobNoBytes = false;
    priv->readonly = ro;
320

321
    priv->conn = virshConnect(ctl, ctl->connname, priv->readonly);
322

323 324 325 326
    if (!priv->conn) {
        vshError(ctl, "%s", _("Failed to connect to the hypervisor"));
        return false;
    }
327

328
    if (virConnectRegisterCloseCallback(priv->conn, virshCatchDisconnect,
329
                                        ctl, NULL) < 0)
330
        vshError(ctl, "%s", _("Unable to register disconnect callback"));
331

332
    return true;
333 334
}

335 336 337 338
/* ---------------
 * Utils for work with runtime commands data
 * ---------------
 */
339

340 341
static bool
virshConnectionUsability(vshControl *ctl, virConnectPtr conn)
342
{
343 344 345 346
    if (!conn ||
        virConnectIsAlive(conn) == 0) {
        vshError(ctl, "%s", _("no valid connection"));
        return false;
347 348
    }

349 350 351 352
    /* The connection is considered dead only if
     * virConnectIsAlive() successfuly says so.
     */
    vshResetLibvirtError();
353

354
    return true;
355 356
}

357 358
static void *
virshConnectionHandler(vshControl *ctl)
359
{
360
    virshControlPtr priv = ctl->privData;
361

362 363
    if (!priv->conn || disconnected)
        virshReconnect(ctl);
364

365 366 367
    if (virshConnectionUsability(ctl, priv->conn))
        return priv->conn;
    return NULL;
368 369
}

370 371 372
/* ---------------
 * Misc utils
 * ---------------
373
 */
374 375
int
virshDomainState(vshControl *ctl, virDomainPtr dom, int *reason)
376
{
377 378
    virDomainInfo info;
    virshControlPtr priv = ctl->privData;
379

380 381
    if (reason)
        *reason = -1;
382

383 384 385 386 387 388 389 390 391 392
    if (!priv->useGetInfo) {
        int state;
        if (virDomainGetState(dom, &state, reason, 0) < 0) {
            virErrorPtr err = virGetLastError();
            if (err && err->code == VIR_ERR_NO_SUPPORT)
                priv->useGetInfo = true;
            else
                return -1;
        } else {
            return state;
393 394 395
        }
    }

396 397 398 399 400
    /* fall back to virDomainGetInfo if virDomainGetState is not supported */
    if (virDomainGetInfo(dom, &info) < 0)
        return -1;
    else
        return info.state;
M
Martin Kletzander 已提交
401 402 403 404 405 406
}

/*
 * Initialize connection.
 */
static bool
407
virshInit(vshControl *ctl)
M
Martin Kletzander 已提交
408
{
409 410
    virshControlPtr priv = ctl->privData;

M
Martin Kletzander 已提交
411
    /* Since we have the commandline arguments parsed, we need to
E
Erik Skultety 已提交
412 413 414
     * reload our initial settings to make debugging and readline
     * work properly */
    vshInitReload(ctl);
M
Martin Kletzander 已提交
415

416
    if (priv->conn)
M
Martin Kletzander 已提交
417
        return false;
418

419
    /* set up the library error handler */
420
    virSetErrorFunc(NULL, vshErrorHandler);
421

422
    if (virEventRegisterDefaultImpl() < 0)
E
Eric Blake 已提交
423
        return false;
424

J
Jiri Denemark 已提交
425 426 427 428
    if (virThreadCreate(&ctl->eventLoop, true, vshEventLoop, ctl) < 0)
        return false;
    ctl->eventLoopStarted = true;

429 430 431 432
    if ((ctl->eventTimerId = virEventAddTimeout(-1, vshEventTimeout, ctl,
                                                NULL)) < 0)
        return false;

433
    if (ctl->connname) {
434
        virshReconnect(ctl);
435 436 437 438 439 440
        /* Connecting to a named connection must succeed, but we delay
         * connecting to the default connection until we need it
         * (since the first command might be 'connect' which allows a
         * non-default connection, or might be 'help' which needs no
         * connection).
         */
441
        if (!priv->conn) {
E
Eric Blake 已提交
442
            vshReportError(ctl);
443 444
            return false;
        }
445
    }
K
Karel Zak 已提交
446

E
Eric Blake 已提交
447
    return true;
K
Karel Zak 已提交
448 449
}

450
static void
451
virshDeinitTimer(int timer ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED)
452 453 454 455
{
    /* nothing to be done here */
}

K
Karel Zak 已提交
456
/*
J
Jim Meyering 已提交
457
 * Deinitialize virsh
K
Karel Zak 已提交
458
 */
E
Eric Blake 已提交
459
static bool
460
virshDeinit(vshControl *ctl)
461
{
462 463 464
    virshControlPtr priv = ctl->privData;

    vshDeinit(ctl);
465
    VIR_FREE(ctl->connname);
466
    if (priv->conn) {
467
        int ret;
468 469
        virConnectUnregisterCloseCallback(priv->conn, virshCatchDisconnect);
        ret = virConnectClose(priv->conn);
470 471 472 473 474
        if (ret < 0)
            vshError(ctl, "%s", _("Failed to disconnect from the hypervisor"));
        else if (ret > 0)
            vshError(ctl, "%s", _("One or more references were leaked after "
                                  "disconnect from the hypervisor"));
K
Karel Zak 已提交
475
    }
D
Daniel P. Berrange 已提交
476 477
    virResetLastError();

J
Jiri Denemark 已提交
478
    if (ctl->eventLoopStarted) {
479 480 481 482
        int timer;

        virMutexLock(&ctl->lock);
        ctl->quit = true;
J
Jiri Denemark 已提交
483
        /* HACK: Add a dummy timeout to break event loop */
484
        timer = virEventAddTimeout(0, virshDeinitTimer, NULL, NULL);
485 486 487 488
        virMutexUnlock(&ctl->lock);

        virThreadJoin(&ctl->eventLoop);

J
Jiri Denemark 已提交
489 490 491
        if (timer != -1)
            virEventRemoveTimeout(timer);

492 493 494
        if (ctl->eventTimerId != -1)
            virEventRemoveTimeout(ctl->eventTimerId);

J
Jiri Denemark 已提交
495 496 497
        ctl->eventLoopStarted = false;
    }

498 499
    virMutexDestroy(&ctl->lock);

E
Eric Blake 已提交
500
    return true;
K
Karel Zak 已提交
501
}
502

K
Karel Zak 已提交
503 504 505
/*
 * Print usage
 */
E
Eric Blake 已提交
506
static void
507
virshUsage(void)
508
{
509
    const vshCmdGrp *grp;
510
    const vshCmdDef *cmd;
511

L
Lai Jiangshan 已提交
512 513
    fprintf(stdout, _("\n%s [options]... [<command_string>]"
                      "\n%s [options]... <command> [args...]\n\n"
514
                      "  options:\n"
515 516
                      "    -c | --connect=URI      hypervisor connection URI\n"
                      "    -d | --debug=NUM        debug level [0-4]\n"
517
                      "    -e | --escape <char>    set escape sequence for console\n"
518
                      "    -h | --help             this help\n"
519 520 521 522
                      "    -k | --keepalive-interval=NUM\n"
                      "                            keepalive interval in seconds, 0 for disable\n"
                      "    -K | --keepalive-count=NUM\n"
                      "                            number of possible missed keepalive messages\n"
523
                      "    -l | --log=FILE         output logging to file\n"
524
                      "    -q | --quiet            quiet mode\n"
525
                      "    -r | --readonly         connect readonly\n"
526
                      "    -t | --timing           print timing information\n"
527 528 529
                      "    -v                      short version\n"
                      "    -V                      long version\n"
                      "         --version[=TYPE]   version, TYPE is short or long (default short)\n"
530 531
                      "  commands (non interactive mode):\n\n"), progname,
            progname);
532

533
    for (grp = cmdGroups; grp->name; grp++) {
E
Eric Blake 已提交
534 535 536 537 538
        fprintf(stdout, _(" %s (help keyword '%s')\n"),
                grp->name, grp->keyword);
        for (cmd = grp->commands; cmd->name; cmd++) {
            if (cmd->flags & VSH_CMD_FLAG_ALIAS)
                continue;
539
            fprintf(stdout,
E
Eric Blake 已提交
540 541 542
                    "    %-30s %s\n", cmd->name,
                    _(vshCmddefGetInfo(cmd, "help")));
        }
543 544 545 546 547
        fprintf(stdout, "\n");
    }

    fprintf(stdout, "%s",
            _("\n  (specify help <group> for details about the commands in the group)\n"));
548 549 550
    fprintf(stdout, "%s",
            _("\n  (specify help <command> for details about the command)\n\n"));
    return;
K
Karel Zak 已提交
551 552
}

553 554 555 556
/*
 * Show version and options compiled in
 */
static void
557
virshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
558 559 560 561 562
{
    /* FIXME - list a copyright blurb, as in GNU programs?  */
    vshPrint(ctl, _("Virsh command line tool of libvirt %s\n"), VERSION);
    vshPrint(ctl, _("See web site at %s\n\n"), "http://libvirt.org/");

L
Laine Stump 已提交
563 564
    vshPrint(ctl, "%s", _("Compiled with support for:\n"));
    vshPrint(ctl, "%s", _(" Hypervisors:"));
565
#ifdef WITH_QEMU
566
    vshPrint(ctl, " QEMU/KVM");
567
#endif
D
Doug Goldstein 已提交
568 569 570
#ifdef WITH_LXC
    vshPrint(ctl, " LXC");
#endif
571 572 573
#ifdef WITH_UML
    vshPrint(ctl, " UML");
#endif
D
Doug Goldstein 已提交
574 575 576 577 578 579
#ifdef WITH_XEN
    vshPrint(ctl, " Xen");
#endif
#ifdef WITH_LIBXL
    vshPrint(ctl, " LibXL");
#endif
580 581 582
#ifdef WITH_OPENVZ
    vshPrint(ctl, " OpenVZ");
#endif
583 584 585
#ifdef WITH_VZ
    vshPrint(ctl, " Virtuozzo");
#endif
D
Doug Goldstein 已提交
586
#ifdef WITH_VMWARE
J
Ján Tomko 已提交
587
    vshPrint(ctl, " VMware");
588
#endif
D
Doug Goldstein 已提交
589 590
#ifdef WITH_PHYP
    vshPrint(ctl, " PHYP");
591
#endif
D
Doug Goldstein 已提交
592 593
#ifdef WITH_VBOX
    vshPrint(ctl, " VirtualBox");
594 595 596 597
#endif
#ifdef WITH_ESX
    vshPrint(ctl, " ESX");
#endif
D
Doug Goldstein 已提交
598 599
#ifdef WITH_HYPERV
    vshPrint(ctl, " Hyper-V");
600
#endif
D
Doug Goldstein 已提交
601 602
#ifdef WITH_XENAPI
    vshPrint(ctl, " XenAPI");
603
#endif
604 605 606
#ifdef WITH_BHYVE
    vshPrint(ctl, " Bhyve");
#endif
607 608 609 610 611
#ifdef WITH_TEST
    vshPrint(ctl, " Test");
#endif
    vshPrint(ctl, "\n");

L
Laine Stump 已提交
612
    vshPrint(ctl, "%s", _(" Networking:"));
613 614 615 616 617 618 619 620 621
#ifdef WITH_REMOTE
    vshPrint(ctl, " Remote");
#endif
#ifdef WITH_NETWORK
    vshPrint(ctl, " Network");
#endif
#ifdef WITH_BRIDGE
    vshPrint(ctl, " Bridging");
#endif
622
#if defined(WITH_INTERFACE)
D
Doug Goldstein 已提交
623
    vshPrint(ctl, " Interface");
624 625
# if defined(WITH_NETCF)
    vshPrint(ctl, " netcf");
626
# elif defined(WITH_UDEV)
627
    vshPrint(ctl, " udev");
628
# endif
629 630 631 632 633 634 635 636 637
#endif
#ifdef WITH_NWFILTER
    vshPrint(ctl, " Nwfilter");
#endif
#ifdef WITH_VIRTUALPORT
    vshPrint(ctl, " VirtualPort");
#endif
    vshPrint(ctl, "\n");

L
Laine Stump 已提交
638
    vshPrint(ctl, "%s", _(" Storage:"));
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
#ifdef WITH_STORAGE_DIR
    vshPrint(ctl, " Dir");
#endif
#ifdef WITH_STORAGE_DISK
    vshPrint(ctl, " Disk");
#endif
#ifdef WITH_STORAGE_FS
    vshPrint(ctl, " Filesystem");
#endif
#ifdef WITH_STORAGE_SCSI
    vshPrint(ctl, " SCSI");
#endif
#ifdef WITH_STORAGE_MPATH
    vshPrint(ctl, " Multipath");
#endif
#ifdef WITH_STORAGE_ISCSI
    vshPrint(ctl, " iSCSI");
#endif
#ifdef WITH_STORAGE_LVM
    vshPrint(ctl, " LVM");
659 660 661
#endif
#ifdef WITH_STORAGE_RBD
    vshPrint(ctl, " RBD");
662 663 664
#endif
#ifdef WITH_STORAGE_SHEEPDOG
    vshPrint(ctl, " Sheepdog");
665 666 667
#endif
#ifdef WITH_STORAGE_GLUSTER
    vshPrint(ctl, " Gluster");
668 669 670
#endif
#ifdef WITH_STORAGE_ZFS
    vshPrint(ctl, " ZFS");
671 672 673
#endif
    vshPrint(ctl, "\n");

674
    vshPrint(ctl, "%s", _(" Miscellaneous:"));
675 676 677
#ifdef WITH_LIBVIRTD
    vshPrint(ctl, " Daemon");
#endif
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
#ifdef WITH_NODE_DEVICES
    vshPrint(ctl, " Nodedev");
#endif
#ifdef WITH_SECDRIVER_APPARMOR
    vshPrint(ctl, " AppArmor");
#endif
#ifdef WITH_SECDRIVER_SELINUX
    vshPrint(ctl, " SELinux");
#endif
#ifdef WITH_SECRETS
    vshPrint(ctl, " Secrets");
#endif
#ifdef ENABLE_DEBUG
    vshPrint(ctl, " Debug");
#endif
#ifdef WITH_DTRACE_PROBES
    vshPrint(ctl, " DTrace");
#endif
696
#if WITH_READLINE
697 698 699 700 701 702 703 704 705
    vshPrint(ctl, " Readline");
#endif
#ifdef WITH_DRIVER_MODULES
    vshPrint(ctl, " Modular");
#endif
    vshPrint(ctl, "\n");
}

static bool
706
virshAllowedEscapeChar(char c)
707 708 709 710 711 712 713 714 715 716 717 718
{
    /* Allowed escape characters:
     * a-z A-Z @ [ \ ] ^ _
     */
    return ('a' <= c && c <= 'z') ||
        ('@' <= c && c <= '_');
}

/*
 * argv[]:  virsh [options] [command]
 *
 */
E
Eric Blake 已提交
719
static bool
720
virshParseArgv(vshControl *ctl, int argc, char **argv)
721
{
722
    int arg, len, debug, keepalive;
723
    size_t i;
724
    int longindex = -1;
725
    virshControlPtr priv = ctl->privData;
726
    struct option opt[] = {
727
        {"connect", required_argument, NULL, 'c'},
728
        {"debug", required_argument, NULL, 'd'},
729
        {"escape", required_argument, NULL, 'e'},
730
        {"help", no_argument, NULL, 'h'},
731 732
        {"keepalive-interval", required_argument, NULL, 'k'},
        {"keepalive-count", required_argument, NULL, 'K'},
733
        {"log", required_argument, NULL, 'l'},
734
        {"quiet", no_argument, NULL, 'q'},
735
        {"readonly", no_argument, NULL, 'r'},
736 737 738 739 740 741 742 743
        {"timing", no_argument, NULL, 't'},
        {"version", optional_argument, NULL, 'v'},
        {NULL, 0, NULL, 0}
    };

    /* Standard (non-command) options. The leading + ensures that no
     * argument reordering takes place, so that command options are
     * not confused with top-level virsh options. */
744
    while ((arg = getopt_long(argc, argv, "+:c:d:e:hk:K:l:qrtvV", opt, &longindex)) != -1) {
745
        switch (arg) {
746
        case 'c':
747 748
            VIR_FREE(ctl->connname);
            ctl->connname = vshStrdup(ctl, optarg);
749
            break;
750
        case 'd':
751
            if (virStrToLong_i(optarg, NULL, 10, &debug) < 0) {
752 753
                vshError(ctl, _("option %s takes a numeric argument"),
                         longindex == -1 ? "-d" : "--debug");
754 755
                exit(EXIT_FAILURE);
            }
756 757 758 759 760
            if (debug < VSH_ERR_DEBUG || debug > VSH_ERR_ERROR)
                vshError(ctl, _("ignoring debug level %d out of range [%d-%d]"),
                         debug, VSH_ERR_DEBUG, VSH_ERR_ERROR);
            else
                ctl->debug = debug;
761
            break;
762 763 764 765
        case 'e':
            len = strlen(optarg);

            if ((len == 2 && *optarg == '^' &&
766
                 virshAllowedEscapeChar(optarg[1])) ||
767
                (len == 1 && *optarg != '^')) {
768
                priv->escapeChar = optarg;
769 770 771 772 773 774
            } else {
                vshError(ctl, _("Invalid string '%s' for escape sequence"),
                         optarg);
                exit(EXIT_FAILURE);
            }
            break;
775
        case 'h':
776
            virshUsage();
777 778
            exit(EXIT_SUCCESS);
            break;
779
        case 'k':
E
Erik Skultety 已提交
780 781 782 783 784 785 786 787 788 789
            if (virStrToLong_i(optarg, NULL, 0, &keepalive) < 0) {
                vshError(ctl,
                         _("Invalid value for option %s"),
                         longindex == -1 ? "-k" : "--keepalive-interval");
                exit(EXIT_FAILURE);
            }

            if (keepalive < 0) {
                vshError(ctl,
                         _("option %s requires a positive integer argument"),
790 791 792 793 794 795
                         longindex == -1 ? "-k" : "--keepalive-interval");
                exit(EXIT_FAILURE);
            }
            ctl->keepalive_interval = keepalive;
            break;
        case 'K':
E
Erik Skultety 已提交
796 797 798 799 800 801 802 803 804 805
            if (virStrToLong_i(optarg, NULL, 0, &keepalive) < 0) {
                vshError(ctl,
                         _("Invalid value for option %s"),
                         longindex == -1 ? "-K" : "--keepalive-count");
                exit(EXIT_FAILURE);
            }

            if (keepalive < 0) {
                vshError(ctl,
                         _("option %s requires a positive integer argument"),
806 807 808 809 810
                         longindex == -1 ? "-K" : "--keepalive-count");
                exit(EXIT_FAILURE);
            }
            ctl->keepalive_count = keepalive;
            break;
811 812 813 814 815
        case 'l':
            vshCloseLogFile(ctl);
            ctl->logfile = vshStrdup(ctl, optarg);
            vshOpenLogFile(ctl);
            break;
816 817 818 819 820 821
        case 'q':
            ctl->quiet = true;
            break;
        case 't':
            ctl->timing = true;
            break;
822
        case 'r':
823
            priv->readonly = true;
824 825 826 827 828 829 830 831
            break;
        case 'v':
            if (STRNEQ_NULLABLE(optarg, "long")) {
                puts(VERSION);
                exit(EXIT_SUCCESS);
            }
            /* fall through */
        case 'V':
832
            virshShowVersion(ctl);
833
            exit(EXIT_SUCCESS);
834
        case ':':
835
            for (i = 0; opt[i].name != NULL; i++) {
836 837
                if (opt[i].val == optopt)
                    break;
838
            }
839 840 841 842 843 844
            if (opt[i].name)
                vshError(ctl, _("option '-%c'/'--%s' requires an argument"),
                         optopt, opt[i].name);
            else
                vshError(ctl, _("option '-%c' requires an argument"), optopt);
            exit(EXIT_FAILURE);
845
        case '?':
846 847 848 849
            if (optopt)
                vshError(ctl, _("unsupported option '-%c'. See --help."), optopt);
            else
                vshError(ctl, _("unsupported option '%s'. See --help."), argv[optind - 1]);
850
            exit(EXIT_FAILURE);
851
        default:
852
            vshError(ctl, _("unknown option"));
853 854
            exit(EXIT_FAILURE);
        }
855
        longindex = -1;
856 857
    }

858 859 860
    if (argc == optind) {
        ctl->imode = true;
    } else {
861 862 863 864 865 866 867 868 869 870 871 872 873
        /* parse command */
        ctl->imode = false;
        if (argc - optind == 1) {
            vshDebug(ctl, VSH_ERR_INFO, "commands: \"%s\"\n", argv[optind]);
            return vshCommandStringParse(ctl, argv[optind]);
        } else {
            return vshCommandArgvParse(ctl, argc - optind, argv + optind);
        }
    }
    return true;
}

static const vshCmdDef virshCmds[] = {
874 875 876 877 878 879
    VSH_CMD_CD,
    VSH_CMD_ECHO,
    VSH_CMD_EXIT,
    VSH_CMD_HELP,
    VSH_CMD_PWD,
    VSH_CMD_QUIT,
880 881 882 883 884
    {.name = "connect",
     .handler = cmdConnect,
     .opts = opts_connect,
     .info = info_connect,
     .flags = VSH_CMD_FLAG_NOCONNECT
885 886
    },
    {.name = NULL}
887
};
888

889
static const vshCmdGrp cmdGroups[] = {
890 891 892 893 894 895 896 897 898 899 900 901
    {VIRSH_CMD_GRP_DOM_MANAGEMENT, "domain", domManagementCmds},
    {VIRSH_CMD_GRP_DOM_MONITORING, "monitor", domMonitoringCmds},
    {VIRSH_CMD_GRP_HOST_AND_HV, "host", hostAndHypervisorCmds},
    {VIRSH_CMD_GRP_IFACE, "interface", ifaceCmds},
    {VIRSH_CMD_GRP_NWFILTER, "filter", nwfilterCmds},
    {VIRSH_CMD_GRP_NETWORK, "network", networkCmds},
    {VIRSH_CMD_GRP_NODEDEV, "nodedev", nodedevCmds},
    {VIRSH_CMD_GRP_SECRET, "secret", secretCmds},
    {VIRSH_CMD_GRP_SNAPSHOT, "snapshot", snapshotCmds},
    {VIRSH_CMD_GRP_STORAGE_POOL, "pool", storagePoolCmds},
    {VIRSH_CMD_GRP_STORAGE_VOL, "volume", storageVolCmds},
    {VIRSH_CMD_GRP_VIRSH, "virsh", virshCmds},
902 903
    {NULL, NULL, NULL}
};
K
Karel Zak 已提交
904

905 906 907 908
static const vshClientHooks hooks = {
    .connHandler = virshConnectionHandler
};

909 910 911 912
int
main(int argc, char **argv)
{
    vshControl _ctl, *ctl = &_ctl;
913
    virshControl virshCtl;
E
Eric Blake 已提交
914
    bool ret = true;
K
Karel Zak 已提交
915

916
    memset(ctl, 0, sizeof(vshControl));
917 918
    memset(&virshCtl, 0, sizeof(virshControl));
    ctl->name = "virsh";        /* hardcoded name of the binary */
919
    ctl->log_fd = -1;           /* Initialize log file descriptor */
J
Jiri Denemark 已提交
920
    ctl->debug = VSH_DEBUG_DEFAULT;
921
    ctl->hooks = &hooks;
922 923 924 925 926

    /* In order to distinguish default from setting to 0 */
    ctl->keepalive_interval = -1;
    ctl->keepalive_count = -1;

927 928 929
    ctl->eventPipe[0] = -1;
    ctl->eventPipe[1] = -1;
    ctl->eventTimerId = -1;
930 931 932 933 934 935 936 937
    virshCtl.escapeChar = "^]";     /* Same default as telnet */
    ctl->privData = &virshCtl;

    if (!(progname = strrchr(argv[0], '/')))
        progname = argv[0];
    else
        progname++;
    ctl->progname = progname;
938

939 940
    if (!setlocale(LC_ALL, "")) {
        perror("setlocale");
941
        /* failure to setup locale is not fatal */
942
    }
943
    if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
944
        perror("bindtextdomain");
E
Eric Blake 已提交
945
        return EXIT_FAILURE;
946
    }
947
    if (!textdomain(PACKAGE)) {
948
        perror("textdomain");
E
Eric Blake 已提交
949
        return EXIT_FAILURE;
950 951
    }

952 953 954
    if (isatty(STDIN_FILENO)) {
        ctl->istty = true;

955
#ifndef WIN32
956 957
        if (tcgetattr(STDIN_FILENO, &ctl->termattr) < 0)
            ctl->istty = false;
958
#endif
959 960
    }

961 962 963 964 965
    if (virMutexInit(&ctl->lock) < 0) {
        vshError(ctl, "%s", _("Failed to initialize mutex"));
        return EXIT_FAILURE;
    }

966 967 968 969 970
    if (virInitialize() < 0) {
        vshError(ctl, "%s", _("Failed to initialize libvirt"));
        return EXIT_FAILURE;
    }

971 972
    virFileActivateDirOverride(argv[0]);

973
    if (!vshInit(ctl, cmdGroups, NULL))
974
        exit(EXIT_FAILURE);
975

976 977 978
    if (!virshParseArgv(ctl, argc, argv) ||
        !virshInit(ctl)) {
        virshDeinit(ctl);
K
Karel Zak 已提交
979
        exit(EXIT_FAILURE);
D
Daniel P. Berrange 已提交
980
    }
981

982
    ctl->connname = vshStrdup(ctl, virGetEnvBlockSUID("VIRSH_DEFAULT_CONNECT_URI"));
983

K
Karel Zak 已提交
984
    if (!ctl->imode) {
985
        ret = vshCommandRun(ctl, ctl->cmd);
986
    } else {
K
Karel Zak 已提交
987 988
        /* interactive mode */
        if (!ctl->quiet) {
K
Karel Zak 已提交
989
            vshPrint(ctl,
990
                     _("Welcome to %s, the virtualization interactive terminal.\n\n"),
991
                     progname);
J
Jim Meyering 已提交
992
            vshPrint(ctl, "%s",
993
                     _("Type:  'help' for help with commands\n"
994
                       "       'quit' to quit\n\n"));
K
Karel Zak 已提交
995
        }
996

K
Karel Zak 已提交
997
        do {
998 999
            const char *prompt = virshCtl.readonly ? VIRSH_PROMPT_RO
                : VIRSH_PROMPT_RW;
1000
            ctl->cmdstr =
1001
                vshReadline(ctl, prompt);
1002 1003
            if (ctl->cmdstr == NULL)
                break;          /* EOF */
K
Karel Zak 已提交
1004
            if (*ctl->cmdstr) {
1005
#if WITH_READLINE
K
Karel Zak 已提交
1006
                add_history(ctl->cmdstr);
1007
#endif
1008
                if (vshCommandStringParse(ctl, ctl->cmdstr))
K
Karel Zak 已提交
1009 1010
                    vshCommandRun(ctl, ctl->cmd);
            }
1011
            VIR_FREE(ctl->cmdstr);
1012
        } while (ctl->imode);
K
Karel Zak 已提交
1013

1014 1015
        if (ctl->cmdstr == NULL)
            fputc('\n', stdout);        /* line break after alone prompt */
K
Karel Zak 已提交
1016
    }
1017

1018
    virshDeinit(ctl);
K
Karel Zak 已提交
1019
    exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
1020
}