From: "Daniel P. Berrange" <berra...@redhat.com> The sheepdog driver declares an instance of BDRVSheepdogState in the stack. This struct is 4 MB in size. While the default Linux stack size may be 10 MB, we should not assume that since QEMU needs to be portable to other OS.
block/sheepdog.c: In function ‘sd_create’: block/sheepdog.c:1240:1: error: the frame size of 4199888 bytes is larger than 131072 bytes [-Werror=frame-larger-than=] * block/sheepdog.c: Allow BDRVSheepdogState on the heap instead of stack * configure: Add -Wframe-larger-than to validate stack size does not exceed 128k Signed-off-by: Daniel P. Berrange <berra...@redhat.com> --- block/sheepdog.c | 43 ++++++++++++++++++++++++++----------------- configure | 1 + 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/block/sheepdog.c b/block/sheepdog.c index 00276f6f..ff6f3d2 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -1163,20 +1163,22 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) uint32_t vid = 0, base_vid = 0; int64_t vdi_size = 0; char *backing_file = NULL; - BDRVSheepdogState s; + BDRVSheepdogState *s1; char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN]; uint32_t snapid; int prealloc = 0; const char *vdiname; + int rv = -EINVAL; + + s1 = g_new0(BDRVSheepdogState, 1); strstart(filename, "sheepdog:", &vdiname); - memset(&s, 0, sizeof(s)); memset(vdi, 0, sizeof(vdi)); memset(tag, 0, sizeof(tag)); - if (parse_vdiname(&s, vdiname, vdi, &snapid, tag) < 0) { + if (parse_vdiname(s1, vdiname, vdi, &snapid, tag) < 0) { error_report("invalid filename"); - return -EINVAL; + goto cleanup; } while (options && options->name) { @@ -1192,7 +1194,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) } else { error_report("Invalid preallocation mode: '%s'", options->value.s); - return -EINVAL; + goto cleanup; } } options++; @@ -1200,43 +1202,50 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) if (vdi_size > SD_MAX_VDI_SIZE) { error_report("too big image size"); - return -EINVAL; + goto cleanup; } if (backing_file) { BlockDriverState *bs; - BDRVSheepdogState *s; + BDRVSheepdogState *s2; BlockDriver *drv; /* Currently, only Sheepdog backing image is supported. */ drv = bdrv_find_protocol(backing_file); if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { error_report("backing_file must be a sheepdog image"); - return -EINVAL; + goto cleanup; } ret = bdrv_file_open(&bs, backing_file, 0); - if (ret < 0) - return -EIO; + if (ret < 0) { + rv = -EIO; + goto cleanup; + } - s = bs->opaque; + s2 = bs->opaque; - if (!is_snapshot(&s->inode)) { + if (!is_snapshot(&s2->inode)) { error_report("cannot clone from a non snapshot vdi"); bdrv_delete(bs); - return -EINVAL; + goto cleanup; } - base_vid = s->inode.vdi_id; + base_vid = s2->inode.vdi_id; bdrv_delete(bs); } - ret = do_sd_create(vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port); + ret = do_sd_create(vdi, vdi_size, base_vid, &vid, 0, s1->addr, s1->port); if (!prealloc || ret) { - return ret; + rv = ret; + goto cleanup; } - return sd_prealloc(filename); + rv = sd_prealloc(filename); + + cleanup: + g_free(s1); + return rv; } static void sd_close(BlockDriverState *bs) diff --git a/configure b/configure index 44b28c8..28b5dd5 100755 --- a/configure +++ b/configure @@ -1165,6 +1165,7 @@ gcc_flags="$gcc_flags -Wmissing-include-dirs" gcc_flags="$gcc_flags -Wempty-body" gcc_flags="$gcc_flags -Wnested-externs" gcc_flags="$gcc_flags -Wendif-labels" +gcc_flags="$gcc_flags -Wframe-larger-than=131072" cat > $TMPC << EOF int main(void) { return 0; } EOF -- 1.7.7.6