ImageClass c,
const char *pretty,
const char *path,
- const char *filename,
bool read_only,
usec_t crtime,
usec_t mtime,
assert(t >= 0);
assert(t < _IMAGE_TYPE_MAX);
assert(pretty);
- assert(filename);
+ assert(path);
assert(ret);
i = new(Image, 1);
if (!i->name)
return -ENOMEM;
- i->path = path_join(path, filename);
+ i->path = strdup(path);
if (!i->path)
return -ENOMEM;
static int image_make(
ImageClass c,
const char *pretty,
- int dir_fd,
- const char *dir_path,
- const char *filename,
int fd, /* O_PATH fd */
+ const char *path,
const struct stat *st,
Image **ret) {
bool read_only;
int r;
- assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
- assert(dir_path || dir_fd == AT_FDCWD);
- assert(filename);
+ assert(path);
+ assert(path_is_absolute(path));
/* 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.
_cleanup_close_ int _fd = -EBADF;
if (fd < 0) {
/* If we didn't get an fd passed in, then let's pin it via O_PATH now */
- _fd = openat(dir_fd, filename, O_PATH|O_CLOEXEC);
+ _fd = open(path, O_PATH|O_CLOEXEC);
if (_fd < 0)
return -errno;
st = &stbuf;
}
- _cleanup_free_ char *parent = NULL;
- if (!dir_path) {
- (void) fd_get_path(dir_fd, &parent);
- dir_path = parent;
- }
-
read_only =
- (dir_path && path_startswith(dir_path, "/usr")) ||
+ path_startswith(path, "/usr") ||
(faccessat(fd, "", W_OK, AT_EACCESS|AT_EMPTY_PATH) < 0 && errno == EROFS);
if (S_ISDIR(st->st_mode)) {
if (!pretty) {
r = extract_image_basename(
- filename,
+ path,
image_class_suffix_to_string(c),
/* format_suffixes= */ NULL,
&pretty_buffer,
r = image_new(IMAGE_SUBVOLUME,
c,
pretty,
- dir_path,
- filename,
+ path,
info.read_only || read_only,
info.otime,
info.ctime,
r = image_new(IMAGE_DIRECTORY,
c,
pretty,
- dir_path,
- filename,
+ path,
read_only || (file_attr & FS_IMMUTABLE_FL),
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 */
(*ret)->foreign_uid_owned = uid_is_foreign(st->st_uid);
return 0;
- } else if (S_ISREG(st->st_mode) && endswith(filename, ".raw")) {
+ } else if (S_ISREG(st->st_mode) && endswith(path, ".raw")) {
usec_t crtime = 0;
/* It's a RAW disk image */
if (!pretty) {
r = extract_image_basename(
- filename,
+ path,
image_class_suffix_to_string(c),
STRV_MAKE(".raw"),
&pretty_buffer,
r = image_new(IMAGE_RAW,
c,
pretty,
- dir_path,
- filename,
+ path,
!(st->st_mode & 0222) || read_only,
crtime,
timespec_load(&st->st_mtim),
if (!pretty) {
r = extract_image_basename(
- filename,
+ path,
/* class_suffix= */ NULL,
/* format_suffix= */ NULL,
&pretty_buffer,
_cleanup_close_ int block_fd = fd_reopen(fd, O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
if (block_fd < 0)
- log_debug_errno(errno, "Failed to open block device %s/%s, ignoring: %m", strnull(dir_path), filename);
+ log_debug_errno(errno, "Failed to open block device '%s', ignoring: %m", path);
else {
if (!read_only) {
int state = 0;
if (ioctl(block_fd, BLKROGET, &state) < 0)
- log_debug_errno(errno, "Failed to issue BLKROGET on device %s/%s, ignoring: %m", strnull(dir_path), filename);
+ log_debug_errno(errno, "Failed to issue BLKROGET on device '%s', ignoring: %m", path);
else if (state)
read_only = true;
}
r = blockdev_get_device_size(block_fd, &size);
if (r < 0)
- log_debug_errno(r, "Failed to issue BLKGETSIZE64 on device %s/%s, ignoring: %m", strnull(dir_path), filename);
+ log_debug_errno(r, "Failed to issue BLKGETSIZE64 on device '%s', ignoring: %m", path);
block_fd = safe_close(block_fd);
}
r = image_new(IMAGE_BLOCK,
c,
pretty,
- dir_path,
- filename,
+ path,
!(st->st_mode & 0222) || read_only,
0,
0,
if (r < 0)
return r;
- STRV_FOREACH(path, search) {
+ STRV_FOREACH(s, search) {
_cleanup_free_ char *resolved = NULL;
_cleanup_closedir_ DIR *d = NULL;
- r = chase_and_opendir(*path, root, CHASE_PREFIX_ROOT, &resolved, &d);
+ r = chase_and_opendir(*s, root, CHASE_PREFIX_ROOT, &resolved, &d);
if (r == -ENOENT)
continue;
if (r < 0)
/* Refresh the stat data for the discovered target */
st = result.st;
- fd = safe_close(fd);
+ close_and_replace(fd, result.fd);
_cleanup_free_ char *bn = NULL;
r = path_extract_filename(result.path, &bn);
continue;
}
- r = image_make(class, name, dirfd(d), resolved, fname, fd, &st, ret);
+ _cleanup_free_ char *path = path_join(resolved, fname);
+ if (!path)
+ return -ENOMEM;
+
+ r = image_make(class, name, fd, path, &st, ret);
if (IN_SET(r, -ENOENT, -EMEDIUMTYPE))
continue;
if (r < 0)
if (scope == RUNTIME_SCOPE_SYSTEM && class == IMAGE_MACHINE && streq(name, ".host")) {
r = image_make(class,
".host",
- /* dir_fd= */ AT_FDCWD,
- /* dir_path= */ NULL,
- /* filename= */ empty_to_root(root),
/* fd= */ -EBADF,
+ /* path= */ empty_to_root(root),
/* st= */ NULL,
ret);
if (r < 0)
};
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
* the image is in the image search path. And if it is we don't know if the path we used is actually not
return image_make(
IMAGE_MACHINE,
".host",
- /* dir_fd= */ AT_FDCWD,
- /* dir_path= */ NULL,
- /* filename= */ "/",
/* fd= */ -EBADF,
+ /* path= */ "/",
/* st= */ NULL,
ret);
+ _cleanup_free_ char *absolute = NULL;
+ r = path_make_absolute_cwd(path, &absolute);
+ if (r < 0)
+ return r;
+
return image_make(
_IMAGE_CLASS_INVALID,
/* pretty= */ NULL,
- /* dir_fd= */ AT_FDCWD,
- /* dir_path= */ NULL,
- /* filename= */ path,
/* fd= */ -EBADF,
+ absolute,
/* st= */ NULL,
ret);
}
if (r < 0)
return r;
- STRV_FOREACH(path, search) {
+ STRV_FOREACH(s, search) {
_cleanup_free_ char *resolved = NULL;
_cleanup_closedir_ DIR *d = NULL;
- r = chase_and_opendir(*path, root, CHASE_PREFIX_ROOT, &resolved, &d);
+ r = chase_and_opendir(*s, root, CHASE_PREFIX_ROOT, &resolved, &d);
if (r == -ENOENT)
continue;
if (r < 0)
/* Refresh the stat data for the discovered target */
st = result.st;
- fd = safe_close(fd);
+ close_and_replace(fd, result.fd);
_cleanup_free_ char *bn = NULL;
r = path_extract_filename(result.path, &bn);
return log_oom();
fname = fname_buf;
+
} else {
r = extract_image_basename(
fname,
if (hashmap_contains(*images, pretty))
continue;
- r = image_make(class, pretty, dirfd(d), resolved, fname, fd, &st, &image);
+ _cleanup_free_ char *path = path_join(resolved, fname);
+ if (!path)
+ return -ENOMEM;
+
+ r = image_make(class, pretty, fd, path, &st, &image);
if (IN_SET(r, -ENOENT, -EMEDIUMTYPE))
continue;
if (r < 0)
r = image_make(IMAGE_MACHINE,
".host",
- /* dir_fd= */ AT_FDCWD,
- /* dir_path= */ NULL,
- empty_to_root(root),
/* fd= */ -EBADF,
+ /* path= */ empty_to_root(root),
/* st= */ NULL,
&image);
if (r < 0)