Skip to content

Commit

Permalink
client: Check for config priorities at reading stage
Browse files Browse the repository at this point in the history
  • Loading branch information
wipawel committed Feb 18, 2014
1 parent a882cc6 commit ad7b47d
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 110 deletions.
5 changes: 4 additions & 1 deletion client/compat.c
Expand Up @@ -1224,7 +1224,10 @@ ni_compat_generate_interfaces(xml_document_array_t *array, ni_compat_ifconfig_t
}
}

xml_document_array_append(array, config_doc);
if (ni_ifconfig_validate_adding_doc(array, config_doc, raw))
xml_document_array_append(array, config_doc);
else
xml_document_free(config_doc);
}

return i;
Expand Down
8 changes: 3 additions & 5 deletions client/ifcheck.c
Expand Up @@ -325,11 +325,9 @@ ni_do_ifcheck(int argc, char **argv)
}
}

for (i = 0; i < opt_ifconfig.count; ++i) {
if (!ni_ifconfig_load(fsm, opt_global_rootdir, opt_ifconfig.data[i], TRUE)) {
status = NI_WICKED_RC_NOT_CONFIGURED;
goto cleanup;
}
if (!ni_ifconfig_load(fsm, opt_global_rootdir, &opt_ifconfig, TRUE)) {
status = NI_WICKED_RC_NOT_CONFIGURED;
goto cleanup;
}

if (!ni_fsm_create_client(fsm)) {
Expand Down
22 changes: 4 additions & 18 deletions client/ifreload.c
Expand Up @@ -59,7 +59,6 @@ ni_do_ifreload(int argc, char **argv)
ni_string_array_t opt_ifconfig = NI_STRING_ARRAY_INIT;
ni_ifworker_array_t marked = { 0, NULL };
ni_ifmatcher_t ifmatch;
const char *opt_ifpolicy = NULL;
ni_bool_t opt_force = FALSE;
ni_bool_t opt_persistent = FALSE;
int c, status = NI_WICKED_RC_USAGE;
Expand All @@ -80,11 +79,8 @@ ni_do_ifreload(int argc, char **argv)
while ((c = getopt_long(argc, argv, "", ifreload_options, NULL)) != EOF) {
switch (c) {
case OPT_IFCONFIG:
ni_string_array_append(&opt_ifconfig, optarg);
break;

case OPT_IFPOLICY:
opt_ifpolicy = optarg;
ni_string_array_append(&opt_ifconfig, optarg);
break;

case OPT_FORCE:
Expand Down Expand Up @@ -149,19 +145,9 @@ ni_do_ifreload(int argc, char **argv)
}
}

for (i = 0; i < opt_ifconfig.count; ++i) {
if (!ni_ifconfig_load(fsm, opt_global_rootdir,
opt_ifconfig.data[i], opt_force)) {
status = NI_WICKED_RC_NOT_CONFIGURED;
goto cleanup;
}
}
if (opt_ifpolicy) {
if (!ni_ifconfig_load(fsm, opt_global_rootdir,
opt_ifpolicy, opt_force)) {
status = NI_WICKED_RC_NOT_CONFIGURED;
goto cleanup;
}
if (!ni_ifconfig_load(fsm, opt_global_rootdir, &opt_ifconfig, opt_force)) {
status = NI_WICKED_RC_NOT_CONFIGURED;
goto cleanup;
}

status = NI_WICKED_RC_SUCCESS;
Expand Down
10 changes: 4 additions & 6 deletions client/ifstatus.c
Expand Up @@ -580,12 +580,10 @@ ni_do_ifstatus(int argc, char **argv)
if (sources && sources->count)
ni_string_array_copy(&opt_ifconfig, sources);
}
for (i = 0; i < opt_ifconfig.count; ++i) {
if (!ni_ifconfig_load(fsm, opt_global_rootdir,
opt_ifconfig.data[i], TRUE)) {
status = NI_WICKED_ST_ERROR;
goto cleanup;
}

if (!ni_ifconfig_load(fsm, opt_global_rootdir, &opt_ifconfig, TRUE)) {
status = NI_WICKED_ST_ERROR;
goto cleanup;
}

status = NI_WICKED_ST_OK;
Expand Down
17 changes: 3 additions & 14 deletions client/ifup.c
Expand Up @@ -81,9 +81,8 @@ ni_do_ifup(int argc, char **argv)
ni_ifmarker_t ifmarker;
ni_ifworker_array_t ifmarked;
ni_string_array_t opt_ifconfig = NI_STRING_ARRAY_INIT;
const char *opt_ifpolicy = NULL;
ni_bool_t opt_force = FALSE;
unsigned int nmarked, i;
unsigned int nmarked;
ni_fsm_t *fsm;
int c, status = NI_WICKED_RC_USAGE;

Expand All @@ -107,11 +106,8 @@ ni_do_ifup(int argc, char **argv)
while ((c = getopt_long(argc, argv, "", ifup_options, NULL)) != EOF) {
switch (c) {
case OPT_IFCONFIG:
ni_string_array_append(&opt_ifconfig, optarg);
break;

case OPT_IFPOLICY:
opt_ifpolicy = optarg;
ni_string_array_append(&opt_ifconfig, optarg);
break;

case OPT_CONTROL_MODE:
Expand Down Expand Up @@ -208,14 +204,7 @@ ni_do_ifup(int argc, char **argv)
}
}

for (i = 0; i < opt_ifconfig.count; ++i) {
if (!ni_ifconfig_load(fsm, opt_global_rootdir, opt_ifconfig.data[i], opt_force)) {
status = NI_WICKED_RC_NOT_CONFIGURED;
goto cleanup;
}
}

if (opt_ifpolicy && !ni_ifconfig_load(fsm, opt_global_rootdir, opt_ifpolicy, opt_force)) {
if (!ni_ifconfig_load(fsm, opt_global_rootdir, &opt_ifconfig, opt_force)) {
status = NI_WICKED_RC_NOT_CONFIGURED;
goto cleanup;
}
Expand Down
150 changes: 129 additions & 21 deletions client/read-config.c
Expand Up @@ -191,17 +191,19 @@ static const ni_ifconfig_type_t __ni_ifconfig_types[] = {
};

ni_bool_t
ni_ifconfig_load(ni_fsm_t *fsm, const char *root, const char *location, ni_bool_t force)
ni_ifconfig_load(ni_fsm_t *fsm, const char *root, ni_string_array_t *opt_ifconfig, ni_bool_t force)
{
xml_document_array_t docs = XML_DOCUMENT_ARRAY_INIT;
unsigned int i;

if (!ni_ifconfig_read(&docs, root, location, FALSE))
return FALSE;
for (i = 0; i < opt_ifconfig->count; ++i) {
if (!ni_ifconfig_read(&docs, root, opt_ifconfig->data[i], force))
return FALSE;
}

for (i = 0; i < docs.count; i++) {
/* TODO: review ni_fsm_workers_from_xml return codes */
ni_fsm_workers_from_xml(fsm, docs.data[i], force);
ni_fsm_workers_from_xml(fsm, docs.data[i]);
}

/* Do not destroy xml documents as referenced by the fsm workers */
Expand Down Expand Up @@ -233,6 +235,81 @@ ni_ifconfig_read(xml_document_array_t *array, const char *root, const char *path
return FALSE;
}

static ni_config_origin_prio_t
__ni_ifconfig_origin_get_prio(const char *origin)
{
ni_config_origin_prio_t prio;

if (ni_string_empty(origin))
return NI_CONFIG_ORIGIN_PRIO_UNKNOWN;

if (ni_string_startswith(origin, "firmware:"))
prio = NI_CONFIG_ORIGIN_PRIO_FIRMWARE;
else if (ni_string_startswith(origin, "compat:"))
prio = NI_CONFIG_ORIGIN_PRIO_COMPAT;
else if (ni_string_startswith(origin, "wicked:"))
prio = NI_CONFIG_ORIGIN_PRIO_WICKED;
else
prio = NI_CONFIG_ORIGIN_PRIO_UNKNOWN; /* Currently wicked */

return prio;
}

static inline const char *
__ifconfig_read_get_iface_name(xml_node_t *ifnode)
{
xml_node_t *nnode = NULL;

if (ifnode)
nnode = xml_node_get_child(ifnode, "name");
return (!nnode || ni_string_empty(nnode->cdata)) ? NULL : nnode->cdata;
}

ni_bool_t
ni_ifconfig_validate_adding_doc(xml_document_array_t *docs, xml_document_t *config_doc, ni_bool_t force)
{
xml_node_t *dst_root, *src_root, *dst_child, *src_child;
ni_config_origin_prio_t dst_prio, src_prio;
const char *dst_ifname, *src_ifname;
unsigned int i;

ni_assert(docs);
if (!config_doc)
return FALSE;
if (force)
return TRUE;

/* Go through all config_doc's <interfaces> */
src_root = xml_document_root(config_doc);
src_prio = __ni_ifconfig_origin_get_prio(xml_node_get_location_filename(src_root));

/* Go through all already added docs */
for (i = 0; i < docs->count; i++) {
dst_root = xml_document_root(docs->data[i]);
dst_prio = __ni_ifconfig_origin_get_prio(xml_node_get_location_filename(dst_root));

/* Go through all already added docs' <interfaces> */
for (dst_child = dst_root->children; dst_child; dst_child = dst_child->next) {
if (!(dst_ifname = __ifconfig_read_get_iface_name(dst_child)))
return FALSE;

/* Go through all <interfaces> of a doc being added */
for (src_child = src_root->children; src_child; src_child = src_child->next) {
if (!(src_ifname = __ifconfig_read_get_iface_name(src_child)))
return FALSE;
if (ni_string_eq(dst_ifname, src_ifname) && dst_prio <= src_prio) {
ni_warn("Ignoring config %s because of higher prio config %s",
xml_node_get_location_filename(src_root),
xml_node_get_location_filename(dst_root));
return FALSE;
}
}
}
}

return TRUE;
}

/*
* Read ifconfig file
*/
Expand All @@ -257,7 +334,11 @@ __ni_ifconfig_xml_read_file(xml_document_array_t *docs, const char *root, const
ni_ifconfig_generate_client_info("wicked", pathname, NULL), NULL);
}

xml_document_array_append(docs, config_doc);
if (ni_ifconfig_validate_adding_doc(docs, config_doc, raw))
xml_document_array_append(docs, config_doc);
else
xml_document_free(config_doc);

return TRUE;
}

Expand Down Expand Up @@ -447,7 +528,11 @@ ni_ifconfig_read_firmware(xml_document_array_t *array, const char *type,
}

ni_device_clientinfo_free(client_info);
xml_document_array_append(array, config_doc);

if (ni_ifconfig_validate_adding_doc(array, config_doc, raw))
xml_document_array_append(array, config_doc);
else
xml_document_free(config_doc);
return TRUE;
}

Expand Down Expand Up @@ -476,30 +561,53 @@ ni_ifconfig_generate_client_info(const char *schema, const char *filename, const
return client_info;
}

static ni_bool_t
ni_ifconfig_parse_client_info_xml(const xml_node_t *node, ni_device_clientinfo_t *ci)
{
const xml_node_t *child;

if (!node || !ci)
return FALSE;

if ((child = xml_node_get_child(node, "state"))) {
if (ni_string_empty(child->cdata))
return FALSE;
ni_string_dup(&ci->state, child->cdata);
}

child = xml_node_get_child(node, "config-origin");
if (!child || ni_string_empty(child->cdata))
return FALSE;
ni_string_dup(&ci->config_origin, child->cdata);

child = xml_node_get_child(node, "config-uuid");
if (!child || ni_string_empty(child->cdata) ||
!ni_uuid_parse(&ci->config_uuid, child->cdata)) {
return FALSE;
}

return TRUE;
}


ni_device_clientinfo_t *
ni_ifconfig_get_client_info(xml_document_t *doc)
{
ni_device_clientinfo_t *client_info = NULL;
xml_node_t *cinode = NULL;
const char *val;

if (!doc || !xml_document_root(doc))
return NULL;
ni_device_clientinfo_t *ci;
xml_node_t *cinode;

ni_assert(doc);
/* FIXME: Currently returns either the first occurence or NULL */
cinode = xml_node_get_next_child(doc->root, "interface", cinode);
cinode = xml_node_get_child(xml_document_root(doc), "interface");

if (cinode) {
client_info = ni_device_clientinfo_new();
if ((val = xml_node_get_attr(cinode, "state")))
ni_string_dup(&client_info->state, val);
if ((val = xml_node_get_attr(cinode, "config-origin")))
ni_string_dup(&client_info->config_origin, val);
if ((val = xml_node_get_attr(cinode, "config-uuid")))
ni_uuid_parse(&client_info->config_uuid, val);
ci = ni_device_clientinfo_new();
if (ni_ifconfig_parse_client_info_xml(cinode, ci))
return ci;
ni_device_clientinfo_free(ci);
}

return client_info;
return NULL;
}

void
Expand Down
4 changes: 3 additions & 1 deletion client/wicked-client.h
Expand Up @@ -80,6 +80,7 @@ typedef struct ni_compat_netdev_array {

typedef struct ni_compat_ifconfig {
ni_compat_netdev_array_t netdev_array;
unsigned int timeout;
} ni_compat_ifconfig_t;

extern ni_compat_netdev_t * ni_compat_netdev_new(const char *);
Expand All @@ -93,10 +94,11 @@ extern void ni_compat_netdev_client_info_set(ni_netdev_t *, const char *);
extern unsigned int ni_compat_generate_interfaces(xml_document_array_t *, ni_compat_ifconfig_t *, ni_bool_t);

extern ni_bool_t ni_ifconfig_read(xml_document_array_t *, const char *, const char *, ni_bool_t);
extern ni_bool_t ni_ifconfig_load(ni_fsm_t *, const char *, const char *, ni_bool_t);
extern ni_bool_t ni_ifconfig_load(ni_fsm_t *, const char *, ni_string_array_t *, ni_bool_t);

extern const ni_string_array_t *ni_config_sources(const char *);

extern ni_bool_t ni_ifconfig_validate_adding_doc(xml_document_array_t *, xml_document_t *, ni_bool_t);
extern ni_device_clientinfo_t * ni_ifconfig_generate_client_info(const char *, const char *, const char *);
extern ni_device_clientinfo_t * ni_ifconfig_get_client_info(xml_document_t *);
extern void ni_ifconfig_add_client_info(xml_document_t *, ni_device_clientinfo_t *, char *);
Expand Down
2 changes: 1 addition & 1 deletion include/wicked/fsm.h
Expand Up @@ -259,7 +259,7 @@ extern unsigned int ni_fsm_mark_matching_workers(ni_fsm_t *, ni_ifworker_array_
extern unsigned int ni_fsm_start_matching_workers(ni_fsm_t *, ni_ifworker_array_t *);
extern void ni_fsm_reset_matching_workers(ni_fsm_t *, ni_ifworker_array_t *, const ni_uint_range_t *, ni_bool_t);
extern int ni_fsm_build_hierarchy(ni_fsm_t *);
extern unsigned int ni_fsm_workers_from_xml(ni_fsm_t *, xml_document_t *, ni_bool_t);
extern unsigned int ni_fsm_workers_from_xml(ni_fsm_t *, xml_document_t *);
extern unsigned int ni_fsm_fail_count(ni_fsm_t *);
extern ni_ifworker_t * ni_fsm_ifworker_by_object_path(ni_fsm_t *, const char *);
extern ni_ifworker_t * ni_fsm_ifworker_by_netdev(ni_fsm_t *, const ni_netdev_t *);
Expand Down

0 comments on commit ad7b47d

Please sign in to comment.