Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

ioctl(2)

dsk(7)

rdsk(7)

vdm(7)



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


NAME
       vdmphys - Virtual Disk Manager Physical Subdriver

DESCRIPTION
       The Physical Subdriver translates internal VDM interfaces for virtual
       disks into physical disk device driver interfaces.  A physical
       instance must exist at the bottom of every virtual disk hierarchy.

       A physical instance manages one specific physical disk.  The physical
       instance can be used to access all blocks of the disk, so partitions
       are usually created on top of the physical instance to subdivide the
       disk into usable regions.

       The Physical Subdriver implements a read/write or read-only flag so
       that disks can be made read-only if desired.  Most fixed hard disks
       do not have a hardware tab or jumper that can be used to make the
       disk read-only, so the Physical Subdriver supports it in software.

       Finally, the Physical Subdriver implements a cluster or non-cluster
       flag to control the cluster mode of the physical disk.

       Pictorially, a physical instance for a physical disk looks like this:

                           +-------------------+
                           | physical          |
                           | sd(ncsc(0,7),0,0) |
                           +-------------------+
                                     |
                                     |
                                 ----------
                                (          )
                                (          )
                                (   disk   )
                                (   drive  )
                                (     1    )
                                (          )
                                 ----------

       The physical instance's only child is always a physical disk.
       Physical instances cannot control tape drives, terminal lines, etc.,
       only true physical disks.

       Physical instances can control any type of removable or non-removable
       hard disk, including traditional magnetic disks, CLARiiON® disks,
       floppy disks, and CD-ROMs.  All device controller types supported by
       DG/UX are supported by the Physical Subdriver.

       Physical instances are generally invisible on the system.  They are
       created automatically when you format a disk with sysadm(1M) or
       admpdisk(1M).  Whenever you use sysadm(1M) or admvdisk(1M) to get the
       name of a physical instance in a listing, you will get the name of
       the physical disk that it is managing instead, since the name of the
       physical disk is usually more important.

       Physical instances are generally created without a name.  You can
       rename them if you care to.  The name will then become a sort of
       "volume label" for the disk.  Choose names that reflect the data
       stored on the disk, like "Payroll_Disk" or "Home_Dirs_Disk".  You can
       use these names when specifying physical disks to sysadm(1M),
       admvdisk(1M), and admpdisk(1M) while the disks are registered.

       Do not use the name of the physical disk as the name of the physical
       instance, since the physical disk name will change if you move the
       disk around on your system.  The out-of-date physical instance name
       would then cause confusion.

       In order to use the Physical Subdriver, you must configure vdmphys()
       into your kernel.  It appears in all new system files by default, so
       it is usually already configured.

       For more details about how the Physical Subdriver fits into the
       Virtual Disk Manager, see the vdm(7) man page.

   READ-ONLY DISKS
       Since most physical disks do not have hardware tabs or jumpers that
       can be used to make them read-only, the Physical Subdriver implements
       the feature in software instead.

       By changing the open flag of the instance from O_RDWR to O_RDONLY,
       the physical instance will treat the disk as if it were read-only.
       All writes to a read-only physical instance will return an error.
       The physical instance can be changed back from O_RDONLY to O_RDWR as
       well.

       This is useful if a disk contains archival information that is never
       supposed to be changed.  You would write the data to the disk while
       the physical instance was read/write, then unmount all the file
       systems on it and close the databases on it, and finally change the
       physical instance for the disk to read-only mode.  That will prevent
       any further modifications to the user data stored on the disk, as
       well as the VDM metadata stored in the VDITs.

       The file systems on a read-only disk will have to be mounted read-
       only as well, in order to use them properly.

   CLUSTER DISKS
       The Physical Subdriver implements the low-level support for cluster
       disks.  This involves placing cluster disks into shared mode and non-
       cluster disks into private mode.

       You cannot change the cluster mode of a physical instance directly.
       Instead, use the DG_VDM_CLUSTER_DISK command, which will coordinate
       all the necessary virtual disk changes along with the change of the
       physical instance into cluster or non-cluster mode.

       You can query a physical instance to see if it is in cluster mode
       without restrictions.

       The Physical Subdriver does not support changing a cluster disk into
       read-only mode.

       Do not change the shared/private mode of the physical disk that a
       physical instance is managing by hand.  Doing so will open the disk
       up to serious potential data corruption.  Let the physical instance
       manage the disk safely.

   USABILITY
       A physical instance is usable as long as the physical disk it is
       controlling is usable.  If the physical disk fails due to a hardware
       problem, the physical instance will likewise be unusable.

   INSERTING AND EXTRACTING PHYSICAL INSTANCES
       Physical instances cannot be inserted or extracted.  Since insert and
       extract require a virtual disk child, and the physical instance
       always has a physical disk child, the operations simply can't be
       done.

PROGRAMMING INTERFACE
       The ioctl(2) system call is used for all communication with the
       Physical 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
       Physical 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_VDMPHYS_FIND_PHYSICAL
       Finds the physical instance that manages a physical disk.

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_VDMPHYS_SUBDRIVER_ID
       The unique ID that identifies the Physical Subdriver.

   DG_VDMPHYS_IOCTL_PACKET_VERSION_0
       The version zero stamp used in all Physical Subdriver ioctl(2)
       packets.

       The stamp indicates which version of the Physical Subdriver interface
       is being used and allows the Physical Subdriver to support previous
       versions without requiring that applications be recompiled.

   DG_VDMPHYS_CREATE_PACKET_VERSION_1
       The stamp used in version one of the dg_vdmphys_create_packet.

   DG_VDMPHYS_GET_PACKET_VERSION_1
       The stamp used in version one of the dg_vdmphys_get_packet.

   DG_VDMPHYS_UPDATE_PACKET_VERSION_1
       The stamp used in version one of the dg_vdmphys_update_packet.

STRUCTURES
   dg_vdmphys_create_packet
       The Physical Subdriver ioctl(2) packet for creating a new physical
       instance.  Put a pointer to this packet into the packet for the
       DG_VDM_CREATE_INSTANCE command.

       There are two versions of this packet.  Unless otherwise stated
       below, all fields are used in all versions.

       struct      dg_vdmphys_create_packet
           {
           int             version;
           int             open_flag;
           dev_t           child_device_number;
           unsigned int    cluster_mode : 1;
           };

       version
              The version of the packet.  Set this to either
              DG_VDMPHYS_IOCTL_PACKET_VERSION_0 or
              DG_VDMPHYS_CREATE_PACKET_VERSION_1, depending on which version
              of the packet you want to use.

       open_flag
              The flag controlling the read/write mode of the physical
              instance.  Set it to O_RDONLY for read-only mode, or O_RDWR
              for read/write mode.

       child_device_number
              The device number of the physical disk that the physical
              instance is to manage.

       cluster_mode
              If set to one, it indicates that the physical instance and
              physical disk are to be put into cluster mode.  If set to
              zero, it indicates that they are to be put into non-cluster
              mode.

              Users may not set this field to one.  Only the DG/UX system is
              permitted to put disks into cluster mode.

              This field is used only if the packet version is set to
              DG_VDMPHYS_CREATE_PACKET_VERSION_1.

   dg_vdmphys_get_packet
       The Physical Subdriver ioctl(2) packet for getting information about
       a physical instance.  Put a pointer to this packet into the packet
       for the DG_VDM_GET_ATTRIBUTES command.

       There are two versions of this packet.  Unless otherwise stated
       below, all fields are used in all versions.

       struct      dg_vdmphys_get_packet
           {
           int             version;
           int             open_flag;
           dev_t           child_device_number;
           unsigned int    cluster_mode : 1;
           };

       version
              The version of the packet.  Set this to either
              DG_VDMPHYS_IOCTL_PACKET_VERSION_0 or
              DG_VDMPHYS_GET_PACKET_VERSION_1, depending on which version of
              the packet you want to use.

       open_flag
              The returned flag indicating the read/write mode of the
              physical instance.  If set to O_RDONLY, it indicates that the
              physical instance is in read-only mode.  If set to O_RDWR, it
              is in read/write mode.

       child_device_number
              The returned device number of the physical disk that the
              physical instance is managing.

       cluster_mode
              The returned clustering mode of the physical instance and
              physical disk.  If set to one, it indicates that the physical
              instance and physical disk are in cluster mode.  If set to
              zero, it indicates that they are in non-cluster mode.

              This field is used only if the packet version is set to
              DG_VDMPHYS_GET_PACKET_VERSION_1.

   dg_vdmphys_update_packet
       The Physical Subdriver ioctl(2) packet for updating the attributes of
       a physical instance.  Put a pointer to this packet into the packet
       for the DG_VDM_UPDATE_ATTRIBUTES command.

       There are two versions of this packet.  Unless otherwise stated
       below, all fields are used in all versions.

       struct      dg_vdmphys_update_packet
           {
           int             version;
           int             open_flag;
           unsigned int    cluster_mode        : 1;
           unsigned int    update_open_flag    : 1;
           unsigned int    update_cluster_mode : 1;
           };

       version
              The version of the packet.  Set this to either
              DG_VDMPHYS_IOCTL_PACKET_VERSION_0 or
              DG_VDMPHYS_UPDATE_PACKET_VERSION_1, depending on which version
              of the packet you want to use.

       open_flag
              The flag controlling the read/write mode of the physical
              instance.  Set it to O_RDONLY for read-only mode, or O_RDWR
              for read/write mode.

              You may not update the open_flag and the cluster_mode at the
              same time.  Make each change separately.

              If the packet version is DG_VDMPHYS_IOCTL_PACKET_VERSION_0,
              this field is used without any conditions.

              If the packet version is DG_VDMPHYS_UPDATE_PACKET_VERSION_1,
              then this field is used only if update_open_flag is set to
              one.

       cluster_mode
              If set to one, it indicates that the physical instance and
              physical disk are to be changed from non-cluster mode to
              cluster mode.  If set to zero, it indicates that they are to
              be changed from cluster mode to non-cluster mode.  This field
              is used only if update_cluster_mode is set to one.

              You may not update the open_flag and the cluster_mode at the
              same time.  Make each change separately.

              Users may not set this field.  Only the DG/UX system is
              permitted to change the clustering mode of disks.

              You may not change the cluster mode of read-only disks.

              This field is used only if the packet version is set to
              DG_VDMPHYS_UPDATE_PACKET_VERSION_1.

       update_open_flag
              If set to one, it indicates that the open_flag field should be
              used to update the physical instance.  Otherwise, the physical
              instance's read/write mode will not be changed.

              You may not update the open_flag and the cluster_mode at the
              same time.  Make each change separately.

              This field is used only if the packet version is set to
              DG_VDMPHYS_UPDATE_PACKET_VERSION_1.

       update_cluster_mode
              If set to one, it indicates that the cluster_mode field should
              be used to update the physical instance.  Otherwise, the
              physical instance's cluster mode will not be changed.

              You may not update the open_flag and the cluster_mode at the
              same time.  Make each change separately.

              Users may not set this field to one.  Only the DG/UX system is
              permitted to change the clustering mode of disks.

              This field is used only if the packet version is set to
              DG_VDMPHYS_UPDATE_PACKET_VERSION_1.

   dg_vdmphys_find_physical_packet
       The Physical Subdriver ioctl(2) packet for finding the device number
       of the physical instance that is managing a physical disk.  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_VDMPHYS_FIND_PHYSICAL.  Set the instance device number field to
       NODEV, so the command will be issued to the Physical Subdriver
       itself.

       struct      dg_vdmphys_find_physical_packet
           {
           int     version;
           dev_t   disk_device_number;
           dev_t   instance_device_number;
           };

       version
              The version of the packet.

       disk_device_number
              The device number of the physical disk to locate.

       instance_device_number
              The returned device number of the physical instance that is
              managing the physical disk.

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 */

   Create a physical instance

       dev_t   phys_instance;
       dev_t   disk_device;
       struct  dg_vdm_create_instance_packet   create_pkt;
       struct  dg_vdmphys_create_packet        phys_create_pkt;

       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;

       printf ("Physical instance device number = 0x%08x\n", phys_instance);

   Update a physical instance's open flag

       dev_t   update_instance;
       struct  dg_vdm_update_attributes_packet     update_attrs_pkt;
       struct  dg_vdmphys_update_packet            phys_update_pkt;

       update_attrs_pkt.version                = DG_VDM_IOCTL_PACKET_VERSION_0;
       update_attrs_pkt.instance_device_number = update_instance;
       update_attrs_pkt.subdriver_id           = DG_VDMPHYS_SUBDRIVER_ID;
       update_attrs_pkt.subdriver_attributes_packet_ptr = &phys_update_pkt;

       phys_update_pkt.version = DG_VDMPHYS_UPDATE_PACKET_VERSION_1;
       phys_update_pkt.open_flag           = O_RDONLY;
       phys_update_pkt.update_open_flag    = 1;
       phys_update_pkt.update_cluster_mode = 0;

       status = ioctl (vdm_channel,
                       DG_VDM_UPDATE_ATTRIBUTES,
                       &update_attrs_pkt);

   Get a physical instance's attributes

       dev_t   get_instance;
       struct  dg_vdm_get_attributes_packet    get_attrs_pkt;
       struct  dg_vdmphys_get_packet           phys_get_pkt;

       get_attrs_pkt.version                = DG_VDM_IOCTL_PACKET_VERSION_0;
       get_attrs_pkt.instance_device_number = get_instance;
       get_attrs_pkt.subdriver_id           = DG_VDMPHYS_SUBDRIVER_ID;
       get_attrs_pkt.subdriver_attributes_packet_ptr = &phys_get_pkt;

       phys_get_pkt.version = DG_VDMPHYS_GET_PACKET_VERSION_1;

       status = ioctl (vdm_channel,
                       DG_VDM_GET_ATTRIBUTES,
                       &get_attrs_pkt);

       switch (phys_get_pkt.open_flag)
           {
           case O_RDONLY:

               printf ("I/O mode       = read only\n");

               break;

           case O_RDWR:

               printf ("I/O mode       = read/write\n");

               break;
           }

       if (phys_get_pkt.cluster_mode)
           {
           printf ("Cluster mode   = cluster\n");
           }
       else
           {
           printf ("Cluster mode   = non-cluster\n");
           }

       printf ("Disk device number = 0x%08x\n",
               phys_get_pkt.child_device_number);

   Get the children of a physical instance

       int     i;
       dev_t   phys_instance;
       dev_t   child_instance;
       struct  dg_vdm_child_instance_packet        child_pkt;
       struct  dg_vdm_get_child_instance_packet    get_child_pkt;

       get_child_pkt.version                  = DG_VDM_IOCTL_PACKET_VERSION_0;
       get_child_pkt.key                      = 0;
       get_child_pkt.parent_device_number     = phys_instance;
       get_child_pkt.parent_subdriver_id      = DG_VDMPHYS_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 = NULL;

       i = 0;

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

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

           printf ("Child %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);
               }

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

   Find the physical instance managing a physical disk

       dev_t   disk_device;
       struct  dg_vdm_ioctl_subdriver_packet       ioctl_pkt;
       struct  dg_vdmphys_find_physical_packet     find_phys_pkt;

       ioctl_pkt.version                = DG_VDM_IOCTL_PACKET_VERSION_0;
       ioctl_pkt.subdriver_id           = DG_VDMPHYS_SUBDRIVER_ID;
       ioctl_pkt.instance_device_number = NODEV;
       ioctl_pkt.command                = DG_VDMPHYS_FIND_PHYSICAL;
       ioctl_pkt.argument               = (int) &find_phys_pkt;

       find_phys_pkt.version = DG_VDMPHYS_IOCTL_PACKET_VERSION_0;
       find_phys_pkt.disk_device_number = disk_device;

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

       printf ("Physical instance device number = 0x%08x\n",
               find_phys_pkt.instance_device_number);

   Get the size of a physical instance (the disk size)

       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_VDMPHYS_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 Physical Subdriver commands is controlled by
       the subdriver itself.

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

       Only users with appropriate privilege may execute these commands:
       DG_VDM_CREATE_INSTANCE, DG_VDM_UPDATE_ATTRIBUTES.

       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:

       EINVAL The open flag field is not valid.

       EINVAL Cannot open that type of device, only real disks are
              supported.

       EINVAL Cannot update the open flag and cluster mode at the same time.

       EINVAL Cannot change the cluster mode of read-only disks.

       EINVAL Cannot change the cluster mode of non-persistent 'physical'
              virtual disks.

       EIO    Cannot write to a read-only virtual disk.

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


Licensed material--property of copyright holder(s)

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