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
        vshEventDone(ctl);
134
    }
135 136
}

137 138 139
/* Main Function which should be used for connecting.
 * This function properly handles keepalive settings. */
virConnectPtr
140
virshConnect(vshControl *ctl, const char *uri, bool readonly)
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 176
{
    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;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

301
    return true;
302 303
}

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

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

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

323
    return true;
324 325
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        virThreadJoin(&ctl->eventLoop);

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

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

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

467 468
    virMutexDestroy(&ctl->lock);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

935 936
    virFileActivateDirOverride(argv[0]);

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

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

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

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

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

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

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