diff mbox series

block/iscsi: cancel libiscsi task when ABORT TASK TMF completes

Message ID 20180215111526.2464-1-stefanha@redhat.com
State New
Headers show
Series block/iscsi: cancel libiscsi task when ABORT TASK TMF completes | expand

Commit Message

Stefan Hajnoczi Feb. 15, 2018, 11:15 a.m. UTC
The libiscsi iscsi_task_mgmt_async() API documentation says:

  abort_task will also cancel the scsi task. The callback for the scsi
  task will be invoked with SCSI_STATUS_CANCELLED

The libiscsi implementation does not fulfil this promise.  The task's
callback is not invoked and its struct iscsi_pdu remains in the internal
list (effectively leaked).

This patch invokes the libiscsi iscsi_scsi_cancel_task() API to force
the task's callback to be invoked with SCSI_STATUS_CANCELLED when the
ABORT TASK TMF completes and the task's callback hasn't been invoked
yet.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/iscsi.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

Comments

Peter Lieven Feb. 15, 2018, 2:24 p.m. UTC | #1
Am 15.02.2018 um 12:15 schrieb Stefan Hajnoczi:
> The libiscsi iscsi_task_mgmt_async() API documentation says:
>
>    abort_task will also cancel the scsi task. The callback for the scsi
>    task will be invoked with SCSI_STATUS_CANCELLED
>
> The libiscsi implementation does not fulfil this promise.  The task's
> callback is not invoked and its struct iscsi_pdu remains in the internal
> list (effectively leaked).

If that contract is fixed in libiscsi, will the Qemu iSCSI driver still work?

Peter
Stefan Hajnoczi Feb. 15, 2018, 5:27 p.m. UTC | #2
On Thu, Feb 15, 2018 at 03:24:54PM +0100, Peter Lieven wrote:
> Am 15.02.2018 um 12:15 schrieb Stefan Hajnoczi:
> > The libiscsi iscsi_task_mgmt_async() API documentation says:
> > 
> >    abort_task will also cancel the scsi task. The callback for the scsi
> >    task will be invoked with SCSI_STATUS_CANCELLED
> > 
> > The libiscsi implementation does not fulfil this promise.  The task's
> > callback is not invoked and its struct iscsi_pdu remains in the internal
> > list (effectively leaked).
> 
> If that contract is fixed in libiscsi, will the Qemu iSCSI driver still work?

In

+    /* If the command callback hasn't been called yet, drop the task */
+    if (!acb->bh) {

and

+    if (status == SCSI_STATUS_CANCELLED) {
+        if (!acb->bh) {

we're mindful of the fact that the callback may have been invoked by
libiscsi already.  There is no risk of double-completion.

Stefan
Peter Lieven Feb. 20, 2018, 3:12 p.m. UTC | #3
Am 15.02.2018 um 18:27 schrieb Stefan Hajnoczi:
> On Thu, Feb 15, 2018 at 03:24:54PM +0100, Peter Lieven wrote:
>> Am 15.02.2018 um 12:15 schrieb Stefan Hajnoczi:
>>> The libiscsi iscsi_task_mgmt_async() API documentation says:
>>>
>>>     abort_task will also cancel the scsi task. The callback for the scsi
>>>     task will be invoked with SCSI_STATUS_CANCELLED
>>>
>>> The libiscsi implementation does not fulfil this promise.  The task's
>>> callback is not invoked and its struct iscsi_pdu remains in the internal
>>> list (effectively leaked).
>> If that contract is fixed in libiscsi, will the Qemu iSCSI driver still work?
> In
>
> +    /* If the command callback hasn't been called yet, drop the task */
> +    if (!acb->bh) {
>
> and
>
> +    if (status == SCSI_STATUS_CANCELLED) {
> +        if (!acb->bh) {
>
> we're mindful of the fact that the callback may have been invoked by
> libiscsi already.  There is no risk of double-completion.

Hi Stefan,

thanks for the clarification. I am fine with this change. I will check with Ronnie for the
libiscsi fix.

Peter
Stefan Hajnoczi Feb. 20, 2018, 5:59 p.m. UTC | #4
On Tue, Feb 20, 2018 at 3:12 PM, Peter Lieven <pl@kamp.de> wrote:
> Am 15.02.2018 um 18:27 schrieb Stefan Hajnoczi:
>>
>> On Thu, Feb 15, 2018 at 03:24:54PM +0100, Peter Lieven wrote:
>>>
>>> Am 15.02.2018 um 12:15 schrieb Stefan Hajnoczi:
>>>>
>>>> The libiscsi iscsi_task_mgmt_async() API documentation says:
>>>>
>>>>     abort_task will also cancel the scsi task. The callback for the scsi
>>>>     task will be invoked with SCSI_STATUS_CANCELLED
>>>>
>>>> The libiscsi implementation does not fulfil this promise.  The task's
>>>> callback is not invoked and its struct iscsi_pdu remains in the internal
>>>> list (effectively leaked).
>>>
>>> If that contract is fixed in libiscsi, will the Qemu iSCSI driver still
>>> work?
>>
>> In
>>
>> +    /* If the command callback hasn't been called yet, drop the task */
>> +    if (!acb->bh) {
>>
>> and
>>
>> +    if (status == SCSI_STATUS_CANCELLED) {
>> +        if (!acb->bh) {
>>
>> we're mindful of the fact that the callback may have been invoked by
>> libiscsi already.  There is no risk of double-completion.
>
>
> Hi Stefan,
>
> thanks for the clarification. I am fine with this change. I will check with
> Ronnie for the
> libiscsi fix.

Great, then this patch can go via Paolo's SCSI tree.

Stefan
diff mbox series

Patch

diff --git a/block/iscsi.c b/block/iscsi.c
index 41e67cb371..4cb188ac2b 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -292,8 +292,12 @@  iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
 {
     IscsiAIOCB *acb = private_data;
 
-    acb->status = -ECANCELED;
-    iscsi_schedule_bh(acb);
+    /* If the command callback hasn't been called yet, drop the task */
+    if (!acb->bh) {
+        /* Call iscsi_aio_ioctl_cb() with SCSI_STATUS_CANCELLED */
+        iscsi_scsi_cancel_task(iscsi, acb->task);
+    }
+
     qemu_aio_unref(acb); /* acquired in iscsi_aio_cancel() */
 }
 
@@ -941,6 +945,14 @@  iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
 {
     IscsiAIOCB *acb = opaque;
 
+    if (status == SCSI_STATUS_CANCELLED) {
+        if (!acb->bh) {
+            acb->status = -ECANCELED;
+            iscsi_schedule_bh(acb);
+        }
+        return;
+    }
+
     acb->status = 0;
     if (status < 0) {
         error_report("Failed to ioctl(SG_IO) to iSCSI lun. %s",