diff --git a/sbin/raidctl/raidctl.c b/sbin/raidctl/raidctl.c index 3123b5b0f44fd..22d6d68571dc5 100644 --- a/sbin/raidctl/raidctl.c +++ b/sbin/raidctl/raidctl.c @@ -94,6 +94,7 @@ static void rf_output_pmstat(int, int); static void rf_pm_configure(int, int, char *, int[]); static void rf_simple_create(int, int, char *[]); static unsigned int xstrtouint(const char *); +static void rf_scrub_begin(int, int, char *[]); int verbose; @@ -141,8 +142,12 @@ main(int argc,char *argv[]) last_unit = 0; openmode = O_RDWR; /* default to read/write */ - if (argc > 5) { - /* we have at least 5 args, so it might be a simplified config */ + if (argc > 5 || (argc > 2 && !strncmp(argv[2], "scrub", 5))) { + + /* + * we have at least 5 args, so it might be a simplified config + * for cases where we will be doing scrubbing, args may be less than 5 + */ strlcpy(name, argv[1], sizeof(name)); fd = opendisk(name, openmode, dev_name, sizeof(dev_name), 0); @@ -168,6 +173,8 @@ main(int argc,char *argv[]) strlcpy(autoconf, "yes", sizeof(autoconf)); set_autoconfig(fd, raidID, autoconf); + } else if (strncmp(argv[2], "scrub", 5) == 0) { + rf_scrub_begin(fd, argc-3, &argv[3]); } else usage(); @@ -435,7 +442,6 @@ do_ioctl(int fd, unsigned long command, void *arg, const char *ioctl_name) err(1, "ioctl (%s) failed", ioctl_name); } - static void rf_configure(int fd, char *config_file, int force) { @@ -1227,6 +1233,41 @@ get_time_string(char *string, size_t len, int simple_time) } +static void +rf_scrub_begin(int fd, int argc, char *argv[]) +{ + int rate; + int portion; + RF_Scrub_t scrb; + RF_ComponentLabel_t label; + /* initialize default values for scrubbing */ + scrb.rate = 2; + scrb.portion = 100; + + for (int i = 0; i < argc; i++) + { + if (strcmp(argv[i], "rate" == 0)) { + rate = atoi(argv[++i]); + scrb.rate = rate; + } + else if (strcmp(argv[i], "portion" == 0)) { + portion = atoi(argv[++i]); + if (portion > 100) + errx(1, "scrubbing portion should not be more than 100 percent"); + } + } + + memset(&label, 0, sizeof(label)); + do_ioctl(fd, RAIDFRAME_GET_COMPONENT_LABEL, &label, + "RAIDFRAME_GET_COMPONENT_LABEL"); + + scrb.level = label.parityConfig; + + do_ioctl(fd, RAIDFRAME_COMPONENT_SCRUB, &scrb, + "RAIDFRAME_COMPONENT_SCRUB"); + +} + /* Simplified RAID creation with a single command line... */ static void rf_simple_create(int fd, int argc, char *argv[]) diff --git a/sys/dev/raidframe/raidframeio.h b/sys/dev/raidframe/raidframeio.h index cfc52686b6233..313a1b70a3aa1 100644 --- a/sys/dev/raidframe/raidframeio.h +++ b/sys/dev/raidframe/raidframeio.h @@ -135,5 +135,6 @@ #define RAIDFRAME_GET_INFO _IOWR('r', 42, RF_DeviceConfig_t *) /* get configuration */ #define RAIDFRAME_CONFIGURE _IOW ('r', 43, void *) /* configure the driver */ #define RAIDFRAME_RESCAN _IO ('r', 44) +#define RAIDFRAME_COMPONENT_SCRUB _IOW('r', 45, RF_Scrub_t *) #endif /* !_RF_RAIDFRAMEIO_H_ */ diff --git a/sys/dev/raidframe/raidframevar.h b/sys/dev/raidframe/raidframevar.h index be9ecb6463f9c..522bf02260453 100644 --- a/sys/dev/raidframe/raidframevar.h +++ b/sys/dev/raidframe/raidframevar.h @@ -215,6 +215,7 @@ typedef struct RF_CallbackValueDesc_s RF_CallbackValueDesc_t; typedef struct RF_ChunkDesc_s RF_ChunkDesc_t; typedef struct RF_CommonLogData_s RF_CommonLogData_t; typedef struct RF_Config_s RF_Config_t; +typedef struct RF_Scrub_s RF_Scrub_t; typedef struct RF_CumulativeStats_s RF_CumulativeStats_t; typedef struct RF_DagHeader_s RF_DagHeader_t; typedef struct RF_DagList_s RF_DagList_t; @@ -351,6 +352,13 @@ struct RF_Config_s { */ }; +/* introduce a scrub components containing scrub rate and portion to scrub */ +struct RF_Scrub_s { + int rate; + int portion; + int level; /* parityConfig from config*/ +} + typedef RF_uint32 RF_ReconReqFlags_t; /* flags that can be put in the rf_recon_req structure */ #define RF_FDFLAGS_NONE 0x0 /* just fail the disk */ @@ -386,7 +394,7 @@ enum RF_DiskStatus_e { rf_ds_reconstructing, /* reconstruction ongoing */ rf_ds_dist_spared, /* reconstruction complete to distributed * spare space, dead disk not yet replaced */ - rf_ds_spared, /* reconstruction complete, dead disk not + rf_ds_spared, /* reconstruction complete, dead disk not yet replaced */ rf_ds_spare, /* an available spare disk */ rf_ds_used_spare, /* a spare which has been used, and hence is diff --git a/sys/dev/raidframe/rf_driver.c b/sys/dev/raidframe/rf_driver.c index 0044189626676..04c76cd70bc9a 100644 --- a/sys/dev/raidframe/rf_driver.c +++ b/sys/dev/raidframe/rf_driver.c @@ -123,6 +123,8 @@ __KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.144 2024/09/19 06:13:03 andvar Exp $ /* main configuration routines */ static int raidframe_booted = 0; +/* RAID scrubbing starting*/ + static void rf_ConfigureDebug(RF_Config_t * cfgPtr); static void set_debug_option(char *name, long val); static void rf_UnconfigureArray(void); @@ -361,7 +363,7 @@ rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac) DO_RAID_INIT_CONFIGURE(rf_ConfigureReconstruction); DO_RAID_INIT_CONFIGURE(rf_ConfigureDiskQueueSystem); DO_RAID_INIT_CONFIGURE(rf_ConfigurePSStatus); - + DO_RAID_INIT_CONFIGURE(rf_ConfigureEngine); DO_RAID_INIT_CONFIGURE(rf_ConfigureStripeLocks); @@ -384,8 +386,8 @@ rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac) DO_RAID_INIT_CONFIGURE(rf_ConfigureLayout); - - + + /* Initialize per-RAID PSS bits */ rf_InitPSStatus(raidPtr); @@ -560,7 +562,7 @@ rf_ShutdownRDFreeList(void *arg) RF_Raid_t *raidPtr; raidPtr = (RF_Raid_t *) arg; - + pool_destroy(&raidPtr->pools.rad); } @@ -706,9 +708,9 @@ rf_DoAccess(RF_Raid_t * raidPtr, RF_IoType_t type, RF_RaidAddr_t raidAddress, RF RF_ETIMER_START(desc->tracerec.tot_timer); #endif - if (raidPtr->parity_map != NULL && + if (raidPtr->parity_map != NULL && type == RF_IO_TYPE_WRITE) - rf_paritymap_begin(raidPtr->parity_map, raidAddress, + rf_paritymap_begin(raidPtr->parity_map, raidAddress, numBlocks); rf_ContinueRaidAccess(desc); diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c index baa2c7e6d2d0b..176ae7cc958a9 100644 --- a/sys/dev/raidframe/rf_netbsdkintf.c +++ b/sys/dev/raidframe/rf_netbsdkintf.c @@ -1611,6 +1611,9 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) return retcode; return rf_construct(rs, k_cfg); + case RAIDFRAME_COMPONENT_SCRUB: + /* think about kernel later */ + /* shutdown the system */ case RAIDFRAME_SHUTDOWN: