virsh.c 27.2 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 127 128 129 130 131
        case VIR_CONNECT_CLOSE_REASON_CLIENT:
        case VIR_CONNECT_CLOSE_REASON_LAST:
            break;
        }
        vshError(ctl, _(str), NULLSTR(uri));

        if (error) {
            virSetError(error);
            virFreeError(error);
        }
132
        disconnected++;
133
    }
134 135
}

136 137 138
/* Main Function which should be used for connecting.
 * This function properly handles keepalive settings. */
virConnectPtr
139
virshConnect(vshControl *ctl, const char *uri, bool readonly)
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
{
    virConnectPtr c = NULL;
    int interval = 5; /* Default */
    int count = 6;    /* Default */
    bool keepalive_forced = false;

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

    c = virConnectOpenAuth(uri, virConnectAuthPtrDefault,
                           readonly ? VIR_CONNECT_RO : 0);
    if (!c)
        return NULL;

    if (interval > 0 &&
        virConnectSetKeepAlive(c, interval, count) != 0) {
        if (keepalive_forced) {
            vshError(ctl, "%s",
                     _("Cannot setup keepalive on connection "
                       "as requested, disconnecting"));
            virConnectClose(c);
            return NULL;
        }
        vshDebug(ctl, VSH_ERR_INFO, "%s",
                 _("Failed to setup keepalive on connection\n"));
    }

    return c;
}

176
/*
177
 * virshReconnect:
178
 *
L
Laine Stump 已提交
179
 * Reconnect after a disconnect from libvirtd
180 181
 *
 */
L
Laine Stump 已提交
182
static void
183
virshReconnect(vshControl *ctl)
184 185
{
    bool connected = false;
186
    virshControlPtr priv = ctl->privData;
187

188
    if (priv->conn) {
189
        int ret;
190
        connected = true;
191

192 193
        virConnectUnregisterCloseCallback(priv->conn, virshCatchDisconnect);
        ret = virConnectClose(priv->conn);
194 195 196 197 198
        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"));
199
    }
200

201
    priv->conn = virshConnect(ctl, ctl->connname, priv->readonly);
202

203
    if (!priv->conn) {
204 205 206 207
        if (disconnected)
            vshError(ctl, "%s", _("Failed to reconnect to the hypervisor"));
        else
            vshError(ctl, "%s", _("failed to connect to the hypervisor"));
208
    } else {
209
        if (virConnectRegisterCloseCallback(priv->conn, virshCatchDisconnect,
210 211 212 213 214
                                            NULL, NULL) < 0)
            vshError(ctl, "%s", _("Unable to register disconnect callback"));
        if (connected)
            vshError(ctl, "%s", _("Reconnected to the hypervisor"));
    }
215
    disconnected = 0;
216 217 218
    priv->useGetInfo = false;
    priv->useSnapshotOld = false;
    priv->blockJobNoBytes = false;
219
}
220

221 222 223 224 225 226 227
int virshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED,
                    const char *bytes, size_t nbytes, void *opaque)
{
    int *fd = opaque;

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

229 230 231
/* ---------------
 * Command Connect
 * ---------------
232 233 234 235
 */

static const vshCmdOptDef opts_connect[] = {
    {.name = "name",
236
     .type = VSH_OT_STRING,
237 238 239 240 241 242 243 244 245 246
     .flags = VSH_OFLAG_EMPTY_OK,
     .help = N_("hypervisor connection URI")
    },
    {.name = "readonly",
     .type = VSH_OT_BOOL,
     .help = N_("read-only connection")
    },
    {.name = NULL}
};

247
static const vshCmdInfo info_connect[] = {
248
    {.name = "help",
249
     .data = N_("(re)connect to hypervisor")
250 251
    },
    {.name = "desc",
252 253
     .data = N_("Connect to local hypervisor. This is built-in "
                "command after shell start up.")
254 255
    },
    {.name = NULL}
P
Paolo Bonzini 已提交
256 257
};

E
Eric Blake 已提交
258
static bool
259
cmdConnect(vshControl *ctl, const vshCmd *cmd)
P
Paolo Bonzini 已提交
260
{
261 262 263
    bool ro = vshCommandOptBool(cmd, "readonly");
    const char *name = NULL;
    virshControlPtr priv = ctl->privData;
P
Paolo Bonzini 已提交
264

265 266
    if (priv->conn) {
        int ret;
267

268 269 270 271 272 273 274 275
        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 已提交
276 277
    }

278
    VIR_FREE(ctl->connname);
279 280
    if (vshCommandOptStringReq(ctl, cmd, "name", &name) < 0)
        return false;
281

282
    ctl->connname = vshStrdup(ctl, name);
283

284 285 286 287
    priv->useGetInfo = false;
    priv->useSnapshotOld = false;
    priv->blockJobNoBytes = false;
    priv->readonly = ro;
288

289
    priv->conn = virshConnect(ctl, ctl->connname, priv->readonly);
290

291 292 293 294
    if (!priv->conn) {
        vshError(ctl, "%s", _("Failed to connect to the hypervisor"));
        return false;
    }
295

296 297 298
    if (virConnectRegisterCloseCallback(priv->conn, virshCatchDisconnect,
                                        NULL, NULL) < 0)
        vshError(ctl, "%s", _("Unable to register disconnect callback"));
299

300
    return true;
301 302
}

303 304 305 306
/* ---------------
 * Utils for work with runtime commands data
 * ---------------
 */
307

308 309
static bool
virshConnectionUsability(vshControl *ctl, virConnectPtr conn)
310
{
311 312 313 314
    if (!conn ||
        virConnectIsAlive(conn) == 0) {
        vshError(ctl, "%s", _("no valid connection"));
        return false;
315 316
    }

317 318 319 320
    /* The connection is considered dead only if
     * virConnectIsAlive() successfuly says so.
     */
    vshResetLibvirtError();
321

322
    return true;
323 324
}

325 326
static void *
virshConnectionHandler(vshControl *ctl)
327
{
328
    virshControlPtr priv = ctl->privData;
329

330 331
    if (!priv->conn || disconnected)
        virshReconnect(ctl);
332

333 334 335
    if (virshConnectionUsability(ctl, priv->conn))
        return priv->conn;
    return NULL;
336 337
}

338 339 340
/* ---------------
 * Misc utils
 * ---------------
341
 */
342 343
int
virshDomainState(vshControl *ctl, virDomainPtr dom, int *reason)
344
{
345 346
    virDomainInfo info;
    virshControlPtr priv = ctl->privData;
347

348 349
    if (reason)
        *reason = -1;
350

351 352 353 354 355 356 357 358 359 360
    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;
361 362 363
        }
    }

364 365 366 367 368
    /* fall back to virDomainGetInfo if virDomainGetState is not supported */
    if (virDomainGetInfo(dom, &info) < 0)
        return -1;
    else
        return info.state;
M
Martin Kletzander 已提交
369 370 371 372 373 374
}

/*
 * Initialize connection.
 */
static bool
375
virshInit(vshControl *ctl)
M
Martin Kletzander 已提交
376
{
377 378
    virshControlPtr priv = ctl->privData;

M
Martin Kletzander 已提交
379
    /* Since we have the commandline arguments parsed, we need to
E
Erik Skultety 已提交
380 381 382
     * reload our initial settings to make debugging and readline
     * work properly */
    vshInitReload(ctl);
M
Martin Kletzander 已提交
383

384
    if (priv->conn)
M
Martin Kletzander 已提交
385
        return false;
386

387
    /* set up the library error handler */
388
    virSetErrorFunc(NULL, vshErrorHandler);
389

390
    if (virEventRegisterDefaultImpl() < 0)
E
Eric Blake 已提交
391
        return false;
392

J
Jiri Denemark 已提交
393 394 395 396
    if (virThreadCreate(&ctl->eventLoop, true, vshEventLoop, ctl) < 0)
        return false;
    ctl->eventLoopStarted = true;

397 398 399 400
    if ((ctl->eventTimerId = virEventAddTimeout(-1, vshEventTimeout, ctl,
                                                NULL)) < 0)
        return false;

401
    if (ctl->connname) {
402
        virshReconnect(ctl);
403 404 405 406 407 408
        /* 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).
         */
409
        if (!priv->conn) {
E
Eric Blake 已提交
410
            vshReportError(ctl);
411 412
            return false;
        }
413
    }
K
Karel Zak 已提交
414

E
Eric Blake 已提交
415
    return true;
K
Karel Zak 已提交
416 417
}

418
static void
419
virshDeinitTimer(int timer ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED)
420 421 422 423
{
    /* nothing to be done here */
}

K
Karel Zak 已提交
424
/*
J
Jim Meyering 已提交
425
 * Deinitialize virsh
K
Karel Zak 已提交
426
 */
E
Eric Blake 已提交
427
static bool
428
virshDeinit(vshControl *ctl)
429
{
430 431 432
    virshControlPtr priv = ctl->privData;

    vshDeinit(ctl);
433
    VIR_FREE(ctl->connname);
434
    if (priv->conn) {
435
        int ret;
436 437
        virConnectUnregisterCloseCallback(priv->conn, virshCatchDisconnect);
        ret = virConnectClose(priv->conn);
438 439 440 441 442
        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 已提交
443
    }
D
Daniel P. Berrange 已提交
444 445
    virResetLastError();

J
Jiri Denemark 已提交
446
    if (ctl->eventLoopStarted) {
447 448 449 450
        int timer;

        virMutexLock(&ctl->lock);
        ctl->quit = true;
J
Jiri Denemark 已提交
451
        /* HACK: Add a dummy timeout to break event loop */
452
        timer = virEventAddTimeout(0, virshDeinitTimer, NULL, NULL);
453 454 455 456
        virMutexUnlock(&ctl->lock);

        virThreadJoin(&ctl->eventLoop);

J
Jiri Denemark 已提交
457 458 459
        if (timer != -1)
            virEventRemoveTimeout(timer);

460 461 462
        if (ctl->eventTimerId != -1)
            virEventRemoveTimeout(ctl->eventTimerId);

J
Jiri Denemark 已提交
463 464 465
        ctl->eventLoopStarted = false;
    }

466 467
    virMutexDestroy(&ctl->lock);

E
Eric Blake 已提交
468
    return true;
K
Karel Zak 已提交
469
}
470

K
Karel Zak 已提交
471 472 473
/*
 * Print usage
 */
E
Eric Blake 已提交
474
static void
475
virshUsage(void)
476
{
477
    const vshCmdGrp *grp;
478
    const vshCmdDef *cmd;
479

L
Lai Jiangshan 已提交
480 481
    fprintf(stdout, _("\n%s [options]... [<command_string>]"
                      "\n%s [options]... <command> [args...]\n\n"
482
                      "  options:\n"
483 484
                      "    -c | --connect=URI      hypervisor connection URI\n"
                      "    -d | --debug=NUM        debug level [0-4]\n"
485
                      "    -e | --escape <char>    set escape sequence for console\n"
486
                      "    -h | --help             this help\n"
487 488 489 490
                      "    -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"
491
                      "    -l | --log=FILE         output logging to file\n"
492
                      "    -q | --quiet            quiet mode\n"
493
                      "    -r | --readonly         connect readonly\n"
494
                      "    -t | --timing           print timing information\n"
495 496 497
                      "    -v                      short version\n"
                      "    -V                      long version\n"
                      "         --version[=TYPE]   version, TYPE is short or long (default short)\n"
498 499
                      "  commands (non interactive mode):\n\n"), progname,
            progname);
500

501
    for (grp = cmdGroups; grp->name; grp++) {
E
Eric Blake 已提交
502 503 504 505 506
        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;
507
            fprintf(stdout,
E
Eric Blake 已提交
508 509 510
                    "    %-30s %s\n", cmd->name,
                    _(vshCmddefGetInfo(cmd, "help")));
        }
511 512 513 514 515
        fprintf(stdout, "\n");
    }

    fprintf(stdout, "%s",
            _("\n  (specify help <group> for details about the commands in the group)\n"));
516 517 518
    fprintf(stdout, "%s",
            _("\n  (specify help <command> for details about the command)\n\n"));
    return;
K
Karel Zak 已提交
519 520
}

521 522 523 524
/*
 * Show version and options compiled in
 */
static void
525
virshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
526 527 528 529 530
{
    /* 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 已提交
531 532
    vshPrint(ctl, "%s", _("Compiled with support for:\n"));
    vshPrint(ctl, "%s", _(" Hypervisors:"));
533
#ifdef WITH_QEMU
534
    vshPrint(ctl, " QEMU/KVM");
535
#endif
D
Doug Goldstein 已提交
536 537 538
#ifdef WITH_LXC
    vshPrint(ctl, " LXC");
#endif
539 540 541
#ifdef WITH_UML
    vshPrint(ctl, " UML");
#endif
D
Doug Goldstein 已提交
542 543 544 545 546 547
#ifdef WITH_XEN
    vshPrint(ctl, " Xen");
#endif
#ifdef WITH_LIBXL
    vshPrint(ctl, " LibXL");
#endif
548 549 550
#ifdef WITH_OPENVZ
    vshPrint(ctl, " OpenVZ");
#endif
D
Doug Goldstein 已提交
551 552
#ifdef WITH_VMWARE
    vshPrint(ctl, " VMWare");
553
#endif
D
Doug Goldstein 已提交
554 555
#ifdef WITH_PHYP
    vshPrint(ctl, " PHYP");
556
#endif
D
Doug Goldstein 已提交
557 558
#ifdef WITH_VBOX
    vshPrint(ctl, " VirtualBox");
559 560 561 562
#endif
#ifdef WITH_ESX
    vshPrint(ctl, " ESX");
#endif
D
Doug Goldstein 已提交
563 564
#ifdef WITH_HYPERV
    vshPrint(ctl, " Hyper-V");
565
#endif
D
Doug Goldstein 已提交
566 567
#ifdef WITH_XENAPI
    vshPrint(ctl, " XenAPI");
568
#endif
569 570 571
#ifdef WITH_BHYVE
    vshPrint(ctl, " Bhyve");
#endif
572 573 574 575 576
#ifdef WITH_TEST
    vshPrint(ctl, " Test");
#endif
    vshPrint(ctl, "\n");

L
Laine Stump 已提交
577
    vshPrint(ctl, "%s", _(" Networking:"));
578 579 580 581 582 583 584 585 586
#ifdef WITH_REMOTE
    vshPrint(ctl, " Remote");
#endif
#ifdef WITH_NETWORK
    vshPrint(ctl, " Network");
#endif
#ifdef WITH_BRIDGE
    vshPrint(ctl, " Bridging");
#endif
587
#if defined(WITH_INTERFACE)
D
Doug Goldstein 已提交
588
    vshPrint(ctl, " Interface");
589 590
# if defined(WITH_NETCF)
    vshPrint(ctl, " netcf");
591
# elif defined(WITH_UDEV)
592
    vshPrint(ctl, " udev");
593
# endif
594 595 596 597 598 599 600 601 602
#endif
#ifdef WITH_NWFILTER
    vshPrint(ctl, " Nwfilter");
#endif
#ifdef WITH_VIRTUALPORT
    vshPrint(ctl, " VirtualPort");
#endif
    vshPrint(ctl, "\n");

L
Laine Stump 已提交
603
    vshPrint(ctl, "%s", _(" Storage:"));
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
#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");
624 625 626
#endif
#ifdef WITH_STORAGE_RBD
    vshPrint(ctl, " RBD");
627 628 629
#endif
#ifdef WITH_STORAGE_SHEEPDOG
    vshPrint(ctl, " Sheepdog");
630 631 632
#endif
#ifdef WITH_STORAGE_GLUSTER
    vshPrint(ctl, " Gluster");
633 634 635
#endif
    vshPrint(ctl, "\n");

636
    vshPrint(ctl, "%s", _(" Miscellaneous:"));
637 638 639
#ifdef WITH_LIBVIRTD
    vshPrint(ctl, " Daemon");
#endif
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
#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
658
#if WITH_READLINE
659 660 661 662 663 664 665 666 667
    vshPrint(ctl, " Readline");
#endif
#ifdef WITH_DRIVER_MODULES
    vshPrint(ctl, " Modular");
#endif
    vshPrint(ctl, "\n");
}

static bool
668
virshAllowedEscapeChar(char c)
669 670 671 672 673 674 675 676 677 678 679 680
{
    /* Allowed escape characters:
     * a-z A-Z @ [ \ ] ^ _
     */
    return ('a' <= c && c <= 'z') ||
        ('@' <= c && c <= '_');
}

/*
 * argv[]:  virsh [options] [command]
 *
 */
E
Eric Blake 已提交
681
static bool
682
virshParseArgv(vshControl *ctl, int argc, char **argv)
683
{
684
    int arg, len, debug, keepalive;
685
    size_t i;
686
    int longindex = -1;
687
    virshControlPtr priv = ctl->privData;
688
    struct option opt[] = {
689
        {"connect", required_argument, NULL, 'c'},
690
        {"debug", required_argument, NULL, 'd'},
691
        {"escape", required_argument, NULL, 'e'},
692
        {"help", no_argument, NULL, 'h'},
693 694
        {"keepalive-interval", required_argument, NULL, 'k'},
        {"keepalive-count", required_argument, NULL, 'K'},
695
        {"log", required_argument, NULL, 'l'},
696
        {"quiet", no_argument, NULL, 'q'},
697
        {"readonly", no_argument, NULL, 'r'},
698 699 700 701 702 703 704 705
        {"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. */
706
    while ((arg = getopt_long(argc, argv, "+:c:d:e:hk:K:l:qrtvV", opt, &longindex)) != -1) {
707
        switch (arg) {
708
        case 'c':
709 710
            VIR_FREE(ctl->connname);
            ctl->connname = vshStrdup(ctl, optarg);
711
            break;
712
        case 'd':
713
            if (virStrToLong_i(optarg, NULL, 10, &debug) < 0) {
714 715
                vshError(ctl, _("option %s takes a numeric argument"),
                         longindex == -1 ? "-d" : "--debug");
716 717
                exit(EXIT_FAILURE);
            }
718 719 720 721 722
            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;
723
            break;
724 725 726 727
        case 'e':
            len = strlen(optarg);

            if ((len == 2 && *optarg == '^' &&
728
                 virshAllowedEscapeChar(optarg[1])) ||
729
                (len == 1 && *optarg != '^')) {
730
                priv->escapeChar = optarg;
731 732 733 734 735 736
            } else {
                vshError(ctl, _("Invalid string '%s' for escape sequence"),
                         optarg);
                exit(EXIT_FAILURE);
            }
            break;
737
        case 'h':
738
            virshUsage();
739 740
            exit(EXIT_SUCCESS);
            break;
741
        case 'k':
E
Erik Skultety 已提交
742 743 744 745 746 747 748 749 750 751
            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"),
752 753 754 755 756 757
                         longindex == -1 ? "-k" : "--keepalive-interval");
                exit(EXIT_FAILURE);
            }
            ctl->keepalive_interval = keepalive;
            break;
        case 'K':
E
Erik Skultety 已提交
758 759 760 761 762 763 764 765 766 767
            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"),
768 769 770 771 772
                         longindex == -1 ? "-K" : "--keepalive-count");
                exit(EXIT_FAILURE);
            }
            ctl->keepalive_count = keepalive;
            break;
773 774 775 776 777
        case 'l':
            vshCloseLogFile(ctl);
            ctl->logfile = vshStrdup(ctl, optarg);
            vshOpenLogFile(ctl);
            break;
778 779 780 781 782 783
        case 'q':
            ctl->quiet = true;
            break;
        case 't':
            ctl->timing = true;
            break;
784
        case 'r':
785
            priv->readonly = true;
786 787 788 789 790 791 792 793
            break;
        case 'v':
            if (STRNEQ_NULLABLE(optarg, "long")) {
                puts(VERSION);
                exit(EXIT_SUCCESS);
            }
            /* fall through */
        case 'V':
794
            virshShowVersion(ctl);
795
            exit(EXIT_SUCCESS);
796
        case ':':
797
            for (i = 0; opt[i].name != NULL; i++) {
798 799
                if (opt[i].val == optopt)
                    break;
800
            }
801 802 803 804 805 806
            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);
807
        case '?':
808 809 810 811
            if (optopt)
                vshError(ctl, _("unsupported option '-%c'. See --help."), optopt);
            else
                vshError(ctl, _("unsupported option '%s'. See --help."), argv[optind - 1]);
812
            exit(EXIT_FAILURE);
813
        default:
814
            vshError(ctl, _("unknown option"));
815 816
            exit(EXIT_FAILURE);
        }
817
        longindex = -1;
818 819
    }

820 821 822
    if (argc == optind) {
        ctl->imode = true;
    } else {
823 824 825 826 827 828 829 830 831 832 833 834 835
        /* 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[] = {
836 837 838 839 840 841
    VSH_CMD_CD,
    VSH_CMD_ECHO,
    VSH_CMD_EXIT,
    VSH_CMD_HELP,
    VSH_CMD_PWD,
    VSH_CMD_QUIT,
842 843 844 845 846
    {.name = "connect",
     .handler = cmdConnect,
     .opts = opts_connect,
     .info = info_connect,
     .flags = VSH_CMD_FLAG_NOCONNECT
847 848
    },
    {.name = NULL}
849
};
850

851
static const vshCmdGrp cmdGroups[] = {
852 853 854 855 856 857 858 859 860 861 862 863
    {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},
864 865
    {NULL, NULL, NULL}
};
K
Karel Zak 已提交
866

867 868 869 870
static const vshClientHooks hooks = {
    .connHandler = virshConnectionHandler
};

871 872 873 874
int
main(int argc, char **argv)
{
    vshControl _ctl, *ctl = &_ctl;
875
    virshControl virshCtl;
876
    const char *defaultConn;
E
Eric Blake 已提交
877
    bool ret = true;
K
Karel Zak 已提交
878

879
    memset(ctl, 0, sizeof(vshControl));
880 881
    memset(&virshCtl, 0, sizeof(virshControl));
    ctl->name = "virsh";        /* hardcoded name of the binary */
882
    ctl->log_fd = -1;           /* Initialize log file descriptor */
J
Jiri Denemark 已提交
883
    ctl->debug = VSH_DEBUG_DEFAULT;
884
    ctl->hooks = &hooks;
885 886 887 888 889

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

890 891 892
    ctl->eventPipe[0] = -1;
    ctl->eventPipe[1] = -1;
    ctl->eventTimerId = -1;
893 894 895 896 897 898 899 900
    virshCtl.escapeChar = "^]";     /* Same default as telnet */
    ctl->privData = &virshCtl;

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

902 903
    if (!setlocale(LC_ALL, "")) {
        perror("setlocale");
904
        /* failure to setup locale is not fatal */
905
    }
906
    if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
907
        perror("bindtextdomain");
E
Eric Blake 已提交
908
        return EXIT_FAILURE;
909
    }
910
    if (!textdomain(PACKAGE)) {
911
        perror("textdomain");
E
Eric Blake 已提交
912
        return EXIT_FAILURE;
913 914
    }

915 916 917
    if (isatty(STDIN_FILENO)) {
        ctl->istty = true;

918
#ifndef WIN32
919 920
        if (tcgetattr(STDIN_FILENO, &ctl->termattr) < 0)
            ctl->istty = false;
921
#endif
922 923
    }

924 925 926 927 928
    if (virMutexInit(&ctl->lock) < 0) {
        vshError(ctl, "%s", _("Failed to initialize mutex"));
        return EXIT_FAILURE;
    }

929 930 931 932 933
    if (virInitialize() < 0) {
        vshError(ctl, "%s", _("Failed to initialize libvirt"));
        return EXIT_FAILURE;
    }

934 935
    virFileActivateDirOverride(argv[0]);

936
    if ((defaultConn = virGetEnvBlockSUID("VIRSH_DEFAULT_CONNECT_URI")))
937
        ctl->connname = vshStrdup(ctl, defaultConn);
938

939
    if (!vshInit(ctl, cmdGroups, NULL))
940
        exit(EXIT_FAILURE);
941

942 943 944
    if (!virshParseArgv(ctl, argc, argv) ||
        !virshInit(ctl)) {
        virshDeinit(ctl);
K
Karel Zak 已提交
945
        exit(EXIT_FAILURE);
D
Daniel P. Berrange 已提交
946
    }
947

K
Karel Zak 已提交
948
    if (!ctl->imode) {
949
        ret = vshCommandRun(ctl, ctl->cmd);
950
    } else {
K
Karel Zak 已提交
951 952
        /* interactive mode */
        if (!ctl->quiet) {
K
Karel Zak 已提交
953
            vshPrint(ctl,
954
                     _("Welcome to %s, the virtualization interactive terminal.\n\n"),
955
                     progname);
J
Jim Meyering 已提交
956
            vshPrint(ctl, "%s",
957
                     _("Type:  'help' for help with commands\n"
958
                       "       'quit' to quit\n\n"));
K
Karel Zak 已提交
959
        }
960

K
Karel Zak 已提交
961
        do {
962 963
            const char *prompt = virshCtl.readonly ? VIRSH_PROMPT_RO
                : VIRSH_PROMPT_RW;
964
            ctl->cmdstr =
965
                vshReadline(ctl, prompt);
966 967
            if (ctl->cmdstr == NULL)
                break;          /* EOF */
K
Karel Zak 已提交
968
            if (*ctl->cmdstr) {
969
#if WITH_READLINE
K
Karel Zak 已提交
970
                add_history(ctl->cmdstr);
971
#endif
972
                if (vshCommandStringParse(ctl, ctl->cmdstr))
K
Karel Zak 已提交
973 974
                    vshCommandRun(ctl, ctl->cmd);
            }
975
            VIR_FREE(ctl->cmdstr);
976
        } while (ctl->imode);
K
Karel Zak 已提交
977

978 979
        if (ctl->cmdstr == NULL)
            fputc('\n', stdout);        /* line break after alone prompt */
K
Karel Zak 已提交
980
    }
981

982
    virshDeinit(ctl);
K
Karel Zak 已提交
983
    exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
984
}