From: Richard W.M. Jones Date: Thu, 23 Apr 2009 18:23:33 +0000 (+0100) Subject: Reduce the amount of memory allocated to guests based on some testing. X-Git-Tag: 1.0.11~3 X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=commitdiff_plain;h=5f8c46db05966a6e31b696d629fd3f74e4fb6c71 Reduce the amount of memory allocated to guests based on some testing. --- diff --git a/configure.ac b/configure.ac index 46aac94..02d983c 100644 --- a/configure.ac +++ b/configure.ac @@ -35,6 +35,9 @@ AM_PROG_CC_C_O dnl Check support for 64 bit file offsets. AC_SYS_LARGEFILE +dnl Check sizeof long. +AC_CHECK_SIZEOF([long]) + dnl Headers. AC_CHECK_HEADERS([errno.h sys/types.h sys/un.h sys/wait.h sys/socket.h]) diff --git a/src/guestfs.c b/src/guestfs.c index dec9a1b..4dc8dec 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -29,7 +29,9 @@ #include #include #include +#include #include + #include #include @@ -632,7 +634,7 @@ int guestfs_launch (guestfs_h *g) { static const char *dir_template = "/tmp/libguestfsXXXXXX"; - int r, i, len, pmore; + int r, i, len, pmore, memsize; int wfd[2], rfd[2]; int tries; const char *kernel_name = "vmlinuz." REPO "." host_cpu; @@ -641,6 +643,7 @@ guestfs_launch (guestfs_h *g) char *kernel = NULL, *initrd = NULL; char unixsock[256]; struct sockaddr_un addr; + struct stat statbuf; /* Configured? */ if (!g->cmdline) { @@ -700,6 +703,40 @@ guestfs_launch (guestfs_h *g) goto cleanup0; } + /* Choose a suitable memory size (in MB). This is more art + * than science, but you can help by doing + * ./configure --enable-debug-command + * and then running: + * debug sh free + * debug mem '' + * and seeing how much free memory is left for particular + * configurations. + * + * It's also helpful to report both the compressed and uncompressed + * size of the initramfs (ls -lh initramfs*.img; du -sh initramfs). + * + * XXX KVM virtio balloon driver? + */ + if (stat (initrd, &statbuf) != -1) { + /* Approximate size of the initramfs after it is decompressed + * in kernel memory. The compression factor is ~2.5-3. + */ + memsize = 3 * statbuf.st_size / 1024 / 1024; + + /* Approximate size used by the kernel. */ + memsize += 10; + + /* Want to give userspace some room, so: */ + memsize += 128; + +#if AC_SIZEOF_LONG == 8 + /* On 64 bit, assume some overhead. */ + memsize += 32; +#endif + } else + memsize = 512; + + /* Make the temporary directory containing the socket. */ if (!g->tmpdir) { g->tmpdir = safe_strdup (g, dir_template); @@ -730,6 +767,7 @@ guestfs_launch (guestfs_h *g) if (r == 0) { /* Child (qemu). */ char vmchannel[256]; char append[256]; + char memsize_str[256]; /* Set up the full command line. Do this in the subprocess so we * don't need to worry about cleaning up. @@ -747,8 +785,10 @@ guestfs_launch (guestfs_h *g) VMCHANNEL_ADDR, VMCHANNEL_PORT, g->verbose ? " guestfs_verbose=1" : ""); + snprintf (memsize_str, sizeof memsize_str, "%d", memsize); + add_cmdline (g, "-m"); - add_cmdline (g, "384"); /* XXX Choose best size. */ + add_cmdline (g, memsize_str); #if 0 add_cmdline (g, "-no-kqemu"); /* Avoids a warning. */ #endif