blocktest: support for stateless driver restarts
This commit is contained in:
parent
4005bba437
commit
f65e531ee4
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
RESULT_OK, /* exactly as expected */
|
RESULT_OK, /* exactly as expected */
|
||||||
|
RESULT_DEATH, /* driver died */
|
||||||
RESULT_COMMFAIL, /* communication failed */
|
RESULT_COMMFAIL, /* communication failed */
|
||||||
RESULT_BADTYPE, /* bad type in message */
|
RESULT_BADTYPE, /* bad type in message */
|
||||||
RESULT_BADID, /* bad request ID in message */
|
RESULT_BADID, /* bad request ID in message */
|
||||||
@ -94,6 +95,9 @@ PRIVATE void got_result(result_t *res, char *desc)
|
|||||||
(res->type == RESULT_OK) ? "PASS" : "FAIL");
|
(res->type == RESULT_OK) ? "PASS" : "FAIL");
|
||||||
|
|
||||||
switch (res->type) {
|
switch (res->type) {
|
||||||
|
case RESULT_DEATH:
|
||||||
|
printf("- driver died\n");
|
||||||
|
break;
|
||||||
case RESULT_COMMFAIL:
|
case RESULT_COMMFAIL:
|
||||||
printf("- communication failed; sendrec returned %d\n",
|
printf("- communication failed; sendrec returned %d\n",
|
||||||
res->value);
|
res->value);
|
||||||
@ -159,47 +163,52 @@ PRIVATE int sendrec_driver(message *m_ptr, ssize_t exp, result_t *res)
|
|||||||
{
|
{
|
||||||
/* Make a call to the driver, and perform basic checks on the return
|
/* Make a call to the driver, and perform basic checks on the return
|
||||||
* message. Fill in the result structure, wiping out what was in there
|
* message. Fill in the result structure, wiping out what was in there
|
||||||
* before. If the driver reports being restarted, reopen all previously
|
* before. If the driver dies in the process, attempt to recover but
|
||||||
* opened devices and retry the call.
|
* fail the request.
|
||||||
*/
|
*/
|
||||||
message m_orig;
|
message m_orig;
|
||||||
int i, r, retry;
|
endpoint_t last_endpt;
|
||||||
|
int i, r;
|
||||||
|
|
||||||
m_orig = *m_ptr;
|
m_orig = *m_ptr;
|
||||||
retry = 0;
|
|
||||||
|
|
||||||
do {
|
r = sendrec(driver_endpt, m_ptr);
|
||||||
r = sendrec(driver_endpt, m_ptr);
|
|
||||||
|
|
||||||
if (r != OK)
|
if (r == EDEADSRCDST) {
|
||||||
return set_result(res, RESULT_COMMFAIL, r);
|
/* The driver has died. Find its new endpoint, and reopen all
|
||||||
|
* devices that we opened earlier. Then return failure.
|
||||||
if (m_ptr->m_type != BDEV_REPLY)
|
|
||||||
return set_result(res, RESULT_BADTYPE, m_ptr->m_type);
|
|
||||||
|
|
||||||
if (m_ptr->BDEV_ID != m_orig.BDEV_ID)
|
|
||||||
return set_result(res, RESULT_BADID, m_ptr->BDEV_ID);
|
|
||||||
|
|
||||||
if (m_ptr->BDEV_STATUS != ERESTART) break;
|
|
||||||
|
|
||||||
/* The driver has died. Reopen all devices that we opened
|
|
||||||
* earlier, and resend the request. Up to three times.
|
|
||||||
*/
|
*/
|
||||||
printf("WARNING: driver has died, attempting to proceed\n");
|
printf("WARNING: driver has died, attempting to proceed\n");
|
||||||
|
|
||||||
driver_deaths++;
|
driver_deaths++;
|
||||||
|
|
||||||
|
/* Keep trying until we get a new endpoint. */
|
||||||
|
last_endpt = driver_endpt;
|
||||||
|
for (;;) {
|
||||||
|
r = ds_retrieve_label_endpt(driver_label,
|
||||||
|
&driver_endpt);
|
||||||
|
|
||||||
|
if (r == OK && last_endpt != driver_endpt)
|
||||||
|
break;
|
||||||
|
|
||||||
|
micro_delay(100000);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < nr_opened; i++)
|
for (i = 0; i < nr_opened; i++)
|
||||||
reopen_device(opened[i]);
|
reopen_device(opened[i]);
|
||||||
|
|
||||||
*m_ptr = m_orig;
|
return set_result(res, RESULT_DEATH, 0);
|
||||||
} while (++retry < 3);
|
|
||||||
|
|
||||||
if (retry == 3) {
|
|
||||||
printf("FATAL: driver has died three times in a row\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r != OK)
|
||||||
|
return set_result(res, RESULT_COMMFAIL, r);
|
||||||
|
|
||||||
|
if (m_ptr->m_type != BDEV_REPLY)
|
||||||
|
return set_result(res, RESULT_BADTYPE, m_ptr->m_type);
|
||||||
|
|
||||||
|
if (m_ptr->BDEV_ID != m_orig.BDEV_ID)
|
||||||
|
return set_result(res, RESULT_BADID, m_ptr->BDEV_ID);
|
||||||
|
|
||||||
if ((exp < 0 && m_ptr->BDEV_STATUS >= 0) ||
|
if ((exp < 0 && m_ptr->BDEV_STATUS >= 0) ||
|
||||||
(exp >= 0 && m_ptr->BDEV_STATUS < 0))
|
(exp >= 0 && m_ptr->BDEV_STATUS < 0))
|
||||||
return set_result(res, RESULT_BADSTATUS, m_ptr->BDEV_STATUS);
|
return set_result(res, RESULT_BADSTATUS, m_ptr->BDEV_STATUS);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user