[libvirt-users] Programmatically force shutdown a guest: possible?

I am looking at the shutdown method, but if the guest system is a desktop system, like for example ubuntu, it just has the effect to show a box prompting the user for a shutdown/reboot/ and such. I could enter the guest and change this default behaviour and it actually works..but I'd like for a way to send a shutdown command without doing so. Is it possible?

On 03/29/2014 06:21 AM, Pasquale Dir wrote:
I am looking at the shutdown method, but if the guest system is a desktop system, like for example ubuntu, it just has the effect to show a box prompting the user for a shutdown/reboot/ and such.
I could enter the guest and change this default behaviour and it actually works..but I'd like for a way to send a shutdown command without doing so.
Is it possible?
Guest shutdown is ALWAYS a cooperative action. It sounds like your guest defaults to an interactive shutdown when an ACPI shutdown request is received. You can install qemu-guest-agent in your guest and send shutdown via the agent instead of via ACPI - that may be a bit more responsive at doing an immediate shutdown. But beyond that, no, there is no way to guarantee a graceful guest shutdown without guest cooperation. If you must stop a guest, and shutdown is taking too long because the guest is not cooperating, then use the 'virsh destroy' command. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Yes, you are right. Listen, as the documentation is not very exaustive, can you explain briefly to me how a guest agent works? After installing it via the apt-get on the hypervisor (I am using ubuntu as host system) how can I create a script which would do this? That is waiting for an acpi signal and actually shut down the guest. And what other operation can you actually do with a guest agent? I would be interested in getting the current amount of memory the guest is using too...as libvirt apis just tell me the max memory allocated. 2014-03-29 15:12 GMT+01:00 Eric Blake <eblake@redhat.com>:
On 03/29/2014 06:21 AM, Pasquale Dir wrote:
I am looking at the shutdown method, but if the guest system is a desktop system, like for example ubuntu, it just has the effect to show a box prompting the user for a shutdown/reboot/ and such.
I could enter the guest and change this default behaviour and it actually works..but I'd like for a way to send a shutdown command without doing so.
Is it possible?
Guest shutdown is ALWAYS a cooperative action. It sounds like your guest defaults to an interactive shutdown when an ACPI shutdown request is received. You can install qemu-guest-agent in your guest and send shutdown via the agent instead of via ACPI - that may be a bit more responsive at doing an immediate shutdown. But beyond that, no, there is no way to guarantee a graceful guest shutdown without guest cooperation. If you must stop a guest, and shutdown is taking too long because the guest is not cooperating, then use the 'virsh destroy' command.
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

or you could do it through an acpi event. If you use kde, you can shut it down via dbus. This is how I did it (as root): su - username -c "DBUS_SESSION_BUS_ADDRESS='unix:abstract=/tmp/dbus-vS7K32zzd7,guid=9eb3fedc45f523665b178a4d53373536' qdbus-qt4 org.kde.ks mserver /KSMServer logout 0 0 0" In theory this should work too, if your dbus is compiled with support for X11 dbus-daemon autolaunch: su - username -c "DISPLAY=:0 qdbus-qt4 org.kde.ksmserver /KSMServer logout 0 0 0" The trick is to know which user is currently logged in and to know/find out their DBUS_SESSION_BUS_ADDRESS. The former is easy: who | awk '!/pts/ {print $1}' This will print the username of whoever is logged into X. If you get nothing, nobody is logged on :0 and you could use wall to prompt all currently logged in users to log out, give them a grace period of say one minute, then shutdown. If on the other hand you have someone logged into X, you could use kdialog/zenity/xmessage to tell them they have say a minute to quit whatever they are doing, then you can use the dbus to shutdown. It works for KDE. I don't know if/how it works for GNOME/Unity/XFCE, etc. As for the DBUS_SESSION_BUS_ADDRESS, if you use a standard/modern distribution this is probably available in the user's shell environment variables already, so you need not worry about it. Trouble is it may not be available outside the X session. You'll need to change your KDE/GNOME/XFCE, etc start-up scripts to print this variable into a file, which you can later source when you need it. But you can control how your system will react on an acpi shutdown via the acpi hooks. You don't have to get real fancy and worry about graceful shutdown, cause under certain conditions it may not be possible to quit your graphical environment -- I've had stubborn processes refuse to end and the shutdown is canceled. Read the dbus documentation about the three numerical parameters (0 0 0 in this case) -- they deal with session control, etc. Read up on acpi events as well and you should figure it out. IvanK. ----- Original Message ----- From: "Pasquale Dir" <phate867@gmail.com> To: "Eric Blake" <eblake@redhat.com> Cc: libvirt-users@redhat.com Sent: Sunday, March 30, 2014 11:47:23 AM Subject: Re: [libvirt-users] Programmatically force shutdown a guest: possible? Yes, you are right. Listen, as the documentation is not very exaustive, can you explain briefly to me how a guest agent works? After installing it via the apt-get on the hypervisor (I am using ubuntu as host system) how can I create a script which would do this? That is waiting for an acpi signal and actually shut down the guest. And what other operation can you actually do with a guest agent? I would be interested in getting the current amount of memory the guest is using too...as libvirt apis just tell me the max memory allocated. 2014-03-29 15:12 GMT+01:00 Eric Blake < eblake@redhat.com > : On 03/29/2014 06:21 AM, Pasquale Dir wrote:
I am looking at the shutdown method, but if the guest system is a desktop system, like for example ubuntu, it just has the effect to show a box prompting the user for a shutdown/reboot/ and such.
I could enter the guest and change this default behaviour and it actually works..but I'd like for a way to send a shutdown command without doing so.
Is it possible?
Guest shutdown is ALWAYS a cooperative action. It sounds like your guest defaults to an interactive shutdown when an ACPI shutdown request is received. You can install qemu-guest-agent in your guest and send shutdown via the agent instead of via ACPI - that may be a bit more responsive at doing an immediate shutdown. But beyond that, no, there is no way to guarantee a graceful guest shutdown without guest cooperation. If you must stop a guest, and shutdown is taking too long because the guest is not cooperating, then use the 'virsh destroy' command. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org _______________________________________________ libvirt-users mailing list libvirt-users@redhat.com https://www.redhat.com/mailman/listinfo/libvirt-users

On 03/30/2014 02:47 AM, Pasquale Dir wrote:
Yes, you are right.
[please don't top-post on technical lists]
Listen, as the documentation is not very exaustive, can you explain briefly to me how a guest agent works?
There's two essential pieces - while you can add the pieces in either order, both must be present before you have a guest agent channel. 1. You must expose the guest agent hardware to the guest. In libvirt, this is done with the <channel> device: http://libvirt.org/formatdomain.html#elementCharChannel (look at the org.qemu.guest_agent.0 example) Newer virt-manager has some gui elements for making this a bit easier to set up. 2. You must install the guest agent in the guest, set to run as a daemon. If the agent detects the hardware exposed by step 1, then you have set up a communication channel between host and guest, where the guest can react to host commands. The idea is that the host issues one of the limited set of commands understood by the agent protocol (the current list of commands understood in qemu.git is here: http://git.qemu.org/?p=qemu.git;a=blob;f=qga/qapi-schema.json;h=80edca14;hb=...). Libvirt has the 'virsh qemu-agent-command' for issuing any command not already directly utilized by formal libvirt API. The agent then receives that command over the virtual channel hardware, and does the semantics of the command. The agent has been ported at least to Linux and Windows guests. If there is an action you want the guest to do that is not covered by those commands, then patches to the qemu list can be proposed to expand the set.
After installing it via the apt-get on the hypervisor (I am using ubuntu as host system) how can I create a script which would do this?
For piece 2, you would use apt-get on your guest (not your host). The only thing you do on the host is step 1 (xml modification to add the device, if it isn't already present; newer virt-manager will add the xml automatically).
That is waiting for an acpi signal and actually shut down the guest.
I'm not sure I followed this statement. The idea is that the 'virsh shutdown' command knows two separate approaches to request guest shutdown: one is by ACPI, the other by the agent. If the agent is wired up, then that way is preferred; but if it is not wired up, or if it is wired up but unresponsive (for example, if the agent is not actually running because you forgot step 2 in the guest), then libvirt falls back to ACPI (unless you told libvirt to specifically use only 1 of the two possible shutdown methods).
And what other operation can you actually do with a guest agent? I would be interested in getting the current amount of memory the guest is using too...as libvirt apis just tell me the max memory allocated.
See the link I posted above for the current set of agent commands. Unfortunately, I don't see an existing command that reports the guest's view of memory usage. On the other hand, I do know that newer qemu has the ability to get information about guest memory usage when doing balloon commands (in fact, older qemu also had that ability, except that the older way REQUIRED the guest to cooperate, and that could lead to host deadlock for non-cooperative guests, so it was withdrawn at the time; it was only recently re-enabled when newer qemu made the interaction more of a status poll instead of a lockstep query-response). If your qemu is new enough, then libvirt's virDomainSetMemoryStatsPeriod() can control how frequently you poll, and virDomainMemoryStats() can actually provide details about the guest's view of memory usage according to what the guest reported via the balloon driver. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (3)
-
Eric Blake
-
Ivan Kabaivanov
-
Pasquale Dir