2019-09-10 11:19:01 +02:00
|
|
|
// SPDX-License-Identifier: LGPL-2.1+
|
2019-09-25 13:13:40 +02:00
|
|
|
/*
|
2018-04-28 20:36:15 +02:00
|
|
|
* Copyright (C) 2018 Red Hat, Inc.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "nm-default.h"
|
|
|
|
|
#include "nm-core-utils.h"
|
|
|
|
|
#include "nm-core-internal.h"
|
|
|
|
|
#include "nm-keyfile-internal.h"
|
|
|
|
|
#include "nm-initrd-generator.h"
|
2019-04-15 08:16:00 +02:00
|
|
|
#include "nm-glib-aux/nm-io-utils.h"
|
2018-04-28 20:36:15 +02:00
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#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)
|
|
|
|
|
{
|
|
|
|
|
const char *basename = key;
|
|
|
|
|
NMConnection *connection = value;
|
|
|
|
|
char *connections_dir = user_data;
|
2018-10-19 12:11:27 +02:00
|
|
|
gs_unref_keyfile GKeyFile *file = NULL;
|
2018-04-28 20:36:15 +02:00
|
|
|
gs_free char *data = NULL;
|
2018-10-19 12:11:27 +02:00
|
|
|
gs_free_error GError *error = NULL;
|
2018-04-28 20:36:15 +02:00
|
|
|
gsize len;
|
|
|
|
|
|
2018-10-19 12:11:27 +02:00
|
|
|
if (!nm_connection_normalize (connection, NULL, NULL, &error))
|
|
|
|
|
goto err_out;
|
2018-04-28 20:36:15 +02:00
|
|
|
|
|
|
|
|
file = nm_keyfile_write (connection, NULL, NULL, &error);
|
2018-10-19 12:11:27 +02:00
|
|
|
if (file == NULL)
|
|
|
|
|
goto err_out;
|
2018-04-28 20:36:15 +02:00
|
|
|
|
|
|
|
|
data = g_key_file_to_data (file, &len, &error);
|
2018-10-19 12:11:27 +02:00
|
|
|
if (!data)
|
|
|
|
|
goto err_out;
|
2018-04-28 20:36:15 +02:00
|
|
|
|
2018-10-19 12:11:27 +02:00
|
|
|
if (connections_dir) {
|
|
|
|
|
gs_free char *filename = NULL;
|
|
|
|
|
gs_free char *full_filename = NULL;
|
|
|
|
|
|
2018-10-19 12:34:17 +02:00
|
|
|
filename = nm_keyfile_utils_create_filename (basename, TRUE);
|
|
|
|
|
full_filename = g_build_filename (connections_dir, filename, NULL);
|
2018-10-19 12:11:27 +02:00
|
|
|
|
shared,all: return boolean success from nm_utils_file_get_contents()
... and nm_utils_fd_get_contents() and nm_utils_file_set_contents().
Don't mix negative errno return value with a GError output. Instead,
return a boolean result indicating success or failure.
Also, optionally
- output GError
- set out_errsv to the positive errno (or 0 on success)
Obviously, the return value and the output arguments (contents, length,
out_errsv, error) must all agree in their success/failure result.
That means, you may check any of the return value, out_errsv, error, and
contents to reliably detect failure or success.
Also note that out_errsv gives the positive(!) errno. But you probably
shouldn't care about the distinction and use nm_errno_native() either
way to normalize the value.
2019-08-08 11:09:58 +02:00
|
|
|
if (!nm_utils_file_set_contents (full_filename,
|
|
|
|
|
data,
|
|
|
|
|
len,
|
|
|
|
|
0600,
|
|
|
|
|
NULL,
|
|
|
|
|
&error))
|
2018-10-19 12:11:27 +02:00
|
|
|
goto err_out;
|
|
|
|
|
} else
|
2019-07-02 09:33:20 +02:00
|
|
|
g_print ("\n*** Connection '%s' ***\n\n%s", basename, data);
|
2018-04-28 20:36:15 +02:00
|
|
|
|
2018-10-19 12:11:27 +02:00
|
|
|
return;
|
|
|
|
|
err_out:
|
|
|
|
|
g_print ("%s\n", error->message);
|
2018-04-28 20:36:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define DEFAULT_SYSFS_DIR "/sys"
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
GHashTable *connections;
|
|
|
|
|
gs_free char *connections_dir = NULL;
|
|
|
|
|
gs_free char *sysfs_dir = NULL;
|
|
|
|
|
gboolean dump_to_stdout = FALSE;
|
|
|
|
|
gs_strfreev char **remaining = NULL;
|
|
|
|
|
GOptionEntry option_entries[] = {
|
2018-10-19 12:34:17 +02:00
|
|
|
{ "connections-dir", 'c', 0, G_OPTION_ARG_FILENAME, &connections_dir, "Output connection directory", NM_KEYFILE_PATH_NAME_RUN },
|
2018-04-28 20:36:15 +02:00
|
|
|
{ "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;
|
|
|
|
|
GError *error = NULL;
|
2019-01-31 13:29:21 +01:00
|
|
|
int errsv;
|
2018-04-28 20:36:15 +02:00
|
|
|
|
|
|
|
|
option_context = g_option_context_new ("-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] "
|
2019-09-20 16:25:17 +02:00
|
|
|
"[bootdev=...] [nameserver=...] [rd.peerdns=...] [rd.bootif=...] [BOOTIF=...] [rd.znet=...] ... ");
|
2018-04-28 20:36:15 +02:00
|
|
|
|
|
|
|
|
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)) {
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "%s", error->message);
|
2018-04-28 20:36:15 +02:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!remaining) {
|
|
|
|
|
/* No arguments, no networking. Don't bother. */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!connections_dir)
|
2018-10-19 12:34:17 +02:00
|
|
|
connections_dir = g_strdup (NM_KEYFILE_PATH_NAME_RUN);
|
2018-04-28 20:36:15 +02:00
|
|
|
if (!sysfs_dir)
|
|
|
|
|
sysfs_dir = g_strdup (DEFAULT_SYSFS_DIR);
|
|
|
|
|
if (dump_to_stdout)
|
|
|
|
|
g_clear_pointer (&connections_dir, g_free);
|
|
|
|
|
|
|
|
|
|
if (connections_dir && g_mkdir_with_parents (connections_dir, 0755) != 0) {
|
2019-01-31 13:29:21 +01:00
|
|
|
errsv = errno;
|
2019-01-31 17:22:18 +01:00
|
|
|
_LOGW (LOGD_CORE, "%s: %s", connections_dir, nm_strerror_native (errsv));
|
2018-04-28 20:36:15 +02:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-27 08:32:08 +02:00
|
|
|
connections = nmi_cmdline_reader_parse (sysfs_dir, (const char *const*) remaining);
|
2018-04-28 20:36:15 +02:00
|
|
|
g_hash_table_foreach (connections, output_conn, connections_dir);
|
|
|
|
|
g_hash_table_destroy (connections);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|