lifecycle: implement requires keyword
This commit is contained in:
parent
bc88e3fcd2
commit
38537339ab
4 changed files with 68 additions and 8 deletions
|
@ -60,7 +60,7 @@ is_ifdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
change_interface(struct lif_interface *iface, struct lif_dict *state, const char *ifname)
|
change_interface(struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *ifname)
|
||||||
{
|
{
|
||||||
if (exec_opts.verbose)
|
if (exec_opts.verbose)
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ change_interface(struct lif_interface *iface, struct lif_dict *state, const char
|
||||||
argv0, ifname, up ? "up" : "down");
|
argv0, ifname, up ? "up" : "down");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lif_lifecycle_run(&exec_opts, iface, state, ifname, up))
|
if (!lif_lifecycle_run(&exec_opts, iface, collection, state, ifname, up))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: failed to change interface %s state to '%s'\n",
|
fprintf(stderr, "%s: failed to change interface %s state to '%s'\n",
|
||||||
argv0, ifname, up ? "up" : "down");
|
argv0, ifname, up ? "up" : "down");
|
||||||
|
@ -99,7 +99,7 @@ change_auto_interfaces(struct lif_dict *collection, struct lif_dict *state, stru
|
||||||
fnmatch(opts->include_pattern, iface->ifname, 0))
|
fnmatch(opts->include_pattern, iface->ifname, 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!change_interface(iface, state, iface->ifname))
|
if (!change_interface(iface, collection, state, iface->ifname))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ ifupdown_main(int argc, char *argv[])
|
||||||
iface = entry->data;
|
iface = entry->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!change_interface(iface, &state, ifname))
|
if (!change_interface(iface, &collection, &state, ifname))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ struct lif_interface {
|
||||||
bool is_auto;
|
bool is_auto;
|
||||||
|
|
||||||
struct lif_dict vars;
|
struct lif_dict vars;
|
||||||
|
|
||||||
|
bool is_up;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LIF_INTERFACE_COLLECTION_FOREACH(iter, collection) \
|
#define LIF_INTERFACE_COLLECTION_FOREACH(iter, collection) \
|
||||||
|
|
|
@ -264,16 +264,66 @@ on_error:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
next_token(char **buf)
|
||||||
|
{
|
||||||
|
char *out = *buf;
|
||||||
|
|
||||||
|
while (*out && isspace(*out))
|
||||||
|
out++;
|
||||||
|
|
||||||
|
char *end = out;
|
||||||
|
while (*end && !isspace(*end))
|
||||||
|
end++;
|
||||||
|
|
||||||
|
*end++ = '\0';
|
||||||
|
*buf = end;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
handle_dependents(const struct lif_execute_opts *opts, struct lif_interface *parent, struct lif_dict *collection, struct lif_dict *state, bool up)
|
||||||
|
{
|
||||||
|
struct lif_dict_entry *requires = lif_dict_find(&parent->vars, "requires");
|
||||||
|
|
||||||
|
/* no dependents, nothing to worry about */
|
||||||
|
if (requires == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
char require_ifs[4096];
|
||||||
|
strlcpy(require_ifs, requires->data, sizeof require_ifs);
|
||||||
|
char *bufp = require_ifs;
|
||||||
|
|
||||||
|
for (char *tokenp = next_token(&bufp); *tokenp; tokenp = next_token(&bufp))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "next iface: %s\n", tokenp);
|
||||||
|
|
||||||
|
struct lif_interface *iface = lif_interface_collection_find(collection, tokenp);
|
||||||
|
|
||||||
|
/* already up or down, skip */
|
||||||
|
if (up == iface->is_up)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!lif_lifecycle_run(opts, iface, collection, state, iface->ifname, up))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *iface, struct lif_dict *state, const char *lifname, bool up)
|
lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *lifname, bool up)
|
||||||
{
|
{
|
||||||
if (lifname == NULL)
|
if (lifname == NULL)
|
||||||
lifname = iface->ifname;
|
lifname = iface->ifname;
|
||||||
|
|
||||||
/* XXX: actually handle dependents here */
|
|
||||||
|
|
||||||
if (up)
|
if (up)
|
||||||
{
|
{
|
||||||
|
/* when going up, dependents go up first. */
|
||||||
|
if (!handle_dependents(opts, iface, collection, state, up))
|
||||||
|
return false;
|
||||||
|
|
||||||
/* XXX: we should try to recover (take the iface down) if bringing it up fails.
|
/* XXX: we should try to recover (take the iface down) if bringing it up fails.
|
||||||
* but, right now neither debian ifupdown or busybox ifupdown do any recovery,
|
* but, right now neither debian ifupdown or busybox ifupdown do any recovery,
|
||||||
* so we wont right now.
|
* so we wont right now.
|
||||||
|
@ -288,6 +338,8 @@ lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *ifa
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
lif_state_upsert(state, lifname, iface);
|
lif_state_upsert(state, lifname, iface);
|
||||||
|
|
||||||
|
iface->is_up = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -300,7 +352,13 @@ lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *ifa
|
||||||
if (!lif_lifecycle_run_phase(opts, iface, "post-down", lifname, up))
|
if (!lif_lifecycle_run_phase(opts, iface, "post-down", lifname, up))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/* when going up, dependents go down last. */
|
||||||
|
if (!handle_dependents(opts, iface, collection, state, up))
|
||||||
|
return false;
|
||||||
|
|
||||||
lif_state_delete(state, lifname);
|
lif_state_delete(state, lifname);
|
||||||
|
|
||||||
|
iface->is_up = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "libifupdown/execute.h"
|
#include "libifupdown/execute.h"
|
||||||
|
|
||||||
extern bool lif_lifecycle_run_phase(const struct lif_execute_opts *opts, struct lif_interface *iface, const char *phase, const char *lifname, bool up);
|
extern bool lif_lifecycle_run_phase(const struct lif_execute_opts *opts, struct lif_interface *iface, const char *phase, const char *lifname, bool up);
|
||||||
extern bool lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *iface, struct lif_dict *state, const char *lifname, bool up);
|
extern bool lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *lifname, bool up);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue