/* $Id$ */
/*
* FedStage DRMAA for PBS Pro
* Copyright (C) 2006-2007 FedStage Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* @file pbs_drmaa/util.c
* PBS DRMAA utilities.
*/
#ifdef HAVE_CONFIG_H
# include
#endif
#include
#include
#include
#include
#include
#include
#include
#ifndef lint
static char rcsid[]
# ifdef __GNUC__
__attribute__ ((unused))
# endif
= "$Id$";
#endif
void
pbsdrmaa_dump_attrl( const struct attrl *attribute_list, const char *prefix )
{
const struct attrl *i;
if( prefix == NULL )
prefix = "";
for( i = attribute_list; i != NULL; i = i->next )
fsd_log_debug(( "\n %s %s%s%s=%s",
prefix, i->name,
i->resource ? "." : "", i->resource ? i->resource : "",
i->value
));
}
void
pbsdrmaa_free_attrl( struct attrl *attr )
{
while( attr != NULL )
{
struct attrl *p = attr;
attr = attr->next;
fsd_free( p->name );
fsd_free( p->value );
fsd_free( p->resource );
fsd_free( p );
}
}
void
pbsdrmaa_exc_raise_pbs( const char *function )
{
int _pbs_errno;
int fsd_errno;
const char *message = NULL;
_pbs_errno = pbs_errno;
#ifndef PBS_PROFESSIONAL_NO_LOG
message = pbse_to_txt( pbs_errno );
#else
message = "pbs error";
#endif
fsd_errno = pbsdrmaa_map_pbs_errno( _pbs_errno );
fsd_log_error((
"call to %s returned with error %d:%s mapped to %d:%s",
function,
_pbs_errno, message,
fsd_errno, fsd_strerror(fsd_errno)
));
fsd_exc_raise_fmt( fsd_errno, "%s: %s", function, message );
}
/** Maps PBS error code into DMRAA code. */
int
pbsdrmaa_map_pbs_errno( int _pbs_errno )
{
fsd_log_enter(( "(pbs_errno=%d)", _pbs_errno ));
switch( _pbs_errno )
{
case PBSE_NONE: /* no error */
return FSD_ERRNO_SUCCESS;
case PBSE_UNKJOBID: /* Unknown Job Identifier */
return FSD_DRMAA_ERRNO_INVALID_JOB;
case PBSE_NOATTR: /* Undefined Attribute */
case PBSE_ATTRRO: /* attempt to set READ ONLY attribute */
case PBSE_IVALREQ: /* Invalid request */
case PBSE_UNKREQ: /* Unknown batch request */
return FSD_ERRNO_INTERNAL_ERROR;
case PBSE_PERM: /* No permission */
case PBSE_BADHOST: /* access from host not allowed */
return FSD_ERRNO_AUTHZ_FAILURE;
case PBSE_JOBEXIST: /* job already exists */
case PBSE_SVRDOWN: /* req rejected -server shutting down */
case PBSE_EXECTHERE: /* cannot execute there */
case PBSE_NOSUP: /* Feature/function not supported */
case PBSE_EXCQRESC: /* Job exceeds Queue resource limits */
case PBSE_QUENODFLT: /* No Default Queue Defined */
case PBSE_NOTSNODE: /* no time-shared nodes */
return FSD_ERRNO_DENIED_BY_DRM;
case PBSE_SYSTEM: /* system error occurred */
case PBSE_INTERNAL: /* internal server error occurred */
case PBSE_REGROUTE: /* parent job of dependent in rte que */
case PBSE_UNKSIG: /* unknown signal name */
return FSD_ERRNO_INTERNAL_ERROR;
case PBSE_BADATVAL: /* bad attribute value */
case PBSE_BADATLST: /* Bad attribute list structure */
case PBSE_BADUSER: /* Bad user - no password entry */
case PBSE_BADGRP: /* Bad Group specified */
case PBSE_BADACCT: /* Bad Account attribute value */
case PBSE_UNKQUE: /* Unknown queue name */
case PBSE_UNKRESC: /* Unknown resource */
case PBSE_UNKNODEATR: /* node-attribute not recognized */
case PBSE_BADNDATVAL: /* Bad node-attribute value */
case PBSE_BADDEPEND: /* Invalid dependency */
case PBSE_DUPLIST: /* Duplicate entry in List */
return FSD_ERRNO_INVALID_VALUE;
case PBSE_MODATRRUN: /* Cannot modify attrib in run state */
case PBSE_BADSTATE: /* request invalid for job state */
case PBSE_BADCRED: /* Invalid Credential in request */
case PBSE_EXPIRED: /* Expired Credential in request */
case PBSE_QUNOENB: /* Queue not enabled */
return FSD_ERRNO_INTERNAL_ERROR;
case PBSE_QACESS: /* No access permission for queue */
return FSD_ERRNO_AUTHZ_FAILURE;
case PBSE_HOPCOUNT: /* Max hop count exceeded */
case PBSE_QUEEXIST: /* Queue already exists */
case PBSE_ATTRTYPE: /* incompatable queue attribute type */
return FSD_ERRNO_INTERNAL_ERROR;
# ifdef PBSE_QUEBUSY
case PBSE_QUEBUSY: /* Queue Busy (not empty) */
# endif
case PBSE_MAXQUED: /* Max number of jobs in queue */
case PBSE_NOCONNECTS: /* No free connections */
case PBSE_TOOMANY: /* Too many submit retries */
case PBSE_RESCUNAV: /* Resources temporarily unavailable */
return FSD_ERRNO_TRY_LATER;
case 111:
case PBSE_PROTOCOL: /* Protocol (ASN.1) error */
case PBSE_DISPROTO: /* Bad DIS based Request Protocol */
return FSD_ERRNO_DRM_COMMUNICATION_FAILURE;
#if 0
case PBSE_QUENBIG: /* Queue name too long */
case PBSE_QUENOEN: /* Cannot enable queue,needs add def */
case PBSE_NOSERVER: /* No server to connect to */
case PBSE_NORERUN: /* Job Not Rerunnable */
case PBSE_ROUTEREJ: /* Route rejected by all destinations */
case PBSE_ROUTEEXPD: /* Time in Route Queue Expired */
case PBSE_MOMREJECT: /* Request to MOM failed */
case PBSE_BADSCRIPT: /* (qsub) cannot access script file */
case PBSE_STAGEIN: /* Stage In of files failed */
case PBSE_CKPBSY: /* Checkpoint Busy, may be retries */
case PBSE_EXLIMIT: /* Limit exceeds allowable */
case PBSE_ALRDYEXIT: /* Job already in exit state */
case PBSE_NOCOPYFILE: /* Job files not copied */
case PBSE_CLEANEDOUT: /* unknown job id after clean init */
case PBSE_NOSYNCMSTR: /* No Master in Sync Set */
case PBSE_SISREJECT: /* sister rejected */
case PBSE_SISCOMM: /* sister could not communicate */
case PBSE_CKPSHORT: /* not all tasks could checkpoint */
case PBSE_UNKNODE: /* Named node is not in the list */
case PBSE_NONODES: /* Server has no node list */
case PBSE_NODENBIG: /* Node name is too big */
case PBSE_NODEEXIST: /* Node name already exists */
case PBSE_MUTUALEX: /* State values are mutually exclusive */
case PBSE_GMODERR: /* Error(s) during global modification of nodes */
case PBSE_NORELYMOM: /* could not contact Mom */
return FSD_ERRNO_INTERNAL_ERROR;
#endif
default:
return FSD_ERRNO_INTERNAL_ERROR;
}
}
char *
pbsdrmaa_write_tmpfile( const char *content, size_t len )
{
static const char *tmpfile_template = "/tmp/pbs_drmaa.XXXXXX";
char *volatile name = NULL;
volatile int fd = -1;
fsd_log_enter(( "" ));
TRY
{
name = fsd_strdup( tmpfile_template );
fd = mkstemp( name );
if( fd < 0 )
fsd_exc_raise_sys(0);
while( len > 0 )
{
size_t written = write( fd, content, len );
if( written != (size_t)-1 )
{
content += written;
len -= written;
}
else
fsd_exc_raise_sys(0);
}
}
EXCEPT_DEFAULT
{ fsd_free( name ); }
FINALLY
{
if( fd >= 0 )
{
if( close( fd ) )
fsd_exc_raise_sys(0);
}
}
END_TRY
fsd_log_return(( "=%s", name ));
return name;
}
ssize_t fsd_getline(char * line,ssize_t size, int fd)
{
char buf;
char * ptr = NULL;
ssize_t n = 0, rc;
ptr = line;
for(n = 1; n< size; n++)
{
if( (rc = read(fd,&buf,1 )) == 1) {
*ptr++ = buf;
if(buf == '\n')
{
break;
}
}
else if (rc == 0) {
if (n == 1)
return 0;
else
break;
}
else
return -1;
}
return n;
}
ssize_t fsd_getline_buffered(char * line,char * buf, ssize_t size, int fd, int * idx, int * end_idx, int * line_idx)
{
int i = -1;
int rc = -1;
memset(line,0,size);
start:
/* idx - start of data to parse (in buffer)
end_idx - end of data read from log (in buffer)
line_idx - place to write data in output line */
if(*idx < *end_idx)
{
/* take line from buffer */
for(i = *idx; i<= *end_idx;i++)
{
if(buf[i] == '\n')
{
int tmp = i - *idx;
strncpy(line + *line_idx,buf + *idx,tmp);
*idx = i + 1;
tmp+= *line_idx;
*line_idx = 0;
return tmp;
}
}
/* there was no '\n' so next part of log needs to be read. save lines beginning */
if(*line_idx + i - *idx > size )
fsd_exc_raise_fmt(FSD_ERRNO_INTERNAL_ERROR,"Line longer than %d unsupported",size);
strncpy(line + *line_idx,buf + *idx,i - *idx);
*line_idx += i - *idx;
*idx = 0;
*end_idx = 0;
goto start;
}
else
{
/* read log */
if((rc = read(fd,buf,size)) > 0)
{
*end_idx = rc - 1;
*idx = 0;
goto start;
}
else if (rc == 0)
return 0;
else
return -1;
}
}