libvirt/tools/virsh.c

2946 lines
76 KiB
C
Raw Normal View History

/*
* virsh.c: a shell to exercise the libvirt API
*
* Copyright (C) 2005, 2007-2012 Red Hat, Inc.
*
* 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
* License along with this library; If not, see
* <http://www.gnu.org/licenses/>.
*
* Daniel Veillard <veillard@redhat.com>
2005-12-08 14:22:52 +00:00
* Karel Zak <kzak@redhat.com>
2006-05-29 15:39:31 +00:00
* Daniel P. Berrange <berrange@redhat.com>
*/
#include <config.h>
#include "virsh.h"
#include <stdio.h>
2005-12-08 10:23:34 +00:00
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
2005-12-08 10:23:34 +00:00
#include <getopt.h>
2005-12-08 14:22:52 +00:00
#include <sys/time.h>
#include "c-ctype.h"
#include <fcntl.h>
#include <locale.h>
#include <time.h>
#include <limits.h>
#include <assert.h>
#include <sys/stat.h>
#include <inttypes.h>
#include <strings.h>
#include <termios.h>
2005-12-08 10:23:34 +00:00
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xmlsave.h>
#ifdef HAVE_READLINE_READLINE_H
# include <readline/readline.h>
# include <readline/history.h>
#endif
2005-12-08 10:23:34 +00:00
#include "internal.h"
#include "virterror_internal.h"
#include "base64.h"
#include "buf.h"
#include "console.h"
2008-01-21 15:27:14 +00:00
#include "util.h"
#include "memory.h"
#include "xml.h"
#include "libvirt/libvirt-qemu.h"
#include "virfile.h"
#include "event_poll.h"
maint: use gnulib configmake rather than open-coding things * bootstrap.conf (gnulib_modules): Add configmake. * daemon/Makefile.am (libvirtd_CFLAGS): Drop defines provided by gnulib. * src/Makefile.am (INCLUDES): Likewise. * tests/Makefile.am (INCLUDES): Likewise. * tools/Makefile.am (virsh_CFLAGS): Likewise. * daemon/libvirtd.c (qemudInitPaths, usage, main): Update clients. * src/cpu/cpu_map.c (CPUMAPFILE): Likewise. * src/driver.c (DEFAULT_DRIVER_DIR): Likewise. * src/internal.h (_): Likewise. * src/libvirt.c (virInitialize): Likewise. * src/lxc/lxc_conf.h (LXC_CONFIG_DIR, LXC_STATE_DIR, LXC_LOG_DIR): Likewise. * src/lxc/lxc_conf.c (lxcCapsInit, lxcLoadDriverConfig): Likewise. * src/network/bridge_driver.c (NETWORK_PID_DIR) (NETWORK_STATE_DIR, DNSMASQ_STATE_DIR, networkStartup): Likewise. * src/nwfilter/nwfilter_driver.c (nwfilterDriverStartup): Likewise. * src/qemu/qemu_conf.c (qemudLoadDriverConfig): Likewise. * src/qemu/qemu_driver.c (qemudStartup): Likewise. * src/remote/remote_driver.h (LIBVIRTD_PRIV_UNIX_SOCKET) (LIBVIRTD_PRIV_UNIX_SOCKET_RO, LIBVIRTD_CONFIGURATION_FILE) (LIBVIRT_PKI_DIR): Likewise. * src/secret/secret_driver.c (secretDriverStartup): Likewise. * src/security/security_apparmor.c (VIRT_AA_HELPER): Likewise. * src/security/virt-aa-helper.c (main): Likewise. * src/storage/storage_backend_disk.c (PARTHELPER): Likewise. * src/storage/storage_driver.c (storageDriverStartup): Likewise. * src/uml/uml_driver.c (TEMPDIR, umlStartup): Likewise. * src/util/hooks.c (LIBVIRT_HOOK_DIR): Likewise. * tools/virsh.c (main): Likewise. * docs/hooks.html.in: Likewise.
2010-11-16 14:54:17 +00:00
#include "configmake.h"
#include "threads.h"
#include "command.h"
#include "virkeycode.h"
#include "virnetdevbandwidth.h"
#include "util/bitmap.h"
#include "conf/domain_conf.h"
#include "virtypedparam.h"
2005-12-08 10:23:34 +00:00
#include "virsh-domain.h"
#include "virsh-domain-monitor.h"
#include "virsh-host.h"
#include "virsh-interface.h"
#include "virsh-network.h"
#include "virsh-nodedev.h"
#include "virsh-nwfilter.h"
#include "virsh-pool.h"
#include "virsh-secret.h"
2005-12-08 10:23:34 +00:00
static char *progname;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
static const vshCmdGrp cmdGroups[];
2005-12-08 10:23:34 +00:00
/* Bypass header poison */
#undef strdup
void *
_vshMalloc(vshControl *ctl, size_t size, const char *filename, int line)
{
char *x;
if (VIR_ALLOC_N(x, size) == 0)
return x;
vshError(ctl, _("%s: %d: failed to allocate %d bytes"),
filename, line, (int) size);
exit(EXIT_FAILURE);
}
void *
_vshCalloc(vshControl *ctl, size_t nmemb, size_t size, const char *filename,
int line)
{
char *x;
if (!xalloc_oversized(nmemb, size) &&
VIR_ALLOC_N(x, nmemb * size) == 0)
return x;
vshError(ctl, _("%s: %d: failed to allocate %d bytes"),
filename, line, (int) (size*nmemb));
exit(EXIT_FAILURE);
}
char *
_vshStrdup(vshControl *ctl, const char *s, const char *filename, int line)
{
char *x;
if (s == NULL)
return NULL;
if ((x = strdup(s)))
return x;
vshError(ctl, _("%s: %d: failed to allocate %lu bytes"),
filename, line, (unsigned long)strlen(s));
exit(EXIT_FAILURE);
}
/* Poison the raw allocating identifiers in favor of our vsh variants. */
#define strdup use_vshStrdup_instead_of_strdup
int
vshNameSorter(const void *a, const void *b)
{
const char **sa = (const char**)a;
const char **sb = (const char**)b;
return vshStrcasecmp(*sa, *sb);
}
double
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshPrettyCapacity(unsigned long long val, const char **unit)
{
if (val < 1024) {
*unit = "";
return (double)val;
} else if (val < (1024.0l * 1024.0l)) {
*unit = "KiB";
return (((double)val / 1024.0l));
} else if (val < (1024.0l * 1024.0l * 1024.0l)) {
*unit = "MiB";
return (double)val / (1024.0l * 1024.0l);
} else if (val < (1024.0l * 1024.0l * 1024.0l * 1024.0l)) {
*unit = "GiB";
return (double)val / (1024.0l * 1024.0l * 1024.0l);
} else {
*unit = "TiB";
return (double)val / (1024.0l * 1024.0l * 1024.0l * 1024.0l);
}
}
virErrorPtr last_error;
2009-02-09 14:24:06 +00:00
/*
* Quieten libvirt until we're done with the command.
*/
static void
virshErrorHandler(void *unused ATTRIBUTE_UNUSED, virErrorPtr error)
{
virFreeError(last_error);
last_error = virSaveLastError();
if (getenv("VIRSH_DEBUG") != NULL)
virDefaultErrorFunc(error);
}
/*
* Reset libvirt error on graceful fallback paths
*/
void
vshResetLibvirtError(void)
{
virFreeError(last_error);
last_error = NULL;
}
2009-02-09 14:24:06 +00:00
/*
* Report an error when a command finishes. This is better than before
* (when correct operation would report errors), but it has some
* problems: we lose the smarter formatting of virDefaultErrorFunc(),
* and it can become harder to debug problems, if errors get reported
* twice during one command. This case shouldn't really happen anyway,
* and it's IMHO a bug that libvirt does that sometimes.
*/
void
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshReportError(vshControl *ctl)
2009-02-09 14:24:06 +00:00
{
if (last_error == NULL) {
/* Calling directly into libvirt util functions won't trigger the
* error callback (which sets last_error), so check it ourselves.
*
* If the returned error has CODE_OK, this most likely means that
* no error was ever raised, so just ignore */
last_error = virSaveLastError();
if (!last_error || last_error->code == VIR_ERR_OK)
goto out;
}
2009-02-09 14:24:06 +00:00
if (last_error->code == VIR_ERR_OK) {
vshError(ctl, "%s", _("unknown error"));
2009-02-09 14:24:06 +00:00
goto out;
}
vshError(ctl, "%s", last_error->message);
2009-02-09 14:24:06 +00:00
out:
vshResetLibvirtError();
2009-02-09 14:24:06 +00:00
}
/*
* Detection of disconnections and automatic reconnection support
*/
static int disconnected = 0; /* we may have been disconnected */
/*
* vshCatchDisconnect:
*
* We get here when the connection was closed. We can't do much in the
* handler, just save the fact it was raised.
*/
static void
vshCatchDisconnect(virConnectPtr conn ATTRIBUTE_UNUSED,
int reason,
void *opaque ATTRIBUTE_UNUSED)
{
if (reason != VIR_CONNECT_CLOSE_REASON_CLIENT)
disconnected++;
}
/*
* vshReconnect:
*
* Reconnect after a disconnect from libvirtd
*
*/
static void
vshReconnect(vshControl *ctl)
{
bool connected = false;
if (ctl->conn != NULL) {
connected = true;
virConnectClose(ctl->conn);
}
ctl->conn = virConnectOpenAuth(ctl->name,
virConnectAuthPtrDefault,
ctl->readonly ? VIR_CONNECT_RO : 0);
if (!ctl->conn) {
vshError(ctl, "%s", _("Failed to reconnect to the hypervisor"));
} else {
if (virConnectRegisterCloseCallback(ctl->conn, vshCatchDisconnect,
NULL, NULL) < 0)
vshError(ctl, "%s", _("Unable to register disconnect callback"));
if (connected)
vshError(ctl, "%s", _("Reconnected to the hypervisor"));
}
disconnected = 0;
ctl->useGetInfo = false;
ctl->useSnapshotOld = false;
}
#ifndef WIN32
static void
vshPrintRaw(vshControl *ctl, ...)
{
va_list ap;
char *key;
va_start(ap, ctl);
while ((key = va_arg(ap, char *)) != NULL) {
vshPrint(ctl, "%s\r\n", key);
}
va_end(ap);
}
/**
* vshAskReedit:
* @msg: Question to ask user
*
* Ask user if he wants to return to previously
* edited file.
*
* Returns 'y' if he wants to
* 'f' if he forcibly wants to
* 'n' if he doesn't want to
* -1 on error
* 0 otherwise
*/
int
vshAskReedit(vshControl *ctl, const char *msg)
{
int c = -1;
struct termios ttyattr;
if (!isatty(STDIN_FILENO))
return -1;
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshReportError(ctl);
if (vshMakeStdinRaw(&ttyattr, false) < 0)
return -1;
while (true) {
/* TRANSLATORS: For now, we aren't using LC_MESSAGES, and the user
* choices really are limited to just 'y', 'n', 'f' and '?' */
vshPrint(ctl, "\r%s %s", msg, _("Try again? [y,n,f,?]:"));
c = c_tolower(getchar());
if (c == '?') {
vshPrintRaw(ctl,
"",
_("y - yes, start editor again"),
_("n - no, throw away my changes"),
_("f - force, try to redefine again"),
_("? - print this help"),
NULL);
continue;
} else if (c == 'y' || c == 'n' || c == 'f') {
break;
}
}
tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttyattr);
vshPrint(ctl, "\r\n");
return c;
}
#else /* WIN32 */
int
vshAskReedit(vshControl *ctl, const char *msg ATTRIBUTE_UNUSED)
{
vshDebug(ctl, VSH_ERR_WARNING, "%s", _("This function is not "
"supported on WIN32 platform"));
return 0;
}
#endif /* WIN32 */
int vshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED,
const char *bytes, size_t nbytes, void *opaque)
{
int *fd = opaque;
return safewrite(*fd, bytes, nbytes);
}
2005-12-08 10:23:34 +00:00
/* ---------------
* Commands
* ---------------
*/
/*
* "help" command
2005-12-08 10:23:34 +00:00
*/
static const vshCmdInfo info_help[] = {
{"help", N_("print help")},
{"desc", N_("Prints global help, command specific help, or help for a\n"
" group of related commands")},
{NULL, NULL}
2005-12-08 10:23:34 +00:00
};
static const vshCmdOptDef opts_help[] = {
{"command", VSH_OT_DATA, 0, N_("Prints global help, command specific help, or help for a group of related commands")},
{NULL, 0, 0, NULL}
2005-12-08 10:23:34 +00:00
};
static bool
2008-08-01 13:51:18 +00:00
cmdHelp(vshControl *ctl, const vshCmd *cmd)
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
{
const char *name = NULL;
if (vshCommandOptString(cmd, "command", &name) <= 0) {
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
const vshCmdGrp *grp;
const vshCmdDef *def;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
vshPrint(ctl, "%s", _("Grouped commands:\n\n"));
for (grp = cmdGroups; grp->name; grp++) {
vshPrint(ctl, _(" %s (help keyword '%s'):\n"), grp->name,
grp->keyword);
for (def = grp->commands; def->name; def++) {
if (def->flags & VSH_CMD_FLAG_ALIAS)
continue;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
vshPrint(ctl, " %-30s %s\n", def->name,
_(vshCmddefGetInfo(def, "help")));
}
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
vshPrint(ctl, "\n");
}
return true;
}
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
if (vshCmddefSearch(name)) {
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
return vshCmddefHelp(ctl, name);
} else if (vshCmdGrpSearch(name)) {
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
return vshCmdGrpHelp(ctl, name);
} else {
vshError(ctl, _("command or command group '%s' doesn't exist"), name);
return false;
2005-12-08 10:23:34 +00:00
}
}
/* Tree listing helpers. */
static int
vshTreePrintInternal(vshControl *ctl,
vshTreeLookup lookup,
void *opaque,
int num_devices,
int devid,
int lastdev,
bool root,
virBufferPtr indent)
{
int i;
int nextlastdev = -1;
int ret = -1;
const char *dev = (lookup)(devid, false, opaque);
if (virBufferError(indent))
goto cleanup;
/* Print this device, with indent if not at root */
vshPrint(ctl, "%s%s%s\n", virBufferCurrentContent(indent),
root ? "" : "+- ", dev);
/* Update indent to show '|' or ' ' for child devices */
if (!root) {
virBufferAddChar(indent, devid == lastdev ? ' ' : '|');
virBufferAddChar(indent, ' ');
if (virBufferError(indent))
goto cleanup;
}
/* Determine the index of the last child device */
for (i = 0 ; i < num_devices ; i++) {
const char *parent = (lookup)(i, true, opaque);
if (parent && STREQ(parent, dev))
nextlastdev = i;
}
/* If there is a child device, then print another blank line */
if (nextlastdev != -1)
vshPrint(ctl, "%s |\n", virBufferCurrentContent(indent));
/* Finally print all children */
virBufferAddLit(indent, " ");
for (i = 0 ; i < num_devices ; i++) {
const char *parent = (lookup)(i, true, opaque);
if (parent && STREQ(parent, dev) &&
vshTreePrintInternal(ctl, lookup, opaque,
num_devices, i, nextlastdev,
false, indent) < 0)
goto cleanup;
}
virBufferTrim(indent, " ", -1);
/* If there was no child device, and we're the last in
* a list of devices, then print another blank line */
if (nextlastdev == -1 && devid == lastdev)
vshPrint(ctl, "%s\n", virBufferCurrentContent(indent));
if (!root)
virBufferTrim(indent, NULL, 2);
ret = 0;
cleanup:
return ret;
}
int
vshTreePrint(vshControl *ctl, vshTreeLookup lookup, void *opaque,
int num_devices, int devid)
{
int ret;
virBuffer indent = VIR_BUFFER_INITIALIZER;
ret = vshTreePrintInternal(ctl, lookup, opaque, num_devices,
devid, devid, true, &indent);
if (ret < 0)
vshError(ctl, "%s", _("Failed to complete tree listing"));
virBufferFreeAndReset(&indent);
return ret;
}
/* Common code for the edit / net-edit / pool-edit functions which follow. */
char *
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshEditWriteToTempFile(vshControl *ctl, const char *doc)
{
char *ret;
const char *tmpdir;
int fd;
tmpdir = getenv ("TMPDIR");
if (!tmpdir) tmpdir = "/tmp";
if (virAsprintf(&ret, "%s/virshXXXXXX.xml", tmpdir) < 0) {
vshError(ctl, "%s", _("out of memory"));
return NULL;
}
fd = mkstemps(ret, 4);
if (fd == -1) {
vshError(ctl, _("mkstemps: failed to create temporary file: %s"),
strerror(errno));
VIR_FREE(ret);
return NULL;
}
if (safewrite(fd, doc, strlen(doc)) == -1) {
vshError(ctl, _("write: %s: failed to write to temporary file: %s"),
ret, strerror(errno));
VIR_FORCE_CLOSE(fd);
unlink(ret);
VIR_FREE(ret);
return NULL;
}
if (VIR_CLOSE(fd) < 0) {
vshError(ctl, _("close: %s: failed to write or close temporary file: %s"),
ret, strerror(errno));
unlink(ret);
VIR_FREE(ret);
return NULL;
}
/* Temporary filename: caller frees. */
return ret;
}
/* Characters permitted in $EDITOR environment variable and temp filename. */
#define ACCEPTED_CHARS \
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/_.:@"
int
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshEditFile(vshControl *ctl, const char *filename)
{
const char *editor;
virCommandPtr cmd;
int ret = -1;
int outfd = STDOUT_FILENO;
int errfd = STDERR_FILENO;
editor = getenv("VISUAL");
if (!editor)
editor = getenv("EDITOR");
if (!editor)
editor = "vi"; /* could be cruel & default to ed(1) here */
/* Check that filename doesn't contain shell meta-characters, and
* if it does, refuse to run. Follow the Unix conventions for
* EDITOR: the user can intentionally specify command options, so
* we don't protect any shell metacharacters there. Lots more
* than virsh will misbehave if EDITOR has bogus contents (which
* is why sudo scrubs it by default). Conversely, if the editor
* is safe, we can run it directly rather than wasting a shell.
*/
if (strspn(editor, ACCEPTED_CHARS) != strlen(editor)) {
if (strspn(filename, ACCEPTED_CHARS) != strlen(filename)) {
vshError(ctl,
_("%s: temporary filename contains shell meta or other "
"unacceptable characters (is $TMPDIR wrong?)"),
filename);
return -1;
}
cmd = virCommandNewArgList("sh", "-c", NULL);
virCommandAddArgFormat(cmd, "%s %s", editor, filename);
} else {
cmd = virCommandNewArgList(editor, filename, NULL);
}
virCommandSetInputFD(cmd, STDIN_FILENO);
virCommandSetOutputFD(cmd, &outfd);
virCommandSetErrorFD(cmd, &errfd);
if (virCommandRunAsync(cmd, NULL) < 0 ||
virCommandWait(cmd, NULL) < 0) {
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshReportError(ctl);
goto cleanup;
}
ret = 0;
cleanup:
virCommandFree(cmd);
return ret;
}
char *
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshEditReadBackFile(vshControl *ctl, const char *filename)
{
char *ret;
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
if (virFileReadAll(filename, VSH_MAX_XML_FILE, &ret) == -1) {
vshError(ctl,
_("%s: failed to read temporary file: %s"),
filename, strerror(errno));
return NULL;
}
return ret;
}
/*
* "cd" command
*/
static const vshCmdInfo info_cd[] = {
{"help", N_("change the current directory")},
{"desc", N_("Change the current directory.")},
{NULL, NULL}
};
static const vshCmdOptDef opts_cd[] = {
{"dir", VSH_OT_DATA, 0, N_("directory to switch to (default: home or else root)")},
{NULL, 0, 0, NULL}
};
static bool
cmdCd(vshControl *ctl, const vshCmd *cmd)
{
const char *dir = NULL;
char *dir_malloced = NULL;
bool ret = true;
if (!ctl->imode) {
vshError(ctl, "%s", _("cd: command valid only in interactive mode"));
return false;
}
if (vshCommandOptString(cmd, "dir", &dir) <= 0) {
dir = dir_malloced = virGetUserDirectory();
}
if (!dir)
dir = "/";
if (chdir(dir) == -1) {
vshError(ctl, _("cd: %s: %s"), strerror(errno), dir);
ret = false;
}
VIR_FREE(dir_malloced);
return ret;
}
/*
* "pwd" command
*/
static const vshCmdInfo info_pwd[] = {
{"help", N_("print the current directory")},
{"desc", N_("Print the current directory.")},
{NULL, NULL}
};
static bool
cmdPwd(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
{
char *cwd;
bool ret = true;
cwd = getcwd(NULL, 0);
if (!cwd) {
vshError(ctl, _("pwd: cannot get current directory: %s"),
strerror(errno));
ret = false;
} else {
vshPrint(ctl, _("%s\n"), cwd);
VIR_FREE(cwd);
}
return ret;
}
/*
* "echo" command
*/
static const vshCmdInfo info_echo[] = {
{"help", N_("echo arguments")},
{"desc", N_("Echo back arguments, possibly with quoting.")},
{NULL, NULL}
};
static const vshCmdOptDef opts_echo[] = {
{"shell", VSH_OT_BOOL, 0, N_("escape for shell use")},
{"xml", VSH_OT_BOOL, 0, N_("escape for XML use")},
{"str", VSH_OT_ALIAS, 0, "string"},
{"string", VSH_OT_ARGV, 0, N_("arguments to echo")},
{NULL, 0, 0, NULL}
};
/* Exists mainly for debugging virsh, but also handy for adding back
* quotes for later evaluation.
*/
static bool
cmdEcho(vshControl *ctl, const vshCmd *cmd)
{
bool shell = false;
bool xml = false;
int count = 0;
const vshCmdOpt *opt = NULL;
char *arg;
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (vshCommandOptBool(cmd, "shell"))
shell = true;
if (vshCommandOptBool(cmd, "xml"))
xml = true;
while ((opt = vshCommandOptArgv(cmd, opt))) {
2011-10-13 20:49:15 +00:00
char *str;
virBuffer xmlbuf = VIR_BUFFER_INITIALIZER;
arg = opt->data;
2011-10-13 20:49:15 +00:00
if (count)
virBufferAddChar(&buf, ' ');
2011-10-13 20:49:15 +00:00
if (xml) {
2011-10-13 20:49:15 +00:00
virBufferEscapeString(&xmlbuf, "%s", arg);
if (virBufferError(&buf)) {
vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
return false;
}
2011-10-13 20:49:15 +00:00
str = virBufferContentAndReset(&xmlbuf);
} else {
str = vshStrdup(ctl, arg);
}
2011-10-13 20:49:15 +00:00
if (shell)
virBufferEscapeShell(&buf, str);
else
virBufferAdd(&buf, str, -1);
count++;
2011-10-13 20:49:15 +00:00
VIR_FREE(str);
}
if (virBufferError(&buf)) {
vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
return false;
}
arg = virBufferContentAndReset(&buf);
if (arg)
vshPrint(ctl, "%s", arg);
VIR_FREE(arg);
return true;
}
2005-12-08 10:23:34 +00:00
/*
* "quit" command
*/
static const vshCmdInfo info_quit[] = {
{"help", N_("quit this interactive terminal")},
{"desc", ""},
{NULL, NULL}
2005-12-08 10:23:34 +00:00
};
static bool
2008-08-01 13:51:18 +00:00
cmdQuit(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
{
ctl->imode = false;
return true;
2005-12-08 10:23:34 +00:00
}
/* ---------------
* Utils for work with command definition
* ---------------
*/
const char *
vshCmddefGetInfo(const vshCmdDef * cmd, const char *name)
{
const vshCmdInfo *info;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
for (info = cmd->info; info && info->name; info++) {
if (STREQ(info->name, name))
return info->data;
}
return NULL;
}
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
/* Validate that the options associated with cmd can be parsed. */
static int
vshCmddefOptParse(const vshCmdDef *cmd, uint32_t *opts_need_arg,
uint32_t *opts_required)
{
int i;
bool optional = false;
*opts_need_arg = 0;
*opts_required = 0;
if (!cmd->opts)
return 0;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
for (i = 0; cmd->opts[i].name; i++) {
const vshCmdOptDef *opt = &cmd->opts[i];
if (i > 31)
return -1; /* too many options */
if (opt->type == VSH_OT_BOOL) {
if (opt->flags & VSH_OFLAG_REQ)
return -1; /* bool options can't be mandatory */
continue;
}
if (opt->type == VSH_OT_ALIAS) {
int j;
if (opt->flags || !opt->help)
return -1; /* alias options are tracked by the original name */
for (j = i + 1; cmd->opts[j].name; j++) {
if (STREQ(opt->help, cmd->opts[j].name))
break;
}
if (!cmd->opts[j].name)
return -1; /* alias option must map to a later option name */
continue;
}
if (opt->flags & VSH_OFLAG_REQ_OPT) {
if (opt->flags & VSH_OFLAG_REQ)
*opts_required |= 1 << i;
continue;
}
*opts_need_arg |= 1 << i;
if (opt->flags & VSH_OFLAG_REQ) {
if (optional)
return -1; /* mandatory options must be listed first */
*opts_required |= 1 << i;
} else {
optional = true;
}
if (opt->type == VSH_OT_ARGV && cmd->opts[i + 1].name)
return -1; /* argv option must be listed last */
}
return 0;
}
static vshCmdOptDef helpopt = {"help", VSH_OT_BOOL, 0,
N_("print help for this function")};
static const vshCmdOptDef *
vshCmddefGetOption(vshControl *ctl, const vshCmdDef *cmd, const char *name,
uint32_t *opts_seen, int *opt_index)
{
int i;
if (STREQ(name, helpopt.name)) {
return &helpopt;
}
for (i = 0; cmd->opts && cmd->opts[i].name; i++) {
const vshCmdOptDef *opt = &cmd->opts[i];
if (STREQ(opt->name, name)) {
if (opt->type == VSH_OT_ALIAS) {
name = opt->help;
continue;
}
if ((*opts_seen & (1 << i)) && opt->type != VSH_OT_ARGV) {
vshError(ctl, _("option --%s already seen"), name);
return NULL;
}
*opts_seen |= 1 << i;
*opt_index = i;
2005-12-08 10:23:34 +00:00
return opt;
}
}
if (STRNEQ(cmd->name, "help")) {
vshError(ctl, _("command '%s' doesn't support option --%s"),
cmd->name, name);
}
2005-12-08 10:23:34 +00:00
return NULL;
}
static const vshCmdOptDef *
vshCmddefGetData(const vshCmdDef *cmd, uint32_t *opts_need_arg,
uint32_t *opts_seen)
{
int i;
const vshCmdOptDef *opt;
2005-12-08 10:23:34 +00:00
if (!*opts_need_arg)
return NULL;
/* Grab least-significant set bit */
i = ffs(*opts_need_arg) - 1;
opt = &cmd->opts[i];
if (opt->type != VSH_OT_ARGV)
*opts_need_arg &= ~(1 << i);
*opts_seen |= 1 << i;
return opt;
2005-12-08 10:23:34 +00:00
}
2006-01-25 09:46:22 +00:00
/*
* Checks for required options
*/
static int
vshCommandCheckOpts(vshControl *ctl, const vshCmd *cmd, uint32_t opts_required,
uint32_t opts_seen)
2006-01-25 09:46:22 +00:00
{
const vshCmdDef *def = cmd->def;
int i;
opts_required &= ~opts_seen;
if (!opts_required)
return 0;
for (i = 0; def->opts[i].name; i++) {
if (opts_required & (1 << i)) {
const vshCmdOptDef *opt = &def->opts[i];
vshError(ctl,
opt->type == VSH_OT_DATA || opt->type == VSH_OT_ARGV ?
_("command '%s' requires <%s> option") :
_("command '%s' requires --%s option"),
def->name, opt->name);
2006-01-25 09:46:22 +00:00
}
}
return -1;
2006-01-25 09:46:22 +00:00
}
const vshCmdDef *
vshCmddefSearch(const char *cmdname)
{
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
const vshCmdGrp *g;
const vshCmdDef *c;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
for (g = cmdGroups; g->name; g++) {
for (c = g->commands; c->name; c++) {
if (STREQ(c->name, cmdname))
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
return c;
}
}
2005-12-08 10:23:34 +00:00
return NULL;
}
const vshCmdGrp *
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
vshCmdGrpSearch(const char *grpname)
{
const vshCmdGrp *g;
for (g = cmdGroups; g->name; g++) {
if (STREQ(g->name, grpname) || STREQ(g->keyword, grpname))
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
return g;
}
return NULL;
}
bool
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
vshCmdGrpHelp(vshControl *ctl, const char *grpname)
{
const vshCmdGrp *grp = vshCmdGrpSearch(grpname);
const vshCmdDef *cmd = NULL;
if (!grp) {
vshError(ctl, _("command group '%s' doesn't exist"), grpname);
return false;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
} else {
vshPrint(ctl, _(" %s (help keyword '%s'):\n"), grp->name,
grp->keyword);
for (cmd = grp->commands; cmd->name; cmd++) {
vshPrint(ctl, " %-30s %s\n", cmd->name,
_(vshCmddefGetInfo(cmd, "help")));
}
}
return true;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
}
bool
vshCmddefHelp(vshControl *ctl, const char *cmdname)
{
const vshCmdDef *def = vshCmddefSearch(cmdname);
2005-12-08 10:23:34 +00:00
if (!def) {
vshError(ctl, _("command '%s' doesn't exist"), cmdname);
return false;
} else {
/* Don't translate desc if it is "". */
const char *desc = vshCmddefGetInfo(def, "desc");
const char *help = _(vshCmddefGetInfo(def, "help"));
char buf[256];
uint32_t opts_need_arg;
uint32_t opts_required;
bool shortopt = false; /* true if 'arg' works instead of '--opt arg' */
if (vshCmddefOptParse(def, &opts_need_arg, &opts_required)) {
vshError(ctl, _("internal error: bad options in command: '%s'"),
def->name);
return false;
}
2005-12-08 10:23:34 +00:00
fputs(_(" NAME\n"), stdout);
fprintf(stdout, " %s - %s\n", def->name, help);
fputs(_("\n SYNOPSIS\n"), stdout);
fprintf(stdout, " %s", def->name);
if (def->opts) {
const vshCmdOptDef *opt;
for (opt = def->opts; opt->name; opt++) {
const char *fmt = "%s";
switch (opt->type) {
case VSH_OT_BOOL:
fmt = "[--%s]";
break;
case VSH_OT_INT:
/* xgettext:c-format */
fmt = ((opt->flags & VSH_OFLAG_REQ) ? "<%s>"
: _("[--%s <number>]"));
if (!(opt->flags & VSH_OFLAG_REQ_OPT))
shortopt = true;
break;
case VSH_OT_STRING:
/* xgettext:c-format */
fmt = _("[--%s <string>]");
if (!(opt->flags & VSH_OFLAG_REQ_OPT))
shortopt = true;
break;
case VSH_OT_DATA:
fmt = ((opt->flags & VSH_OFLAG_REQ) ? "<%s>" : "[<%s>]");
if (!(opt->flags & VSH_OFLAG_REQ_OPT))
shortopt = true;
break;
case VSH_OT_ARGV:
/* xgettext:c-format */
if (shortopt) {
fmt = (opt->flags & VSH_OFLAG_REQ)
? _("{[--%s] <string>}...")
: _("[[--%s] <string>]...");
} else {
fmt = (opt->flags & VSH_OFLAG_REQ) ? _("<%s>...")
: _("[<%s>]...");
}
break;
case VSH_OT_ALIAS:
/* aliases are intentionally undocumented */
continue;
default:
assert(0);
}
fputc(' ', stdout);
fprintf(stdout, fmt, opt->name);
}
2005-12-08 10:23:34 +00:00
}
fputc('\n', stdout);
if (desc[0]) {
/* Print the description only if it's not empty. */
fputs(_("\n DESCRIPTION\n"), stdout);
fprintf(stdout, " %s\n", _(desc));
2005-12-08 10:23:34 +00:00
}
2005-12-08 10:23:34 +00:00
if (def->opts) {
const vshCmdOptDef *opt;
fputs(_("\n OPTIONS\n"), stdout);
for (opt = def->opts; opt->name; opt++) {
switch (opt->type) {
case VSH_OT_BOOL:
2005-12-08 10:23:34 +00:00
snprintf(buf, sizeof(buf), "--%s", opt->name);
break;
case VSH_OT_INT:
snprintf(buf, sizeof(buf),
(opt->flags & VSH_OFLAG_REQ) ? _("[--%s] <number>")
: _("--%s <number>"), opt->name);
break;
case VSH_OT_STRING:
/* OT_STRING should never be VSH_OFLAG_REQ */
snprintf(buf, sizeof(buf), _("--%s <string>"), opt->name);
break;
case VSH_OT_DATA:
snprintf(buf, sizeof(buf), _("[--%s] <string>"),
opt->name);
break;
case VSH_OT_ARGV:
snprintf(buf, sizeof(buf),
shortopt ? _("[--%s] <string>") : _("<%s>"),
opt->name);
break;
case VSH_OT_ALIAS:
continue;
default:
assert(0);
}
fprintf(stdout, " %-15s %s\n", buf, _(opt->help));
}
2005-12-08 10:23:34 +00:00
}
fputc('\n', stdout);
}
return true;
2005-12-08 10:23:34 +00:00
}
/* ---------------
* Utils for work with runtime commands data
* ---------------
*/
static void
vshCommandOptFree(vshCmdOpt * arg)
{
2005-12-08 10:23:34 +00:00
vshCmdOpt *a = arg;
while (a) {
2005-12-08 10:23:34 +00:00
vshCmdOpt *tmp = a;
2005-12-08 10:23:34 +00:00
a = a->next;
VIR_FREE(tmp->data);
VIR_FREE(tmp);
2005-12-08 10:23:34 +00:00
}
}
static void
2008-08-01 13:51:18 +00:00
vshCommandFree(vshCmd *cmd)
{
2005-12-08 10:23:34 +00:00
vshCmd *c = cmd;
while (c) {
2005-12-08 10:23:34 +00:00
vshCmd *tmp = c;
2005-12-08 10:23:34 +00:00
c = c->next;
if (tmp->opts)
vshCommandOptFree(tmp->opts);
VIR_FREE(tmp);
2005-12-08 10:23:34 +00:00
}
}
/**
* vshCommandOpt:
* @cmd: parsed command line to search
* @name: option name to search for
* @opt: result of the search
*
* Look up an option passed to CMD by NAME. Returns 1 with *OPT set
* to the option if found, 0 with *OPT set to NULL if the name is
* valid and the option is not required, -1 with *OPT set to NULL if
* the option is required but not present, and -2 if NAME is not valid
* (-2 indicates a programming error). No error messages are issued.
2005-12-08 10:23:34 +00:00
*/
int
vshCommandOpt(const vshCmd *cmd, const char *name, vshCmdOpt **opt)
{
vshCmdOpt *candidate = cmd->opts;
const vshCmdOptDef *valid = cmd->def->opts;
/* See if option is present on command line. */
while (candidate) {
if (STREQ(candidate->def->name, name)) {
*opt = candidate;
return 1;
}
candidate = candidate->next;
2005-12-08 10:23:34 +00:00
}
/* Option not present, see if command requires it. */
*opt = NULL;
while (valid) {
if (!valid->name)
break;
if (STREQ(name, valid->name))
return (valid->flags & VSH_OFLAG_REQ) == 0 ? 0 : -1;
valid++;
}
/* If we got here, the name is unknown. */
return -2;
2005-12-08 10:23:34 +00:00
}
/**
* vshCommandOptInt:
* @cmd command reference
* @name option name
* @value result
*
* Convert option to int
* Return value:
* >0 if option found and valid (@value updated)
* 0 if option not found and not required (@value untouched)
* <0 in all other cases (@value untouched)
2005-12-08 10:23:34 +00:00
*/
int
vshCommandOptInt(const vshCmd *cmd, const char *name, int *value)
{
vshCmdOpt *arg;
int ret;
ret = vshCommandOpt(cmd, name, &arg);
if (ret <= 0)
return ret;
if (!arg->data) {
/* only possible on bool, but if name is bool, this is a
* programming bug */
return -2;
}
if (virStrToLong_i(arg->data, NULL, 10, value) < 0)
return -1;
return 1;
2005-12-08 10:23:34 +00:00
}
/**
* vshCommandOptUInt:
* @cmd command reference
* @name option name
* @value result
*
* Convert option to unsigned int
* See vshCommandOptInt()
*/
int
vshCommandOptUInt(const vshCmd *cmd, const char *name, unsigned int *value)
{
vshCmdOpt *arg;
int ret;
ret = vshCommandOpt(cmd, name, &arg);
if (ret <= 0)
return ret;
if (!arg->data) {
/* only possible on bool, but if name is bool, this is a
* programming bug */
return -2;
}
if (virStrToLong_ui(arg->data, NULL, 10, value) < 0)
return -1;
return 1;
}
/*
* vshCommandOptUL:
* @cmd command reference
* @name option name
* @value result
*
* Convert option to unsigned long
* See vshCommandOptInt()
*/
int
vshCommandOptUL(const vshCmd *cmd, const char *name, unsigned long *value)
{
vshCmdOpt *arg;
int ret;
ret = vshCommandOpt(cmd, name, &arg);
if (ret <= 0)
return ret;
if (!arg->data) {
/* only possible on bool, but if name is bool, this is a
* programming bug */
return -2;
}
if (virStrToLong_ul(arg->data, NULL, 10, value) < 0)
return -1;
return 1;
}
/**
* vshCommandOptString:
* @cmd command reference
* @name option name
* @value result
*
2005-12-08 10:23:34 +00:00
* Returns option as STRING
* Return value:
* >0 if option found and valid (@value updated)
* 0 if option not found and not required (@value untouched)
* <0 in all other cases (@value untouched)
2005-12-08 10:23:34 +00:00
*/
int
vshCommandOptString(const vshCmd *cmd, const char *name, const char **value)
{
vshCmdOpt *arg;
int ret;
ret = vshCommandOpt(cmd, name, &arg);
if (ret <= 0)
return ret;
if (!arg->data) {
/* only possible on bool, but if name is bool, this is a
* programming bug */
return -2;
}
if (!*arg->data && !(arg->def->flags & VSH_OFLAG_EMPTY_OK)) {
return -1;
}
*value = arg->data;
return 1;
2005-12-08 10:23:34 +00:00
}
/**
* vshCommandOptLongLong:
* @cmd command reference
* @name option name
* @value result
*
* Returns option as long long
* See vshCommandOptInt()
*/
int
vshCommandOptLongLong(const vshCmd *cmd, const char *name,
long long *value)
{
vshCmdOpt *arg;
int ret;
ret = vshCommandOpt(cmd, name, &arg);
if (ret <= 0)
return ret;
if (!arg->data) {
/* only possible on bool, but if name is bool, this is a
* programming bug */
return -2;
}
if (virStrToLong_ll(arg->data, NULL, 10, value) < 0)
return -1;
return 1;
}
/**
* vshCommandOptULongLong:
* @cmd command reference
* @name option name
* @value result
*
* Returns option as long long
* See vshCommandOptInt()
*/
int
vshCommandOptULongLong(const vshCmd *cmd, const char *name,
unsigned long long *value)
{
vshCmdOpt *arg;
int ret;
ret = vshCommandOpt(cmd, name, &arg);
if (ret <= 0)
return ret;
if (!arg->data) {
/* only possible on bool, but if name is bool, this is a
* programming bug */
return -2;
}
if (virStrToLong_ull(arg->data, NULL, 10, value) < 0)
return -1;
return 1;
}
/**
* vshCommandOptScaledInt:
* @cmd command reference
* @name option name
* @value result
* @scale default of 1 or 1024, if no suffix is present
* @max maximum value permitted
*
* Returns option as long long, scaled according to suffix
* See vshCommandOptInt()
*/
int
vshCommandOptScaledInt(const vshCmd *cmd, const char *name,
unsigned long long *value, int scale,
unsigned long long max)
{
const char *str;
int ret;
char *end;
ret = vshCommandOptString(cmd, name, &str);
if (ret <= 0)
return ret;
if (virStrToLong_ull(str, &end, 10, value) < 0 ||
virScaleInteger(value, end, scale, max) < 0)
return -1;
return 1;
}
/**
* vshCommandOptBool:
* @cmd command reference
* @name option name
*
* Returns true/false if the option exists. Note that this does NOT
* validate whether the option is actually boolean, or even whether
* name is legal; so that this can be used to probe whether a data
* option is present without actually using that data.
2005-12-08 10:23:34 +00:00
*/
bool
2008-08-01 13:51:18 +00:00
vshCommandOptBool(const vshCmd *cmd, const char *name)
{
vshCmdOpt *dummy;
return vshCommandOpt(cmd, name, &dummy) == 1;
2005-12-08 10:23:34 +00:00
}
/**
* vshCommandOptArgv:
* @cmd command reference
* @opt starting point for the search
*
* Returns the next argv argument after OPT (or the first one if OPT
* is NULL), or NULL if no more are present.
*
* Requires that a VSH_OT_ARGV option be last in the
* list of supported options in CMD->def->opts.
*/
const vshCmdOpt *
vshCommandOptArgv(const vshCmd *cmd, const vshCmdOpt *opt)
{
opt = opt ? opt->next : cmd->opts;
while (opt) {
if (opt->def->type == VSH_OT_ARGV) {
return opt;
}
opt = opt->next;
}
return NULL;
}
remove redundant optname arguments This is the second part of the change mentioned here: http://thread.gmane.org/gmane.comp.emulators.libvirt/10331 It removes the essentially redundant "optname" parameter from each of the vshCommandOptNetworkBy and vshCommandOptDomainBy functions as well as the correspond macros (without "By" suffix). Now, instead of always passing the optname, "domain", to vshCommandOptDomainBy, that function requires that its command argument refer to an opts array containing a "domain" option. This normalization makes one more help-related change: it renames the net-start "name" argument to the more sensible and consistent "network". * src/virsh.c (VSH_BYNAME, vshCommandOptDomain) (cmd_has_option): New function, used in vshCommandOptDomainBy and vshCommandOptNetworkBy. (vshCommandOptDomainBy, vshCommandOptNetworkBy): Remove the optname parameter, it's always "domain" ("network"). Update all callers. Call cmd_has_option. (vshCommandOptNetwork, cmdAutostart, cmdConsole, cmdDomstate) (cmdDomblkstat, cmdDomIfstat, cmdSuspend, cmdUndefine, cmdStart) (cmdSave, cmdSchedinfo, cmdDump, cmdResume, cmdShutdown) (cmdReboot, cmdDestroy, cmdDominfo, cmdVcpuinfo, cmdVcpupin) (cmdSetvcpus, cmdSetmem, cmdSetmaxmem, cmdDumpXML, cmdDomname) (cmdDomid, cmdDomuuid, cmdMigrate, cmdNetworkAutostart) (cmdNetworkDestroy, cmdNetworkDumpXML, cmdNetworkName) (opts_network_start, cmdNetworkStart, cmdNetworkUndefine) (cmdNetworkUuid, cmdVNCDisplay, cmdTTYConsole, cmdAttachDevice) (cmdDetachDevice, cmdAttachInterface, cmdDetachInterface) (cmdAttachDisk, cmdDetachDisk, cmdEdit) * src/Makefile.am (virsh-pool-edit.c): This code is generated from cmdEdit, and cmdEdit uses the vshCommandOptDomain macro which now, with the changes above, has only 3 (was 4) arguments, yet the macro use is mapped to vshCommandOptPool, which still requires 4 arguments. So this change adjusts the sed code to reinsert the just-removed argument -- we're not changing pool-related code right now, because it's not as straight-forward.
2008-12-15 10:26:54 +00:00
/* Determine whether CMD->opts includes an option with name OPTNAME.
If not, give a diagnostic and return false.
If so, return true. */
bool
vshCmdHasOption(vshControl *ctl, const vshCmd *cmd, const char *optname)
remove redundant optname arguments This is the second part of the change mentioned here: http://thread.gmane.org/gmane.comp.emulators.libvirt/10331 It removes the essentially redundant "optname" parameter from each of the vshCommandOptNetworkBy and vshCommandOptDomainBy functions as well as the correspond macros (without "By" suffix). Now, instead of always passing the optname, "domain", to vshCommandOptDomainBy, that function requires that its command argument refer to an opts array containing a "domain" option. This normalization makes one more help-related change: it renames the net-start "name" argument to the more sensible and consistent "network". * src/virsh.c (VSH_BYNAME, vshCommandOptDomain) (cmd_has_option): New function, used in vshCommandOptDomainBy and vshCommandOptNetworkBy. (vshCommandOptDomainBy, vshCommandOptNetworkBy): Remove the optname parameter, it's always "domain" ("network"). Update all callers. Call cmd_has_option. (vshCommandOptNetwork, cmdAutostart, cmdConsole, cmdDomstate) (cmdDomblkstat, cmdDomIfstat, cmdSuspend, cmdUndefine, cmdStart) (cmdSave, cmdSchedinfo, cmdDump, cmdResume, cmdShutdown) (cmdReboot, cmdDestroy, cmdDominfo, cmdVcpuinfo, cmdVcpupin) (cmdSetvcpus, cmdSetmem, cmdSetmaxmem, cmdDumpXML, cmdDomname) (cmdDomid, cmdDomuuid, cmdMigrate, cmdNetworkAutostart) (cmdNetworkDestroy, cmdNetworkDumpXML, cmdNetworkName) (opts_network_start, cmdNetworkStart, cmdNetworkUndefine) (cmdNetworkUuid, cmdVNCDisplay, cmdTTYConsole, cmdAttachDevice) (cmdDetachDevice, cmdAttachInterface, cmdDetachInterface) (cmdAttachDisk, cmdDetachDisk, cmdEdit) * src/Makefile.am (virsh-pool-edit.c): This code is generated from cmdEdit, and cmdEdit uses the vshCommandOptDomain macro which now, with the changes above, has only 3 (was 4) arguments, yet the macro use is mapped to vshCommandOptPool, which still requires 4 arguments. So this change adjusts the sed code to reinsert the just-removed argument -- we're not changing pool-related code right now, because it's not as straight-forward.
2008-12-15 10:26:54 +00:00
{
/* Iterate through cmd->opts, to ensure that there is an entry
with name OPTNAME and type VSH_OT_DATA. */
bool found = false;
const vshCmdOpt *opt;
for (opt = cmd->opts; opt; opt = opt->next) {
if (STREQ(opt->def->name, optname) && opt->def->type == VSH_OT_DATA) {
remove redundant optname arguments This is the second part of the change mentioned here: http://thread.gmane.org/gmane.comp.emulators.libvirt/10331 It removes the essentially redundant "optname" parameter from each of the vshCommandOptNetworkBy and vshCommandOptDomainBy functions as well as the correspond macros (without "By" suffix). Now, instead of always passing the optname, "domain", to vshCommandOptDomainBy, that function requires that its command argument refer to an opts array containing a "domain" option. This normalization makes one more help-related change: it renames the net-start "name" argument to the more sensible and consistent "network". * src/virsh.c (VSH_BYNAME, vshCommandOptDomain) (cmd_has_option): New function, used in vshCommandOptDomainBy and vshCommandOptNetworkBy. (vshCommandOptDomainBy, vshCommandOptNetworkBy): Remove the optname parameter, it's always "domain" ("network"). Update all callers. Call cmd_has_option. (vshCommandOptNetwork, cmdAutostart, cmdConsole, cmdDomstate) (cmdDomblkstat, cmdDomIfstat, cmdSuspend, cmdUndefine, cmdStart) (cmdSave, cmdSchedinfo, cmdDump, cmdResume, cmdShutdown) (cmdReboot, cmdDestroy, cmdDominfo, cmdVcpuinfo, cmdVcpupin) (cmdSetvcpus, cmdSetmem, cmdSetmaxmem, cmdDumpXML, cmdDomname) (cmdDomid, cmdDomuuid, cmdMigrate, cmdNetworkAutostart) (cmdNetworkDestroy, cmdNetworkDumpXML, cmdNetworkName) (opts_network_start, cmdNetworkStart, cmdNetworkUndefine) (cmdNetworkUuid, cmdVNCDisplay, cmdTTYConsole, cmdAttachDevice) (cmdDetachDevice, cmdAttachInterface, cmdDetachInterface) (cmdAttachDisk, cmdDetachDisk, cmdEdit) * src/Makefile.am (virsh-pool-edit.c): This code is generated from cmdEdit, and cmdEdit uses the vshCommandOptDomain macro which now, with the changes above, has only 3 (was 4) arguments, yet the macro use is mapped to vshCommandOptPool, which still requires 4 arguments. So this change adjusts the sed code to reinsert the just-removed argument -- we're not changing pool-related code right now, because it's not as straight-forward.
2008-12-15 10:26:54 +00:00
found = true;
break;
}
}
if (!found)
vshError(ctl, _("internal error: virsh %s: no %s VSH_OT_DATA option"),
remove redundant optname arguments This is the second part of the change mentioned here: http://thread.gmane.org/gmane.comp.emulators.libvirt/10331 It removes the essentially redundant "optname" parameter from each of the vshCommandOptNetworkBy and vshCommandOptDomainBy functions as well as the correspond macros (without "By" suffix). Now, instead of always passing the optname, "domain", to vshCommandOptDomainBy, that function requires that its command argument refer to an opts array containing a "domain" option. This normalization makes one more help-related change: it renames the net-start "name" argument to the more sensible and consistent "network". * src/virsh.c (VSH_BYNAME, vshCommandOptDomain) (cmd_has_option): New function, used in vshCommandOptDomainBy and vshCommandOptNetworkBy. (vshCommandOptDomainBy, vshCommandOptNetworkBy): Remove the optname parameter, it's always "domain" ("network"). Update all callers. Call cmd_has_option. (vshCommandOptNetwork, cmdAutostart, cmdConsole, cmdDomstate) (cmdDomblkstat, cmdDomIfstat, cmdSuspend, cmdUndefine, cmdStart) (cmdSave, cmdSchedinfo, cmdDump, cmdResume, cmdShutdown) (cmdReboot, cmdDestroy, cmdDominfo, cmdVcpuinfo, cmdVcpupin) (cmdSetvcpus, cmdSetmem, cmdSetmaxmem, cmdDumpXML, cmdDomname) (cmdDomid, cmdDomuuid, cmdMigrate, cmdNetworkAutostart) (cmdNetworkDestroy, cmdNetworkDumpXML, cmdNetworkName) (opts_network_start, cmdNetworkStart, cmdNetworkUndefine) (cmdNetworkUuid, cmdVNCDisplay, cmdTTYConsole, cmdAttachDevice) (cmdDetachDevice, cmdAttachInterface, cmdDetachInterface) (cmdAttachDisk, cmdDetachDisk, cmdEdit) * src/Makefile.am (virsh-pool-edit.c): This code is generated from cmdEdit, and cmdEdit uses the vshCommandOptDomain macro which now, with the changes above, has only 3 (was 4) arguments, yet the macro use is mapped to vshCommandOptPool, which still requires 4 arguments. So this change adjusts the sed code to reinsert the just-removed argument -- we're not changing pool-related code right now, because it's not as straight-forward.
2008-12-15 10:26:54 +00:00
cmd->def->name, optname);
return found;
}
2006-01-25 09:46:22 +00:00
2005-12-08 10:23:34 +00:00
/*
* Executes command(s) and returns return code from last command
*/
static bool
2008-08-01 13:51:18 +00:00
vshCommandRun(vshControl *ctl, const vshCmd *cmd)
{
bool ret = true;
while (cmd) {
2005-12-08 10:23:34 +00:00
struct timeval before, after;
bool enable_timing = ctl->timing;
if ((ctl->conn == NULL || disconnected) &&
!(cmd->def->flags & VSH_CMD_FLAG_NOCONNECT))
vshReconnect(ctl);
if (enable_timing)
2005-12-08 10:23:34 +00:00
GETTIMEOFDAY(&before);
2005-12-08 10:23:34 +00:00
ret = cmd->def->handler(ctl, cmd);
if (enable_timing)
2005-12-08 10:23:34 +00:00
GETTIMEOFDAY(&after);
/* try to automatically catch disconnections */
if (!ret &&
((last_error != NULL) &&
(((last_error->code == VIR_ERR_SYSTEM_ERROR) &&
(last_error->domain == VIR_FROM_REMOTE)) ||
(last_error->code == VIR_ERR_RPC) ||
(last_error->code == VIR_ERR_NO_CONNECT) ||
(last_error->code == VIR_ERR_INVALID_CONN))))
disconnected++;
if (!ret)
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshReportError(ctl);
2009-02-09 14:24:06 +00:00
if (!ret && disconnected != 0)
vshReconnect(ctl);
if (STREQ(cmd->def->name, "quit")) /* hack ... */
2005-12-08 10:23:34 +00:00
return ret;
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
if (enable_timing) {
double diff_ms = (((after.tv_sec - before.tv_sec) * 1000000.0) +
((after.tv_usec - before.tv_usec) / 1000.0));
vshPrint(ctl, _("\n(Time: %.3f ms)\n\n"), diff_ms);
} else {
2006-05-22 14:38:33 +00:00
vshPrintExtra(ctl, "\n");
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
}
2005-12-08 10:23:34 +00:00
cmd = cmd->next;
}
return ret;
}
/* ---------------
* Command parsing
2005-12-08 10:23:34 +00:00
* ---------------
*/
typedef enum {
VSH_TK_ERROR, /* Failed to parse a token */
VSH_TK_ARG, /* Arbitrary argument, might be option or empty */
VSH_TK_SUBCMD_END, /* Separation between commands */
VSH_TK_END /* No more commands */
} vshCommandToken;
typedef struct _vshCommandParser vshCommandParser;
struct _vshCommandParser {
vshCommandToken(*getNextArg)(vshControl *, vshCommandParser *,
char **);
/* vshCommandStringGetArg() */
char *pos;
/* vshCommandArgvGetArg() */
char **arg_pos;
char **arg_end;
};
static bool
vshCommandParse(vshControl *ctl, vshCommandParser *parser)
{
2005-12-08 10:23:34 +00:00
char *tkdata = NULL;
vshCmd *clast = NULL;
vshCmdOpt *first = NULL;
2005-12-08 10:23:34 +00:00
if (ctl->cmd) {
vshCommandFree(ctl->cmd);
ctl->cmd = NULL;
}
while (1) {
2005-12-08 10:23:34 +00:00
vshCmdOpt *last = NULL;
const vshCmdDef *cmd = NULL;
vshCommandToken tk;
bool data_only = false;
uint32_t opts_need_arg = 0;
uint32_t opts_required = 0;
uint32_t opts_seen = 0;
2005-12-08 10:23:34 +00:00
first = NULL;
while (1) {
const vshCmdOptDef *opt = NULL;
2005-12-08 10:23:34 +00:00
tkdata = NULL;
tk = parser->getNextArg(ctl, parser, &tkdata);
if (tk == VSH_TK_ERROR)
2005-12-08 10:23:34 +00:00
goto syntaxError;
2010-12-22 07:12:34 +00:00
if (tk != VSH_TK_ARG) {
VIR_FREE(tkdata);
break;
2010-12-22 07:12:34 +00:00
}
if (cmd == NULL) {
2005-12-08 10:23:34 +00:00
/* first token must be command name */
if (!(cmd = vshCmddefSearch(tkdata))) {
vshError(ctl, _("unknown command: '%s'"), tkdata);
goto syntaxError; /* ... or ignore this command only? */
2005-12-08 10:23:34 +00:00
}
if (vshCmddefOptParse(cmd, &opts_need_arg,
&opts_required) < 0) {
vshError(ctl,
_("internal error: bad options in command: '%s'"),
tkdata);
goto syntaxError;
}
VIR_FREE(tkdata);
} else if (data_only) {
goto get_data;
} else if (tkdata[0] == '-' && tkdata[1] == '-' &&
c_isalnum(tkdata[2])) {
char *optstr = strchr(tkdata + 2, '=');
int opt_index = 0;
if (optstr) {
*optstr = '\0'; /* convert the '=' to '\0' */
optstr = vshStrdup(ctl, optstr + 1);
}
/* Special case 'help' to ignore all spurious options */
if (!(opt = vshCmddefGetOption(ctl, cmd, tkdata + 2,
&opts_seen, &opt_index))) {
VIR_FREE(optstr);
if (STREQ(cmd->name, "help"))
continue;
2005-12-08 10:23:34 +00:00
goto syntaxError;
}
VIR_FREE(tkdata);
2005-12-08 10:23:34 +00:00
if (opt->type != VSH_OT_BOOL) {
/* option data */
if (optstr)
tkdata = optstr;
else
tk = parser->getNextArg(ctl, parser, &tkdata);
if (tk == VSH_TK_ERROR)
2005-12-08 10:23:34 +00:00
goto syntaxError;
if (tk != VSH_TK_ARG) {
vshError(ctl,
_("expected syntax: --%s <%s>"),
opt->name,
opt->type ==
VSH_OT_INT ? _("number") : _("string"));
2005-12-08 10:23:34 +00:00
goto syntaxError;
}
if (opt->type != VSH_OT_ARGV)
opts_need_arg &= ~(1 << opt_index);
} else {
tkdata = NULL;
if (optstr) {
vshError(ctl, _("invalid '=' after option --%s"),
opt->name);
VIR_FREE(optstr);
goto syntaxError;
}
2005-12-08 10:23:34 +00:00
}
} else if (tkdata[0] == '-' && tkdata[1] == '-' &&
tkdata[2] == '\0') {
data_only = true;
continue;
} else {
get_data:
/* Special case 'help' to ignore spurious data */
if (!(opt = vshCmddefGetData(cmd, &opts_need_arg,
&opts_seen)) &&
STRNEQ(cmd->name, "help")) {
vshError(ctl, _("unexpected data '%s'"), tkdata);
2005-12-08 10:23:34 +00:00
goto syntaxError;
}
}
if (opt) {
/* save option */
vshCmdOpt *arg = vshMalloc(ctl, sizeof(vshCmdOpt));
2005-12-08 10:23:34 +00:00
arg->def = opt;
arg->data = tkdata;
arg->next = NULL;
tkdata = NULL;
2005-12-08 10:23:34 +00:00
if (!first)
first = arg;
if (last)
last->next = arg;
last = arg;
vshDebug(ctl, VSH_ERR_INFO, "%s: %s(%s): %s\n",
cmd->name,
opt->name,
opt->type != VSH_OT_BOOL ? _("optdata") : _("bool"),
opt->type != VSH_OT_BOOL ? arg->data : _("(none)"));
2005-12-08 10:23:34 +00:00
}
}
/* command parsed -- allocate new struct for the command */
2005-12-08 10:23:34 +00:00
if (cmd) {
vshCmd *c = vshMalloc(ctl, sizeof(vshCmd));
vshCmdOpt *tmpopt = first;
/* if we encountered --help, replace parsed command with
* 'help <cmdname>' */
for (tmpopt = first; tmpopt; tmpopt = tmpopt->next) {
if (STRNEQ(tmpopt->def->name, "help"))
continue;
vshCommandOptFree(first);
first = vshMalloc(ctl, sizeof(vshCmdOpt));
first->def = &(opts_help[0]);
first->data = vshStrdup(ctl, cmd->name);
first->next = NULL;
cmd = vshCmddefSearch("help");
opts_required = 0;
opts_seen = 0;
break;
}
2005-12-08 10:23:34 +00:00
c->opts = first;
c->def = cmd;
c->next = NULL;
if (vshCommandCheckOpts(ctl, c, opts_required, opts_seen) < 0) {
VIR_FREE(c);
2006-01-25 09:46:22 +00:00
goto syntaxError;
}
2005-12-08 10:23:34 +00:00
if (!ctl->cmd)
ctl->cmd = c;
if (clast)
clast->next = c;
clast = c;
}
if (tk == VSH_TK_END)
break;
2005-12-08 10:23:34 +00:00
}
return true;
2005-12-08 10:23:34 +00:00
syntaxError:
if (ctl->cmd) {
2005-12-08 10:23:34 +00:00
vshCommandFree(ctl->cmd);
ctl->cmd = NULL;
}
2005-12-08 10:23:34 +00:00
if (first)
vshCommandOptFree(first);
VIR_FREE(tkdata);
return false;
2005-12-08 10:23:34 +00:00
}
/* --------------------
* Command argv parsing
* --------------------
*/
static vshCommandToken ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
vshCommandArgvGetArg(vshControl *ctl, vshCommandParser *parser, char **res)
{
if (parser->arg_pos == parser->arg_end) {
*res = NULL;
return VSH_TK_END;
}
*res = vshStrdup(ctl, *parser->arg_pos);
parser->arg_pos++;
return VSH_TK_ARG;
}
static bool
vshCommandArgvParse(vshControl *ctl, int nargs, char **argv)
{
vshCommandParser parser;
if (nargs <= 0)
return false;
parser.arg_pos = argv;
parser.arg_end = argv + nargs;
parser.getNextArg = vshCommandArgvGetArg;
return vshCommandParse(ctl, &parser);
}
/* ----------------------
* Command string parsing
* ----------------------
*/
static vshCommandToken ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res)
{
bool single_quote = false;
bool double_quote = false;
int sz = 0;
char *p = parser->pos;
char *q = vshStrdup(ctl, p);
*res = q;
while (*p && (*p == ' ' || *p == '\t'))
p++;
if (*p == '\0')
return VSH_TK_END;
if (*p == ';') {
parser->pos = ++p; /* = \0 or begin of next command */
return VSH_TK_SUBCMD_END;
}
while (*p) {
/* end of token is blank space or ';' */
if (!double_quote && !single_quote &&
(*p == ' ' || *p == '\t' || *p == ';'))
break;
if (!double_quote && *p == '\'') { /* single quote */
single_quote = !single_quote;
p++;
continue;
} else if (!single_quote && *p == '\\') { /* escape */
/*
* The same as the bash, a \ in "" is an escaper,
* but a \ in '' is not an escaper.
*/
p++;
if (*p == '\0') {
vshError(ctl, "%s", _("dangling \\"));
return VSH_TK_ERROR;
}
} else if (!single_quote && *p == '"') { /* double quote */
double_quote = !double_quote;
p++;
continue;
}
*q++ = *p++;
sz++;
}
if (double_quote) {
vshError(ctl, "%s", _("missing \""));
return VSH_TK_ERROR;
}
*q = '\0';
parser->pos = p;
return VSH_TK_ARG;
}
static bool
vshCommandStringParse(vshControl *ctl, char *cmdstr)
{
vshCommandParser parser;
if (cmdstr == NULL || *cmdstr == '\0')
return false;
parser.pos = cmdstr;
parser.getNextArg = vshCommandStringGetArg;
return vshCommandParse(ctl, &parser);
}
2005-12-08 10:23:34 +00:00
/* ---------------
* Misc utils
2005-12-08 10:23:34 +00:00
* ---------------
*/
int
vshDomainState(vshControl *ctl, virDomainPtr dom, int *reason)
{
virDomainInfo info;
if (reason)
*reason = -1;
if (!ctl->useGetInfo) {
int state;
if (virDomainGetState(dom, &state, reason, 0) < 0) {
virErrorPtr err = virGetLastError();
if (err && err->code == VIR_ERR_NO_SUPPORT)
ctl->useGetInfo = true;
else
return -1;
} else {
return state;
}
}
/* fall back to virDomainGetInfo if virDomainGetState is not supported */
if (virDomainGetInfo(dom, &info) < 0)
return -1;
else
return info.state;
}
/* Return a non-NULL string representation of a typed parameter; exit
* if we are out of memory. */
char *
vshGetTypedParamValue(vshControl *ctl, virTypedParameterPtr item)
{
int ret = 0;
char *str = NULL;
switch(item->type) {
case VIR_TYPED_PARAM_INT:
ret = virAsprintf(&str, "%d", item->value.i);
break;
case VIR_TYPED_PARAM_UINT:
ret = virAsprintf(&str, "%u", item->value.ui);
break;
case VIR_TYPED_PARAM_LLONG:
ret = virAsprintf(&str, "%lld", item->value.l);
break;
case VIR_TYPED_PARAM_ULLONG:
ret = virAsprintf(&str, "%llu", item->value.ul);
break;
case VIR_TYPED_PARAM_DOUBLE:
ret = virAsprintf(&str, "%f", item->value.d);
break;
case VIR_TYPED_PARAM_BOOLEAN:
ret = virAsprintf(&str, "%s", item->value.b ? _("yes") : _("no"));
break;
case VIR_TYPED_PARAM_STRING:
str = vshStrdup(ctl, item->value.s);
break;
default:
vshError(ctl, _("unimplemented parameter type %d"), item->type);
}
if (ret < 0) {
vshError(ctl, "%s", _("Out of memory"));
exit(EXIT_FAILURE);
}
return str;
}
virTypedParameterPtr
vshFindTypedParamByName(const char *name, virTypedParameterPtr list, int count)
{
int i = count;
virTypedParameterPtr found = list;
if (!list || !name)
return NULL;
while (i-- > 0) {
if (STREQ(name, found->field))
return found;
found++; /* go to next struct in array */
}
/* not found */
return NULL;
}
bool
vshConnectionUsability(vshControl *ctl, virConnectPtr conn)
{
/* TODO: use something like virConnectionState() to
* check usability of the connection
2005-12-08 10:23:34 +00:00
*/
if (!conn) {
vshError(ctl, "%s", _("no valid connection"));
return false;
2005-12-08 10:23:34 +00:00
}
return true;
2005-12-08 10:23:34 +00:00
}
void
2008-08-01 13:51:18 +00:00
vshDebug(vshControl *ctl, int level, const char *format, ...)
{
2006-05-22 14:38:33 +00:00
va_list ap;
char *str;
2006-05-22 14:38:33 +00:00
/* Aligning log levels to that of libvirt.
* Traces with levels >= user-specified-level
* gets logged into file
*/
if (level < ctl->debug)
return;
va_start(ap, format);
vshOutputLogFile(ctl, level, format, ap);
va_end(ap);
2006-05-22 14:38:33 +00:00
va_start(ap, format);
if (virVasprintf(&str, format, ap) < 0) {
/* Skip debug messages on low memory */
va_end(ap);
return;
}
2006-05-22 14:38:33 +00:00
va_end(ap);
fputs(str, stdout);
VIR_FREE(str);
2005-12-08 10:23:34 +00:00
}
void
2008-08-01 13:51:18 +00:00
vshPrintExtra(vshControl *ctl, const char *format, ...)
{
2005-12-08 10:23:34 +00:00
va_list ap;
char *str;
if (ctl && ctl->quiet)
2005-12-08 10:23:34 +00:00
return;
2005-12-08 10:23:34 +00:00
va_start(ap, format);
if (virVasprintf(&str, format, ap) < 0) {
vshError(ctl, "%s", _("Out of memory"));
va_end(ap);
return;
}
2005-12-08 10:23:34 +00:00
va_end(ap);
fputs(str, stdout);
VIR_FREE(str);
2005-12-08 10:23:34 +00:00
}
2006-05-22 14:38:33 +00:00
void
vshError(vshControl *ctl, const char *format, ...)
{
2005-12-08 10:23:34 +00:00
va_list ap;
char *str;
if (ctl != NULL) {
va_start(ap, format);
vshOutputLogFile(ctl, VSH_ERR_ERROR, format, ap);
va_end(ap);
}
/* Most output is to stdout, but if someone ran virsh 2>&1, then
* printing to stderr will not interleave correctly with stdout
* unless we flush between every transition between streams. */
fflush(stdout);
fputs(_("error: "), stderr);
2005-12-08 10:23:34 +00:00
va_start(ap, format);
/* We can't recursively call vshError on an OOM situation, so ignore
failure here. */
ignore_value(virVasprintf(&str, format, ap));
2005-12-08 10:23:34 +00:00
va_end(ap);
fprintf(stderr, "%s\n", NULLSTR(str));
fflush(stderr);
VIR_FREE(str);
2005-12-08 10:23:34 +00:00
}
static void
vshEventLoop(void *opaque)
{
vshControl *ctl = opaque;
while (1) {
bool quit;
virMutexLock(&ctl->lock);
quit = ctl->quit;
virMutexUnlock(&ctl->lock);
if (quit)
break;
if (virEventRunDefaultImpl() < 0)
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshReportError(ctl);
}
}
2005-12-08 10:23:34 +00:00
/*
* Initialize connection.
2005-12-08 10:23:34 +00:00
*/
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
static bool
2008-08-01 13:51:18 +00:00
vshInit(vshControl *ctl)
{
char *debugEnv;
2005-12-08 10:23:34 +00:00
if (ctl->conn)
return false;
2005-12-08 10:23:34 +00:00
if (ctl->debug == VSH_DEBUG_DEFAULT) {
/* log level not set from commandline, check env variable */
debugEnv = getenv("VIRSH_DEBUG");
if (debugEnv) {
int debug;
if (virStrToLong_i(debugEnv, NULL, 10, &debug) < 0 ||
debug < VSH_ERR_DEBUG || debug > VSH_ERR_ERROR) {
vshError(ctl, "%s",
_("VIRSH_DEBUG not set with a valid numeric value"));
} else {
ctl->debug = debug;
}
}
}
if (ctl->logfile == NULL) {
/* log file not set from cmdline */
debugEnv = getenv("VIRSH_LOG_FILE");
if (debugEnv && *debugEnv) {
ctl->logfile = vshStrdup(ctl, debugEnv);
}
}
vshOpenLogFile(ctl);
/* set up the library error handler */
virSetErrorFunc(NULL, virshErrorHandler);
if (virEventRegisterDefaultImpl() < 0)
return false;
if (virThreadCreate(&ctl->eventLoop, true, vshEventLoop, ctl) < 0)
return false;
ctl->eventLoopStarted = true;
if (ctl->name) {
ctl->conn = virConnectOpenAuth(ctl->name,
virConnectAuthPtrDefault,
ctl->readonly ? VIR_CONNECT_RO : 0);
/* 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).
*/
if (!ctl->conn) {
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
vshReportError(ctl);
vshError(ctl, "%s", _("failed to connect to the hypervisor"));
return false;
}
}
2005-12-08 10:23:34 +00:00
return true;
2005-12-08 10:23:34 +00:00
}
#define LOGFILE_FLAGS (O_WRONLY | O_APPEND | O_CREAT | O_SYNC)
/**
* vshOpenLogFile:
*
* Open log file.
*/
void
vshOpenLogFile(vshControl *ctl)
{
struct stat st;
if (ctl->logfile == NULL)
return;
/* check log file */
if (stat(ctl->logfile, &st) == -1) {
switch (errno) {
case ENOENT:
break;
default:
vshError(ctl, "%s",
_("failed to get the log file information"));
exit(EXIT_FAILURE);
}
} else {
if (!S_ISREG(st.st_mode)) {
vshError(ctl, "%s", _("the log path is not a file"));
exit(EXIT_FAILURE);
}
}
/* log file open */
if ((ctl->log_fd = open(ctl->logfile, LOGFILE_FLAGS, FILE_MODE)) < 0) {
vshError(ctl, "%s",
_("failed to open the log file. check the log file path"));
exit(EXIT_FAILURE);
}
}
/**
* vshOutputLogFile:
*
* Outputting an error to log file.
*/
void
vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format,
va_list ap)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *str;
size_t len;
const char *lvl = "";
struct timeval stTimeval;
struct tm *stTm;
if (ctl->log_fd == -1)
return;
/**
* create log format
*
* [YYYY.MM.DD HH:MM:SS SIGNATURE PID] LOG_LEVEL message
*/
gettimeofday(&stTimeval, NULL);
stTm = localtime(&stTimeval.tv_sec);
virBufferAsprintf(&buf, "[%d.%02d.%02d %02d:%02d:%02d %s %d] ",
(1900 + stTm->tm_year),
(1 + stTm->tm_mon),
stTm->tm_mday,
stTm->tm_hour,
stTm->tm_min,
stTm->tm_sec,
SIGN_NAME,
(int) getpid());
switch (log_level) {
case VSH_ERR_DEBUG:
lvl = LVL_DEBUG;
break;
case VSH_ERR_INFO:
lvl = LVL_INFO;
break;
case VSH_ERR_NOTICE:
lvl = LVL_INFO;
break;
case VSH_ERR_WARNING:
lvl = LVL_WARNING;
break;
case VSH_ERR_ERROR:
lvl = LVL_ERROR;
break;
default:
lvl = LVL_DEBUG;
break;
}
virBufferAsprintf(&buf, "%s ", lvl);
virBufferVasprintf(&buf, msg_format, ap);
virBufferAddChar(&buf, '\n');
if (virBufferError(&buf))
goto error;
str = virBufferContentAndReset(&buf);
len = strlen(str);
if (len > 1 && str[len - 2] == '\n') {
str[len - 1] = '\0';
len--;
}
/* write log */
if (safewrite(ctl->log_fd, str, len) < 0)
goto error;
return;
error:
vshCloseLogFile(ctl);
vshError(ctl, "%s", _("failed to write the log file"));
virBufferFreeAndReset(&buf);
VIR_FREE(str);
}
/**
* vshCloseLogFile:
*
* Close log file.
*/
void
vshCloseLogFile(vshControl *ctl)
{
/* log file close */
if (VIR_CLOSE(ctl->log_fd) < 0) {
vshError(ctl, _("%s: failed to write log file: %s"),
ctl->logfile ? ctl->logfile : "?", strerror (errno));
}
if (ctl->logfile) {
VIR_FREE(ctl->logfile);
ctl->logfile = NULL;
}
}
#ifdef USE_READLINE
2005-12-08 10:23:34 +00:00
/* -----------------
* Readline stuff
* -----------------
*/
/*
2005-12-08 10:23:34 +00:00
* Generator function for command completion. STATE lets us
* know whether to start from scratch; without any state
* (i.e. STATE == 0), then we start at the top of the list.
2005-12-08 10:23:34 +00:00
*/
static char *
vshReadlineCommandGenerator(const char *text, int state)
{
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
static int grp_list_index, cmd_list_index, len;
2005-12-08 14:22:52 +00:00
const char *name;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
const vshCmdGrp *grp;
const vshCmdDef *cmds;
2005-12-08 10:23:34 +00:00
if (!state) {
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
grp_list_index = 0;
cmd_list_index = 0;
len = strlen(text);
2005-12-08 10:23:34 +00:00
}
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
grp = cmdGroups;
2005-12-08 10:23:34 +00:00
/* Return the next name which partially matches from the
* command list.
2005-12-08 10:23:34 +00:00
*/
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
while (grp[grp_list_index].name) {
cmds = grp[grp_list_index].commands;
if (cmds[cmd_list_index].name) {
while ((name = cmds[cmd_list_index].name)) {
cmd_list_index++;
if (STREQLEN(name, text, len))
return vshStrdup(NULL, name);
}
} else {
cmd_list_index = 0;
grp_list_index++;
}
2005-12-08 10:23:34 +00:00
}
/* If no names matched, then return NULL. */
return NULL;
}
static char *
vshReadlineOptionsGenerator(const char *text, int state)
{
2005-12-08 10:23:34 +00:00
static int list_index, len;
static const vshCmdDef *cmd = NULL;
2005-12-08 14:22:52 +00:00
const char *name;
2005-12-08 10:23:34 +00:00
if (!state) {
/* determine command name */
char *p;
char *cmdname;
if (!(p = strchr(rl_line_buffer, ' ')))
return NULL;
cmdname = vshCalloc(NULL, (p - rl_line_buffer) + 1, 1);
memcpy(cmdname, rl_line_buffer, p - rl_line_buffer);
2005-12-08 10:23:34 +00:00
cmd = vshCmddefSearch(cmdname);
list_index = 0;
len = strlen(text);
VIR_FREE(cmdname);
2005-12-08 10:23:34 +00:00
}
if (!cmd)
return NULL;
if (!cmd->opts)
return NULL;
2005-12-08 14:22:52 +00:00
while ((name = cmd->opts[list_index].name)) {
const vshCmdOptDef *opt = &cmd->opts[list_index];
2005-12-08 10:23:34 +00:00
char *res;
2005-12-08 10:23:34 +00:00
list_index++;
if (opt->type == VSH_OT_DATA || opt->type == VSH_OT_ARGV)
2005-12-08 10:23:34 +00:00
/* ignore non --option */
continue;
2005-12-08 10:23:34 +00:00
if (len > 2) {
if (STRNEQLEN(name, text + 2, len - 2))
2005-12-08 10:23:34 +00:00
continue;
}
res = vshMalloc(NULL, strlen(name) + 3);
snprintf(res, strlen(name) + 3, "--%s", name);
2005-12-08 10:23:34 +00:00
return res;
}
/* If no names matched, then return NULL. */
return NULL;
}
static char **
vshReadlineCompletion(const char *text, int start,
int end ATTRIBUTE_UNUSED)
{
2005-12-08 10:23:34 +00:00
char **matches = (char **) NULL;
if (start == 0)
2005-12-08 10:23:34 +00:00
/* command name generator */
matches = rl_completion_matches(text, vshReadlineCommandGenerator);
2005-12-08 10:23:34 +00:00
else
/* commands options */
matches = rl_completion_matches(text, vshReadlineOptionsGenerator);
2005-12-08 10:23:34 +00:00
return matches;
}
static int
vshReadlineInit(vshControl *ctl)
{
char *userdir = NULL;
2005-12-08 10:23:34 +00:00
/* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name = "virsh";
/* Tell the completer that we want a crack first. */
rl_attempted_completion_function = vshReadlineCompletion;
/* Limit the total size of the history buffer */
stifle_history(500);
/* Prepare to read/write history from/to the $XDG_CACHE_HOME/virsh/history file */
userdir = virGetUserCacheDirectory();
if (userdir == NULL) {
vshError(ctl, "%s", _("Could not determine home directory"));
return -1;
}
if (virAsprintf(&ctl->historydir, "%s/virsh", userdir) < 0) {
vshError(ctl, "%s", _("Out of memory"));
VIR_FREE(userdir);
return -1;
}
if (virAsprintf(&ctl->historyfile, "%s/history", ctl->historydir) < 0) {
vshError(ctl, "%s", _("Out of memory"));
VIR_FREE(userdir);
return -1;
}
VIR_FREE(userdir);
read_history(ctl->historyfile);
return 0;
}
static void
vshReadlineDeinit(vshControl *ctl)
{
if (ctl->historyfile != NULL) {
if (virFileMakePathWithMode(ctl->historydir, 0755) < 0 &&
errno != EEXIST) {
char ebuf[1024];
vshError(ctl, _("Failed to create '%s': %s"),
ctl->historydir, virStrerror(errno, ebuf, sizeof(ebuf)));
} else {
write_history(ctl->historyfile);
}
}
VIR_FREE(ctl->historydir);
VIR_FREE(ctl->historyfile);
2005-12-08 10:23:34 +00:00
}
static char *
vshReadline(vshControl *ctl ATTRIBUTE_UNUSED, const char *prompt)
{
return readline(prompt);
}
#else /* !USE_READLINE */
static int
vshReadlineInit(vshControl *ctl ATTRIBUTE_UNUSED)
{
/* empty */
return 0;
}
static void
vshReadlineDeinit(vshControl *ctl ATTRIBUTE_UNUSED)
{
/* empty */
}
static char *
vshReadline(vshControl *ctl, const char *prompt)
{
char line[1024];
char *r;
int len;
fputs(prompt, stdout);
r = fgets(line, sizeof(line), stdin);
if (r == NULL) return NULL; /* EOF */
/* Chomp trailing \n */
len = strlen(r);
if (len > 0 && r[len-1] == '\n')
r[len-1] = '\0';
return vshStrdup(ctl, r);
}
#endif /* !USE_READLINE */
static void
vshDeinitTimer(int timer ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED)
{
/* nothing to be done here */
}
2005-12-08 10:23:34 +00:00
/*
* Deinitialize virsh
2005-12-08 10:23:34 +00:00
*/
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
static bool
2008-08-01 13:51:18 +00:00
vshDeinit(vshControl *ctl)
{
vshReadlineDeinit(ctl);
vshCloseLogFile(ctl);
VIR_FREE(ctl->name);
2005-12-08 10:23:34 +00:00
if (ctl->conn) {
int ret;
if ((ret = virConnectClose(ctl->conn)) != 0) {
vshError(ctl, _("Failed to disconnect from the hypervisor, %d leaked reference(s)"), ret);
2005-12-08 10:23:34 +00:00
}
}
2007-12-01 15:45:25 +00:00
virResetLastError();
if (ctl->eventLoopStarted) {
int timer;
virMutexLock(&ctl->lock);
ctl->quit = true;
/* HACK: Add a dummy timeout to break event loop */
timer = virEventAddTimeout(0, vshDeinitTimer, NULL, NULL);
virMutexUnlock(&ctl->lock);
virThreadJoin(&ctl->eventLoop);
if (timer != -1)
virEventRemoveTimeout(timer);
ctl->eventLoopStarted = false;
}
virMutexDestroy(&ctl->lock);
return true;
2005-12-08 10:23:34 +00:00
}
2005-12-08 10:23:34 +00:00
/*
* Print usage
*/
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
static void
vshUsage(void)
{
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
const vshCmdGrp *grp;
const vshCmdDef *cmd;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
fprintf(stdout, _("\n%s [options]... [<command_string>]"
"\n%s [options]... <command> [args...]\n\n"
" options:\n"
" -c | --connect=URI hypervisor connection URI\n"
" -r | --readonly connect readonly\n"
" -d | --debug=NUM debug level [0-4]\n"
" -h | --help this help\n"
" -q | --quiet quiet mode\n"
" -t | --timing print timing information\n"
" -l | --log=FILE output logging to file\n"
" -v short version\n"
" -V long version\n"
" --version[=TYPE] version, TYPE is short or long (default short)\n"
" -e | --escape <char> set escape sequence for console\n\n"
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
" commands (non interactive mode):\n\n"), progname, progname);
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
for (grp = cmdGroups; grp->name; grp++) {
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;
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
fprintf(stdout,
" %-30s %s\n", cmd->name,
_(vshCmddefGetInfo(cmd, "help")));
}
virsh: Categorize commands into groups for virsh help Change the virsh help out. The new output of "virsh help" and "virsh --help" will be like: Secret (help keyword 'secret'): secret-define define or modify a secret from an XML file secret-dumpxml secret attributes in XML secret-set-value set a secret value secret-get-value Output a secret value secret-undefine undefine a secret secret-list list secrets Snapshot (help keyword 'snapshot'): snapshot-create Create a snapshot snapshot-current Get the current snapshot snapshot-delete Delete a domain snapshot snapshot-dumpxml Dump XML for a domain snapshot snapshot-list List snapshots for a domain snapshot-revert Revert a domain to a snapshot Also support output help information of specified command group, e.g. % ./tools/virsh help "Network Filter" Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter Each group has a help keyword, e.g. % ./tools/virsh help filter Network Filter (help keyword 'filter'): nwfilter-define define or update a network filter from an XML file nwfilter-undefine undefine a network filter nwfilter-dumpxml network filter information in XML nwfilter-list list network filters nwfilter-edit edit XML configuration for a network filter * tools/virsh.c: - introduce new struct "vshCmdGrp" and macros to define the groups. - split previous array "commands" into small arrays which are orgnized by group - changed some functions, e.g. "vshCmdDefSearch" - Added new functions, e.g. "vshCmdGrpSearch" - commands of each group are in "alphabetical order" now. - command groups are in "alphabetical order" now. - the commands are categorized with reference of http://wiki.libvirt.org/page/VirshHelpV2 (by Justin) - the modifications doesn't affect tests * TODO: - doc
2010-11-30 06:37:04 +00:00
fprintf(stdout, "\n");
}
fprintf(stdout, "%s",
_("\n (specify help <group> for details about the commands in the group)\n"));
fprintf(stdout, "%s",
_("\n (specify help <command> for details about the command)\n\n"));
return;
2005-12-08 10:23:34 +00:00
}
/*
* Show version and options compiled in
*/
static void
vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
{
/* 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/");
vshPrint(ctl, "%s", _("Compiled with support for:\n"));
vshPrint(ctl, "%s", _(" Hypervisors:"));
#ifdef WITH_QEMU
vshPrint(ctl, " QEmu/KVM");
#endif
#ifdef WITH_LXC
vshPrint(ctl, " LXC");
#endif
#ifdef WITH_UML
vshPrint(ctl, " UML");
#endif
#ifdef WITH_XEN
vshPrint(ctl, " Xen");
#endif
#ifdef WITH_LIBXL
vshPrint(ctl, " LibXL");
#endif
#ifdef WITH_OPENVZ
vshPrint(ctl, " OpenVZ");
#endif
#ifdef WITH_VMWARE
vshPrint(ctl, " VMWare");
#endif
#ifdef WITH_PHYP
vshPrint(ctl, " PHYP");
#endif
#ifdef WITH_VBOX
vshPrint(ctl, " VirtualBox");
#endif
#ifdef WITH_ESX
vshPrint(ctl, " ESX");
#endif
#ifdef WITH_HYPERV
vshPrint(ctl, " Hyper-V");
#endif
#ifdef WITH_XENAPI
vshPrint(ctl, " XenAPI");
#endif
#ifdef WITH_TEST
vshPrint(ctl, " Test");
#endif
vshPrint(ctl, "\n");
vshPrint(ctl, "%s", _(" Networking:"));
#ifdef WITH_REMOTE
vshPrint(ctl, " Remote");
#endif
#ifdef WITH_LIBVIRTD
vshPrint(ctl, " Daemon");
#endif
#ifdef WITH_NETWORK
vshPrint(ctl, " Network");
#endif
#ifdef WITH_BRIDGE
vshPrint(ctl, " Bridging");
#endif
#ifdef WITH_NETCF
vshPrint(ctl, " Interface");
#endif
#ifdef WITH_NWFILTER
vshPrint(ctl, " Nwfilter");
#endif
#ifdef WITH_VIRTUALPORT
vshPrint(ctl, " VirtualPort");
#endif
vshPrint(ctl, "\n");
vshPrint(ctl, "%s", _(" Storage:"));
#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");
#endif
#ifdef WITH_STORAGE_RBD
vshPrint(ctl, " RBD");
#endif
#ifdef WITH_STORAGE_SHEEPDOG
vshPrint(ctl, " Sheepdog");
#endif
vshPrint(ctl, "\n");
vshPrint(ctl, "%s", _(" Miscellaneous:"));
#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
#ifdef USE_READLINE
vshPrint(ctl, " Readline");
#endif
#ifdef WITH_DRIVER_MODULES
vshPrint(ctl, " Modular");
#endif
vshPrint(ctl, "\n");
}
static bool
vshAllowedEscapeChar(char c)
{
/* Allowed escape characters:
* a-z A-Z @ [ \ ] ^ _
*/
return ('a' <= c && c <= 'z') ||
('@' <= c && c <= '_');
}
/*
* argv[]: virsh [options] [command]
*
*/
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
static bool
vshParseArgv(vshControl *ctl, int argc, char **argv)
{
int arg, len, debug;
struct option opt[] = {
{"debug", required_argument, NULL, 'd'},
{"help", no_argument, NULL, 'h'},
{"quiet", no_argument, NULL, 'q'},
{"timing", no_argument, NULL, 't'},
{"version", optional_argument, NULL, 'v'},
{"connect", required_argument, NULL, 'c'},
{"readonly", no_argument, NULL, 'r'},
{"log", required_argument, NULL, 'l'},
{"escape", required_argument, NULL, 'e'},
{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. */
while ((arg = getopt_long(argc, argv, "+d:hqtc:vVrl:e:", opt, NULL)) != -1) {
switch (arg) {
case 'd':
if (virStrToLong_i(optarg, NULL, 10, &debug) < 0) {
vshError(ctl, "%s", _("option -d takes a numeric argument"));
exit(EXIT_FAILURE);
}
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;
break;
case 'h':
vshUsage();
exit(EXIT_SUCCESS);
break;
case 'q':
ctl->quiet = true;
break;
case 't':
ctl->timing = true;
break;
case 'c':
ctl->name = vshStrdup(ctl, optarg);
break;
case 'v':
if (STRNEQ_NULLABLE(optarg, "long")) {
puts(VERSION);
exit(EXIT_SUCCESS);
}
/* fall through */
case 'V':
vshShowVersion(ctl);
exit(EXIT_SUCCESS);
case 'r':
ctl->readonly = true;
break;
case 'l':
ctl->logfile = vshStrdup(ctl, optarg);
break;
case 'e':
len = strlen(optarg);
if ((len == 2 && *optarg == '^' &&
vshAllowedEscapeChar(optarg[1])) ||
(len == 1 && *optarg != '^')) {
ctl->escapeChar = optarg;
} else {
vshError(ctl, _("Invalid string '%s' for escape sequence"),
optarg);
exit(EXIT_FAILURE);
}
break;
default:
vshError(ctl, _("unsupported option '-%c'. See --help."), arg);
exit(EXIT_FAILURE);
}
}
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;
}
#include "virsh-snapshot.c"
#include "virsh-volume.c"
static const vshCmdDef virshCmds[] = {
{"cd", cmdCd, opts_cd, info_cd, VSH_CMD_FLAG_NOCONNECT},
{"echo", cmdEcho, opts_echo, info_echo, VSH_CMD_FLAG_NOCONNECT},
{"exit", cmdQuit, NULL, info_quit, VSH_CMD_FLAG_NOCONNECT},
{"help", cmdHelp, opts_help, info_help, VSH_CMD_FLAG_NOCONNECT},
{"pwd", cmdPwd, NULL, info_pwd, VSH_CMD_FLAG_NOCONNECT},
{"quit", cmdQuit, NULL, info_quit, VSH_CMD_FLAG_NOCONNECT},
{NULL, NULL, NULL, NULL, 0}
};
static const vshCmdGrp cmdGroups[] = {
{VSH_CMD_GRP_DOM_MANAGEMENT, "domain", domManagementCmds},
{VSH_CMD_GRP_DOM_MONITORING, "monitor", domMonitoringCmds},
{VSH_CMD_GRP_HOST_AND_HV, "host", hostAndHypervisorCmds},
{VSH_CMD_GRP_IFACE, "interface", ifaceCmds},
{VSH_CMD_GRP_NWFILTER, "filter", nwfilterCmds},
{VSH_CMD_GRP_NETWORK, "network", networkCmds},
{VSH_CMD_GRP_NODEDEV, "nodedev", nodedevCmds},
{VSH_CMD_GRP_SECRET, "secret", secretCmds},
{VSH_CMD_GRP_SNAPSHOT, "snapshot", snapshotCmds},
{VSH_CMD_GRP_STORAGE_POOL, "pool", storagePoolCmds},
{VSH_CMD_GRP_STORAGE_VOL, "volume", storageVolCmds},
{VSH_CMD_GRP_VIRSH, "virsh", virshCmds},
{NULL, NULL, NULL}
};
2005-12-08 10:23:34 +00:00
int
main(int argc, char **argv)
{
vshControl _ctl, *ctl = &_ctl;
char *defaultConn;
bool ret = true;
2005-12-08 10:23:34 +00:00
memset(ctl, 0, sizeof(vshControl));
ctl->imode = true; /* default is interactive mode */
ctl->log_fd = -1; /* Initialize log file descriptor */
ctl->debug = VSH_DEBUG_DEFAULT;
virsh: use common namespacing Convert the exported items in virsh.h to use a common 'vsh' prefix. * tools/virsh.h (VIRSH_MAX_XML_FILE): Rename... (VSH_MAX_XML_FILE): ...and parenthesize. (DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete. (vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype. (editWriteToTempFile, editFile, editReadBackFile, prettyCapacity) (virshReportError): Rename... (vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile) (vshPrettyCapacity, vshReportError): ...into vsh namespace. (jobWatchTimeoutFunc): Move to virsh-domain.c. * tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC. (main): Inline former CTRL_CLOSE_BRACKET. (vshUsage, vshInit, vshDeinit, vshParseArgv): Make static. (prettyCapacity, virshReportError, editWriteToTempFile, editFile): Fix naming, and adjust usage. (vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust usage. * tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare) (cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice) (cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount) (cmdAttachDevice, cmdDomjobinfo): Likewise. * tools/virsh-edit.c (do): Likewise. * tools/virsh-interface.c (cmdInterfaceDefine): Likewise. * tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine): Likewise. * tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise. * tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise. * tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine) (cmdPoolDiscoverSources, cmdPoolList): Likewise. * tools/virsh-secret.c (cmdSecretDefine): Likewise. * tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate) (vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent) (vshGetSnapshotParent): Likewise. * tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom) (cmdVolInfo, cmdVolList): Likewise.
2012-08-19 04:10:17 +00:00
ctl->escapeChar = "^]"; /* Same default as telnet */
if (!setlocale(LC_ALL, "")) {
perror("setlocale");
2009-01-29 11:49:33 +00:00
/* failure to setup locale is not fatal */
}
maint: use gnulib configmake rather than open-coding things * bootstrap.conf (gnulib_modules): Add configmake. * daemon/Makefile.am (libvirtd_CFLAGS): Drop defines provided by gnulib. * src/Makefile.am (INCLUDES): Likewise. * tests/Makefile.am (INCLUDES): Likewise. * tools/Makefile.am (virsh_CFLAGS): Likewise. * daemon/libvirtd.c (qemudInitPaths, usage, main): Update clients. * src/cpu/cpu_map.c (CPUMAPFILE): Likewise. * src/driver.c (DEFAULT_DRIVER_DIR): Likewise. * src/internal.h (_): Likewise. * src/libvirt.c (virInitialize): Likewise. * src/lxc/lxc_conf.h (LXC_CONFIG_DIR, LXC_STATE_DIR, LXC_LOG_DIR): Likewise. * src/lxc/lxc_conf.c (lxcCapsInit, lxcLoadDriverConfig): Likewise. * src/network/bridge_driver.c (NETWORK_PID_DIR) (NETWORK_STATE_DIR, DNSMASQ_STATE_DIR, networkStartup): Likewise. * src/nwfilter/nwfilter_driver.c (nwfilterDriverStartup): Likewise. * src/qemu/qemu_conf.c (qemudLoadDriverConfig): Likewise. * src/qemu/qemu_driver.c (qemudStartup): Likewise. * src/remote/remote_driver.h (LIBVIRTD_PRIV_UNIX_SOCKET) (LIBVIRTD_PRIV_UNIX_SOCKET_RO, LIBVIRTD_CONFIGURATION_FILE) (LIBVIRT_PKI_DIR): Likewise. * src/secret/secret_driver.c (secretDriverStartup): Likewise. * src/security/security_apparmor.c (VIRT_AA_HELPER): Likewise. * src/security/virt-aa-helper.c (main): Likewise. * src/storage/storage_backend_disk.c (PARTHELPER): Likewise. * src/storage/storage_driver.c (storageDriverStartup): Likewise. * src/uml/uml_driver.c (TEMPDIR, umlStartup): Likewise. * src/util/hooks.c (LIBVIRT_HOOK_DIR): Likewise. * tools/virsh.c (main): Likewise. * docs/hooks.html.in: Likewise.
2010-11-16 14:54:17 +00:00
if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
perror("bindtextdomain");
return EXIT_FAILURE;
}
maint: use gnulib configmake rather than open-coding things * bootstrap.conf (gnulib_modules): Add configmake. * daemon/Makefile.am (libvirtd_CFLAGS): Drop defines provided by gnulib. * src/Makefile.am (INCLUDES): Likewise. * tests/Makefile.am (INCLUDES): Likewise. * tools/Makefile.am (virsh_CFLAGS): Likewise. * daemon/libvirtd.c (qemudInitPaths, usage, main): Update clients. * src/cpu/cpu_map.c (CPUMAPFILE): Likewise. * src/driver.c (DEFAULT_DRIVER_DIR): Likewise. * src/internal.h (_): Likewise. * src/libvirt.c (virInitialize): Likewise. * src/lxc/lxc_conf.h (LXC_CONFIG_DIR, LXC_STATE_DIR, LXC_LOG_DIR): Likewise. * src/lxc/lxc_conf.c (lxcCapsInit, lxcLoadDriverConfig): Likewise. * src/network/bridge_driver.c (NETWORK_PID_DIR) (NETWORK_STATE_DIR, DNSMASQ_STATE_DIR, networkStartup): Likewise. * src/nwfilter/nwfilter_driver.c (nwfilterDriverStartup): Likewise. * src/qemu/qemu_conf.c (qemudLoadDriverConfig): Likewise. * src/qemu/qemu_driver.c (qemudStartup): Likewise. * src/remote/remote_driver.h (LIBVIRTD_PRIV_UNIX_SOCKET) (LIBVIRTD_PRIV_UNIX_SOCKET_RO, LIBVIRTD_CONFIGURATION_FILE) (LIBVIRT_PKI_DIR): Likewise. * src/secret/secret_driver.c (secretDriverStartup): Likewise. * src/security/security_apparmor.c (VIRT_AA_HELPER): Likewise. * src/security/virt-aa-helper.c (main): Likewise. * src/storage/storage_backend_disk.c (PARTHELPER): Likewise. * src/storage/storage_driver.c (storageDriverStartup): Likewise. * src/uml/uml_driver.c (TEMPDIR, umlStartup): Likewise. * src/util/hooks.c (LIBVIRT_HOOK_DIR): Likewise. * tools/virsh.c (main): Likewise. * docs/hooks.html.in: Likewise.
2010-11-16 14:54:17 +00:00
if (!textdomain(PACKAGE)) {
perror("textdomain");
return EXIT_FAILURE;
}
if (virMutexInit(&ctl->lock) < 0) {
vshError(ctl, "%s", _("Failed to initialize mutex"));
return EXIT_FAILURE;
}
if (virInitialize() < 0) {
vshError(ctl, "%s", _("Failed to initialize libvirt"));
return EXIT_FAILURE;
}
if (!(progname = strrchr(argv[0], '/')))
2005-12-08 10:23:34 +00:00
progname = argv[0];
else
progname++;
if ((defaultConn = getenv("VIRSH_DEFAULT_CONNECT_URI"))) {
ctl->name = vshStrdup(ctl, defaultConn);
}
2007-12-01 15:45:25 +00:00
if (!vshParseArgv(ctl, argc, argv)) {
vshDeinit(ctl);
2005-12-08 10:23:34 +00:00
exit(EXIT_FAILURE);
2007-12-01 15:45:25 +00:00
}
2007-12-01 15:45:25 +00:00
if (!vshInit(ctl)) {
vshDeinit(ctl);
2005-12-08 10:23:34 +00:00
exit(EXIT_FAILURE);
2007-12-01 15:45:25 +00:00
}
2005-12-08 10:23:34 +00:00
if (!ctl->imode) {
ret = vshCommandRun(ctl, ctl->cmd);
} else {
2005-12-08 10:23:34 +00:00
/* interactive mode */
if (!ctl->quiet) {
2006-05-22 14:38:33 +00:00
vshPrint(ctl,
_("Welcome to %s, the virtualization interactive terminal.\n\n"),
progname);
vshPrint(ctl, "%s",
_("Type: 'help' for help with commands\n"
" 'quit' to quit\n\n"));
2005-12-08 10:23:34 +00:00
}
if (vshReadlineInit(ctl) < 0) {
vshDeinit(ctl);
exit(EXIT_FAILURE);
}
2005-12-08 10:23:34 +00:00
do {
const char *prompt = ctl->readonly ? VSH_PROMPT_RO : VSH_PROMPT_RW;
ctl->cmdstr =
vshReadline(ctl, prompt);
if (ctl->cmdstr == NULL)
break; /* EOF */
2005-12-08 10:23:34 +00:00
if (*ctl->cmdstr) {
#if USE_READLINE
2005-12-08 10:23:34 +00:00
add_history(ctl->cmdstr);
#endif
if (vshCommandStringParse(ctl, ctl->cmdstr))
2005-12-08 10:23:34 +00:00
vshCommandRun(ctl, ctl->cmd);
}
VIR_FREE(ctl->cmdstr);
} while (ctl->imode);
2005-12-08 10:23:34 +00:00
if (ctl->cmdstr == NULL)
fputc('\n', stdout); /* line break after alone prompt */
2005-12-08 10:23:34 +00:00
}
2005-12-08 10:23:34 +00:00
vshDeinit(ctl);
exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
}