Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ vdmphys(7) — DG/UX R4.11

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

ioctl(2)

dsk(7)

rdsk(7)

vdm(7)



vdmphys(7)                       DG/UX R4.11                      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 so that they do have a name.  This name then becomes 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 ORDWR to ORDONLY,
       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 ORDONLY to ORDWR 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 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 DGVDMCLUSTERDISK 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 currently does not support changing a cluster
       disk into read-only mode.

       Do not change the shared/private mode of the physical disk 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 EXTRACT 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/dgsysctl.h>, <sys/types.h>,
       <stdio.h>, and <unistd.h> include files will be helpful.

SUBDRIVER-SPECIFIC COMMANDS
   DGVDMPHYSFINDPHYSICAL
       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).

       This command is also used to trigger parent instances to get the
       sizes of their children again after one of the children has changed
       size.  After you change the size of the child, you must issue
       DSKIOCGET commands to all the ancestors of the child, so that they
       will update their sizes as well.

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

   DGVDMPHYSIOCTLPACKETVERSION0
       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.

   DGVDMPHYSCREATEPACKETVERSION1
       The stamp used in version one of the dgvdmphyscreatepacket.

   DGVDMPHYSGETPACKETVERSION1
       The stamp used in version one of the dgvdmphysgetpacket.

   DGVDMPHYSUPDATEPACKETVERSION1
       The stamp used in version one of the dgvdmphysupdatepacket.

STRUCTURES
   dgvdmphyscreatepacket
       The Physical Subdriver ioctl(2) packet for creating a new physical
       instance.  Put a pointer to this packet into the packet for the
       DGVDMCREATEINSTANCE 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
              DGVDMPHYSIOCTLPACKETVERSION0 or
              DGVDMPHYSCREATEPACKETVERSION1, depending on which version
              of the packet you want to use.

       openflag
              The flag controlling the read/write mode of the physical
              instance.  Set it to ORDONLY for read-only mode, or ORDWR
              for read/write mode.

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

       clustermode
              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 only used if the packet version is set to
              DGVDMPHYSCREATEPACKETVERSION1.

   dgvdmphysgetpacket
       The Physical Subdriver ioctl(2) packet for getting information about
       a physical instance.  Put a pointer to this packet into the packet
       for the DGVDMGETATTRIBUTES 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
              DGVDMPHYSIOCTLPACKETVERSION0 or
              DGVDMPHYSGETPACKETVERSION1, depending on which version of
              the packet you want to use.

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

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

       clustermode
              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 only used if the packet version is set to
              DGVDMPHYSGETPACKETVERSION1.

   dgvdmphysupdatepacket
       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 DGVDMUPDATEATTRIBUTES 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
              DGVDMPHYSIOCTLPACKETVERSION0 or
              DGVDMPHYSUPDATEPACKETVERSION1, depending on which version
              of the packet you want to use.

       openflag
              The flag controlling the read/write mode of the physical
              instance.  Set it to ORDONLY for read-only mode, or ORDWR
              for read/write mode.

              You may not update the openflag and the clustermode at the
              same time.  Make each change separately.

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

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

       clustermode
              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 only used if updateclustermode is set to one.

              You may not update the openflag and the clustermode 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.  To do
              so, first make them read/write, then change their cluster
              mode, then make then read-only again.

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

       updateopenflag
              If set to one, it indicates that the openflag 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 openflag and the clustermode at the
              same time.  Make each change separately.

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

       updateclustermode
              If set to one, it indicates that the clustermode 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 openflag and the clustermode 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 only used if the packet version is set to
              DGVDMPHYSUPDATEPACKETVERSION1.

   dgvdmphysfindphysicalpacket
       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
       DGVDMIOCTLSUBDRIVER command, and set the command field to
       DGVDMPHYSFINDPHYSICAL.  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.

       diskdevicenumber
              The device number of the physical disk to locate.

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

EXAMPLES
       The following code fragments illustrate the use of 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 instances 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.  Below is the listing of these commands.

       All users may execute these commands: DGVDMPHYSFINDPHYSICAL,
       DSKIOCGET (to get the size of an instance), DSKIOCUSAGE.

       Only users with appropriate privilege may execute these commands:
       DSKIOCGET (to change the size of a parent instance).

       On a generic DG/UX system, appropriate privilege is granted by having
       an effective UID of 0 (root).  See the appropriateprivilege(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 capdefaults(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
       dgexterrno(2), extendedstrerror(3C), and extendedperror(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