mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-02 03:00:37 +01:00
ifcfg-rh: split function to write connection to disk
This commit is contained in:
parent
7ed57f2286
commit
4af4e92646
2 changed files with 181 additions and 76 deletions
|
|
@ -173,7 +173,7 @@ utils_get_extra_path (const char *parent, const char *tag)
|
|||
|
||||
dirname = g_path_get_dirname (parent);
|
||||
if (!dirname)
|
||||
return NULL;
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
name = utils_get_ifcfg_name (parent, FALSE);
|
||||
if (name) {
|
||||
|
|
|
|||
|
|
@ -688,7 +688,7 @@ write_wireless_security_setting (NMConnection *connection,
|
|||
key = ascii_key;
|
||||
}
|
||||
} else {
|
||||
_LOGW ("invalid WEP key '%s'", key);
|
||||
g_warn_if_reached ();
|
||||
key_valid = FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1921,7 +1921,7 @@ get_route_attributes_string (NMIPRoute *route, int family)
|
|||
|
||||
g_string_append_printf (str, "%s %s", arg, g_variant_get_string (attr, NULL));
|
||||
} else {
|
||||
_LOGW ("unknown route option '%s'", names[i]);
|
||||
g_warn_if_reached ();
|
||||
continue;
|
||||
}
|
||||
if (names[i + 1])
|
||||
|
|
@ -2333,7 +2333,7 @@ write_ip4_setting (NMConnection *connection,
|
|||
}
|
||||
|
||||
static void
|
||||
write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path)
|
||||
write_ip4_aliases (NMConnection *connection, const char *base_ifcfg_path)
|
||||
{
|
||||
NMSettingIPConfig *s_ip4;
|
||||
gs_free char *base_ifcfg_dir = NULL, *base_ifcfg_name = NULL;
|
||||
|
|
@ -2707,42 +2707,44 @@ escape_id (const char *id)
|
|||
return escaped;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
||||
const char *ifcfg_dir,
|
||||
const char *filename,
|
||||
char **out_filename,
|
||||
NMConnection **out_reread,
|
||||
gboolean *out_reread_same,
|
||||
GError **error)
|
||||
static gboolean
|
||||
do_write_construct (NMConnection *connection,
|
||||
const char *ifcfg_dir,
|
||||
const char *filename,
|
||||
shvarFile **out_ifcfg,
|
||||
GHashTable **out_blobs,
|
||||
GHashTable **out_secrets,
|
||||
gboolean *out_route_ignore,
|
||||
shvarFile **out_route_content_svformat,
|
||||
GString **out_route_content,
|
||||
GString **out_route6_content,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingConnection *s_con;
|
||||
nm_auto_shvar_file_close shvarFile *ifcfg = NULL;
|
||||
gs_free char *ifcfg_name = NULL;
|
||||
const char *type;
|
||||
gboolean no_8021x = FALSE;
|
||||
gboolean wired = FALSE;
|
||||
gboolean route_path_is_svformat;
|
||||
gs_free char *route_path = NULL;
|
||||
gs_free char *route6_path = NULL;
|
||||
nm_auto_free_gstring GString *route_content = NULL;
|
||||
gboolean route_ignore = FALSE;
|
||||
const char *type;
|
||||
gs_unref_hashtable GHashTable *blobs = NULL;
|
||||
gs_unref_hashtable GHashTable *secrets = NULL;
|
||||
gboolean wired;
|
||||
gboolean no_8021x;
|
||||
gboolean route_path_is_svformat;
|
||||
gboolean has_complex_routes_v4;
|
||||
gboolean has_complex_routes_v6;
|
||||
gboolean route_ignore;
|
||||
nm_auto_shvar_file_close shvarFile *route_content_svformat = NULL;
|
||||
nm_auto_free_gstring GString *route_content = NULL;
|
||||
nm_auto_free_gstring GString *route6_content = NULL;
|
||||
gs_unref_hashtable GHashTable *secrets = NULL;
|
||||
gs_unref_hashtable GHashTable *blobs = NULL;
|
||||
|
||||
nm_assert (NM_IS_CONNECTION (connection));
|
||||
nm_assert (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS);
|
||||
nm_assert (!out_reread || !*out_reread);
|
||||
|
||||
if (!nms_ifcfg_rh_writer_can_write_connection (connection, error))
|
||||
return FALSE;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
g_assert (s_con);
|
||||
|
||||
if (filename) {
|
||||
/* For existing connections, 'filename' should be full path to ifcfg file */
|
||||
|
|
@ -2751,7 +2753,7 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
return FALSE;
|
||||
|
||||
ifcfg_name = g_strdup (filename);
|
||||
} else {
|
||||
} else if (ifcfg_dir) {
|
||||
char *escaped;
|
||||
|
||||
escaped = escape_id (nm_setting_connection_get_id (s_con));
|
||||
|
|
@ -2782,7 +2784,8 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
}
|
||||
|
||||
ifcfg = svCreateFile (ifcfg_name);
|
||||
}
|
||||
} else
|
||||
ifcfg = svCreateFile ("/tmp/ifcfg-dummy");
|
||||
|
||||
route_path = utils_get_route_path (svFileGetName (ifcfg));
|
||||
if (!route_path) {
|
||||
|
|
@ -2807,6 +2810,8 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
|
||||
secrets = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
|
||||
|
||||
wired = FALSE;
|
||||
no_8021x = FALSE;
|
||||
if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) {
|
||||
// FIXME: can't write PPPoE at this time
|
||||
if (nm_connection_get_setting_pppoe (connection)) {
|
||||
|
|
@ -2896,7 +2901,8 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
return FALSE;
|
||||
}
|
||||
route_ignore = TRUE;
|
||||
}
|
||||
} else
|
||||
route_ignore = FALSE;
|
||||
|
||||
if (!write_ip4_setting (connection,
|
||||
ifcfg,
|
||||
|
|
@ -2916,6 +2922,27 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
|
||||
write_connection_setting (s_con, ifcfg);
|
||||
|
||||
NM_SET_OUT (out_ifcfg, g_steal_pointer (&ifcfg));
|
||||
NM_SET_OUT (out_blobs, g_steal_pointer (&blobs));
|
||||
NM_SET_OUT (out_secrets, g_steal_pointer (&secrets));
|
||||
NM_SET_OUT (out_route_ignore, route_ignore);
|
||||
NM_SET_OUT (out_route_content_svformat, g_steal_pointer (&route_content_svformat));
|
||||
NM_SET_OUT (out_route_content, g_steal_pointer (&route_content));
|
||||
NM_SET_OUT (out_route6_content, g_steal_pointer (&route6_content));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_write_to_disk (NMConnection *connection,
|
||||
shvarFile *ifcfg,
|
||||
GHashTable *blobs,
|
||||
GHashTable *secrets,
|
||||
gboolean route_ignore,
|
||||
shvarFile *route_content_svformat,
|
||||
GString *route_content,
|
||||
GString *route6_content,
|
||||
GError **error)
|
||||
{
|
||||
/* From here on, we persist data to disk. Before, it was all in-memory
|
||||
* only. But we loaded the ifcfg files from disk, and managled our
|
||||
* new settings (in-momory). */
|
||||
|
|
@ -2923,7 +2950,7 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
if (!svWriteFile (ifcfg, 0644, error))
|
||||
return FALSE;
|
||||
|
||||
write_ip4_aliases (connection, ifcfg_name);
|
||||
write_ip4_aliases (connection, svFileGetName (ifcfg));
|
||||
|
||||
if (!write_blobs (blobs, error))
|
||||
return FALSE;
|
||||
|
|
@ -2932,10 +2959,13 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
return FALSE;
|
||||
|
||||
if (!route_ignore) {
|
||||
gs_free char *route_path = utils_get_route_path (svFileGetName (ifcfg));
|
||||
|
||||
if (!route_content && !route_content_svformat)
|
||||
(void) unlink (route_path);
|
||||
else {
|
||||
if (route_path_is_svformat) {
|
||||
nm_assert (route_content_svformat || route_content);
|
||||
if (route_content_svformat) {
|
||||
if (!svWriteFile (route_content_svformat, 0644, error))
|
||||
return FALSE;
|
||||
} else {
|
||||
|
|
@ -2949,6 +2979,8 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
}
|
||||
|
||||
if (!route_ignore) {
|
||||
gs_free char *route6_path = utils_get_route6_path (svFileGetName (ifcfg));
|
||||
|
||||
if (!route6_content)
|
||||
(void) unlink (route6_path);
|
||||
else {
|
||||
|
|
@ -2960,50 +2992,122 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_write_reread (NMConnection *connection,
|
||||
const char *ifcfg_name,
|
||||
NMConnection **out_reread,
|
||||
gboolean *out_reread_same,
|
||||
GError **error)
|
||||
{
|
||||
gs_unref_object NMConnection *reread = NULL;
|
||||
gs_free_error GError *local = NULL;
|
||||
gs_free char *unhandled = NULL;
|
||||
gboolean reread_same = FALSE;
|
||||
|
||||
nm_assert (!out_reread || !*out_reread);
|
||||
|
||||
reread = connection_from_file (ifcfg_name, &unhandled, &local, NULL);
|
||||
|
||||
if (!reread) {
|
||||
g_propagate_error (error, local);
|
||||
local = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
if (unhandled) {
|
||||
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
|
||||
"connection is unhandled");
|
||||
return FALSE;
|
||||
}
|
||||
if (out_reread_same) {
|
||||
if (nm_connection_compare (reread, connection, NM_SETTING_COMPARE_FLAG_EXACT))
|
||||
reread_same = TRUE;
|
||||
|
||||
nm_assert (reread_same == nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
|
||||
nm_assert (reread_same == ({
|
||||
gs_unref_hashtable GHashTable *_settings = NULL;
|
||||
|
||||
( nm_connection_diff (reread, connection, NM_SETTING_COMPARE_FLAG_EXACT, &_settings)
|
||||
&& !_settings);
|
||||
}));
|
||||
}
|
||||
|
||||
NM_SET_OUT (out_reread, g_steal_pointer (&reread));
|
||||
NM_SET_OUT (out_reread_same, reread_same);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
||||
const char *ifcfg_dir,
|
||||
const char *filename,
|
||||
char **out_filename,
|
||||
NMConnection **out_reread,
|
||||
gboolean *out_reread_same,
|
||||
GError **error)
|
||||
{
|
||||
nm_auto_shvar_file_close shvarFile *ifcfg = NULL;
|
||||
nm_auto_free_gstring GString *route_content = NULL;
|
||||
gboolean route_ignore = FALSE;
|
||||
nm_auto_shvar_file_close shvarFile *route_content_svformat = NULL;
|
||||
nm_auto_free_gstring GString *route6_content = NULL;
|
||||
gs_unref_hashtable GHashTable *secrets = NULL;
|
||||
gs_unref_hashtable GHashTable *blobs = NULL;
|
||||
GError *local = NULL;
|
||||
|
||||
nm_assert (!out_reread || !*out_reread);
|
||||
|
||||
if (!do_write_construct (connection,
|
||||
ifcfg_dir,
|
||||
filename,
|
||||
&ifcfg,
|
||||
&blobs,
|
||||
&secrets,
|
||||
&route_ignore,
|
||||
&route_content_svformat,
|
||||
&route_content,
|
||||
&route6_content,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
_LOGT ("write: write connection %s (%s) to file \"%s\"",
|
||||
nm_connection_get_id (connection),
|
||||
nm_connection_get_uuid (connection),
|
||||
svFileGetName (ifcfg));
|
||||
|
||||
if (!do_write_to_disk (connection,
|
||||
ifcfg,
|
||||
blobs,
|
||||
secrets,
|
||||
route_ignore,
|
||||
route_content_svformat,
|
||||
route_content,
|
||||
route6_content,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* Note that we just wrote the connection to disk, and re-read it from there.
|
||||
* That is racy if somebody else modifies the connection.
|
||||
*
|
||||
* A better solution might be, to re-read the connection only based on the
|
||||
* in-memory representation of what we collected above. But the reader
|
||||
* does not yet allow to inject the configuration. */
|
||||
|
||||
if (out_reread || out_reread_same) {
|
||||
gs_unref_object NMConnection *reread = NULL;
|
||||
gs_free_error GError *local = NULL;
|
||||
gs_free char *unhandled = NULL;
|
||||
gboolean reread_same = FALSE;
|
||||
|
||||
reread = connection_from_file (ifcfg_name, &unhandled, &local, NULL);
|
||||
|
||||
if (unhandled) {
|
||||
_LOGW ("failure to re-read the new connection from file \"%s\": %s",
|
||||
ifcfg_name, "connection is unhandled");
|
||||
g_clear_object (&reread);
|
||||
} else if (!reread) {
|
||||
_LOGW ("failure to re-read the new connection from file \"%s\": %s",
|
||||
ifcfg_name, local ? local->message : "<unknown>");
|
||||
} else {
|
||||
if (out_reread_same) {
|
||||
if (nm_connection_compare (reread, connection, NM_SETTING_COMPARE_FLAG_EXACT))
|
||||
reread_same = TRUE;
|
||||
|
||||
nm_assert (reread_same == nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
|
||||
nm_assert (reread_same == ({
|
||||
gs_unref_hashtable GHashTable *_settings = NULL;
|
||||
|
||||
( nm_connection_diff (reread, connection, NM_SETTING_COMPARE_FLAG_EXACT, &_settings)
|
||||
&& !_settings);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
NM_SET_OUT (out_reread, g_steal_pointer (&reread));
|
||||
NM_SET_OUT (out_reread_same, reread_same);
|
||||
if ( (out_reread || out_reread_same)
|
||||
&& !do_write_reread (connection,
|
||||
svFileGetName (ifcfg),
|
||||
out_reread,
|
||||
out_reread_same,
|
||||
&local)) {
|
||||
_LOGW ("write: failure to re-read connection \"%s\": %s",
|
||||
svFileGetName (ifcfg), local->message);
|
||||
g_clear_error (&local);
|
||||
}
|
||||
|
||||
/* Only return the filename if this was a newly written ifcfg */
|
||||
if (out_filename && !filename)
|
||||
*out_filename = g_steal_pointer (&ifcfg_name);
|
||||
*out_filename = g_strdup (svFileGetName (ifcfg));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -3011,25 +3115,26 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
|
|||
gboolean
|
||||
nms_ifcfg_rh_writer_can_write_connection (NMConnection *connection, GError **error)
|
||||
{
|
||||
NMSettingConnection *s_con;
|
||||
const char *type, *id;
|
||||
|
||||
if ( ( nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)
|
||||
&& !nm_connection_get_setting_pppoe (connection))
|
||||
|| nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)
|
||||
|| nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)
|
||||
|| nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)
|
||||
|| nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)
|
||||
|| nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)
|
||||
|| nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME))
|
||||
type = nm_connection_get_connection_type (connection);
|
||||
if (NM_IN_STRSET (type,
|
||||
NM_SETTING_VLAN_SETTING_NAME,
|
||||
NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_INFINIBAND_SETTING_NAME,
|
||||
NM_SETTING_BOND_SETTING_NAME,
|
||||
NM_SETTING_TEAM_SETTING_NAME,
|
||||
NM_SETTING_BRIDGE_SETTING_NAME))
|
||||
return TRUE;
|
||||
if ( nm_streq0 (type, NM_SETTING_WIRED_SETTING_NAME)
|
||||
&& !nm_connection_get_setting_pppoe (connection))
|
||||
return TRUE;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
g_assert (s_con);
|
||||
id = nm_connection_get_id (connection);
|
||||
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
|
||||
"The ifcfg-rh plugin cannot write the connection '%s' (type '%s' pppoe %d)",
|
||||
nm_connection_get_id (connection),
|
||||
nm_setting_connection_get_connection_type (s_con),
|
||||
!!nm_connection_get_setting_pppoe (connection));
|
||||
"The ifcfg-rh plugin cannot write the connection %s%s%s (type %s%s%s)",
|
||||
NM_PRINT_FMT_QUOTE_STRING (id),
|
||||
NM_PRINT_FMT_QUOTE_STRING (type));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue