diff --git a/HISTORY b/HISTORY index 22fe43e9..86b012a0 100644 --- a/HISTORY +++ b/HISTORY @@ -4,6 +4,8 @@ SnapRAID HISTORY 12.5 2025/XX ============ * Add a bandwidth limit option --bw-limit [Allan Clark] + * Add a new smartignore configuration option to ignore specific SMART + attributes. 12.4 2025/01 ============ diff --git a/TODO b/TODO index af3292be..cc486302 100644 --- a/TODO +++ b/TODO @@ -5,15 +5,13 @@ This is the list of TODO items for SnapRAID. - Next -* Add an option to ignore a specific Smart attribute. This solves PullRequest #17 an #21 - * Support BTRFS subvolumes. Keep track of the subvolumeid, along with the inode, and use it when searching/comparing inodes. The value 0 can be used for the root volume, like a normal filesystem. See: https://github.com/kdave/btrfs-progs/tree/master/libbtrfsutil -* A "dependents" output option to [--test-fmt file|disk|path|dependents] for LIST. +* A "dependents" output option to [--test-fmt file|disk|path|dependents] for LIST. Example, snapraid LIST --test-fmt dependents >FileList_with_dependents.txt -The goal is a filelist that, for every file, includes full paths to the dependent files +The goal is a filelist that, for every file, includes full paths to the dependent files on other data disks needed to repair that file (in addition to the parity data). I created a thread about it here: https://sourceforge.net/p/snapraid/discussion/1677233/thread/6e872fdae0/ diff --git a/cmdline/device.c b/cmdline/device.c index 605fdc3a..238047f8 100644 --- a/cmdline/device.c +++ b/cmdline/device.c @@ -605,7 +605,7 @@ static double raid_prob_of_one_or_more_failures(double array_failure_rate, doubl return poisson_prob_n_or_more_failures(raid_failure_rate, 1); } -static void state_smart(unsigned n, tommy_list* low) +static void state_smart(struct snapraid_state* state, unsigned n, tommy_list* low) { tommy_node* i; unsigned j; @@ -665,6 +665,12 @@ static void state_smart(unsigned n, tommy_list* low) double afr; uint64_t flag; + /* clear attributes to ignore */ + for (j = 0; j < SMART_IGNORE_MAX; ++j) { + devinfo->smart[state->smartignore[j]] = SMART_UNASSIGNED; + devinfo->smart[devinfo->smartignore[j]] = SMART_UNASSIGNED; + } + if (devinfo->smart[SMART_TEMPERATURE_CELSIUS] != SMART_UNASSIGNED) printf("%7" PRIu64, devinfo->smart[SMART_TEMPERATURE_CELSIUS] & mask16); else if (devinfo->smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS] != SMART_UNASSIGNED) @@ -932,6 +938,7 @@ void state_device(struct snapraid_state* state, int operation, tommy_list* filte pathcpy(entry->name, sizeof(entry->name), disk->name); pathcpy(entry->mount, sizeof(entry->mount), disk->dir); pathcpy(entry->smartctl, sizeof(entry->smartctl), disk->smartctl); + memcpy(entry->smartignore, disk->smartignore, sizeof(entry->smartignore)); tommy_list_insert_tail(&high, &entry->node, entry); } @@ -951,6 +958,7 @@ void state_device(struct snapraid_state* state, int operation, tommy_list* filte pathcpy(entry->name, sizeof(entry->name), lev_config_name(j)); pathcpy(entry->mount, sizeof(entry->mount), state->parity[j].split_map[s].path); pathcpy(entry->smartctl, sizeof(entry->smartctl), state->parity[j].smartctl); + memcpy(entry->smartignore, state->parity[j].smartignore, sizeof(entry->smartignore)); pathcut(entry->mount); /* remove the parity file */ tommy_list_insert_tail(&high, &entry->node, entry); @@ -992,7 +1000,7 @@ void state_device(struct snapraid_state* state, int operation, tommy_list* filte } if (operation == DEVICE_SMART) - state_smart(state->level + tommy_list_count(&state->disklist), &low); + state_smart(state, state->level + tommy_list_count(&state->disklist), &low); } tommy_list_foreach(&high, free); diff --git a/cmdline/elem.c b/cmdline/elem.c index 9ffe59e1..1e2fd08b 100644 --- a/cmdline/elem.c +++ b/cmdline/elem.c @@ -739,6 +739,7 @@ int dir_name_compare(const void* void_arg, const void* void_data) struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, const char* uuid, int skip_access) { struct snapraid_disk* disk; + unsigned i; disk = malloc_nofail(sizeof(struct snapraid_disk)); pathcpy(disk->name, sizeof(disk->name), name); @@ -754,6 +755,8 @@ struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev #endif disk->smartctl[0] = 0; + for (i = 0; i < SMART_IGNORE_MAX; ++i) + disk->smartignore[i] = 0; disk->device = dev; disk->tick = 0; disk->cached_blocks = 0; diff --git a/cmdline/elem.h b/cmdline/elem.h index 8d7346ef..e8eb3100 100644 --- a/cmdline/elem.h +++ b/cmdline/elem.h @@ -330,6 +330,7 @@ struct snapraid_disk { char name[PATH_MAX]; /**< Name of the disk. */ char dir[PATH_MAX]; /**< Mount point of the disk. It always terminates with /. */ char smartctl[PATH_MAX]; /**< Custom command for smartctl. Empty means auto. */ + int smartignore[SMART_IGNORE_MAX]; /**< Smart attributes to ignore for this device. */ char uuid[UUID_MAX]; /**< UUID of the disk. */ uint64_t device; /**< Device identifier. */ @@ -471,6 +472,7 @@ struct snapraid_parity { struct snapraid_split split_map[SPLIT_MAX]; /**< Parity splits. */ unsigned split_mac; /**< Number of parity splits. */ char smartctl[PATH_MAX]; /**< Custom command for smartctl. Empty means auto. */ + int smartignore[SMART_IGNORE_MAX]; /**< Smart attributes to ignore for this device. */ block_off_t total_blocks; /**< Number of total blocks. */ block_off_t free_blocks; /**< Number of free blocks at the last sync. */ int is_excluded_by_filter; /**< If the parity is excluded by filters. */ diff --git a/cmdline/mingw.c b/cmdline/mingw.c index b639dcc3..65246b83 100644 --- a/cmdline/mingw.c +++ b/cmdline/mingw.c @@ -2154,7 +2154,7 @@ static int devresolve(const char* mount, char* file, size_t file_size, char* wfi /** * Read a device tree filling the specified list of disk_t entries. */ -static int devtree(const char* name, const char* custom, const char* wfile, devinfo_t* parent, tommy_list* list) +static int devtree(const char* name, const char* smartctl, const int* smartignore, const char* wfile, devinfo_t* parent, tommy_list* list) { wchar_t conv_buf[CONV_MAX]; HANDLE h; @@ -2203,7 +2203,8 @@ static int devtree(const char* name, const char* custom, const char* wfile, devi devinfo = calloc_nofail(1, sizeof(devinfo_t)); pathcpy(devinfo->name, sizeof(devinfo->name), name); - pathcpy(devinfo->smartctl, sizeof(devinfo->smartctl), custom); + pathcpy(devinfo->smartctl, sizeof(devinfo->smartctl), smartctl); + memcpy(devinfo->smartignore, smartignore, sizeof(devinfo->smartignore)); devinfo->device = vde->Extents[i].DiskNumber; pathprint(devinfo->file, sizeof(devinfo->file), "/dev/pd%" PRIu64, devinfo->device); pathprint(devinfo->wfile, sizeof(devinfo->wfile), "\\\\.\\PhysicalDrive%" PRIu64, devinfo->device); @@ -2339,7 +2340,7 @@ static int devscan(tommy_list* list) /** * Get SMART attributes. */ -static int devsmart(uint64_t device, const char* name, const char* custom, uint64_t* smart, char* serial, char* vendor, char* model) +static int devsmart(uint64_t device, const char* name, const char* smartctl, uint64_t* smart, char* serial, char* vendor, char* model) { char conv_buf[CONV_MAX]; WCHAR cmd[MAX_PATH + 128]; @@ -2350,10 +2351,10 @@ static int devsmart(uint64_t device, const char* name, const char* custom, uint6 snprintf(file, sizeof(file), "/dev/pd%" PRIu64, device); - /* if there is a custom command */ - if (custom[0]) { + /* if there is a custom smartctl command */ + if (smartctl[0]) { char option[128]; - snprintf(option, sizeof(option), custom, file); + snprintf(option, sizeof(option), smartctl, file); snwprintf(cmd, sizeof(cmd), L"\"%lssmartctl.exe\" -a %s", exedir, option); } else { snwprintf(cmd, sizeof(cmd), L"\"%lssmartctl.exe\" -a %s", exedir, file); @@ -2390,8 +2391,8 @@ retry: /* LCOV_EXCL_STOP */ } - /* if first try without custom command */ - if (count == 0 && custom[0] == 0) { + /* if first try without custom smartctl command */ + if (count == 0 && smartctl[0] == 0) { /* * Handle some common cases in Windows. * @@ -2425,7 +2426,7 @@ retry: /** * Spin down a specific device. */ -static int devdown(uint64_t device, const char* name, const char* custom) +static int devdown(uint64_t device, const char* name, const char* smartctl) { char conv_buf[CONV_MAX]; WCHAR cmd[MAX_PATH + 128]; @@ -2436,10 +2437,10 @@ static int devdown(uint64_t device, const char* name, const char* custom) snprintf(file, sizeof(file), "/dev/pd%" PRIu64, device); - /* if there is a custom command */ - if (custom[0]) { + /* if there is a custom smartctl command */ + if (smartctl[0]) { char option[128]; - snprintf(option, sizeof(option), custom, file); + snprintf(option, sizeof(option), smartctl, file); snwprintf(cmd, sizeof(cmd), L"\"%lssmartctl.exe\" -s standby,now %s", exedir, option); } else { snwprintf(cmd, sizeof(cmd), L"\"%lssmartctl.exe\" -s standby,now %s", exedir, file); @@ -2476,8 +2477,8 @@ retry: /* LCOV_EXCL_STOP */ } - /* if first try without custom command */ - if (count == 0 && custom[0] == 0) { + /* if first try without custom smartctl command */ + if (count == 0 && smartctl[0] == 0) { /* * Handle some common cases in Windows. * @@ -2660,7 +2661,7 @@ int devquery(tommy_list* high, tommy_list* low, int operation, int others) } /* expand the tree of devices */ - if (devtree(devinfo->name, devinfo->smartctl, devinfo->wfile, devinfo, low) != 0) { + if (devtree(devinfo->name, devinfo->smartctl, devinfo->smartignore, devinfo->wfile, devinfo, low) != 0) { /* LCOV_EXCL_START */ log_fatal("Failed to expand device '%s'.\n", devinfo->file); return -1; diff --git a/cmdline/portable.h b/cmdline/portable.h index e0131408..17aa73fb 100644 --- a/cmdline/portable.h +++ b/cmdline/portable.h @@ -461,6 +461,8 @@ int randomize(void* ptr, size_t size); */ #define SMART_COUNT 260 +#define SMART_IGNORE_MAX 4 /**< Max number of ignored smart attributes */ + /** * Flags returned by smartctl. */ @@ -491,6 +493,7 @@ struct devinfo_struct { char name[PATH_MAX]; /**< Name of the disk. */ char mount[PATH_MAX]; /**< Mount point or other contained directory. */ char smartctl[PATH_MAX]; /**< Options for smartctl. */ + int smartignore[SMART_IGNORE_MAX]; /**< Attribues to ignore */ char file[PATH_MAX]; /**< File device. */ #ifdef _WIN32 char wfile[PATH_MAX]; /**< File device in Windows format. Like \\.\PhysicalDriveX, or \\?\Volume{X}. */ diff --git a/cmdline/state.c b/cmdline/state.c index 65d09e3b..e4a5e3db 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -134,7 +134,7 @@ const char* lev_raid_name(unsigned mode, unsigned n) void state_init(struct snapraid_state* state) { - unsigned l, s; + unsigned l, s, i; memset(&state->opt, 0, sizeof(state->opt)); state->filter_hidden = 0; @@ -153,6 +153,8 @@ void state_init(struct snapraid_state* state) state->parity[l].split_map[s].device = 0; } state->parity[l].smartctl[0] = 0; + for (i = 0; i < SMART_IGNORE_MAX; ++i) + state->parity[l].smartignore[i] = 0; state->parity[l].total_blocks = 0; state->parity[l].free_blocks = 0; state->parity[l].skip_access = 0; @@ -173,6 +175,8 @@ void state_init(struct snapraid_state* state) state->level = 1; /* default is the lowest protection */ state->clear_past_hash = 0; state->no_conf = 0; + for (i = 0; i < SMART_IGNORE_MAX; ++i) + state->smartignore[i] = 0; tommy_list_init(&state->disklist); tommy_list_init(&state->maplist); @@ -1063,6 +1067,93 @@ void state_config(struct snapraid_state* state, const char* path, const char* co pathcpy(disk->smartctl, sizeof(disk->smartctl), custom); } + } else if (strcmp(tag, "smartignore") == 0) { + int* smart; + + ret = sgettok(f, buffer, sizeof(buffer)); + if (ret < 0) { + /* LCOV_EXCL_START */ + log_fatal("Invalid 'smartignore' name in '%s' at line %u\n", path, line); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + + if (!*buffer) { + /* LCOV_EXCL_START */ + log_fatal("Empty 'smartignore' name in '%s' at line %u\n", path, line); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + + sgetspace(f); + + if (strcmp(buffer, "*") == 0) { + smart = state->smartignore; + } else if (lev_config_scan(buffer, &level, 0) == 0) { /* search for parity */ + smart = state->parity[level].smartignore; + } else { + struct snapraid_disk* disk; + + /* search the disk */ + disk = 0; + for (i = state->disklist; i != 0; i = i->next) { + disk = i->data; + if (strcmp(disk->name, buffer) == 0) + break; + } + if (!disk) { + /* LCOV_EXCL_START */ + log_fatal("Missing disk 'smartctl' '%s' at line %u\n", buffer, line); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + + smart = disk->smartignore; + } + + int si = 0; + + while (1) { + char* e; + + ret = sgettok(f, buffer, sizeof(buffer)); + if (ret < 0) { + /* LCOV_EXCL_START */ + log_fatal("Invalid 'smartignore' specification in '%s' at line %u\n", path, line); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + + if (!*buffer) + break; + + if (si == SMART_IGNORE_MAX) { + /* LCOV_EXCL_START */ + log_fatal("Too many 'smartignore' specification in '%s' at line %u\n", path, line); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + + smart[si] = strtoul(buffer, &e, 0); + + if (!e || *e) { + /* LCOV_EXCL_START */ + log_fatal("Invalid 'smartignore' specification in '%s' at line %u\n", path, line); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + + ++si; + + sgetspace(f); + } + + if (si == 0) { + /* LCOV_EXCL_START */ + log_fatal("Invalid 'smartignore' specification in '%s' at line %u\n", path, line); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } } else if (strcmp(tag, "nohidden") == 0) { state->filter_hidden = 1; } else if (strcmp(tag, "exclude") == 0) { diff --git a/cmdline/state.h b/cmdline/state.h index 77af8620..f95881d6 100644 --- a/cmdline/state.h +++ b/cmdline/state.h @@ -144,6 +144,7 @@ struct snapraid_state { unsigned prevhash; /**< Previous hash kind used. In case of rehash. */ unsigned besthash; /**< Best hash suggested. */ const char* command; /**< Command running. */ + int smartignore[SMART_IGNORE_MAX]; /**< Smart attributes to ignore for all devices. */ tommy_list contentlist; /**< List of content files. */ tommy_list disklist; /**< List of all the disks. */ tommy_list maplist; /**< List of all the disk mappings. */ diff --git a/cmdline/unix.c b/cmdline/unix.c index 2dbd4e5a..44ff07d7 100644 --- a/cmdline/unix.c +++ b/cmdline/unix.c @@ -513,7 +513,7 @@ static int devuuid_blkid(uint64_t device, char* uuid, size_t uuid_size) #endif #ifdef __APPLE__ -static int devuuid_darwin(const char* path, char* uuid, size_t uuid_size) +static int devuuid_darwin(const char* path, char* uuid, size_t uuid_size) { CFStringRef path_apple = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8); DASessionRef session = DASessionCreate(kCFAllocatorDefault); @@ -531,7 +531,7 @@ static int devuuid_darwin(const char* path, char* uuid, size_t uuid_size) path_appler = parent_path_appler; } } while (true); // This is guaranteed to succeed eventually because it'll hit `/`. - + CFDictionaryRef description = DADiskCopyDescription(disk); CFUUIDRef uuid_apple = CFDictionaryGetValue(description, kDADiskDescriptionVolumeUUIDKey); CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, uuid_apple); @@ -948,7 +948,7 @@ static dev_t devread(const char* path) * Read a device tree filling the specified list of disk_t entries. */ #if HAVE_LINUX_DEVICE -static int devtree(const char* name, const char* custom, dev_t device, devinfo_t* parent, tommy_list* list) +static int devtree(const char* name, const char* smartctl, const int* smartignore, dev_t device, devinfo_t* parent, tommy_list* list) { char path[PATH_MAX]; DIR* d; @@ -976,7 +976,7 @@ static int devtree(const char* name, const char* custom, dev_t device, devinfo_t /* LCOV_EXCL_STOP */ } - if (devtree(name, custom, subdev, parent, list) != 0) { + if (devtree(name, smartctl, smartignore, subdev, parent, list) != 0) { /* LCOV_EXCL_START */ closedir(d); return -1; @@ -1021,7 +1021,8 @@ static int devtree(const char* name, const char* custom, dev_t device, devinfo_t devinfo->device = device; pathcpy(devinfo->name, sizeof(devinfo->name), name); - pathcpy(devinfo->smartctl, sizeof(devinfo->smartctl), custom); + pathcpy(devinfo->smartctl, sizeof(devinfo->smartctl), smartctl); + memcpy(devinfo->smartignore, smartignore, sizeof(devinfo->smartignore)); pathcpy(devinfo->file, sizeof(devinfo->file), path); devinfo->parent = parent; @@ -1118,7 +1119,7 @@ static int devscan(tommy_list* list) * Get SMART attributes. */ #if HAVE_LINUX_DEVICE -static int devsmart(dev_t device, const char* name, const char* custom, uint64_t* smart, char* serial, char* vendor, char* model) +static int devsmart(dev_t device, const char* name, const char* smartctl, uint64_t* smart, char* serial, char* vendor, char* model) { char cmd[PATH_MAX + 64]; char file[PATH_MAX]; @@ -1132,10 +1133,10 @@ static int devsmart(dev_t device, const char* name, const char* custom, uint64_t /* LCOV_EXCL_STOP */ } - /* if there is a custom command */ - if (custom[0]) { + /* if there is a custom smartctl command */ + if (smartctl[0]) { char option[PATH_MAX]; - snprintf(option, sizeof(option), custom, file); + snprintf(option, sizeof(option), smartctl, file); snprintf(cmd, sizeof(cmd), "smartctl -a %s", option); } else { snprintf(cmd, sizeof(cmd), "smartctl -a %s", file); @@ -1186,7 +1187,7 @@ static int devsmart(dev_t device, const char* name, const char* custom, uint64_t * Spin down a specific device. */ #if HAVE_LINUX_DEVICE -static int devdown(dev_t device, const char* name, const char* custom) +static int devdown(dev_t device, const char* name, const char* smartctl) { char cmd[PATH_MAX + 64]; char file[PATH_MAX]; @@ -1200,10 +1201,10 @@ static int devdown(dev_t device, const char* name, const char* custom) /* LCOV_EXCL_STOP */ } - /* if there is a custom command */ - if (custom[0]) { + /* if there is a custom smartctl command */ + if (smartctl[0]) { char option[PATH_MAX]; - snprintf(option, sizeof(option), custom, file); + snprintf(option, sizeof(option), smartctl, file); snprintf(cmd, sizeof(cmd), "smartctl -s standby,now %s", option); } else { snprintf(cmd, sizeof(cmd), "smartctl -s standby,now %s", file); @@ -1447,7 +1448,7 @@ int devquery(tommy_list* high, tommy_list* low, int operation, int others) } /* expand the tree of devices */ - if (devtree(devinfo->name, devinfo->smartctl, device, devinfo, low) != 0) { + if (devtree(devinfo->name, devinfo->smartctl, devinfo->smartignore, device, devinfo, low) != 0) { /* LCOV_EXCL_START */ log_fatal("Failed to expand device '%u:%u'.\n", major(device), minor(device)); return -1; diff --git a/snapraid.1 b/snapraid.1 index 3543449c..4f35b770 100644 --- a/snapraid.1 +++ b/snapraid.1 @@ -1504,6 +1504,32 @@ https://www.smartmontools.org/wiki/Supported_USB\-Devices .PP .PD .RE +.SS smartignore DISK/PARITY ATTR [ATTR...] +Ignores the specified SMART attribute when computing the probability +of disk failure. This option is useful if a disk reports unusual or +misleading values for a particular attribute. +.PP +DISK is the same disk name specified in the \[dq]disk\[dq] option. +PARITY is one of the parity name as \[dq]parity,(1,2,3,4,5,6,z)\-parity\[dq]. +The special value * can be used to ignore the attribute on all disks. +.PP +For example, to ignore the \[dq]Load_Cycle_Count\[dq] attribute on all disks: +.PP +.RS 4 +smartignore * 193 +.PD 0 +.PP +.PD +.RE +.PP +To ignore it only on the first parity disk: +.PP +.RS 4 +smartignore parity 193 +.PD 0 +.PP +.PD +.RE .SS Examples An example of a typical configuration for Unix is: .PP diff --git a/snapraid.d b/snapraid.d index cfe49df7..1ef3127a 100644 --- a/snapraid.d +++ b/snapraid.d @@ -1181,6 +1181,23 @@ Configuration :https://www.smartmontools.org/wiki/Supported_RAID-Controllers :https://www.smartmontools.org/wiki/Supported_USB-Devices + smartignore DISK/PARITY ATTR [ATTR...] + Ignores the specified SMART attribute when computing the probability + of disk failure. This option is useful if a disk reports unusual or + misleading values for a particular attribute. + + DISK is the same disk name specified in the "disk" option. + PARITY is one of the parity name as "parity,(1,2,3,4,5,6,z)-parity". + The special value * can be used to ignore the attribute on all disks. + + For example, to ignore the "Load_Cycle_Count" attribute on all disks: + + :smartignore * 193 + + To ignore it only on the first parity disk: + + :smartignore parity 193 + Examples An example of a typical configuration for Unix is: diff --git a/snapraid.txt b/snapraid.txt index 32d62c4f..b639618d 100644 --- a/snapraid.txt +++ b/snapraid.txt @@ -1267,7 +1267,26 @@ Refers at the smartmontools documentation about the possible options: https://www.smartmontools.org/wiki/Supported_RAID-Controllers https://www.smartmontools.org/wiki/Supported_USB-Devices -7.14 Examples +7.14 smartignore DISK/PARITY ATTR [ATTR...] +------------------------------------------- + +Ignores the specified SMART attribute when computing the probability +of disk failure. This option is useful if a disk reports unusual or +misleading values for a particular attribute. + +DISK is the same disk name specified in the "disk" option. +PARITY is one of the parity name as "parity,(1,2,3,4,5,6,z)-parity". +The special value * can be used to ignore the attribute on all disks. + +For example, to ignore the "Load_Cycle_Count" attribute on all disks: + + smartignore * 193 + +To ignore it only on the first parity disk: + + smartignore parity 193 + +7.15 Examples ------------- An example of a typical configuration for Unix is: diff --git a/test/test-par1.conf b/test/test-par1.conf index 93d45595..3b9bf8eb 100644 --- a/test/test-par1.conf +++ b/test/test-par1.conf @@ -14,4 +14,3 @@ exclude *.unrecoverable pool bench/pool share \\server\jbod autosave 1 - diff --git a/test/test-par6.conf b/test/test-par6.conf index 15112bc0..3e2ca0ee 100644 --- a/test/test-par6.conf +++ b/test/test-par6.conf @@ -22,4 +22,5 @@ include *.hidden exclude *.unrecoverable smartctl disk1 %s smartctl parity /dev/sda - +smartignore * 193 +smartignore parity 193