secret: Inhibit shutdown for ephemeral secrets

Our secret driver divides secrets into two groups: ephemeral
(stored only in memory) and persistent (stored on disk). Now, the
aim of ephemeral secrets is to define them shortly before being
used and then undefine them. But 'shortly before being used' is a
very vague time frame. And since we default to socket activation
and thus pass '--timeout 120' to every daemon it may happen that
just defined ephemeral secret is gone among with the virtsecretd.

This is no problem for persistent secrets as their definition
(and value) is restored when the virtsecretd starts again, but
ephemeral secrets can't be restored.

Therefore, we could view ephemeral secrets as active objects that
the daemon manages and thus inhibit automatic shutdown (just like
hypervisor daemons do when a guest is running).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Michal Privoznik 2022-12-20 09:04:48 +01:00
parent d7d4056645
commit 9e3cc0ff5e

View File

@ -66,6 +66,10 @@ struct _virSecretDriverState {
/* Immutable pointer, self-locking APIs */ /* Immutable pointer, self-locking APIs */
virObjectEventState *secretEventState; virObjectEventState *secretEventState;
/* Immutable pointers. Caller must provide locking */
virStateInhibitCallback inhibitCallback;
void *inhibitOpaque;
}; };
static virSecretDriverState *driver; static virSecretDriverState *driver;
@ -86,6 +90,23 @@ secretObjFromSecret(virSecretPtr secret)
} }
static bool
secretNumOfEphemeralSecretsHelper(virConnectPtr conn G_GNUC_UNUSED,
virSecretDef *def)
{
return def->isephemeral;
}
static int
secretNumOfEphemeralSecrets(void)
{
return virSecretObjListNumOfSecrets(driver->secrets,
secretNumOfEphemeralSecretsHelper,
NULL);
}
/* Driver functions */ /* Driver functions */
static int static int
@ -266,6 +287,10 @@ secretDefineXML(virConnectPtr conn,
cleanup: cleanup:
virSecretDefFree(def); virSecretDefFree(def);
virSecretObjEndAPI(&obj); virSecretObjEndAPI(&obj);
if (secretNumOfEphemeralSecrets() > 0)
driver->inhibitCallback(true, driver->inhibitOpaque);
virObjectEventStateQueue(driver->secretEventState, event); virObjectEventStateQueue(driver->secretEventState, event);
return ret; return ret;
@ -424,6 +449,10 @@ secretUndefine(virSecretPtr secret)
cleanup: cleanup:
virSecretObjEndAPI(&obj); virSecretObjEndAPI(&obj);
if (secretNumOfEphemeralSecrets() == 0)
driver->inhibitCallback(false, driver->inhibitOpaque);
virObjectEventStateQueue(driver->secretEventState, event); virObjectEventStateQueue(driver->secretEventState, event);
return ret; return ret;
@ -463,8 +492,8 @@ static int
secretStateInitialize(bool privileged, secretStateInitialize(bool privileged,
const char *root, const char *root,
bool monolithic G_GNUC_UNUSED, bool monolithic G_GNUC_UNUSED,
virStateInhibitCallback callback G_GNUC_UNUSED, virStateInhibitCallback callback,
void *opaque G_GNUC_UNUSED) void *opaque)
{ {
VIR_LOCK_GUARD lock = virLockGuardLock(&mutex); VIR_LOCK_GUARD lock = virLockGuardLock(&mutex);
@ -473,6 +502,8 @@ secretStateInitialize(bool privileged,
driver->lockFD = -1; driver->lockFD = -1;
driver->secretEventState = virObjectEventStateNew(); driver->secretEventState = virObjectEventStateNew();
driver->privileged = privileged; driver->privileged = privileged;
driver->inhibitCallback = callback;
driver->inhibitOpaque = opaque;
if (root) { if (root) {
driver->embeddedRoot = g_strdup(root); driver->embeddedRoot = g_strdup(root);