From 4e85324729f8c11135b131310089fff4d81692e9 Mon Sep 17 00:00:00 2001 From: Mark Vitale Date: Fri, 18 Sep 2020 12:46:57 -0400 Subject: [PATCH] xstat: prevent CPU loop when -period 0 Historically xstat_cm_test and xstat_fs_test have supported option '-period ' to specify continuous operaiton for a length of time. If '-period 0' was specified, both programs exited immediately. Beginning with commits 2c1a7e47336c8f8d14dd6c65d53925a9e0e87c66 'xstat: add xstat_*_Wait functions' and 6b67cac432043a43d7cdfa6af972ab54412aff94 'convert xstat and friends to pthreads', xstat_cm_test and xstat_fs_test now support -period 0 to run "forever". This support is implemented in xstat_cm_Wait and xstat_fs_Wait, respectively. Although the "wait forever" logic was added to allow consolidation of similar code in afsmonitor, it also changed how xstat_cm_test and xstat_fs_test behave for '-period 0'. Unfortunately, there is a bug in this support, at least when running on pthreads. After the initial 24 minute timer expires, the while (1) will repeatedly run select with a timeout that is now 0. This causes the while loop to consume 100% of the CPU on which this thread is dispatched. Instead, modify the wait-forever logic to specify NULL for the select() timeout value. Also update the man page to document that '-period 0' means forever. Change-Id: I25d0d5be0eedb8bf3de495785b9b03a3e3d45221 Reviewed-on: https://gerrit.openafs.org/14366 Tested-by: BuildBot Reviewed-by: Benjamin Kaduk --- doc/man-pages/pod1/xstat_fs_test.pod | 3 ++- src/xstat/xstat_cm.c | 4 +--- src/xstat/xstat_fs.c | 4 +--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/doc/man-pages/pod1/xstat_fs_test.pod b/doc/man-pages/pod1/xstat_fs_test.pod index b405cb7..f8d94db 100644 --- a/doc/man-pages/pod1/xstat_fs_test.pod +++ b/doc/man-pages/pod1/xstat_fs_test.pod @@ -94,7 +94,8 @@ Cache Manager. The default is 30 seconds. =item B<-period> > Sets the number of minutes the program runs; at the end of this period of -time, the program exits. The default is 10 minutes. +time, the program exits. The default is 10 minutes. Period 0 means run +forever. =item B<-debug> diff --git a/src/xstat/xstat_cm.c b/src/xstat/xstat_cm.c index a7d0a03..9850d43 100644 --- a/src/xstat/xstat_cm.c +++ b/src/xstat/xstat_cm.c @@ -662,8 +662,6 @@ xstat_cm_Wait(int sleep_secs) } } else if (sleep_secs == 0) { /* Sleep forever. */ - tv.tv_sec = 24 * 60; - tv.tv_usec = 0; if (xstat_cm_debug) fprintf(stderr, "[%s] going to sleep ...\n", rn); while (1) { @@ -671,7 +669,7 @@ xstat_cm_Wait(int sleep_secs) 0, /*Descriptors ready for reading */ 0, /*Descriptors ready for writing */ 0, /*Descriptors with exceptional conditions */ - &tv); /*Timeout structure */ + NULL); /* NULL timeout means "forever" */ if (code < 0) { fprintf(stderr, "[%s] select() error %d\n", rn, errno); break; diff --git a/src/xstat/xstat_fs.c b/src/xstat/xstat_fs.c index 3ebf97f..3145a00 100644 --- a/src/xstat/xstat_fs.c +++ b/src/xstat/xstat_fs.c @@ -856,8 +856,6 @@ xstat_fs_Wait(int sleep_secs) } } else if (sleep_secs == 0) { /* Sleep forever. */ - tv.tv_sec = 24 * 60; - tv.tv_usec = 0; if (xstat_fs_debug) fprintf(stderr, "[ %s ] going to sleep ...\n", rn); while (1) { @@ -865,7 +863,7 @@ xstat_fs_Wait(int sleep_secs) 0, /*Descriptors ready for reading */ 0, /*Descriptors ready for writing */ 0, /*Descriptors with exceptional conditions */ - &tv); /*Timeout structure */ + NULL); /* NULL timeout means "forever" */ if (code < 0) { fprintf(stderr, "[%s] select() error %d\n", rn, errno); break; -- 1.9.4