diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2022-11-23 15:55:16 +0100 |
---|---|---|
committer | Daan De Meyer <daan.j.demeyer@gmail.com> | 2022-11-29 10:08:51 +0100 |
commit | 621083481b4e00c8cb983d3853bd4cf567ca7796 (patch) | |
tree | 7d228bc0b73d2370976fdbfdbc021aa0fab3e5c6 /src/partition | |
parent | repart: Make sure we clean up temporary files created in context_minimize() (diff) | |
download | systemd-621083481b4e00c8cb983d3853bd4cf567ca7796.tar.xz systemd-621083481b4e00c8cb983d3853bd4cf567ca7796.zip |
repart: Refactor split names
Diffstat (limited to 'src/partition')
-rw-r--r-- | src/partition/repart.c | 134 |
1 files changed, 69 insertions, 65 deletions
diff --git a/src/partition/repart.c b/src/partition/repart.c index 5ac3b26dff..860ffdae36 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -234,7 +234,7 @@ struct Partition { size_t roothash_size; char *split_name_format; - char *split_name_resolved; + char *split_path; Partition *siblings[_VERITY_MODE_MAX]; @@ -355,7 +355,7 @@ static Partition* partition_free(Partition *p) { free(p->roothash); free(p->split_name_format); - free(p->split_name_resolved); + free(p->split_path); return mfree(p); } @@ -4473,7 +4473,7 @@ static int context_mangle_partitions(Context *context) { return 0; } -static int split_name_printf(Partition *p) { +static int split_name_printf(Partition *p, char **ret) { assert(p); const Specifier table[] = { @@ -4486,125 +4486,129 @@ static int split_name_printf(Partition *p) { {} }; - return specifier_printf(p->split_name_format, NAME_MAX, table, arg_root, p, &p->split_name_resolved); + return specifier_printf(p->split_name_format, NAME_MAX, table, arg_root, p, ret); } -static int split_name_resolve(Context *context) { +static int split_node(const char *node, char **ret_base, char **ret_ext) { + _cleanup_free_ char *base = NULL, *ext = NULL; + char *e; + int r; + + assert(node); + assert(ret_base); + assert(ret_ext); + + r = path_extract_filename(node, &base); + if (r == O_DIRECTORY || r == -EADDRNOTAVAIL) + return log_error_errno(r, "Device node %s cannot be a directory", node); + if (r < 0) + return log_error_errno(r, "Failed to extract filename from %s: %m", node); + + e = endswith(base, ".raw"); + if (e) { + ext = strdup(e); + if (!ext) + return log_oom(); + + *e = 0; + } + + *ret_base = TAKE_PTR(base); + *ret_ext = TAKE_PTR(ext); + + return 0; +} + +static int split_name_resolve(Context *context, const char *node) { + _cleanup_free_ char *parent = NULL, *base = NULL, *ext = NULL; int r; + assert(context); + assert(node); + + r = path_extract_directory(node, &parent); + if (r < 0 && r != -EDESTADDRREQ) + return log_error_errno(r, "Failed to extract directory from %s: %m", node); + + r = split_node(node, &base, &ext); + if (r < 0) + return r; + LIST_FOREACH(partitions, p, context->partitions) { + _cleanup_free_ char *resolved = NULL; + if (p->dropped) continue; if (!p->split_name_format) continue; - r = split_name_printf(p); + r = split_name_printf(p, &resolved); if (r < 0) return log_error_errno(r, "Failed to resolve specifiers in %s: %m", p->split_name_format); + + if (parent) + p->split_path = strjoin(parent, "/", base, ".", resolved, ext); + else + p->split_path = strjoin(base, ".", resolved, ext); + if (!p->split_path) + return log_oom(); } LIST_FOREACH(partitions, p, context->partitions) { - if (!p->split_name_resolved) + if (!p->split_path) continue; LIST_FOREACH(partitions, q, context->partitions) { if (p == q) continue; - if (!q->split_name_resolved) + if (!q->split_path) continue; - if (!streq(p->split_name_resolved, q->split_name_resolved)) + if (!streq(p->split_path, q->split_path)) continue; return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "%s and %s have the same resolved split name \"%s\", refusing", - p->definition_path, q->definition_path, p->split_name_resolved); + p->definition_path, q->definition_path, p->split_path); } } return 0; } -static int split_node(const char *node, char **ret_base, char **ret_ext) { - _cleanup_free_ char *base = NULL, *ext = NULL; - char *e; - int r; - - assert(node); - assert(ret_base); - assert(ret_ext); - - r = path_extract_filename(node, &base); - if (r == O_DIRECTORY || r == -EADDRNOTAVAIL) - return log_error_errno(r, "Device node %s cannot be a directory", arg_node); - if (r < 0) - return log_error_errno(r, "Failed to extract filename from %s: %m", arg_node); - - e = endswith(base, ".raw"); - if (e) { - ext = strdup(e); - if (!ext) - return log_oom(); - - *e = 0; - } - - *ret_base = TAKE_PTR(base); - *ret_ext = TAKE_PTR(ext); - - return 0; -} - -static int context_split(Context *context) { - _cleanup_free_ char *base = NULL, *ext = NULL; - _cleanup_close_ int dir_fd = -1; +static int context_split(Context *context, const char *node) { int fd = -1, r; if (!arg_split) return 0; assert(context); - assert(arg_node); + assert(node); /* We can't do resolution earlier because the partition UUIDs for verity partitions are only filled * in after they've been generated. */ - r = split_name_resolve(context); - if (r < 0) - return r; - - r = split_node(arg_node, &base, &ext); + r = split_name_resolve(context, node); if (r < 0) return r; - dir_fd = r = open_parent(arg_node, O_PATH|O_CLOEXEC, 0); - if (r == -EDESTADDRREQ) - dir_fd = AT_FDCWD; - else if (r < 0) - return log_error_errno(r, "Failed to open parent directory of %s: %m", arg_node); - LIST_FOREACH(partitions, p, context->partitions) { - _cleanup_free_ char *fname = NULL; _cleanup_close_ int fdt = -1; if (p->dropped) continue; - if (!p->split_name_resolved) + if (!p->split_path) continue; if (partition_skip(p)) continue; - fname = strjoin(base, ".", p->split_name_resolved, ext); - if (!fname) - return log_oom(); - - fdt = openat(dir_fd, fname, O_WRONLY|O_NOCTTY|O_CLOEXEC|O_NOFOLLOW|O_CREAT|O_EXCL, 0666); + fdt = open(p->split_path, O_WRONLY|O_NOCTTY|O_CLOEXEC|O_NOFOLLOW|O_CREAT|O_EXCL, 0666); if (fdt < 0) - return log_error_errno(errno, "Failed to open %s: %m", fname); + return log_error_errno(fdt, "Failed to open split partition file %s: %m", p->split_path); if (fd < 0) assert_se((fd = fdisk_get_devfd(context->fdisk_context)) >= 0); @@ -4614,7 +4618,7 @@ static int context_split(Context *context) { r = copy_bytes(fd, fdt, p->new_size, COPY_REFLINK|COPY_HOLES); if (r < 0) - return log_error_errno(r, "Failed to copy to split partition %s: %m", fname); + return log_error_errno(r, "Failed to copy to split partition %s: %m", p->split_path); } return 0; @@ -6485,7 +6489,7 @@ static int run(int argc, char *argv[]) { if (r < 0) return r; - r = context_split(context); + r = context_split(context, node); if (r < 0) return r; |