mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Abort spindown when filesystem flush fails
This commit is contained in:
parent
d210e95997
commit
57e15416ae
6 changed files with 54 additions and 12 deletions
|
|
@ -422,8 +422,9 @@ void device_name_set(devinfo_t* dev, const char* name, int index);
|
|||
|
||||
/**
|
||||
* Sync filesystems associated with the "high" level devices.
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
void devsync(tommy_list* high);
|
||||
int devsync(tommy_list* high);
|
||||
|
||||
/**
|
||||
* Query all the "high" level devices and produce a list of "low" level devices.
|
||||
|
|
|
|||
|
|
@ -1090,13 +1090,14 @@ void state_devmap(struct snapraid_state* state)
|
|||
}
|
||||
}
|
||||
|
||||
int state_device(struct snapraid_state* state, int operation, tommy_list* filterlist_disk)
|
||||
int state_device_force(struct snapraid_state* state, int operation, tommy_list* filterlist_disk, int force)
|
||||
{
|
||||
tommy_node* i;
|
||||
unsigned j;
|
||||
tommy_list high;
|
||||
tommy_list low;
|
||||
int ret;
|
||||
int sync_failed = 0;
|
||||
time_t now = time(0);
|
||||
|
||||
switch (operation) {
|
||||
|
|
@ -1192,9 +1193,19 @@ int state_device(struct snapraid_state* state, int operation, tommy_list* filter
|
|||
if (state->opt.fake_device) {
|
||||
ret = devtest(&high, &low, operation);
|
||||
} else {
|
||||
/* issue pending filesystem writes before the underlying devices enter standby */
|
||||
if (operation == DEVICE_DOWN)
|
||||
devsync(&high);
|
||||
/*
|
||||
* Flush before DOWN, but not DOWNIFUP: syncfs() could wake disks
|
||||
* already in standby during the repeated thermal cooldown checks.
|
||||
*/
|
||||
if (operation == DEVICE_DOWN) {
|
||||
ret = devsync(&high);
|
||||
if (ret != 0) {
|
||||
/* thermal cooldown must attempt spindown even after a failed flush */
|
||||
if (!force)
|
||||
goto bail;
|
||||
sync_failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = devquery(&high, &low);
|
||||
if (ret > 0) {
|
||||
|
|
@ -1254,7 +1265,14 @@ bail:
|
|||
ret = 1;
|
||||
if (ret == 0 && query_failed)
|
||||
ret = -1;
|
||||
if (sync_failed)
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int state_device(struct snapraid_state* state, int operation, tommy_list* filterlist_disk)
|
||||
{
|
||||
return state_device_force(state, operation, filterlist_disk, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2178,9 +2178,10 @@ static int device_thread(tommy_list* list, void* (*func)(void* arg))
|
|||
return 0;
|
||||
}
|
||||
|
||||
void devsync(tommy_list* high)
|
||||
int devsync(tommy_list* high)
|
||||
{
|
||||
(void)high;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int devquery(tommy_list* high, tommy_list* low)
|
||||
|
|
|
|||
|
|
@ -275,6 +275,11 @@ void state_devmap(struct snapraid_state* state);
|
|||
*/
|
||||
int state_device(struct snapraid_state* state, int operation, tommy_list* filterlist_disk);
|
||||
|
||||
/**
|
||||
* Perform a device operation, continuing after a failed flush when force is set.
|
||||
*/
|
||||
int state_device_force(struct snapraid_state* state, int operation, tommy_list* filterlist_disk, int force);
|
||||
|
||||
/**
|
||||
* Sync the parity data.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ void state_thermal_cooldown(struct snapraid_state* state)
|
|||
* effective; it does not allow the operation to resume while a measurable disk
|
||||
* is still above the temperature limit.
|
||||
*/
|
||||
state_device(state, DEVICE_DOWN, 0);
|
||||
state_device_force(state, DEVICE_DOWN, 0, 1);
|
||||
|
||||
msg_progress("Cooldown...\n");
|
||||
|
||||
|
|
@ -376,7 +376,7 @@ void state_thermal_cooldown(struct snapraid_state* state)
|
|||
|
||||
/* every 30 seconds spin down any disk that was spunup */
|
||||
while (sleep_time > 0 && !os_signal_interrupt()) {
|
||||
state_device(state, DEVICE_DOWNIFUP, 0);
|
||||
state_device_force(state, DEVICE_DOWNIFUP, 0, 1);
|
||||
|
||||
sleep(30);
|
||||
sleep_time -= 30;
|
||||
|
|
|
|||
|
|
@ -4265,11 +4265,13 @@ static int device_thread(tommy_list* list, void* (*func)(void* arg))
|
|||
return 0;
|
||||
}
|
||||
|
||||
void devsync(tommy_list* high)
|
||||
int devsync(tommy_list* high)
|
||||
{
|
||||
#if HAVE_SYNCFS
|
||||
tommy_node* i;
|
||||
int ret = 0;
|
||||
|
||||
/* flush every filesystem even if one fails before a forced thermal spindown */
|
||||
for (i = tommy_list_head(high); i != 0; i = i->next) {
|
||||
devinfo_t* devinfo = i->data;
|
||||
int f;
|
||||
|
|
@ -4279,13 +4281,28 @@ void devsync(tommy_list* high)
|
|||
continue;
|
||||
|
||||
f = open(devinfo->mount, O_RDONLY);
|
||||
if (f >= 0) {
|
||||
syncfs(f);
|
||||
close(f);
|
||||
if (f < 0) {
|
||||
log_error(errno, "Failed to open filesystem at '%s'. %s.\n", devinfo->mount, strerror(errno));
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (syncfs(f) != 0) {
|
||||
int err = errno;
|
||||
log_error(err, "Failed to sync filesystem at '%s'. %s.\n", devinfo->mount, strerror(err));
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (close(f) != 0) {
|
||||
log_error(errno, "Failed to close filesystem at '%s'. %s.\n", devinfo->mount, strerror(errno));
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
#else
|
||||
(void)high;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue