summaryrefslogtreecommitdiffstats
path: root/src/partition
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2022-11-23 15:55:16 +0100
committerDaan De Meyer <daan.j.demeyer@gmail.com>2022-11-29 10:08:51 +0100
commit621083481b4e00c8cb983d3853bd4cf567ca7796 (patch)
tree7d228bc0b73d2370976fdbfdbc021aa0fab3e5c6 /src/partition
parentrepart: Make sure we clean up temporary files created in context_minimize() (diff)
downloadsystemd-621083481b4e00c8cb983d3853bd4cf567ca7796.tar.xz
systemd-621083481b4e00c8cb983d3853bd4cf567ca7796.zip
repart: Refactor split names
Diffstat (limited to 'src/partition')
-rw-r--r--src/partition/repart.c134
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;