Making use of new libcdio capability to obtain SCSI address tuple on Linux
This commit is contained in:
parent
509db68d82
commit
12a2be8d86
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2009.12.29.224506"
|
#define Cdrskin_timestamP "2009.12.30.154140"
|
||||||
|
@ -1560,14 +1560,23 @@ int burn_drive_is_enumerable_adr(char *adr)
|
|||||||
#define BURN_DRIVE_MAX_LINK_DEPTH 20
|
#define BURN_DRIVE_MAX_LINK_DEPTH 20
|
||||||
|
|
||||||
/* ts A60922 ticket 33 */
|
/* ts A60922 ticket 33 */
|
||||||
int burn_drive_resolve_link(char *path, char adr[], int *recursion_count)
|
/* @param flag bit0= no debug messages
|
||||||
|
bit1= resolve only links,
|
||||||
|
do not rely on drive list for resolving via st_rdev
|
||||||
|
*/
|
||||||
|
int burn_drive_resolve_link(char *path, char adr[], int *recursion_count,
|
||||||
|
int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char link_target[4096], msg[4096+100], link_adr[4096], *adrpt;
|
char link_target[4096], msg[4096+100], link_adr[4096], *adrpt;
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )", path);
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )",
|
||||||
|
path);
|
||||||
if (*recursion_count >= BURN_DRIVE_MAX_LINK_DEPTH) {
|
if (*recursion_count >= BURN_DRIVE_MAX_LINK_DEPTH) {
|
||||||
burn_drive_adr_debug_msg(
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg(
|
||||||
"burn_drive_resolve_link aborts because link too deep",
|
"burn_drive_resolve_link aborts because link too deep",
|
||||||
NULL);
|
NULL);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1575,12 +1584,15 @@ int burn_drive_resolve_link(char *path, char adr[], int *recursion_count)
|
|||||||
(*recursion_count)++;
|
(*recursion_count)++;
|
||||||
ret = readlink(path, link_target, sizeof(link_target));
|
ret = readlink(path, link_target, sizeof(link_target));
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
burn_drive_adr_debug_msg("readlink( %s ) returns -1", path);
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg("readlink( %s ) returns -1",
|
||||||
|
path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ret >= sizeof(link_target) - 1) {
|
if (ret >= sizeof(link_target) - 1) {
|
||||||
sprintf(msg,"readlink( %s ) returns %d (too much)", path, ret);
|
sprintf(msg,"readlink( %s ) returns %d (too much)", path, ret);
|
||||||
burn_drive_adr_debug_msg(msg, NULL);
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg(msg, NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
link_target[ret] = 0;
|
link_target[ret] = 0;
|
||||||
@ -1593,10 +1605,25 @@ int burn_drive_resolve_link(char *path, char adr[], int *recursion_count)
|
|||||||
} else
|
} else
|
||||||
adrpt = link_target;
|
adrpt = link_target;
|
||||||
}
|
}
|
||||||
ret = burn_drive_convert_fs_adr_sub(adrpt, adr, recursion_count);
|
if (flag & 2) {
|
||||||
sprintf(msg,"burn_drive_convert_fs_adr( %s ) returns %d",
|
/* Link-only recursion */
|
||||||
link_target, ret);
|
if (lstat(adrpt, &stbuf) == -1) {
|
||||||
burn_drive_adr_debug_msg(msg, NULL);
|
;
|
||||||
|
} else if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
|
||||||
|
ret = burn_drive_resolve_link(adrpt, adr,
|
||||||
|
recursion_count, flag);
|
||||||
|
} else {
|
||||||
|
strcpy(adr, adrpt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Link and device number recursion */
|
||||||
|
ret = burn_drive_convert_fs_adr_sub(adrpt, adr,
|
||||||
|
recursion_count);
|
||||||
|
sprintf(msg,"burn_drive_convert_fs_adr( %s ) returns %d",
|
||||||
|
link_target, ret);
|
||||||
|
}
|
||||||
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg(msg, NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1770,7 +1797,7 @@ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
|
if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
|
||||||
ret = burn_drive_resolve_link(path, adr, rec_count);
|
ret = burn_drive_resolve_link(path, adr, rec_count, 0);
|
||||||
if(ret > 0)
|
if(ret > 0)
|
||||||
return 1;
|
return 1;
|
||||||
burn_drive_adr_debug_msg("link fallback via stat( %s )", path);
|
burn_drive_adr_debug_msg("link fallback via stat( %s )", path);
|
||||||
|
@ -131,7 +131,8 @@ extern struct libdax_msgs *libdax_messenger;
|
|||||||
|
|
||||||
/* is in portable part of libburn */
|
/* is in portable part of libburn */
|
||||||
int burn_drive_is_banned(char *device_address);
|
int burn_drive_is_banned(char *device_address);
|
||||||
|
int burn_drive_resolve_link(char *path, char adr[],
|
||||||
|
int *recursion_count, int flag); /* drive.c */
|
||||||
|
|
||||||
/* Whether to log SCSI commands:
|
/* Whether to log SCSI commands:
|
||||||
bit0= log in /tmp/libburn_sg_command_log
|
bit0= log in /tmp/libburn_sg_command_log
|
||||||
@ -175,11 +176,21 @@ static int sg_close_drive(struct burn_drive * d)
|
|||||||
static int sg_give_next_adr_raw(burn_drive_enumerator_t *idx,
|
static int sg_give_next_adr_raw(burn_drive_enumerator_t *idx,
|
||||||
char adr[], int adr_size, int initialize)
|
char adr[], int adr_size, int initialize)
|
||||||
{
|
{
|
||||||
|
char **pos;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
if (initialize == 1) {
|
if (initialize == 1) {
|
||||||
idx->pos = idx->ppsz_cd_drives =
|
idx->pos = idx->ppsz_cd_drives =
|
||||||
cdio_get_devices(DRIVER_DEVICE);
|
cdio_get_devices(DRIVER_DEVICE);
|
||||||
if (idx->ppsz_cd_drives == NULL)
|
if (idx->ppsz_cd_drives == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
for (pos = idx->ppsz_cd_drives ; pos != NULL; pos++) {
|
||||||
|
if (*pos == NULL)
|
||||||
|
break;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (initialize == -1) {
|
} else if (initialize == -1) {
|
||||||
if (*(idx->ppsz_cd_drives) != NULL)
|
if (*(idx->ppsz_cd_drives) != NULL)
|
||||||
cdio_free_device_list(idx->ppsz_cd_drives);
|
cdio_free_device_list(idx->ppsz_cd_drives);
|
||||||
@ -197,47 +208,6 @@ static int sg_give_next_adr_raw(burn_drive_enumerator_t *idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Resolve eventual softlink, E.g. /dev/cdrom . */
|
|
||||||
static int sg_resolve_link(char *in_path, char target[], int target_size,
|
|
||||||
int flag)
|
|
||||||
{
|
|
||||||
int i, max_link_depth = 100, ret;
|
|
||||||
char path[4096], link_target[4096];
|
|
||||||
struct stat stbuf;
|
|
||||||
|
|
||||||
if (strlen(in_path) >= sizeof(path)) {
|
|
||||||
if (strlen(in_path) >= target_size)
|
|
||||||
return -1;
|
|
||||||
strcpy(target, path);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
strcpy(path, in_path);
|
|
||||||
|
|
||||||
/* (burn_drive_resolve_link() relies on a completed drive list and
|
|
||||||
cannot be used here) */
|
|
||||||
for (i= 0; i < max_link_depth; i++) {
|
|
||||||
if (lstat(path, &stbuf) == -1) {
|
|
||||||
strcpy(path, in_path);
|
|
||||||
break; /* dead link */
|
|
||||||
}
|
|
||||||
if ((stbuf.st_mode & S_IFMT) != S_IFLNK)
|
|
||||||
break; /* found target */
|
|
||||||
ret = readlink(path, link_target, sizeof(link_target));
|
|
||||||
if (ret == -1) {
|
|
||||||
strcpy(path, in_path);
|
|
||||||
break; /* unreadable link pointer */
|
|
||||||
}
|
|
||||||
strcpy(path, link_target);
|
|
||||||
}
|
|
||||||
if (i >= max_link_depth) /* endless link loop */
|
|
||||||
strcpy(path, in_path);
|
|
||||||
if (strlen(path) >= target_size)
|
|
||||||
return -1;
|
|
||||||
strcpy(target, path);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
/* PORTING: Private functions which contain publicly needed functionality. */
|
/* PORTING: Private functions which contain publicly needed functionality. */
|
||||||
/* Their portable part must be performed. So it is probably best */
|
/* Their portable part must be performed. So it is probably best */
|
||||||
@ -399,7 +369,7 @@ int sg_dispose_drive(struct burn_drive *d, int flag)
|
|||||||
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||||
char adr[], int adr_size, int initialize)
|
char adr[], int adr_size, int initialize)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, recursion_count = 0;
|
||||||
char path[4096];
|
char path[4096];
|
||||||
|
|
||||||
ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
|
ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
|
||||||
@ -408,8 +378,8 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
if (strlen(adr) >= sizeof(path))
|
if (strlen(adr) >= sizeof(path))
|
||||||
return ret;
|
return ret;
|
||||||
strcpy(path, adr);
|
strcpy(path, adr);
|
||||||
ret = sg_resolve_link(path, adr, adr_size, 0);
|
ret = burn_drive_resolve_link(path, adr, &recursion_count, 2);
|
||||||
return ret;
|
return (ret >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -419,7 +389,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
int scsi_enumerate_drives(void)
|
int scsi_enumerate_drives(void)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1, ret, i_bus_no = -1;
|
int initialize = 1, ret, i_bus_no = -1, recursion_count = 0;
|
||||||
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
|
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
|
||||||
char buf[4096], target[4096];
|
char buf[4096], target[4096];
|
||||||
|
|
||||||
@ -428,7 +398,7 @@ int scsi_enumerate_drives(void)
|
|||||||
initialize = 0;
|
initialize = 0;
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
break;
|
break;
|
||||||
ret = sg_resolve_link(buf, target, sizeof(target), 0);
|
ret = burn_drive_resolve_link(buf, target, &recursion_count,2);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
strcpy(target, buf);
|
strcpy(target, buf);
|
||||||
if (burn_drive_is_banned(target))
|
if (burn_drive_is_banned(target))
|
||||||
@ -653,11 +623,24 @@ ex:;
|
|||||||
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
int *target_no, int *lun_no)
|
int *target_no, int *lun_no)
|
||||||
{
|
{
|
||||||
|
CdIo_t *p_cdio;
|
||||||
/* >>> any chance to get them from libcdio ? */;
|
char *tuple;
|
||||||
|
|
||||||
*bus_no = *host_no = *channel_no = *target_no = *lun_no = -1;
|
*bus_no = *host_no = *channel_no = *target_no = *lun_no = -1;
|
||||||
return (0);
|
|
||||||
|
p_cdio = cdio_open(path, DRIVER_DEVICE);
|
||||||
|
if (p_cdio == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Try whether a Linux address tuple is available */
|
||||||
|
tuple = (char *) cdio_get_arg(p_cdio, "scsi-tuple-linux");
|
||||||
|
if (tuple != NULL) if (tuple[0]) {
|
||||||
|
sscanf(tuple, "%d,%d,%d,%d,%d",
|
||||||
|
bus_no, host_no, channel_no, target_no, lun_no);
|
||||||
|
}
|
||||||
|
|
||||||
|
cdio_destroy(p_cdio);
|
||||||
|
return (*bus_no >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user