1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright (c) 1997, by Sun Microsystems, Inc. 28*7c478bd9Sstevel@tonic-gate * All rights reserved. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate /* 35*7c478bd9Sstevel@tonic-gate * Globals defined: 36*7c478bd9Sstevel@tonic-gate * 37*7c478bd9Sstevel@tonic-gate * devreserv() Reserve a set of OA&M devices 38*7c478bd9Sstevel@tonic-gate * devfree() Free a reserved device 39*7c478bd9Sstevel@tonic-gate * reservdev() Get a list of reserved devices 40*7c478bd9Sstevel@tonic-gate * _openlkfile() Opens the lock file 41*7c478bd9Sstevel@tonic-gate * _rsvtabpath() Get the pathname of the lock table file 42*7c478bd9Sstevel@tonic-gate * _closelkfile() Closes the lock file 43*7c478bd9Sstevel@tonic-gate */ 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate /* 46*7c478bd9Sstevel@tonic-gate * Headers referenced: 47*7c478bd9Sstevel@tonic-gate * <sys/types.h> System data types 48*7c478bd9Sstevel@tonic-gate * <errno.h> Error definitions (including "errno") 49*7c478bd9Sstevel@tonic-gate * <string.h> String handling definitions 50*7c478bd9Sstevel@tonic-gate * <fcntl.h> File control definitions 51*7c478bd9Sstevel@tonic-gate * <unistd.h> Unix standard value definitions 52*7c478bd9Sstevel@tonic-gate * <devmgmt.h> Global Device Management definitions 53*7c478bd9Sstevel@tonic-gate * "devtab.h" Local Device Management definitions 54*7c478bd9Sstevel@tonic-gate */ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 57*7c478bd9Sstevel@tonic-gate #include <errno.h> 58*7c478bd9Sstevel@tonic-gate #include <string.h> 59*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 60*7c478bd9Sstevel@tonic-gate #include <unistd.h> 61*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 62*7c478bd9Sstevel@tonic-gate #include <devmgmt.h> 63*7c478bd9Sstevel@tonic-gate #include "devtab.h" 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate /* 66*7c478bd9Sstevel@tonic-gate * Local Definitions: 67*7c478bd9Sstevel@tonic-gate */ 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate /* 71*7c478bd9Sstevel@tonic-gate * Local data types: 72*7c478bd9Sstevel@tonic-gate * struct devlks Structure that defines locking information (key 73*7c478bd9Sstevel@tonic-gate * with alias name (may be '\0' terminated) 74*7c478bd9Sstevel@tonic-gate */ 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate struct devlks { 77*7c478bd9Sstevel@tonic-gate int lk_key; 78*7c478bd9Sstevel@tonic-gate char lk_alias[((DTAB_MXALIASLN+2)/2)*2]; 79*7c478bd9Sstevel@tonic-gate }; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate /* 83*7c478bd9Sstevel@tonic-gate * Local Functions: 84*7c478bd9Sstevel@tonic-gate * isanullstr() Is a character string a null string ("")? 85*7c478bd9Sstevel@tonic-gate * getlkcnt() Get the number of devices locked 86*7c478bd9Sstevel@tonic-gate * locklkfile() Lock the OA&M Device locking file 87*7c478bd9Sstevel@tonic-gate * getlocks() Get the device locks from the device-lock file 88*7c478bd9Sstevel@tonic-gate * islocked() Determines if a device is locked 89*7c478bd9Sstevel@tonic-gate * putlocks() Close the device locks w/ update 90*7c478bd9Sstevel@tonic-gate * freelkfile() Close the device locks w/o updating 91*7c478bd9Sstevel@tonic-gate * compresslks() Compresses the table containing lock info 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate #define isanullstr(s) (s[0] == '\0') 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate static int locklkfile(short); /* Lock the lock file */ 97*7c478bd9Sstevel@tonic-gate static int getlkcnt(void); /* Get the number of locked devices */ 98*7c478bd9Sstevel@tonic-gate static int getlocks(void); /* Get the lock information */ 99*7c478bd9Sstevel@tonic-gate static int putlocks(char **, int); /* Update lock information */ 100*7c478bd9Sstevel@tonic-gate static int freelkfile(void); /* Free lock information (no update) */ 101*7c478bd9Sstevel@tonic-gate static char *islocked(char *); /* Determines if a device is locked */ 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate /* 105*7c478bd9Sstevel@tonic-gate * Static data 106*7c478bd9Sstevel@tonic-gate */ 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate static struct flock lkinfo = {0, 0, 0, 0, 0}; 109*7c478bd9Sstevel@tonic-gate static struct devlks *locklist; 110*7c478bd9Sstevel@tonic-gate static int lockcount; 111*7c478bd9Sstevel@tonic-gate static int lkfilefd = -1; 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate /* 114*7c478bd9Sstevel@tonic-gate * char *_rsvtabpath() 115*7c478bd9Sstevel@tonic-gate * 116*7c478bd9Sstevel@tonic-gate * Determines the pathname of the device reservation table file 117*7c478bd9Sstevel@tonic-gate * 118*7c478bd9Sstevel@tonic-gate * Uses the following sequential steps: 119*7c478bd9Sstevel@tonic-gate * 1) If OAM_DEVLKFILE is defined and is not null, use that as 120*7c478bd9Sstevel@tonic-gate * the pathname to the file 121*7c478bd9Sstevel@tonic-gate * 2) Otherwise, use the devault name found in DVLK_PATH (defined 122*7c478bd9Sstevel@tonic-gate * in the header file <devtab.h> 123*7c478bd9Sstevel@tonic-gate * 124*7c478bd9Sstevel@tonic-gate * Arguments: None 125*7c478bd9Sstevel@tonic-gate * 126*7c478bd9Sstevel@tonic-gate * Returns: char * 127*7c478bd9Sstevel@tonic-gate * A pointer to the filename in malloc()ed memory or (char *) NULL if 128*7c478bd9Sstevel@tonic-gate * it fails. "errno" will indicate the error if it fails. 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate char * 132*7c478bd9Sstevel@tonic-gate _rsvtabpath(void) 133*7c478bd9Sstevel@tonic-gate { 134*7c478bd9Sstevel@tonic-gate /* Automatics */ 135*7c478bd9Sstevel@tonic-gate char *lockname; /* Name of the lockfile */ 136*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 137*7c478bd9Sstevel@tonic-gate char *p; /* Temporary pointer */ 138*7c478bd9Sstevel@tonic-gate #endif 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 141*7c478bd9Sstevel@tonic-gate p = getenv(OAM_DEVLKTAB); 142*7c478bd9Sstevel@tonic-gate if ((p != NULL) && (*p != '\0')) { 143*7c478bd9Sstevel@tonic-gate if (lockname = malloc(strlen(p)+1)) 144*7c478bd9Sstevel@tonic-gate (void) strcpy(lockname, p); 145*7c478bd9Sstevel@tonic-gate } else { 146*7c478bd9Sstevel@tonic-gate #endif 147*7c478bd9Sstevel@tonic-gate if (lockname = malloc(strlen(DVLK_PATH)+1)) 148*7c478bd9Sstevel@tonic-gate (void) strcpy(lockname, DVLK_PATH); 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate #endif 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate /* Fini -- return a pointer to the lockfile pathname */ 155*7c478bd9Sstevel@tonic-gate return (lockname); 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate /* 159*7c478bd9Sstevel@tonic-gate * int _openlkfile() 160*7c478bd9Sstevel@tonic-gate * 161*7c478bd9Sstevel@tonic-gate * The _openlkfile() function opens a device-reservation table file 162*7c478bd9Sstevel@tonic-gate * for read/write access. 163*7c478bd9Sstevel@tonic-gate * 164*7c478bd9Sstevel@tonic-gate * Arguments: None 165*7c478bd9Sstevel@tonic-gate * 166*7c478bd9Sstevel@tonic-gate * Returns: int 167*7c478bd9Sstevel@tonic-gate * TRUE if successful, FALSE otherwise. 168*7c478bd9Sstevel@tonic-gate * 169*7c478bd9Sstevel@tonic-gate * Statics Used: 170*7c478bd9Sstevel@tonic-gate * lkfilefd Lock file file descriptor 171*7c478bd9Sstevel@tonic-gate */ 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate int 174*7c478bd9Sstevel@tonic-gate _openlkfile(void) 175*7c478bd9Sstevel@tonic-gate { 176*7c478bd9Sstevel@tonic-gate /* 177*7c478bd9Sstevel@tonic-gate * Automatic data 178*7c478bd9Sstevel@tonic-gate */ 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate char *lockname; /* Name of the lock file */ 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate /* Close the lockfile -- it might be open */ 184*7c478bd9Sstevel@tonic-gate (void) _closelkfile(); 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate /* If we can get the name of the lock file ... */ 187*7c478bd9Sstevel@tonic-gate if (lockname = _rsvtabpath()) { 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate /* Open it */ 190*7c478bd9Sstevel@tonic-gate lkfilefd = open(lockname, O_RDWR|O_CREAT, 0600); 191*7c478bd9Sstevel@tonic-gate free(lockname); 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate } 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate /* Finis */ 196*7c478bd9Sstevel@tonic-gate return ((lkfilefd != -1) ? TRUE : FALSE); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate /* 200*7c478bd9Sstevel@tonic-gate * int _closelkfile() 201*7c478bd9Sstevel@tonic-gate * 202*7c478bd9Sstevel@tonic-gate * Function closes the device-reservation table file and sets the 203*7c478bd9Sstevel@tonic-gate * necessary external variables to indicate such. 204*7c478bd9Sstevel@tonic-gate * 205*7c478bd9Sstevel@tonic-gate * Arguments: None 206*7c478bd9Sstevel@tonic-gate * 207*7c478bd9Sstevel@tonic-gate * Returns: int 208*7c478bd9Sstevel@tonic-gate * Same as close() 209*7c478bd9Sstevel@tonic-gate * 210*7c478bd9Sstevel@tonic-gate * Statics referenced: 211*7c478bd9Sstevel@tonic-gate * lkfilefd The device reservation table file's file descriptor 212*7c478bd9Sstevel@tonic-gate */ 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate int 215*7c478bd9Sstevel@tonic-gate _closelkfile(void) 216*7c478bd9Sstevel@tonic-gate { 217*7c478bd9Sstevel@tonic-gate /* Automatics */ 218*7c478bd9Sstevel@tonic-gate int rtnval; /* Value to return */ 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate /* Close the lock file if it's open */ 221*7c478bd9Sstevel@tonic-gate if (lkfilefd != -1) rtnval = close(lkfilefd); 222*7c478bd9Sstevel@tonic-gate else rtnval = 0; 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate /* Indicate that the lock-file is closed */ 225*7c478bd9Sstevel@tonic-gate lkfilefd = -1; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate /* Finis */ 228*7c478bd9Sstevel@tonic-gate return (rtnval); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate /* 232*7c478bd9Sstevel@tonic-gate * int locklkfile(lkflag) 233*7c478bd9Sstevel@tonic-gate * short lkflag 234*7c478bd9Sstevel@tonic-gate * 235*7c478bd9Sstevel@tonic-gate * This function locks the device lock file. If the request cannot 236*7c478bd9Sstevel@tonic-gate * be serviced, it keeps on trying until it manages to lock the file 237*7c478bd9Sstevel@tonic-gate * or it encounters an error. 238*7c478bd9Sstevel@tonic-gate * 239*7c478bd9Sstevel@tonic-gate * Arguments: 240*7c478bd9Sstevel@tonic-gate * lkflag Flag (from FCNTL(BA_OS)) indicating which type 241*7c478bd9Sstevel@tonic-gate * of lock is being requested. Values that make 242*7c478bd9Sstevel@tonic-gate * sense: 243*7c478bd9Sstevel@tonic-gate * F_RDLCK: Read lock. 244*7c478bd9Sstevel@tonic-gate * F_WRLCK: Write lock. 245*7c478bd9Sstevel@tonic-gate * 246*7c478bd9Sstevel@tonic-gate * Returns: int 247*7c478bd9Sstevel@tonic-gate * TRUE (non-zero) if the function managed to lock the file, FALSE 248*7c478bd9Sstevel@tonic-gate * otherwise ("errno" will indicate the problem). 249*7c478bd9Sstevel@tonic-gate * 250*7c478bd9Sstevel@tonic-gate * Statics used: 251*7c478bd9Sstevel@tonic-gate * int lkfilefd File descriptor of the open lock file 252*7c478bd9Sstevel@tonic-gate * struct flock lkinfo Structure used by fcntl() to lock a file 253*7c478bd9Sstevel@tonic-gate */ 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate static int 256*7c478bd9Sstevel@tonic-gate locklkfile(short lkflag) 257*7c478bd9Sstevel@tonic-gate { 258*7c478bd9Sstevel@tonic-gate /* Automatic data */ 259*7c478bd9Sstevel@tonic-gate int noerror; /* TRUE if no error yet */ 260*7c478bd9Sstevel@tonic-gate int locked; /* TRUE if the file is locked */ 261*7c478bd9Sstevel@tonic-gate int olderrno; /* Value of errno on call */ 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* Set up the locking structure */ 265*7c478bd9Sstevel@tonic-gate lkinfo.l_type = lkflag; 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate /* Try to lock the file. If it's locked, wait and try again */ 268*7c478bd9Sstevel@tonic-gate noerror = TRUE; 269*7c478bd9Sstevel@tonic-gate locked = FALSE; 270*7c478bd9Sstevel@tonic-gate olderrno = errno; 271*7c478bd9Sstevel@tonic-gate while (noerror && !locked) { 272*7c478bd9Sstevel@tonic-gate if (fcntl(lkfilefd, F_SETLK, &lkinfo) != -1) locked = TRUE; 273*7c478bd9Sstevel@tonic-gate else { 274*7c478bd9Sstevel@tonic-gate if ((errno == EACCES) || (errno == EAGAIN)) { 275*7c478bd9Sstevel@tonic-gate errno = olderrno; 276*7c478bd9Sstevel@tonic-gate if (sleep(2)) noerror = FALSE; 277*7c478bd9Sstevel@tonic-gate } else noerror = FALSE; 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate /* Return a success flag */ 282*7c478bd9Sstevel@tonic-gate return (locked); 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate /* 286*7c478bd9Sstevel@tonic-gate * int getlkcnt() 287*7c478bd9Sstevel@tonic-gate * 288*7c478bd9Sstevel@tonic-gate * This function extracts the number of currently-locked devices 289*7c478bd9Sstevel@tonic-gate * from the lock file. 290*7c478bd9Sstevel@tonic-gate * 291*7c478bd9Sstevel@tonic-gate * Arguments: None 292*7c478bd9Sstevel@tonic-gate * 293*7c478bd9Sstevel@tonic-gate * Returns: int 294*7c478bd9Sstevel@tonic-gate * The number of devices locked or -1 if an error occurred. 295*7c478bd9Sstevel@tonic-gate * 296*7c478bd9Sstevel@tonic-gate * Statics used: 297*7c478bd9Sstevel@tonic-gate * lkfilefd File descriptor of the open lockfile 298*7c478bd9Sstevel@tonic-gate * 299*7c478bd9Sstevel@tonic-gate * Assumptions: 300*7c478bd9Sstevel@tonic-gate * - The file is positioned to the beginning-of-file 301*7c478bd9Sstevel@tonic-gate */ 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate static int 304*7c478bd9Sstevel@tonic-gate getlkcnt(void) 305*7c478bd9Sstevel@tonic-gate { 306*7c478bd9Sstevel@tonic-gate /* Automatics */ 307*7c478bd9Sstevel@tonic-gate int cntread; /* Number of bytes read */ 308*7c478bd9Sstevel@tonic-gate int lkcnt; /* Number of current locks */ 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate /* Get the lock count from the file */ 311*7c478bd9Sstevel@tonic-gate cntread = (int)read(lkfilefd, &lkcnt, sizeof (int)); 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate /* If there wasn't one, set to 0. If error, set to -1 */ 314*7c478bd9Sstevel@tonic-gate if (cntread != (int)sizeof (int)) 315*7c478bd9Sstevel@tonic-gate lkcnt = (cntread < 0) ? -1 : 0; 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate /* Return the lock count */ 318*7c478bd9Sstevel@tonic-gate return (lkcnt); 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate /* 322*7c478bd9Sstevel@tonic-gate * int readlocks() 323*7c478bd9Sstevel@tonic-gate * 324*7c478bd9Sstevel@tonic-gate * The readlocks() function reads the reserved-device list from 325*7c478bd9Sstevel@tonic-gate * the reserved-device file (which has already been opened) 326*7c478bd9Sstevel@tonic-gate * 327*7c478bd9Sstevel@tonic-gate * Arguments: None 328*7c478bd9Sstevel@tonic-gate * 329*7c478bd9Sstevel@tonic-gate * Returns: int 330*7c478bd9Sstevel@tonic-gate * TRUE if all went well, FALSE otherwise. 331*7c478bd9Sstevel@tonic-gate * 332*7c478bd9Sstevel@tonic-gate * Statics Used: 333*7c478bd9Sstevel@tonic-gate * lockcount Sets this to the number of locks in the lock list 334*7c478bd9Sstevel@tonic-gate * locklist Sets this to the malloc()ed space containing the 335*7c478bd9Sstevel@tonic-gate * list of reserved devices. 336*7c478bd9Sstevel@tonic-gate * lkfilefd Reads data from this file 337*7c478bd9Sstevel@tonic-gate */ 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate static int 340*7c478bd9Sstevel@tonic-gate readlocks(void) 341*7c478bd9Sstevel@tonic-gate { 342*7c478bd9Sstevel@tonic-gate /* Automatics */ 343*7c478bd9Sstevel@tonic-gate struct devlks *alloc; /* Ptr to alloc'ed space */ 344*7c478bd9Sstevel@tonic-gate int noerror; /* TRUE if all is well */ 345*7c478bd9Sstevel@tonic-gate size_t bufsiz; /* # bytes needed for lock data */ 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate /* Initializations */ 349*7c478bd9Sstevel@tonic-gate noerror = TRUE; 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate /* Get the number of devices currently locked */ 352*7c478bd9Sstevel@tonic-gate if ((lockcount = getlkcnt()) > 0) { 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate /* Allocate space for the locks */ 355*7c478bd9Sstevel@tonic-gate bufsiz = lockcount * sizeof (struct devlks); 356*7c478bd9Sstevel@tonic-gate if (alloc = malloc(bufsiz)) { 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate /* Read the locks into the malloc()ed buffer */ 359*7c478bd9Sstevel@tonic-gate if (read(lkfilefd, alloc, bufsiz) != (ssize_t)bufsiz) 360*7c478bd9Sstevel@tonic-gate noerror = FALSE; 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate /* If the read failed, free malloc()ed buffer */ 363*7c478bd9Sstevel@tonic-gate if (!noerror) free(alloc); 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate } else noerror = FALSE; /* malloc() failed */ 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate } else if (lockcount < 0) noerror = FALSE; 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate /* Finished */ 370*7c478bd9Sstevel@tonic-gate if (noerror) 371*7c478bd9Sstevel@tonic-gate locklist = (lockcount > 0) ? alloc : NULL; 372*7c478bd9Sstevel@tonic-gate return (noerror); 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate /* 376*7c478bd9Sstevel@tonic-gate * int getlocks() 377*7c478bd9Sstevel@tonic-gate * 378*7c478bd9Sstevel@tonic-gate * getlocks() extracts the list of locked devices from the file 379*7c478bd9Sstevel@tonic-gate * containing that information. It returns the number of locked 380*7c478bd9Sstevel@tonic-gate * devices. If there are any locked devices, it allocates a buffer 381*7c478bd9Sstevel@tonic-gate * for the locked file information, saves that buffer address in 382*7c478bd9Sstevel@tonic-gate * the allocated buffer. Also, the device lock file is open and 383*7c478bd9Sstevel@tonic-gate * locked if the function is successful. 384*7c478bd9Sstevel@tonic-gate * 385*7c478bd9Sstevel@tonic-gate * Arguments: None 386*7c478bd9Sstevel@tonic-gate * 387*7c478bd9Sstevel@tonic-gate * Returns: int 388*7c478bd9Sstevel@tonic-gate * TRUE if successful, FALSE otherwise. "errno" will reflect the 389*7c478bd9Sstevel@tonic-gate * error if the function returns FALSE. 390*7c478bd9Sstevel@tonic-gate * 391*7c478bd9Sstevel@tonic-gate * Static data referenced: 392*7c478bd9Sstevel@tonic-gate * int lkfilefd File descriptor of the lock file 393*7c478bd9Sstevel@tonic-gate */ 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate static int 396*7c478bd9Sstevel@tonic-gate getlocks(void) 397*7c478bd9Sstevel@tonic-gate { 398*7c478bd9Sstevel@tonic-gate /* Automatic data */ 399*7c478bd9Sstevel@tonic-gate int noerror; /* TRUE if all's well */ 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate /* Initializations */ 403*7c478bd9Sstevel@tonic-gate noerror = TRUE; 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate /* Open the lock file */ 406*7c478bd9Sstevel@tonic-gate if (_openlkfile()) { 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate /* Lock the lock file */ 409*7c478bd9Sstevel@tonic-gate if (locklkfile(F_WRLCK)) { 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate /* Get the number of devices currently locked */ 412*7c478bd9Sstevel@tonic-gate if (!readlocks()) noerror = FALSE; 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate /* If something happened, unlock the file */ 415*7c478bd9Sstevel@tonic-gate if (!noerror) (void) freelkfile(); 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate } else noerror = FALSE; /* Lock failed */ 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate /* If something happened, close the lock file */ 420*7c478bd9Sstevel@tonic-gate if (!noerror) 421*7c478bd9Sstevel@tonic-gate (void) _closelkfile(); 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate } else noerror = FALSE; /* Open failed */ 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate /* Done */ 426*7c478bd9Sstevel@tonic-gate return (noerror); 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate /* 430*7c478bd9Sstevel@tonic-gate * int writelks(tblcnt) 431*7c478bd9Sstevel@tonic-gate * int tblcnt 432*7c478bd9Sstevel@tonic-gate * 433*7c478bd9Sstevel@tonic-gate * writelks() writes the lock information to the lock file. Lock 434*7c478bd9Sstevel@tonic-gate * information includes the number of locks (to be) in the table. 435*7c478bd9Sstevel@tonic-gate * Note that functions may still be appending new locks after this 436*7c478bd9Sstevel@tonic-gate * call... 437*7c478bd9Sstevel@tonic-gate * 438*7c478bd9Sstevel@tonic-gate * Arguments: 439*7c478bd9Sstevel@tonic-gate * tblcnt Number of locks in the lock table 440*7c478bd9Sstevel@tonic-gate * 441*7c478bd9Sstevel@tonic-gate * Returns: 442*7c478bd9Sstevel@tonic-gate * TRUE if successful, FALSE otherwise with "errno" containing an 443*7c478bd9Sstevel@tonic-gate * indication of the error. 444*7c478bd9Sstevel@tonic-gate * 445*7c478bd9Sstevel@tonic-gate * Statics Used: 446*7c478bd9Sstevel@tonic-gate * lockcount Number of locks to exist 447*7c478bd9Sstevel@tonic-gate * locklist Table of locks (may not include new ones) 448*7c478bd9Sstevel@tonic-gate * lkfilefd File descriptor of the lock file 449*7c478bd9Sstevel@tonic-gate * 450*7c478bd9Sstevel@tonic-gate * Notes: 451*7c478bd9Sstevel@tonic-gate * - The number of locks that are going to be in the lock file 452*7c478bd9Sstevel@tonic-gate * is in the static variable "lockcount". <tblcnt> indicates 453*7c478bd9Sstevel@tonic-gate * the number of entries in the lock table. 454*7c478bd9Sstevel@tonic-gate */ 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate static int 457*7c478bd9Sstevel@tonic-gate writelks(int tblcnt) 458*7c478bd9Sstevel@tonic-gate { 459*7c478bd9Sstevel@tonic-gate /* Automatic data */ 460*7c478bd9Sstevel@tonic-gate int noerr; /* FLAG, TRUE if all's well */ 461*7c478bd9Sstevel@tonic-gate size_t tblsz; /* Size of the table to write */ 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate /* Initializations */ 464*7c478bd9Sstevel@tonic-gate noerr = TRUE; 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate /* Rewind the OA&M Device Lock File */ 467*7c478bd9Sstevel@tonic-gate if (lseek(lkfilefd, 0L, 0) >= 0L) 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate /* Write the number of locks that will (eventually) exist */ 470*7c478bd9Sstevel@tonic-gate if (write(lkfilefd, &lockcount, sizeof (int)) == sizeof (int)) { 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate /* Write the table as we currently know it */ 473*7c478bd9Sstevel@tonic-gate tblsz = tblcnt * sizeof (struct devlks); 474*7c478bd9Sstevel@tonic-gate if (tblsz) 475*7c478bd9Sstevel@tonic-gate if (!write(lkfilefd, locklist, tblsz) == (ssize_t)tblsz) 476*7c478bd9Sstevel@tonic-gate noerr = FALSE; /* Write of locks failed */ 477*7c478bd9Sstevel@tonic-gate 478*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* write() of count failed */ 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate else noerr = FALSE; /* Rewind failed */ 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate /* Return an indicator of our success */ 483*7c478bd9Sstevel@tonic-gate return (noerr); 484*7c478bd9Sstevel@tonic-gate } 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate /* 487*7c478bd9Sstevel@tonic-gate * int appendlk(key, alias) 488*7c478bd9Sstevel@tonic-gate * int key 489*7c478bd9Sstevel@tonic-gate * char *alias 490*7c478bd9Sstevel@tonic-gate * 491*7c478bd9Sstevel@tonic-gate * Write device locking information to the device locking file. 492*7c478bd9Sstevel@tonic-gate * 493*7c478bd9Sstevel@tonic-gate * Arguments: 494*7c478bd9Sstevel@tonic-gate * key Key the device is being locked on 495*7c478bd9Sstevel@tonic-gate * alias The device alias being locked 496*7c478bd9Sstevel@tonic-gate * 497*7c478bd9Sstevel@tonic-gate * Returns: int 498*7c478bd9Sstevel@tonic-gate * TRUE if we successfully appended a lock to the lock file, 499*7c478bd9Sstevel@tonic-gate * FALSE with "errno" set otherwise. 500*7c478bd9Sstevel@tonic-gate * 501*7c478bd9Sstevel@tonic-gate * Static data used: 502*7c478bd9Sstevel@tonic-gate * lkfilefd The open file descriptor for the open device 503*7c478bd9Sstevel@tonic-gate * locking file 504*7c478bd9Sstevel@tonic-gate */ 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate static int 507*7c478bd9Sstevel@tonic-gate appendlk( 508*7c478bd9Sstevel@tonic-gate int key, /* Lock key */ 509*7c478bd9Sstevel@tonic-gate char *alias) /* Alias to lock */ 510*7c478bd9Sstevel@tonic-gate { 511*7c478bd9Sstevel@tonic-gate /* Automatic data */ 512*7c478bd9Sstevel@tonic-gate struct devlks lk; /* Structure for writing a lock */ 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate /* Set up the data to write */ 515*7c478bd9Sstevel@tonic-gate lk.lk_key = key; 516*7c478bd9Sstevel@tonic-gate (void) strcpy(lk.lk_alias, alias); 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate /* Write the data, returning an indicator of our success */ 519*7c478bd9Sstevel@tonic-gate return (write(lkfilefd, &lk, 520*7c478bd9Sstevel@tonic-gate sizeof (struct devlks)) == sizeof (struct devlks)); 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate /* 524*7c478bd9Sstevel@tonic-gate * int compresslks() 525*7c478bd9Sstevel@tonic-gate * 526*7c478bd9Sstevel@tonic-gate * This function compresses the lock table, squeezing out the empty 527*7c478bd9Sstevel@tonic-gate * lock entries. 528*7c478bd9Sstevel@tonic-gate * 529*7c478bd9Sstevel@tonic-gate * Arguments: none 530*7c478bd9Sstevel@tonic-gate * 531*7c478bd9Sstevel@tonic-gate * Returns: int 532*7c478bd9Sstevel@tonic-gate * The number of non-empty entries in the table. They will be the 533*7c478bd9Sstevel@tonic-gate * first 'n' entries in the table after compression. 534*7c478bd9Sstevel@tonic-gate * 535*7c478bd9Sstevel@tonic-gate * Statics Used 536*7c478bd9Sstevel@tonic-gate * lockcount Number of locks in the device lock list 537*7c478bd9Sstevel@tonic-gate * locklist The device lock list 538*7c478bd9Sstevel@tonic-gate */ 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate static int 541*7c478bd9Sstevel@tonic-gate compresslks(void) 542*7c478bd9Sstevel@tonic-gate { 543*7c478bd9Sstevel@tonic-gate /* Automatics */ 544*7c478bd9Sstevel@tonic-gate struct devlks *avail; /* Pointer to empty slot */ 545*7c478bd9Sstevel@tonic-gate struct devlks *p; /* Running pointer to locks */ 546*7c478bd9Sstevel@tonic-gate int nlocks; /* Number of locks (up to date) */ 547*7c478bd9Sstevel@tonic-gate int i; /* Temporary counter */ 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate /* Initializations */ 550*7c478bd9Sstevel@tonic-gate p = locklist; 551*7c478bd9Sstevel@tonic-gate nlocks = lockcount; 552*7c478bd9Sstevel@tonic-gate avail = NULL; 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate /* Loop through the lock list squeezing out unused slots */ 555*7c478bd9Sstevel@tonic-gate for (i = 0; i < lockcount; i++) { 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate /* If we've found an empty slot ... */ 558*7c478bd9Sstevel@tonic-gate if (isanullstr(p->lk_alias)) { 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate /* 561*7c478bd9Sstevel@tonic-gate * If we've an empty slot to move to, just decrement 562*7c478bd9Sstevel@tonic-gate * count of used slots. Otherwise, make it the next 563*7c478bd9Sstevel@tonic-gate * available slot 564*7c478bd9Sstevel@tonic-gate */ 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate nlocks--; 567*7c478bd9Sstevel@tonic-gate if (!avail) avail = p; 568*7c478bd9Sstevel@tonic-gate } 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate else if (avail) { 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate /* 573*7c478bd9Sstevel@tonic-gate * If we found a slot in use and there's an 574*7c478bd9Sstevel@tonic-gate * available slot, move this one there 575*7c478bd9Sstevel@tonic-gate */ 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate (void) strcpy(avail->lk_alias, p->lk_alias); 578*7c478bd9Sstevel@tonic-gate avail->lk_key = p->lk_key; 579*7c478bd9Sstevel@tonic-gate avail++; 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate /* Next, please */ 583*7c478bd9Sstevel@tonic-gate p++; 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate return (nlocks); 587*7c478bd9Sstevel@tonic-gate } 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate /* 590*7c478bd9Sstevel@tonic-gate * int freelkfile() 591*7c478bd9Sstevel@tonic-gate * 592*7c478bd9Sstevel@tonic-gate * This function unlocks the OA&M device locking file. 593*7c478bd9Sstevel@tonic-gate * 594*7c478bd9Sstevel@tonic-gate * Arguments: None 595*7c478bd9Sstevel@tonic-gate * 596*7c478bd9Sstevel@tonic-gate * Returns: int 597*7c478bd9Sstevel@tonic-gate * TRUE if it successfully unlocked the file, FALSE otherwise 598*7c478bd9Sstevel@tonic-gate * with "errno" set to indicate the problem. 599*7c478bd9Sstevel@tonic-gate * 600*7c478bd9Sstevel@tonic-gate * Statics Used: 601*7c478bd9Sstevel@tonic-gate * lkinfo File-locking structure 602*7c478bd9Sstevel@tonic-gate * lkfilefd File-descriptor of the open lock file 603*7c478bd9Sstevel@tonic-gate */ 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate static int 606*7c478bd9Sstevel@tonic-gate freelkfile(void) 607*7c478bd9Sstevel@tonic-gate { 608*7c478bd9Sstevel@tonic-gate /* Automatic data */ 609*7c478bd9Sstevel@tonic-gate int noerr; /* TRUE if all's well */ 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate /* Set the action to "unlock" */ 612*7c478bd9Sstevel@tonic-gate lkinfo.l_type = F_UNLCK; 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate /* Unlock the file */ 615*7c478bd9Sstevel@tonic-gate noerr = (fcntl(lkfilefd, F_SETLK, &lkinfo) != -1); 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate /* Return an indication of our success */ 618*7c478bd9Sstevel@tonic-gate return (noerr); 619*7c478bd9Sstevel@tonic-gate } 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate /* 622*7c478bd9Sstevel@tonic-gate * int putlocks(newlist, key) 623*7c478bd9Sstevel@tonic-gate * char **newlist 624*7c478bd9Sstevel@tonic-gate * int key 625*7c478bd9Sstevel@tonic-gate * 626*7c478bd9Sstevel@tonic-gate * This function updates the file containing OA&M device locks. 627*7c478bd9Sstevel@tonic-gate * 628*7c478bd9Sstevel@tonic-gate * Arguments: 629*7c478bd9Sstevel@tonic-gate * newlist The address of the list of addresses of device 630*7c478bd9Sstevel@tonic-gate * aliases to add to the list of locked devices 631*7c478bd9Sstevel@tonic-gate * key The key on which to lock the devices 632*7c478bd9Sstevel@tonic-gate * 633*7c478bd9Sstevel@tonic-gate * Returns: int 634*7c478bd9Sstevel@tonic-gate * TRUE if all went well, FALSE otherwise with "errno" set to an 635*7c478bd9Sstevel@tonic-gate * error code that indicates the problem. 636*7c478bd9Sstevel@tonic-gate * 637*7c478bd9Sstevel@tonic-gate * Statics Used: 638*7c478bd9Sstevel@tonic-gate * lockcount Number of locks in the locked device structure 639*7c478bd9Sstevel@tonic-gate * locklist Locked device structure 640*7c478bd9Sstevel@tonic-gate */ 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate static int 643*7c478bd9Sstevel@tonic-gate putlocks( 644*7c478bd9Sstevel@tonic-gate char **newlist, /* New devices to lock */ 645*7c478bd9Sstevel@tonic-gate int key) /* Key we're locking stuff on */ 646*7c478bd9Sstevel@tonic-gate { 647*7c478bd9Sstevel@tonic-gate /* Automatic data */ 648*7c478bd9Sstevel@tonic-gate struct devlks *plk; /* Ptr into the locks list */ 649*7c478bd9Sstevel@tonic-gate char **pp; /* Pointer into the device list */ 650*7c478bd9Sstevel@tonic-gate char **qq; /* Another ptr into the dev list */ 651*7c478bd9Sstevel@tonic-gate int lkndx; /* Index into locks list */ 652*7c478bd9Sstevel@tonic-gate int noerr; /* TRUE if all's well */ 653*7c478bd9Sstevel@tonic-gate int lksintbl; /* Number of locks in the table */ 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate /* 657*7c478bd9Sstevel@tonic-gate * Look through the existing lock list, looking for holes we can 658*7c478bd9Sstevel@tonic-gate * use for the newly locked devices 659*7c478bd9Sstevel@tonic-gate */ 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate plk = locklist; 662*7c478bd9Sstevel@tonic-gate pp = newlist; 663*7c478bd9Sstevel@tonic-gate lkndx = 0; 664*7c478bd9Sstevel@tonic-gate while (*pp && (lkndx < lockcount)) { 665*7c478bd9Sstevel@tonic-gate if (isanullstr(plk->lk_alias)) { 666*7c478bd9Sstevel@tonic-gate plk->lk_key = key; 667*7c478bd9Sstevel@tonic-gate (void) strcpy(plk->lk_alias, *pp++); 668*7c478bd9Sstevel@tonic-gate } 669*7c478bd9Sstevel@tonic-gate lkndx++; 670*7c478bd9Sstevel@tonic-gate plk++; 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate /* 674*7c478bd9Sstevel@tonic-gate * Update the locks file (algorithm depends on whether we're adding 675*7c478bd9Sstevel@tonic-gate * new locks or not. May be replacing old locks!) 676*7c478bd9Sstevel@tonic-gate */ 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate if (*pp) { 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate /* 681*7c478bd9Sstevel@tonic-gate * Need to expand the locks file 682*7c478bd9Sstevel@tonic-gate * - Remember the old lock count (in existing lock buffer) 683*7c478bd9Sstevel@tonic-gate * - Count the number of new locks we need to add 684*7c478bd9Sstevel@tonic-gate * - Write out the old locks structure 685*7c478bd9Sstevel@tonic-gate * - Append locks for the newly added locks 686*7c478bd9Sstevel@tonic-gate */ 687*7c478bd9Sstevel@tonic-gate 688*7c478bd9Sstevel@tonic-gate lksintbl = lockcount; 689*7c478bd9Sstevel@tonic-gate for (qq = pp; *qq; qq++) lockcount++; 690*7c478bd9Sstevel@tonic-gate noerr = writelks(lksintbl); 691*7c478bd9Sstevel@tonic-gate while (noerr && *pp) noerr = appendlk(key, *pp++); 692*7c478bd9Sstevel@tonic-gate } else { 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate /* 695*7c478bd9Sstevel@tonic-gate * Don't need to expand the locks file. Compress the locks 696*7c478bd9Sstevel@tonic-gate * then write out the locks information 697*7c478bd9Sstevel@tonic-gate */ 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate lockcount = compresslks(); 700*7c478bd9Sstevel@tonic-gate noerr = writelks(lockcount); 701*7c478bd9Sstevel@tonic-gate } 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate /* Done. Return an indication of our success */ 704*7c478bd9Sstevel@tonic-gate return (noerr); 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate /* 708*7c478bd9Sstevel@tonic-gate * char *islocked(device) 709*7c478bd9Sstevel@tonic-gate * char *device 710*7c478bd9Sstevel@tonic-gate * 711*7c478bd9Sstevel@tonic-gate * This function checks a device to see if it is locked. If it is 712*7c478bd9Sstevel@tonic-gate * not locked, it returns the device alias. 713*7c478bd9Sstevel@tonic-gate * 714*7c478bd9Sstevel@tonic-gate * A device is not locked if the device's alias does not appear in 715*7c478bd9Sstevel@tonic-gate * the device locks table, or the key on which the device was locked 716*7c478bd9Sstevel@tonic-gate * is no longer active. 717*7c478bd9Sstevel@tonic-gate * 718*7c478bd9Sstevel@tonic-gate * Argumetns: 719*7c478bd9Sstevel@tonic-gate * char *device The device to be reserved. This can be 720*7c478bd9Sstevel@tonic-gate * a pathname to the device or a device 721*7c478bd9Sstevel@tonic-gate * alias. 722*7c478bd9Sstevel@tonic-gate * 723*7c478bd9Sstevel@tonic-gate * Returns: char * 724*7c478bd9Sstevel@tonic-gate * Returns a pointer to the device alias if it's not locked, or 725*7c478bd9Sstevel@tonic-gate * (char *) NULL if it's locked or some error occurred. 726*7c478bd9Sstevel@tonic-gate * 727*7c478bd9Sstevel@tonic-gate * Static data used: 728*7c478bd9Sstevel@tonic-gate * struct devlks *locklist Pointer to the list of device locks 729*7c478bd9Sstevel@tonic-gate * int lockcount The number of devices that are locked 730*7c478bd9Sstevel@tonic-gate */ 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate static char * 733*7c478bd9Sstevel@tonic-gate islocked(char *device) 734*7c478bd9Sstevel@tonic-gate { 735*7c478bd9Sstevel@tonic-gate /* Automatic data */ 736*7c478bd9Sstevel@tonic-gate char *alias; /* Alias of "device" */ 737*7c478bd9Sstevel@tonic-gate struct devlks *plk; /* Ptr to locking info */ 738*7c478bd9Sstevel@tonic-gate int locked; /* TRUE if device in locked list */ 739*7c478bd9Sstevel@tonic-gate int i; /* Temp counter */ 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate /* Get the device's alias */ 742*7c478bd9Sstevel@tonic-gate if (alias = devattr(device, DTAB_ALIAS)) { 743*7c478bd9Sstevel@tonic-gate 744*7c478bd9Sstevel@tonic-gate /* 745*7c478bd9Sstevel@tonic-gate * Look through the device locks to see if this device alias 746*7c478bd9Sstevel@tonic-gate * is locked 747*7c478bd9Sstevel@tonic-gate */ 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate locked = FALSE; 750*7c478bd9Sstevel@tonic-gate plk = locklist; 751*7c478bd9Sstevel@tonic-gate for (i = 0; !locked && (i < lockcount); i++) { 752*7c478bd9Sstevel@tonic-gate if (strncmp(alias, plk->lk_alias, DTAB_MXALIASLN) == 0) 753*7c478bd9Sstevel@tonic-gate locked = TRUE; 754*7c478bd9Sstevel@tonic-gate else plk++; 755*7c478bd9Sstevel@tonic-gate } 756*7c478bd9Sstevel@tonic-gate 757*7c478bd9Sstevel@tonic-gate if (locked) { 758*7c478bd9Sstevel@tonic-gate free(alias); 759*7c478bd9Sstevel@tonic-gate alias = NULL; 760*7c478bd9Sstevel@tonic-gate errno = EAGAIN; 761*7c478bd9Sstevel@tonic-gate } 762*7c478bd9Sstevel@tonic-gate 763*7c478bd9Sstevel@tonic-gate } /* devattr() failed, no such device? */ 764*7c478bd9Sstevel@tonic-gate 765*7c478bd9Sstevel@tonic-gate /* Return pointer to the device */ 766*7c478bd9Sstevel@tonic-gate return (alias); 767*7c478bd9Sstevel@tonic-gate } 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate /* 770*7c478bd9Sstevel@tonic-gate * int unreserv(key, device) 771*7c478bd9Sstevel@tonic-gate * int key 772*7c478bd9Sstevel@tonic-gate * char *device 773*7c478bd9Sstevel@tonic-gate * 774*7c478bd9Sstevel@tonic-gate * This function removes a device reservation. 775*7c478bd9Sstevel@tonic-gate * 776*7c478bd9Sstevel@tonic-gate * Arguments: 777*7c478bd9Sstevel@tonic-gate * int key The key on which the device was allocated 778*7c478bd9Sstevel@tonic-gate * char *device The device to be freed. 779*7c478bd9Sstevel@tonic-gate * 780*7c478bd9Sstevel@tonic-gate * Returns: int 781*7c478bd9Sstevel@tonic-gate * TRUE if successful, FALSE otherwise with "errno" set. 782*7c478bd9Sstevel@tonic-gate * 783*7c478bd9Sstevel@tonic-gate * Explicit "errno" settings: 784*7c478bd9Sstevel@tonic-gate * (This follows the "signal()" model which gives one the ability 785*7c478bd9Sstevel@tonic-gate * to determine if a device is allocated without having the 786*7c478bd9Sstevel@tonic-gate * permission to free it.) 787*7c478bd9Sstevel@tonic-gate * 788*7c478bd9Sstevel@tonic-gate * EINVAL The device specified was not locked 789*7c478bd9Sstevel@tonic-gate * EPERM The device specified was locked but not on the 790*7c478bd9Sstevel@tonic-gate * specified key 791*7c478bd9Sstevel@tonic-gate * 792*7c478bd9Sstevel@tonic-gate * Static data used: 793*7c478bd9Sstevel@tonic-gate * locklist List of locked devices 794*7c478bd9Sstevel@tonic-gate * lockcount Number of entries in the locked-device list 795*7c478bd9Sstevel@tonic-gate */ 796*7c478bd9Sstevel@tonic-gate 797*7c478bd9Sstevel@tonic-gate int 798*7c478bd9Sstevel@tonic-gate unreserv(int key, char *device) 799*7c478bd9Sstevel@tonic-gate { 800*7c478bd9Sstevel@tonic-gate /* Automatics */ 801*7c478bd9Sstevel@tonic-gate char *srchalias; /* Device alias to search table with */ 802*7c478bd9Sstevel@tonic-gate char *alias; /* Device's alias (from devattr()) */ 803*7c478bd9Sstevel@tonic-gate struct devlks *plk; /* Pointer to a device lock */ 804*7c478bd9Sstevel@tonic-gate int locked; /* TRUE if device currently locked */ 805*7c478bd9Sstevel@tonic-gate int noerr; /* TRUE if all's well */ 806*7c478bd9Sstevel@tonic-gate int olderrno; /* Entry value of "errno" */ 807*7c478bd9Sstevel@tonic-gate int i; /* Counter of locks */ 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate /* Initializations */ 811*7c478bd9Sstevel@tonic-gate noerr = TRUE; 812*7c478bd9Sstevel@tonic-gate 813*7c478bd9Sstevel@tonic-gate /* 814*7c478bd9Sstevel@tonic-gate * Get the device alias. If none can be found, try to free 815*7c478bd9Sstevel@tonic-gate * whatever it is that was given to us (the possibility exists 816*7c478bd9Sstevel@tonic-gate * that the device has been removed from the device table since 817*7c478bd9Sstevel@tonic-gate * it was reserved, so the device not being in the table shouldn't 818*7c478bd9Sstevel@tonic-gate * pose too much of a problem with us...) 819*7c478bd9Sstevel@tonic-gate */ 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate olderrno = errno; 822*7c478bd9Sstevel@tonic-gate if (alias = devattr(device, DTAB_ALIAS)) srchalias = alias; 823*7c478bd9Sstevel@tonic-gate else { 824*7c478bd9Sstevel@tonic-gate errno = olderrno; 825*7c478bd9Sstevel@tonic-gate srchalias = device; 826*7c478bd9Sstevel@tonic-gate } 827*7c478bd9Sstevel@tonic-gate 828*7c478bd9Sstevel@tonic-gate /* Loop through the locked-device list looking for what we've got... */ 829*7c478bd9Sstevel@tonic-gate locked = FALSE; 830*7c478bd9Sstevel@tonic-gate plk = locklist; 831*7c478bd9Sstevel@tonic-gate for (i = 0; !locked && (i < lockcount); i++) { 832*7c478bd9Sstevel@tonic-gate if (strcmp(srchalias, plk->lk_alias) == 0) 833*7c478bd9Sstevel@tonic-gate locked = TRUE; 834*7c478bd9Sstevel@tonic-gate else plk++; 835*7c478bd9Sstevel@tonic-gate } 836*7c478bd9Sstevel@tonic-gate 837*7c478bd9Sstevel@tonic-gate /* Free the alias string (if any), we don't need it anymore */ 838*7c478bd9Sstevel@tonic-gate if (alias) free(alias); 839*7c478bd9Sstevel@tonic-gate 840*7c478bd9Sstevel@tonic-gate /* If the device is locked ... */ 841*7c478bd9Sstevel@tonic-gate if (locked) { 842*7c478bd9Sstevel@tonic-gate 843*7c478bd9Sstevel@tonic-gate /* 844*7c478bd9Sstevel@tonic-gate * If it's locked on the key we've been given, free it. 845*7c478bd9Sstevel@tonic-gate * Otherwise, don't free it and set errno to EPERM 846*7c478bd9Sstevel@tonic-gate */ 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate if (plk->lk_key == key) { 849*7c478bd9Sstevel@tonic-gate plk->lk_alias[0] = '\0'; 850*7c478bd9Sstevel@tonic-gate } else { 851*7c478bd9Sstevel@tonic-gate noerr = FALSE; 852*7c478bd9Sstevel@tonic-gate errno = EPERM; 853*7c478bd9Sstevel@tonic-gate } 854*7c478bd9Sstevel@tonic-gate } else { 855*7c478bd9Sstevel@tonic-gate 856*7c478bd9Sstevel@tonic-gate /* The device isn't locked. Set errno to EINVAL */ 857*7c478bd9Sstevel@tonic-gate noerr = FALSE; 858*7c478bd9Sstevel@tonic-gate errno = EINVAL; 859*7c478bd9Sstevel@tonic-gate } 860*7c478bd9Sstevel@tonic-gate 861*7c478bd9Sstevel@tonic-gate /* Finished. Return an indication of our success */ 862*7c478bd9Sstevel@tonic-gate return (noerr); 863*7c478bd9Sstevel@tonic-gate } 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate /* 866*7c478bd9Sstevel@tonic-gate * char **devreserv(key, rsvlst) 867*7c478bd9Sstevel@tonic-gate * int key 868*7c478bd9Sstevel@tonic-gate * char **rsvlist[] 869*7c478bd9Sstevel@tonic-gate * 870*7c478bd9Sstevel@tonic-gate * The devreserv() function reserves devices known to the OA&M Device 871*7c478bd9Sstevel@tonic-gate * Management family of functions. Once a device is reserved, it can't 872*7c478bd9Sstevel@tonic-gate * be reserved by another until it is freed or the process with the 873*7c478bd9Sstevel@tonic-gate * "key" is no longer active. It returns a list aliases of the devices 874*7c478bd9Sstevel@tonic-gate * it allocated. 875*7c478bd9Sstevel@tonic-gate * 876*7c478bd9Sstevel@tonic-gate * The function attempts to reserve a single device from each of the 877*7c478bd9Sstevel@tonic-gate * lists. It scans each list sequentially until it was able to 878*7c478bd9Sstevel@tonic-gate * reserve a requested device. If it successfully reserved a device 879*7c478bd9Sstevel@tonic-gate * from each of the lists, it updates the device-locked file and 880*7c478bd9Sstevel@tonic-gate * returns those aliases to the caller. If it fails, it allocates 881*7c478bd9Sstevel@tonic-gate * nothing and returns (char **) NULL to the caller. "errno" 882*7c478bd9Sstevel@tonic-gate * indicates the error. 883*7c478bd9Sstevel@tonic-gate * 884*7c478bd9Sstevel@tonic-gate * Arguments: 885*7c478bd9Sstevel@tonic-gate * int key The key on which this device is being reserved. 886*7c478bd9Sstevel@tonic-gate * 887*7c478bd9Sstevel@tonic-gate * char **rsvlist[] The address of the list of addresses of lists 888*7c478bd9Sstevel@tonic-gate * of pointers to the devices to allocate. 889*7c478bd9Sstevel@tonic-gate * 890*7c478bd9Sstevel@tonic-gate * Returns: char ** 891*7c478bd9Sstevel@tonic-gate * A pointer to malloc()ed space containing pointers to the aliases 892*7c478bd9Sstevel@tonic-gate * of the reserved devices. The aliases are in malloc()ed space also. 893*7c478bd9Sstevel@tonic-gate * The list is terminated by the value (char *) NULL. 894*7c478bd9Sstevel@tonic-gate * 895*7c478bd9Sstevel@tonic-gate * Static Data Used: 896*7c478bd9Sstevel@tonic-gate * None directly, but functions called share hidden information 897*7c478bd9Sstevel@tonic-gate * that really isn't of concern to devreserv(). 898*7c478bd9Sstevel@tonic-gate */ 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate char ** 901*7c478bd9Sstevel@tonic-gate devreserv( 902*7c478bd9Sstevel@tonic-gate int key, /* Key to reserve device on */ 903*7c478bd9Sstevel@tonic-gate char **rsvlst[]) /* List of lists of devs to reserve */ 904*7c478bd9Sstevel@tonic-gate { 905*7c478bd9Sstevel@tonic-gate char ***ppp; /* Ptr to current list in rsvlist */ 906*7c478bd9Sstevel@tonic-gate char **pp; /* Ptr to current item in list */ 907*7c478bd9Sstevel@tonic-gate char **qq; /* Ptr to item in rtnlist */ 908*7c478bd9Sstevel@tonic-gate char **rr; /* Ptr to item in aliases */ 909*7c478bd9Sstevel@tonic-gate char **aliases; /* List of aliases allocated */ 910*7c478bd9Sstevel@tonic-gate char **rtnlist; /* Ptr to buf to return */ 911*7c478bd9Sstevel@tonic-gate char *alias; /* Alias of dev to reserve */ 912*7c478bd9Sstevel@tonic-gate int noerr; /* TRUE if all's well */ 913*7c478bd9Sstevel@tonic-gate int olderrno; /* Old value of errno */ 914*7c478bd9Sstevel@tonic-gate int gotone; /* TRUE if unreserved dev found */ 915*7c478bd9Sstevel@tonic-gate int foundone; /* Found a valid device in the list */ 916*7c478bd9Sstevel@tonic-gate int ndevs; /* # of devs to reserve */ 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate noerr = TRUE; 919*7c478bd9Sstevel@tonic-gate ppp = rsvlst; 920*7c478bd9Sstevel@tonic-gate olderrno = errno; 921*7c478bd9Sstevel@tonic-gate for (ndevs = 0; *ppp++; ndevs++) 922*7c478bd9Sstevel@tonic-gate ; 923*7c478bd9Sstevel@tonic-gate if (rtnlist = malloc((ndevs+1)*sizeof (char **))) { 924*7c478bd9Sstevel@tonic-gate if (aliases = malloc((ndevs+1)*sizeof (char **))) { 925*7c478bd9Sstevel@tonic-gate if (getlocks()) { 926*7c478bd9Sstevel@tonic-gate qq = rtnlist; 927*7c478bd9Sstevel@tonic-gate rr = aliases; 928*7c478bd9Sstevel@tonic-gate 929*7c478bd9Sstevel@tonic-gate /* Go through the lists of devices we're to reserve */ 930*7c478bd9Sstevel@tonic-gate 931*7c478bd9Sstevel@tonic-gate for (ppp = rsvlst; noerr && *ppp; ppp++) { 932*7c478bd9Sstevel@tonic-gate 933*7c478bd9Sstevel@tonic-gate /* Try to reserve a device from each list */ 934*7c478bd9Sstevel@tonic-gate gotone = FALSE; 935*7c478bd9Sstevel@tonic-gate foundone = FALSE; 936*7c478bd9Sstevel@tonic-gate for (pp = *ppp; noerr && !gotone && *pp; pp++) { 937*7c478bd9Sstevel@tonic-gate 938*7c478bd9Sstevel@tonic-gate /* 939*7c478bd9Sstevel@tonic-gate * Check the next device in the list. If islocked() 940*7c478bd9Sstevel@tonic-gate * returns that device's alias, it's ours to have 941*7c478bd9Sstevel@tonic-gate */ 942*7c478bd9Sstevel@tonic-gate 943*7c478bd9Sstevel@tonic-gate if (alias = islocked(*pp)) { 944*7c478bd9Sstevel@tonic-gate gotone = TRUE; 945*7c478bd9Sstevel@tonic-gate foundone = TRUE; 946*7c478bd9Sstevel@tonic-gate if (*qq = malloc(strlen(*pp)+1)) { 947*7c478bd9Sstevel@tonic-gate (void) strcpy(*qq++, *pp); 948*7c478bd9Sstevel@tonic-gate *rr++ = alias; 949*7c478bd9Sstevel@tonic-gate } else { 950*7c478bd9Sstevel@tonic-gate *rr = NULL; 951*7c478bd9Sstevel@tonic-gate noerr = FALSE; 952*7c478bd9Sstevel@tonic-gate } 953*7c478bd9Sstevel@tonic-gate } else { 954*7c478bd9Sstevel@tonic-gate if (errno == EAGAIN) { 955*7c478bd9Sstevel@tonic-gate foundone = TRUE; 956*7c478bd9Sstevel@tonic-gate errno = olderrno; 957*7c478bd9Sstevel@tonic-gate } else if (errno == ENODEV) errno = olderrno; 958*7c478bd9Sstevel@tonic-gate else { 959*7c478bd9Sstevel@tonic-gate noerr = FALSE; 960*7c478bd9Sstevel@tonic-gate *rr = NULL; 961*7c478bd9Sstevel@tonic-gate } 962*7c478bd9Sstevel@tonic-gate } 963*7c478bd9Sstevel@tonic-gate } 964*7c478bd9Sstevel@tonic-gate 965*7c478bd9Sstevel@tonic-gate /* 966*7c478bd9Sstevel@tonic-gate * If no device from the list could be reserved, 967*7c478bd9Sstevel@tonic-gate * we've failed 968*7c478bd9Sstevel@tonic-gate */ 969*7c478bd9Sstevel@tonic-gate 970*7c478bd9Sstevel@tonic-gate if (noerr && !gotone) { 971*7c478bd9Sstevel@tonic-gate noerr = FALSE; 972*7c478bd9Sstevel@tonic-gate if (!foundone) errno = ENODEV; 973*7c478bd9Sstevel@tonic-gate else errno = EAGAIN; 974*7c478bd9Sstevel@tonic-gate *qq = NULL; 975*7c478bd9Sstevel@tonic-gate *rr = NULL; 976*7c478bd9Sstevel@tonic-gate } 977*7c478bd9Sstevel@tonic-gate 978*7c478bd9Sstevel@tonic-gate } /* End of loop through lists loop */ 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate /* 981*7c478bd9Sstevel@tonic-gate * If all went well, update lock file. 982*7c478bd9Sstevel@tonic-gate * Then, free locks 983*7c478bd9Sstevel@tonic-gate */ 984*7c478bd9Sstevel@tonic-gate 985*7c478bd9Sstevel@tonic-gate if (noerr) { 986*7c478bd9Sstevel@tonic-gate *qq = NULL; 987*7c478bd9Sstevel@tonic-gate *rr = NULL; 988*7c478bd9Sstevel@tonic-gate if (!putlocks(aliases, key)) noerr = FALSE; 989*7c478bd9Sstevel@tonic-gate } 990*7c478bd9Sstevel@tonic-gate 991*7c478bd9Sstevel@tonic-gate /* Free resources */ 992*7c478bd9Sstevel@tonic-gate if (!freelkfile()) noerr = FALSE; 993*7c478bd9Sstevel@tonic-gate if (_closelkfile() != 0) noerr = FALSE; 994*7c478bd9Sstevel@tonic-gate for (qq = aliases; *qq; qq++) free(*qq); 995*7c478bd9Sstevel@tonic-gate if (!noerr) 996*7c478bd9Sstevel@tonic-gate for (pp = rtnlist; *pp; pp++) 997*7c478bd9Sstevel@tonic-gate free(*pp); 998*7c478bd9Sstevel@tonic-gate 999*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* Error getting locks */ 1000*7c478bd9Sstevel@tonic-gate 1001*7c478bd9Sstevel@tonic-gate free(aliases); 1002*7c478bd9Sstevel@tonic-gate 1003*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* Malloc() for alias list failed */ 1004*7c478bd9Sstevel@tonic-gate 1005*7c478bd9Sstevel@tonic-gate if (!noerr) { 1006*7c478bd9Sstevel@tonic-gate free(rtnlist); 1007*7c478bd9Sstevel@tonic-gate rtnlist = NULL; 1008*7c478bd9Sstevel@tonic-gate } 1009*7c478bd9Sstevel@tonic-gate 1010*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* malloc() failed */ 1011*7c478bd9Sstevel@tonic-gate 1012*7c478bd9Sstevel@tonic-gate /* Return list or an indication of an error */ 1013*7c478bd9Sstevel@tonic-gate return (noerr ? rtnlist : NULL); 1014*7c478bd9Sstevel@tonic-gate } 1015*7c478bd9Sstevel@tonic-gate 1016*7c478bd9Sstevel@tonic-gate /* 1017*7c478bd9Sstevel@tonic-gate * int devfree(key, device) 1018*7c478bd9Sstevel@tonic-gate * int key 1019*7c478bd9Sstevel@tonic-gate * char *device 1020*7c478bd9Sstevel@tonic-gate * 1021*7c478bd9Sstevel@tonic-gate * This function unreserves (frees) the given device. It returns 1022*7c478bd9Sstevel@tonic-gate * an indication of success with "errno" containing information about 1023*7c478bd9Sstevel@tonic-gate * a failure. 1024*7c478bd9Sstevel@tonic-gate * 1025*7c478bd9Sstevel@tonic-gate * Arguments: 1026*7c478bd9Sstevel@tonic-gate * int key The key that the device is locked on 1027*7c478bd9Sstevel@tonic-gate * char *device The device (alias, pathname to, etc.) to be freed. 1028*7c478bd9Sstevel@tonic-gate * 1029*7c478bd9Sstevel@tonic-gate * Returns: int 1030*7c478bd9Sstevel@tonic-gate * 0 if successful, -1 with "errno" set if fails. 1031*7c478bd9Sstevel@tonic-gate */ 1032*7c478bd9Sstevel@tonic-gate 1033*7c478bd9Sstevel@tonic-gate int 1034*7c478bd9Sstevel@tonic-gate devfree( 1035*7c478bd9Sstevel@tonic-gate int key, /* Key device is locked on */ 1036*7c478bd9Sstevel@tonic-gate char *device) /* Device to free */ 1037*7c478bd9Sstevel@tonic-gate { 1038*7c478bd9Sstevel@tonic-gate /* Automatics */ 1039*7c478bd9Sstevel@tonic-gate int noerr; 1040*7c478bd9Sstevel@tonic-gate 1041*7c478bd9Sstevel@tonic-gate /* Initializations */ 1042*7c478bd9Sstevel@tonic-gate noerr = TRUE; 1043*7c478bd9Sstevel@tonic-gate 1044*7c478bd9Sstevel@tonic-gate /* Get the locks, locking the lock file */ 1045*7c478bd9Sstevel@tonic-gate if (getlocks()) { 1046*7c478bd9Sstevel@tonic-gate 1047*7c478bd9Sstevel@tonic-gate /* Attempt to unreserve the device */ 1048*7c478bd9Sstevel@tonic-gate if (unreserv(key, device)) { 1049*7c478bd9Sstevel@tonic-gate 1050*7c478bd9Sstevel@tonic-gate /* 1051*7c478bd9Sstevel@tonic-gate * Successful. Compress the lock structure and 1052*7c478bd9Sstevel@tonic-gate * write the new locks 1053*7c478bd9Sstevel@tonic-gate */ 1054*7c478bd9Sstevel@tonic-gate 1055*7c478bd9Sstevel@tonic-gate lockcount = compresslks(); 1056*7c478bd9Sstevel@tonic-gate if (!writelks(lockcount)) noerr = FALSE; 1057*7c478bd9Sstevel@tonic-gate 1058*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* Couldn't unreserve the device */ 1059*7c478bd9Sstevel@tonic-gate 1060*7c478bd9Sstevel@tonic-gate /* Unlock and close the locks file */ 1061*7c478bd9Sstevel@tonic-gate if (!freelkfile()) noerr = FALSE; 1062*7c478bd9Sstevel@tonic-gate if (_closelkfile() != 0) noerr = FALSE; 1063*7c478bd9Sstevel@tonic-gate 1064*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate /* Return 0 if successful, something else otherwise */ 1067*7c478bd9Sstevel@tonic-gate return (noerr? 0 : -1); 1068*7c478bd9Sstevel@tonic-gate } 1069*7c478bd9Sstevel@tonic-gate 1070*7c478bd9Sstevel@tonic-gate /* 1071*7c478bd9Sstevel@tonic-gate * struct reservdev **reservdev() 1072*7c478bd9Sstevel@tonic-gate * 1073*7c478bd9Sstevel@tonic-gate * This function returns the list of reserved devices 1074*7c478bd9Sstevel@tonic-gate * along with the key on which those devices were locked. 1075*7c478bd9Sstevel@tonic-gate * 1076*7c478bd9Sstevel@tonic-gate * Arguments: None. 1077*7c478bd9Sstevel@tonic-gate * 1078*7c478bd9Sstevel@tonic-gate * Returns: struct reservdev ** 1079*7c478bd9Sstevel@tonic-gate * Pointer to the list of pointers to structures describing 1080*7c478bd9Sstevel@tonic-gate * the reserved devices, or (struct reservdev **) NULL if an 1081*7c478bd9Sstevel@tonic-gate * error occurred. The list of pointers is terminated by 1082*7c478bd9Sstevel@tonic-gate * (struct reservdev *) NULL. 1083*7c478bd9Sstevel@tonic-gate * 1084*7c478bd9Sstevel@tonic-gate * Statics Used: 1085*7c478bd9Sstevel@tonic-gate * locklist List of reserved devices 1086*7c478bd9Sstevel@tonic-gate * lockcount Number of items in the reserved-devices list 1087*7c478bd9Sstevel@tonic-gate */ 1088*7c478bd9Sstevel@tonic-gate 1089*7c478bd9Sstevel@tonic-gate struct reservdev ** 1090*7c478bd9Sstevel@tonic-gate reservdev(void) 1091*7c478bd9Sstevel@tonic-gate { 1092*7c478bd9Sstevel@tonic-gate /* Automatics */ 1093*7c478bd9Sstevel@tonic-gate struct reservdev **rtnlist; /* Ptr to return list */ 1094*7c478bd9Sstevel@tonic-gate struct devlks *p; /* Running ptr, locklist */ 1095*7c478bd9Sstevel@tonic-gate struct reservdev **q; /* Running ptr, rtnlist */ 1096*7c478bd9Sstevel@tonic-gate char *r; /* Temp ptr to char */ 1097*7c478bd9Sstevel@tonic-gate size_t bufsiz; /* Size of buffer to alloc */ 1098*7c478bd9Sstevel@tonic-gate int noerr; /* TRUE if all's well */ 1099*7c478bd9Sstevel@tonic-gate int i; /* Lock counter */ 1100*7c478bd9Sstevel@tonic-gate 1101*7c478bd9Sstevel@tonic-gate 1102*7c478bd9Sstevel@tonic-gate /* Initializations */ 1103*7c478bd9Sstevel@tonic-gate noerr = TRUE; 1104*7c478bd9Sstevel@tonic-gate 1105*7c478bd9Sstevel@tonic-gate /* Open the lock file ... */ 1106*7c478bd9Sstevel@tonic-gate if (_openlkfile()) { 1107*7c478bd9Sstevel@tonic-gate 1108*7c478bd9Sstevel@tonic-gate /* Put a read-lock on the lock-file ... */ 1109*7c478bd9Sstevel@tonic-gate if (locklkfile(F_RDLCK)) { 1110*7c478bd9Sstevel@tonic-gate 1111*7c478bd9Sstevel@tonic-gate /* Read the locks ... */ 1112*7c478bd9Sstevel@tonic-gate if (readlocks()) { 1113*7c478bd9Sstevel@tonic-gate 1114*7c478bd9Sstevel@tonic-gate /* Alloc space for the return list */ 1115*7c478bd9Sstevel@tonic-gate bufsiz = (lockcount+1) * sizeof (struct reservdev *); 1116*7c478bd9Sstevel@tonic-gate if (rtnlist = malloc(bufsiz)) { 1117*7c478bd9Sstevel@tonic-gate 1118*7c478bd9Sstevel@tonic-gate /* Build the return list from the lock list */ 1119*7c478bd9Sstevel@tonic-gate p = locklist; 1120*7c478bd9Sstevel@tonic-gate q = rtnlist; 1121*7c478bd9Sstevel@tonic-gate for (i = 0; noerr && (i < lockcount); i++) { 1122*7c478bd9Sstevel@tonic-gate if (*q = malloc(sizeof (struct reservdev))) { 1123*7c478bd9Sstevel@tonic-gate if (r = malloc(strlen(p->lk_alias)+1)) { 1124*7c478bd9Sstevel@tonic-gate (*q)->devname = strcpy(r, p->lk_alias); 1125*7c478bd9Sstevel@tonic-gate (*q)->key = p->lk_key; 1126*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* malloc() error */ 1127*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* malloc() error */ 1128*7c478bd9Sstevel@tonic-gate p++; 1129*7c478bd9Sstevel@tonic-gate q++; 1130*7c478bd9Sstevel@tonic-gate } 1131*7c478bd9Sstevel@tonic-gate 1132*7c478bd9Sstevel@tonic-gate /* 1133*7c478bd9Sstevel@tonic-gate * If no error, terminate the list. Otherwise, free 1134*7c478bd9Sstevel@tonic-gate * the space we've allocated 1135*7c478bd9Sstevel@tonic-gate */ 1136*7c478bd9Sstevel@tonic-gate 1137*7c478bd9Sstevel@tonic-gate if (noerr) *q = NULL; 1138*7c478bd9Sstevel@tonic-gate else { 1139*7c478bd9Sstevel@tonic-gate for (q = rtnlist; *q; q++) { 1140*7c478bd9Sstevel@tonic-gate free((*q)->devname); 1141*7c478bd9Sstevel@tonic-gate free(*q); 1142*7c478bd9Sstevel@tonic-gate } 1143*7c478bd9Sstevel@tonic-gate free(rtnlist); 1144*7c478bd9Sstevel@tonic-gate } 1145*7c478bd9Sstevel@tonic-gate 1146*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* Couldn't malloc() list space */ 1147*7c478bd9Sstevel@tonic-gate 1148*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* Problem reading locks */ 1149*7c478bd9Sstevel@tonic-gate 1150*7c478bd9Sstevel@tonic-gate /* Free the lock file */ 1151*7c478bd9Sstevel@tonic-gate (void) freelkfile(); 1152*7c478bd9Sstevel@tonic-gate 1153*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* Error locking the lock file */ 1154*7c478bd9Sstevel@tonic-gate 1155*7c478bd9Sstevel@tonic-gate /* Close the lock file */ 1156*7c478bd9Sstevel@tonic-gate (void) _closelkfile(); 1157*7c478bd9Sstevel@tonic-gate 1158*7c478bd9Sstevel@tonic-gate } else noerr = FALSE; /* Error opening the lock file */ 1159*7c478bd9Sstevel@tonic-gate 1160*7c478bd9Sstevel@tonic-gate /* Return ptr to list of locks or NULL if an error has occurred */ 1161*7c478bd9Sstevel@tonic-gate return (noerr ? rtnlist : NULL); 1162*7c478bd9Sstevel@tonic-gate } 1163