Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

admiopath(1M)

ioctl(2)

dsk(7)

rdsk(7)

vdm(7)



vdmmpio(7)                     DG/UX R4.11MU05                    vdmmpio(7)


NAME
       vdmmpio - Virtual Disk Manager Multi-Path Disk I/O Subdriver

DESCRIPTION
       The Multi-Path Disk I/O Subdriver provides high-availability access
       to physical disks by maintaining multiple controller paths that can
       all access the same physical disk.  In the event one controller path
       fails, the Multi-Path Disk I/O Subdriver will automatically switch to
       one of the alternate controller paths, and will re-issue the failed
       I/O on the new path.

       Such controller path failures are transparent to the upper levels of
       the system and to user applications.  No errors are returned on the
       I/O unless all paths to the disk have failed.  Messages are sent to
       the operator's console whenever there is an I/O failure or when the
       operator issues a path switch or repair command.

       Pictorially, a multi-path disk I/O instance with four paths looks
       like this:

                             +-------------------+
                             |  multi-path disk  |
                             |    I/O instance   |
                             +-------------------+
                              |  |           |  |
       +-------------------+  |  |           |  |  +-------------------+
       | path 0            |--+  |           |  +--| path 3            |
       | physical          |     |           |     | physical          |
       | sd(dgsc(0,6),0,0) |     |           |     | sd(dgsc(3,6),0,0) |
       +-------------------+     |           |     +-------------------+
           |                     |           |                     |
           |   +-------------------+       +-------------------+   |
           |   | path 1            |       | path 2            |   |
           |   | physical          |       | physical          |   |
           |   | sd(dgsc(1,7),0,0) |       | sd(dgsc(2,7),0,0) |   |
           |   +-------------------+       +-------------------+   |
           |            |                           |              |
           |            +------------+  +-----------+              |
           |                         |  |                          |
           +----------------------+  |  |  +-----------------------+
                                  |  |  |  |
                                  |  |  |  |
                                  ----------
                                 (          )
                                 (          )
                                 (   disk   )
                                 (   drive  )
                                 (          )
                                 (          )
                                  ----------

       In order to use the Multi-Path Disk I/O Subdriver, you must configure
       vdmmpio() into your kernel.  It appears in all new system files by
       default, so it is usually already configured.

   CONFIGURATION
       The Multi-Path Disk I/O Subdriver provides protection against a
       single point of failure in a disk controller, I/O chassis, cable, or
       CLARiiON® Storage Processor (SP), depending on the hardware
       configuration.  It does not provide protection against failure of the
       physical disk itself.

       After a path failure, if your hardware permits it, you can hot-repair
       the path by replacing the failed controller board(s), cables, etc.
       Then you can inform the Multi-Path Disk I/O Subdriver that the path
       has been repaired, making it available for future use in case some
       other path fails.

       You can also initiate a path switch to cause the Multi-Path Disk I/O
       Subdriver to switch to a particular path.  You might choose to do
       this to perform some maintenance on the controller for the old path.

       A multi-path disk I/O instance may have up to four paths.  Each path
       must be connected to a different disk controller, and all of them
       must be connected to the same physical disk.  You may have several
       multi-path disk I/O instances on a system, each managing a different
       physical disk.

       There are several hardware and software requirements for using multi-
       path disk I/O:

         ·    The physical disk to be managed must be a SCSI disk (either a
              separate disk or a disk in a CLARiiON® array).

         ·    The disk controllers attached to the physical disk must be
              capable of supporting multi-path I/O.  In general, this means
              they must be one of the newer model controllers like a ncsc()
              or npsc().  Disk controller types may be mixed, as long as the
              hardware permits it.

         ·    The physical disks may be wholly owned by a single system, be
              cluster disks shared between multiple systems, or be failover
              disks used between systems.  Multi-path disk I/O can be used
              on each system that accesses such a dual-initiator physical
              disk.

         ·    The physical disk must be DG/UX VDM-formatted.  You cannot use
              multi-path disk I/O with optical WORM or Magneto-Optical
              devices since they do not use the DG/UX VDM format.

         ·    The physical disk must be a read/write device.  This means
              that you cannot use multi-path disk I/O with read-only CD-
              ROMs.

   MULTIPLE PATHS
       Only one path in a multi-path disk I/O instance is active at any one
       time, and it is called the primary path.  The other paths are called
       alternate paths.  The primary path is used for all I/O until there is
       an I/O failure or the operator issues a path switch command (this
       means there is no load-balancing between paths).  When a switch
       occurs, an alternate path becomes the new primary path and the old
       primary path becomes an alternate path.  If the switch was due to an
       I/O failure, the old path is also marked as failed.  The first path
       listed in the create ioctl(2) packet is the initial primary path when
       the multi-path disk I/O instance is set up.

       When an I/O failure happens, the Multi-Path Disk I/O Subdriver will
       automatically choose one of the available alternate paths to become
       the new primary path.  If all of the alternate paths have failed, an
       automatic repair operation will be attempted once on each failed path
       to see if any of them can be made operational again.  If a path can
       be repaired, it will be chosen as the new primary path.  If all of
       the paths remain failed, then the I/O request will fail and return an
       error.  Future I/O requests will also fail, until one of the paths is
       repaired by the operator.  This automatic repair/retry mechanism
       prevents transient failures in one or more paths from causing I/O to
       fail.

   PATH VERIFICATION
       The Multi-Path Disk I/O Subdriver verifies each path when it is
       created, linked, switched to, or repaired, and before automatically
       switching to a new path due to an I/O failure on the old path.  This
       verification ensures that the disk controller is capable of
       supporting multi-path I/O, and that the path is connected to the same
       physical disk as all the other paths being managed.  If a
       configuration mistake is detected, the path will be rejected (if it
       is being newly linked) or marked failed (if it already exists), and
       another path will be chosen.  This verification prevents accidental
       misconfiguration of the disk, controllers, and cables from damaging
       the data stored on the disk.

       Verification of a path may take several seconds.  Issuing a repair
       command for a path may take several seconds to a minute or more,
       depending on whether a SCSI bus reset is required to complete the
       repair.  During these delays, all I/O to the multi-path disk I/O
       instance will be pended, and the applications issuing those I/Os will
       likewise be pended.  The I/O will be resumed after the operation
       completes.  Messages will be sent to the operator's console to keep
       you informed about what is happening.

   PERSISTENCE
       Multi-path disk I/O instances are non-persistent, meaning that their
       attributes are never stored in the VDIT on disk.  You must create
       temporary physical instances for the alternate paths.  You must
       insert the multi-path disk I/O instance on top of the initial
       physical instance using a temporary dummy instance.  This guarantees
       that the multi-path disk I/O instance will protect all of the virtual
       disks that live on the physical disk.  The VDM framework will
       automatically change the initial physical instance to temporary
       during the insert.

       Because they are non-persistent, multi-path disk I/O instances must
       be set up again each time the system is booted or the disk is
       registered.  The most convenient way to do this is to use the
       admiopath(1M) command to manage the multi-path disk I/O associations.

   USABILITY
       For you to be able to use a multi-path disk I/O instance, it must
       have at least one usable path.  If all paths have failed, a repair
       will automatically be attempted on each path.  If any path is
       repaired, it will become the primary path and I/O will continue.

       If all paths are still failed after the repair attempt, the multi-
       path disk I/O instance becomes unusable and will begin to issue I/O
       errors to the calling applications to inform them that their I/O is
       no longer being stored to disk.

       Once you repair the hardware, you can tell the multi-path disk I/O
       instance that one or more of the paths have been repaired.  The
       instance will test the path to ensure it is working again.  If it is
       working, it will be marked as the primary path and the instance will
       become usable again.  I/O will then be allowed to the disk.

   CLUSTER DISKS
       All multi-path disk I/O functionality is available on cluster disks.
       You can run multi-path disk I/O instances on each node for each disk
       to fully protect them from controller failures.

       When new paths are linked to a cluster multi-path disk instance, it
       is not verified immediately.  Doing so would cause I/O errors on the
       other nodes of the cluster.  Instead, each path is verified
       immediately before it is put into use.  So, if a path is switched to,
       it is verified for configuration correctness then.  If it is ok, it
       will be used.  If it not valid, it will be declared failed, and
       another path will be chosen.  The data remains fully protected during
       these operations.

   BOOTING FROM MULTI-PATH DISKS
       You may use multi-path disk I/O on all physical disks, regardless of
       what virtual disks they contain.  You may use it on physical disks
       that contain root, usr, and swap if you care to.  If the initial
       primary path to your boot disk fails, you will need to boot the
       system using one of the alternate paths instead.  You should take
       this into account when setting up automatic reboot paths.  See
       dg_sysctl(1M) for details.

   ADMIOPATH
       The admiopath(1M) command provides an easy command line interface for
       managing multi-path disk I/O relationships.  Since the relationships
       must be rebuilt each time the system is booted, the command saves the
       relationships in a file and will rebuild them as the system runs the
       rc init scripts.

       See the admiopath(1M) man page for more details on using the command
       to manage multi-path disk I/O relationships.

PROGRAMMING INTERFACE
       The ioctl(2) system call is used for all communication with the
       Multi-Path Disk I/O Subdriver.  Use the open(2) system call to open a
       channel to the /dev/vdm node, and issue all ioctl(2) commands through
       that channel.  See vdm(7) for more details on the programming
       interface.

       The <sys/ioctl.h> include file is required for communicating with the
       Multi-Path Disk I/O Subdriver.  The <errno.h>, <sys/dg_sysctl.h>,
       <sys/types.h>, <stdio.h>, and <unistd.h> include files will be
       helpful.

SUBDRIVER-SPECIFIC COMMANDS
   DG_VDMMPIO_SWITCH_PATHS
       Switch to using a different path to the disk.

   DG_VDMMPIO_PATH_REPAIRED
       Mark a path as repaired so it can be used again.

COMMON DISK COMMANDS
       The following commands are common to all device drivers that manage
       physical disks.  The VDM and the subdrivers support the commands on
       virtual disks as well, because they present the same interfaces as
       physical disks.

   DSKIOCGET
       This command returns the size of the virtual disk in sectors.  For
       virtual disks, one sector is one disk block, or 512 bytes.  The
       command and associated structure is described in more detail in
       dsk(7).

   DSKIOCUSAGE
       This command returns I/O count and performance statistics on the I/O
       issued to a virtual disk.  The command and associated packet is
       described in more detail in dsk(7).

SUBDRIVER-SPECIFIC DEFINES
   DG_VDMMPIO_SUBDRIVER_ID
       The unique ID that identifies the Multi-Path Disk I/O Subdriver.

   DG_VDMMPIO_IOCTL_PACKET_VERSION_0
       The version zero stamp used in all Multi-Path Disk I/O Subdriver
       ioctl(2) packets.

       The stamp indicates which version of the Multi-Path Disk I/O
       Subdriver interface is being used and allows the Multi-Path Disk I/O
       Subdriver to support previous versions without requiring that
       applications be recompiled.

   DG_VDMMPIO_MAX_PATHS
       The maximum number of paths that can be managed by a multi-path I/O
       instance.

STRUCTURES
   dg_vdmmpio_create_packet
       The Multi-Path Disk I/O Subdriver ioctl(2) packet for creating a new
       multi-path disk instance.  Put a pointer to this packet into the
       packet for the DG_VDM_INSERT_INSTANCE command.

       Multi-path disk instances may not be created.  They must be inserted
       on top of the physical instance controlling an existing registered
       physical disk.

       struct      dg_vdmmpio_create_packet
           {
           int                 version;
           unsigned short      number_of_paths;
           dev_t               path_device_numbers [DG_VDMMPIO_MAX_PATHS];
           };

       version
              The version of the packet.

       number_of_paths
              The number of paths in the multi-path disk instance.

       path_device_numbers
              An array of device numbers for the virtual disks that are the
              paths to the multi-path disk.  The path in element zero of the
              array is considered to be the initial primary path.  Put the
              number of paths into number_of_paths.

   dg_vdmmpio_get_child_packet
       The Multi-Path Disk I/O Subdriver ioctl(2) packet for getting child
       role information about the children of a multi-path disk instance.
       Put a pointer to this packet into the child instance sub-packet for
       the DG_VDM_GET_CHILD_INSTANCE command.

       struct      dg_vdmmpio_get_child_packet
           {
           int             version;
           unsigned int    primary : 1;
           unsigned int    failed  : 1;
           };

       version
              The version of the packet.

       primary
              A returned flag indicating whether the path is the primary
              path that is in use.  If set to one, it is the primary path
              and is being used for I/O.

       failed A returned flag indicating whether the path has failed due to
              an I/O error.  If set to one, the path has failed.

   dg_vdmmpio_switch_paths_packet
       The Multi-Path Disk I/O Subdriver ioctl(2) packet for forcing another
       path to become the primary path used for I/O to the multi-path disk
       instance.  Put a pointer to this packet into the argument field of
       the packet for the DG_VDM_IOCTL_SUBDRIVER command and set the command
       field to DG_VDMMPIO_SWITCH_PATHS.  Put the device number of the
       multi-path disk instance to update into the instance device number
       field.

       struct      dg_vdmmpio_switch_paths_packet
           {
           int     version;
           dev_t   new_primary_path_device_number;
           };

       version
              The version of the packet.

       new_primary_path_device_number
              The device number of the new primary path to use for I/O.

   dg_vdmmpio_path_repaired_packet
       The Multi-Path Disk I/O Subdriver ioctl(2) packet for marking a path
       as repaired so it can be used again to access a multi-path disk
       instance.  Put a pointer to this packet into the argument field of
       the packet for the DG_VDM_IOCTL_SUBDRIVER command and set the command
       field to DG_VDMMPIO_PATH_REPAIRED.  Put the device number of the
       multi-path disk instance to update into the instance device number
       field.

       struct     dg_vdmmpio_path_repaired_packet
               {
               int             version;
               dev_t           repaired_path;
               };

       version
              The version of the packet.

       repaired_path
              The device number of the path that has been repaired.

EXAMPLES
       The following code fragments illustrate how to use the packets and
       commands described in this man page.  The fragments are not complete
       and are not intended to be compilable or executable.  In particular,
       initialization code, instance locating code, and error handling are
       left out for brevity.

   Common includes and variables

       #include <errno.h>
       #include <sys/dg_sysctl.h>
       #include <sys/ioctl.h>
       #include <sys/types.h>
       #include <stdio.h>
       #include <unistd.h>

       int     status;             /* status from system call */
       int     vdm_channel;        /* channel to /dev/vdm node */

   Insert a multi-path disk I/O instance

       dev_t   mpio_instance;
       dev_t   dummy_instance;
       dev_t   insert_instance;
       dev_t   path_0_instance;
       struct  dg_vdm_create_instance_packet   create_pkt;
       struct  dg_vdm_insert_instance_packet   insert_pkt;
       struct  dg_vdmmpio_create_packet        mpio_create_pkt;

       /*  Create a non-persistent dummy instance. */

       create_pkt.version             = DG_VDM_IOCTL_PACKET_VERSION_0;
       create_pkt.subdriver_id        = DG_VDMDUMMY_SUBDRIVER_ID;
       create_pkt.persistent          = 0;
       create_pkt.enable_disk_updates = 0;
       create_pkt.instance_name [0]   = '\0';
       create_pkt.subdriver_attributes_packet_ptr = NULL;

       status = ioctl (vdm_channel,
                       DG_VDM_CREATE_INSTANCE,
                       &create_pkt);

       dummy_instance = create_pkt.device_number;

       /*  Insert the mpio instance. */

       insert_pkt.version               = DG_VDM_IOCTL_PACKET_VERSION_0;
       insert_pkt.instance_to_change    = insert_instance;
       insert_pkt.dummy_instance        = dummy_instance;
       insert_pkt.subdriver_id          = DG_VDMMPIO_SUBDRIVER_ID;
       insert_pkt.attributes_packet_ptr = &mpio_create_pkt;

       mpio_create_pkt.version = DG_VDMMPIO_IOCTL_PACKET_VERSION_0;
       mpio_create_pkt.number_of_paths         = 1;
       mpio_create_pkt.path_device_numbers [0] = dummy_instance;

       status = ioctl (vdm_channel,
                       DG_VDM_INSERT_INSTANCE,
                       &insert_pkt);

       mpio_instance  = insert_instance;
       path_instance = dummy_instance;

   Extract a multi-path disk I/O instance

       dev_t   mpio_instance;
       dev_t   child_instance;
       dev_t   dummy_instance;
       dev_t   extract_instance;
       struct  dg_vdm_create_instance_packet   create_pkt;
       struct  dg_vdm_delete_instance_packet   delete_pkt;
       struct  dg_vdm_extract_instance_packet  extract_pkt;

       /*  Create a non-persistent dummy instance. */

       create_pkt.version             = DG_VDM_IOCTL_PACKET_VERSION_0;
       create_pkt.subdriver_id        = DG_VDMDUMMY_SUBDRIVER_ID;
       create_pkt.persistent          = 0;
       create_pkt.enable_disk_updates = 0;
       create_pkt.instance_name [0]   = '\0';
       create_pkt.subdriver_attributes_packet_ptr = NULL;

       status = ioctl (vdm_channel,
                       DG_VDM_CREATE_INSTANCE,
                       &create_pkt);

       dummy_instance = create_pkt.device_number;

       /*  Extract the mpio instance. */

       extract_pkt.version                  = DG_VDM_IOCTL_PACKET_VERSION_0;
       extract_pkt.parent_device_number     = extract_instance;
       extract_pkt.new_parent_device_number = dummy_instance;

       status = ioctl (vdm_channel,
                       DG_VDM_EXTRACT_INSTANCE,
                       &extract_pkt);

       mpio_instance  = dummy_instance;
       dummy_instance = child_instance;

       /*  Delete the leftover instance and the child dummy instance. */

       delete_pkt.version       = DG_VDM_IOCTL_PACKET_VERSION_0;
       delete_pkt.device_number = mpio_instance;

       status = ioctl (vdm_channel,
                       DG_VDM_DELETE_INSTANCE,
                       &delete_pkt);

       delete_pkt.device_number = dummy_instance;

       status = ioctl (vdm_channel,
                       DG_VDM_DELETE_INSTANCE,
                       &delete_pkt);

   Link a path to a multi-path disk I/O instance

       dev_t   link_instance;
       dev_t   disk_device;
       dev_t   phys_instance;
       struct  dg_vdm_create_instance_packet       create_pkt;
       struct  dg_vdmphys_create_packet            phys_create_pkt;
       struct  dg_vdm_link_child_instance_packet   link_pkt;

       /*  Create a non-persistent physical instance for the disk. */

       create_pkt.version             = DG_VDM_IOCTL_PACKET_VERSION_0;
       create_pkt.subdriver_id        = DG_VDMPHYS_SUBDRIVER_ID;
       create_pkt.persistent          = 0;
       create_pkt.enable_disk_updates = 0;
       create_pkt.instance_name [0]   = '\0';
       create_pkt.subdriver_attributes_packet_ptr = &phys_create_pkt;

       phys_create_pkt.version = DG_VDMPHYS_CREATE_PACKET_VERSION_1;
       phys_create_pkt.open_flag = O_RDWR;
       phys_create_pkt.child_device_number = disk_device;
       phys_create_pkt.cluster_mode = 0;

       status = ioctl (vdm_channel,
                       DG_VDM_CREATE_INSTANCE,
                       &create_pkt);

       phys_instance = create_pkt.device_number;

       /*  Link the new path to the mpio instance. */

       link_pkt.version               = DG_VDM_IOCTL_PACKET_VERSION_0;
       link_pkt.parent_device_number  = link_instance;
       link_pkt.parent_subdriver_id   = DG_VDMMPIO_SUBDRIVER_ID;
       link_pkt.child_device_number   = phys_instance;
       link_pkt.child_packet_ptr      = NULL;

       status = ioctl (vdm_channel,
                       DG_VDM_LINK_CHILD_INSTANCE,
                       &link_pkt);

   Get the children of a multi-path disk I/O instance

       int     i;
       dev_t   mpio_instance;
       dev_t   child_instance;
       struct  dg_vdm_child_instance_packet        child_pkt;
       struct  dg_vdm_get_child_instance_packet    get_child_pkt;
       struct  dg_vdmmpio_get_child_packet         mpio_get_child_pkt;

       get_child_pkt.version                  = DG_VDM_IOCTL_PACKET_VERSION_0;
       get_child_pkt.key                      = 0;
       get_child_pkt.parent_device_number     = mpio_instance;
       get_child_pkt.parent_subdriver_id      = DG_VDMMPIO_SUBDRIVER_ID;
       get_child_pkt.available                = 0;
       get_child_pkt.child_instance_array_ptr = NULL;

       status = ioctl (vdm_channel,
                       DG_VDM_GET_CHILD_INSTANCE,
                       &get_child_pkt);

       printf ("Number of children = %d\n",
               get_child_pkt.number_of_children);

       get_child_pkt.key                      = 0;
       get_child_pkt.available                = 1;
       get_child_pkt.child_instance_array_ptr = &child_pkt;

       child_pkt.child_role_packet_ptr = &mpio_get_child_pkt;

       mpio_get_child_pkt.version = DG_VDMMPIO_IOCTL_PACKET_VERSION_0;

       i = 0;

       while (1)
           {
           status = ioctl (vdm_channel,
                           DG_VDM_GET_CHILD_INSTANCE,
                           &get_child_pkt);

           if ((status == -1) && (errno == ENOENT))
               {
               break;
               }

           printf ("Path %d\n", i);

           if (child_pkt.child_instance.device_number_used)
               {
               child_instance = child_instance_pkt.child_instance.
                                specifier_value.device_number;

               printf ("Child device number = 0x%08x\n", child_instance);

               if (child_pkt.child_subdriver_id ==
                   DG_VDM_SUBDRIVER_ID_OF_A_NON_VDM_DEVICE)
                   {
                   printf ("  Non-vdm child\n");
                   }
               else
                   {
                   printf ("  Child subdriver 0x%08x\n",
                           child_pkt.child_subdriver_id);
                   }
               }
           else
               {
               printf ("  Missing child ID %08x,%08x\n",
                       child_pkt.child_instance.specifier_value.id.generation,
                       child_pkt.child_instance.specifier_value.id.system_id);
               }

           if (mpio_get_child_pkt.primary)
               {
               printf ("  Path is primary\n");
               }

           if (mpio_get_child_pkt.failed)
               {
               printf ("  Path has failed\n");
               }

           printf ("\n");
           i++;
           }

   Unlink a path from a mpio

       dev_t   unlink_instance;
       dev_t   child_instance;
       struct  dg_vdm_unlink_child_instance_packet   unlink_pkt;

       unlink_pkt.version               = DG_VDM_IOCTL_PACKET_VERSION_0;
       unlink_pkt.parent_device_number  = unlink_instance;
       unlink_pkt.child_instance.device_number_used = 1;
       unlink_pkt.child_instance.specifier_value.device_number =
           child_instance;

       status = ioctl (vdm_channel,
                       DG_VDM_UNLINK_CHILD_INSTANCE,
                       &unlink_pkt);

   Switch a multi-path disk I/O instance to a new path

       dev_t   mpio_instance;
       dev_t   new_path_instance
       struct  dg_vdm_ioctl_subdriver_packet       ioctl_pkt;
       struct  dg_vdmmpio_switch_paths_packet      switch_path_pkt;

       ioctl_pkt.version                = DG_VDM_IOCTL_PACKET_VERSION_0;
       ioctl_pkt.subdriver_id           = DG_VDMMPIO_SUBDRIVER_ID;
       ioctl_pkt.instance_device_number = mpio_instance;
       ioctl_pkt.command                = DG_VDMMPIO_SWITCH_PATHS;
       ioctl_pkt.argument               = (int) &switch_path_pkt;

       switch_path_pkt.version = DG_VDMMPIO_IOCTL_PACKET_VERSION_0;
       switch_path_pkt.new_primary_path_device_number = new_path_instance;

       status = ioctl (vdm_channel,
                       DG_VDM_IOCTL_SUBDRIVER,
                       &ioctl_pkt);

   Mark a failed multi-path disk I/O path as repaired

       dev_t   mpio_instance;
       dev_t   repaired_path_instance
       struct  dg_vdm_ioctl_subdriver_packet       ioctl_pkt;
       struct  dg_vdmmpio_path_repaired_packet     path_repaired_pkt;

       ioctl_pkt.version                = DG_VDM_IOCTL_PACKET_VERSION_0;
       ioctl_pkt.subdriver_id           = DG_VDMMPIO_SUBDRIVER_ID;
       ioctl_pkt.instance_device_number = mpio_instance;
       ioctl_pkt.command                = DG_VDMMPIO_PATH_REPAIRED;
       ioctl_pkt.argument               = (int) &path_repaired_pkt;

       path_repaired_pkt.version       = DG_VDMMPIO_IOCTL_PACKET_VERSION_0;
       path_repaired_pkt.repaired_path = repaired_path_instance;

       status = ioctl (vdm_channel,
                       DG_VDM_IOCTL_SUBDRIVER,
                       &ioctl_pkt);

   Get the size of a multi-path disk I/O instance

       dev_t   ioctl_instance;
       struct  dg_vdm_ioctl_subdriver_packet       ioctl_pkt;
       struct  dskget                              dskget_pkt;

       ioctl_pkt.version                = DG_VDM_IOCTL_PACKET_VERSION_0;
       ioctl_pkt.subdriver_id           = DG_VDMMPIO_SUBDRIVER_ID;
       ioctl_pkt.instance_device_number = ioctl_instance;
       ioctl_pkt.command                = DSKIOCGET;
       ioctl_pkt.argument               = (int) &dskget_pkt;

       status = ioctl (vdm_channel,
                       DG_VDM_IOCTL_SUBDRIVER,
                       &ioctl_pkt);

       printf ("Total blocks = %u\n",
               dskget_pkt.total_sectors *
               (dskget_pkt.bytes_per_sector / 512));

FILES
       /dev/dsk
              Directory for the block special device nodes for virtual
              disks.  These are the buffered access device nodes.

       /dev/rdsk
              Directory for the character special device nodes for virtual
              disks.  These are the unbuffered (or raw) access device nodes.

       /dev/vdm
              Device node for issuing all ioctl(2) commands.

       /usr/include/sys/ioctl.h
              ioctl(2) definitions.

ACCESS CONTROL
       Access control for the standard VDM framework commands is controlled
       by the VDM itself.  See the vdm(7) man page for a listing of these
       controls.

       Access control for the Multi-Path Disk I/O Subdriver commands is
       controlled by the subdriver itself.

       All users may execute these commands: DG_VDM_GET_CHILD_INSTANCE,
       DSKIOCGET, DSKIOCUSAGE.

       Only users with appropriate privilege may execute these commands:
       DG_VDM_EXTRACT_INSTANCE, DG_VDM_INSERT_INSTANCE,
       DG_VDM_LINK_CHILD_INSTANCE, DG_VDM_UNLINK_CHILD_INSTANCE,
       DG_VDMMPIO_SWITCH_PATHS, DG_VDMMPIO_PATH_REPAIRED.

       On a generic DG/UX system, appropriate privilege is granted by having
       an effective UID of 0 (root).  See the appropriate_privilege(5) man
       page for more information.

       On a system with DG/UX information security, appropriate privilege is
       granted by having one or more specific capabilities enabled in the
       effective capability set of the user.  See the cap_defaults(5) man
       page for the default capabilities for these commands.

RETURN VALUE
       The return value from the ioctl(2) system call used to issue the
       command will be one of the following:

       0      The command was successful.

       -1     An error occurred.  errno is set to indicate the error.

DIAGNOSTICS
       There are descriptive extended error message strings available for
       most of the error codes.  They can be retrieved with the
       dg_ext_errno(2), extended_strerror(3C), and extended_perror(3C)
       routines.

       Errno may be set to one of the DG/UX standard error codes.  See
       /usr/include/sys/errno.h for a listing of those error codes.

       Errno may be set to one of the standard error codes provided by the
       VDM framework.  See vdm(7) for a listing of those error codes.

       Errno may also be set to one of the following error codes that are
       specific to this subdriver:

       EBUSY      Cannot remove the primary path from a multi-path disk.

       EINVAL     There are no paths specified.

       EINVAL     There are too many paths specified.

       EINVAL     The maximum number of paths are already defined.

       EINVAL     Cannot remove the last path from a multi-path disk.

       EINVAL     The path to a multi-path disk must be of type 'physical'.

       EINVAL     The path for the multi-path disk does not need to be
                  repaired.

       EINVAL     The path for the multi-path disk has already failed.

       EINVAL     The path is already the primary path for the multi-path
                  disk.

       EINVAL     The disk and/or controller does not support multi-path I/O
                  access.

       EINVAL     Multi-path disks must be DG/UX formatted.

       EINVAL     The path is not properly connected to the multi-path disk.
                  Check the disk cables.

       EINVAL     Cannot remove the initial primary path from a multi-path
                  disk.

       ENXIO      The virtual disk is not a path of the multi-path disk.

       EOPNOTSUPP Multi-path virtual disks must be inserted on top of VDM
                  registered disks.

SEE ALSO
       admiopath(1M), ioctl(2), dsk(7), rdsk(7), vdm(7).


Licensed material--property of copyright holder(s)

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026