1
0
mirror of https://github.com/systemd/systemd synced 2026-03-25 16:25:04 +01:00

Compare commits

..

No commits in common. "7524671f74c9b0ea858a077ae9b1af3fe574d57e" and "9848f56cc68a5f193d515f080b7b01e6a689ae22" have entirely different histories.

3 changed files with 57 additions and 50 deletions

View File

@ -3740,21 +3740,21 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
if (c->root_image_policy) if (c->root_image_policy)
return -EINVAL; /* duplicated */ return -EINVAL; /* duplicated */
r = image_policy_from_string(val, /* graceful= */ false, &c->root_image_policy); r = image_policy_from_string(val, /* graceful= */ true, &c->root_image_policy);
if (r < 0) if (r < 0)
return r; return r;
} else if ((val = startswith(l, "exec-context-mount-image-policy="))) { } else if ((val = startswith(l, "exec-context-mount-image-policy="))) {
if (c->mount_image_policy) if (c->mount_image_policy)
return -EINVAL; /* duplicated */ return -EINVAL; /* duplicated */
r = image_policy_from_string(val, /* graceful= */ false, &c->mount_image_policy); r = image_policy_from_string(val, /* graceful= */ true, &c->mount_image_policy);
if (r < 0) if (r < 0)
return r; return r;
} else if ((val = startswith(l, "exec-context-extension-image-policy="))) { } else if ((val = startswith(l, "exec-context-extension-image-policy="))) {
if (c->extension_image_policy) if (c->extension_image_policy)
return -EINVAL; /* duplicated */ return -EINVAL; /* duplicated */
r = image_policy_from_string(val, /* graceful= */ false, &c->extension_image_policy); r = image_policy_from_string(val, /* graceful= */ true, &c->extension_image_policy);
if (r < 0) if (r < 0)
return r; return r;
} else } else

View File

@ -238,6 +238,7 @@ static int image_new(
ImageClass c, ImageClass c,
const char *pretty, const char *pretty,
const char *path, const char *path,
const char *filename,
bool read_only, bool read_only,
usec_t crtime, usec_t crtime,
usec_t mtime, usec_t mtime,
@ -248,7 +249,7 @@ static int image_new(
assert(t >= 0); assert(t >= 0);
assert(t < _IMAGE_TYPE_MAX); assert(t < _IMAGE_TYPE_MAX);
assert(pretty); assert(pretty);
assert(path); assert(filename);
assert(ret); assert(ret);
i = new(Image, 1); i = new(Image, 1);
@ -272,7 +273,7 @@ static int image_new(
if (!i->name) if (!i->name)
return -ENOMEM; return -ENOMEM;
i->path = strdup(path); i->path = path_join(path, filename);
if (!i->path) if (!i->path)
return -ENOMEM; return -ENOMEM;
@ -386,8 +387,10 @@ static int image_update_quota(Image *i, int fd) {
static int image_make( static int image_make(
ImageClass c, ImageClass c,
const char *pretty, const char *pretty,
int dir_fd,
const char *dir_path,
const char *filename,
int fd, /* O_PATH fd */ int fd, /* O_PATH fd */
const char *path,
const struct stat *st, const struct stat *st,
Image **ret) { Image **ret) {
@ -395,8 +398,9 @@ static int image_make(
bool read_only; bool read_only;
int r; int r;
assert(path); assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path_is_absolute(path)); assert(dir_path || dir_fd == AT_FDCWD);
assert(filename);
/* We explicitly *do* follow symlinks here, since we want to allow symlinking trees, raw files and block /* We explicitly *do* follow symlinks here, since we want to allow symlinking trees, raw files and block
* devices into /var/lib/machines/, and treat them normally. * devices into /var/lib/machines/, and treat them normally.
@ -407,7 +411,7 @@ static int image_make(
_cleanup_close_ int _fd = -EBADF; _cleanup_close_ int _fd = -EBADF;
if (fd < 0) { if (fd < 0) {
/* If we didn't get an fd passed in, then let's pin it via O_PATH now */ /* If we didn't get an fd passed in, then let's pin it via O_PATH now */
_fd = open(path, O_PATH|O_CLOEXEC); _fd = openat(dir_fd, filename, O_PATH|O_CLOEXEC);
if (_fd < 0) if (_fd < 0)
return -errno; return -errno;
@ -423,8 +427,14 @@ static int image_make(
st = &stbuf; st = &stbuf;
} }
_cleanup_free_ char *parent = NULL;
if (!dir_path) {
(void) fd_get_path(dir_fd, &parent);
dir_path = parent;
}
read_only = read_only =
path_startswith(path, "/usr") || (dir_path && path_startswith(dir_path, "/usr")) ||
(faccessat(fd, "", W_OK, AT_EACCESS|AT_EMPTY_PATH) < 0 && errno == EROFS); (faccessat(fd, "", W_OK, AT_EACCESS|AT_EMPTY_PATH) < 0 && errno == EROFS);
if (S_ISDIR(st->st_mode)) { if (S_ISDIR(st->st_mode)) {
@ -436,7 +446,7 @@ static int image_make(
if (!pretty) { if (!pretty) {
r = extract_image_basename( r = extract_image_basename(
path, filename,
image_class_suffix_to_string(c), image_class_suffix_to_string(c),
/* format_suffixes= */ NULL, /* format_suffixes= */ NULL,
&pretty_buffer, &pretty_buffer,
@ -464,7 +474,8 @@ static int image_make(
r = image_new(IMAGE_SUBVOLUME, r = image_new(IMAGE_SUBVOLUME,
c, c,
pretty, pretty,
path, dir_path,
filename,
info.read_only || read_only, info.read_only || read_only,
info.otime, info.otime,
info.ctime, info.ctime,
@ -489,7 +500,8 @@ static int image_make(
r = image_new(IMAGE_DIRECTORY, r = image_new(IMAGE_DIRECTORY,
c, c,
pretty, pretty,
path, dir_path,
filename,
read_only || (file_attr & FS_IMMUTABLE_FL), read_only || (file_attr & FS_IMMUTABLE_FL),
crtime, crtime,
0, /* we don't use mtime of stat() here, since it's not the time of last change of the tree, but only of the top-level dir */ 0, /* we don't use mtime of stat() here, since it's not the time of last change of the tree, but only of the top-level dir */
@ -500,7 +512,7 @@ static int image_make(
(*ret)->foreign_uid_owned = uid_is_foreign(st->st_uid); (*ret)->foreign_uid_owned = uid_is_foreign(st->st_uid);
return 0; return 0;
} else if (S_ISREG(st->st_mode) && endswith(path, ".raw")) { } else if (S_ISREG(st->st_mode) && endswith(filename, ".raw")) {
usec_t crtime = 0; usec_t crtime = 0;
/* It's a RAW disk image */ /* It's a RAW disk image */
@ -512,7 +524,7 @@ static int image_make(
if (!pretty) { if (!pretty) {
r = extract_image_basename( r = extract_image_basename(
path, filename,
image_class_suffix_to_string(c), image_class_suffix_to_string(c),
STRV_MAKE(".raw"), STRV_MAKE(".raw"),
&pretty_buffer, &pretty_buffer,
@ -526,7 +538,8 @@ static int image_make(
r = image_new(IMAGE_RAW, r = image_new(IMAGE_RAW,
c, c,
pretty, pretty,
path, dir_path,
filename,
!(st->st_mode & 0222) || read_only, !(st->st_mode & 0222) || read_only,
crtime, crtime,
timespec_load(&st->st_mtim), timespec_load(&st->st_mtim),
@ -549,7 +562,7 @@ static int image_make(
if (!pretty) { if (!pretty) {
r = extract_image_basename( r = extract_image_basename(
path, filename,
/* class_suffix= */ NULL, /* class_suffix= */ NULL,
/* format_suffix= */ NULL, /* format_suffix= */ NULL,
&pretty_buffer, &pretty_buffer,
@ -562,20 +575,20 @@ static int image_make(
_cleanup_close_ int block_fd = fd_reopen(fd, O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY); _cleanup_close_ int block_fd = fd_reopen(fd, O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
if (block_fd < 0) if (block_fd < 0)
log_debug_errno(errno, "Failed to open block device '%s', ignoring: %m", path); log_debug_errno(errno, "Failed to open block device %s/%s, ignoring: %m", strnull(dir_path), filename);
else { else {
if (!read_only) { if (!read_only) {
int state = 0; int state = 0;
if (ioctl(block_fd, BLKROGET, &state) < 0) if (ioctl(block_fd, BLKROGET, &state) < 0)
log_debug_errno(errno, "Failed to issue BLKROGET on device '%s', ignoring: %m", path); log_debug_errno(errno, "Failed to issue BLKROGET on device %s/%s, ignoring: %m", strnull(dir_path), filename);
else if (state) else if (state)
read_only = true; read_only = true;
} }
r = blockdev_get_device_size(block_fd, &size); r = blockdev_get_device_size(block_fd, &size);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to issue BLKGETSIZE64 on device '%s', ignoring: %m", path); log_debug_errno(r, "Failed to issue BLKGETSIZE64 on device %s/%s, ignoring: %m", strnull(dir_path), filename);
block_fd = safe_close(block_fd); block_fd = safe_close(block_fd);
} }
@ -583,7 +596,8 @@ static int image_make(
r = image_new(IMAGE_BLOCK, r = image_new(IMAGE_BLOCK,
c, c,
pretty, pretty,
path, dir_path,
filename,
!(st->st_mode & 0222) || read_only, !(st->st_mode & 0222) || read_only,
0, 0,
0, 0,
@ -759,11 +773,11 @@ int image_find(RuntimeScope scope,
if (r < 0) if (r < 0)
return r; return r;
STRV_FOREACH(s, search) { STRV_FOREACH(path, search) {
_cleanup_free_ char *resolved = NULL; _cleanup_free_ char *resolved = NULL;
_cleanup_closedir_ DIR *d = NULL; _cleanup_closedir_ DIR *d = NULL;
r = chase_and_opendir(*s, root, CHASE_PREFIX_ROOT, &resolved, &d); r = chase_and_opendir(*path, root, CHASE_PREFIX_ROOT, &resolved, &d);
if (r == -ENOENT) if (r == -ENOENT)
continue; continue;
if (r < 0) if (r < 0)
@ -834,7 +848,7 @@ int image_find(RuntimeScope scope,
/* Refresh the stat data for the discovered target */ /* Refresh the stat data for the discovered target */
st = result.st; st = result.st;
close_and_replace(fd, result.fd); fd = safe_close(fd);
_cleanup_free_ char *bn = NULL; _cleanup_free_ char *bn = NULL;
r = path_extract_filename(result.path, &bn); r = path_extract_filename(result.path, &bn);
@ -854,11 +868,7 @@ int image_find(RuntimeScope scope,
continue; continue;
} }
_cleanup_free_ char *path = path_join(resolved, fname); r = image_make(class, name, dirfd(d), resolved, fname, fd, &st, ret);
if (!path)
return -ENOMEM;
r = image_make(class, name, fd, path, &st, ret);
if (IN_SET(r, -ENOENT, -EMEDIUMTYPE)) if (IN_SET(r, -ENOENT, -EMEDIUMTYPE))
continue; continue;
if (r < 0) if (r < 0)
@ -874,8 +884,10 @@ int image_find(RuntimeScope scope,
if (scope == RUNTIME_SCOPE_SYSTEM && class == IMAGE_MACHINE && streq(name, ".host")) { if (scope == RUNTIME_SCOPE_SYSTEM && class == IMAGE_MACHINE && streq(name, ".host")) {
r = image_make(class, r = image_make(class,
".host", ".host",
/* dir_fd= */ AT_FDCWD,
/* dir_path= */ NULL,
/* filename= */ empty_to_root(root),
/* fd= */ -EBADF, /* fd= */ -EBADF,
/* path= */ empty_to_root(root),
/* st= */ NULL, /* st= */ NULL,
ret); ret);
if (r < 0) if (r < 0)
@ -891,7 +903,6 @@ int image_find(RuntimeScope scope,
}; };
int image_from_path(const char *path, Image **ret) { int image_from_path(const char *path, Image **ret) {
int r;
/* Note that we don't set the 'discoverable' field of the returned object, because we don't check here whether /* Note that we don't set the 'discoverable' field of the returned object, because we don't check here whether
* the image is in the image search path. And if it is we don't know if the path we used is actually not * the image is in the image search path. And if it is we don't know if the path we used is actually not
@ -901,21 +912,20 @@ int image_from_path(const char *path, Image **ret) {
return image_make( return image_make(
IMAGE_MACHINE, IMAGE_MACHINE,
".host", ".host",
/* dir_fd= */ AT_FDCWD,
/* dir_path= */ NULL,
/* filename= */ "/",
/* fd= */ -EBADF, /* fd= */ -EBADF,
/* path= */ "/",
/* st= */ NULL, /* st= */ NULL,
ret); ret);
_cleanup_free_ char *absolute = NULL;
r = path_make_absolute_cwd(path, &absolute);
if (r < 0)
return r;
return image_make( return image_make(
_IMAGE_CLASS_INVALID, _IMAGE_CLASS_INVALID,
/* pretty= */ NULL, /* pretty= */ NULL,
/* dir_fd= */ AT_FDCWD,
/* dir_path= */ NULL,
/* filename= */ path,
/* fd= */ -EBADF, /* fd= */ -EBADF,
absolute,
/* st= */ NULL, /* st= */ NULL,
ret); ret);
} }
@ -954,11 +964,11 @@ int image_discover(
if (r < 0) if (r < 0)
return r; return r;
STRV_FOREACH(s, search) { STRV_FOREACH(path, search) {
_cleanup_free_ char *resolved = NULL; _cleanup_free_ char *resolved = NULL;
_cleanup_closedir_ DIR *d = NULL; _cleanup_closedir_ DIR *d = NULL;
r = chase_and_opendir(*s, root, CHASE_PREFIX_ROOT, &resolved, &d); r = chase_and_opendir(*path, root, CHASE_PREFIX_ROOT, &resolved, &d);
if (r == -ENOENT) if (r == -ENOENT)
continue; continue;
if (r < 0) if (r < 0)
@ -1046,7 +1056,7 @@ int image_discover(
/* Refresh the stat data for the discovered target */ /* Refresh the stat data for the discovered target */
st = result.st; st = result.st;
close_and_replace(fd, result.fd); fd = safe_close(fd);
_cleanup_free_ char *bn = NULL; _cleanup_free_ char *bn = NULL;
r = path_extract_filename(result.path, &bn); r = path_extract_filename(result.path, &bn);
@ -1060,7 +1070,6 @@ int image_discover(
return log_oom(); return log_oom();
fname = fname_buf; fname = fname_buf;
} else { } else {
r = extract_image_basename( r = extract_image_basename(
fname, fname,
@ -1093,11 +1102,7 @@ int image_discover(
if (hashmap_contains(*images, pretty)) if (hashmap_contains(*images, pretty))
continue; continue;
_cleanup_free_ char *path = path_join(resolved, fname); r = image_make(class, pretty, dirfd(d), resolved, fname, fd, &st, &image);
if (!path)
return -ENOMEM;
r = image_make(class, pretty, fd, path, &st, &image);
if (IN_SET(r, -ENOENT, -EMEDIUMTYPE)) if (IN_SET(r, -ENOENT, -EMEDIUMTYPE))
continue; continue;
if (r < 0) if (r < 0)
@ -1118,8 +1123,10 @@ int image_discover(
r = image_make(IMAGE_MACHINE, r = image_make(IMAGE_MACHINE,
".host", ".host",
/* dir_fd= */ AT_FDCWD,
/* dir_path= */ NULL,
empty_to_root(root),
/* fd= */ -EBADF, /* fd= */ -EBADF,
/* path= */ empty_to_root(root),
/* st= */ NULL, /* st= */ NULL,
&image); &image);
if (r < 0) if (r < 0)

View File

@ -231,7 +231,7 @@ PartitionPolicyFlags partition_policy_flags_from_string(const char *s, bool grac
ff = policy_flag_from_string_one(strstrip(f)); ff = policy_flag_from_string_one(strstrip(f));
if (ff < 0) { if (ff < 0) {
if (graceful) { if (graceful) {
log_debug("Unknown partition policy flag, ignoring: %s", f); log_debug("Unknown partition policy flag: %s, ignoring", f);
continue; continue;
} }
return -EBADRQC; /* recognizable error */ return -EBADRQC; /* recognizable error */
@ -345,7 +345,7 @@ int image_policy_from_string(const char *s, bool graceful, ImagePolicy **ret) {
if (!graceful) if (!graceful)
return log_debug_errno(SYNTHETIC_ERRNO(EBADSLT), "Unknown partition designator: %s", ds); /* recognizable error */ return log_debug_errno(SYNTHETIC_ERRNO(EBADSLT), "Unknown partition designator: %s", ds); /* recognizable error */
log_debug("Unknown partition designator, ignoring: %s", ds); log_debug("Unknown partition designator: %s, ignoring", ds);
continue; continue;
} }
if (dmask & (UINT64_C(1) << designator)) if (dmask & (UINT64_C(1) << designator))