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

408 lines
12 KiB
C

static char sccsid[] = "@(#)48 1.8 src/bos/usr/lib/methods/common/pvidtools.c, cfgmethods, bos411, 9428A410j 3/23/93 09:31:28";
/*
* COMPONENT_NAME: (CFGMETHODS) pvidtools.c
*
* FUNCTIONS: bootdev()
*
* ORIGINS: 27
*
* IBM CONFIDENTIAL -- (IBM Confidential Restricted when
* combined with the aggregated modules for this product)
* SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1989, 1993
* All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
#include <fcntl.h>
#include <sys/types.h>
#include <sys/bootrecord.h>
#include <sys/utsname.h>
#include <sys/scsi.h>
#include <cf.h>
#include <sys/cfgodm.h>
#include <sys/cfgdb.h>
#include <sys/hd_psn.h>
#include <stdio.h>
#include <errno.h>
#include "cfgdebug.h"
#define makehex(x) "0123456789abcdef"[x&15]
#define NULLPVID "00000000000000000000000000000000"
/*
convert pvid to ascii string (33 bytes total)
*/
char *pvidtoa(ip)
struct unique_id *ip;
{
int i;
char *ptr = (char*)ip;
static char buf[33];
for(i=0;i<32;i++) {
if (i&1)
buf[i] = makehex(ptr[i/2]);
else
buf[i] = makehex(ptr[i/2]>>4);
}
buf[32] = '\0';
return(buf);
}
int
pvid_to_disk(lname, pvidstr,openx_ext)
char *lname; /* Device's logical name */
char *pvidstr; /* ASCII PVID string created */
int openx_ext; /* extended parmeter for openx */
{
struct unique_id uid;
int rc;
DEBUG_0("Calling mkuuid from pvid_to_disk\n")
mkuuid(&uid);
strcpy(pvidstr,pvidtoa(&uid));
DEBUG_0("Calling write_pvid from pvid_to_disk\n")
rc = write_pvid(lname, uid,openx_ext);
DEBUG_1("write_pvid routine rc: %d\n",rc)
return(rc);
}
int
putpvidattr(lname,pvidstr)
char *lname; /* Device's logical name */
char *pvidstr; /* ASCII PVID string extracted */
{
struct CuAt *pvidattr;
int cnt;
/* get pvid attribute stuff to serve as a template */
if ((pvidattr=getattr(lname,"pvid",FALSE,&cnt))==NULL) {
DEBUG_1("putpvidattr: didn't get pvid attr for %s\n",
lname)
return(-1);
}
/* put pvid in this structure */
if (*pvidstr) {
/* If not a NULL character then use the input string */
strcpy(pvidattr->value,pvidstr);
} else {
/* Make sure we are writing default value */
strcpy(pvidattr->value,"none");
}
/* put new object into database */
if (putattr(pvidattr)==-1) {
DEBUG_1("putpvidattr: failed to put pvid attr for %s\n",
lname)
return(-1);
}
return(0);
}
int
clear_pvid(lname,openx_ext)
char *lname; /* Device's logical name */
int openx_ext; /* extended parmeter for openx */
{
struct unique_id unique_id; /* pvid structure */
bzero((caddr_t)&unique_id, sizeof (struct unique_id));
return(write_pvid(lname, unique_id,openx_ext));
}
/***********************************************************************
* *
* NAME: mkuuid *
* *
* FUNCTION: *
* This routine returns a unique id. *
* *
* NOTES: *
* *
* INPUT: *
* unique_id *
* *
* OUTPUT: *
* *unique_id *
* *
* RETURN VALUE DESCRIPTION: *
* A return value = 0 indicates successful return. *
* *
* EXTERNAL PROCEDURES CALLED: *
* *
***********************************************************************/
int mkuuid (unique_id)
struct unique_id *unique_id; /* where unique id is to be stored */
{
struct timestruc_t cur_time;
struct utsname uname_buf;
long machine_id;
int retcode;
/***********************************************************************
* For this release, only two words of the unique id structure will *
* be used. Words 3 and 4 will contain zeroes for this release. *
* Word 1 is generated from the current time in seconds. Word 2 *
* is generated from the machine id. *
***********************************************************************/
bzero((caddr_t) unique_id, sizeof (struct unique_id));
retcode = gettimer (TIMEOFDAY, &cur_time);
if (retcode == -1)
return (retcode);
retcode = uname (&uname_buf);
if (retcode == -1)
return (retcode);
/* initialize machine id to 0 */
machine_id = 0;
/* convert character machine id to an integer */
retcode = sscanf (uname_buf.machine, "%8X", &machine_id);
/* store the machine id into the first word of the unique id */
unique_id -> word1 = machine_id;
/* store the current time in milliseconds (?) into the second word of
the unique id */
unique_id -> word2 = cur_time.tv_sec*1000+cur_time.tv_nsec/1000000;
return (0);
}
/***********************************************************************
* *
* NAME: write_pvid *
* *
* FUNCTION: *
* This routine writes the pvid to the bootrecord on PSN 1 *
* *
* NOTES: *
* *
* If the openx_ext flag is non zero, then a special openx using *
* openx_ext as the extended parameter will be used instead of *
* of a normal open. *
* *
* INPUT: *
* unique_id, lname, openx_ext *
* *
* *
* *
* RETURN VALUE DESCRIPTION: *
* A return value = 0 indicates successful return. *
* *
* EXTERNAL PROCEDURES CALLED: *
* *
***********************************************************************/
int write_pvid ( char *lname,
struct unique_id pvid,
int openx_ext)
{
char bdevice[64]; /* special filename for device */
int fd; /* file descriptor for physical vol */
int rc; /* function call return code */
static IPL_REC clearipl; /* clears IPL record (static) */
static IPL_REC ipl_rec; /* IPL (boot record) */
off_t offset;
/*
*
* Read boot record from given disk.
*
*/
sprintf(bdevice,"/dev/r%s",lname);
DEBUG_1("write_pvid: opening device: %s\n",bdevice)
if (openx_ext) {
/*
* If a non zero openx ext is passed in, then
* use the special openx instead of a normal
* open.
*/
fd = openx(bdevice, O_RDWR, 0, openx_ext);
}
else {
fd = open(bdevice, O_RDWR);
}
if (fd < 0) {
if (errno == EBUSY) {
return (E_BUSY);
}
else {
return (E_DEVACCESS);
}
}
DEBUG_0("write_pvid: lseek\n")
offset = lseek(fd, PSN_IPL_REC, 0);
if (offset < 0) {
return(E_DEVACCESS);
}
DEBUG_0("write_pvid: read of ipl record\n")
rc = read(fd, (char *) &ipl_rec, sizeof(ipl_rec));
if (rc < 0) {
return(E_DEVACCESS);
}
DEBUG_1("ipl rec id: %x\n", ipl_rec.IPL_record_id)
/*
*
* Update boot record with given pvid.
*/
if (ipl_rec.IPL_record_id != (unsigned int) IPLRECID) {
/*
* Boot record does not exist on disk yet.
*/
ipl_rec = clearipl;
ipl_rec.IPL_record_id = IPLRECID;
}
ipl_rec.pv_id = pvid;
DEBUG_1("write_pvid: ipl pv_id: %x\n", ipl_rec.pv_id)
/*
*
* Write IPL record to boot image file.
*
*/
DEBUG_0("write_pvid: lseek\n")
offset = lseek(fd, PSN_IPL_REC, 0);
if (offset < 0) {
return(E_DEVACCESS);
}
rc = write(fd, (char *) &ipl_rec, sizeof(ipl_rec));
if (rc < 0) {
return(E_DEVACCESS);
}
close(fd);
return(0);
}
/***********************************************************************
* *
* NAME: read_pvid *
* *
* FUNCTION: *
* This routine reads the pvid from the bootrecord on PSN 1. *
* If the disk does not contain a valid bootrecord then *
* pvidstr will be set to NULLPVID *
* *
* NOTES: *
* *
* If the openx_ext flag is non zero, then a special openx using *
* openx_ext as the extended parameter will be used instead of *
* of a normal open. *
* *
* INPUT: *
* lname, openx_ext *
* *
* OUTPUT: *
* pvidstr *
* *
* RETURN VALUE DESCRIPTION: *
* A return value = 0 indicates successful return. *
* *
* EXTERNAL PROCEDURES CALLED: *
* *
***********************************************************************/
int read_pvid ( char *lname,
char *pvidstr,
int openx_ext)
{
char bdevice[64]; /* special filename for device */
int fd; /* file descriptor for physical vol */
int rc; /* function call return code */
static IPL_REC ipl_rec; /* IPL (boot record) */
off_t offset;
/*
*
* Read boot record from given disk.
*
*/
sprintf(bdevice,"/dev/r%s",lname);
DEBUG_1("read_pvid: opening device: %s\n",bdevice)
if (openx_ext) {
/*
* If a non zero openx ext is passed in, then
* use the special openx instead of a normal
* open.
*/
fd = openx(bdevice,O_RDONLY, 0, openx_ext);
}
else {
fd = open(bdevice, O_RDONLY);
}
if (fd < 0) {
return(E_DEVACCESS);
}
DEBUG_0("read_pvid: lseek\n")
offset = lseek(fd, PSN_IPL_REC, 0);
if (offset < 0) {
return(E_DEVACCESS);
}
DEBUG_0("read_pvid: read of ipl record\n")
rc = read(fd, (char *) &ipl_rec, sizeof(ipl_rec));
if (rc < 0) {
return(E_DEVACCESS);
}
DEBUG_1("ipl rec id: %x\n", ipl_rec.IPL_record_id)
if (ipl_rec.IPL_record_id != (unsigned int) IPLRECID) {
/*
* Boot record does not exist on device.
*/
strcpy(pvidstr,NULLPVID);
}
else {
/*
* Device does have a valid boot
* record, so let's extract the
* PVID.
*/
strcpy(pvidstr,pvidtoa(&(ipl_rec.pv_id)));
}
DEBUG_1("read_pvid: ipl pv_id: %s\n", *pvidstr)
close(fd);
return(0);
}