vdmphys(7) DG/UX R4.11MU05 vdmphys(7)
NAME
vdmphys - Virtual Disk Manager Physical Subdriver
DESCRIPTION
The Physical Subdriver translates internal VDM interfaces for virtual
disks into physical disk device driver interfaces. A physical
instance must exist at the bottom of every virtual disk hierarchy.
A physical instance manages one specific physical disk. The physical
instance can be used to access all blocks of the disk, so partitions
are usually created on top of the physical instance to subdivide the
disk into usable regions.
The Physical Subdriver implements a read/write or read-only flag so
that disks can be made read-only if desired. Most fixed hard disks
do not have a hardware tab or jumper that can be used to make the
disk read-only, so the Physical Subdriver supports it in software.
Finally, the Physical Subdriver implements a cluster or non-cluster
flag to control the cluster mode of the physical disk.
Pictorially, a physical instance for a physical disk looks like this:
+-------------------+
| physical |
| sd(ncsc(0,7),0,0) |
+-------------------+
|
|
----------
( )
( )
( disk )
( drive )
( 1 )
( )
----------
The physical instance's only child is always a physical disk.
Physical instances cannot control tape drives, terminal lines, etc.,
only true physical disks.
Physical instances can control any type of removable or non-removable
hard disk, including traditional magnetic disks, CLARiiON® disks,
floppy disks, and CD-ROMs. All device controller types supported by
DG/UX are supported by the Physical Subdriver.
Physical instances are generally invisible on the system. They are
created automatically when you format a disk with sysadm(1M) or
admpdisk(1M). Whenever you use sysadm(1M) or admvdisk(1M) to get the
name of a physical instance in a listing, you will get the name of
the physical disk that it is managing instead, since the name of the
physical disk is usually more important.
Physical instances are generally created without a name. You can
rename them if you care to. The name will then become a sort of
"volume label" for the disk. Choose names that reflect the data
stored on the disk, like "Payroll_Disk" or "Home_Dirs_Disk". You can
use these names when specifying physical disks to sysadm(1M),
admvdisk(1M), and admpdisk(1M) while the disks are registered.
Do not use the name of the physical disk as the name of the physical
instance, since the physical disk name will change if you move the
disk around on your system. The out-of-date physical instance name
would then cause confusion.
In order to use the Physical Subdriver, you must configure vdmphys()
into your kernel. It appears in all new system files by default, so
it is usually already configured.
For more details about how the Physical Subdriver fits into the
Virtual Disk Manager, see the vdm(7) man page.
READ-ONLY DISKS
Since most physical disks do not have hardware tabs or jumpers that
can be used to make them read-only, the Physical Subdriver implements
the feature in software instead.
By changing the open flag of the instance from O_RDWR to O_RDONLY,
the physical instance will treat the disk as if it were read-only.
All writes to a read-only physical instance will return an error.
The physical instance can be changed back from O_RDONLY to O_RDWR as
well.
This is useful if a disk contains archival information that is never
supposed to be changed. You would write the data to the disk while
the physical instance was read/write, then unmount all the file
systems on it and close the databases on it, and finally change the
physical instance for the disk to read-only mode. That will prevent
any further modifications to the user data stored on the disk, as
well as the VDM metadata stored in the VDITs.
The file systems on a read-only disk will have to be mounted read-
only as well, in order to use them properly.
CLUSTER DISKS
The Physical Subdriver implements the low-level support for cluster
disks. This involves placing cluster disks into shared mode and non-
cluster disks into private mode.
You cannot change the cluster mode of a physical instance directly.
Instead, use the DG_VDM_CLUSTER_DISK command, which will coordinate
all the necessary virtual disk changes along with the change of the
physical instance into cluster or non-cluster mode.
You can query a physical instance to see if it is in cluster mode
without restrictions.
The Physical Subdriver does not support changing a cluster disk into
read-only mode.
Do not change the shared/private mode of the physical disk that a
physical instance is managing by hand. Doing so will open the disk
up to serious potential data corruption. Let the physical instance
manage the disk safely.
USABILITY
A physical instance is usable as long as the physical disk it is
controlling is usable. If the physical disk fails due to a hardware
problem, the physical instance will likewise be unusable.
INSERTING AND EXTRACTING PHYSICAL INSTANCES
Physical instances cannot be inserted or extracted. Since insert and
extract require a virtual disk child, and the physical instance
always has a physical disk child, the operations simply can't be
done.
PROGRAMMING INTERFACE
The ioctl(2) system call is used for all communication with the
Physical 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
Physical 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_VDMPHYS_FIND_PHYSICAL
Finds the physical instance that manages a physical disk.
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_VDMPHYS_SUBDRIVER_ID
The unique ID that identifies the Physical Subdriver.
DG_VDMPHYS_IOCTL_PACKET_VERSION_0
The version zero stamp used in all Physical Subdriver ioctl(2)
packets.
The stamp indicates which version of the Physical Subdriver interface
is being used and allows the Physical Subdriver to support previous
versions without requiring that applications be recompiled.
DG_VDMPHYS_CREATE_PACKET_VERSION_1
The stamp used in version one of the dg_vdmphys_create_packet.
DG_VDMPHYS_GET_PACKET_VERSION_1
The stamp used in version one of the dg_vdmphys_get_packet.
DG_VDMPHYS_UPDATE_PACKET_VERSION_1
The stamp used in version one of the dg_vdmphys_update_packet.
STRUCTURES
dg_vdmphys_create_packet
The Physical Subdriver ioctl(2) packet for creating a new physical
instance. Put a pointer to this packet into the packet for the
DG_VDM_CREATE_INSTANCE command.
There are two versions of this packet. Unless otherwise stated
below, all fields are used in all versions.
struct dg_vdmphys_create_packet
{
int version;
int open_flag;
dev_t child_device_number;
unsigned int cluster_mode : 1;
};
version
The version of the packet. Set this to either
DG_VDMPHYS_IOCTL_PACKET_VERSION_0 or
DG_VDMPHYS_CREATE_PACKET_VERSION_1, depending on which version
of the packet you want to use.
open_flag
The flag controlling the read/write mode of the physical
instance. Set it to O_RDONLY for read-only mode, or O_RDWR
for read/write mode.
child_device_number
The device number of the physical disk that the physical
instance is to manage.
cluster_mode
If set to one, it indicates that the physical instance and
physical disk are to be put into cluster mode. If set to
zero, it indicates that they are to be put into non-cluster
mode.
Users may not set this field to one. Only the DG/UX system is
permitted to put disks into cluster mode.
This field is used only if the packet version is set to
DG_VDMPHYS_CREATE_PACKET_VERSION_1.
dg_vdmphys_get_packet
The Physical Subdriver ioctl(2) packet for getting information about
a physical instance. Put a pointer to this packet into the packet
for the DG_VDM_GET_ATTRIBUTES command.
There are two versions of this packet. Unless otherwise stated
below, all fields are used in all versions.
struct dg_vdmphys_get_packet
{
int version;
int open_flag;
dev_t child_device_number;
unsigned int cluster_mode : 1;
};
version
The version of the packet. Set this to either
DG_VDMPHYS_IOCTL_PACKET_VERSION_0 or
DG_VDMPHYS_GET_PACKET_VERSION_1, depending on which version of
the packet you want to use.
open_flag
The returned flag indicating the read/write mode of the
physical instance. If set to O_RDONLY, it indicates that the
physical instance is in read-only mode. If set to O_RDWR, it
is in read/write mode.
child_device_number
The returned device number of the physical disk that the
physical instance is managing.
cluster_mode
The returned clustering mode of the physical instance and
physical disk. If set to one, it indicates that the physical
instance and physical disk are in cluster mode. If set to
zero, it indicates that they are in non-cluster mode.
This field is used only if the packet version is set to
DG_VDMPHYS_GET_PACKET_VERSION_1.
dg_vdmphys_update_packet
The Physical Subdriver ioctl(2) packet for updating the attributes of
a physical instance. Put a pointer to this packet into the packet
for the DG_VDM_UPDATE_ATTRIBUTES command.
There are two versions of this packet. Unless otherwise stated
below, all fields are used in all versions.
struct dg_vdmphys_update_packet
{
int version;
int open_flag;
unsigned int cluster_mode : 1;
unsigned int update_open_flag : 1;
unsigned int update_cluster_mode : 1;
};
version
The version of the packet. Set this to either
DG_VDMPHYS_IOCTL_PACKET_VERSION_0 or
DG_VDMPHYS_UPDATE_PACKET_VERSION_1, depending on which version
of the packet you want to use.
open_flag
The flag controlling the read/write mode of the physical
instance. Set it to O_RDONLY for read-only mode, or O_RDWR
for read/write mode.
You may not update the open_flag and the cluster_mode at the
same time. Make each change separately.
If the packet version is DG_VDMPHYS_IOCTL_PACKET_VERSION_0,
this field is used without any conditions.
If the packet version is DG_VDMPHYS_UPDATE_PACKET_VERSION_1,
then this field is used only if update_open_flag is set to
one.
cluster_mode
If set to one, it indicates that the physical instance and
physical disk are to be changed from non-cluster mode to
cluster mode. If set to zero, it indicates that they are to
be changed from cluster mode to non-cluster mode. This field
is used only if update_cluster_mode is set to one.
You may not update the open_flag and the cluster_mode at the
same time. Make each change separately.
Users may not set this field. Only the DG/UX system is
permitted to change the clustering mode of disks.
You may not change the cluster mode of read-only disks.
This field is used only if the packet version is set to
DG_VDMPHYS_UPDATE_PACKET_VERSION_1.
update_open_flag
If set to one, it indicates that the open_flag field should be
used to update the physical instance. Otherwise, the physical
instance's read/write mode will not be changed.
You may not update the open_flag and the cluster_mode at the
same time. Make each change separately.
This field is used only if the packet version is set to
DG_VDMPHYS_UPDATE_PACKET_VERSION_1.
update_cluster_mode
If set to one, it indicates that the cluster_mode field should
be used to update the physical instance. Otherwise, the
physical instance's cluster mode will not be changed.
You may not update the open_flag and the cluster_mode at the
same time. Make each change separately.
Users may not set this field to one. Only the DG/UX system is
permitted to change the clustering mode of disks.
This field is used only if the packet version is set to
DG_VDMPHYS_UPDATE_PACKET_VERSION_1.
dg_vdmphys_find_physical_packet
The Physical Subdriver ioctl(2) packet for finding the device number
of the physical instance that is managing a physical disk. 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_VDMPHYS_FIND_PHYSICAL. Set the instance device number field to
NODEV, so the command will be issued to the Physical Subdriver
itself.
struct dg_vdmphys_find_physical_packet
{
int version;
dev_t disk_device_number;
dev_t instance_device_number;
};
version
The version of the packet.
disk_device_number
The device number of the physical disk to locate.
instance_device_number
The returned device number of the physical instance that is
managing the physical disk.
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 physical instance
dev_t phys_instance;
dev_t disk_device;
struct dg_vdm_create_instance_packet create_pkt;
struct dg_vdmphys_create_packet phys_create_pkt;
create_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
create_pkt.subdriver_id = DG_VDMPHYS_SUBDRIVER_ID;
create_pkt.persistent = 0;
create_pkt.enable_disk_updates = 0;
create_pkt.instance_name [0] = '\0';;
create_pkt.subdriver_attributes_packet_ptr = &phys_create_pkt;
phys_create_pkt.version = DG_VDMPHYS_CREATE_PACKET_VERSION_1;
phys_create_pkt.open_flag = O_RDWR;
phys_create_pkt.child_device_number = disk_device;
phys_create_pkt.cluster_mode = 0;
status = ioctl (vdm_channel,
DG_VDM_CREATE_INSTANCE,
&create_pkt);
phys_instance = create_pkt.device_number;
printf ("Physical instance device number = 0x%08x\n", phys_instance);
Update a physical instance's open flag
dev_t update_instance;
struct dg_vdm_update_attributes_packet update_attrs_pkt;
struct dg_vdmphys_update_packet phys_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_VDMPHYS_SUBDRIVER_ID;
update_attrs_pkt.subdriver_attributes_packet_ptr = &phys_update_pkt;
phys_update_pkt.version = DG_VDMPHYS_UPDATE_PACKET_VERSION_1;
phys_update_pkt.open_flag = O_RDONLY;
phys_update_pkt.update_open_flag = 1;
phys_update_pkt.update_cluster_mode = 0;
status = ioctl (vdm_channel,
DG_VDM_UPDATE_ATTRIBUTES,
&update_attrs_pkt);
Get a physical instance's attributes
dev_t get_instance;
struct dg_vdm_get_attributes_packet get_attrs_pkt;
struct dg_vdmphys_get_packet phys_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_VDMPHYS_SUBDRIVER_ID;
get_attrs_pkt.subdriver_attributes_packet_ptr = &phys_get_pkt;
phys_get_pkt.version = DG_VDMPHYS_GET_PACKET_VERSION_1;
status = ioctl (vdm_channel,
DG_VDM_GET_ATTRIBUTES,
&get_attrs_pkt);
switch (phys_get_pkt.open_flag)
{
case O_RDONLY:
printf ("I/O mode = read only\n");
break;
case O_RDWR:
printf ("I/O mode = read/write\n");
break;
}
if (phys_get_pkt.cluster_mode)
{
printf ("Cluster mode = cluster\n");
}
else
{
printf ("Cluster mode = non-cluster\n");
}
printf ("Disk device number = 0x%08x\n",
phys_get_pkt.child_device_number);
Get the children of a physical instance
int i;
dev_t phys_instance;
dev_t child_instance;
struct dg_vdm_child_instance_packet child_pkt;
struct dg_vdm_get_child_instance_packet get_child_pkt;
get_child_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
get_child_pkt.key = 0;
get_child_pkt.parent_device_number = phys_instance;
get_child_pkt.parent_subdriver_id = DG_VDMPHYS_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 = NULL;
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);
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);
}
printf ("\n");
i++;
}
Find the physical instance managing a physical disk
dev_t disk_device;
struct dg_vdm_ioctl_subdriver_packet ioctl_pkt;
struct dg_vdmphys_find_physical_packet find_phys_pkt;
ioctl_pkt.version = DG_VDM_IOCTL_PACKET_VERSION_0;
ioctl_pkt.subdriver_id = DG_VDMPHYS_SUBDRIVER_ID;
ioctl_pkt.instance_device_number = NODEV;
ioctl_pkt.command = DG_VDMPHYS_FIND_PHYSICAL;
ioctl_pkt.argument = (int) &find_phys_pkt;
find_phys_pkt.version = DG_VDMPHYS_IOCTL_PACKET_VERSION_0;
find_phys_pkt.disk_device_number = disk_device;
status = ioctl (vdm_channel,
DG_VDM_IOCTL_SUBDRIVER,
&ioctl_pkt);
printf ("Physical instance device number = 0x%08x\n",
find_phys_pkt.instance_device_number);
Get the size of a physical instance (the disk size)
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_VDMPHYS_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 Physical Subdriver commands is controlled by
the subdriver itself.
All users may execute these commands: DG_VDM_GET_ATTRIBUTES,
DG_VDM_GET_CHILD_INSTANCE, DG_VDMPHYS_FIND_PHYSICAL, DSKIOCGET,
DSKIOCUSAGE.
Only users with appropriate privilege may execute these commands:
DG_VDM_CREATE_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:
EINVAL The open flag field is not valid.
EINVAL Cannot open that type of device, only real disks are
supported.
EINVAL Cannot update the open flag and cluster mode at the same time.
EINVAL Cannot change the cluster mode of read-only disks.
EINVAL Cannot change the cluster mode of non-persistent 'physical'
virtual disks.
EIO Cannot write to a read-only virtual disk.
SEE ALSO
ioctl(2), dsk(7), rdsk(7), vdm(7).
Licensed material--property of copyright holder(s)