mm_mmp_mount.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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <syslog.h>
#include <mms_list.h>
#include <mms_parser.h>
#include <mms_par_impl.h>
#include <libpq-fe.h>
#include <mms_trace.h>
#include <mms_strapp.h>
#include "mm_db.h"
#include "mm.h"
#include "mm_util.h"
#include "mm_commands.h"
#include "mm_sql.h"
#include "mm_sql_impl.h"
#include "mm_task.h"
#include "mm_path.h"
#define SELECT_GETALL "select \"DriveName\" from " \
"getall('%s', '%s', '%s');"
#define SELECT_LIB "select \"LibraryName\" from " \
"gettypename('%s', '%s');"
/* Unmount command states */
#define UM_CANDIDATE_SELECTION 0
#define UM_DM_DETACH 1
#define UM_SCHEDULE_UNLOAD 2
#define UM_DM_UNLOAD 3
#define UM_DM_RELEASE 4
#define UM_LM_UNMOUNT 5
#define UM_FINAL 100
void
mm_print_unmount_state(int state) {
switch (state) {
case UM_CANDIDATE_SELECTION:
"unmount candidate selection");
return;
case UM_DM_DETACH:
"add dm detach command");
return;
case UM_SCHEDULE_UNLOAD:
"schedule dm unload command");
return;
case UM_DM_UNLOAD:
"add dm unload command");
return;
case UM_DM_RELEASE:
"add dm release command");
return;
case UM_LM_UNMOUNT:
"add lm unmount command");
return;
case UM_FINAL:
"umount final commmand state");
return;
}
}
void
if (cart->cmi_cart_not_ready) {
cart->cmi_cart_id);
} else {
cart->cmi_cart_id);
}
cart->cmi_cart_pcl);
}
cart->cmi_library);
" Drive Candidates:");
if (drive->cmi_mode_valid == 0) {
" * no DM configured *",
} else {
if (drive->cmi_drive_not_ready) {
" %s, (not ready)",
} else {
}
}
}
}
}
void
int i;
for (i = 0; i < mount_info->cmi_num_firstmount; i ++) {
mount_info->cmi_firstmount[i]);
}
for (i = 0;
i < mode->cmi_num_accessmode;
i ++) {
mode->cmi_accessmode[i]);
}
}
}
void
/* Print mount information */
} else {
}
conn->cci_client);
conn->cci_instance);
"Standard Privilege");
} else {
"Privileged Client");
}
switch (mount_info->cmi_type) {
case MM_SIDE:
break;
case MM_PARTITION:
break;
case MM_VOLUME:
break;
}
switch (mount_info->cmi_when) {
case MM_BLOCKING:
break;
case MM_IMMEDIATE:
break;
}
if (mount_info->cmi_where)
/* Print access modes */
}
int
{
/* Need to set cmd error buf for every return (0) */
char *cap_tokens = NULL;
int a_mode = 0;
/* Check if a DM is configured for this drive */
return (0);
}
/* DM is not configured for this drive */
"EDRVNODMCONFIGURED",
"dm",
"drive",
NULL);
return (0);
}
/* Check the cartridge shape */
"select distinct * from drive_cart('%s', '%s');",
return (0);
}
/* Drive does not support this cartridge shape */
"ECARTDRVNOTCOMPATIBLE",
"drive",
"cart",
NULL);
return (0);
}
/* For each Access Mode, check if the drive supports it */
"checking a mode");
a_mode = 1;
if (cap_tokens != NULL) {
/* There is at least one supported mode */
/* mode is ok */
return (1);
}
}
if (a_mode) {
/* there was at least 1 mode passed, */
/* and none were not good, return error */
if (cap_tokens != NULL) {
}
"ECARTDRVNOTCOMPATIBLE",
"dm",
"drive",
NULL);
return (0);
}
/* No modes exist, access is default */
if (cap_tokens != NULL) {
}
return (1);
return (MM_CMD_ERROR);
}
#ifdef MM_LIBRARY_DRIVE_HAS_PCL
static int
char *cart_pcl)
{
int loaded;
"where \"LibraryName\" = '%s' "
"and \"DriveName\" = '%s' "
"and \"CartridgePCL\" = '%s' "
"and \"DriveLibraryAccessible\" = 'true' "
"and \"DriveLibraryOccupied\" = 'true' "
"and \"DriveBroken\" = 'false' "
"and \"DriveDisabled\" = 'false';",
return (0);
}
return (loaded);
}
#endif
int
char *candidate_cartid,
/* Determines if the candidate drive */
/* is available as a candidate */
int rc;
"Error getting drive information, "
"drive %s",
"failed to get drive information");
}
/* For mounts we know drive and host, for umounts we know dm */
/* Use the approperate call to getdmstatus */
"Error getting dm information, "
"drive %s",
"failed to get dm information");
}
} else {
"cmi_dm_name/candidate_dm == %s",
"Error getting dm information, "
"drive %s",
"failed to get dm information");
}
}
/* The order of check is the order errors get returned */
/* check higher level problems before lower level */
/* ie. online, diabled first */
/* Exclusive access check */
drive_stat->drive_stat_excl_app) != 0) {
"%s exclusive app is not clients app,"
" ExclusiveAppName != %s or none",
conn->cci_client);
"EAPPDRVNOACC",
"drive", candidate_drive,
NULL);
}
}
/* DRIVEGROUPAPPLICATION check */
"Non-privileged client, "
"checking Drive Access");
/* standard priv, check drive group access */
"select \"DRIVEGROUPAPPLICATION\".\"ApplicationName\" "
"from \"DRIVEGROUPAPPLICATION\" "
"where \"DriveGroupName\" = '%s' and "
"\"ApplicationName\" = '%s';",
"Error getting drive group information, "
"drive %s, db trans failed",
}
"%s does not have "
"access to drive group %s",
"EAPPDRVNOACC",
"drive", candidate_drive,
NULL);
}
} else {
"Privileged Client, "
"skip Drive Access check");
}
/* Online check */
"%s is not online",
"EDRIVEOFFLINE",
"drive", candidate_drive,
NULL);
}
/* Drive In use */
"%s is not ready,"
" DriveStateSoft != ready ",
"EDRVINUSE",
"drive", candidate_drive,
NULL);
} else {
"drive in use, keep as"
" candidate for blocking mounts");
}
/* Keep this drive as a candidate for blocking mounts */
}
/* Find this drive's delayed unload and set to dispatch */
"drive is loaded with %s, need to unload",
/* This drive is in the process of unloading */
"This drive is in the process of "
/* make a real error message for this */
"EDRVUNLOADING",
"drive", candidate_drive,
NULL);
}
} else {
if (strcmp(MM_NON_MMS_CART,
drive_stat->drive_stat_pcl) == 0) {
"drive is loaded with a non-mms tape");
"EDRVINUSE",
"drive", candidate_drive,
NULL);
}
}
}
}
"but has MOUNTPHYSICAL",
"drive with MOUNTPHYSICAL not "
}
}
/* Drive disabled */
"%s is disabled",
"temporary") == 0) {
"EDRVDISABLEDTEMP",
"drive", candidate_drive,
NULL);
} else {
"EDRVDISABLEDPERM",
"drive", candidate_drive,
NULL);
}
}
/* Drive Broken */
"%s is broken",
"EDRVBROKEN",
"drive", candidate_drive,
NULL);
}
/* Drive is library accessible */
"%s is not accessible",
"ELMDRVNOTACCESS",
"drive", candidate_drive,
NULL);
}
/* DM Status Checks */
"DM for %s is not ready,"
" DMStateSoft != ready ",
"absent") == 0) {
"EDMNOTCONNECTED",
"dm",
"drive",
NULL);
"disconnected") == 0) {
"EDRVBROKEN",
"dm",
"drive",
NULL);
"not ready") == 0) {
/* drive is not ready for blocked */
"EDMSTILLBOOTING",
"dm",
"drive",
NULL);
}
"present") == 0) {
/* drive is not ready for blocked */
"EDRVNODMCONFIGURED",
"dm",
"drive",
NULL);
}
"reserved") == 0)) {
/* drive is not ready for blocked */
"EDRVINUSE",
"dm",
NULL);
}
}
/* Unmount, and DM is ready */
"%s is in incorrect state for unmount",
"DM is in incorrect state for unmount");
}
"DM for %s is not ready,"
" DMStateHard != ready ",
"EDRVBROKEN",
"drive",
"dm",
NULL);
}
}
"DM Status ok, check DM accessmodes DM, %s",
db) == 1) {
/* DM supports the access modes */
"DM configured for at least 1 access mode");
} else {
"DM not configured to support the access mode");
/* Error buf should be set by check drive */
}
end:
return (rc);
}
int
int rc;
"select "
"\"CARTRIDGE\".\"CartridgeState\", "
"\"CARTRIDGE\".\"CartridgeStatus\", "
"\"CARTRIDGE\".\"CartridgeGroupName\", "
"\"CARTRIDGE\".\"CartridgeDriveOccupied\" "
"from \"CARTRIDGE\" "
"where \"CartridgeID\" = '%s';",
candidate_cartid) != MM_DB_DATA) {
"Error getting cartridge information, "
"cartridge, %s, db trans failed",
}
"Error getting cartridge information, "
"cartridge, %s, db results != 1",
"row number mismatch getting "
"cartridge information");
}
"Cartridge Status for Cartridge, %s",
" CartridgeState = %s",
PQgetvalue(cart, 0, 0));
" CartridgeStatus = %s",
" CartridgeGroup = %s",
" CartridgeDriveOccupied = %s",
/* Ignore this attribute for now */
/*
* if (strcmp(PQgetvalue(cart, 0, 0), "defined") != 0) {
*
* }
*/
"%s is in use,"
" CartridgeStatus != available ",
"unavailable") == 0) {
"ECARTNOTLOCATED",
"cart",
NULL);
}
/* mark this cartridge not ready */
/* for blocked mounts */
/* State is 'in use' */
"ECARTINUSE",
"cart",
NULL);
}
}
"%s is not in use,"
" CartridgeStatus != in use ",
"cartridge status is not in use");
}
/* Check if this CARTRIDGE has a SLOT created for it */
"select \"SlotName\" "
"from \"SLOT\" "
"where \"CartridgeID\" = '%s';",
candidate_cartid) != MM_DB_DATA) {
"Error getting slot info, "
"cartridge, %s, db trans failed",
}
"no slot found for cartridge, %s",
"ENOSLOT",
"cart",
NULL);
}
/* skip volume check */
/* This cart already has mapped to mount physical */
"skip vol check for unmount");
}
/* Get VOLUME information */
"Checking for Volumes");
"select \"ApplicationName\" "
"from \"VOLUME\" where "
"\"CartridgeID\" = '%s' and "
"\"ApplicationName\" = '%s';",
"Error getting volume information, "
"cartridge, %s, db trans failed",
}
"%s doesn't have a volume "
"on cartridge, %s",
"EAPPHASNOVOLS",
"app",
"cart",
NULL);
}
end:
mm_clear_db(&cart);
}
}
mm_clear_db(&slot);
}
return (rc);
}
int
char *candidate_library) {
/* Determines if the candidate library */
/* is available as a candidate */
int rc;
"Error getting library information, "
"library %s",
"failed to get library "
"information from database");
}
"%s is not online",
"ELIBRARYOFFLINE",
"lib",
NULL);
}
"%s is disabled",
"temporary") == 0) {
"ELIBDISABLEDTEMP",
"lib",
NULL);
} else {
"ELIBDISABLEDPERM",
"lib",
NULL);
}
}
"%s is broken",
"ELIBBROKEN",
"lib",
NULL);
}
"Library status ok, check LM");
/* Library is online and ready, get LM status */
"Error getting lm information, "
"library %s",
"failed to get lm information");
}
"%s is not ready,"
" LMStateHard != ready ",
"ELIBBROKEN",
"lm",
NULL);
}
"%s is not ready,"
" LMStateSoft != ready ",
"absent") == 0) {
"ELMNOTCONNECTED",
"lm",
"lib",
NULL);
}
"present") == 0) {
"ELMNOTREADY",
"lm",
"lib",
NULL);
}
"disconnected") == 0) {
"ELIBBROKEN",
"lm",
"lib",
NULL);
}
"not ready") == 0) {
"ELMSTILLBOOTING",
"lm",
"lib",
NULL);
}
}
"LM status ok");
end:
return (rc);
}
int
/*
* This will insert the drive_struct into its
* proper place in drive_list
*
* the drives are inserted in order of drive_priority
* check the dm shape and dm density priority to
* arrange the drives within each drive priority group
*/
int drv_priority;
int dm_shape_priority;
int dm_density_priority;
int cur_drv_priority;
int cur_shape_priority;
int cur_density_priority;
int next_drv_priority;
int a_drive = 0;
drive = next_drive) {
a_drive = 1;
drive);
if (cur_drv_priority != drv_priority) {
/* go to the next drive */
continue;
}
if (cur_shape_priority > dm_shape_priority) {
/* Insert before cur */
return (0);
}
if ((cur_shape_priority == dm_shape_priority) &&
/* Insert before cur */
return (0);
}
if (next_drive == NULL) {
return (0);
}
if (next_drv_priority != drv_priority) {
return (0);
}
}
return (a_drive);
}
int drive_row) {
"select \"DMName\""
" from \"DRIVE\" where "
"\"DriveName\" = '%s';",
candidate_drive) != MM_DB_DATA) {
"Error getting dm information");
return (NULL);
}
"Coudn't find DRIVE for "
"this drive, %s",
"missing DRIVE obj during unmount");
return (NULL);
}
drive = (cmi_drive_list_t *)
calloc(1,
sizeof (cmi_drive_list_t));
"Unable to malloc"\
" cmi_drive_list: %s",
"unable to allocate mem for drive stat");
mm_clear_db(&dm);
return (NULL);
}
drive->cmi_drive_not_ready = 0;
drive->cmi_dm_shape_priority = 0;
drive->cmi_dm_density_priority = 0;
/* Column references must match what is in mm_mount_init_candidates */
drive_row, 2));
drive_row, 3));
drive);
mm_clear_db(&dm);
return (drive);
}
int drive_row) {
/* drive_results is created in mm_init_candidates */
int dm_shape_priority;
int dm_density_priority;
int drive_not_ready;
int i;
drive_row, 0);
char *cur_dm_shape;
char *cur_dm_shape_priority;
char *cur_dm_density;
char *cur_dm_density_priority;
/* get the dm name */
/* get name by host */
"select \"DMName\""
" from \"DM\" where "
"\"DriveName\" = '%s' "
"and pg_host_ident("
"\"DMTargetHost\") "
"= pg_host_ident('%s');",
"Error getting dm information");
return (NULL);
}
"No dm configured for "
"this drive, on host %s",
"EAPPDMDIFFHOSTS",
"host",
NULL);
return (NULL);
}
/* Check the cartridge shape */
"select \"DMSHAPEPRIORITY\".\"DMName\", "
"\"DMSHAPEPRIORITY\".\"DMShapeName\","
"\"DMSHAPEPRIORITY\".\"DMShapePriority\","
"\"DMDENSITYPRIORITY\".\"DMDensityName\","
"\"DMDENSITYPRIORITY\".\"DMDensityPriority\" from "
"\"DMSHAPEPRIORITY\",\"DMDENSITYPRIORITY\""
"where "
"\"DMSHAPEPRIORITY\".\"DMName\" = '%s' and "
"\"DMDENSITYPRIORITY\".\"DMName\" = '%s';",
dm_name) != MM_DB_DATA) {
"Error checking cartridge shape");
mm_clear_db(&dm);
return (NULL);
}
drive_not_ready = 0;
/* This will be an error for immediate mounts */
/* for blocking keep drive, and set drive_not_ready */
"dm has not been configured for this drive");
drive_not_ready = 1;
}
dm_shape_priority = -1;
/* Default density is 1 */
dm_density_priority = 1;
}
}
}
if ((dm_shape_priority == -1) &&
(drive_not_ready != 1)) {
/* Drive has configed dm, but slot does not match */
/* Didn't find this dm_shape */
"dm is not configured for this slot type");
"ECARTDRVSLOTMISMATCH",
NULL);
mm_clear_db(&dm);
return (NULL);
}
/* Confirm DM MOUNT POINT */
if (drive_not_ready == 0) {
"drive is configured, quickly check the mountpoint");
"select \"DMName\" from \"DMMOUNTPOINT\" "
"cross join \"CARTRIDGE\" where "
"\"CARTRIDGE\".\"CartridgeMountPoint\" = "
"\"DMMOUNTPOINT\".\"DMMountPoint\""
"and"
"\"CARTRIDGE\".\"CartridgeID\" = '%s'"
"and \"DMMOUNTPOINT\".\"DMName\" = '%s'",
dm_name) != MM_DB_DATA) {
"Error checking cartridge shape");
mm_clear_db(&dm);
return (NULL);
}
/* This will be an error for immediate mounts */
/* for blocking keep drive, and set drive_not_ready */
"dm does not support this mount point");
"EDMNOMOUNTPOINT",
"dm",
NULL);
mm_clear_db(&dm);
return (NULL);
}
"dm is configured for this cart's mountpoint");
} else {
"drive not ready, skip mountpoint check for now");
}
drive = (cmi_drive_list_t *)
calloc(1,
sizeof (cmi_drive_list_t));
"Unable to malloc"\
" cmi_drive_list: %s",
"unable to allocate mem for drive stat");
mm_clear_db(&dm);
return (NULL);
}
drive->cmi_dm_name =
0, 0));
/* Column references must match what is in mm_mount_init_candidates */
drive_row, 2));
drive_row, 3));
/* Insert Drives into the correct place in the list here */
/* Drives are already orderd by priority and number mounts */
/* Enforce shape and density priority here */
/* Go down the drive list and find where this */
/* drive's pritoriy group starts */
/* Then insert the current drive according to dm_shape_priority */
/* Maintain the original ordering within like prioritys */
drive)) {
"error inserting drive into list");
}
mm_clear_db(&dm);
return (drive);
}
int row_number) {
/* Column references must match what is in mm_mount_cart_results */
char *bit_format = NULL;
/* Get PARTITION."PartitionBitFormat" */
"select \"PARTITION\".\"PartitionBitFormat\" "
"from \"PARTITION\" where \"CartridgeID\" = '%s';",
candidate_cartid) != MM_DB_DATA) {
"db error getting PartitionBitFormat");
return (NULL);
}
if (PQntuples(partition_results) == 0) {
"couldn't find PARTITION for %s",
"couldn't find PARTITION");
return (NULL);
}
cart = (cmi_cart_list_t *)
"Unable to malloc cmi_cart_list: %s",
"unable to allocate mem for drive list");
return (NULL);
}
sizeof (cmi_drive_list_t),
cart_pcl);
cart->cmi_cart_not_ready = 0;
} else {
cart->cmi_cart_loaded = 0;
}
cart);
return (cart);
}
int
/*
* this function needs to determine if a candidate
* cartridge is already loaded into a candidate drive.
* If there is, it must set the mount_info
*/
char *cur_cartid = NULL;
char *cur_library = NULL;
"mm_mount_candidate_loaded: ");
/* The list should already be ordered */
/* select the 1st available */
/* The list should already be ordered */
/* select the 1st available */
if (cart->cmi_cart_not_ready) {
continue;
}
if (drive->cmi_drive_not_ready) {
continue;
}
if (drive->cmi_drive_loaded) {
/* set this mount info and return */
return (1);
}
}
}
}
return (0);
}
int
/*
* this function needs to determine if there is an
* open drive for a candidate cartridge
* If there is, it must set the mount_info
*/
char *cur_cartid = NULL;
char *cur_library = NULL;
"mm_mount_open_drive: ");
/* The list should already be ordered */
/* select the 1st available */
if (cart->cmi_cart_not_ready) {
continue;
}
/* only look at non loaded carts */
if (cart->cmi_cart_loaded) {
continue;
}
/* The list should already be ordered */
/* select the 1st available */
if (drive->cmi_drive_not_ready) {
continue;
}
/* only look at non-loaded drives */
if (drive->cmi_drive_loaded) {
continue;
}
/* set this mount info and return */
return (1);
}
}
return (0);
}
int
/* check if a loaded candidate cartridge */
/* must be mounted in a drive loaded with a non-candidate */
/* need unmount candidate drive and candidate cart */
/* then mount */
char *cur_cartid = NULL;
char *cur_library = NULL;
"mm_unmount_2_drive: ");
if (cart->cmi_cart_not_ready) {
continue;
}
if (drive->cmi_drive_not_ready) {
continue;
}
if (cart->cmi_cart_loaded &&
"select \"LibraryName\",\"DriveName\" "
"from \"DRIVE\" where \"DRIVE\"."
"\"CartridgePCL\" = '%s' and "
"\"DRIVE\".\"DriveName\" = '%s';",
"mm_unmount_2_drive:"
" db error reading data");
continue;
}
/* Cur cart is not loaded */
"%s not found in drive %s",
continue;
}
"** 2 Unmount Summary **");
"1st unmount %s %s",
"2nd unmount %s %s",
return (1);
}
}
}
return (0);
}
int
char **drive_to_unload, char **lib_to_unload) {
/*
* this function needs to determine if a candidate
* cartridge must be mounted on a drive already loaded
* with a non-candidate cartridge that needs to be unmounted
* OR
* If a candidate cartridge is loaded in a non-candidate drive
* that 1st must be unmounted
* If there is, it must set the mount_info
*/
char *cur_cartid = NULL;
char *cur_library = NULL;
"mm_mount_loaded_drive: ");
/* The list should already be ordered */
/* select the 1st available */
if (cart->cmi_cart_not_ready) {
continue;
}
/* If the cartridge is not mounted */
/* The list should already be ordered */
/* select the 1st available */
if (drive->cmi_drive_not_ready) {
continue;
}
if (cart->cmi_cart_loaded &&
(drive->cmi_drive_loaded == 0)) {
/* Candidate is loaded and drive is empty */
/* this candidate cart is loaded in a drive */
/* this cartridge is mounted */
"select \"LibraryName\",\"DriveName\" "
"from \"DRIVE\" where \"DRIVE\"."
"\"CartridgePCL\" = '%s';",
cur_pcl) != MM_DB_DATA) {
"mm_mount_loaded_drive: "
"db error getting data");
continue;
}
/* Cur cart is not loaded */
"%s not found in a drive",
cur_pcl);
continue;
} else {
/* cur cart is loaded */
*(drive_to_unload) =
0, 1));
*(lib_to_unload) =
0, 0));
"%s loaded in %s %s",
0, 0),
0, 1));
}
return (1);
} else if ((cart->cmi_cart_loaded == 0) &&
/* set this mount info and return */
*(drive_to_unload) = NULL;
*(lib_to_unload) = NULL;
return (1);
}
}
}
return (0);
}
int
char *cur_cartid = NULL;
char *cur_library = NULL;
int rc = MM_CMD_DONE;
/* The list should already be ordered */
/* select the 1st available */
"internal error setting cmi info, "
"cannot find candidate carts structfound");
"internal error setting cmi info, "
"no candidate carts found");
return (MM_CMD_ERROR);
}
"internal error setting cmi info, "
"no candidate drives found");
"internal error setting cmi info, "
"no candidate drives found");
return (MM_CMD_ERROR);
}
}
/* Select Is done - print the results */
"complete for task %s",
mount_info->cmi_dm);
"where \"TaskID\" = '%s';",
"mm_set_immediate_unmount: "
"db error removing TASK");
}
"mm_set_immediate_unmount: "
"db error creating TASK");
}
/* Delete all old TASK objects and create them anew */
"where \"TaskID\" = '%s';",
"mm_set_immediate_unmount: "
"db error removing TASKDRIVE");
}
"where \"TaskID\" = '%s';",
"mm_set_immediate_unmount: "
"db error removing TASKLIBRARY");
}
"where \"TaskID\" = '%s';",
"mm_set_immediate_unmount: "
"db error removing TASKCARTRIDGE");
}
if (mm_set_tm_drive(db,
"mm_set_immediate_unmount: "
"db error setting TASKDRIVE");
}
if (mm_set_tm_library(db,
"mm_set_immediate_unmount: "
"db error setting TASKLIBRARY");
}
if (mm_set_tm_cartridge(db,
"mm_set_immediate_unmount: "
"db error setting TASKCARTRIDGE");
}
"set \"DriveStateSoft\" = 'in use'"
"where \"DriveName\" = '%s';",
"mm_set_immediate_unmount: "
"db error setting DriveStateSoft");
}
"set \"DMName\" = '%s' "
"where \"DriveName\" = '%s';",
"mm_set_immediate_unmount: "
"db error setting DMName");
}
"update \"CARTRIDGE\" set "
"\"CartridgeStatus\" = 'in use' "
"where \"CartridgeID\" = '%s';",
"mm_set_immediate_unmount: "
"db error setting CartridgeStatus");
}
return (rc);
}
void
"where \"TaskID\" = '%s';",
"mm_set_mount_objs: "
"db error deleting TASK");
}
"mm_set_mount_objs: "
"db error inserting TASK");
}
/* Delete all old TASK objects and create them anew */
"where \"TaskID\" = '%s';",
"mm_set_mount_objs: "
"db error deleting TASKDRIVE");
}
"where \"TaskID\" = '%s';",
"mm_set_mount_objs: "
"db error deleting TASKLIBRARY");
}
"where \"TaskID\" = '%s';",
"mm_set_mount_objs: "
"db error deleting TASKCARTRIDGE");
}
if (mm_set_tm_drive(db,
"mm_set_mount_objs: "
"db error inserting TASKDRIVE");
}
if (mm_set_tm_library(db,
"mm_set_mount_objs: "
"db error inserting TASKLIBRARY");
}
if (mm_set_tm_cartridge(db,
"mm_set_mount_objs: "
"db error inserting TASKCARTRIDGE");
}
"set \"DriveStateSoft\" = 'in use'"
"where \"DriveName\" = '%s';",
"mm_set_mount_objs: "
"db error updating DriveStateSoft");
}
"set \"DMName\" = '%s' "
"where \"DriveName\" = '%s';",
"mm_set_mount_objs: "
"db error updating DMName");
}
"update \"CARTRIDGE\" set "
"\"CartridgeStatus\" = 'in use' "
"where \"CartridgeID\" = '%s';",
"mm_set_mount_objs: "
"db error updating CartridgeStatus");
}
}
int
/* This function is used to setup the command */
/* flags and depend pointers for the mount */
/* Need to set error message in this function */
if (mount_info->cmi_mount_type ==
"MM_CANDIDATE_LOADED");
/* Remove the delay unload command */
return (0);
}
if (mount_info->cmi_mount_type ==
"MM_OPEN_DRIVE");
return (0);
}
if (mount_info->cmi_mount_type ==
"MM_UNMOUNT_DRIVE");
/* Set the delay unload for immdiate dispatch */
cmd,
/* Instead of return error */
/* attempt to fix by adding a clear_drive */
/* for this drive, set this */
/* command as parent of */
/* the clear drive */
"could not find delay unload, "
"attempt to clear and continue");
"error adding clear drive cmd");
return (1);
}
}
return (0);
}
if (mount_info->cmi_mount_type ==
"MM_UNMOUNT_CART");
/* Set the delay unload for immdiate dispatch */
if (mm_dispatch_unload(mount_info->
cmd,
/* Instead of return error */
/* attempt to fix by adding a clear_drive */
/* for this drive, set this */
/* command as parent of */
/* the clear drive */
"could not find delay unload, "
"attempt to clear and continue");
if (mm_add_clear_drive(mount_info->
"error adding clear drive cmd");
return (1);
}
}
return (0);
}
if (mount_info->cmi_mount_type ==
MM_UNMOUNT_2) {
"MM_UNMOUNT_2");
if ((unmnt_cmd_1 =
NULL,
"error finding unmount command");
if ((unmnt_cmd_1 =
"error adding clear drive cmd");
return (1);
}
}
if ((unmnt_cmd_2 =
"error finding unmount command");
if ((unmnt_cmd_2 =
"error adding clear drive cmd");
return (1);
}
}
return (0);
}
"encountered unknown mount type");
return (1);
}
int
int rc = MM_CMD_DONE;
char *drive_to_unload = NULL;
char *lib_to_unload = NULL;
/* Every candidate is currently in a ready state */
/* Drives may be loaded with a cartridge */
/* Cartridge could be: */
/* a. a non-candidate cartridge */
/* b. a candidate cartridge */
/* If a candidate drive has a candidate loaded, use that now */
/* If their are no candidate cartridge's loaded, */
/* try to find an open drive */
/* If there are no open drives, use a drive loaded */
/* with a non-candidate cartridge */
if (mm_mount_candidate_loaded(cmd)) {
/* 0 mount time */
"a candidate cartridge is loaded");
} else if (mm_mount_open_drive(cmd)) {
/* 1 mount time */
"open drive found");
&lib_to_unload)) {
/* 2 mount time */
/* these mounts need an unmount, then mount */
if (drive_to_unload == NULL &&
lib_to_unload == NULL) {
"drive loaded with non-candidate "
"must unload 1st");
/* Need to set up parent command */
/* return as dispatch depend */
"%s needs unload to complete first",
} else {
"candidate loaded in non-candidate drive "
"must unload 1st");
/* Need to set up parent command */
/* return as dispatch depend */
"%s needs unload to complete first",
}
/* 3 mount time */
/* Candidate cart is mounted, */
/* the only candidate drive is loaded with non-candidate */
/* need to unmount candidate cart, unmount candidate drive */
} else {
/* should never reach herer */
"MMS_ERROR - no drives found");
"internal error, "
"could not find ready drive, "
"submitt a bug if you hit this!,"
"MM internal states out of sync");
"returning MM_RESYNC");
return (MM_RESYNC);
}
}
/* call function to kick off delay unmounts */
/* error should be set */
"error setting up mount for dispatch");
return (MM_CMD_ERROR);
}
/* Select Is done - print the results */
"complete for task %s",
mount_info->cmi_dm);
"where \"TaskID\" = '%s';",
"mm_set_immediate_mount: "
"db error removing TASK");
}
"mm_set_immediate_mount: "
"db error creating TASK");
}
/* Delete all old TASK objects and create them anew */
"where \"TaskID\" = '%s';",
"mm_set_immediate_mount: "
"db error removing TASKDRIVE");
}
"where \"TaskID\" = '%s';",
"mm_set_immediate_mount: "
"db error removing TASKLIBRARY");
}
"where \"TaskID\" = '%s';",
"mm_set_immediate_mount: "
"db error removing TASKCARTRIDGE");
}
if (mm_set_tm_drive(db,
"mm_set_immediate_mount: "
"db error creating TASKDRIVE");
}
if (mm_set_tm_library(db,
"mm_set_immediate_mount: "
"db error creating TASKLIBRARY");
}
if (mm_set_tm_cartridge(db,
"mm_set_immediate_mount: "
"db error creating TASKCARTRIDGE");
}
"set \"DriveStateSoft\" = 'in use'" \
"where \"DriveName\" = '%s';",
"mm_set_immediate_mount: "
"db error updating DriveStateSoft");
}
"set \"DMName\" = '%s' "\
"where \"DriveName\" = '%s';",
"mm_set_immediate_mount: "
"db error updating DMName");
}
"update \"CARTRIDGE\" set "
"\"CartridgeStatus\" = 'in use' "
"where \"CartridgeID\" = '%s';",
"mm_set_immediate_mount: "
"db error updating CartridgeStatus");
}
return (rc);
}
int
int go;
int count;
char *dm_host;
/* Get the type */
} else {
NULL);
return (MM_CMD_ERROR);
}
/* Get when */
} else {
}
} else {
/* when is optional and defaults to immediate */
}
/* Get where */
MMS_PN_CLAUSE, &work);
} else {
}
} else {
}
/* Get File Name - Optional */
MMS_PN_CLAUSE, &work);
} else {
}
} else {
}
/* Get BlockSize - Optional */
MMS_PN_CLAUSE, &work);
} else {
}
} else {
}
/* Get volumeid - Optional */
MMS_PN_CLAUSE, &work);
} else {
}
} else {
}
/* Get filesequence - Optional */
MMS_PN_CLAUSE, &work);
} else {
}
} else {
}
/* Get user - Optional */
MMS_PN_CLAUSE, &work);
} else {
}
} else {
}
/* Get First Mount Clause */
MMS_PN_CLAUSE, &work);
count = 0;
go = 1;
while (go) {
if ((value =
go = 0;
} else {
count ++;
}
}
} else {
}
/* Get Access Mode Clause */
MMS_PN_CLAUSE, &work);
MMS_PN_CLAUSE, &work)) {
/* Malloc a new mode object */
mode = (cmi_mode_list_t *)
"Unable to malloc cmi_mode_list: %s",
"unable to allocate "
"memory for mode list");
return (MM_CMD_ERROR);
}
/* Get all of the access Mode tokens */
count = 0;
go = 1;
while (go) {
if ((value =
go = 0;
} else {
count ++;
}
}
/* Put this access mode into the Accessmode list */
}
/* Get retention clause */
/* Get user - Optional */
MMS_PN_CLAUSE, &work);
} else {
}
} else {
}
return (MM_CMD_DONE);
NULL);
return (MM_CMD_ERROR);
return (MM_CMD_ERROR);
}
void
int has_drive = 0;
/* Cannot use mms_list_foreach when removing list elements */
/* For each cart */
cart);
cart->cmi_cart_pcl);
has_drive = 0;
/* For each drive */
drive = next_drive) {
drive);
if (drive->cmi_remove_drive) {
drive);
" free drive %s",
} else {
" drive good, %s",
has_drive = 1;
}
}
if (has_drive == 0)
if (cart->cmi_remove_cart) {
" free cart, %s",
cart->cmi_cart_pcl);
} else {
" cart good, %s",
cart->cmi_cart_pcl);
}
}
}
int
char *candidate_cartid = NULL;
char *candidate_drive = NULL;
cart)) {
/* Cartridge is ok */
if (cart->cmi_cart_not_ready) {
"cartridge %s is not "
} else {
"Cartridge, %s, is available",
}
} else {
/* Cartridge not available */
"Cartridge, %s, is not "
"available for mount",
/* Go on to next cartridge */
continue;
}
if (cart->cmi_cart_not_ready) {
continue;
}
"Check Drive, %s", candidate_drive);
drive)) {
if (drive->cmi_drive_not_ready) {
} else {
"Drive, %s, is available",
}
} else {
"Drive, %s, not available"
" for mounts",
}
}
}
return (0);
}
int
int cart_rows;
int cart_row;
int drive_rows;
int drive_row;
char *candidate_library = NULL;
char *candidate_drive = NULL;
char *candidate_cartid = NULL;
"mm_mount_init_candidates: cartid = %s, library = %s",
/* Allocate this cartridge */
db,
cart_row);
"error allocing candidate cart");
return (1);
}
"Library, %s, is available",
} else {
"Library, %s, not available",
/* Go on to next cartridge */
continue;
}
/* Get the drives in this library */
/* Do some ordering of drives here */
/* mm_mount_order_candidates will do the ordering */
"select distinct \"DriveName\","
"\"LibraryName\",\"DrivePriority\","
"\"DriveNumberMounts\" from ("
"select \"DriveName\",\"LibraryName\","
"\"DrivePriority\",\"DriveNumberMounts\""
"from \"DRIVE\""
"where (\"DRIVE\".\"LibraryName\" = '%s')"
"order by \"DRIVE\".\"DriveNumberMounts\""
") as foo order by \"DrivePriority\";",
candidate_library) != MM_DB_DATA) {
"db error, init candidate cart");
return (1);
}
} else {
"select distinct \"DriveName\","
"\"LibraryName\",\"DrivePriority\","
"\"DriveNumberMounts\" from ("
"select \"DriveName\",\"LibraryName\","
"\"DrivePriority\",\"DriveNumberMounts\""
"from \"DRIVE\""
"where (\"DRIVE\".\"LibraryName\" = '%s' "
"and \"DRIVE\".\"CartridgePCL\" = '%s')"
"order by \"DRIVE\".\"DriveNumberMounts\""
") as foo order by \"DrivePriority\";",
"db error, init candidate cart");
return (1);
}
}
if (drive_rows == 0) {
"couldn't match any drives for library %s",
"lib",
NULL);
return (1);
}
drive_row, 0);
"mm_mount_init_candidates: drive = %s",
/* mm_set_dirve_unmount and */
/* mm_setup_drive return a pointer */
/* to the set up drive struct */
(void) mm_setup_drive_unmount(cmd,
db,
} else {
(void) mm_setup_drive(cmd,
db,
}
}
}
return (0);
}
int i;
} else {
/* TEMP - Trace out our dest info */
}
} else {
/* TEMP - Trace out our const info */
}
/* add CARTRIDGEGROUPAPPLICATION constraint */
(void) mm_add_to_dest(cmd,
"CARTRIDGEGROUPAPPLICATION");
if (tmp_buf)
"\"CARTRIDGEGROUPAPPLICATION\"."
"\"ApplicationName\" = '%s'",
app_name);
if (tmp_buf)
}
/* Clear cmd_buf */
&cmd->cmd_bufsize, 0);
/* Make path_buf and set source */
"select distinct");
if (mm_add_char("VOLUME",
&cmd->cmd_source_list)) {
"mm_mount_cart_results: "
"Error adding char to source list");
"out of mem adding to source list");
return (NULL);
}
"\"VOLUME\"");
}
if (mm_add_char("PARTITION",
&cmd->cmd_source_list)) {
"mm_mount_cart_results: "
"Error adding char to source list");
"out of mem adding to source list");
return (NULL);
}
"\"PARTITION\"");
}
if (mm_add_char("SIDE",
&cmd->cmd_source_list)) {
"mm_mount_cart_results: "
"Error adding char to source list");
"out of mem adding to source list");
return (NULL);
}
"\"SIDE\"");
}
}
/* Put path_buf into cmd_buf */
".\"CartridgeID\" from\n");
/* Make report funcs */
"mm_mount_cart_results: "
"db error creating helper functions");
return (NULL);
}
"db error getting candidate cartridges");
return (NULL);
}
/* no cartridge matches */
"match statment in mount "
NULL);
return (NULL);
}
/* Order cartridges based on priority and last time mounted */
/* Additional Cartridge Ordering */
/* done in mm_mount_order_candidates */
"select distinct \"CartridgeID\","
"\"LibraryName\",\"CartridgeGroupPriority\","
"\"CartridgeNumberMounts\", "
"\"CartridgeShapeName\",\"CartridgePCL\", "
"\"CartridgeDriveOccupied\" "
"from ( "
"select \"CartridgeID\",\"LibraryName\", "
"\"CartridgeGroupPriority\","
"\"CartridgeNumberMounts\", "
"\"CartridgeShapeName\",\"CartridgePCL\", "
"\"CartridgeDriveOccupied\" "
"from \"CARTRIDGE\","
"\"CARTRIDGEGROUP\",\"CARTRIDGETYPE\" ");
if (i == 0) {
} else {
}
}
") and"
"(\"CARTRIDGEGROUP\".\"CartridgeGroupName\" "
"= \"CARTRIDGE\".\"CartridgeGroupName\")"
"and"
"(\"CARTRIDGE\".\"CartridgeTypeName\" "
"= \"CARTRIDGETYPE\".\"CartridgeTypeName\")"
"order by \"CARTRIDGE\".\"CartridgeTimeMountedLast\""
") as foo order by \"CartridgeGroupPriority\";");
return (NULL);
}
return (db->mm_db_results);
return (NULL);
}
int
int cart_rows;
int found_cart_drive = 0;
int found_ready_cart_drive = 0;
int rc;
int resync_tries = 5;
int i = 0;
/* No carts or error */
return (MM_MOUNT_ERROR);
}
if (cart_rows == 0) {
/* No Cartridge Matches Error */
"match statment in mount "
NULL);
return (MM_MOUNT_ERROR);
}
/* Create the list objects for */
db)) {
"error initializing candidate lists");
/* err buf should be set by mm_mount_init */
/* so return and remove */
return (MM_MOUNT_ERROR);
}
/* Check the availability of the candidates */
db)) {
"error checking candidate lists");
"error checking candidate lists");
return (MM_MOUNT_ERROR);
}
/* Print mount information */
/*
* For blocking mounts,
*
* for immediate mounts, check that at least one combination exists
*/
found_cart_drive = 0;
if (cart->cmi_cart_not_ready)
found_cart_drive = 1;
if ((cart->cmi_cart_not_ready == 0) &&
(drive->cmi_drive_not_ready == 0)) {
}
if (drive->cmi_drive_not_ready)
}
}
/* If there is a library or drive error */
/* the error buff has already been set */
if (found_cart_drive == 0) {
"No candidate "
"combination found");
return (MM_MOUNT_ERROR);
}
if (found_ready_cart_drive == 0) {
"candidate "
"combination found, but is not ready");
return (MM_MOUNT_NOT_READY);
}
/* we may have set some non ready for remove */
/* so call the clean func before contine */
if (is_retry) {
return (rc);
}
/* Destroy all cart lists */
"mm_mount_ready: "
"states out of sync, attempt to resync this mount");
for (i = 0; i < resync_tries; i++) {
"mm_mount_ready: "
"resync successful");
return (rc);
}
}
"mm_mount_ready: "
"states out of sync, resync failed");
return (MM_MOUNT_ERROR);
}
if (rc == MM_CMD_ERROR) {
"error setting up immediate mount");
return (MM_MOUNT_ERROR);
} else if (rc == MM_DISPATCH_DEPEND) {
/* this immediate mount needs to */
/* wait for an unload */
" mount waiting "
"for unload to complete");
return (MM_MOUNT_NEED_UNLOAD);
}
"mount ready for dispatch");
return (MM_MOUNT_READY);
return (MM_MOUNT_ERROR);
}
int
{
int rows;
int rc;
char *response_message = NULL;
/*
* Generate Candidate Cartridge and Drive lists
* First parse and save the mount info
* then use SQL queries to gereate the lists
*/
"error parsing mount command");
/* Error buf should already be set */
return (MM_CMD_ERROR);
}
/* ***DONE PARSING MOUNT COMMAND*** */
goto db_error;
}
"blocking mount will be passed to task manager");
return (MM_WORK_TODO);
}
/* This is an immediate mount */
switch (rc) {
case MM_MOUNT_ERROR:
/* Error code should be set */
"internal error, mm_mount_ready");
return (MM_CMD_ERROR);
case MM_MOUNT_READY:
/* The mount is ready, mount_info should be set */
/* continue to state 1 */
"mount is ready to go, "
"continue to state 1");
break;
case MM_MOUNT_NEED_UNLOAD:
/* this immediate mount needs to */
/* wait for an unload */
"mount waiting "
"for unload to complete");
return (MM_DISPATCH_DEPEND);
case MM_MOUNT_NOT_READY:
/* Error code should be set */
"immediate mount not ready, "
"send error to client");
return (MM_CMD_ERROR);
default:
"bad rc mm_mount_ready");
"bad rc mm_mount_ready");
return (MM_CMD_ERROR);
}
}
/* Reserve the DM */
/*
* mm_sql_update_state(mm_wka->mm_data, "DM",
* "DMStateSoft",
* "reserved", "DMName",
* mount_info->cmi_dm);
*/
"DMName",
/* Add activate command */
MM_DMP_RESERVE) == NULL) {
"error adding dmp reserve");
"error adding dmp reserve");
goto reset_states;
}
return (MM_DISPATCH_DEPEND);
/*
* Mount cartridge in the library drive
*/
char *cart_pcl;
char *side_name;
/*
* DM Activate failed
*/
/* Reset drive and cartridge */
/* return error to client */
goto lm_dm_error;
}
if (mount_info->cmi_mount_cart_loaded) {
/* Skip lmp mount */
goto start;
}
/*
* Cartridge pcl and side name
*/
/* Error buf should be set in mm_get_cart_pcl */
goto reset_states;
}
/* TODO side name needs to be generated in candidate query */
side_name = "side 1";
}
/*
* LMP mount command
*/
"Unable to malloc mm_command_t: %s",
"Unable to malloc lmp mount cmd");
goto reset_states;
}
return (MM_DISPATCH_DEPEND);
/*
* LMP Mount command failed
*/
/* Reset drive and cartridge */
/* return error to client */
/* DM is reserved, release the DM */
MM_DMP_RELEASE)) {
/* run withtout parent */
}
/* Generate error message */
"msg_rsp", response_message,
NULL);
/* Set cmd for remove, send message to client */
rc = MM_CMD_ERROR;
goto end;
}
MM_DMP_PRIV) == NULL) {
"error adding dmp private");
"error adding dmp private");
goto reset_states;
}
return (MM_DISPATCH_DEPEND);
/* DM_load state */
/*
* Private has finished, add a load command to the
* queue
*/
/* Reset drive and cartridge */
/* return error to client */
/* DM is reserved, release the DM */
MM_DMP_RELEASE)) {
/* run withtout parent */
}
goto lm_dm_error;
}
MM_DMP_LOAD) == NULL) {
"error adding dmp load");
"error adding dmp load");
goto reset_states;
}
return (MM_DISPATCH_DEPEND);
/* load command has finished, add an attach */
/* Update Drive Table */
/* Reset drive and cartridge */
/* return error to client */
/* DM is reserved, release the DM */
MM_DMP_RELEASE)) {
/* run withtout parent */
}
"EDMPLOAD",
"cartridge",
"drive",
"msg_rsp",
NULL);
rc = MM_CMD_ERROR;
goto end;
}
MM_DMP_ATTACH) == NULL) {
"error adding dmp attach");
"error adding dmp attach");
goto reset_states;
}
return (MM_DISPATCH_DEPEND);
int priv_no_vol = 0;
/* DM_identify tester state */
/* Reset drive and cartridge */
/* return error to client */
/* DM is reserved, release the DM */
MM_DMP_RELEASE)) {
/* run withtout parent */
}
/* write error message */
"EDMPATTACH",
"cartridge",
"drive",
"msg_rsp",
NULL);
rc = MM_CMD_ERROR;
goto end;
}
"select * from \"MOUNTPHYSICAL\" "\
"where \"CartridgeID\" = '%s';",
if (rc != MM_DB_DATA) {
goto reset_states;
}
/* attach command has finished, add an indentify */
/* insert row into MOUNTLOGICAL */
"select \"VolumeName\", "
"\"PartitionName\", \"SideName\" "
"from \"VOLUME\" where \"CartridgeID\" = '%s'"
"and \"ApplicationName\" = '%s';",
conn->cci_client);
if (rc != MM_DB_DATA) {
goto reset_states;
}
/* Priv app doesn't have a volume */
"select \"VolumeName\", "
"\"PartitionName\", \"SideName\", "
"\"ApplicationName\" "
"from \"VOLUME\" where \"CartridgeID\" = '%s';",
priv_no_vol = 1;
}
"select \"SideName\" from " \
"\"SIDE\" where \"CartridgeID\" = '%s';",
if (rc != MM_DB_DATA) {
goto reset_states;
}
"missing SIDE obj for %s",
"cartridge missing SIDE obj");
mm_clear_db(&side);
goto reset_states;
}
"select \"SlotName\", "\
"\"CartridgePCL\" from \"SLOT\" "\
"where \"CartridgeID\" = '%s';",
if (rc != MM_DB_DATA) {
mm_clear_db(&side);
goto reset_states;
}
"missing SLOT obj for %s",
"cartridge missing SLOT obj");
mm_clear_db(&side);
mm_clear_db(&slot);
goto reset_states;
}
if (rows == 0) {
if (priv_no_vol) {
"insert into \"MOUNTLOGICAL\" "\
"(\"ApplicationName\", \"VolumeName\", "\
"\"PartitionName\", \"SideName\", "\
"\"CartridgeID\", \"DriveName\", "\
"\"DMName\", \"DMCapabilityName\", "\
"\"MountLogicalHandle\", "\
"\"MountLogicalTimeWhenMounted\") "\
"values ('%s', '%s', '%s', '%s', "\
"'%s', '%s', '%s', '%s', '%s', now());",
PQgetvalue(results, 0, 0),
} else {
"insert into \"MOUNTLOGICAL\" "
"(\"ApplicationName\", \"VolumeName\", "
"\"PartitionName\", \"SideName\", "
"\"CartridgeID\", \"DriveName\", "
"\"DMName\", \"DMCapabilityName\", "
"\"MountLogicalHandle\", "
"\"MountLogicalTimeWhenMounted\") "
"values ('%s', '%s', '%s', '%s', "
"'%s', '%s', '%s', '%s', '%s', now());",
PQgetvalue(results, 0, 0),
}
"mm_mount_cmd_func: "
"error inserting MOUNTLOGICAL");
}
"insert into \"MOUNTPHYSICAL\" "
"(\"ApplicationName\",\"DriveName\", "
"\"LibraryName\", "
"\"CartridgeID\", \"CartridgePCL\", "
"\"SideName\", "
"\"SlotName\", "
"\"MountPhysicalTimeWhenMounted\", "
"\"SessionID\") "
"values('%s', '%s', '%s', '%s', "
"'%s', '%s', '%s', now(), '%s');",
"mm_mount_cmd_func: "
"error inserting MOUNTPHYSICAL");
}
} else {
"delete from \"MOUNTLOGICAL\" "\
"where \"CartridgeID\" = '%s';",
"mm_mount_cmd_func: "
"error deleting MOUNTLOGICAL");
}
"insert into \"MOUNTLOGICAL\" "\
"(\"ApplicationName\", \"VolumeName\", "\
"\"PartitionName\", \"SideName\", "\
"\"CartridgeID\", \"DriveName\", "\
"\"DMName\", \"DMCapabilityName\", "\
"\"MountLogicalHandle\", "\
"\"MountLogicalTimeWhenMounted\") "\
"values ('%s', '%s', '%s', '%s', "\
"'%s', '%s', '%s', '%s', '%s', now());",
PQgetvalue(results, 0, 0),
"mm_mount_cmd_func: "
"error inserting MOUNTLOGICAL");
}
}
mm_clear_db(&side);
mm_clear_db(&slot);
MM_DMP_IDENTIFY) == NULL) {
"error adding dmp identify");
"error adding dmp identify");
goto reset_states;
}
return (MM_DISPATCH_DEPEND);
/* Reset drive and cartridge */
/* return error to client */
/* DM is reserved, release the DM */
MM_DMP_RELEASE)) {
/* run withtout parent */
}
goto lm_dm_error;
}
/* The command is finished so generate a report */
/* Remove the TASK objs */
"where \"TaskID\" = '%s';",
"mm_mount_cmd_func: "
"db error deleting TASKCARTRIDGE");
}
"mm_mount_cmd_func: "
"db error deleting TASKDRIVE");
}
"mm_mount_cmd_func: "
"db error deleting TASKLIBRARY");
}
"mm_mount_cmd_func: "
"db error deleting TASK");
}
/*
* Report clause.
*/
rc = MM_CMD_DONE;
goto end;
}
rc = MM_CMD_ERROR;
goto end;
return (MM_CMD_ERROR);
rc = MM_CMD_ERROR;
goto end;
NULL);
rc = MM_CMD_ERROR;
goto end;
"msg_rsp", response_message,
NULL);
/* Clear the Drive */
}
rc = MM_CMD_ERROR;
goto end;
rc = MM_CMD_ERROR;
goto end;
end:
return (rc);
}
int
{
char *response_message = NULL;
"wait longer for this unload");
return (MM_DISPATCH_DEPEND);
}
if (mount_info->cui_skip_unload) {
"procced with unload, "
"but skip the DM unload command");
return (MM_CMD_DONE);
}
"proceed with DM unload command");
}
MM_DMP_UNLOAD) == NULL) {
"mm_delay_unmount_cmd_func: "
"error adding dmp unload");
return (MM_CMD_ERROR);
}
return (MM_DISPATCH_DEPEND);
}
char *cart_pcl;
char *side_name;
/*
* Unload has returned
* check error, update states
*/
"msg_rsp", response_message,
NULL);
}
/*
* Cartridge pcl and side name
*/
"mm_get_cart_pcl error");
return (MM_CMD_ERROR);
}
/* TODO side name needs to be generated in candidate query */
side_name = "side 1";
}
/*
* LMP unmount command
*/
"Unable to malloc mm_command_t: %s",
return (MM_CMD_ERROR);
}
return (MM_DISPATCH_DEPEND);
}
"scan both drive and slot");
/* Clear depend error flags */
/* Add LMP scan command for this drive */
"Error adding LMP scan");
return (MM_CMD_ERROR);
} else {
"Added LMP scan");
}
return (MM_DISPATCH_DEPEND);
}
/*
* Don't reset the soft state
* "\"DriveStateSoft\" = 'ready',"
*/
"\"DMName\" = '',"
"\"DriveStateHard\" = 'unloaded' where "
"\"DriveName\" = '%s';",
"mm_delay_unmount_cmd_func: "
"db error updating DriveStateHard");
}
/* Don't update the cartridge soft state */
/* The unload may be part of a mount sequence */
if (mm_has_depend(cmd)) {
if (cur_depend->cmd_func ==
"this delay unmount has "
"delay unmount as parent,"
" set parent ready for dispatch");
NULL);
}
}
return (MM_DEPEND_DONE);
}
return (MM_CMD_DONE);
}
/* This is state after lmp scan of drive */
/* send a scan of the cartridge now */
"slot scan anyways");
/* Clear depend error flags */
}
/* Add LMP scan command for this drive */
NULL,
mount_info->cmi_library)) {
"Error adding LMP scan");
return (MM_CMD_ERROR);
} else {
"Added LMP scan");
}
return (MM_DISPATCH_DEPEND);
}
/* cartridge scan returned , return cmd done */
}
/* Don't update the cartridge soft state */
/* The unload may be part of a mount sequence */
if (mm_has_depend(cmd)) {
if (cur_depend->cmd_func ==
"this delay unmount has "
"delay unmount as parent,"
" set parent ready for dispatch");
NULL);
}
}
return (MM_DEPEND_DONE);
}
return (MM_CMD_DONE);
}
"mm_delay_unmount_cmd_func: unknown command state");
return (MM_CMD_ERROR);
}
int
/* Time releated */
char cur_date[100];
char unload_date[100];
struct tm unload_time;
/* allocate the unmount command */
"Unable to malloc mm_command_t: %s",
return (1);
}
/* Copy over the mount info to the new command */
/* Set up timer */
"select \"DriveGroupUnloadTime\" from "
"\"DRIVEGROUP\",\"DRIVE\" where "
"\"DRIVE\".\"DriveGroupName\" = "
"\"DRIVEGROUP\".\"DriveGroupName\" and "
"\"DRIVE\".\"DriveName\" = '%s';",
return (1);
}
return (1);
}
/* set the time to unload */
/* Get the delay time, get the current time */
/* unload time is in min, so mult by 60 for sec */
"Current time is %s, delay time is %s mins, unload at %s",
return (0);
}
int
/* Get the type */
}
MMS_PN_KEYWORD, NULL)) {
}
/* signature optional */
MMS_PN_CLAUSE, NULL)) {
NULL);
if (value &&
} else {
MMS_PN_STRING, &work);
MMS_PN_STRING, &work);
}
} else {
/* default signature */
}
return (MM_CMD_DONE);
NULL);
return (MM_CMD_ERROR);
return (MM_CMD_ERROR);
}
int i;
switch (mount_info->cmi_type) {
case MM_SIDE:
break;
case MM_PARTITION:
break;
case MM_VOLUME:
break;
}
} else {
/* TEMP - Trace out our dest info */
}
} else {
/* TEMP - Trace out our const info */
}
/* add CARTRIDGEGROUPAPPLICATION constraint */
(void) mm_add_to_dest(cmd,
"CARTRIDGEGROUPAPPLICATION");
if (tmp_buf)
"\"CARTRIDGEGROUPAPPLICATION\"."
"\"ApplicationName\" = '%s'",
app_name);
if (tmp_buf)
}
/* Constrain to only cartridges mounted by this session */
/* Maybe a forced unmount will not use this constraint */
(void) mm_add_to_dest(cmd,
"SESSION");
if (tmp_buf)
"\"SESSION\"."
"\"ConnectionID\" = '%s'",
if (tmp_buf)
/* Add MOUNTPHYSICAL constraint */
/* Maybe a forced unmount will not use this constraint */
(void) mm_add_to_dest(cmd,
"MOUNTPHYSICAL");
if (tmp_buf)
"(\"MOUNTPHYSICAL\".\"CartridgeID\" "
"= \"%s\".\"CartridgeID\")", type);
if (tmp_buf)
/* Make tmp_buf and set source */
"select \"%s\"."
"\"CartridgeID\" from\n ", type);
if (type)
if (tmp_buf)
"mm_unmount_cart_results: "
"db error creating helper functions");
return (NULL);
}
return (NULL);
}
/* no cartridge matches */
"match statment in mount "
NULL);
return (NULL);
}
"select distinct \"CartridgeID\","
"\"LibraryName\",\"CartridgeGroupPriority\","
"\"CartridgeNumberMounts\", "
"\"CartridgeTypeName\",\"CartridgePCL\", "
"\"CartridgeDriveOccupied\" "
"from ( "
"select \"CartridgeID\",\"LibraryName\", "
"\"CartridgeGroupPriority\","
"\"CartridgeNumberMounts\", "
"\"CartridgeTypeName\",\"CartridgePCL\", "
"\"CartridgeDriveOccupied\" "
"from \"CARTRIDGE\",\"CARTRIDGEGROUP\"");
if (i == 0) {
} else {
}
}
") and"
"(\"CARTRIDGEGROUP\".\"CartridgeGroupName\" "
"= \"CARTRIDGE\".\"CartridgeGroupName\")"
"order by \"CARTRIDGE\".\"CartridgeTimeMountedLast\""
") as foo order by \"CartridgeGroupPriority\";");
if (tmp_buf)
return (NULL);
}
if (tmp_buf)
return (db->mm_db_results);
return (NULL);
}
int
int cart_rows;
int found_cart_drive = 0;
int found_ready_cart_drive = 0;
int rc;
/* No carts or error */
return (MM_UNMOUNT_ERROR);
}
if (cart_rows == 0) {
/* No Cartridge Matches Error */
"match statment in mount "
NULL);
return (MM_UNMOUNT_ERROR);
}
/* Create the list objects for */
db)) {
"error initializing candidate lists");
/* err buf should be set by mm_mount_init */
/* so return and remove */
return (MM_UNMOUNT_ERROR);
}
/* Check the availability of the candidates */
db)) {
"error checking candidate lists");
"error checking candidate lists");
return (MM_UNMOUNT_ERROR);
}
/* Print mount information */
found_cart_drive = 0;
if (cart->cmi_cart_not_ready)
found_cart_drive = 1;
if ((cart->cmi_cart_not_ready == 0) &&
(drive->cmi_drive_not_ready == 0)) {
}
if (drive->cmi_drive_not_ready)
}
}
/* If there is a library or drive error */
/* the error buff has already been set */
if (found_cart_drive == 0) {
"No candidate "
"combination found");
return (MM_UNMOUNT_ERROR);
}
if (found_ready_cart_drive == 0) {
"candidate "
"combination found, but is not ready");
return (MM_UNMOUNT_NOT_READY);
}
/* we may have set some non ready for remove */
/* so call the clean func before contine */
if (rc == MM_CMD_ERROR) {
"error setting up immediate mount");
return (MM_UNMOUNT_ERROR);
}
"mount ready for dispatch");
return (MM_UNMOUNT_READY);
}
int
{
int rc;
char *response_message = NULL;
/* UM_CANDIDATE_SELECTION == 0 */
/*
* Generate Candidate Cartridge and Drive lists
* First parse and save the mount info
* then use SQL queries to gereate the lists
*/
"error parsing unmount command");
/* Error buf should already be set */
return (MM_CMD_ERROR);
}
goto db_error;
}
"unmount will be passed to task manager");
return (MM_WORK_TODO);
/*
* Add Detach command
*/
MM_DMP_DETACH) == NULL) {
"mm_unmount_cmd_func: "
"error adding dmp unload");
"error adding dmp unload");
return (MM_CMD_ERROR);
}
return (MM_DISPATCH_DEPEND);
}
/*
* Detach has returned
* check error, update states
* Add release command
*/
"DM_E_NOEXISTHANDLE")) {
/* DM doesn't know about the handle */
/* Continue with unmount regardless */
/* skip unload */
"DM doesn't know the handle, "
"skip DMP unload, "
"send LMP unmount");
/* Clear depend error flags */
} else {
"msg_rsp", response_message,
NULL);
rc = MM_CMD_ERROR;
goto end;
}
}
"where \"CartridgeID\" = '%s';",
"mm_unmount_cmd_func: "
"db error deleteing MOUNTLOGICAL");
}
"where \"CartridgeID\" = '%s';",
"mm_unmount_cmd_func: "
"db error deleteing STALEHANDLE");
}
MM_DMP_RELEASE) == NULL) {
"mm_unmount_cmd_func: "
"error adding dmp release");
"error adding dmp release");
return (MM_CMD_ERROR);
}
return (MM_DISPATCH_DEPEND);
}
/*
* release command has returned
* check for errors, update states
*/
NULL);
rc = MM_CMD_ERROR;
goto end;
}
if (mount_info->cui_physical) {
/* This is a physical unmount */
MM_DMP_UNLOAD) == NULL) {
"mm_unmount_cmd_func: "
"error adding dmp unload");
"error adding dmp unload");
return (MM_CMD_ERROR);
}
goto end;
}
/* Delayed unmount */
"DELAY UNLOAD NOW!!!!");
/* update drive and cartridge states */
"\"DriveStateSoft\" = 'ready',"
"\"DMName\" = ''"
" where "
"\"DriveName\" = '%s';",
"mm_unmount_cmd_func: "
"db error updating DriveStateSoft");
}
"update \"CARTRIDGE\" set \"CartridgeStatus\" "
"= 'available' where "
"\"CartridgeID\" = '%s';",
"mm_unmount_cmd_func: "
"db error updating CartridgeStatus");
}
"mm_unmount_cmd_func: "
"db error deleting TASKCARTRIDGE");
}
"mm_unmount_cmd_func: "
"db error deleting TASKDRIVE");
}
"mm_unmount_cmd_func: "
"db error deleting TASKLIBRARY");
}
"mm_unmount_cmd_func: "
"db error deleting TASK");
}
"where \"CartridgeID\" = '%s';",
"mm_unmount_cmd_func: "
"db error deleting MOUNTPHYSICAL");
}
"mm_unmount_cmd_func: "
"error scheduling unload");
}
/* Send success for the unmount */
goto end;
}
char *cart_pcl;
char *side_name;
/*
* Unload has returned
* check error, update states
* Add release command
*/
"msg_rsp", response_message,
NULL);
rc = MM_CMD_ERROR;
goto end;
}
/*
* Cartridge pcl and side name
*/
"mm_get_cart_pcl error");
return (MM_CMD_ERROR);
}
/* TODO side name needs to be generated in candidate query */
side_name = "side 1";
}
/*
* LMP unmount command
*/
"Unable to malloc mm_command_t: %s",
return (MM_CMD_ERROR);
}
return (MM_DISPATCH_DEPEND);
"msg_rsp", response_message,
NULL);
rc = MM_CMD_ERROR;
goto end;
}
/*
* TEMPORARY update drive states remove TASK objs
*/
/* If cmd_depend is set this is part of a begin-end group */
/* so do not reset the drive state */
if (mm_has_depend(cmd) == 0) {
"\"DriveStateSoft\" = 'ready',"
"\"DMName\" = '',"
"\"DriveStateHard\" = 'unloaded' where "
"\"DriveName\" = '%s';",
"mm_unmount_cmd_func: "
"db error updating DRIVE");
}
} else {
"\"DMName\" = '',"
"\"DriveStateHard\" = 'unloaded' where "
"\"DriveName\" = '%s';",
"mm_unmount_cmd_func: "
"db error updating DRIVE");
}
}
"update \"CARTRIDGE\" set \"CartridgeStatus\" "
"= 'available' where "
"\"CartridgeID\" = '%s';",
"mm_unmount_cmd_func: "
"db error updating CartridgeStatus");
}
"mm_unmount_cmd_func: "
"db error deleting TASKCARTRIDGE");
}
"mm_unmount_cmd_func: "
"db error deleting TASKDRIVE");
}
"mm_unmount_cmd_func: "
"db error deleting TASKLIBRARY");
}
"mm_unmount_cmd_func: "
"db error deleting TASK");
}
"where \"CartridgeID\" = '%s';",
"mm_unmount_cmd_func: "
"db error deleting MOUNTPHYSICAL");
}
/*
* Report clause.
*/
if (mm_has_depend(cmd)) {
if (cur_depend->cmd_func ==
"this delay unmount has "
"delay unmount as parent,"
" set parent ready for dispatch");
NULL);
}
}
rc = MM_DEPEND_DONE;
goto end;
}
rc = MM_CMD_DONE;
goto end;
}
rc = MM_CMD_ERROR;
goto end;
rc = MM_CMD_ERROR;
goto end;
NULL);
rc = MM_CMD_ERROR;
goto end;
rc = MM_CMD_ERROR;
goto end;
end:
return (rc);
}
int
{
} else {
}
} else {
/* when is optional and defaults to immediate */
}
/* return MM_DISPATCH_DEPEND??? */
return (MM_DISPATCH_DEPEND);
}
/* when End has been accepted, send success for begin */
/* Send success */
return (MM_DEPEND_DONE);
}
"bad command state- begin command");
"bad command state- begin command");
return (MM_CMD_ERROR);
return (MM_CMD_ERROR);
NULL);
return (MM_CMD_ERROR);
}
void
/* begin end command list */
/* Move beginend commands from begin to end */
next_cmd =
cur_cmd);
cur_cmd);
cur_cmd);
}
}
int
int cmd_count = 0;
cmd_count = 0;
cmd_count ++;
"Begin-end cmd %d, %s",
cur_cmd) == MM_CMD_ERROR) {
"error parsing unmount command");
/* Error buf should already be set */
return (-1);
}
} else {
cur_cmd) == MM_CMD_ERROR) {
"error parsing unmount command");
/* Error buf should already be set */
return (-1);
}
}
} else {
}
}
return (cmd_count);
}
int
{
int cmd_count;
if (be_command == NULL) {
"couldn't find begin for this end");
"couldn't find begin for this end");
return (MM_CMD_ERROR);
}
/* Copy begin cmd list ptr */
/* set begin for dispatch */
/* as depend */
return (MM_DISPATCH_DEPEND);
}
/* Begin has returned success */
/* abort command group */
MMS_PN_KEYWORD, NULL)) {
/* Cancel all the commands */
/* and return success for the abort */
return (MM_CMD_DONE);
}
/* Error parsing a command */
"inside begin-end group");
return (MM_CMD_ERROR);
} else if (cmd_count == 0) {
/* No commands in this command group */
/* Send success ??? */
return (MM_CMD_DONE);
}
"done parsing %d commands for begin-end group",
return (MM_CMD_ERROR);
}
"begin-end group will be passed to task manager");
return (MM_WORK_TODO);
}
/* Task manager has dispatched this command */
/* Send success for end */
return (MM_CMD_DONE);
}
"bad command state- end command");
"bad command state- end command");
return (MM_CMD_ERROR);
return (MM_CMD_ERROR);
}