Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

364 lines
11 KiB
C

static char sccsid[] = "@(#)49 1.3 src/bos/usr/lib/methods/cfgaio/cfgaio.c, cfgmethods, bos411, 9428A410j 9/19/91 14:22:15";
/*
* COMPONENT_NAME: (CFGMETH) Configure Method for aio extension
*
* FUNCTIONS: main, err_exit
*
* ORIGINS: 27
*
* (C) COPYRIGHT International Business Machines Corp. 1991
* 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 <stdio.h>
#include <sys/types.h>
#include <cf.h>
#include <malloc.h>
#include <errno.h>
#include <sys/cfgdb.h>
#include <sys/sysmacros.h>
#include <sys/sysconfig.h>
#include <sys/device.h>
#include <sys/cfgodm.h>
#include <aio_interface.h>
#include "cfgdebug.h"
#include "pparms.h"
#define DEFAULT_ODMDIR "/etc/objrepos"
char *prog;
/*
* NAME: main
*
* FUNCTION: This process is executed to "configure" a aio extension .
*
* EXECUTION ENVIRONMENT:
*
* This process is invoked when an aio extension is to be
* "configured".
*
* NOTES: Interface:
* cfgaio -l aio0 <phase>
*
* RETURNS: Exits with 0 on success, >0 Error code.
*/
main(argc,argv,envp)
int argc;
char *argv[];
char *envp[];
{
struct cfg_kmod cfg; /* Parameter list for SYS_CFGKMOD command*/
void err_exit();
char *logical_name; /* logical name to configure */
char sstring[256]; /* search criteria pointer */
char hw_vpd[VPDSIZE]; /* vpd for parent adapter */
struct Class *cusdev; /* customized devices class ptr */
struct Class *predev; /* predefined devices class ptr */
struct Class *cusatt; /* customized attribute class ptr */
struct Class *preatt; /* predefined attribute class ptr */
struct Class *cuvpd; /* customized vpd class ptr */
struct CuDv cusobj; /* customized device object storage */
struct PdDv preobj; /* predefined device object storage */
struct PdDv parpdobj; /* predefined device object storage */
struct CuDv parobj; /* customized device object storage */
struct CuDv dmyobj; /* customized device object storage */
struct CuVPD vpdobj; /* customized vpd object storage */
struct CuAt *cuat;
int ipl_phase = RUNTIME_CFG; /* ipl phase */
extern int optind; /* for getopt function */
extern char *optarg; /* for getopt function */
int errflg,c, rc; /* used in parsing parameters */
char *odmdir = getenv("ODMDIR");
char odmlockfile[MAXPATHLEN+1] = { '\0' };
/* set up initial variable values */
errflg = 0;
logical_name = NULL;
prog = argv[0];
/***** */
/***** Parse Parameters */
/***** */
while ((c = getopt(argc,argv,"l:12?")) != EOF) {
switch (c) {
case 'l':
if (logical_name != NULL)
errflg++;
logical_name = optarg;
break;
case '1':
ipl_phase = PHASE1;
break;
case '2':
ipl_phase = PHASE2;
break;
default:
errflg++;
}
}
if (errflg) {
/* error parsing parameters */
fprintf(stderr, "usage: %s -l aio0 [ -(1|2) ]\n", prog);
exit(E_ARGS);
}
/*************************************************************
check command-line parameters for validity
The customized devices object class must also be searched
to see if the logical name is valid.
*************************************************************/
/* start up odm */
if (odm_initialize() < 0) {
fprintf(stderr, "%s: odm initialization failed\n", prog);
exit(E_ODMINIT);
}
/* open customized devices object class (CuDv) */
if ((int)(cusdev = odm_open_class(CuDv_CLASS)) == -1) {
fprintf(stderr, "%s: couldn't open customized object class\n",
prog);
err_exit(E_ODMOPEN);
}
/****************************************************
Get the Customized Devices Object for this device.
****************************************************/
sprintf(sstring,"name = '%s'",logical_name);
if ((rc = (int)odm_get_obj(cusdev,sstring,&cusobj,ODM_FIRST)) == 0) {
/* odm objects not found */
fprintf(stderr, "%s: CuDv crit=\"%s\" found no objects.\n",
prog, sstring);
err_exit (E_NOCuDv);
} else if (rc == -1) {
/* odm error occurred */
fprintf(stderr, "%s: get_obj failed, crit=\"%s\".\n",
prog, sstring);
err_exit (E_ODMGET);
}
/*******************************************************************
Get the predefined object for this device. This object is located
searching the predefined devices object class based on the unique
type link descriptor in the customized device.
*******************************************************************/
/* open predefined devices object class (PdDv) */
if ((int)(predev = odm_open_class(PdDv_CLASS)) == -1) {
fprintf(stderr, "%s: couldn't open predefined object class\n",
prog);
err_exit (E_ODMOPEN);
}
/* search Predefined devices for object with this unique type */
sprintf(sstring,"uniquetype = '%s'",cusobj.PdDvLn_Lvalue);
if ((rc = (int)odm_get_obj(predev,sstring,&preobj,ODM_FIRST)) == 0) {
/* odm objects not found */
fprintf(stderr, "%s: PdDv crit=\"%s\" found no objects.\n",
prog, sstring);
err_exit (E_NOPdDv);
} else if (rc == -1) {
/* odm error occurred */
fprintf(stderr, "%s: get_obj failed, crit=\"%s\".\n",
prog, sstring);
err_exit (E_ODMGET);
}
/****************************************************************
Display this device's LED value on the system LEDs.
****************************************************************/
if (ipl_phase != RUNTIME_CFG)
setleds (preobj.led);
/***************************************************************
Check to see if the device is already configured.
We actually go about the business of configuring the device
only if the device is not configured yet i.e. DEFINED.
***************************************************************/
if (cusobj.status == (short)DEFINED) {
/*******************************************************
Get the attributes for the aio object from
predefined and customized attribute object class.
*******************************************************/
if ((int)(cusatt = odm_open_class(CuAt_CLASS)) == -1) {
fprintf(stderr, "%s: couldn't open CuAt class\n", prog);
err_exit (E_ODMOPEN);
}
if ((int)(preatt = odm_open_class(PdAt_CLASS)) == -1) {
fprintf(stderr, "%s: couldn't open PdAt class\n", prog);
err_exit (E_ODMOPEN);
}
if (cuat = getattr(logical_name,"minservers", FALSE, &rc))
aio_cfg.minservers = atoi(cuat->value);
if (cuat = getattr(logical_name,"maxservers", FALSE, &rc))
aio_cfg.maxservers = atoi(cuat->value);
if (cuat = getattr(logical_name,"kprocprio", FALSE, &rc))
aio_cfg.kprocprio = atoi(cuat->value);
if (cuat = getattr(logical_name,"maxreqs", FALSE, &rc))
aio_cfg.maxreqs = atoi(cuat->value);
DEBUG_1(" minservers = %d \n", aio_cfg.minservers);
DEBUG_1(" maxservers = %d \n", aio_cfg.maxservers);
DEBUG_1(" kprocprio = %d \n", aio_cfg.kprocprio);
DEBUG_1(" maxreqs = %d \n", aio_cfg.maxreqs);
if (odm_close_class(cusatt) < 0) {
fprintf(stderr, "%s: error closing CuAt class\n", prog);
err_exit (E_ODMCLOSE);
}
if (odm_close_class(preatt) < 0) {
fprintf(stderr, "%s: error closing PdAt class\n", prog);
err_exit (E_ODMCLOSE);
}
/***********************************************
Call loadext() to load aio extension.
loadext will load the extension only if needed,
and always returns the kmid of the extension.
***********************************************/
DEBUG_1 ("Loading %s\n",preobj.DvDr)
if ((cfg.kmid = loadext(preobj.DvDr,TRUE,FALSE)) == NULL) {
/* error loading device driver */
fprintf(stderr, "%s: error %d loading %s\n",
prog, errno, preobj.DvDr);
err_exit (E_LOADEXT);
}
/*************************************************
Now call sysconfig() to configure the driver.
*************************************************/
DEBUG_0 ("Initializing Device ...\n")
cfg.cmd = CFG_INIT;
cfg.mdiptr = (caddr_t) &aio_cfg;
cfg.mdilen = sizeof(aio_cfg);
if (sysconfig(SYS_CFGKMOD,&cfg,sizeof(struct cfg_kmod))==-1) {
fprintf(stderr, "%s: error %d from sysconfig",
prog, errno);
err_undo1(logical_name);
err_exit (E_CFGINIT);
}
DEBUG_0 ("Initialize Complete\n")
/**********************************************************
Update the customized object to reflect the device's
current status.
changed to AVAILABLE, and, if they were generated, the
**********************************************************/
cusobj.status = (short) AVAILABLE;
if ((rc = odm_change_obj(cusdev,&cusobj)) < 0) {
/* change object failed */
fprintf(stderr, "%s: update of %s failed.\n",
prog, logical_name);
err_exit (E_ODMUPDATE);
}
}
/* close object classes */
if (odm_close_class(predev) < 0) {
fprintf(stderr, "%s: error closing PdDv class\n", prog);
err_exit (E_ODMCLOSE);
}
if (odm_close_class(cusdev) < 0) {
fprintf(stderr, "%s: error closing CuDv class\n", prog);
err_exit (E_ODMCLOSE);
}
/***********************************************************
Config method is finished at this point. Terminate the
ODM, and exit with a good return code.
***********************************************************/
odm_terminate();
exit(0);
}
/*
* NAME: err_exit
*
* FUNCTION: Closes any open object classes and terminates ODM. Used to
* back out on an error.
*
* EXECUTION ENVIRONMENT:
*
* This routine is to be used only within this file. The device
* specific routines for the various device specific config methods
* must not call this function.
*
* NOTES:
*
* void
* err_exit( exitcode )
* exitcode = The error exit code.
*
* RETURNS:
* None
*/
void
err_exit(exitcode)
int exitcode;
{
/* Close any open object class */
odm_close_class(CuDv_CLASS);
odm_close_class(PdDv_CLASS);
odm_close_class(CuAt_CLASS);
odm_close_class(PdAt_CLASS);
/* Terminate the ODM */
odm_terminate();
fprintf(stderr, "%s: exiting with code %d\n", prog, exitcode);
exit(exitcode);
}
/*
* NAME: err_undo1
*
* FUNCTION: Unloads the device's device driver. Used to back out on an
* error.
*
* EXECUTION ENVIRONMENT:
*
* This routine is to be used only within this file. The device
* specific routines for the various device specific config methods
* must not call this function.
*
* NOTES:
*
* void
* err_undo1( DvDr )
* DvDr = pointer to device driver name.
*
* RETURNS:
* None
*/
err_undo1(DvDr)
char *DvDr; /* pointer to device driver name */
{
/* unload driver */
if (loadext(DvDr,FALSE,FALSE) == NULL)
fprintf(stderr, "%s: error unloading %s\n", prog, DvDr);
return;
}