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;
|
||||
|
||||
if (!ddlpa_is_scsi(o, o->std_path))
|
||||
return EFAULT;
|
||||
fd = open(path, open_mode);
|
||||
if (fd == -1)
|
||||
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)
|
||||
*bus = -1;
|
||||
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;
|
||||
struct stat stbuf;
|
||||
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;
|
||||
|
||||
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->ino = stbuf.st_ino;
|
||||
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) {
|
||||
o->errmsg = strdup(
|
||||
"Cannot obtain SCSI parameters host,channel,id,lun");
|
||||
return ret;
|
||||
}
|
||||
o->hcilb_is_valid = 1;
|
||||
|
||||
while (ddlpa_enumerate(o, &idx, try_path) == 0) {
|
||||
if (!ddlpa_is_scsi(o, try_path))
|
||||
@ -262,8 +250,8 @@ static int ddlpa_collect_siblings(struct ddlpa_lock *o)
|
||||
|
||||
continue;
|
||||
}
|
||||
if (t_host != p_host || t_channel != p_channel ||
|
||||
t_id != p_id || t_lun != p_lun)
|
||||
if (t_host != o->host || t_channel != o->channel ||
|
||||
t_id != o->id || t_lun != o->lun)
|
||||
continue;
|
||||
|
||||
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)
|
||||
{
|
||||
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,
|
||||
struct ddlpa_lock **lockbundle, char **errmsg)
|
||||
{
|
||||
/* >>> */
|
||||
struct ddlpa_lock *o;
|
||||
int ret;
|
||||
|
||||
*errmsg = strdup("Function ddlpa_lock_btl() not implemented yet.");
|
||||
return ENOSYS;
|
||||
*errmsg = NULL;
|
||||
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;
|
||||
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) {
|
||||
usage:;
|
||||
@ -471,11 +518,18 @@ usage:;
|
||||
if (duration < 0)
|
||||
goto usage;
|
||||
|
||||
if (my_path[0] != '/' && my_path[0] != '.' &&
|
||||
strchr(my_path, ',') != NULL) {
|
||||
/* cdrecord style dev=Bus,Target,Lun */
|
||||
sscanf(my_path, "%d,%d,%d", &bus, &target, &lun);
|
||||
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, DDLPA_ALLOW_ROGUE_BUSIDLUN,
|
||||
&lck, &errmsg);
|
||||
ret = ddlpa_lock_path(my_path, O_RDWR, 0, &lck, &errmsg);
|
||||
}
|
||||
if (ret) {
|
||||
fprintf(stderr, "Cannot exclusively open '%s'\n", my_path);
|
||||
if (errmsg != NULL)
|
||||
|
@ -77,11 +77,6 @@ struct ddlpa_lock {
|
||||
although not both, a sg and a sr|scd device, have been
|
||||
found during sibling search. Normally this is counted
|
||||
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 errmsg if *errmsg is not NULL after the call, it contains an
|
||||
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_ALLOW_MISSING_SGRCD 2
|
||||
#define DDLPA_ALLOW_ROGUE_BUSIDLUN 4
|
||||
|
||||
|
||||
#endif /* DDLPA_H_INCLUDED */
|
||||
|
Loading…
Reference in New Issue
Block a user