networkd-wait-online: allow specific devices to be ignored

In addition to the loopback device, also explicitly configured devices to be ignored.

Suggested by Charles Devereaux <systemd@guylhem.net>.
This commit is contained in:
Tom Gundersen 2015-01-29 07:34:34 +01:00
parent 233ba5c3a0
commit 79b1f37d95
5 changed files with 48 additions and 16 deletions

View file

@ -82,6 +82,14 @@
used more than once to wait for multiple network
interfaces.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--ignore=</option></term>
<listitem><para>Network interfaces to be ignored when
deciding if the system is online. By default only
the loopback interface is ignored. This option may be used
more than once to ignore multiple network interfaces.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>

View file

@ -134,12 +134,3 @@ int link_update_monitor(Link *l) {
return 0;
}
bool link_relevant(Link *l) {
assert(l);
if (l->flags & IFF_LOOPBACK)
return false;
return true;
}

View file

@ -31,6 +31,19 @@
#include "util.h"
bool manager_ignore_link(Manager *m, Link *link) {
assert(m);
assert(link);
if (link->flags & IFF_LOOPBACK)
return true;
if (strv_contains(m->ignore, link->ifname))
return true;
return false;
}
bool manager_all_configured(Manager *m) {
Iterator i;
Link *l;
@ -49,8 +62,8 @@ bool manager_all_configured(Manager *m) {
/* wait for all links networkd manages to be in admin state 'configured'
and at least one link to gain a carrier */
HASHMAP_FOREACH(l, m->links, i) {
if (!link_relevant(l)) {
log_info("ignore irrelevant link: %s", l->ifname);
if (manager_ignore_link(m, l)) {
log_info("ignoring: %s", l->ifname);
continue;
}
@ -245,7 +258,7 @@ static int manager_network_monitor_listen(Manager *m) {
return 0;
}
int manager_new(Manager **ret, char **interfaces) {
int manager_new(Manager **ret, char **interfaces, char **ignore) {
_cleanup_(manager_freep) Manager *m = NULL;
int r;
@ -256,6 +269,7 @@ int manager_new(Manager **ret, char **interfaces) {
return -ENOMEM;
m->interfaces = interfaces;
m->ignore = ignore;
r = sd_event_default(&m->event);
if (r < 0)

View file

@ -29,6 +29,7 @@
static bool arg_quiet = false;
static char **arg_interfaces = NULL;
static char **arg_ignore = NULL;
static void help(void) {
printf("%s [OPTIONS...]\n\n"
@ -37,6 +38,7 @@ static void help(void) {
" --version Print version string\n"
" -q --quiet Do not show status information\n"
" -i --interface=INTERFACE Block until at least these interfaces have appeared\n"
" --ignore=INTERFACE Don't take these interfaces into account\n"
, program_invocation_short_name);
}
@ -44,6 +46,7 @@ static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_IGNORE,
};
static const struct option options[] = {
@ -51,6 +54,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION },
{ "quiet", no_argument, NULL, 'q' },
{ "interface", required_argument, NULL, 'i' },
{ "ignore", required_argument, NULL, ARG_IGNORE },
{}
};
@ -82,6 +86,12 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_IGNORE:
if (strv_extend(&arg_ignore, optarg) < 0)
return log_oom();
break;
case '?':
return -EINVAL;
@ -111,7 +121,7 @@ int main(int argc, char *argv[]) {
assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
r = manager_new(&m, arg_interfaces);
r = manager_new(&m, arg_interfaces, arg_ignore);
if (r < 0) {
log_error_errno(r, "Could not create manager: %m");
goto finish;
@ -135,5 +145,8 @@ int main(int argc, char *argv[]) {
finish:
sd_notify(false, "STATUS=All interfaces configured...");
strv_free(arg_interfaces);
strv_free(arg_ignore);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

View file

@ -28,11 +28,16 @@
#include "util.h"
#include "hashmap.h"
typedef struct Manager {
typedef struct Manager Manager;
#include "networkd-wait-online-link.h"
struct Manager {
Hashmap *links;
Hashmap *links_by_name;
char **interfaces;
char **ignore;
sd_rtnl *rtnl;
sd_event_source *rtnl_event_source;
@ -41,11 +46,12 @@ typedef struct Manager {
sd_event_source *network_monitor_event_source;
sd_event *event;
} Manager;
};
void manager_free(Manager *m);
int manager_new(Manager **ret, char **interfaces);
int manager_new(Manager **ret, char **interfaces, char **ignore);
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
bool manager_all_configured(Manager *m);
bool manager_ignore_link(Manager *m, Link *link);