diff --git a/src/initrd/nm-initrd-generator.h b/src/initrd/nm-initrd-generator.h index 9719992125..8e17f04555 100644 --- a/src/initrd/nm-initrd-generator.h +++ b/src/initrd/nm-initrd-generator.h @@ -9,6 +9,8 @@ #include "nm-connection.h" #include "nm-utils.h" +#define NMI_WAIT_DEVICE_TIMEOUT_MS 60000 + static inline gboolean guess_ip_address_family (const char *str) { diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index 17f9e1dfd2..85be9f132e 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -584,7 +584,6 @@ reader_parse_master (Reader *reader, { NMConnection *connection; NMSettingConnection *s_con; - NMSettingBond *s_bond; gs_free char *master_to_free = NULL; const char *master; char *slaves; @@ -603,8 +602,15 @@ reader_parse_master (Reader *reader, s_con = nm_connection_get_setting_connection (connection); master = nm_setting_connection_get_uuid (s_con); - if (nm_streq (type_name, NM_SETTING_BOND_SETTING_NAME)) { - s_bond = (NMSettingBond *)nm_connection_get_setting_by_name (connection, type_name); + if (nm_streq (type_name, NM_SETTING_BRIDGE_SETTING_NAME)) { + NMSettingBridge *s_bridge = nm_connection_get_setting_bridge (connection); + + /* Avoid the forwarding delay */ + g_object_set (s_bridge, + NM_SETTING_BRIDGE_STP, FALSE, + NULL); + } else if (nm_streq (type_name, NM_SETTING_BOND_SETTING_NAME)) { + NMSettingBond *s_bond = nm_connection_get_setting_bond (connection); opts = get_word (&argument, ':'); while (opts && *opts) { @@ -867,6 +873,30 @@ reader_add_nameservers (Reader *reader, GPtrArray *nameservers) } } +static void +connection_set_needed (NMConnection *connection) +{ + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + if (!nm_streq0 (nm_setting_connection_get_connection_type (s_con), + NM_SETTING_WIRED_SETTING_NAME)) + return; + + if (nm_str_is_empty (nm_setting_connection_get_interface_name (s_con))) + return; + + g_object_set (s_con, + NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, NMI_WAIT_DEVICE_TIMEOUT_MS, + NULL); +} + +static void +connection_set_needed_cb (gpointer key, gpointer value, gpointer user_data) +{ + connection_set_needed (value); +} + GHashTable * nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv, char **hostname) { @@ -1001,11 +1031,16 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv, char ** connection = reader_get_connection (reader, bootdev, NULL, TRUE); reader->bootdev_connection = connection; + connection_set_needed (connection); } - if (neednet && g_hash_table_size (reader->hash) == 0) { - /* Make sure there's some connection. */ - reader_get_default_connection (reader); + if (neednet) { + if (g_hash_table_size (reader->hash) == 0) { + /* Make sure there's some connection. */ + reader_get_default_connection (reader); + } + + g_hash_table_foreach (reader->hash, connection_set_needed_cb, NULL); } if (routes) diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c index 04594c48be..7787cf5ea0 100644 --- a/src/initrd/tests/test-cmdline-reader.c +++ b/src/initrd/tests/test-cmdline-reader.c @@ -49,6 +49,7 @@ test_auto (void) g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "Wired Connection"); g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); g_assert_cmpint (nm_setting_connection_get_multi_connect (s_con), ==, NM_CONNECTION_MULTI_CONNECT_MULTIPLE); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, -1); g_assert (nm_setting_connection_get_autoconnect (s_con)); @@ -190,6 +191,7 @@ test_if_ip4_manual (void) "ip=203.0.113.2::203.0.113.1:26:" "hostname1.example.com:eth4"); NMConnection *connection; + NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; NMIPAddress *ip_addr; @@ -205,6 +207,10 @@ test_if_ip4_manual (void) nmtst_assert_connection_verifies_without_normalization (connection); g_assert_cmpstr (nm_connection_get_id (connection), ==, "eth3"); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, -1); + s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); @@ -294,6 +300,7 @@ test_multiple_merge (void) const char *const*ARGV = NM_MAKE_STRV ("ip=192.0.2.2:::::eth0", "ip=[2001:db8::2]:::::eth0"); NMConnection *connection; + NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; @@ -310,6 +317,10 @@ test_multiple_merge (void) nmtst_assert_connection_verifies_without_normalization (connection); g_assert_cmpstr (nm_connection_get_id (connection), ==, "eth0"); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, -1); + s_wired = nm_connection_get_setting_wired (connection); g_assert (s_wired); @@ -341,6 +352,7 @@ test_multiple_bootdev (void) "ip=eth4:dhcp", "bootdev=eth4"); NMConnection *connection; + NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; gs_free char *hostname = NULL; @@ -352,12 +364,18 @@ test_multiple_bootdev (void) connection = g_hash_table_lookup (connections, "eth3"); g_assert (connection); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, -1); s_ip6 = nm_connection_get_setting_ip6_config (connection); g_assert (s_ip6); g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); connection = g_hash_table_lookup (connections, "eth4"); g_assert (connection); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, NMI_WAIT_DEVICE_TIMEOUT_MS); s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); @@ -388,6 +406,7 @@ test_bootdev (void) g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "ens3"); g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, "ens3"); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout(s_con), ==, NMI_WAIT_DEVICE_TIMEOUT_MS); connection = g_hash_table_lookup (connections, "vlan2"); g_assert (connection); @@ -774,6 +793,7 @@ test_bridge (void) s_bridge = nm_connection_get_setting_bridge (connection); g_assert (s_bridge); + g_assert_cmpint (nm_setting_bridge_get_stp (s_bridge), ==, FALSE); connection = g_hash_table_lookup (connections, "eth0"); g_assert (connection); @@ -1254,6 +1274,56 @@ test_bootif_ip (void) g_assert (!nm_setting_ip_config_get_ignore_auto_dns (s_ip6)); } +static void +test_neednet (void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const*ARGV = NM_MAKE_STRV ("rd.neednet", + "ip=eno1:dhcp", + "ip=172.25.1.100::172.25.1.1:24::eno2", + "bridge=br0:eno3"); + NMConnection *connection; + NMSettingConnection *s_con; + gs_free char *hostname = NULL; + + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + g_assert (connections); + g_assert_cmpint (g_hash_table_size (connections), ==, 4); + g_assert_cmpstr (hostname, ==, NULL); + + connection = g_hash_table_lookup (connections, "eno1"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, "eno1"); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, NMI_WAIT_DEVICE_TIMEOUT_MS); + + connection = g_hash_table_lookup (connections, "eno2"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, "eno2"); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, NMI_WAIT_DEVICE_TIMEOUT_MS); + + connection = g_hash_table_lookup (connections, "eno3"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, "eno3"); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, NMI_WAIT_DEVICE_TIMEOUT_MS); + + connection = g_hash_table_lookup (connections, "br0"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, "br0"); + g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, -1); +} + static void test_bootif_no_ip (void) { @@ -1450,6 +1520,7 @@ int main (int argc, char **argv) g_test_add_func ("/initrd/cmdline/bootif/no_ip", test_bootif_no_ip); g_test_add_func ("/initrd/cmdline/bootif/hwtype", test_bootif_hwtype); g_test_add_func ("/initrd/cmdline/bootif/off", test_bootif_off); + g_test_add_func ("/initrd/cmdline/neednet", test_neednet); return g_test_run (); }