diff --git a/man/nm-initrd-generator.xml b/man/nm-initrd-generator.xml index 37f5ffdf4b..fcfb54fe50 100644 --- a/man/nm-initrd-generator.xml +++ b/man/nm-initrd-generator.xml @@ -102,6 +102,20 @@ + + + + + + + path + + + + Output directory for config files. + + + @@ -133,6 +147,7 @@ + diff --git a/src/initrd/nm-initrd-generator.c b/src/initrd/nm-initrd-generator.c index 1a33713eaf..ea26c9fe12 100644 --- a/src/initrd/nm-initrd-generator.c +++ b/src/initrd/nm-initrd-generator.c @@ -9,6 +9,7 @@ #include "nm-keyfile/nm-keyfile-internal.h" #include "nm-initrd-generator.h" #include "nm-glib-aux/nm-io-utils.h" +#include "nm-config.h" /*****************************************************************************/ @@ -63,6 +64,7 @@ err_out: #define DEFAULT_SYSFS_DIR "/sys" #define DEFAULT_INITRD_DATA_DIR NMRUNDIR "/initrd" +#define DEFAULT_RUN_CONFIG_DIR NMRUNDIR "/conf.d" int main(int argc, char *argv[]) @@ -71,6 +73,7 @@ main(int argc, char *argv[]) gs_free char * connections_dir = NULL; gs_free char * initrd_dir = NULL; gs_free char * sysfs_dir = NULL; + gs_free char * run_config_dir = NULL; gboolean dump_to_stdout = FALSE; gs_strfreev char **remaining = NULL; GOptionEntry option_entries[] = { @@ -95,6 +98,13 @@ main(int argc, char *argv[]) &sysfs_dir, "The sysfs mount point", DEFAULT_SYSFS_DIR}, + {"run-config-dir", + 'r', + 0, + G_OPTION_ARG_FILENAME, + &run_config_dir, + "Output config directory", + DEFAULT_RUN_CONFIG_DIR}, {"stdout", 's', 0, @@ -108,11 +118,12 @@ main(int argc, char *argv[]) gs_free_error GError *error = NULL; gs_free char * hostname = NULL; int errsv; + gint64 carrier_timeout_sec = 0; option_context = g_option_context_new( "-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] " "[bootdev=...] [nameserver=...] [rd.peerdns=...] [rd.bootif=...] [BOOTIF=...] " - "[rd.znet=...] ... "); + "[rd.znet=...] [rd.net.timeout.carrier=...] ... "); g_option_context_set_summary(option_context, "Generate early NetworkManager configuration."); g_option_context_set_description( @@ -138,29 +149,39 @@ main(int argc, char *argv[]) sysfs_dir = g_strdup(DEFAULT_SYSFS_DIR); if (!initrd_dir) initrd_dir = g_strdup(DEFAULT_INITRD_DATA_DIR); - if (dump_to_stdout) - nm_clear_g_free(&connections_dir); + if (!run_config_dir) + run_config_dir = g_strdup(DEFAULT_RUN_CONFIG_DIR); - if (connections_dir && g_mkdir_with_parents(connections_dir, 0755) != 0) { - errsv = errno; - _LOGW(LOGD_CORE, "%s: %s", connections_dir, nm_strerror_native(errsv)); - return 1; - } - - connections = nmi_cmdline_reader_parse(sysfs_dir, (const char *const *) remaining, &hostname); - - g_hash_table_foreach(connections, output_conn, connections_dir); - g_hash_table_destroy(connections); + connections = nmi_cmdline_reader_parse(sysfs_dir, + (const char *const *) remaining, + &hostname, + &carrier_timeout_sec); if (dump_to_stdout) { + nm_clear_g_free(&connections_dir); + nm_clear_g_free(&initrd_dir); + nm_clear_g_free(&run_config_dir); if (hostname) g_print("\n*** Hostname '%s' ***\n", hostname); + if (carrier_timeout_sec != 0) + g_print("\n*** Carrier Wait Timeout %" G_GINT64_FORMAT " sec ***\n", + carrier_timeout_sec); } else { + if (g_mkdir_with_parents(connections_dir, 0755) != 0) { + errsv = errno; + _LOGW(LOGD_CORE, "%s: %s", connections_dir, nm_strerror_native(errsv)); + return 1; + } if (g_mkdir_with_parents(initrd_dir, 0755) != 0) { errsv = errno; _LOGW(LOGD_CORE, "%s: %s", initrd_dir, nm_strerror_native(errsv)); return 1; } + if (g_mkdir_with_parents(run_config_dir, 0755) != 0) { + errsv = errno; + _LOGW(LOGD_CORE, "%s: %s", run_config_dir, nm_strerror_native(errsv)); + return 1; + } if (hostname) { gs_free char *hostname_file = NULL; @@ -174,7 +195,32 @@ main(int argc, char *argv[]) return 1; } } + if (carrier_timeout_sec != 0) { + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gs_free char * filename = NULL; + + keyfile = g_key_file_new(); + g_key_file_set_list_separator(keyfile, NM_CONFIG_KEYFILE_LIST_SEPARATOR); + filename = g_strdup_printf("%s/15-carrier-timeout.conf", run_config_dir); + + g_key_file_set_value(keyfile, + NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "-15-carrier-timeout", + NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE, + "*"); + g_key_file_set_int64(keyfile, + NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "-15-carrier-timeout", + NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT, + carrier_timeout_sec * 1000); + + if (!g_key_file_save_to_file(keyfile, filename, &error)) { + _LOGW(LOGD_CORE, "%s: %s", filename, error->message); + return 1; + } + } } + g_hash_table_foreach(connections, output_conn, connections_dir); + g_hash_table_destroy(connections); + return 0; } diff --git a/src/initrd/nm-initrd-generator.h b/src/initrd/nm-initrd-generator.h index 69c24b1b0b..758f50b99a 100644 --- a/src/initrd/nm-initrd-generator.h +++ b/src/initrd/nm-initrd-generator.h @@ -37,7 +37,9 @@ nmi_ibft_update_connection_from_nic(NMConnection *connection, GHashTable *nic, G NMConnection *nmi_dt_reader_parse(const char *sysfs_dir); -GHashTable * -nmi_cmdline_reader_parse(const char *sysfs_dir, const char *const *argv, char **hostname); +GHashTable *nmi_cmdline_reader_parse(const char * sysfs_dir, + const char *const *argv, + char ** hostname, + gint64 * carrier_timeout_sec); #endif /* __NM_INITRD_GENERATOR_H__ */ diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index 02e4142b83..d9251862b2 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -34,6 +34,8 @@ typedef struct { gboolean ignore_auto_dns; int dhcp_timeout; char * dhcp4_vci; + + gint64 carrier_timeout_sec; } Reader; static Reader * @@ -1020,7 +1022,10 @@ connection_set_needed_cb(gpointer key, gpointer value, gpointer user_data) } GHashTable * -nmi_cmdline_reader_parse(const char *sysfs_dir, const char *const *argv, char **hostname) +nmi_cmdline_reader_parse(const char * sysfs_dir, + const char *const *argv, + char ** hostname, + gint64 * carrier_timeout_sec) { Reader * reader; const char * tag; @@ -1054,6 +1059,9 @@ nmi_cmdline_reader_parse(const char *sysfs_dir, const char *const *argv, char ** } else if (nm_streq(tag, "rd.net.dhcp.vendor-class")) { if (nm_utils_validate_dhcp4_vendor_class_id(argument, NULL)) nm_utils_strdup_reset(&reader->dhcp4_vci, argument); + } else if (nm_streq(tag, "rd.net.timeout.carrier")) { + reader->carrier_timeout_sec = + _nm_utils_ascii_str_to_int64(argument, 10, 0, G_MAXINT32, 0); } } @@ -1214,5 +1222,7 @@ nmi_cmdline_reader_parse(const char *sysfs_dir, const char *const *argv, char ** NM_SET_OUT(hostname, g_steal_pointer(&reader->hostname)); + NM_SET_OUT(carrier_timeout_sec, reader->carrier_timeout_sec); + return reader_destroy(reader, FALSE); } diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c index 95acc91116..a89486954d 100644 --- a/src/initrd/tests/test-cmdline-reader.c +++ b/src/initrd/tests/test-cmdline-reader.c @@ -30,12 +30,15 @@ test_auto(void) NMSettingWired * s_wired; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "default_connection"); g_assert(connection); @@ -89,12 +92,15 @@ test_dhcp_with_hostname(void) NMSettingWired * s_wired; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "host1"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "default_connection"); g_assert(connection); @@ -145,12 +151,17 @@ test_dhcp_with_mtu(void) NMSettingWired * s_wired; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV[i], &hostname); + connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", + ARGV[i], + &hostname, + &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "default_connection"); g_assert(connection); @@ -198,12 +209,15 @@ test_if_auto_with_mtu(void) NMSettingWired * s_wired; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth0"); g_assert(connection); @@ -233,12 +247,15 @@ test_if_dhcp6(void) NMConnection * connection; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth1"); g_assert(connection); @@ -267,12 +284,15 @@ test_if_auto_with_mtu_and_mac(void) NMSettingWired * s_wired; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth2"); g_assert(connection); @@ -310,12 +330,15 @@ test_if_ip4_manual(void) NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; NMIPAddress * ip_addr; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, "hostname1.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth3"); g_assert(connection); @@ -386,12 +409,15 @@ test_if_ip6_manual(void) NMConnection * connection; NMSettingIPConfig * s_ip6; NMIPAddress * ip_addr; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "hostname0.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth4"); g_assert(connection); @@ -427,7 +453,8 @@ test_if_off(void) NMConnection * connection; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; struct { const char name[32]; const char ipv4_method[32]; @@ -442,10 +469,12 @@ test_if_off(void) {"ens5", NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NM_SETTING_IP6_CONFIG_METHOD_MANUAL}, }; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, G_N_ELEMENTS(conn_expected)); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); for (int i = 0; i < G_N_ELEMENTS(conn_expected); ++i) { connection = g_hash_table_lookup(connections, conn_expected[i].name); @@ -472,12 +501,15 @@ test_if_mac_ifname(void) NMSettingIPConfig * s_ip6; NMSettingWired * s_wired; NMIPAddress * ip_addr; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "hostname0"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "00:11:22:33:44:55"); g_assert(connection); @@ -519,12 +551,15 @@ test_multiple_merge(void) NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; NMIPAddress * ip_addr; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth0"); g_assert(connection); @@ -573,12 +608,15 @@ test_multiple_bootdev(void) NMSettingConnection *s_con; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth3"); g_assert(connection); @@ -610,12 +648,15 @@ test_bootdev(void) const char *const * ARGV = NM_MAKE_STRV("vlan=vlan2:ens5", "bootdev=ens3"); NMConnection * connection; NMSettingConnection * s_con; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 3); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "ens3"); g_assert(connection); @@ -676,12 +717,15 @@ test_some_more(void) NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; NMIPRoute * ip_route; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth1"); g_assert(connection); @@ -767,12 +811,15 @@ test_bond(void) NMSettingWired * s_wired; NMIPRoute * ip_route; const char * master_uuid; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 3); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "bong0"); g_assert(connection); @@ -867,12 +914,15 @@ test_bond_ip(void) NMSettingBond * s_bond; NMIPAddress * ip_addr; const char * master_uuid; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 3); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "bond0"); g_assert(connection); @@ -965,12 +1015,15 @@ test_bond_default(void) NMSettingIPConfig * s_ip6; NMSettingBond * s_bond; const char * master_uuid; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "bond0"); @@ -1036,12 +1089,15 @@ test_bridge(void) NMSettingBridge * s_bridge; NMIPRoute * ip_route; const char * master_uuid; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 3); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "bridge0"); g_assert(connection); @@ -1131,12 +1187,15 @@ test_bridge_default(void) NMSettingIPConfig * s_ip6; NMSettingBridge * s_bridge; const char * master_uuid; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "br0"); @@ -1202,13 +1261,16 @@ test_bridge_ip(void) NMSettingWired * s_wired; NMSettingBridge * s_bridge; const char * master_uuid; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; guint i; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 11); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "bridge123"); g_assert(connection); @@ -1273,12 +1335,15 @@ test_team(void) NMSettingIPConfig * s_ip6; NMSettingTeam * s_team; const char * master_uuid; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 3); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "team0"); g_assert(connection); @@ -1360,12 +1425,17 @@ test_vlan(void) NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; NMSettingVlan * s_vlan; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV[i], &hostname); + connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", + ARGV[i], + &hostname, + &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); /* VLAN eth0.100 */ connection = g_hash_table_lookup(connections, "eth0.100"); @@ -1430,12 +1500,17 @@ test_vlan_with_dhcp_on_parent(void) NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; NMSettingVlan * s_vlan; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV[i], &hostname); + connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", + ARGV[i], + &hostname, + &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); /* VLAN eth0.100 */ connection = g_hash_table_lookup(connections, "eth0.100"); @@ -1507,12 +1582,17 @@ test_vlan_over_bond(void) NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; NMSettingVlan * s_vlan; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV[i], &hostname); + connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", + ARGV[i], + &hostname, + &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 4); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); /* VLAN vlan1 */ connection = g_hash_table_lookup(connections, "vlan1"); @@ -1576,12 +1656,15 @@ test_ibft_ip_dev(void) gs_unref_hashtable GHashTable *connections = NULL; NMSettingConnection * s_con; NMConnection * connection; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth0"); g_assert(connection); @@ -1601,12 +1684,15 @@ test_ibft_ip_dev_mac(void) gs_unref_hashtable GHashTable *connections = NULL; NMSettingConnection * s_con; NMConnection * connection; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "00:53:06:66:AB:01"); g_assert(connection); @@ -1624,12 +1710,15 @@ _test_ibft_ip(const char *const *ARGV) { gs_unref_hashtable GHashTable *connections = NULL; NMConnection * connection; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "ibft0"); g_assert(connection); @@ -1663,14 +1752,17 @@ test_ibft_rd_iscsi_ibft(void) static void test_ignore_extra(void) { - gs_unref_hashtable GHashTable *connections = NULL; - const char *const * ARGV = NM_MAKE_STRV("blabla", "extra", "lalala"); - gs_free char * hostname = NULL; + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("blabla", "extra", "lalala"); + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 0); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); } static void @@ -1691,12 +1783,15 @@ test_rd_znet(void) {.name = "portno", .value_str = "1"}, }; int i_s390_options_keys; - gs_free char *hostname = NULL; + gs_free char *hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, "foo.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "enc800"); g_assert(NM_IS_CONNECTION(connection)); @@ -1777,12 +1872,15 @@ test_rd_znet_legacy(void) "net.ifnames=0"); NMConnection * connection; NMSettingConnection *s_con; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, "foo.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth0"); g_assert(NM_IS_CONNECTION(connection)); @@ -1817,12 +1915,15 @@ test_rd_znet_no_ip(void) gs_unref_hashtable GHashTable *connections = NULL; const char *const *const ARGV = NM_MAKE_STRV("rd.znet=qeth,0.0.0800,0.0.0801,0.0.0802,layer2=0,portno=1"); - gs_free char *hostname = NULL; + gs_free char *hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 0); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); } static void @@ -1834,12 +1935,15 @@ test_bootif_ip(void) NMSettingWired * s_wired; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "default_connection"); g_assert(connection); @@ -1872,12 +1976,15 @@ test_neednet(void) "bridge=br0:eno3"); NMConnection * connection; NMSettingConnection * s_con; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 4); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eno1"); g_assert(connection); @@ -1927,12 +2034,15 @@ test_bootif_no_ip(void) NMSettingWired * s_wired; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "default_connection"); g_assert(connection); @@ -1968,12 +2078,17 @@ test_bootif_hwtype(void) NMSettingWired * s_wired; NMSettingIPConfig * s_ip4; NMSettingIPConfig * s_ip6; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV[i], &hostname); + connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", + ARGV[i], + &hostname, + &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth0"); g_assert(connection); @@ -2043,12 +2158,15 @@ test_nameserver(void) "nameserver=[2606:4700:4700::1111]"); NMConnection * connection; NMSettingIPConfig *s_ip; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 3); g_assert_cmpstr(hostname, ==, "foo.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eth0"); g_assert(connection); @@ -2086,11 +2204,14 @@ test_bootif_off(void) gs_unref_hashtable GHashTable *connections = NULL; const char *const *ARGV = NM_MAKE_STRV("BOOTIF=01-00-53-AB-cd-02-03", "rd.bootif=0"); gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 0); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); } static void @@ -2100,14 +2221,17 @@ test_dhcp_vendor_class_id(void) const char *const * ARGV = NM_MAKE_STRV("rd.net.dhcp.vendor-class=testvci", "ip=eno1:dhcp"); NMConnection * connection; NMSettingIP4Config *s_ip4; - gs_free char * hostname = NULL; - gs_free char * vci_long = NULL; - char vci_arg_long[512] = {0}; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; + gs_free char * vci_long = NULL; + char vci_arg_long[512] = {0}; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "eno1"); g_assert(connection); @@ -2117,9 +2241,10 @@ test_dhcp_vendor_class_id(void) nm_clear_pointer(&connections, g_hash_table_unref); - ARGV = NM_MAKE_STRV("rd.net.dhcp.vendor-class", "ip=eno1:dhcp"); - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); - connection = g_hash_table_lookup(connections, "eno1"); + ARGV = NM_MAKE_STRV("rd.net.dhcp.vendor-class", "ip=eno1:dhcp"); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); + connection = g_hash_table_lookup(connections, "eno1"); g_assert(connection); nmtst_assert_connection_verifies_without_normalization(connection); s_ip4 = NM_SETTING_IP4_CONFIG(nm_connection_get_setting_ip4_config(connection)); @@ -2128,10 +2253,11 @@ test_dhcp_vendor_class_id(void) nm_clear_pointer(&connections, g_hash_table_unref); memset(vci_arg_long, 'A', 400); - vci_long = g_strdup_printf("rd.net.dhcp.vendor-class=%s", vci_arg_long); - ARGV = NM_MAKE_STRV(vci_long, "ip=eno1:dhcp"); - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); - connection = g_hash_table_lookup(connections, "eno1"); + vci_long = g_strdup_printf("rd.net.dhcp.vendor-class=%s", vci_arg_long); + ARGV = NM_MAKE_STRV(vci_long, "ip=eno1:dhcp"); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); + connection = g_hash_table_lookup(connections, "eno1"); g_assert(connection); nmtst_assert_connection_verifies_without_normalization(connection); s_ip4 = NM_SETTING_IP4_CONFIG(nm_connection_get_setting_ip4_config(connection)); @@ -2145,12 +2271,15 @@ test_infiniband_iface(void) const char *const * ARGV = NM_MAKE_STRV("ip=ib1:dhcp"); NMConnection * connection; NMSettingInfiniband * s_ib; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "ib1"); g_assert(connection); @@ -2170,12 +2299,15 @@ test_infiniband_mac(void) NM_MAKE_STRV("ip=00-11-22-33-44-55-66-77-88-99-aa-bb-cc-dd-ee-ff-00-11-22-33:dhcp"); NMConnection * connection; NMSettingInfiniband *s_ib; - gs_free char * hostname = NULL; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; - connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); g_assert(connections); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); connection = g_hash_table_lookup(connections, "00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33"); @@ -2192,6 +2324,22 @@ test_infiniband_mac(void) "00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33"); } +static void +test_carrier_timeout(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("rd.net.timeout.carrier=20"); + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; + + connections = + nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname, &carrier_timeout_sec); + g_assert(connections); + g_assert_cmpint(g_hash_table_size(connections), ==, 0); + g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 20); +} + NMTST_DEFINE(); int @@ -2240,6 +2388,7 @@ main(int argc, char **argv) g_test_add_func("/initrd/cmdline/dhcp/vendor_class_id", test_dhcp_vendor_class_id); g_test_add_func("/initrd/cmdline/infiniband/iface", test_infiniband_iface); g_test_add_func("/initrd/cmdline/infiniband/mac", test_infiniband_mac); + g_test_add_func("/initrd/cmdline/carrier_timeout", test_carrier_timeout); return g_test_run(); }