@@ -94,6 +94,7 @@ static void rf_output_pmstat(int, int);
9494static void rf_pm_configure (int , int , char * , int []);
9595static void rf_simple_create (int , int , char * []);
9696static unsigned int xstrtouint (const char * );
97+ static void rf_scrub_begin (int , int , char * []);
9798
9899int verbose ;
99100
@@ -141,8 +142,12 @@ main(int argc,char *argv[])
141142 last_unit = 0 ;
142143 openmode = O_RDWR ; /* default to read/write */
143144
144- if (argc > 5 ) {
145- /* we have at least 5 args, so it might be a simplified config */
145+ if (argc > 5 || (argc > 2 && !strncmp (argv [2 ], "scrub" , 5 ))) {
146+
147+ /*
148+ * we have at least 5 args, so it might be a simplified config
149+ * for cases where we will be doing scrubbing, args may be less than 5
150+ */
146151
147152 strlcpy (name , argv [1 ], sizeof (name ));
148153 fd = opendisk (name , openmode , dev_name , sizeof (dev_name ), 0 );
@@ -168,6 +173,8 @@ main(int argc,char *argv[])
168173 strlcpy (autoconf , "yes" , sizeof (autoconf ));
169174 set_autoconfig (fd , raidID , autoconf );
170175
176+ } else if (strncmp (argv [2 ], "scrub" , 5 ) == 0 ) {
177+ rf_scrub_begin (fd , argc - 3 , & argv [3 ]);
171178 } else
172179 usage ();
173180
@@ -435,7 +442,6 @@ do_ioctl(int fd, unsigned long command, void *arg, const char *ioctl_name)
435442 err (1 , "ioctl (%s) failed" , ioctl_name );
436443}
437444
438-
439445static void
440446rf_configure (int fd , char * config_file , int force )
441447{
@@ -1227,6 +1233,66 @@ get_time_string(char *string, size_t len, int simple_time)
12271233
12281234}
12291235
1236+ static void
1237+ rf_scrub_begin (int fd , int argc , char * argv [])
1238+ {
1239+ int rate ;
1240+ int portion ;
1241+ RF_Scrub_t scrb ;
1242+ /* initialize default values for scrubbing */
1243+ scrb .rate = 2 * 1000 * 1000 ;
1244+ scrb .portion_begin = 0 ;
1245+ scrb .portion_end = 100 ;
1246+
1247+ for (int i = 0 ; i < argc ; i ++ )
1248+ {
1249+ if (strcmp (argv [i ], "rate" ) == 0 ) {
1250+ if (argc == i + 1 )
1251+ errx (1 , "scrubbing rate unspecified" );
1252+
1253+ char * c ;
1254+ double bps = strtod (argv [++ i ], & c );
1255+ if (bps == 0 )
1256+ errx (1 , "invalid input rate" );
1257+
1258+ if (c != NULL ) {
1259+ if (!strcmp (c , "B" ))
1260+ ; /* do nothing */
1261+ else if (!strcmp (c , "KB" ))
1262+ scrb .rate = bps * 1000 ;
1263+ else if (!strcmp (c , "MB" ))
1264+ scrb .rate = bps * 1000 * 1000 ;
1265+ else if (!strcmp (c , "GB" ))
1266+ scrb .rate = bps * 1000 * 1000 * 1000 ;
1267+ } else
1268+ errx (1 , "no scrubbing rate unit specified" );
1269+
1270+ }
1271+ else if (strcmp (argv [i ], "portion" ) == 0 ) {
1272+ if (argc <= i + 2 ) /* do argc check once */
1273+ errx (1 , "portion needs a lower to upper bound range" );
1274+
1275+ portion = atoi (argv [++ i ]); /* i increased */
1276+ if (portion >= 100 )
1277+ errx (1 , "begin scrubbing portion range should be less than 100 percent" );
1278+ scrb .portion_begin = portion ;
1279+
1280+ portion = atoi (argv [++ i ]);
1281+ if (portion > 100 )
1282+ errx (1 , "scrubbing portion upper bound should not be more than 100 percent" );
1283+ scrb .portion_end = portion ;
1284+
1285+ if (scrb .portion_begin >= scrb .portion_end ) {
1286+ errx (1 , "upper bound must be greater than lower bound for scrub portions" );
1287+ }
1288+
1289+ }
1290+ }
1291+
1292+ do_ioctl (fd , RAIDFRAME_SCRUB , & scrb ,
1293+ "RAIDFRAME_COMPONENT_SCRUB" );
1294+ }
1295+
12301296/* Simplified RAID creation with a single command line... */
12311297static void
12321298rf_simple_create (int fd , int argc , char * argv [])
0 commit comments