diff --git a/libburn/trunk/cdrskin/cdrskin.1 b/libburn/trunk/cdrskin/cdrskin.1 index dd2e3c03..4d0c262f 100644 --- a/libburn/trunk/cdrskin/cdrskin.1 +++ b/libburn/trunk/cdrskin/cdrskin.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH CDRSKIN 1 "March 30, 2007" +.TH CDRSKIN 1 "April 03, 2007" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -732,6 +732,13 @@ Linux specific: Try to wait for a busy drive to become free. This is not guaranteed to work with all drivers. Some need nonblocking i/o. .TP .BI \--drive_not_exclusive +Linux specific: Combine --drive_not_f_setlk and --drive_not_o_excl. +.TP +.BI \--drive_not_f_setlk +Linux specific: Do not try to get exclusive lock on drive device file via +fcntl(2). +.TP +.BI \--drive_not_o_excl 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. .TP diff --git a/libburn/trunk/cdrskin/cdrskin.c b/libburn/trunk/cdrskin/cdrskin.c index dff42f8e..b2a0ed08 100644 --- a/libburn/trunk/cdrskin/cdrskin.c +++ b/libburn/trunk/cdrskin/cdrskin.c @@ -1565,6 +1565,9 @@ struct CdrpreskiN { /** Linux specific : Wether to try to avoid collisions when opening drives */ int drive_exclusive; + /** Linux specific : Wether to obtain an exclusive drive lock via fcntl() */ + int drive_fcntl_f_setlk; + /** Linux specific : Device file address family to use : 0=default , 1=sr , 2=scd , 4=sg */ int drive_scsi_dev_family; @@ -1630,6 +1633,7 @@ int Cdrpreskin_new(struct CdrpreskiN **preskin, int flag) o->scan_demands_drive= 0; o->abort_on_busy_drive= 0; o->drive_exclusive= 1; + o->drive_fcntl_f_setlk= 1; o->drive_scsi_dev_family= 0; o->drive_blocking= 0; strcpy(o->write_mode_name,"DEFAULT"); @@ -2099,6 +2103,13 @@ set_dev:; } else if(strcmp(argv[i],"--drive_not_exclusive")==0) { o->drive_exclusive= 0; + o->drive_fcntl_f_setlk= 0; + + } else if(strcmp(argv[i],"--drive_not_f_setlk")==0) { + o->drive_fcntl_f_setlk= 0; + + } else if(strcmp(argv[i],"--drive_not_o_excl")==0) { + o->drive_exclusive= 0; } else if(strncmp(argv[i],"drive_scsi_dev_family=",22)==0) { value_pt= argv[i]+22; @@ -2161,7 +2172,9 @@ set_dev:; printf(" (might be triggered by a busy hard disk)\n"); printf(" --drive_blocking try to wait for busy drive to become free\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 combined not_o_excl and not_f_setlk.\n"); + printf(" --drive_not_f_setlk do not obtain exclusive lock via fcntl.\n"); + printf(" --drive_not_o_excl do not ask kernel to prevent opening\n"); printf(" busy drives. Effect is kernel dependend.\n"); printf( " drive_scsi_dev_family= select Linux device\n"); @@ -2400,6 +2413,7 @@ final_checks:; burn_preset_device_open(o->drive_exclusive #ifdef Cdrskin_libburn_preset_device_familY | (o->drive_scsi_dev_family<<2) + | ((!!o->drive_fcntl_f_setlk)<<5) #endif , o->drive_blocking, @@ -5908,7 +5922,9 @@ set_blank:; } else if(strcmp(argv[i],"--drive_blocking")==0) { /* is handled in Cdrpreskin_setup() */; - } else if(strcmp(argv[i],"--drive_not_exclusive")==0) { + } else if(strcmp(argv[i],"--drive_not_exclusive")==0 || + strcmp(argv[i],"--drive_not_f_setlk")==0 || + strcmp(argv[i],"--drive_not_o_excl")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strncmp(argv[i],"drive_scsi_dev_family=",22)==0) { diff --git a/libburn/trunk/cdrskin/cdrskin_timestamp.h b/libburn/trunk/cdrskin/cdrskin_timestamp.h index 9cde6a30..fc5dccf4 100644 --- a/libburn/trunk/cdrskin/cdrskin_timestamp.h +++ b/libburn/trunk/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2007.04.03.145806" +#define Cdrskin_timestamP "2007.04.04.184341" diff --git a/libburn/trunk/libburn/init.c b/libburn/trunk/libburn/init.c index 25570c23..5b72b1f2 100644 --- a/libburn/trunk/libburn/init.c +++ b/libburn/trunk/libburn/init.c @@ -26,9 +26,13 @@ struct libdax_msgs *libdax_messenger= NULL; int burn_running = 0; -/* ts A60813 : Linux: wether to use O_EXCL and/or O_NONBLOCK in libburn/sg.c */ +/* ts A60813 : Linux: wether to use O_EXCL on open() of device files */ int burn_sg_open_o_excl = 1; +/* ts A70403 : Linux: wether to use fcntl(,F_SETLK,) + after open() of device files */ +int burn_sg_fcntl_f_setlk = 1; + /* ts A70314 : Linux: what device family to use : 0= default family 1= sr @@ -128,11 +132,11 @@ void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy) /* a ssert(burn_running); */ if (!burn_running) return; - - 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; + burn_sg_open_o_excl = exclusive & 3; + burn_sg_fcntl_f_setlk = !!(exclusive & 32); + burn_sg_use_family = (exclusive >> 2) & 15; + burn_sg_open_o_nonblock = !blocking; + burn_sg_open_abort_busy = !!abort_on_busy; } diff --git a/libburn/trunk/libburn/libburn.h b/libburn/trunk/libburn/libburn.h index c416ef27..ebae0958 100644 --- a/libburn/trunk/libburn/libburn.h +++ b/libburn/trunk/libburn/libburn.h @@ -586,6 +586,8 @@ void burn_set_verbosity(int level); 8 = /dev/scd%d 16 = /dev/sg%d Do not use other values ! + Add 32 to demand an exclusive lock by fcntl(,F_SETLK,) + after open() has succeeded. @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. @@ -772,8 +774,8 @@ int burn_drive_grab(struct burn_drive *drive, int load); /** Release a drive. This should not be done until the drive is no longer - busy (see burn_drive_get_status). The drive is (O_EXCL) unlocked - afterwards. + busy (see burn_drive_get_status). + Linux: The drive is unlocked afterwards. (O_EXCL , F_SETLK). @param drive The drive to release. @param eject Nonzero to make the drive eject the disc in it. */ diff --git a/libburn/trunk/libburn/sg-linux.c b/libburn/trunk/libburn/sg-linux.c index c088664a..feae9a15 100644 --- a/libburn/trunk/libburn/sg-linux.c +++ b/libburn/trunk/libburn/sg-linux.c @@ -171,11 +171,13 @@ 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 + wether to use O_EXCL with open(2) of devices + wether to use fcntl(,F_SETLK,) after open(2) of devices 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_fcntl_f_setlk; extern int burn_sg_use_family; extern int burn_sg_open_o_nonblock; extern int burn_sg_open_abort_busy; @@ -304,14 +306,13 @@ static int sg_close_drive_fd(char *fname, int driveno, int *fd, int sorry) */ int sg_fcntl_lock(int *fd, char *fd_name) { - -#define Libburn_sg_with_fcntl_locK 1 -#ifdef Libburn_sg_with_fcntl_locK - struct flock lockthing; char msg[81]; int ret; + if (!burn_sg_fcntl_f_setlk) + return 1; + memset(&lockthing, 0, sizeof(lockthing)); lockthing.l_type = F_WRLCK; lockthing.l_whence = SEEK_SET; @@ -330,9 +331,7 @@ int sg_fcntl_lock(int *fd, char *fd_name) *fd = -1; return(0); } - -#endif /* Libburn_sg_with_fcntl_locK */ - return(1); + return 1; }