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.