mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-05 16:33:50 +00:00
qemu: virsh wrapper for qemu events
Any new API deserves a good virsh wrapper :) qemu-monitor-event [<domain>] [<event>] [--pretty] [--loop] [--timeout <number>] Very similar to the previous work on 'virsh event'. For an example session: $ virsh -c qemu:///system qemu-monitor-event --event SHUTDOWN& $ virsh -c qemu:///system start f18-live Domain f18-live started $ virsh -c qemu:///system destroy f18-live Domain f18-live destroyed event SHUTDOWN at 1391212552.026544 for domain f18-live: (null) events received: 1 [1]+ Done virsh -c qemu:///system qemu-monitor-event --event SHUTDOWN $ * tools/virsh-domain.c (cmdQemuMonitorEvent): New command. * tools/virsh.pod (qemu-monitor-event): Document it. Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
2629520342
commit
88996de1c3
@ -7915,6 +7915,135 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "qemu-monitor-event" command
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct vshQemuEventData {
|
||||||
|
vshControl *ctl;
|
||||||
|
bool loop;
|
||||||
|
bool pretty;
|
||||||
|
int count;
|
||||||
|
};
|
||||||
|
typedef struct vshQemuEventData vshQemuEventData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
vshEventPrint(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom,
|
||||||
|
const char *event, long long seconds, unsigned int micros,
|
||||||
|
const char *details, void *opaque)
|
||||||
|
{
|
||||||
|
vshQemuEventData *data = opaque;
|
||||||
|
virJSONValuePtr pretty = NULL;
|
||||||
|
char *str = NULL;
|
||||||
|
|
||||||
|
if (!data->loop && data->count)
|
||||||
|
return;
|
||||||
|
if (data->pretty && details) {
|
||||||
|
pretty = virJSONValueFromString(details);
|
||||||
|
if (pretty && (str = virJSONValueToString(pretty, true)))
|
||||||
|
details = str;
|
||||||
|
}
|
||||||
|
vshPrint(data->ctl, "event %s at %lld.%06u for domain %s: %s\n",
|
||||||
|
event, seconds, micros, virDomainGetName(dom), NULLSTR(details));
|
||||||
|
data->count++;
|
||||||
|
if (!data->loop)
|
||||||
|
vshEventDone(data->ctl);
|
||||||
|
|
||||||
|
VIR_FREE(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const vshCmdInfo info_qemu_monitor_event[] = {
|
||||||
|
{.name = "help",
|
||||||
|
.data = N_("QEMU Monitor Events")
|
||||||
|
},
|
||||||
|
{.name = "desc",
|
||||||
|
.data = N_("Listen for QEMU Monitor Events")
|
||||||
|
},
|
||||||
|
{.name = NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const vshCmdOptDef opts_qemu_monitor_event[] = {
|
||||||
|
{.name = "domain",
|
||||||
|
.type = VSH_OT_DATA,
|
||||||
|
.help = N_("filter by domain name, id or uuid")
|
||||||
|
},
|
||||||
|
{.name = "event",
|
||||||
|
.type = VSH_OT_DATA,
|
||||||
|
.help = N_("filter by event name")
|
||||||
|
},
|
||||||
|
{.name = "pretty",
|
||||||
|
.type = VSH_OT_BOOL,
|
||||||
|
.help = N_("pretty-print any JSON output")
|
||||||
|
},
|
||||||
|
{.name = "loop",
|
||||||
|
.type = VSH_OT_BOOL,
|
||||||
|
.help = N_("loop until timeout or interrupt, rather than one-shot")
|
||||||
|
},
|
||||||
|
{.name = "timeout",
|
||||||
|
.type = VSH_OT_INT,
|
||||||
|
.help = N_("timeout seconds")
|
||||||
|
},
|
||||||
|
{.name = NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cmdQemuMonitorEvent(vshControl *ctl, const vshCmd *cmd)
|
||||||
|
{
|
||||||
|
virDomainPtr dom = NULL;
|
||||||
|
bool ret = false;
|
||||||
|
unsigned int flags = 0;
|
||||||
|
int eventId = -1;
|
||||||
|
int timeout = 0;
|
||||||
|
const char *event = NULL;
|
||||||
|
vshQemuEventData data;
|
||||||
|
|
||||||
|
data.ctl = ctl;
|
||||||
|
data.loop = vshCommandOptBool(cmd, "loop");
|
||||||
|
data.pretty = vshCommandOptBool(cmd, "pretty");
|
||||||
|
data.count = 0;
|
||||||
|
if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0)
|
||||||
|
return false;
|
||||||
|
if (vshCommandOptString(cmd, "event", &event) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (vshCommandOptBool(cmd, "domain"))
|
||||||
|
dom = vshCommandOptDomain(ctl, cmd, NULL);
|
||||||
|
if (vshEventStart(ctl, timeout) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((eventId = virConnectDomainQemuMonitorEventRegister(ctl->conn, dom,
|
||||||
|
event,
|
||||||
|
vshEventPrint,
|
||||||
|
&data, NULL,
|
||||||
|
flags)) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
switch (vshEventWait(ctl)) {
|
||||||
|
case VSH_EVENT_INTERRUPT:
|
||||||
|
vshPrint(ctl, _("event loop interrupted\n"));
|
||||||
|
break;
|
||||||
|
case VSH_EVENT_TIMEOUT:
|
||||||
|
vshPrint(ctl, _("event loop timed out\n"));
|
||||||
|
break;
|
||||||
|
case VSH_EVENT_DONE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
vshPrint(ctl, _("events received: %d\n"), data.count);
|
||||||
|
if (data.count)
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
vshEventCleanup(ctl);
|
||||||
|
if (eventId >= 0 &&
|
||||||
|
virConnectDomainQemuMonitorEventDeregister(ctl->conn, eventId) < 0)
|
||||||
|
ret = false;
|
||||||
|
if (dom)
|
||||||
|
virDomainFree(dom);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "qemu-attach" command
|
* "qemu-attach" command
|
||||||
*/
|
*/
|
||||||
@ -11550,6 +11679,12 @@ const vshCmdDef domManagementCmds[] = {
|
|||||||
.info = info_qemu_monitor_command,
|
.info = info_qemu_monitor_command,
|
||||||
.flags = 0
|
.flags = 0
|
||||||
},
|
},
|
||||||
|
{.name = "qemu-monitor-event",
|
||||||
|
.handler = cmdQemuMonitorEvent,
|
||||||
|
.opts = opts_qemu_monitor_event,
|
||||||
|
.info = info_qemu_monitor_event,
|
||||||
|
.flags = 0
|
||||||
|
},
|
||||||
{.name = "qemu-agent-command",
|
{.name = "qemu-agent-command",
|
||||||
.handler = cmdQemuAgentCommand,
|
.handler = cmdQemuAgentCommand,
|
||||||
.opts = opts_qemu_agent_command,
|
.opts = opts_qemu_agent_command,
|
||||||
|
@ -3326,12 +3326,15 @@ variables, and defaults to C<vi>.
|
|||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 QEMU-SPECIFIC COMMANDS
|
=head1 HYPERVISOR-SPECIFIC COMMANDS
|
||||||
|
|
||||||
NOTE: Use of the following commands is B<strongly> discouraged. They
|
NOTE: Use of the following commands is B<strongly> discouraged. They
|
||||||
can cause libvirt to become confused and do the wrong thing on subsequent
|
can cause libvirt to become confused and do the wrong thing on subsequent
|
||||||
operations. Once you have used this command, please do not report
|
operations. Once you have used these commands, please do not report
|
||||||
problems to the libvirt developers; the reports will be ignored.
|
problems to the libvirt developers; the reports will be ignored. If
|
||||||
|
you find that these commands are the only way to accomplish something,
|
||||||
|
then it is better to request that the feature be added as a first-class
|
||||||
|
citizen in the regular libvirt library.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|
||||||
@ -3370,7 +3373,8 @@ and the monitor uses QMP, then the output will be pretty-printed. If more
|
|||||||
than one argument is provided for I<command>, they are concatenated with a
|
than one argument is provided for I<command>, they are concatenated with a
|
||||||
space in between before passing the single command to the monitor.
|
space in between before passing the single command to the monitor.
|
||||||
|
|
||||||
=item B<qemu-agent-command> I<domain> [I<--timeout> I<seconds> | I<--async> | I<--block>] I<command>...
|
=item B<qemu-agent-command> I<domain> [I<--timeout> I<seconds> | I<--async> |
|
||||||
|
I<--block>] I<command>...
|
||||||
|
|
||||||
Send an arbitrary guest agent command I<command> to domain I<domain> through
|
Send an arbitrary guest agent command I<command> to domain I<domain> through
|
||||||
qemu agent.
|
qemu agent.
|
||||||
@ -3380,6 +3384,21 @@ When I<--aysnc> is given, the command waits for timeout whether success or
|
|||||||
failed. And when I<--block> is given, the command waits forever with blocking
|
failed. And when I<--block> is given, the command waits forever with blocking
|
||||||
timeout.
|
timeout.
|
||||||
|
|
||||||
|
=item B<qemu-monitor-event> [I<domain>] [I<--event> I<event-name>] [I<--loop>]
|
||||||
|
[I<--timeout> I<seconds>] [I<--pretty>]
|
||||||
|
|
||||||
|
Wait for arbitrary QEMU monitor events to occur, and print out the
|
||||||
|
details of events as they happen. The events can optionally be filtered
|
||||||
|
by I<domain> or I<event-name>. The 'query-events' QMP command can be
|
||||||
|
used via I<qemu-monitor-command> to learn what events are supported.
|
||||||
|
|
||||||
|
By default, this command is one-shot, and returns success once an event
|
||||||
|
occurs; you can send SIGINT (usually via C<Ctrl-C>) to quit immediately.
|
||||||
|
If I<--timeout> is specified, the command gives up waiting for events
|
||||||
|
after I<seconds> have elapsed. With I<--loop>, the command prints all
|
||||||
|
events until a timeout or interrupt key. If I<--pretty> is specified,
|
||||||
|
any JSON event details are pretty-printed for better legibility.
|
||||||
|
|
||||||
=item B<lxc-enter-namespace> I<domain> -- /path/to/binary [arg1, [arg2, ...]]
|
=item B<lxc-enter-namespace> I<domain> -- /path/to/binary [arg1, [arg2, ...]]
|
||||||
|
|
||||||
Enter the namespace of I<domain> and execute the command C</path/to/binary>
|
Enter the namespace of I<domain> and execute the command C</path/to/binary>
|
||||||
|
Loading…
Reference in New Issue
Block a user