vmspawn: add --ephemeral (#40505)
This PR implements --ephemeral for vmspawn in the same way as nspawn. Note that this does not support snapshots for --extra-drives.
This commit is contained in:
@@ -177,6 +177,7 @@ shared_sources = files(
|
||||
'sleep-config.c',
|
||||
'smack-util.c',
|
||||
'smbios11.c',
|
||||
'snapshot-util.c',
|
||||
'socket-label.c',
|
||||
'socket-netlink.c',
|
||||
'specifier.c',
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/file.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "btrfs-util.h"
|
||||
#include "discover-image.h"
|
||||
#include "log.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "snapshot-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "tmpfile-util.h"
|
||||
|
||||
int create_ephemeral_snapshot(
|
||||
const char *directory,
|
||||
RuntimeScope scope,
|
||||
bool read_only,
|
||||
LockFile *tree_global_lock,
|
||||
LockFile *tree_local_lock,
|
||||
char **ret_new_path) {
|
||||
|
||||
_cleanup_free_ char *np = NULL;
|
||||
int r;
|
||||
|
||||
/* If the specified path is a mount point we generate the new snapshot immediately
|
||||
* inside it under a random name. However if the specified is not a mount point we
|
||||
* create the new snapshot in the parent directory, just next to it. */
|
||||
r = path_is_mount_point(directory);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to determine whether directory %s is mount point: %m", directory);
|
||||
if (r > 0)
|
||||
r = tempfn_random_child(directory, "snapshot.", &np);
|
||||
else
|
||||
r = tempfn_random(directory, "snapshot.", &np);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to generate name for directory snapshot: %m");
|
||||
|
||||
/* We take an exclusive lock on this image, since it's our private, ephemeral copy
|
||||
* only owned by us and no one else. */
|
||||
r = image_path_lock(
|
||||
scope,
|
||||
np,
|
||||
LOCK_EX|LOCK_NB,
|
||||
scope == RUNTIME_SCOPE_SYSTEM ? tree_global_lock : NULL,
|
||||
tree_local_lock);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to lock %s: %m", np);
|
||||
|
||||
{
|
||||
BLOCK_SIGNALS(SIGINT);
|
||||
r = btrfs_subvol_snapshot_at(AT_FDCWD, directory, AT_FDCWD, np,
|
||||
(read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) |
|
||||
BTRFS_SNAPSHOT_FALLBACK_COPY |
|
||||
BTRFS_SNAPSHOT_FALLBACK_DIRECTORY |
|
||||
BTRFS_SNAPSHOT_RECURSIVE |
|
||||
BTRFS_SNAPSHOT_QUOTA |
|
||||
BTRFS_SNAPSHOT_SIGINT);
|
||||
}
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to create snapshot %s from %s: %m", np, directory);
|
||||
|
||||
*ret_new_path = TAKE_PTR(np);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "runtime-scope.h"
|
||||
|
||||
/* create_ephemeral_snapshot - create a snapshot of the given directory.
|
||||
*
|
||||
* It will use a btrfs snapshot when available with fallback to traditional dir copy. It will set the global
|
||||
* and local lock files based on the passed runtime scope. On success the new directory path is returned via
|
||||
* `ret_new_path`.
|
||||
*
|
||||
* The caller is responsible for the cleanup of the directory, using `_cleanup_(rm_rf_subvolume_and_freep)`
|
||||
* is recommended.
|
||||
*/
|
||||
int create_ephemeral_snapshot(
|
||||
const char *directory,
|
||||
RuntimeScope scope,
|
||||
bool read_only,
|
||||
LockFile *tree_global_lock,
|
||||
LockFile *tree_local_lock,
|
||||
char **ret_new_path);
|
||||
Reference in New Issue
Block a user