discover-image: nicely support .sysext.raw + .confext.raw suffix for DDIs

Back at Plumbers 2022 we discussed that we should push people towards
using the .sysext.raw and .confext.raw for their DDIs if they are
extension images. Let's actually support that, by chopping off these
suffixes when turning file names into "pretty image names".
This commit is contained in:
Lennart Poettering
2023-09-28 18:22:24 +02:00
parent a121b331e3
commit a747994b45
2 changed files with 40 additions and 31 deletions

View File

@@ -85,6 +85,13 @@ static const char* const image_search_path_initrd[_IMAGE_CLASS_MAX] = {
"/.extra/sysext\0" /* put sysext picked up by systemd-stub last, since not trusted */
};
static const char* image_class_suffix_table[_IMAGE_CLASS_MAX] = {
[IMAGE_SYSEXT] = ".sysext",
[IMAGE_CONFEXT] = ".confext",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(image_class_suffix, ImageClass);
static Image *image_free(Image *i) {
assert(i);
@@ -201,29 +208,36 @@ static int image_new(
return 0;
}
static int extract_pretty(const char *path, const char *suffix, char **ret) {
static int extract_pretty(
const char *path,
const char *class_suffix,
const char *format_suffix,
char **ret) {
_cleanup_free_ char *name = NULL;
const char *p;
int r;
assert(path);
assert(ret);
p = last_path_component(path);
r = path_extract_filename(path, &name);
if (r < 0)
return r;
name = strdupcspn(p, "/");
if (!name)
return -ENOMEM;
if (suffix) {
char *e;
e = endswith(name, suffix);
if (!e)
if (format_suffix) {
char *e = endswith(name, format_suffix);
if (!e) /* Format suffix is required */
return -EINVAL;
*e = 0;
}
if (class_suffix) {
char *e = endswith(name, class_suffix);
if (e) /* Class suffix is optional */
*e = 0;
}
if (!image_name_is_valid(name))
return -EINVAL;
@@ -282,7 +296,7 @@ static int image_make(
return 0;
if (!pretty) {
r = extract_pretty(filename, NULL, &pretty_buffer);
r = extract_pretty(filename, image_class_suffix_to_string(c), NULL, &pretty_buffer);
if (r < 0)
return r;
@@ -369,7 +383,7 @@ static int image_make(
(void) fd_getcrtime_at(dfd, filename, AT_SYMLINK_FOLLOW, &crtime);
if (!pretty) {
r = extract_pretty(filename, ".raw", &pretty_buffer);
r = extract_pretty(filename, image_class_suffix_to_string(c), ".raw", &pretty_buffer);
if (r < 0)
return r;
@@ -403,7 +417,7 @@ static int image_make(
return 0;
if (!pretty) {
r = extract_pretty(filename, NULL, &pretty_buffer);
r = extract_pretty(filename, NULL, NULL, &pretty_buffer);
if (r < 0)
return r;
@@ -592,8 +606,7 @@ int image_discover(
FOREACH_DIRENT_ALL(de, d, return -errno) {
_cleanup_(image_unrefp) Image *image = NULL;
_cleanup_free_ char *truncated = NULL;
const char *pretty;
_cleanup_free_ char *pretty = NULL;
struct stat st;
int flags;
@@ -610,22 +623,16 @@ int image_discover(
return -errno;
}
if (S_ISREG(st.st_mode)) {
const char *e;
e = endswith(de->d_name, ".raw");
if (!e)
continue;
truncated = strndup(de->d_name, e - de->d_name);
if (!truncated)
return -ENOMEM;
pretty = truncated;
} else if (S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode))
pretty = de->d_name;
if (S_ISREG(st.st_mode))
r = extract_pretty(de->d_name, image_class_suffix_to_string(class), ".raw", &pretty);
else if (S_ISDIR(st.st_mode))
r = extract_pretty(de->d_name, image_class_suffix_to_string(class), NULL, &pretty);
else if (S_ISBLK(st.st_mode))
r = extract_pretty(de->d_name, NULL, NULL, &pretty);
else
continue;
if (r < 0)
return r;
if (!image_name_is_valid(pretty))
continue;

View File

@@ -167,6 +167,8 @@ int raw_strip_suffixes(const char *p, char **ret) {
".xz\0"
".gz\0"
".bz2\0"
".sysext.raw\0"
".confext.raw\0"
".raw\0"
".qcow2\0"
".img\0"