Implemented ddlpa_lock_btl()
This commit is contained in:
parent
218b525c55
commit
359c87956e
@ -185,22 +185,9 @@ static int ddlpa_obtain_scsi_adr(struct ddlpa_lock *o, char *path,
|
|||||||
};
|
};
|
||||||
struct my_scsi_idlun idlun;
|
struct my_scsi_idlun idlun;
|
||||||
|
|
||||||
if (!ddlpa_is_scsi(o, o->std_path))
|
|
||||||
return EFAULT;
|
|
||||||
fd = open(path, open_mode);
|
fd = open(path, open_mode);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return (errno ? errno : EBUSY);
|
return (errno ? errno : EBUSY);
|
||||||
if (!(o->ddlpa_flags & DDLPA_ALLOW_ROGUE_BUSIDLUN)) {
|
|
||||||
ret = ddlpa_fcntl_lock(o, fd, F_RDLCK);
|
|
||||||
if (ret) {
|
|
||||||
if (ddlpa_debug_mode)
|
|
||||||
fprintf(stderr,
|
|
||||||
"DDLPA_DEBUG: fcntl '%s' errno=%d ret=%d\n",
|
|
||||||
path, errno, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus) == -1)
|
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus) == -1)
|
||||||
*bus = -1;
|
*bus = -1;
|
||||||
ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun);
|
ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun);
|
||||||
@ -222,7 +209,6 @@ static int ddlpa_collect_siblings(struct ddlpa_lock *o)
|
|||||||
ino_t path_inode;
|
ino_t path_inode;
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
char *path, try_path[DDLPA_MAX_STD_LEN+1];
|
char *path, try_path[DDLPA_MAX_STD_LEN+1];
|
||||||
int p_bus, p_host, p_channel, p_id, p_lun;
|
|
||||||
int t_bus, t_host, t_channel, t_id, t_lun;
|
int t_bus, t_host, t_channel, t_id, t_lun;
|
||||||
|
|
||||||
if (o->ddlpa_flags & DDLPA_OPEN_GIVEN_PATH)
|
if (o->ddlpa_flags & DDLPA_OPEN_GIVEN_PATH)
|
||||||
@ -242,12 +228,14 @@ static int ddlpa_collect_siblings(struct ddlpa_lock *o)
|
|||||||
o->dev = stbuf.st_dev;
|
o->dev = stbuf.st_dev;
|
||||||
o->ino = stbuf.st_ino;
|
o->ino = stbuf.st_ino;
|
||||||
ret = ddlpa_obtain_scsi_adr(o, path,
|
ret = ddlpa_obtain_scsi_adr(o, path,
|
||||||
&p_bus, &p_host, &p_channel, &p_id, &p_lun);
|
&(o->bus), &(o->host), &(o->channel),
|
||||||
|
&(o->id), &(o->lun));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
o->errmsg = strdup(
|
o->errmsg = strdup(
|
||||||
"Cannot obtain SCSI parameters host,channel,id,lun");
|
"Cannot obtain SCSI parameters host,channel,id,lun");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
o->hcilb_is_valid = 1;
|
||||||
|
|
||||||
while (ddlpa_enumerate(o, &idx, try_path) == 0) {
|
while (ddlpa_enumerate(o, &idx, try_path) == 0) {
|
||||||
if (!ddlpa_is_scsi(o, try_path))
|
if (!ddlpa_is_scsi(o, try_path))
|
||||||
@ -262,8 +250,8 @@ static int ddlpa_collect_siblings(struct ddlpa_lock *o)
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (t_host != p_host || t_channel != p_channel ||
|
if (t_host != o->host || t_channel != o->channel ||
|
||||||
t_id != p_id || t_lun != p_lun)
|
t_id != o->id || t_lun != o->lun)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (o->num_siblings >= DDLPA_MAX_SIBLINGS) {
|
if (o->num_siblings >= DDLPA_MAX_SIBLINGS) {
|
||||||
@ -302,6 +290,42 @@ static int ddlpa_collect_siblings(struct ddlpa_lock *o)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ddlpa_std_by_btl(struct ddlpa_lock *o)
|
||||||
|
{
|
||||||
|
int idx = 0, ret;
|
||||||
|
char try_path[DDLPA_MAX_STD_LEN+1];
|
||||||
|
int t_bus, t_host, t_channel, t_id, t_lun;
|
||||||
|
|
||||||
|
if (!o->inbtl_is_valid)
|
||||||
|
return EFAULT;
|
||||||
|
|
||||||
|
while (ddlpa_enumerate(o, &idx, try_path) == 0) {
|
||||||
|
if (!ddlpa_is_sr(o, try_path))
|
||||||
|
continue;
|
||||||
|
ret = ddlpa_obtain_scsi_adr(o, try_path,
|
||||||
|
&t_bus, &t_host, &t_channel, &t_id, &t_lun);
|
||||||
|
if (ret) {
|
||||||
|
|
||||||
|
/* >>> interpret error, memorize busy, no permission */
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (t_bus != o->in_bus || t_id != o->in_target ||
|
||||||
|
t_lun != o->in_lun)
|
||||||
|
continue;
|
||||||
|
strcpy(o->std_path, try_path);
|
||||||
|
|
||||||
|
if (ddlpa_debug_mode)
|
||||||
|
fprintf(stderr,
|
||||||
|
"DDLPA_DEBUG: ddlpa_std_by_rdev(%d,%d,%d) = \"%s\"\n",
|
||||||
|
t_bus, t_id, t_lun, o->std_path);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ddlpa_open_all(struct ddlpa_lock *o)
|
static int ddlpa_open_all(struct ddlpa_lock *o)
|
||||||
{
|
{
|
||||||
int i, j, ret, no_o_excl;
|
int i, j, ret, no_o_excl;
|
||||||
@ -413,10 +437,33 @@ int ddlpa_lock_btl(int bus, int target, int lun,
|
|||||||
int o_flags, int ddlpa_flags,
|
int o_flags, int ddlpa_flags,
|
||||||
struct ddlpa_lock **lockbundle, char **errmsg)
|
struct ddlpa_lock **lockbundle, char **errmsg)
|
||||||
{
|
{
|
||||||
/* >>> */
|
struct ddlpa_lock *o;
|
||||||
|
int ret;
|
||||||
|
|
||||||
*errmsg = strdup("Function ddlpa_lock_btl() not implemented yet.");
|
*errmsg = NULL;
|
||||||
return ENOSYS;
|
ddlpa_flags &= ~DDLPA_OPEN_GIVEN_PATH;
|
||||||
|
if (ddlpa_new(&o, o_flags, ddlpa_flags))
|
||||||
|
return ENOMEM;
|
||||||
|
*lockbundle = o;
|
||||||
|
|
||||||
|
o->in_bus = bus;
|
||||||
|
o->in_target = target;
|
||||||
|
o->in_lun = lun;
|
||||||
|
o->inbtl_is_valid = 1;
|
||||||
|
ret = ddlpa_std_by_btl(o);
|
||||||
|
if (ret) {
|
||||||
|
*errmsg = strdup(
|
||||||
|
"Cannot find /dev/sr* with given Bus,Target,Lun");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = ddlpa_open_all(o);
|
||||||
|
if (ret) {
|
||||||
|
*errmsg = o->errmsg;
|
||||||
|
o->errmsg = NULL;
|
||||||
|
ddlpa_destroy(&o);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -459,7 +506,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
struct ddlpa_lock *lck = NULL;
|
struct ddlpa_lock *lck = NULL;
|
||||||
char *errmsg = NULL, *opened_path = NULL, *my_path = NULL;
|
char *errmsg = NULL, *opened_path = NULL, *my_path = NULL;
|
||||||
int i, ret, fd = -1, duration = -1;
|
int i, ret, fd = -1, duration = -1, bus = -1, target = -1, lun = -1;
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
usage:;
|
usage:;
|
||||||
@ -471,11 +518,18 @@ usage:;
|
|||||||
if (duration < 0)
|
if (duration < 0)
|
||||||
goto usage;
|
goto usage;
|
||||||
|
|
||||||
/* This substitutes for:
|
if (my_path[0] != '/' && my_path[0] != '.' &&
|
||||||
fd = open(my_path, O_RDWR | O_EXCL);
|
strchr(my_path, ',') != NULL) {
|
||||||
*/
|
/* cdrecord style dev=Bus,Target,Lun */
|
||||||
ret = ddlpa_lock_path(my_path, O_RDWR, DDLPA_ALLOW_ROGUE_BUSIDLUN,
|
sscanf(my_path, "%d,%d,%d", &bus, &target, &lun);
|
||||||
&lck, &errmsg);
|
ret = ddlpa_lock_btl(bus, target, lun, O_RDWR, 0, &lck,
|
||||||
|
&errmsg);
|
||||||
|
} else {
|
||||||
|
/* This substitutes for:
|
||||||
|
fd = open(my_path, O_RDWR | O_EXCL);
|
||||||
|
*/
|
||||||
|
ret = ddlpa_lock_path(my_path, O_RDWR, 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);
|
||||||
if (errmsg != NULL)
|
if (errmsg != NULL)
|
||||||
|
@ -77,11 +77,6 @@ struct ddlpa_lock {
|
|||||||
although not both, a sg and a sr|scd device, have been
|
although not both, a sg and a sr|scd device, have been
|
||||||
found during sibling search. Normally this is counted
|
found during sibling search. Normally this is counted
|
||||||
as failure due to EBUSY.
|
as failure due to EBUSY.
|
||||||
DDLPA_ALLOW_ROGUE_BUSIDLUN allows to perform the ioctls
|
|
||||||
SCSI_IOCTL_GET_BUS_NUMBER and SCSI_IOCTL_GET_IDLUN
|
|
||||||
without prior fcntl lock. This is expected to be
|
|
||||||
harmless. It helps to detect and report drives which
|
|
||||||
are really busy.
|
|
||||||
@param lockbundle gets allocated and then represents the locking state
|
@param lockbundle gets allocated and then represents the locking state
|
||||||
@param errmsg if *errmsg is not NULL after the call, it contains an
|
@param errmsg if *errmsg is not NULL after the call, it contains an
|
||||||
error message. Then to be released by free(3).
|
error message. Then to be released by free(3).
|
||||||
@ -158,7 +153,6 @@ int ddlpa_get_siblings(struct ddlpa_lock *lockbundle,
|
|||||||
|
|
||||||
#define DDLPA_OPEN_GIVEN_PATH 1
|
#define DDLPA_OPEN_GIVEN_PATH 1
|
||||||
#define DDLPA_ALLOW_MISSING_SGRCD 2
|
#define DDLPA_ALLOW_MISSING_SGRCD 2
|
||||||
#define DDLPA_ALLOW_ROGUE_BUSIDLUN 4
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* DDLPA_H_INCLUDED */
|
#endif /* DDLPA_H_INCLUDED */
|
||||||
|
Loading…
Reference in New Issue
Block a user