qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Do you have a use for a tester of virtio-scsi with CD d


From: Thomas Schmitt
Subject: Re: [Qemu-devel] Do you have a use for a tester of virtio-scsi with CD drives ?
Date: Thu, 03 Nov 2011 23:30:24 +0100

Hi,

i could track down the reason for sense code B 00 06 to an ioctl(SG_IO)
which returns -1.  errno is 1.
The host system has in /usr/include/asm-generic/errno-base.h
  #define EPERM            1      /* Operation not permitted */

The user who runs qemu is able to perform e.g. 
  PREVENT/ALLOW MEDIA REMOVAL
  1e 00 00 00 00 00 
via ioctl(SG_IO) on /dev/sg1.
So it can hardly be the permissions of the device file:
  crw-rw---- 1 root cdrom 21, 1 Nov  2 12:44 /dev/sg1
The user is member of group cdrom.

For today, i close my shop. Maybe i get an idea tomorrow, how
to further investigate the problem.

---------------------------------------------------------------------

B 00 06 comes from hw/scsi-generic.c:scsi_command_complete()

  static void scsi_command_complete(void *opaque, int ret)
  {
  ...
      if (ret != 0) {
          switch (ret) {
          ...
          default:
              status = CHECK_CONDITION;
              scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));

SENSE_CODE is defined in hw/scsi.h
  #define SENSE_CODE(x) sense_code_ ## x

so that SENSE_CODE(IO_ERROR) yields this struct from hw/scsi-bus.c
  /* Command aborted, I/O process terminated */
  const struct SCSISense sense_code_IO_ERROR = {
      .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
  };


I tried to activate DPRINTF in hw/scsi-generic.c by removing the "//"
before
  #define DEBUG_SCSI

make yields:
  .../hw/scsi-generic.c: In function 'scsi_send_command':
  .../hw/scsi-generic.c:286: error: 'lun' undeclared (first use in this 
function)
  .../hw/scsi-generic.c:286: error: 'tag' undeclared (first use in this 
function)

So i had to change in scsi_send_command():

  -     DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
  +     DPRINTF("Command: len %zd data=0x%02x",

Further i added DPRINTFs to the suspected thrower of B 00 06:

        if (ret < 0) {
            DPRINTF("scsi_send_command: calling scsi_command_complete(%d)\n", 
                    ret);
            scsi_command_complete(r, ret);
            return 0;
        }
        DPRINTF("scsi_send_command: returning 0\n");

This yields with boot-time command
  1e 00 00 00 00 00 
in the qemu start terminal:

  scsi-generic: Command: len 0 data=0x1e 0x00 0x00 0x00 0x00 0x00
  scsi-generic: scsi_send_command: returning 0
  scsi-generic: scsi_command_complete: ret= -1

I.e. it went through scsi_send_command() and got 0 as return value from
  ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
Nevertheless there happens a call to scsi_command_complete() with ret==-1.

I added more DPRINTF and printf. 
It turns out that the offending call comes from
  posix-aio-compat.c: posix_aio_process_queue
after the ioctl(SG_IO) failed.

My print points report:
  scsi-generic: Command: len 0 data=0x1e 0x00 0x00 0x00 0x00 0x00
  block.c: bdrv_aio_ioctl: drv= 0x961f00 , drv->bdrv_aio_ioctl= 0x42bc30
  block.c: bdrv_aio_ioctl: drv= 0x9619e0 , drv->bdrv_aio_ioctl= 0x42b2d0
  block/raw-posix.c: hdev_aio_ioctl: calling paio_ioctl()
  scsi-generic: scsi_send_command: returning 0
  posix-aio-compat.c: handle_aiocb_ioctl: ioctl(12, 0x2285, ), ret= -1 , errno= 
1
  posix-aio-compat.c: qemu_paio_error: ret= -1
  posix-aio-compat.c: qemu_paio_error: returning 1
  posix-aio-compat.c: posix_aio_process_queue: ret= 1 -> -1
  posix-aio-compat.c: posix_aio_process_queue: calling acb->common.cb(,-1)
  scsi-generic: scsi_command_complete: ret= -1
  scsi-generic: Command complete 0x0x16c0e60 tag=0x0 status=2

ioctl command 0x2285 is defined in /usr/include/scsi/sg.h of host:
  #define SG_IO 0x2285

---------------------------------------------------------------------

Since i inserted the last few of the new printf() calls, i occasionaly
suffer qemu abort by SIGSEGV during guest boot. It happens before the
first DPRINTF happens in scsi_send_command(). 

But "git diff" reveils no changes towards the original state, which
would be to blame.
The printf format codes and the types match good enough to cause
no warnings at compile time.

Is it a known problem, that adding DPRINTF() or printf() can cause this ?
Or am i just too tired to see my fault ?

+    printf("block.c: bdrv_aio_ioctl: drv= 0x%lx , drv->bdrv_aio_ioctl= 0x%lx\n"
,
+           (unsigned long) drv,
+           (unsigned long) (drv ? drv->bdrv_aio_ioctl : NULL));

+    printf("block/raw-posix.c: hdev_aio_ioctl: calling paio_ioctl()\n");

+            DPRINTF("scsi_command_complete: ret= %d\n", ret);

+        DPRINTF("scsi_read_data: calling scsi_command_complete(%d)\n", ret);

+    DPRINTF("scsi_write_complete: calling scsi_command_complete(%d)\n", ret);

+        DPRINTF("scsi_write_data: calling scsi_command_complete(%d)\n",
+                ret);

+    DPRINTF("Command: len %zd data=0x%02x",
             r->req.cmd.xfer, cmd[0]);

+            DPRINTF("scsi_send_command: calling scsi_command_complete(%d)\n",
+                    ret);

+        DPRINTF("scsi_send_command: returning 0\n");

+    DPRINTF("scsi_send_command: not through execute_command()\n");

+        if(ret)
+           printf("linux-aio.c: qemu_laio_process_completion: ret= %d\n",
+                  ret);

+    if(ret)
+      printf("posix-aio-compat.c: handle_aiocb_ioctl: ioctl(%d, 0x%lx, ), ret= 
%d , errno= %d\n",
+         aiocb->aio_fildes, (unsigned long) aiocb->aio_ioctl_cmd, ret, errno);

+    if(ret)
+      printf("posix-aio-compat.c: qemu_paio_error: ret= %ld\n", (long int) 
ret);

+    if(ret)
+      printf("posix-aio-compat.c: qemu_paio_error: returning %ld\n", (long 
int) ret);

+                    if(ret)
+                      printf("posix-aio-compat.c: posix_aio_process_queue: 
ret= %d -> %d\n", ret, -ret);

+                if(ret)
+                  printf("posix-aio-compat.c: posix_aio_process_queue: calling 
acb->common.cb(,%d)\n", ret);

---------------------------------------------------------------------

Have a nice day :)

Thomas




reply via email to

[Prev in Thread] Current Thread [Next in Thread]