#include "label-util.h"
#include "mkdir-label.h"
#include "mount-util.h"
+#include "mount.h"
#include "mountpoint-util.h"
#include "process-util.h"
#include "random-util.h"
return unit_add_dependency_by_name(u, UNIT_AFTER, m, /* add_reference= */ true, UNIT_DEPENDENCY_FILE);
}
-int exec_context_destroy_credentials(const ExecContext *c, const char *runtime_prefix, const char *unit) {
+int exec_context_destroy_credentials(Unit *u) {
_cleanup_free_ char *p = NULL;
int r;
- assert(c);
+ assert(u);
- r = get_credential_directory(runtime_prefix, unit, &p);
+ r = get_credential_directory(u->manager->prefix[EXEC_DIRECTORY_RUNTIME], u->id, &p);
if (r <= 0)
return r;
/* This is either a tmpfs/ramfs of its own, or a plain directory. Either way, let's first try to
* unmount it, and afterwards remove the mount point */
- (void) umount2(p, MNT_DETACH|UMOUNT_NOFOLLOW);
+ if (umount2(p, MNT_DETACH|UMOUNT_NOFOLLOW) >= 0)
+ (void) mount_invalidate_state_by_path(u->manager, p);
+
(void) rm_rf(p, REMOVE_ROOT|REMOVE_CHMOD);
return 0;
int unit_add_default_credential_dependencies(Unit *u, const ExecContext *c);
-int exec_context_destroy_credentials(const ExecContext *c, const char *runtime_root, const char *unit);
+int exec_context_destroy_credentials(Unit *u);
int exec_setup_credentials(
const ExecContext *context,
const ExecParameters *params,
assert(m);
+ /* When we directly call umount() for a path, then the state of the corresponding mount unit may be
+ * outdated. Let's re-read mountinfo now and update the state. */
+ if (m->invalidated_state)
+ (void) mount_process_proc_self_mountinfo(u->manager);
+
switch (m->state) {
case MOUNT_UNMOUNTING:
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
return 0;
+ case MOUNT_DEAD:
+ case MOUNT_FAILED:
+ /* The mount has just been unmounted by somebody else. */
+ return 0;
+
default:
assert_not_reached();
}
LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
Mount *mount = MOUNT(u);
+ mount->invalidated_state = false;
+
if (!mount_is_mounted(mount)) {
/* A mount point is not around right now. It might be gone, or might never have
return mount_process_proc_self_mountinfo(m);
}
+int mount_invalidate_state_by_path(Manager *manager, const char *path) {
+ _cleanup_free_ char *name = NULL;
+ Unit *u;
+ int r;
+
+ assert(manager);
+ assert(path);
+
+ r = unit_name_from_path(path, ".mount", &name);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to generate unit name from path \"%s\", ignoring: %m", path);
+
+ u = manager_get_unit(manager, name);
+ if (!u)
+ return -ENOENT;
+
+ MOUNT(u)->invalidated_state = true;
+ return 0;
+}
+
static void mount_reset_failed(Unit *u) {
Mount *m = MOUNT(u);
MountParameters parameters_proc_self_mountinfo;
MountParameters parameters_fragment;
+ bool invalidated_state:1; /* Set when the 'state' of the mount unit may be outdated, and we need to
+ * re-read /proc/self/mountinfo. */
bool from_proc_self_mountinfo:1;
bool from_fragment:1;
void mount_fd_event(Manager *m, int events);
+int mount_invalidate_state_by_path(Manager *manager, const char *path);
+
const char* mount_exec_command_to_string(MountExecCommand i) _const_;
MountExecCommand mount_exec_command_from_string(const char *s) _pure_;
if (context->runtime_directory_preserve_mode == EXEC_PRESERVE_NO)
exec_context_destroy_runtime_directory(context, u->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
- exec_context_destroy_credentials(context, u->manager->prefix[EXEC_DIRECTORY_RUNTIME], u->id);
+ exec_context_destroy_credentials(u);
exec_context_destroy_mount_ns_dir(u);
}