genimage/image-squashfs.c
Rasmus Villemoes 7cc8078c41 image-squashfs: handle image->size appropriately
I was trying to actually make use of genimage's ability to split a
root filesystem into a read-only part stored in a squashfs, and a
writable /home partition in an ext4 image. Unfortunately, the squashfs
didn't end up included in the sd image:

INFO: hdimage(...): adding partition 'rootfs-A' (in MBR) from 'rootfs.squashfs' ...
INFO: hdimage(...): adding partition 'rootfs-B' (in MBR) from 'rootfs.squashfs' ...

INFO: hdimage(...): adding partition 'home' (in MBR) from 'home.ext4' ...
DEBUG: hdimage(...): copying 524288000 bytes from .../genimage-tmp/home.ext4 at offset 1577058304

I.e., there's no "copying xxx bytes from" lines following the "adding
partition rootfs" lines. That's due to

		if (child->size == 0)
			continue;

around line 457 in image-hd.c.

For a squashfs, we don't know the final size of the image, and we
should not be forced to decide upfront how large it can be. So
interpret a squashfs image node's size, when given, as a maximum
size. So if a size has been set and the generated image turns out to
be larger, make it an error.

Otherwise, that is, when the size is given and >= the generated
image, or when the size is not given explicitly, set image->size to
the size of the generated file.

There is one small problem: Consumers, e.g. image-hd.c, may have done
a sanity check (part size v child image size) during the setup phase,
but we don't (and can't) set the final size until the generate
phase. The next patch will fix that by repeating the sanity check
during generate.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
2021-11-29 08:02:40 +01:00

92 lines
2.9 KiB
C

/*
* Copyright (c) 2014 Juergen Beisert <jbe@pengutronix.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <confuse.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "genimage.h"
static int squash_generate(struct image *image)
{
char *extraargs = cfg_getstr(image->imagesec, "extraargs");
char compression[128];
char *comp_setup = cfg_getstr(image->imagesec, "compression");
unsigned block_size = cfg_getint_suffix(image->imagesec, "block-size");
unsigned long long file_size;
struct stat sb;
int ret;
/*
* 'mksquashfs' currently defaults to 'gzip' compression. Provide a shortcut
* to be able to disable all kind of compression and force the current
* default behaviour for the future. Disabling compression is very useful
* to handle binary diffs.
*/
if (!strcasecmp(comp_setup, "none"))
strncpy(compression, "-comp gzip -noInodeCompression -noDataCompression -noFragmentCompression -noXattrCompression", sizeof(compression));
else
snprintf(compression, sizeof(compression), "-comp %s", comp_setup);
ret = systemp(image, "%s '%s' '%s' -b %u -noappend %s %s",
get_opt("mksquashfs"),
mountpath(image), /* source dir */
imageoutfile(image), /* destination file */
block_size, compression, extraargs);
if (ret)
return ret;
ret = stat(imageoutfile(image), &sb);
if (ret) {
ret = -errno;
image_error(image, "stat(%s) failed: %s\n", imageoutfile(image), strerror(errno));
return ret;
}
file_size = sb.st_size;
if (image->size && file_size > image->size) {
image_error(image, "generated image %s is larger than given image size (%llu v %llu)\n",
imageoutfile(image), file_size, image->size);
return -E2BIG;
}
image_debug(image, "setting image size to %llu bytes\n", file_size);
image->size = file_size;
return 0;
}
/**
* 'compression' can be 'gzip' (the current default), 'lzo', 'xz' or 'none'
* @note 'none' is a special keyword to add the parameters '-noInodeCompression -noDataCompression -noFragmentCompression -noXattrCompression'
*/
static cfg_opt_t squash_opts[] = {
CFG_STR("extraargs", "", CFGF_NONE),
CFG_STR("compression", "gzip", CFGF_NONE),
CFG_STR("block-size", "4096", CFGF_NONE),
CFG_END()
};
struct image_handler squashfs_handler = {
.type = "squashfs",
.generate = squash_generate,
.opts = squash_opts,
};