New option drive_scsi_dev_family=sr|scd|sg

This commit is contained in:
2007-03-14 13:37:32 +00:00
parent fe6f0becf5
commit c03d02ff39
6 changed files with 102 additions and 19 deletions

View File

@ -26,9 +26,18 @@ struct libdax_msgs *libdax_messenger= NULL;
int burn_running = 0;
/* ts A60813 : wether to use O_EXCL and/or O_NONBLOCK in libburn/sg.c */
/* ts A60813 : Linux: wether to use O_EXCL and/or O_NONBLOCK in libburn/sg.c */
int burn_sg_open_o_excl = 1;
/* ts A70314 : Linux: what device family to use :
0= default family
1= sr
2= scd
(3= st)
4= sg
*/
int burn_sg_use_family = 0;
/* O_NONBLOCK was hardcoded in enumerate_ata() which i hardly use.
For enumerate_sg() it seems ok.
So it should stay default mode until enumerate_ata() without O_NONBLOCK
@ -120,7 +129,8 @@ void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy)
if (!burn_running)
return;
burn_sg_open_o_excl= exclusive;
burn_sg_open_o_excl= exclusive & 3;
burn_sg_use_family= (exclusive >> 2) & 15;
burn_sg_open_o_nonblock= !blocking;
burn_sg_open_abort_busy= !!abort_on_busy;
}

View File

@ -572,13 +572,20 @@ void burn_set_verbosity(int level);
after burn_initialize() and before any bus scan. But not mandatory at all.
Parameter value 1 enables a feature, 0 disables.
Default is (1,0,0). Have a good reason before you change it.
@param exclusive 1 = Try to open only devices which are not marked as busy
@param exclusive Linux only:
0 = no attempt to make drive access exclusive.
1 = Try to open only devices which are not marked as busy
and try to mark them busy if opened sucessfully. (O_EXCL)
There are kernels which simply don't care about O_EXCL.
Some have it off, some have it on, some are switchable.
2 = in case of a SCSI device, also try to open exclusively
the matching /dev/sr, /dev/scd and /dev/st .
0 = no attempt to make drive access exclusive.
the matching /dev/sr, /dev/scd and /dev/st .
One may select a device SCSI file family by adding
0 = default family
4 = /dev/sr%d
8 = /dev/scd%d
16 = /dev/sg%d
Do not use other values !
@param blocking Try to wait for drives which do not open immediately but
also do not return an error as well. (O_NONBLOCK)
This might stall indefinitely with /dev/hdX hard disks.

View File

@ -105,16 +105,9 @@ static int linux_sg_enumerate_debug = 0;
address parameters Host, Channel, Id, Lun and also Bus.
E.g.: "/dev/sg%d"
*/
/* NEW INFO: If hard disks at /dev/sr allow ioctl(CDROM_DRIVE_STATUS), they
are in danger.
If you want it less dangerous:
#undef CDROM_DRIVE_STATUS
but then you might need linux_sg_accept_any_type = 1 which
is _more dangerous_.
/* sr%d is supposed to map only CD-ROM style devices. Additionally a test
with ioctl(CDROM_DRIVE_STATUS) is made to assert that it is such a drive,
*/
/* !!! DO NOT SET TO sr%d UNLESS YOU PROTECTED ALL INDISPENSIBLE DEVICES
by chmod -rw . A test wether non-CD devices are properly excluded would
be well needed though. Heroic disks, scanners, etc. wanted !!! */
static char linux_sg_device_family[80] = {"/dev/sg%d"};
@ -171,9 +164,11 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
/* >>> ts A61115 : this needs mending. A Linux aspect shows up in cdrskin. */
/* ts A60813 : storage objects are in libburn/init.c
wether to use O_EXCL
what device family to use : 0=default, 1=sr, 2=scd, (3=st), 4=sg
wether to use O_NOBLOCK with open(2) on devices
wether to take O_EXCL rejection as fatal error */
extern int burn_sg_open_o_excl;
extern int burn_sg_use_family;
extern int burn_sg_open_o_nonblock;
extern int burn_sg_open_abort_busy;
@ -188,6 +183,21 @@ int mmc_function_spy(char * text);
/* (Public functions are listed below) */
/* ------------------------------------------------------------------------ */
/* This installs (much too often) the device file family if one was
chosen explicitely by burn_preset_device_open()
*/
void sg_select_device_family(void)
{
if (burn_sg_use_family == 1)
strcpy(linux_sg_device_family, "/dev/sr%d");
else if (burn_sg_use_family == 2)
strcpy(linux_sg_device_family, "/dev/scd%d");
else if (burn_sg_use_family == 3)
strcpy(linux_sg_device_family, "/dev/st%d");
else if (burn_sg_use_family == 4)
strcpy(linux_sg_device_family, "/dev/sg%d");
}
static int sgio_test(int fd)
{
@ -352,6 +362,7 @@ static int sg_open_scsi_siblings(char *path, int driveno,
static char tldev[][81]= {"/dev/sr%d", "/dev/scd%d", "/dev/st%d",
"/dev/sg%d", ""};
sg_select_device_family();
if (linux_sg_device_family[0] == 0)
return 1;
@ -482,6 +493,8 @@ static void sg_enumerate(void)
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
char fname[10];
sg_select_device_family();
if (linux_sg_enumerate_debug)
fprintf(stderr, "libburn_debug: linux_sg_device_family = %s\n",
linux_sg_device_family);
@ -520,6 +533,16 @@ static void sg_enumerate(void)
"ioctl(SG_GET_SCSI_ID) failed, errno=%d '%s' , ",
errno, strerror(errno));
if (sgio_test(fd) == -1) {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"FATAL: sgio_test() failed: errno=%d '%s'",
errno, strerror(errno));
sg_close_drive_fd(fname, -1, &fd, 0);
continue;
}
#ifdef CDROM_DRIVE_STATUS
/* ts A61211 : not widening old acceptance range */
if (strcmp(linux_sg_device_family,"/dev/sg%d") != 0) {
@ -698,6 +721,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
if (initialize == -1)
return 0;
sg_select_device_family();
if (linux_sg_device_family[0] == 0)
sg_limit = 0;
if (linux_ata_device_family[0] == 0)