libcdio-devel
[Top][All Lists]
Advanced

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

[Libcdio-devel] Re: Burned CD-RW and DVD+RW via libcdio MMC interface


From: Thomas Schmitt
Subject: [Libcdio-devel] Re: Burned CD-RW and DVD+RW via libcdio MMC interface
Date: Sun, 20 Dec 2009 09:30:28 +0100

Hi,

this mail gets longer and longer.
So many points to discuss. Sorry in advance.


> I had some trouble with cut and paste with "patch" but Emacs 23's Diff mode
> didn't seem to have a problem.

They were produced by diff -puN.
I rarely submit patches.
Any other command preferred for generating them ?


> The question I
> have is whether run_mmc_linux after the patch *now* does something
> reasonable (or not incorrect) when e_direction parameter is
> SCSI_MMC_DATA_NONE ?

It works with all commands which i send out of
the NONE class. E.g 00h TEST UNIT READY ,
1Eh PREVENT/ALLOW MEDIA REMOVAL, 1Bh START/STOP
UNIT.

It may be that the transport mechanisms of the
operating systems tolerate if you submit a
no-transfer command as read command with length
0. But at least both Linux interfaces and the
FreeBSD CAM interface have NONE directions:
CDROM_SEND_PACKET :  CGC_DATA_NONE
SG_IO             :  SG_DXFER_NONE
CAM               :  CAM_DIR_NONE
So it seems wise to use them with commands which
do not transfer payload according to SCSI specs.

growisofs uses above NONE directions as default
if no READ or WRITE is set explicitely.
libburn uses them too. No problems known.


> Clearly opening read-only *when that is all you need* is
> probably a good thing.

I agree.
O_RDWR should not be hardcoded but controlled by
the application. 

> Herbert Valerio Riedel when he wrote vcdimager (from which this grew out of)
> added a provision on the open to specify an "access mode" .

How about a mode "MMC_RDWR" which opens for
writing and uses READ(10) or READ(12) via
mmc_run_cmd() for libcdio read functions ?

On Linux it should open O_RDWR|O_EXCL for
getting hopefully exclusive access.

> whether to use blocking or non-blocking mode.

I too wonder whether O_NONBLOCK is needed. 
I inherited it with the Linux adapter of libburn
and had no reason to disable it yet.


> It is likely that many processes can simultaneously
> open read only, while with read/write one might need exclusive access. (I
> can't imagine for CD's that Unix's "last write wins" policy is used.)

No policy in Linux but rather a bit of ignorance.
The situation in this aspect is still precarious.
  http://lkml.org/lkml/2007/3/30/63

It is crucial for sequential media models that
they do not get disturbed while writing is going
on. Especially CD-R[W] and DVD-R[W] react with
burn aborts if other commands are sent inbetween.

Linux has no good mechanism to negotiate
exclusive access. Eduard Bloch, Ted T'so and me
once explored that topic and finally had to
give up finding a neat solution. Alan Cox and
others see no problem. (They use tapes, i guess.)
A locking protocol was sketched, evaluated, and
discarded.
  http://libburnia-project.org/browser/libburn/trunk/doc/ddlp.txt
See especially beginning at line 340:
  "What are the Stumble Stones ?"

Finally wodim, growisofs and libburn agreed to
use the inofficial O_EXCL protocol in order to
be at least mutually friendly.
But libblkid by Ted T'so could not join because
O_EXCL would prevent parts of its functionality.

The worst offender is of course hald with its
ever changing behavior and interfaces.
I curb it by killing all  addon-storage  
processes which watch my MMC drives.

SuSE Linux traditionally takes a bit more
care for exclusivity than the vanilla kernel
does. Often it lasts months before hald
has a first success with spoiling CD burns.

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

> the request to support CD burning comes from
> rms via Karl Berry
> this is strategic!

libburn has the MMC knowledge to burn audio
and data tracks. libcdio has in principle the
knowledge to transport the necessary commands
to the drive.

What the libburnia project can offer:

- A set of libraries and two applications
  which cover writing of data and audio,
  reading of data, manipulation of ISO 9660
  filesystem trees, production of ISO 9660 
  images, extraction of data from ISO images.

- Some MMC knowledge. Maybe our BD capabilities
  and my test drives can be of help.
  How about media manufacturer identification ?

- Emulated ISO 9660 multi session on media or
  files which offer no own table-of-content.
  
- A RRIP-like extension to ISO 9660 for xattr,
  ACL, and internal extra info. 
  
What libburnia could use from libcdio:

- A system adapter based on libcdio.
  Our operating system SCSI adapters have to
  detect drives, to open a connection to a
  drive, to send SCSI commands, and to close the
  connection to the drive. Multiple drives must
  be usable at the same time.

- Knowledge about CD-XA, CD-TEXT, ...

An allocation of responsibilities could be:

- libcdio for -ROM drives of nearly any age,
  for reading of all sector formats, for light
  weight read-only ISO 9660 access.

- libburnia for writer drives and MMC -ROM
  drives, for reading of data sectors, for
  writing of CD audio and CD/DVD/BD data tracks,
  for creation, manipulation and writing of
  ISO 9660, for throughput optimized ISO 9660
  extraction.

Both should have own capabilities for evaluating
type and state of CD/DVD/BD media. But we can
share code and knowledge.

One should strive for expanding the ISO 9660
capabilities to UDF.

To do for that:

- libburnia develops a system adapter sg-libcdio
  which can be chosen by ./configure. It will be
  default on operating systems where libcdio is
  available and libburn has no matching
  sg-adapter.

- libcdio learns to handle BD and to recognize
  emulated ISO 9660 multi session.
  (How is ISO 9660 multi-session support
   anyway ? Something like on Linux
     mount -o sbsector=...
  )
  (cd-info recognizes ISO 9660 on DVD+RW but not
   on BD-RE or BD-ROM:
     $ cd-info -i /dev/sr1 --dvd
     ...
     ++ WARN: error in ioctl CDROMREADTOCENTRY for lead-out: Input/output error
   Can it be libcdio tries to handle the BD
   as CD ? Command READ TOC/PMA/ATIP is of very
   limited use with BD. READ DISC INFORMATION
   and READ TRACK INFORMATION work ok.
  )

- libcdio learns to read ACL and xattr from
  eventual AAIP entries in ISO 9660 images.

- both projects check whether the other has
  some goodies to learn from.

- continued work to plan for UDF multi-session
  (in contrast to UDF (pseudo-)random-write).

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

For the sg-libcdio system adapter there is
one important open point left:

libburn needs a way to learn about the SCSI
sense replies of the commands.
At least on Linux and FreeBSD they are
available. But libcdio does not forward them
to its apps.

Yesterday i failed to implement a function
which hands out the most recent sense reply.
I have to find a place where to store it
from  run_mmc_cmd_linux() which only has a
_img_private_t and to later read it via the
CdIo_t which owns that _img_private_t.
There is a void pointer gap.

I naively introduced in lib/driver/generic.h:

  typedef struct {
  ...
    driver_return_code_t scsi_mmc_driver_ret;
    unsigned char scsi_mmc_sense[18];
  } generic_img_private_t;

in lib/driver/gnu_linux.c

    int i_rc = ioctl (p_env->gen.fd, CDROM_SEND_PACKET, &cgc);

+   memcpy((void *) p_env->gen.scsi_mmc_sense, cgc.sense,
+           sizeof(p_env->gen.scsi_mmc_sense));

and in lib/driver/mmc.c

  /** Obtain transport return code and SCSI sense of the most
      recently performed MMC command.
      @param sense  See SPC-3 4.5.3 Fixed format sense data
                    SCSI error codes: sense[2]=Key, [12]=ASC, [13]=ASCQ
      @return same value as with most recent MMC command
  */
  mmc_get_cmd_scsi_sense( const CdIo_t *p_cdio, unsigned char sense[18])
  {
    int len = 18;
    unsigned char s;

    if (!p_cdio) return DRIVER_OP_UNINIT;
    memset(sense, 0, len);
    s = p_cdio->env->gen.scsi_mmc_sense;
    if(sizeof(s) < 18)
      len = sizeof(s);
    memcpy(sense, s, len);
    return p_cdio->env->gen.scsi_mmc_driver_ret;
  }

But
  s = p_cdio->env->gen.scsi_mmc_sense;
yields in gcc
  mmc.c:979: warning: dereferencing 'void *' pointer
  mmc.c:979: error: request for member 'gen' in something
                    not a structure or union

So i would need some architectural advise here.

Shall one rather introduce a new
mmc_run_cmd_sense() which performs a command and
returns the sense bytes as parameter ?

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

Whew. Time for breakfast.
I am sure i forgot some important topic.


Have a nice day :)

Thomas





reply via email to

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