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 350 351 352
    /* Since we have the commandline arguments parsed, we need to
     * re-initialize all the debugging to make it work properly */
    vshInitDebug(ctl);

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

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

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

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

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

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

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

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

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

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

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

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

        virThreadJoin(&ctl->eventLoop);

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

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

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

435 436
    virMutexDestroy(&ctl->lock);

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

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

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

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

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

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

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

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

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

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

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

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

    if (argc > optind) {
        /* 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[] = {
803 804 805 806 807 808
    VSH_CMD_CD,
    VSH_CMD_ECHO,
    VSH_CMD_EXIT,
    VSH_CMD_HELP,
    VSH_CMD_PWD,
    VSH_CMD_QUIT,
809 810 811 812 813
    {.name = "connect",
     .handler = cmdConnect,
     .opts = opts_connect,
     .info = info_connect,
     .flags = VSH_CMD_FLAG_NOCONNECT
814 815
    },
    {.name = NULL}
816
};
817

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

834 835 836 837
static const vshClientHooks hooks = {
    .connHandler = virshConnectionHandler
};

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

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

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

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

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

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

883 884 885
    if (isatty(STDIN_FILENO)) {
        ctl->istty = true;

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

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

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

902 903
    virFileActivateDirOverride(argv[0]);

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

907
    if (!vshInit(ctl, cmdGroups, NULL))
908
        exit(EXIT_FAILURE);
909

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

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

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

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

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