DSMVOID uttrace() { int fd; /* file descriptor to print on */ int ret; LONG clock; TEXT *pdate; int syserror; TEXT fileName[MAXNAM]; /* get a unique name by using the pid to generate a filename */ stnclr(fileName, sizeof(fileName)); sprintf((psc_rtlchar_t *)fileName, "%s.%d","gemtrace",getpid()); fd = open(fileName, CREATE_RW_APPEND, DEFLT_PERM); if (fd < 0) { /* if the open failed, put a message out to the screen * and we will dump the stack to the screen */ printf("Failed to open file %s errno %d", fileName, syserror); fd = 1; } /* we should have a valid fileHandle, even though it might be stdout. * Time to call the routine to print the stack trace */ ret = write(fd, UT_TRACE_HEADING,stlen(UT_TRACE_HEADING)); if (ret != stlen(UT_TRACE_HEADING)) { /* write failed, revert to stdout */ fd = 1; } /* get the date and time so we can put it into the file */ time(&clock); pdate = (TEXT *)ctime(&clock); ret = write(fd, pdate, stlen(pdate)); uttraceback(fd); if (fd != 1) { /* cleanup */ close(fd); } } /* end uttrace */
/* PROGRAM: shmCreateSegmentTable - initialize segment table for shared memory * references * * RETURNS: Pointer to created segment table */ shmTable_t * shmCreateSegmentTable(STPOOL *pstpool /* pointer to storage pool */) { shmTable_t *pshsgctl; /* pointer to segment control */ pshsgctl = (shmTable_t * )stGet(NULL, pstpool,sizeof(shmTable_t)); /* Rich T. claims that we do not need pcontext here */ stnclr((TEXT*)pshsgctl,sizeof(shmTable_t)); pshsgctl->ipub = MAXPRIVSLT + 1; /* initialize start of public slots */ pshsgctl->iprv = MAXPRIVSLT; /* initialize start of private slots */ return pshsgctl; }
/* * PROGRAM: rlaoff -- turns off after imaging and returns status * * This program turns off after imaging by clearing the information in the * masterblock used by the ai subsystems. It does not write the masterblock * back out, so that must happen before it is really turned off. * * RETURNS: 0 if ai was turned off, 1 if it was never on in the first place */ int rlaoff(struct mstrblk *pmstr) { /* clear information in masterblock for after imaging, except dates */ pmstr->mb_aisync = 0; pmstr->mb_aiwrtloc = 0; pmstr->mb_aictr = 0; pmstr->mb_aiflgs = 0; pmstr->mb_aibusy_extent = 0; if (pmstr->mb_ai.ainew == 0) { /* dates are clear, after imaging was not on */ return 1; } /* after imaging was on, clear remaining dates */ stnclr((TEXT *)&pmstr->mb_ai, sizeof(AIDATES)); return 0; } /* rlaoff */
DSMVOID utmkosnm( TEXT *prefix, TEXT *pname, TEXT *buf, int len, int id) { TEXT *p, *pch; stnclr(buf, len); pch = buf; pch = stcopy(pch, prefix); #if OPSYS==WIN32API /* [johnls] */ for (p = pname; *p && (int)(pch - buf) != len; pch++, p++) { if (*p == ':' && (*(p+1) == '\\' || *(p+1) == '/')) p++; if (*p == '/' || *p == '\\' || *p == ':') *pch = '.'; else *pch = tolower(*p); } *pch = 0; #else pch = stncop(pch, pname, MIN(8, len-11-stlen(prefix))); #endif if (id >= 0) { pch = stcopy(pch, "."); utitoa(id, pch); } }
/* PROGRAM: bkioCreateLkFile -- lock the database in desired mode. * * Create a .lk file holding the following information: * a.) The mode the db is in BKIO_LKSNGL | BKIO_LKMULT * b.) The process ID of the starter of the db * c.) The hostname of the machine where the db was started * * * RETURNS: * 0 database locked in requested mode. * BKIO_LKSNGL database currently locked in single-user mode, * request denied. * BKIO_LKMULT database currently locked in multi-user mode, * request denied. * BKIO_LKSTARTUP database is in the process of starting up * request denied. * */ int bkioCreateLkFile ( dsmContext_t *pcontext, int mode, /* desired usage mode, either BKIO_LKSNGL or BKIO_LKMULT */ TEXT *dbname, /* name of database */ int dispmsg) /* if true, then display a message */ { TEXT namebuf[MAXPATHN+1]; TEXT dbnamebuf[MAXPATHN+1]; TEXT nodebuf[BKIO_NODESZ]; int ret = 0; ULONG spid = 0; int errorStatus = 0; int bytesWritten; LONG retWrite; LONG retMakePath = 0; int lockret = 1; int wmode = mode; fileHandle_t lkhandle; int i; int local = 0; dbcontext_t *pdbcontext = pcontext->pdbcontext; /* see if the *.lk file already exists and is valid */ if(pdbcontext->pdatadir) utmypath(namebuf,pdbcontext->pdatadir,dbname, (TEXT *)".lk"); else retMakePath = utMakePathname(namebuf, sizeof(namebuf), dbname, (TEXT *)".lk"); if (retMakePath != DBUT_S_SUCCESS) { /* Report error */ dbUserError(pcontext, retMakePath, errno, 0, (DSMVOID *)NULL, (DSMVOID *)NULL); } if(pdbcontext->pdatadir) utmypath(dbnamebuf,pdbcontext->pdatadir,dbname, (TEXT *)".db"); else retMakePath = utMakePathname(dbnamebuf, sizeof(dbnamebuf), dbname, (TEXT *)".db"); if (retMakePath != DBUT_S_SUCCESS) { /* Report error */ dbUserError(pcontext, retMakePath, errno, 0, (DSMVOID *)NULL, (DSMVOID *)NULL); } ret = bkioTestLkFile(pcontext, dbname); if (ret) { switch(ret) { case BKIO_LKSNGL: if(dispmsg) MSGN_CALLBACK(pcontext, bkMSG005, dbname); break; /* db in use single-user */ case BKIO_LKMULT: case BKIO_LKSTARTUP: if(dispmsg) MSGN_CALLBACK(pcontext, bkMSG006, dbname); break; /* db in use multi-user */ case BKIO_LKNOHOST: MSGN_CALLBACK(pcontext, bkMSG007, namebuf); MSGN_CALLBACK(pcontext, bkMSG008); MSGN_CALLBACK(pcontext, bkMSG009); MSGN_CALLBACK(pcontext, bkMSG010); MSGN_CALLBACK(pcontext, bkMSG011, namebuf); break; case BKIO_LKTRUNC: break; /* message was put out by bkioTestLkFile */ default: FATAL_MSGN_CALLBACK(pcontext, bkFTL009, dbname); break; } } else { /* open failed, try to creat it */ /* 19990525-028 - small window of opportunity for two brokers */ /* to start on same database. Replace utOsCreat call with */ /* utOsOpen. */ /* lkhandle = utOsCreat((TEXT *)namebuf, 0444, 0, &errorStatus); */ /* 19990525-028 second try. Can only call utOsOpen if not on NFS */ /* See bug for details. */ local = bkioIsLocalFile(pcontext,dbnamebuf); /* if .lk file is on NFS drive */ if (local == 0) { lkhandle = utOsCreat((TEXT *)namebuf, 0444, 0, &errorStatus); } else { #if OPSYS == WIN32API lkhandle = utOsOpen((TEXT *)namebuf, (O_CREAT | O_EXCL | O_WRONLY), CREATE_DATA_FILE, 0, &errorStatus); #else lkhandle = utOsOpen((TEXT *)namebuf, (O_CREAT | O_EXCL | O_WRONLY), 0444, 0, &errorStatus); #endif } if (lkhandle == INVALID_FILE_HANDLE) { /* cant open */ MSGN_CALLBACK(pcontext, bkMSG002, namebuf, errorStatus); return -1; } /* Remove this conditional once file locking is implemented for UNIX */ #if OPSYS == WIN32API /* attempt to get a lock in the .lk file itself */ lockret = utLockLkFile(lkhandle); #endif /* if we got the lock, write out the mode, pid and nodename */ if (lockret) { if (mode == BKIO_LKMULT) { wmode = BKIO_LKSTARTUP; } /* write out the mode the database is in */ retWrite = utWriteToFile(lkhandle, 0, (TEXT *)&wmode, sizeof(int), &bytesWritten, &errorStatus); /* get the process id and put that into the file */ spid = utgetpid (); retWrite = utWriteToFile(lkhandle, sizeof(int), (TEXT *)&spid, sizeof(int), &bytesWritten, &errorStatus); stnclr(nodebuf,BKIO_NODESZ); /*fill with nulls*/ /* get the hostname and put it into the file */ ret = utgethostname((TEXT *)nodebuf,BKIO_NODESZ - 1); if (ret < 0) { /* if the utgethostname call failed, write out an ampty hostname, that will cause the .lk file checking to be more strict */ stnclr(nodebuf,BKIO_NODESZ); /*fill with nulls*/ } retWrite = utWriteToFile(lkhandle,2*(sizeof(int)),nodebuf, BKIO_NODESZ, &bytesWritten, &errorStatus); /* Save the handle in the lkstr structure */ for (i = 0; i < 240; i++) { if (lkstr[i].lkHandle == (fileHandle_t)0) { /* we found an empty slot, populate it */ lkstr[i].lkHandle = lkhandle; lkstr[i].nameCrc = calc_crc((UCOUNT)0, namebuf, (COUNT)stlen(namebuf)); break; } } } else { /* we did no succeed in locking the .lk file */ utOsClose(lkhandle,0); MSGN_CALLBACK(pcontext, bkMSG131, namebuf, errorStatus); return -1; } } return(ret); }
/* PROGRAM: bkioTestLkFile -- examine the database to see if it is locked, and * if so return the mode, i.e. single-user or multi-user. * This version uses a special file, ".lk", instead of the * UNIX locking call. * * RETURNS: Returns 0 if the database is not locked, else returns * BKIO_LKSNGL or BKIO_LKMULT. */ int bkioTestLkFile ( dsmContext_t *pcontext, TEXT *dbname) /* path name for ".db" file */ { TEXT namebuf[MAXPATHN+1]; #if OPSYS == UNIX TEXT nodebuf[BKIO_NODESZ]; TEXT mynode[BKIO_NODESZ]; #endif LONG retRead; ULONG spid = 0; int lkmode = 0; int errorStatus = 0; int bytesRead; LONG retMakePath = 0; fileHandle_t lkhandle; int lockret = 0; /* form path name for *.lk file, see if it's there and current */ if(pcontext->pdbcontext->pdatadir) utmypath(namebuf,pcontext->pdbcontext->pdatadir, pcontext->pdbcontext->pdbname, (TEXT *)".lk"); else retMakePath = utMakePathname(namebuf, sizeof(namebuf), dbname, (TEXT *)".lk"); if (retMakePath != DBUT_S_SUCCESS) { /* Report Error */ dbUserError(pcontext, retMakePath, errno, 0, (DSMVOID *)NULL, (DSMVOID *)NULL); } #if OPSYS == WIN32API lkhandle = utOsOpen(namebuf, OPEN_RW, DEFLT_PERM, OPEN_SEQL, &errorStatus); #else lkhandle = utOsOpen(namebuf, OPEN_R, DEFLT_PERM, OPEN_SEQL, &errorStatus); #endif if (lkhandle == INVALID_FILE_HANDLE) { /* open failed, either db not in use, or permission screwed up */ if (errorStatus != ENOENT) FATAL_MSGN_CALLBACK(pcontext, svFTL013, namebuf, errorStatus); } else { /* read lock mode and server pid out of lock file */ /* the following loop takes care of a timing window that exists * when the server creates the .lk file, and the client attempts * to read the file before the server has written the lock mode * and its pid into the file. This loop should also handle interrupted * system call under Unix, and hence no special case for EINTR */ /* Remove this conditional once file locking is implemented for UNIX */ #if OPSYS == WIN32API /* Try to lock the .lk file */ lockret = utLockLkFile(lkhandle); #endif /* We got a lock, so the .lk file is invalid. Now unlock so it * can be overwritten. */ if (lockret) { lockret = utUnlockLkFile(&lkhandle); /* 19990525-028 - If we are going to change behavior such */ /* that the .lk file is only created if it does not already */ /* exist, then if the .lk file is invalid we must delete it */ bkioRemoveLkFile(pcontext, dbname); return (0); } else { /* The .lk file exists, we can't lock it, so it is valid */ retRead = utReadFromFile(lkhandle, 0, (TEXT *)&lkmode, sizeof (int), &bytesRead, &errorStatus); if ( bytesRead != sizeof(int)) { MSGN_CALLBACK(pcontext, svMSG005); return BKIO_LKTRUNC; } #if OPSYS == UNIX /* get PID and HOST name from file-- if its the same HOST as we are on, it is then safe to test the PID and erase .lk if its not a live process on this same machine and allow login. if the HOSTS are different, or gethostname() is not supported on this machine, the PID cannot be guaranteed to be valid because of NFS so return BKIO_LKNOHOST */ retRead = utReadFromFile(lkhandle, sizeof(int), (TEXT *)&spid, sizeof(int), &bytesRead, &errorStatus); if ( spid ) { stnclr(mynode,BKIO_NODESZ); utgethostname((TEXT *)mynode,BKIO_NODESZ -1); retRead = utReadFromFile(lkhandle, 2 * sizeof(int), (TEXT *)nodebuf, BKIO_NODESZ, &bytesRead, &errorStatus); if ( bytesRead == BKIO_NODESZ) { if (nodebuf[0] == '\0') /* No hostname in the .lk file */ { return BKIO_LKNOHOST; } if (stpcmp(nodebuf,mynode) == 0) /*see if nodes match*/ { if ( (kill ( spid, 0 ) == -1) && (errno == ESRCH) ) { lkmode= 0; } } } } #endif /* UNIX */ } } if (lkhandle != INVALID_FILE_HANDLE) { utOsClose(lkhandle, OPEN_SEQL); if (lkmode == 0) { bkioRemoveLkFile(pcontext, dbname); } } return(lkmode); }