mirror of
https://github.com/systemd/systemd.git
synced 2024-11-24 10:43:35 +08:00
Merge pull request #4123 from keszybz/network-file-dropins
Network file dropins
This commit is contained in:
commit
6ac288a990
@ -58,31 +58,38 @@
|
||||
<citerefentry><refentrytitle>systemd-networkd</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
|
||||
</para>
|
||||
|
||||
<para>Virtual Network Device files must have the extension
|
||||
<filename>.netdev</filename>; other extensions are ignored.
|
||||
Virtual network devices are created as soon as networkd is
|
||||
started. If a netdev with the specified name already exists,
|
||||
networkd will use that as-is rather than create its own. Note that
|
||||
the settings of the pre-existing netdev will not be changed by
|
||||
<para>The main Virtual Network Device file must have the extension <filename>.netdev</filename>;
|
||||
other extensions are ignored. Virtual network devices are created as soon as networkd is
|
||||
started. If a netdev with the specified name already exists, networkd will use that as-is rather
|
||||
than create its own. Note that the settings of the pre-existing netdev will not be changed by
|
||||
networkd.</para>
|
||||
|
||||
<para>The <filename>.netdev</filename> files are read from the
|
||||
files located in the system network directory
|
||||
<filename>/usr/lib/systemd/network</filename>, the volatile
|
||||
runtime network directory
|
||||
<filename>/run/systemd/network</filename> and the local
|
||||
administration network directory
|
||||
<filename>/etc/systemd/network</filename>. All configuration files
|
||||
are collectively sorted and processed in lexical order, regardless
|
||||
of the directories in which they live. However, files with
|
||||
identical filenames replace each other. Files in
|
||||
<filename>/etc</filename> have the highest priority, files in
|
||||
<filename>/run</filename> take precedence over files with the same
|
||||
name in <filename>/usr/lib</filename>. This can be used to
|
||||
override a system-supplied configuration file with a local file if
|
||||
needed. As a special case, an empty file (file size 0) or symlink
|
||||
with the same name pointing to <filename>/dev/null</filename>
|
||||
disables the configuration file entirely (it is "masked").</para>
|
||||
<para>The <filename>.netdev</filename> files are read from the files located in the system
|
||||
network directory <filename>/usr/lib/systemd/network</filename>, the volatile runtime network
|
||||
directory <filename>/run/systemd/network</filename> and the local administration network
|
||||
directory <filename>/etc/systemd/network</filename>. All configuration files are collectively
|
||||
sorted and processed in lexical order, regardless of the directories in which they live.
|
||||
However, files with identical filenames replace each other. Files in <filename>/etc</filename>
|
||||
have the highest priority, files in <filename>/run</filename> take precedence over files with
|
||||
the same name in <filename>/usr/lib</filename>. This can be used to override a system-supplied
|
||||
configuration file with a local file if needed. As a special case, an empty file (file size 0)
|
||||
or symlink with the same name pointing to <filename>/dev/null</filename> disables the
|
||||
configuration file entirely (it is "masked").</para>
|
||||
|
||||
<para>Along with the netdev file <filename>foo.netdev</filename>, a "drop-in" directory
|
||||
<filename>foo.netdev.d/</filename> may exist. All files with the suffix <literal>.conf</literal>
|
||||
from this directory will be parsed after the file itself is parsed. This is useful to alter or
|
||||
add configuration settings, without having to modify the main configuration file. Each drop-in
|
||||
file must have appropriate section headers.</para>
|
||||
|
||||
<para>In addition to <filename>/etc/systemd/network</filename>, drop-in <literal>.d</literal>
|
||||
directories can be placed in <filename>/usr/lib/systemd/network</filename> or
|
||||
<filename>/run/systemd/network</filename> directories. Drop-in files in
|
||||
<filename>/etc</filename> take precedence over those in <filename>/run</filename> which in turn
|
||||
take precedence over those in <filename>/usr/lib</filename>. Drop-in files under any of these
|
||||
directories take precedence over the main netdev file wherever located. (Of course, since
|
||||
<filename>/run</filename> is temporary and <filename>/usr/lib</filename> is for vendors, it is
|
||||
unlikely drop-ins should be used in either of those places.)</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
@ -58,31 +58,40 @@
|
||||
<citerefentry><refentrytitle>systemd-networkd</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
|
||||
</para>
|
||||
|
||||
<para>Network files must have the extension
|
||||
<filename>.network</filename>; other extensions are ignored.
|
||||
Networks are applied to links whenever the links appear.</para>
|
||||
<para>The main network file must have the extension <filename>.network</filename>; other
|
||||
extensions are ignored. Networks are applied to links whenever the links appear.</para>
|
||||
|
||||
<para>The <filename>.network</filename> files are read from the
|
||||
files located in the system network directory
|
||||
<filename>/usr/lib/systemd/network</filename>, the volatile
|
||||
runtime network directory
|
||||
<filename>/run/systemd/network</filename> and the local
|
||||
administration network directory
|
||||
<filename>/etc/systemd/network</filename>. All configuration files
|
||||
are collectively sorted and processed in lexical order, regardless
|
||||
of the directories in which they live. However, files with
|
||||
identical filenames replace each other. Files in
|
||||
<filename>/etc</filename> have the highest priority, files in
|
||||
<filename>/run</filename> take precedence over files with the same
|
||||
name in <filename>/usr/lib</filename>. This can be used to
|
||||
override a system-supplied configuration file with a local file if
|
||||
needed. As a special case, an empty file (file size 0) or symlink
|
||||
with the same name pointing to <filename>/dev/null</filename>
|
||||
disables the configuration file entirely (it is "masked").</para>
|
||||
<para>The <filename>.network</filename> files are read from the files located in the system
|
||||
network directory <filename>/usr/lib/systemd/network</filename>, the volatile runtime network
|
||||
directory <filename>/run/systemd/network</filename> and the local administration network
|
||||
directory <filename>/etc/systemd/network</filename>. All configuration files are collectively
|
||||
sorted and processed in lexical order, regardless of the directories in which they live.
|
||||
However, files with identical filenames replace each other. Files in <filename>/etc</filename>
|
||||
have the highest priority, files in <filename>/run</filename> take precedence over files with
|
||||
the same name in <filename>/usr/lib</filename>. This can be used to override a system-supplied
|
||||
configuration file with a local file if needed. As a special case, an empty file (file size 0)
|
||||
or symlink with the same name pointing to <filename>/dev/null</filename> disables the
|
||||
configuration file entirely (it is "masked").</para>
|
||||
|
||||
<para>Note that an interface without any static IPv6 addresses configured, and neither DHCPv6 nor IPv6LL enabled,
|
||||
shall be considered to have no IPv6 support. IPv6 will be automatically disabled for that interface by writing "1"
|
||||
to <filename>/proc/sys/net/ipv6/conf/<replaceable>ifname</replaceable>/disable_ipv6</filename>.
|
||||
<para>Along with the network file <filename>foo.network</filename>, a "drop-in" directory
|
||||
<filename>foo.network.d/</filename> may exist. All files with the suffix
|
||||
<literal>.conf</literal> from this directory will be parsed after the file itself is
|
||||
parsed. This is useful to alter or add configuration settings, without having to modify the main
|
||||
configuration file. Each drop-in file must have appropriate section headers.</para>
|
||||
|
||||
<para>In addition to <filename>/etc/systemd/network</filename>, drop-in <literal>.d</literal>
|
||||
directories can be placed in <filename>/usr/lib/systemd/network</filename> or
|
||||
<filename>/run/systemd/network</filename> directories. Drop-in files in
|
||||
<filename>/etc</filename> take precedence over those in <filename>/run</filename> which in turn
|
||||
take precedence over those in <filename>/usr/lib</filename>. Drop-in files under any of these
|
||||
directories take precedence over the main netdev file wherever located. (Of course, since
|
||||
<filename>/run</filename> is temporary and <filename>/usr/lib</filename> is for vendors, it is
|
||||
unlikely drop-ins should be used in either of those places.)</para>
|
||||
|
||||
<para>Note that an interface without any static IPv6 addresses configured, and neither DHCPv6
|
||||
nor IPv6LL enabled, shall be considered to have no IPv6 support. IPv6 will be automatically
|
||||
disabled for that interface by writing "1" to
|
||||
<filename>/proc/sys/net/ipv6/conf/<replaceable>ifname</replaceable>/disable_ipv6</filename>.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
|
@ -144,71 +144,71 @@
|
||||
<option>false</option> and <option>off</option> are
|
||||
equivalent.</para>
|
||||
|
||||
<para>Time span values encoded in unit files can be written in various formats. A stand-alone number specifies a
|
||||
time in seconds. If suffixed with a time unit, the unit is honored. A concatenation of multiple values with units
|
||||
is supported, in which case the values are added up. Example: <literal>50</literal> refers to 50 seconds;
|
||||
<literal>2min 200ms</literal> refers to 2 minutes and 200 milliseconds, i.e. 120200 ms. The following time units
|
||||
are understood: <literal>s</literal>, <literal>min</literal>, <literal>h</literal>, <literal>d</literal>,
|
||||
<para>Time span values encoded in unit files can be written in various formats. A stand-alone
|
||||
number specifies a time in seconds. If suffixed with a time unit, the unit is honored. A
|
||||
concatenation of multiple values with units is supported, in which case the values are added
|
||||
up. Example: <literal>50</literal> refers to 50 seconds; <literal>2min 200ms</literal> refers to
|
||||
2 minutes and 200 milliseconds, i.e. 120200 ms. The following time units are understood:
|
||||
<literal>s</literal>, <literal>min</literal>, <literal>h</literal>, <literal>d</literal>,
|
||||
<literal>w</literal>, <literal>ms</literal>, <literal>us</literal>. For details see
|
||||
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
||||
|
||||
<para>Empty lines and lines starting with <literal>#</literal> or <literal>;</literal> are ignored. This may be
|
||||
used for commenting. Lines ending in a backslash are concatenated with the following line while reading and the
|
||||
backslash is replaced by a space character. This may be used to wrap long lines.</para>
|
||||
<para>Empty lines and lines starting with <literal>#</literal> or <literal>;</literal> are
|
||||
ignored. This may be used for commenting. Lines ending in a backslash are concatenated with the
|
||||
following line while reading and the backslash is replaced by a space character. This may be
|
||||
used to wrap long lines.</para>
|
||||
|
||||
<para>Units can be aliased (have an alternative name), by creating a symlink from the new name to the existing name
|
||||
in one of the unit search paths. For example, <filename>systemd-networkd.service</filename> has the alias
|
||||
<filename>dbus-org.freedesktop.network1.service</filename>, created during installation as the symlink
|
||||
<filename>/usr/lib/systemd/system/dbus-org.freedesktop.network1.service</filename>. In addition, unit files may
|
||||
specify aliases through the <varname>Alias=</varname> directive in the [Install] section; those aliases are only
|
||||
effective when the unit is enabled. When the unit is enabled, symlinks will be created for those names, and removed
|
||||
when the unit is disabled. For example, <filename>reboot.target</filename> specifies
|
||||
<varname>Alias=ctrl-alt-del.target</varname>, so when enabled it will be invoked whenever CTRL+ALT+DEL is
|
||||
pressed. Alias names may be used in commands like <command>enable</command>, <command>disable</command>,
|
||||
<command>start</command>, <command>stop</command>, <command>status</command>, …, and in unit dependency directives
|
||||
<varname>Wants=</varname>, <varname>Requires=</varname>, <varname>Before=</varname>, <varname>After=</varname>, …,
|
||||
with the limitation that aliases specified through <varname>Alias=</varname> are only effective when the unit is
|
||||
enabled. Aliases cannot be used with the <command>preset</command> command.</para>
|
||||
<para>Units can be aliased (have an alternative name), by creating a symlink from the new name
|
||||
to the existing name in one of the unit search paths. For example,
|
||||
<filename>systemd-networkd.service</filename> has the alias
|
||||
<filename>dbus-org.freedesktop.network1.service</filename>, created during installation as the
|
||||
symlink <filename>/usr/lib/systemd/system/dbus-org.freedesktop.network1.service</filename>. In
|
||||
addition, unit files may specify aliases through the <varname>Alias=</varname> directive in the
|
||||
[Install] section; those aliases are only effective when the unit is enabled. When the unit is
|
||||
enabled, symlinks will be created for those names, and removed when the unit is disabled. For
|
||||
example, <filename>reboot.target</filename> specifies
|
||||
<varname>Alias=ctrl-alt-del.target</varname>, so when enabled it will be invoked whenever
|
||||
CTRL+ALT+DEL is pressed. Alias names may be used in commands like <command>enable</command>,
|
||||
<command>disable</command>, <command>start</command>, <command>stop</command>,
|
||||
<command>status</command>, …, and in unit dependency directives <varname>Wants=</varname>,
|
||||
<varname>Requires=</varname>, <varname>Before=</varname>, <varname>After=</varname>, …, with the
|
||||
limitation that aliases specified through <varname>Alias=</varname> are only effective when the
|
||||
unit is enabled. Aliases cannot be used with the <command>preset</command> command.</para>
|
||||
|
||||
<para>Along with a unit file <filename>foo.service</filename>, the
|
||||
directory <filename>foo.service.wants/</filename> may exist. All
|
||||
unit files symlinked from such a directory are implicitly added as
|
||||
dependencies of type <varname>Wants=</varname> to the unit. This
|
||||
is useful to hook units into the start-up of other units, without
|
||||
having to modify their unit files. For details about the semantics
|
||||
of <varname>Wants=</varname>, see below. The preferred way to
|
||||
create symlinks in the <filename>.wants/</filename> directory of a
|
||||
unit file is with the <command>enable</command> command of the
|
||||
<para>Along with a unit file <filename>foo.service</filename>, the directory
|
||||
<filename>foo.service.wants/</filename> may exist. All unit files symlinked from such a
|
||||
directory are implicitly added as dependencies of type <varname>Wants=</varname> to the unit.
|
||||
This is useful to hook units into the start-up of other units, without having to modify their
|
||||
unit files. For details about the semantics of <varname>Wants=</varname>, see below. The
|
||||
preferred way to create symlinks in the <filename>.wants/</filename> directory of a unit file is
|
||||
with the <command>enable</command> command of the
|
||||
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
tool which reads information from the [Install] section of unit
|
||||
files (see below). A similar functionality exists for
|
||||
<varname>Requires=</varname> type dependencies as well, the
|
||||
directory suffix is <filename>.requires/</filename> in this
|
||||
case.</para>
|
||||
tool which reads information from the [Install] section of unit files (see below). A similar
|
||||
functionality exists for <varname>Requires=</varname> type dependencies as well, the directory
|
||||
suffix is <filename>.requires/</filename> in this case.</para>
|
||||
|
||||
<para>Along with a unit file <filename>foo.service</filename>, a "drop-in" directory
|
||||
<filename>foo.service.d/</filename> may exist. All files with the suffix <literal>.conf</literal> from this
|
||||
directory will be parsed after the file itself is parsed. This is useful to alter or add configuration settings for
|
||||
a unit, without having to modify unit files. Each drop-in file must have appropriate section headers. Note that for
|
||||
instantiated units, this logic will first look for the instance <literal>.d/</literal> subdirectory and read its
|
||||
<literal>.conf</literal> files, followed by the template <literal>.d/</literal> subdirectory and the
|
||||
<literal>.conf</literal> files there. Also note that settings from the <literal>[Install]</literal> section are not
|
||||
honoured in drop-in unit files, and have no effect.</para>
|
||||
<filename>foo.service.d/</filename> may exist. All files with the suffix
|
||||
<literal>.conf</literal> from this directory will be parsed after the file itself is
|
||||
parsed. This is useful to alter or add configuration settings for a unit, without having to
|
||||
modify unit files. Each drop-in file must have appropriate section headers. Note that for
|
||||
instantiated units, this logic will first look for the instance <literal>.d/</literal>
|
||||
subdirectory and read its <literal>.conf</literal> files, followed by the template
|
||||
<literal>.d/</literal> subdirectory and the <literal>.conf</literal> files there. Also note that
|
||||
settings from the <literal>[Install]</literal> section are not honoured in drop-in unit files,
|
||||
and have no effect.</para>
|
||||
|
||||
<para>In addition to <filename>/etc/systemd/system</filename>,
|
||||
the drop-in <literal>.conf</literal> files for system services
|
||||
can be placed in <filename>/usr/lib/systemd/system</filename> or
|
||||
<filename>/run/systemd/system</filename> directories. Drop-in
|
||||
files in <filename>/etc</filename> take precedence over those in
|
||||
<filename>/run</filename> which in turn take precedence over
|
||||
those in <filename>/usr/lib</filename>. Drop-in files under any of
|
||||
these directories take precedence over unit files wherever located.
|
||||
(Of course, since <filename>/run</filename> is temporary and
|
||||
<filename>/usr/lib</filename> is for vendors, it is unlikely
|
||||
drop-ins should be used in either of those places.)</para>
|
||||
<!-- Note that we do not document .include here, as we
|
||||
consider it mostly obsolete, and want people to
|
||||
use .d/ drop-ins instead. -->
|
||||
<para>In addition to <filename>/etc/systemd/system</filename>, the drop-in <literal>.d</literal>
|
||||
directories for system services can be placed in <filename>/usr/lib/systemd/system</filename> or
|
||||
<filename>/run/systemd/system</filename> directories. Drop-in files in <filename>/etc</filename>
|
||||
take precedence over those in <filename>/run</filename> which in turn take precedence over those
|
||||
in <filename>/usr/lib</filename>. Drop-in files under any of these directories take precedence
|
||||
over unit files wherever located. (Of course, since <filename>/run</filename> is temporary and
|
||||
<filename>/usr/lib</filename> is for vendors, it is unlikely drop-ins should be used in either
|
||||
of those places.)</para>
|
||||
|
||||
<!-- Note that we do not document .include here, as we consider it mostly obsolete, and want
|
||||
people to use .d/ drop-ins instead. -->
|
||||
|
||||
<para>Some unit names reflect paths existing in the file system
|
||||
namespace. Example: a device unit
|
||||
|
@ -79,7 +79,7 @@
|
||||
#endif
|
||||
|
||||
/* Return a nulstr for a standard cascade of configuration paths,
|
||||
* suitable to pass to conf_files_list_nulstr() or config_parse_many()
|
||||
* suitable to pass to conf_files_list_nulstr() or config_parse_many_nulstr()
|
||||
* to implement drop-in directories for extending configuration
|
||||
* files. */
|
||||
#define CONF_PATHS_NULSTR(n) \
|
||||
|
@ -715,7 +715,7 @@ static int parse_config_file(void) {
|
||||
CONF_PATHS_NULSTR("systemd/system.conf.d") :
|
||||
CONF_PATHS_NULSTR("systemd/user.conf.d");
|
||||
|
||||
config_parse_many(fn, conf_dirs_nulstr, "Manager\0", config_item_table_lookup, items, false, NULL);
|
||||
config_parse_many_nulstr(fn, conf_dirs_nulstr, "Manager\0", config_item_table_lookup, items, false, NULL);
|
||||
|
||||
/* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we used USEC_INFINITY
|
||||
* like everywhere else. */
|
||||
|
@ -128,7 +128,7 @@ static int parse_config(void) {
|
||||
{}
|
||||
};
|
||||
|
||||
return config_parse_many(PKGSYSCONFDIR "/coredump.conf",
|
||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/coredump.conf",
|
||||
CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
|
||||
"Coredump\0",
|
||||
config_item_table_lookup, items,
|
||||
|
@ -1194,7 +1194,7 @@ static int parse_config(void) {
|
||||
{ "Remote", "TrustedCertificateFile", config_parse_path, 0, &arg_trust },
|
||||
{}};
|
||||
|
||||
return config_parse_many(PKGSYSCONFDIR "/journal-remote.conf",
|
||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-remote.conf",
|
||||
CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
|
||||
"Remote\0", config_item_table_lookup, items,
|
||||
false, NULL);
|
||||
|
@ -542,7 +542,7 @@ static int parse_config(void) {
|
||||
{ "Upload", "TrustedCertificateFile", config_parse_path, 0, &arg_trust },
|
||||
{}};
|
||||
|
||||
return config_parse_many(PKGSYSCONFDIR "/journal-upload.conf",
|
||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-upload.conf",
|
||||
CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"),
|
||||
"Upload\0", config_item_table_lookup, items,
|
||||
false, NULL);
|
||||
|
@ -1474,7 +1474,7 @@ static int server_parse_proc_cmdline(Server *s) {
|
||||
static int server_parse_config_file(Server *s) {
|
||||
assert(s);
|
||||
|
||||
return config_parse_many(PKGSYSCONFDIR "/journald.conf",
|
||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/journald.conf",
|
||||
CONF_PATHS_NULSTR("systemd/journald.conf.d"),
|
||||
"Journal\0",
|
||||
config_item_perf_lookup, journald_gperf_lookup,
|
||||
|
@ -1002,7 +1002,7 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us
|
||||
static int manager_parse_config_file(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
return config_parse_many(PKGSYSCONFDIR "/logind.conf",
|
||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/logind.conf",
|
||||
CONF_PATHS_NULSTR("systemd/logind.conf.d"),
|
||||
"Login\0",
|
||||
config_item_perf_lookup, logind_gperf_lookup,
|
||||
|
@ -29,7 +29,7 @@
|
||||
int manager_parse_config_file(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
return config_parse_many(PKGSYSCONFDIR "/networkd.conf",
|
||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/networkd.conf",
|
||||
CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
|
||||
"DHCP\0",
|
||||
config_item_perf_lookup, networkd_gperf_lookup,
|
||||
|
@ -576,6 +576,7 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
||||
_cleanup_netdev_unref_ NetDev *netdev = NULL;
|
||||
_cleanup_free_ NetDev *netdev_raw = NULL;
|
||||
_cleanup_fclose_ FILE *file = NULL;
|
||||
const char *dropin_dirname;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
@ -599,11 +600,12 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
||||
return log_oom();
|
||||
|
||||
netdev_raw->kind = _NETDEV_KIND_INVALID;
|
||||
dropin_dirname = strjoina(basename(filename), ".d");
|
||||
|
||||
r = config_parse(NULL, filename, file,
|
||||
"Match\0NetDev\0",
|
||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||
true, false, true, netdev_raw);
|
||||
r = config_parse_many(filename, network_dirs, dropin_dirname,
|
||||
"Match\0NetDev\0",
|
||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||
true, netdev_raw);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -619,7 +621,7 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
||||
return 0;
|
||||
|
||||
if (netdev_raw->kind == _NETDEV_KIND_INVALID) {
|
||||
log_warning("NetDev with invalid Kind configured in %s. Ignoring", filename);
|
||||
log_warning("NetDev has no Kind configured in %s. Ignoring", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ static int network_load_one(Manager *manager, const char *filename) {
|
||||
_cleanup_network_free_ Network *network = NULL;
|
||||
_cleanup_fclose_ FILE *file = NULL;
|
||||
char *d;
|
||||
const char *dropin_dirname;
|
||||
Route *route;
|
||||
Address *address;
|
||||
int r;
|
||||
@ -137,21 +138,23 @@ static int network_load_one(Manager *manager, const char *filename) {
|
||||
network->arp = -1;
|
||||
network->ipv6_accept_ra_use_dns = true;
|
||||
|
||||
r = config_parse(NULL, filename, file,
|
||||
"Match\0"
|
||||
"Link\0"
|
||||
"Network\0"
|
||||
"Address\0"
|
||||
"Route\0"
|
||||
"DHCP\0"
|
||||
"DHCPv4\0" /* compat */
|
||||
"DHCPServer\0"
|
||||
"IPv6AcceptRA\0"
|
||||
"Bridge\0"
|
||||
"BridgeFDB\0"
|
||||
"BridgeVLAN\0",
|
||||
config_item_perf_lookup, network_network_gperf_lookup,
|
||||
false, false, true, network);
|
||||
dropin_dirname = strjoina(network->name, ".network.d");
|
||||
|
||||
r = config_parse_many(filename, network_dirs, dropin_dirname,
|
||||
"Match\0"
|
||||
"Link\0"
|
||||
"Network\0"
|
||||
"Address\0"
|
||||
"Route\0"
|
||||
"DHCP\0"
|
||||
"DHCPv4\0" /* compat */
|
||||
"DHCPServer\0"
|
||||
"IPv6AcceptRA\0"
|
||||
"Bridge\0"
|
||||
"BridgeFDB\0"
|
||||
"BridgeVLAN\0",
|
||||
config_item_perf_lookup, network_network_gperf_lookup,
|
||||
false, network);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -221,7 +221,7 @@ int manager_parse_config_file(Manager *m) {
|
||||
|
||||
assert(m);
|
||||
|
||||
r = config_parse_many(PKGSYSCONFDIR "/resolved.conf",
|
||||
r = config_parse_many_nulstr(PKGSYSCONFDIR "/resolved.conf",
|
||||
CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
|
||||
"Resolve\0",
|
||||
config_item_perf_lookup, resolved_gperf_lookup,
|
||||
|
@ -396,22 +396,18 @@ int config_parse(const char *unit,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse each config file in the specified directories. */
|
||||
int config_parse_many(const char *conf_file,
|
||||
const char *conf_file_dirs,
|
||||
const char *sections,
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
bool relaxed,
|
||||
void *userdata) {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
static int config_parse_many_files(
|
||||
const char *conf_file,
|
||||
char **files,
|
||||
const char *sections,
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
bool relaxed,
|
||||
void *userdata) {
|
||||
|
||||
char **fn;
|
||||
int r;
|
||||
|
||||
r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (conf_file) {
|
||||
r = config_parse(NULL, conf_file, NULL, sections, lookup, table, relaxed, false, true, userdata);
|
||||
if (r < 0)
|
||||
@ -427,6 +423,56 @@ int config_parse_many(const char *conf_file,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse each config file in the directories specified as nulstr. */
|
||||
int config_parse_many_nulstr(
|
||||
const char *conf_file,
|
||||
const char *conf_file_dirs,
|
||||
const char *sections,
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
bool relaxed,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
int r;
|
||||
|
||||
r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return config_parse_many_files(conf_file, files,
|
||||
sections, lookup, table, relaxed, userdata);
|
||||
}
|
||||
|
||||
/* Parse each config file in the directories specified as strv. */
|
||||
int config_parse_many(
|
||||
const char *conf_file,
|
||||
const char* const* conf_file_dirs,
|
||||
const char *dropin_dirname,
|
||||
const char *sections,
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
bool relaxed,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_strv_free_ char **dropin_dirs = NULL;
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
const char *suffix;
|
||||
int r;
|
||||
|
||||
suffix = strjoina("/", dropin_dirname);
|
||||
r = strv_extend_strv_concat(&dropin_dirs, (char**) conf_file_dirs, suffix);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = conf_files_list_strv(&files, ".conf", NULL, (const char* const*) dropin_dirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return config_parse_many_files(conf_file, files,
|
||||
sections, lookup, table, relaxed, userdata);
|
||||
}
|
||||
|
||||
#define DEFINE_PARSER(type, vartype, conv_func) \
|
||||
int config_parse_##type( \
|
||||
const char *unit, \
|
||||
|
@ -84,24 +84,36 @@ int config_item_table_lookup(const void *table, const char *section, const char
|
||||
* ConfigPerfItem tables */
|
||||
int config_item_perf_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
|
||||
|
||||
int config_parse(const char *unit,
|
||||
const char *filename,
|
||||
FILE *f,
|
||||
const char *sections, /* nulstr */
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
bool relaxed,
|
||||
bool allow_include,
|
||||
bool warn,
|
||||
void *userdata);
|
||||
int config_parse(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
FILE *f,
|
||||
const char *sections, /* nulstr */
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
bool relaxed,
|
||||
bool allow_include,
|
||||
bool warn,
|
||||
void *userdata);
|
||||
|
||||
int config_parse_many(const char *conf_file, /* possibly NULL */
|
||||
const char *conf_file_dirs, /* nulstr */
|
||||
const char *sections, /* nulstr */
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
bool relaxed,
|
||||
void *userdata);
|
||||
int config_parse_many_nulstr(
|
||||
const char *conf_file, /* possibly NULL */
|
||||
const char *conf_file_dirs, /* nulstr */
|
||||
const char *sections, /* nulstr */
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
bool relaxed,
|
||||
void *userdata);
|
||||
|
||||
int config_parse_many(
|
||||
const char *conf_file, /* possibly NULL */
|
||||
const char* const* conf_file_dirs,
|
||||
const char *dropin_dirname,
|
||||
const char *sections, /* nulstr */
|
||||
ConfigItemLookup lookup,
|
||||
const void *table,
|
||||
bool relaxed,
|
||||
void *userdata);
|
||||
|
||||
/* Generic parsers */
|
||||
int config_parse_int(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
|
@ -58,7 +58,7 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
|
||||
{}
|
||||
};
|
||||
|
||||
config_parse_many(PKGSYSCONFDIR "/sleep.conf",
|
||||
config_parse_many_nulstr(PKGSYSCONFDIR "/sleep.conf",
|
||||
CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
|
||||
"Sleep\0", config_item_table_lookup, items,
|
||||
false, NULL);
|
||||
|
@ -98,7 +98,7 @@ int config_parse_servers(
|
||||
int manager_parse_config_file(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
return config_parse_many(PKGSYSCONFDIR "/timesyncd.conf",
|
||||
return config_parse_many_nulstr(PKGSYSCONFDIR "/timesyncd.conf",
|
||||
CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
|
||||
"Time\0",
|
||||
config_item_perf_lookup, timesyncd_gperf_lookup,
|
||||
|
@ -54,7 +54,6 @@ class ClientTestBase:
|
||||
self.workdir_obj = tempfile.TemporaryDirectory()
|
||||
self.workdir = self.workdir_obj.name
|
||||
self.config = '/run/systemd/network/test_eth42.network'
|
||||
os.makedirs(os.path.dirname(self.config), exist_ok=True)
|
||||
|
||||
# avoid "Failed to open /dev/tty" errors in containers
|
||||
os.environ['SYSTEMD_LOG_TARGET'] = 'journal'
|
||||
@ -77,10 +76,14 @@ class ClientTestBase:
|
||||
|
||||
def tearDown(self):
|
||||
self.shutdown_iface()
|
||||
if os.path.exists(self.config):
|
||||
os.unlink(self.config)
|
||||
subprocess.call(['systemctl', 'stop', 'systemd-networkd'])
|
||||
|
||||
def writeConfig(self, fname, contents):
|
||||
os.makedirs(os.path.dirname(fname), exist_ok=True)
|
||||
with open(fname, 'w') as f:
|
||||
f.write(contents)
|
||||
self.addCleanup(os.remove, fname)
|
||||
|
||||
def show_journal(self, unit):
|
||||
'''Show journal of given unit since start of the test'''
|
||||
|
||||
@ -107,8 +110,8 @@ class ClientTestBase:
|
||||
def do_test(self, coldplug=True, ipv6=False, extra_opts='',
|
||||
online_timeout=10, dhcp_mode='yes'):
|
||||
subprocess.check_call(['systemctl', 'start', 'systemd-resolved'])
|
||||
with open(self.config, 'w') as f:
|
||||
f.write('''[Match]
|
||||
self.writeConfig(self.config, '''\
|
||||
[Match]
|
||||
Name=%s
|
||||
[Network]
|
||||
DHCP=%s
|
||||
@ -225,20 +228,18 @@ DHCP=%s
|
||||
self.do_test(coldplug=False, ipv6=True)
|
||||
|
||||
def test_route_only_dns(self):
|
||||
with open('/run/systemd/network/myvpn.netdev', 'w') as f:
|
||||
f.write('''[NetDev]
|
||||
self.writeConfig('/run/systemd/network/myvpn.netdev', '''\
|
||||
[NetDev]
|
||||
Name=dummy0
|
||||
Kind=dummy
|
||||
MACAddress=12:34:56:78:9a:bc''')
|
||||
with open('/run/systemd/network/myvpn.network', 'w') as f:
|
||||
f.write('''[Match]
|
||||
self.writeConfig('/run/systemd/network/myvpn.network', '''\
|
||||
[Match]
|
||||
Name=dummy0
|
||||
[Network]
|
||||
Address=192.168.42.100
|
||||
DNS=192.168.42.1
|
||||
Domains= ~company''')
|
||||
self.addCleanup(os.remove, '/run/systemd/network/myvpn.netdev')
|
||||
self.addCleanup(os.remove, '/run/systemd/network/myvpn.network')
|
||||
|
||||
self.do_test(coldplug=True, ipv6=False,
|
||||
extra_opts='IPv6AcceptRouterAdvertisements=False')
|
||||
@ -320,7 +321,8 @@ class NetworkdClientTest(ClientTestBase, unittest.TestCase):
|
||||
(fd, script) = tempfile.mkstemp(prefix='networkd-router.sh')
|
||||
self.addCleanup(os.remove, script)
|
||||
with os.fdopen(fd, 'w+') as f:
|
||||
f.write('''#!/bin/sh -eu
|
||||
f.write('''\
|
||||
#!/bin/sh -eu
|
||||
mkdir -p /run/systemd/network
|
||||
mkdir -p /run/systemd/netif
|
||||
mount -t tmpfs none /run/systemd/network
|
||||
@ -398,20 +400,18 @@ exec $(systemctl cat systemd-networkd.service | sed -n '/^ExecStart=/ { s/^.*=//
|
||||
# we don't use this interface for this test
|
||||
self.if_router = None
|
||||
|
||||
with open('/run/systemd/network/test.netdev', 'w') as f:
|
||||
f.write('''[NetDev]
|
||||
self.writeConfig('/run/systemd/network/test.netdev', '''\
|
||||
[NetDev]
|
||||
Name=dummy0
|
||||
Kind=dummy
|
||||
MACAddress=12:34:56:78:9a:bc''')
|
||||
with open('/run/systemd/network/test.network', 'w') as f:
|
||||
f.write('''[Match]
|
||||
self.writeConfig('/run/systemd/network/test.network', '''\
|
||||
[Match]
|
||||
Name=dummy0
|
||||
[Network]
|
||||
Address=192.168.42.100
|
||||
DNS=192.168.42.1
|
||||
Domains= one two three four five six seven eight nine ten''')
|
||||
self.addCleanup(os.remove, '/run/systemd/network/test.netdev')
|
||||
self.addCleanup(os.remove, '/run/systemd/network/test.network')
|
||||
|
||||
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||
|
||||
@ -432,23 +432,18 @@ Domains= one two three four five six seven eight nine ten''')
|
||||
|
||||
name_prefix = 'a' * 60
|
||||
|
||||
with open('/run/systemd/network/test.netdev', 'w') as f:
|
||||
f.write('''[NetDev]
|
||||
self.writeConfig('/run/systemd/network/test.netdev', '''\
|
||||
[NetDev]
|
||||
Name=dummy0
|
||||
Kind=dummy
|
||||
MACAddress=12:34:56:78:9a:bc''')
|
||||
with open('/run/systemd/network/test.network', 'w') as f:
|
||||
f.write('''[Match]
|
||||
self.writeConfig('/run/systemd/network/test.network', '''\
|
||||
[Match]
|
||||
Name=dummy0
|
||||
[Network]
|
||||
Address=192.168.42.100
|
||||
DNS=192.168.42.1
|
||||
Domains=''')
|
||||
for i in range(5):
|
||||
f.write('%s%i ' % (name_prefix, i))
|
||||
|
||||
self.addCleanup(os.remove, '/run/systemd/network/test.netdev')
|
||||
self.addCleanup(os.remove, '/run/systemd/network/test.network')
|
||||
Domains={p}0 {p}1 {p}2 {p}3 {p}4'''.format(p=name_prefix))
|
||||
|
||||
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||
|
||||
@ -458,9 +453,38 @@ Domains=''')
|
||||
if ' one' in contents:
|
||||
break
|
||||
time.sleep(0.1)
|
||||
self.assertRegex(contents, 'search .*%(p)s0 %(p)s1 %(p)s2' % {'p': name_prefix})
|
||||
self.assertRegex(contents, 'search .*{p}0 {p}1 {p}2'.format(p=name_prefix))
|
||||
self.assertIn('# Total length of all search domains is too long, remaining ones ignored.', contents)
|
||||
|
||||
def test_dropin(self):
|
||||
# we don't use this interface for this test
|
||||
self.if_router = None
|
||||
|
||||
self.writeConfig('/run/systemd/network/test.netdev', '''\
|
||||
[NetDev]
|
||||
Name=dummy0
|
||||
Kind=dummy
|
||||
MACAddress=12:34:56:78:9a:bc''')
|
||||
self.writeConfig('/run/systemd/network/test.network', '''\
|
||||
[Match]
|
||||
Name=dummy0
|
||||
[Network]
|
||||
Address=192.168.42.100
|
||||
DNS=192.168.42.1''')
|
||||
self.writeConfig('/run/systemd/network/test.network.d/dns.conf', '''\
|
||||
[Network]
|
||||
DNS=127.0.0.1''')
|
||||
|
||||
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||
|
||||
for timeout in range(50):
|
||||
with open(RESOLV_CONF) as f:
|
||||
contents = f.read()
|
||||
if ' 127.0.0.1' in contents:
|
||||
break
|
||||
time.sleep(0.1)
|
||||
self.assertIn('nameserver 192.168.42.1\n', contents)
|
||||
self.assertIn('nameserver 127.0.0.1\n', contents)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
|
||||
|
Loading…
Reference in New Issue
Block a user