2015-06-15 16:53:58 +00:00
|
|
|
/*
|
|
|
|
* vsh.h: common data to be used by clients to exercise the libvirt API
|
|
|
|
*
|
|
|
|
* Copyright (C) 2005, 2007-2015 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/>.
|
|
|
|
*/
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#pragma once
|
2015-06-15 16:53:58 +00:00
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#include <stdarg.h>
|
2020-01-09 13:18:50 +00:00
|
|
|
#ifndef WIN32
|
|
|
|
# include <termios.h>
|
|
|
|
#endif
|
2015-06-15 16:53:58 +00:00
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#include "internal.h"
|
|
|
|
#include "virthread.h"
|
2015-06-15 16:53:58 +00:00
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
2015-06-15 16:53:58 +00:00
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_MAX_XML_FILE (10*1024*1024)
|
|
|
|
#define VSH_MATCH(FLAG) (flags & (FLAG))
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The log configuration
|
|
|
|
*/
|
2019-06-18 16:13:15 +00:00
|
|
|
#define MSG_BUFFER 4096
|
|
|
|
#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 */
|
|
|
|
#define LVL_DEBUG "DEBUG"
|
|
|
|
#define LVL_INFO "INFO"
|
|
|
|
#define LVL_NOTICE "NOTICE"
|
|
|
|
#define LVL_WARNING "WARNING"
|
|
|
|
#define LVL_ERROR "ERROR"
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* vshErrorLevel:
|
|
|
|
*
|
|
|
|
* Indicates the level of a log message
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
VSH_ERR_DEBUG = 0,
|
|
|
|
VSH_ERR_INFO,
|
|
|
|
VSH_ERR_NOTICE,
|
|
|
|
VSH_ERR_WARNING,
|
|
|
|
VSH_ERR_ERROR
|
|
|
|
} vshErrorLevel;
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_DEBUG_DEFAULT VSH_ERR_ERROR
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* virsh command line grammar:
|
|
|
|
*
|
|
|
|
* command_line = <command>\n | <command>; <command>; ...
|
|
|
|
*
|
|
|
|
* command = <keyword> <option> [--] <data>
|
|
|
|
*
|
|
|
|
* option = <bool_option> | <int_option> | <string_option>
|
|
|
|
* data = <string>
|
|
|
|
*
|
|
|
|
* bool_option = --optionname
|
|
|
|
* int_option = --optionname <number> | --optionname=<number>
|
|
|
|
* string_option = --optionname <string> | --optionname=<string>
|
|
|
|
*
|
|
|
|
* keyword = [a-zA-Z][a-zA-Z-]*
|
|
|
|
* number = [0-9]+
|
|
|
|
* string = ('[^']*'|"([^\\"]|\\.)*"|([^ \t\n\\'"]|\\.))+
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* vshCmdOptType - command option type
|
|
|
|
*/
|
|
|
|
typedef enum {
|
2024-03-04 14:40:40 +00:00
|
|
|
VSH_OT_NONE = 0, /* cannary to catch programming errors */
|
2015-06-15 16:53:58 +00:00
|
|
|
VSH_OT_BOOL, /* optional boolean option */
|
|
|
|
VSH_OT_STRING, /* optional string option */
|
|
|
|
VSH_OT_INT, /* optional or mandatory int option */
|
|
|
|
VSH_OT_ARGV, /* remaining arguments */
|
|
|
|
VSH_OT_ALIAS, /* alternate spelling for a later argument */
|
|
|
|
} vshCmdOptType;
|
|
|
|
|
|
|
|
/* forward declarations */
|
|
|
|
typedef struct _vshClientHooks vshClientHooks;
|
|
|
|
typedef struct _vshCmd vshCmd;
|
|
|
|
typedef struct _vshCmdDef vshCmdDef;
|
|
|
|
typedef struct _vshCmdGrp vshCmdGrp;
|
|
|
|
typedef struct _vshCmdInfo vshCmdInfo;
|
|
|
|
typedef struct _vshCmdOpt vshCmdOpt;
|
|
|
|
typedef struct _vshCmdOptDef vshCmdOptDef;
|
|
|
|
typedef struct _vshControl vshControl;
|
|
|
|
|
2017-11-07 09:41:00 +00:00
|
|
|
typedef char **(*vshCompleter)(vshControl *ctl,
|
2017-11-21 16:45:50 +00:00
|
|
|
const vshCmd *cmd,
|
2017-11-07 09:41:00 +00:00
|
|
|
unsigned int flags);
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* "help" - short description of command
|
|
|
|
* "desc" - description of command, or empty string
|
|
|
|
*/
|
|
|
|
struct _vshCmdInfo {
|
2024-03-04 12:21:50 +00:00
|
|
|
const char *help; /* short description of command */
|
|
|
|
const char *desc; /* description of command */
|
2015-06-15 16:53:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* vshCmdOptDef - command option definition
|
|
|
|
*/
|
|
|
|
struct _vshCmdOptDef {
|
|
|
|
const char *name; /* the name of option, or NULL for list end */
|
|
|
|
vshCmdOptType type; /* option type */
|
2024-03-05 14:07:47 +00:00
|
|
|
bool required; /* option is required */
|
|
|
|
bool positional; /* option is a positional option (not requiring '--optionname') */
|
2024-03-13 21:31:20 +00:00
|
|
|
|
|
|
|
/* Historically the command parser in virsh allowed many optional arguments
|
|
|
|
* which were documented as non-positional to be filled positionally. To
|
|
|
|
* preserve this functionality those need to be annotated with the
|
|
|
|
* 'unwanted_positional' flag. New options must not use this flag */
|
|
|
|
bool unwanted_positional;
|
|
|
|
|
2024-03-11 12:17:50 +00:00
|
|
|
bool allowEmpty; /* allow empty string */
|
2015-06-15 16:53:58 +00:00
|
|
|
const char *help; /* non-NULL help string; or for VSH_OT_ALIAS
|
|
|
|
* the name of a later public option */
|
|
|
|
vshCompleter completer; /* option completer */
|
|
|
|
unsigned int completer_flags; /* option completer flags */
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* vshCmdOpt - command options
|
|
|
|
*
|
|
|
|
* After parsing a command, all arguments to the command have been
|
|
|
|
* collected into a list of these objects.
|
|
|
|
*/
|
|
|
|
struct _vshCmdOpt {
|
|
|
|
const vshCmdOptDef *def; /* non-NULL pointer to option definition */
|
|
|
|
char *data; /* allocated data, or NULL for bool option */
|
2021-01-26 08:51:27 +00:00
|
|
|
bool completeThis; /* true if this is the option user's wishing to
|
|
|
|
autocomplete */
|
2015-06-15 16:53:58 +00:00
|
|
|
vshCmdOpt *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Command Usage Flags
|
|
|
|
*/
|
|
|
|
enum {
|
|
|
|
VSH_CMD_FLAG_NOCONNECT = (1 << 0), /* no prior connection needed */
|
2024-03-01 22:14:51 +00:00
|
|
|
VSH_CMD_FLAG_HIDDEN = (1 << 1), /* command is hidden/internal */
|
2015-06-15 16:53:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* vshCmdDef - command definition
|
|
|
|
*/
|
|
|
|
struct _vshCmdDef {
|
|
|
|
const char *name; /* name of command, or NULL for list end */
|
|
|
|
bool (*handler) (vshControl *, const vshCmd *); /* command handler */
|
|
|
|
const vshCmdOptDef *opts; /* definition of command options */
|
|
|
|
const vshCmdInfo *info; /* details about command */
|
|
|
|
unsigned int flags; /* bitwise OR of VSH_CMD_FLAG */
|
2016-09-07 15:30:48 +00:00
|
|
|
const char *alias; /* name of the aliased command */
|
2015-06-15 16:53:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* vshCmd - parsed command
|
|
|
|
*/
|
|
|
|
struct _vshCmd {
|
|
|
|
const vshCmdDef *def; /* command definition */
|
|
|
|
vshCmdOpt *opts; /* list of command arguments */
|
2024-03-12 07:29:00 +00:00
|
|
|
vshCmdOpt *lastopt; /* last option of the commandline */
|
2017-11-09 17:06:11 +00:00
|
|
|
vshCmd *next; /* next command */
|
|
|
|
bool skipChecks; /* skip validity checks when retrieving opts */
|
2015-06-15 16:53:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* vshControl
|
|
|
|
*/
|
|
|
|
struct _vshControl {
|
|
|
|
const char *name; /* hardcoded name of the binary that cannot
|
|
|
|
* be changed without recompilation compared
|
|
|
|
* to program name */
|
2016-07-28 10:54:16 +00:00
|
|
|
const char *env_prefix; /* hardcoded environment variable prefix */
|
2015-12-10 12:46:45 +00:00
|
|
|
char *connname; /* connection name */
|
2015-06-15 16:53:58 +00:00
|
|
|
char *progname; /* program name */
|
|
|
|
vshCmd *cmd; /* the current command */
|
|
|
|
char *cmdstr; /* string with command */
|
|
|
|
bool imode; /* interactive mode? */
|
|
|
|
bool quiet; /* quiet mode */
|
|
|
|
bool timing; /* print timing info? */
|
|
|
|
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 */
|
|
|
|
virThread eventLoop;
|
|
|
|
virMutex lock;
|
|
|
|
bool eventLoopStarted;
|
|
|
|
bool quit;
|
|
|
|
int eventPipe[2]; /* Write-to-self pipe to end waiting for an
|
|
|
|
* event to occur */
|
|
|
|
int eventTimerId; /* id of event loop timeout registration */
|
|
|
|
|
|
|
|
int keepalive_interval; /* Client keepalive interval */
|
|
|
|
int keepalive_count; /* Client keepalive count */
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#ifndef WIN32
|
2015-06-15 16:53:58 +00:00
|
|
|
struct termios termattr; /* settings of the tty terminal */
|
2019-06-18 16:13:15 +00:00
|
|
|
#endif
|
2015-06-15 16:53:58 +00:00
|
|
|
bool istty; /* is the terminal a tty */
|
|
|
|
|
|
|
|
const vshClientHooks *hooks;/* mandatory client specific hooks */
|
|
|
|
void *privData; /* client specific data */
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef void *
|
|
|
|
(*vshConnectionHook)(vshControl *ctl);
|
|
|
|
|
|
|
|
struct _vshClientHooks {
|
|
|
|
vshConnectionHook connHandler;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _vshCmdGrp {
|
|
|
|
const char *name; /* name of group, or NULL for list end */
|
|
|
|
const char *keyword; /* help keyword */
|
|
|
|
const vshCmdDef *commands;
|
|
|
|
};
|
|
|
|
|
|
|
|
void vshError(vshControl *ctl, const char *format, ...)
|
2019-10-15 11:35:07 +00:00
|
|
|
G_GNUC_PRINTF(2, 3);
|
2015-06-15 16:53:58 +00:00
|
|
|
void vshOpenLogFile(vshControl *ctl);
|
|
|
|
void vshOutputLogFile(vshControl *ctl, int log_level, const char *format,
|
|
|
|
va_list ap)
|
2019-10-15 11:35:07 +00:00
|
|
|
G_GNUC_PRINTF(3, 0);
|
2015-06-15 16:53:58 +00:00
|
|
|
void vshCloseLogFile(vshControl *ctl);
|
|
|
|
|
|
|
|
const vshCmdDef *vshCmddefSearch(const char *cmdname);
|
|
|
|
const vshCmdGrp *vshCmdGrpSearch(const char *grpname);
|
2018-01-25 15:08:46 +00:00
|
|
|
bool vshCmdGrpHelp(vshControl *ctl, const vshCmdGrp *grp);
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
int vshCommandOptInt(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, int *value)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshCommandOptUInt(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, unsigned int *value)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshCommandOptUIntWrap(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, unsigned int *value)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshCommandOptUL(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, unsigned long *value)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshCommandOptULWrap(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, unsigned long *value)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2015-12-03 12:47:56 +00:00
|
|
|
int vshCommandOptStringQuiet(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, const char **value)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2024-03-11 14:55:11 +00:00
|
|
|
int vshCommandOptString(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, const char **value)
|
2015-06-15 16:53:58 +00:00
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshCommandOptLongLong(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, long long *value)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshCommandOptULongLong(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, unsigned long long *value)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshCommandOptULongLongWrap(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, unsigned long long *value)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshCommandOptScaledInt(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const char *name, unsigned long long *value,
|
|
|
|
int scale, unsigned long long max)
|
2019-10-14 12:25:14 +00:00
|
|
|
ATTRIBUTE_NONNULL(4) G_GNUC_WARN_UNUSED_RESULT;
|
2016-03-29 13:47:40 +00:00
|
|
|
int vshBlockJobOptionBandwidth(vshControl *ctl,
|
|
|
|
const vshCmd *cmd,
|
|
|
|
bool bytes,
|
|
|
|
unsigned long *bandwidth);
|
2015-06-15 16:53:58 +00:00
|
|
|
bool vshCommandOptBool(const vshCmd *cmd, const char *name);
|
|
|
|
bool vshCommandRun(vshControl *ctl, const vshCmd *cmd);
|
2021-01-26 08:51:27 +00:00
|
|
|
bool vshCommandStringParse(vshControl *ctl, char *cmdstr,
|
|
|
|
vshCmd **partial, size_t point);
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
const vshCmdOpt *vshCommandOptArgv(vshControl *ctl, const vshCmd *cmd,
|
|
|
|
const vshCmdOpt *opt);
|
|
|
|
bool vshCommandArgvParse(vshControl *ctl, int nargs, char **argv);
|
|
|
|
int vshCommandOptTimeoutToMs(vshControl *ctl, const vshCmd *cmd, int *timeout);
|
|
|
|
|
2023-04-13 07:19:27 +00:00
|
|
|
void vshPrintVa(vshControl *ctl,
|
|
|
|
const char *format,
|
|
|
|
va_list ap)
|
|
|
|
G_GNUC_PRINTF(2, 0);
|
2016-02-12 13:09:02 +00:00
|
|
|
void vshPrint(vshControl *ctl, const char *format, ...)
|
2019-10-15 11:35:07 +00:00
|
|
|
G_GNUC_PRINTF(2, 3);
|
2015-06-15 16:53:58 +00:00
|
|
|
void vshPrintExtra(vshControl *ctl, const char *format, ...)
|
2019-10-15 11:35:07 +00:00
|
|
|
G_GNUC_PRINTF(2, 3);
|
2024-03-04 14:51:28 +00:00
|
|
|
bool vshInit(vshControl *ctl, const vshCmdGrp *groups);
|
2015-09-03 14:59:01 +00:00
|
|
|
bool vshInitReload(vshControl *ctl);
|
2015-06-15 16:53:58 +00:00
|
|
|
void vshDeinit(vshControl *ctl);
|
|
|
|
void vshDebug(vshControl *ctl, int level, const char *format, ...)
|
2019-10-15 11:35:07 +00:00
|
|
|
G_GNUC_PRINTF(3, 4);
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
/* User visible sort, so we want locale-specific case comparison. */
|
2019-06-18 16:13:15 +00:00
|
|
|
#define vshStrcasecmp(S1, S2) strcasecmp(S1, S2)
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshNameSorter(const void *a, const void *b);
|
|
|
|
|
|
|
|
char *vshGetTypedParamValue(vshControl *ctl, virTypedParameterPtr item)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
|
|
|
|
|
|
double vshPrettyCapacity(unsigned long long val, const char **unit);
|
|
|
|
int vshStringToArray(const char *str, char ***array);
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
/* error handling */
|
|
|
|
extern virErrorPtr last_error;
|
|
|
|
void vshErrorHandler(void *opaque, virErrorPtr error);
|
|
|
|
void vshReportError(vshControl *ctl);
|
|
|
|
void vshResetLibvirtError(void);
|
|
|
|
void vshSaveLibvirtError(void);
|
2017-04-11 15:23:23 +00:00
|
|
|
void vshSaveLibvirtHelperError(void);
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
/* file handling */
|
2022-03-01 16:00:56 +00:00
|
|
|
void vshEditUnlinkTempfile(char *file);
|
|
|
|
typedef char vshTempFile;
|
|
|
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(vshTempFile, vshEditUnlinkTempfile);
|
2015-06-15 16:53:58 +00:00
|
|
|
char *vshEditWriteToTempFile(vshControl *ctl, const char *doc);
|
|
|
|
int vshEditFile(vshControl *ctl, const char *filename);
|
|
|
|
char *vshEditReadBackFile(vshControl *ctl, const char *filename);
|
2024-02-28 15:31:35 +00:00
|
|
|
int vshEditString(vshControl *ctl, char **output, const char *string);
|
2015-06-15 16:53:58 +00:00
|
|
|
int vshAskReedit(vshControl *ctl, const char *msg, bool relax_avail);
|
|
|
|
|
|
|
|
/* terminal modifications */
|
|
|
|
bool vshTTYIsInterruptCharacter(vshControl *ctl, const char chr);
|
|
|
|
int vshTTYDisableInterrupt(vshControl *ctl);
|
|
|
|
int vshTTYRestore(vshControl *ctl);
|
|
|
|
int vshTTYMakeRaw(vshControl *ctl, bool report_errors);
|
|
|
|
bool vshTTYAvailable(vshControl *ctl);
|
|
|
|
|
|
|
|
/* waiting for events */
|
|
|
|
enum {
|
|
|
|
VSH_EVENT_INTERRUPT,
|
|
|
|
VSH_EVENT_TIMEOUT,
|
|
|
|
VSH_EVENT_DONE,
|
|
|
|
};
|
|
|
|
void vshEventCleanup(vshControl *ctl);
|
|
|
|
void vshEventDone(vshControl *ctl);
|
|
|
|
void vshEventLoop(void *opaque);
|
|
|
|
int vshEventStart(vshControl *ctl, int timeout_ms);
|
|
|
|
void vshEventTimeout(int timer, void *opaque);
|
|
|
|
int vshEventWait(vshControl *ctl);
|
|
|
|
|
|
|
|
/* generic commands */
|
|
|
|
extern const vshCmdOptDef opts_help[];
|
2024-03-04 12:21:50 +00:00
|
|
|
extern const vshCmdInfo info_help;
|
2015-06-15 16:53:58 +00:00
|
|
|
extern const vshCmdOptDef opts_cd[];
|
2024-03-04 12:21:50 +00:00
|
|
|
extern const vshCmdInfo info_cd;
|
2015-06-15 16:53:58 +00:00
|
|
|
extern const vshCmdOptDef opts_echo[];
|
2024-03-04 12:21:50 +00:00
|
|
|
extern const vshCmdInfo info_echo;
|
|
|
|
extern const vshCmdInfo info_pwd;
|
|
|
|
extern const vshCmdInfo info_quit;
|
2021-03-04 14:47:28 +00:00
|
|
|
extern const vshCmdOptDef opts_selftest[];
|
2024-03-04 12:21:50 +00:00
|
|
|
extern const vshCmdInfo info_selftest;
|
2017-11-01 14:34:14 +00:00
|
|
|
extern const vshCmdOptDef opts_complete[];
|
2024-03-04 12:21:50 +00:00
|
|
|
extern const vshCmdInfo info_complete;
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
bool cmdHelp(vshControl *ctl, const vshCmd *cmd);
|
|
|
|
bool cmdCd(vshControl *ctl, const vshCmd *cmd);
|
|
|
|
bool cmdEcho(vshControl *ctl, const vshCmd *cmd);
|
|
|
|
bool cmdPwd(vshControl *ctl, const vshCmd *cmd);
|
|
|
|
bool cmdQuit(vshControl *ctl, const vshCmd *cmd);
|
2016-09-14 07:50:22 +00:00
|
|
|
bool cmdSelfTest(vshControl *ctl, const vshCmd *cmd);
|
2017-11-01 14:34:14 +00:00
|
|
|
bool cmdComplete(vshControl *ctl, const vshCmd *cmd);
|
2015-06-15 16:53:58 +00:00
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_CMD_CD \
|
2017-11-03 12:09:47 +00:00
|
|
|
{ \
|
|
|
|
.name = "cd", \
|
|
|
|
.handler = cmdCd, \
|
|
|
|
.opts = opts_cd, \
|
2024-03-04 12:21:50 +00:00
|
|
|
.info = &info_cd, \
|
2017-11-03 12:09:47 +00:00
|
|
|
.flags = VSH_CMD_FLAG_NOCONNECT \
|
2015-06-15 16:53:58 +00:00
|
|
|
}
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_CMD_ECHO \
|
2017-11-03 12:09:47 +00:00
|
|
|
{ \
|
|
|
|
.name = "echo", \
|
|
|
|
.handler = cmdEcho, \
|
|
|
|
.opts = opts_echo, \
|
2024-03-04 12:21:50 +00:00
|
|
|
.info = &info_echo, \
|
2017-11-03 12:09:47 +00:00
|
|
|
.flags = VSH_CMD_FLAG_NOCONNECT \
|
2015-06-15 16:53:58 +00:00
|
|
|
}
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_CMD_EXIT \
|
2017-11-03 12:09:47 +00:00
|
|
|
{ \
|
|
|
|
.name = "exit", \
|
|
|
|
.handler = cmdQuit, \
|
|
|
|
.opts = NULL, \
|
2024-03-04 12:21:50 +00:00
|
|
|
.info = &info_quit, \
|
2017-11-03 12:09:47 +00:00
|
|
|
.flags = VSH_CMD_FLAG_NOCONNECT \
|
2015-06-15 16:53:58 +00:00
|
|
|
}
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_CMD_HELP \
|
2017-11-03 12:09:47 +00:00
|
|
|
{ \
|
|
|
|
.name = "help", \
|
|
|
|
.handler = cmdHelp, \
|
|
|
|
.opts = opts_help, \
|
2024-03-04 12:21:50 +00:00
|
|
|
.info = &info_help, \
|
2017-11-03 12:09:47 +00:00
|
|
|
.flags = VSH_CMD_FLAG_NOCONNECT \
|
2015-06-15 16:53:58 +00:00
|
|
|
}
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_CMD_PWD \
|
2017-11-03 12:09:47 +00:00
|
|
|
{ \
|
|
|
|
.name = "pwd", \
|
|
|
|
.handler = cmdPwd, \
|
|
|
|
.opts = NULL, \
|
2024-03-04 12:21:50 +00:00
|
|
|
.info = &info_pwd, \
|
2017-11-03 12:09:47 +00:00
|
|
|
.flags = VSH_CMD_FLAG_NOCONNECT \
|
2015-06-15 16:53:58 +00:00
|
|
|
}
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_CMD_QUIT \
|
2017-11-03 12:09:47 +00:00
|
|
|
{ \
|
|
|
|
.name = "quit", \
|
|
|
|
.handler = cmdQuit, \
|
|
|
|
.opts = NULL, \
|
2024-03-04 12:21:50 +00:00
|
|
|
.info = &info_quit, \
|
2017-11-03 12:09:47 +00:00
|
|
|
.flags = VSH_CMD_FLAG_NOCONNECT \
|
2015-06-15 16:53:58 +00:00
|
|
|
}
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_CMD_SELF_TEST \
|
2017-11-03 12:09:47 +00:00
|
|
|
{ \
|
|
|
|
.name = "self-test", \
|
|
|
|
.handler = cmdSelfTest, \
|
2021-03-04 14:47:28 +00:00
|
|
|
.opts = opts_selftest, \
|
2024-03-04 12:21:50 +00:00
|
|
|
.info = &info_selftest, \
|
2021-09-16 13:57:28 +00:00
|
|
|
.flags = VSH_CMD_FLAG_NOCONNECT | VSH_CMD_FLAG_HIDDEN, \
|
2016-09-14 07:50:22 +00:00
|
|
|
}
|
|
|
|
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_CMD_COMPLETE \
|
2017-11-01 14:34:14 +00:00
|
|
|
{ \
|
|
|
|
.name = "complete", \
|
|
|
|
.handler = cmdComplete, \
|
|
|
|
.opts = opts_complete, \
|
2024-03-04 12:21:50 +00:00
|
|
|
.info = &info_complete, \
|
2021-09-16 13:57:28 +00:00
|
|
|
.flags = VSH_CMD_FLAG_NOCONNECT | VSH_CMD_FLAG_HIDDEN, \
|
2017-11-01 14:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
|
|
|
|
/* readline */
|
|
|
|
char * vshReadline(vshControl *ctl, const char *prompt);
|
|
|
|
|
2020-09-03 08:02:52 +00:00
|
|
|
void vshReadlineHistoryAdd(const char *cmd);
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
/* Macros to help dealing with mutually exclusive options. */
|
|
|
|
|
|
|
|
/* VSH_EXCLUSIVE_OPTIONS_EXPR:
|
|
|
|
*
|
|
|
|
* @NAME1: String containing the name of the option.
|
|
|
|
* @EXPR1: Expression to validate the variable (boolean variable)
|
|
|
|
* @NAME2: String containing the name of the option.
|
|
|
|
* @EXPR2: Expression to validate the variable (boolean variable)
|
|
|
|
*
|
|
|
|
* Reject mutually exclusive command options in virsh. Use the
|
|
|
|
* provided expression to check the variables.
|
|
|
|
*
|
|
|
|
* This helper does an early return and therefore it has to be called
|
|
|
|
* before anything that would require cleanup.
|
|
|
|
*/
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_EXCLUSIVE_OPTIONS_EXPR(NAME1, EXPR1, NAME2, EXPR2) \
|
2017-11-03 12:09:47 +00:00
|
|
|
if ((EXPR1) && (EXPR2)) { \
|
2023-03-09 14:54:58 +00:00
|
|
|
vshError(ctl, _("Options --%1$s and --%2$s are mutually exclusive"), \
|
2017-11-03 12:09:47 +00:00
|
|
|
NAME1, NAME2); \
|
|
|
|
return false; \
|
2015-06-15 16:53:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* VSH_EXCLUSIVE_OPTIONS:
|
|
|
|
*
|
|
|
|
* @NAME1: String containing the name of the option.
|
|
|
|
* @NAME2: String containing the name of the option.
|
|
|
|
*
|
|
|
|
* Reject mutually exclusive command options in virsh. Use the
|
|
|
|
* vshCommandOptBool call to request them.
|
|
|
|
*
|
|
|
|
* This helper does an early return and therefore it has to be called
|
|
|
|
* before anything that would require cleanup.
|
|
|
|
*/
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_EXCLUSIVE_OPTIONS(NAME1, NAME2) \
|
2017-11-03 12:09:47 +00:00
|
|
|
VSH_EXCLUSIVE_OPTIONS_EXPR(NAME1, vshCommandOptBool(cmd, NAME1), \
|
2015-06-15 16:53:58 +00:00
|
|
|
NAME2, vshCommandOptBool(cmd, NAME2))
|
|
|
|
|
|
|
|
/* VSH_EXCLUSIVE_OPTIONS_VAR:
|
|
|
|
*
|
|
|
|
* @VARNAME1: Boolean variable containing the value of the option of same name
|
|
|
|
* @VARNAME2: Boolean variable containing the value of the option of same name
|
|
|
|
*
|
|
|
|
* Reject mutually exclusive command options in virsh. Check in variables that
|
|
|
|
* contain the value and have same name as the option.
|
|
|
|
*
|
|
|
|
* This helper does an early return and therefore it has to be called
|
|
|
|
* before anything that would require cleanup.
|
|
|
|
*/
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_EXCLUSIVE_OPTIONS_VAR(VARNAME1, VARNAME2) \
|
2015-06-15 16:53:58 +00:00
|
|
|
VSH_EXCLUSIVE_OPTIONS_EXPR(#VARNAME1, VARNAME1, #VARNAME2, VARNAME2)
|
|
|
|
|
2022-10-06 14:29:32 +00:00
|
|
|
/* Macros to help dealing with alternative mutually exclusive options. */
|
|
|
|
|
|
|
|
/* VSH_ALTERNATIVE_OPTIONS_EXPR:
|
|
|
|
*
|
|
|
|
* @NAME1: String containing the name of the option.
|
|
|
|
* @EXPR1: Expression to validate the variable (must evaluate to bool).
|
|
|
|
* @NAME2: String containing the name of the option.
|
|
|
|
* @EXPR2: Expression to validate the variable (must evaluate to bool).
|
|
|
|
*
|
|
|
|
* Require exactly one of the command options in virsh. Use the provided
|
|
|
|
* expression to check the variables.
|
|
|
|
*
|
|
|
|
* This helper does an early return and therefore it has to be called
|
|
|
|
* before anything that would require cleanup.
|
|
|
|
*/
|
|
|
|
#define VSH_ALTERNATIVE_OPTIONS_EXPR(NAME1, EXPR1, NAME2, EXPR2) \
|
|
|
|
do { \
|
|
|
|
bool _expr1 = EXPR1; \
|
|
|
|
bool _expr2 = EXPR2; \
|
|
|
|
VSH_EXCLUSIVE_OPTIONS_EXPR(NAME1, _expr1, NAME2, _expr2); \
|
|
|
|
if (!_expr1 && !_expr2) { \
|
2023-03-09 14:54:58 +00:00
|
|
|
vshError(ctl, _("Either --%1$s or --%2$s must be provided"), \
|
2022-10-06 14:29:32 +00:00
|
|
|
NAME1, NAME2); \
|
|
|
|
return false; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2023-12-13 13:23:45 +00:00
|
|
|
#define VSH_ALTERNATIVE_OPTIONS(NAME1, NAME2) \
|
|
|
|
VSH_ALTERNATIVE_OPTIONS_EXPR(NAME1, vshCommandOptBool(cmd, NAME1), \
|
|
|
|
NAME2, vshCommandOptBool(cmd, NAME2))
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
/* Macros to help dealing with required options. */
|
|
|
|
|
|
|
|
/* VSH_REQUIRE_OPTION_EXPR:
|
|
|
|
*
|
|
|
|
* @NAME1: String containing the name of the option.
|
|
|
|
* @EXPR1: Expression to validate the variable (boolean variable).
|
|
|
|
* @NAME2: String containing the name of required option.
|
|
|
|
* @EXPR2: Expression to validate the variable (boolean variable).
|
|
|
|
*
|
|
|
|
* Check if required command options in virsh was set. Use the
|
|
|
|
* provided expression to check the variables.
|
|
|
|
*
|
|
|
|
* This helper does an early return and therefore it has to be called
|
|
|
|
* before anything that would require cleanup.
|
|
|
|
*/
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_REQUIRE_OPTION_EXPR(NAME1, EXPR1, NAME2, EXPR2) \
|
2017-11-03 12:09:47 +00:00
|
|
|
do { \
|
|
|
|
if ((EXPR1) && !(EXPR2)) { \
|
2023-03-09 14:54:58 +00:00
|
|
|
vshError(ctl, _("Option --%1$s is required by option --%2$s"), \
|
2017-11-03 12:09:47 +00:00
|
|
|
NAME2, NAME1); \
|
|
|
|
return false; \
|
|
|
|
} \
|
2015-06-15 16:53:58 +00:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/* VSH_REQUIRE_OPTION:
|
|
|
|
*
|
|
|
|
* @NAME1: String containing the name of the option.
|
|
|
|
* @NAME2: String containing the name of required option.
|
|
|
|
*
|
|
|
|
* Check if required command options in virsh was set. Use the
|
|
|
|
* vshCommandOptBool call to request them.
|
|
|
|
*
|
|
|
|
* This helper does an early return and therefore it has to be called
|
|
|
|
* before anything that would require cleanup.
|
|
|
|
*/
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_REQUIRE_OPTION(NAME1, NAME2) \
|
2017-11-03 12:09:47 +00:00
|
|
|
VSH_REQUIRE_OPTION_EXPR(NAME1, vshCommandOptBool(cmd, NAME1), \
|
2015-06-15 16:53:58 +00:00
|
|
|
NAME2, vshCommandOptBool(cmd, NAME2))
|
|
|
|
|
|
|
|
/* VSH_REQUIRE_OPTION_VAR:
|
|
|
|
*
|
|
|
|
* @VARNAME1: Boolean variable containing the value of the option of same name.
|
|
|
|
* @VARNAME2: Boolean variable containing the value of required option of
|
|
|
|
* same name.
|
|
|
|
*
|
|
|
|
* Check if required command options in virsh was set. Check in variables
|
|
|
|
* that contain the value and have same name as the option.
|
|
|
|
*
|
|
|
|
* This helper does an early return and therefore it has to be called
|
|
|
|
* before anything that would require cleanup.
|
|
|
|
*/
|
2019-06-18 16:13:15 +00:00
|
|
|
#define VSH_REQUIRE_OPTION_VAR(VARNAME1, VARNAME2) \
|
2015-06-15 16:53:58 +00:00
|
|
|
VSH_REQUIRE_OPTION_EXPR(#VARNAME1, VARNAME1, #VARNAME2, VARNAME2)
|