diff options
Diffstat (limited to 'src/initrd/nm-initrd-generator.c')
| -rw-r--r-- | src/initrd/nm-initrd-generator.c | 288 |
1 files changed, 155 insertions, 133 deletions
diff --git a/src/initrd/nm-initrd-generator.c b/src/initrd/nm-initrd-generator.c index f984ed73..1a33713e 100644 --- a/src/initrd/nm-initrd-generator.c +++ b/src/initrd/nm-initrd-generator.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -12,147 +12,169 @@ /*****************************************************************************/ -#define _NMLOG(level, domain, ...) \ - nm_log ((level), (domain), NULL, NULL, \ - "initrd-generator: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__) \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) +#define _NMLOG(level, domain, ...) \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "initrd-generator: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) /*****************************************************************************/ static void -output_conn (gpointer key, gpointer value, gpointer user_data) +output_conn(gpointer key, gpointer value, gpointer user_data) { - const char *basename = key; - NMConnection *connection = value; - char *connections_dir = user_data; - gs_unref_keyfile GKeyFile *file = NULL; - gs_free char *data = NULL; - gs_free_error GError *error = NULL; - gsize len; - - if (!nm_connection_normalize (connection, NULL, NULL, &error)) - goto err_out; - - file = nm_keyfile_write (connection, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); - if (file == NULL) - goto err_out; - - data = g_key_file_to_data (file, &len, &error); - if (!data) - goto err_out; - - if (connections_dir) { - gs_free char *filename = NULL; - gs_free char *full_filename = NULL; - - filename = nm_keyfile_utils_create_filename (basename, TRUE); - full_filename = g_build_filename (connections_dir, filename, NULL); - - if (!nm_utils_file_set_contents (full_filename, - data, - len, - 0600, - NULL, - &error)) - goto err_out; - } else - g_print ("\n*** Connection '%s' ***\n\n%s", basename, data); - - return; + const char * basename = key; + NMConnection * connection = value; + char * connections_dir = user_data; + nm_auto_unref_keyfile GKeyFile *file = NULL; + gs_free char * data = NULL; + gs_free_error GError *error = NULL; + gsize len; + + if (!nm_connection_normalize(connection, NULL, NULL, &error)) + goto err_out; + + file = nm_keyfile_write(connection, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + if (file == NULL) + goto err_out; + + data = g_key_file_to_data(file, &len, &error); + if (!data) + goto err_out; + + if (connections_dir) { + gs_free char *filename = NULL; + gs_free char *full_filename = NULL; + + filename = nm_keyfile_utils_create_filename(basename, TRUE); + full_filename = g_build_filename(connections_dir, filename, NULL); + + if (!nm_utils_file_set_contents(full_filename, data, len, 0600, NULL, &error)) + goto err_out; + } else + g_print("\n*** Connection '%s' ***\n\n%s", basename, data); + + return; err_out: - g_print ("%s\n", error->message); + g_print("%s\n", error->message); } -#define DEFAULT_SYSFS_DIR "/sys" -#define DEFAULT_INITRD_DATA_DIR NMRUNDIR "/initrd" +#define DEFAULT_SYSFS_DIR "/sys" +#define DEFAULT_INITRD_DATA_DIR NMRUNDIR "/initrd" int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - GHashTable *connections; - gs_free char *connections_dir = NULL; - gs_free char *initrd_dir = NULL; - gs_free char *sysfs_dir = NULL; - gboolean dump_to_stdout = FALSE; - gs_strfreev char **remaining = NULL; - GOptionEntry option_entries[] = { - { "connections-dir", 'c', 0, G_OPTION_ARG_FILENAME, &connections_dir, "Output connection directory", NM_KEYFILE_PATH_NAME_RUN }, - { "initrd-data-dir", 'i', 0, G_OPTION_ARG_FILENAME, &initrd_dir, "Output initrd data directory", DEFAULT_INITRD_DATA_DIR }, - { "sysfs-dir", 'd', 0, G_OPTION_ARG_FILENAME, &sysfs_dir, "The sysfs mount point", DEFAULT_SYSFS_DIR }, - { "stdout", 's', 0, G_OPTION_ARG_NONE, &dump_to_stdout, "Dump connections to standard output", NULL }, - { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &remaining, NULL, NULL }, - { NULL } - }; - GOptionContext *option_context; - gs_free_error GError *error = NULL; - gs_free char *hostname = NULL; - int errsv; - - option_context = g_option_context_new ("-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] " - "[bootdev=...] [nameserver=...] [rd.peerdns=...] [rd.bootif=...] [BOOTIF=...] [rd.znet=...] ... "); - - g_option_context_set_summary (option_context, "Generate early NetworkManager configuration."); - g_option_context_set_description (option_context, - "This tool scans the command line for options relevant to network\n" - "configuration and creates configuration files for an early instance\n" - "of NetworkManager run from the initial ramdisk during early boot."); - g_option_context_add_main_entries (option_context, option_entries, GETTEXT_PACKAGE); - - if (!g_option_context_parse (option_context, &argc, &argv, &error)) { - _LOGW (LOGD_CORE, "%s", error->message); - return 1; - } - - if (!remaining) { - /* No arguments, no networking. Don't bother. */ - return 0; - } - - if (!connections_dir) - connections_dir = g_strdup (NM_KEYFILE_PATH_NAME_RUN); - if (!sysfs_dir) - 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 (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); - - if (dump_to_stdout) { - if (hostname) - g_print ("\n*** Hostname '%s' ***\n", hostname); - } else { - 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 (hostname) { - gs_free char *hostname_file = NULL; - gs_free char *data = NULL; - - hostname_file = g_strdup_printf ("%s/hostname", initrd_dir); - data = g_strdup_printf ("%s\n", hostname); - - if (!g_file_set_contents (hostname_file, data, strlen (data), &error)) { - _LOGW (LOGD_CORE, "%s: %s", hostname_file, error->message); - return 1; - } - } - } - - return 0; + GHashTable * connections; + gs_free char * connections_dir = NULL; + gs_free char * initrd_dir = NULL; + gs_free char * sysfs_dir = NULL; + gboolean dump_to_stdout = FALSE; + gs_strfreev char **remaining = NULL; + GOptionEntry option_entries[] = { + {"connections-dir", + 'c', + 0, + G_OPTION_ARG_FILENAME, + &connections_dir, + "Output connection directory", + NM_KEYFILE_PATH_NAME_RUN}, + {"initrd-data-dir", + 'i', + 0, + G_OPTION_ARG_FILENAME, + &initrd_dir, + "Output initrd data directory", + DEFAULT_INITRD_DATA_DIR}, + {"sysfs-dir", + 'd', + 0, + G_OPTION_ARG_FILENAME, + &sysfs_dir, + "The sysfs mount point", + DEFAULT_SYSFS_DIR}, + {"stdout", + 's', + 0, + G_OPTION_ARG_NONE, + &dump_to_stdout, + "Dump connections to standard output", + NULL}, + {G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &remaining, NULL, NULL}, + {NULL}}; + nm_auto_free_option_context GOptionContext *option_context = NULL; + gs_free_error GError *error = NULL; + gs_free char * hostname = NULL; + int errsv; + + option_context = g_option_context_new( + "-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] " + "[bootdev=...] [nameserver=...] [rd.peerdns=...] [rd.bootif=...] [BOOTIF=...] " + "[rd.znet=...] ... "); + + g_option_context_set_summary(option_context, "Generate early NetworkManager configuration."); + g_option_context_set_description( + option_context, + "This tool scans the command line for options relevant to network\n" + "configuration and creates configuration files for an early instance\n" + "of NetworkManager run from the initial ramdisk during early boot."); + g_option_context_add_main_entries(option_context, option_entries, GETTEXT_PACKAGE); + + if (!g_option_context_parse(option_context, &argc, &argv, &error)) { + _LOGW(LOGD_CORE, "%s", error->message); + return 1; + } + + if (!remaining) { + /* No arguments, no networking. Don't bother. */ + return 0; + } + + if (!connections_dir) + connections_dir = g_strdup(NM_KEYFILE_PATH_NAME_RUN); + if (!sysfs_dir) + 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 (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); + + if (dump_to_stdout) { + if (hostname) + g_print("\n*** Hostname '%s' ***\n", hostname); + } else { + 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 (hostname) { + gs_free char *hostname_file = NULL; + gs_free char *data = NULL; + + hostname_file = g_strdup_printf("%s/hostname", initrd_dir); + data = g_strdup_printf("%s\n", hostname); + + if (!g_file_set_contents(hostname_file, data, strlen(data), &error)) { + _LOGW(LOGD_CORE, "%s: %s", hostname_file, error->message); + return 1; + } + } + } + + return 0; } |