From c6bf6bfe1dfa3a3989e7d8ccbb71dce6704c5726 Mon Sep 17 00:00:00 2001 From: Kai Krakow Date: Fri, 27 Oct 2017 22:36:00 +0200 Subject: [PATCH 1/6] Implement getopt options parser This commit adds a simple getopt options parser to show help. This can be used as a boilerplate for adding more options later. Signed-off-by: Kai Krakow --- src/bees.cc | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/bees.cc b/src/bees.cc index d555899..f912f12 100644 --- a/src/bees.cc +++ b/src/bees.cc @@ -19,18 +19,23 @@ #include #include +#include + using namespace crucible; using namespace std; int -do_cmd_help(const char **argv) +do_cmd_help(char *argv[]) { - cerr << "Usage: " << argv[0] << " fs-root-path [fs-root-path-2...]\n" + cerr << "Usage: " << argv[0] << " [options] fs-root-path [fs-root-path-2...]\n" "Performs best-effort extent-same deduplication on btrfs.\n" "\n" "fs-root-path MUST be the root of a btrfs filesystem tree (id 5).\n" "Other directories will be rejected.\n" "\n" + "Options:\n" + "\t-h, --help\t\tShow this help\n" + "\n" "Optional environment variables:\n" "\tBEESHOME\tPath to hash table and configuration files\n" "\t\t\t(default is .beeshome/ in the root of each filesystem).\n" @@ -575,7 +580,7 @@ BeesTempFile::make_copy(const BeesFileRange &src) } int -bees_main(int argc, const char **argv) +bees_main(int argc, char *argv[]) { set_catch_explainer([&](string s) { BEESLOG("\n\n*** EXCEPTION ***\n\t" << s << "\n***\n"); @@ -589,14 +594,35 @@ bees_main(int argc, const char **argv) shared_ptr bc; THROW_CHECK1(invalid_argument, argc, argc >= 0); - vector args(argv + 1, argv + argc); + + // Parse options + int c; + while (1) { + int option_index = 0; + static struct option long_options[] = { + { "help", no_argument, NULL, 'h' } + }; + + c = getopt_long(argc, argv, "h", long_options, &option_index); + if (-1 == c) { + break; + } + + switch (c) { + case 'T': + case 'h': + do_cmd_help(argv); + default: + return 2; + } + } // Create a context and start crawlers bool did_subscription = false; - for (string arg : args) { + while (optind < argc) { catch_all([&]() { bc = make_shared(bc); - bc->set_root_path(arg); + bc->set_root_path(argv[optind++]); did_subscription = true; }); } @@ -617,7 +643,7 @@ bees_main(int argc, const char **argv) } int -main(int argc, const char **argv) +main(int argc, char *argv[]) { cerr << "bees version " << BEES_VERSION << endl; From c6be07e158b590d1435d7c373c0368d3f32c9308 Mon Sep 17 00:00:00 2001 From: Kai Krakow Date: Fri, 27 Oct 2017 23:02:47 +0200 Subject: [PATCH 2/6] Add option for prefixing timestamps To make bees more friendly to use with syslog/systemd, we add an option to omit timestamps from the log output. Signed-off-by: Kai Krakow --- include/crucible/chatter.h | 5 +++++ lib/chatter.cc | 27 +++++++++++++++++++-------- scripts/beesd.in | 16 +--------------- src/bees.cc | 18 ++++++++++++++++-- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/include/crucible/chatter.h b/include/crucible/chatter.h index d14c80c..e42620e 100644 --- a/include/crucible/chatter.h +++ b/include/crucible/chatter.h @@ -86,6 +86,11 @@ namespace crucible { } }; + class ChatterTimestamp { + public: + ChatterTimestamp(int); + }; + class ChatterBox { string m_file; int m_line; diff --git a/lib/chatter.cc b/lib/chatter.cc index c9d187b..60dbb61 100644 --- a/lib/chatter.cc +++ b/lib/chatter.cc @@ -17,6 +17,7 @@ namespace crucible { static shared_ptr> chatter_names; static const char *SPACETAB = " \t"; + static int chatter_prefix_timestamp = 1; static void @@ -52,16 +53,21 @@ namespace crucible { { ostringstream header_stream; - time_t ltime; - DIE_IF_MINUS_ONE(time(<ime)); - struct tm ltm; - DIE_IF_ZERO(localtime_r(<ime, <m)); + if (chatter_prefix_timestamp) { + time_t ltime; + DIE_IF_MINUS_ONE(time(<ime)); + struct tm ltm; + DIE_IF_ZERO(localtime_r(<ime, <m)); - char buf[1024]; - DIE_IF_ZERO(strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", <m)); + char buf[1024]; + DIE_IF_ZERO(strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", <m)); + + header_stream << buf; + header_stream << " " << getpid() << "." << gettid(); + } else { + header_stream << "tid " << gettid(); + } - header_stream << buf; - header_stream << " " << getpid() << "." << gettid(); if (!m_name.empty()) { header_stream << " " << m_name; } @@ -91,6 +97,11 @@ namespace crucible { c.m_oss.str(""); } + ChatterTimestamp::ChatterTimestamp(int prefix_timestamp) + { + chatter_prefix_timestamp = prefix_timestamp; + } + set ChatterBox::s_boxes; set& ChatterBox::all_boxes() diff --git a/scripts/beesd.in b/scripts/beesd.in index f99ea09..2e46410 100755 --- a/scripts/beesd.in +++ b/scripts/beesd.in @@ -49,7 +49,6 @@ BEESHOME="${BEESHOME:-$MNT_DIR/.beeshome}" BEESSTATUS="${BEESSTATUS:-$WORK_DIR/$UUID.status}" DB_SIZE="${DB_SIZE:-$((64*AL16M))}" LOG_SHORT_PATH="${LOG_SHORT_PATH:-N}" -LOG_FILTER_TIME="${LOG_FILTER_TIME:-N}" INFO "Check: Disk exists" if [ ! -b "/dev/disk/by-uuid/$UUID" ]; then @@ -101,19 +100,6 @@ fi MNT_DIR="${MNT_DIR//\/\//\/}" -filter_time(){ - if YN $LOG_FILTER_TIME; then - sed -e 's/^.*crawl:/crawl:/g' \ - -e 's/^.*status:/status:/g' \ - -e 's/^.*bees:/bees:/g' \ - -e 's/^.*crawl_writeback:/crawl_writeback:/g' \ - -e 's/^.*main:/main:/g' \ - -e 's/^.*hash_prefetch:/hash_prefetch:/g' - else - cat - fi -} - filter_path(){ if YN $LOG_SHORT_PATH; then sed -e "s#$MNT_DIR##g" @@ -122,6 +108,6 @@ filter_path(){ fi } -@LIBEXEC_PREFIX@/bees "$MNT_DIR" 3>&1 2>&1 | filter_time | filter_path +@LIBEXEC_PREFIX@/bees $OPTIONS "$MNT_DIR" 3>&1 2>&1 | filter_path exit 0 diff --git a/src/bees.cc b/src/bees.cc index f912f12..a79d1fc 100644 --- a/src/bees.cc +++ b/src/bees.cc @@ -35,6 +35,8 @@ do_cmd_help(char *argv[]) "\n" "Options:\n" "\t-h, --help\t\tShow this help\n" + "\t-t, --timestamps\tShow timestamps in log output (default)\n" + "\t-T, --notimestamps\tOmit timestamps in log output\n" "\n" "Optional environment variables:\n" "\tBEESHOME\tPath to hash table and configuration files\n" @@ -595,21 +597,31 @@ bees_main(int argc, char *argv[]) THROW_CHECK1(invalid_argument, argc, argc >= 0); + // Defaults + int chatter_prefix_timestamp = 1; + // Parse options int c; while (1) { int option_index = 0; static struct option long_options[] = { - { "help", no_argument, NULL, 'h' } + { "timestamps", no_argument, NULL, 't' }, + { "notimestamps", no_argument, NULL, 'T' }, + { "help", no_argument, NULL, 'h' } }; - c = getopt_long(argc, argv, "h", long_options, &option_index); + c = getopt_long(argc, argv, "Tth", long_options, &option_index); if (-1 == c) { break; } switch (c) { case 'T': + chatter_prefix_timestamp = 0; + break; + case 't': + chatter_prefix_timestamp = 1; + break; case 'h': do_cmd_help(argv); default: @@ -617,6 +629,8 @@ bees_main(int argc, char *argv[]) } } + ChatterTimestamp cts(chatter_prefix_timestamp); + // Create a context and start crawlers bool did_subscription = false; while (optind < argc) { From 9d67329ef76446e97fb73b661afeed95bb0568bd Mon Sep 17 00:00:00 2001 From: Kai Krakow Date: Fri, 27 Oct 2017 23:10:14 +0200 Subject: [PATCH 3/6] Update README after integrating new features Let's update the README file. Signed-off-by: Kai Krakow --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f737348..3f9d635 100644 --- a/README.md +++ b/README.md @@ -107,9 +107,9 @@ fresh full-filesystem rescan, and restart `bees'. Things You Might Expect That Bees Doesn't Have ---------------------------------------------- -* There's no configuration file or getopt command line option processing -(patches welcome!). There are some tunables hardcoded in the source -that could eventually become configuration options. +* There's no configuration file (patches welcome!). There are some tunables +hardcoded in the source that could eventually become configuration options. +There's also an incomplete option parser (patches welcome!). * There's no way to *stop* the Bees daemon. Use SIGKILL, SIGTERM, or Ctrl-C for now. Some of the destructors are unreachable and have never From 58157d03dd552f35447dbec5e011a91ebc17437d Mon Sep 17 00:00:00 2001 From: Kai Krakow Date: Sat, 28 Oct 2017 00:13:23 +0200 Subject: [PATCH 4/6] Add beesd generated script to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d8ca283..cb02a07 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ latex/ make.log make.log.new localconf +scripts/beesd From 629e33b4f3d9d04c41f7436d56d3ec93a9659169 Mon Sep 17 00:00:00 2001 From: Kai Krakow Date: Sat, 28 Oct 2017 00:13:38 +0200 Subject: [PATCH 5/6] Fix naming --- scripts/beesd.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/beesd.in b/scripts/beesd.in index 2e46410..5aa25ed 100755 --- a/scripts/beesd.in +++ b/scripts/beesd.in @@ -55,10 +55,10 @@ if [ ! -b "/dev/disk/by-uuid/$UUID" ]; then ERRO "Missing disk: /dev/disk/by-uuid/$UUID" fi -it_btrfs(){ [ "$(blkid -s TYPE -o value "$1")" == "btrfs" ]; } +is_btrfs(){ [ "$(blkid -s TYPE -o value "$1")" == "btrfs" ]; } INFO "Check: Disk with btrfs" -if ! it_btrfs "/dev/disk/by-uuid/$UUID"; then +if ! is_btrfs "/dev/disk/by-uuid/$UUID"; then ERRO "Disk not contain btrfs: /dev/disk/by-uuid/$UUID" fi From 47805253e6042e3ef050799e12d2cc9ef4b53756 Mon Sep 17 00:00:00 2001 From: Kai Krakow Date: Sat, 28 Oct 2017 00:14:36 +0200 Subject: [PATCH 6/6] Make service starter accept bees options The service starter wasn't able to pass options to the new getopt parser. This commit fixes it. --- scripts/beesd.in | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/beesd.in b/scripts/beesd.in index 5aa25ed..044fc98 100755 --- a/scripts/beesd.in +++ b/scripts/beesd.in @@ -23,7 +23,23 @@ readonly CONFIG_DIR=@PREFIX@/etc/bees/ command -v @LIBEXEC_PREFIX@/bees &> /dev/null || ERRO "Missing 'bees' agent" ## Parse args -UUID="$1" +ARGUMENTS=() +while [ $# -gt 0 ]; do + case "$1" in + -*) + ARGUMENTS+=($1) + ;; + *) + if [ -z "$UUID" ]; then + UUID="$1" + else + ERRO "Only one filesystem may be supplied" + fi + ;; + esac + shift +done + case "$UUID" in *-*-*-*-*) FILE_CONFIG="" @@ -38,7 +54,7 @@ case "$UUID" in source "$FILE_CONFIG" ;; *) - echo "beesd " + echo "beesd [options] " exit 1 ;; esac @@ -108,6 +124,6 @@ filter_path(){ fi } -@LIBEXEC_PREFIX@/bees $OPTIONS "$MNT_DIR" 3>&1 2>&1 | filter_path +@LIBEXEC_PREFIX@/bees ${ARGUMENTS[@]} $OPTIONS "$MNT_DIR" 3>&1 2>&1 | filter_path exit 0