As its name implies,
LDdriver is a logical disk driver that allows you to use a file on any type of
hard disk as a disk. For example, if you have a file called
LDDISK:[VMS]DISK.DAT, you can use that file as a disk by entering the command
LD CONNECT LDDISK:[VMS]DISK.DAT LDA1:. After that you have a device LDA1: on
the system which you can use as a disk.
The LD system startup
procedure is SYS$STARTUP:LD$STARTUP. You
can put the startup command the SYS$SYSTEM:SYSTARTUP_VMS.COM file. An optional
startup parameter allows you to increase the number of LD devices by specifying
the controller letter to use for LD. If the controller letter is not specified,
then LDA will be used (allowing up to 9999 LD devices), but if you would like
an additional controller, specify B as the first parameter to get LDB.
LDdriver operates in three different modes:
- FILE mode, which allows any arbitrary file to be used as disk.
- LBN mode, which allows you to specify blocks on a disk.
- REPLACE mode, which allows access to the disk.
These modes are
explained in the following subsections. If you need any help, just remember the
command LD HELP. Every command is described in detail, and a couple of examples
are provided as well.
FILE Mode
The most widely-used
mode of operation is FILE mode. It allows an arbitrary file to be used as a
disk. The only restriction on the file itself is that it must fit on a real
disk; the size may be as big as the physical disk can handle. In the past, the
file needed to be contiguous, but that restriction has been removed.
The setup is very simple:
- Create a file on a physical disk.
- Connect the file to a logical disk.
- Use it!
- After use, disconnect it.
For example:
$ ld create lddisk:[vms]disk.dsk/size=10000
$ ld connect lddisk:[vms]disk.dsk lda1:
$ ld show lda1:
%LD-I-CONNECTED, Connected $7$LDA1: to $7$DRA6:[VMS]DISK.DSK;1
This creates a new disk on the system (LDA1:), which can do anything a normal disk can do:
$ initialize lda1: lddisk
$ mount/system lda1: lddisk
%MOUNT-I-MOUNTED, LDDISK mounted on _$7$LDA1: (LDDRVR)
$ dismount lda1:
$ ld disconnect lda1:
This setup allows for
very flexible use of disk space. Suppose you want to create an OpenVMS disk that
you want to burn on a CD. All you need to do is mount the LD device, copy any
files on it the way you want, dismount the disk, disconnect the file from the
LD device and burn the file on a CD in any way you like. This can also be done
on a PC with a variety of PC software.
Another use of LD is
sharing the LD devices across different nodes in a cluster. Notice that LD
devices are not MSCP-served (for a number of reasons). If sharing is to be
used, the physical disk where LD's container file resides needs to be visible
on other cluster members. For example:
$ ld connect lddisk:[vms]disk.dsk lda1:/share/log
%LD-I-CONNECTED, Connected $7$LDA1: to $7$DRA6:[VMS]DISK.DSK;1 (Shared)
If the same command is
given on another node in the cluster, the resulting LD device can be mounted on
that node as well. For this to work, the driver imposes several checks.
First, the device name
has to match, as well as the allocation class, unit number, and controller
letter. The device must also connect to exactly the same file, and with the
same sharing options. The maximum disk size and the device geometry must be the
same as well.
If one of these
prerequisites is not met, a specific message will follow. Suppose a device is
connected on one node, and when you try to connect it on a second node you see
the following error:
$ ld connect lddisk:[vms]disk.dsk lda1:
%LD-F-FILEINUSE, File incompatible connected to other LD disk in cluster
-LD-F-ALLOCLASS, Allocation class mismatch
This means that you
have an allocation class mismatch. This occurs when two nodes in a cluster have
a different allocation class. Remember,
the default allocation class of an LD device will be the allocation class of
the node. You can change this at connect time by specifying the correct
allocation class. However, you can only do this if no other LD devices for the
same controller are connected.
If you look at the
other node where the file was first connected, you see this:
$ ld show/all
%LD-I-CONNECTED, Connected _$12$LDA1: to $7$DRA6:[VMS]DISK.DSK;1 (Shared)
By specifying the correct allocation class, you can do what you want:
$ ld connect lddisk:[vms]disk.dsk lda1:/alloclass=12
%LD-F-DEVICEINUSE, Device incompatible connected to other LD disk in cluster
-LD-F-NOSHARE, No sharing specified for file on this node
Oops! That does not
work, either! Remember that everything has to be the same. You have to specify that you want to share
the file, or the driver will reject our request. The following command will
work:
$ ld connect lddisk:[vms]disk.dsk lda1:/alloclass=12/share/log
%LD-I-CONNECTED, Connected $12$LDA1: to $7$DRA6:[VMS]DISK.DSK;1 (Shared)
You can use different
LD devices with different allocation classes on one node. In this case, you need a new controller
letter, which can be created by invoking LD's startup procedure and specifying
the controller letter as the command parameter, as follows:
$ @sys$startup:ld$startup b
$ ld create disk2
$ ld connect disk2 ldb5
$ ld show/all
%LD-I-CONNECTED, Connected _$12$LDA1: to $7$DRA6:[VMS]DISK.DSK;1 (Shared)
%LD-I-CONNECTED, Connected _$7$LDB5: to $7$DRA6:[VMS]DISK2.DSK;1
Connect, Create and Other Options
Several options can be
specified at connect time to influence the appearance of the logical disk. For
example, if a file was created with a size of 10000 blocks and you only want to
use the first 5000, you can do so by specifying /MAXBLOCK=5000 at connect time.
You can also influence the geometry by specifying /CYLINDERS, /TRACKS, and
/SECTORS. Although of limited use with modern disks, these qualifiers allow you
to configure a disk to exactly mimic another disk. The geometry can be copied
from an already mounted disk with /CLONE, which can also be used to create a
container file that mimics a real disk, as follows:
$ ld create/clone=$8$dua14: lddisk:[vms]cloned.dsk
$ ld connect cloned lda2/log
%LD-I-CONNECTED, Connected $12$LDA2: to $7$DRA6:[VMS]CLONED.DSK;1
This procedure will
create a logical disk LDA2 with exactly the same properties as device
$8$DUA14:. Notice that the geometry information is stored in the container
file, so a subsequent disconnect/connect will restore the same disk parameters.
The geometry information can be overridden by specifying /NOAUTOGEOMETRY, in
which case the geometry will be calculated by the driver.
The geometry
information will also be saved in the container file if /SAVE was specified
during connect.
LD devices can be
write-protected using the LD PROTECT command. You can make this protection
permanent by adding /PERMANENT, which will store the write-protect status in
the container file. This way it will be possible, for example, to emulate a
CDROM; on a subsequent CONNECT command, the write-protect status will be
restored.
Normally, a file is
connected to an LD device by explicitly specifying which device you want to
get. If you don't do this, the driver will assign a unit number and inform you
about it. If you specify /SYMBOL as well, you will get the assigned unit number
in a DCL symbol:
$ ld connect disk.dsk/symbol
%LD-I-UNIT, Allocated device is $12$LDA22:
$ show symbol ld_unit LD_UNIT = "22"
This procedure is
useful in command procedures, where the actual device name is unimportant. The
symbol makes it easy to reference such a device.
LBN Mode
In LBN (Logical Block
Number) mode, a physical disk can be accessed in several parts, as specified by
a LBN range. Look at it as partitioning a disk without any file structure on
it. For example:
$ ld connect $1$dga1: lda1:/lbn=(start=0,count=1000)/log
%LD-I-CONNECTED, Connected $7$LDA1: to _$1$DGA1: (LBN Mapping: Start=0 End=999)
$ ld connect $1$dga1: lda2:/lbn=(start=1000,end=2000)/log
%LD-I-CONNECTED, Connected $7$LDA2: to _$1$DGA1: (LBN Mapping: Start=1000 End=2000)
This procedure uses
two fragments of device $1$DGA1 for devices $7$LDA1 and $7$LDA2. The range of
LBNs can be specified in either of the following ways:
- A starting LBN with a block count
- A starting LBN and an ending LBN
The driver will check
for an overlap of LBNs, so any attempt to use a range already in use will
result in the following error:
$ ld connect $1$dga1: lda3:/lbn=(start=600,end=2000)/log
%LD-F-DEVICEINUSE, Device incompatible connected to other LD disk in cluster
-LD-F-RANGEINUSE, LBN range already in use
This way of
partitioning a disk is the most efficient way to use the physical device, since
the overhead of unused blocks is zero. The physical device can be divided in as
many parts as you need, as long as the system's resources will allow them.
Another way to use
this is to map a range of blocks from a foreign volume, for example a UNIX file system. Use your imagination!
As with FILE mode, these LD devices can be shared in a cluster:
$ ld connect $1$dga1: lda3:/lbn=(start=5000,count=5000)/log/share<
%LD-I-CONNECTED, Connected $7$LDA3: to _$1$DGA1: (LBN Mapping: Start=5000
End=9999) (Shared)
The same restrictions
apply as with FILE sharing: the device name, unit number, controller letter,
and allocation class must match the remote node. The range and physical device
have to match as well, of course. Notice that the range of LBNs in use is
checked on all the nodes in the cluster that have an interest in the physical
device, so if any block in the specified range is already in use, an error will
be generated. This is really a tricky thing to check; for more information
about this check, see Internals.
To be able to use LBN
connect, the physical device must not be in use anywhere in the cluster. The
driver will enforce a check on this, and if the check fails an error will
follow. After the first LD device is connected with LBN, the physical device
will not be available for any other use in the cluster; that is, a mount on any node will fail until the last LD
device disconnects. For example:
$ mount/over=id $1$dga1:
%MOUNT-I-OPRQST, device already allocated to another user
%MOUNT-I-OPRQST, device _$1$DGA1: (LDDRVR) is not available for mounting.
If any failure to use
the physical device occurs on any node, make sure that all LD devices are
disconnected from this device. The driver will go to great lengths to protect
the user against any errors.
REPLACE Mode
REPLACE mode is not a
form of partitioning, but a way to create access to the physical device using
LDdriver. You will understand how to use this when you read about I/O Tracing and Watchpoints, which describe how to perform a real-time trace of
all I/O requests.
The following example
creates a device ($7$LDA1) that will direct all I/O to the physical device
$1$DGA1:
$ ld connect $1$dga1: lda1:/replace/log
%LD-I-CONNECTED, Connected $7$LDA1: to _$1$DGA1: (Replaced)
Replaced devices can
also be shared:
$ ld connect $1$dga1: lda1:/replace/log/share
%LD-I-CONNECTED, Connected $7$LDA1: to _$1$DGA1: (Replaced) (Shared)
The same restrictions apply for
sharing as with FILE and LBN mode: the device name, unit number, controller
letter, and allocation class must match. The physical device will be made
unavailable by means of a lock.
I/O Tracing
One of the most
powerful and little known features of LDdriver is I/O tracing. For any mode
that an LD device operates, a real-time trace of all I/O activity can be
created. This is a simple example:
$ ld connect disk.dsk lda1
$ ld trace lda1
$ mount lda1: testdisk
%MOUNT-I-MOUNTED, TESTDISK mounted on _$7$LDA1: (LDDRVR)
$ ld show/trace lda1
I/O trace for device $7$LDA1:
26-APR-2005 22:18:36.28 on node LDDRVR::
Start Time Elaps Pid Lbn Bytes Iosb Function
--------------------------------------------------------------
22:18:32.65 00.00 09C00227 0 0 NORMAL PACKACK|INHERLOG
22:18:32.65 00.01 09C00227 1 512 NORMAL READPBLK
22:18:32.66 00.00 09C00227 1034 512 NORMAL READPBLK
22:18:32.67 00.00 09C00227 5007 512 NORMAL READPBLK
22:18:32.67 00.00 09C00227 5008 512 NORMAL READPBLK
22:18:32.67 00.00 09C00227 5002 512 NORMAL READPBLK
22:18:32.67 00.00 09C00227 5002 512 NORMAL WRITEPBLK
22:18:32.68 00.00 09C00227 5002 512 NORMAL WRITEPBLK
22:18:32.69 00.00 09C00227 5003 1536 NORMAL READPBLK
22:18:32.69 00.00 09C00227 5006 512 NORMAL READPBLK
22:18:32.69 00.00 09C00227 5010 512 NORMAL READPBLK|EXFUNC
22:18:32.69 00.00 09C00227 5000 512 NORMAL READPBLK|EXFUNC
22:18:32.69 00.00 09C00227 0 0 NORMAL PACKACK|BYPASS_VALID_CHK
22:18:32.69 00.00 09C00227 5002 512 NORMAL READPBLK|EXFUNC
22:18:32.70 00.00 09C00227 5016 512 NORMAL READPBLK|EXFUNC
22:18:32.70 00.00 09C00227 5023 1024 NORMAL READPBLK
22:18:32.70 00.00 09C00227 5016 512 NORMAL WRITEPBLK|EXFUNC|DATACHECK
The default
display shows a timestamp, the elapsed
time of the request, and so forth. Various qualifiers allow you to modify the
display, such as /IOSB=LONGHEX to show the real contents of the IOSB, and
/FUNCTION=HEX to show the function code without any translation.
Another powerful function
is to trace FDT (Function Decision Table) calls to the driver. These always happen but are not easy to see.
These requests happen in the first part of calling a driver and are used, for example,
to validate parameters. But the I/O completion can occur directly from these
FDT routines, so that the I/O request is normally not noticed. FDT tracing is
not implemented on the VAX version of LDdriver.
The timing can be
measured not only by the normal timestamps, but also by means of the SCC
(System Cycle Counter), which is a hardware register in the processor
architecture that can be used for accurate timing measurements. This counter is
only available on Alpha and IA64, so accurate tracing is not implemented on the
VAX version of LDdriver. Accurate tracing must be enabled at the time that the
trace buffer is activated (using the LD TRACE command); it is not the default
because activating this option may impose a small performance hit. The SCC counter
is specific for each processor; therefore, in a multiprocessor system, the
driver may need to reschedule the completion of an I/O request to the same
processor where the request was initiated to get an accurate measurement.
If you enable FDT and
accurate tracing, you get this:
$ ld notrace lda1
$ ld trace/fdt/accurate lda1
$ dir lda1:[000000]/out=nl:
$ ld show/trace/fdt/accurate lda1
I/O trace for device $7$LDA1:
26-APR-2005 22:36:35.69 on node LDDRVR::
Start Time Elaps uSecs Pid Lbn Bytes Iosb Function
---------------------------------------------------------------------
22:36:29.10 00.00 0 09C00227 0 0 FDT ACCESS
22:36:29.10 00.00 0 09C00227 0 0 FDT ACCESS|ACCESS|EXFUNC
22:36:29.10 00.00 0 09C00227 0 0 FDT READVBLK|EXFUNC
22:36:29.10 00.00 422 00000000 5000 512 NORMAL READPBLK|EXFUNC
22:36:29.10 00.00 0 09C00227 0 0 FDT DEACCESS|EXFUNC
Notice that the driver
is called more times to do the FDT work. The real I/O request had an elapsed
time of 422 microseconds; you can measure the timing with much finer
granularity this way.
Of course, all trace
data can be saved to disk, either as ASCII or as binary data. You need binary
data to process the trace data later. You can specify a block size, which will
force LD to create a new version of the output file once the number of blocks
have been reached. Together with a version limit, this provides continuous
tracing without having to worry about filling up a disk, while still capturing
a predictable amount of data.
The trace data can
also be viewed in real time with LD SHOW/TRACE/CONTINUOUS. This command reads
the trace data from the driver and resets the trace buffer after reading it. As
soon as there is new data available, the driver notifies LD driver so that you
can get it. The viewer can be stopped either by Control-C or by the LD
TRACE/STOP LDA1 command issued from another terminal.
The default size of
the trace buffer is 512 entries, but this can be as big as non-paged pool
allows. The amount of bytes taken for the buffer is charged against the byte
count quota of the process issuing the command.
|