From e2f88d5af04413b61be4fce9176627ef71171677 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 6 May 2019 08:48:24 +0200 Subject: [PATCH 1/4] config: allow parsing percentages Signed-off-by: Michael Olbrich --- config.c | 17 ++++++++++++++++- genimage.h | 5 ++++- util.c | 14 ++++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/config.c b/config.c index 3e5ab80..b0dd721 100644 --- a/config.c +++ b/config.c @@ -152,7 +152,22 @@ unsigned long long cfg_getint_suffix(cfg_t *sec, const char *name) unsigned long long val = 0; if (str) - val = strtoul_suffix(str, NULL, 0); + val = strtoul_suffix(str, NULL, NULL); + + return val; +} + +/* + * Like cfg_getint_suffix() but allow '%' as suffix as well + */ +unsigned long long cfg_getint_suffix_percent(cfg_t *sec, const char *name, + cfg_bool_t *percent) +{ + const char *str = cfg_getstr(sec, name); + unsigned long long val = 0; + + if (str) + val = strtoul_suffix(str, NULL, percent); return val; } diff --git a/genimage.h b/genimage.h index e339d1d..1e87602 100644 --- a/genimage.h +++ b/genimage.h @@ -124,7 +124,8 @@ extern struct image_handler fit_handler; (type *)( (char *)__mptr - offsetof(type,member) );}) void *xzalloc(size_t n); -unsigned long long strtoul_suffix(const char *str, char **endp, int base); +unsigned long long strtoul_suffix(const char *str, char **endp, + cfg_bool_t *percent); int init_config(void); cfg_opt_t *get_confuse_opts(void); @@ -144,6 +145,8 @@ int insert_data(struct image *image, const char *data, const char *outfile, int reload_partitions(struct image *image); unsigned long long cfg_getint_suffix(cfg_t *sec, const char *name); +unsigned long long cfg_getint_suffix_percent(cfg_t *sec, const char *name, + cfg_bool_t *percent); static inline const char *imageoutfile(const struct image *image) { diff --git a/util.c b/util.c index 2b91a94..3202b26 100644 --- a/util.c +++ b/util.c @@ -251,12 +251,16 @@ void *xzalloc(size_t n) * Like simple_strtoul() but handles an optional G, M, K or k * suffix for Gigabyte, Megabyte or Kilobyte */ -unsigned long long strtoul_suffix(const char *str, char **endp, int base) +unsigned long long strtoul_suffix(const char *str, char **endp, + cfg_bool_t *percent) { unsigned long long val; char *end; - val = strtoull(str, &end, base); + val = strtoull(str, &end, 0); + + if (percent) + *percent = cfg_false; switch (*end) { case 'G': @@ -271,6 +275,12 @@ unsigned long long strtoul_suffix(const char *str, char **endp, int base) end++; case '\0': break; + case '%': + if (percent) { + *percent = cfg_true; + break; + } + /* fall-through */ default: error("Invalid size suffix '%s' in '%s'\n", end, str); exit(1); From 393897209665117e32360d5346bc1d3960f40a41 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 6 May 2019 08:50:05 +0200 Subject: [PATCH 2/4] util: add helper to calculate directory size Signed-off-by: Michael Olbrich --- genimage.h | 2 ++ util.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/genimage.h b/genimage.h index 1e87602..2559511 100644 --- a/genimage.h +++ b/genimage.h @@ -157,6 +157,8 @@ int uuid_validate(const char *str); void uuid_parse(const char *str, unsigned char *uuid); char *uuid_random(void); +unsigned long long image_dir_size(struct image *image); + uint32_t crc32(const void *data, size_t len); #endif /* __PTX_IMAGE_H */ diff --git a/util.c b/util.c index 3202b26..71104a1 100644 --- a/util.c +++ b/util.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "genimage.h" @@ -566,3 +567,52 @@ int reload_partitions(struct image *image) close(fd); return 0; } + +#define ROUND_UP(num,align) ((((num) + ((align) - 1)) & ~((align) - 1))) + +static unsigned long long dir_size(struct image *image, int dirfd, + const char *subdir, size_t blocksize) +{ + struct dirent *d; + DIR *dir; + int fd; + unsigned long long size = 0; + struct stat st; + + fd = openat(dirfd, subdir, O_RDONLY); + if (fd < 0) { + image_error(image, "failed to open '%s': %s", subdir, + strerror(errno)); + return 0; + } + + dir = fdopendir(dup(fd)); + if (dir == NULL) { + image_error(image, "failed to opendir '%s': %s", subdir, + strerror(errno)); + return 0; + } + while ((d = readdir(dir)) != NULL) { + if (d->d_type == DT_DIR) { + if (d->d_name[0] == '.' && (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) + continue; + size += dir_size(image, fd, d->d_name, blocksize); + continue; + } + if (d->d_type != DT_REG) + continue; + if (fstatat(fd, d->d_name, &st, AT_NO_AUTOMOUNT) < 0) { + image_error(image, "failed to stat '%s': %s", + d->d_name, strerror(errno)); + continue; + } + size += ROUND_UP(st.st_size, blocksize); + } + return size + blocksize; +} + +unsigned long long image_dir_size(struct image *image) +{ + return dir_size(image, AT_FDCWD, mountpath(image), 4096); +} From 8d9c1a2bd3d995434f3f66c3c0a08edc035b1f3a Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 6 May 2019 08:58:42 +0200 Subject: [PATCH 3/4] genimage: allow percentages for image sizes Signed-off-by: Michael Olbrich --- Makefile.am | 2 ++ README.rst | 6 +++++- genimage.c | 16 ++++++++++----- genimage.h | 1 + test/basic-images.test | 5 +++++ test/ext2percent.config | 7 +++++++ test/ext2test-percent.dump | 40 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 test/ext2percent.config create mode 100644 test/ext2test-percent.dump diff --git a/Makefile.am b/Makefile.am index 3c96229..d283212 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,6 +51,8 @@ EXTRA_DIST += \ test/cramfs.config \ test/ext2.config \ test/ext2test.dump \ + test/ext2percent.config \ + test/ext2test-percent.dump \ test/ext3.config \ test/ext3test.dump \ test/ext4.config \ diff --git a/README.rst b/README.rst index 67a648a..6cc5846 100644 --- a/README.rst +++ b/README.rst @@ -68,7 +68,11 @@ Here are all options for images: :name: The name of this image. This is used for some image types to set the name of the image. -:size: Size of this image in bytes +:size: Size of this image in bytes. 'k', 'M' or 'G' can be used as suffix to + specify the size in multiple of 1024 etc. If the image if filled from + a mountpoint then '%' as suffix indicates a percentage. '200%' means + the resulting filesystem should be about 50% filled. Note that is is + only a rough estimate based on the original size of the content. :mountpoint: mountpoint if image refers to a filesystem image. The default is "/". The content of "${rootpath}${mountpoint}" will be used used fill the filesystem. diff --git a/genimage.c b/genimage.c index 64a7b2e..ca2c6d6 100644 --- a/genimage.c +++ b/genimage.c @@ -157,6 +157,11 @@ static int image_setup(struct image *image) image->seen = -1; + if (image->size_is_percent) { + image->size = image_dir_size(image) * image->size / 100; + image->size_is_percent = cfg_false; + } + list_for_each_entry(part, &image->partitions, list) { struct image *child; if (!part->image) @@ -664,7 +669,8 @@ int main(int argc, char *argv[]) list_add_tail(&image->list, &images); image->file = cfg_title(imagesec); image->name = cfg_getstr(imagesec, "name"); - image->size = cfg_getint_suffix(imagesec, "size"); + image->size = cfg_getint_suffix_percent(imagesec, "size", + &image->size_is_percent); image->mountpoint = cfg_getstr(imagesec, "mountpoint"); image->exec_pre = cfg_getstr(imagesec, "exec-pre"); image->exec_post = cfg_getstr(imagesec, "exec-post"); @@ -717,6 +723,10 @@ int main(int argc, char *argv[]) if (ret) goto cleanup; + ret = collect_mountpoints(); + if (ret) + goto cleanup; + list_for_each_entry(image, &images, list) { ret = image_setup(image); if (ret) @@ -731,10 +741,6 @@ int main(int argc, char *argv[]) if (ret) goto cleanup; - ret = collect_mountpoints(); - if (ret) - goto cleanup; - list_for_each_entry(image, &images, list) { ret = setenv_image(image); if (ret) diff --git a/genimage.h b/genimage.h index 2559511..1ebe1cd 100644 --- a/genimage.h +++ b/genimage.h @@ -51,6 +51,7 @@ struct image { const char *name; const char *file; unsigned long long size; + cfg_bool_t size_is_percent; const char *mountpoint; const char *exec_pre; const char *exec_post; diff --git a/test/basic-images.test b/test/basic-images.test index 9b53b45..cf6d68b 100755 --- a/test/basic-images.test +++ b/test/basic-images.test @@ -157,6 +157,11 @@ test_expect_success genext2fs,e2fsck "ext2" " check_ext images/test.ext2 ext2test 4194304 " +test_expect_success genext2fs,e2fsck "ext2percent" " + run_genimage ext2percent.config test.ext2 && + check_ext images/test.ext2 ext2test-percent 69632 +" + test_expect_success genext2fs,e2fsck "ext3" " run_genimage ext3.config test.ext3 && check_ext images/test.ext3 ext3test 4194304 diff --git a/test/ext2percent.config b/test/ext2percent.config new file mode 100644 index 0000000..f9cd848 --- /dev/null +++ b/test/ext2percent.config @@ -0,0 +1,7 @@ +image test.ext2 { + ext2 { + label = "ext2test" + fs-timestamp = "20000101000000" + } + size = 100% +} diff --git a/test/ext2test-percent.dump b/test/ext2test-percent.dump new file mode 100644 index 0000000..f771eb4 --- /dev/null +++ b/test/ext2test-percent.dump @@ -0,0 +1,40 @@ +Filesystem volume name: ext2test +Last mounted on: +Filesystem magic number: 0xEF53 +Filesystem revision #: 0 (original) +Filesystem features: (none) +Default mount options: (none) +Filesystem state: clean +Errors behavior: Unknown (continue) +Filesystem OS type: Linux +Inode count: 56 +Block count: 68 +Reserved block count: 3 +Free blocks: 36 +Free inodes: 5 +First block: 1 +Block size: 1024 +Fragment size: 1024 +Blocks per group: 72 +Fragments per group: 72 +Inodes per group: 56 +Inode blocks per group: 7 +Filesystem created: Sat Jan 1 00:00:00 2000 +Last mount time: n/a +Last write time: Sat Jan 1 00:00:00 2000 +Mount count: 0 +Maximum mount count: 20 +Last checked: Sat Jan 1 00:00:00 2000 +Check interval: 0 () +Reserved blocks uid: 0 (user root) +Reserved blocks gid: 0 (group root) + + +Group 0: (Blocks 1-67) + Primary superblock at 1, Group descriptors at 2-2 + Block bitmap at 3 (+2) + Inode bitmap at 4 (+3) + Inode table at 5-11 (+4) + 36 free blocks, 5 free inodes, 18 directories + Free blocks: 32-67 + Free inodes: 52-56 From 34aa92e4faf52c1a14c7c772c5b980e4bdc40b48 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Tue, 7 May 2019 12:45:02 +0200 Subject: [PATCH 4/4] travis: find any logfile and dump it Signed-off-by: Michael Olbrich --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 395937e..187a7f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,4 +23,4 @@ script: - ./configure - make distcheck after_failure: - - cat genimage-*/_build/test-suite.log + - find -name test-suite.log -print0 | xargs -0 cat