dm_command.c revision d1d2228c6cf3ec632d28262810ab7902932a5d33
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>
#include <stdarg.h>
#include <ctype.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <errno.h>
#include <dlfcn.h>
#include <mms_network.h>
#include <mms_trace.h>
#include <mms_sym.h>
#include <dm_impl.h>
#include <mms_dmd.h>
#include <dm_msg.h>
#include <dm_proto.h>
#include <mms_strapp.h>
#include <mms_cat.h>
/*
* Function name
* dm_bld_task(char *cmd)
*
* Parameters:
* cmd command name pointer
*
* Description:
* create a task id for use with a DMP command
*
* Return code:
* pointer to the task id. Caller must free after its use
*
* Note:
*
*
*/
char *
dm_bld_task(char *cmd)
{
char *task;
return (task);
}
/*
* Function name
* dm_parse_err(mms_par_node_t *root, mms_list_t *err_list)
*
* Parameters:
* root root of parse tree
* err_list list of errors
*
* Description:
* trace parser error
* put the first error in the parse tree in the response
*
* Return code:
* none
*
* Note:
*
*
*/
void
{
} else {
}
"near token \"%s\", err code %d, %s",
}
/*
* Return the first error message
*/
"command %s, "
"line %d, "
"col %d, "
"token %s, "
"code %d, "
"%s",
}
/*
* Function name
* dm_reader(char **cmdbuf)
*
* Parameters:
* cmdbuf pointer to the buffer address
*
* Description:
* read a message from the socket connection to MM
*
* Return code:
* > 0 number of bytes of message
* 0 EOF
* -1 error
*
* Note:
*
*
*/
int
{
int rc;
int err;
if (rc == 0) {
} else if (rc > 0) {
} else {
}
return (rc);
}
/*
* Function name
* dm_writer_accept(char *cmdbuf)
*
* Parameters:
* cmdbuf command buffer
*
* Description:
* send accepted and unacceptable command
*
* Return code:
* 0 success
* -1 Error
* -2 incomplete write, write interrupted
*
* Note:
*
*
*/
int
dm_writer_accept(char *cmdbuf)
{
}
/*
* Function name
* dm_writer(char *cmdbuf)
*
* Parameters:
* cmdbuf command buffer
*
* Description:
* send a command
*
* Return code:
* 0 success
* -1 Error
* -2 incomplete write, write interrupted
*
* Note:
*
*
*/
int
{
}
/*
* Function name
* dm_writer_aux(char *cmdbuf)
*
* Parameters:
* cmdbuf command buffer
*
* Description:
* send a command
* wait until no outstanding accept before sending a command
*
* Return code:
* 0 success
* -1 Error
* -2 incomplete write, write interrupted
*
* Note:
*
*
*/
int
{
int rc;
if (accept == DM_WRITE_ACCEPT) {
/* write accept, just write it */
} else {
/* Wait for all accept is done */
mms_trace_flush(); /* flush mms_trace buffer */
&wka->dm_queue_mutex);
}
/* accept is sent */
}
if (rc > 0) {
/* success */
rc = 0;
} else {
/* partial write */
rc = -2;
}
} else {
/* error */
rc = -1;
}
return (rc);
}
/*
* Function name
* dm_get_task(mms_par_node_t *root)
*
* Parameters:
* root root of parse tree
*
* Description:
* return the task id of a command from the parse tree
*
* Return code:
* task id string
*
* Note:
*
*
*/
char *
{
char *task;
return (NULL); /* no tree to lookup */
}
"No task clause"));
return (NULL);
}
return (NULL);
}
return (task);
}
/*
* Function name
* dm_get_cmd_by_task(char *task)
*
* Parameters:
* task task id
*
* Description:
* return the dm_command_t that has the task id
*
* Return code:
* dm_command_t pointer
* NULL can't find a command with matching task id
*
* Note:
*
*
*/
dm_get_cmd_by_task(char *task)
{
/* found cmd with matching task */
return (cmd);
}
}
/* Not found */
"No command for task %s", task));
return (NULL);
}
/*
* Function name
* dm_read_input(void)
*
* Parameters:
* none
*
* Description:
* read commands from the connection socket.
* If a command from MM is read, put it in a dm_command_t and
* put it in the command list.
* If a response to a command sent to MM is read, then set the
* command dispatchable.
*
* Return code:
* none
*
* Note:
*
*
*/
/*
* dm_read_input
* Read input command from MM and put it on input list
*/
void
dm_read_input(void)
{
int rc;
char *task;
if (rc > 0) {
/*
* Read a command
*/
if (rc < 0) {
return;
}
/*
* MM responded to a command sent by DM
*/
} else {
/* Must be response unacceptable */
}
return;
}
if (rc == DM_COMPLETE) {
/*
* Command completed
*/
} else {
/*
* Command not complete, free the parse tree
*/
}
} else {
/*
* A new command from MM
*/
MMS_DM_E_INTERNAL, "Out of memory"));
return;
}
/* Failed */
return;
} else {
cmd);
}
}
} else if (rc == 0) {
/*
* Hit end of file or connection closed by MM
*/
}
/*
* Close current connection
*/
"Lost connection to MM"));
} else {
/*
* Got an error
*/
}
}
/*
* Function name
* dm_responded_with(dm_command_t *cmd, char *keyword)
*
* Parameters:
* cmd dm_command_t with the command
* keyword keyword of response type
*
* Description:
* Check to see if the response matches the input keyword
*
* Return code:
* 1 type matched
* 0 type not matched
*
* Note:
*
*
*/
int
{
/* Found respond with keyword */
return (1);
} else {
return (0);
}
}
/*
* Function name
* dm_accept_cmds(void)
*
* Parameters:
* none
*
* Description:
* send accepted commands to all commands that have not been accepted
*
* Return code:
* none
*
* Note:
*
*
*/
void
dm_accept_cmds(void)
{
int rc;
if (rc == 0) {
/* Accept sent, move cmd to dispatch list */
/* no error */
/* wakeup worker thread to do work */
}
}
/* all commands accepted. enable writing commands */
}
}
/*
* Function name
* dm_accept_cmd_aux(dm_command_t *cmd)
*
* Parameters:
* cmd dm_command_t pointer
*
* Description:
* construct an accepted command and send it
*
* Return code:
* 0 success
* -1 error
*
* Note:
*
*
*/
int
{
char *accept;
int rc;
int err;
}
if (rc != 0) {
"unable to send accept to task %s: %s",
return (-1);
}
return (0);
}
/*
* Function name
* dm_resp_unacceptable(int msgid, ...)
*
* Parameters:
* msgid message id
* ... argument list, terminated by NULL.
*
* Description:
* send response unacceptable command
*
* Return code:
* none
*
* Note:
*
*
*/
void
dm_resp_unacceptable(int msgid, ...)
{
char *msgcl;
char *unacc;
int rc;
/*
* Build a message clause
*/
} else if (rc == DM_PARTIAL_WRITE) {
}
}
/*
* Function name
* dm_resp_error(int msgid, ...)
*
* Parameters:
* msgid message id
* ... argument list, terminated by NULL.
*
* Description:
* send response error command
*
* Return code:
* none
*
* Note:
*
*
*/
void
{
char *rep;
char *msgcl;
int rc;
/*
* Build a message clause
*/
"error [ '%s' '%s' ] %s ;",
task,
msgcl);
} else if (rc == DM_PARTIAL_WRITE) {
}
}
/*
* Function name
* dm_resp_success(char *task, char *text)
*
* Parameters:
* task task id
* text content of text clause
*
* Description:
* send response success command
*
* Return code:
* none
*
* Note:
*
*
*/
void
{
char *rep;
int rc;
}
} else if (rc == DM_PARTIAL_WRITE) {
}
}
/*
* Function name
* dm_send_message(char *who, char *severity, int msgid, ...)
*
* Parameters:
* who who to send message to
* severity severity of message
* msgid message id
* ... variable list of arguments of the message ending with NULL
*
* Description:
* send a message to the administrator
*
* Return code:
* none
*
* Note:
*
*
*/
void
{
char *msg_cmd;
char *task;
char *msgcl;
if (cmd) {
}
return;
}
dm_msg_destroy(); /* clean up message queue */
}
/*
* Function name
* dm_send_ready(int msgid, ...)
*
* Parameters:
* msgid message id
* ... variable list of arguments ending with NULL
*
* Description:
* send a ready command
*
* Return code:
*
*
* Note:
*
*
*/
int
dm_send_ready(int msgid, ...)
{
int rc;
return (rc);
}
/*
* Function name
* dm_send_ready_broken(int msgid, ...)
*
* Parameters:
* msgid message id
* ... arguments for message ending with NULL
*
* Description:
* send ready broken message
*
* Return code:
* 0 success
* -1 error
*
* Note:
*
*
*/
int
dm_send_ready_broken(int msgid, ...)
{
int rc;
return (rc);
}
/*
* Function name
* dm_send_ready_disconnected(int msgid, ...)
*
* Parameters:
* msgid message id
* ... arguments for message ending with NULL
*
* Description:
* send ready disconnected message
*
* Return code:
* 0 success
* -1 error
*
* Note:
*
*
*/
int
dm_send_ready_disconnected(int msgid, ...)
{
int rc;
return (rc);
}
/*
* Function name
* dm_send_ready_not(int msgid, ...)
*
* Parameters:
* msgid message id
* ... arguments for message ending with NULL
*
* Description:
* send ready not message
*
* Return code:
* 0 success
* -1 error
*
* Note:
*
*
*/
int
dm_send_ready_not(int msgid, ...)
{
int rc;
return (rc);
}
/*
* Function name
* dm_send_ready_aux(char *spec, int msgid, va_list args)
*
* Parameters:
* spec specific ready type
* msgid message id
* args variable length arg list terminated by NULL
*
* Description:
* construct a ready message and send it
*
* Return code:
* 0 success
* -1 error
*
* Note:
*
*
*/
int
{
char *ready_cmd;
char *task;
char *msgcl;
/*
* Build a message clause
*/
spec = "";
}
"send ready command error"));
if (cmd) {
}
return (-1);
}
return (0);
}
/*
* Function name
* dm_update_capacity(void)
*
* Parameters:
* none
*
* Description:
* get capacity of cartridge and update the partition size in
* the PARTITION object.
*
* Return code:
* 0 success
* -1 error
*
* Note:
*
*
*/
int
dm_update_capacity(void)
{
int rc = 0;
/*
* Read capacity from tape
*/
/* update capacity */
"update capacity error"));
rc = -1;
}
} else {
"cannot get cartridge capacity"));
}
}
return (rc);
}
/*
* Function name
* dm_send_capacity(mms_capacity_t *cap)
*
* Parameters:
* cap addr of mms_capacity_t
*
* Description:
* send capacity to MM to update capacity
*
* Return code:
* o success
* -1 error
*
* Note:
*
*
*/
int
{
char *attr_cmd;
char *task;
return (-1);
}
"match[ and (streq(CARTRIDGE.'CartridgePCL' '%s') "
"streq(PARTITION.'PartitionName' '%s') "
"streq(DRIVE.'DriveName' '%s'))]"
"set[PARTITION.'PartitionSize' '%lld'] "
"set[PARTITION.'PartitionAvailable' '%lld'] "
"set[PARTITION.'PartitionPercentAvailable' '%d'] "
"set[CARTRIDGETYPE.'CartridgeTypeMediaLength' '%lld'] "
";",
"update capacity error"));
if (cmd) {
}
return (-1);
}
return (0);
}
/*
* Function name
* dm_send_loaded(void)
*
* Parameters:
* none
*
* Description:
* update DriveStateHard to loaded
*
* Return code:
* 0 success
* -1 error
*
* Note:
*
*
*/
int
dm_send_loaded(void)
{
char *attr_cmd;
char *task;
"match[ streq(DRIVE.'DriveName' '%s') ] "
"set[DRIVE.'DriveStateHard' 'loaded'] "
"send loaded error"));
if (cmd) {
}
return (-1);
}
return (0);
}
/*
* Function name
* dm_get_capacity(mms_par_node_t *root)
*
* Parameters:
* root pointer to the parse tree
*
* Description:
* get capacity from the response of a show command and save it
* in drv->drv_avail.
*
* Return code:
* 0 success
* -1 error
*
* Note:
*
*
*/
int
{
char *val;
/*
* Save tape capacity
*/
"unable to get partition size"));
return (-1);
}
"unable to get partition available"));
return (-1);
}
"unable to get partition % available"));
return (-1);
}
return (0);
}
/*
* Function name
* dm_show_mount_point(mms_par_node_t **typeroot)
*
* Parameters:
* typeroot addr of pointer to root of response parse tree
*
* Description:
* Show mount points of all cartridges that can be mounted on
* the drive controlled by this DM.
*
* Return code:
* 0 success - root of parse tree returned in typeroot.
* -1 error
*
* Note:
*
*
*/
int
{
char *show_cmd;
char *task;
/*
* Show mount points of all cartridges that can be mounted on
* the drive controlled by this DM.
*/
"match[and(streq(DM.'DMName' '%s') "
"streq(CARTRIDGETYPE.'CartridgeShapeName' 'DISK'))] "
"report[CARTRIDGE.'CartridgeMountPoint'] "
"show mount point error"));
if (cmd) {
}
return (-1);
}
return (0);
}
/*
* Function name
* dm_show_virt_cart_path(void)
*
* Parameters:
* none
*
* Description:
* show the path to a DISK cartridge
*
* Return code:
* pointer to path string. Caller must free after use.
* NULL can't get path
*
* Note:
*
*
*/
char *
dm_show_virt_cart_path(void)
{
char *show_cmd;
char *task;
char *mp;
char *fn;
char *path;
int len;
"match[streq(CARTRIDGE.'CartridgePCL' '%s') ] "
"report[CARTRIDGE.'CartridgeMountPoint' CARTRIDGE.'CartridgePath' ]"
"show virt cart type error"));
if (cmd) {
}
return (NULL);
}
}
return (path);
}
int
dm_show_eof_pos(void)
{
char *show_cmd;
char *task;
char *val;
int eof;
int pmode;
"match[ and (streq(CARTRIDGE.'CartridgePCL' '%s') "
"streq(SIDE.'SideName' '%s') "
"streq(PARTITION.'PartitionName' '%s') "
"streq(DRIVE.'DriveName' '%s'))]"
"report[ PARTITION.'PartitionEOFPos' ]"
";",
drv->drv_drvname);
"show eof position error"));
if (cmd) {
}
return (-1);
}
/*
* Save EOF position
*/
"unable to get EOF position"));
if (cmd) {
}
return (-1);
}
/* EOF position is valid */
}
}
return (0);
}
int
dm_send_eof_pos(void)
{
char *attr_cmd;
char *task;
return (-1);
}
"match[ and (streq(CARTRIDGE.'CartridgePCL' '%s') "
"streq(SIDE.'SideName' '%s') "
"streq(PARTITION.'PartitionName' '%s') "
"streq(DRIVE.'DriveName' '%s'))]"
"set[PARTITION.'PartitionEOFPos' '%lld %d %d %d %d %d '] "
";",
} else {
"match[ and (streq(CARTRIDGE.'CartridgePCL' '%s') "
"streq(SIDE.'SideName' '%s') "
"streq(PARTITION.'PartitionName' '%s') "
"streq(DRIVE.'DriveName' '%s'))]"
"unset[PARTITION.'PartitionEOFPos'] "
";",
drv->drv_drvname);
}
"send eof position error"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
dm_send_write_protect(int wp)
{
char *attr_cmd;
char *task;
return (-1);
}
"match[ and (streq(CARTRIDGE.'CartridgePCL' '%s') "
"streq(SIDE.'SideName' '%s') "
"streq(PARTITION.'PartitionName' '%s') "
"streq(DRIVE.'DriveName' '%s'))]"
"set[CARTRIDGE.'CartridgeWriteProtected' '%s'] "
";",
"send write protect error"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
{
char *show_cmd;
char *val;
char *task;
"match[ and( streq(DRIVE.'DriveName' '%s') "
"streq(VOLUME.'VolumeName' '%s')) ] "
"report[ "
"DRIVE.'DriveTimeMountedLast' "
"DRIVE.'DriveShapeName' "
"CARTRIDGETYPE.'CartridgeShapeName' "
"CARTRIDGETYPE.'CartridgeTypeMediaType' "
"CARTRIDGE.'CartridgeNumberMounts' "
"PARTITION.'SideName' "
"PARTITION.'PartitionName' "
"PARTITION.'CartridgeID' "
"PARTITION.'PartitionRWMode' "
"PARTITION.'PartitionSize' "
"PARTITION.'PartitionAvailable' "
"PARTITION.'PartitionPercentAvailable' "
"PARTITION.'PartitionEOFPos' "
"send show dca info error"));
goto error;
}
"unable to get side name"));
goto error;
}
"unable to get partition name"));
goto error;
}
"unable to get cartridge ID"));
goto error;
}
"unable to get DriveTimeMountedLast"));
goto error;
}
"unable to get CartridgeShapeName"));
goto error;
}
"unable to get DriveShapeName"));
goto error;
}
return (0);
}
return (-1);
}
int
{
char *show_cmd;
char *task;
"match[ streq(VOLUME.'VolumeName' '%s') ] "
"report[ "
"APPLICATION "
"send show application error"));
goto error;
}
return (0);
}
return (-1);
}
int
dm_send_error(void)
{
char *create_cmd;
char *ts;
char sense[200];
char cdb[64];
char *task;
return (-1);
}
/*
* Create DRIVECARTRIDGEERROR
*/
ts = dm_timestamp();
"type [ DRIVECARTRIDGEERROR ] "
"set[DRIVECARTRIDGEERROR.'DriveName' '%s' ] "
"set[DRIVECARTRIDGEERROR.'DMName' '%s' ] "
"set[DRIVECARTRIDGEERROR.'CartridgeID' '%s' ] "
"set[DRIVECARTRIDGEERROR.'SideName' '%s' ] "
"set[DRIVECARTRIDGEERROR.'PartitionName' '%s' ] "
"set[DRIVECARTRIDGEERROR.'ApplicationName' '%s' ] "
"set[DRIVECARTRIDGEERROR.'CartridgePCL' '%s' ] "
"set[DRIVECARTRIDGEERROR.'DriveSerialNum' '%s' ] "
"set[DRIVECARTRIDGEERROR.'CartridgeShapeName' '%s' ] "
"set[DRIVECARTRIDGEERROR.'DriveShapeName' '%s' ] "
"set[DRIVECARTRIDGEERROR.'SCSICommand' '%s' ] "
"set[DRIVECARTRIDGEERROR.'TimeStamp' '%s' ] "
"set[DRIVECARTRIDGEERROR.'CDB' '%s' ] "
"set[DRIVECARTRIDGEERROR.'IOStatus' '%s' ] "
"set[DRIVECARTRIDGEERROR.'SenseKey' '%s' ] "
"set[DRIVECARTRIDGEERROR.'AdditionalSenseCode' '%2.2x' ] "
"set[DRIVECARTRIDGEERROR.'AdditionalSenseCodeQualifier' '%2.2x' ] "
"set[DRIVECARTRIDGEERROR.'SenseBytes' '%s' ] "
"set[DRIVECARTRIDGEERROR.'ErrorText' '%s' ] "
";",
ts,
"send drive cartridge error error"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
dm_send_clean_request(void)
{
char *clean_cmd;
char *task;
return (-1);
}
"set[DRIVE.'DriveNeedsCleaning' 'true'] "
";", task);
"send drive needs cleaning error"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
dm_send_statistics(void)
{
char *create_cmd;
char *unmnttime;
char *task;
return (-1);
}
/*
* Create DRIVECARTRIDGEACCESS
*/
unmnttime = dm_timestamp();
"type [ DRIVECARTRIDGEACCESS ] "
"set[DRIVECARTRIDGEACCESS.'DriveName' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'DMName' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'CartridgeID' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'SideName' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'PartitionName' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'ApplicationName' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'CartridgePCL' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'DriveSerialNum' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'CartridgeShapeName' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'DriveShapeName' '%s' ] "
"set[DRIVECARTRIDGEACCESS.'DriveCartridgeAccessTimeMount' '%s' ] "
"set[DRIVECARTRIDGEACCESS."
"'DriveCartridgeAccessTimeUnmount' '%s' ] "
"set[DRIVECARTRIDGEACCESS."
"'DriveCartridgeAccessByteReadCount' '%lld' ] "
"set[DRIVECARTRIDGEACCESS."
"'DriveCartridgeAccessMediumByteReadCount' '%lld' ] "
"set[DRIVECARTRIDGEACCESS."
"'DriveCartridgeAccessByteWriteCount' '%lld' ] "
"set[DRIVECARTRIDGEACCESS."
"'DriveCartridgeAccessMediumByteWriteCount' '%lld' ] "
"set[DRIVECARTRIDGEACCESS."
"'DriveCartridgeAccessHardReadErrorCount' '%d' ] "
"set[DRIVECARTRIDGEACCESS."
"'DriveCartridgeAccessSoftReadErrorCount' '%d' ] "
"set[DRIVECARTRIDGEACCESS."
"'DriveCartridgeAccessHardWriteErrorCount' '%d' ] "
"set[DRIVECARTRIDGEACCESS."
"'DriveCartridgeAccessSoftWriteErrorCount' '%d' ] "
"send drive cartridge access error"));
if (cmd) {
}
return (-1);
}
return (0);
}
void
dm_destroy_dca(void)
{
if (dca->dca_side_name)
if (dca->dca_part_name)
if (dca->dca_app_name)
if (dca->dca_cart_id)
if (dca->dca_mounted_last)
if (dca->dca_cart_shape_name)
if (dca->dca_drv_shape_name)
}
char *
dm_timestamp(void)
{
char *buf;
return (buf);
}
void
dm_mms_to_db_time(char *db)
{
}
int
dm_send_drive_broken(void)
{
char *attr_cmd;
char *task;
return (-1);
}
"match[ streq(DRIVE.'DriveName' '%s') ] "
"set[DRIVE.'DriveBroken' '%s'] "
"send drive broken error"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
{
char *attr_cmd;
char *task;
return (-1);
}
"match[ and (streq(CARTRIDGE.'CartridgePCL' '%s') "
"streq(SIDE.'SideName' '%s') "
"streq(PARTITION.'PartitionName' '%s') "
"streq(DRIVE.'DriveName' '%s'))]"
"set[CARTRIDGE.'CartridgeMediaError' '%s'] "
";",
"yes");
"send cartridge media error error"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
dm_show_drive_dmname(char **dmname)
{
char *show_cmd;
char *task;
char *val;
"match[ streq(DRIVE.'DriveName' '%s') ] "
"send show command error"));
if (cmd) {
}
return (-1);
}
/*
* Save drive dmname
*/
"unable to get drive DMName"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
{
char *show_cmd;
char *task;
"report[SYSTEM] ;", task);
"unable to send show SYSTEM command"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
{
char *show_cmd;
char *task;
"match[ streq(DRIVE.'DriveName' '%s') ] "
"report[DRIVE] ;",
"send show drive error"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
{
case 0:
/*
* check for accept
*/
mms_pn_token(root)));
return (DM_CONTINUE);
NULL);
MMS_PN_STRING, &work);
MMS_PN_STRING, &work);
MMS_PN_STRING, &work);
}
"manufacturer '%s', model '%s', msgid '%s'",
NULL);
MMS_PN_STRING, &work);
MMS_PN_STRING, &work);
MMS_PN_STRING, &work);
}
"manufacturer '%s', model '%s', msgid '%s'",
mms_pn_token(msgid)));
}
return (DM_COMPLETE);
case 1:
/*
* check for success
*/
return (DM_COMPLETE);
"command cancelled"));
return (DM_COMPLETE);
"command had error"));
return (DM_COMPLETE);
} else {
"Unexpected response from MM"));
}
default:
/*
* Should not happen
*/
}
return (DM_COMPLETE);
}
void
dm_dispatch_cmds(void)
{
while (wka->dm_cmd_dispatchable) {
wka->dm_cmd_dispatchable = 0;
/* Dispatch commands */
/*
* dispatch the command
*/
dm_msg_destroy(); /* clean up messages */
cmd);
}
if (rc == DM_COMPLETE) {
/* Incoming command completes */
dm_cmd_queue, cmd);
}
}
dm_msg_destroy(); /* clean up messages */
}
}
}
}
void
{
}
}
if (cmd->cmd_textcmd) {
}
}
{
/* Build dm_command_t */
"send command error: out of memory"));
return (NULL);
}
/* Put command in cmd_queue */
/* send cmd */
cmd));
"unable to send command to MM: socket write error"));
return (NULL);
}
/*
* Wait for command to complete
*/
}
return (cmd);
}
int
{
} else {
/* Unknown command */
return (-1);
}
return (0);
}
int
dm_send_config(void)
{
char *cfg_cmd;
char *task;
return (-1);
}
"send config command error"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
{
int rc;
/* Enable DM */
/* Disable DM */
/* Reserve Drive */
/* Release Drive */
}
return (rc);
}
/*
* Activate DM
* - send contact drive and send config
*/
int
{
/* Already enabled */
"already enabled"));
goto error;
}
/*
* default size of sense data
*/
/*
* Close all the device dynamic libraries
*/
if (wka->dm_default_lib_hdl) {
}
if (wka->dm_dev_lib_hdl) {
}
/*
* Load default device library
*/
if (dm_load_default_lib() != 0) {
goto error1;
}
/*
* Get system options
*/
if (dm_get_system_options() != 0) {
goto error1;
}
/*
* Get DM target path
*/
if (dm_get_target_base() != 0 ||
goto error1;
}
/*
* configure device
*/
if (dm_stat_targ_base() != 0) {
goto error1;
}
/*
* Connect to target drive
*/
if (dm_bind_target() != 0) {
goto error1;
}
/*
* Load the device dependent library
*/
if (dm_load_devlib() != 0) {
goto error1;
}
if (DRV_CALL(drv_rebind_target, ()) != 0) {
goto error1;
}
DRV_CALL(drv_init_dev, ());
/*
* Get sense data size
*/
if (dm_update_drivetype() != 0) {
goto error1;
}
/*
* Make prsv key and set it in dmd.
*/
DRV_CALL(drv_mk_prsv_key, ());
/*
* Set up disallowed USCSI commands and ioctl
*/
DRV_CALL(drv_disallowed, ());
/*
* Tell driver we are ready
*/
/*
* Send config to MM
*/
if (dm_send_config() != 0) {
goto error1;
}
/*
* Initialize the device
*/
DRV_CALL(drv_init_dev, ());
return (DM_COMPLETE);
return (DM_COMPLETE);
}
/*
* Activate DM
* - reserve the drive
*/
int
{
/*
* Start timing mount time
*/
/*
* Get system options. Use what we know if error.
*/
if (dm_get_system_options() != 0) {
goto error;
}
/*
* Check if reserve drive
*/
/* Don't reserve drive */
goto success;
}
/*
* Reserve target
*/
if (dm_reserve_target() != 0) {
goto error;
}
return (DM_COMPLETE);
return (DM_COMPLETE);
}
int
{
/* Didn't reserve drive */
return (DM_COMPLETE);
}
/*
* Release is always successful.
* If there is any problem, let
* activate reserve take care of it.
*/
/* Do persistent release */
if (DRV_CALL(drv_prsv_register, ()) ||
DRV_CALL(drv_prsv_release, ())) {
goto error;
}
/* Do SCSI release */
} else if (DRV_CALL(drv_release, ()) != 0) {
goto error;
}
}
return (DM_COMPLETE);
return (DM_COMPLETE);
}
int
{
/* success */
return (DM_COMPLETE);
}
int
{
int len;
if (dm_get_mount_options(cmd) != 0) {
/* had error */
return (DM_COMPLETE);
}
/*
* If a private cmd for mounting, check to see if authorized to
* use tape
*/
"User %s is not authorized to use MMS",
return (DM_COMPLETE);
}
}
/*
* Set up default options
*/
}
}
/* Filename defaults to volumename */
"out of memory"));
return (DM_COMPLETE);
}
if (len > 17) {
} else {
}
}
/* In MMS mode */
/* set default if no TM processing option */
}
} else {
/*
* Raw mode
*/
/* set default if no TM processing option */
}
}
return (DM_COMPLETE);
}
int
{
char *np;
char *vp;
char *errtok;
int len;
/*
* Check if mount options
*/
MMS_PN_CLAUSE, &work);
MMS_PN_CLAUSE, &work)) {
/* look for set cap. If found then this is mount option */
/* Mount options, clean out mnttab */
}
}
MMS_PN_CLAUSE, &work);
MMS_PN_CLAUSE, &work)) {
}
if (len > 17) {
/* Get last 17 chars from name */
} else {
}
/* VID must be in uppercase */
/* Have an invalid capability */
return (-1);
}
(void) mms_trace_filter(sev);
(void) mms_trace_set_fsize(vp);
}
}
/* Ignore unknown attributes */
}
}
return (0);
}
int
{
char *handle;
time_t t;
int err;
int i;
char tbuf[] = "YYYYMMDDhhmmss";
int try = 0;
char *val;
/* Drive already attached */
"already attached"));
/*
* Something is very wrong here because MM has not done
* a detach. Restart and cleanup.
*/
}
/*
* Create a handle for application
*/
time(&t);
/* Replace blanks in handle with '-' */
for (i = 0; handle[i] != '\0'; i++) {
if (handle[i] == ' ') {
handle[i] = '-';
}
}
/*
* Get a minor dev number for handle which must be > 255.
*/
"make handle error: %s: %s",
return (DM_COMPLETE);
}
/*
* Tell dmd driver about the current minor dev number
*/
/* Change owner of handle to user */
setpwent(); /* to beginning of PW file */
endpwent();
/*
* Can't find user
*/
"no user"));
return (DM_COMPLETE);
}
/* chown error */
"cannot chown handle to user"));
return (DM_COMPLETE);
}
}
drv->drv_rdbytes = 0;
drv->drv_wrbytes = 0;
/*
* Get info from databse
*/
if (dm_show_application(&approot) != 0) {
"unable to get APPLICATION"));
NULL);
return (DM_COMPLETE);
}
if (dm_show_dca_info(&root) != 0) {
sleep(1);
try++;
continue;
}
}
"unable to get application name"));
NULL);
return (DM_COMPLETE);
}
"unable to get info for DRIVECARTRIDGEACCESS"));
NULL);
return (DM_COMPLETE);
}
/*
* Get application options
*/
if (dm_get_app_options(approot) != 0 ||
"unable to get info for application/partition"));
NULL);
return (DM_COMPLETE);
}
/*
* Override options with mount command options
*/
}
}
}
}
}
}
/*
*/
/*
* get tape capacity from DB
*/
if (dm_get_capacity(root) != 0) {
"unable to get info for application/partition"));
NULL);
return (DM_COMPLETE);
}
/*
* Update capacity
*/
/* Uninitialized capacity */
if (dm_update_capacity() != 0) {
"unable to update capacity"));
NULL);
return (DM_COMPLETE);
}
}
/* Success */
return (DM_COMPLETE);
}
int
{
"unable to get attrlist"));
return (-1);
}
} else {
}
"ValidateVolumeID") == 0) {
} else {
}
"ValidateExpirationDate") == 0) {
} else {
}
}
"WriteOverExistingData") == 0) {
}
&drv->drv_retention);
}
}
return (0);
}
int
{
char *val;
"unable to get partition RW mode, assume readonly"));
return (-1);
}
}
return (0);
}
int
dm_update_write_protect(void)
{
int wp;
/*
* Read mode sense data
*/
/* Error getting WP flag */
"unable to get WP flag"));
return (-1);
}
if (dm_send_write_protect(wp) != 0) {
"update write protect error"));
return (-1);
}
if (wp == 1) {
/* Cartridge is write protected */
}
return (0);
}
int
dm_update_drivetype(void)
{
char *attr_cmd;
char *task;
return (-1);
}
"match[ streq(DRIVE.'DriveName' '%s') ] "
"set[DRIVE.'DriveVendorID' '%s'] "
"set[DRIVE.'DriveProductID' '%s'] "
"set[DRIVE.'DriveTypeName' '%s'] "
"set[DM.'DMTargetPath' '%s'] "
"update drivetype error"));
if (cmd) {
}
return (-1);
}
return (0);
}
int
{
/*
* If the tape is already loaded, check to see if access mode
* asks for a load command to be issued.
*/
/* Don't issue load command */
return (DM_COMPLETE);
}
}
/*
* Save DRV_ATTACH flag and reserved flag
*/
/* issue a load command */
"load failed, drive not ready"));
return (DM_COMPLETE);
}
/*
* Get rid of any pending attention
*/
;
}
return (DM_COMPLETE);
}
int
{
int rc;
char *resp;
return (DM_COMPLETE);
}
/* No MMS control */
goto done;
}
/*
* If tape has already been identified, then return VSN.
* else rewind the tape and read VOL1.
*/
goto done;
}
/* No VSN, must determine VSN */
if (DRV_CALL(drv_rewind, ()) != 0) {
/* I/O error */
return (DM_COMPLETE);
}
if (dm_set_label_blksize() != 0) {
/* I/O error */
return (DM_COMPLETE);
}
if (rc != 80) {
/* Did not read a label */
} else {
}
/*
* Read something ot hit a tapemark. Not a blank tape anymore.
*/
}
/* Hit EOM, must be a blank tape */
}
if (DRV_CALL(drv_rewind, ()) != 0) {
/* I/O error */
"rewind error"));
return (DM_COMPLETE);
}
if (dm_get_bof_pos() != 0) {
"unable to get BOF position"));
return (DM_COMPLETE);
}
resp = "No Signature";
} else {
/* Created by SUN mms */
}
/* Return VSN */
/*
* Verify the mounted cartridge has the requested VSN
*/
/* Wrong cartridge mounted */
"incorrect volume id: "
"requested %s, mounted %s",
DM_6510_MSG, NULL);
return (DM_COMPLETE);
}
}
}
}
done:
/*
* Calculate mount time
*/
}
return (DM_COMPLETE);
}
int
{
handle =
NULL);
stale =
"no handle"));
return (DM_COMPLETE);
/* unknown handle name */
"unknown handle"));
return (DM_COMPLETE);
} else if (wka->dm_app_pid != 0) {
return (DM_COMPLETE);
return (DM_COMPLETE);
}
/*
* Not a stale handle. Must be a detach from normal
* unmount processing.
* Remove the handle.
*/
}
/*
* Clean up mnt table
*/
} else {
/*
* A stale handle
*/
"stale handle"));
}
return (DM_COMPLETE);
}
int
{
int release = 0;
/* library not loaded */
"dm_unload_cmd: device libraries not loaded"));
return (DM_COMPLETE);
}
/*
* Update capacity
*/
} else {
}
}
/*
* Update EOF pos
*/
if (dm_send_eof_pos()) {
} else {
}
}
/*
* If not reserved, then reserve it to prevent st from reserving it
*/
if (DRV_CALL(drv_prsv_register, ()) == 0 &&
DRV_CALL(drv_prsv_reserve, ()) == 0) {
release = 1;
}
}
/*
* Get drive statistics before unloading
*/
if (DRV_CALL(drv_get_statistics, ()) == 0) {
(void) dm_send_statistics();
}
}
/*
* Ignore any unload error so MM can unload the tape
*/
DRV_CALL(drv_unload, ());
if (release == 1) {
DRV_CALL(drv_prsv_register, ());
DRV_CALL(drv_prsv_release, ());
}
/*
* Save DRV_ATTACH flag
*/
return (DM_COMPLETE);
}
void
{
}
void
{
}
void
dm_destroy_mnt(void)
{
if (mnt->mnt_volumename) {
}
}
}
}
}
if (mnt->mnt_dencode) {
}
}
}
char *
dm_bld_config_cmd(char *task)
{
int kwlen;
int i;
char *fmt = DRV_CONFIG;
char **cp;
"cannot get mount point"));
return (NULL);
}
/*
* Now, substitute values
*/
kwlen = 0;
}
}
}
}
"'bit_%s' ",
}
"'bit_%s' ",
}
}
"'bit_%s'",
}
}
"'bit_%s'",
}
}
if (dm_duplicate_bit(sd)) {
continue;
}
"bitformat "
"['bitformat_%s' 'bit_%s'] ",
}
"'%s' ", *cp);
}
"'%s' ", "*none");
}
"'%s' ", *cp);
}
continue;
}
}
continue;
}
}
if (dm_cap_clause(&conf) != 0) {
goto err;
}
} else {
kwlen = 1;
}
}
return (conf);
err:
return (NULL);
}
int
dm_cap_clause(char **pconf)
{
char *readwrite = DRV_CAP_READWRITE;
char *writeover = DRV_CAP_WRITEOVER;
/* Readwrite density */
return (-1);
}
/* Writeover density */
return (-1);
}
}
}
return (0);
}
int
{
int i;
int kwlen;
char *buf;
} else if (fmt[i] == '$') {
"Unknown keyword %s", buf));
goto err;
} else {
kwlen = 1;
}
}
return (0);
err:
return (-1);
}
int
dm_rw_shape(char *shape)
{
return (1);
}
}
}
return (0);
}
int
{
return (1);
}
}
return (0);
}
int
{
int rw;
if (rw) {
/* Readwrite shape */
== 0) {
return (1);
}
}
} else {
/* Readonly shape */
== 0) {
return (1);
}
}
}
}
return (0);
}
/*
* drv_get_capabilities - get capabilities values from string
* If no error, return NULL, otherwise, return the token in error.
*/
char *
dm_get_capabilities(char *tokens)
{
char *cp;
cp[0] = '\0';
/*
* Look for drive type name
*/
/* Matching drive type name */
continue;
}
/*
*/
break;
}
}
/* Found a matching R/W density */
continue;
}
}
/*
* Look for bitformat
*/
/* skip "bit_" to get density */
/* Found matching bitformat */
continue;
}
/*
* Look for matching shape
*/
/* found a matching shape */
break;
}
}
/* Unknown token, error */
"unsupported capability: %s", tok));
return (tok);
}
}
}
return (NULL);
}
int
dm_verify_serial_num(void)
{
return (-1);
}
"mismatched drive serial number, "
"from library %s, from drive %s",
return (-1);
}
return (0);
}
int
dm_drv_assigned(void)
{
char *dmname;
if (dm_show_drive_dmname(&dmname) != 0) {
"Can't read DRIVE.'DMName'"));
return (-1);
}
/* drive not assigned */
return (-1);
}
/* Drive assigned */
return (0);
}
int
dm_get_system_options(void)
{
char *val;
if (dm_show_system(&root) != 0) {
"cannot get SYSTEM attributes"));
return (-1);
}
/*
* Save system options
*/
return (-1);
}
}
return (-1);
}
/*
* Get attributes from drive
*/
if (dm_show_drive(&root) != 0) {
"cannot get DRIVE attributes"));
return (-1);
}
/*
* Save drive options
*/
return (-1);
}
} else {
}
return (-1);
}
return (0);
}
void
{
char *req_cmd;
char *task;
char *msgcl;
"unable to send request"));
if (cmd) {
}
return;
}
/*
* Get reply
*/
/* Skip down to the replied value */
}
char *
{
return (NULL);
}
return (NULL);
}
return (mms_pn_token(val));
}
int
dm_update_bitformat(void)
{
int den;
char *cmdbuf;
char *task;
/*
* Get current density
*/
return (-1);
}
/*
* If current density matches density of requested bitformat density,
* then no need to update.
*/
return (0);
}
}
/*
* Lookup density name
*/
mms_sym++) {
break;
}
}
"Unsupported density 0x%x", den));
return (-1);
}
/*
* Update bitformat
*/
"match[ and (streq(CARTRIDGE.'CartridgePCL' '%s') "
"streq(SIDE.'SideName' '%s') "
"streq(PARTITION.'PartitionName' '%s') "
"streq(DRIVE.'DriveName' '%s'))]"
"set [ PARTITION.'PartitionBitFormat' 'bitformat_%s' ] ;",
if (cmd) {
}
return (-1);
}
return (0);
}
{
/* mms_sym in arr */
return (mms_sym);
}
}
/*
* Symbol not in array
*/
return (NULL);
}