Exemplo n.º 1
0
/*
** Writes or erases a transaction log and displays a completion thermometer.
**
** 'context' must not be NULL, and defaults for element 0 & 1 of context
** must have been set.
*/
i4
write_transaction_log(bool create, PM_CONTEXT *context,
	char *log_dir[], char *log_file[],
	void (*message)(char *), void (*init_graph)(bool, i4), 
	i4 graph_size, void (*update_graph)())
{

# define LG_PAGE_SIZE		2048L
# define LG_NUMBER_OF_PAGES	32L	/* Number of pages to write at a time */

    DI_IO 		dio[LG_MAX_FILE];
    char 		buf[LG_PAGE_SIZE * LG_NUMBER_OF_PAGES];
    char		nodename[GL_MAXNAME];
    i4  		i, j, marker, count, num_logs;
    i4 		num_pages, page, part_size, remainder, loop;
    CL_ERR_DESC 	err;
    char		*string;
    LOCATION 		loc[LG_MAX_FILE];
    char 		locbuf[MAX_LOC + 1];
    char 		*path[LG_MAX_FILE];
    i4  		LOinfo_flag;
    LOINFORMATION 	loc_info;
    i8 		size;
    CS_SCB 		scb;
    bool		size_in_kbytes = FALSE;

    MEfill( sizeof( scb ), 0, ( PTR ) &scb ); 
    
    ++graph_size;

    /* Prepare transaction for log LOCATION(s) */
    for (num_logs = 0; num_logs < LG_MAX_FILE; num_logs++)
    {
	if (log_dir[num_logs] == 0)
	    break;
	STcopy( log_dir[num_logs], locbuf );
	LOfroms( PATH, locbuf, &loc[num_logs] );
	LOfstfile( log_file[num_logs], &loc[num_logs] );
	LOtos( &loc[num_logs], &path[num_logs] );
    }

    /* get size (in bytes) of log file to be created or erased */
    if( create )
    {
	STATUS status;
	char *value;
	bool havevalue = FALSE;

	status = PMmGet( context, ERx( "$.$.rcp.file.kbytes" ), &value );
	if ( status == OK )
	{
	    havevalue = TRUE;
	    size_in_kbytes = TRUE;
	}

	if ( havevalue == FALSE )
	{
	    status = PMmGet( context, ERx( "$.$.rcp.file.size" ), &value );
	    if ( status == OK )
		havevalue = TRUE;
	}

	if ( havevalue == FALSE )
	{
	    if ( message != NULL )
	    {
		char msg[ BIG_ENOUGH ];
		STprintf( msg, ERx( "%s %s" ),
			PMmExpandRequest( context,
			ERx( "$.$.rcp.file.kbytes" ) ),
			"not found." );
		message( msg );
	    }
	    return( 0 );	
	}
	CVal8( value, &size );
    }
    else
    {
	LOinfo_flag = LO_I_SIZE;
	size = 0;

	for (i = 0; i < num_logs; i++)
	{
	    if ( LOinfo( &loc[i], &LOinfo_flag, &loc_info ) != OK )
	    {
		if ( message != NULL )
		{
		    char msg[ BIG_ENOUGH ];

		    STprintf( msg,
			    "Unable to get size of transaction log:\n\n\t%s",
			    path[i] );	
		    (*message)( msg );
		}
		return( 0 );	
	    }
	    else
		size += loc_info.li_size;
	    if ((LOinfo_flag & LO_I_SIZE) == 0)
		break;
	}

	if ( (LOinfo_flag & LO_I_SIZE) == 0 || size == 0L)
	{
	    STATUS status;
	    char *value;
	    bool havevalue = FALSE;

	    status = PMmGet( context, ERx( "$.$.rcp.file.kbytes" ), &value );
	    if ( status == OK )
	    {
		havevalue = TRUE;
		size_in_kbytes = TRUE;
	    }

	    if ( havevalue == FALSE )
	    {
		status = PMmGet( context, ERx( "$.$.rcp.file.size" ), &value );
		if ( status == OK )
		    havevalue = TRUE;
	    }

	    if ( havevalue == FALSE  )
	    {
		if ( message != NULL )
		{
		    char msg[ BIG_ENOUGH ];

		    STprintf( msg, ERx( "%s %s." ),
			    PMmExpandRequest( context,
			    ERx( "$.$.rcp.file.kbytes" ) ),
			    "not found." );
		    message( msg );
		}
		return( 0 );	
	    }
	    CVal8( value, &size );
	}
    }

    for (i = 0; i < num_logs; i++)
    {
	if ( create && LOexist( &loc[i] ) == OK )
	{
		char msg[ BIG_ENOUGH ];

		if ( message != NULL )
		{
			STprintf( msg, "%s already exists.", path[i] ); 
			(*message)( msg ); 
			STprintf( msg, "To create a new transaction log, you must first delete all partitions of the old one." ); 
			(*message)( msg ); 
		}
		return( 0 );	
	}
    }

    if ( CSinitiate( (i4 *) NULL, (char ***) NULL, (CS_CB *) NULL )
	    != OK )
    {
	    if ( message != NULL )
		    message( "Unable to connect to shared memory" );
	    return( 0 );	
    }

    CSset_sid( &scb );

    /* create DI file */
    for (i = 0; i < num_logs; i++)
    {
	if ( create && DIcreate( &dio[i], 
		log_dir[i],  (u_i4)STlength(log_dir[i]), 
		log_file[i], (u_i4)STlength(log_file[i]),
		(i4)LG_PAGE_SIZE, &err) != OK )
	{
	    char msg[ BIG_ENOUGH ];

	    if ( message != NULL )
	    {
		STprintf( msg,
			"Unable to create transaction log:\n\n\t%s",
			path[i] );	
		(*message)( msg );
	    }
	    return( 0 );
	}

	/* open DI file */
	if ( DIopen( &dio[i],
		log_dir[i],  (u_i4)STlength(log_dir[i]), 
		log_file[i], (u_i4)STlength(log_file[i]),
		(i4)LG_PAGE_SIZE, DI_IO_WRITE, 0, &err) != OK )
	{
	    if ( message != NULL )
	    {
		char msg[ BIG_ENOUGH ];

		STprintf( msg,
			"Unable to open transaction log:\n\n\t%s",
			path[i] );	
		(*message)( msg );
	    }
	    return( 0 );
	}
    }

    if ( size_in_kbytes == FALSE )
	size = (size + 1023) / 1024;

    (*init_graph)( create, (i4) size );

    num_pages = size / (LG_PAGE_SIZE/1024);

    part_size = num_pages / num_logs;

    /* Readjust num_pages to be a multiple of num_logs */
    num_pages = part_size * num_logs;

    loop = part_size / LG_NUMBER_OF_PAGES;
    remainder = part_size % LG_NUMBER_OF_PAGES;

    marker = loop / graph_size;

    /* Fill buffer with zeroes */
    MEfill( sizeof( buf ), 0 , buf);

    for (i = 0; i < num_logs; i++)
    {
	if ( create &&
		DIalloc( &dio[i], part_size, &page, &err ) != OK )
	{
	    DIdelete( &dio[i], log_dir[i], (u_i4)STlength( log_dir[i] ),
		    log_file[i], (u_i4)STlength( log_file[i] ), &err );
	    if ( message != NULL )
		    (*message)( "Unable to allocate space in transaction log file." );
	    return( 0 );
	}
    }

    count = 0;
    for( j = 0; j < loop; j++ )
    {
	i4	n = LG_NUMBER_OF_PAGES;
	i4	page_no = j * n;

	for (i = 0; i < num_logs; i++)
	{
	    if ( DIwrite( &dio[i], &n, page_no, 
			buf, &err ) != OK )
	    {
		DIdelete( &dio[i], 
		    log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]),
		    &err );
		if ( message != NULL )
			(*message)( "Unable to continue writing transaction log." );
		return( 0 );
	    }
	}

	if ( j >= marker && j % marker == 0 &&
		(f4) ((f4) j / (f4) loop) >= ((f4) count + 1) /
		graph_size )
	{
	    ++count;
	    (*update_graph)();
	    SIflush( stdout );
	}
    }

    if (remainder)
    {
	i4	page_no = loop * LG_NUMBER_OF_PAGES;

	for (i = 0; i < num_logs; i++)
	{
	    if ( DIwrite( &dio[i], &remainder, page_no,
			buf, &err ) != OK )
	    {
		DIdelete( &dio[i], 
		    log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]),
		    &err );
		if ( message != NULL )
			(*message)( "Unable to continue writing transaction log." );
		return( 0 );
	    }
	}
    }

    for (i = 0; i < num_logs; i++)
    {
	if ( DIforce( &dio[i], &err ) != OK )
	{
	    DIdelete( &dio[i], log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]), &err );
	    if ( message != NULL )
		(*message)( "Unable to force changes to transaction log." );
	    return( 0 );
	}

	if ( create && DIflush( &dio[i], &err ) != OK )
	{
	    DIdelete( &dio[i], log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]), &err );
	    if ( message != NULL )
		(*message)( "Unable to flush transaction log to disk." );
	    return( 0 );
	}

	if( DIclose( &dio[i], &err ) != OK)
	{
	    DIdelete( &dio[i], log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]), &err );
	    if ( message != NULL )
		(*message)( "Unable to finish writing transaction log." );
	    return( 0 );
	}
    }

    return( (i4) size );
}
Exemplo n.º 2
0
/*
PROGRAM =	iijobdef
**
NEEDLIBS =	UTILLIB MALLOCLIB COMPATLIB GLLIB
**
UNDEFS =	II_copyright
**
DEST =		utility
*/

# endif /* VMS */
main( i4  argc, char **argv)
{
# ifdef VMS
	char *host;
	i4 i;
	PM_SCAN_REC state;
	STATUS status;
	char *lnm_table_name;
	struct dsc$descriptor lnm_table;
	char *regexp;
	char *name, *value;
	PM_CONTEXT *config;
	struct dsc$descriptor lnm_name;
	ILE3 item_list[ 2 ];
	long access_mode = PSL$C_SUPER;

	bool failed_once = FALSE;		/* lib$set_logical works? */
	const match_1 = LIB$_NOCLI;		/* Process has no CLI. */
	const match_2 = LIB$_UNECLIERR;		/* Unexpected CLI error
						 * (non-standard CLI?).
						 */
	const match_3 = SS$_NORMAL;		/* Normal return. */
	const match_4 = SS$_SUPERSEDE;		/* Replaced old value. */
	const match_5 = SS$_NOLOGNAM;		/* Not currently defined. */

	bool delete_logs = FALSE;		/* What are we doing? */
	char *act_str;				/* String for action. */
	char *err_str;				/* String for error exit. */
	char *log_str;				/* String to log action. */
        char tmp_buf[BIG_ENOUGH];

	MEadvise( ME_INGRES_ALLOC );

	if( argc != 1 )
		delete_logs = TRUE;

	(void) PMmInit( &config );

	if( PMmLoad( config, NULL, PMerror ) != OK )
		PCexit( FAIL );

	host = PMmHost( config );

	PMmSetDefault( config, HOST_PM_IDX, host );

	/* get logical table name */ 

	STprintf (tmp_buf , ERx( "%s.$.lnm.table.id" ), SystemCfgPrefix);

	if( PMmGet( config, tmp_buf , &lnm_table_name )
		!= OK )
	{
		F_ERROR( "%s not found.", PMmExpandRequest( config,
			tmp_buf ) );
	}

	/* set logical name table */
	lnm_table_name = ERx( "LNM$JOB" );

	/* compose string descriptor for logical table name */
	lnm_table.dsc$w_length = STlength( lnm_table_name );
	lnm_table.dsc$a_pointer = lnm_table_name; 
	lnm_table.dsc$b_class = DSC$K_CLASS_S;
	lnm_table.dsc$b_dtype = DSC$K_DTYPE_T;

	if ( delete_logs ) {
	    act_str =  ERx( "\nDeleting %s logicals...\n\n(%s)\n\n" );
	    err_str = ERx( "Unable to deassign %s.\n\n" );
	    log_str = ERx( "" );
	} else {
	    act_str = ERx( "\nDeleting %s logicals...\n\n(%s)\n\n" );
	    err_str = ERx( "Unable to set %s to \"%s\".\n\n" );
	    log_str = ERx( "\"%s\" = \"%s\"\n" );
	}

	F_PRINT2( act_str, SystemDBMSName, lnm_table_name );

	/* scan and set node-specific logicals */

	regexp = PMmExpToRegExp( config, ERx( "ii.$.lnm.%") );
	for(
		status = PMmScan( config, regexp, &state, NULL, &name,
		&value ); status == OK; status = PMmScan( config,
		NULL, &state, NULL, &name, &value ) )
	{
		name = PMmGetElem( config, 3, name );

		lnm_name.dsc$w_length = STlength( name );
		lnm_name.dsc$a_pointer = name;
		lnm_name.dsc$b_class = DSC$K_CLASS_S;
		lnm_name.dsc$b_dtype = DSC$K_DTYPE_T;

		item_list[ 0 ].ile3$w_length = STlength( value );
		item_list[ 0 ].ile3$w_code = LNM$_STRING; 
		item_list[ 0 ].ile3$ps_bufaddr = value; 
		item_list[ 0 ].ile3$ps_retlen_addr = NULL; 
		item_list[ 1 ].ile3$w_length = 0;
		item_list[ 1 ].ile3$w_code = 0;

		if ( !failed_once ) {
		    if ( delete_logs )
			status = lib$delete_logical( &lnm_name, &lnm_table );
		    else
			status = lib$set_logical( &lnm_name, NULL, &lnm_table,
						 NULL, item_list );
		    if ( lib$match_cond( &status, &match_1, &match_2 ))
			failed_once = TRUE;
		}
		if ( failed_once ) {
		    if ( delete_logs )
			status = sys$dellnm( &lnm_table, &lnm_name,
					    &access_mode );
		    else
			status = sys$crelnm( NULL, &lnm_table, &lnm_name,
					    &access_mode, item_list );
		}

		if ( !lib$match_cond( &status, &match_3, &match_4, &match_5 ))
		{
			SIfprintf( stderr, err_str, name, value );
			PCexit( FAIL );
		}

		SIprintf( log_str, name, value );
	}

	PCexit( OK );
# else /* VMS */
	SIprintf( "\nThis doesn't do much.\n\n" );
# endif /* VMS */
}