Merge pull request #12160 from yuwata/wait-online-allow-configuring
wait-online: add --any option
This commit is contained in:
@@ -59,7 +59,7 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalState s) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool manager_all_configured(Manager *m) {
|
||||
bool manager_configured(Manager *m) {
|
||||
bool one_ready = false;
|
||||
Iterator i;
|
||||
const char *ifname;
|
||||
@@ -67,24 +67,33 @@ bool manager_all_configured(Manager *m) {
|
||||
Link *l;
|
||||
int r;
|
||||
|
||||
/* wait for all the links given on the command line to appear */
|
||||
HASHMAP_FOREACH_KEY(p, ifname, m->interfaces, i) {
|
||||
LinkOperationalState s = PTR_TO_INT(p);
|
||||
if (!hashmap_isempty(m->interfaces)) {
|
||||
/* wait for all the links given on the command line to appear */
|
||||
HASHMAP_FOREACH_KEY(p, ifname, m->interfaces, i) {
|
||||
LinkOperationalState s = PTR_TO_INT(p);
|
||||
|
||||
l = hashmap_get(m->links_by_name, ifname);
|
||||
if (!l) {
|
||||
log_debug("still waiting for %s", ifname);
|
||||
return false;
|
||||
l = hashmap_get(m->links_by_name, ifname);
|
||||
if (!l) {
|
||||
log_debug("still waiting for %s", ifname);
|
||||
if (!m->any)
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (manager_link_is_online(m, l, s) <= 0) {
|
||||
if (!m->any)
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
one_ready = true;
|
||||
}
|
||||
|
||||
if (manager_link_is_online(m, l, s) <= 0)
|
||||
return false;
|
||||
/* all interfaces given by the command line are online, or
|
||||
* one of the specified interfaces is online. */
|
||||
return one_ready;
|
||||
}
|
||||
|
||||
if (!hashmap_isempty(m->interfaces))
|
||||
/* all interfaces given by the command line are online. */
|
||||
return true;
|
||||
|
||||
/* 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) {
|
||||
@@ -94,7 +103,7 @@ bool manager_all_configured(Manager *m) {
|
||||
}
|
||||
|
||||
r = manager_link_is_online(m, l, _LINK_OPERSTATE_INVALID);
|
||||
if (r < 0)
|
||||
if (r < 0 && !m->any)
|
||||
return false;
|
||||
if (r > 0)
|
||||
/* we wait for at least one link to be ready,
|
||||
@@ -180,7 +189,7 @@ static int on_rtnl_event(sd_netlink *rtnl, sd_netlink_message *mm, void *userdat
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (manager_all_configured(m))
|
||||
if (manager_configured(m))
|
||||
sd_event_exit(m->event, 0);
|
||||
|
||||
return 1;
|
||||
@@ -248,7 +257,7 @@ static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *
|
||||
log_link_warning_errno(l, r, "Failed to update monitor information: %m");
|
||||
}
|
||||
|
||||
if (manager_all_configured(m))
|
||||
if (manager_configured(m))
|
||||
sd_event_exit(m->event, 0);
|
||||
|
||||
return 0;
|
||||
@@ -280,7 +289,8 @@ static int manager_network_monitor_listen(Manager *m) {
|
||||
}
|
||||
|
||||
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
||||
LinkOperationalState required_operstate, usec_t timeout) {
|
||||
LinkOperationalState required_operstate,
|
||||
bool any, usec_t timeout) {
|
||||
_cleanup_(manager_freep) Manager *m = NULL;
|
||||
int r;
|
||||
|
||||
@@ -294,6 +304,7 @@ int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
||||
.interfaces = interfaces,
|
||||
.ignore = ignore,
|
||||
.required_operstate = required_operstate,
|
||||
.any = any,
|
||||
};
|
||||
|
||||
r = sd_event_default(&m->event);
|
||||
|
||||
@@ -21,6 +21,7 @@ struct Manager {
|
||||
char **ignore;
|
||||
|
||||
LinkOperationalState required_operstate;
|
||||
bool any;
|
||||
|
||||
sd_netlink *rtnl;
|
||||
sd_event_source *rtnl_event_source;
|
||||
@@ -33,8 +34,9 @@ struct Manager {
|
||||
|
||||
void manager_free(Manager *m);
|
||||
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
||||
LinkOperationalState required_operstate, usec_t timeout);
|
||||
LinkOperationalState required_operstate,
|
||||
bool any, usec_t timeout);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||
|
||||
bool manager_all_configured(Manager *m);
|
||||
bool manager_configured(Manager *m);
|
||||
|
||||
@@ -19,6 +19,7 @@ static usec_t arg_timeout = 120 * USEC_PER_SEC;
|
||||
static Hashmap *arg_interfaces = NULL;
|
||||
static char **arg_ignore = NULL;
|
||||
static LinkOperationalState arg_required_operstate = _LINK_OPERSTATE_INVALID;
|
||||
static bool arg_any = false;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, hashmap_free_free_keyp);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_ignore, strv_freep);
|
||||
@@ -41,6 +42,7 @@ static int help(void) {
|
||||
" --ignore=INTERFACE Don't take these interfaces into account\n"
|
||||
" -o --operational-state=OPERSTATE\n"
|
||||
" Required operational state\n"
|
||||
" --any Wait until at least one of the interfaces is online\n"
|
||||
" --timeout=SECS Maximum time to wait for network connectivity\n"
|
||||
"\nSee the %s for details.\n"
|
||||
, program_invocation_short_name
|
||||
@@ -101,6 +103,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_IGNORE,
|
||||
ARG_ANY,
|
||||
ARG_TIMEOUT,
|
||||
};
|
||||
|
||||
@@ -111,6 +114,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "interface", required_argument, NULL, 'i' },
|
||||
{ "ignore", required_argument, NULL, ARG_IGNORE },
|
||||
{ "operational-state", required_argument, NULL, 'o' },
|
||||
{ "any", no_argument, NULL, ARG_ANY },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{}
|
||||
};
|
||||
@@ -158,6 +162,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_required_operstate = s;
|
||||
break;
|
||||
}
|
||||
case ARG_ANY:
|
||||
arg_any = true;
|
||||
break;
|
||||
|
||||
case ARG_TIMEOUT:
|
||||
r = parse_sec(optarg, &arg_timeout);
|
||||
if (r < 0)
|
||||
@@ -192,11 +200,11 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
|
||||
|
||||
r = manager_new(&m, arg_interfaces, arg_ignore, arg_required_operstate, arg_timeout);
|
||||
r = manager_new(&m, arg_interfaces, arg_ignore, arg_required_operstate, arg_any, arg_timeout);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not create manager: %m");
|
||||
|
||||
if (manager_all_configured(m))
|
||||
if (manager_configured(m))
|
||||
goto success;
|
||||
|
||||
notify_message = notify_start("READY=1\n"
|
||||
|
||||
Reference in New Issue
Block a user