Virt shell (vsh) started as a copy of virsh, but it needs to be split from virsh, so remove all virsh specific data that cannot/need not be used with other potential clients like virt-admin --- tools/vsh.c | 1505 +---------------------------------------------------------- tools/vsh.h | 66 +-- 2 files changed, 9 insertions(+), 1562 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index 609c8f3..8ef04b9 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -32,7 +32,6 @@ #include <stdarg.h> #include <unistd.h> #include <errno.h> -#include <getopt.h> #include <sys/time.h> #include "c-ctype.h" #include <fcntl.h> @@ -63,27 +62,12 @@ #include "virtypedparam.h" #include "virstring.h" -#include "virsh-console.h" -#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" -#include "virsh-snapshot.h" -#include "virsh-volume.h" - /* Gnulib doesn't guarantee SA_SIGINFO support. */ #ifndef SA_SIGINFO # define SA_SIGINFO 0 #endif -static char *progname; - -static const vshCmdGrp cmdGroups[]; +static const vshCmdGrp *cmdGroups; /* Bypass header poison */ #undef strdup @@ -138,44 +122,6 @@ vshNameSorter(const void *a, const void *b) return vshStrcasecmp(*sa, *sb); } -double -vshPrettyCapacity(unsigned long long val, const char **unit) -{ - double limit = 1024; - - if (val < limit) { - *unit = "B"; - return val; - } - limit *= 1024; - if (val < limit) { - *unit = "KiB"; - return val / (limit / 1024); - } - limit *= 1024; - if (val < limit) { - *unit = "MiB"; - return val / (limit / 1024); - } - limit *= 1024; - if (val < limit) { - *unit = "GiB"; - return val / (limit / 1024); - } - limit *= 1024; - if (val < limit) { - *unit = "TiB"; - return val / (limit / 1024); - } - limit *= 1024; - if (val < limit) { - *unit = "PiB"; - return val / (limit / 1024); - } - limit *= 1024; - *unit = "EiB"; - return val / (limit / 1024); -} /* * Convert the strings separated by ',' into array. The returned @@ -299,743 +245,14 @@ vshReportError(vshControl *ctl) vshError(ctl, "%s", last_error->message); - out: - vshResetLibvirtError(); -} - -/* - * Detection of disconnections and automatic reconnection support - */ -static int disconnected; /* 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++; -} - -/* Main Function which should be used for connecting. - * This function properly handles keepalive settings. */ -virConnectPtr -vshConnect(vshControl *ctl, const char *uri, bool readonly) -{ - virConnectPtr c = NULL; - int interval = 5; /* Default */ - int count = 6; /* Default */ - bool keepalive_forced = false; - - if (ctl->keepalive_interval >= 0) { - interval = ctl->keepalive_interval; - keepalive_forced = true; - } - if (ctl->keepalive_count >= 0) { - count = ctl->keepalive_count; - keepalive_forced = true; - } - - c = virConnectOpenAuth(uri, virConnectAuthPtrDefault, - readonly ? VIR_CONNECT_RO : 0); - if (!c) - return NULL; - - if (interval > 0 && - virConnectSetKeepAlive(c, interval, count) != 0) { - if (keepalive_forced) { - vshError(ctl, "%s", - _("Cannot setup keepalive on connection " - "as requested, disconnecting")); - virConnectClose(c); - return NULL; - } - vshDebug(ctl, VSH_ERR_INFO, "%s", - _("Failed to setup keepalive on connection\n")); - } - - return c; -} - -/* - * vshReconnect: - * - * Reconnect after a disconnect from libvirtd - * - */ -static void -vshReconnect(vshControl *ctl) -{ - bool connected = false; - - if (ctl->conn) { - int ret; - - connected = true; - - virConnectUnregisterCloseCallback(ctl->conn, vshCatchDisconnect); - ret = virConnectClose(ctl->conn); - if (ret < 0) - vshError(ctl, "%s", _("Failed to disconnect from the hypervisor")); - else if (ret > 0) - vshError(ctl, "%s", _("One or more references were leaked after " - "disconnect from the hypervisor")); - } - - ctl->conn = vshConnect(ctl, ctl->name, ctl->readonly); - - if (!ctl->conn) { - if (disconnected) - vshError(ctl, "%s", _("Failed to reconnect to the hypervisor")); - else - vshError(ctl, "%s", _("failed to connect 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; - ctl->blockJobNoBytes = false; -} - - -/* - * "connect" command - */ -static const vshCmdInfo info_connect[] = { - {.name = "help", - .data = N_("(re)connect to hypervisor") - }, - {.name = "desc", - .data = N_("Connect to local hypervisor. This is built-in " - "command after shell start up.") - }, - {.name = NULL} -}; - -static const vshCmdOptDef opts_connect[] = { - {.name = "name", - .type = VSH_OT_STRING, - .flags = VSH_OFLAG_EMPTY_OK, - .help = N_("hypervisor connection URI") - }, - {.name = "readonly", - .type = VSH_OT_BOOL, - .help = N_("read-only connection") - }, - {.name = NULL} -}; - -static bool -cmdConnect(vshControl *ctl, const vshCmd *cmd) -{ - bool ro = vshCommandOptBool(cmd, "readonly"); - const char *name = NULL; - - if (ctl->conn) { - int ret; - - virConnectUnregisterCloseCallback(ctl->conn, vshCatchDisconnect); - ret = virConnectClose(ctl->conn); - if (ret < 0) - vshError(ctl, "%s", _("Failed to disconnect from the hypervisor")); - else if (ret > 0) - vshError(ctl, "%s", _("One or more references were leaked after " - "disconnect from the hypervisor")); - ctl->conn = NULL; - } - - VIR_FREE(ctl->name); - if (vshCommandOptStringReq(ctl, cmd, "name", &name) < 0) - return false; - - ctl->name = vshStrdup(ctl, name); - - ctl->useGetInfo = false; - ctl->useSnapshotOld = false; - ctl->blockJobNoBytes = false; - ctl->readonly = ro; - - ctl->conn = vshConnect(ctl, ctl->name, ctl->readonly); - - if (!ctl->conn) { - vshError(ctl, "%s", _("Failed to connect to the hypervisor")); - return false; - } - - if (virConnectRegisterCloseCallback(ctl->conn, vshCatchDisconnect, - NULL, NULL) < 0) - vshError(ctl, "%s", _("Unable to register disconnect callback")); - - return true; -} - - -#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 - * 'n' if he doesn't want to - * 'i' if he wants to try defining it again while ignoring validation - * 'f' if he forcibly wants to - * -1 on error - * 0 otherwise - */ -int -vshAskReedit(vshControl *ctl, const char *msg, bool relax_avail) -{ - int c = -1; - - if (!isatty(STDIN_FILENO)) - return -1; - - vshReportError(ctl); - - if (vshTTYMakeRaw(ctl, false) < 0) - return -1; - - while (true) { - vshPrint(ctl, "\r%s %s %s: ", msg, _("Try again?"), - relax_avail ? "[y,n,i,f,?]" : "[y,n,f,?]"); - c = c_tolower(getchar()); - - if (c == '?') { - vshPrintRaw(ctl, - "", - _("y - yes, start editor again"), - _("n - no, throw away my changes"), - NULL); - - if (relax_avail) { - vshPrintRaw(ctl, - _("i - turn off validation and try to redefine again"), - NULL); - } - - vshPrintRaw(ctl, - _("f - force, try to redefine again"), - _("? - print this help"), - NULL); - continue; - } else if (c == 'y' || c == 'n' || c == 'f' || - (relax_avail && c == 'i')) { - break; - } - } - - vshTTYRestore(ctl); - - vshPrint(ctl, "\r\n"); - return c; -} -#else /* WIN32 */ -int -vshAskReedit(vshControl *ctl, - const char *msg ATTRIBUTE_UNUSED, - bool relax_avail 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); -} - -/* --------------- - * Commands - * --------------- - */ - -/* - * "help" command - */ -static const vshCmdInfo info_help[] = { - {.name = "help", - .data = N_("print help") - }, - {.name = "desc", - .data = N_("Prints global help, command specific help, or help for a\n" - " group of related commands") - }, - {.name = NULL} -}; - -static const vshCmdOptDef opts_help[] = { - {.name = "command", - .type = VSH_OT_STRING, - .help = N_("Prints global help, command specific help, or help for a group of related commands") - }, - {.name = NULL} -}; - -static bool -cmdHelp(vshControl *ctl, const vshCmd *cmd) - { - const char *name = NULL; - - if (vshCommandOptString(ctl, cmd, "command", &name) <= 0) { - const vshCmdGrp *grp; - const vshCmdDef *def; - - 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; - vshPrint(ctl, " %-30s %s\n", def->name, - _(vshCmddefGetInfo(def, "help"))); - } - - vshPrint(ctl, "\n"); - } - - return true; - } - - if (vshCmddefSearch(name)) { - return vshCmddefHelp(ctl, name); - } else if (vshCmdGrpSearch(name)) { - return vshCmdGrpHelp(ctl, name); - } else { - vshError(ctl, _("command or command group '%s' doesn't exist"), name); - return false; - } -} - -/* Tree listing helpers. */ - -static int -vshTreePrintInternal(vshControl *ctl, - vshTreeLookup lookup, - void *opaque, - int num_devices, - int devid, - int lastdev, - bool root, - virBufferPtr indent) -{ - size_t 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, " "); - if (virBufferError(indent)) - goto cleanup; - 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 * -vshEditWriteToTempFile(vshControl *ctl, const char *doc) -{ - char *ret; - const char *tmpdir; - int fd; - char ebuf[1024]; - - tmpdir = virGetEnvBlockSUID("TMPDIR"); - if (!tmpdir) tmpdir = "/tmp"; - if (virAsprintf(&ret, "%s/virshXXXXXX.xml", tmpdir) < 0) { - vshError(ctl, "%s", _("out of memory")); - return NULL; - } - fd = mkostemps(ret, 4, O_CLOEXEC); - if (fd == -1) { - vshError(ctl, _("mkostemps: failed to create temporary file: %s"), - virStrerror(errno, ebuf, sizeof(ebuf))); - VIR_FREE(ret); - return NULL; - } - - if (safewrite(fd, doc, strlen(doc)) == -1) { - vshError(ctl, _("write: %s: failed to write to temporary file: %s"), - ret, virStrerror(errno, ebuf, sizeof(ebuf))); - 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, virStrerror(errno, ebuf, sizeof(ebuf))); - 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 -vshEditFile(vshControl *ctl, const char *filename) -{ - const char *editor; - virCommandPtr cmd; - int ret = -1; - int outfd = STDOUT_FILENO; - int errfd = STDERR_FILENO; - - editor = virGetEnvBlockSUID("VISUAL"); - if (!editor) - editor = virGetEnvBlockSUID("EDITOR"); - if (!editor) - editor = DEFAULT_EDITOR; - - /* 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) { - vshReportError(ctl); - goto cleanup; - } - ret = 0; - - cleanup: - virCommandFree(cmd); - return ret; -} - -char * -vshEditReadBackFile(vshControl *ctl, const char *filename) -{ - char *ret; - char ebuf[1024]; - - if (virFileReadAll(filename, VSH_MAX_XML_FILE, &ret) == -1) { - vshError(ctl, - _("%s: failed to read temporary file: %s"), - filename, virStrerror(errno, ebuf, sizeof(ebuf))); - return NULL; - } - return ret; -} - - -/* - * "cd" command - */ -static const vshCmdInfo info_cd[] = { - {.name = "help", - .data = N_("change the current directory") - }, - {.name = "desc", - .data = N_("Change the current directory.") - }, - {.name = NULL} -}; - -static const vshCmdOptDef opts_cd[] = { - {.name = "dir", - .type = VSH_OT_STRING, - .help = N_("directory to switch to (default: home or else root)") - }, - {.name = NULL} -}; - -static bool -cmdCd(vshControl *ctl, const vshCmd *cmd) -{ - const char *dir = NULL; - char *dir_malloced = NULL; - bool ret = true; - char ebuf[1024]; - - if (!ctl->imode) { - vshError(ctl, "%s", _("cd: command valid only in interactive mode")); - return false; - } - - if (vshCommandOptString(ctl, cmd, "dir", &dir) <= 0) - dir = dir_malloced = virGetUserDirectory(); - if (!dir) - dir = "/"; - - if (chdir(dir) == -1) { - vshError(ctl, _("cd: %s: %s"), - virStrerror(errno, ebuf, sizeof(ebuf)), dir); - ret = false; - } - - VIR_FREE(dir_malloced); - return ret; -} - -/* - * "pwd" command - */ -static const vshCmdInfo info_pwd[] = { - {.name = "help", - .data = N_("print the current directory") - }, - {.name = "desc", - .data = N_("Print the current directory.") - }, - {.name = NULL} -}; - -static bool -cmdPwd(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) -{ - char *cwd; - bool ret = true; - char ebuf[1024]; - - cwd = getcwd(NULL, 0); - if (!cwd) { - vshError(ctl, _("pwd: cannot get current directory: %s"), - virStrerror(errno, ebuf, sizeof(ebuf))); - ret = false; - } else { - vshPrint(ctl, _("%s\n"), cwd); - VIR_FREE(cwd); - } - - return ret; -} - -/* - * "echo" command - */ -static const vshCmdInfo info_echo[] = { - {.name = "help", - .data = N_("echo arguments") - }, - {.name = "desc", - .data = N_("Echo back arguments, possibly with quoting.") - }, - {.name = NULL} -}; - -static const vshCmdOptDef opts_echo[] = { - {.name = "shell", - .type = VSH_OT_BOOL, - .help = N_("escape for shell use") - }, - {.name = "xml", - .type = VSH_OT_BOOL, - .help = N_("escape for XML use") - }, - {.name = "str", - .type = VSH_OT_ALIAS, - .help = "string" - }, - {.name = "hi", - .type = VSH_OT_ALIAS, - .help = "string=hello" - }, - {.name = "string", - .type = VSH_OT_ARGV, - .help = N_("arguments to echo") - }, - {.name = 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(ctl, cmd, opt))) { - char *str; - virBuffer xmlbuf = VIR_BUFFER_INITIALIZER; - - arg = opt->data; - - if (count) - virBufferAddChar(&buf, ' '); - - if (xml) { - virBufferEscapeString(&xmlbuf, "%s", arg); - if (virBufferError(&xmlbuf)) { - vshPrint(ctl, "%s", _("Failed to allocate XML buffer")); - return false; - } - str = virBufferContentAndReset(&xmlbuf); - } else { - str = vshStrdup(ctl, arg); - } - - if (shell) - virBufferEscapeShell(&buf, str); - else - virBufferAdd(&buf, str, -1); - count++; - 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; + out: + vshResetLibvirtError(); } /* - * "quit" command + * Detection of disconnections and automatic reconnection support */ -static const vshCmdInfo info_quit[] = { - {.name = "help", - .data = N_("quit this interactive terminal") - }, - {.name = "desc", - .data = "" - }, - {.name = NULL} -}; - -static bool -cmdQuit(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) -{ - ctl->imode = false; - return true; -} +static int disconnected; /* we may have been disconnected */ /* --------------- * Utils for work with command definition @@ -1906,56 +1123,6 @@ vshCommandOptArgv(vshControl *ctl ATTRIBUTE_UNUSED, const vshCmd *cmd, return NULL; } -/* - * vshCommandOptTimeoutToMs: - * @ctl virsh control structure - * @cmd command reference - * @timeout result - * - * Parse an optional --timeout parameter in seconds, but store the - * value of the timeout in milliseconds. - * See vshCommandOptInt() - */ -int -vshCommandOptTimeoutToMs(vshControl *ctl, const vshCmd *cmd, int *timeout) -{ - int ret; - unsigned int utimeout; - - if ((ret = vshCommandOptUInt(ctl, cmd, "timeout", &utimeout)) <= 0) - return ret; - - /* Ensure that the timeout is not zero and that we can convert - * it from seconds to milliseconds without overflowing. */ - if (utimeout == 0 || utimeout > INT_MAX / 1000) { - vshError(ctl, - _("Numeric value '%u' for <%s> option is malformed or out of range"), - utimeout, - "timeout"); - ret = -1; - } else { - *timeout = ((int) utimeout) * 1000; - } - - return ret; -} - -static bool -vshConnectionUsability(vshControl *ctl, virConnectPtr conn) -{ - if (!conn || - virConnectIsAlive(conn) == 0) { - vshError(ctl, "%s", _("no valid connection")); - return false; - } - - /* The connection is considered dead only if - * virConnectIsAlive() successfuly says so. - */ - vshResetLibvirtError(); - - return true; -} /* * Executes command(s) and returns return code from last command @@ -2187,13 +1354,14 @@ vshCommandParse(vshControl *ctl, vshCommandParser *parser) if (STRNEQ(tmpopt->def->name, "help")) continue; + const vshCmdDef *help = vshCmddefSearch("help"); vshCommandOptFree(first); first = vshMalloc(ctl, sizeof(vshCmdOpt)); - first->def = &(opts_help[0]); + first->def = help->opts; first->data = vshStrdup(ctl, cmd->name); first->next = NULL; - cmd = vshCmddefSearch("help"); + cmd = help; opts_required = 0; opts_seen = 0; break; @@ -2346,33 +1514,6 @@ vshCommandStringParse(vshControl *ctl, char *cmdstr) * Misc utils * --------------- */ -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. */ @@ -2803,49 +1944,6 @@ vshInitDebug(vshControl *ctl) } } -/* - * Initialize connection. - */ -static bool -vshInit(vshControl *ctl) -{ - /* Since we have the commandline arguments parsed, we need to - * re-initialize all the debugging to make it work properly */ - vshInitDebug(ctl); - - if (ctl->conn) - return false; - - /* 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->eventTimerId = virEventAddTimeout(-1, vshEventTimeout, ctl, - NULL)) < 0) - return false; - - if (ctl->name) { - vshReconnect(ctl); - /* 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) { - vshReportError(ctl); - return false; - } - } - - return true; -} #define LOGFILE_FLAGS (O_WRONLY | O_APPEND | O_CREAT | O_SYNC) @@ -3211,590 +2309,3 @@ vshReadline(vshControl *ctl, const char *prompt) } #endif /* !WITH_READLINE */ - -static void -vshDeinitTimer(int timer ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED) -{ - /* nothing to be done here */ -} - -/* - * Deinitialize virsh - */ -static bool -vshDeinit(vshControl *ctl) -{ - vshReadlineDeinit(ctl); - vshCloseLogFile(ctl); - VIR_FREE(ctl->name); - if (ctl->conn) { - int ret; - virConnectUnregisterCloseCallback(ctl->conn, vshCatchDisconnect); - ret = virConnectClose(ctl->conn); - if (ret < 0) - vshError(ctl, "%s", _("Failed to disconnect from the hypervisor")); - else if (ret > 0) - vshError(ctl, "%s", _("One or more references were leaked after " - "disconnect from the hypervisor")); - } - 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); - - if (ctl->eventTimerId != -1) - virEventRemoveTimeout(ctl->eventTimerId); - - ctl->eventLoopStarted = false; - } - - virMutexDestroy(&ctl->lock); - - return true; -} - -/* - * Print usage - */ -static void -vshUsage(void) -{ - const vshCmdGrp *grp; - const vshCmdDef *cmd; - - fprintf(stdout, _("\n%s [options]... [<command_string>]" - "\n%s [options]... <command> [args...]\n\n" - " options:\n" - " -c | --connect=URI hypervisor connection URI\n" - " -d | --debug=NUM debug level [0-4]\n" - " -e | --escape <char> set escape sequence for console\n" - " -h | --help this help\n" - " -k | --keepalive-interval=NUM\n" - " keepalive interval in seconds, 0 for disable\n" - " -K | --keepalive-count=NUM\n" - " number of possible missed keepalive messages\n" - " -l | --log=FILE output logging to file\n" - " -q | --quiet quiet mode\n" - " -r | --readonly connect readonly\n" - " -t | --timing print timing information\n" - " -v short version\n" - " -V long version\n" - " --version[=TYPE] version, TYPE is short or long (default short)\n" - " commands (non interactive mode):\n\n"), progname, progname); - - 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; - fprintf(stdout, - " %-30s %s\n", cmd->name, - _(vshCmddefGetInfo(cmd, "help"))); - } - 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; -} - -/* - * 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_BHYVE - vshPrint(ctl, " Bhyve"); -#endif -#ifdef WITH_TEST - vshPrint(ctl, " Test"); -#endif - vshPrint(ctl, "\n"); - - vshPrint(ctl, "%s", _(" Networking:")); -#ifdef WITH_REMOTE - vshPrint(ctl, " Remote"); -#endif -#ifdef WITH_NETWORK - vshPrint(ctl, " Network"); -#endif -#ifdef WITH_BRIDGE - vshPrint(ctl, " Bridging"); -#endif -#if defined(WITH_INTERFACE) - vshPrint(ctl, " Interface"); -# if defined(WITH_NETCF) - vshPrint(ctl, " netcf"); -# elif defined(WITH_UDEV) - vshPrint(ctl, " udev"); -# endif -#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 -#ifdef WITH_STORAGE_GLUSTER - vshPrint(ctl, " Gluster"); -#endif - vshPrint(ctl, "\n"); - - vshPrint(ctl, "%s", _(" Miscellaneous:")); -#ifdef WITH_LIBVIRTD - vshPrint(ctl, " Daemon"); -#endif -#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 -#if WITH_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] - * - */ -static bool -vshParseArgv(vshControl *ctl, int argc, char **argv) -{ - int arg, len, debug, keepalive; - size_t i; - int longindex = -1; - struct option opt[] = { - {"connect", required_argument, NULL, 'c'}, - {"debug", required_argument, NULL, 'd'}, - {"escape", required_argument, NULL, 'e'}, - {"help", no_argument, NULL, 'h'}, - {"keepalive-interval", required_argument, NULL, 'k'}, - {"keepalive-count", required_argument, NULL, 'K'}, - {"log", required_argument, NULL, 'l'}, - {"quiet", no_argument, NULL, 'q'}, - {"readonly", no_argument, NULL, 'r'}, - {"timing", no_argument, NULL, 't'}, - {"version", optional_argument, NULL, 'v'}, - {NULL, 0, NULL, 0} - }; - - /* Standard (non-command) options. The leading + ensures that no - * argument reordering takes place, so that command options are - * not confused with top-level virsh options. */ - while ((arg = getopt_long(argc, argv, "+:c:d:e:hk:K:l:qrtvV", opt, &longindex)) != -1) { - switch (arg) { - case 'c': - VIR_FREE(ctl->name); - ctl->name = vshStrdup(ctl, optarg); - break; - case 'd': - if (virStrToLong_i(optarg, NULL, 10, &debug) < 0) { - vshError(ctl, _("option %s takes a numeric argument"), - longindex == -1 ? "-d" : "--debug"); - 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 '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; - case 'h': - vshUsage(); - exit(EXIT_SUCCESS); - break; - case 'k': - if (virStrToLong_i(optarg, NULL, 0, &keepalive) < 0) { - vshError(ctl, - _("Invalid value for option %s"), - longindex == -1 ? "-k" : "--keepalive-interval"); - exit(EXIT_FAILURE); - } - - if (keepalive < 0) { - vshError(ctl, - _("option %s requires a positive integer argument"), - longindex == -1 ? "-k" : "--keepalive-interval"); - exit(EXIT_FAILURE); - } - ctl->keepalive_interval = keepalive; - break; - case 'K': - if (virStrToLong_i(optarg, NULL, 0, &keepalive) < 0) { - vshError(ctl, - _("Invalid value for option %s"), - longindex == -1 ? "-K" : "--keepalive-count"); - exit(EXIT_FAILURE); - } - - if (keepalive < 0) { - vshError(ctl, - _("option %s requires a positive integer argument"), - longindex == -1 ? "-K" : "--keepalive-count"); - exit(EXIT_FAILURE); - } - ctl->keepalive_count = keepalive; - break; - case 'l': - vshCloseLogFile(ctl); - ctl->logfile = vshStrdup(ctl, optarg); - vshOpenLogFile(ctl); - break; - case 'q': - ctl->quiet = true; - break; - case 't': - ctl->timing = true; - break; - case 'r': - ctl->readonly = true; - break; - case 'v': - if (STRNEQ_NULLABLE(optarg, "long")) { - puts(VERSION); - exit(EXIT_SUCCESS); - } - /* fall through */ - case 'V': - vshShowVersion(ctl); - exit(EXIT_SUCCESS); - case ':': - for (i = 0; opt[i].name != NULL; i++) { - if (opt[i].val == optopt) - break; - } - if (opt[i].name) - vshError(ctl, _("option '-%c'/'--%s' requires an argument"), - optopt, opt[i].name); - else - vshError(ctl, _("option '-%c' requires an argument"), optopt); - exit(EXIT_FAILURE); - case '?': - if (optopt) - vshError(ctl, _("unsupported option '-%c'. See --help."), optopt); - else - vshError(ctl, _("unsupported option '%s'. See --help."), argv[optind - 1]); - exit(EXIT_FAILURE); - default: - vshError(ctl, _("unknown option")); - exit(EXIT_FAILURE); - } - longindex = -1; - } - - if (argc > optind) { - /* parse command */ - ctl->imode = false; - if (argc - optind == 1) { - vshDebug(ctl, VSH_ERR_INFO, "commands: \"%s\"\n", argv[optind]); - return vshCommandStringParse(ctl, argv[optind]); - } else { - return vshCommandArgvParse(ctl, argc - optind, argv + optind); - } - } - return true; -} - -static const vshCmdDef virshCmds[] = { - {.name = "cd", - .handler = cmdCd, - .opts = opts_cd, - .info = info_cd, - .flags = VSH_CMD_FLAG_NOCONNECT - }, - {.name = "connect", - .handler = cmdConnect, - .opts = opts_connect, - .info = info_connect, - .flags = VSH_CMD_FLAG_NOCONNECT - }, - {.name = "echo", - .handler = cmdEcho, - .opts = opts_echo, - .info = info_echo, - .flags = VSH_CMD_FLAG_NOCONNECT - }, - {.name = "exit", - .handler = cmdQuit, - .opts = NULL, - .info = info_quit, - .flags = VSH_CMD_FLAG_NOCONNECT - }, - {.name = "help", - .handler = cmdHelp, - .opts = opts_help, - .info = info_help, - .flags = VSH_CMD_FLAG_NOCONNECT - }, - {.name = "pwd", - .handler = cmdPwd, - .opts = NULL, - .info = info_pwd, - .flags = VSH_CMD_FLAG_NOCONNECT - }, - {.name = "quit", - .handler = cmdQuit, - .opts = NULL, - .info = info_quit, - .flags = VSH_CMD_FLAG_NOCONNECT - }, - {.name = NULL} -}; - -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} -}; - -int -main(int argc, char **argv) -{ - vshControl _ctl, *ctl = &_ctl; - const char *defaultConn; - bool ret = true; - - 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; - ctl->escapeChar = "^]"; /* Same default as telnet */ - - /* In order to distinguish default from setting to 0 */ - ctl->keepalive_interval = -1; - ctl->keepalive_count = -1; - - ctl->eventPipe[0] = -1; - ctl->eventPipe[1] = -1; - ctl->eventTimerId = -1; - - if (!setlocale(LC_ALL, "")) { - perror("setlocale"); - /* failure to setup locale is not fatal */ - } - if (!bindtextdomain(PACKAGE, LOCALEDIR)) { - perror("bindtextdomain"); - return EXIT_FAILURE; - } - if (!textdomain(PACKAGE)) { - perror("textdomain"); - return EXIT_FAILURE; - } - - if (isatty(STDIN_FILENO)) { - ctl->istty = true; - -#ifndef WIN32 - if (tcgetattr(STDIN_FILENO, &ctl->termattr) < 0) - ctl->istty = false; -#endif - } - - 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; - } - - virFileActivateDirOverride(argv[0]); - - if (!(progname = strrchr(argv[0], '/'))) - progname = argv[0]; - else - progname++; - - if ((defaultConn = virGetEnvBlockSUID("VIRSH_DEFAULT_CONNECT_URI"))) - ctl->name = vshStrdup(ctl, defaultConn); - - vshInitDebug(ctl); - - if (!vshParseArgv(ctl, argc, argv) || - !vshInit(ctl)) { - vshDeinit(ctl); - exit(EXIT_FAILURE); - } - - if (!ctl->imode) { - ret = vshCommandRun(ctl, ctl->cmd); - } else { - /* interactive mode */ - if (!ctl->quiet) { - 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")); - } - - if (vshReadlineInit(ctl) < 0) { - vshDeinit(ctl); - exit(EXIT_FAILURE); - } - - do { - const char *prompt = ctl->readonly ? VSH_PROMPT_RO : VSH_PROMPT_RW; - ctl->cmdstr = - vshReadline(ctl, prompt); - if (ctl->cmdstr == NULL) - break; /* EOF */ - if (*ctl->cmdstr) { -#if WITH_READLINE - add_history(ctl->cmdstr); -#endif - if (vshCommandStringParse(ctl, ctl->cmdstr)) - vshCommandRun(ctl, ctl->cmd); - } - VIR_FREE(ctl->cmdstr); - } while (ctl->imode); - - if (ctl->cmdstr == NULL) - fputc('\n', stdout); /* line break after alone prompt */ - } - - vshDeinit(ctl); - exit(ret ? EXIT_SUCCESS : EXIT_FAILURE); -} diff --git a/tools/vsh.h b/tools/vsh.h index 345eb99..4b99b65 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -37,11 +37,6 @@ # include "virerror.h" # include "virthread.h" -# define VSH_MAX_XML_FILE (10*1024*1024) - -# define VSH_PROMPT_RW "virsh # " -# define VSH_PROMPT_RO "virsh > " - # define VIR_FROM_THIS VIR_FROM_NONE # define GETTIMEOFDAY(T) gettimeofday(T, NULL) @@ -52,7 +47,6 @@ * The log configuration */ # define MSG_BUFFER 4096 -# define SIGN_NAME "virsh" # define DIR_MODE (S_IWUSR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) /* 0755 */ # define FILE_MODE (S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH) /* 0644 */ # define LOCK_MODE (S_IWUSR | S_IRUSR) /* 0600 */ @@ -110,22 +104,6 @@ typedef enum { } vshCmdOptType; /* - * Command group types - */ -# define VSH_CMD_GRP_DOM_MANAGEMENT "Domain Management" -# define VSH_CMD_GRP_DOM_MONITORING "Domain Monitoring" -# define VSH_CMD_GRP_STORAGE_POOL "Storage Pool" -# define VSH_CMD_GRP_STORAGE_VOL "Storage Volume" -# define VSH_CMD_GRP_NETWORK "Networking" -# define VSH_CMD_GRP_NODEDEV "Node Device" -# define VSH_CMD_GRP_IFACE "Interface" -# define VSH_CMD_GRP_NWFILTER "Network Filter" -# define VSH_CMD_GRP_SECRET "Secret" -# define VSH_CMD_GRP_SNAPSHOT "Snapshot" -# define VSH_CMD_GRP_HOST_AND_HV "Host and Hypervisor" -# define VSH_CMD_GRP_VIRSH "Virsh itself" - -/* * Command Option Flags */ enum { @@ -143,7 +121,6 @@ typedef struct _vshCmdInfo vshCmdInfo; typedef struct _vshCmdOpt vshCmdOpt; typedef struct _vshCmdOptDef vshCmdOptDef; typedef struct _vshControl vshControl; -typedef struct _vshCtrlData vshCtrlData; typedef char **(*vshCompleter)(unsigned int flags); @@ -217,26 +194,16 @@ struct _vshCmd { */ struct _vshControl { char *name; /* connection name */ - virConnectPtr conn; /* connection to hypervisor (MAY BE NULL) */ vshCmd *cmd; /* the current command */ char *cmdstr; /* string with command */ bool imode; /* interactive mode? */ bool quiet; /* quiet mode */ - int debug; /* print debug messages? */ bool timing; /* print timing info? */ - bool readonly; /* connect readonly (first time only, not - * during explicit connect command) - */ + int debug; /* print debug messages? */ char *logfile; /* log file name */ int log_fd; /* log file descriptor */ char *historydir; /* readline history directory name */ char *historyfile; /* readline history file name */ - bool useGetInfo; /* must use virDomainGetInfo, since - virDomainGetState is not supported */ - bool useSnapshotOld; /* cannot use virDomainSnapshotGetParent or - virDomainSnapshotNumChildren */ - bool blockJobNoBytes; /* true if _BANDWIDTH_BYTE blockjob flags - are missing */ virThread eventLoop; virMutex lock; bool eventLoopStarted; @@ -245,9 +212,6 @@ struct _vshControl { * event to occur */ int eventTimerId; /* id of event loop timeout registration */ - const char *escapeChar; /* String representation of - console escape character */ - int keepalive_interval; /* Client keepalive interval */ int keepalive_count; /* Client keepalive count */ @@ -271,8 +235,6 @@ void vshOutputLogFile(vshControl *ctl, int log_level, const char *format, ATTRIBUTE_FMT_PRINTF(3, 0); void vshCloseLogFile(vshControl *ctl); -virConnectPtr vshConnect(vshControl *ctl, const char *uri, bool readonly); - const char *vshCmddefGetInfo(const vshCmdDef *cmd, const char *info); const vshCmdDef *vshCmddefSearch(const char *cmdname); bool vshCmddefHelp(vshControl *ctl, const char *name); @@ -317,7 +279,6 @@ int vshCommandOptScaledInt(vshControl *ctl, const vshCmd *cmd, bool vshCommandOptBool(const vshCmd *cmd, const char *name); const vshCmdOpt *vshCommandOptArgv(vshControl *ctl, const vshCmd *cmd, const vshCmdOpt *opt); -int vshCommandOptTimeoutToMs(vshControl *ctl, const vshCmd *cmd, int *timeout); /* Filter flags for various vshCommandOpt*By() functions */ typedef enum { @@ -327,12 +288,6 @@ typedef enum { VSH_BYMAC = (1 << 4), } vshLookupByFlags; -/* Given an index, return either the name of that device (non-NULL) or - * of its parent (NULL if a root). */ -typedef const char * (*vshTreeLookup)(int devid, bool parent, void *opaque); -int vshTreePrint(vshControl *ctl, vshTreeLookup lookup, void *opaque, - int num_devices, int devid); - void vshPrintExtra(vshControl *ctl, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); void vshDebug(vshControl *ctl, int level, const char *format, ...) @@ -345,33 +300,14 @@ void vshDebug(vshControl *ctl, int level, const char *format, ...) # define vshStrcasecmp(S1, S2) strcasecmp(S1, S2) int vshNameSorter(const void *a, const void *b); -int vshDomainState(vshControl *ctl, virDomainPtr dom, int *reason); virTypedParameterPtr vshFindTypedParamByName(const char *name, virTypedParameterPtr list, int count); char *vshGetTypedParamValue(vshControl *ctl, virTypedParameterPtr item) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -char *vshEditWriteToTempFile(vshControl *ctl, const char *doc); -int vshEditFile(vshControl *ctl, const char *filename); -char *vshEditReadBackFile(vshControl *ctl, const char *filename); -int vshAskReedit(vshControl *ctl, const char *msg, bool relax_avail); -int vshStreamSink(virStreamPtr st, const char *bytes, size_t nbytes, - void *opaque); -double vshPrettyCapacity(unsigned long long val, const char **unit); int vshStringToArray(const char *str, char ***array); -/* Typedefs, function prototypes for job progress reporting. - * There are used by some long lingering commands like - * migrate, dump, save, managedsave. - */ -struct _vshCtrlData { - vshControl *ctl; - const vshCmd *cmd; - int writefd; - virConnectPtr dconn; -}; - /* error handling */ extern virErrorPtr last_error; void vshReportError(vshControl *ctl); -- 1.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list