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