Skip to content

Commit 8cac639

Browse files
committed
UCP/CORE: Return an error if there is no modifiable configuration.
1 parent 6177e3a commit 8cac639

File tree

5 files changed

+105
-0
lines changed

5 files changed

+105
-0
lines changed

src/ucp/core/ucp_context.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <ucs/debug/debug_int.h>
2424
#include <ucs/sys/compiler.h>
2525
#include <ucs/sys/string.h>
26+
#include <ucs/type/init_once.h>
2627
#include <ucs/vfs/base/vfs_cb.h>
2728
#include <ucs/vfs/base/vfs_obj.h>
2829
#include <string.h>
@@ -863,6 +864,47 @@ ucs_status_t ucp_config_modify_internal(ucp_config_t *config, const char *name,
863864
value);
864865
}
865866

867+
static void ucp_config_query_uct_components(void)
868+
{
869+
static ucs_init_once_t init_once = UCS_INIT_ONCE_INITIALIZER;
870+
uct_component_h *components;
871+
unsigned num_components;
872+
ucs_status_t status;
873+
874+
UCS_INIT_ONCE(&init_once) {
875+
status = uct_query_components(&components, &num_components);
876+
if (status == UCS_OK) {
877+
uct_release_component_list(components);
878+
} else {
879+
ucs_warn("failed to query UCT components: %s",
880+
ucs_status_string(status));
881+
}
882+
}
883+
}
884+
885+
static int ucp_config_global_list_has_field(const char *name)
886+
{
887+
const ucs_config_global_list_entry_t *entry;
888+
const char *field_name;
889+
size_t prefix_len;
890+
891+
ucs_list_for_each(entry, &ucs_config_global_list, list) {
892+
field_name = name;
893+
if (entry->prefix != NULL) {
894+
prefix_len = strlen(entry->prefix);
895+
if (!strncmp(entry->prefix, field_name, prefix_len)) {
896+
field_name += prefix_len;
897+
}
898+
}
899+
900+
if (ucs_config_parser_has_field(entry->table, field_name)) {
901+
return 1;
902+
}
903+
}
904+
905+
return 0;
906+
}
907+
866908
ucs_status_t ucp_config_modify(ucp_config_t *config, const char *name,
867909
const char *value)
868910
{
@@ -878,6 +920,18 @@ ucs_status_t ucp_config_modify(ucp_config_t *config, const char *name,
878920
return status;
879921
}
880922

923+
if (ucs_global_opts_is_unmodifiable(name)) {
924+
ucs_debug("%s configuration cannot be changed, the change is only "
925+
"available through the environment variable",
926+
name);
927+
return UCS_ERR_UNSUPPORTED;
928+
}
929+
930+
ucp_config_query_uct_components();
931+
if (!ucp_config_global_list_has_field(name)) {
932+
return UCS_ERR_NO_ELEM;
933+
}
934+
881935
return ucp_config_cached_key_add(&config->cached_key_list, name, value);
882936
}
883937

src/ucs/config/global_opts.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,11 @@ ucs_status_t ucs_global_opts_set_value_modifiable(const char *name,
368368
NULL, name, value);
369369
}
370370

371+
int ucs_global_opts_is_unmodifiable(const char *name)
372+
{
373+
return ucs_config_parser_has_field(ucs_global_opts_read_only_table, name);
374+
}
375+
371376
ucs_status_t ucs_global_opts_get_value(const char *name, char *value,
372377
size_t max)
373378
{

src/ucs/config/global_opts.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,14 @@ ucs_status_t ucs_global_opts_clone(void *dst);
180180
void ucs_global_opts_release(void);
181181
void ucs_global_opts_print(FILE *stream, ucs_config_print_flags_t print_flags);
182182

183+
/**
184+
* Check if a field is unmodifiable.
185+
*
186+
* @param name Field name to check.
187+
* @return 1 if the field is unmodifiable, 0 otherwise.
188+
*/
189+
int ucs_global_opts_is_unmodifiable(const char *name);
190+
183191
END_C_DECLS
184192

185193
#endif

src/ucs/config/parser.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,3 +2461,31 @@ void ucs_config_parser_cleanup()
24612461
})
24622462
kh_destroy_inplace(ucs_config_map, &ucs_config_file_vars);
24632463
}
2464+
2465+
int ucs_config_parser_has_field(const ucs_config_field_t *fields,
2466+
const char *name)
2467+
{
2468+
const ucs_config_field_t *field;
2469+
size_t table_name_len;
2470+
2471+
if (!fields || !name) {
2472+
return 0;
2473+
}
2474+
2475+
for (field = fields; !ucs_config_field_is_last(field); ++field) {
2476+
if (!strncmp(field->name, name, strlen(name))) {
2477+
return 1;
2478+
}
2479+
2480+
if (ucs_config_is_table_field(field)) {
2481+
table_name_len = strlen(field->name);
2482+
if (!strncmp(field->name, name, table_name_len) &&
2483+
ucs_config_parser_has_field(field->parser.arg,
2484+
name + table_name_len)) {
2485+
return 1;
2486+
}
2487+
}
2488+
}
2489+
2490+
return 0;
2491+
}

src/ucs/config/parser.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,16 @@ void ucs_config_parser_get_env_vars(ucs_string_buffer_t *env_strb,
640640
void ucs_config_parser_cleanup(void);
641641

642642

643+
/**
644+
* Check if a field exists in the configuration table.
645+
*
646+
* @param fields Array of fields which define the configuration table.
647+
* @param name Field name to check.
648+
* @return 1 if the field exists, 0 otherwise.
649+
*/
650+
int ucs_config_parser_has_field(const ucs_config_field_t *fields,
651+
const char *name);
652+
643653
END_C_DECLS
644654

645655
#endif

0 commit comments

Comments
 (0)