New option drive_scsi_dev_family=sr|scd|sg

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

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "March 6, 2007" .TH CDRSKIN 1 "March 14, 2007"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -725,6 +725,13 @@ This is not guaranteed to work with all drivers. Some need nonblocking i/o.
Linux specific: Do not ask the operating system to prevent opening busy drives. Linux specific: Do not ask the operating system to prevent opening busy drives.
Wether this leads to senseful behavior depends on operating system and kernel. Wether this leads to senseful behavior depends on operating system and kernel.
.TP .TP
.BI drive_scsi_dev_family= sr | scd | sg
Linux specific: Select a SCSI device file family to be used for drive command
transactions. Normally this is /dev/sgN but on modern kernels it might be
helpful to use drive_scsi_dev_family=sr in order to meet other programs at
a common device file for each drive. On kernel 2.4 this will find no drives.
Device file family /dev/hdX on kernel 2.6 is not affected by this setting.
.TP
.BI \--drive_scsi_exclusive .BI \--drive_scsi_exclusive
Linux specific: Linux specific:
Try to exclusively reserve device files /dev/srN, /dev/scdM, /dev/stK of drive. Try to exclusively reserve device files /dev/srN, /dev/scdM, /dev/stK of drive.

View File

@ -131,6 +131,7 @@ or
/* Place novelty switch macros here. /* Place novelty switch macros here.
Move them down to Cdrskin_libburn_from_pykix_svN on version leap Move them down to Cdrskin_libburn_from_pykix_svN on version leap
*/ */
#define Cdrskin_libburn_preset_device_familY 1
#endif /* Cdrskin_libburn_0_3_5 */ #endif /* Cdrskin_libburn_0_3_5 */
@ -1427,9 +1428,14 @@ struct CdrpreskiN {
/** Wether to abort when a busy drive is encountered during bus scan */ /** Wether to abort when a busy drive is encountered during bus scan */
int abort_on_busy_drive; int abort_on_busy_drive;
/** Wether to try to avoid collisions when opening drives */ /** Linux specific : Wether to try to avoid collisions when opening drives */
int drive_exclusive; int drive_exclusive;
/** Linux specific : Device file address family to use :
0=default , 1=sr , 2=scd , 4=sg */
int drive_scsi_dev_family;
/** Wether to try to wait for unwilling drives to become willing to open */ /** Wether to try to wait for unwilling drives to become willing to open */
int drive_blocking; int drive_blocking;
@ -1490,6 +1496,7 @@ int Cdrpreskin_new(struct CdrpreskiN **preskin, int flag)
o->scan_demands_drive= 0; o->scan_demands_drive= 0;
o->abort_on_busy_drive= 0; o->abort_on_busy_drive= 0;
o->drive_exclusive= 1; o->drive_exclusive= 1;
o->drive_scsi_dev_family= 0;
o->drive_blocking= 0; o->drive_blocking= 0;
strcpy(o->write_mode_name,"DEFAULT"); strcpy(o->write_mode_name,"DEFAULT");
@ -1959,6 +1966,17 @@ set_dev:;
} else if(strcmp(argv[i],"--drive_not_exclusive")==0) { } else if(strcmp(argv[i],"--drive_not_exclusive")==0) {
o->drive_exclusive= 0; o->drive_exclusive= 0;
} else if(strncmp(argv[i],"drive_scsi_dev_family=",22)==0) {
value_pt= argv[i]+22;
if(strcmp(value_pt,"sr")==0)
o->drive_scsi_dev_family= 1;
else if(strcmp(value_pt,"scd")==0)
o->drive_scsi_dev_family= 2;
else if(strcmp(value_pt,"sg")==0)
o->drive_scsi_dev_family= 4;
else
o->drive_scsi_dev_family= 0;
} else if(strcmp(argv[i],"--drive_scsi_exclusive")==0) { } else if(strcmp(argv[i],"--drive_scsi_exclusive")==0) {
o->drive_exclusive= 2; o->drive_exclusive= 2;
@ -2011,6 +2029,9 @@ set_dev:;
printf(" (might be stalled by a busy hard disk)\n"); printf(" (might be stalled by a busy hard disk)\n");
printf(" --drive_not_exclusive do not ask kernel to prevent opening\n"); printf(" --drive_not_exclusive do not ask kernel to prevent opening\n");
printf(" busy drives. Effect is kernel dependend.\n"); printf(" busy drives. Effect is kernel dependend.\n");
printf(
" drive_scsi_dev_family=<sr|scd|sg|default> select Linux device\n");
printf(" file family to be used for (pseudo-)SCSI.\n");
printf( printf(
" --drive_scsi_exclusive try to exclusively reserve device files\n"); " --drive_scsi_exclusive try to exclusively reserve device files\n");
printf(" /dev/srN, /dev/scdM, /dev/stK of drive.\n"); printf(" /dev/srN, /dev/scdM, /dev/stK of drive.\n");
@ -5608,6 +5629,16 @@ set_blank:;
} else if(strcmp(argv[i],"--drive_not_exclusive")==0) { } else if(strcmp(argv[i],"--drive_not_exclusive")==0) {
/* is handled in Cdrpreskin_setup() */; /* is handled in Cdrpreskin_setup() */;
} else if(strncmp(argv[i],"drive_scsi_dev_family=",22)==0) {
/* is handled in Cdrpreskin_setup() */;
if(skin->verbosity>=Cdrskin_verbose_debuG &&
skin->preskin->drive_scsi_dev_family!=0)
ClN(fprintf(stderr,"cdrskin_debug: drive_scsi_dev_family= %d\n",
skin->preskin->drive_scsi_dev_family));
} else if(strcmp(argv[i],"--drive_scsi_exclusive")==0) {
/* is handled in Cdrpreskin_setup() */;
} else if(strncmp(argv[i],"-driveropts=",12)==0) { } else if(strncmp(argv[i],"-driveropts=",12)==0) {
value_pt= argv[i]+12; value_pt= argv[i]+12;
goto set_driveropts; goto set_driveropts;
@ -6103,10 +6134,14 @@ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin,
*exit_value= 0; *exit_value= 0;
#ifndef Cdrskin_libburn_no_burn_preset_device_opeN #ifndef Cdrskin_libburn_no_burn_preset_device_opeN
burn_preset_device_open((*preskin)->drive_exclusive, burn_preset_device_open((*preskin)->drive_exclusive
#ifdef Cdrskin_libburn_preset_device_familY
| ((*preskin)->drive_scsi_dev_family<<2)
#endif
,
(*preskin)->drive_blocking, (*preskin)->drive_blocking,
(*preskin)->abort_on_busy_drive); (*preskin)->abort_on_busy_drive);
#endif #endif /* ! Cdrskin_libburn_no_burn_preset_device_opeN */
if(strlen((*preskin)->device_adr)>0) { /* disable scan for all others */ if(strlen((*preskin)->device_adr)>0) { /* disable scan for all others */
ClN(printf( ClN(printf(

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.03.12.155600" #define Cdrskin_timestamP "2007.03.14.133618"

View File

@ -26,9 +26,18 @@ struct libdax_msgs *libdax_messenger= NULL;
int burn_running = 0; 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; 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. /* O_NONBLOCK was hardcoded in enumerate_ata() which i hardly use.
For enumerate_sg() it seems ok. For enumerate_sg() it seems ok.
So it should stay default mode until enumerate_ata() without O_NONBLOCK 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) if (!burn_running)
return; 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_o_nonblock= !blocking;
burn_sg_open_abort_busy= !!abort_on_busy; 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. after burn_initialize() and before any bus scan. But not mandatory at all.
Parameter value 1 enables a feature, 0 disables. Parameter value 1 enables a feature, 0 disables.
Default is (1,0,0). Have a good reason before you change it. 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) and try to mark them busy if opened sucessfully. (O_EXCL)
There are kernels which simply don't care about O_EXCL. There are kernels which simply don't care about O_EXCL.
Some have it off, some have it on, some are switchable. Some have it off, some have it on, some are switchable.
2 = in case of a SCSI device, also try to open exclusively 2 = in case of a SCSI device, also try to open exclusively
the matching /dev/sr, /dev/scd and /dev/st . the matching /dev/sr, /dev/scd and /dev/st .
0 = no attempt to make drive access exclusive. 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 @param blocking Try to wait for drives which do not open immediately but
also do not return an error as well. (O_NONBLOCK) also do not return an error as well. (O_NONBLOCK)
This might stall indefinitely with /dev/hdX hard disks. 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. address parameters Host, Channel, Id, Lun and also Bus.
E.g.: "/dev/sg%d" E.g.: "/dev/sg%d"
*/ */
/* NEW INFO: If hard disks at /dev/sr allow ioctl(CDROM_DRIVE_STATUS), they /* sr%d is supposed to map only CD-ROM style devices. Additionally a test
are in danger. with ioctl(CDROM_DRIVE_STATUS) is made to assert that it is such a drive,
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_.
*/ */
/* !!! 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"}; 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 A61115 : this needs mending. A Linux aspect shows up in cdrskin. */
/* ts A60813 : storage objects are in libburn/init.c /* ts A60813 : storage objects are in libburn/init.c
wether to use O_EXCL 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 use O_NOBLOCK with open(2) on devices
wether to take O_EXCL rejection as fatal error */ wether to take O_EXCL rejection as fatal error */
extern int burn_sg_open_o_excl; 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_o_nonblock;
extern int burn_sg_open_abort_busy; extern int burn_sg_open_abort_busy;
@ -188,6 +183,21 @@ int mmc_function_spy(char * text);
/* (Public functions are listed below) */ /* (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) 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", static char tldev[][81]= {"/dev/sr%d", "/dev/scd%d", "/dev/st%d",
"/dev/sg%d", ""}; "/dev/sg%d", ""};
sg_select_device_family();
if (linux_sg_device_family[0] == 0) if (linux_sg_device_family[0] == 0)
return 1; 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; int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
char fname[10]; char fname[10];
sg_select_device_family();
if (linux_sg_enumerate_debug) if (linux_sg_enumerate_debug)
fprintf(stderr, "libburn_debug: linux_sg_device_family = %s\n", fprintf(stderr, "libburn_debug: linux_sg_device_family = %s\n",
linux_sg_device_family); linux_sg_device_family);
@ -520,6 +533,16 @@ static void sg_enumerate(void)
"ioctl(SG_GET_SCSI_ID) failed, errno=%d '%s' , ", "ioctl(SG_GET_SCSI_ID) failed, errno=%d '%s' , ",
errno, strerror(errno)); 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 #ifdef CDROM_DRIVE_STATUS
/* ts A61211 : not widening old acceptance range */ /* ts A61211 : not widening old acceptance range */
if (strcmp(linux_sg_device_family,"/dev/sg%d") != 0) { 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) if (initialize == -1)
return 0; return 0;
sg_select_device_family();
if (linux_sg_device_family[0] == 0) if (linux_sg_device_family[0] == 0)
sg_limit = 0; sg_limit = 0;
if (linux_ata_device_family[0] == 0) if (linux_ata_device_family[0] == 0)