virsh.c 26.3 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 99 100
virshCatchDisconnect(virConnectPtr conn ATTRIBUTE_UNUSED,
                     int reason,
                     void *opaque ATTRIBUTE_UNUSED)
101 102 103
{
    if (reason != VIR_CONNECT_CLOSE_REASON_CLIENT)
        disconnected++;
104 105
}

106 107 108
/* Main Function which should be used for connecting.
 * This function properly handles keepalive settings. */
virConnectPtr
109
virshConnect(vshControl *ctl, const char *uri, bool readonly)
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
{
    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;
}

146
/*
147
 * virshReconnect:
148
 *
L
Laine Stump 已提交
149
 * Reconnect after a disconnect from libvirtd
150 151
 *
 */
L
Laine Stump 已提交
152
static void
153
virshReconnect(vshControl *ctl)
154 155
{
    bool connected = false;
156
    virshControlPtr priv = ctl->privData;
157

158
    if (priv->conn) {
159
        int ret;
160
        connected = true;
161

162 163
        virConnectUnregisterCloseCallback(priv->conn, virshCatchDisconnect);
        ret = virConnectClose(priv->conn);
164 165 166 167 168
        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"));
169
    }
170

171
    priv->conn = virshConnect(ctl, ctl->connname, priv->readonly);
172

173
    if (!priv->conn) {
174 175 176 177
        if (disconnected)
            vshError(ctl, "%s", _("Failed to reconnect to the hypervisor"));
        else
            vshError(ctl, "%s", _("failed to connect to the hypervisor"));
178
    } else {
179
        if (virConnectRegisterCloseCallback(priv->conn, virshCatchDisconnect,
180 181 182 183 184
                                            NULL, NULL) < 0)
            vshError(ctl, "%s", _("Unable to register disconnect callback"));
        if (connected)
            vshError(ctl, "%s", _("Reconnected to the hypervisor"));
    }
185
    disconnected = 0;
186 187 188
    priv->useGetInfo = false;
    priv->useSnapshotOld = false;
    priv->blockJobNoBytes = false;
189
}
190

191 192 193 194 195 196 197
int virshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED,
                    const char *bytes, size_t nbytes, void *opaque)
{
    int *fd = opaque;

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

199 200 201
/* ---------------
 * Command Connect
 * ---------------
202 203 204 205
 */

static const vshCmdOptDef opts_connect[] = {
    {.name = "name",
206
     .type = VSH_OT_STRING,
207 208 209 210 211 212 213 214 215 216
     .flags = VSH_OFLAG_EMPTY_OK,
     .help = N_("hypervisor connection URI")
    },
    {.name = "readonly",
     .type = VSH_OT_BOOL,
     .help = N_("read-only connection")
    },
    {.name = NULL}
};

217
static const vshCmdInfo info_connect[] = {
218
    {.name = "help",
219
     .data = N_("(re)connect to hypervisor")
220 221
    },
    {.name = "desc",
222 223
     .data = N_("Connect to local hypervisor. This is built-in "
                "command after shell start up.")
224 225
    },
    {.name = NULL}
P
Paolo Bonzini 已提交
226 227
};

E
Eric Blake 已提交
228
static bool
229
cmdConnect(vshControl *ctl, const vshCmd *cmd)
P
Paolo Bonzini 已提交
230
{
231 232 233
    bool ro = vshCommandOptBool(cmd, "readonly");
    const char *name = NULL;
    virshControlPtr priv = ctl->privData;
P
Paolo Bonzini 已提交
234

235 236
    if (priv->conn) {
        int ret;
237

238 239 240 241 242 243 244 245
        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 已提交
246 247
    }

248 249 250
    VIR_FREE(ctl->connname);
    if (vshCommandOptStringReq(ctl, cmd, "name", &name) < 0)
        return false;
251

252
    ctl->connname = vshStrdup(ctl, name);
253

254 255 256 257
    priv->useGetInfo = false;
    priv->useSnapshotOld = false;
    priv->blockJobNoBytes = false;
    priv->readonly = ro;
258

259
    priv->conn = virshConnect(ctl, ctl->connname, priv->readonly);
260

261 262 263 264
    if (!priv->conn) {
        vshError(ctl, "%s", _("Failed to connect to the hypervisor"));
        return false;
    }
265

266 267 268
    if (virConnectRegisterCloseCallback(priv->conn, virshCatchDisconnect,
                                        NULL, NULL) < 0)
        vshError(ctl, "%s", _("Unable to register disconnect callback"));
269

270
    return true;
271 272
}

273 274 275 276
/* ---------------
 * Utils for work with runtime commands data
 * ---------------
 */
277

278 279
static bool
virshConnectionUsability(vshControl *ctl, virConnectPtr conn)
280
{
281 282 283 284
    if (!conn ||
        virConnectIsAlive(conn) == 0) {
        vshError(ctl, "%s", _("no valid connection"));
        return false;
285 286
    }

287 288 289 290
    /* The connection is considered dead only if
     * virConnectIsAlive() successfuly says so.
     */
    vshResetLibvirtError();
291

292
    return true;
293 294
}

295 296
static void *
virshConnectionHandler(vshControl *ctl)
297
{
298
    virshControlPtr priv = ctl->privData;
299

300 301
    if (!priv->conn || disconnected)
        virshReconnect(ctl);
302

303 304 305
    if (virshConnectionUsability(ctl, priv->conn))
        return priv->conn;
    return NULL;
306 307
}

308 309 310
/* ---------------
 * Misc utils
 * ---------------
311
 */
312 313
int
virshDomainState(vshControl *ctl, virDomainPtr dom, int *reason)
314
{
315 316
    virDomainInfo info;
    virshControlPtr priv = ctl->privData;
317

318 319
    if (reason)
        *reason = -1;
320

321 322 323 324 325 326 327 328 329 330
    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;
331 332 333
        }
    }

334 335 336 337 338
    /* fall back to virDomainGetInfo if virDomainGetState is not supported */
    if (virDomainGetInfo(dom, &info) < 0)
        return -1;
    else
        return info.state;
M
Martin Kletzander 已提交
339 340 341 342 343 344
}

/*
 * Initialize connection.
 */
static bool
345
virshInit(vshControl *ctl)
M
Martin Kletzander 已提交
346
{
347 348
    virshControlPtr priv = ctl->privData;

M
Martin Kletzander 已提交
349
    /* Since we have the commandline arguments parsed, we need to
E
Erik Skultety 已提交
350 351 352
     * reload our initial settings to make debugging and readline
     * work properly */
    vshInitReload(ctl);
M
Martin Kletzander 已提交
353

354
    if (priv->conn)
M
Martin Kletzander 已提交
355
        return false;
356

357
    /* set up the library error handler */
358
    virSetErrorFunc(NULL, vshErrorHandler);
359

360
    if (virEventRegisterDefaultImpl() < 0)
E
Eric Blake 已提交
361
        return false;
362

J
Jiri Denemark 已提交
363 364 365 366
    if (virThreadCreate(&ctl->eventLoop, true, vshEventLoop, ctl) < 0)
        return false;
    ctl->eventLoopStarted = true;

367 368 369 370
    if ((ctl->eventTimerId = virEventAddTimeout(-1, vshEventTimeout, ctl,
                                                NULL)) < 0)
        return false;

371 372
    if (ctl->connname) {
        virshReconnect(ctl);
373 374 375 376 377 378
        /* 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).
         */
379
        if (!priv->conn) {
E
Eric Blake 已提交
380
            vshReportError(ctl);
381 382
            return false;
        }
383
    }
K
Karel Zak 已提交
384

E
Eric Blake 已提交
385
    return true;
K
Karel Zak 已提交
386 387
}

388
static void
389
virshDeinitTimer(int timer ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED)
390 391 392 393
{
    /* nothing to be done here */
}

K
Karel Zak 已提交
394
/*
J
Jim Meyering 已提交
395
 * Deinitialize virsh
K
Karel Zak 已提交
396
 */
E
Eric Blake 已提交
397
static bool
398
virshDeinit(vshControl *ctl)
399
{
400 401 402 403 404
    virshControlPtr priv = ctl->privData;

    vshDeinit(ctl);
    VIR_FREE(ctl->connname);
    if (priv->conn) {
405
        int ret;
406 407
        virConnectUnregisterCloseCallback(priv->conn, virshCatchDisconnect);
        ret = virConnectClose(priv->conn);
408 409 410 411 412
        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 已提交
413
    }
D
Daniel P. Berrange 已提交
414 415
    virResetLastError();

J
Jiri Denemark 已提交
416
    if (ctl->eventLoopStarted) {
417 418 419 420
        int timer;

        virMutexLock(&ctl->lock);
        ctl->quit = true;
J
Jiri Denemark 已提交
421
        /* HACK: Add a dummy timeout to break event loop */
422
        timer = virEventAddTimeout(0, virshDeinitTimer, NULL, NULL);
423 424 425 426
        virMutexUnlock(&ctl->lock);

        virThreadJoin(&ctl->eventLoop);

J
Jiri Denemark 已提交
427 428 429
        if (timer != -1)
            virEventRemoveTimeout(timer);

430 431 432
        if (ctl->eventTimerId != -1)
            virEventRemoveTimeout(ctl->eventTimerId);

J
Jiri Denemark 已提交
433 434 435
        ctl->eventLoopStarted = false;
    }

436 437
    virMutexDestroy(&ctl->lock);

E
Eric Blake 已提交
438
    return true;
K
Karel Zak 已提交
439
}
440

K
Karel Zak 已提交
441 442 443
/*
 * Print usage
 */
E
Eric Blake 已提交
444
static void
445
virshUsage(void)
446
{
447
    const vshCmdGrp *grp;
448
    const vshCmdDef *cmd;
449

L
Lai Jiangshan 已提交
450 451
    fprintf(stdout, _("\n%s [options]... [<command_string>]"
                      "\n%s [options]... <command> [args...]\n\n"
452
                      "  options:\n"
453 454
                      "    -c | --connect=URI      hypervisor connection URI\n"
                      "    -d | --debug=NUM        debug level [0-4]\n"
455
                      "    -e | --escape <char>    set escape sequence for console\n"
456
                      "    -h | --help             this help\n"
457 458 459 460
                      "    -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"
461
                      "    -l | --log=FILE         output logging to file\n"
462
                      "    -q | --quiet            quiet mode\n"
463
                      "    -r | --readonly         connect readonly\n"
464
                      "    -t | --timing           print timing information\n"
465 466 467
                      "    -v                      short version\n"
                      "    -V                      long version\n"
                      "         --version[=TYPE]   version, TYPE is short or long (default short)\n"
468 469
                      "  commands (non interactive mode):\n\n"), progname,
            progname);
470

471
    for (grp = cmdGroups; grp->name; grp++) {
E
Eric Blake 已提交
472 473 474 475 476
        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;
477
            fprintf(stdout,
E
Eric Blake 已提交
478 479 480
                    "    %-30s %s\n", cmd->name,
                    _(vshCmddefGetInfo(cmd, "help")));
        }
481 482 483 484 485
        fprintf(stdout, "\n");
    }

    fprintf(stdout, "%s",
            _("\n  (specify help <group> for details about the commands in the group)\n"));
486 487 488
    fprintf(stdout, "%s",
            _("\n  (specify help <command> for details about the command)\n\n"));
    return;
K
Karel Zak 已提交
489 490
}

491 492 493 494
/*
 * Show version and options compiled in
 */
static void
495
virshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
496 497 498 499 500
{
    /* 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 已提交
501 502
    vshPrint(ctl, "%s", _("Compiled with support for:\n"));
    vshPrint(ctl, "%s", _(" Hypervisors:"));
503
#ifdef WITH_QEMU
504
    vshPrint(ctl, " QEMU/KVM");
505
#endif
D
Doug Goldstein 已提交
506 507 508
#ifdef WITH_LXC
    vshPrint(ctl, " LXC");
#endif
509 510 511
#ifdef WITH_UML
    vshPrint(ctl, " UML");
#endif
D
Doug Goldstein 已提交
512 513 514 515 516 517
#ifdef WITH_XEN
    vshPrint(ctl, " Xen");
#endif
#ifdef WITH_LIBXL
    vshPrint(ctl, " LibXL");
#endif
518 519 520
#ifdef WITH_OPENVZ
    vshPrint(ctl, " OpenVZ");
#endif
D
Doug Goldstein 已提交
521 522
#ifdef WITH_VMWARE
    vshPrint(ctl, " VMWare");
523
#endif
D
Doug Goldstein 已提交
524 525
#ifdef WITH_PHYP
    vshPrint(ctl, " PHYP");
526
#endif
D
Doug Goldstein 已提交
527 528
#ifdef WITH_VBOX
    vshPrint(ctl, " VirtualBox");
529 530 531 532
#endif
#ifdef WITH_ESX
    vshPrint(ctl, " ESX");
#endif
D
Doug Goldstein 已提交
533 534
#ifdef WITH_HYPERV
    vshPrint(ctl, " Hyper-V");
535
#endif
D
Doug Goldstein 已提交
536 537
#ifdef WITH_XENAPI
    vshPrint(ctl, " XenAPI");
538
#endif
539 540 541
#ifdef WITH_BHYVE
    vshPrint(ctl, " Bhyve");
#endif
542 543 544 545 546
#ifdef WITH_TEST
    vshPrint(ctl, " Test");
#endif
    vshPrint(ctl, "\n");

L
Laine Stump 已提交
547
    vshPrint(ctl, "%s", _(" Networking:"));
548 549 550 551 552 553 554 555 556
#ifdef WITH_REMOTE
    vshPrint(ctl, " Remote");
#endif
#ifdef WITH_NETWORK
    vshPrint(ctl, " Network");
#endif
#ifdef WITH_BRIDGE
    vshPrint(ctl, " Bridging");
#endif
557
#if defined(WITH_INTERFACE)
D
Doug Goldstein 已提交
558
    vshPrint(ctl, " Interface");
559 560
# if defined(WITH_NETCF)
    vshPrint(ctl, " netcf");
561
# elif defined(WITH_UDEV)
562
    vshPrint(ctl, " udev");
563
# endif
564 565 566 567 568 569 570 571 572
#endif
#ifdef WITH_NWFILTER
    vshPrint(ctl, " Nwfilter");
#endif
#ifdef WITH_VIRTUALPORT
    vshPrint(ctl, " VirtualPort");
#endif
    vshPrint(ctl, "\n");

L
Laine Stump 已提交
573
    vshPrint(ctl, "%s", _(" Storage:"));
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
#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");
594 595 596
#endif
#ifdef WITH_STORAGE_RBD
    vshPrint(ctl, " RBD");
597 598 599
#endif
#ifdef WITH_STORAGE_SHEEPDOG
    vshPrint(ctl, " Sheepdog");
600 601 602
#endif
#ifdef WITH_STORAGE_GLUSTER
    vshPrint(ctl, " Gluster");
603 604 605
#endif
    vshPrint(ctl, "\n");

606
    vshPrint(ctl, "%s", _(" Miscellaneous:"));
607 608 609
#ifdef WITH_LIBVIRTD
    vshPrint(ctl, " Daemon");
#endif
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
#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
628
#if WITH_READLINE
629 630 631 632 633 634 635 636 637
    vshPrint(ctl, " Readline");
#endif
#ifdef WITH_DRIVER_MODULES
    vshPrint(ctl, " Modular");
#endif
    vshPrint(ctl, "\n");
}

static bool
638
virshAllowedEscapeChar(char c)
639 640 641 642 643 644 645 646 647 648 649 650
{
    /* Allowed escape characters:
     * a-z A-Z @ [ \ ] ^ _
     */
    return ('a' <= c && c <= 'z') ||
        ('@' <= c && c <= '_');
}

/*
 * argv[]:  virsh [options] [command]
 *
 */
E
Eric Blake 已提交
651
static bool
652
virshParseArgv(vshControl *ctl, int argc, char **argv)
653
{
654
    int arg, len, debug, keepalive;
655
    size_t i;
656
    int longindex = -1;
657
    virshControlPtr priv = ctl->privData;
658
    struct option opt[] = {
659
        {"connect", required_argument, NULL, 'c'},
660
        {"debug", required_argument, NULL, 'd'},
661
        {"escape", required_argument, NULL, 'e'},
662
        {"help", no_argument, NULL, 'h'},
663 664
        {"keepalive-interval", required_argument, NULL, 'k'},
        {"keepalive-count", required_argument, NULL, 'K'},
665
        {"log", required_argument, NULL, 'l'},
666
        {"quiet", no_argument, NULL, 'q'},
667
        {"readonly", no_argument, NULL, 'r'},
668 669 670 671 672 673 674 675
        {"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. */
676
    while ((arg = getopt_long(argc, argv, "+:c:d:e:hk:K:l:qrtvV", opt, &longindex)) != -1) {
677
        switch (arg) {
678
        case 'c':
679 680
            VIR_FREE(ctl->connname);
            ctl->connname = vshStrdup(ctl, optarg);
681
            break;
682
        case 'd':
683
            if (virStrToLong_i(optarg, NULL, 10, &debug) < 0) {
684 685
                vshError(ctl, _("option %s takes a numeric argument"),
                         longindex == -1 ? "-d" : "--debug");
686 687
                exit(EXIT_FAILURE);
            }
688 689 690 691 692
            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;
693
            break;
694 695 696 697
        case 'e':
            len = strlen(optarg);

            if ((len == 2 && *optarg == '^' &&
698
                 virshAllowedEscapeChar(optarg[1])) ||
699
                (len == 1 && *optarg != '^')) {
700
                priv->escapeChar = optarg;
701 702 703 704 705 706
            } else {
                vshError(ctl, _("Invalid string '%s' for escape sequence"),
                         optarg);
                exit(EXIT_FAILURE);
            }
            break;
707
        case 'h':
708
            virshUsage();
709 710
            exit(EXIT_SUCCESS);
            break;
711
        case 'k':
E
Erik Skultety 已提交
712 713 714 715 716 717 718 719 720 721
            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"),
722 723 724 725 726 727
                         longindex == -1 ? "-k" : "--keepalive-interval");
                exit(EXIT_FAILURE);
            }
            ctl->keepalive_interval = keepalive;
            break;
        case 'K':
E
Erik Skultety 已提交
728 729 730 731 732 733 734 735 736 737
            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"),
738 739 740 741 742
                         longindex == -1 ? "-K" : "--keepalive-count");
                exit(EXIT_FAILURE);
            }
            ctl->keepalive_count = keepalive;
            break;
743 744 745 746 747
        case 'l':
            vshCloseLogFile(ctl);
            ctl->logfile = vshStrdup(ctl, optarg);
            vshOpenLogFile(ctl);
            break;
748 749 750 751 752 753
        case 'q':
            ctl->quiet = true;
            break;
        case 't':
            ctl->timing = true;
            break;
754
        case 'r':
755
            priv->readonly = true;
756 757 758 759 760 761 762 763
            break;
        case 'v':
            if (STRNEQ_NULLABLE(optarg, "long")) {
                puts(VERSION);
                exit(EXIT_SUCCESS);
            }
            /* fall through */
        case 'V':
764
            virshShowVersion(ctl);
765
            exit(EXIT_SUCCESS);
766
        case ':':
767
            for (i = 0; opt[i].name != NULL; i++) {
768 769
                if (opt[i].val == optopt)
                    break;
770
            }
771 772 773 774 775 776
            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);
777
        case '?':
778 779 780 781
            if (optopt)
                vshError(ctl, _("unsupported option '-%c'. See --help."), optopt);
            else
                vshError(ctl, _("unsupported option '%s'. See --help."), argv[optind - 1]);
782
            exit(EXIT_FAILURE);
783
        default:
784
            vshError(ctl, _("unknown option"));
785 786
            exit(EXIT_FAILURE);
        }
787
        longindex = -1;
788 789
    }

790 791 792
    if (argc == optind) {
        ctl->imode = true;
    } else {
793 794 795 796 797 798 799 800 801 802 803 804 805
        /* 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[] = {
806 807 808 809 810 811
    VSH_CMD_CD,
    VSH_CMD_ECHO,
    VSH_CMD_EXIT,
    VSH_CMD_HELP,
    VSH_CMD_PWD,
    VSH_CMD_QUIT,
812 813 814 815 816
    {.name = "connect",
     .handler = cmdConnect,
     .opts = opts_connect,
     .info = info_connect,
     .flags = VSH_CMD_FLAG_NOCONNECT
817 818
    },
    {.name = NULL}
819
};
820

821
static const vshCmdGrp cmdGroups[] = {
822 823 824 825 826 827 828 829 830 831 832 833
    {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},
834 835
    {NULL, NULL, NULL}
};
K
Karel Zak 已提交
836

837 838 839 840
static const vshClientHooks hooks = {
    .connHandler = virshConnectionHandler
};

841 842 843 844
int
main(int argc, char **argv)
{
    vshControl _ctl, *ctl = &_ctl;
845
    virshControl virshCtl;
846
    const char *defaultConn;
E
Eric Blake 已提交
847
    bool ret = true;
K
Karel Zak 已提交
848

849
    memset(ctl, 0, sizeof(vshControl));
850 851
    memset(&virshCtl, 0, sizeof(virshControl));
    ctl->name = "virsh";        /* hardcoded name of the binary */
852
    ctl->log_fd = -1;           /* Initialize log file descriptor */
J
Jiri Denemark 已提交
853
    ctl->debug = VSH_DEBUG_DEFAULT;
854
    ctl->hooks = &hooks;
855 856 857 858 859

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

860 861 862
    ctl->eventPipe[0] = -1;
    ctl->eventPipe[1] = -1;
    ctl->eventTimerId = -1;
863 864 865 866 867 868 869 870
    virshCtl.escapeChar = "^]";     /* Same default as telnet */
    ctl->privData = &virshCtl;

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

872 873
    if (!setlocale(LC_ALL, "")) {
        perror("setlocale");
874
        /* failure to setup locale is not fatal */
875
    }
876
    if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
877
        perror("bindtextdomain");
E
Eric Blake 已提交
878
        return EXIT_FAILURE;
879
    }
880
    if (!textdomain(PACKAGE)) {
881
        perror("textdomain");
E
Eric Blake 已提交
882
        return EXIT_FAILURE;
883 884
    }

885 886 887
    if (isatty(STDIN_FILENO)) {
        ctl->istty = true;

888
#ifndef WIN32
889 890
        if (tcgetattr(STDIN_FILENO, &ctl->termattr) < 0)
            ctl->istty = false;
891
#endif
892 893
    }

894 895 896 897 898
    if (virMutexInit(&ctl->lock) < 0) {
        vshError(ctl, "%s", _("Failed to initialize mutex"));
        return EXIT_FAILURE;
    }

899 900 901 902 903
    if (virInitialize() < 0) {
        vshError(ctl, "%s", _("Failed to initialize libvirt"));
        return EXIT_FAILURE;
    }

904 905
    virFileActivateDirOverride(argv[0]);

906
    if ((defaultConn = virGetEnvBlockSUID("VIRSH_DEFAULT_CONNECT_URI")))
907
        ctl->connname = vshStrdup(ctl, defaultConn);
908

909
    if (!vshInit(ctl, cmdGroups, NULL))
910
        exit(EXIT_FAILURE);
911

912 913 914
    if (!virshParseArgv(ctl, argc, argv) ||
        !virshInit(ctl)) {
        virshDeinit(ctl);
K
Karel Zak 已提交
915
        exit(EXIT_FAILURE);
D
Daniel P. Berrange 已提交
916
    }
917

K
Karel Zak 已提交
918
    if (!ctl->imode) {
919
        ret = vshCommandRun(ctl, ctl->cmd);
920
    } else {
K
Karel Zak 已提交
921 922
        /* interactive mode */
        if (!ctl->quiet) {
K
Karel Zak 已提交
923
            vshPrint(ctl,
924
                     _("Welcome to %s, the virtualization interactive terminal.\n\n"),
925
                     progname);
J
Jim Meyering 已提交
926
            vshPrint(ctl, "%s",
927
                     _("Type:  'help' for help with commands\n"
928
                       "       'quit' to quit\n\n"));
K
Karel Zak 已提交
929
        }
930

K
Karel Zak 已提交
931
        do {
932 933
            const char *prompt = virshCtl.readonly ? VIRSH_PROMPT_RO
                : VIRSH_PROMPT_RW;
934
            ctl->cmdstr =
935
                vshReadline(ctl, prompt);
936 937
            if (ctl->cmdstr == NULL)
                break;          /* EOF */
K
Karel Zak 已提交
938
            if (*ctl->cmdstr) {
939
#if WITH_READLINE
K
Karel Zak 已提交
940
                add_history(ctl->cmdstr);
941
#endif
942
                if (vshCommandStringParse(ctl, ctl->cmdstr))
K
Karel Zak 已提交
943 944
                    vshCommandRun(ctl, ctl->cmd);
            }
945
            VIR_FREE(ctl->cmdstr);
946
        } while (ctl->imode);
K
Karel Zak 已提交
947

948 949
        if (ctl->cmdstr == NULL)
            fputc('\n', stdout);        /* line break after alone prompt */
K
Karel Zak 已提交
950
    }
951

952
    virshDeinit(ctl);
K
Karel Zak 已提交
953
    exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
954
}