Logo Search packages:      
Sourcecode: maxdb-7.5.00 version File versions

ven32.c

Go to the documentation of this file.
/*!
  @file           ven32.c
  @author         JoergM
  @brief          RunTime: Communication Functions for Local Access
  @see            

\if EMIT_LICENCE

    ========== licence begin  GPL
    Copyright (c) 2001-2005 SAP AG

    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 2
    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, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end



\endif
*/

#define MOD__ "ven32.c:"

#include "gen00.h"
#include "vsp001c.h"
#include "gen32.h"
#include "hen40.h"
#include "gen41.h"
/*
 * ===========================================================================
 */

#undef MF__
#define MF__ MOD__"sql32_open_kernel_fifo"
int sql32_open_kernel_fifo ( 
char           *dbname ,
int                  *fdp ,
uid_t          *uidp ,
tsp00_ErrTextc  pErrText )
{
    int         rc ;
    struct stat statbuf ;
    tsp00_Pathc file ;

    DBG1 (( MF__,"sql32_kernel: dbname '%s' \n", dbname ));

    sql41_get_request_fifo_name ( (char *)file , (char *)dbname );
    DBG1 (( MF__,"sql32_kernel: fifo '%s' \n", file ));

    /*
     *  Check, if file is a fifo.
     */
    rc = RTE_save_stat ( (const char *)file , &statbuf );
    if ( rc == -1 )
    {
          if ( errno == ENOENT )
          {
              DBG1 (( MF__,"sql32_kernel: cannot stat '%s': %s \n", file , sqlerrs() ));
              en42FillErrText(pErrText, "database not running: no request pipe");
              return ( SP1CE_START_REQUIRED );
          }
          else
          {
              DBG1 (( MF__, "sql32_kernel: cannot stat '%s': %s \n",
                                        file , sqlerrs() ));
              en42FillErrText(pErrText, "database not accesssible: stat on pipe (%d:%s)", errno, sqlerrs());
              return ( SP1CE_NOTOK );
          }
    }
    if ( ! S_ISFIFO(statbuf.st_mode) )
    {
          DBG1 (( MF__, "sql32_kernel: not a fifo '%s' \n", sqlerrs() ));
          en42FillErrText(pErrText, "database not accesssible: pipe is no pipe (%d)", (int)statbuf.st_mode);
          return ( SP1CE_NOTOK );
    }
    DBG1 (( MF__,"sql32_kernel: fifo uid %ld \n", (long) statbuf.st_uid ));
    *uidp = statbuf.st_uid ;

    /*
     *  Test first, if a REQUESTOR is reading on the fifo.
     */
    rc = RTE_save_open ( (const char *)file , O_WRONLY | O_NONBLOCK );
    if ( rc == -1 )
    {
          if ( errno == ENOENT )
          {
              DBG1 (( MF__,"sql32_kernel: cannot open '%s': %s \n", file , sqlerrs() ));
            en42FillErrText(pErrText, "database not accesssible: pipe does not exist" );
              return ( SP1CE_START_REQUIRED );
        }
        else
        {
              DBG1 (( MF__, "sql32_kernel: cannot open '%s': %s \n",
                                        file , sqlerrs() ));
            en42FillErrText(pErrText, "database not accesssible: pipe open (%d:%s)", errno, sqlerrs() );
              return ( SP1CE_NOTOK );
          }
    }
    else
    {
        RTE_save_close ( rc );
    }

    /*
     *  This open would block, if the REQUESTOR did just close the fifo.
     */
    *fdp = RTE_save_open ( (const char *)file , O_WRONLY );
    if ( *fdp == -1 )
    {
          if ( errno == ENOENT )
          {
              DBG1 (( MF__,"sql32_kernel: cannot open '%s': %s \n", file , sqlerrs() ));
            en42FillErrText( pErrText,
                             "database not accesssible: write pipe does not exist" );
              return ( SP1CE_START_REQUIRED );
          }
          else
          {
              DBG1 (( MF__, "sql32_kernel: cannot open '%s': %s \n",
                                        file , sqlerrs() ));
            en42FillErrText( pErrText, 
                             "database not accesssible: write pipe open(%d:%s)",
                             errno,
                             sqlerrs() );
              return ( SP1CE_NOTOK );
          }
    }
    DBG1 (( MF__,"sql32_kernel: fd %d \n", *fdp ));

    DBG1 (( MF__,"sql32_kernel: returning %d \n", SP1CE_OK ));
    return ( SP1CE_OK );
}

/*
 * ===========================================================================
 */
#undef MF__
#define MF__ MOD__"sql32_open_reply_fifo"
int sql32_open_reply_fifo ( 
char              *dbname ,
pid_t             pid ,
tsp00_Int4        ref ,
char              *file ,
int               *fdp ,
tsp00_ErrTextc  pErrText )
{
    int                       rc ;

    DBG1 (( MF__,"sql32_reply: dbname '%s' pid %ld ref %d \n",
                      dbname , (long) pid , ref ));

    sql41_get_reply_fifo_name ( file , dbname , pid , ref );
    DBG1 (( MF__,"sql32_reply: fifo '%s' \n", file ));

    rc = sql41_create_fifo ( file , 0666 );
    if ( rc == -1 )
    {
            en42FillErrText( pErrText, 
                         "Cannot create reply fifo (%d:%s)",
                         errno,
                         sqlerrs() );
            DBG1 (( MF__, "sql32_reply: %s '%s' \n", *errm , file ));
            return ( SP1CE_NOTOK );
    }

    /*
     *  This open does not block.
     */
    *fdp = RTE_save_open ( file , O_RDWR , 0 );
    if ( *fdp == -1 )
    {
            en42FillErrText( pErrText, 
                         "Cannot open reply fifo (%d:%s)",
                         errno,
                         sqlerrs() );
            DBG1 (( MF__, "sql32_reply: %s '%s': %s \n",
                              *errm , file , sqlerrs() ));
            RTE_save_unlink ( file );
            return ( SP1CE_NOTOK );
    }
    DBG1 (( MF__,"sql32_reply: fd %d \n", *fdp ));

    DBG1 (( MF__,"sql32_reply: returning %d \n", SP1CE_OK ));
    return ( SP1CE_OK );
}

/*
 * ======================================================================
 */

#undef MF__
#define MF__ MOD__"sql32_attach_comseg"
int   sql32_attach_comseg ( 
connection_info         *cip )
{
    int                       rc ;
    int                       idx ;
    long                siz ;
    long                off ;
    ten_com_long   *offp ;
    char                *ptr ;
    comseg_header       *comseg ;
    struct shmid_ds           mbuf ;

    /*
     *  Check the received packet_cnt.
     */
    if ( (cip->ci_packet_cnt < 1) || (cip->ci_packet_cnt > MAX_SQL_PACKETS) )
    {
            DBG1 (( MF__, "ill packet count %d \n", cip->ci_packet_cnt ));
            return ( SP1CE_NOTOK );
    }

    if ( cip->ci_big_size > 0 )
    {
            siz = cip->ci_big_size ;
    }
    else
    {
            /*
             *  Stat the shared memory segment to determine its size.
             */
            rc = shmctl ( cip->ci_shmid , IPC_STAT , &mbuf );
            if ( rc == -1 )
            {
                  DBG1 (( MF__, "sql32_att_comseg: shmctl (stat %d) error: %s\n",
                                                cip->ci_shmid , sqlerrs() ));
                  return ( SP1CE_NOTOK );
            }
            siz = (long) mbuf.shm_segsz ;
            DBG1 (( MF__,"sql32_att_comseg: shmid %d size %ld \n", 
                              cip->ci_shmid , siz ));
    }

    /*
     *  Check the received big_offset for range and alignment.
     */
    if (    (cip->ci_big_offset < 0)
         || (cip->ci_big_offset > siz - sizeof(comseg_header))
       || (cip->ci_big_offset & (sizeof(comseg_header*)-1)) )
    {
            DBG1 (( MF__,"sql32_att_comseg: ill comseg offset %ld siz %ld \n",
                                        cip->ci_big_offset , siz ));
            return ( SP1CE_NOTOK );
    }

    if ( cip->ci_big_comseg )
    {
            ptr = (char*) cip->ci_big_comseg ;
    }
    else
    {
            /*
             *  Here, cip->ci_big_offset is in range.
             *  Now, we have to attach the shared memory
             *  before we can do further checks.
             *  Except of FIXED_COMSEG, ci_loccomseg is NULL,
             *  thus allowing to attach at a system-selected address.
             */
            ptr = sql41_attach_shm ( cip->ci_shmid , (char*) cip->ci_loccomseg );
            if ( ! ptr )
            {
                  return ( SP1CE_NOTOK );
            }
            DBG1 (( MF__,"sql32_att_comseg: attached shmid %5d at 0x%08lx \n",
                              cip->ci_shmid , (long) ptr ));
    }

    if (    cip->ci_big_offset
       && (((big_comseg_header*)ptr)->bc_size != siz) )
      {
            DBG1 (( MF__, "sql32_att_comseg: %s: shmstat %ld bc_size %ld \n",
                        "inconsistent big comseg size" ,
                        siz , ((big_comseg_header*)ptr)->bc_size ));
            if ( ! cip->ci_big_comseg )
            {
                  (void) sql41_detach_shm ( &ptr );
            }
            return ( rc );
      }

    /*
     *  Check the offsets.
     */
    rc = SP1CE_OK ;
    comseg = (comseg_header*) (ptr + cip->ci_big_offset);
    off = comseg->cs_list_offset ;
    if ( comseg->cs_packet_cnt != cip->ci_packet_cnt )
    {
            DBG1 (( MF__,"sql32_att_comseg: ill packet cnt %d wanted %d \n",
                              comseg->cs_packet_cnt , cip->ci_packet_cnt ));
            rc = SP1CE_NOTOK ;
    }
    else if (    (off < 0)
            || (off >= siz - sizeof(long*) * cip->ci_packet_cnt)
            || (off & (sizeof(long*)-1)) )
      {
            DBG1 (( MF__,"sql32_att_comseg: ill list offset %ld siz %ld \n",
                                                      off , siz ));
            rc = SP1CE_NOTOK ;
      }
    else
      {
            offp = (ten_com_long *) (ptr + off);
            for ( idx = 0 ; idx < cip->ci_packet_cnt ; idx ++ )
            {
                  /* packets must be 8-byte aligned. */
                  if (    (*offp < 0)
                   || (*offp >= siz - cip->ci_packet_size)
                   || ((unsigned long) (ptr + *offp) & 7) )
                  {
                        DBG1 (( MF__, "sql32_att_comseg: ill pkt off %ld siz %ld \n",
                                                            *offp , siz ));
                        rc = SP1CE_NOTOK ;
                        break ;
                  }
                  cip->ci_packet[idx] = (rte_header*) (ptr + *(offp ++));
            }
      }
    if ( rc != SP1CE_OK )
      {
            if ( ! cip->ci_big_comseg )
            {
                  (void) sql41_detach_shm ( &ptr );
            }
            return ( rc );
      }

    if ( cip->ci_big_offset )
    {
            cip->ci_big_comseg = (big_comseg_header*) ptr ;
            cip->ci_big_size   = siz ;
    }
    else
    {
            /* these values might have been temporarily assigned. */
            cip->ci_big_comseg = 0 ;
            cip->ci_big_size   = 0 ;
    }
    cip->ci_comseg = comseg ;
    cip->ci_request = cip->ci_packet[0];
    cip->ci_reply   = cip->ci_request ; /* should always point inside packet */

    DBG1 (( MF__,"sql32_att_comseg: big_off  %7ld comseg 0x%08lx \n",
          cip->ci_big_offset , (long) cip->ci_comseg ));
    DBG1 (( MF__,"sql32_att_comseg: list_off %7ld list   0x%08lx \n",
          comseg->cs_list_offset , (long) (ptr + comseg->cs_list_offset) ));
    DBG1 (( MF__,"sql32_att_comseg: pack_off %7ld packet 0x%08lx \n",
          (long) cip->ci_request - (long) ptr , (long) cip->ci_request ));

    return ( SP1CE_OK );
}

/*
 *  ======================================================================
 */
#undef MF__
#define MF__ MOD__"sql32_lock_comseg"
void sql32_lock_comseg ( 
connection_info         *cip ,
char              *msg )
{
    /*
     *  This is coded as a function to avoid
     *  instruction reordering at the point where it is called.
     */
    if ( cip->ci_protocol == PROT_BIGSHM_EO003 )
      {
          for ( ; 
#if defined(_IBMR2) || defined(PA11) || defined(PA20W)
                    e49_lock_int4_4fold ( &cip->ci_comseg->cs_exclusive , 1 ) ;
#else
                  INTERLOCK( &cip->ci_comseg->cs_exclusive ) ;
#endif  /* _IBMR2 || PA11 || PA20W */
                  )
          {
            /* Prevent alreadsy crashed client from locking kernel.... */
            if ( cip->ci_state == CON_ABORTED ) /* PTS 1124430 */
            {
#if defined(_IBMR2) || defined(PA11) || defined(PA20W)
              e49_unlock_int4_4fold ( &cip->ci_comseg->cs_exclusive , 1 ) ;
#else
                INIT_LOCK ( &cip->ci_comseg->cs_exclusive );
#endif
            }
              DBG1 (( MF__, msg , (long) &cip->ci_comseg->cs_exclusive ));
                  (void) sleep ( 0 );
            }
      }
}

/*
 *  ======================================================================
 */
void sql32_unlock_comseg ( 
connection_info         *cip )
{
    /*
     *  This is coded as a function to avoid
     *  instruction reordering at the point where it is called.
     */
    if ( cip->ci_protocol == PROT_BIGSHM_EO003 )
    {
#if defined(_IBMR2) || defined(PA11) || defined(PA20W)
          e49_unlock_int4_4fold ( &cip->ci_comseg->cs_exclusive , 1 ) ;
#else
            CLEARLOCK ( &cip->ci_comseg->cs_exclusive );
#endif
    }
}

Generated by  Doxygen 1.6.0   Back to index