cli: fix crash when edited profile was removed by another client (rh #1011942)
Use g_weak_ref_get() that either returns an object with reference increment or returns NULL. That fixes the problem. However, in the long run we should rework the editor loop trying to merge that with GMainLoop, which could help for various issues. https://bugzilla.redhat.com/show_bug.cgi?id=1011942
This commit is contained in:
@@ -6112,6 +6112,21 @@ editor_show_status_line (NMConnection *connection, gboolean dirty)
|
|||||||
con_type, con_id, con_uuid, dirty ? _("yes") : _("no"));
|
con_type, con_id, con_uuid, dirty ? _("yes") : _("no"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
refresh_remote_connection (GWeakRef *weak, NMRemoteConnection **remote)
|
||||||
|
{
|
||||||
|
gboolean previous;
|
||||||
|
|
||||||
|
g_return_val_if_fail (remote != NULL, FALSE);
|
||||||
|
|
||||||
|
previous = (*remote != NULL);
|
||||||
|
if (*remote)
|
||||||
|
g_object_unref (*remote);
|
||||||
|
*remote = g_weak_ref_get (weak);
|
||||||
|
|
||||||
|
return (previous && !*remote);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Submenu for detailed property editing
|
* Submenu for detailed property editing
|
||||||
* Return: TRUE - continue; FALSE - should quit
|
* Return: TRUE - continue; FALSE - should quit
|
||||||
@@ -6119,7 +6134,8 @@ editor_show_status_line (NMConnection *connection, gboolean dirty)
|
|||||||
static gboolean
|
static gboolean
|
||||||
property_edit_submenu (NmCli *nmc,
|
property_edit_submenu (NmCli *nmc,
|
||||||
NMConnection *connection,
|
NMConnection *connection,
|
||||||
NMRemoteConnection *rem_con,
|
NMRemoteConnection **rem_con,
|
||||||
|
GWeakRef *rem_con_weak,
|
||||||
NMSetting *curr_setting,
|
NMSetting *curr_setting,
|
||||||
const char *prop_name)
|
const char *prop_name)
|
||||||
{
|
{
|
||||||
@@ -6132,6 +6148,7 @@ property_edit_submenu (NmCli *nmc,
|
|||||||
char *prompt;
|
char *prompt;
|
||||||
gboolean dirty;
|
gboolean dirty;
|
||||||
GValue prop_g_value = G_VALUE_INIT;
|
GValue prop_g_value = G_VALUE_INIT;
|
||||||
|
gboolean removed;
|
||||||
|
|
||||||
prompt = nmc_colorize (nmc->editor_prompt_color, "nmcli %s.%s> ",
|
prompt = nmc_colorize (nmc->editor_prompt_color, "nmcli %s.%s> ",
|
||||||
nm_setting_get_name (curr_setting), prop_name);
|
nm_setting_get_name (curr_setting), prop_name);
|
||||||
@@ -6140,9 +6157,15 @@ property_edit_submenu (NmCli *nmc,
|
|||||||
char *cmd_property_user;
|
char *cmd_property_user;
|
||||||
char *cmd_property_arg;
|
char *cmd_property_arg;
|
||||||
|
|
||||||
|
/* Get the remote connection again, it may have disapeared */
|
||||||
|
removed = refresh_remote_connection (rem_con_weak, rem_con);
|
||||||
|
if (removed)
|
||||||
|
printf (_("The connection profile has been removed from another client. "
|
||||||
|
"You may type 'save' in the main menu to restore it.\n"));
|
||||||
|
|
||||||
/* Connection is dirty? (not saved or differs from the saved) */
|
/* Connection is dirty? (not saved or differs from the saved) */
|
||||||
dirty = !nm_connection_compare (connection,
|
dirty = !nm_connection_compare (connection,
|
||||||
rem_con ? NM_CONNECTION (rem_con) : NULL,
|
*rem_con ? NM_CONNECTION (*rem_con) : NULL,
|
||||||
NM_SETTING_COMPARE_FLAG_EXACT);
|
NM_SETTING_COMPARE_FLAG_EXACT);
|
||||||
|
|
||||||
if (nmc->editor_status_line)
|
if (nmc->editor_status_line)
|
||||||
@@ -6507,7 +6530,10 @@ menu_switch_to_level1 (NmcEditorMenuContext *menu_ctx,
|
|||||||
static gboolean
|
static gboolean
|
||||||
editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_type)
|
editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_type)
|
||||||
{
|
{
|
||||||
NMRemoteConnection *rem_con = NULL;
|
NMRemoteConnection *rem_con;
|
||||||
|
NMRemoteConnection *con_tmp;
|
||||||
|
GWeakRef weak = { { NULL } };
|
||||||
|
gboolean removed;
|
||||||
NmcEditorMainCmd cmd;
|
NmcEditorMainCmd cmd;
|
||||||
char *cmd_user;
|
char *cmd_user;
|
||||||
gboolean cmd_loop = TRUE;
|
gboolean cmd_loop = TRUE;
|
||||||
@@ -6531,11 +6557,13 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||||||
menu_ctx.valid_props = NULL;
|
menu_ctx.valid_props = NULL;
|
||||||
menu_ctx.valid_props_str = NULL;
|
menu_ctx.valid_props_str = NULL;
|
||||||
|
|
||||||
while (cmd_loop) {
|
/* Get remote connection */
|
||||||
if (!rem_con)
|
con_tmp = nm_remote_settings_get_connection_by_uuid (nmc->system_settings,
|
||||||
rem_con = nm_remote_settings_get_connection_by_uuid (nmc->system_settings,
|
|
||||||
nm_connection_get_uuid (connection));
|
nm_connection_get_uuid (connection));
|
||||||
|
g_weak_ref_init (&weak, con_tmp);
|
||||||
|
rem_con = g_weak_ref_get (&weak);
|
||||||
|
|
||||||
|
while (cmd_loop) {
|
||||||
/* Connection is dirty? (not saved or differs from the saved) */
|
/* Connection is dirty? (not saved or differs from the saved) */
|
||||||
dirty = !nm_connection_compare (connection,
|
dirty = !nm_connection_compare (connection,
|
||||||
rem_con ? NM_CONNECTION (rem_con) : NULL,
|
rem_con ? NM_CONNECTION (rem_con) : NULL,
|
||||||
@@ -6543,7 +6571,15 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||||||
if (nmc->editor_status_line)
|
if (nmc->editor_status_line)
|
||||||
editor_show_status_line (connection, dirty);
|
editor_show_status_line (connection, dirty);
|
||||||
|
|
||||||
|
/* Read user input */
|
||||||
cmd_user = readline_x (menu_ctx.main_prompt);
|
cmd_user = readline_x (menu_ctx.main_prompt);
|
||||||
|
|
||||||
|
/* Get the remote connection again, it may have disapeared */
|
||||||
|
removed = refresh_remote_connection (&weak, &rem_con);
|
||||||
|
if (removed)
|
||||||
|
printf (_("The connection profile has been removed from another client. "
|
||||||
|
"You may type 'save' to restore it.\n"));
|
||||||
|
|
||||||
if (!cmd_user || *cmd_user == '\0')
|
if (!cmd_user || *cmd_user == '\0')
|
||||||
continue;
|
continue;
|
||||||
cmd = parse_editor_main_cmd (g_strstrip (cmd_user), &cmd_arg);
|
cmd = parse_editor_main_cmd (g_strstrip (cmd_user), &cmd_arg);
|
||||||
@@ -6693,7 +6729,12 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* submenu - level 2 - editing properties */
|
/* submenu - level 2 - editing properties */
|
||||||
cmd_loop = property_edit_submenu (nmc, connection, rem_con, menu_ctx.curr_setting, prop_name);
|
cmd_loop = property_edit_submenu (nmc,
|
||||||
|
connection,
|
||||||
|
&rem_con,
|
||||||
|
&weak,
|
||||||
|
menu_ctx.curr_setting,
|
||||||
|
prop_name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -6933,18 +6974,19 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||||||
|
|
||||||
g_error_free (nmc_editor_error);
|
g_error_free (nmc_editor_error);
|
||||||
} else {
|
} else {
|
||||||
NMRemoteConnection *con_tmp;
|
|
||||||
|
|
||||||
printf (_("Connection '%s' (%s) successfully saved.\n"),
|
printf (_("Connection '%s' (%s) successfully saved.\n"),
|
||||||
nm_connection_get_id (connection),
|
nm_connection_get_id (connection),
|
||||||
nm_connection_get_uuid (connection));
|
nm_connection_get_uuid (connection));
|
||||||
|
|
||||||
|
con_tmp = nm_remote_settings_get_connection_by_uuid (nmc->system_settings,
|
||||||
|
nm_connection_get_uuid (connection));
|
||||||
|
g_weak_ref_set (&weak, con_tmp);
|
||||||
|
refresh_remote_connection (&weak, &rem_con);
|
||||||
|
|
||||||
/* Replace local connection with the remote one to be sure they are equal.
|
/* Replace local connection with the remote one to be sure they are equal.
|
||||||
* This mitigates problems with plugins not preserving some properties or
|
* This mitigates problems with plugins not preserving some properties or
|
||||||
* adding ipv{4,6} settings when not present.
|
* adding ipv{4,6} settings when not present.
|
||||||
*/
|
*/
|
||||||
con_tmp = nm_remote_settings_get_connection_by_uuid (nmc->system_settings,
|
|
||||||
nm_connection_get_uuid (connection));
|
|
||||||
if (con_tmp) {
|
if (con_tmp) {
|
||||||
char *s_name = NULL;
|
char *s_name = NULL;
|
||||||
if (menu_ctx.curr_setting)
|
if (menu_ctx.curr_setting)
|
||||||
@@ -7128,6 +7170,9 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||||||
g_free (menu_ctx.main_prompt);
|
g_free (menu_ctx.main_prompt);
|
||||||
g_strfreev (menu_ctx.valid_props);
|
g_strfreev (menu_ctx.valid_props);
|
||||||
g_free (menu_ctx.valid_props_str);
|
g_free (menu_ctx.valid_props_str);
|
||||||
|
if (rem_con)
|
||||||
|
g_object_unref (rem_con);
|
||||||
|
g_weak_ref_clear (&weak);
|
||||||
|
|
||||||
/* Save history file */
|
/* Save history file */
|
||||||
save_history_cmds (nm_connection_get_uuid (connection));
|
save_history_cmds (nm_connection_get_uuid (connection));
|
||||||
|
Reference in New Issue
Block a user