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

Re: Request for cooperation with all burn backends

Is it really a problem between recording programs?

It is especially a problem between growisofs and libburn
on my 2.4 system.

- growisofs burns of DVD+RW experience data damage in about
25 % of the cases after libburn did a bus scan on the burning drive.

- growisofs burns of DVD-RW stall libburn bus scan as soon as the
active drive is enumerated. Affected growisofs burns have about
50 % probability to be damaged.


I can offer a patch of 100 to 150 lines in growisofs.c
to achieve locking of /dev/srN or /dev/scdN via the
corresponding /dev/sgM.

Since i implemented that on my system i am free of trouble between growisofs and libburn.
I published the test version (loudly declaring itself as
inofficial hack) on the libburn-hackers@pykix.org mailing list
in the hope of some test results ... then i wanted to approach

No echo. Everybody is on 2.6 already.

See diff -puN at

If "sg scanning" is so intrusive, why are you using at all? Isn't there a way to list sg binding, say though ... /proc? And look, there is! It's even possible to see what kind each device is and limit search to type 5, a.k.a. CD-ROM, devices... In either case below is function which will appear in next release. Test it. A.


int grab_sg (int blkfd)
{ struct { unsigned int dev_id,host_unique_id; } idlunblk,idlunsg;
  FILE *fp;
  int   host_no,channel,lun,id,type,i,sgfd=-1;
  char  str[128];
  struct stat sb;

    if (ioctl (blkfd,SCSI_IOCTL_GET_IDLUN,&idlunblk) < 0) return -1;

    if ((fp=fopen ("/proc/scsi/sg/devices","r")) == NULL) return -1;

    for (i=0;i>=0;i++)
    {	if (fgets (str,sizeof(str),fp) == NULL)	break;

	if (sscanf (str,"%d\t%d\t%d\t%d\t%d",
			&host_no,&channel,&id,&lun,&type) != 5)

	if (idlunblk.dev_id ==	((id & 0xff) +
				((lun & 0xff) << 8) +
				((channel & 0xff) << 16) +
				((host_no & 0xff) << 24)))
	{   sprintf (str,"/dev/sg%d",i);
	    if (stat (str,&sb) < 0)	break;
	    errno = ENOENT;
	    if (minor(sb.st_rdev) != i)	break;
	    sgfd = open (str,O_RDWR|O_NONBLOCK|O_EXCL);
	    if (sgfd>=0)
	    {	if (ioctl (sgfd,SCSI_IOCTL_GET_IDLUN,&idlunsg) < 0 ||
		    idlunblk.dev_id != idlunsg.dev_id ||
		    idlunblk.host_unique_id != idlunsg.host_unique_id)
		    close (sgfd), sgfd = -1, errno = ENOENT;
    fclose (fp);

  return sgfd;

Reply to: