summaryrefslogtreecommitdiff
path: root/vtysh/vtysh_main.c
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@nvidia.com>2021-11-19 16:03:02 -0500
committerDonald Sharp <sharpd@nvidia.com>2023-03-28 10:10:33 -0400
commitac768090270459cd032f5f325a8dffa27819c541 (patch)
tree9e4dbf2276fffe4b4a4ae690ee85cb572af964a3 /vtysh/vtysh_main.c
parent449f66552fd85277f9fa8724ae9c26e652ded7e0 (diff)
vtysh: use fork() workflow for -f too
It was being used for -b only; we should be able to use it for -f as well. This also merges the codepaths for -b and -f since they have no real functional difference. Signed-off-by: Quentin Young <qlyoung@nvidia.com>
Diffstat (limited to 'vtysh/vtysh_main.c')
-rw-r--r--vtysh/vtysh_main.c120
1 files changed, 12 insertions, 108 deletions
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index 053d663245..860d79d5f9 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -7,7 +7,6 @@
#include <sys/un.h>
#include <setjmp.h>
-#include <sys/wait.h>
#include <pwd.h>
#include <sys/file.h>
#include <unistd.h>
@@ -345,8 +344,6 @@ int main(int argc, char **argv, char **env)
char pathspace[MAXPATHLEN] = "";
const char *histfile = NULL;
const char *histfile_env = getenv("VTYSH_HISTFILE");
- char my_client[64];
- int my_client_type;
/* SUID: drop down to calling user & go back up when needed */
elevuid = geteuid();
@@ -497,7 +494,7 @@ int main(int argc, char **argv, char **env)
/* Read vtysh configuration file before connecting to daemons.
* (file may not be readable to calling user in SUID mode) */
suid_on();
- vtysh_read_config(vtysh_config, dryrun);
+ vtysh_apply_config(vtysh_config, dryrun, false);
suid_off();
}
/* Error code library system */
@@ -516,9 +513,9 @@ int main(int argc, char **argv, char **env)
/* Start execution only if not in dry-run mode */
if (dryrun && !cmd) {
if (inputfile) {
- ret = vtysh_read_config(inputfile, dryrun);
+ ret = vtysh_apply_config(inputfile, dryrun, false);
} else {
- ret = vtysh_read_config(frr_config, dryrun);
+ ret = vtysh_apply_config(frr_config, dryrun, false);
}
exit(ret);
@@ -597,10 +594,17 @@ int main(int argc, char **argv, char **env)
return vtysh_write_config_integrated();
}
- if (inputfile) {
+ if (boot_flag)
+ inputfile = frr_config;
+
+ if (inputfile || boot_flag) {
vtysh_flock_config(inputfile);
- ret = vtysh_read_config(inputfile, dryrun);
+ ret = vtysh_apply_config(inputfile, dryrun, !no_fork);
vtysh_unflock_config();
+
+ if (no_error)
+ ret = 0;
+
exit(ret);
}
@@ -717,106 +721,6 @@ int main(int argc, char **argv, char **env)
exit(0);
}
- /* Boot startup configuration file. */
- if (boot_flag) {
- /*
- * flock config file before fork. After fork, each child will
- * hold the same lock. The lock can be released by any one of
- * them but they will exit without releasing the lock - the
- * parent (us) will release it when they are done
- */
- vtysh_flock_config(frr_config);
-
- /*
- * In boot mode, we need to apply the whole config file to all
- * daemons. Instead of having one client talk to N daemons, we
- * fork N times and let each child handle one daemon.
- */
- pid_t fork_pid = getpid();
- int status = 0;
-
- if (!no_fork) {
- for (unsigned int i = 0; i < array_size(vtysh_client);
- i++) {
- /* Store name of client this fork will handle */
- strlcpy(my_client, vtysh_client[i].name,
- sizeof(my_client));
- my_client_type = vtysh_client[i].flag;
- fork_pid = fork();
-
- /* If child, break */
- if (fork_pid == 0)
- break;
- }
-
- /* parent, wait for children */
- if (fork_pid != 0) {
- fprintf(stdout,
- "Waiting for children to finish applying config...\n");
- while (wait(&status) > 0)
- ;
- ret = 0;
- goto boot_done;
- }
-
- /*
- * children, grow up to be cowboys
- */
- for (unsigned int i = 0; i < array_size(vtysh_client);
- i++) {
- if (my_client_type != vtysh_client[i].flag) {
- struct vtysh_client *cl;
-
- /*
- * If this is a client we aren't
- * responsible for, disconnect
- */
- for (cl = &vtysh_client[i]; cl;
- cl = cl->next) {
- if (cl->fd >= 0)
- close(cl->fd);
- cl->fd = -1;
- }
- } else if (vtysh_client[i].fd == -1 &&
- vtysh_client[i].next == NULL) {
- /*
- * If this is the client we are
- * responsible for, but we aren't
- * already connected to that client,
- * that means the client isn't up in the
- * first place and we can exit early
- */
- ret = 0;
- goto boot_done;
- }
- }
-
- fprintf(stdout, "[%d|%s] sending configuration\n",
- getpid(), my_client);
- }
-
- ret = vtysh_read_config(frr_config, dryrun);
- if (ret) {
- if (!no_fork)
- fprintf(stderr,
- "[%d|%s] Configuration file[%s] processing failure: %d\n",
- getpid(), my_client, frr_config, ret);
- else
- fprintf(stderr,
- "Configuration file[%s] processing failure: %d\n",
- frr_config, ret);
- if (no_error)
- ret = 0;
- } else if (!no_fork) {
- fprintf(stderr, "[%d|%s] done\n", getpid(), my_client);
- }
-
- boot_done:
- if (fork_pid != 0)
- vtysh_unflock_config();
- exit(ret);
- }
-
vtysh_readline_init();
vty_hello(vty);