Operating System - HP-UX
1845930 Members
3393 Online
110250 Solutions
New Discussion

Re: pstat_getdisk Does Not Return All Disk

 
SOLVED
Go to solution
Philip A. Reyniers
Occasional Advisor

pstat_getdisk Does Not Return All Disk

The pstat_getdisk function from sys/pstat.h does not return all the disks installed on a HP-UX 11.0/11.i PA-RISC server. Take the following code as an example:

##########START CODE foo.cc##########
#include
#include
int main(void){
struct pst_diskinfo pst[100];
int i, count;

count = pstat_getdisk(pst, sizeof(struct pst_diskinfo),
sizeof(pst) / sizeof(struct pst_diskinfo), 0);
if (count < 0) {
perror("pstat_getdisk()");
return ( EXIT_FAILURE );
}
for (i = 0; i < count; i++) {
printf("\n Disk hardware path = %s",
pst[i].psd_hw_path.psh_name);
}
return( EXIT_SUCCESS );
}
##########STOP CODE foo.cc##########

Compile Options:
aCC -o foo foo.cc

On the server that I am dealing with, the following ioscan command shows 68 disks.
# ioscan -FC disk | wc -l
# 68

While the output from foo, which uses function call pstat_getdisk() only shows 27 installed disks.

If I take and run the same code and command on a 8700, ioscan shows 87 disks while the pstat_getdisk() only displays 48.

I have checked to see if the pstat_getdisk() function call displays information from alternate links and it does. Can someone please tell me about the behavior that I am seeing from the pstat_getdisk() command.

Thanks in advance to all that respond.

Phil
If it is not broken leave it alone, if you have time try to improve it, and if you do not care then get another job.
10 REPLIES 10
Steve Steel
Honored Contributor
Solution

Re: pstat_getdisk Does Not Return All Disk

Hi


Are all the disks open when you run this;

It gets data I believe via the kernel and is only guaranteed to show open discs


Steve Steel
If you want truly to understand something, try to change it. (Kurt Lewin)
Philip A. Reyniers
Occasional Advisor

Re: pstat_getdisk Does Not Return All Disk

Steve,

Define what you mean by open. Do you mean that I need to open( ptrDiskName, O_RDONLY|O_NDELAY ) for all the disks installed on the system or do you mean that the disk must belong to a Volume Group. Because I do see, in some cases, disks that are not part of a VG and sometimes even the CDROM drives.

Phil
If it is not broken leave it alone, if you have time try to improve it, and if you do not care then get another job.
Mark Grant
Honored Contributor

Re: pstat_getdisk Does Not Return All Disk

Also,

ioscan -FC disk doesn't just show you disks. It shows everything in the class disks. This includes funky stuff like array information from XP's or other storage devices. I would check exactly how many disks are really attached to the system
Never preceed any demonstration with anything more predictive than "watch this"
Philip A. Reyniers
Occasional Advisor

Re: pstat_getdisk Does Not Return All Disk

I understand that behavior in ioscan however, it is not an issue in this case. I have verified that there are 68 disks in the server in under evaluation. The behavior being seen, from pstat_getdisk, is that I do not see all the installed disks on the server in question.

Phil.
If it is not broken leave it alone, if you have time try to improve it, and if you do not care then get another job.
Philip A. Reyniers
Occasional Advisor

Re: pstat_getdisk Does Not Return All Disk

Mark and Steve,

Using the open ( ptrDeviceName, O_RDONLY|O_NDELAY ) and holding the file descriptors until the pstat_getdisk() operations are complete is what it takes. I would hazard to guess that it is true that the kernel does not know anything about these devices, other than they exist, and pstat is unable to obtain access to the information until an open file descriptor to the device(s) in question exists.

Thanks for the speedy replies.

Phil.
If it is not broken leave it alone, if you have time try to improve it, and if you do not care then get another job.
Ramesh Babu_1
New Member

Re: pstat_getdisk Does Not Return All Disk

Hi
I am also facing the same problem. The pstat_getdisk is not listing all the disk configured in the HP-UX system.
Even i tried opening the devices using open(devicename,O_RDONLY|O_NDELAY) but it didn't help. can some one please tell me why it is not listin all the disks.

Thanks in advance..

Ramesh Babu
Philip Reyniers
Advisor

Re: pstat_getdisk Does Not Return All Disk

Ramesh,

It has been nearly a year since I worked on this issue; however, in my last response the original issue, I indicated that I solved the problem.

It appears that your source code example, "open(devicename,O_RDONLY|O_NDELAY)" is passing the device name and not a pointer to the device. This may not be true, but your code does not indicate otherwise.

Please read my original response:

"Using the open ( ptrDeviceName, O_RDONLY|O_NDELAY ) and holding the file descriptors until the pstat_getdisk() operations are complete is what it takes. I would hazard to guess that it is true that the kernel does not know anything about these devices, other than they exist, and pstat is unable to obtain access to the information until an open file descriptor to the device(s) in question exists."

1). Obtain a Pointer to the directory, such as, /dev.

ptrD = opendir( FULLPATH )

2). Read the directory in something like a while loop.

ptrDir = readdir( ptrD )

3). Perform what ever action you are wanting to accompish, such as, lstat.

4). Cleanup any pointers and data structures.

Here is a couple of chunks of code you can read through to get an idea of what you need to do.

/////////////////////////////////////////////////////////////////////////////////////
// PROTOTYPES //
/////////////////////////////////////////////////////////////////////////////////////
typedef int get_pt ( const char *, const struct stat *, int );
static get_pt get_path_type;
static int get_path ( const char *, get_pt * );
static int parse_path ( get_pt * );


static int parse_path ( get_pt *gpt ) {
////////////////////////////////////////////////////////////////////////////////////
// Descend through the hierarchy, starting at "fullpath". If "fullpath" is //
// anything other than a directory, then lstat() it, call get_path_type [gpt], and//
// return. For a directory, we call ourself ( parse_path ) recursively for each //
// name in the directory. //
////////////////////////////////////////////////////////////////////////////////////
struct stat statbuf;
struct dirent *ptrDir;
DIR *ptrD;
int ret;
char *ptr;

(void)memset( &statbuf, 0, sizeof( struct stat ) );

if ( lstat( FULLPATH, &statbuf ) < 0 ) {
return( gpt( FULLPATH, &statbuf, FTW_NS ) ); /* lstat error */
}
if ( S_ISDIR( statbuf.st_mode ) == 0 ) {
return( gpt( FULLPATH, &statbuf, FTW_F ) ); /* not a directory */
}

/*************************************************************************
** It is a directory. First call get_path_type [gpt] for the directory **
** then process each file name in the directory. **
*************************************************************************/
if ( ( ret = gpt( FULLPATH, &statbuf, FTW_D ) ) != 0 ) {
return( ret );
}

ptr = FULLPATH + strlen( FULLPATH ); /* point to the end of FULLPATH */
*ptr++ = '/';
*ptr = 0;

if ( ( ptrD = opendir( FULLPATH ) ) == NULL ) {
return ( gpt( FULLPATH, &statbuf, FTW_DNR ) ); /* Cannot read directory */
}

while ( ( ptrDir = readdir( ptrD ) ) != NULL ) {
if ( strcmp( ptrDir->d_name, "." ) == 0 |
strcmp( ptrDir->d_name, ".." ) == 0 |
strcmp( ptrDir->d_name, "group" ) == 0 ) {
continue; /* ignore dot ".", dot dot ".." and group */
}
strcpy( ptr, ptrDir->d_name ); /* append name after slash */

if ( ( ret = parse_path( gpt ) ) != 0 ) { break; } /* recursive */
}

ptr[-1] = 0; /* erase everything from slash onward */
if ( closedir( ptrD ) < 0 ) {
printf ( "ERROR: Cannot close directory %s", FULLPATH );
}
////////////////////////////////////////////////////////////////////////////////////
// Cleanup //
////////////////////////////////////////////////////////////////////////////////////
if ( ptrDir ) { delete [] ptrDir; }
return ( ret );
}



static int get_path_type( const char *ptrPathname, const struct stat *ptrStat, int type ) {
////////////////////////////////////////////////////////////////////////////////////
// Determine the path type, is it a directory or a file, can we stat it... //
////////////////////////////////////////////////////////////////////////////////////

string s;
auto unsigned int i =0;

switch (type) {
case FTW_F:
switch( ptrStat->st_mode & S_IFMT ) {
case S_IFREG:
////////////////////////////////////////////////////////////////////////////////
// Regular File. //
////////////////////////////////////////////////////////////////////////////////
break;
case S_IFBLK:
////////////////////////////////////////////////////////////////////////////////
// Block Device File. //
// dev_t st_rdev Device ID; this entry defined only for char or blk spec //
// files. //
////////////////////////////////////////////////////////////////////////////////
for ( i =0; i < strlen( ptrPathname ); i++ ) { s += ptrPathname[i]; }
vdevice.push_back( s );
vmajor.push_back( (int)major(ptrStat->st_rdev) );
vminor.push_back( (int)minor(ptrStat->st_rdev) );
break;
case S_IFCHR:
////////////////////////////////////////////////////////////////////////////////
// Character Device File. //
// dev_t st_rdev Device ID; this entry defined only for char or blk spec //
// files. //
////////////////////////////////////////////////////////////////////////////////
for ( i =0; i < strlen( ptrPathname ); i++ ) { s += ptrPathname[i]; }
vdevice.push_back( s );
vmajor.push_back( (int)major(ptrStat->st_rdev) );
vminor.push_back( (int)minor(ptrStat->st_rdev) );
break;
case S_IFIFO:
//printf ( "%s = IFO\n", ptrPathname );
break;
case S_IFLNK:
////////////////////////////////////////////////////////////////////////////////
// Link File. //
////////////////////////////////////////////////////////////////////////////////
break;
case S_IFSOCK:
////////////////////////////////////////////////////////////////////////////////
// Socket File. //
////////////////////////////////////////////////////////////////////////////////
break;
case S_IFDIR:
////////////////////////////////////////////////////////////////////////////////
// Directory (We should not get here). //
////////////////////////////////////////////////////////////////////////////////
break;
}
break;
case FTW_D:
////////////////////////////////////////////////////////////////////////////////
// Directory. //
////////////////////////////////////////////////////////////////////////////////
break;
case FTW_DNR:
printf ( "ERROR: Cannot read directory %s\n", ptrPathname );
break;
case FTW_NS:
printf ( "ERROR: Cannot stat %s\n", ptrPathname );
break;
default:
printf ( "ERROR: unknown type %d for path %s\n", type, ptrPathname );
break;
}
return ( 0 );
}
Ramesh Babu_1
New Member

Re: pstat_getdisk Does Not Return All Disk

Thanks Phil!!

I have five devices in my HP-UX host, all are in the /dev/rdsk directory. The pstat_getdisk lists only two devices. Below is the sample program. Program is particularly written for the device "c12t0d0" which is not listed by the pstat_getdisk. Even i have passed pointer to device name in the open call but still pstat is not listing this device. I can open the device successfully and even the lstat worked perfectly. called pstat after opening the device and closed after later.

int main()
{
struct pst_diskinfo sDiskData;
int nReturnCode;
int j;
int nfd;

DIR *ptrD;
struct dirent *ptrDir;

struct stat statbuf;
char DeviceName[50];
char *ptr;

bzero(DeviceName,strlen(DeviceName));

ptrD = opendir("/dev/rdsk");
while( (ptrDir = readdir(ptrD)) != NULL)
{

if(strcmp(ptrDir->d_name,"c12t0d0") != 0)
continue;

sprintf(DeviceName,"/dev/rdsk/%s",ptrDir->d_name);

if(lstat(DeviceName,&statbuf) < 0)
perror("lstat failed");

ptr = DeviceName;

nfd = open(ptr,O_RDONLY|O_NDELAY);

if(nfd == -1)
perror("open failed ");
else
printf("file descriptor is %d \n",nfd);

for(j = 0; j<999; j++)
{
nReturnCode = pstat_getdisk(&sDiskData,sizeof(sDiskData),1,j);

if(nReturnCode == -1)
perror("pstat_getdisk failed : ");
else
printf("%d Name = %s%d \n",j,sDiskData.psd_drv_name.psd_name,sDiskData.psd_instance);
}
}

close(nfd);
return 0;
}


please let me know is there any problem in the sample program.
Stephen Keane
Honored Contributor

Re: pstat_getdisk Does Not Return All Disk

Your loop for each disk should be using the index field

e.g.

int idx = 0;
struct pst_diskinfo psd;
int rc = 1;

while (rc == 1)
{
rc = pstat_getdisk(&psd, sizeof(psd), 1, idx);
if (rc != 1) break;

// do your stuff ...

idx = psd.psd_idx + 1; /* Next disk */
}
Ramesh Babu_1
New Member

Re: pstat_getdisk Does Not Return All Disk

I tried modifying the index field in the loop. Still it is not listing all the devices.

Thx,
Ramesh