Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ vdmpart(7) — DG/UX 5.4R3.00

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

vdm(7)

vdmphys(7)

ioctl(2)



vdmpart(7)                     DG/UX 5.4R3.00                     vdmpart(7)


NAME
       vdmpart - Partition Subdriver of the Virtual Disk Manager

SYNOPSIS
       #include <types.h>
       #include <ioctl.h>

       ioctl(int fildes, int command, int argument);

DESCRIPTION
       The Partition Subdriver is a pseudo-device driver that works under
       the Virtual Disk Management (VDM) framework (see vdm(7)).  The
       purpose of the Partition Subdriver is to provide the ability to
       control the sharing of the space on a given virtual disk instance.

STRUCTURES
       The structures defined in this section are pointed to by fields
       described in VDM commands (see vdm(7)).  The VDM command and the
       field in the argument structure will be described.  For many VDM
       commands, a subdriver ID is required as an input value.  The
       subdriver ID for the Partition Subdriver is defined by
       DGVDMPARTSUBDRIVERID.

       All of the Partition Subdriver's packets contain a version field.
       This field provides compatibility to application programs not yet
       using the most up to date versions of the packets available.  Unless
       it is noted specifically, this field should be filled with the value
       DGVDMPARTIOCTLPACKETVERSION0.

   DGVDMCREATEINSTANCE
       The subdriverattributespacketptr field points to the following
       structure:

       struct dgvdmpartcreatepacket
            {
            int                version;
            devt              partitionedinstance;
            daddrt            startingblock;
            unsigned int       sizeinblocks;
            devt              remapdevicenumber;
            };

       The partitionedinstance field is an input field and identifies the
       instance that will be partitioned.  The startingblock field is an
       input field and provides the beginning displacement in blocks from
       the beginning of the partitioned instance.

       The input field sizeinblocks is the number of blocks in the
       partition.  This value must be greater than 0.

       The remapdevicenumber is an input field that identifies an instance
       the Partition Subdriver will use to handle any bad blocks that are
       encountered.  The remap instance supplied must have its children on
       the same partitioned instance (see vdmremap(7) for more).  If dynamic



Licensed material--property of copyright holder(s)                         1




vdmpart(7)                     DG/UX 5.4R3.00                     vdmpart(7)


       bad block remapping is not desired, then NODEV should be provided for
       this argument.

       The request for a partition will fail if it overlaps an existing
       partition or is not an available address on the partitioned instance.
       If an overlap is detected, then the call will fail and errno is set
       to EBUSY.

       If any part of the requested partition is off the end of the
       underlying instance as a result of the startingblock not existing on
       the device or the sizeinblocks causing the requested partition to
       be off of the device, the call will fail and errno will be set to
       EINVAL.

   DGVDMGETATTRIBUTES
       The subdriverattributespacketptr field points to the following
       structure:

       struct dgvdmpartgetpacket
            {
            int                version;
            daddrt            startingblock;
            unsigned int       sizeinblocks;
            };

       The startingblock is the block offset on the instance that this
       instance partitions (this can be obtained by getting the children of
       this partition).  The sizeinblocks is the number of blocks in the
       partition.

   DGVDMGETCHILDINSTANCE
       The childrolepacketptr points to the following structure:

       struct dgvdmpartgetchildpacket
           {
           int                  version;
           int                  childtype;
           union
               {
               struct
                   {
                   daddrt      startingblock;
                   unsigned int sizeinblocks;
                   } partitioned;
               } child;
           };

       A partition may have up to two children: on child represents the
       instance of which the partition resides; the other is an optional
       remap device.  As the children are being obtained, the childtype
       field will be set to indicate which child is being returned.  The the
       childtype field is set to DGVDMPARTPARTITIONEDCHILD, then the
       child returned is the partitioned instance and the partitioned
       portion of the child union is filled.  The partitioned.startingblock



Licensed material--property of copyright holder(s)                         2




vdmpart(7)                     DG/UX 5.4R3.00                     vdmpart(7)


       is the starting offset of the partition on the child.  The
       partitioned.sizeinblocks contains the number of blocks in the
       partition.

       If the childtype field is set to DGVDMPARTREMAPCHILD, then the
       partition uses dynamic bad block remapping and the remap instance is
       in the childinstance field of the VDM get child packet.  Since there
       is no additional information required, the child union above contains
       no data with respect to remap children.

   DGVDMUPDATEATTRIBUTES
       Use of this command changes the size of a partition.  The partition
       can either be increased or decreased in size. The
       subdriverattributespacketptr is a pointer to the following
       structure:

       struct dgvdmpartupdateattributespacket
           {
           int                version;
           int                changeinsize;
           };

       the changeinsize field should be used to change the size of the
       partition.  The changeinsize field is an input field that indicates
       the number of blocks the size of the partition is to change.  The
       field can be positive or negative, but not 0.  A positive value
       indicates a growth in size and a negative value indicates a reduction
       in size.

       The request for an increase in size may be rejected if it overlaps
       another partition.  In this case, the call will fail and errno will
       be set to EBUSY.

       Although this command can be performed while the partition is in use,
       it is dangerous to do this if it is done without cooperation of the
       application accessing the partition.  If the partition is increased
       in size, then the application may be oblivious to the change and
       unable to take advantage of it.  If the partition is reduced in size
       and the application does not respond to the decrease in size, all
       I/O's to the space beyond the end of the new size will be rejected.

       DG/UX file systems can respond to an increase in size while mounted,
       but not a decrease in size.

   DGVDMEXTRACTINSTANCE
       To extract an instance, it must have only one child and be the same
       size as its child.  Therefore, only partition instances that have no
       remap child and cover the entire partitioned child instance can be
       extracted.

   DGVDMLINKCHILDINSTANCE
       This command results in a child being added to an instance.  The only
       child that can be added to a partition is a remap instance.  The
       linking of a remap child to a partition instance enables bad block



Licensed material--property of copyright holder(s)                         3




vdmpart(7)                     DG/UX 5.4R3.00                     vdmpart(7)


       remapping for the instance.  Since it is the only child that can be
       added, no supplement packet is required to describe the role this
       child will play on the parent instance.  Therefore, the
       childpacketptr in the dgvdmlinkchildinstancepacket.

       The partitioned instance child of a partition instance is required at
       the time the partition is created and it cannot be unlinked from the
       instance.  If any other instance but a remap device is linked to a
       partition instance, the call will fail and errno will be set to
       EINVAL.

   DGVDMUNLINKCHILDINSTANCE
       This command results in a child being removed from an instance.  This
       can only be the remap child.  Unlinking the remap child from a
       partition instance will result in the partition's bad block remapping
       to be disabled.

IOCTLS
       The ioctls supported by the Partition Subdriver are listed below.
       The ioctl(2) command can be issued to the Partition Subdriver in two
       ways:

       1.     Issue the command to an exported instance of the Partition
              Subdriver.  In this case, the fd is an open file descriptor of
              the device node created when the instance was exported.  The
              command and the argument are described below.

       2.     Use the DGVDMIOCTLSUBDRIVER command described in more
              detail in vdm(7).  In this case, the fd is an open file
              descriptor of /dev/vdm device node.  The argument is a pointer
              to a structure that contains command and argument fields.  The
              values supplied for these fields are described below.

   DGVDMPARTLISTPARTITIONS
       This command returns the list of partitions on a given partitioned
       instance.  All of the partitions are returned in sorted order
       starting from the lowest starting address to the highest.  The
       argument is a pointer to the following structure:

       struct dgvdmpartlistpartitionspacket
           {
           int                 version;
           devt               partitionedinstance;
           keyt               key;
           devt               partitiondevicenumber;
           daddrt             startingblock;
           unsigned int        sizeinblocks;
           };

       The partitionedinstance is an input field that is the device number
       of a VDM instance.  If there are no partition instances that have the
       given partitioned instance as their children, no entries are
       returned.  The key is an input field and should be set to 0 when you
       want the list to start at the beginning.  After the first call to



Licensed material--property of copyright holder(s)                         4




vdmpart(7)                     DG/UX 5.4R3.00                     vdmpart(7)


       list the partitions, all remaining calls should not read or write the
       key. The partitiondevicenumber is an output field and is the device
       number of a partition instance on the partitioned instance.  The
       startingblock is the displacement on the partitioned instance where
       the partition starts.  The sizeinblocks is the size of the
       partition.

       When there are no more partitions to be listed, the call will return
       -1 and errno will be set to ENOENT.

   DSKIOCGET
       This command returns the size of an instance and is described in more
       detail in dsk(7).

   DSKIOCUSAGE
       This command returns statistics associated with the use of an
       instance and is described in more detail in dsk(7).

   DSKIOCGETADDRESS
       This command returns the logical address at which a given memory
       address to the specified instance should be mapped.

EXAMPLE
       #include <errno.h>
       #include <fcntl.h>
       #include <stdio.h>
       #include <string.h>
       #include <sys/dgsysctl.h>
       #include <sys/ioctl.h>
       #include <unistd.h>

       extern int errno;

       /*
        *  This example makes use of functions defined in the vdm(7) man page
        *  and the vdmphys(7) man page. These functions defined in the vdm(7)
        *  all begin with a vdm prefix and the functions defined in the
        *  vdmphys(7) man page begin with a vdmphys prefix.
        */

       /***********************************************************************
        *  This macro initializes a packet used by the Partition Subdriver.
        ***********************************************************************/
       #define vdminitpacket(p) \
               (bzero((char *)&p, sizeof(p)), \
               p.version = DGVDMIOCTLPACKETVERSION0);

       #define vdmpartinitpacket(p) \
               (bzero((char *)&p, sizeof(p)), \
               p.version = DGVDMPARTIOCTLPACKETVERSION0);

       /***********************************************************************
        *  This function searches a given instance for partitions that may
        *  belong to a remap instance.  This would indicate that bad block



Licensed material--property of copyright holder(s)                         5




vdmpart(7)                     DG/UX 5.4R3.00                     vdmpart(7)


        *  remapping is available to any partition created in the given
        *  instance.
        ***********************************************************************/
       devt vdmpartgetremapinstance (
       devt partitionedinstance
                                        )
       {
       int                                      status;
       struct dgvdmpartlistpartitionspacket partlistpkt;
       struct dgvdmgetparentinstancepacket getparentpkt;
       struct dgvdmparentinstancepacket     parentpkt;

       vdmpartinitpacket(partlistpkt);
       partlistpkt.partitionedinstance = partitionedinstance;
       partlistpkt.key = 0;
       while ( (status = vdmioctlsubdriver(
                             DGVDMPARTSUBDRIVERID,
                             NODEV,
                             DGVDMPARTLISTPARTITIONS,
                             (int)&partlistpkt)) == 0)
           {
           /* We know partitions only have one parent so there is no need to loop. */
           getparentpkt.key = 0;
           getparentpkt.parentinstancearrayptr = &parentpkt;
           getparentpkt.available = 1;
           getparentpkt.childdevicenumber = partlistpkt.partitiondevicenumber;
           status = vdmioctl(DGVDMGETPARENTINSTANCE, (int)&getparentpkt);
           if (status == 0)
               {
               if (parentpkt.parentsubdriverid == DGVDMREMAPSUBDRIVERID)
                   {
                   return(parentpkt.parentdevicenumber);
                   }
               }
           }
       return (NODEV);
       }

       /***********************************************************************
        *  This function creates a physical instance for the given device
        *  specification - like sd(insc(),0).
        ***********************************************************************/
       devt vdmpartcreateinstance (
       char *        instancename,
       daddrt       startingblock,
       unsigned long sizeinblocks,
       devt         partitionedinstance,
       devt         remapdevicenumber
                                     )
       {
       struct dgvdmpartcreatepacket createpkt;
       devt                           devicenumber;

       vdmpartinitpacket(createpkt);



Licensed material--property of copyright holder(s)                         6




vdmpart(7)                     DG/UX 5.4R3.00                     vdmpart(7)


       createpkt.partitionedinstance = partitionedinstance;
       createpkt.startingblock = startingblock;
       createpkt.sizeinblocks = sizeinblocks;
       createpkt.remapdevicenumber = remapdevicenumber;
       devicenumber = vdmcreateinstance(
                          instancename, DGVDMPARTSUBDRIVERID, &createpkt);

       return (devicenumber);
       }

       /***********************************************************************
        *  This function prints to the given output file the information
        *  about each partition on the given partitioned instance.
        ***********************************************************************/
       int vdmpartlistpartitions (
       FILE * output,
       devt  partitionedinstance
                                   )
       {
       int                                      status;
       struct dgvdmpartlistpartitionspacket listpartitionspkt;
       struct dgvdmgetinstanceinfopacket   getinfopkt;

       vdmpartinitpacket(listpartitionspkt);
       listpartitionspkt.partitionedinstance = partitionedinstance;
       listpartitionspkt.key = 0;

       while ( (status = vdmioctlsubdriver(
                      DGVDMPARTSUBDRIVERID,
                               NODEV,
                               DGVDMPARTLISTPARTITIONS,
                               (int)&listpartitionspkt)) == 0)
           {
           vdminitpacket(getinfopkt);
           getinfopkt.devicenumber = listpartitionspkt.partitiondevicenumber;
           status = vdmioctl(DGVDMGETINSTANCEINFO, &getinfopkt);
           if (status == -1)
               {
               return (status);
            }
           fprintf(output, "%s starts at block %d and is %d blocks long\n",
               getinfopkt.instancename,
               listpartitionspkt.startingblock,
               listpartitionspkt.sizeinblocks);
           }

       if (errno != ENOENT)
           {
           return (-1);
           }
       return (0);
       }

       /***********************************************************************



Licensed material--property of copyright holder(s)                         7




vdmpart(7)                     DG/UX 5.4R3.00                     vdmpart(7)


        *  This function resizes a given instance to a given change in size.
        ***********************************************************************/
       int vdmpartresizepartition (
       devt         partitioninstance,
       unsigned long changeinsize
                                    )
       {
       int                                        status;
       struct dgvdmpartupdateattributespacket updatepartitionpkt;

       vdmpartinitpacket(updatepartitionpkt);
       updatepartitionpkt.changeinsize = changeinsize;

       status = vdmupdateinstanceattributes(
                       partitioninstance,
                       DGVDMPARTSUBDRIVERID,
                       (int)&updatepartitionpkt);
       return (status);
       }

       int vdmpartexample (void)
       {
       int   status;
       devt physdevicenumber;
       devt partdevicenumber;

       /*
        *  Create a physical instance.
        */
       physdevicenumber = vdmphyscreateinstance("a", "sd(insc(),0)", ORDWR);
       if (physdevicenumber == NODEV)
           {
           perror("sd(insc(),0)");
           exit(1);
           }

       /*
        *  Create a partition instance on top of the physical instance.  Make it
        *  a 10000 block partition starting at block zero.  Since we know
        *  that we have not created any partitions to be used by a remap
        *  instance, NODEV is supplied for the remapinstance.
        */

       partdevicenumber = vdmpartcreateinstance(
                      "b", 0, 10000, physdevicenumber, NODEV);
       if (partdevicenumber == NODEV)
           {
           perror("create b");
           exit(1);
           }

       /*
        *  Resize the partition to be 1000 blocks larger and then resize it
        *  back to its original size.



Licensed material--property of copyright holder(s)                         8




vdmpart(7)                     DG/UX 5.4R3.00                     vdmpart(7)


        */
       status = vdmpartresizepartition(partdevicenumber, 1000);
       if (status == -1)
           {
           perror("increase b");
           exit(1);
           }
       status = vdmpartresizepartition(partdevicenumber, -1000);
       if (status == -1)
           {
           perror("decrease b");
           exit(1);
           }
       exit(0);
       }



FILES
       Files in or under /dev

SEE ALSO
       vdm(7), vdmphys(7), ioctl(2).


































Licensed material--property of copyright holder(s)                         9


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