Signed-off-by: Lin Ma <lma@suse.com>
---
tools/virsh-domain.c | 107 +++++++++++++++++++++++++++------------------------
1 file changed, 57 insertions(+), 50 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 30da953446..36278ebc1c 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -13335,10 +13335,6 @@ static const vshCmdInfo info_event[] = {
static const vshCmdOptDef opts_event[] = {
VIRSH_COMMON_OPT_DOMAIN_OT_STRING(N_("filter by domain name, id or uuid"),
0),
- {.name = "event",
- .type = VSH_OT_STRING,
- .help = N_("which event type to wait for")
- },
{.name = "all",
.type = VSH_OT_BOOL,
.help = N_("wait for all events instead of just one type")
@@ -13359,6 +13355,10 @@ static const vshCmdOptDef opts_event[] = {
.type = VSH_OT_BOOL,
.help = N_("show timestamp for each printed event")
},
+ {.name = "event",
+ .type = VSH_OT_ARGV,
+ .help = N_("which event type to wait for")
+ },
{.name = NULL}
};
@@ -13368,58 +13368,64 @@ cmdEvent(vshControl *ctl, const vshCmd *cmd)
virDomainPtr dom = NULL;
bool ret = false;
int timeout = 0;
- virshDomEventData *data = NULL;
+ virshDomEventData *dataList = NULL;
size_t i;
- const char *eventName = NULL;
- int event = -1;
+ int *eventIdxList = NULL;
+ size_t nevents = 0;
+ int eventid = -1;
bool all = vshCommandOptBool(cmd, "all");
bool loop = vshCommandOptBool(cmd, "loop");
bool timestamp = vshCommandOptBool(cmd, "timestamp");
+ bool event = vshCommandOptBool(cmd, "event");
int count = 0;
+ const vshCmdOpt *opt = NULL;
virshControlPtr priv = ctl->privData;
if (vshCommandOptBool(cmd, "list")) {
- for (event = 0; event < VIR_DOMAIN_EVENT_ID_LAST; event++)
- vshPrint(ctl, "%s\n", vshEventCallbacks[event].name);
+ for (eventid = 0; eventid < VIR_DOMAIN_EVENT_ID_LAST; eventid++)
+ vshPrint(ctl, "%s\n", vshEventCallbacks[eventid].name);
return true;
}
- if (vshCommandOptStringReq(ctl, cmd, "event", &eventName) < 0)
- return false;
- if (eventName) {
- for (event = 0; event < VIR_DOMAIN_EVENT_ID_LAST; event++)
- if (STREQ(eventName, vshEventCallbacks[event].name))
- break;
- if (event == VIR_DOMAIN_EVENT_ID_LAST) {
- vshError(ctl, _("unknown event type %s"), eventName);
- return false;
+ if (event) {
+ while ((opt = vshCommandOptArgv(ctl, cmd, opt))) {
+ if (opt->data) {
+ for (eventid = 0; eventid < VIR_DOMAIN_EVENT_ID_LAST; eventid++)
+ if (STREQ(opt->data, vshEventCallbacks[eventid].name))
+ break;
+ if (eventid == VIR_DOMAIN_EVENT_ID_LAST) {
+ vshError(ctl, _("unknown event type %s"), opt->data);
+ goto cleanup;
+ }
+ size_t n = nevents;
+ virshDomEventData data;
+ data.ctl = ctl;
+ data.loop = loop;
+ data.count = &count;
+ data.timestamp = timestamp;
+ data.cb = &vshEventCallbacks[eventid];
+ data.id = -1;
+ if (VIR_APPEND_ELEMENT(dataList, nevents, data) < 0)
+ goto cleanup;
+ if (VIR_APPEND_ELEMENT(eventIdxList, n, eventid) < 0)
+ goto cleanup;
+ }
}
- } else if (!all) {
- vshError(ctl, "%s",
- _("one of --list, --all, or --event <type> is required"));
- return false;
- }
-
- if (all) {
- if (VIR_ALLOC_N(data, VIR_DOMAIN_EVENT_ID_LAST) < 0)
+ } else if (all) {
+ if (VIR_ALLOC_N(dataList, VIR_DOMAIN_EVENT_ID_LAST) < 0)
goto cleanup;
for (i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i++) {
- data[i].ctl = ctl;
- data[i].loop = loop;
- data[i].count = &count;
- data[i].timestamp = timestamp;
- data[i].cb = &vshEventCallbacks[i];
- data[i].id = -1;
+ dataList[i].ctl = ctl;
+ dataList[i].loop = loop;
+ dataList[i].count = &count;
+ dataList[i].timestamp = timestamp;
+ dataList[i].cb = &vshEventCallbacks[i];
+ dataList[i].id = -1;
}
} else {
- if (VIR_ALLOC_N(data, 1) < 0)
- goto cleanup;
- data[0].ctl = ctl;
- data[0].loop = vshCommandOptBool(cmd, "loop");
- data[0].count = &count;
- data[0].timestamp = timestamp;
- data[0].cb = &vshEventCallbacks[event];
- data[0].id = -1;
+ vshError(ctl, "%s",
+ _("one of --list, --all, or --event <type> is required"));
+ return false;
}
if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0)
goto cleanup;
@@ -13431,11 +13437,11 @@ cmdEvent(vshControl *ctl, const vshCmd *cmd)
if (vshEventStart(ctl, timeout) < 0)
goto cleanup;
- for (i = 0; i < (all ? VIR_DOMAIN_EVENT_ID_LAST : 1); i++) {
- if ((data[i].id = virConnectDomainEventRegisterAny(priv->conn, dom,
- all ? i : event,
- data[i].cb->cb,
- &data[i],
+ for (i = 0; i < (event ? nevents : VIR_DOMAIN_EVENT_ID_LAST); i++) {
+ if ((dataList[i].id = virConnectDomainEventRegisterAny(priv->conn, dom,
+ event ? eventIdxList[i] : i,
+ dataList[i].cb->cb,
+ &dataList[i],
NULL)) < 0) {
/* When registering for all events: if the first
* registration succeeds, silently ignore failures on all
@@ -13465,14 +13471,15 @@ cmdEvent(vshControl *ctl, const vshCmd *cmd)
cleanup:
vshEventCleanup(ctl);
- if (data) {
- for (i = 0; i < (all ? VIR_DOMAIN_EVENT_ID_LAST : 1); i++) {
- if (data[i].id >= 0 &&
- virConnectDomainEventDeregisterAny(priv->conn, data[i].id) < 0)
+ if (dataList) {
+ for (i = 0; i < (event ? nevents : VIR_DOMAIN_EVENT_ID_LAST); i++) {
+ if (dataList[i].id >= 0 &&
+ virConnectDomainEventDeregisterAny(priv->conn, dataList[i].id) < 0)
ret = false;
}
- VIR_FREE(data);
+ VIR_FREE(dataList);
}
+ VIR_FREE(eventIdxList);
virshDomainFree(dom);
return ret;
}
--
2.15.1
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 05/08/2018 04:20 PM, Lin Ma wrote: > Signed-off-by: Lin Ma <lma@suse.com> > --- > tools/virsh-domain.c | 107 +++++++++++++++++++++++++++------------------------ > 1 file changed, 57 insertions(+), 50 deletions(-) > > diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c > index 30da953446..36278ebc1c 100644 > --- a/tools/virsh-domain.c > +++ b/tools/virsh-domain.c > @@ -13335,10 +13335,6 @@ static const vshCmdInfo info_event[] = { > static const vshCmdOptDef opts_event[] = { > VIRSH_COMMON_OPT_DOMAIN_OT_STRING(N_("filter by domain name, id or uuid"), > 0), > - {.name = "event", > - .type = VSH_OT_STRING, > - .help = N_("which event type to wait for") > - }, > {.name = "all", > .type = VSH_OT_BOOL, > .help = N_("wait for all events instead of just one type") > @@ -13359,6 +13355,10 @@ static const vshCmdOptDef opts_event[] = { > .type = VSH_OT_BOOL, > .help = N_("show timestamp for each printed event") > }, > + {.name = "event", > + .type = VSH_OT_ARGV, > + .help = N_("which event type to wait for") > + }, > {.name = NULL} > }; I'm not sure we can do this. Consider somebody has the following line in their script: virsh event domain reboot (which is supposed to wait for reboot event on domain "domain"). However, after your change virsh fails. This would introduce a regression. Not mentioning the fact that documentation needs update too ;-) > > @@ -13368,58 +13368,64 @@ cmdEvent(vshControl *ctl, const vshCmd *cmd) > virDomainPtr dom = NULL; > bool ret = false; > int timeout = 0; > - virshDomEventData *data = NULL; > + virshDomEventData *dataList = NULL; > size_t i; > - const char *eventName = NULL; > - int event = -1; > + int *eventIdxList = NULL; > + size_t nevents = 0; > + int eventid = -1; > bool all = vshCommandOptBool(cmd, "all"); > bool loop = vshCommandOptBool(cmd, "loop"); > bool timestamp = vshCommandOptBool(cmd, "timestamp"); > + bool event = vshCommandOptBool(cmd, "event"); > int count = 0; > + const vshCmdOpt *opt = NULL; > virshControlPtr priv = ctl->privData; > > if (vshCommandOptBool(cmd, "list")) { > - for (event = 0; event < VIR_DOMAIN_EVENT_ID_LAST; event++) > - vshPrint(ctl, "%s\n", vshEventCallbacks[event].name); > + for (eventid = 0; eventid < VIR_DOMAIN_EVENT_ID_LAST; eventid++) > + vshPrint(ctl, "%s\n", vshEventCallbacks[eventid].name); > return true; > } > > - if (vshCommandOptStringReq(ctl, cmd, "event", &eventName) < 0) > - return false; > - if (eventName) { > - for (event = 0; event < VIR_DOMAIN_EVENT_ID_LAST; event++) > - if (STREQ(eventName, vshEventCallbacks[event].name)) > - break; > - if (event == VIR_DOMAIN_EVENT_ID_LAST) { > - vshError(ctl, _("unknown event type %s"), eventName); > - return false; > + if (event) { > + while ((opt = vshCommandOptArgv(ctl, cmd, opt))) { > + if (opt->data) { > + for (eventid = 0; eventid < VIR_DOMAIN_EVENT_ID_LAST; eventid++) > + if (STREQ(opt->data, vshEventCallbacks[eventid].name)) > + break; > + if (eventid == VIR_DOMAIN_EVENT_ID_LAST) { > + vshError(ctl, _("unknown event type %s"), opt->data); > + goto cleanup; > + } > + size_t n = nevents; > + virshDomEventData data; > + data.ctl = ctl; > + data.loop = loop; > + data.count = &count; > + data.timestamp = timestamp; > + data.cb = &vshEventCallbacks[eventid]; > + data.id = -1; > + if (VIR_APPEND_ELEMENT(dataList, nevents, data) < 0) > + goto cleanup; > + if (VIR_APPEND_ELEMENT(eventIdxList, n, eventid) < 0) > + goto cleanup; > + } > } > - } else if (!all) { > - vshError(ctl, "%s", > - _("one of --list, --all, or --event <type> is required")); > - return false; > - } > - > - if (all) { > - if (VIR_ALLOC_N(data, VIR_DOMAIN_EVENT_ID_LAST) < 0) > + } else if (all) { > + if (VIR_ALLOC_N(dataList, VIR_DOMAIN_EVENT_ID_LAST) < 0) > goto cleanup; > for (i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i++) { > - data[i].ctl = ctl; > - data[i].loop = loop; > - data[i].count = &count; > - data[i].timestamp = timestamp; > - data[i].cb = &vshEventCallbacks[i]; > - data[i].id = -1; > + dataList[i].ctl = ctl; > + dataList[i].loop = loop; > + dataList[i].count = &count; > + dataList[i].timestamp = timestamp; > + dataList[i].cb = &vshEventCallbacks[i]; > + dataList[i].id = -1; How about doing simple: if (event) { parse events into @eventIdxList } else if (all) { VIR_ALLOC_N(eventIdxList, VIR_DOMAIN_EVENT_ID_LAST); for (i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i++) eventIdxList[i] = i; } The idea is that eventIdxList will be populated in both cases. It simplifies the code a bit because then we don't have to special case on all the places. The @dataList can be constructed outside of those if bodies then. > } > } else { > - if (VIR_ALLOC_N(data, 1) < 0) > - goto cleanup; > - data[0].ctl = ctl; > - data[0].loop = vshCommandOptBool(cmd, "loop"); > - data[0].count = &count; > - data[0].timestamp = timestamp; > - data[0].cb = &vshEventCallbacks[event]; > - data[0].id = -1; > + vshError(ctl, "%s", > + _("one of --list, --all, or --event <type> is required")); > + return false; > } > if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0) > goto cleanup; > @@ -13431,11 +13437,11 @@ cmdEvent(vshControl *ctl, const vshCmd *cmd) > if (vshEventStart(ctl, timeout) < 0) > goto cleanup; > > - for (i = 0; i < (all ? VIR_DOMAIN_EVENT_ID_LAST : 1); i++) { > - if ((data[i].id = virConnectDomainEventRegisterAny(priv->conn, dom, > - all ? i : event, > - data[i].cb->cb, > - &data[i], > + for (i = 0; i < (event ? nevents : VIR_DOMAIN_EVENT_ID_LAST); i++) { > + if ((dataList[i].id = virConnectDomainEventRegisterAny(priv->conn, dom, > + event ? eventIdxList[i] : i, > + dataList[i].cb->cb, > + &dataList[i], > NULL)) < 0) { > /* When registering for all events: if the first > * registration succeeds, silently ignore failures on all > @@ -13465,14 +13471,15 @@ cmdEvent(vshControl *ctl, const vshCmd *cmd) > > cleanup: > vshEventCleanup(ctl); > - if (data) { > - for (i = 0; i < (all ? VIR_DOMAIN_EVENT_ID_LAST : 1); i++) { > - if (data[i].id >= 0 && > - virConnectDomainEventDeregisterAny(priv->conn, data[i].id) < 0) > + if (dataList) { > + for (i = 0; i < (event ? nevents : VIR_DOMAIN_EVENT_ID_LAST); i++) { > + if (dataList[i].id >= 0 && > + virConnectDomainEventDeregisterAny(priv->conn, dataList[i].id) < 0) > ret = false; > } > - VIR_FREE(data); > + VIR_FREE(dataList); > } > + VIR_FREE(eventIdxList); > virshDomainFree(dom); > return ret; > } > Again, problem is that we cannot do the argument swap like you did. But without it the rest of the patch is needless. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 05/10/2018 05:17 PM, Michal Privoznik wrote: > On 05/08/2018 04:20 PM, Lin Ma wrote: >> Signed-off-by: Lin Ma <lma@suse.com> >> --- >> tools/virsh-domain.c | 107 +++++++++++++++++++++++++++------------------------ >> 1 file changed, 57 insertions(+), 50 deletions(-) >> >> diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c >> index 30da953446..36278ebc1c 100644 >> --- a/tools/virsh-domain.c >> +++ b/tools/virsh-domain.c >> @@ -13335,10 +13335,6 @@ static const vshCmdInfo info_event[] = { >> static const vshCmdOptDef opts_event[] = { >> VIRSH_COMMON_OPT_DOMAIN_OT_STRING(N_("filter by domain name, id or uuid"), >> 0), >> - {.name = "event", >> - .type = VSH_OT_STRING, >> - .help = N_("which event type to wait for") >> - }, >> {.name = "all", >> .type = VSH_OT_BOOL, >> .help = N_("wait for all events instead of just one type") >> @@ -13359,6 +13355,10 @@ static const vshCmdOptDef opts_event[] = { >> .type = VSH_OT_BOOL, >> .help = N_("show timestamp for each printed event") >> }, >> + {.name = "event", >> + .type = VSH_OT_ARGV, >> + .help = N_("which event type to wait for") >> + }, >> {.name = NULL} >> }; > I'm not sure we can do this. Consider somebody has the following line in > their script: > > virsh event domain reboot > > (which is supposed to wait for reboot event on domain "domain"). > > However, after your change virsh fails. This would introduce a > regression. Not mentioning the fact that documentation needs update too ;-) > >> >> @@ -13368,58 +13368,64 @@ cmdEvent(vshControl *ctl, const vshCmd *cmd) >> virDomainPtr dom = NULL; >> bool ret = false; >> int timeout = 0; >> - virshDomEventData *data = NULL; >> + virshDomEventData *dataList = NULL; >> size_t i; >> - const char *eventName = NULL; >> - int event = -1; >> + int *eventIdxList = NULL; >> + size_t nevents = 0; >> + int eventid = -1; >> bool all = vshCommandOptBool(cmd, "all"); >> bool loop = vshCommandOptBool(cmd, "loop"); >> bool timestamp = vshCommandOptBool(cmd, "timestamp"); >> + bool event = vshCommandOptBool(cmd, "event"); >> int count = 0; >> + const vshCmdOpt *opt = NULL; >> virshControlPtr priv = ctl->privData; >> >> if (vshCommandOptBool(cmd, "list")) { >> - for (event = 0; event < VIR_DOMAIN_EVENT_ID_LAST; event++) >> - vshPrint(ctl, "%s\n", vshEventCallbacks[event].name); >> + for (eventid = 0; eventid < VIR_DOMAIN_EVENT_ID_LAST; eventid++) >> + vshPrint(ctl, "%s\n", vshEventCallbacks[eventid].name); >> return true; >> } >> >> - if (vshCommandOptStringReq(ctl, cmd, "event", &eventName) < 0) >> - return false; >> - if (eventName) { >> - for (event = 0; event < VIR_DOMAIN_EVENT_ID_LAST; event++) >> - if (STREQ(eventName, vshEventCallbacks[event].name)) >> - break; >> - if (event == VIR_DOMAIN_EVENT_ID_LAST) { >> - vshError(ctl, _("unknown event type %s"), eventName); >> - return false; >> + if (event) { >> + while ((opt = vshCommandOptArgv(ctl, cmd, opt))) { >> + if (opt->data) { >> + for (eventid = 0; eventid < VIR_DOMAIN_EVENT_ID_LAST; eventid++) >> + if (STREQ(opt->data, vshEventCallbacks[eventid].name)) >> + break; >> + if (eventid == VIR_DOMAIN_EVENT_ID_LAST) { >> + vshError(ctl, _("unknown event type %s"), opt->data); >> + goto cleanup; >> + } >> + size_t n = nevents; >> + virshDomEventData data; >> + data.ctl = ctl; >> + data.loop = loop; >> + data.count = &count; >> + data.timestamp = timestamp; >> + data.cb = &vshEventCallbacks[eventid]; >> + data.id = -1; >> + if (VIR_APPEND_ELEMENT(dataList, nevents, data) < 0) >> + goto cleanup; >> + if (VIR_APPEND_ELEMENT(eventIdxList, n, eventid) < 0) >> + goto cleanup; >> + } >> } >> - } else if (!all) { >> - vshError(ctl, "%s", >> - _("one of --list, --all, or --event <type> is required")); >> - return false; >> - } >> - >> - if (all) { >> - if (VIR_ALLOC_N(data, VIR_DOMAIN_EVENT_ID_LAST) < 0) >> + } else if (all) { >> + if (VIR_ALLOC_N(dataList, VIR_DOMAIN_EVENT_ID_LAST) < 0) >> goto cleanup; >> for (i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i++) { >> - data[i].ctl = ctl; >> - data[i].loop = loop; >> - data[i].count = &count; >> - data[i].timestamp = timestamp; >> - data[i].cb = &vshEventCallbacks[i]; >> - data[i].id = -1; >> + dataList[i].ctl = ctl; >> + dataList[i].loop = loop; >> + dataList[i].count = &count; >> + dataList[i].timestamp = timestamp; >> + dataList[i].cb = &vshEventCallbacks[i]; >> + dataList[i].id = -1; > How about doing simple: > > if (event) { > parse events into @eventIdxList > } else if (all) { > VIR_ALLOC_N(eventIdxList, VIR_DOMAIN_EVENT_ID_LAST); > for (i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i++) > eventIdxList[i] = i; > } > > The idea is that eventIdxList will be populated in both cases. It > simplifies the code a bit because then we don't have to special case on > all the places. The @dataList can be constructed outside of those if > bodies then. > >> } >> } else { >> - if (VIR_ALLOC_N(data, 1) < 0) >> - goto cleanup; >> - data[0].ctl = ctl; >> - data[0].loop = vshCommandOptBool(cmd, "loop"); >> - data[0].count = &count; >> - data[0].timestamp = timestamp; >> - data[0].cb = &vshEventCallbacks[event]; >> - data[0].id = -1; >> + vshError(ctl, "%s", >> + _("one of --list, --all, or --event <type> is required")); >> + return false; >> } >> if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0) >> goto cleanup; >> @@ -13431,11 +13437,11 @@ cmdEvent(vshControl *ctl, const vshCmd *cmd) >> if (vshEventStart(ctl, timeout) < 0) >> goto cleanup; >> >> - for (i = 0; i < (all ? VIR_DOMAIN_EVENT_ID_LAST : 1); i++) { >> - if ((data[i].id = virConnectDomainEventRegisterAny(priv->conn, dom, >> - all ? i : event, >> - data[i].cb->cb, >> - &data[i], >> + for (i = 0; i < (event ? nevents : VIR_DOMAIN_EVENT_ID_LAST); i++) { >> + if ((dataList[i].id = virConnectDomainEventRegisterAny(priv->conn, dom, >> + event ? eventIdxList[i] : i, >> + dataList[i].cb->cb, >> + &dataList[i], >> NULL)) < 0) { >> /* When registering for all events: if the first >> * registration succeeds, silently ignore failures on all >> @@ -13465,14 +13471,15 @@ cmdEvent(vshControl *ctl, const vshCmd *cmd) >> >> cleanup: >> vshEventCleanup(ctl); >> - if (data) { >> - for (i = 0; i < (all ? VIR_DOMAIN_EVENT_ID_LAST : 1); i++) { >> - if (data[i].id >= 0 && >> - virConnectDomainEventDeregisterAny(priv->conn, data[i].id) < 0) >> + if (dataList) { >> + for (i = 0; i < (event ? nevents : VIR_DOMAIN_EVENT_ID_LAST); i++) { >> + if (dataList[i].id >= 0 && >> + virConnectDomainEventDeregisterAny(priv->conn, dataList[i].id) < 0) >> ret = false; >> } >> - VIR_FREE(data); >> + VIR_FREE(dataList); >> } >> + VIR_FREE(eventIdxList); >> virshDomainFree(dom); >> return ret; >> } >> > Again, problem is that we cannot do the argument swap like you did. > But without it the rest of the patch is needless. Hmm, If we can't change the type to 'VSH_OT_ARGV', then this patch is needless. OK, Let's forget this patch for the time being. Thanks, Lin -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.