summary refs log tree commit diff
path: root/src/nm-initrd-generator/nmi-cmdline-reader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-initrd-generator/nmi-cmdline-reader.c')
-rw-r--r--src/nm-initrd-generator/nmi-cmdline-reader.c265
1 files changed, 150 insertions, 115 deletions
diff --git a/src/nm-initrd-generator/nmi-cmdline-reader.c b/src/nm-initrd-generator/nmi-cmdline-reader.c
index 8fafb08f..412c7510 100644
--- a/src/nm-initrd-generator/nmi-cmdline-reader.c
+++ b/src/nm-initrd-generator/nmi-cmdline-reader.c
@@ -27,18 +27,19 @@
 /*****************************************************************************/
 
 typedef struct {
-    GHashTable *  hash;
-    GPtrArray *   array;
-    GPtrArray *   vlan_parents;
-    GHashTable *  explicit_ip_connections;
+    GHashTable   *hash;
+    GPtrArray    *array;
+    GPtrArray    *vlan_parents;
+    GHashTable   *explicit_ip_connections;
     NMConnection *bootdev_connection; /* connection for bootdev=$ifname */
     NMConnection *default_connection; /* connection not bound to any ifname */
-    char *        hostname;
+    char         *hostname;
+    GHashTable   *znet_ifnames;
 
     /* Parameters to be set for all connections */
     gboolean ignore_auto_dns;
     int      dhcp_timeout;
-    char *   dhcp4_vci;
+    char    *dhcp4_vci;
 
     gint64 carrier_timeout_sec;
 } Reader;
@@ -55,6 +56,7 @@ reader_new(void)
             g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL),
         .vlan_parents = g_ptr_array_new_with_free_func(g_free),
         .array        = g_ptr_array_new(),
+        .znet_ifnames = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free),
     };
 
     return reader;
@@ -70,6 +72,7 @@ reader_destroy(Reader *reader, gboolean free_hash)
     g_hash_table_unref(reader->explicit_ip_connections);
     hash = g_steal_pointer(&reader->hash);
     nm_clear_g_free(&reader->hostname);
+    g_hash_table_unref(reader->znet_ifnames);
     nm_clear_g_free(&reader->dhcp4_vci);
     nm_g_slice_free(reader);
     if (!free_hash)
@@ -91,16 +94,16 @@ reader_add_connection(Reader *reader, const char *name, NMConnection *connection
 
 /* Returns a new connection owned by the reader */
 static NMConnection *
-reader_create_connection(Reader *                 reader,
-                         const char *             basename,
-                         const char *             id,
-                         const char *             ifname,
-                         const char *             mac,
-                         const char *             type_name,
+reader_create_connection(Reader                  *reader,
+                         const char              *basename,
+                         const char              *id,
+                         const char              *ifname,
+                         const char              *mac,
+                         const char              *type_name,
                          NMConnectionMultiConnect multi_connect)
 {
     NMConnection *connection;
-    NMSetting *   setting;
+    NMSetting    *setting;
 
     connection = reader_add_connection(reader, basename, nm_simple_connection_new());
 
@@ -195,14 +198,14 @@ reader_get_default_connection(Reader *reader)
 }
 
 static NMConnection *
-reader_get_connection(Reader *    reader,
+reader_get_connection(Reader     *reader,
                       const char *iface_spec,
                       const char *type_name,
                       gboolean    create_if_missing)
 {
     NMConnection *connection = NULL;
-    NMSetting *   setting;
-    const char *  ifname = NULL;
+    NMSetting    *setting;
+    const char   *ifname = NULL;
     gs_free char *mac    = NULL;
 
     if (iface_spec) {
@@ -216,7 +219,7 @@ reader_get_connection(Reader *    reader,
     }
 
     if (!ifname && !mac) {
-        NMConnection *       candidate;
+        NMConnection        *candidate;
         NMSettingConnection *s_con;
         guint                i;
 
@@ -314,14 +317,14 @@ get_word(char **argument, const char separator)
 
 static void
 connection_set(NMConnection *connection,
-               const char *  setting_name,
-               const char *  property,
-               const char *  value)
+               const char   *setting_name,
+               const char   *property,
+               const char   *value)
 {
-    NMSetting *              setting;
-    GType                    setting_type;
+    NMSetting                             *setting;
+    GType                                  setting_type;
     nm_auto_unref_gtypeclass GObjectClass *object_class = NULL;
-    GParamSpec *                           spec;
+    GParamSpec                            *spec;
 
     setting_type = nm_setting_lookup_type(setting_name);
     object_class = g_type_class_ref(setting_type);
@@ -355,20 +358,20 @@ static void
 reader_read_all_connections_from_fw(Reader *reader, const char *sysfs_dir)
 {
     gs_unref_hashtable GHashTable *ibft = NULL;
-    NMConnection *                 dt_connection;
-    const char *                   mac;
-    GHashTable *                   nic;
-    const char *                   index;
-    GError *                       error = NULL;
+    NMConnection                  *dt_connection;
+    const char                    *mac;
+    GHashTable                    *nic;
+    const char                    *index;
+    GError                        *error = NULL;
     guint                          i, length;
-    gs_free const char **          keys = NULL;
+    gs_free const char           **keys = NULL;
 
     ibft = nmi_ibft_read(sysfs_dir);
     keys = nm_strdict_get_keys(ibft, TRUE, &length);
 
     for (i = 0; i < length; i++) {
         gs_unref_object NMConnection *connection = NULL;
-        gs_free char *                name       = NULL;
+        gs_free char                 *name       = NULL;
 
         mac        = keys[i];
         nic        = g_hash_table_lookup(ibft, mac);
@@ -426,7 +429,7 @@ _parse_ip_method(const char *kind)
         "auto",
         "ibft",
     };
-    gs_free char *       kind_to_free = NULL;
+    gs_free char        *kind_to_free = NULL;
     gs_free const char **strv         = NULL;
     gsize                i;
 
@@ -512,26 +515,26 @@ _parse_ip_method(const char *kind)
 static void
 reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument)
 {
-    NMConnection *       connection;
-    NMSettingConnection *s_con;
-    NMSettingIPConfig *  s_ip4 = NULL, *s_ip6 = NULL;
+    NMConnection                  *connection;
+    NMSettingConnection           *s_con;
+    NMSettingIPConfig             *s_ip4 = NULL, *s_ip6 = NULL;
     gs_unref_hashtable GHashTable *ibft = NULL;
-    const char *                   tmp;
-    const char *                   tmp2;
-    const char *                   tmp3;
-    const char *                   kind;
-    const char *                   client_ip                  = NULL;
-    const char *                   peer                       = NULL;
-    const char *                   gateway_ip                 = NULL;
-    const char *                   netmask                    = NULL;
-    const char *                   client_hostname            = NULL;
-    const char *                   iface_spec                 = NULL;
-    const char *                   mtu                        = NULL;
-    const char *                   macaddr                    = NULL;
+    const char                    *tmp;
+    const char                    *tmp2;
+    const char                    *tmp3;
+    const char                    *kind;
+    const char                    *client_ip                  = NULL;
+    const char                    *peer                       = NULL;
+    const char                    *gateway_ip                 = NULL;
+    const char                    *netmask                    = NULL;
+    const char                    *client_hostname            = NULL;
+    const char                    *iface_spec                 = NULL;
+    const char                    *mtu                        = NULL;
+    const char                    *macaddr                    = NULL;
     int                            client_ip_family           = AF_UNSPEC;
     int                            client_ip_prefix           = -1;
     gboolean                       clear_ip4_required_timeout = TRUE;
-    const char *                   dns[2]                     = {
+    const char                    *dns[2]                     = {
         NULL,
         NULL,
     };
@@ -770,11 +773,11 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument)
         }
     } else if (nm_streq(kind, "ibft")) {
         NMSettingWired *s_wired;
-        const char *    mac = NULL;
-        const char *    ifname;
-        gs_free char *  mac_free     = NULL;
-        gs_free char *  address_path = NULL;
-        GHashTable *    nic          = NULL;
+        const char     *mac = NULL;
+        const char     *ifname;
+        gs_free char   *mac_free     = NULL;
+        gs_free char   *address_path = NULL;
+        GHashTable     *nic          = NULL;
 
         if ((s_wired = nm_connection_get_setting_wired(connection))
             && (mac = nm_setting_wired_get_mac_address(s_wired))) {
@@ -857,14 +860,14 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument)
 static void
 reader_parse_master(Reader *reader, char *argument, const char *type_name, const char *default_name)
 {
-    NMConnection *       connection;
+    NMConnection        *connection;
     NMSettingConnection *s_con;
-    gs_free char *       master_to_free = NULL;
-    const char *         master;
-    char *               slaves;
-    const char *         slave;
-    char *               opts;
-    const char *         mtu = NULL;
+    gs_free char        *master_to_free = NULL;
+    const char          *master;
+    char                *slaves;
+    const char          *slave;
+    char                *opts;
+    const char          *mtu = NULL;
 
     master = get_word(&argument, ':');
     if (!master)
@@ -886,8 +889,8 @@ reader_parse_master(Reader *reader, char *argument, const char *type_name, const
         opts = get_word(&argument, ':');
         while (opts && *opts) {
             gs_free_error GError *error = NULL;
-            char *                opt;
-            const char *          opt_name;
+            char                 *opt;
+            const char           *opt_name;
 
             opt      = get_word(&opts, ',');
             opt_name = get_word(&opt, '=');
@@ -934,17 +937,17 @@ reader_add_routes(Reader *reader, GPtrArray *array)
     guint i;
 
     for (i = 0; i < array->len; i++) {
-        NMConnection *     connection = NULL;
-        const char *       net;
-        const char *       gateway;
-        const char *       interface;
-        int                family       = AF_UNSPEC;
-        NMIPAddr           net_addr     = {};
-        NMIPAddr           gateway_addr = {};
-        int                net_prefix   = -1;
-        NMIPRoute *        route;
-        NMSettingIPConfig *s_ip;
-        char *             argument;
+        NMConnection         *connection = NULL;
+        const char           *net;
+        const char           *gateway;
+        const char           *interface;
+        int                   family       = AF_UNSPEC;
+        NMIPAddr              net_addr     = {};
+        NMIPAddr              gateway_addr = {};
+        int                   net_prefix   = -1;
+        NMIPRoute            *route;
+        NMSettingIPConfig    *s_ip;
+        char                 *argument;
         gs_free_error GError *error = NULL;
 
         argument  = array->pdata[i];
@@ -1010,11 +1013,11 @@ reader_add_routes(Reader *reader, GPtrArray *array)
 static void
 reader_parse_vlan(Reader *reader, char *argument)
 {
-    NMConnection * connection;
+    NMConnection  *connection;
     NMSettingVlan *s_vlan;
-    const char *   vlan;
-    const char *   phy;
-    const char *   vlanid;
+    const char    *vlan;
+    const char    *phy;
+    const char    *vlanid;
 
     vlan = get_word(&argument, ':');
     phy  = get_word(&argument, ':');
@@ -1044,11 +1047,11 @@ reader_parse_vlan(Reader *reader, char *argument)
 static void
 reader_parse_ib_pkey(Reader *reader, char *argument)
 {
-    NMConnection *       connection;
+    NMConnection        *connection;
     NMSettingInfiniband *s_ib;
-    char *               ifname;
-    gs_free char *       parent = NULL;
-    char *               pkey;
+    char                *ifname;
+    gs_free char        *parent = NULL;
+    char                *pkey;
     gint64               pkey_int;
 
     /* At the moment we only support ib.pkey=<parent>.<pkey>;
@@ -1092,18 +1095,35 @@ reader_parse_ib_pkey(Reader *reader, char *argument)
 }
 
 static void
+reader_parse_znet_ifname(Reader *reader, char *argument)
+{
+    char *ifname;
+
+    ifname = get_word(&argument, ':');
+    if (!ifname) {
+        _LOGW(LOGD_CORE, "rd.znet_ifname= without argument");
+        return;
+    }
+
+    if (!g_hash_table_replace(reader->znet_ifnames, g_strdup(argument), g_strdup(ifname))) {
+        _LOGW(LOGD_CORE, "duplicate rd.znet_ifname for ifname=%s", ifname);
+    }
+}
+
+static void
 reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames)
 {
-    const char *    nettype;
-    const char *    subchannels[4] = {0, 0, 0, 0};
-    const char *    tmp;
-    gs_free char *  ifname = NULL;
-    const char *    prefix;
-    NMConnection *  connection;
+    const char     *nettype;
+    const char     *subchannels[4] = {0, 0, 0, 0};
+    const char     *tmp;
+    gs_free char   *ifname          = NULL;
+    gs_free char   *str_subchannels = NULL;
+    const char     *prefix;
+    NMConnection   *connection;
     NMSettingWired *s_wired;
     static int      count_ctc = 0;
     static int      count_eth = 0;
-    int             index;
+    int             index     = -1;
 
     nettype        = get_word(&argument, ',');
     subchannels[0] = get_word(&argument, ',');
@@ -1131,7 +1151,13 @@ reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames)
         }
     }
 
-    if (net_ifnames == TRUE) {
+    str_subchannels = g_strjoinv(",", (char **) subchannels);
+    ifname          = g_hash_table_lookup(reader->znet_ifnames, str_subchannels);
+
+    if (ifname) {
+        ifname = g_strdup(ifname);
+        g_hash_table_remove(reader->znet_ifnames, str_subchannels);
+    } else if (net_ifnames == TRUE) {
         const char *bus_id;
         size_t      bus_id_len;
         size_t      bus_id_start;
@@ -1144,6 +1170,7 @@ reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames)
 
         ifname = g_strdup_printf("%sc%s", prefix, bus_id);
     } else {
+        nm_assert(index > -1);
         ifname = g_strdup_printf("%s%d", prefix, index);
     }
 
@@ -1160,7 +1187,7 @@ reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames)
 
     while ((tmp = get_word(&argument, ',')) != NULL) {
         const char *key;
-        char *      val;
+        char       *val;
 
         val = strchr(tmp, '=');
         if (!val) {
@@ -1184,11 +1211,11 @@ reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames)
 static void
 reader_parse_ethtool(Reader *reader, char *argument)
 {
-    NMConnection *  connection;
+    NMConnection   *connection;
     NMSettingWired *s_wired;
-    const char *    autoneg_str;
-    const char *    speed_str;
-    const char *    interface;
+    const char     *autoneg_str;
+    const char     *speed_str;
+    const char     *interface;
     int             autoneg;
     guint           speed;
 
@@ -1251,11 +1278,11 @@ _normalize_conn(gpointer key, gpointer value, gpointer user_data)
 static void
 reader_add_nameservers(Reader *reader, GPtrArray *nameservers)
 {
-    NMConnection *     connection;
+    NMConnection      *connection;
     NMSettingIPConfig *s_ip;
     GHashTableIter     iter;
     int                addr_family;
-    const char *       ns;
+    const char        *ns;
     guint              i;
 
     for (i = 0; i < nameservers->len; i++) {
@@ -1316,21 +1343,22 @@ connection_set_needed_cb(gpointer key, gpointer value, gpointer user_data)
 }
 
 GHashTable *
-nmi_cmdline_reader_parse(const char *       sysfs_dir,
+nmi_cmdline_reader_parse(const char        *etc_connections_dir,
+                         const char        *sysfs_dir,
                          const char *const *argv,
-                         char **            hostname,
-                         gint64 *           carrier_timeout_sec)
+                         char             **hostname,
+                         gint64            *carrier_timeout_sec)
 {
-    Reader *          reader;
-    const char *      tag;
-    gboolean          ignore_bootif          = FALSE;
-    gboolean          neednet                = FALSE;
-    gs_free char *    bootif_val             = NULL;
-    gs_free char *    bootdev                = NULL;
-    gboolean          net_ifnames            = TRUE;
-    gs_unref_ptrarray GPtrArray *nameservers = NULL;
-    gs_unref_ptrarray GPtrArray *routes      = NULL;
-    gs_unref_ptrarray GPtrArray *znets       = NULL;
+    Reader                      *reader;
+    const char                  *tag;
+    gboolean                     ignore_bootif = FALSE;
+    gboolean                     neednet       = FALSE;
+    gs_free char                *bootif_val    = NULL;
+    gs_free char                *bootdev       = NULL;
+    gboolean                     net_ifnames   = TRUE;
+    gs_unref_ptrarray GPtrArray *nameservers   = NULL;
+    gs_unref_ptrarray GPtrArray *routes        = NULL;
+    gs_unref_ptrarray GPtrArray *znets         = NULL;
     int                          i;
     guint64                      dhcp_timeout   = 90;
     guint64                      dhcp_num_tries = 1;
@@ -1339,7 +1367,7 @@ nmi_cmdline_reader_parse(const char *       sysfs_dir,
 
     for (i = 0; argv[i]; i++) {
         gs_free char *argument_clone = NULL;
-        char *        argument;
+        char         *argument;
 
         argument_clone = g_strdup(argv[i]);
         argument       = argument_clone;
@@ -1375,8 +1403,8 @@ nmi_cmdline_reader_parse(const char *       sysfs_dir,
 
     for (i = 0; argv[i]; i++) {
         gs_free char *argument_clone = NULL;
-        char *        argument;
-        char *        word;
+        char         *argument;
+        char         *word;
 
         argument_clone = g_strdup(argv[i]);
         argument       = argument_clone;
@@ -1422,6 +1450,8 @@ nmi_cmdline_reader_parse(const char *       sysfs_dir,
             if (!znets)
                 znets = g_ptr_array_new_with_free_func(g_free);
             g_ptr_array_add(znets, g_strdup(argument));
+        } else if (nm_streq(tag, "rd.znet_ifname")) {
+            reader_parse_znet_ifname(reader, argument);
         } else if (g_ascii_strcasecmp(tag, "BOOTIF") == 0) {
             nm_clear_g_free(&bootif_val);
             bootif_val = g_strdup(argument);
@@ -1430,7 +1460,7 @@ nmi_cmdline_reader_parse(const char *       sysfs_dir,
     }
 
     for (i = 0; i < reader->vlan_parents->len; i++) {
-        NMConnection *     connection;
+        NMConnection      *connection;
         NMSettingIPConfig *s_ip;
 
         /* Disable IP configuration for parent connections of VLANs,
@@ -1459,9 +1489,9 @@ nmi_cmdline_reader_parse(const char *       sysfs_dir,
     if (ignore_bootif)
         nm_clear_g_free(&bootif_val);
     if (bootif_val) {
-        NMConnection *  connection;
+        NMConnection   *connection;
         NMSettingWired *s_wired;
-        const char *    bootif = bootif_val;
+        const char     *bootif = bootif_val;
         char            prefix[4];
 
         if (!nm_utils_hwaddr_valid(bootif, ETH_ALEN)) {
@@ -1512,7 +1542,8 @@ nmi_cmdline_reader_parse(const char *       sysfs_dir,
     }
 
     if (neednet) {
-        if (g_hash_table_size(reader->hash) == 0) {
+        if (!(etc_connections_dir && g_file_test(etc_connections_dir, G_FILE_TEST_IS_DIR))
+            && g_hash_table_size(reader->hash) == 0) {
             /* Make sure there's some connection. */
             reader_get_default_connection(reader);
         }
@@ -1531,6 +1562,10 @@ nmi_cmdline_reader_parse(const char *       sysfs_dir,
             reader_parse_rd_znet(reader, znets->pdata[i], net_ifnames);
     }
 
+    if (g_hash_table_size(reader->znet_ifnames)) {
+        _LOGW(LOGD_CORE, "Mismatch between rd.znet_ifname and rd.znet");
+    }
+
     g_hash_table_foreach(reader->hash, _normalize_conn, NULL);
 
     NM_SET_OUT(hostname, g_steal_pointer(&reader->hostname));