Progress due to tests with test/open-cd-excl

This commit is contained in:
Thomas Schmitt 2007-04-18 10:35:38 +00:00
parent bf335978f8
commit 52a66bff95
2 changed files with 56 additions and 14 deletions

View File

@ -3,6 +3,23 @@
Implementation of Delicate Device Locking Protocol level A. Implementation of Delicate Device Locking Protocol level A.
Copyright (C) 2007 Thomas Schmitt <scdbackup@gmx.net> Copyright (C) 2007 Thomas Schmitt <scdbackup@gmx.net>
Provided under any of the following licenses: GPL, LGPL, BSD. Choose one. Provided under any of the following licenses: GPL, LGPL, BSD. Choose one.
Compile as test program:
cc -g -Wall \
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE \
-DDDLPA_C_STANDALONE -o ddlpa ddlpa.c
The system macros are needed for 8-bit off_t and for open flag O_LARGEFILE
which are not absolutely necessary but explicitely take into respect that
our devices can offer more than 2 GB of addressable data.
Run test program:
./ddlpa /dev/sr0 15
./ddlpa 0,0,0 15
*/ */
#include <stdio.h> #include <stdio.h>
@ -91,7 +108,7 @@ static int ddlpa_std_by_rdev(struct ddlpa_lock *o)
if (ddlpa_debug_mode) if (ddlpa_debug_mode)
fprintf(stderr, fprintf(stderr,
"DDLPA_DEBUG: ddlpa_std_by_rdev(\"%s\") = \"%s\"\n", "DDLPA_DEBUG: ddlpa_std_by_rdev(\"%s\") = \"%s\"\n",
o->path, o->std_path); o->path, o->std_path);
return 0; return 0;
@ -143,20 +160,32 @@ static int ddlpa_fcntl_lock(struct ddlpa_lock *o, int fd, int l_type)
static int ddlpa_occupy(struct ddlpa_lock *o, char *path, int *fd, static int ddlpa_occupy(struct ddlpa_lock *o, char *path, int *fd,
int no_o_excl) int no_o_excl)
{ {
int ret, o_flags = O_RDWR | O_NDELAY; int ret, o_flags, o_rw, l_type;
char *o_rwtext;
o_flags = o->o_flags | O_NDELAY;
if(!no_o_excl) if(!no_o_excl)
o_flags |= O_EXCL; o_flags |= O_EXCL;
o_rw = (o_flags) & (O_RDONLY | O_WRONLY | O_RDWR);
o_rwtext = (o_rw == O_RDONLY ? "O_RDONLY" :
(o_rw == O_WRONLY ? "O_WRONLY" :
(o_rw == O_RDWR ? "O_RDWR " : "O_?rw-mode?")));
*fd = open(path, o_flags); *fd = open(path, o_flags);
if (*fd == -1) { if (*fd == -1) {
o->errmsg = malloc(strlen(path)+160); o->errmsg = malloc(strlen(path)+160);
if (o->errmsg) if (o->errmsg)
sprintf(o->errmsg, sprintf(o->errmsg,
"Failed to open O_RDWR | O_NDELAY %s: '%s'", "Failed to open %s | O_NDELAY %s: '%s'",
(no_o_excl ? "" : "| O_EXCL "), path); o_rwtext,
(o_flags & O_EXCL ? "| O_EXCL " : ""), path);
return (errno ? errno : EBUSY); return (errno ? errno : EBUSY);
} }
ret = ddlpa_fcntl_lock(o, *fd, F_WRLCK); if (o_rw == O_RDWR || o_rw == O_WRONLY)
l_type = F_WRLCK;
else
l_type = F_RDLCK;
ret = ddlpa_fcntl_lock(o, *fd, l_type);
if (ret) { if (ret) {
o->errmsg = malloc(strlen(path)+160); o->errmsg = malloc(strlen(path)+160);
if (o->errmsg) if (o->errmsg)
@ -167,7 +196,8 @@ static int ddlpa_occupy(struct ddlpa_lock *o, char *path, int *fd,
return ret; return ret;
} }
if (ddlpa_debug_mode) if (ddlpa_debug_mode)
fprintf(stderr, "DDLPA_DEBUG: ddlpa_occupy() %s: '%s'\n", fprintf(stderr, "DDLPA_DEBUG: ddlpa_occupy() %s %s: '%s'\n",
o_rwtext,
(no_o_excl ? " " : "O_EXCL "), path); (no_o_excl ? " " : "O_EXCL "), path);
return 0; return 0;
} }
@ -270,7 +300,7 @@ static int ddlpa_collect_siblings(struct ddlpa_lock *o)
if (ddlpa_debug_mode) if (ddlpa_debug_mode)
fprintf(stderr, fprintf(stderr,
"DDLPA_DEBUG: ddlpa_collect_siblings() found \"%s\"\n", "DDLPA_DEBUG: ddlpa_collect_siblings() found \"%s\"\n",
try_path); try_path);
(o->num_siblings)++; (o->num_siblings)++;
@ -315,7 +345,7 @@ static int ddlpa_std_by_btl(struct ddlpa_lock *o)
if (ddlpa_debug_mode) if (ddlpa_debug_mode)
fprintf(stderr, fprintf(stderr,
"DDLPA_DEBUG: ddlpa_std_by_rdev(%d,%d,%d) = \"%s\"\n", "DDLPA_DEBUG: ddlpa_std_by_btl(%d,%d,%d) = \"%s\"\n",
t_bus, t_id, t_lun, o->std_path); t_bus, t_id, t_lun, o->std_path);
return 0; return 0;
@ -490,6 +520,14 @@ usage:;
if (duration < 0) if (duration < 0)
goto usage; goto usage;
/* For our purpose, only O_RDWR is a suitable access mode.
But in order to allow experiments, o_flags are freely adjustable.
Warning: Do _not_ set an own O_EXCL flag with the following calls !
(This freedom to fail may get removed in a final version.)
*/
if (my_path[0] != '/' && my_path[0] != '.' && if (my_path[0] != '/' && my_path[0] != '.' &&
strchr(my_path, ',') != NULL) { strchr(my_path, ',') != NULL) {
/* /*
@ -497,15 +535,17 @@ usage:;
*/ */
sscanf(my_path, "%d,%d,%d", &bus, &target, &lun); sscanf(my_path, "%d,%d,%d", &bus, &target, &lun);
ret = ddlpa_lock_btl(bus, target, lun, O_RDWR, 0, &lck, ret = ddlpa_lock_btl(bus, target, lun, O_RDWR | O_LARGEFILE,
&errmsg); 0, &lck, &errmsg);
} else { } else {
/* /*
This substitutes for: This substitutes for:
fd = open(my_path, O_RDWR | O_EXCL); fd = open(my_path, O_RDWR | O_EXCL | O_LARGEFILE);
*/ */
ret = ddlpa_lock_path(my_path, O_RDWR, 0, &lck, &errmsg); ret = ddlpa_lock_path(my_path, O_RDWR | O_LARGEFILE,
0, &lck, &errmsg);
} }
if (ret) { if (ret) {
fprintf(stderr, "Cannot exclusively open '%s'\n", my_path); fprintf(stderr, "Cannot exclusively open '%s'\n", my_path);

View File

@ -51,7 +51,9 @@ struct ddlpa_lock {
/** Lock a recorder by naming a device file path. Allocate a new container. /** Lock a recorder by naming a device file path. Allocate a new container.
@param path Gives the file system path of the recorder @param path Gives the file system path of the recorder
as known to the calling program. as known to the calling program.
@param o_flags flags for open(2) @param o_flags flags for open(2). Do not use O_EXCL here because this
is done automatically whenever appropriate.
Advised is O_RDWR | O_LARGEFILE, eventually | O_NDELAY.
@param ddlpa_flags 0 = default behavior: the standard path will be opened @param ddlpa_flags 0 = default behavior: the standard path will be opened
and treated by fcntl(F_SETLK) and treated by fcntl(F_SETLK)
DDLPA_OPEN_GIVEN_PATH causes the input parameter "path" DDLPA_OPEN_GIVEN_PATH causes the input parameter "path"
@ -75,7 +77,7 @@ int ddlpa_lock_path(char *path, int o_flags, int ddlpa_flags,
@param bus parameter to match ioctl(SCSI_IOCTL_GET_BUS_NUMBER) @param bus parameter to match ioctl(SCSI_IOCTL_GET_BUS_NUMBER)
@param target parameter to match ioctl(SCSI_IOCTL_GET_IDLUN) &0xff @param target parameter to match ioctl(SCSI_IOCTL_GET_IDLUN) &0xff
@param lun parameter to match ioctl(SCSI_IOCTL_GET_IDLUN) &0xff00 @param lun parameter to match ioctl(SCSI_IOCTL_GET_IDLUN) &0xff00
@param o_flags flags for open(2) @param o_flags see ddlpa_lock_path().
@param ddlpa_flags see ddlpa_lock_path(). Flag DDLPA_OPEN_GIVEN_PATH @param ddlpa_flags see ddlpa_lock_path(). Flag DDLPA_OPEN_GIVEN_PATH
will be ignored. will be ignored.
@param lockbundle see ddlpa_lock_path(). @param lockbundle see ddlpa_lock_path().