d1f6e01e47
Let's explicitly deactivate all home dirs on shutdown, in order to properly synchronizing unmounting and avoiding blocking devices. Previously, we'd rely on automatic deactivation when home directories become unused. However, that scheme is asynchronous, and ongoing deactviations might conflicts with attempts to unmount /home. Let's fix that by providing an explicit service systemd-homed-activate.service whose only job is to have a ExecStop= line that explicitly deactivates all home directories on shutdown. This service can the be ordered after home.mount and similar, ensuring that we'll first deactivate all homes before deactivating /home itself during shutdown. This is kept separate from systemd-homed.service so that it is possible to restart systemd-homed.service without deactivating all home directories. Fixes: #16842
64 lines
2.6 KiB
C
64 lines
2.6 KiB
C
/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
#pragma once
|
|
|
|
#include <sd-bus.h>
|
|
|
|
#include "user-record.h"
|
|
|
|
typedef enum OperationType {
|
|
OPERATION_ACQUIRE, /* enqueued on AcquireHome() */
|
|
OPERATION_RELEASE, /* enqueued on ReleaseHome() */
|
|
OPERATION_LOCK_ALL, /* enqueued on LockAllHomes() */
|
|
OPERATION_DEACTIVATE_ALL, /* enqueued on DeactivateAllHomes() */
|
|
OPERATION_PIPE_EOF, /* enqueued when we see EOF on the per-home reference pipes */
|
|
OPERATION_DEACTIVATE_FORCE, /* enqueued on hard $HOME unplug */
|
|
OPERATION_IMMEDIATE, /* this is never enqueued, it's just a marker we immediately started executing an operation without enqueuing anything first. */
|
|
_OPERATION_MAX,
|
|
_OPERATION_INVALID = -1,
|
|
} OperationType;
|
|
|
|
/* Encapsulates an operation on one or more home directories. This has two uses:
|
|
*
|
|
* 1) For queuing an operation when we need to execute one for some reason but there's already one being
|
|
* executed.
|
|
*
|
|
* 2) When executing an operation without enqueuing it first (OPERATION_IMMEDIATE)
|
|
*
|
|
* Note that a single operation object can encapsulate operations on multiple home directories. This is used
|
|
* for the LockAllHomes() operation, which is one operation but applies to all homes at once. In case the
|
|
* operation applies to multiple homes the reference counter is increased once for each, and thus the
|
|
* operation is fully completed only after it reached zero again.
|
|
*
|
|
* The object (optionally) contains a reference of the D-Bus message triggering the operation, which is
|
|
* replied to when the operation is fully completed, i.e. when n_ref reaches zero.
|
|
*/
|
|
|
|
typedef struct Operation {
|
|
unsigned n_ref;
|
|
OperationType type;
|
|
sd_bus_message *message;
|
|
|
|
UserRecord *secret;
|
|
int send_fd; /* pipe fd for AcquireHome() which is taken already when we start the operation */
|
|
|
|
int result; /* < 0 if not completed yet, == 0 on failure, > 0 on success */
|
|
sd_bus_error error;
|
|
int ret;
|
|
} Operation;
|
|
|
|
Operation *operation_new(OperationType type, sd_bus_message *m);
|
|
Operation *operation_ref(Operation *operation);
|
|
Operation *operation_unref(Operation *operation);
|
|
|
|
DEFINE_TRIVIAL_CLEANUP_FUNC(Operation*, operation_unref);
|
|
|
|
void operation_result(Operation *o, int ret, const sd_bus_error *error);
|
|
|
|
static inline Operation* operation_result_unref(Operation *o, int ret, const sd_bus_error *error) {
|
|
if (!o)
|
|
return NULL;
|
|
|
|
operation_result(o, ret, error);
|
|
return operation_unref(o);
|
|
}
|