Determining when a guest booted / how long it's been running

daggs <daggs@gmx.com> writes:
I'd assume that saying vm running you mean that the os is up and running too. I have similar need, I was able to get something as such to work using virsh console when the guest was a linux with serial console support enabled. I wasn't able to get this to work in a script as I was never able to terminate the console seesion as virsh console wasn't able to send the termination combination properly.
I wouldn't have assumed this meaning, but running off the tangent anyway: I think installing a guest agent could help solving this problem. However, if you want something extremely lightweight, the following (a custom one-line guest agent if you wish) worked for me: 1. Add a channel with a descriptive name to the guest config: <channel type="unix"> <target type="virtio" name="startup_signal"/> </channel> 2. After starting the domain, query the assigned socket path: virsh dumpxml $domain | xmllint --nonet --xpath \ "string(/domain/devices/channel[@type='unix' and target/@name='startup_signal']/source/@path)" -) 3. Then wait for the signal (and optionally acknowledge it): socat UNIX-CONNECT:"$socket_path" \ SYSTEM:'read msg id && [ $msg = ready ] && echo ack $id' This will wait until you send the signal from the chosen point of the guest bootup procedure via something like: port=/dev/virtio-ports/startup_signal msg=foobar reply="$(echo "ready $msg" | socat STDIO "$port")" [ "($reply)" = "(ack $msg)" ] # for checking proper acknowledgment I folded this into a oneshot systemd service on Linux, but the implementation should be similarly simple under any OS. -- Feri

On 2020-10-01 2:29 a.m., wferi@niif.hu wrote:
daggs <daggs@gmx.com> writes:
I'd assume that saying vm running you mean that the os is up and running too. I have similar need, I was able to get something as such to work using virsh console when the guest was a linux with serial console support enabled. I wasn't able to get this to work in a script as I was never able to terminate the console seesion as virsh console wasn't able to send the termination combination properly.
I wouldn't have assumed this meaning, but running off the tangent anyway: I think installing a guest agent could help solving this problem. However, if you want something extremely lightweight, the following (a custom one-line guest agent if you wish) worked for me:
1. Add a channel with a descriptive name to the guest config:
<channel type="unix"> <target type="virtio" name="startup_signal"/> </channel>
2. After starting the domain, query the assigned socket path:
virsh dumpxml $domain | xmllint --nonet --xpath \ "string(/domain/devices/channel[@type='unix' and target/@name='startup_signal']/source/@path)" -)
3. Then wait for the signal (and optionally acknowledge it):
socat UNIX-CONNECT:"$socket_path" \ SYSTEM:'read msg id && [ $msg = ready ] && echo ack $id'
This will wait until you send the signal from the chosen point of the guest bootup procedure via something like:
port=/dev/virtio-ports/startup_signal msg=foobar reply="$(echo "ready $msg" | socat STDIO "$port")" [ "($reply)" = "(ack $msg)" ] # for checking proper acknowledgment
I folded this into a oneshot systemd service on Linux, but the implementation should be similarly simple under any OS.
Thanks, both. In our case, we have zero control over the servers installed in our platform, and asking users to install agents in their OSes is not feasible. I did find a way to do it working around virsh, but of course I'd prefer to directly query the source instead of infering it if possible. The work around we're doing now is watching for a given guest to transition from 'shut off' to 'running' and, when that transition is seen, using the guest's PID to query 'ps -p <pid> -o etimes=' and subtracting the current epoch time minus the returned value to get the boot time. When the server transitions to 'shut off', we reset the stored boot time to 0. -- Digimer Papers and Projects: https://alteeve.com/w/ "I am, somehow, less interested in the weight and convolutions of Einstein’s brain than in the near certainty that people of equal talent have lived and died in cotton fields and sweatshops." - Stephen Jay Gould

Digimer <lists@alteeve.ca> writes:
I did find a way to do it working around virsh, but of course I'd prefer to directly query the source instead of infering it if possible.
Speaking about other possible workarounds, what about watching the /var/log/libvirt/qemu/*.log files (assuming you use the QEMU driver)? Those contain timestamps of QEMU startups (and other info). Or if you've got systemd around, "machinectl status" prints the start time of a given VM. If you don't want to mistake live migrations for fresh startups, more careful log analysis will be needed, though. And your current solution may still be the best for your exact purpose, of course. -- Regards, Feri

On 10/1/20 3:42 AM, Digimer wrote:
Hi all,
Is there a way to tell when a tool made a change to guest (ie: used virt-manager to make a change)? Following, is there a way to check to see if there are changes queued to take effect when the guest next reboots?
You can listen for events. For changes to inactive XML you will get VIR_DOMAIN_EVENT_DEFINED+VIR_DOMAIN_EVENT_DEFINED_UPDATED lifecycle event (+reason) and for changes to live XML (like hotplug and hotunplug) you'll get DEVICE_ADDED or DEVICE_REMOVED. But there is no API/virsh command that you could call to get the timestamp of last modification. You have to listen for events. And the second question - you can dump live and inactive XML and see if there is any difference (modulo runtime configuration from live XML). The live XML should be strictly bigger than inactive XML, meaning live XML should be inactive XML + runtime info. But again, no API there, because changes to inactive XML can be done any time - libvirt keeps live and inactive XMLs separately.
If either of the above are not possible, is there a way to see when a guest last booted or how long a guest has been running?
Again, if listening to evens - libvirt emits one when a guest is started. But I don't think we store a timestamp of start anywhere nor expose it through an API. Maybe there is some indirect way? Michal

On 2020-10-01 1:21 a.m., Michal Prívozník wrote:
On 10/1/20 3:42 AM, Digimer wrote:
Hi all,
Is there a way to tell when a tool made a change to guest (ie: used virt-manager to make a change)? Following, is there a way to check to see if there are changes queued to take effect when the guest next reboots?
You can listen for events. For changes to inactive XML you will get VIR_DOMAIN_EVENT_DEFINED+VIR_DOMAIN_EVENT_DEFINED_UPDATED lifecycle event (+reason) and for changes to live XML (like hotplug and hotunplug) you'll get DEVICE_ADDED or DEVICE_REMOVED.
But there is no API/virsh command that you could call to get the timestamp of last modification. You have to listen for events.
And the second question - you can dump live and inactive XML and see if there is any difference (modulo runtime configuration from live XML). The live XML should be strictly bigger than inactive XML, meaning live XML should be inactive XML + runtime info. But again, no API there, because changes to inactive XML can be done any time - libvirt keeps live and inactive XMLs separately.
If either of the above are not possible, is there a way to see when a guest last booted or how long a guest has been running?
Again, if listening to evens - libvirt emits one when a guest is started. But I don't think we store a timestamp of start anywhere nor expose it through an API. Maybe there is some indirect way?
Michal
Thanks, Michal. Now I know not to keep looking. I do infer the boot time (explained in my reply to daggs and feri. In brief, when we notice a server is running, that had last been seen off, we use the pid to get the runtime in seconds and subtract that from the current time to get a boot time. -- Digimer Papers and Projects: https://alteeve.com/w/ "I am, somehow, less interested in the weight and convolutions of Einstein’s brain than in the near certainty that people of equal talent have lived and died in cotton fields and sweatshops." - Stephen Jay Gould
participants (4)
-
daggs
-
Digimer
-
Michal Prívozník
-
wferi@niif.hu