From b04e799b3116198146e9d0dc8e4d334db704cf10 Mon Sep 17 00:00:00 2001 From: Kaige Fu Date: Fri, 29 Jun 2018 13:50:50 +0800 Subject: [PATCH] tools :acrntrace: Reserved configurable space on the disk acrntrace writes trace data to /tmp with unlimited size and will cause tmpfs 100% occupied. Consequently, some problem will raise up on SOS, like failing to exec cmd. This patch introduce an option -r to let user configre minimal space left on the disk which ensures that acrntrace will exit when free storage space is less than the reserved space. By default, we reserve 512M on the disk. Users can configure reserved space through '-r'. Signed-off-by: Kaige Fu Reviewed-by: Eddie Dong Reviewed-by: Geoffroy Van Cutsem --- tools/acrntrace/README.rst | 6 ++++++ tools/acrntrace/acrntrace.c | 40 +++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/tools/acrntrace/README.rst b/tools/acrntrace/README.rst index 4c2e1d42e..f7bf2de2e 100644 --- a/tools/acrntrace/README.rst +++ b/tools/acrntrace/README.rst @@ -20,6 +20,8 @@ Options: -h print this message -t period specify polling interval in milliseconds [1-999] -c clear the buffered old data +-r minimal amount (in MB) of free space kept on the disk + before acrntrace stops The ``acrntrace_format.py`` is a offline tool for parsing trace data (as output by acrntrace) to human-readable formats based on given format. @@ -89,6 +91,10 @@ data to your linux system, and running the analysis tool. # acrntrace + 512MB storage space will be reserved by default. This ensures that acrntrace + will exit automatically when the free storage space on the disk is less than + reserved space. Reserved space on the disk is configurable through '-r'. + Trace files are created under ``/tmp/acrntrace/``, with a date-time-based directory name such as ``20171115-101605`` diff --git a/tools/acrntrace/acrntrace.c b/tools/acrntrace/acrntrace.c index deadd485b..d556d824c 100644 --- a/tools/acrntrace/acrntrace.c +++ b/tools/acrntrace/acrntrace.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -17,9 +18,13 @@ #include "acrntrace.h" +/* default minimal amount free space (in MB) left on the disk */ +static uint64_t disk_reserved = 512; +static int exiting = 0; + /* for opt */ static uint64_t period = 10000; -static const char optString[] = "t:hc"; +static const char optString[] = "t:hcr:"; static const char dev_name[] = "/dev/acrn_trace"; static uint32_t flags; @@ -34,6 +39,8 @@ static void display_usage(void) "[Usage] acrntrace [-t] [period in msec] [-ch]\n\n" "[Options]\n" "\t-h: print this message\n" + "\t-r: minimal amount (in MB) of free space kept on the disk\n" + "\t before acrntrace stops\n" "\t-t: period_in_ms: specify polling interval [1-999]\n" "\t-c: clear the buffered old data\n"); } @@ -53,6 +60,15 @@ static int parse_opt(int argc, char *argv[]) period = ret * 1000; pr_dbg("Period is %lu\n", period); break; + case 'r': + ret = atoi(optarg); + if (ret <=0) { + pr_err("'-r' require integer greater than 0\n"); + return -EINVAL; + } + disk_reserved = ret; + pr_dbg("Keeping %dMB of space on the disk\n", ret); + break; case 'c': flags |= FLAG_CLEAR_BUF; break; @@ -179,6 +195,8 @@ static void reader_fn(param_t * param) int fd = param->trace_fd; shared_buf_t *sbuf = param->sbuf; trace_ev_t e; + struct statvfs stat; + uint64_t freespace; pr_dbg("reader thread[%lu] created for FILE*[0x%p]\n", pthread_self(), fp); @@ -192,6 +210,24 @@ static void reader_fn(param_t * param) while (1) { do { + /* Check that filesystem has enough space */ + if (fstatvfs(fd, &stat)) { + printf("Fail to get vfs stat.\n"); + exiting = 1; + exit(EXIT_FAILURE); + } + + freespace = stat.f_frsize * (uint64_t)stat.f_bfree; + freespace >>= 20; /* Convert to MB */ + + if (freespace <= disk_reserved) { + printf("Disk space limit reached (free space:" + "%luMB, limit %luMB).\n", + freespace, disk_reserved); + exiting = 1; + exit(EXIT_FAILURE); + } + ret = sbuf_write(fd, sbuf); } while (ret > 0); @@ -328,7 +364,7 @@ int main(int argc, char *argv[]) /* wait for user input to stop */ printf("q to quit:\n"); - while (getchar() != 'q') + while (!exiting && getchar() != 'q') printf("q to quit:\n"); out_free: