Files
Arquivotheca.AIX-4.1.3/bos/usr/lib/nim/methods/m_ckspot.c
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

474 lines
12 KiB
C

static char sccs_id[] = " @(#)17 1.15.1.4 src/bos/usr/lib/nim/methods/m_ckspot.c, cmdnim, bos41J, 9519A_all 5/4/95 08:45:58";
/*
* COMPONENT_NAME: CMDNIM
*
* FUNCTIONS: ./usr/lib/nim/methods/m_ckspot.c
*
*
* ORIGINS: 27
*
*
* (C) COPYRIGHT International Business Machines Corp. 1993
* All Rights Reserved
* Licensed Materials - Property of IBM
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
#include "cmdnim_mstr.h"
#include <swvpd.h>
extern int ch_pdattr_ass();
extern int ok_to_op_spot();
/*---------------------------- module globals -----------------------------*/
ATTR_ASS_LIST attr_ass;
VALID_ATTR valid_attrs[] =
{
{ATTR_AUTO_EXPAND, ATTR_AUTO_EXPAND_T, FALSE, ch_pdattr_ass},
{ATTR_INSTALLP_FLAGS, ATTR_INSTALLP_FLAGS_T, FALSE, ch_pdattr_ass},
{ATTR_IGNORE_STATE, ATTR_IGNORE_STATE_T, FALSE, ch_pdattr_ass},
{ATTR_FORCE, ATTR_FORCE_T, FALSE, ch_pdattr_ass},
{ATTR_VERBOSE, ATTR_VERBOSE_T, FALSE, ch_pdattr_ass},
{ATTR_DEBUG, ATTR_DEBUG_T, FALSE, ch_pdattr_ass},
{0, NULL, FALSE, ch_pdattr_ass}
};
char *name=NULL; /* NIM name of object to create */
NIM_OBJECT( spot, sinfo ) /* SPOT's object */
char *c_ckspot_msgs = NULL; /* messages from C_CKSPOT */
char *auto_expand="yes"; /* do auto expand.. */
/*---------------------------- parse_args ------------------------------
*
* NAME: parse_args
*
* FUNCTION:
* parses command line arguments
*
* EXECUTION ENVIRONMENT:
*
* NOTES:
* calls nim_error
*
* RECOVERY OPERATION:
*
* DATA STRUCTURES:
* parameters:
* argc = argc from main
* argv = argv from main
* global:
*
* RETURNS: (int)
* SUCCESS = no syntax errors on command line
*
* OUTPUT:
*-----------------------------------------------------------------------------*/
int
parse_args( int argc,
char *argv[] )
{ extern char *optarg;
extern int optind, optopt;
int c;
int syntax_err=FALSE;
/* loop through all args */
while ( (c = getopt(argc, argv, "a:q")) != -1 )
{ switch (c)
{
case 'a': /* attribute assignment */
if (! parse_attr_ass( &attr_ass, valid_attrs, optarg, FALSE ) )
nim_error( 0, NULL, NULL, NULL );
break;
case 'q': /* display valid_attrs */
mstr_what( valid_attrs, NULL );
exit( 0 );
break;
case ':': /* option is missing a required argument */
nim_error( ERR_MISSING_OPT_ARG, optopt, NULL, NULL );
break;
case '?': /* unknown option */
nim_error( ERR_BAD_OPT, optopt, MSG_msg(MSG_GENERIC_MKSYNTAX),NULL);
break;
}
if ( syntax_err )
nim_error( ERR_SYNTAX, MSG_msg(MSG_GENERIC_MKSYNTAX), NULL, NULL );
}
/* check for errors */
if ( optind == argc )
nim_error( ERR_MISSING_OPERAND, MSG_msg(MSG_OBJ_NAME), NULL, NULL );
else if ( optind < (argc-1) )
nim_error( ERR_SYNTAX, MSG_msg(MSG_GENERIC_MKSYNTAX), NULL, NULL );
name = argv[optind];
/* return */
return( SUCCESS );
} /* end of parse_args */
/*---------------------------- spot_Rstate ------------------------------
*
* NAME: spot_Rstate
*
* FUNCTION:
* sets the Rstate for the SPOT
* if any ATTR_MISSING exist, then Rstate set to STATE_INCOMPLETE;
* otherwise, Rstate set to STATE_AVAILABLE
*
* EXECUTION ENVIRONMENT:
*
* NOTES:
*
* RECOVERY OPERATION:
*
* DATA STRUCTURES:
* parameters:
* global:
* name
* spot
*
* RETURNS: (int)
* SUCCESS
*
* OUTPUT:
*-----------------------------------------------------------------------------*/
int
spot_Rstate()
{
/* free memory */
if ( spot != NULL )
odm_free_list( spot, &sinfo );
/* get the latest info */
if ( lag_object( 0, name, &spot, &sinfo ) == SUCCESS )
{
/* any ATTR_IF_SUPPORTED attrs? */
if ( find_attr( spot, NULL, NULL, 0, ATTR_IF_SUPPORTED ) >= 0 )
{
/* there may be ATTR_MISSING attrs, but, since there is at least */
/* one network boot image available, the SPOT can support */
/* some kind of client, so make it available */
set_state( spot->id, NULL, ATTR_RSTATE, STATE_AVAILABLE );
/* remove any ATTR_MISSING attrs so we don't confuse the users */
rm_attr( spot->id, NULL, ATTR_MISSING, 0, NULL );
return( SUCCESS );
}
else
errstr( ERR_MISSING, name, NULL, NULL );
}
/* some type of error has occurred: either the SPOT is missing stuff */
/* or we were unable to lag_object */
protect_errstr = TRUE;
set_state( spot->id, NULL, ATTR_RSTATE, STATE_INCOMPLETE );
return( FAILURE );
} /* end of spot_Rstate */
/* --------------------------- undo ----------------------------------------
*
* NAME: undo
*
* FUNCTION:
* sets SPOT's Rstate to incomplete
*
* EXECUTION ENVIRONMENT:
*
* NOTES:
* calls nim_error
*
* RECOVERY OPERATION:
*
* DATA STRUCTURES:
* parameters:
* errno = error code
* str1 = str1 for error msg
* str2 = str2 for error msg
* str3 = str3 for error msg
* global:
* spot
*
* RETURNS: (void)
*
* OUTPUT:
* -------------------------------------------------------------------------- */
void
undo( int errno,
char *str1,
char *str2,
char *str3 )
{
disable_err_sig();
errno = nene( errno, str1, str2, str3 );
/* set the new Rstate */
if ( spot_Rstate() == FAILURE )
warning( 0, NULL, NULL, NULL );
/* bye-bye */
exit( errno );
} /* end of undo */
/*---------------------------- ck_spot ------------------------------
*
* NAME: ck_spot
*
* FUNCTION:
* scrutinizes the SPOT to determine if it has everything a SPOT must have
* in order for clients to use it
*
* EXECUTION ENVIRONMENT:
*
* NOTES:
* sets errstr on failure
*
* RECOVERY OPERATION:
*
* DATA STRUCTURES:
* parameters:
* global:
*
* RETURNS: (int)
* SUCCESS = SPOT is viable
* FAILURE = internal err or something is missing from the SPOT
*
* OUTPUT:
*-----------------------------------------------------------------------------*/
int
ck_spot()
{ int Rstate;
int method_call=0, debug_present=0, nobooti_added=0, remove_if_supported=0;
int sx;
int lx;
int rc;
FILE *c_stdout=NULL;
char *flags = NULL;
int arg = 0;
char *ckspot[] = { C_CKSPOT, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL };
char *warning_msg = NULL;
int errno = 0;
NIM_PDATTR( platform, pinfo )
int i;
int chcnt;
/* get the SPOT's object */
if ( lag_object( 0, name, &spot, &sinfo ) == FAILURE )
undo( 0, NULL, NULL, NULL );
/*
* If this is called via a method (in particular instspot) the ignore_state
* attr was added by that method (via the function check_spot). This is a clue that
* we've been called from a method and not via nim (nim -o check...)..
* We need to check if ignore_state is present without the force attr and
* this needs to occur before the call to ok_to_op_spot. ok_to_op_spot will set the force
* flag based on ignore_state and the force flag...
*/
if (!force)
method_call=(find_attr_ass( &attr_ass, ATTR_IGNORE_STATE ) >= 0 );
/* ok to perform this operation? */
if ( ok_to_op_spot( spot ) == FAILURE )
undo( 0, NULL, NULL, NULL );
/* find server & location */
if ( (sx = find_attr( spot, NULL, NULL, 0, ATTR_SERVER )) < 0 )
undo( ERR_OBJ_MISSING_ATTR, ATTR_SERVER_T, name, NULL );
else if ( (lx = find_attr( spot, NULL, NULL, 0, ATTR_LOCATION )) < 0 )
undo( ERR_OBJ_MISSING_ATTR, ATTR_LOCATION_T, name, NULL );
/* get the predefined platform information */
if ( get_pdattr( &platform, &pinfo, ATTR_CLASS_MACHINES,
ATTR_SUBCLASS_PLATFORM, 0, 0, NULL ) <= 0 )
undo( ERR_BAD_OBJECT, "predefined", ATTR_SUBCLASS_PLATFORM_T, NULL );
/* make sure SPOT's Rstate gets set */
undo_on_interrupt = undo;
/* initialize parameter string for C_CKSPOT */
/* SPOT name */
ckspot[ ++arg ] = nim_malloc( strlen(ATTR_NAME_T) + strlen(name) + 4 );
sprintf( ckspot[arg], "-a%s=%s", ATTR_NAME_T, name );
/* location */
ckspot[ ++arg ] = nim_malloc( strlen(ATTR_LOCATION_T) +
strlen(spot->attrs[lx].value) + 4 );
sprintf( ckspot[arg], "-a%s=%s", ATTR_LOCATION_T, spot->attrs[lx].value );
/* value of ST_APPLIED */
ckspot[ ++arg ] = nim_malloc( strlen(ATTR_ST_APPLIED_T) + 10 );
sprintf( ckspot[arg], "-a%s=%d", ATTR_ST_APPLIED_T, ST_APPLIED );
/* value of ST_COMMITTED */
ckspot[ ++arg ] = nim_malloc( strlen(ATTR_ST_COMMITTED_T) + 10 );
sprintf( ckspot[arg], "-a%s=%d", ATTR_ST_COMMITTED_T, ST_COMMITTED );
/* platform information */
chcnt = 0;
for (i=0; i < pinfo.num; i++)
chcnt += strlen(platform[i].name) + strlen(platform[i].value) + 3;
ckspot[ ++arg ] = nim_malloc( strlen(ATTR_PLATFORM_T) + chcnt + 5 );
sprintf( ckspot[arg], "-a%s= ", ATTR_PLATFORM_T );
for (i=0; i < pinfo.num; i++)
{
chcnt = strlen( ckspot[arg] );
sprintf( (ckspot[arg] + chcnt), "%s=%s ", platform[i].name,
platform[i].value );
}
/*
* was ATTR_DEBUG specified?
*/
if ( find_attr_ass( &attr_ass, ATTR_DEBUG ) >= 0 ) {
if ( strcmp(attr_value(&attr_ass, ATTR_DEBUG ),"yes") == 0 ) {
/*
* pass ATTR_DEBUG so we get the kernel
* debugger turned on for the network boot images
*/
ckspot[ ++arg ] = nim_malloc( strlen(ATTR_DEBUG_T) + 7 );
sprintf( ckspot[arg], "-a%s=yes", ATTR_DEBUG_T );
}
VERBOSE(" debug is present \n",NULL,NULL,NULL,NULL)
remove_if_supported++;
}
else {
if ( force && !method_call ) {
VERBOSE(" force via cmdline\n",NULL,NULL,NULL,NULL)
remove_if_supported++;
}
else {
if ( find_attr( spot, NULL, NULL, 0, ATTR_MK_NETBOOT) < 0 ) {
VERBOSE(" spot does not have mk_netboot\n",NULL,NULL,NULL,NULL)
ckspot[ ++arg ] = nim_malloc( strlen(ATTR_NO_MKBOOTI_T) + 7 );
sprintf( ckspot[arg], "-a%s=yes", ATTR_NO_MKBOOTI_T );
}
else {
VERBOSE(" spot has mk_netboot, remove if_supported\n",NULL,NULL,NULL,NULL)
remove_if_supported++;
}
}
}
ckspot[ ++arg ] = nim_malloc( strlen(ATTR_AUTO_EXPAND_T) + 7 );
/* did user specify ATTR_AUTO_EXPAND value? */
if ( find_attr_ass( &attr_ass, ATTR_AUTO_EXPAND ) >= 0 )
sprintf( ckspot[arg], "-a%s=%s", ATTR_AUTO_EXPAND_T,
attr_value(&attr_ass, ATTR_AUTO_EXPAND) );
else
sprintf( ckspot[arg], "-a%s=%s", ATTR_AUTO_EXPAND_T, auto_expand );
/*
* pass ATTR_INSTALLP_FLAGS?
* we pass these in case they have the auto expand flag ("X")
*/
if ( (flags = attr_value( &attr_ass, ATTR_INSTALLP_FLAGS )) != NULL )
{
ckspot[ ++arg ] = nim_malloc( strlen(ATTR_INSTALLP_FLAGS_T) +
strlen(flags) + 4 );
sprintf( ckspot[arg], "-a%s=%s", ATTR_INSTALLP_FLAGS_T, flags );
}
VERBOSE(" going to check the SPOT at %s:%s\n",spot->attrs[sx].value,
spot->attrs[lx].value,NULL,NULL)
VERBOSE(" this may take some time - please wait\n",NULL,NULL,NULL,NULL)
/* invoke C_CKSPOT on SPOT's server */
if ( master_exec(spot->attrs[sx].value,&rc,&c_stdout,ckspot) == FAILURE )
undo( 0, NULL, NULL, NULL );
else if ( (rc > 0) && (rc != ERR_MISSING) )
{
/* cache the warning to be displayed after errors (if any) */
warning_msg = niminfo.errstr;
niminfo.errstr = NULL;
}
/* no interruptions here (please) */
undo_on_interrupt = NULL;
disable_err_sig();
/* remove any info attrs the SPOT had before this operation */
rm_attr( spot->id, NULL, ATTR_MISSING, 0, NULL );
rm_attr( spot->id, NULL, ATTR_INFO, 0, NULL );
if (remove_if_supported) {
rm_attr( spot->id, NULL, ATTR_ENTER_DBG, 0, NULL );
rm_attr( spot->id, NULL, ATTR_IF_SUPPORTED, 0, NULL );
}
/*
* add any attrs which were written to stdout
*/
attrs_from_FILE( spot->id, c_stdout );
/* re-get the SPOT's object after the updates */
if ( lag_object( 0, name, &spot, &sinfo ) == FAILURE )
nim_error( 0, NULL, NULL, NULL );
/*
* if we removed the if_supported attr then check if boot build
* was ok. If it was then removed the mk_netboot attr.
*/
if (remove_if_supported) {
if ( find_attr( spot, NULL, NULL, 0, ATTR_IF_SUPPORTED) >= 0 )
rm_attr( spot->id, NULL, ATTR_MK_NETBOOT, 0, NULL );
}
/* set the new Rstate */
if ( spot_Rstate() == FAILURE )
errno = nene( 0, NULL, NULL, NULL );
/* display warnings */
if ( warning_msg != NULL )
warning( ERR_METHOD, spot->attrs[sx].value, warning_msg, NULL );
/* all done - bye bye */
exit( errno );
} /* end of ck_spot */
/************************** main ********************************/
main( int argc, char *argv[] )
{
/* initialize NIM environment */
spot = NULL;
mstr_init( argv[0], ERR_POLICY_METHOD, NULL );
if ( get_list_space( &attr_ass, DEFAULT_CHUNK_SIZE, TRUE ) == FAILURE )
undo( 0, NULL, NULL, NULL );
/* parse command line */
parse_args( argc, argv );
VERBOSE("m_ckspot: check the %s SPOT\n",name,NULL,NULL,NULL)
/* check the SPOT in order to determine what it's current state should be */
ck_spot();
exit( 0 );
}