[gnome-ostree] Dynamically choose memory for QEMU
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-ostree] Dynamically choose memory for QEMU
- Date: Fri, 7 Jun 2013 16:31:58 +0000 (UTC)
commit 69300cd6c11b37677721aac2e6b342cb24d669fe
Author: Colin Walters <walters verbum org>
Date: Mon Jun 3 19:35:11 2013 -0400
Dynamically choose memory for QEMU
integrationtest was often triggering OOM since we're running 16 cores,
but only 768M. Let's scale resources to the machine more slightly
more intelligently.
But this is still a hack; we really need a global view of resources
across all tasks.
src/js/libqa.js | 81 +++++++++++++++++++++++++++++++--------------
src/js/tasks/testbase.js | 6 +---
2 files changed, 57 insertions(+), 30 deletions(-)
---
diff --git a/src/js/libqa.js b/src/js/libqa.js
index f975eec..6d699c5 100644
--- a/src/js/libqa.js
+++ b/src/js/libqa.js
@@ -25,10 +25,62 @@ const ProcUtil = imports.procutil;
const GuestFish = imports.guestfish;
const DEFAULT_GF_PARTITION_OPTS = ['-m', '/dev/sda3', '-m', '/dev/sda1:/boot'];
-const DEFAULT_QEMU_OPTS = ['-vga', 'std', '-m', '768M',
- '-usb', '-usbdevice', 'tablet',
- '-net', 'none'];
+function linuxGetMemTotalMb() {
+ let [success,contents] = GLib.file_get_contents('/proc/meminfo');
+ let contentLines = contents.toString().split(/\n/);
+ for (let i = 0; contentLines.length; i++) {
+ let line = contentLines[i];
+ if (line.indexOf('MemTotal:') == 0) {
+ return parseInt(/([0-9]+) kB/.exec(line)[1]) / 1024;
+ }
+ }
+ throw new Error("Couldn't determine total memory from /proc/meminfo");
+}
+
+function getQemuPath() {
+ let fallbackPaths = ['/usr/libexec/qemu-kvm']
+ let qemuPathString = GLib.find_program_in_path('qemu-kvm');
+ qemuPathString = GLib.find_program_in_path('qemu-kvm');
+ if (!qemuPathString)
+ qemuPathString = GLib.find_program_in_path('kvm');
+ if (qemuPathString == null) {
+ for (let i = 0; i < fallbackPaths.length; i++) {
+ let path = Gio.File.new_for_path(fallbackPaths[i]);
+ if (!path.query_exists(null))
+ continue;
+ qemuPathString = path.get_path();
+ }
+ }
+ if (qemuPathString == null) {
+ throw new Error("Unable to find qemu-kvm");
+ }
+ return qemuPathString;
+}
+
+function getDefaultQemuOptions(params) {
+ params = Params.parse(params, { parallel: false });
+ let args = [getQemuPath(), '-vga', 'std', '-usb', '-usbdevice', 'tablet', '-net', 'none'];
+
+ let systemMemoryMb = linuxGetMemTotalMb();
+ let minimumGuestMemoryMb = 768;
+ let maximumGuestMemoryMb = 4 * 1024;
+ // As a guess, use 1/4 of host memory, rounded up to the nearest
+ // multiple of 128M; subject to above constraints as a lame
+ // default...we need global coordination here.
+ let guestMemoryGuessMb = Math.floor(systemMemoryMb / 4 / 128) * 128;
+ let guestMemory = Math.floor(Math.max(minimumGuestMemoryMb,
+ Math.min(maximumGuestMemoryMb,
+ guestMemoryGuessMb)));
+ args.push.apply(args, ['-m', ''+guestMemory]);
+
+ if (params.parallel) {
+ let nCores = Math.min(16, GLib.get_num_processors());
+ args.push.apply(args, ['-smp', ''+nCores]);
+ }
+
+ return args;
+}
function newReadWriteMount(diskpath, cancellable) {
let mntdir = Gio.File.new_for_path('mnt');
@@ -95,26 +147,6 @@ function copyDisk(srcpath, destpath, cancellable) {
destpath.get_path()], cancellable);
}
-function getQemuPath() {
- let fallbackPaths = ['/usr/libexec/qemu-kvm']
- let qemuPathString = GLib.find_program_in_path('qemu-kvm');
- qemuPathString = GLib.find_program_in_path('qemu-kvm');
- if (!qemuPathString)
- qemuPathString = GLib.find_program_in_path('kvm');
- if (qemuPathString == null) {
- for (let i = 0; i < fallbackPaths.length; i++) {
- let path = Gio.File.new_for_path(fallbackPaths[i]);
- if (!path.query_exists(null))
- continue;
- qemuPathString = path.get_path();
- }
- }
- if (qemuPathString == null) {
- throw new Error("Unable to find qemu-kvm");
- }
- return qemuPathString;
-}
-
function getDeployDirs(mntdir, osname) {
let basedir = mntdir.resolve_relative_path('ostree/deploy/' + osname);
return [basedir.get_child('current'),
@@ -315,8 +347,7 @@ LABEL %s\n\
}
function bootloaderInstall(diskpath, workdir, osname, cancellable) {
- let qemuArgs = [getQemuPath()];
- qemuArgs.push.apply(qemuArgs, DEFAULT_QEMU_OPTS);
+ let qemuArgs = getDefaultQemuOptions();
let tmpKernelPath = workdir.get_child('kernel.img');
let tmpInitrdPath = workdir.get_child('initrd.img');
diff --git a/src/js/tasks/testbase.js b/src/js/tasks/testbase.js
index 64ec6ec..03abd39 100644
--- a/src/js/tasks/testbase.js
+++ b/src/js/tasks/testbase.js
@@ -260,12 +260,8 @@ const TestOneDisk = new Lang.Class({
else
this._diskArch = 'i686';
- let qemuArgs = [LibQA.getQemuPath()];
- qemuArgs.push.apply(qemuArgs, LibQA.DEFAULT_QEMU_OPTS);
+ let qemuArgs = LibQA.getDefaultQemuOptions({ parallel: true });
- let nCores = Math.min(16, GLib.get_num_processors());
- qemuArgs.push.apply(qemuArgs, ['-smp', ''+nCores]);
-
let diskClone = subworkdir.get_child('testoverlay-' + diskPath.get_basename());
GSystem.shutil_rm_rf(diskClone, cancellable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]