diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 4f00e65867..44f65adc22 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -36,6 +36,7 @@ #include "intprops.h" #include "memory.h" #include "virmacaddr.h" +#include "virsh-domain.h" #include "xml.h" static const char * diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index e949dcffab..6a87d4996d 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -58,6 +58,57 @@ # define SA_SIGINFO 0 #endif +virDomainPtr +vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd, + const char **name, unsigned int flags) +{ + virDomainPtr dom = NULL; + const char *n = NULL; + int id; + const char *optname = "domain"; + virCheckFlags(VSH_BYID | VSH_BYUUID | VSH_BYNAME, NULL); + + if (!vshCmdHasOption(ctl, cmd, optname)) + return NULL; + + if (vshCommandOptString(cmd, optname, &n) <= 0) + return NULL; + + vshDebug(ctl, VSH_ERR_INFO, "%s: found option <%s>: %s\n", + cmd->def->name, optname, n); + + if (name) + *name = n; + + /* try it by ID */ + if (flags & VSH_BYID) { + if (virStrToLong_i(n, NULL, 10, &id) == 0 && id >= 0) { + vshDebug(ctl, VSH_ERR_DEBUG, + "%s: <%s> seems like domain ID\n", + cmd->def->name, optname); + dom = virDomainLookupByID(ctl->conn, id); + } + } + /* try it by UUID */ + if (!dom && (flags & VSH_BYUUID) && + strlen(n) == VIR_UUID_STRING_BUFLEN-1) { + vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as domain UUID\n", + cmd->def->name, optname); + dom = virDomainLookupByUUIDString(ctl->conn, n); + } + /* try it by NAME */ + if (!dom && (flags & VSH_BYNAME)) { + vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as domain NAME\n", + cmd->def->name, optname); + dom = virDomainLookupByName(ctl->conn, n); + } + + if (!dom) + vshError(ctl, _("failed to get domain '%s'"), n); + + return dom; +} + static const char * vshDomainVcpuStateToString(int state) { diff --git a/tools/virsh-domain.h b/tools/virsh-domain.h index b1b79304ed..cd51b573a4 100644 --- a/tools/virsh-domain.h +++ b/tools/virsh-domain.h @@ -28,6 +28,13 @@ # include "virsh.h" +virDomainPtr vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd, + const char **name, unsigned int flags); + +/* default is lookup by Id, Name and UUID */ +# define vshCommandOptDomain(_ctl, _cmd, _name) \ + vshCommandOptDomainBy(_ctl, _cmd, _name, VSH_BYID|VSH_BYUUID|VSH_BYNAME) + extern const vshCmdDef domManagementCmds[]; #endif /* VIRSH_DOMAIN_H */ diff --git a/tools/virsh-host.c b/tools/virsh-host.c index e3cff8ede8..3c44969405 100644 --- a/tools/virsh-host.c +++ b/tools/virsh-host.c @@ -35,6 +35,7 @@ #include "buf.h" #include "memory.h" #include "util.h" +#include "virsh-domain.h" #include "xml.h" /* diff --git a/tools/virsh-interface.c b/tools/virsh-interface.c index ad080a18a2..e43aa91ceb 100644 --- a/tools/virsh-interface.c +++ b/tools/virsh-interface.c @@ -38,7 +38,7 @@ vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd, if (!optname) optname = "interface"; - if (!cmd_has_option(ctl, cmd, optname)) + if (!vshCmdHasOption(ctl, cmd, optname)) return NULL; if (vshCommandOptString(cmd, optname, &n) <= 0) diff --git a/tools/virsh-network.c b/tools/virsh-network.c index b33e2d61ed..b891c91068 100644 --- a/tools/virsh-network.c +++ b/tools/virsh-network.c @@ -35,7 +35,7 @@ vshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd, virNetworkPtr network = NULL; const char *n = NULL; const char *optname = "network"; - if (!cmd_has_option(ctl, cmd, optname)) + if (!vshCmdHasOption(ctl, cmd, optname)) return NULL; if (vshCommandOptString(cmd, optname, &n) <= 0) diff --git a/tools/virsh-nwfilter.c b/tools/virsh-nwfilter.c index 501e20dc24..a6ef233f55 100644 --- a/tools/virsh-nwfilter.c +++ b/tools/virsh-nwfilter.c @@ -35,7 +35,7 @@ vshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd, virNWFilterPtr nwfilter = NULL; const char *n = NULL; const char *optname = "nwfilter"; - if (!cmd_has_option(ctl, cmd, optname)) + if (!vshCmdHasOption(ctl, cmd, optname)) return NULL; if (vshCommandOptString(cmd, optname, &n) <= 0) diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c index 049ead595f..6f971dac4d 100644 --- a/tools/virsh-secret.c +++ b/tools/virsh-secret.c @@ -30,7 +30,7 @@ vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, const char **name) const char *n = NULL; const char *optname = "secret"; - if (!cmd_has_option(ctl, cmd, optname)) + if (!vshCmdHasOption(ctl, cmd, optname)) return NULL; if (vshCommandOptString(cmd, optname, &n) <= 0) diff --git a/tools/virsh.c b/tools/virsh.c index 793a357bd1..fe79b7c98d 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -128,7 +128,7 @@ _vshStrdup(vshControl *ctl, const char *s, const char *filename, int line) /* Poison the raw allocating identifiers in favor of our vsh variants. */ #define strdup use_vshStrdup_instead_of_strdup -static int +int vshNameSorter(const void *a, const void *b) { const char **sa = (const char**)a; @@ -1441,8 +1441,8 @@ vshCommandOptArgv(const vshCmd *cmd, const vshCmdOpt *opt) /* Determine whether CMD->opts includes an option with name OPTNAME. If not, give a diagnostic and return false. If so, return true. */ -static bool -cmd_has_option(vshControl *ctl, const vshCmd *cmd, const char *optname) +bool +vshCmdHasOption(vshControl *ctl, const vshCmd *cmd, const char *optname) { /* Iterate through cmd->opts, to ensure that there is an entry with name OPTNAME and type VSH_OT_DATA. */ @@ -1461,54 +1461,6 @@ cmd_has_option(vshControl *ctl, const vshCmd *cmd, const char *optname) return found; } -virDomainPtr -vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd, - const char **name, int flag) -{ - virDomainPtr dom = NULL; - const char *n = NULL; - int id; - const char *optname = "domain"; - if (!cmd_has_option(ctl, cmd, optname)) - return NULL; - - if (vshCommandOptString(cmd, optname, &n) <= 0) - return NULL; - - vshDebug(ctl, VSH_ERR_INFO, "%s: found option <%s>: %s\n", - cmd->def->name, optname, n); - - if (name) - *name = n; - - /* try it by ID */ - if (flag & VSH_BYID) { - if (virStrToLong_i(n, NULL, 10, &id) == 0 && id >= 0) { - vshDebug(ctl, VSH_ERR_DEBUG, - "%s: <%s> seems like domain ID\n", - cmd->def->name, optname); - dom = virDomainLookupByID(ctl->conn, id); - } - } - /* try it by UUID */ - if (dom==NULL && (flag & VSH_BYUUID) && strlen(n)==VIR_UUID_STRING_BUFLEN-1) { - vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as domain UUID\n", - cmd->def->name, optname); - dom = virDomainLookupByUUIDString(ctl->conn, n); - } - /* try it by NAME */ - if (dom==NULL && (flag & VSH_BYNAME)) { - vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as domain NAME\n", - cmd->def->name, optname); - dom = virDomainLookupByName(ctl->conn, n); - } - - if (!dom) - vshError(ctl, _("failed to get domain '%s'"), n); - - return dom; -} - /* * Executes command(s) and returns return code from last command */ diff --git a/tools/virsh.h b/tools/virsh.h index 24d2020f41..818d51546a 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -286,18 +286,15 @@ int vshCommandOptScaledInt(const vshCmd *cmd, const char *name, bool vshCommandOptBool(const vshCmd *cmd, const char *name); const vshCmdOpt *vshCommandOptArgv(const vshCmd *cmd, const vshCmdOpt *opt); +bool vshCmdHasOption(vshControl *ctl, const vshCmd *cmd, const char *optname); -# define VSH_BYID (1 << 1) -# define VSH_BYUUID (1 << 2) -# define VSH_BYNAME (1 << 3) -# define VSH_BYMAC (1 << 4) - -virDomainPtr vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd, - const char **name, int flag); - -/* default is lookup by Id, Name and UUID */ -# define vshCommandOptDomain(_ctl, _cmd, _name) \ - vshCommandOptDomainBy(_ctl, _cmd, _name, VSH_BYID|VSH_BYUUID|VSH_BYNAME) +/* Filter flags for various vshCommandOpt*By() functions */ +typedef enum { + VSH_BYID = (1 << 1), + VSH_BYUUID = (1 << 2), + VSH_BYNAME = (1 << 3), + VSH_BYMAC = (1 << 4), +} vshLookupByFlags; void vshPrintExtra(vshControl *ctl, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); @@ -309,6 +306,7 @@ void vshDebug(vshControl *ctl, int level, const char *format, ...) /* 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); int vshDomainState(vshControl *ctl, virDomainPtr dom, int *reason); bool vshConnectionUsability(vshControl *ctl, virConnectPtr conn);