Using the HP-UX libIO Library (HP-UX 11i v3) Introduction......................................................................................................................................... 3 I/O Subsystem Terms and Definitions ..................................................................................................... 4 Using the libIO Library on HP-UX 11i v3.................................................................................................
io_legacy_to_new_dsf() ......................................................................................................... 29 Examples................................................................................................................................ 29 Hardware Path Related Routines ...................................................................................................... 35 io_hw_path_to_node() ..................................................................................
Introduction The document describes the libIO functionality for HP-UX 11i v3 and later. libIO provides an interface for user processes to read information from and write information to kernel I/O data structures. The libIO routines are commonly used by HP-UX commands such as ioscan, ioinit, and so forth.
I/O Subsystem Terms and Definitions Legacy Hardware Path A data structure to store hardware paths (using the format and structure used prior to HP-UX 11i v3). This structure has 14 elements of 8 bits each. Agile Hardware Path A data structure to store hardware paths used for HP-UX 11i v3 and later releases. This structure has 64 elements of 64 bits each. I/O Tree A complete set of I/O modules and devices that constitute a system. The basic building block of the I/O Tree data structure is the I/O node.
Device number (dev_t) The operating system communicates with the hardware by associating the driver name with a hardware address and recognizes interface and device drivers by a unique number named dev_t. In HP-UX 11i v3, there are legacy dev_ts and agile dev_ts. An agile dev_t is the dev_t of an agile I/O node; a legacy dev_t is the dev_t of a legacy I/O node. Device Special File (DSF) A special file used to communicate with a device driver.
Using the libIO Library on HP-UX 11i v3 The libIO routines are used as follows: 1. Call io_init() to establish the connection between user application and kernel. 2. Perform the required operations by calling libIO routines. 3. Call io_end() to close the connection. To use the libIO library, the program must include and be linked using -lIO. io_init() – Establishing the Connection This routine must be called before calling any other routine in the libIO library.
libIO Routines libIO routines are classified based on the services that they provide, as follows: • • • • • Search/Query the I/O Tree and Switch Table dev_t related functions Device Special File services Hardware path related functions Other miscellaneous functions Search/Query the I/O Tree and Switch Table Table 1 lists the routines in the libIO library that can be used to search or query the I/O Tree and switch table: Table 1 – libIO routines to Search/Query the I/O Tree and Switch Table Routine Descrip
io_token_t io_search_array(io_token_t token, int type, int qual, char *key[], void *dat[]); The type used as argument in the io_search() routine can have the following values: • • • • S_IOTREE S_IOTREE_EXT S_BDEVSW S_CDEVSW The defined qualifiers used for io_search() are described in Table 2 Table 2 – io_search() Qualifiers Qualifier Description Q_SW I/O Tree node is claimed by driver Q_HW I/O Tree node has associated hardware Q_PSEUDO Pseudo driver Q_DEVSW Driver is in a switch table Q_SUBTREE
Table 3 – keys to Search I/O Trees Key Name "parent" Data Type void * Description Token corresponding to the parent of the given token. "name" char * The name of the given token. "b_major" int Block major number. "c_major" int Character major number. "instance" int The instance number of the given node. "type" char * The corresponding node’s type. For example, DEVICE, PROCESSOR, MEMORY, etc. "class" char * The class of the corresponding class. For example, disk, tape, etc.
The defined key used to search switch tables are described in Table 4. Table 4 – Defined Key to Search Switch Tables TYPE KEYS "c_major", "is_pseudo", "b_major", S_CDEVSW/S_BDEVSW "driver_name", "class", "is_char", "is_block", and "is_dyn_major" io_search_array() This routine searches the kernel I/O system and returns the next token that matches the given search criteria.
The defined key values are described in io_search(). io_query_array() This routine is an enhancement to io_query(). It returns multiple keys for a token at one time. The maximum number of keys is set to12 (IO_MAX_NUM_QUERY). The function prototype for this routine is: int io_query_array(io_token_t token, int type, int nkeys, char *key [], void *ptr[]); io_query_batch() This routine copies the key/dat arguments (one or more pair) into an array and calls io_query_array() with the passed search parameters.
io_token_t node; char my_string[MAX_HW_PATH_STR]; hw_path_t hw_path; /*initialize libIO operations */ if (io_init (O_RDONLY)! =IO_SUCCESS){ io_error ("io_init"); exit (1); } /* get an existing disk node */ if ((node=io_search((io_token_t)NULL, S_IOTREE, Q_SW, "class", "disk", NULL)) == NULL) { io_error("io_search"); exit(1); } if (io_query (node, S_IOTREE, "hw_path", &hw_path) ==IO_ERROR ) { io_error ("ERROR:io_query"); exit (1); } if(io_hw_path_to_str(my_string,&hw_path)==IO_ERROR) { io_error("io_hw_path_t
1. Initialize the libIO library. 2. Search for the disk device in the legacy kernel I/O data structures. 3. Get the class name, instance number, hardware path, and driver name(s) of this disk device and print it. 4. Terminate the connection. Solution #include #include
instance, my_string, driver_name , state, type); /*end of libIO operations */ io_end(); } Output class instance disk 25 hardware path driver name state 1/0/1/0/0/1/1.6.0 sdisk CLAIMED type DEVICE Example 3 Get all disk devices from the legacy kernel I/O data structure and print the class name, instance, hardware path and driver names. Algorithm 1. Initialize the libIO library. 2. Search for all disk devices in the legacy kernel I/O data structures. 3.
/*Initialize the libIO connection */ if (io_init(O_RDONLY)!=IO_SUCCESS){ io_error("io_init") ; exit(1); } key[0]="class"; ptr[0]=(void *)class_name; key[1]="driver_name"; ptr[1]=(void *)driver_name; /*get an existing disk device node */ if((token=io_search((io_token_t)NULL, S_IOTREE, 0, "class", "disk", NULL))==NULL){ io_error("io_search"); exit(1); } if (io_search_array_batch(token, S_IOTREE, 0, key, ptr, ret_token)==IO_ERROR) { io_error("io_search_array_batch"); exit(1); } /*get the property of the node *
============================================ disk 26 1/0/0/3/1.2.0 disk 27 1/0/1/0/0/1/1.6.0 disk 14 1/0/2/0/0.8.0.255.1.2.0 disk 15 1/0/2/0/0.8.0.255.1.3.0 disk 16 1/0/2/0/0.8.0.255.1.4.0 disk 17 1/0/2/0/0.8.0.255.1.6.0 disk 18 1/0/2/0/0.8.0.255.1.7.0 disk 19 1/0/2/0/0.8.0.255.1.8.0 disk 21 1/0/2/0/0.8.0.255.1.9.0 disk 20 1/0/2/0/0.8.0.255.1.10.0 disk 22 1/0/2/0/0.8.0.255.1.11.0 disk 23 1/0/2/0/0.8.0.255.1.13.0 disk 24 1/0/2/0/0.8.0.255.1.14.
dev_t Related Routines The operating system communicates with the hardware by associating the driver name with a hardware address and recognizes interface and device drivers by a unique number named dev_t. The communication generally pertains to input/output related to that device. The libIO routines related to dev_t are listed in Table 5.
io_get_devs() This routine gets all the dev_ts (including char and block dev_ts) of a given node. It will return all the dev_ts, the device-specific options, and the dev_t type in dev_arry. The dev_type field of dev_arry is updated to indicate if the dev_t type is D_CHR (character) or D_BLK (block). The interface will copy the data into the array if it is large enough. If it is too small, no data is returned and the count is set to indicate the required size (number of io_dev_info_t).
This routine returns an I/O node corresponding to the specified dev_t and dev_type. The type of the dev_t (D_CHR or D_BLK) is specified as input. The function prototype of this routine is: io_token_t io_dev_to_node(dev_t dev, int dev_type); io_legacy_to_new_dev() This routine maps a legacy dev_t to an agile dev_t. The type of the dev_t (D_CHR or D_BLK) is specified as input. The interface returns the agile dev_t or IO_ERROR in case of an error.
int io_block_to_raw(dev_t bdev, dev_t *rdev); io_raw_to_block() The routine returns the character dev_t of a block dev_t. The synopsis of the function is: int io_raw_to_block(dev_t rdev, dev_t *bdev); Examples Example 1 Build a dev_t from an I/O node of a disk device for partition 0 of the disk in the legacy and agile views. Print the major number and minor number of this dev_t. Algorithm 1. 2. 3. 4. 5. 6. 7. 8. 9. Initialize the libIO library.
} /*get an existing disk node from legacy view */ if ((node=io_search((io_token_t)NULL, S_IOTREE, Q_SW, "class", "disk", NULL)) == (io_token_t)NULL) { io_error("ERROR:io_search"); exit(1); } /* ascertain the type of device */ if (io_query(node, S_IOTREE, "is_char", &is_char) ==IO_SUCCESS) { dev_type = D_CHR; } else if(io_query(node, S_IOTREE, "is_block", &is_block) == IO_SUCCESS) dev_type = D_BLK; /*get the dev_t */ if (io_mkdev(node, dev_type, "s0", &dev)!=IO_SUCCESS) { io_error("ERROR:io_mkdev"); exit(1);
major(dev), minor(dev)); /*terminate libio operations */ io_end(); } Output Legacy view =========== The major num: 188 minor num: 24576 Agile view ============== The major num: 11 minor num: 0 Example 2 Get all the dev_ts of a disk device in the agile kernel I/O data structure and print the number of agile dev_ts found. Algorithm 1. 2. 3. 4. Initialize the libIO library. Search for a disk device in the agile kernel I/O data structures.
"class", "disk", "driver_name", "esdisk", NULL)) ==(io_token_t)NULL) { io_error("ERROR:io_search:class:disk"); exit(1); } /*call io_get_devs to get the agile dev_ts */ if (io_get_devs(node, dev_array, &count) != IO_SUCCESS) if (io_errno == IO_E_BUF_TOO_SMALL) { dev_array=(io_dev_info_t*) malloc(count*sizeof(io_dev_info_t)); if (io_get_devs(node, dev_array, &count) !=IO_SUCCESS) { io_error("io_get_devs"); exit(1); } } printf("%d agile dev_t’s were found\n", count); /*end of libIO operations */ io_end(); } O
int dev_type=-1; dev_t dev=-1; hw_path_t hw_path; char str[MAX_HW_PATH_STR]; /* initialize libIO operations */ if (io_init(O_RDONLY)!=IO_SUCCESS) { io_error("ERROR:io_init"); exit(1); } /*get an exiting agile disk I/O node */ if ((node=io_search((io_token_t)NULL, S_IOTREE_EXT, 0, "class", "disk", NULL))==(io_token_t)NULL) { io_error("ERROR:io_search:class:disk"); exit(1); } dev_type=D_CHR; options=1; if (io_mkdev_ext(node, dev_type, options, &dev) != IO_SUCCESS) { io_error("ERROR:io_mkdev_ext:options:1"); e
io_end(); } Output Disk option 1 for dev_t 0xb00001d of the hardware path 64000/0xfa00/0x0. Example 4 Get a disk device from legacy and agile kernel I/O data structure. Find the dev_t of these I/O nodes. Map the dev_t to its corresponding agile/legacy dev_t and print the major number of the dev_t. Algorithm 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Initialize the libIO library. Search for a legacy disk device in the kernel data structures. Get the dev_t of this node. Map the legacy dev_t to agile dev_t.
/* initialize libIO operations */ if (io_init(O_RDONLY)!=IO_SUCCESS) { io_error("ERROR:io_init"); exit(1); } /* get an existing legacy disk I/O node */ if ((node = io_search ((io_token_t)NULL, S_IOTREE, Q_SW, "driver_name", "sdisk", "class", "disk", NULL)) ==(io_token_t)NULL) { io_error("ERROR:io_search:class:disk"); exit(1); } /* ascertain the type of device */ if (io_query(node, S_IOTREE, "is_char", &is_char) == IO_SUCCESS) { dev_type=D_CHR } else if (io_query(node, S_IOTREE, "is_block", &is_block)== IO_
/* build the dev_t of the node */ if (io_mkdev_ext(node, dev_type, 0, &dev)!=IO_SUCCESS) { io_error("ERROR:io_mkdev_ext:options:s0"); exit(1); } if (io_new_to_legacy_devs(dev, dev_type, leg_dev, &count)== IO_ERROR) if (io_errno == IO_E_BUF_TOO_SMALL) { leg_dev=(dev_t *)malloc(count*sizeof(dev_t)); if (io_new_to_legacy_devs(dev, dev_type, leg_dev, &count)==IO_ERROR ) { io_error("ERROR io_new_to_legacy_devs"); exit (1); } } else { io_error("io_new_to_legacy_devs"); exit(1); } } for (i=0 ; i
Device Special File Services A special file (typically) used to communicate with an I/O device is called a device special file. The libIO routines that deal with device special files are listed in Table 6. Table 6 – Device Special File routines in libIO Routines io_char_to_block_dsf() Description Maps a character device special file to block device special file. io_block_to_char_dsf() Maps a block device special file to character device special file.
int io_new_to_legacy_dsfs(char *new_dsf, char *legacy_dsf, int *count); Callers allocate the array and specify the size of the array (number of legacy DSFs expected) in count. If the array is big enough, the service will return successfully and the count will indicate the actual count. If the array is not big enough: 1. 2. 3. 4. no data will be returned, the count will be set to represent the needed size, the service will return IO_ERROR,and io_errno will be set to IO_E_BUF_TOO_SMALL.
{ io_token_t node; io_dev_info_t *dev_array; int is_char=0, is_block=0, ret=0, count=1, i=0; char dsf_path[MAXPATHLEN], blk_dsf[MAXPATHLEN]; char retrieved_chr_dsf[MAXPATHLEN]; /* initialise libio operations */ if (io_init(O_RDONLY)!=IO_SUCCESS) { io_error("ERROR:io_init"); exit(1); } /* get an existing disk node */ if ((node=io_search((io_token_t)NULL, S_IOTREE_EXT, Q_SW, "class", "disk", "driver_name", "esdisk", NULL))==(io_token_t)NULL) { io_error("ERROR:io_search:class:disk"); exit(1); } /* ascertain th
printf("Block Special File Character Special File\n"); printf("================== ===============\n"); printf("%s %s \n",blk_dsf ,retrieved_chr_dsf); } /*end of libio operations */ io_end(); } Output Character Special File ====================== /dev/rdisk/disk14 Block Special File =================== /dev/disk/disk14 Block Special File ===================== /dev/disk/disk14 Character Special File ======================== /dev/rdisk/disk14 Example 2 Get a persistent special file from an agile disk device
dsf_array=(char *)malloc(MAXPATHLEN ); /* initialize libio operations */ if (io_init(O_RDONLY)!=IO_SUCCESS) { io_error("ERROR:io_init"); exit(1); } /* get an existing disk I/O node */ if ((node = io_search ((io_token_t)NULL, S_IOTREE_EXT, Q_SW, "class", "disk", NULL)) == (io_token_t)NULL) { io_error ("ERROR:io_search:class:disk"); exit (1); } /* ascertain the type of device */ if (io_query(node, S_IOTREE_EXT, "is_char", &is_char) ==IO_SUCCESS) { dev_type = D_CHR; } else if (io_query(node, S_IOTREE_EXT, "is_
Output Persistent Special File ======================= /dev/rdisk/disk14 Legacy Special File(s) ================= /dev/rdsk/c4t2d0; Example 3 Get a legacy special file from a legacy disk device, and find the corresponding persistent special file. Algorithm 1. 2. 3. 4. Initialize the libIO library. Get a legacy special file from an I/O node. Get the persistent special file from the legacy special file. Terminate the connection. Solution #include #include #include #include
} else if (io_query(node, S_IOTREE, "is_block", &is_block) == IO_SUCCESS) dev_type = D_BLK; /* try out io_mkdev() */ if (io_mkdev(node, dev_type, "s0", &dev) != IO_SUCCESS) { io_error("ERROR:io_mkdev:options:s0"); exit(1); } if (dev_type == D_CHR) { ret=devnm(S_IFCHR,dev,dsf_path, sizeof(dsf_path), 1); if (ret != 0) { printf("devnm failed \n"); exit(1); } ret=io_legacy_to_new_dsf(dsf_path,retrieved_new_dsf); if(ret == IO_ERROR) io_error("ERROR:io_legacy_to_new_dsf"); exit(1); } else { printf("\nLegacy Speci
Hardware Path Related Routines Each I/O node is assigned a hardware address that is unique among its siblings (no two siblings can have the same hardware address). Concatenating a series of hardware addresses together describes a path through the I/O Tree with an I/O node at the end point. Each node can be uniquely identified by a hardware path. However HP-UX 11i v3 introduces the agile naming model. So each node can be uniquely identified by a hardware path in either the legacy or agile naming model.
io_hw_path_to_node() Each node can be uniquely identified by a hardware path. This routine returns the token for the specified hardware path. The synopsis of the function is: io_token_t io_hw_path_to_node(hw_path_t *path); io_node_to_hwpath() This routine assigns path with the full hardware path of the given node.
The routine returns: • IO_HWPATH_LEGACY(1) - for legacy • IO_HWPATH_NEW(0) - for agile • IO_ERROR() - for failure io_legacy_to_new_hwpath() This routine converts the data structure of a pre-HP-UX11i v3 hardware path to the HP-UX 11i v3 (or later) hardware path.
io_hw_compare_ext() This routine compares two hardware path structures used on HP-UX 11i v3 or later. If they are equivalent, it returns success. Otherwise, it returns an error. The function prototype for this routine is: int io_hw_compare_ext(hw_path_t *path1, hw_path_t *path2); Examples Example 1 Get a disk device I/O node from the kernel I/O data structure and: 1. Map the I/O node to its hardware path, 2. Map the hardware path to its I/O node, 3. Validate the two nodes. Algorithm 1. 2. 3. 4. 5. 6. 7.
"class","disk",NULL)) == (io_token_t)NULL){ io_error("ERROR:io_search:class:disk"); exit(1); } /* get the hw_path from the I/O node */ if (io_node_to_hw_path (node, &hw_path) == IO_ERROR) { io_error("ERROR:io_node_to_hw_path"); exit(1); } /*get the hw_path in string format of driver */ if ((io_hw_path_to_str (path, &hw_path)) == IO_ERROR) { io_error("ERROR:io_hw_path_to_str"); exit(1); } /* get the node of driver */ if ((h_node = io_hw_path_to_node (&hw_path)) == (io_token_t)NULL) { io_error("ERROR:io_hw_pa
5. Get the hardware path string of that node. 6. Convert the hardware path to pre-HP-UX 11i v3 hardware path data structure. 7. Convert this pre-HP-UX 11i v3 hardware path to the HP-UX 11i v3 hardware path data structure. 8. Terminate the connection. Solution #include #include
== IO_ERROR) { io_error("ERROR:io_new_to_legacy_hwpath"); exit(1); } else printf("\nConversion of HP-UX 11i v3 hardware path to pre-HP-UX 11i v3 hardware path Sucesses\n"); if(io_legacy_to_new_hwpath(&leg_path , &hw_path1) == IO_ERROR) { io_error("ERROR:io_legacy_to_new_hwpath"); exit(1); } else if (io_hw_compare_ext(&hw_path,&hw_path1) == IO_SUCCESS) { printf("\nConversion of pre- HP-UX 11i v3 hardware path to HP-UX 11i v3 hardware path Sucesses \n"); } } /*Terminate libIO operation */ io_end(); Output Co
{ hw_path_t hw1, hw2; int inst=10; io_token_t node1 ,node2; char my_string[MAX_HW_PATH_STR]; char my_string1[MAX_HW_PATH_STR]; /*initialize libio operations */ if (io_init(O_RDONLY) == IO_ERROR) { io_error("ERROR:io_init"); exit(1); } if ((node1=io_search((io_token_t)NULL, S_IOTREE_EXT, Q_SW, "class", "disk", NULL)) == NULL) { io_error("ERROR:io_search"); exit(1); } if (io_query (node1, S_IOTREE_EXT, "hw_path", &hw1) ==IO_ERROR ) { io_error("ERROR:io_query"); exit(1); } if (io_hw_path_to_str(my_string,&hw1)
/*terminate libio operations */ io_end(); } Output Hardware path 64000/0xfa00/0x0 and Hardware path 1/0/0/3/0.6.
Miscellaneous Routines The libIO library contains the following routines for miscellaneous services: Routine io_is_legacy_token() Description Determines whether token is of agile or legacy style. io_is_option_set() Determines if the option(s) is set for a dev_t. io_get_node_relation() Retrieve a relative of a given node token. io_get_mapping() Get the mapping of lun to/from lunpath tokens and legacy to/from agile node.
If relative is NULL, addr is used to identify a particular child or sibling. If relative is not NULL, addr is ignored. If relative is equivalent to node, the first child or sibling is returned. Otherwise, the next child or sibling (after the one identified by relative) is returned. io_is_option_set() This routine determines if the option(s) is set for a dev.
Examples Example 1 Get an I/O node of a disk device from the kernel I/O data structure. Verify the I/O node from agile view or legacy view and print the hardware path of that I/O node from agile view or legacy view. Algorithm 1. 2. 3. 4. 5. Initialize the libIO library. Search for a disk device in the kernel data structures. Verify if it is from agile view or legacy view. Print the hardware path of that I/O node is from agile view or legacy view. Terminate the connection. Solution #include
io_error ("ERROR:io_query"); exit (1); } if (io_hw_path_to_str(my_string, &hw_path) == IO_ERROR) { io_error("io_hw_path_to_str"); exit(1); } printf("%s is from LEGACY view\n ",my_string); exit(0); } if (ret==IO_TOKEN_NEW) { if (io_query (node, S_IOTREE, "hw_path", &hw_path) ==IO_ERROR ){ io_error("ERROR:io_query"); exit(1); } if (io_hw_path_to_str(my_string, &hw_path) == IO_ERROR){ io_error("io_hw_path_to_str"); exit(1); } printf(" %s is from AGILE view ",my_string); exit(0); } if (ret==IO_ERROR) { io_error
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Initialize the libIO library. Search for a disk device in the kernel data structures from legacy view. Map this legacy node to corresponding agile node. Print the mapping. Map this agile node to corresponding node in the legacy view. Print the mapping. Search for a lunpath of a device in the kernel data structures from agile view. Map this lunpath node to corresponding node in the agile view. Print the mapping. Terminate the connection. Solution #include
&count, token_array); } if (ret!=IO_SUCCESS) { io_error ("ERROR:io_get_mapping:"); exit(1); } if (io_query (legacy_node, S_IOTREE, "hw_path", &hw_path) ==IO_ERROR ) { io_error("ERROR:io_query"); exit(1); } if (io_hw_path_to_str(my_string, &hw_path)==IO_ERROR) { io_error("io_hw_path_to_str"); exit(1); } if (io_query (token_array[0], S_IOTREE_EXT, "hw_path", &hw_path1)==IO_ERROR ) { io_error("ERROR:io_query"); exit(1); } if (io_hw_path_to_str(my_string1, &hw_path1)==IO_ERROR) { io_error("io_hw_path_to_str");
if (io_hw_path_to_str(my_string, &hw_path1)==IO_ERROR) { io_error("io_hw_path_to_str"); exit(1); } printf("IO_NEW_2_LEGACY MAPPING\n-----------------------\n"); printf("%s maps %s \n\n",my_string1, my_string); free(token_array); free(token_array1); /*IO_LUNPATH_2_LUN Mapping */ lun_path_node=io_search((io_token_t)NULL, S_IOTREE_EXT, Q_SW, "type", "LUN_PATH", NULL); if (lun_path_node==(io_token_t)NULL) { io_error("ERROR:io_search:"); exit(1); } count=1; token_array=(io_token_t*)malloc(sizeof(io_token_t)); re
exit(1); } printf("IO_LUNPATH_2_LUN MAPPING\n-----------------------\n"); printf("%s maps %s \n\n",my_string, my_string1); /*IO__LUN_2_LUNPATH Mapping */ token_array1=(io_token_t*)malloc(sizeof(io_token_t)); ret=io_get_mapping(token_array[0], IO_LUN_2_LUNPATH, &count,token_array1); if (ret==IO_E_MEM_ALLOC) { token_array1=(io_token_t*) malloc(count*sizeof(io_token_t)); ret=io_get_mapping(token_array[0], IO_LUN_2_LUNPATH, &count, token_array1); } if (ret != IO_SUCCESS) { io_error("ERROR:io_get_mapping:"); e
1/0/0/3/0.0x6.0x0 maps 1/0/0/3/0.6.0 IO_LUNPATH_2_LUN MAPPING -----------------------1/0/0/3/0.0x6.0x0 maps 64000/0xfa00/0xc IO_LUN_2_LUNPATH MAPPING -----------------------64000/0xfa00/0xc maps 1/0/0/3/0.0x6.0x0 Example 3 Get an I/O node of class “ext_bus” from the agile kernel I/O data structure and print the hardware path of its parent, child and sibling nodes. Algorithm 1. 2. 3. 4. 5. Initialize the libIO library. Search for class “ext_bus” node in the kernel data structures from agile view.
} if (io_query (node, S_IOTREE_EXT, "hw_path", &hw_path)==IO_ERROR) { io_error("ERROR:io_query"); exit(1); } if (io_hw_path_to_str(my_string, &hw_path)==IO_ERROR) { io_error("io_hw_path_to_str"); exit(1); } if (io_get_node_relation(node,IO_REL_PARENT,0,&relative) ==IO_ERROR) { io_error("ERROR:io_get_node_relation IO_REL_PARENT "); exit(1); } else { if (io_query (relative, S_IOTREE_EXT, "hw_path", &hw_path1) ==IO_ERROR) { io_error("ERROR:io_query"); exit(1); } if (io_hw_path_to_str(my_string1, &hw_path1) ==
exit(1); } printf("\nChild of \"ext_bus\" I/O node my_string1); %s \n", } strcpy(my_string1," "); if (io_get_node_relation(node, IO_REL_SIBLING, 1, &relative2)==IO_ERROR) { io_error("ERROR:io_get_node_relationIO_REL_SIBLING"); exit(1) ; } else { if (io_query (relative2, S_IOTREE_EXT, "hw_path", &hw_path1)==IO_ERROR) { io_error("ERROR:io_query"); exit(1); } if (io_hw_path_to_str(my_string1, &hw_path1)==IO_ERROR) { io_error("io_hw_path_to_str"); exit(1); } printf("\n Sibling of \"ext_bus\" I/O node my_strin
For more information To learn more about the mass storage stack and agile addressing on HP-UX 11i v3, refer to the following documents available on the HP web site at http://docs.hp.com/en/netsys.html#Storage%20Area%20Management • The Next Generation Mass Storage Stack HP-UX 11i v3 White Paper • HP-UX 11i v3 Mass Storage Device Naming White Paper • HP-UX 11i v3 Native Multi-Pathing for Mass Storage • SCSI Management and Diagnostics utility on HP-UX 11i v3 Call to action HP welcomes your input.