Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

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

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

admpdisk(1M)

vdm(7)

ioctl(2)



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


NAME
       vdmcache - Disk Cache Subdriver of the Virtual Disk Manager

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

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

DESCRIPTION
       The Cache Subdriver is a pseudo-device driver that works under the
       Virtual Disk Management (VDM) framework (see vdm(7)).  The purpose of
       the Cache Subdriver is to provide the capability to use a relatively
       small and fast block device as a stable cache for a relatively large
       and slow block device. A stable device is one whose contents are non-
       volatile. For example, a non-volatile card can be used as a front end
       device for a SCSI-disk, or a fast SCSI-disk as a front end for an
       optical storage jukebox.

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 Cache Subdriver is defined by
       DGVDMCACHESUBDRIVERID.

       Unless otherwise noted, the version field in the following structures
       is an input field that must be set to DGVDMCACHEPACKETVERSION0.
       Additionally, all packets must have every byte set to zero before it
       is used.

   DGVDMCREATEINSTANCE
       The subdriverattributespacketptr field points to the following
       structure:

       struct dgvdmcachecreatepacket
            {
            int                version;
            devt              childdevicenumber;
            };

       The childdevicenumber field is an input field indicating the back
       end  virtual disk instances that are to be cached.

   DGVDMLINKCHILDINSTANCE
       This command adds a front end device to a cache instance.  The
       childpacketptr is not used by Cache Subdriver because the children
       added to a cache instance are always front end devices.

       To add an instance as the front end of a cache device, it must be
       formatted first.  This is accomplished using admpdisk(1M) command
       (note that the admpdisk(1M) command can be used to format virtual
       disks as well as physical disks).



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




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


       The childdevicenumber field is an input field indicating the block
       device that has been formatted as a cache front end device.  This
       device is used to cache the data for the back end device.  A cache
       device may have more than one front end device and may share front
       end devices with other cache devices.

       Cache devices that have no front end device associated with them, are
       in passthru mode. By this, it is meant that data being written to the
       cache goes directly to the back end device without being cached.

       If an attempt is made to add a front end that has not been properly
       formatted, the call will fail and errno will be set to EINVAL.

   DGVDMUNLINKCHILDINSTANCE
       This command removes a front end device from a cache instance.

       The childdevicenumber field is an input field indicating the front
       end device that is to be removed from the cache instance. Any data
       stored on the front end for the cache instance is first flushed to
       the back end device. The cache device will no longer use it to store
       data; however, other cache devices may still use it.

   DGVDMGETCHILDINSTANCE
       The childpacketptr is not used by the Cache Subdriver.

       The childdevicenumber field is returned in the VDM packet.  The
       first child returned is always the back end device. If any additional
       children are returned, they are front end devices.

   DGVDMGETATTRIBUTES
       The subdriverattributespacketptr field points to the following
       structure:

       struct dgvdmcachegetattributespacket
            {
            int              version;
            unsigned long    flags;
            unsigned long    state;
            unsigned long    readcount;
            unsigned long    writecount;
            unsigned long    readmisscount;
            unsigned long    writemisscount;
            unsigned long    readhitcount;
            unsigned long    writehitcount;
            unsigned long    readpurgecount;
            unsigned long    writepurgecount;
            unsigned long    allocatepurgecount;
            unsigned long    bedwritecount;
            unsigned long    bedreadcount;
            unsigned long    totalbufferscount;
            unsigned long    totaldatablockscount;
            unsigned long    dirtybufferscount;
            unsigned long    allocatedbufferscount;
            unsigned long    allocateddatablockscount;



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




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


            unsigned long    statestallcount;
            unsigned long    flushstallcount;
            unsigned int     cachereads                : 1;
            unsigned int     cachewrites               : 1;
            unsigned int     cacheonlymetadata       : 1;
            unsigned int     asyncflushonfirstwrite   : 1;
            unsigned int     asyncflushonallwrites   : 1;
            unsigned int     disabledmatovme         : 1;
            unsigned int     readretention;
            unsigned int     writeretention;
            unsigned int     searchpercentage;
            unsinged int     flushertype;
            };

       The flags field is an input field. If set to DG_VDMCACHE_RESET_STATS
       the statistics are return and reset to zero.

       The state field is an output field. It returns the current state of
       the cache device. The current states are:

        DGVDMCACHESTATEUP - The cache device is up and available.

        DGVDMCACHESTATEDOWN - The cache device is being shutdown.

        DGVDMCACHESTATERECOVERING - The cache device is up recovering
       data from a front-end device.

        DGVDMCACHESTATESEALEDBEDFAILED - The cache device is in an
       error state. All I/O is disallowed because I/O to the back-end device
       failed. Once the back-end device it fixed, removing and re-creating
       the cache device will fix the problem.

        DGVDMCACHESTATESEALEDFEDFAILED - The cache device is in an
       error state. All I/O is disallowed because I/O to the front-end
       device failed. Unlinking the front-end will fix the problem.

        DGVDMCACHESTATESEALEDCACHEFAILED - The cache device is in an
       error state. All I/O is disallowed because internal cache structures
       are corrupted. The user data should be fine.  Removing and re-
       creating the cache device may fix the problem. However, system dump
       should be taken if possible and an str filed on the bug.

       The readcount field is an output field. It returns the total number
       of reads issued to the cache device.

       The writecount field is an output field. It returns the total number
       of writes issued to the cache device.

       The readmisscount field is an output field. It returns the total
       number of times the buffer was not in the cache on a read.

       The writemisscount field is an output field. It returns the total
       number of times the buffer was not in the cache on a write.




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




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


       The readhitcount field is an output field. It returns the total
       number of times the buffer was in the cache on a read.

       The writehitcount field is an output field. It returns the total
       number of times the buffer was in the cache on a write.

       The readpurgecount field is an output field. It returns the total
       number of reads that cause another buffer to flushed and removed from
       the cache because it overlap the new request.

       The writepurgecount field is an output field. It returns the total
       number of writes that cause another buffer to flushed and removed
       from the cache because it overlap the new request.

       The allocationpurgecount field is an output field. It returns the
       total number of I/O that cause another buffer to flushed and removed
       from the cache to free up space.

       The bedreadcount field is an output field. It returns the total
       number of reads issued to the back-end device.

       The bedwritecount field is an output field. It returns the total
       number of writes issued to the back-end device.

       The totalbufferscount field is an output field. It returns the
       total number of buffers available on all of the front-end devices.

       The totaldatablockscount field is an output field.  It returns the
       total number of 512 byte blocks available to hold the data area of
       each buffer on all the front-end devices.

       The dirtybufferscount field is an output field.  It returns the
       number buffers that have data in them that is newer then the data on
       the back-end device.

       The allocatedbufferscount field is an output field.  It returns the
       number of buffers containing data on all of the front-end devices.

       The allocateddatablockscount field is an output field.  It returns
       the number of 512 byte blocks containing data on all of the front-end
       devices.

       The statestallcount field is an output field.  It returns the total
       number of times an I/O had to wait on a buffer that another I/O was
       using.

       The flushstallcount field is an output field.  It returns the total
       number of times an I/O had to wait on a buffer that was being flushed
       to the back-end device.

       The cachereads field is an output field.  It represents the current
       policy value.

       The cachewrites field is an output field.  It represents the current



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




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


       policy value.

       The cacheonlymetadata field is an output field.  It represents the
       current policy value.

       The asyncflushonfirstwrite field is an output field.  It
       represents the current policy value.

       The asyncflushonallwrites field is an output field.  It
       represents the current policy value.

       The disabledmatovme field is an output field.  It represents the
       current policy value.

       The readretention field is an output field.  It represents the
       current policy value.

       The writeretention field is an output field.  It represents the
       current policy value.

       The searchpercentage field is an output field.  It represents the
       current policy value.

       The flushertype field is an output field.  It represents the current
       policy value.


   DGVDMUPDATEATTRIBUTES
       The subdriverattributespacketptr field points to the following
       structure:

       struct dgvdmcacheupdateattributespacket
            {
            int              version;
            unsigned int     cachereads                : 1;
            unsigned int     cachewrites               : 1;
            unsigned int     cacheonlymetadata       : 1;
            unsigned int     asyncflushonfirstwrite   : 1;
            unsigned int     asyncflushonallwrites   : 1;
            unsigned int     disabledmatovme         : 1;
            int              readretention;
            int              writeretention;
            int              searchpercentage;
            int              flushertype;
            };

       The cachereads field is an input bit field. If set to 1, the cache
       device will cache reads if a front end device is present.  Default 1.

       The cachewrites field is an input bit field. If set to 1, the cache
       device will cache writes if a front end device is present.  Default
       1.

       The cacheonlymetadata field is an input field.  Cache attempts to



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




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


       cache only DG/UX file system meta data.  It is however, possible for
       user data to be cached, if the data matches the meta data test.
       Default 0.

       The readretention field is an input field. This value is added to a
       counter associated with a block buffer each time the block is read.
       When free space is required to write a new entry in the cache and
       none can be found in search, the buffers with the lowest retention
       values are purged first. Thus, buffers with high retention values are
       retained in the cache as long as possible. These retention values can
       be used to give preference to the different types of I/O performed on
       the buffers.  Default 1.

       The writeretention field is an input field. This value is added to a
       counter associated with a block buffer each time the block is
       written.  Default 1.  See readretention above for more information.

       The asyncflushonfirstwrite field is an input field.  The first
       time a buffer is written to the cache, an async request to flush the
       data to the back-end device is issued.  Default 1.

       The asyncflushonallwrites field is an input field.  Any time a
       buffer is written to the cache, an async request to flush the data to
       the back-end device is issued.  Default 0.

       The disabledmatovme field is an input field.  Disable Direct
       Memory Access to VME memory on systems that allow the disk
       controllers to move data to and from a VME device.  If feature
       disabled or system does not support the feature, all data transfers
       to and from the NVRAM VME Memory board must be copied through main
       memory.  Default 0.

       The searchpercentage field is an input field. This value is used to
       control the amount of searching performed to find free space in the
       cache.  If the value is zero, no searching will be done and free
       space will be obtained by purging a buffer in the cache with the
       lowest retention value.  A value of 100, indicates that the entire
       cache should be searched before a buffer is purged to make space
       available.  Default 10%.

       The flushertype field is an input field. The value of this field is
       used to determine what type of flushing algorithm is used for the
       cache.  It can be set to DGVDMCACHEPOLICYNOFLUSHER indicating
       that no separate thread of control is used to write dirty buffers
       from the front end device to the back end device.  If
       DGVDMCACHEPOLICYCYCLEFLUSHER is used for the flushertype value,
       a thread of control is used to constantly search through the front
       end device flushing dirty buffers to the back end device.  Default
       DG_VDMCACHE_POLICY_CYCLE_FLUSHER.

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




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




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


       1.     Issue the command to an exported instance of the Cache
              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.

   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 in a non-volatile RAM board
       that is mapped into kernel memory. If the device queried is not a
       non-volatile RAM board, the call will fail and errno is set to
       EINVAL.

   DGVDMCACHEGETFEDSTATS
       The argument field points to the following structure:

       struct  dgvdmcachefedstatspacket
               {
               int              version;
               unsigned int     flags;
               devt            feddevicenumber;
               unsigned long    readcount;
               unsigned long    writecount;
               unsigned long    totalbufferscount;
               unsigned long    totaldatablockscount;
               unsigned long    allocatedbuffernodescount;
               unsigned long    allocateddatablockscount;
               unsigned long    dirtybufferscount;
               unsigned long    buffernodesawaitingrecoverycount;
               unsigned long    datablocksawaitingrecoverycount;
               };

       The flags field is an input field. If set to DG_VDMCACHE_RESET_STATS
       the statistics are return and reset to zero.

       The   field is an input field. It is the device number of the front-
       end device the request should get the statistics from.

       The readcount field is an output field. It returns the total number
       of reads issued to the front-end device

       The writecount field is an output field. It returns the total number



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




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


       of writes issued to the front-end device.

       The totalbufferscount field is an output field. It returns the
       total number of buffers available on the front-end device.

       The totaldatablockscount field is an output field.  It returns the
       total number of 512 byte blocks available to hold the data area of
       each buffer on the front-end device.

       The allocatedbufferscount field is an output field.  It returns the
       number of buffers containing data on the front-end devices.

       The allocateddatablockscount field is an output field.  It returns
       the number of 512 byte blocks containing data on the front-end
       device.

       The dirtybufferscount field is an output field.  It returns the
       number buffers that have data in them that is newer then the data on
       the back-end device.

       The buffersnodesawaitingrecoverycount is an output field.  It
       returns the number of buffers that can not be recovered because the
       back-end device is not available.

       The datablocksawaitingrecoverycount It returns the number of data
       blocks that can not be recovered because the back-end device is not
       available.

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

       /*
        *  This example makes use of the vdmioctl() function described in the
        *  vdm(7) man page.  The vdmioctl() function issues ioctl(2) commands
        *  to the /dev/vdm device node.
        */

       int main (void)
       {
       int                                                status;

       devt                                              feddevicenumber;
       devt                                              beddevicenumber;
       devt                                              cachedevicenumber;

       struct dgsysctlnametodevice                    nametodevicepkt;
       extern int                                         errno;




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




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


       struct dgvdmcreateinstancepacket               createinstancepkt;
       struct dgvdmexportinstancepacket               exportpkt;
       struct dgvdmlinkchildinstancepacket           linkchildpkt;
       struct dgvdmupdateattributespacket             updateattributespkt;
       struct dgvdmgetattributespacket                getattributespkt;

       struct dgvdmphyscreatepacket                    createphyspkt;

       struct dgvdmcachecreatepacket                   createcachepkt;
       struct dgvdmcachechangeupdateattributespacket changepolicypkt;
       struct dgvdmcachecachegetattributespacket     cachestatspkt;

       /*
        *  Create a physical instance for the nvram board.
        */

       nametodevicepkt.devicename = "nvrd(0)";
       status = dgsysctl(DGSYSCTLNAMETODEVICE, &nametodevicepkt);
       if (status == -1)
           {
           eperror("nvrd(0)");
           exit(1);
           }

       /*
        *  Create a fed
        */

       initvdmpacket(createinstancepkt);
       initvdmpacket(createphyspkt);

       createphyspkt.childdevicenumber = nametodevicepkt.devicenumber;
       createinstancepkt.subdriverid = DGVDMPHYSSUBDRIVERID;
       createinstancepkt.subdriverattributespacketptr = &createphyspkt;
       strcpy (createinstancepkt.instancename, "fed");

       status = vdmioctl(DGVDMCREATEINSTANCE,(int)&createinstancepkt);

       if (status == -1)
           {
           eperror("create fed");
           exit(1);
           }

       feddevicenumber = createinstancepkt.devicenumber;

       /*
        *  Create a physical instance for the back-end device.
        */

       nametodevicepkt.devicename = "sd(insc(),0)";
       status = dgsysctl(DGSYSCTLNAMETODEVICE, &nametodevicepkt);
       if (status == -1)
           {



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




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


           eperror("sd(insc(),0)");
           exit(1);
           }

       /*
        *  Create bed
        */

       initvdmpacket(createphyspkt);
       initvdmpacket(createinstancepkt);

       createphyspkt.childdevicenumber = nametodevicepkt.devicenumber;
       createinstancepkt.subdriverid = DGVDMPHYSSUBDRIVERID;
       createinstancepkt.subdriverattributespacketptr = &createphyspkt;
       strcpy (createinstancepkt.instancename, "bed");

       status = vdmioctl(DGVDMCREATEINSTANCE,(int)&createinstancepkt);

       if (status == -1)
           {
           eperror("create bed");
           exit(1);
           }

       beddevicenumber = createinstancepkt.devicenumber;

       /*
        *  Create a cache device.
        */

       initvdmpacket(createcachepkt);
       initvdmpacket(createinstancepkt);

       createcachepkt.childdevicenumber = beddevicenumber;

       createinstancepkt.subdriverid = DGVDMCACHESUBDRIVERID;
       createinstancepkt.subdriverattributespacketptr = &createcachepkt;
       strcpy (createinstancepkt.instancename, "cache");

       status = vdmioctl(DGVDMCREATEINSTANCE,(int)&createinstancepkt);

       if (status == -1)
           {
           eperror("create cache");
           exit(1);
           }

       cachedevicenumber = createinstancepkt.devicenumber;

       /*
        *  Export cache device.
        */

       initvdmpacket(exportpkt);



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




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


       exportpkt.devicenumber = cachedevicenumber;
       status = vdmioctl(DGVDMEXPORTINSTANCE,(int)&exportpkt);

       if (status == -1)
           {
           eperror("export cache");
           exit(1);
           }

       /*
        *  Export fed device.
        */

       initvdmpacket(exportpkt);
       exportpkt.devicenumber = feddevicenumber;
       status = vdmioctl(DGVDMEXPORTINSTANCE,(int)&exportpkt);

       if (status == -1)
           {
           eperror("export a");
           fprintf(stderr,"dgexterrno = %o, Subsystem %o, Sequence Number %o\n",
                   ((unsigned int)dgexterrno()),
                   ((((unsigned int)dgexterrno()) & 0x7fff0000)  >> 16),
                   (((unsigned int)dgexterrno()) & 0x0000ffff));
           exit(1);
           }

       /*
        *  Export bed device.
        */

       initvdmpacket(exportpkt);
       exportpkt.devicenumber = beddevicenumber;
       status = vdmioctl(DGVDMEXPORTINSTANCE,(int)&exportpkt);

       if (status == -1)
           {
           eperror("export b");
           exit(1);
           }

       /*
        *  Link a front-end to the cache device.
        */
       initvdmpacket(linkchildpkt);
       linkchildpkt.parentdevicenumber = cachedevicenumber;
       linkchildpkt.childdevicenumber  = feddevicenumber;
       linkchildpkt.parentsubdriverid  = DGVDMCACHESUBDRIVERID;

       status = vdmioctl(DGVDMLINKCHILDINSTANCE,(int)&linkchildpkt);

       if (status == -1)
           {
           eperror("link fed to bed");



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




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


           exit(1);
           }

       /*
        *  Change the cache policy for best NFS performance.
        */

       initvdmpacket(updateattributespkt);
       initvdmpacket(changepolicypkt);
       changepolicypkt.cachereads = FALSE;
       changepolicypkt.cachewrites = TRUE;
       changepolicypkt.cacheonlymetadata = FALSE;
       changepolicypkt.asyncflushonfirstwrite = TRUE;
       changepolicypkt.asyncflushonallwrites = FALSE;
       changepolicypkt.disabledmatovme = FALSE;
       changepolicypkt.readretention = 0;
       changepolicypkt.writeretention = 1;
       changepolicypkt.searchpercentage = 25;
       changepolicypkt.flushertype = DGVDMCACHEPOLICYCYCLEFLUSHER;

       updateattributespkt.instancedevicenumber = cachedevicenumber;
       updateattributespkt.subdriverid = DGVDMCACHESUBDRIVERID;
       updateattributespkt.subdriverattributespacketptr = &changepolicypkt;

       status = vdmioctl(DGVDMUPDATEATTRIBUTES,(int)&updateattributespkt);

       if (status == -1)
           {
           eperror("change policy");
           exit(1);
           }

       /*
        *  Get the cache statistics.
        */

       initvdmpacket(getattributespkt);
       initvdmpacket(cachestatspkt);

       getattributespkt.instancedevicenumber = cachedevicenumber;
       getattributespkt.subdriverid = DGVDMCACHESUBDRIVERID;
       getattributespkt.subdriverattributespacketptr = &cachestatspkt;

       status = vdmioctl(DGVDMGETATTRIBUTES,(int)&getattributespkt);

       if (status == -1)
           {
           eperror("cache stats");
           exit(1);
           }

       fprintf(stdout,"\n   totalbufferscount           %d\n",
               cachestatspkt.totalbufferscount);




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




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


       fprintf(stdout,"   totaldatablockscount         %d\n",
               cachestatspkt.totaldatablockscount);

       exit(0);
       }

FILES
       Files in or under /dev

SEE ALSO
       admpdisk(1M), vdm(7), ioctl(2).














































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


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