sysupdate: fix transfer config parsing and cleanup regressions (#43287)

This commit is contained in:
Yu Watanabe
2026-08-06 20:20:29 +09:00
committed by GitHub
2 changed files with 46 additions and 8 deletions

View File

@@ -34,7 +34,7 @@ int config_parse_url_specifiers(
}
_cleanup_free_ char *resolved = NULL;
r = specifier_printf(rvalue, NAME_MAX, system_and_tmp_specifier_table, root, NULL, &resolved);
r = specifier_printf(rvalue, SIZE_MAX, system_and_tmp_specifier_table, root, NULL, &resolved);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to expand specifiers in %s=, ignoring: %s", lvalue, rvalue);
@@ -90,7 +90,7 @@ int config_parse_url_specifiers_many(
}
_cleanup_free_ char *resolved = NULL;
r = specifier_printf(rvalue, NAME_MAX, system_and_tmp_specifier_table, root, NULL, &resolved);
r = specifier_printf(rvalue, SIZE_MAX, system_and_tmp_specifier_table, root, NULL, &resolved);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to expand specifiers in %s=, ignoring: %s", lvalue, rvalue);

View File

@@ -134,6 +134,11 @@ static int config_parse_protect_version(
assert(rvalue);
if (isempty(rvalue)) {
*protected_versions = strv_free(*protected_versions);
return 0;
}
r = specifier_printf(rvalue, NAME_MAX, system_and_tmp_specifier_table, t->context->root, NULL, &resolved);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
@@ -173,6 +178,11 @@ static int config_parse_min_version(
assert(rvalue);
if (isempty(rvalue)) {
*version = mfree(*version);
return 0;
}
r = specifier_printf(rvalue, NAME_MAX, system_and_tmp_specifier_table, t->context->root, NULL, &resolved);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
@@ -228,7 +238,12 @@ static int config_parse_current_symlink(
assert(rvalue);
r = specifier_printf(rvalue, NAME_MAX, system_and_tmp_specifier_table, t->context->root, NULL, &resolved);
if (isempty(rvalue)) {
*current_symlink = mfree(*current_symlink);
return 0;
}
r = specifier_printf(rvalue, PATH_MAX-1, system_and_tmp_specifier_table, t->context->root, NULL, &resolved);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to expand specifiers in CurrentSymlink=, ignoring: %s", rvalue);
@@ -415,6 +430,12 @@ static int config_parse_resource_ptype(
assert(rvalue);
if (isempty(rvalue)) {
rr->partition_type = (GptPartitionType) {};
rr->partition_type_set = false;
return 0;
}
r = gpt_partition_type_from_string(rvalue, &rr->partition_type);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
@@ -443,6 +464,12 @@ static int config_parse_partition_uuid(
assert(rvalue);
if (isempty(rvalue)) {
t->partition_uuid = SD_ID128_NULL;
t->partition_uuid_set = false;
return 0;
}
r = sd_id128_from_string(rvalue, &t->partition_uuid);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
@@ -471,7 +498,13 @@ static int config_parse_partition_flags(
assert(rvalue);
r = safe_atou64(rvalue, &t->partition_flags);
if (isempty(rvalue)) {
t->partition_flags = 0;
t->partition_flags_set = false;
return 0;
}
r = safe_atoux64(rvalue, &t->partition_flags);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse partition flags, ignoring: %s", rvalue);
@@ -608,6 +641,11 @@ int transfer_read_definition(Transfer *t, const char *path, const char **dirs, H
return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
"Target Type= must be one of partition, regular-file, directory, subvolume.");
if (t->target.type == RESOURCE_PARTITION && !t->target.partition_type_set) {
t->target.partition_type = gpt_partition_type_from_uuid(SD_GPT_LINUX_GENERIC);
t->target.partition_type_set = true;
}
if ((IN_SET(t->source.type, RESOURCE_URL_FILE, RESOURCE_PARTITION, RESOURCE_REGULAR_FILE) &&
!IN_SET(t->target.type, RESOURCE_PARTITION, RESOURCE_REGULAR_FILE)) ||
(IN_SET(t->source.type, RESOURCE_URL_TAR, RESOURCE_TAR, RESOURCE_DIRECTORY, RESOURCE_SUBVOLUME) &&
@@ -730,7 +768,8 @@ static void transfer_remove_temporary(Transfer *t) {
if (!IN_SET(t->target.type, RESOURCE_REGULAR_FILE, RESOURCE_DIRECTORY, RESOURCE_SUBVOLUME))
return;
/* Removes all temporary files/dirs from previous runs in the target directory, i.e. all those starting with '.#' */
/* Removes all incomplete files/dirs from previous runs in the target directory. Clean both the
* current partial sysupdate prefix and the legacy '.#' prefix. */
d = opendir(t->target.path);
if (!d) {
@@ -752,7 +791,7 @@ static void transfer_remove_temporary(Transfer *t) {
break;
}
if (!startswith(de->d_name, ".#"))
if (!STARTSWITH_SET(de->d_name, ".#", ".sysupdate.partial."))
continue;
r = rm_rf_child(dirfd(d), de->d_name, REMOVE_PHYSICAL|REMOVE_SUBVOLUME|REMOVE_CHMOD);
@@ -1269,8 +1308,7 @@ int transfer_compute_temporary_paths(Transfer *t, Instance *i, InstanceMetadata
if (!r)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Formatted pattern is not suitable as GPT partition label, refusing: %s", formatted_pattern);
if (!t->target.partition_type_set)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Partition type must be set for partition targets.");
assert(t->target.partition_type_set);
/* Derive temporary partition type UUIDs for partial/pending states from the configured
* partition type. This avoids the need for label prefixes. */