vdmpart(7) DG/UX R4.11MU05 vdmpart(7)
NAME
vdmpart - Virtual Disk Manager Partition Subdriver
DESCRIPTION
The Partition Subdriver enables you to subdivide the space on a
physical disk so that you can store different information on
different parts of a single physical disk. Without it, you would
have to devote an entire physical disk to one file system or
database. With it, you can subdivide the physical disk into discrete
units, or "partitions", each of which can be used to store a
different file system or database.
Partitions also support software bad-block remapping. If it is
enabled, and a write to the partitioned device fails due to a media
failure (i.e., a hard error on the disk), software bad-block
remapping will redirect the block to the remap area on the disk to
store the data, and the I/O will succeed.
Pictorially, two partitions of a physical disk, both with software
bad-block remapping enabled look like this:
0 49999 0 39999
+-------------------+ +-------------------+
| partition "swap" | | partition "root" |
| starts at 1000 | | starts at 51000 |
| is 50000 blocks | | is 40000 blocks |
+-------------------+ +-------------------+
1000 | | 50999 51000 | | 90999
| | | |
| | | |
| +-------------------+ |
| | remap instance | |
| +-------------------+ |
| | |
| | |
+------------+ | +------------+
| | |
+-------------------+
| physical |
| sd(ncsc(0,7),0,0 |
+-------------------+
|
|
----------
( )
( )
( disk )
( drive )
( 1 )
( )
----------
Partitions have up to two children. In this example, each partition
has one child that is the partitioned device (the physical instance),
and another child that is the software bad-block remapping child.
Typically, the remap child is not drawn in diagrams with partitions
since it is of secondary importance to the partition itself.
DG/UX supports up to approximately 90 partitions per gigabyte of
physical disk size. So, for disks up to 1 Gbyte, you can have
approximately 90 partitions. For disks between 1 Gbyte and 2 Gbytes,
you can have approximately 180 partitions. The actual number
possible for any given physical disk depends on the amount of free
space available in the VDIT (Virtual Disk Information Table) on the
physical disk. In general, enough free space exists to build as many
partitions as you want.
In order to use the Partition Subdriver, you must configure vdmpart()
into your kernel. It appears in all new system files by default, so
it is usually already configured.
For more details about how the Partition Subdriver fits into the
Virtual Disk Manager, see the vdm(7) man page.
MULTIPLE PARTITIONS
Each partition you create acts like a disk all its own, hence the
name "virtual disk". Your application can think of a partition as an
ordered set of disk blocks, the first of which is numbered zero, and
the last of which is numbered N - 1, where N is the number of blocks
in the partition. The application does not need to worry about where
the partition is stored on disk.
The Partition Subdriver takes care of offsetting the I/Os to each
partition by the starting block number of the partition to map it
onto the blocks of the physical disk.
In the example, the tops of the two partitions indicate the block
numbers that the beginning and end of the partitions have from the
application's perspective. The bottom of the partitions indicate the
blocks on the physical disk where the data for the partition is
actually stored.
You can have as many partitions on a physical disk as you want, as
long as there is free space for them. Partitions may not overlap,
and must be wholly contained on the disk (they can't go off the end
of the disk).
BAD-BLOCK REMAPPING
Software bad-block remapping is an optional feature used to prevent
single block media failures from causing I/O failures to the
applications. It is enabled at the partition level by linking the
remap child for the physical disk to the partition. If the remap
child is not linked to the partition, any media failures from the
physical disk will result in unrecoverable I/O errors being sent to
the application.
By default, when you format a physical disk with sysadm(1M), software
bad-block remapping will be enabled. Further, by default when you
create a partition on a physical disk that has software bad-block
remapping enabled, the partition will also have it enabled. You can
override both defaults if you care to.
We recommend that you enable software bad-block remapping on all
disks and for all partitions as the default. In some situations,
however, you may safely choose to remove it.
One situation where software bad-block remapping can be safely
removed is if the disk is in a CLARiiON® RAID-5 stripe. In this
case, the RAID technology in the CLARiiON® is already protecting
against single bad blocks on the disks, so you can safely disable
software bad-block remapping for it. It can be enabled without
problems, but it would be redundant.
NVRAM (Non-Volatile Random Access Memory) boards also do not need to
have software bad-block remapping enabled for them, since they
provide single-bit ECC (Error Correcting Code) to prevent single-bit
errors from resulting in I/O failures. These NVRAM boards are
commonly used to hold Front-End Devices for VDM caches. See
vdmcache(1M) for more details.
For more details about the Bad-Block Remapping Subdriver, see the
vdmremap(7) man page.
PARTITIONS OF NON-PHYSICAL VIRTUAL DISKS
Normally, partitions are built on top of the physical instance for a
physical disk. This is the most natural way of creating them.
However, since a partition does not know what type of virtual disk
the partitioned child is, it can be built on top of any other type of
virtual disk.
For example, if you wanted to have two partitions mirrored across two
physical disks, the usual way to create this is to create two
partitions on each physical disk, with each distributed pair of
partitions being the same size. You would then build a mirror for
each distributed pair of partitions. Your applications would then
open the two mirrors to do their work.
Pictorially, this traditional arrangement looks like this:
0 49999 0 39999
+-------------------+ +-------------------+
| mirror "swap" | | mirror "root" |
| is 50000 blocks | | is 40000 blocks |
+-------------------+ +-------------------+
| | | |
| | | |
| | | +----------+
| | / |
| | / |
| +--------------------+ |
| / | |
0 | 49999 / 0 | 49999 |
+-------------------+ / +-------------------+ |
| image 1 of "swap" | / | image 2 of "swap" | |
| partition | / | partition | |
| starts at 1000 | / | starts at 2000 | |
| is 50000 blocks | / | is 50000 blocks | |
+-------------------+ | +-------------------+ |
1000 | 50999 | 2000 | 51999 |
| | | |
| 0 | 39999 | 0 | 39999
| +-------------------+ | +-------------------+
| | image 1 of "root" | | | image 2 of "root" |
| | partition | | | partition |
| | starts at 51000 | | | starts at 52000 |
| | is 40000 blocks | | | is 40000 blocks |
| +-------------------+ | +-------------------+
| 51000 | 90999 | 52000 | 91999
| | | |
| | | |
+-----+ | +-----+ |
| | | |
+-------------------+ +-------------------+
| physical | | physical |
| sd(ncsc(0,7),0,0 | | sd(ncsc(0,7),1,0 |
+-------------------+ +-------------------+
| |
| |
---------- ----------
( ) ( )
( ) ( )
( disk ) ( disk )
( drive ) ( drive )
( 1 ) ( 2 )
( ) ( )
---------- ----------
If having two mirrors is inconvenient for some reason, you could
build this arrangement a different way. First, create a partition on
each physical disk that's the combined size of the two separate
partitions. Then build a mirror between those two partitions.
Finally, build the two user partitions on top of the mirror.
Pictorially, this alternate arrangement looks like the diagram below.
Warning: You cannot boot from the root virtual disk in this
alternate example. Do not set up your root or usr virtual
disk in this fashion.
0 49999 0 39999
+-------------------+ +-------------------+
| partition "swap" | | partition "root" |
| starts at 0 | | starts at 50000 |
| is 50000 blocks | | is 40000 blocks |
+-------------------+ +-------------------+
0 | 49999 50000 | 89999
| |
+-------+ +-------+
| |
0 | | 89999
+-------------------+
| mirror |
| is 90000 blocks |
+-------------------+
| |
| |
+------------+ +-----------+
| |
| |
0 | 89999 0 | 89999
+-------------------+ +-------------------+
| image 1 of mirror | | image 2 of mirror |
| partition | | partition |
| starts at 1000 | | starts at 2000 |
| is 90000 blocks | | is 90000 blocks |
+-------------------+ +-------------------+
1000 | 90999 2000 | 91999
| |
| |
+-------------------+ +-------------------+
| physical | | physical |
| sd(ncsc(0,7),0,0 | | sd(ncsc(0,7),1,0 |
+-------------------+ +-------------------+
| |
| |
---------- ----------
( ) ( )
( ) ( )
( disk ) ( disk )
( drive ) ( drive )
( 1 ) ( 2 )
( ) ( )
---------- ----------
There are pros and cons to each arrangement:
Traditional Arrangement Pros:
1. It is a traditional arrangement and may be easier to
understand.
2. The I/O to the two top level virtual disks is independent
until it reaches the disk drives. This may mean better
performance because there is a smaller bottleneck.
3. You can boot from the traditional root by booting from one
image of the mirror.
Traditional Arrangement Cons:
1. There are two mirrors to manage.
2. If you want to add additional partitions, you have to create
them on both physical disks and create another mirror.
Alternate Arrangement Pros:
1. There is only one mirror to manage.
2. This creates "mirrored storage", which you can build
additional partitions out of easily.
Alternate Arrangement Cons:
1. It it a non-traditional arrangement and may be harder to
understand. A physical disk listing from admpdisk(1M), for
instance, will show the two partitions of the mirror instead
of the two top level partitions, so it may be harder to find
things.
2. The single mirror represents a bottleneck and may cause
performance problems. The I/O from each top level partition
will compete for mirror resources to be executed.
3. You cannot boot from the alternate root, since it is not a
simple partition of the physical instance. Do not set root or
usr up this way because you will not be able to boot your
system.
You are free to choose the arrangement for your partitions that best
fits your needs.
Software bad-block remapping is only supported for partitions of the
physical instance itself. Partitions like the top level ones in the
alternate example above implicitly have bad-block protection if the
base partitions (the images of the mirror) have it enabled.
USABILITY
For you to be able to use a partition (i.e., open it), both both the
partitioned child and the remap child must be usable. This is
usually the case, except when the remap child has been damaged for
some reason, which is rare.
EXPANDING AND SHRINKING PARTITIONS
Partitions can be expanded on-line while they are open and the
virtual disk is in use. This will make the partition larger, by
incorporating contiguous free space that immediately follows the
partition.
The application using the partition must be prepared for such an
expansion. The DG/UX file system is, so you can expand DG/UX file
systems on-line, without unmounting them. The users can continue to
read and write to the file system while it is being expanded.
However, most database software is not prepared to have its regions
expanded. Instead, simply add another region to the database.
Partitions can likewise be shrunk, but only when the virtual disk is
closed and not in use. Applications like the DG/UX file system can
be made to handle on-line expansions relatively easily, but on-line
shrinking would be more difficult to build, so the VDM does not
permit it. A shrink requires the data in the portion to be removed,
be migrated out, and rewritten to other places in the virtual disk.
INSERTING AND EXTRACTING PARTITIONS
Partitions can be inserted and extracted, but it's not a useful thing
to do. If you insert a partition, it must cover the entire range of
the partitioned child, otherwise it will implicitly shrink the
virtual disk the application is using, causing I/O errors. Further,
because of this, there will be no free space left on the partitioned
child for additional partitions.
In order to extract a partition, it must have one child, the
partitioned disk. Further, the partition must span the entire
physical disk to avoid causing I/O errors to the applications using
it for the same reasons given above. This is not possible for
registered disks, since the VDM itself maintains several system
partitions to manage things like the disk label and the VDITs.
Since it is of no practical use to insert or extract partitions, we
do not recommend it be done.
CLUSTER DISKS
Partitions may be created on cluster disks and may use software bad-
block remapping if desired.
BOOTING FROM PARTITIONS
You can boot from partitions as long as they are simple partitions of
the physical instance (e.g., you cannot boot from the root in the
alternate swap and root example above). They may have software bad-
block remapping enabled if desired.
HALT DUMPS TO VIRTUAL DISKS
When the DG/UX system abnormally halts due to a hardware problem or
an internal DG/UX problem, you are given the opportunity to take a
halt dump to submit with a Software Trouble Report (STR).
You can take the halt dump to a partition that you have previously
set up. This is many times faster than taking the dump to tape. For
more details on this, see the vdm(7) man page.
PROGRAMMING INTERFACE
The ioctl(2) system call is used for all communication with the
Partition Subdriver. Use the open(2) system call to open a channel
to the /dev/vdm node, and issue all ioctl(2) commands through that
channel. See vdm(7) for more details on the programming interface.
The <sys/ioctl.h> include file is required for communicating with the
Partition Subdriver. The <errno.h>, <sys/dg_sysctl.h>,
<sys/types.h>, <stdio.h>, and <unistd.h> include files will be
helpful.
SUBDRIVER-SPECIFIC COMMANDS
DG_VDMPART_LIST_PARTITIONS
List the partitions of a partitioned instance.
COMMON DISK COMMANDS
The following commands are common to all device drivers that manage
physical disks. The VDM and the subdrivers support the commands on
virtual disks as well, because they present the same interfaces as
physical disks.
DSKIOCGET
This command returns the size of the virtual disk in sectors. For
virtual disks, one sector is one disk block, or 512 bytes. The
command and associated structure is described in more detail in
dsk(7).
DSKIOCUSAGE
This command returns I/O count and performance statistics on the I/O
issued to a virtual disk. The command and associated packet is
described in more detail in dsk(7).
SUBDRIVER-SPECIFIC DEFINES
DG_VDMPART_SUBDRIVER_ID
The unique ID that identifies the Partition Subdriver.
DG_VDMPART_IOCTL_PACKET_VERSION_0
The version zero stamp used in all Partition Subdriver ioctl(2)
packets.
The stamp indicates which version of the Partition Subdriver
interface is being used and allows the Partition Subdriver to support
previous versions without requiring that applications be recompiled.
DG_VDMPART_PARTITIONED_CHILD
The value indicating that this child is the partitioned child. The
partitions reside on the partitioned instance.
DG_VDMPART_REMAP_CHILD
The value indicating that this child is the remap child. The remap
child is used for bad-block remapping for the partition.
STRUCTURES
dg_vdmpart_create_packet
The Partition Subdriver ioctl(2) packet for creating a new partition
instance. Put a pointer to this packet into the packet for the
DG_VDM_CREATE_INSTANCE command.
struct dg_vdmpart_create_packet
{
int version;
dev_t partitioned_instance;
daddr_t starting_block;
unsigned int size_in_blocks;
dev_t remap_device_number;
};
version
The version of the packet.
partitioned_instance
The device number of the instance being partitioned.
starting_block
The starting block number of the partition. Block numbers are
zero-based.
size_in_blocks
The number of blocks in the partition.
remap_device_number
The device number of the bad-block remapping instance to use
with the partition. If bad-block remapping is not desired,
set the field to NODEV.
dg_vdmpart_get_packet
The Partition Subdriver ioctl(2) packet for getting the attributes of
a partition instance. Put a pointer to this packet into the packet
for the DG_VDM_GET_ATTRIBUTES command.
struct dg_vdmpart_get_packet
{
int version;
daddr_t starting_block;
unsigned int size_in_blocks;
};
version
The version of the packet.
starting_block
The returned starting block number of the partition. Block
numbers are zero-based.
size_in_blocks
The returned number of blocks in the partition.
dg_vdmpart_update_attributes_packet
The Partition Subdriver ioctl(2) packet for updating the attributes
of a partition instance. Put a pointer to this packet into the
packet for the DG_VDM_UPDATE_ATTRIBUTES command.
struct dg_vdmpart_update_attributes_packet
{
int version;
int change_in_size;
};
version
The version of the packet.
change_in_size
The number of blocks by which to grow (if positive) or shrink
(if negative) the partition. Partitions may be grown while
they are on-line and in use. They may only be shrunk while
they are off-line.
dg_vdmpart_get_child_packet
The Partition Subdriver ioctl(2) packet for getting child role
information about the children of a partition instance. Put a
pointer to this packet into the child instance sub-packet for the
DG_VDM_GET_CHILD_INSTANCE command.
struct dg_vdmpart_get_child_packet
{
int version;
int child_type;
union
{
struct
{
daddr_t starting_block;
unsigned int size_in_blocks;
} partitioned;
} child;
};
version
The version of the packet.
child_type
The returned type of the child. The type will either be
DG_VDMPART_PARTITIONED_CHILD or DG_VDMPART_REMAP_CHILD. This
identifies the role the child plays for the partition, and
which fields of the child union are returned. Note that child
information is only returned for the partitioned child. The
remap child has no additional role information to return.
child A returned union of the structures used for child role
information about the children of a partition.
partitioned
The returned structure containing the child role information
about the partitioned child of a partition.
child.partitioned.starting_block
The returned starting block number of the partition. Block
numbers are zero-based.
child.partitioned.size_in_blocks
The returned number of blocks in the partition.
dg_vdmpart_list_partitions_packet
The Partition Subdriver ioctl(2) packet for listing the partitions of
a partitioned instance. Put a pointer to this packet into the
argument field of the packet for the DG_VDM_IOCTL_SUBDRIVER command,
and set the command field to DG_VDMPART_LIST_PARTITIONS. Set the
instance device number field to NODEV, so the command will be issued
to the Partition Subdriver itself.
Each time the DG_VDMPART_LIST_PARTITIONS command is issued, the
device number of the next partition will be returned. When there are
no more partitions to return, error ENOENT will be returned.
Note that the information returned can become invalid if partitions
are created or deleted in between commands.
struct dg_vdmpart_list_partitions_packet
{
int version;
dev_t partitioned_instance;
unsigned int key;
dev_t partition_device_number;
daddr_t starting_block;
unsigned int size_in_blocks;
};
version
The version of the packet.
partitioned_instance
The device number of the partitioned instance. The partitions
residing on this instance will be listed.
key The key for the request. Initialize the key to zero before
issuing the command for the first time. The key value will be
updated by the Partition Subdriver on each subsequent call to
keep track of its place in the list. Do not further alter the
key value, except to reset it to zero to start the listing
over again.
partition_device_number
The returned device number of the next partition of the
instance.
starting_block
The returned starting block number of the partition. Block
numbers are zero-based.
length_in_blocks
The returned number of blocks in the partition.
EXAMPLES
The following code fragments illustrate how to use the packets and
commands described in this man page. The fragments are not complete
and are not intended to be compilable or executable. In particular,
initialization code, instance locating code, and error handling are
left out for brevity.
Common includes and variables
#include <errno.h>
#include <sys/dg_sysctl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int status; /* status from system call */
int vdm_channel; /* channel to /dev/vdm node */
Create a partition
dev_t part_instance;
dev_t phys_instance;
dev_t remap_instance;
struct dg_vdm_create_instance_packet create_pkt;
struct dg_vdmpart_create_packet part_create_pkt;
create_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
create_pkt.subdriver_id = DG_VDMPART_SUBDRIVER_ID;
create_pkt.persistent = 1;
create_pkt.enable_disk_updates = 1;
strcpy (create_pkt.instance_name, "inventory_db");
create_pkt.subdriver_attributes_packet_ptr = &part_create_pkt;
part_create_pkt.version = DG_VDMPART_IOCTL_PACKET_VERSION_0;
part_create_pkt.partitioned_instance = phys_instance;
part_create_pkt.starting_block = 1000;
part_create_pkt.size_in_blocks = 300000;
part_create_pkt.remap_device_number = remap_instance;
status = ioctl (vdm_channel,
DG_VDM_CREATE_INSTANCE,
&create_pkt);
part_instance = create_pkt.device_number;
printf ("Partition device number = 0x%08x\n", part_instance);
Update a partition's attributes to expand it
dev_t update_instance;
struct dg_vdm_update_attributes_packet update_attrs_pkt;
struct dg_vdmpart_update_attributes_packet part_update_pkt;
update_attrs_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
update_attrs_pkt.instance_device_number = update_instance;
update_attrs_pkt.subdriver_id = DG_VDMPART_SUBDRIVER_ID;
update_attrs_pkt.subdriver_attributes_packet_ptr = &part_update_pkt;
part_update_pkt.version = DG_VDMPART_IOCTL_PACKET_VERSION_0;
part_update_pkt.change_in_size = 55000;
status = ioctl (vdm_channel,
DG_VDM_UPDATE_ATTRIBUTES,
&update_attrs_pkt);
Get a partition's attributes
dev_t get_instance;
struct dg_vdm_get_attributes_packet get_attrs_pkt;
struct dg_vdmpart_get_packet part_get_pkt;
get_attrs_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
get_attrs_pkt.instance_device_number = get_instance;
get_attrs_pkt.subdriver_id = DG_VDMPART_SUBDRIVER_ID;
get_attrs_pkt.subdriver_attributes_packet_ptr = &part_get_pkt;
part_get_pkt.version = DG_VDMPART_IOCTL_PACKET_VERSION_0;
status = ioctl (vdm_channel,
DG_VDM_GET_ATTRIBUTES,
&get_attrs_pkt);
printf ("Starting block = %lu\n",
part_get_pkt.starting_block,
printf ("Number of blocks = %u\n",
part_get_pkt.size_in_blocks);
Link a remap child to a partition (enable remapping)
dev_t link_instance;
dev_t remap_instance;
struct dg_vdm_link_child_instance_packet link_pkt;
link_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
link_pkt.parent_device_number = link_instance;
link_pkt.parent_subdriver_id = DG_VDMPART_SUBDRIVER_ID;
link_pkt.child_device_number = remap_instance;
link_pkt.child_packet_ptr = NULL;
status = ioctl (vdm_channel,
DG_VDM_LINK_CHILD_INSTANCE,
&link_pkt);
Get the children of a partition
int i;
dev_t part_instance;
dev_t child_instance;
struct dg_vdm_child_instance_packet child_pkt;
struct dg_vdm_get_child_instance_packet get_child_pkt;
struct dg_vdmpart_get_child_packet part_get_child_pkt;
get_child_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
get_child_pkt.key = 0;
get_child_pkt.parent_device_number = part_instance;
get_child_pkt.parent_subdriver_id = DG_VDMPART_SUBDRIVER_ID;
get_child_pkt.available = 0;
get_child_pkt.child_instance_array_ptr = NULL;
status = ioctl (vdm_channel,
DG_VDM_GET_CHILD_INSTANCE,
&get_child_pkt);
printf ("Number of children = %d\n",
get_child_pkt.number_of_children);
get_child_pkt.key = 0;
get_child_pkt.available = 1;
get_child_pkt.child_instance_array_ptr = &child_pkt;
child_pkt.child_role_packet_ptr = &part_get_child_pkt;
part_get_child_pkt.version = DG_VDMPART_IOCTL_PACKET_VERSION_0;
i = 0;
while (1)
{
status = ioctl (vdm_channel,
DG_VDM_GET_CHILD_INSTANCE,
&get_child_pkt);
if ((status == -1) && (errno == ENOENT))
{
break;
}
printf ("Child %d\n", i);
switch (part_get_child_pkt.child_type)
{
case DG_VDMPART_PARTITIONED_CHILD:
printf ("Partition of\n");
break;
case DG_VDMPART_REMAP_CHILD:
printf ("Remapping with\n");
remap_found = 1;
break;
}
if (child_pkt.child_instance.device_number_used)
{
child_instance = child_instance_pkt.child_instance.
specifier_value.device_number;
printf ("Child device number = 0x%08x\n", child_instance);
if (child_pkt.child_subdriver_id ==
DG_VDM_SUBDRIVER_ID_OF_A_NON_VDM_DEVICE)
{
printf (" Non-vdm child\n");
}
else
{
printf (" Child subdriver 0x%08x\n",
child_pkt.child_subdriver_id);
}
}
else
{
printf (" Missing child ID %08x,%08x\n",
child_pkt.child_instance.specifier_value.id.generation,
child_pkt.child_instance.specifier_value.id.system_id);
}
if (part_get_child_pkt.child_type == DG_VDMPART_PARTITIONED_CHILD)
{
printf (" Start = %lu, blocks = %u\n",
part_get_child_pkt.child.partitioned.starting_block,
part_get_child_pkt.child.partitioned.size_in_blocks);
}
printf ("\n");
i++;
}
Unlink a remap child from a partition (disable remapping)
dev_t unlink_instance;
dev_t remap_instance;
struct dg_vdm_unlink_child_instance_packet unlink_pkt;
unlink_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
unlink_pkt.parent_device_number = unlink_instance;
unlink_pkt.child_instance.device_number_used = 1;
unlink_pkt.child_instance.specifier_value.device_number =
remap_instance;
status = ioctl (vdm_channel,
DG_VDM_UNLINK_CHILD_INSTANCE,
&unlink_pkt);
List the partitions on a physical instance
int i;
dev_t phys_instance
struct dg_vdm_ioctl_subdriver_packet ioctl_pkt;
struct dg_vdmpart_list_partitions_packet list_partitions_pkt;
ioctl_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
ioctl_pkt.subdriver_id = DG_VDMPART_SUBDRIVER_ID;
ioctl_pkt.instance_device_number = NODEV;
ioctl_pkt.command = DG_VDMPART_LIST_PARTITIONS;
ioctl_pkt.argument = (int) &list_partitions_pkt;
list_partitions_pkt.version = DG_VDMPART_IOCTL_PACKET_VERSION_0;
list_partitions_pkt.partitioned_instance = phys_instance;
list_partitions_pkt.key = 0;
i = 0;
while (1)
{
status = ioctl (vdm_channel,
DG_VDM_IOCTL_SUBDRIVER,
&ioctl_pkt);
if ((status == -1) && (errno == ENOENT))
{
break;
}
printf ("Partition %d\n", i);
printf ("Partition device number = 0x%08x\n",
list_partitions_pkt.partition_device_number);
printf (" Start = %lu, blocks = %u\n",
list_partitions_pkt.starting_block,
list_partitions_pkt.size_in_blocks);
printf ("\n");
i++;
}
Get the size of a partition
dev_t ioctl_instance;
struct dg_vdm_ioctl_subdriver_packet ioctl_pkt;
struct dskget dskget_pkt;
ioctl_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
ioctl_pkt.subdriver_id = DG_VDMPART_SUBDRIVER_ID;
ioctl_pkt.instance_device_number = ioctl_instance;
ioctl_pkt.command = DSKIOCGET;
ioctl_pkt.argument = (int) &dskget_pkt;
status = ioctl (vdm_channel,
DG_VDM_IOCTL_SUBDRIVER,
&ioctl_pkt);
printf ("Total blocks = %u\n",
dskget_pkt.total_sectors *
(dskget_pkt.bytes_per_sector / 512));
FILES
/dev/dsk
Directory for the block special device nodes for virtual
disks. These are the buffered access device nodes.
/dev/rdsk
Directory for the character special device nodes for virtual
disks. These are the unbuffered (or raw) access device nodes.
/dev/vdm
Device node for issuing all ioctl(2) commands.
/usr/include/sys/ioctl.h
ioctl(2) definitions.
ACCESS CONTROL
Access control for the standard VDM framework commands is controlled
by the VDM itself. See the vdm(7) man page for a listing of these
controls.
Access control for the Partition Subdriver commands is controlled by
the subdriver itself.
All users may execute these commands: DG_VDM_GET_ATTRIBUTES,
DG_VDM_GET_CHILD_INSTANCE, DG_VDMPART_LIST_PARTITIONS, DSKIOCGET,
DSKIOCUSAGE.
Only users with appropriate privilege may execute these commands:
DG_VDM_CREATE_INSTANCE, DG_VDM_LINK_CHILD_INSTANCE,
DG_VDM_UNLINK_CHILD_INSTANCE, DG_VDM_UPDATE_ATTRIBUTES.
On a generic DG/UX system, appropriate privilege is granted by having
an effective UID of 0 (root). See the appropriate_privilege(5) man
page for more information.
On a system with DG/UX information security, appropriate privilege is
granted by having one or more specific capabilities enabled in the
effective capability set of the user. See the cap_defaults(5) man
page for the default capabilities for these commands.
RETURN VALUE
The return value from the ioctl(2) system call used to issue the
command will be one of the following:
0 The command was successful.
-1 An error occurred. errno is set to indicate the error.
DIAGNOSTICS
There are descriptive extended error message strings available for
most of the error codes. They can be retrieved with the
dg_ext_errno(2), extended_strerror(3C), and extended_perror(3C)
routines.
Errno may be set to one of the DG/UX standard error codes. See
/usr/include/sys/errno.h for a listing of those error codes.
Errno may be set to one of the standard error codes provided by the
VDM framework. See vdm(7) for a listing of those error codes.
Errno may also be set to one of the following error codes that are
specific to this subdriver:
EBUSY There are still remapped partitions on the virtual disk.
EBUSY Cannot create or modify the partition. It would overlap
another partition.
EBUSY Cannot shrink a partition while it is open.
EINVAL Cannot open the partitioned virtual disk yet, it is not
usable.
EINVAL Cannot open the remap virtual disk yet, it is not usable.
EINVAL The partition is already remapped.
EINVAL The partition is not remapped.
EINVAL Cannot create or modify the partition. Its size would be zero
or negative.
ENOENT There are no more partitions to list.
ENXIO There are no partitions on the virtual disk.
ENXIO The remap virtual disk does not belong to the partitioned
virtual disk.
ENXIO Cannot create or modify the partition. It does not fit on the
partitioned virtual disk.
SEE ALSO
ioctl(2), dsk(7), rdsk(7), vdm(7).
Licensed material--property of copyright holder(s)