From 11fd4ada696a42345b57240a937fda5ca53d4e1d Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Mon, 16 Feb 2026 17:54:41 +0100 Subject: [PATCH] Support decimal point for -p, --plan --- HISTORY | 2 ++ Makefile.am | 2 +- cmdline/scrub.c | 20 ++++++++++---------- cmdline/snapraid.c | 17 +++++++++-------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/HISTORY b/HISTORY index 6258721b..5a2a672e 100644 --- a/HISTORY +++ b/HISTORY @@ -24,6 +24,8 @@ SnapRAID HISTORY reclaiming unused space ("holes") that may exist in the parity due to previous fragmentation, allowing to compact the parity toward the beginning [Ralf1108]. + * The -p / --plan option now accepts percentage values with decimal points + (e.g. -p 1.5, -p 0.2) * Added detection of the smartctl executable. Improves reliability when running under sudo or in environments where /sbin and /usr/sbin are not in PATH. * Avoided saving the content file when it was not strictly necessary. diff --git a/Makefile.am b/Makefile.am index d7f4b5b1..d3a97ba6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -642,7 +642,7 @@ endif $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) fix -e $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --percentage bad scrub - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --plan 1 scrub + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --plan 1.5 scrub $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -o 0 scrub $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -p full scrub $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync diff --git a/cmdline/scrub.c b/cmdline/scrub.c index 8b956c90..a36a091f 100644 --- a/cmdline/scrub.c +++ b/cmdline/scrub.c @@ -786,7 +786,7 @@ static uint32_t md(uint32_t a, uint32_t b, uint32_t c) return v; } -int state_scrub(struct snapraid_state* state, int plan, int olderthan) +int state_scrub(struct snapraid_state* state, int plan100, int olderthan) { block_off_t blockmax; block_off_t countlimit; @@ -804,7 +804,7 @@ int state_scrub(struct snapraid_state* state, int plan, int olderthan) msg_progress("Initializing...\n"); - if ((plan == SCRUB_BAD || plan == SCRUB_NEW || plan == SCRUB_FULL) + if ((plan100 == SCRUB_BAD || plan100 == SCRUB_NEW || plan100 == SCRUB_FULL) && olderthan >= 0) { /* LCOV_EXCL_START */ log_fatal(EUSER, "You can specify -o, --older-than only with a numeric percentage.\n"); @@ -821,13 +821,13 @@ int state_scrub(struct snapraid_state* state, int plan, int olderthan) ps.state = state; if (state->opt.force_scrub_even) { ps.plan = SCRUB_EVEN; - } else if (plan == SCRUB_FULL) { + } else if (plan100 == SCRUB_FULL) { ps.plan = SCRUB_FULL; msg_progress("Scrub plan: full. All data blocks will be checked.\n"); - } else if (plan == SCRUB_NEW) { + } else if (plan100 == SCRUB_NEW) { ps.plan = SCRUB_NEW; msg_progress("Scrub plan: new. Only blocks that have never been scrubbed will be checked.\n"); - } else if (plan == SCRUB_BAD) { + } else if (plan100 == SCRUB_BAD) { ps.plan = SCRUB_BAD; msg_progress("Scrub plan: bad. Only blocks previously marked as bad will be checked.\n"); } else if (state->opt.force_scrub_at) { @@ -837,8 +837,8 @@ int state_scrub(struct snapraid_state* state, int plan, int olderthan) recentlimit = now; } else { ps.plan = SCRUB_AUTO; - if (plan >= 0) { - countlimit = md(blockmax, plan, 100); + if (plan100 >= 0) { + countlimit = md(blockmax, plan100, 10000); } else { /* by default scrub 8.33% of the array (100/12=8.(3)) */ countlimit = md(blockmax, 1, 12); @@ -851,11 +851,11 @@ int state_scrub(struct snapraid_state* state, int plan, int olderthan) recentlimit = now - 10 * 24 * 3600; } - if (plan >= 0) { + if (plan100 >= 0) { if (olderthan >= 0) - msg_progress("Scrub plan: auto. %d%% of the array, older than %d days, will be checked.\n", plan, olderthan); + msg_progress("Scrub plan: auto. %.1f%% of the array, older than %d days, will be checked.\n", plan100 / 100.0, olderthan); else - msg_progress("Scrub plan: auto. %d%% of the array, older than 10 days, will be checked.\n", plan); + msg_progress("Scrub plan: auto. %.1f%% of the array, older than 10 days, will be checked.\n", plan100 / 100.0); } else { if (olderthan >= 0) msg_progress("Scrub plan: auto. 8.3%% of the array, older than %d days, will be checked.\n", olderthan); diff --git a/cmdline/snapraid.c b/cmdline/snapraid.c index 60be4d73..0b12f3bb 100644 --- a/cmdline/snapraid.c +++ b/cmdline/snapraid.c @@ -981,7 +981,7 @@ int snapraid_main(int argc, char* argv[]) tommy_list filterlist_disk; int filter_missing; int filter_error; - int plan; + int plan100; int olderthan; char* e; const char* command; @@ -1019,7 +1019,7 @@ int snapraid_main(int argc, char* argv[]) speed_test_disks_number = -1; filter_missing = 0; filter_error = 0; - plan = SCRUB_AUTO; + plan100 = SCRUB_AUTO; olderthan = SCRUB_AUTO; import_timestamp = 0; import_content = 0; @@ -1082,14 +1082,15 @@ int snapraid_main(int argc, char* argv[]) break; case 'p' : if (strcmp(optarg, "bad") == 0) { - plan = SCRUB_BAD; + plan100 = SCRUB_BAD; } else if (strcmp(optarg, "new") == 0) { - plan = SCRUB_NEW; + plan100 = SCRUB_NEW; } else if (strcmp(optarg, "full") == 0) { - plan = SCRUB_FULL; + plan100 = SCRUB_FULL; } else { - plan = strtoul(optarg, &e, 10); - if (!e || *e || plan > 100) { + double plan_double = strtod(optarg, &e); + plan100 = plan_double * 100; + if (!e || *e || plan100 > 10000) { /* LCOV_EXCL_START */ log_fatal(EUSER, "Invalid plan/percentage '%s'\n", optarg); exit(EXIT_FAILURE); @@ -1937,7 +1938,7 @@ int snapraid_main(int argc, char* argv[]) /* intercept signals while operating */ signal_init(); - ret = state_scrub(&state, plan, olderthan); + ret = state_scrub(&state, plan100, olderthan); } else if (operation == OPERATION_REWRITE) { state_read(&state);