qemu-ga: improve recovery options for fsfreeze

guest-fsfreeze-thaw relies on state information obtained from
guest-fsfreeze-freeze to determine what filesystems to unfreeze.
This is unreliable due to the fact that that state does not account
for FIFREEZE being issued by other processes, or previous instances
of qemu-ga. This means in certain situations we cannot thaw
filesystems even with a responsive qemu-ga instance at our disposal.

This patch allows guest-fsfreeze-thaw to be issued unconditionally.
It also adds some additional logic to allow us to thaw filesystems
regardless of how many times the filesystem's "frozen" refcount has
been incremented by any guest processes.

Also, guest-fsfreeze-freeze now operates atomically: on success all
freezable filesystems are frozen, and on error all filesystems are
thawed. The ambiguous "GUEST_FSFREEZE_STATUS_ERROR" state is no
longer entered.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
qemu-ga: add a whitelist for fsfreeze-safe commands

Currently we rely on fsfreeze/thaw commands disabling/enabling logging
then having other commands check whether logging is disabled to avoid
executing if they aren't safe for running while a filesystem is frozen.

Instead, have an explicit whitelist of fsfreeze-safe commands, and
consolidate logging and command enablement/disablement into a pair
of helper functions: ga_set_frozen()/ga_unset_frozen()

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
qemu-ga: persist tracking of fsfreeze state via filesystem

Currently, qemu-ga may die/get killed/go away for whatever reason after
guest-fsfreeze-freeze has been issued, and before guest-fsfreeze-thaw
has been issued. This means the only way to unfreeze the guest is via
VNC/network/console access, but obtaining that access after-the-fact can
often be very difficult when filesystems are frozen. Logins will almost
always hang, for instance. In many cases the only recourse would be to
reboot the guest without any quiescing of volatile state, which makes
this a corner-case worth giving some attention to.

A likely failsafe for this situation would be to use a watchdog to
restart qemu-ga if it goes away. There are some precautions qemu-ga
needs to take in order to avoid immediately hanging itself on I/O,
however, namely, we must disable logging and defer to processing/creation
of user-specific logfiles, along with creation of the pid file if we're
running as a daemon. We also need to disable non-fsfreeze-safe commands,
as we normally would when processing the guest-fsfreeze-freeze command.

To track when we need to do this in a way that persists between multiple
invocations of qemu-ga, we create a file on the guest filesystem before
issuing the fsfreeze, and delete it when doing the thaw. On qemu-ga
startup, we check for the existance of this file to determine
the need to take the above precautions.

We're forced to do it this way since a more traditional approach such as
reading/writing state to a dedicated state file will cause
access/modification time updates, respectively, both of which will hang
if the file resides on a frozen filesystem. Both can occur even if
relatime is enabled. Checking for file existence will not update the
access time, however, so it's a safe way to check for fsfreeze state.

An actual watchdog-based restart of qemu-ga can itself cause an access
time update that would thus hang the invocation of qemu-ga, but the
logic to workaround that can be handled via the watchdog, so we don't
address that here (for relatime we'd periodically touch the qemu-ga
binary if the file $qga_statedir/qga.state.isfrozen is not present, this
avoids qemu-ga updates or the 1 day relatime threshold causing an
access-time update if we try to respawn qemu-ga shortly after it goes
away)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>