Introduce a checkbox that lets the user choose between options (a) and
(b), as outlined in one of the previous patches in this series. When the
checkbox is ticked -- that is, the fully populated physical topology is
copied --, make the VCPU count text entry insensitive, and overwrite its
contents with the value calculated from the physical topology. Upon
unticking the checkbox, restore the last manual entry.
The VCPU limit warning applies automatically when the checkbox is toggled,
because when the VCPU count text entry is programmatically modified, the
entry emits the "changed" signal, and that chains to
vcpus_or_memory_check_callback().
However, in show_conversion_dialog(), we need to handle the case of option
(a) potentially becoming the default. In that case we have to render the
VCPU count text entry insensitive immediately, and overwrite its contents
(set originally from the *online* logical processor count, or on the
kernel command line) with the full population count derived from the
topology. For this, call vcpu_topo_toggled() manually. This in turn may
(as it should) trigger the VCPU limit warning at once, handled by the
vcpus_or_memory_check_callback() call right after.
Bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=1590721
Signed-off-by: Laszlo Ersek <lersek(a)redhat.com>
---
gui.c | 47 +++++++++++++++++++-
1 file changed, 45 insertions(+), 2 deletions(-)
diff --git a/gui.c b/gui.c
index eeb15a096351..b734f1bda8be 100644
--- a/gui.c
+++ b/gui.c
@@ -121,12 +121,13 @@ static GtkWidget *conn_dlg,
/* The conversion dialog. */
static GtkWidget *conv_dlg,
- *guestname_entry, *vcpus_entry, *memory_entry,
+ *guestname_entry, *vcpu_topo, *vcpus_entry, *memory_entry,
*vcpus_warning, *memory_warning, *target_warning_label,
*o_combo, *oc_entry, *os_entry, *of_entry, *oa_combo,
*info_label,
*disks_list, *removable_list, *interfaces_list,
*start_button;
+static int vcpus_entry_when_last_sensitive;
/* The running dialog which is displayed when virt-v2v is running. */
static GtkWidget *run_dlg,
@@ -690,8 +691,10 @@ static void set_removable_from_ui (struct config *);
static void set_interfaces_from_ui (struct config *);
static void conversion_back_clicked (GtkWidget *w, gpointer data);
static void start_conversion_clicked (GtkWidget *w, gpointer data);
+static void vcpu_topo_toggled (GtkWidget *w, gpointer data);
static void vcpus_or_memory_check_callback (GtkWidget *w, gpointer data);
static void notify_ui_callback (int type, const char *data);
+static bool get_dense_topo_from_conv_dlg (void);
static int get_vcpus_from_conv_dlg (void);
static uint64_t get_memory_from_conv_dlg (void);
@@ -756,7 +759,7 @@ create_conversion_dialog (struct config *config)
vbox_new (target_vbox, FALSE, 1);
- table_new (target_tbl, 3, 3);
+ table_new (target_tbl, 4, 3);
row = 0;
guestname_label = gtk_label_new_with_mnemonic (_("_Name:"));
table_attach (target_tbl, guestname_label,
@@ -769,6 +772,13 @@ create_conversion_dialog (struct config *config)
table_attach (target_tbl, guestname_entry,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
+ row++;
+ vcpu_topo = gtk_check_button_new_with_mnemonic (
+ _("Copy fully populated _pCPU topology"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (vcpu_topo),
+ config->vcpu.dense_topo);
+ table_attach (target_tbl, vcpu_topo, 0, 2, row, GTK_FILL, GTK_FILL, 1, 1);
+
row++;
vcpus_label = gtk_label_new_with_mnemonic (_("# _vCPUs:"));
table_attach (target_tbl, vcpus_label,
@@ -778,6 +788,7 @@ create_conversion_dialog (struct config *config)
gtk_label_set_mnemonic_widget (GTK_LABEL (vcpus_label), vcpus_entry);
snprintf (vcpus_str, sizeof vcpus_str, "%d", config->vcpu.cores);
gtk_entry_set_text (GTK_ENTRY (vcpus_entry), vcpus_str);
+ vcpus_entry_when_last_sensitive = config->vcpu.cores;
table_attach (target_tbl, vcpus_entry,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
vcpus_warning = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
@@ -970,6 +981,8 @@ create_conversion_dialog (struct config *config)
G_CALLBACK (conversion_back_clicked), NULL);
g_signal_connect (G_OBJECT (start_button), "clicked",
G_CALLBACK (start_conversion_clicked), config);
+ g_signal_connect (G_OBJECT (vcpu_topo), "toggled",
+ G_CALLBACK (vcpu_topo_toggled), NULL);
g_signal_connect (G_OBJECT (vcpus_entry), "changed",
G_CALLBACK (vcpus_or_memory_check_callback), NULL);
g_signal_connect (G_OBJECT (memory_entry), "changed",
@@ -988,6 +1001,7 @@ show_conversion_dialog (void)
/* Show the conversion dialog. */
gtk_widget_show_all (conv_dlg);
+ vcpu_topo_toggled (NULL, NULL);
vcpus_or_memory_check_callback (NULL, NULL);
/* output_drivers may have been updated, so repopulate o_combo. */
@@ -1534,6 +1548,28 @@ concat_warning (char *warning, const char *fs, ...)
return warning;
}
+static void
+vcpu_topo_toggled (GtkWidget *w, gpointer data)
+{
+ bool dense_topo;
+ unsigned vcpus;
+ char vcpus_str[64];
+
+ dense_topo = get_dense_topo_from_conv_dlg ();
+ if (dense_topo) {
+ struct cpu_topo topo;
+
+ get_cpu_topology (&topo);
+ vcpus = topo.sockets * topo.cores * topo.threads;
+ vcpus_entry_when_last_sensitive = get_vcpus_from_conv_dlg ();
+ } else
+ vcpus = vcpus_entry_when_last_sensitive;
+
+ snprintf (vcpus_str, sizeof vcpus_str, "%u", vcpus);
+ gtk_entry_set_text (GTK_ENTRY (vcpus_entry), vcpus_str);
+ gtk_widget_set_sensitive (vcpus_entry, !dense_topo);
+}
+
/**
* Display a warning if the vCPUs or memory is outside the supported
* range (
L<https://bugzilla.redhat.com/823758>).
@@ -1577,6 +1613,12 @@ vcpus_or_memory_check_callback (GtkWidget *w, gpointer data)
gtk_label_set_text (GTK_LABEL (target_warning_label), "");
}
+static bool
+get_dense_topo_from_conv_dlg (void)
+{
+ return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (vcpu_topo));
+}
+
static int
get_vcpus_from_conv_dlg (void)
{
@@ -2025,6 +2067,7 @@ start_conversion_clicked (GtkWidget *w, gpointer data)
return;
}
+ config->vcpu.dense_topo = get_dense_topo_from_conv_dlg ();
config->vcpu.cores = get_vcpus_from_conv_dlg ();
config->memory = get_memory_from_conv_dlg ();