mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 07:37:29 +00:00
Merge pull request #2449 from donaldsharp/lib_delayed_read
Lib delayed read
This commit is contained in:
commit
ec446a4673
@ -405,6 +405,18 @@ These options apply to all |PACKAGE_NAME| daemons.
|
|||||||
|
|
||||||
Print program version.
|
Print program version.
|
||||||
|
|
||||||
|
.. option:: --log <stdout|syslog|file:/path/to/log/file>
|
||||||
|
|
||||||
|
When initializing the daemon, setup the log to go to either stdout,
|
||||||
|
syslog or to a file. These values will be displayed as part of
|
||||||
|
a show run. Additionally they can be overridden at runtime if
|
||||||
|
desired via the normal log commands.
|
||||||
|
|
||||||
|
.. option:: --log-level <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>
|
||||||
|
|
||||||
|
When initializing the daemon, allow the specification of a default
|
||||||
|
log level at startup from one of the specified levels.
|
||||||
|
|
||||||
.. _loadable-module-support:
|
.. _loadable-module-support:
|
||||||
|
|
||||||
Loadable Module Support
|
Loadable Module Support
|
||||||
|
19
ldpd/ldpd.c
19
ldpd/ldpd.c
@ -187,6 +187,22 @@ FRR_DAEMON_INFO(ldpd, LDP,
|
|||||||
.privs = &ldpd_privs,
|
.privs = &ldpd_privs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
static int ldp_config_fork_apply(struct thread *t)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* So the frr_config_fork() function schedules
|
||||||
|
* the read of the vty config( if there is a
|
||||||
|
* non-integrated config ) to be after the
|
||||||
|
* end of startup and we are starting the
|
||||||
|
* main process loop. We need to schedule
|
||||||
|
* the application of this if necessary
|
||||||
|
* after the read in of the config.
|
||||||
|
*/
|
||||||
|
ldp_config_apply(NULL, vty_conf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -195,6 +211,7 @@ main(int argc, char *argv[])
|
|||||||
int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
|
int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
|
||||||
int pipe_parent2lde[2], pipe_parent2lde_sync[2];
|
int pipe_parent2lde[2], pipe_parent2lde_sync[2];
|
||||||
char *ctl_sock_name;
|
char *ctl_sock_name;
|
||||||
|
struct thread *thread = NULL;
|
||||||
|
|
||||||
ldpd_process = PROC_MAIN;
|
ldpd_process = PROC_MAIN;
|
||||||
log_procname = log_procnames[ldpd_process];
|
log_procname = log_procnames[ldpd_process];
|
||||||
@ -331,7 +348,7 @@ main(int argc, char *argv[])
|
|||||||
frr_config_fork();
|
frr_config_fork();
|
||||||
|
|
||||||
/* apply configuration */
|
/* apply configuration */
|
||||||
ldp_config_apply(NULL, vty_conf);
|
thread_add_event(master, ldp_config_fork_apply, NULL, 0, &thread);
|
||||||
|
|
||||||
/* setup pipes to children */
|
/* setup pipes to children */
|
||||||
if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL ||
|
if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL ||
|
||||||
|
@ -2429,6 +2429,7 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel)
|
|||||||
XFREE(MTYPE_TMP, p);
|
XFREE(MTYPE_TMP, p);
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
if (vty)
|
||||||
vty_out(vty, "can't open logfile %s\n", fname);
|
vty_out(vty, "can't open logfile %s\n", fname);
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
}
|
}
|
||||||
@ -2445,6 +2446,36 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel)
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void command_setup_early_logging(const char *dest, const char *level)
|
||||||
|
{
|
||||||
|
char *token;
|
||||||
|
|
||||||
|
if (level) {
|
||||||
|
int nlevel = level_match(level);
|
||||||
|
|
||||||
|
if (nlevel != ZLOG_DISABLED)
|
||||||
|
zlog_default->default_lvl = nlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dest)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (strcmp(dest, "stdout") == 0) {
|
||||||
|
zlog_set_level(ZLOG_DEST_STDOUT, zlog_default->default_lvl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(dest, "syslog") == 0) {
|
||||||
|
zlog_set_level(ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = strstr(dest, ":");
|
||||||
|
token++;
|
||||||
|
|
||||||
|
set_log_file(NULL, token, zlog_default->default_lvl);
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (config_log_file,
|
DEFUN (config_log_file,
|
||||||
config_log_file_cmd,
|
config_log_file_cmd,
|
||||||
"log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
|
"log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
|
||||||
|
@ -479,4 +479,5 @@ extern void
|
|||||||
cmd_variable_handler_register(const struct cmd_variable_handler *cvh);
|
cmd_variable_handler_register(const struct cmd_variable_handler *cvh);
|
||||||
extern char *cmd_variable_comp2str(vector comps, unsigned short cols);
|
extern char *cmd_variable_comp2str(vector comps, unsigned short cols);
|
||||||
|
|
||||||
|
extern void command_setup_early_logging(const char *dest, const char *level);
|
||||||
#endif /* _ZEBRA_COMMAND_H */
|
#endif /* _ZEBRA_COMMAND_H */
|
||||||
|
47
lib/libfrr.c
47
lib/libfrr.c
@ -78,6 +78,8 @@ static void opt_extend(const struct optspec *os)
|
|||||||
|
|
||||||
#define OPTION_VTYSOCK 1000
|
#define OPTION_VTYSOCK 1000
|
||||||
#define OPTION_MODULEDIR 1002
|
#define OPTION_MODULEDIR 1002
|
||||||
|
#define OPTION_LOG 1003
|
||||||
|
#define OPTION_LOGLEVEL 1004
|
||||||
|
|
||||||
static const struct option lo_always[] = {
|
static const struct option lo_always[] = {
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
@ -86,6 +88,8 @@ static const struct option lo_always[] = {
|
|||||||
{"module", no_argument, NULL, 'M'},
|
{"module", no_argument, NULL, 'M'},
|
||||||
{"vty_socket", required_argument, NULL, OPTION_VTYSOCK},
|
{"vty_socket", required_argument, NULL, OPTION_VTYSOCK},
|
||||||
{"moduledir", required_argument, NULL, OPTION_MODULEDIR},
|
{"moduledir", required_argument, NULL, OPTION_MODULEDIR},
|
||||||
|
{"log", required_argument, NULL, OPTION_LOG},
|
||||||
|
{"log-level", required_argument, NULL, OPTION_LOGLEVEL},
|
||||||
{NULL}};
|
{NULL}};
|
||||||
static const struct optspec os_always = {
|
static const struct optspec os_always = {
|
||||||
"hvdM:",
|
"hvdM:",
|
||||||
@ -94,7 +98,9 @@ static const struct optspec os_always = {
|
|||||||
" -d, --daemon Runs in daemon mode\n"
|
" -d, --daemon Runs in daemon mode\n"
|
||||||
" -M, --module Load specified module\n"
|
" -M, --module Load specified module\n"
|
||||||
" --vty_socket Override vty socket path\n"
|
" --vty_socket Override vty socket path\n"
|
||||||
" --moduledir Override modules directory\n",
|
" --moduledir Override modules directory\n"
|
||||||
|
" --log Set Logging to stdout, syslog, or file:<name>\n"
|
||||||
|
" --log-level Set Logging Level to use, debug, info, warn, etc\n",
|
||||||
lo_always};
|
lo_always};
|
||||||
|
|
||||||
|
|
||||||
@ -444,6 +450,12 @@ static int frr_opt(int opt)
|
|||||||
return 1;
|
return 1;
|
||||||
di->privs->group = optarg;
|
di->privs->group = optarg;
|
||||||
break;
|
break;
|
||||||
|
case OPTION_LOG:
|
||||||
|
di->early_logging = optarg;
|
||||||
|
break;
|
||||||
|
case OPTION_LOGLEVEL:
|
||||||
|
di->early_loglevel = optarg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -543,9 +555,8 @@ struct thread_master *frr_init(void)
|
|||||||
|
|
||||||
openzlog(di->progname, di->logname, di->instance,
|
openzlog(di->progname, di->logname, di->instance,
|
||||||
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
|
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
|
||||||
#if defined(HAVE_CUMULUS)
|
|
||||||
zlog_set_level(ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
|
command_setup_early_logging(di->early_logging, di->early_loglevel);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!frr_zclient_addr(&zclient_addr, &zclient_addr_len,
|
if (!frr_zclient_addr(&zclient_addr, &zclient_addr_len,
|
||||||
frr_zclientpath)) {
|
frr_zclientpath)) {
|
||||||
@ -721,15 +732,37 @@ static void frr_daemonize(void)
|
|||||||
frr_daemon_wait(fds[0]);
|
frr_daemon_wait(fds[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Why is this a thread?
|
||||||
|
*
|
||||||
|
* The read in of config for integrated config happens *after*
|
||||||
|
* thread execution starts( because it is passed in via a vtysh -b -n )
|
||||||
|
* While if you are not using integrated config we want the ability
|
||||||
|
* to read the config in after thread execution starts, so that
|
||||||
|
* we can match this behavior.
|
||||||
|
*/
|
||||||
|
static int frr_config_read_in(struct thread *t)
|
||||||
|
{
|
||||||
|
if (!vty_read_config(di->config_file, config_default) &&
|
||||||
|
di->backup_config_file) {
|
||||||
|
zlog_info("Attempting to read backup config file: %s specified",
|
||||||
|
di->backup_config_file);
|
||||||
|
vty_read_config(di->backup_config_file, config_default);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void frr_config_fork(void)
|
void frr_config_fork(void)
|
||||||
{
|
{
|
||||||
hook_call(frr_late_init, master);
|
hook_call(frr_late_init, master);
|
||||||
|
|
||||||
vty_read_config(di->config_file, config_default);
|
|
||||||
|
|
||||||
/* Don't start execution if we are in dry-run mode */
|
/* Don't start execution if we are in dry-run mode */
|
||||||
if (di->dryrun)
|
if (di->dryrun) {
|
||||||
|
frr_config_read_in(NULL);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_add_event(master, frr_config_read_in, NULL, 0, &di->read_in);
|
||||||
|
|
||||||
if (di->daemon_mode || di->terminal)
|
if (di->daemon_mode || di->terminal)
|
||||||
frr_daemonize();
|
frr_daemonize();
|
||||||
|
@ -50,11 +50,16 @@ struct frr_daemon_info {
|
|||||||
bool dryrun;
|
bool dryrun;
|
||||||
bool daemon_mode;
|
bool daemon_mode;
|
||||||
bool terminal;
|
bool terminal;
|
||||||
|
|
||||||
|
struct thread *read_in;
|
||||||
const char *config_file;
|
const char *config_file;
|
||||||
|
const char *backup_config_file;
|
||||||
const char *pid_file;
|
const char *pid_file;
|
||||||
const char *vty_path;
|
const char *vty_path;
|
||||||
const char *module_path;
|
const char *module_path;
|
||||||
const char *pathspace;
|
const char *pathspace;
|
||||||
|
const char *early_logging;
|
||||||
|
const char *early_loglevel;
|
||||||
|
|
||||||
const char *proghelp;
|
const char *proghelp;
|
||||||
void (*printhelp)(FILE *target);
|
void (*printhelp)(FILE *target);
|
||||||
|
10
lib/vty.c
10
lib/vty.c
@ -2462,12 +2462,13 @@ static FILE *vty_use_backup_config(const char *fullpath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read up configuration file from file_name. */
|
/* Read up configuration file from file_name. */
|
||||||
void vty_read_config(const char *config_file, char *config_default_dir)
|
bool vty_read_config(const char *config_file, char *config_default_dir)
|
||||||
{
|
{
|
||||||
char cwd[MAXPATHLEN];
|
char cwd[MAXPATHLEN];
|
||||||
FILE *confp = NULL;
|
FILE *confp = NULL;
|
||||||
const char *fullpath;
|
const char *fullpath;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
|
bool read_success = false;
|
||||||
|
|
||||||
/* If -f flag specified. */
|
/* If -f flag specified. */
|
||||||
if (config_file != NULL) {
|
if (config_file != NULL) {
|
||||||
@ -2525,9 +2526,11 @@ void vty_read_config(const char *config_file, char *config_default_dir)
|
|||||||
|
|
||||||
if (strstr(config_default_dir, "vtysh") == NULL) {
|
if (strstr(config_default_dir, "vtysh") == NULL) {
|
||||||
ret = stat(integrate_default, &conf_stat);
|
ret = stat(integrate_default, &conf_stat);
|
||||||
if (ret >= 0)
|
if (ret >= 0) {
|
||||||
|
read_success = true;
|
||||||
goto tmp_free_and_out;
|
goto tmp_free_and_out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif /* VTYSH */
|
#endif /* VTYSH */
|
||||||
confp = fopen(config_default_dir, "r");
|
confp = fopen(config_default_dir, "r");
|
||||||
if (confp == NULL) {
|
if (confp == NULL) {
|
||||||
@ -2550,6 +2553,7 @@ void vty_read_config(const char *config_file, char *config_default_dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vty_read_file(confp);
|
vty_read_file(confp);
|
||||||
|
read_success = true;
|
||||||
|
|
||||||
fclose(confp);
|
fclose(confp);
|
||||||
|
|
||||||
@ -2558,6 +2562,8 @@ void vty_read_config(const char *config_file, char *config_default_dir)
|
|||||||
tmp_free_and_out:
|
tmp_free_and_out:
|
||||||
if (tmp)
|
if (tmp)
|
||||||
XFREE(MTYPE_TMP, tmp);
|
XFREE(MTYPE_TMP, tmp);
|
||||||
|
|
||||||
|
return read_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Small utility function which output log to the VTY. */
|
/* Small utility function which output log to the VTY. */
|
||||||
|
@ -242,7 +242,7 @@ extern void vty_frame(struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3);
|
|||||||
extern void vty_endframe(struct vty *, const char *);
|
extern void vty_endframe(struct vty *, const char *);
|
||||||
bool vty_set_include(struct vty *vty, const char *regexp);
|
bool vty_set_include(struct vty *vty, const char *regexp);
|
||||||
|
|
||||||
extern void vty_read_config(const char *, char *);
|
extern bool vty_read_config(const char *, char *);
|
||||||
extern void vty_time_print(struct vty *, int);
|
extern void vty_time_print(struct vty *, int);
|
||||||
extern void vty_serv_sock(const char *, unsigned short, const char *);
|
extern void vty_serv_sock(const char *, unsigned short, const char *);
|
||||||
extern void vty_close(struct vty *);
|
extern void vty_close(struct vty *);
|
||||||
|
@ -2415,10 +2415,11 @@ DEFUNSH(VTYSH_ALL, vtysh_log_syslog, vtysh_log_syslog_cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEFUNSH(VTYSH_ALL, no_vtysh_log_syslog, no_vtysh_log_syslog_cmd,
|
DEFUNSH(VTYSH_ALL, no_vtysh_log_syslog, no_vtysh_log_syslog_cmd,
|
||||||
"no log syslog [LEVEL]", NO_STR
|
"no log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
|
||||||
|
NO_STR
|
||||||
"Logging control\n"
|
"Logging control\n"
|
||||||
"Cancel logging to syslog\n"
|
"Cancel logging to syslog\n"
|
||||||
"Logging level\n")
|
LOG_LEVEL_DESC)
|
||||||
{
|
{
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user