summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--bgpd/bgp_updgrp_adv.c2
-rwxr-xr-xbuildtest.sh2
-rw-r--r--configure.ac27
-rw-r--r--doc/developer/building-frr-for-centos6.rst1
-rw-r--r--doc/developer/building-frr-for-centos7.rst1
-rw-r--r--doc/developer/building-frr-for-centos8.rst1
-rw-r--r--doc/developer/building-frr-for-debian8.rst1
-rw-r--r--doc/developer/building-frr-for-debian9.rst1
-rw-r--r--doc/developer/building-frr-for-netbsd6.rst1
-rw-r--r--doc/developer/building-frr-for-netbsd7.rst1
-rw-r--r--doc/developer/include-compile.rst1
-rw-r--r--doc/developer/topotests.rst1
-rw-r--r--doc/user/basic.rst33
-rw-r--r--doc/user/installation.rst24
-rw-r--r--isisd/isis_nb_config.c131
-rw-r--r--lib/command.c30
-rw-r--r--lib/subdir.am3
-rw-r--r--lib/thread.c184
-rw-r--r--lib/thread.h11
-rw-r--r--lib/vty.c54
-rw-r--r--python/xrelfo.py6
-rw-r--r--tests/topotests/bgp_route_map/test_route_map_topo1.py103
-rw-r--r--vtysh/vtysh.c4
24 files changed, 388 insertions, 238 deletions
diff --git a/Makefile.am b/Makefile.am
index a38029dcfa..8c9d7df77c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -109,8 +109,6 @@ CLEANFILES =
DISTCLEANFILES =
SUFFIXES =
-examplesdir = $(exampledir)
-
bin_PROGRAMS =
sbin_PROGRAMS =
sbin_SCRIPTS =
@@ -122,7 +120,6 @@ lib_LTLIBRARIES =
module_LTLIBRARIES =
pkginclude_HEADERS =
nodist_pkginclude_HEADERS =
-dist_examples_DATA =
dist_yangmodels_DATA =
man_MANS =
vtysh_scan =
diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c
index 4dd7597e5f..18829aa747 100644
--- a/bgpd/bgp_updgrp_adv.c
+++ b/bgpd/bgp_updgrp_adv.c
@@ -839,6 +839,8 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
bgp_dest_get_prefix(dest), &tmp_pi);
if (ret == RMAP_DENYMATCH) {
+ /* The aspath belongs to 'attr' */
+ tmp_attr.aspath = NULL;
bgp_attr_flush(&tmp_attr);
continue;
} else {
diff --git a/buildtest.sh b/buildtest.sh
index b4b02d10bf..eeae82fc44 100755
--- a/buildtest.sh
+++ b/buildtest.sh
@@ -4,7 +4,7 @@
# builds some git commit of FRR in some different configurations
# usage: buildtest.sh [commit [configurations...]]
-basecfg="--prefix=/usr --enable-user=frr --enable-group=frr --enable-vty-group=frr --enable-configfile-mask=0660 --enable-logfile-mask=0640 --enable-vtysh --sysconfdir=/etc/frr --enable-exampledir=/etc/frr/samples --localstatedir=/var/run/frr --libdir=/usr/lib64/frr --enable-rtadv --disable-static --enable-isisd --enable-multipath=0 --enable-pimd --enable-werror"
+basecfg="--prefix=/usr --enable-user=frr --enable-group=frr --enable-vty-group=frr --enable-configfile-mask=0660 --enable-logfile-mask=0640 --enable-vtysh --sysconfdir=/etc/frr --localstatedir=/var/run/frr --libdir=/usr/lib64/frr --enable-rtadv --disable-static --enable-isisd --enable-multipath=0 --enable-pimd --enable-werror"
configs_base="gcc|$basecfg"
diff --git a/configure.ac b/configure.ac
index 96bacc9ed4..0ea209bbfa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,15 +114,6 @@ AC_PATH_PROG([PERL], [perl])
PKG_PROG_PKG_CONFIG
dnl default is to match previous behavior
-exampledir=${sysconfdir}
-AC_ARG_ENABLE([exampledir],
- AS_HELP_STRING([--enable-exampledir],
- [specify alternate directory for examples]),
- exampledir="$enableval",)
-dnl XXX add --exampledir to autoconf standard directory list somehow
-AC_SUBST([exampledir])
-
-dnl default is to match previous behavior
pkgsrcrcdir=""
AC_ARG_ENABLE([pkgsrcrcdir],
AS_HELP_STRING([--enable-pkgsrcrcdir],
@@ -663,8 +654,6 @@ AC_ARG_ENABLE([irdp],
AS_HELP_STRING([--disable-irdp], [disable IRDP server support in zebra (enabled by default if supported)]))
AC_ARG_ENABLE([capabilities],
AS_HELP_STRING([--disable-capabilities], [disable using POSIX capabilities]))
-AC_ARG_ENABLE([rusage],
- AS_HELP_STRING([--disable-rusage], [disable using getrusage]))
AC_ARG_ENABLE([gcc_ultra_verbose],
AS_HELP_STRING([--enable-gcc-ultra-verbose], [enable ultra verbose GCC warnings]))
AC_ARG_ENABLE([backtrace],
@@ -794,7 +783,6 @@ fi
if test "$enable_datacenter" = "yes" ; then
AC_DEFINE([HAVE_DATACENTER], [1], [Compile extensions for a DataCenter])
- AC_MSG_WARN([The --enable-datacenter compile time option is deprecated. Please modify the init script to pass -F datacenter to the daemons instead.])
DFLT_NAME="datacenter"
else
DFLT_NAME="traditional"
@@ -2241,6 +2229,10 @@ AC_CHECK_DECL([CLOCK_MONOTONIC],
AC_DEFINE([HAVE_CLOCK_MONOTONIC], [1], [Have monotonic clock])
], [AC_MSG_RESULT([no])], [FRR_INCLUDES])
+AC_CHECK_DECL([CLOCK_THREAD_CPUTIME_ID], [
+ AC_DEFINE([HAVE_CLOCK_THREAD_CPUTIME_ID], [1], [Have cpu-time clock])
+], [AC_MSG_RESULT([no])], [FRR_INCLUDES])
+
AC_SEARCH_LIBS([clock_nanosleep], [rt], [
AC_DEFINE([HAVE_CLOCK_NANOSLEEP], [1], [Have clock_nanosleep()])
])
@@ -2693,7 +2685,6 @@ make : ${MAKE-make}
linker flags : ${LDFLAGS} ${SAN_FLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM}
state file directory : ${frr_statedir}
config file directory : `eval echo \`echo ${sysconfdir}\``
-example directory : `eval echo \`echo ${exampledir}\``
module directory : ${CFG_MODULE}
script directory : ${CFG_SCRIPT}
user to run as : ${enable_user}
@@ -2707,6 +2698,16 @@ vici socket path : ${vici_socket}
The above user and group must have read/write access to the state file
directory and to the config files in the config file directory."
+if test -n "$enable_datacenter"; then
+ AC_MSG_WARN([The --enable-datacenter compile time option is deprecated. Please modify the init script to pass -F datacenter to the daemons instead.])
+fi
+if test -n "$enable_time_check"; then
+ AC_MSG_WARN([The --enable-time-check compile time option is deprecated. Please use the service cputime-stats configuration option instead.])
+fi
+if test -n "$enable_cpu_time"; then
+ AC_MSG_WARN([The --enable-cpu-time compile time option is deprecated. Please use the service cputime-warning NNN configuration option instead.])
+fi
+
if test "$enable_doc" != "no" -a "$frr_py_mod_sphinx" = "false"; then
AC_MSG_WARN([sphinx is missing but required to build documentation])
fi
diff --git a/doc/developer/building-frr-for-centos6.rst b/doc/developer/building-frr-for-centos6.rst
index 5d3be492de..7a7af42119 100644
--- a/doc/developer/building-frr-for-centos6.rst
+++ b/doc/developer/building-frr-for-centos6.rst
@@ -172,7 +172,6 @@ an example.)
--enable-user=frr \
--enable-group=frr \
--enable-vty-group=frrvty \
- --disable-exampledir \
--disable-ldpd \
--enable-fpm \
--with-pkg-git-version \
diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst
index 8d0aea943c..93b9993a38 100644
--- a/doc/developer/building-frr-for-centos7.rst
+++ b/doc/developer/building-frr-for-centos7.rst
@@ -67,7 +67,6 @@ an example.)
--enable-group=frr \
--enable-vty-group=frrvty \
--enable-systemd=yes \
- --disable-exampledir \
--disable-ldpd \
--enable-fpm \
--with-pkg-git-version \
diff --git a/doc/developer/building-frr-for-centos8.rst b/doc/developer/building-frr-for-centos8.rst
index 77fe489358..65c93286b7 100644
--- a/doc/developer/building-frr-for-centos8.rst
+++ b/doc/developer/building-frr-for-centos8.rst
@@ -60,7 +60,6 @@ an example.)
--enable-group=frr \
--enable-vty-group=frrvty \
--enable-systemd=yes \
- --disable-exampledir \
--disable-ldpd \
--enable-fpm \
--with-pkg-git-version \
diff --git a/doc/developer/building-frr-for-debian8.rst b/doc/developer/building-frr-for-debian8.rst
index 51dd07c42a..475e0303fc 100644
--- a/doc/developer/building-frr-for-debian8.rst
+++ b/doc/developer/building-frr-for-debian8.rst
@@ -57,7 +57,6 @@ an example.)
cd frr
./bootstrap.sh
./configure \
- --enable-exampledir=/usr/share/doc/frr/examples/ \
--localstatedir=/var/run/frr \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
diff --git a/doc/developer/building-frr-for-debian9.rst b/doc/developer/building-frr-for-debian9.rst
index 919b010314..1981127b3d 100644
--- a/doc/developer/building-frr-for-debian9.rst
+++ b/doc/developer/building-frr-for-debian9.rst
@@ -44,7 +44,6 @@ an example.)
cd frr
./bootstrap.sh
./configure \
- --enable-exampledir=/usr/share/doc/frr/examples/ \
--localstatedir=/var/opt/frr \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
diff --git a/doc/developer/building-frr-for-netbsd6.rst b/doc/developer/building-frr-for-netbsd6.rst
index e50d11130a..a78f8b3c2f 100644
--- a/doc/developer/building-frr-for-netbsd6.rst
+++ b/doc/developer/building-frr-for-netbsd6.rst
@@ -64,7 +64,6 @@ an example)
export CPPFLAGS="-I/usr/pkg/include"
./configure \
--sysconfdir=/usr/pkg/etc/frr \
- --enable-exampledir=/usr/pkg/share/examples/frr \
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
--localstatedir=/var/run/frr \
--enable-multipath=64 \
diff --git a/doc/developer/building-frr-for-netbsd7.rst b/doc/developer/building-frr-for-netbsd7.rst
index 32d1145edc..a52ece19a1 100644
--- a/doc/developer/building-frr-for-netbsd7.rst
+++ b/doc/developer/building-frr-for-netbsd7.rst
@@ -55,7 +55,6 @@ an example)
export CPPFLAGS="-I/usr/pkg/include"
./configure \
--sysconfdir=/usr/pkg/etc/frr \
- --enable-exampledir=/usr/pkg/share/examples/frr \
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
--localstatedir=/var/run/frr \
--enable-multipath=64 \
diff --git a/doc/developer/include-compile.rst b/doc/developer/include-compile.rst
index 0ff0ae3ffe..d9fa260221 100644
--- a/doc/developer/include-compile.rst
+++ b/doc/developer/include-compile.rst
@@ -15,7 +15,6 @@ obtained by running ``./configure -h``. The options shown below are examples.
./configure \
--prefix=/usr \
--includedir=\${prefix}/include \
- --enable-exampledir=\${prefix}/share/doc/frr/examples \
--bindir=\${prefix}/bin \
--sbindir=\${prefix}/lib/frr \
--libdir=\${prefix}/lib/frr \
diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst
index ba03aa9045..18317cd33c 100644
--- a/doc/developer/topotests.rst
+++ b/doc/developer/topotests.rst
@@ -221,7 +221,6 @@ for ``master`` branch:
--prefix=/usr/lib/frr --sysconfdir=/etc/frr \
--localstatedir=/var/run/frr \
--sbindir=/usr/lib/frr --bindir=/usr/lib/frr \
- --enable-exampledir=/usr/lib/frr/examples \
--with-moduledir=/usr/lib/frr/modules \
--enable-multipath=0 --enable-rtadv \
--enable-tcp-zebra --enable-fpm --enable-pimd \
diff --git a/doc/user/basic.rst b/doc/user/basic.rst
index 6a0249f316..92357bec83 100644
--- a/doc/user/basic.rst
+++ b/doc/user/basic.rst
@@ -80,6 +80,39 @@ Basic Config Commands
Set enable password. The ``no`` form of the command deletes the enable
password.
+.. clicmd:: service cputime-stats
+
+ Collect CPU usage statistics for individual FRR event handlers and CLI
+ commands. This is enabled by default and can be disabled if the extra
+ overhead causes a noticeable slowdown on your system.
+
+ Disabling these statistics will also make the
+ :clicmd:`service cputime-warning (1-4294967295)` limit non-functional.
+
+.. clicmd:: service cputime-warning (1-4294967295)
+
+ Warn if the CPU usage of an event handler or CLI command exceeds the
+ specified limit (in milliseconds.) Such warnings are generally indicative
+ of some routine in FRR mistakenly blocking/hogging the processing loop and
+ should be reported as a FRR bug.
+
+ The default limit is 5 seconds (i.e. 5000), but this can be changed by the
+ deprecated ``--enable-time-check=...`` compile-time option.
+
+ This command has no effect if :clicmd:`service cputime-stats` is disabled.
+
+.. clicmd:: service walltime-warning (1-4294967295)
+
+ Warn if the total wallclock time spent handling an event or executing a CLI
+ command exceeds the specified limit (in milliseconds.) This includes time
+ spent waiting for I/O or other tasks executing and may produce excessive
+ warnings if the system is overloaded. (This may still be useful to
+ provide an immediate sign that FRR is not operating correctly due to
+ externally caused starvation.)
+
+ The default limit is 5 seconds as above, including the same deprecated
+ ``--enable-time-check=...`` compile-time option.
+
.. clicmd:: log trap LEVEL
These commands are deprecated and are present only for historical
diff --git a/doc/user/installation.rst b/doc/user/installation.rst
index f7e45a6231..63254555d9 100644
--- a/doc/user/installation.rst
+++ b/doc/user/installation.rst
@@ -199,6 +199,10 @@ options from the list below.
.. option:: --enable-datacenter
+ This option is deprecated as it is superseded by the `-F` (profile) command
+ line option which allows adjusting the setting at startup rather than
+ compile time.
+
Enable system defaults to work as if in a Data Center. See defaults.h
for what is changed by this configure option.
@@ -343,20 +347,17 @@ options from the list below.
.. option:: --enable-time-check XXX
- When this is enabled with a XXX value in microseconds, any thread that
- runs for over this value will cause a warning to be issued to the log.
- If you do not specify any value or don't include this option then
- the default time is 5 seconds. If --disable-time-check is specified
- then no warning is issued for any thread run length.
+ This option is deprecated as it was replaced by the
+ :clicmd:`service cputime-stats` CLI command, which may be adjusted at
+ runtime rather than being a compile-time setting. See there for further
+ detail.
.. option:: --disable-cpu-time
- Disable cpu process accounting, this command also disables the `show thread cpu`
- command. If this option is disabled, --enable-time-check is ignored. This
- disabling of cpu time effectively means that the getrusage call is skipped.
- Since this is a process switch into the kernel, systems with high FRR
- load might see improvement in behavior. Be aware that `show thread cpu`
- is considered a good data gathering tool from the perspective of developers.
+ This option is deprecated as it was replaced by the
+ :clicmd:`service cputime-warning NNN` CLI command, which may be adjusted at
+ runtime rather than being a compile-time setting. See there for further
+ detail.
.. option:: --enable-pcreposix
@@ -561,7 +562,6 @@ the options you chose:
./configure \
--prefix=/usr \
- --enable-exampledir=/usr/share/doc/frr/examples/ \
--localstatedir=/var/run/frr \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index 2622c5b51b..4a01c728f0 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -111,6 +111,28 @@ int isis_instance_is_type_modify(struct nb_cb_modify_args *args)
return NB_OK;
}
+struct sysid_iter {
+ struct area_addr *addr;
+ bool same;
+};
+
+static int sysid_iter_cb(const struct lyd_node *dnode, void *arg)
+{
+ struct sysid_iter *iter = arg;
+ struct area_addr addr;
+ const char *net;
+
+ net = yang_dnode_get_string(dnode, NULL);
+ addr.addr_len = dotformat2buff(addr.area_addr, net);
+
+ if (memcmp(GETSYSID(iter->addr), GETSYSID((&addr)), ISIS_SYS_ID_LEN)) {
+ iter->same = false;
+ return YANG_ITER_STOP;
+ }
+
+ return YANG_ITER_CONTINUE;
+}
+
/*
* XPath: /frr-isisd:isis/instance/area-address
*/
@@ -119,14 +141,12 @@ int isis_instance_area_address_create(struct nb_cb_create_args *args)
struct isis_area *area;
struct area_addr addr, *addrr = NULL, *addrp = NULL;
struct listnode *node;
+ struct sysid_iter iter;
uint8_t buff[255];
const char *net_title = yang_dnode_get_string(args->dnode, NULL);
switch (args->event) {
case NB_EV_VALIDATE:
- area = nb_running_get_entry(args->dnode, NULL, false);
- if (area == NULL)
- return NB_ERR_VALIDATION;
addr.addr_len = dotformat2buff(buff, net_title);
memcpy(addr.area_addr, buff, addr.addr_len);
if (addr.area_addr[addr.addr_len - 1] != 0) {
@@ -135,15 +155,18 @@ int isis_instance_area_address_create(struct nb_cb_create_args *args)
"nsel byte (last byte) in area address must be 0");
return NB_ERR_VALIDATION;
}
- if (area->isis->sysid_set) {
- /* Check that the SystemID portions match */
- if (memcmp(area->isis->sysid, GETSYSID((&addr)),
- ISIS_SYS_ID_LEN)) {
- snprintf(
- args->errmsg, args->errmsg_len,
- "System ID must not change when defining additional area addresses");
- return NB_ERR_VALIDATION;
- }
+
+ iter.addr = &addr;
+ iter.same = true;
+
+ yang_dnode_iterate(sysid_iter_cb, &iter, args->dnode,
+ "../area-address");
+
+ if (!iter.same) {
+ snprintf(
+ args->errmsg, args->errmsg_len,
+ "System ID must not change when defining additional area addresses");
+ return NB_ERR_VALIDATION;
}
break;
case NB_EV_PREPARE:
@@ -2360,14 +2383,14 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args)
{
struct isis_area *area;
+ const char *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
- area = nb_running_get_entry(args->dnode, NULL, false);
- if (area == NULL || area->isis == NULL)
- return NB_ERR_VALIDATION;
+ vrfname = yang_dnode_get_string(
+ lyd_parent(lyd_parent(args->dnode)), "./vrf");
- if (area->isis->vrf_id != VRF_DEFAULT) {
+ if (strcmp(vrfname, VRF_DEFAULT_NAME)) {
snprintf(args->errmsg, args->errmsg_len,
"LDP-Sync only runs on Default VRF");
return NB_ERR_VALIDATION;
@@ -2404,14 +2427,15 @@ int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args)
{
struct isis_area *area;
uint16_t holddown;
+ const char *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
- area = nb_running_get_entry(args->dnode, NULL, false);
- if (area == NULL || area->isis == NULL)
- return NB_ERR_VALIDATION;
+ vrfname = yang_dnode_get_string(
+ lyd_parent(lyd_parent(lyd_parent(args->dnode))),
+ "./vrf");
- if (area->isis->vrf_id != VRF_DEFAULT) {
+ if (strcmp(vrfname, VRF_DEFAULT_NAME)) {
snprintf(args->errmsg, args->errmsg_len,
"LDP-Sync only runs on Default VRF");
return NB_ERR_VALIDATION;
@@ -3180,26 +3204,14 @@ int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args)
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
bool ldp_sync_enable;
- struct interface *ifp;
+ const char *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
- ifp = nb_running_get_entry(
- lyd_parent(lyd_parent(lyd_parent(args->dnode))), NULL,
- false);
- if (ifp == NULL)
- return NB_ERR_VALIDATION;
- if (if_is_loopback(ifp)) {
- snprintf(args->errmsg, args->errmsg_len,
- "LDP-Sync does not run on loopback interface");
- return NB_ERR_VALIDATION;
- }
-
- circuit = nb_running_get_entry(args->dnode, NULL, false);
- if (circuit == NULL || circuit->area == NULL)
- break;
-
- if (circuit->isis->vrf_id != VRF_DEFAULT) {
+ vrfname = yang_dnode_get_string(
+ lyd_parent(lyd_parent(lyd_parent(args->dnode))),
+ "./vrf");
+ if (strcmp(vrfname, VRF_DEFAULT_NAME)) {
snprintf(args->errmsg, args->errmsg_len,
"LDP-Sync only runs on Default VRF");
return NB_ERR_VALIDATION;
@@ -3236,27 +3248,14 @@ int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args)
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
uint16_t holddown;
- struct interface *ifp;
+ const char *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
-
- ifp = nb_running_get_entry(
- lyd_parent(lyd_parent(lyd_parent(args->dnode))), NULL,
- false);
- if (ifp == NULL)
- return NB_ERR_VALIDATION;
- if (if_is_loopback(ifp)) {
- snprintf(args->errmsg, args->errmsg_len,
- "LDP-Sync does not run on loopback interface");
- return NB_ERR_VALIDATION;
- }
-
- circuit = nb_running_get_entry(args->dnode, NULL, false);
- if (circuit == NULL || circuit->area == NULL)
- break;
-
- if (circuit->isis->vrf_id != VRF_DEFAULT) {
+ vrfname = yang_dnode_get_string(
+ lyd_parent(lyd_parent(lyd_parent(args->dnode))),
+ "./vrf");
+ if (strcmp(vrfname, VRF_DEFAULT_NAME)) {
snprintf(args->errmsg, args->errmsg_len,
"LDP-Sync only runs on Default VRF");
return NB_ERR_VALIDATION;
@@ -3282,26 +3281,14 @@ int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args)
{
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
- struct interface *ifp;
+ const char *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
- ifp = nb_running_get_entry(
- lyd_parent(lyd_parent(lyd_parent(args->dnode))), NULL,
- false);
- if (ifp == NULL)
- return NB_ERR_VALIDATION;
- if (if_is_loopback(ifp)) {
- snprintf(args->errmsg, args->errmsg_len,
- "LDP-Sync does not run on loopback interface");
- return NB_ERR_VALIDATION;
- }
-
- circuit = nb_running_get_entry(args->dnode, NULL, false);
- if (circuit == NULL || circuit->area == NULL)
- break;
-
- if (circuit->isis->vrf_id != VRF_DEFAULT) {
+ vrfname = yang_dnode_get_string(
+ lyd_parent(lyd_parent(lyd_parent(args->dnode))),
+ "./vrf");
+ if (strcmp(vrfname, VRF_DEFAULT_NAME)) {
snprintf(args->errmsg, args->errmsg_len,
"LDP-Sync only runs on Default VRF");
return NB_ERR_VALIDATION;
diff --git a/lib/command.c b/lib/command.c
index 7be54907ed..e00d84a051 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -434,6 +434,36 @@ static int config_write_host(struct vty *vty)
}
log_config_write(vty);
+ /* print disable always, but enable only if default is flipped
+ * => prep for future removal of compile-time knob
+ */
+ if (!cputime_enabled)
+ vty_out(vty, "no service cputime-stats\n");
+#ifdef EXCLUDE_CPU_TIME
+ else
+ vty_out(vty, "service cputime-stats\n");
+#endif
+
+ if (!cputime_threshold)
+ vty_out(vty, "no service cputime-warning\n");
+#if defined(CONSUMED_TIME_CHECK) && CONSUMED_TIME_CHECK != 5000000
+ else /* again, always print non-default */
+#else
+ else if (cputime_threshold != 5000000)
+#endif
+ vty_out(vty, "service cputime-warning %lu\n",
+ cputime_threshold);
+
+ if (!walltime_threshold)
+ vty_out(vty, "no service walltime-warning\n");
+#if defined(CONSUMED_TIME_CHECK) && CONSUMED_TIME_CHECK != 5000000
+ else /* again, always print non-default */
+#else
+ else if (walltime_threshold != 5000000)
+#endif
+ vty_out(vty, "service walltime-warning %lu\n",
+ walltime_threshold);
+
if (host.advanced)
vty_out(vty, "service advanced-vty\n");
diff --git a/lib/subdir.am b/lib/subdir.am
index 4015c67ea8..90301d800a 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -168,6 +168,7 @@ clippy_scan += \
lib/northbound_cli.c \
lib/plist.c \
lib/routemap_cli.c \
+ lib/thread.c \
lib/vty.c \
# end
@@ -463,7 +464,7 @@ endif
SUFFIXES += .xref
%.xref: % $(CLIPPY)
- $(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py $(XRELFO_FLAGS) -o $@ $<
+ $(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py $(WERROR) $(XRELFO_FLAGS) -o $@ $<
# dependencies added in python/makefile.py
frr.xref:
diff --git a/lib/thread.c b/lib/thread.c
index 3af89fad5a..835aa38115 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -90,7 +90,22 @@ static struct list *masters;
static void thread_free(struct thread_master *master, struct thread *thread);
+#ifndef EXCLUDE_CPU_TIME
+#define EXCLUDE_CPU_TIME 0
+#endif
+#ifndef CONSUMED_TIME_CHECK
+#define CONSUMED_TIME_CHECK 0
+#endif
+
+bool cputime_enabled = !EXCLUDE_CPU_TIME;
+unsigned long cputime_threshold = CONSUMED_TIME_CHECK;
+unsigned long walltime_threshold = CONSUMED_TIME_CHECK;
+
/* CLI start ---------------------------------------------------------------- */
+#ifndef VTYSH_EXTRACT_PL
+#include "lib/thread_clippy.c"
+#endif
+
static unsigned int cpu_record_hash_key(const struct cpu_thread_history *a)
{
int size = sizeof(a->func);
@@ -120,7 +135,6 @@ static void cpu_record_hash_free(void *a)
XFREE(MTYPE_THREAD_STATS, hist);
}
-#ifndef EXCLUDE_CPU_TIME
static void vty_out_cpu_thread_history(struct vty *vty,
struct cpu_thread_history *a)
{
@@ -187,6 +201,14 @@ static void cpu_record_print(struct vty *vty, uint8_t filter)
struct thread_master *m;
struct listnode *ln;
+ if (!cputime_enabled)
+ vty_out(vty,
+ "\n"
+ "Collecting CPU time statistics is currently disabled. Following statistics\n"
+ "will be zero or may display data from when collection was enabled. Use the\n"
+ " \"service cputime-stats\" command to start collecting data.\n"
+ "\nCounters and wallclock times are always maintained and should be accurate.\n");
+
memset(&tmp, 0, sizeof(tmp));
tmp.funcname = "TOTAL";
tmp.types = filter;
@@ -236,7 +258,6 @@ static void cpu_record_print(struct vty *vty, uint8_t filter)
if (tmp.total_calls > 0)
vty_out_cpu_thread_history(vty, &tmp);
}
-#endif
static void cpu_record_hash_clear(struct hash_bucket *bucket, void *args[])
{
@@ -306,7 +327,6 @@ static uint8_t parse_filter(const char *filterstr)
return filter;
}
-#ifndef EXCLUDE_CPU_TIME
DEFUN_NOSH (show_thread_cpu,
show_thread_cpu_cmd,
"show thread cpu [FILTER]",
@@ -331,7 +351,61 @@ DEFUN_NOSH (show_thread_cpu,
cpu_record_print(vty, filter);
return CMD_SUCCESS;
}
-#endif
+
+DEFPY (service_cputime_stats,
+ service_cputime_stats_cmd,
+ "[no] service cputime-stats",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Collect CPU usage statistics\n")
+{
+ cputime_enabled = !no;
+ return CMD_SUCCESS;
+}
+
+DEFPY (service_cputime_warning,
+ service_cputime_warning_cmd,
+ "[no] service cputime-warning (1-4294967295)",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Warn for tasks exceeding CPU usage threshold\n"
+ "Warning threshold in milliseconds\n")
+{
+ if (no)
+ cputime_threshold = 0;
+ else
+ cputime_threshold = cputime_warning * 1000;
+ return CMD_SUCCESS;
+}
+
+ALIAS (service_cputime_warning,
+ no_service_cputime_warning_cmd,
+ "no service cputime-warning",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Warn for tasks exceeding CPU usage threshold\n")
+
+DEFPY (service_walltime_warning,
+ service_walltime_warning_cmd,
+ "[no] service walltime-warning (1-4294967295)",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Warn for tasks exceeding total wallclock threshold\n"
+ "Warning threshold in milliseconds\n")
+{
+ if (no)
+ walltime_threshold = 0;
+ else
+ walltime_threshold = walltime_warning * 1000;
+ return CMD_SUCCESS;
+}
+
+ALIAS (service_walltime_warning,
+ no_service_walltime_warning_cmd,
+ "no service walltime-warning",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Warn for tasks exceeding total wallclock threshold\n")
static void show_thread_poll_helper(struct vty *vty, struct thread_master *m)
{
@@ -421,11 +495,15 @@ DEFUN (clear_thread_cpu,
void thread_cmd_init(void)
{
-#ifndef EXCLUDE_CPU_TIME
install_element(VIEW_NODE, &show_thread_cpu_cmd);
-#endif
install_element(VIEW_NODE, &show_thread_poll_cmd);
install_element(ENABLE_NODE, &clear_thread_cpu_cmd);
+
+ install_element(CONFIG_NODE, &service_cputime_stats_cmd);
+ install_element(CONFIG_NODE, &service_cputime_warning_cmd);
+ install_element(CONFIG_NODE, &no_service_cputime_warning_cmd);
+ install_element(CONFIG_NODE, &service_walltime_warning_cmd);
+ install_element(CONFIG_NODE, &no_service_walltime_warning_cmd);
}
/* CLI end ------------------------------------------------------------------ */
@@ -1743,9 +1821,14 @@ static unsigned long timeval_elapsed(struct timeval a, struct timeval b)
unsigned long thread_consumed_time(RUSAGE_T *now, RUSAGE_T *start,
unsigned long *cputime)
{
+#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
+ *cputime = (now->cpu.tv_sec - start->cpu.tv_sec) * TIMER_SECOND_MICRO
+ + (now->cpu.tv_nsec - start->cpu.tv_nsec) / 1000;
+#else
/* This is 'user + sys' time. */
*cputime = timeval_elapsed(now->cpu.ru_utime, start->cpu.ru_utime)
+ timeval_elapsed(now->cpu.ru_stime, start->cpu.ru_stime);
+#endif
return timeval_elapsed(now->real, start->real);
}
@@ -1778,13 +1861,23 @@ void thread_set_yield_time(struct thread *thread, unsigned long yield_time)
void thread_getrusage(RUSAGE_T *r)
{
+ monotime(&r->real);
+ if (!cputime_enabled) {
+ memset(&r->cpu, 0, sizeof(r->cpu));
+ return;
+ }
+
+#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
+ /* not currently implemented in Linux's vDSO, but maybe at some point
+ * in the future?
+ */
+ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &r->cpu);
+#else /* !HAVE_CLOCK_THREAD_CPUTIME_ID */
#if defined RUSAGE_THREAD
#define FRR_RUSAGE RUSAGE_THREAD
#else
#define FRR_RUSAGE RUSAGE_SELF
#endif
- monotime(&r->real);
-#ifndef EXCLUDE_CPU_TIME
getrusage(FRR_RUSAGE, &(r->cpu));
#endif
}
@@ -1802,13 +1895,14 @@ void thread_getrusage(RUSAGE_T *r)
*/
void thread_call(struct thread *thread)
{
-#ifndef EXCLUDE_CPU_TIME
- _Atomic unsigned long realtime, cputime;
- unsigned long exp;
- unsigned long helper;
-#endif
RUSAGE_T before, after;
+ /* if the thread being called is the CLI, it may change cputime_enabled
+ * ("service cputime-stats" command), which can result in nonsensical
+ * and very confusing warnings
+ */
+ bool cputime_enabled_here = cputime_enabled;
+
if (thread->master->ready_run_loop)
before = thread->master->last_getrusage;
else
@@ -1828,43 +1922,45 @@ void thread_call(struct thread *thread)
GETRUSAGE(&after);
thread->master->last_getrusage = after;
-#ifndef EXCLUDE_CPU_TIME
- realtime = thread_consumed_time(&after, &before, &helper);
- cputime = helper;
+ unsigned long walltime, cputime;
+ unsigned long exp;
+
+ walltime = thread_consumed_time(&after, &before, &cputime);
- /* update realtime */
- atomic_fetch_add_explicit(&thread->hist->real.total, realtime,
+ /* update walltime */
+ atomic_fetch_add_explicit(&thread->hist->real.total, walltime,
memory_order_seq_cst);
exp = atomic_load_explicit(&thread->hist->real.max,
memory_order_seq_cst);
- while (exp < realtime
+ while (exp < walltime
&& !atomic_compare_exchange_weak_explicit(
- &thread->hist->real.max, &exp, realtime,
- memory_order_seq_cst, memory_order_seq_cst))
+ &thread->hist->real.max, &exp, walltime,
+ memory_order_seq_cst, memory_order_seq_cst))
;
- /* update cputime */
- atomic_fetch_add_explicit(&thread->hist->cpu.total, cputime,
- memory_order_seq_cst);
- exp = atomic_load_explicit(&thread->hist->cpu.max,
- memory_order_seq_cst);
- while (exp < cputime
- && !atomic_compare_exchange_weak_explicit(
- &thread->hist->cpu.max, &exp, cputime,
- memory_order_seq_cst, memory_order_seq_cst))
- ;
+ if (cputime_enabled_here && cputime_enabled) {
+ /* update cputime */
+ atomic_fetch_add_explicit(&thread->hist->cpu.total, cputime,
+ memory_order_seq_cst);
+ exp = atomic_load_explicit(&thread->hist->cpu.max,
+ memory_order_seq_cst);
+ while (exp < cputime
+ && !atomic_compare_exchange_weak_explicit(
+ &thread->hist->cpu.max, &exp, cputime,
+ memory_order_seq_cst, memory_order_seq_cst))
+ ;
+ }
atomic_fetch_add_explicit(&thread->hist->total_calls, 1,
memory_order_seq_cst);
atomic_fetch_or_explicit(&thread->hist->types, 1 << thread->add_type,
memory_order_seq_cst);
-#ifdef CONSUMED_TIME_CHECK
- if (cputime > CONSUMED_TIME_CHECK) {
+ if (cputime_enabled_here && cputime_enabled && cputime_threshold
+ && cputime > cputime_threshold) {
/*
- * We have a CPU Hog on our hands. The time FRR
- * has spent doing actual work ( not sleeping )
- * is greater than 5 seconds.
+ * We have a CPU Hog on our hands. The time FRR has spent
+ * doing actual work (not sleeping) is greater than 5 seconds.
* Whinge about it now, so we're aware this is yet another task
* to fix.
*/
@@ -1874,13 +1970,13 @@ void thread_call(struct thread *thread)
EC_LIB_SLOW_THREAD_CPU,
"CPU HOG: task %s (%lx) ran for %lums (cpu time %lums)",
thread->xref->funcname, (unsigned long)thread->func,
- realtime / 1000, cputime / 1000);
- } else if (realtime > CONSUMED_TIME_CHECK) {
+ walltime / 1000, cputime / 1000);
+
+ } else if (walltime_threshold && walltime > walltime_threshold) {
/*
- * The runtime for a task is greater than 5 seconds, but
- * the cpu time is under 5 seconds. Let's whine
- * about this because this could imply some sort of
- * scheduling issue.
+ * The runtime for a task is greater than 5 seconds, but the
+ * cpu time is under 5 seconds. Let's whine about this because
+ * this could imply some sort of scheduling issue.
*/
atomic_fetch_add_explicit(&thread->hist->total_wall_warn,
1, memory_order_seq_cst);
@@ -1888,10 +1984,8 @@ void thread_call(struct thread *thread)
EC_LIB_SLOW_THREAD_WALL,
"STARVATION: task %s (%lx) ran for %lums (cpu time %lums)",
thread->xref->funcname, (unsigned long)thread->func,
- realtime / 1000, cputime / 1000);
+ walltime / 1000, cputime / 1000);
}
-#endif /* CONSUMED_TIME_CHECK */
-#endif /* Exclude CPU Time */
}
/* Execute thread */
diff --git a/lib/thread.h b/lib/thread.h
index fee728dbf9..abd94ff4f0 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -33,8 +33,19 @@
extern "C" {
#endif
+extern bool cputime_enabled;
+extern unsigned long cputime_threshold;
+/* capturing wallclock time is always enabled since it is fast (reading
+ * hardware TSC w/o syscalls)
+ */
+extern unsigned long walltime_threshold;
+
struct rusage_t {
+#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
+ struct timespec cpu;
+#else
struct rusage cpu;
+#endif
struct timeval real;
};
#define RUSAGE_T struct rusage_t
diff --git a/lib/vty.c b/lib/vty.c
index 50d116c564..f64ab83847 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -502,37 +502,37 @@ static int vty_command(struct vty *vty, char *buf)
zlog_notice("%s%s", prompt_str, buf);
}
-#ifdef CONSUMED_TIME_CHECK
- {
- RUSAGE_T before;
- RUSAGE_T after;
- unsigned long realtime, cputime;
+ RUSAGE_T before;
+ RUSAGE_T after;
+ unsigned long walltime, cputime;
- GETRUSAGE(&before);
-#endif /* CONSUMED_TIME_CHECK */
+ /* cmd_execute() may change cputime_enabled if we're executing the
+ * "service cputime-stats" command, which can result in nonsensical
+ * and very confusing warnings
+ */
+ bool cputime_enabled_here = cputime_enabled;
- ret = cmd_execute(vty, buf, NULL, 0);
+ GETRUSAGE(&before);
- /* Get the name of the protocol if any */
- protocolname = frr_protoname;
+ ret = cmd_execute(vty, buf, NULL, 0);
-#ifdef CONSUMED_TIME_CHECK
- GETRUSAGE(&after);
- realtime = thread_consumed_time(&after, &before, &cputime);
- if (cputime > CONSUMED_TIME_CHECK) {
- /* Warn about CPU hog that must be fixed. */
- flog_warn(
- EC_LIB_SLOW_THREAD_CPU,
- "CPU HOG: command took %lums (cpu time %lums): %s",
- realtime / 1000, cputime / 1000, buf);
- } else if (realtime > CONSUMED_TIME_CHECK) {
- flog_warn(
- EC_LIB_SLOW_THREAD_WALL,
- "STARVATION: command took %lums (cpu time %lums): %s",
- realtime / 1000, cputime / 1000, buf);
- }
- }
-#endif /* CONSUMED_TIME_CHECK */
+ GETRUSAGE(&after);
+
+ walltime = thread_consumed_time(&after, &before, &cputime);
+
+ if (cputime_enabled_here && cputime_enabled && cputime_threshold
+ && cputime > cputime_threshold)
+ /* Warn about CPU hog that must be fixed. */
+ flog_warn(EC_LIB_SLOW_THREAD_CPU,
+ "CPU HOG: command took %lums (cpu time %lums): %s",
+ walltime / 1000, cputime / 1000, buf);
+ else if (walltime_threshold && walltime > walltime_threshold)
+ flog_warn(EC_LIB_SLOW_THREAD_WALL,
+ "STARVATION: command took %lums (cpu time %lums): %s",
+ walltime / 1000, cputime / 1000, buf);
+
+ /* Get the name of the protocol if any */
+ protocolname = frr_protoname;
if (ret != CMD_SUCCESS)
switch (ret) {
diff --git a/python/xrelfo.py b/python/xrelfo.py
index 0ecd008579..17262da8d9 100644
--- a/python/xrelfo.py
+++ b/python/xrelfo.py
@@ -357,6 +357,7 @@ def main():
argp.add_argument('--out-by-file', type=str, help='write by-file JSON output')
argp.add_argument('-Wlog-format', action='store_const', const=True)
argp.add_argument('-Wlog-args', action='store_const', const=True)
+ argp.add_argument('-Werror', action='store_const', const=True)
argp.add_argument('--profile', action='store_const', const=True)
argp.add_argument('binaries', metavar='BINARY', nargs='+', type=str, help='files to read (ELF files or libtool objects)')
args = argp.parse_args()
@@ -380,9 +381,12 @@ def _main(args):
traceback.print_exc()
for option in dir(args):
- if option.startswith('W'):
+ if option.startswith('W') and option != 'Werror':
checks = sorted(xrelfo.check(args))
sys.stderr.write(''.join([c[-1] for c in checks]))
+
+ if args.Werror and len(checks) > 0:
+ errors += 1
break
diff --git a/tests/topotests/bgp_route_map/test_route_map_topo1.py b/tests/topotests/bgp_route_map/test_route_map_topo1.py
index 0158e24d31..74172501db 100644
--- a/tests/topotests/bgp_route_map/test_route_map_topo1.py
+++ b/tests/topotests/bgp_route_map/test_route_map_topo1.py
@@ -20,47 +20,6 @@
# OF THIS SOFTWARE.
#
-#################################
-# TOPOLOGY
-#################################
-"""
-
- +-------+
- +------- | R2 |
- | +-------+
- | |
- +-------+ |
- | R1 | |
- +-------+ |
- | |
- | +-------+ +-------+
- +---------- | R3 |----------| R4 |
- +-------+ +-------+
-
-"""
-
-#################################
-# TEST SUMMARY
-#################################
-"""
-Following tests are covered to test route-map functionality:
-TC_34:
- Verify if route-maps is applied in both inbound and
- outbound direction to same neighbor/interface.
-TC_36:
- Test permit/deny statements operation in route-maps with a
- permutation and combination of permit/deny in prefix-lists
-TC_35:
- Test multiple sequence numbers in a single route-map for different
- match/set clauses.
-TC_37:
- Test add/remove route-maps with multiple set
- clauses and without any match statement.(Set only)
-TC_38:
- Test add/remove route-maps with multiple match
- clauses and without any set statement.(Match only)
-"""
-
import sys
import json
import time
@@ -91,6 +50,7 @@ from lib.common_config import (
create_bgp_community_lists,
interface_status,
create_route_maps,
+ create_static_routes,
create_prefix_lists,
verify_route_maps,
check_address_types,
@@ -107,6 +67,46 @@ from lib.bgp import (
)
from lib.topojson import build_topo_from_json, build_config_from_json
+#################################
+# TOPOLOGY
+#################################
+"""
+
+ +-------+
+ +------- | R2 |
+ | +-------+
+ | |
+ +-------+ |
+ | R1 | |
+ +-------+ |
+ | |
+ | +-------+ +-------+
+ +---------- | R3 |----------| R4 |
+ +-------+ +-------+
+
+"""
+
+#################################
+# TEST SUMMARY
+#################################
+"""
+Following tests are covered to test route-map functionality:
+TC_34:
+ Verify if route-maps is applied in both inbound and
+ outbound direction to same neighbor/interface.
+TC_36:
+ Test permit/deny statements operation in route-maps with a
+ permutation and combination of permit/deny in prefix-lists
+TC_35:
+ Test multiple sequence numbers in a single route-map for different
+ match/set clauses.
+TC_37:
+ Test add/remove route-maps with multiple set
+ clauses and without any match statement.(Set only)
+TC_38:
+ Test add/remove route-maps with multiple match
+ clauses and without any set statement.(Match only)
+"""
# Global variables
bgp_convergence = False
@@ -475,8 +475,8 @@ def test_route_map_inbound_outbound_same_neighbor_p0(request):
result = verify_rib(
tgen, adt, dut, input_dict_2, protocol=protocol, expected=False
)
- assert result is not True, "Testcase {} : Failed \n"
- "routes are not present in rib \n Error: {}".format(tc_name, result)
+ assert result is not True, ("Testcase {} : Failed \n"
+ "routes are not present in rib \n Error: {}".format(tc_name, result))
logger.info("Expected behaviour: {}".format(result))
# Verifying RIB routes
@@ -495,8 +495,8 @@ def test_route_map_inbound_outbound_same_neighbor_p0(request):
result = verify_rib(
tgen, adt, dut, input_dict, protocol=protocol, expected=False
)
- assert result is not True, "Testcase {} : Failed \n "
- "routes are not present in rib \n Error: {}".format(tc_name, result)
+ assert result is not True, ("Testcase {} : Failed \n "
+ "routes are not present in rib \n Error: {}".format(tc_name, result))
logger.info("Expected behaviour: {}".format(result))
write_test_footer(tc_name)
@@ -687,14 +687,17 @@ def test_route_map_with_action_values_combination_of_prefix_action_p0(
}
# tgen.mininet_cli()
- result = verify_rib(
- tgen, adt, dut, input_dict_2, protocol=protocol, expected=False
- )
if "deny" in [prefix_action, rmap_action]:
- assert result is not True, "Testcase {} : Failed \n "
- "Routes are still present \n Error: {}".format(tc_name, result)
+ result = verify_rib(
+ tgen, adt, dut, input_dict_2, protocol=protocol, expected=False
+ )
+ assert result is not True, ("Testcase {} : Failed \n "
+ "Routes are still present \n Error: {}".format(tc_name, result))
logger.info("Expected behaviour: {}".format(result))
else:
+ result = verify_rib(
+ tgen, adt, dut, input_dict_2, protocol=protocol
+ )
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result
)
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 41b7bc8a10..507c6ce882 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -2851,7 +2851,6 @@ DEFUN (vtysh_show_poll,
return show_per_daemon(vty, argv, argc, "Thread statistics for %s:\n");
}
-#ifndef EXCLUDE_CPU_TIME
DEFUN (vtysh_show_thread,
vtysh_show_thread_cmd,
"show thread cpu [FILTER]",
@@ -2862,7 +2861,6 @@ DEFUN (vtysh_show_thread,
{
return show_per_daemon(vty, argv, argc, "Thread statistics for %s:\n");
}
-#endif
DEFUN (vtysh_show_work_queues,
vtysh_show_work_queues_cmd,
@@ -4567,9 +4565,7 @@ void vtysh_init_vty(void)
install_element(VIEW_NODE, &vtysh_show_modules_cmd);
install_element(VIEW_NODE, &vtysh_show_work_queues_cmd);
install_element(VIEW_NODE, &vtysh_show_work_queues_daemon_cmd);
-#ifndef EXCLUDE_CPU_TIME
install_element(VIEW_NODE, &vtysh_show_thread_cmd);
-#endif
install_element(VIEW_NODE, &vtysh_show_poll_cmd);
/* Logging */