summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_main.c')
-rw-r--r--bgpd/bgp_main.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 9d14683c..69767a9f 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -35,6 +35,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "routemap.h"
#include "filter.h"
#include "plist.h"
+#include "qpnexus.h"
+#include "qlib_init.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
@@ -65,6 +67,7 @@ static const struct option longopts[] =
{ "version", no_argument, NULL, 'v'},
{ "dryrun", no_argument, NULL, 'C'},
{ "help", no_argument, NULL, 'h'},
+ { "threaded", no_argument, NULL, 't'},
{ 0 }
};
@@ -72,6 +75,7 @@ static const struct option longopts[] =
void sighup (void);
void sigint (void);
void sigusr1 (void);
+void sigusr2 (void);
static void bgp_exit (int);
@@ -86,6 +90,10 @@ static struct quagga_signal_t bgp_signals[] =
.handler = &sigusr1,
},
{
+ .signal = SIGUSR2,
+ .handler = &sigusr2,
+ },
+ {
.signal = SIGINT,
.handler = &sigint,
},
@@ -103,6 +111,8 @@ static int retain_mode = 0;
/* Master of threads. */
struct thread_master *master;
+qpn_nexus cli_nexus = NULL;
+qpn_nexus bgp_nexus = NULL;
/* Manually specified configuration file name. */
char *config_file = NULL;
@@ -160,6 +170,7 @@ redistribution between different routing protocols.\n\n\
-v, --version Print program version\n\
-C, --dryrun Check configuration for validity and exit\n\
-h, --help Display this help and exit\n\
+-t, --threaded Use pthreads\n\
\n\
Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
}
@@ -206,6 +217,18 @@ sigusr1 (void)
zlog_rotate (NULL);
}
+/* SIGUSR2 handler. */
+void
+sigusr2 (void)
+{
+ /* Used to signal message queues */
+ if (qpthreads_enabled)
+ return;
+ else
+ exit(1);
+}
+
+
/*
Try to free up allocations we know about so that diagnostic tools such as
valgrind are able to better illuminate leaks.
@@ -296,7 +319,15 @@ bgp_exit (int status)
if (CONF_BGP_DEBUG (normal, NORMAL))
log_memstats_stderr ("bgpd");
- exit (status);
+ if (bgp_nexus)
+ bgp_nexus->terminate = 1;
+
+ if (cli_nexus)
+ cli_nexus->terminate = 1; /* waste of time, its the main thread */
+
+ /* TODO: join threads ? */
+
+ qexit (status);
}
/* Main routine of bgpd. Treatment of argument and start bgp finite
@@ -311,10 +342,13 @@ main (int argc, char **argv)
char *progname;
struct thread thread;
int tmp_port;
+ int threaded = 0;
/* Set umask before anything for security */
umask (0027);
+ qlib_init_first_stage();
+
/* Preserve name of myself. */
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
@@ -327,7 +361,7 @@ main (int argc, char **argv)
/* Command line argument treatment. */
while (1)
{
- opt = getopt_long (argc, argv, "df:i:hp:l:A:P:rnu:g:vC", longopts, 0);
+ opt = getopt_long (argc, argv, "df:i:hp:l:A:P:rnu:g:vCt", longopts, 0);
if (opt == EOF)
break;
@@ -392,6 +426,9 @@ main (int argc, char **argv)
case 'h':
usage (progname, 0);
break;
+ case 't':
+ threaded = 1;
+ break;
default:
usage (progname, 1);
break;
@@ -429,10 +466,21 @@ main (int argc, char **argv)
return (1);
}
-
/* Process ID file creation. */
pid_output (pid_file);
+ /* stage 2 initialisation */
+ qlib_init_second_stage(threaded) ;
+
+ if (qpthreads_enabled)
+ {
+ cli_nexus = qpn_init_main(cli_nexus); /* main thread */
+ bgp_nexus = qpn_init_bgp(bgp_nexus);
+
+ zprivs_init_r ();
+ vty_init_r(cli_nexus, bgp_nexus);
+ }
+
/* Make bgp vty socket. */
vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
@@ -442,9 +490,18 @@ main (int argc, char **argv)
(bm->address ? bm->address : "<all>"),
bm->port);
- /* Start finite state machine, here we go! */
- while (thread_fetch (master, &thread))
- thread_call (&thread);
+ /* Launch finite state machines */
+ if (qpthreads_enabled)
+ {
+ qpn_exec(bgp_nexus);
+ qpn_exec(cli_nexus); /* must be last to start - on main thread */
+ }
+ else
+ {
+ /* Start finite state machine, here we go! */
+ while (thread_fetch (master, &thread))
+ thread_call (&thread);
+ }
/* Not reached. */
return (0);