mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
@@ -959,6 +959,71 @@ fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int setup_volatile_overlay(
|
||||
const char *directory,
|
||||
bool userns, uid_t uid_shift, uid_t uid_range,
|
||||
const char *selinux_apifs_context) {
|
||||
|
||||
_cleanup_free_ char *buf = NULL, *escaped_directory = NULL, *escaped_upper = NULL, *escaped_work = NULL;
|
||||
char template[] = "/tmp/nspawn-volatile-XXXXXX";
|
||||
const char *upper, *work, *options;
|
||||
bool tmpfs_mounted = false;
|
||||
int r;
|
||||
|
||||
assert(directory);
|
||||
|
||||
/* --volatile=overlay means we mount an overlayfs to the root dir. */
|
||||
|
||||
if (!mkdtemp(template))
|
||||
return log_error_errno(errno, "Failed to create temporary directory: %m");
|
||||
|
||||
options = "mode=755";
|
||||
r = tmpfs_patch_options(options, uid_shift == 0 ? UID_INVALID : uid_shift, selinux_apifs_context, &buf);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
if (r > 0)
|
||||
options = buf;
|
||||
|
||||
r = mount_verbose(LOG_ERR, "tmpfs", template, "tmpfs", MS_STRICTATIME, options);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
tmpfs_mounted = true;
|
||||
|
||||
upper = strjoina(template, "/upper");
|
||||
work = strjoina(template, "/work");
|
||||
|
||||
if (mkdir(upper, 0755) < 0) {
|
||||
r = log_error_errno(errno, "Failed to create %s: %m", upper);
|
||||
goto finish;
|
||||
}
|
||||
if (mkdir(work, 0755) < 0) {
|
||||
r = log_error_errno(errno, "Failed to create %s: %m", work);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* And now, let's overmount the root dir with an overlayfs that uses the root dir as lower dir. It's kinda nice
|
||||
* that the kernel allows us to do that without going through some mount point rearrangements. */
|
||||
|
||||
escaped_directory = shell_escape(directory, ",:");
|
||||
escaped_upper = shell_escape(upper, ",:");
|
||||
escaped_work = shell_escape(work, ",:");
|
||||
if (!escaped_directory || !escaped_upper || !escaped_work) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
options = strjoina("lowerdir=", escaped_directory, ",upperdir=", escaped_upper, ",workdir=", escaped_work);
|
||||
r = mount_verbose(LOG_ERR, "overlay", directory, "overlay", 0, options);
|
||||
|
||||
finish:
|
||||
if (tmpfs_mounted)
|
||||
(void) umount_verbose(template);
|
||||
|
||||
(void) rmdir(template);
|
||||
return r;
|
||||
}
|
||||
|
||||
int setup_volatile_mode(
|
||||
const char *directory,
|
||||
VolatileMode mode,
|
||||
@@ -973,6 +1038,9 @@ int setup_volatile_mode(
|
||||
case VOLATILE_STATE:
|
||||
return setup_volatile_state(directory, userns, uid_shift, uid_range, selinux_apifs_context);
|
||||
|
||||
case VOLATILE_OVERLAY:
|
||||
return setup_volatile_overlay(directory, userns, uid_shift, uid_range, selinux_apifs_context);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1431,9 +1431,9 @@ static int setup_timezone(const char *dest) {
|
||||
if (IN_SET(arg_timezone, TIMEZONE_AUTO, TIMEZONE_SYMLINK)) {
|
||||
r = readlink_malloc("/etc/localtime", &p);
|
||||
if (r == -ENOENT && arg_timezone == TIMEZONE_AUTO)
|
||||
m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? TIMEZONE_OFF : TIMEZONE_DELETE;
|
||||
m = arg_read_only && IN_SET(arg_volatile_mode, VOLATILE_NO, VOLATILE_STATE) ? TIMEZONE_OFF : TIMEZONE_DELETE;
|
||||
else if (r == -EINVAL && arg_timezone == TIMEZONE_AUTO) /* regular file? */
|
||||
m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? TIMEZONE_BIND : TIMEZONE_COPY;
|
||||
m = arg_read_only && IN_SET(arg_volatile_mode, VOLATILE_NO, VOLATILE_STATE) ? TIMEZONE_BIND : TIMEZONE_COPY;
|
||||
else if (r < 0) {
|
||||
log_warning_errno(r, "Failed to read host's /etc/localtime symlink, not updating container timezone: %m");
|
||||
/* To handle warning, delete /etc/localtime and replace it with a symbolic link to a time zone data
|
||||
@@ -1444,7 +1444,7 @@ static int setup_timezone(const char *dest) {
|
||||
*/
|
||||
return 0;
|
||||
} else if (arg_timezone == TIMEZONE_AUTO)
|
||||
m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? TIMEZONE_BIND : TIMEZONE_SYMLINK;
|
||||
m = arg_read_only && IN_SET(arg_volatile_mode, VOLATILE_NO, VOLATILE_STATE) ? TIMEZONE_BIND : TIMEZONE_SYMLINK;
|
||||
else
|
||||
m = arg_timezone;
|
||||
} else
|
||||
@@ -1606,11 +1606,11 @@ static int setup_resolv_conf(const char *dest) {
|
||||
if (arg_private_network)
|
||||
m = RESOLV_CONF_OFF;
|
||||
else if (have_resolv_conf(STATIC_RESOLV_CONF) > 0 && resolved_listening() > 0)
|
||||
m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? RESOLV_CONF_BIND_STATIC : RESOLV_CONF_COPY_STATIC;
|
||||
m = arg_read_only && IN_SET(arg_volatile_mode, VOLATILE_NO, VOLATILE_STATE) ? RESOLV_CONF_BIND_STATIC : RESOLV_CONF_COPY_STATIC;
|
||||
else if (have_resolv_conf("/etc/resolv.conf") > 0)
|
||||
m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? RESOLV_CONF_BIND_HOST : RESOLV_CONF_COPY_HOST;
|
||||
m = arg_read_only && IN_SET(arg_volatile_mode, VOLATILE_NO, VOLATILE_STATE) ? RESOLV_CONF_BIND_HOST : RESOLV_CONF_COPY_HOST;
|
||||
else
|
||||
m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? RESOLV_CONF_OFF : RESOLV_CONF_DELETE;
|
||||
m = arg_read_only && IN_SET(arg_volatile_mode, VOLATILE_NO, VOLATILE_STATE) ? RESOLV_CONF_OFF : RESOLV_CONF_DELETE;
|
||||
} else
|
||||
m = arg_resolv_conf;
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ static const char* const volatile_mode_table[_VOLATILE_MODE_MAX] = {
|
||||
[VOLATILE_NO] = "no",
|
||||
[VOLATILE_YES] = "yes",
|
||||
[VOLATILE_STATE] = "state",
|
||||
[VOLATILE_OVERLAY] = "overlay",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(volatile_mode, VolatileMode, VOLATILE_YES);
|
||||
|
||||
@@ -5,6 +5,7 @@ typedef enum VolatileMode {
|
||||
VOLATILE_NO,
|
||||
VOLATILE_YES,
|
||||
VOLATILE_STATE,
|
||||
VOLATILE_OVERLAY,
|
||||
_VOLATILE_MODE_MAX,
|
||||
_VOLATILE_MODE_INVALID = -1
|
||||
} VolatileMode;
|
||||
|
||||
Reference in New Issue
Block a user