initrd: add configuration generator

nm-initrd-generator scans the command line for options relevant to network
configuration and creates configuration files for an early instance of
NetworkManager run from the initial ramdisk during early boot.
This commit is contained in:
Lubomir Rintel 2018-04-28 20:36:15 +02:00
parent ecc074b2f8
commit 9f9609555d
7 changed files with 302 additions and 0 deletions

1
.gitignore vendored
View File

@ -252,6 +252,7 @@ test-*.trs
/src/dhcp/tests/test-dhcp-options
/src/dhcp/tests/test-dhcp-utils
/src/dnsmasq/tests/test-dnsmasq-utils
/src/initrd/nm-initrd-generator
/src/initrd/tests/test-cmdline-reader
/src/initrd/tests/test-ibft-reader
/src/nm-iface-helper

View File

@ -1936,6 +1936,24 @@ src_initrd_libnmi_core_la_SOURCES = \
src/initrd/nmi-ibft-reader.c \
$(NULL)
libexec_PROGRAMS += src/initrd/nm-initrd-generator
src_initrd_nm_initrd_generator_CPPFLAGS = \
$(src_cppflags)
src_initrd_nm_initrd_generator_SOURCES = \
src/initrd/nm-initrd-generator.c
src_initrd_nm_initrd_generator_LDADD = \
libnm-core/libnm-core.la \
src/initrd/libnmi-core.la \
src/libNetworkManagerBase.la \
$(GLIB_LIBS)
src_initrd_nm_initrd_generator_LDFLAGS = \
-Wl,--version-script="$(srcdir)/linker-script-binary.ver" \
$(SANITIZER_EXEC_LDFLAGS)
check_programs += src/initrd/tests/test-ibft-reader
src_initrd_tests_test_ibft_reader_CPPFLAGS = \
@ -2166,6 +2184,7 @@ src_initrd_tests_test_cmdline_reader_LDADD = \
$(GLIB_LIBS)
$(src_initrd_libnmi_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
$(src_initrd_nm_initrd_generator_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
$(src_initrd_tests_test_cmdline_reader_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
$(src_initrd_tests_test_ibft_reader_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
@ -4861,6 +4880,7 @@ man_pages += \
man/NetworkManager.8 \
man/NetworkManager.conf.5 \
man/nm-online.1 \
man/nm-initrd-generator.8 \
man/nmcli-examples.7 \
man/nmcli.1 \
man/nmtui.1

View File

@ -687,6 +687,7 @@ fi
%{_libexecdir}/nm-dhcp-helper
%{_libexecdir}/nm-dispatcher
%{_libexecdir}/nm-iface-helper
%{_libexecdir}/nm-initrd-generator
%dir %{_libdir}/%{name}
%dir %{nmplugindir}
%{nmplugindir}/libnm-settings-plugin*.so

View File

@ -83,6 +83,7 @@ content_files = \
$(top_builddir)/man/nmcli.xml \
$(top_builddir)/man/nmtui.xml \
$(top_builddir)/man/nm-online.xml \
$(top_builddir)/man/nm-initrd-generator.xml \
$(top_builddir)/man/NetworkManager.xml \
$(top_builddir)/man/NetworkManager.conf.xml \
$(top_builddir)/man/nmcli-examples.xml \

View File

@ -77,6 +77,7 @@
<xi:include href="../../man/nm-settings-keyfile.xml"><xi:fallback /></xi:include>
<xi:include href="../../man/nm-settings-ifcfg-rh.xml"><xi:fallback /></xi:include>
<xi:include href="../../man/nm-online.xml"/>
<xi:include href="../../man/nm-initrd-generator.xml"/>
<xi:include href="../../man/nm-openvswitch.xml"/>
</part>

140
man/nm-initrd-generator.xml Normal file
View File

@ -0,0 +1,140 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
<!--
nm-initrd-generator(8) manual page
Copyright 2018 Red Hat, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. You may obtain a copy of the GNU Free Documentation License
from the Free Software Foundation by visiting their Web site or by
writing to:
Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-->
<refentry id='nm-initrd-generator'>
<refentryinfo>
<title>nm-initrd-generator</title>
<author>NetworkManager developers</author>
</refentryinfo>
<refmeta>
<refentrytitle>nm-initrd-generator</refentrytitle>
<manvolnum>8</manvolnum>
<refmiscinfo class="source">NetworkManager</refmiscinfo>
<refmiscinfo class="manual">System Administration</refmiscinfo>
<refmiscinfo class="version">&NM_VERSION;</refmiscinfo>
</refmeta>
<refnamediv>
<refname>nm-initrd-generator</refname>
<refpurpose>early boot NetworkManager configuration generator</refpurpose>
</refnamediv>
<refsynopsisdiv id='synopsis'>
<cmdsynopsis>
<command>nm-initrd-generator</command>
<arg choice="opt" rep="repeat"><replaceable>OPTIONS</replaceable></arg>
<arg choice="plain">--</arg>
<arg choice="opt" rep="repeat"><replaceable>CMDLINE</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1 id='description'><title>Description</title>
<para><command>nm-initrd-generator</command> scans the command line for options
relevant to network configuration and creates configuration files for an early
instance of NetworkManager run from the initial ramdisk during early boot.</para>
</refsect1>
<refsect1 id='options'><title>Options</title>
<variablelist>
<varlistentry>
<term>
<group choice='plain'>
<arg choice='plain'><option>-c</option></arg>
<arg choice='plain'><option>--connections-dir</option></arg>
</group>
<arg choice='plain'><replaceable>path</replaceable></arg>
</term>
<listitem>
<para>Output connection directory.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<group choice='plain'>
<arg choice='plain'><option>-d</option></arg>
<arg choice='plain'><option>--sysfs-dir</option></arg>
</group>
<arg choice='plain'><replaceable>path</replaceable></arg>
</term>
<listitem>
<para>The sysfs mount point.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<group choice='plain'>
<arg choice='plain'><option>-s</option></arg>
<arg choice='plain'><option>--stdout</option></arg>
</group>
</term>
<listitem>
<para>Dump connections to standard output. Useful for debugging.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>CMDLINE</replaceable></term>
<listitem>
<para>The options that appear on the kernel command line. The following options are recognized:</para>
<simplelist>
<member><option>ip</option></member>
<member><option>rd.route</option></member>
<member><option>bridge</option></member>
<member><option>bond</option></member>
<member><option>team</option></member>
<member><option>vlan</option></member>
<member><option>bootdev</option></member>
<member><option>nameserver</option></member>
<member><option>rd.peerdns</option></member>
<member><option>rd.bootif</option></member>
<member><option>BOOTIF</option></member>
</simplelist>
<para>Please consult the <citerefentry><refentrytitle>dracut.cmdline</refentrytitle><manvolnum>7</manvolnum></citerefentry>
manual for the documentation of the precise format of the values supported.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id='exit_status'><title>Exit Status</title>
<para><command>nm-initrd-generator</command> exits with status 0. It ignores unrecognized
options and prints an error message if it encounters a malformed option.</para>
</refsect1>
<refsect1 id='see_also'><title>See Also</title>
<para><link linkend='dracut.cmdline'><citerefentry><refentrytitle>dracut.cmdline</refentrytitle><manvolnum>7</manvolnum></citerefentry></link>,
<link linkend='NetworkManager'><citerefentry><refentrytitle>NetworkManager</refentrytitle><manvolnum>8</manvolnum></citerefentry></link>.</para>
</refsect1>
</refentry>

View File

@ -0,0 +1,138 @@
/* NetworkManager initrd configuration generator
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* 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"
/*****************************************************************************/
#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;
GKeyFile *file;
gs_free char *data = NULL;
GError *error = NULL;
gsize len;
if (!nm_connection_normalize (connection, NULL, NULL, &error)) {
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
file = nm_keyfile_write (connection, NULL, NULL, &error);
if (file == NULL) {
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
data = g_key_file_to_data (file, &len, &error);
if (!data) {
g_print ("%s\n", error->message);
g_error_free (error);
} else if (connections_dir) {
char *filename = g_build_filename (connections_dir, basename, NULL);
if (!nm_utils_file_set_contents (filename, data, len, 0600, &error)) {
g_print ("%s\n", error->message);
g_error_free (error);
}
g_free (filename);
} else {
g_print ("\n*** Connection '%s' ***\n\n%s\n", basename, data);
}
g_key_file_free (file);
}
#define DEFAULT_CONNECTIONS_DIR NMRUNDIR "/system-connections"
#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[] = {
{ "connections-dir", 'c', 0, G_OPTION_ARG_FILENAME, &connections_dir, "Output connection directory", DEFAULT_CONNECTIONS_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;
GError *error = NULL;
option_context = g_option_context_new ("-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] "
"[bootdev=...] [nameserver=...] [rd.peerdns=...] [rd.bootif=...] [BOOTIF=...] ... ");
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\n", error->message);
return 1;
}
if (!remaining) {
/* No arguments, no networking. Don't bother. */
return 0;
}
if (!connections_dir)
connections_dir = g_strdup (DEFAULT_CONNECTIONS_DIR);
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) {
_LOGW (LOGD_CORE, "%s: %s\n", connections_dir, strerror (errno));
return 1;
}
connections = nmi_cmdline_reader_parse (sysfs_dir, remaining);
g_hash_table_foreach (connections, output_conn, connections_dir);
g_hash_table_destroy (connections);
return 0;
}