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
#ifdef WITH_VMWARE
J
Ján Tomko 已提交
553
    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
#ifdef WITH_STORAGE_ZFS
    vshPrint(ctl, " ZFS");
637 638 639
#endif
    vshPrint(ctl, "\n");

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

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

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

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

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

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

871 872 873 874
static const vshClientHooks hooks = {
    .connHandler = virshConnectionHandler
};

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

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

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

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

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

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

919 920 921
    if (isatty(STDIN_FILENO)) {
        ctl->istty = true;

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

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

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

938 939
    virFileActivateDirOverride(argv[0]);

940
    if ((defaultConn = virGetEnvBlockSUID("VIRSH_DEFAULT_CONNECT_URI")))
941
        ctl->connname = vshStrdup(ctl, defaultConn);
942

943
    if (!vshInit(ctl, cmdGroups, NULL))
944
        exit(EXIT_FAILURE);
945

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

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

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

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

986
    virshDeinit(ctl);
K
Karel Zak 已提交
987
    exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
988
}