vsh.h 20.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * 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/>.
 *
 * Daniel Veillard <veillard@redhat.com>
 * Karel Zak <kzak@redhat.com>
 * Daniel P. Berrange <berrange@redhat.com>
 */

25 26
#ifndef LIBVIRT_VSH_H
# define LIBVIRT_VSH_H
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

# include <stdarg.h>
# include <unistd.h>
# include <sys/stat.h>
# include <termios.h>

# include "internal.h"
# include "virerror.h"
# include "virthread.h"

# define VIR_FROM_THIS VIR_FROM_NONE

# define GETTIMEOFDAY(T) gettimeofday(T, NULL)
# define VSH_MAX_XML_FILE (10*1024*1024)
# define VSH_MATCH(FLAG) (flags & (FLAG))

/**
 * The log configuration
 */
# 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"

/**
 * 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;

# define VSH_DEBUG_DEFAULT VSH_ERR_ERROR

/*
 * 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 {
    VSH_OT_BOOL,     /* optional boolean option */
    VSH_OT_STRING,   /* optional string option */
    VSH_OT_INT,      /* optional or mandatory int option */
    VSH_OT_DATA,     /* string data (as non-option) */
    VSH_OT_ARGV,     /* remaining arguments */
    VSH_OT_ALIAS,    /* alternate spelling for a later argument */
} vshCmdOptType;

/*
 * Command Option Flags
 */
enum {
    VSH_OFLAG_NONE     = 0,        /* without flags */
    VSH_OFLAG_REQ      = (1 << 0), /* option required */
    VSH_OFLAG_EMPTY_OK = (1 << 1), /* empty string option allowed */
    VSH_OFLAG_REQ_OPT  = (1 << 2), /* --optionname required */
};

/* 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;

123
typedef char **(*vshCompleter)(vshControl *ctl,
124
                               const vshCmd *cmd,
125
                               unsigned int flags);
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180

/*
 * vshCmdInfo -- name/value pair for information about command
 *
 * Commands should have at least the following names:
 * "help" - short description of command
 * "desc" - description of command, or empty string
 */
struct _vshCmdInfo {
    const char *name;           /* name of information, or NULL for list end */
    const char *data;           /* non-NULL information */
};

/*
 * vshCmdOptDef - command option definition
 */
struct _vshCmdOptDef {
    const char *name;           /* the name of option, or NULL for list end */
    vshCmdOptType type;         /* option type */
    unsigned int flags;         /* flags */
    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 */
    vshCmdOpt *next;
};

/*
 * Command Usage Flags
 */
enum {
    VSH_CMD_FLAG_NOCONNECT = (1 << 0),  /* no prior connection needed */
    VSH_CMD_FLAG_ALIAS     = (1 << 1),  /* command is an alias */
};

/*
 * 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 */
181
    const char *alias;          /* name of the aliased command */
182 183 184 185 186 187 188 189
};

/*
 * vshCmd - parsed command
 */
struct _vshCmd {
    const vshCmdDef *def;       /* command definition */
    vshCmdOpt *opts;            /* list of command arguments */
190 191
    vshCmd *next;               /* next command */
    bool skipChecks;            /* skip validity checks when retrieving opts */
192 193 194 195 196 197 198 199 200
};

/*
 * vshControl
 */
struct _vshControl {
    const char *name;           /* hardcoded name of the binary that cannot
                                 * be changed without recompilation compared
                                 * to program name */
201
    const char *env_prefix;     /* hardcoded environment variable prefix */
202
    char *connname;             /* connection name */
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
    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 */

# ifndef WIN32
    struct termios termattr;    /* settings of the tty terminal */
# endif
    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, ...)
    ATTRIBUTE_FMT_PRINTF(2, 3);
void vshOpenLogFile(vshControl *ctl);
void vshOutputLogFile(vshControl *ctl, int log_level, const char *format,
                      va_list ap)
    ATTRIBUTE_FMT_PRINTF(3, 0);
void vshCloseLogFile(vshControl *ctl);

const char *vshCmddefGetInfo(const vshCmdDef *cmd, const char *info);
const vshCmdDef *vshCmddefSearch(const char *cmdname);
257
bool vshCmddefHelp(vshControl *ctl, const vshCmdDef *def);
258
const vshCmdGrp *vshCmdGrpSearch(const char *grpname);
259
bool vshCmdGrpHelp(vshControl *ctl, const vshCmdGrp *grp);
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275

int vshCommandOptInt(vshControl *ctl, const vshCmd *cmd,
                     const char *name, int *value)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int vshCommandOptUInt(vshControl *ctl, const vshCmd *cmd,
                      const char *name, unsigned int *value)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int vshCommandOptUIntWrap(vshControl *ctl, const vshCmd *cmd,
                          const char *name, unsigned int *value)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int vshCommandOptUL(vshControl *ctl, const vshCmd *cmd,
                    const char *name, unsigned long *value)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int vshCommandOptULWrap(vshControl *ctl, const vshCmd *cmd,
                        const char *name, unsigned long *value)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
276 277
int vshCommandOptStringQuiet(vshControl *ctl, const vshCmd *cmd,
                             const char *name, const char **value)
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int vshCommandOptStringReq(vshControl *ctl, const vshCmd *cmd,
                           const char *name, const char **value)
    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int vshCommandOptLongLong(vshControl *ctl, const vshCmd *cmd,
                          const char *name, long long *value)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int vshCommandOptULongLong(vshControl *ctl, const vshCmd *cmd,
                           const char *name, unsigned long long *value)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int vshCommandOptULongLongWrap(vshControl *ctl, const vshCmd *cmd,
                               const char *name, unsigned long long *value)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int vshCommandOptScaledInt(vshControl *ctl, const vshCmd *cmd,
                           const char *name, unsigned long long *value,
                           int scale, unsigned long long max)
    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
296 297 298 299
int vshBlockJobOptionBandwidth(vshControl *ctl,
                               const vshCmd *cmd,
                               bool bytes,
                               unsigned long *bandwidth);
300 301
bool vshCommandOptBool(const vshCmd *cmd, const char *name);
bool vshCommandRun(vshControl *ctl, const vshCmd *cmd);
302
bool vshCommandStringParse(vshControl *ctl, char *cmdstr, vshCmd **partial);
303 304 305 306 307 308

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);

309 310
void vshPrint(vshControl *ctl, const char *format, ...)
    ATTRIBUTE_FMT_PRINTF(2, 3);
311 312
void vshPrintExtra(vshControl *ctl, const char *format, ...)
    ATTRIBUTE_FMT_PRINTF(2, 3);
313
bool vshInit(vshControl *ctl, const vshCmdGrp *groups, const vshCmdDef *set);
E
Erik Skultety 已提交
314
bool vshInitReload(vshControl *ctl);
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
void vshDeinit(vshControl *ctl);
void vshDebug(vshControl *ctl, int level, const char *format, ...)
    ATTRIBUTE_FMT_PRINTF(3, 4);

/* User visible sort, so we want locale-specific case comparison.  */
# define vshStrcasecmp(S1, S2) strcasecmp(S1, S2)
int vshNameSorter(const void *a, const void *b);

virTypedParameterPtr vshFindTypedParamByName(const char *name,
                                             virTypedParameterPtr list,
                                             int count);
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);
344
void vshSaveLibvirtHelperError(void);
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380

/* file handling */
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);

/* 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[];
extern const vshCmdInfo info_help[];
extern const vshCmdOptDef opts_cd[];
extern const vshCmdInfo info_cd[];
extern const vshCmdOptDef opts_echo[];
extern const vshCmdInfo info_echo[];
extern const vshCmdInfo info_pwd[];
extern const vshCmdInfo info_quit[];
381
extern const vshCmdInfo info_selftest[];
382 383
extern const vshCmdOptDef opts_complete[];
extern const vshCmdInfo info_complete[];
384 385 386 387 388 389

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);
390
bool cmdSelfTest(vshControl *ctl, const vshCmd *cmd);
391
bool cmdComplete(vshControl *ctl, const vshCmd *cmd);
392

393 394 395 396 397 398 399
# define VSH_CMD_CD \
    { \
        .name = "cd", \
        .handler = cmdCd, \
        .opts = opts_cd, \
        .info = info_cd, \
        .flags = VSH_CMD_FLAG_NOCONNECT \
400 401
    }

402 403 404 405 406 407 408
# define VSH_CMD_ECHO \
    { \
        .name = "echo", \
        .handler = cmdEcho, \
        .opts = opts_echo, \
        .info = info_echo, \
        .flags = VSH_CMD_FLAG_NOCONNECT \
409 410
    }

411 412 413 414 415 416 417
# define VSH_CMD_EXIT \
    { \
        .name = "exit", \
        .handler = cmdQuit, \
        .opts = NULL, \
        .info = info_quit, \
        .flags = VSH_CMD_FLAG_NOCONNECT \
418 419
    }

420 421 422 423 424 425 426
# define VSH_CMD_HELP \
    { \
        .name = "help", \
        .handler = cmdHelp, \
        .opts = opts_help, \
        .info = info_help, \
        .flags = VSH_CMD_FLAG_NOCONNECT \
427 428
    }

429 430 431 432 433 434 435
# define VSH_CMD_PWD \
    { \
        .name = "pwd", \
        .handler = cmdPwd, \
        .opts = NULL, \
        .info = info_pwd, \
        .flags = VSH_CMD_FLAG_NOCONNECT \
436 437
    }

438 439 440 441 442 443 444
# define VSH_CMD_QUIT \
    { \
        .name = "quit", \
        .handler = cmdQuit, \
        .opts = NULL, \
        .info = info_quit, \
        .flags = VSH_CMD_FLAG_NOCONNECT \
445 446
    }

447 448 449 450 451 452 453 454
# define VSH_CMD_SELF_TEST \
    { \
        .name = "self-test", \
        .handler = cmdSelfTest, \
        .opts = NULL, \
        .info = info_selftest, \
        .flags = VSH_CMD_FLAG_NOCONNECT | VSH_CMD_FLAG_ALIAS, \
        .alias = "self-test" \
455 456
    }

457 458 459 460 461 462 463 464 465 466 467
# define VSH_CMD_COMPLETE \
    { \
        .name = "complete", \
        .handler = cmdComplete, \
        .opts = opts_complete, \
        .info = info_complete, \
        .flags = VSH_CMD_FLAG_NOCONNECT | VSH_CMD_FLAG_ALIAS, \
        .alias = "complete" \
    }


468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499

/* readline */
char * vshReadline(vshControl *ctl, const char *prompt);

/* allocation wrappers */
void *_vshMalloc(vshControl *ctl, size_t sz, const char *filename, int line);
# define vshMalloc(_ctl, _sz)    _vshMalloc(_ctl, _sz, __FILE__, __LINE__)

void *_vshCalloc(vshControl *ctl, size_t nmemb, size_t sz,
                 const char *filename, int line);
# define vshCalloc(_ctl, _nmemb, _sz) \
    _vshCalloc(_ctl, _nmemb, _sz, __FILE__, __LINE__)

char *_vshStrdup(vshControl *ctl, const char *s, const char *filename,
                 int line);
# define vshStrdup(_ctl, _s)    _vshStrdup(_ctl, _s, __FILE__, __LINE__)

/* 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.
 */
500 501 502 503 504
# define VSH_EXCLUSIVE_OPTIONS_EXPR(NAME1, EXPR1, NAME2, EXPR2) \
    if ((EXPR1) && (EXPR2)) { \
        vshError(ctl, _("Options --%s and --%s are mutually exclusive"), \
                 NAME1, NAME2); \
        return false; \
505 506 507 508 509 510 511 512 513 514 515 516 517
    }

/* 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.
 */
518 519
# define VSH_EXCLUSIVE_OPTIONS(NAME1, NAME2) \
    VSH_EXCLUSIVE_OPTIONS_EXPR(NAME1, vshCommandOptBool(cmd, NAME1), \
520 521 522 523 524 525 526 527 528 529 530 531 532
                               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.
 */
533
# define VSH_EXCLUSIVE_OPTIONS_VAR(VARNAME1, VARNAME2) \
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
    VSH_EXCLUSIVE_OPTIONS_EXPR(#VARNAME1, VARNAME1, #VARNAME2, VARNAME2)

/* 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.
 */
551 552 553 554 555 556 557
# define VSH_REQUIRE_OPTION_EXPR(NAME1, EXPR1, NAME2, EXPR2) \
    do { \
        if ((EXPR1) && !(EXPR2)) { \
            vshError(ctl, _("Option --%s is required by option --%s"), \
                     NAME2, NAME1); \
            return false; \
        } \
558 559 560 561 562 563 564 565 566 567 568 569 570
    } 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.
 */
571 572
# define VSH_REQUIRE_OPTION(NAME1, NAME2) \
    VSH_REQUIRE_OPTION_EXPR(NAME1, vshCommandOptBool(cmd, NAME1), \
573 574 575 576 577 578 579 580 581 582 583 584 585 586
                            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.
 */
587
# define VSH_REQUIRE_OPTION_VAR(VARNAME1, VARNAME2) \
588 589
    VSH_REQUIRE_OPTION_EXPR(#VARNAME1, VARNAME1, #VARNAME2, VARNAME2)

590
#endif /* LIBVIRT_VSH_H */