From 04fbcc63ebf5718608f199eb6b09061cd32283c3 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 28 Sep 2011 14:39:31 +0100 Subject: [PATCH] New API: set-smp, get-smp These calls allow you to change the number of virtual CPUs assigned to the appliance. This also adds a --smp option to virt-rescue. --- generator/generator_actions.ml | 16 ++++++++++++++++ rescue/virt-rescue.c | 16 ++++++++++++++++ rescue/virt-rescue.pod | 4 ++++ src/guestfs-internal.h | 2 ++ src/guestfs.c | 21 +++++++++++++++++++++ src/launch.c | 6 ++++++ test-tool/test-tool.c | 1 + 7 files changed, 66 insertions(+) diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index da49716..8d03275 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -1549,6 +1549,22 @@ C<^C> to kill the subprocess."); "\ This returns the process group flag."); + ("set_smp", (RErr, [Int "smp"], []), -1, [FishAlias "smp"], + [], + "set number of virtual CPUs in appliance", + "\ +Change the number of virtual CPUs assigned to the appliance. The +default is C<1>. Increasing this may improve performance, though +often it has no effect. + +This function must be called before C."); + + ("get_smp", (RInt "smp", [], []), -1, [], + [], + "get number of virtual CPUs in appliance", + "\ +This returns the number of virtual CPUs assigned to the appliance."); + ] (* daemon_functions are any functions which cause some action diff --git a/rescue/virt-rescue.c b/rescue/virt-rescue.c index 7c8a57b..7ad39b5 100644 --- a/rescue/virt-rescue.c +++ b/rescue/virt-rescue.c @@ -77,6 +77,7 @@ usage (int status) " --network Enable network\n" " -r|--ro Access read-only\n" " --selinux Enable SELinux\n" + " --smp N Enable SMP with N >= 2 virtual CPUs\n" " -v|--verbose Verbose messages\n" " -V|--version Display version and exit\n" " -w|--rw Mount read-write\n" @@ -115,6 +116,7 @@ main (int argc, char *argv[]) { "ro", 0, 0, 'r' }, { "rw", 0, 0, 'w' }, { "selinux", 0, 0, 0 }, + { "smp", 1, 0, 0 }, { "verbose", 0, 0, 'v' }, { "version", 0, 0, 'V' }, { 0, 0, 0, 0 } @@ -128,6 +130,7 @@ main (int argc, char *argv[]) const char *append = NULL; char *append_full; int memsize = 0; + int smp = 0; g = guestfs_create (); if (g == NULL) { @@ -154,6 +157,17 @@ main (int argc, char *argv[]) format = NULL; else format = optarg; + } else if (STREQ (long_options[option_index].name, "smp")) { + if (sscanf (optarg, "%u", &smp) != 1) { + fprintf (stderr, _("%s: could not parse --smp parameter '%s'\n"), + program_name, optarg); + exit (EXIT_FAILURE); + } + if (smp < 1) { + fprintf (stderr, _("%s: --smp parameter '%s' should be >= 1\n"), + program_name, optarg); + exit (EXIT_FAILURE); + } } else { fprintf (stderr, _("%s: unknown long option: %s (%d)\n"), program_name, long_options[option_index].name, option_index); @@ -270,6 +284,8 @@ main (int argc, char *argv[]) guestfs_set_memsize (g, memsize); if (network) guestfs_set_network (g, 1); + if (smp >= 1) + guestfs_set_smp (g, smp); /* Kernel command line must include guestfs_rescue=1 (see * appliance/init) as well as other options. diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod index 81a24cf..e25b6ed 100755 --- a/rescue/virt-rescue.pod +++ b/rescue/virt-rescue.pod @@ -175,6 +175,10 @@ See also L. Enable SELinux in the rescue appliance. You should read L before using this option. +=item B<--smp> N + +Enable N E 2 virtual CPUs in the rescue appliance. + =item B<-v> =item B<--verbose> diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index c0a2be4..494003e 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -170,6 +170,8 @@ struct guestfs_h int pgroup; /* Create process group for children? */ + int smp; /* If > 1, -smp flag passed to qemu. */ + char *last_error; int last_errnum; /* errno, or 0 if there was no errno */ diff --git a/src/guestfs.c b/src/guestfs.c index 002418a..f7ad967 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -144,6 +144,9 @@ guestfs_create (void) */ g->msg_next_serial = 0x00123400; + /* Default is uniprocessor appliance. */ + g->smp = 1; + /* Link the handles onto a global list. */ gl_lock_lock (handles_lock); g->next = handles; @@ -814,6 +817,24 @@ guestfs__get_pgroup (guestfs_h *g) return g->pgroup; } +int +guestfs__set_smp (guestfs_h *g, int v) +{ + if (v >= 1) { + g->smp = v; + return 0; + } else { + error (g, "invalid smp parameter: %d", v); + return -1; + } +} + +int +guestfs__get_smp (guestfs_h *g) +{ + return g->smp; +} + /* Note the private data area is allocated lazily, since the vast * majority of callers will never use it. This means g->pda is * likely to be NULL. diff --git a/src/launch.c b/src/launch.c index 80eadef..b0f5b39 100644 --- a/src/launch.c +++ b/src/launch.c @@ -555,6 +555,12 @@ launch_appliance (guestfs_h *g) add_cmdline (g, "-nographic"); + if (g->smp > 1) { + snprintf (buf, sizeof buf, "%d", g->smp); + add_cmdline (g, "-smp"); + add_cmdline (g, buf); + } + snprintf (buf, sizeof buf, "%d", g->memsize); add_cmdline (g, "-m"); add_cmdline (g, buf); diff --git a/test-tool/test-tool.c b/test-tool/test-tool.c index 55e503f..e058dbc 100644 --- a/test-tool/test-tool.c +++ b/test-tool/test-tool.c @@ -206,6 +206,7 @@ main (int argc, char *argv[]) printf ("guestfs_get_recovery_proc: %d\n", guestfs_get_recovery_proc (g)); printf ("guestfs_get_selinux: %d\n", guestfs_get_selinux (g)); + printf ("guestfs_get_smp: %d\n", guestfs_get_smp (g)); printf ("guestfs_get_trace: %d\n", guestfs_get_trace (g)); printf ("guestfs_get_verbose: %d\n", guestfs_get_verbose (g)); -- 1.8.3.1