dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
NAME
dgpd: - physical disk manipulation library
SYNOPSIS
#include <dgpd.h>
int dgpdformat(
char *devicespec,
int formattype,
int argument);
int dgpdgetformattype(
char *devicespec,
int *formattype);
int dgpdinstall(
char *devicespec,
int datatype,
int argument);
int dgpddumpformat(
char *devicespec,
FILE *output);
int dgpdconvertformat(
int numdevicespecs,
char *devicespecs[],
int toformattype);
int dgpdpseudoregister(
int numdevicespecs,
char *devicespecs[]);
int dgpdpseudoderegister(
int numdevicespecs,
char *devicespecs[]);
int dgpdregister(
int numdevicespecs,
char * devicespecs[],
unsigned int trespassflag,
unsigned int * anypartialexportsptr,
unsigned int * anyfailedrecreatesptr);
int dgpdderegister(
char * devicespec,
devt * faileddeviceptr);
int dgpdcopy(
char *sourcedevicespec,
char *destdevicespec);
int dgpdmerge(
char *sourcedevicespec,
Licensed material--property of copyright holder(s) 1
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
char *destdevicespec);
int dgpdgetstate(
char * devicespec,
dgpdstateinfotype * state);
int dgpdtraverseelders(
devt startinginstance,
int (*visitfunction)(devt instance, int depth),
int traversaltype,
int depthcounter);
int dgpdtraversechildren(
devt startinginstance,
int (*visitfunction)(devt instance, int depth),
int traversaltype,
int depthcounter);
char *dgpdstrerror(int status, int errno);
void dgpdperror(char * s);
DESCRIPTION
The following routines provide an interface to devices containing or
intended to contain various DG/UX disk formats. All routines
requiring a physical device to be identified take a devicespec as an
argument. This argument identifies a device on the system. This
specification is in DG/UX Common Device Specification format.
Examples of the specification are: sd(insc(),0) - identifying a SCSI
drive on the system, vdm(root) - identifying an instance of the
Virtual Disk Manager. For more information about this, refer to the
sd(7) and vdm(7) man pages or the Managing the DG/UX System manual.
The following definitions may be helpful in accessing physical disk
drives. DGPDBYTESPERBLOCK is the number of bytes in a block.
DGPDGOODBUFFERSIZE is the number of bytes in a buffer that
provides reasonable I/O throughput per I/O request to a physical
device, but, this size may not be optimal for some devices.
FORMATTING
The dgpdformat() routine formats the given physical device with the
given format type. The formattype argument can be one of the
following: DGPDVDMFORMAT or DGPDFRONTENDFORMAT.
Virtual Disk Information Table
The VDM format creates a Virtual Disk Information Table (VDIT),
allowing the physical device to be registered by the Virtual Disk
Manager (VDM). The result of the format and registration process is
to reserve and manage space on the physical device to allow the VDM
to maintain data about virtual disk instances so they can be created
automatically from the data stored on the drives.
All physical devices configured into the operating system are
Licensed material--property of copyright holder(s) 2
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
attempted to be registered at system boot time. During registration,
the data stored on the devices is read and the virtual disk instances
are created.
The VDIT is always located starting at the second block of the
physical device. The first block of the device is always reserved
for a disk label (whether it is required or not). A secondary copy
of the VDIT is located at the end of the physical device starting at
the block from the end that would put the last block of the VDIT in
the last block of the device. If the device is converted from the
old LDM format, the the secondary copy is located near the front of
the disk. The exact location cannot be specified because it depends
on the previous format.
After the physical device has been formatted with a VDIT and
registered, the VDIT will be represented as a single partition or a
set of partitions on the physical device. Additionally, the label
(the first block of the device) will appear as a partition and the
secondary VDIT will also appear as a partition or set of partitions.
The free space left on the physical device can only be placed into
use by creating a partition instance on the physical device.
When formatting with type DGPDVDMFORMAT the argument field is a
pointer to the following structure:
struct dgpdvdmformatoptions
{
unsigned int version;
unsigned int vditsize;
}
The version field should be set to DGPDPACKETVERSION0.
The vditsize field indicates the size of the VDIT. To set it to the
default, use DGPDDEFAULTVDITSIZE. In future releases, interfaces
will be provided to expand or add non-contiguous disk space to the
VDIT.
Cache Front End
Formatting a physical device as a front end device of a cached device
prepares it for use as the "cache" of the cached device. The
formatted device should be the smaller and faster than the device
that will be used as the back end device when the cached device is
created.
The formatting of the front end device creates data structures on
disk that represent the cached data. It is beneficial to establish
the size of these buffers to closely match those of the typical size
of the I/O being performed to the physical device.
When formatting with type DGPDFRONTENDFORMAT the argument field is
a pointer to the following structure:
struct dgpdfedformatoptions
Licensed material--property of copyright holder(s) 3
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
{
unsigned int version;
unsigned int numberofbuffers;
unsigned int averagebuffersizeinblocks;
};
If the numberofbuffers is not 0, then this will be the number of
buffers created on the physical device. If the
averagebuffersizeinblocks is 0, then the number of buffers will
determine the buffer size.
If both of the above fields is set to 0, then enough buffers of size
DGPDDEFAULTFEDBUFFERSIZE will be created to fill the front end
device.
Getting Format Type
The dgpdgetformattype() routine opens the given device and sets
the location formattype pointer to the following format types:
DGPDNOFORMAT, DGPDLDMFORMAT, DGPDVDMFORMAT, DGPDFSFORMAT, or
DGPDFRONTENDFORMAT.
INSTALLING
The dgpdinstall() routine provides the ability to update the data in
various known data structures on a physical disk. Depending on the
type of data being installed, the disk may need to be formatted,
registered, or both.
Disk Label
If the data being installed is a disk label, then the datatype field
should be set to DGPDINSTALLLABEL. This argument should be a
pointer to the following:
struct dgpdinstalllabeloptions
{
unsigned int version;
char * path;
};
The version field should be set to DGPDPACKETVERSION0. The path
field should be set to a file containing a label description. A
label description is a set of lines in a file of the following
format:
labelfield labelfieldvalue
The space between the labelfield and the labelfieldvalue can be
filled with spaces and tabs.
The first line of the label description file should contain a
description of the type of device for which the label is intended.
If no description is desired, then the first line of the file must be
left blank.
The labelfield must be one of the following:
Licensed material--property of copyright holder(s) 4
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
cylindersperdrive
visiblecylindersperdrive
trackspercylinder
sectorspertrack
bytesperlogicalsector
bytesperunformattedsector
defectinfostartsector
bytesindefectinfo
numberofrelocationareas
sectorsperrelocationarea
nextrelocationsector
interleave
headskew
cylinderskew
headgroupskew
sparespertrack
bytesperdatapreamble
bytesperidpreamble
baseheadforvolume
flags
bytesingap1
bytesingap2
sanityflag
versionnumber
Any label fields left unspecified are set to 0 except the sanity flag
field which will get set to a default value.
Label description files exist for disks that are currently supported
by DG/UX. These description files are located in then
/usr/etc/sysadm/pdisklabels directory.
If the label is being installed on a device containing a bootstrap,
the bootstrap location is preserved (the label contains a pointer to
the bootstrap location).
The physical device can be registered or unregistered when this
operation performed.
Bootstrap
If the data being installed is a bootstrap, then the datatype field
should be set to DGPDINSTALLBOOTSTRAP. This argument should be a
pointer to the following:
struct dgpdinstallbootstrapoptions
{
unsigned int version;
devt bootrappartition;
char * path;
};
The version field should be set to DGPDPACKETVERSION0. The
bootstrappartition field is the device number of a partition on the
device identified by the devicespec argument. The size of this
Licensed material--property of copyright holder(s) 5
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
partition must be large enough to hold the bootstrap. The value
DGPDDEFAULTBOOTSTRAPSIZE is a recommended size. By convention,
the name of the partition should be DGPDBOOTSTRAPNAME. The path
field is the file in the file system containing the bootstrap. The
data in the given file will be copied to the bootstrap location.
The physical device must be registered to install a bootstrap.
Remap
If the data being installed are remap areas, then the datatype field
should be set to DGPDINSTALLREMAP. Installing remap areas provides
the ability to relocate blocks that are located on a failed portion
of a disk's media. Once remapping is available, partitions created
on the physical device containing the remap area can take advantage
of the capability (see vdmremap(7) for more).
To install remapping, the argument should be a pointer to the
following:
struct dgpdinstallremapoptions
{
unsigned int version;
devt primarytable;
devt secondarytable;
devt remaparea;
};
The version field should be set to DGPDPACKETVERSION0. The
primarytable is the device_number of the Primary Bad Block Table
partition. The secondarytable is the device number of the Secondary
Bad Block Table partition. The remaparea is the device number of
the Bad Block Remap Area.
The above tables and area must be partitions on the given physical
device identified with the devicespec argument. It is recommended
that the Primary Bad Block table be created with the name
DGPDPRIMARYBADBLOCKTABLENAME, the Secondary Bad Block Table be
called DGPDSECONDARYBADBLOCKTABLENAME, and the Remap Area be
called DGPDREMAPAREANAME.
All of the blocks used by the above partitions should be checked for
reliability since they do not benefit from the bad block remapping.
The maximum size of the Bad Block Remap Area is defined by
DGPDMAXREMAPAREASIZE. The maximum size of the Bad Block Tables
is DGPDMAXREMAPTABLESIZE. To determine the required size of the
Bad Block Tables from the remap area size,
dgpdminimumtablesize(remapareasize)
will return the minimum table size (in blocks) of the Bad Block
Tables given the size of the Remap Area to utilize all of the blocks
available in the Remap Area.
Licensed material--property of copyright holder(s) 6
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
When a remap is installed on a physical device, the partitions
representing the Primary and Secondary Bad Block Tables are formatted
to participate in a Remap instance. Then an unnamed Remap instance is
created. The remap instance is not exported but is made persistent
on the given physical device.
The physical device must be registered to install remap capability.
COPYING
Currently not implemented.
The dgpdcopy() routine copies the contents of the given
sourcedevice to the given destdevice. In all cases, the contents
of the destination device are overwritten.
If the source device was VDM formatted (see above), then the system
data is copied on to the destination device and all of the partitions
are copied. Any blocks that were remapped will not be remapped on
the destination, but placed in their appropriate location (since the
the blocks are not known to be bad on the destination).
Additionally, any blocks known to be bad but contained no data are
marked as bad on the destination until they are written on the
destination. Any blocks discovered to be bad during the copy (cannot
be read from the source disk) will be marked as unreadable on the
destination until it is written.
The size of the destination must be greater than or equal to the size
of the destination. The location of the partitions on source device
are preserved on the destination device.
If the source device is any other format or raw data, it is copied
directly to the destination device. If a block on the source device
is not readable and the destination device has remap capability (it
is a partition on a VDM formatted device) then the block on the
destination device is marked not readable until the block is written.
If the source disk is VDM formatted, it must be registered to perform
this operation. In all cases, the destination cannot be opened (VDM
registration is a form of an open) to perform the copy.
MERGING
Currently not implemented.
The dgpdmerge() routine takes the virtual disks described on the
source disk and adds them to the virtual disks described on the
destination device.
The destination device must have enough space available to hold the
partitions on the source device without breaking the partitions up
into smaller aggregated pieces. For example, the destination may
have 10,000 blocks of free space in 5,000 block chunks. If a
partition on the source device is 7,000 blocks, the copy cannot be
performed. If the free space is broken up, an attempt will be made
to make the most effective use of the space available. The operation
Licensed material--property of copyright holder(s) 7
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
will only be performed if there is enough space available.
The source device must be registered and the destination device must
be unregistered.
CONVERTING
The dgpdconvertformat() routine takes a formatted physical disk and
converts it to the given toformattype. If the toformattype
argument is DGPDVDMFORMAT, then the given set devicespecs must be
in LDM format. If the toformattype argument is DGPDLDMFORMAT,
then the given set of devicespecs must be in VDM format. The
conversion of cache formats is not provided. To effectively handle
the transition, all cached devices must be deleted before conversion
is performed and recreated after the conversion is performed (the
participants in the cache, the Front End Device and the Back End
Device should be preserved through the conversion; however, since the
cache is deleted, no data currently resides on the Front End Device).
A number of devices can be supplied for the conversion. The reason
for this is to handle the conversion of entities such as mirrors or
multi-piece logical disks that may be distributed among the devices.
To successfully convert a physical device, the entities described on
the device must be complete among all of the devices given. If any
entity is incomplete, a message is printed to stderr and the
conversion will not take place.
All of the devices given in devicespecs must be unregistered.
To convert from VDM format back to LDM format, the physical device
must have originally been an LDM formatted device that was converted
to VDM format. Additionally, the conversion is limited to those
entities that exist in the LDM environment (partitions, remapping,
aggregations, and mirrors). If the devices to be converted back
contain entities that are non-convertible, then the conversion will
not take place. This can be eliminated by deleting any instances
that are not backward compatible.
REGISTERING
The dgpdregister() routine causes a given set of devicespecs to be
supplied for registration with the Virtual Disk Manager.
The numberofdevicespecs argument specifies the number of elements
in the devicespecs array. The trespassflag is an input argument
indicating that the given device should first be trespassed (taken
over although the driver recognizes that it is currently being
accessed) before it is registered.
The anypartialexportsptr argument is a pointer to the location
where a 1 will be written if the registration of the given devices
has any instances that did not have both the long and short name of
the instance exported (if the instance was supposed to be exported).
Otherwise, a 0 will be written to the location.
The anyfailedrecreatesptr argument is a pointer to the location
Licensed material--property of copyright holder(s) 8
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
where a 1 will be written if the registration of the given devices
has any instances that did not get successfully created. Otherwise,
a 0 will be written to the location.
DEREGISTERING
The dgpdderegister() routine causes a given devicespec to be
deregistered by the Virtual Disk Manager. This will result in all
instances dependent on partitions of the given physical device to be
removed from memory.
The faileddeviceptr argument is a pointer to the location where a
device number will be written if the call fails to deregister and a
particular instance can be identified as preventing the
deregistration.
MISCELLANEOUS
The dgpdgetstate() routine attempts to determine the current state
of a physical disk device. The state argument to the routine is a
pointer to the following structure:
struct dgpdstateinfo
{
unsigned int version;
unsigned int writable : 2;
unsigned int vdmregistered : 2;
unsigned int validtoshare : 2;
};
The version field should be set to DGPDPACKETVERSION0.
The writable field returns with one of the following:
DGPDWRITABLE Indicates that the physical device can be
written to.
DGPDNOTWRITABLE Indicates that the physical device cannot
be written to.
DGPDSTATEUNKNOWN Indicates that the writability of the
device cannot be determined.
The vdmregistered field can be set to one of the following:
DGPDVDMREGISTERED Indicates that the physical device is
registered by the Virtual Disk Manager.
DGPDNOTVDMREGISTERED Indicates that the physical device is not
registered by the Virtual Disk Manager.
DGPDSTATEUNKNOWN Indicates that the registration state of
the device cannot be determined. This is
given for the writable state if the device
cannot be opened or read. This state is
most often seen with LDM registered disks
Licensed material--property of copyright holder(s) 9
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
since all physical devices registered by
the LDM have no set area that can be
opened for writing like the label
partition on VDM formatted disks.
On input, the above state fields can be set to DGPDSTATENOTDESIRED
to suppress the determination of the state by the routine.
The validtoshare field can be set to one of the following:
DGPDVALIDTOSHARE Indicates that the physical device is
valid to be a shared between two systems.
DGPDNOTVALIDTOSHARE Indicates that the physical device is not
valid to be a shared between two systems.
DGPDSTATEUNKNOWN Indicates that the ability to share the
given disk cannot be determined.
The dgpdtraverseelders() routine takes a given VDM instance visits
all if the instance's parents and their parents until an instance
with no parents is encountered.
The startinginstance is the instance whose elders are to be
traversed.
The visitfunction is the function called each time an instance is
encountered. The device number of the elder instance being visited
is given along with the depth of the traversal where it was
encountered (this can be useful for printing listings).
The traversaltype should be given as either
DGPDDEPTHFIRSTTRAVERSAL or DGPDBREADTHFIRSTTRAVERSAL to control
the type of tree traversal performed. For a depth first traversal,
each elder will be visited, then its elders will be visited and so
on. In a breadth first traversal, each elder of an instance will be
visited before moving on to their elders.
The depthcounter argument allows the visit function to be handed to
control the depth count given to the visit function. It should be
given as zero.
The dgpdtraversechildren() routine takes a given VDM instance
visits all if the instance's child and their children until an
instance with no children is encountered.
The startinginstance is the instance whose children are to be
traversed.
The visitfunction is the function called each time an instance is
encountered. The device number of the child instance being visited
is given along with the depth of the traversal where it was
encountered (this can be useful for printing listings).
Licensed material--property of copyright holder(s) 10
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
The traversaltype should be given as either
DGPDDEPTHFIRSTTRAVERSAL or DGPDBREADTHFIRSTTRAVERSAL to control
the type of tree traversal performed. For a depth first traversal,
each child will be visited, then its children will be visited and so
on. In a breadth first traversal, each child of an instance will be
visited before moving on to their children.
The depthcounter argument allows the visit function to be handed to
control the depth count given to the visit function. It should be
given as zero.
ERROR HANDLING
The dgpdstrerror() routine takes the given status returned from any
of the library functions and returns a null terminated string
containing a description of the error. The status is used to
determine is the error that was encountered was an internal library
error or a system error (the result of the library making a system
call and encountering an error).
The status can be checked for internal or system using
DGPDINTERNALERROR or DGPDSYSTEMERROR respectively. If a system
error is encountered, errno is used to print the error status. If an
internal error is indicated, dgpd_errno is used.
The dgpdperror() routine prints out the given string s followed by a
: and then prints a descriptive error for the given error status
using the same methodology as described with dgpdstrerror.
RETURN VALUE
All of the functions returning an integer return a status of the
following values: DGPDINTERNALERROR, DGPDOK, DGPDSYSTEMERROR.
For the calls returning a status, a DGPDSYSTEMERROR status, that
indicates a system call failed in the course of the library's
execution. Therefore, errno can be used to print a more meaningful
diagnostic.
A return status of DGPDINTERNALERROR indicates that the library
function experienced an internal error. In this case, the global
variable dgpderrno is set and can be used to print a more meaningful
diagnostic. This errno is set to the common system errno values and
can be interpreted using strerror(3C) function. For a more
descriptive description of the internal library failure, dgpderrno
is set and can be interpreted using the functions described above.
USAGE
Application Program.
Note that some routines may be macros.
EXAMPLE
#include <fcntl.h>
#include <stdio.h>
#include "dgpd.h"
Licensed material--property of copyright holder(s) 11
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
extern int errno;
main(int argc, char * argv[])
{
int status;
if (argc < 2)
{
fprintf(stderr, "Usage: dgpd arguments device0);
exit(1);
}
if (strcmp(argv[1],"type") == 0)
{
char * formatdescription;
int formattype;
status = dgpdgetformattype(argv[2], &formattype);
if (status != DGPDOK)
{
perror(argv[2]);
exit(1);
}
switch (formattype)
{
case DGPDUNKNOWNFORMAT:
formatdescription = "is of an unknown format";
break;
case DGPDFSFORMAT:
formatdescription = "is a DG/UX file system";
break;
case DGPDLDMFORMAT:
formatdescription = "is a DG/UX Logical Disk format";
break;
case DGPDVDMFORMAT:
formatdescription = "is a DG/UX Virtual Disk format";
break;
case DGPDFRONTENDFORMAT:
formatdescription = "is a cache front end";
break;
default:
formatdescription = "was not classified correctly";
break;
}
fprintf(stderr, "%s %s0, argv[2], formatdescription);
exit(0);
}
else if (strcmp(argv[1],"label") == 0)
{
struct dgpdinstalllabeloptions options;
options.version = DGPDPACKETVERSION0;
options.path = argv[2];
status = dgpdinstall(argv[3], DGPDINSTALLLABEL, (int)&options);
}
Licensed material--property of copyright holder(s) 12
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
else if (strcmp(argv[1],"bootstrap") == 0)
{
struct dgpdinstallbootstrapoptions options;
options.version = DGPDPACKETVERSION0;
status = dgpdinstancenametodevice(
argv[2], &options.bootstrappartition);
if (status != DGPDOK)
{
goto exitstatus;
}
options.path = argv[3];
status = dgpdinstall(argv[4], DGPDINSTALLBOOTSTRAP, (int)&options);
}
else if (strcmp(argv[1],"remap") == 0)
{
struct dgpdinstallremapoptions options;
options.version = DGPDPACKETVERSION0;
status = dgpdinstancenametodevice(
argv[2], &options.primarytable);
if (status != DGPDOK)
{
goto exitstatus;
}
status = dgpdinstancenametodevice(
argv[3], &options.secondarytable);
if (status != DGPDOK)
{
goto exitstatus;
}
status = dgpdinstancenametodevice(
argv[4], &options.remaparea);
if (status != DGPDOK)
{
goto exitstatus;
}
status = dgpdinstall(argv[5], DGPDINSTALLREMAP, (int)&options);
}
else if (strcmp(argv[1],"vdit") == 0)
{
struct dgpdvdmformatoptions options;
options.version = DGPDPACKETVERSION0;
options.useredundancy = 1;
options.vditsize = DGPDDEFAULTVDITSIZE;
status = dgpdformat(argv[2], DGPDVDMFORMAT, (int)&options);
}
else if (strcmp(argv[1],"fed") == 0)
{
struct dgpdfedformatoptions options;
options.version = DGPDPACKETVERSION0;
options.numberofbuffers = 0;
options.averagebuffersizeinblocks = DGPDDEFAULTFEDBUFFERSIZE;
status = dgpdformat(argv[2], DGPDFRONTENDFORMAT, (int)&options);
}
else if (strcmp(argv[1],"conv2vdm") == 0)
Licensed material--property of copyright holder(s) 13
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
{
status = dgpdconvertformat(
argc - 2, &argv[2], DGPDVDMFORMAT);
}
else if (strcmp(argv[1], "conv2ldm") == 0)
{
status = dgpdconvertformat(
argc-2, &argv[2], DGPDLDMFORMAT);
}
else if (strcmp(argv[1],"register") == 0)
{
unsigned int anypartialexports;
unsigned int anyfailedrecreates;
status = dgpdregister(
argc - 2, &argv[2], 0,
&anypartialexports, &anyfailedrecreates);
if (status == DGPDOK)
{
if (anypartialexports > 0)
{
fprintf(stderr, "Partial exports indicated0);
}
if (anyfailedrecreates > 0)
{
fprintf(stderr, "Failed recreates indicated0);
}
}
}
else if (strcmp(argv[1],"deregister") == 0)
{
devt device;
status = dgpdderegister(argv[2], &device);
if (status != DGPDOK)
{
if (device != NODEV)
{
fprintf(stderr, "Device 0x%x is still open0, device);
}
}
}
else if (strcmp(argv[1],"dump") == 0)
{
dgpddumpformat(stdout, argv[2]);
}
else if (strcmp(argv[1],"pr") == 0)
{
status = dgpdpseudoregister(argc - 2, &argv[2]);
}
else if (strcmp(argv[1],"pdr") == 0)
{
status = dgpdpseudoderegister(argc - 2, &argv[2]);
}
else if (strcmp(argv[1], "state") == 0)
{
Licensed material--property of copyright holder(s) 14
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
dgpdstateinfotype diskstate;
diskstate.version = DGPDPACKETVERSION0;
diskstate.writable = DGPDSTATEUNKNOWN;
diskstate.vdmregistered = DGPDSTATEUNKNOWN;
diskstate.validtoshare = DGPDSTATEUNKNOWN;
status = dgpdgetstate(argv[2], &diskstate);
if (status == DGPDOK)
{
if (diskstate.writable == DGPDWRITABLE)
{
fprintf(stderr, "Disk is writable.0);
}
else if (diskstate.writable == DGPDNOTWRITABLE)
{
fprintf(stderr, "Disk is not writable.0);
}
else
{
fprintf(stderr, "Don't know if disk is writable.0);
}
if (diskstate.vdmregistered == DGPDVDMREGISTERED)
{
fprintf(stderr, "Disk is registered by VDM.0);
}
else if (diskstate.vdmregistered == DGPDNOTVDMREGISTERED)
{
fprintf(stderr, "Disk is not registered by VDM.0);
}
else
{
fprintf(stderr,
"Don't know if disk is registered by VDM.0);
}
if (diskstate.validtoshare == DGPDVALIDTOSHARE)
{
fprintf(stderr, "Disk is OK to register shared.0);
}
else if (diskstate.validtoshare == DGPDNOTVALIDTOSHARE)
{
fprintf(stderr, "Disk is not OK to register shared.0);
}
else
{
fprintf(stderr,
"Don't know if disk is OK to register shared.0);
}
}
else
{
fprintf(stderr, "Don't know anything about the disk.0);
}
Licensed material--property of copyright holder(s) 15
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
}
else if ((strcmp(argv[1],"elders") == 0) ||
(strcmp(argv[1],"children") == 0))
{
devt device;
int traversaltype;
static int visitinstance();
status = dgpdinstancenametodevice(argv[2], &device);
if (status != DGPDOK)
{
goto exitstatus;
}
if (argc < 4 || strcmp(argv[3], "breadth") == 0)
{
traversaltype = DGPDBREADTHFIRSTTRAVERSAL;
}
else /* if (strcmp(argv[3], "depth" == 0) */
{
traversaltype = DGPDDEPTHFIRSTTRAVERSAL;
}
if (strcmp(argv[1],"elders") == 0)
{
status = dgpdtraverseelders(device, visitinstance,
traversaltype, 0);
}
else
{
status = dgpdtraversechildren(device, visitinstance,
traversaltype, 0);
}
}
else
{
fprintf(stderr, "Usage: dgpd command device0);
exit(1);
}
exitstatus:
if (status != DGPDOK)
{
dgpdperror(status, argv[1]);
exit(1);
}
exit(0);
}
static
int visitinstance(devt parent, int depth)
{
int status;
struct dgsysctldevicetoname packet;
char name[DGSYSCTLMAXNAMELENGTH];
Licensed material--property of copyright holder(s) 16
dgpd(3C) DG/UX 5.4R3.00 dgpd(3C)
packet.devicenumber = parent;
packet.devicename = name;
packet.maxnamelength = sizeof name;
status = dgsysctl(DGSYSCTLDEVICETONAME, &packet);
if (status >= 0)
{
printf("%d: %8lu [%s]0, depth, (unsigned long) parent, name);
}
else
{
printf("%d: %8lu0, depth, (unsigned long) parent);
}
return (DGPDOK);
}
FILES
/usr/etc/sysadm/pdisklabels
SEE ALSO
dgsysctl(2), ioctl(2), strerror(3C), vdm(7), vdmpart(7),
vdmremap(7).
Licensed material--property of copyright holder(s) 17