Skip to content

Commit

Permalink
Shift control socket commands to the top
Browse files Browse the repository at this point in the history
  • Loading branch information
arr2036 committed May 10, 2024
1 parent 1e2b28a commit 23430ea
Showing 1 changed file with 180 additions and 180 deletions.
360 changes: 180 additions & 180 deletions src/lib/server/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,186 @@ RCSID("$Id$")

#include <talloc.h>

static void module_thread_detach(module_thread_instance_t *ti);

/** Heap of all lists/modules used to get a common index with mlg_thread->inst_list
*/
static fr_heap_t *mlg_index;

/** An array of thread-local module lists
*
* The indexes in this array are identical to module_list_global, allowing
* O(1) lookups. Arrays are used here as there's no performance penalty
* once they're populated.
*/
static _Thread_local module_thread_instance_t **mlg_thread_inst_list;

/** Toggle used to determine if it's safe to use index based lookups
*
* Index based heap lookups are significantly more efficient than binary
* searches, but they can only be performed when all module data is inserted
* into both the global module list and the thread local module list.
*
* When we start removing module lists or modules from the thread local
* heap those heaps no longer have a common index with the global module
* list so we need to revert back to doing binary searches instead of using
* common indexes.
*/
static _Thread_local bool mlg_in_sync;

static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info);
static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx, fr_cmd_info_t *info, int max_expansions, char const **expansions);
static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info);
static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info);
static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info);

fr_cmd_table_t module_cmd_table[] = {
{
.parent = "show module",
.add_name = true,
.name = "status",
.func = cmd_show_module_status,
.help = "Show the status of a particular module.",
.read_only = true,
},

{
.parent = "show module",
.add_name = true,
.name = "config",
.func = cmd_show_module_config,
.help = "Show configuration for a module",
// @todo - do tab expand, by walking over the whole module list...
.read_only = true,
},

{
.parent = "set module",
.add_name = true,
.name = "status",
.syntax = "(alive|disallow|fail|reject|handled|invalid|notfound|noop|ok|updated)",
.func = cmd_set_module_status,
.help = "Change module status to fixed value.",
.read_only = false,
},

CMD_TABLE_END
};

fr_cmd_table_t module_cmd_list_table[] = {
{
.parent = "show",
.name = "module",
.help = "Show information about modules.",
.tab_expand = module_name_tab_expand,
.read_only = true,
},

// @todo - what if there's a module called "list" ?
{
.parent = "show module",
.name = "list",
.func = cmd_show_module_list,
.help = "Show the list of modules loaded in the server.",
.read_only = true,
},

{
.parent = "set",
.name = "module",
.help = "Change module settings.",
.tab_expand = module_name_tab_expand,
.read_only = false,
},


CMD_TABLE_END
};

static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
{
module_instance_t *mi = ctx;

fr_assert(mi->conf != NULL);

(void) cf_section_write(fp, mi->conf, 0);

return 0;
}

static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx,
fr_cmd_info_t *info, int max_expansions, char const **expansions)
{
char const *text;
int count;

if (info->argc <= 0) return 0;

text = info->argv[info->argc - 1];
count = 0;

fr_heap_foreach(mlg_index, module_instance_t, instance) {
module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);

if (count >= max_expansions) {
break;
}
if (fr_command_strncmp(text, mi->name)) {
expansions[count] = strdup(mi->name);
count++;
}
}}

return count;
}

static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info)
{
fr_heap_foreach(mlg_index, module_instance_t, instance) {
module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);

fprintf(fp, "\t%s\n", mi->name);
}}

return 0;
}

static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
{
module_instance_t *mi = ctx;

if (!mi->force) {
fprintf(fp, "alive\n");
return 0;
}

fprintf(fp, "%s\n", fr_table_str_by_value(rcode_table, mi->code, "<invalid>"));

return 0;
}

static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
{
module_instance_t *mi = ctx;
rlm_rcode_t rcode;

if (strcmp(info->argv[0], "alive") == 0) {
mi->force = false;
return 0;
}

rcode = fr_table_value_by_str(rcode_table, info->argv[0], RLM_MODULE_NOT_SET);
if (rcode == RLM_MODULE_NOT_SET) {
fprintf(fp_err, "Unknown status '%s'\n", info->argv[0]);
return -1;
}

mi->code = rcode;
mi->force = true;

return 0;
}

/** dl module tracking
*
* This is used by all module lists, irrespecitve of their type, and is thread safe.
Expand Down Expand Up @@ -159,33 +339,6 @@ struct module_list_type_s {
} thread;
};

static void module_thread_detach(module_thread_instance_t *ti);

/** Heap of all lists/modules used to get a common index with mlg_thread->inst_list
*/
static fr_heap_t *mlg_index;

/** An array of thread-local module lists
*
* The indexes in this array are identical to module_list_global, allowing
* O(1) lookups. Arrays are used here as there's no performance penalty
* once they're populated.
*/
static _Thread_local module_thread_instance_t **mlg_thread_inst_list;

/** Toggle used to determine if it's safe to use index based lookups
*
* Index based heap lookups are significantly more efficient than binary
* searches, but they can only be performed when all module data is inserted
* into both the global module list and the thread local module list.
*
* When we start removing module lists or modules from the thread local
* heap those heaps no longer have a common index with the global module
* list so we need to revert back to doing binary searches instead of using
* common indexes.
*/
static _Thread_local bool mlg_in_sync;

typedef struct {
module_instance_t mi; //!< Common module instance fields. Must come first.

Expand Down Expand Up @@ -433,159 +586,6 @@ module_list_type_t const module_list_type_thread_local = {
}
};

static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info);
static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx, fr_cmd_info_t *info, int max_expansions, char const **expansions);
static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info);
static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info);
static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info);

fr_cmd_table_t module_cmd_table[] = {
{
.parent = "show module",
.add_name = true,
.name = "status",
.func = cmd_show_module_status,
.help = "Show the status of a particular module.",
.read_only = true,
},

{
.parent = "show module",
.add_name = true,
.name = "config",
.func = cmd_show_module_config,
.help = "Show configuration for a module",
// @todo - do tab expand, by walking over the whole module list...
.read_only = true,
},

{
.parent = "set module",
.add_name = true,
.name = "status",
.syntax = "(alive|disallow|fail|reject|handled|invalid|notfound|noop|ok|updated)",
.func = cmd_set_module_status,
.help = "Change module status to fixed value.",
.read_only = false,
},

CMD_TABLE_END
};

fr_cmd_table_t module_cmd_list_table[] = {
{
.parent = "show",
.name = "module",
.help = "Show information about modules.",
.tab_expand = module_name_tab_expand,
.read_only = true,
},

// @todo - what if there's a module called "list" ?
{
.parent = "show module",
.name = "list",
.func = cmd_show_module_list,
.help = "Show the list of modules loaded in the server.",
.read_only = true,
},

{
.parent = "set",
.name = "module",
.help = "Change module settings.",
.tab_expand = module_name_tab_expand,
.read_only = false,
},


CMD_TABLE_END
};

static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
{
module_instance_t *mi = ctx;

fr_assert(mi->conf != NULL);

(void) cf_section_write(fp, mi->conf, 0);

return 0;
}

static int module_name_tab_expand(UNUSED TALLOC_CTX *talloc_ctx, UNUSED void *uctx,
fr_cmd_info_t *info, int max_expansions, char const **expansions)
{
char const *text;
int count;

if (info->argc <= 0) return 0;

text = info->argv[info->argc - 1];
count = 0;

fr_heap_foreach(mlg_index, module_instance_t, instance) {
module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);

if (count >= max_expansions) {
break;
}
if (fr_command_strncmp(text, mi->name)) {
expansions[count] = strdup(mi->name);
count++;
}
}}

return count;
}

static int cmd_show_module_list(FILE *fp, UNUSED FILE *fp_err, UNUSED void *uctx, UNUSED fr_cmd_info_t const *info)
{
fr_heap_foreach(mlg_index, module_instance_t, instance) {
module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t);

fprintf(fp, "\t%s\n", mi->name);
}}

return 0;
}

static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
{
module_instance_t *mi = ctx;

if (!mi->force) {
fprintf(fp, "alive\n");
return 0;
}

fprintf(fp, "%s\n", fr_table_str_by_value(rcode_table, mi->code, "<invalid>"));

return 0;
}

static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
{
module_instance_t *mi = ctx;
rlm_rcode_t rcode;

if (strcmp(info->argv[0], "alive") == 0) {
mi->force = false;
return 0;
}

rcode = fr_table_value_by_str(rcode_table, info->argv[0], RLM_MODULE_NOT_SET);
if (rcode == RLM_MODULE_NOT_SET) {
fprintf(fp_err, "Unknown status '%s'\n", info->argv[0]);
return -1;
}

mi->code = rcode;
mi->force = true;

return 0;
}

/** Return the prefix string for the deepest module
*
* This is useful for submodules which don't have a prefix of their own.
Expand Down

0 comments on commit 23430ea

Please sign in to comment.