#include <hallo.h> * Eduard Bloch [Sat, Sep 30 2006, 09:32:19PM]: > #include <hallo.h> > * Graham [Sat, Sep 30 2006, 01:16:46PM]: > > Package: wodim > > Version: 5:1.0~pre4-1.1 > > > > Writing a CD fails on my system. It looks like another problem caused > > by cdrecord trying to open devices that it doesn't need to; see also > > my bug report #370603, which covers the "-scanbus" case. > > That was a different case. "-scanbus" had no option to skip busy/failed > devices. "wodim" should work in that case and just skip the unuseable > devices.
Ok, Graham is right it was not a big deal to reproduce it. The current code does inded break when a device could not be opened because of permission problems when libscg scans (to build its list of "intuitive" SCSI addresses). We had already two cludges to work around this problems, one was from Andreas Metzler to not scan over all devices when the user already specified a device name, and another from me to stop looping forever when exclusiv open fails. However, the last part was only used conditionaly for atapi devices. With SCSI (eg. a mixture of usb-attached harddisks and external recorder which I just used), it fails: -scanbus runs well (because of the endless looping prevention) but opening fails. Now, I rewrote the code a bit more and ask for comments. It consolidates the previous workarounds. I consider adding it to the stable branch RSN, most likely for pre5. Index: libscg/scsi-linux-sg.c =================================================================== --- libscg/scsi-linux-sg.c (Revision 351) +++ libscg/scsi-linux-sg.c (Arbeitskopie) @@ -242,25 +242,21 @@ #endif LOCAL void sg_settimeout __PR((int f, int timeout)); -int sg_open_excl __PR((char *device, int mode, int quickAndQuiet)); +int sg_open_excl __PR((char *device, int mode)); int -sg_open_excl(device, mode, quickAndQuiet) +sg_open_excl(device, mode) char *device; int mode; - int quickAndQuiet; { int f; int i; f = open(device, mode|O_EXCL); - if(!quickAndQuiet) - for (i = 0; (i < 10) && (f == -1 && (errno == EACCES || errno == EBUSY)); i++) { - fprintf(stderr, "Error trying to open %s exclusively (%s)... retrying in 1 second.\n", device, strerror(errno)); - usleep(1000000 + 100000.0 * rand()/(RAND_MAX+1.0)); - f = open(device, mode|O_EXCL); - } - if (f == -1 && errno != EACCES && errno != EBUSY) { - f = open(device, mode); + // try to reopen locked/busy devices up to five times + for (i = 0; (i < 5) && (f == -1 && errno == EBUSY); i++) { + fprintf(stderr, "Error trying to open %s exclusively (%s)... %s\n", device, strerror(errno), (i<5)?"retrying in 1 second.":""); + usleep(1000000 + 100000.0 * rand()/(RAND_MAX+1.0)); + f = open(device, mode|O_EXCL); } return f; } @@ -448,7 +444,7 @@ if (use_ata) for (i=2*busno+tgt >= 0 ? 2*busno+tgt:0; i <= 25; i++) { js_snprintf(devname, sizeof (devname), "/dev/hd%c", i+'a'); /* O_NONBLOCK is dangerous */ - f = sg_open_excl(devname, O_RDWR | O_NONBLOCK, 1); + f = sg_open_excl(devname, O_RDWR | O_NONBLOCK); if (f < 0) { /* * Set up error string but let us clear it later @@ -489,7 +485,7 @@ if (nopen == 0) for (i = 0; i < 32; i++) { js_snprintf(devname, sizeof (devname), "/dev/sg%d", i); /* O_NONBLOCK is dangerous */ - f = sg_open_excl(devname, O_RDWR | O_NONBLOCK, 0); + f = sg_open_excl(devname, O_RDWR | O_NONBLOCK); if (f < 0) { /* * Set up error string but let us clear it later @@ -498,6 +494,8 @@ if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "Cannot open '/dev/sg*'"); + if(errno == EACCES || errno==EPERM) + continue; if (errno != ENOENT && errno != ENXIO && errno != ENODEV) { if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, @@ -518,7 +516,7 @@ if (nopen == 0) for (i = 0; i <= 25; i++) { js_snprintf(devname, sizeof (devname), "/dev/sg%c", i+'a'); /* O_NONBLOCK is dangerous */ - f = sg_open_excl(devname, O_RDWR | O_NONBLOCK, 0); + f = sg_open_excl(devname, O_RDWR | O_NONBLOCK); if (f < 0) { /* * Set up error string but let us clear it later @@ -527,6 +525,8 @@ if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, "Cannot open '/dev/sg*'"); + if(errno == EACCES || errno==EPERM) + continue; if (errno != ENOENT && errno != ENXIO && errno != ENODEV) { if (scgp->errstr) js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE, @@ -570,7 +570,7 @@ */ } /* O_NONBLOCK is dangerous */ - f = sg_open_excl(device, O_RDWR | O_NONBLOCK, 0); + f = sg_open_excl(device, O_RDWR | O_NONBLOCK); /* if (f < 0 && errno == ENOENT)*/ /* goto openpg;*/ -- <Getty> HA! Ich habs <klatsch> Ich Idiot -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]