I have tried to write a small tool to generate a huge amount of READ10 tasks, then using both ABORT_TASK as well as ABORT_TASK_SET but I can not get it to crash here. I have attached the ABORT_TASK/ABORT_TASK_SET torture program here in case someone wants to try to tweak it to reproduce the crashes. It links with libiscsi. regards ronnie sahlberg On Sat, Dec 10, 2011 at 8:34 PM, FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx> wrote: > On Thu, 8 Dec 2011 13:33:04 -0500 > John Pletka <jpletka@xxxxxxxxxxx> wrote: > >> What is the side effect of disabling the task manager? Any important >> functionality lost? Will it need to be periodically restarted to > > I think that if the task management fails, a Linux initiator closes > the connection and try to reconnect then if it works, the initiator > sends the same command again. So the file system doesn't detect > failure. If reconnecting fails, the command fails, then the file > system hits the I/O error. > > >> reset whatever the task manager was doing? This is going into a >> low-priority production server, so anything except data corruption can >> be dealt with. > > -- > To unsubscribe from this list: send the line "unsubscribe stgt" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html
#define PORTAL "127.0.0.1:3260" #define LUN 1 #define TARGET "iqn.ronnie.test" #define NUM_ABORTS 1000000 #define MAX_CONCURRENT 16 #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <poll.h> #include <time.h> #include <iscsi/iscsi.h> #include <iscsi/scsi-lowlevel.h> struct client { int finished; int num_aborts; }; static void read10_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data) { } static void tm_at_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data) { } static void tm_ats_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data) { struct client *clnt = (struct client *)private_data; int i, num; if (clnt->num_aborts++ > NUM_ABORTS) { clnt->finished = 1; } else { struct scsi_task *task; num = random()%MAX_CONCURRENT + 1; for ( i = 0; i < num; i++) { if ((task = iscsi_read10_task(iscsi, LUN, 0, 512, 512, read10_cb, NULL)) == NULL) { printf("failed to send read10 command\n"); exit(10); } /* abort some of the tasks immeidately and sometimes send two of them */ if (num & 0x01) { if (iscsi_task_mgmt_abort_task_async(iscsi, task, tm_at_cb, NULL) != 0) { printf("failed to send task management to abort the task\n"); exit(10); } } if (num & 0x02) { if (iscsi_task_mgmt_abort_task_async(iscsi, task, tm_at_cb, NULL) != 0) { printf("failed to send task management to abort the task\n"); exit(10); } } } if (iscsi_task_mgmt_abort_task_set_async(iscsi, LUN, tm_ats_cb, clnt) != 0) { printf("failed to send task management to abort the task set\n"); exit(10); } } } static void connect_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data) { struct client *clnt = (struct client *)private_data; printf("Connected to iscsi socket\n"); if (status != 0) { printf("connect_cb: connection failed status:%d\n", status); exit(10); } tm_ats_cb(iscsi, 0, command_data, private_data); } int main(int argc, char *argv[]) { struct iscsi_context *iscsi; struct pollfd pfd; struct client clnt; time_t t; memset(&clnt, 0, sizeof(struct client)); iscsi = iscsi_create_context("iqn.2002-10.com.ronnie:tmgm-torture"); if (iscsi == NULL) { printf("Failed to create context\n"); exit(10); } iscsi_set_targetname(iscsi, TARGET); iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); if (iscsi_full_connect_async(iscsi, PORTAL, LUN, connect_cb, &clnt) != 0) { printf("iscsi_connect failed. %s\n", iscsi_get_error(iscsi)); exit(10); } while (clnt.finished == 0) { time_t new_t = time(NULL); if (t != new_t) { printf("num tasks set aborts %d\n", clnt.num_aborts); } t = new_t; pfd.fd = iscsi_get_fd(iscsi); pfd.events = iscsi_which_events(iscsi); if (poll(&pfd, 1, -1) < 0) { printf("Poll failed"); exit(10); } if (iscsi_service(iscsi, pfd.revents) < 0) { printf("iscsi_service failed with : %s\n", iscsi_get_error(iscsi)); break; } } iscsi_destroy_context(iscsi); printf("finished\n"); return 0; }