713 lines
23 KiB
PHP
713 lines
23 KiB
PHP
|
<?php
|
||
|
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/ds_tsm.php,v 1.8 2009/04/19 04:03:05 wurley Exp $
|
||
|
|
||
|
/**
|
||
|
* @package phpTSMadmin
|
||
|
* @author Deon George (c) 2006
|
||
|
*/
|
||
|
|
||
|
class tsm extends DS {
|
||
|
public function __construct($index) {
|
||
|
$this->index = $index;
|
||
|
$this->type = 'tsm';
|
||
|
|
||
|
# Additional values that can go in our config.php
|
||
|
$this->custom = new StdClass;
|
||
|
$this->default = new StdClass;
|
||
|
|
||
|
# TSM Server Stanza Name
|
||
|
$this->default->server['stanza'] = array(
|
||
|
'desc'=>'TSM Server Stanza Name',
|
||
|
'default'=>null);
|
||
|
|
||
|
$this->default->system['dsmadmc'] = array(
|
||
|
'desc'=>'Path to dsmadmc command.',
|
||
|
'default'=>'/opt/tivoli/tsm/client/ba/bin/dsmadmc');
|
||
|
$this->default->system['errorlog'] = array(
|
||
|
'desc'=>'Set errorlog filename',
|
||
|
'default'=>'/tmp/pta-tsm-errorlog.log');
|
||
|
$this->default->system['tapeage'] = array(
|
||
|
'desc'=>'Age of tapes to alert for rotation',
|
||
|
'default'=>180);
|
||
|
|
||
|
# TSM Parameters
|
||
|
$this->default->tsmparm['msgFormat'] = array(
|
||
|
'desc'=>'Format of TSM message codes.',
|
||
|
'default'=>'[A-Z]{3}[0-9]{4}[I|E|W|S]');
|
||
|
|
||
|
$this->default->tsmparm['queryStartMsg'] = array(
|
||
|
'desc'=>'TSM code depicting START of queries results.',
|
||
|
'default'=>'ANS8000I');
|
||
|
|
||
|
$this->default->tsmparm['queryEndMsg'] = array(
|
||
|
'desc'=>'TSM code depicting END of queries results.',
|
||
|
'default'=>'ANS8002I');
|
||
|
|
||
|
$this->default->tsmparm['loginFail'] = array(
|
||
|
'desc'=>'Known TSM "failed login" message codes.',
|
||
|
'default'=>array(
|
||
|
'ANS8023E', //
|
||
|
'ANS1017E', // TCP/IP connection rejected.
|
||
|
'ANS1217E', // Server name not found in System Options File
|
||
|
'ANS1355E', // Sessions disabled.
|
||
|
'ANS8034E' // Your administrator ID is not recognized by this server.
|
||
|
));
|
||
|
$this->default->tsmparm['loginFailIgnore'] = array(
|
||
|
'desc'=>'Known TSM "ignore" message codes during login.',
|
||
|
'default'=>array(
|
||
|
'ANS0110E', // LogMsg: Unable to open error log file '%s' for output.
|
||
|
'ANS8002I' // Highest return code was %s.
|
||
|
));
|
||
|
$this->default->tsmparm['ignoremsg'] = array(
|
||
|
'desc'=>'Known TSM "ignore" message codes.',
|
||
|
'default'=>array(
|
||
|
'ANS8001I', // Return code %s.
|
||
|
'ANS0102W' // Unable to open the message repository %s. The American English repository will be used instead.
|
||
|
));
|
||
|
$this->default->tsmparm['nodatamsg'] = array(
|
||
|
'desc'=>'Known TSM "select returned no data" message codes.',
|
||
|
'default'=>array(
|
||
|
'ANR2034E' // SELECT: No match found using this criteria.
|
||
|
));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Required ABSTRACT functions
|
||
|
*/
|
||
|
/**
|
||
|
* Connect and Bind to the Database
|
||
|
*
|
||
|
* @param method This enables to have multiple different types of connects, ie: read only, readwrite, etc
|
||
|
* @return resource|null Connection resource if successful, null if not.
|
||
|
*/
|
||
|
protected function connect($method,$debug=false) {
|
||
|
$method = $this->getMethod($method);
|
||
|
|
||
|
if (! $this->isLoggedIn($method))
|
||
|
system_message(array('title'=>'Not Logged In',
|
||
|
'body'=>sprintf('You are not logged into server %s',$this->getValue('server','name')),
|
||
|
'type'=>'warn'),'index.php');
|
||
|
|
||
|
if (! file_exists($this->getValue('system','dsmadmc'))) {
|
||
|
system_message(array('title'=>'Cant find DSMADMC',
|
||
|
'body'=>sprintf('Unable to find the dsmadmc at <b>%s</b>',$this->getValue('system','dsmadmc')),
|
||
|
'type'=>'error'));
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ($this->getValue('system','errorlog'))
|
||
|
$errorlog = sprintf('-errorlogname=%s',$this->getValue('system','errorlog'));
|
||
|
|
||
|
if (is_null($this->getValue('server','stanza')) || ! trim($this->getValue('server','stanza')))
|
||
|
$TSMcmd = sprintf('%s -id=%s -password=%s -displ=list %s',
|
||
|
$this->getValue('system','dsmadmc'),$this->getLogin($method),$this->getPassword($method),
|
||
|
isset($errorlog) ? $errorlog : '');
|
||
|
else
|
||
|
$TSMcmd = sprintf('%s -se=%s -id=%s -password=%s -displ=list %s',
|
||
|
$this->getValue('system','dsmadmc'),
|
||
|
$this->getValue('server','stanza'),$this->getLogin($method),$this->getPassword($method),
|
||
|
isset($errorlog) ? $errorlog : '');
|
||
|
|
||
|
return $TSMcmd;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Login to the database with the application user/password
|
||
|
*
|
||
|
* @param method This enables to have multiple different types of connects, ie: read only, readwrite, etc
|
||
|
* @return boolean true|false for successful login.
|
||
|
*/
|
||
|
public function login($user=null,$pass=null,$method=null) {
|
||
|
# Set our user and password.
|
||
|
$this->setLogin($user,$pass,$method);
|
||
|
|
||
|
# Test that it works.
|
||
|
$result = $this->query('SELECT platform,version,release,level,sublevel FROM status',$method);
|
||
|
|
||
|
if (! $result)
|
||
|
$this->logout($method);
|
||
|
else
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Perform a query to the Database
|
||
|
*
|
||
|
* @param string SQL query to perform
|
||
|
* @param string Index items according to this key
|
||
|
* @return array|null Results of query.
|
||
|
*/
|
||
|
public function query($query,$method,$index=null,$debug=false) {
|
||
|
$TSMcmd = sprintf('%s "%s"',$this->connect($method,$debug),$query);
|
||
|
$TSMcmdOutput = exec($TSMcmd,$OutputLines,$return);
|
||
|
|
||
|
if ($debug)
|
||
|
debug_dump(array('cmd'=>$TSMcmd,'TSMcmdOutput'=>$TSMcmdOutput,'return'=>$return));
|
||
|
|
||
|
# Parse the ouput for key:value pairs.
|
||
|
$outindex = 0;
|
||
|
$isQueryResult = 0;
|
||
|
$isKeyValue = 0;
|
||
|
$haveHelp = false;
|
||
|
$QueryResult = false;
|
||
|
$tsmCommands = array();
|
||
|
foreach ($OutputLines as $OutputLine ) {
|
||
|
$OutputLine = preg_replace('/\s+$/','',$OutputLine);
|
||
|
if ($debug)
|
||
|
debug_dump("($isQueryResult/$isKeyValue): WORKING line [$OutputLine]");
|
||
|
|
||
|
# See if we got a message number.
|
||
|
if (preg_match("/^(".$this->getValue('tsmparm','msgFormat').")\s+/",$OutputLine,$matches)) {
|
||
|
$msgnum = $matches[1];
|
||
|
|
||
|
if ($debug)
|
||
|
debug_dump("($isQueryResult/$isKeyValue): Got SYSTEM Msg [$OutputLine]");
|
||
|
|
||
|
# Filter through the output and check if we got our start message.
|
||
|
if (preg_match("/^".$this->getValue('tsmparm','queryStartMsg')."\s+/",$OutputLine)) {
|
||
|
if ($debug)
|
||
|
debug_dump("($isQueryResult/$isKeyValue): Got START Msg [$OutputLine]");
|
||
|
$isQueryResult = 1;
|
||
|
continue;
|
||
|
|
||
|
# Break out of loop when we get our end message.
|
||
|
} elseif (preg_match("/^".$this->getValue('tsmparm','queryEndMsg')."\s+/",$OutputLine)) {
|
||
|
if ($debug)
|
||
|
debug_dump("($isQueryResult/$isKeyValue): Got END Msg [$OutputLine]");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (in_array($msgnum,$this->getValue('tsmparm','nodatamsg')))
|
||
|
continue;
|
||
|
|
||
|
if (! in_array($msgnum,$this->getValue('tsmparm','ignoremsg')))
|
||
|
system_message(array('title'=>'TSM Message','body'=>$OutputLine));
|
||
|
}
|
||
|
|
||
|
# If we the line is a queryResult line
|
||
|
if ($isQueryResult) {
|
||
|
|
||
|
# See if we got a key:value pair, otherwise go to next line.
|
||
|
if (preg_match('/:/',$OutputLine) && ! (preg_match('/^help/',$query))) {
|
||
|
$OutputLine = preg_replace('/\s*:\s+/',':',$OutputLine);
|
||
|
list($key,$value) = explode(':',$OutputLine,2);
|
||
|
$isKeyValue = 1;
|
||
|
|
||
|
# Not key:value, so check if we need to increase the index.
|
||
|
} else {
|
||
|
|
||
|
# Is this a show slots command, so there is more info
|
||
|
if (preg_match('/^show slots/',$query)) {
|
||
|
|
||
|
if (preg_match('/^Slot /',$OutputLine)) {
|
||
|
|
||
|
foreach ((preg_split('/,\s*/',$OutputLine,-1)) as $slotkey => $val) {
|
||
|
|
||
|
if (preg_match('/^element number\s+/',$val)) {
|
||
|
$key = preg_replace('/^element number\s+/','',$val);
|
||
|
|
||
|
} elseif (preg_match('/^Slot\s+/',$val)) {
|
||
|
$slots['slot'] = preg_replace('/^Slot\s+/','',$val);
|
||
|
|
||
|
} elseif (preg_match('/^status\s+/',$val)) {
|
||
|
$slots['status'] = preg_replace('/^status\s+/','',$val);
|
||
|
|
||
|
} elseif (preg_match('/^barcode value </',$val)) {
|
||
|
$slots['barcodelabel'] = preg_replace('/^barcode value <(.*)>/',"$1",$val);
|
||
|
|
||
|
} elseif (preg_match('/^barcode\s+/',$val)) {
|
||
|
$slots['barcode'] = preg_replace('/^barcode /','',$val);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$QueryResult[$outindex]['SlotUsage'][$key] = $slots;
|
||
|
|
||
|
} elseif (preg_match('/busy.$/',$OutputLine)) {
|
||
|
system_message(array('title'=>'Library is Busy',
|
||
|
'body'=>sprintf('The library appears busy at the moment.<br />%s',$OutputLine),
|
||
|
'type'=>'info'),
|
||
|
sprintf('index.php',get_request('cmd','REQUEST') ? sprintf('cmd=%s',get_request('cmd','REQUEST')) : ''));
|
||
|
}
|
||
|
|
||
|
# Is this a help command, so there is more info
|
||
|
} elseif (preg_match('/^help$/',$query)) {
|
||
|
if (preg_match('/^\s*([0-9]+) - Commands /',$OutputLine)) {
|
||
|
$helpnum = preg_replace('/^\s*([0-9]+) - Commands .*/','$1',$OutputLine);
|
||
|
|
||
|
$tsmCommands = array_unique(array_merge($tsmCommands,$this->query("help $helpnum",null)));
|
||
|
}
|
||
|
|
||
|
} elseif (preg_match('/^help\s+[0-9]+/',$query)) {
|
||
|
if (! $OutputLine)
|
||
|
continue;
|
||
|
|
||
|
if (! $haveHelp && preg_match('/^\s*Command Name/',$OutputLine)) {
|
||
|
$haveHelp = true;
|
||
|
$helpCommands = array();
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ($haveHelp) {
|
||
|
# Filter out the beginning spaces.
|
||
|
$OutputLine = preg_replace('/^\s*/','',$OutputLine);
|
||
|
|
||
|
# Filter out the "(See Note)" messages.
|
||
|
$OutputLine = preg_replace('/\s\(.*\)/','',$OutputLine);
|
||
|
|
||
|
# Join the two columns together
|
||
|
$OutputLine = preg_replace('/\ \s+/','|',$OutputLine);
|
||
|
|
||
|
# We should now just have commands and they should be in uppercase.
|
||
|
if (preg_match('/[a-z0-9]/',$OutputLine))
|
||
|
continue;
|
||
|
|
||
|
#debug_dump("Im finally here with [$OutputLine].");
|
||
|
|
||
|
foreach (explode('|',$OutputLine) as $helpCMD)
|
||
|
array_push($helpCommands,$helpCMD);
|
||
|
}
|
||
|
|
||
|
} elseif (preg_match('/^help\s+[A-Z]+/',$query)) {
|
||
|
# Sometimes QueryResult gets data because of colons - we need to capture that.
|
||
|
if (isset($QueryResult) && is_array($QueryResult)) {
|
||
|
foreach ($QueryResult as $lineDetail)
|
||
|
foreach ($lineDetail as $key => $ldindex)
|
||
|
$helpText[] = $key.$ldindex;
|
||
|
$QueryResult = array();
|
||
|
}
|
||
|
|
||
|
$helpText[] = $OutputLine;
|
||
|
//debug_dump(array("Im finally here with [$OutputLine]."=>$QueryResult));
|
||
|
|
||
|
# If this is a blank line
|
||
|
} elseif (!$OutputLine) {
|
||
|
|
||
|
# Only increment index if the previous iteration was a key/value pair.
|
||
|
# Reset isKeyValue so we dont increase index for 2 non key:value lines in a row.
|
||
|
if ($isKeyValue) {
|
||
|
if (!preg_match('/^show/',$query))
|
||
|
$outindex++;
|
||
|
$isKeyValue = 0;
|
||
|
}
|
||
|
|
||
|
} // if
|
||
|
continue;
|
||
|
|
||
|
} // if
|
||
|
|
||
|
$key = preg_replace('/^\s+/','',$key);
|
||
|
$value = preg_replace('/^\s+/','',$value);
|
||
|
$QueryResult[$outindex][$key] = $value;
|
||
|
|
||
|
} // if
|
||
|
} // foreach
|
||
|
|
||
|
if (is_array($tsmCommands) && preg_match('/^help$/',$query)) {
|
||
|
asort($tsmCommands);
|
||
|
$QueryResult = $tsmCommands;
|
||
|
}
|
||
|
|
||
|
if (isset($helpCommands) && preg_match('/^help\s+[0-9]+/',$query))
|
||
|
$QueryResult = $helpCommands;
|
||
|
|
||
|
if (isset($helpText) && preg_match('/^help\s+[A-Z]+/',$query))
|
||
|
$QueryResult = $helpText;
|
||
|
|
||
|
if ($debug)
|
||
|
debug_dump($QueryResult,0);
|
||
|
|
||
|
if (! $isQueryResult && $debug)
|
||
|
Error(sprintf('The query <BR>%s<BR>didnt return anything [%s]',preg_replace('/-password=(.*)\ -/','-password=x -',$TSMcmd),serialize($OutputLines)));
|
||
|
|
||
|
if ($index && is_array($QueryResult)) {
|
||
|
foreach ($QueryResult as $result => $val) {
|
||
|
if (isset($val[$index]))
|
||
|
$IndexQueryResult[$val[$index]] = $QueryResult[$result];
|
||
|
}
|
||
|
|
||
|
return (isset($IndexQueryResult) ? $IndexQueryResult : false);
|
||
|
} elseif (is_array($QueryResult)) {
|
||
|
return $QueryResult;
|
||
|
}
|
||
|
return array();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the last error string
|
||
|
*/
|
||
|
protected function getErrorMessage() {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the last error number
|
||
|
*/
|
||
|
protected function getErrorNum() {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return if anonymous bind is allowed in the configuration
|
||
|
*/
|
||
|
public function isAnonBindAllowed() {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Query the database for particular attributes values.
|
||
|
*/
|
||
|
public function queryAttr($table,$attrs,$key,$where=null,$orderby=null) {
|
||
|
return array();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Register user to the application
|
||
|
*/
|
||
|
public function register($user,$pass,$other=array()) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Query TSM and get Database information
|
||
|
*/
|
||
|
function QueryDBDetail() {
|
||
|
$query = $this->query('select * from DB',null);
|
||
|
$this->CACHE['db'] = $query[0];
|
||
|
$this->CACHE['db']['dbvols'] = $this->query('select * from DBVOLUMES',null);
|
||
|
$this->CACHE['cache']['db'] = time();
|
||
|
$this->CACHE['cache']['log'] = time();
|
||
|
|
||
|
$query = $this->query('select * from LOG',null);
|
||
|
$this->CACHE['log'] = $query[0];
|
||
|
$this->CACHE['log']['logvols'] = $this->query('select * from LOGVOLUMES',null);
|
||
|
|
||
|
$_SESSION['tsm'][$this->index] = $this->CACHE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the DB information.
|
||
|
* @param string attribute
|
||
|
* @return string value for attribute
|
||
|
*/
|
||
|
function GetDBDetail($attribute) {
|
||
|
if (! isset($this->CACHE['db'][$attribute]))
|
||
|
$this->QueryDBDetail();
|
||
|
|
||
|
if (! isset($this->CACHE['db'][$attribute]))
|
||
|
Error(sprintf(_('ERROR: A request to get DB attribute "%" didnt return a value'),$attribute));
|
||
|
|
||
|
return $this->CACHE['db'][$attribute];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the LOG information.
|
||
|
* @param string attribute
|
||
|
* @return string value for attribute
|
||
|
*/
|
||
|
function GetLogDetail($attribute) {
|
||
|
if (! isset($this->CACHE['log'][$attribute]))
|
||
|
$this->QueryDBDetail();
|
||
|
|
||
|
if (! isset($this->CACHE['log'][$attribute]))
|
||
|
Error(sprintf(_('ERROR: A request to get LOG attribute "%" didnt return a value'),$attribute));
|
||
|
|
||
|
return $this->CACHE['log'][$attribute];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the VOLUMES information
|
||
|
* @return array
|
||
|
*/
|
||
|
function GetVolumes() {
|
||
|
if (isset($this->CACHE['volumes']))
|
||
|
return $this->CACHE['volumes'];
|
||
|
|
||
|
$this->CACHE['volumes'] = $this->query('select * from VOLUMES',null,'VOLUME_NAME');
|
||
|
$this->CACHE['cache']['volumes'] = time();
|
||
|
$_SESSION['tsm'][$this->index] = $this->CACHE;
|
||
|
return $this->CACHE['volumes'];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the LIBVOLUMES information
|
||
|
* @return array
|
||
|
*/
|
||
|
function GetLibVolumes() {
|
||
|
if (isset($this->CACHE['libvols']))
|
||
|
return $this->CACHE['libvols'];
|
||
|
|
||
|
$this->CACHE['libvols'] = $this->query('select * from LIBVOLUMES',null,'HOME_ELEMENT');
|
||
|
$this->CACHE['cache']['libvols'] = time();
|
||
|
$_SESSION['tsm'][$this->index] = $this->CACHE;
|
||
|
return $this->CACHE['libvols'];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the DB Backup Volumes
|
||
|
* @return array
|
||
|
*/
|
||
|
function GetDBBackupInfo() {
|
||
|
if (isset($this->CACHE['dbbackup']))
|
||
|
return $this->CACHE['dbbackup'];
|
||
|
|
||
|
$this->CACHE['dbbackup']['vols'] = $this->query("select * from VOLHISTORY where TYPE in ('BACKUPFULL','BACKUPINCR','DBSNAPSHOT') order by BACKUP_SERIES,BACKUP_OPERATION,VOLUME_SEQ",
|
||
|
null,'VOLUME_NAME');
|
||
|
|
||
|
# Now check that a backup series is valid - since it should be in order.
|
||
|
$lastSeries = -1;
|
||
|
$backupfirst = '';
|
||
|
$backuplast = '';
|
||
|
$backupcount = 0;
|
||
|
if (is_array($this->CACHE['dbbackup']['vols'])) {
|
||
|
foreach ($this->CACHE['dbbackup']['vols'] as $volume => $voldetails) {
|
||
|
if ($lastSeries != $voldetails['BACKUP_SERIES']) {
|
||
|
$lastSeries = $voldetails['BACKUP_SERIES'];
|
||
|
$lastOperation = -1;
|
||
|
$lastSeq = 0;
|
||
|
|
||
|
if (! $backupfirst | $voldetails['DATE_TIME'] < $backupfirst)
|
||
|
$backupfirst = $voldetails['DATE_TIME'];
|
||
|
if (! $backuplast | $voldetails['DATE_TIME'] > $backuplast)
|
||
|
$backuplast = $voldetails['DATE_TIME'];
|
||
|
$backupcount++;
|
||
|
}
|
||
|
|
||
|
# No point trying this series if it is invalid.
|
||
|
if (isset($status[$voldetails['BACKUP_SERIES']]['status']) &&
|
||
|
($status[$voldetails['BACKUP_SERIES']]['status'] == 'InValid'))
|
||
|
|
||
|
continue;
|
||
|
|
||
|
$this->CACHE['dbbackup']['vols'][$volume]['STATUS'] = 'Valid';
|
||
|
|
||
|
if (($voldetails['BACKUP_OPERATION'] == $lastOperation) || ($voldetails['BACKUP_OPERATION']-1 == $lastOperation)) {
|
||
|
$status[$voldetails['BACKUP_SERIES']]['status'] = 'Valid';
|
||
|
$lastOperation = $voldetails['BACKUP_OPERATION'];
|
||
|
|
||
|
} else {
|
||
|
$status[$voldetails['BACKUP_SERIES']]['status'] = 'InValid';
|
||
|
$status[$voldetails['BACKUP_SERIES']]['statusreason'] = sprintf(_('Missing SERIES volumes, expected [%s], found [%s].'),
|
||
|
$lastOperation+1,$voldetails['BACKUP_OPERATION']);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (($voldetails['VOLUME_SEQ'] == $lastSeq) || $voldetails['VOLUME_SEQ']-1 == $lastSeq) {
|
||
|
$status[$voldetails['BACKUP_SERIES']]['status'] = 'Valid';
|
||
|
$lastSeq = $voldetails['VOLUME_SEQ'];
|
||
|
|
||
|
} else {
|
||
|
$status[$voldetails['BACKUP_SERIES']]['status'] = 'InValid';
|
||
|
$status[$voldetails['BACKUP_SERIES']]['statusreason'] = sprintf(_('Missing SERIES volumes, expected [%s], found [%s].'),$lastSeq+1,$voldetails['VOLUME_SEQ']);
|
||
|
}
|
||
|
|
||
|
$lastSeq = $voldetails['VOLUME_SEQ'];
|
||
|
}
|
||
|
|
||
|
# Now we know which series are invalid, mark all the volumes.
|
||
|
foreach ($this->CACHE['dbbackup']['vols'] as $volume => $voldetails) {
|
||
|
$this->CACHE['dbbackup']['vols'][$volume]['STATUS'] = $status[$voldetails['BACKUP_SERIES']]['status'];
|
||
|
if (isset($status[$voldetails['BACKUP_SERIES']]['statusreason']))
|
||
|
$this->CACHE['dbbackup']['vols'][$volume]['STATUSREASON'] = $status[$voldetails['BACKUP_SERIES']]['statusreason'];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Grab backup information
|
||
|
$history = $this->query('select DATE_TIME,MSGNO,MESSAGE from ACTLOG where MSGNO in (4550,4551) order by DATE_TIME',null);
|
||
|
|
||
|
if (! isset($history[0]['ANR2034E SELECT']))
|
||
|
foreach ($history as $index => $historydetail) {
|
||
|
$this->CACHE['dbbackup']['history'][$index]['date'] = $historydetail['DATE_TIME'];
|
||
|
|
||
|
switch ($historydetail['MSGNO']) {
|
||
|
case 4550:
|
||
|
if (preg_match('/([0-9]+) pages copied./',$historydetail['MESSAGE'],$matchall)) {
|
||
|
$this->CACHE['dbbackup']['history'][$index]['size'] = $matchall[1];
|
||
|
$this->CACHE['dbbackup']['history'][$index]['type'] = 'FULL';
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 4551:
|
||
|
if (preg_match('/([0-9]+) pages copied./',$historydetail['MESSAGE'],$matchall)) {
|
||
|
$this->CACHE['dbbackup']['history'][$index]['size'] = $matchall[1];
|
||
|
$this->CACHE['dbbackup']['history'][$index]['type'] = 'INCR';
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
printf('Message %s not catered for [%s]...',$historydetail['MSGNO'],$historydetail['MESSAGE']);
|
||
|
die();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Get DBBackup Trigger information.
|
||
|
$select = $this->query('select * from DBBACKUPTRIGGER',null);
|
||
|
$result = array_shift($select);
|
||
|
|
||
|
if (isset($result['ANR2034E SELECT']))
|
||
|
$this->CACHE['dbbackup']['trigger'] = false;
|
||
|
else
|
||
|
$this->CACHE['dbbackup']['trigger'] = $result;
|
||
|
|
||
|
$this->CACHE['dbbackup']['first'] = $backupfirst;
|
||
|
$this->CACHE['dbbackup']['last'] = $backuplast;
|
||
|
$this->CACHE['dbbackup']['count'] = $backupcount;
|
||
|
|
||
|
$this->CACHE['cache']['dbbackup'] = time();
|
||
|
$_SESSION['tsm'][$this->index] = $this->CACHE;
|
||
|
return $this->CACHE['dbbackup'];
|
||
|
}
|
||
|
|
||
|
function GetDBBackupDetail($detail) {
|
||
|
if (isset($this->CACHE['dbbackup'][$detail]))
|
||
|
return $this->CACHE['dbbackup'][$detail];
|
||
|
|
||
|
$this->GetDBBackupInfo();
|
||
|
|
||
|
if (isset($this->CACHE['dbbackup'][$detail]))
|
||
|
return $this->CACHE['dbbackup'][$detail];
|
||
|
else
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the Status Information
|
||
|
* @return array
|
||
|
*/
|
||
|
function GetStatus() {
|
||
|
if (isset($this->CACHE['status']))
|
||
|
return $this->CACHE['status'];
|
||
|
|
||
|
$select = $this->query('select * from STATUS',null);
|
||
|
$this->CACHE['status'] = array_shift($select);
|
||
|
|
||
|
$this->CACHE['cache']['status'] = time();
|
||
|
$_SESSION['tsm'][$this->index] = $this->CACHE;
|
||
|
return $this->CACHE['status'];
|
||
|
}
|
||
|
|
||
|
function GetStatusDetail($detail) {
|
||
|
if (isset($this->CACHE['status'][$detail]))
|
||
|
return $this->CACHE['status'][$detail];
|
||
|
|
||
|
$this->GetStatus();
|
||
|
|
||
|
if (isset($this->CACHE['status'][$detail]))
|
||
|
return $this->CACHE['status'][$detail];
|
||
|
else
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get TSM event information
|
||
|
* @param string Start date for report
|
||
|
* @param string End date for report
|
||
|
* @param string order by key.
|
||
|
* @return array Query result
|
||
|
*/
|
||
|
function GetEvents($reportStart='',$reportEnd='',$orderby='SCHEDULED_START') {
|
||
|
if (isset($this->CACHE['events']) && $reportStart == $this->CACHE['events']['start'] &&
|
||
|
$reportEnd == $this->CACHE['events']['end'] && $orderby == $this->CACHE['events']['orderby'])
|
||
|
|
||
|
return $this->CACHE['events'];
|
||
|
|
||
|
$TSMQuery = 'select * from EVENTS where DOMAIN_NAME is not null';
|
||
|
|
||
|
if (($reportStart) && ($reportEnd))
|
||
|
$TSMQuery .= sprintf(" and (SCHEDULED_START between '%s' and '%s')",$reportStart,$reportEnd);
|
||
|
else if ($reportStart)
|
||
|
$TSMQuery .= sprintf(" and SCHEDULED_START \> '%s'",$reportStart);
|
||
|
else if ($reportEnd)
|
||
|
$TSMQuery .= sprintf(" and SCHEDULED_START <= '%s'",$reportEnd);
|
||
|
|
||
|
$TSMQuery .= sprintf(' order by %s',$orderby);
|
||
|
|
||
|
$result = $this->query($TSMQuery,null);
|
||
|
|
||
|
if (isset($result[0]['ANR2034E SELECT'])) {
|
||
|
$this->CACHE['events'] = false;
|
||
|
|
||
|
} else {
|
||
|
$this->CACHE['events']['detail'] = $result;
|
||
|
$this->CACHE['events']['start'] = $reportStart;
|
||
|
$this->CACHE['events']['end'] = $reportEnd;
|
||
|
$this->CACHE['events']['orderby'] = $orderby;
|
||
|
}
|
||
|
|
||
|
$this->CACHE['cache']['events'] = time();
|
||
|
$_SESSION['tsm'][$this->index] = $this->CACHE;
|
||
|
return $this->CACHE['events'];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get TSM Activity Log Client backup information.
|
||
|
* @param string Start date for report
|
||
|
* @param string End date for report
|
||
|
* @return array Query result
|
||
|
*/
|
||
|
function GetActlogBackupSummary($reportStart='',$reportEnd='') {
|
||
|
if (isset($this->CACHE['actlogbackup']) && $reportStart == $this->CACHE['actlogbackup']['start'] &&
|
||
|
$reportEnd == $this->CACHE['actlogbackup']['end'])
|
||
|
|
||
|
return $this->CACHE['actlogbackup'];
|
||
|
|
||
|
$tsmMSG['4952'] = 'Inspected';
|
||
|
$tsmMSG['4954'] = 'Backup';
|
||
|
$tsmMSG['4958'] = 'Update';
|
||
|
$tsmMSG['4957'] = 'Delete';
|
||
|
$tsmMSG['4959'] = 'Failed';
|
||
|
$tsmMSG['4960'] = 'Rebound';
|
||
|
$tsmMSG['4961'] = 'Transfer';
|
||
|
$tsmMSG['4964'] = 'ProcTime';
|
||
|
$tsmMSG['4967'] = 'AggRate';
|
||
|
$tsmMSG['4968'] = 'Compress';
|
||
|
$tsmMSG['4970'] = 'Expire';
|
||
|
|
||
|
$TSMQuery = sprintf('select MSGNO,NODENAME,SESSID,MESSAGE,SCHEDNAME,DOMAINNAME from ACTLOG where MSGNO in (%s)',
|
||
|
implode(',',array_keys($tsmMSG)));
|
||
|
|
||
|
if (($reportStart) && ($reportEnd))
|
||
|
$TSMQuery .= sprintf(" and (DATE_TIME between '%s' and '%s')",$reportStart,$reportEnd);
|
||
|
else if ($reportStart)
|
||
|
$TSMQuery .= sprintf(" and DATE_TIME \> '%s'",$reportStart);
|
||
|
else if ($reportEnd)
|
||
|
$TSMQuery .= sprintf(" and DATE_TIME <= '%s'",$reportEnd);
|
||
|
|
||
|
$TSMQuery .= ' order by sessid';
|
||
|
|
||
|
foreach ($this->query($TSMQuery,null) as $tsmBackup => $tsmSession) {
|
||
|
# TSM on AIX adds a "SESSION" at the end of each line - maybe others do as well.
|
||
|
if (isset($tsmSession['MESSAGE']))
|
||
|
$tsmSession['MESSAGE'] = preg_replace('/\(SESSION:.*\)/','',$tsmSession['MESSAGE']);
|
||
|
|
||
|
$tsmBackupSummary['detail'][$tsmSession['NODENAME']][$tsmSession['SESSID']][$tsmMSG[$tsmSession['MSGNO']]] = preg_replace('/^.*:\s*/U','',$tsmSession['MESSAGE']);
|
||
|
}
|
||
|
|
||
|
$tsmBackupSummary['start'] = $reportStart;
|
||
|
$tsmBackupSummary['end'] = $reportEnd;
|
||
|
|
||
|
$this->CACHE['actlogbackup'] = $tsmBackupSummary;
|
||
|
$this->CACHE['cache']['actlogbackup'] = time();
|
||
|
$_SESSION['tsm'][$this->index] = $this->CACHE;
|
||
|
return $this->CACHE['actlogbackup'];
|
||
|
}
|
||
|
|
||
|
function GetVolLocation($vol) {
|
||
|
$volumes = $this->GetVolumes();
|
||
|
|
||
|
if ($this->GetLibVolumes())
|
||
|
foreach ($this->GetLibVolumes() as $slot => $details) {
|
||
|
if ($details['VOLUME_NAME'] == $vol)
|
||
|
return sprintf('**%s %s**',_('LIBRARY'),$details['LIBRARY_NAME']);
|
||
|
}
|
||
|
|
||
|
if (isset($volumes[$vol]))
|
||
|
return $volumes[$vol]['LOCATION'];
|
||
|
|
||
|
# If we get here, we dont know where the volume is.
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
?>
|