Atape persistent reserve IOCTLs
The Atape device driver provides Persistent Reserve IOCTLs for application programs to manage their own Persistent Reserve support. These IOCTLs are defined in the header file /usr/include/sys/Atape_pr.h.
- STIOC_READ_RESERVEKEYS
- STIOC_READ_RESERVATIONS
- STIOC_READ_RESERVE_FULL_STATUS
- STIOC_REGISTER_KEY
- STIOC_REMOVE_REGISTRATION
- STIOC_CLEAR_ALL_REGISTRATIONS
- STIOC_PREEMPT_RESERVATION
- STIOC_PREEMPT_ABORT
- STIOC_CREATE_PERSISTENT_RESERVE
- SIOC_RESERVE
- SIOC_RELEASE
The STIOC_READ_RESERVEKEYS IOCTL returns the reservation keys from the device. The argument for this IOCTL is the address of a read_keys structure. If the reserve_key_list pointer is NULL, then only the generation and length fields are returned. This action allows an application to first obtain the length of the reserve_key_list and malloc a return buffer before the IOCTL is issued with a reserve_key_list pointer to that buffer. If the return length is 0, then no reservation keys are registered with the device.
struct read_keys
{
uint generation; /* counter for PERSISTENT RESERVE OUT requests */
uint length; /* number of bytes in the Reservation Key list */
ullong *reserve_key_list; /* list of reservation keys */
};
The STIOC_READ_RESERVATIONS IOCTL returns the current reservations from the device if any exist. The argument for this IOCTL is the address of a read_reserves structure. If the reserve_list pointer is NULL, then only the generation and length fields are returned. This action allows an application to first obtain the length of the reserve_list and malloc a return buffer before the IOCTL is issued with a reserve_list pointer to that buffer. If the return length is 0, then no reservations currently exist on the device.
struct reserve_descriptor
{
ullong key; /* reservation key */
uint scope_spec_addr; /* scope-specific address */
uchar reserved;
uint scope:4, /* persistent reservation scope */
type:4; /* reservation type */
ushort ext_length; /* extent length */
};
struct read_reserves
{
uint generation; /* counter for PERSISTENT RESERVE OUT requests */
uint length; /* number of bytes in the Reservation list */
struct reserve_descriptor* reserve_list; /* list of reservation key descriptors */
};
The STIOC_READ_RESERVE_FULL_STATUS IOCTL returns extended information for all reservation keys and reservations from the device if any exist. The argument for this IOCTL is the address of a read_full_status structure. If the status_list pointer is NULL, then only the generation and length fields are returned. This action allows an application to first obtain the length of the status_list and malloc a return buffer before the IOCTL is issued with a status_list pointer to that buffer. If the return length is 0, then no reservation keys or reservations currently exist on the device.
struct transport_id
{
uint format_code:2,
rsvd:2,
protocol_id:4;
};
struct fcp_transport_id
{
uint format_code:2,
rsvd:2,
protocol_id:4;
char reserved1[7];
ullong n_port_name;
char reserved2[8];
};
struct scsi_transport_id
{
uint format_code:2,
rsvd:2,
protocol_id:4;
char reserved1[1];
ushort scsi_address;
ushort obsolete;
ushort target_port_id;
char reserved2[16];
};
struct sas_transport_id
{
uint format_code:2,
rsvd:2,
protocol_id:4;
char reserved1[3];
ullong sas_address;
char reserved2[12];
};
struct status_descriptor
{
ullong key; /* reservation key */
char reserved1[4];
uint rsvd:5,
spc2_r:1, /* future use for SCSI-2 reserve */
all_tg_pt:1, /* all target ports */
r_holder:1; /* reservation holder */
uint scope:4, /* persistent reservation scope */
type:4; /* reservation type */
char reserved2[4];
ushort target_port_id; /* relative target port id */
uint descriptor_length; /* additional descriptor length */
union {
struct transport_id transport_id; /* transport ID */
struct fcp_transport_id fcp_id; /* FCP transport ID */
struct sas_transport_id sas_id; /* SAS transport ID */
struct scsi_transport_id scsi_id; /* SCSI transport ID */
};
};
struct read_full_status
{
uint generation; /* counter for PERSISTENT RESERVE OUT requests */
uint length; /* number of bytes for total status descriptors */
struct status_descriptor *status_list; /* list of reserve status descriptors */
};
The STIOC_REGISTER_KEY IOCTL registers a host reservation key on the device. The argument for this IOCTL is the address of an unsigned long key that can be 1 - 16 hexadecimal digits. If the key value is 0, then the device driver registers the configuration reserve key on the device. This key is either a user-specified host key or the device driver default host key.
If the host has a current persistent reservation on the device and the key is different from the current reservation key, the reservation is retained and the host reservation key is changed to the new key.
The STIOC_REMOVE_REGISTRATION IOCTL removes the host reservation key and reservation if one exists from the device. There is no argument for this IOCTL. The SIOC_RELEASE IOCTL can also be used to complete the same function.
The STIOC_CLEAR_ALL_REGISTRATIONS IOCTL clears all reservation keys and reservations on the device (if any exist) for the same host and any other host. There is no argument for this IOCTL.
The STIOC_PREEMPT_RESERVATION IOCTL registers a host reservation key on the device and then preempts the reservation that is held by another host if one exists. Or, it creates a new persistent reservation by using the host reservation key. The argument for this IOCTL is the address of an unsigned long key that can be 1 - 16 hexadecimal digits. If the key value is 0, then the device driver registers the configuration reserve key on the device. This key is either a user-specified host key or the device driver default host key.
The STIOC_PREEMPT_ABORT IOCTL registers a host reservation key on the device, preempts the reservation that is held by another host, and clears the task that is set for the preempted initiator if one exists. Or, it creates a new persistent reservation by using the host reservation key. The argument for this IOCTL is the address of an unsigned long key that can be 1 - 16 hexadecimal digits. If the key value is 0, then the device driver registers the configuration reserve key on the device. This key is either a user-specified host key or the device driver default host key.
The STIOC_CREATE_PERSISTENT_RESERVE IOCTL creates a persistent reservation on the device by using the host reservation key that was registered with the STIOC_REGISTER_KEY IOCTL. There is no argument for this IOCTL. The SIOC_RESERVE IOCTL can also be used to complete the same function.
The SIOC_RESERVE IOCTL reserves the device. If the reserve_type is set to reserve_6, the device driver issues a SCSI Reserve 6 command. If the reserve_type is set to persistent, the device driver first registers the current host reservation key and then creates a persistent reservation. The current host reservation key can be either the configuration key for the device or a key that was registered previously with the STIOC_REGISTER_KEY IOCTL.
The SIOC_RELEASE IOCTL releases the device. If the reserve_type is set to reserve_6, the device driver issues a SCSI Release 6 command. If the reserve_type is set to persistent, the device driver removes the host reservation key and reservation if one exists from the device.
- ENOMEM Device driver cannot obtain memory to complete the command.
- EFAULT An error occurred while the caller's data buffer was manipulated
- EACCES The current open is using a reserve_type set to reserve_6
- EINVAL Device does not support either the SCSI Persistent Reserve In/Out command, the service action for the command, or the sequence of the command such as issuing the STIOC_REMOVE_REGISTRATION IOCTL when no reservation key was registered for the host.
- EBUSY Device failed the command with reservation conflict. Either a SCSI-2 Reserve 6 reservation is active, the sequence of the command such as issuing the STIOC_CREATE_PERSISTENT_RESERVE IOCTL when no reservation key was registered for the host, or the reservation for the device was preempted by another host and the device driver does not issue further commands.
- EIO Unknown I/O failure occurred on the command.