cam_get_device, cam_open_device: make behavior simpler and more deterministic

Remove or re-work support for the several features from the past:
- remove incomplete support for trimming slice/partition names
- remove mapping from old device names "sd" and "st"
- remove whitespace trimming
- remove unconditional skipping of leading 'r' in a device name
- skip leading 'n' or 'e' only if the following device name matches
  a list of known devices that support no-rewind and eject-on-close
  features; currently this is only sa(4)
- reflect the above changes in comments in code and in cam(3)
- remove a note cautioning against use of cam_get_device and
  cam_open_device in cam(3)

Reviewed by:	mjacob
This commit is contained in:
avg 2010-10-11 09:27:37 +00:00
parent a439b16971
commit 2c6068194e
2 changed files with 21 additions and 97 deletions

View File

@ -190,12 +190,6 @@ into a device name and unit number.
Once the device name and unit number
are determined, a lookup is performed to determine the passthrough device
that corresponds to the given device.
.Fn cam_open_device
is rather simple to use, but it is not really suitable for general use
because its behavior is not necessarily deterministic.
Programmers writing
new applications should make the extra effort to use one of the other open
routines documented below.
.Pp
.Fn cam_open_spec_device
opens the
@ -354,19 +348,15 @@ respectively.
can handle strings of the following forms, at least:
.Pp
.Bl -tag -width 1234 -compact
.It /dev/foo0a
.It /dev/foo1s2c
.It /dev/foo1
.It foo0
.It foo0a
.It nfoo0
.It nsa2
.El
.Pp
.Fn cam_get_device
is provided as a convenience function for applications that need to provide
functionality similar to
.Fn cam_open_device .
Programmers are encouraged to use more deterministic methods of obtaining
device names and unit numbers if possible.
.Sh RETURN VALUES
.Fn cam_open_device ,
.Fn cam_open_spec_device ,

View File

@ -42,14 +42,9 @@ __FBSDID("$FreeBSD$");
#include <cam/scsi/scsi_pass.h>
#include "camlib.h"
struct cam_devequiv {
char *given_dev;
char *real_dev;
};
struct cam_devequiv devmatchtable[] = {
{"sd", "da"},
{"st", "sa"}
static const char *nonrewind_devs[] = {
"sa"
};
char cam_errbuf[CAM_ERRBUF_SIZE];
@ -103,19 +98,14 @@ cam_freeccb(union ccb *ccb)
/*
* Take a device name or path passed in by the user, and attempt to figure
* out the device name and unit number. Some possible device name formats are:
* /dev/foo0a
* /dev/rfoo0a
* /dev/rfoos2c
* /dev/foo0
* foo0
* foo0a
* rfoo0
* rfoo0a
* nrfoo0
*
* If the caller passes in an old style device name like 'sd' or 'st',
* it will be converted to the new style device name based upon devmatchtable
* above.
* nfoo0
*
* Some peripheral drivers create separate device nodes with 'n' prefix for
* non-rewind operations. Currently only sa(4) tape driver has this feature.
* We extract pure peripheral name as device name for this special case.
*
* Input parameters: device name/path, length of devname string
* Output: device name, unit number
* Return values: returns 0 for success, -1 for failure
@ -127,7 +117,7 @@ cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
char *tmpstr, *tmpstr2;
char *newpath;
int unit_offset;
int i, found = 0;
int i;
if (path == NULL) {
@ -142,10 +132,6 @@ cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
newpath = (char *)strdup(path);
tmpstr = newpath;
/* Get rid of any leading white space */
while (isspace(*tmpstr) && (*tmpstr != '\0'))
tmpstr++;
/*
* Check to see whether we have an absolute pathname.
*/
@ -166,54 +152,15 @@ cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
* Check to see whether the user has given us a nonrewound tape
* device.
*/
if (*tmpstr == 'n')
tmpstr++;
if (*tmpstr == '\0') {
sprintf(cam_errbuf, "%s: no text after leading 'n'", func_name);
free(newpath);
return(-1);
}
/*
* See if the user has given us a character device.
*/
if (*tmpstr == 'r')
tmpstr++;
if (*tmpstr == '\0') {
sprintf(cam_errbuf, "%s: no text after leading 'r'", func_name);
free(newpath);
return(-1);
}
/*
* Try to get rid of any trailing white space or partition letters.
*/
tmpstr2 = &tmpstr[strlen(tmpstr) - 1];
while ((*tmpstr2 != '\0') && (tmpstr2 > tmpstr) &&(!isdigit(*tmpstr2))){
*tmpstr2 = '\0';
tmpstr2--;
}
/*
* Check to see whether we have been given a partition with a slice
* name. If so, get rid of the slice name/number.
*/
if (strlen(tmpstr) > 3) {
/*
* Basically, we're looking for a string that ends in the
* following general manner: 1s1 -- a number, the letter
* s, and then another number. This indicates that the
* user has given us a slice. We substitute nulls for the
* s and the slice number.
*/
if ((isdigit(tmpstr[strlen(tmpstr) - 1]))
&& (tmpstr[strlen(tmpstr) - 2] == 's')
&& (isdigit(tmpstr[strlen(tmpstr) - 3]))) {
tmpstr[strlen(tmpstr) - 1] = '\0';
tmpstr[strlen(tmpstr) - 1] = '\0';
if (*tmpstr == 'n' || *tmpstr == 'e') {
for (i = 0; i < sizeof(nonrewind_devs)/sizeof(char *); i++) {
int len = strlen(nonrewind_devs[i]);
if (strncmp(tmpstr + 1, nonrewind_devs[i], len) == 0) {
if (isdigit(tmpstr[len + 1])) {
tmpstr++;
break;
}
}
}
}
@ -281,20 +228,7 @@ cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
*/
tmpstr[strlen(tmpstr) - unit_offset] = '\0';
/*
* Look through our equivalency table and see if the device name
* the user gave us is an old style device name. If so, translate
* it to the new style device name.
*/
for (i = 0;i < (sizeof(devmatchtable)/sizeof(struct cam_devequiv));i++){
if (strcmp(tmpstr, devmatchtable[i].given_dev) == 0) {
strlcpy(dev_name,devmatchtable[i].real_dev, devnamelen);
found = 1;
break;
}
}
if (found == 0)
strlcpy(dev_name, tmpstr, devnamelen);
strlcpy(dev_name, tmpstr, devnamelen);
/* Clean up allocated memory */
free(newpath);