Skip to Main Content

Infrastructure Software

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Solaris 9: USCSICMD ioctl on volume management devices fails

807567Oct 15 2002 — edited Jul 25 2007
Upto and including Solaris 8, it was possible to use the USCSICMD
ioctl on devices managed by the vold daemon (e.g. the CDROM device,
/vol/dev/aliases/cdrom0) without the need for root permission.

It seems this does not work any more with Solaris 9, it requires
root permission now.

An example program is appended below. On Solaris 8 with a uid != 0
it prints the CDROM drive's manufacturer and product id:

% uname -r
5.8
% id
uid=109(jk) gid=20(usr)
% vol
TOSHIBA DVD-ROM SD-M1612
%


It seems that on Solaris 9, the USCSICMD ioctl fails with an EPERM
error. Can anyone reproduce this on Solaris 9?

Is this a Solaris 9 bug, or a Solaris 9 feature?


------------------------------------------------------------------------

/* compile with: cc -o vol vol.c */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/scsi/generic/commands.h>
#include <sys/scsi/impl/uscsi.h>


#define CD_DEVICE "/vol/dev/aliases/cdrom0"


/* execute a SCSI INQUIRY command on device |fd| */

int inquiry(int fd, void *inq_data, int inq_len)
{
struct uscsi_cmd sc;
union scsi_cdb inq_cdb;

memset(&inq_cdb, 0, sizeof(inq_cdb));
inq_cdb.scc_cmd = SCMD_INQUIRY;
inq_cdb.g0_count0 = inq_len;

memset(&sc, 0, sizeof(sc));
sc.uscsi_cdb = (caddr_t)&inq_cdb;
sc.uscsi_cdblen = 6;
sc.uscsi_bufaddr = inq_data;
sc.uscsi_buflen = inq_len;
sc.uscsi_flags = USCSI_ISOLATE|USCSI_READ;

if (ioctl(fd, USCSICMD, &sc)) {
perror("USCSICMD ioctl, inquiry");
exit(1);
}

if (sc.uscsi_status) {
fprintf(stderr, "bad status for INQUIRY command (%d)\n",
sc.uscsi_status);
return -1;
}
return 0;
}


int main(int argc, char **argv)
{
struct scsi_inquiry inq_data;
int fd;
char *cd_device = CD_DEVICE;

if ((fd = open(cd_device, O_RDONLY)) < 0) {
perror(cd_device);
exit(1);
}

if (inquiry(fd, &inq_data, sizeof(inq_data))) {
fprintf(stderr, "scsi inquiry command failed\n");
exit(1);
}

/* print vendor/product from scsi inquiry data */
printf("%.*s %.*s\n",
sizeof(inq_data.inq_vid), inq_data.inq_vid,
sizeof(inq_data.inq_pid), inq_data.inq_pid);

exit(0);
}
------------------------------------------------------------------------
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 22 2007
Added on Oct 15 2002
3 comments
354 views