1*5c51f124SMoriah Waterland /* 2*5c51f124SMoriah Waterland * CDDL HEADER START 3*5c51f124SMoriah Waterland * 4*5c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 5*5c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 6*5c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 7*5c51f124SMoriah Waterland * 8*5c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 10*5c51f124SMoriah Waterland * See the License for the specific language governing permissions 11*5c51f124SMoriah Waterland * and limitations under the License. 12*5c51f124SMoriah Waterland * 13*5c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 14*5c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 16*5c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 17*5c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 18*5c51f124SMoriah Waterland * 19*5c51f124SMoriah Waterland * CDDL HEADER END 20*5c51f124SMoriah Waterland */ 21*5c51f124SMoriah Waterland 22*5c51f124SMoriah Waterland /* 23*5c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*5c51f124SMoriah Waterland * Use is subject to license terms. 25*5c51f124SMoriah Waterland */ 26*5c51f124SMoriah Waterland 27*5c51f124SMoriah Waterland 28*5c51f124SMoriah Waterland /* 29*5c51f124SMoriah Waterland * Module: lock.c 30*5c51f124SMoriah Waterland * Program: pkgadm (/usr/bin/pkgadm) 31*5c51f124SMoriah Waterland * Synopsis: implements the zone/package administrative lock interface 32*5c51f124SMoriah Waterland * Public methods: 33*5c51f124SMoriah Waterland * admin_lock 34*5c51f124SMoriah Waterland * Usage: 35*5c51f124SMoriah Waterland * Acquire: -a [ -e | -s ] [ -o obj ] [ -k key ] [ -R root ] [ -q ] \ 36*5c51f124SMoriah Waterland * [ -w ] [ -W timeout ] 37*5c51f124SMoriah Waterland * Release: -r -o object -k key [ -R altRoot ] [ -q ] 38*5c51f124SMoriah Waterland * Status: [ -o object ] [ -k key ] [ -R altRoot ] [ -q ] 39*5c51f124SMoriah Waterland */ 40*5c51f124SMoriah Waterland 41*5c51f124SMoriah Waterland /* enable extentions to standard Unix libraries */ 42*5c51f124SMoriah Waterland 43*5c51f124SMoriah Waterland #define __EXTENSIONS__ 44*5c51f124SMoriah Waterland 45*5c51f124SMoriah Waterland /* unix system includes */ 46*5c51f124SMoriah Waterland 47*5c51f124SMoriah Waterland #include <stdio.h> 48*5c51f124SMoriah Waterland #include <stdarg.h> 49*5c51f124SMoriah Waterland #include <stdlib.h> 50*5c51f124SMoriah Waterland #include <string.h> 51*5c51f124SMoriah Waterland #include <strings.h> 52*5c51f124SMoriah Waterland #include <sys/types.h> 53*5c51f124SMoriah Waterland #include <wait.h> 54*5c51f124SMoriah Waterland #include <sys/stat.h> 55*5c51f124SMoriah Waterland #include <fcntl.h> 56*5c51f124SMoriah Waterland #include <unistd.h> 57*5c51f124SMoriah Waterland #include <signal.h> 58*5c51f124SMoriah Waterland #include <locale.h> 59*5c51f124SMoriah Waterland #include <libgen.h> 60*5c51f124SMoriah Waterland #include <sys/param.h> 61*5c51f124SMoriah Waterland #include <openssl/bio.h> 62*5c51f124SMoriah Waterland #include <errno.h> 63*5c51f124SMoriah Waterland #include <assert.h> 64*5c51f124SMoriah Waterland #include <time.h> 65*5c51f124SMoriah Waterland #include <fnmatch.h> 66*5c51f124SMoriah Waterland #include <zone.h> 67*5c51f124SMoriah Waterland 68*5c51f124SMoriah Waterland /* local includes */ 69*5c51f124SMoriah Waterland 70*5c51f124SMoriah Waterland #include <libinst.h> 71*5c51f124SMoriah Waterland #include <pkglib.h> 72*5c51f124SMoriah Waterland #include <pkgerr.h> 73*5c51f124SMoriah Waterland #include <keystore.h> 74*5c51f124SMoriah Waterland #include "pkgadm.h" 75*5c51f124SMoriah Waterland #include "pkgadm_msgs.h" 76*5c51f124SMoriah Waterland 77*5c51f124SMoriah Waterland /* definition and conversion of sleep units */ 78*5c51f124SMoriah Waterland 79*5c51f124SMoriah Waterland #define SECONDS(x) ((unsigned int)(x)) 80*5c51f124SMoriah Waterland #define MINUTES(x) ((unsigned int)(seconds(x)*60)) 81*5c51f124SMoriah Waterland 82*5c51f124SMoriah Waterland /* define how waits are timed */ 83*5c51f124SMoriah Waterland 84*5c51f124SMoriah Waterland #define WAITER_INITIAL SECONDS(1) 85*5c51f124SMoriah Waterland #define WAITER_MAX SECONDS(60) 86*5c51f124SMoriah Waterland #define WAITER_NEXT(x) ((x)*2) 87*5c51f124SMoriah Waterland 88*5c51f124SMoriah Waterland typedef unsigned int WAITER_T; 89*5c51f124SMoriah Waterland 90*5c51f124SMoriah Waterland /* 91*5c51f124SMoriah Waterland * The administrative lock file resides in /tmp 92*5c51f124SMoriah Waterland * It does not survive a reboot 93*5c51f124SMoriah Waterland * It consists of fixed length records 94*5c51f124SMoriah Waterland * Each record has the following information: 95*5c51f124SMoriah Waterland * record number - record position within the lock file 96*5c51f124SMoriah Waterland * lock count - number of lock holders maintaining this lock 97*5c51f124SMoriah Waterland * lock object - object being locked 98*5c51f124SMoriah Waterland * lock key - key needed to manipulate existing lock 99*5c51f124SMoriah Waterland * lock exclusive - is the lock exclusive (single locker only) 100*5c51f124SMoriah Waterland */ 101*5c51f124SMoriah Waterland 102*5c51f124SMoriah Waterland #define LOCK_OBJECT_MAXLEN 512-1 103*5c51f124SMoriah Waterland #define LOCK_KEY_MAXLEN 37 104*5c51f124SMoriah Waterland 105*5c51f124SMoriah Waterland #define LOCK_DIRECTORY "/tmp" 106*5c51f124SMoriah Waterland 107*5c51f124SMoriah Waterland /* 108*5c51f124SMoriah Waterland * this is the "well known name" of the lock file that is used by the 109*5c51f124SMoriah Waterland * package, patch, and zone administration commands to synchronize their 110*5c51f124SMoriah Waterland * various efforts - it must live in a temporary directory that is cleared 111*5c51f124SMoriah Waterland * on system reboot but it is NOT a temporary file in that it survives 112*5c51f124SMoriah Waterland * the process that creates and updates it - if the format of the lock 113*5c51f124SMoriah Waterland * file ever changes, this path should be updated with a later "uuid" 114*5c51f124SMoriah Waterland * so that previous (incompatible) pkgadm's will not use the later data. 115*5c51f124SMoriah Waterland */ 116*5c51f124SMoriah Waterland 117*5c51f124SMoriah Waterland #define LOCK_FILENAME \ 118*5c51f124SMoriah Waterland "/tmp/.ai.pkg.zone.lock-afdb66cf-1dd1-11b2-a049-000d560ddc3e" 119*5c51f124SMoriah Waterland 120*5c51f124SMoriah Waterland /* mode to use for LOCK_FILENAME */ 121*5c51f124SMoriah Waterland 122*5c51f124SMoriah Waterland #define LOCK_FILEMODE \ 123*5c51f124SMoriah Waterland (S_ISGID|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) 124*5c51f124SMoriah Waterland 125*5c51f124SMoriah Waterland #define LOCK_SLEEP_INTERVAL SECONDS(2) 126*5c51f124SMoriah Waterland 127*5c51f124SMoriah Waterland /* lock contents types */ 128*5c51f124SMoriah Waterland 129*5c51f124SMoriah Waterland typedef unsigned long RECORDNUM_T; 130*5c51f124SMoriah Waterland 131*5c51f124SMoriah Waterland #define RECORDNUM_NONE 0xFFFFFFFF 132*5c51f124SMoriah Waterland 133*5c51f124SMoriah Waterland /* actual lock data */ 134*5c51f124SMoriah Waterland 135*5c51f124SMoriah Waterland struct _adminLock 136*5c51f124SMoriah Waterland { 137*5c51f124SMoriah Waterland RECORDNUM_T lockRecordNum; 138*5c51f124SMoriah Waterland unsigned long lockCount; 139*5c51f124SMoriah Waterland unsigned long lockExclusive; 140*5c51f124SMoriah Waterland pid_t lockPid; 141*5c51f124SMoriah Waterland zoneid_t lockZoneId; 142*5c51f124SMoriah Waterland char lockKey[LOCK_KEY_MAXLEN+1]; 143*5c51f124SMoriah Waterland char lockObject[LOCK_OBJECT_MAXLEN+1]; 144*5c51f124SMoriah Waterland }; 145*5c51f124SMoriah Waterland 146*5c51f124SMoriah Waterland typedef struct _adminLock ADMINLOCK_T; 147*5c51f124SMoriah Waterland 148*5c51f124SMoriah Waterland /* size of an individual "lock" */ 149*5c51f124SMoriah Waterland 150*5c51f124SMoriah Waterland #define LOCK_SIZE sizeof (ADMINLOCK_T) 151*5c51f124SMoriah Waterland 152*5c51f124SMoriah Waterland /* union to allow lock to be accessed as raw or structured data */ 153*5c51f124SMoriah Waterland 154*5c51f124SMoriah Waterland union _lockRecord 155*5c51f124SMoriah Waterland { 156*5c51f124SMoriah Waterland char _lrLockData[LOCK_SIZE]; 157*5c51f124SMoriah Waterland ADMINLOCK_T _lrLock; 158*5c51f124SMoriah Waterland }; 159*5c51f124SMoriah Waterland 160*5c51f124SMoriah Waterland typedef union _lockRecord LOCK_T; 161*5c51f124SMoriah Waterland 162*5c51f124SMoriah Waterland /* return codes from "_findLock" */ 163*5c51f124SMoriah Waterland 164*5c51f124SMoriah Waterland typedef unsigned long FINDLOCK_T; 165*5c51f124SMoriah Waterland 166*5c51f124SMoriah Waterland #define FINDLOCK_FOUND ((FINDLOCK_T)0) 167*5c51f124SMoriah Waterland #define FINDLOCK_ERROR ((FINDLOCK_T)-1) 168*5c51f124SMoriah Waterland #define FINDLOCK_NOTFOUND ((FINDLOCK_T)-2) 169*5c51f124SMoriah Waterland #define FINDLOCK_KEYMISMATCH ((FINDLOCK_T)-3) 170*5c51f124SMoriah Waterland #define FINDLOCK_LOCKED ((FINDLOCK_T)-4) 171*5c51f124SMoriah Waterland #define FINDLOCK_NOTLOCKED ((FINDLOCK_T)-5) 172*5c51f124SMoriah Waterland #define FINDLOCK_LOCKACQUIRED ((FINDLOCK_T)-6) 173*5c51f124SMoriah Waterland 174*5c51f124SMoriah Waterland /* 175*5c51f124SMoriah Waterland * Forward declarations 176*5c51f124SMoriah Waterland */ 177*5c51f124SMoriah Waterland 178*5c51f124SMoriah Waterland /* local main function implementation methods */ 179*5c51f124SMoriah Waterland 180*5c51f124SMoriah Waterland static FINDLOCK_T lock_acquire(LOCK_T *a_lock, int *a_fd, char *a_root, 181*5c51f124SMoriah Waterland char *a_key, char *a_object, int a_quiet, 182*5c51f124SMoriah Waterland int a_wait, long a_timeout, int a_exclusive, 183*5c51f124SMoriah Waterland char *a_altRoot, pid_t a_pid, zoneid_t a_zid); 184*5c51f124SMoriah Waterland static int lock_release(int a_fd, char *a_key, char *a_object, 185*5c51f124SMoriah Waterland int a_quiet); 186*5c51f124SMoriah Waterland static int lock_status(int a_fd, char *a_key, char *a_object, 187*5c51f124SMoriah Waterland int a_quiet); 188*5c51f124SMoriah Waterland 189*5c51f124SMoriah Waterland /* local utility functions */ 190*5c51f124SMoriah Waterland 191*5c51f124SMoriah Waterland static int _lockMatch(char *a_s1Lock, char *a_s2Lock); 192*5c51f124SMoriah Waterland static FINDLOCK_T _findLock(LOCK_T *a_theLock, RECORDNUM_T *r_recordNum, 193*5c51f124SMoriah Waterland int a_fd, char *a_object, char *a_key); 194*5c51f124SMoriah Waterland static int _decrementLockCount(int a_fd, LOCK_T *a_theLock); 195*5c51f124SMoriah Waterland static int _addLock(char *r_key, int a_fd, char *a_object, 196*5c51f124SMoriah Waterland int a_exclusive, pid_t a_pid, zoneid_t a_zid); 197*5c51f124SMoriah Waterland static int _incrementLockCount(int a_fd, LOCK_T *a_theLock); 198*5c51f124SMoriah Waterland static FINDLOCK_T _lock_acquire(LOCK_T *a_lock, int a_fd, char *a_key, 199*5c51f124SMoriah Waterland char *a_object, int a_quiet, int a_exclusive, 200*5c51f124SMoriah Waterland pid_t a_pid, zoneid_t a_zid); 201*5c51f124SMoriah Waterland static char *_getUniqueId(void); 202*5c51f124SMoriah Waterland static int _openLockFile(char *a_root); 203*5c51f124SMoriah Waterland static void sighup_handler(int a_signo); 204*5c51f124SMoriah Waterland static void sigint_handler(int a_signo); 205*5c51f124SMoriah Waterland static boolean_t _validateLock(int a_fd, LOCK_T *a_theLock, int a_quiet); 206*5c51f124SMoriah Waterland 207*5c51f124SMoriah Waterland static int signal_received = 0; 208*5c51f124SMoriah Waterland 209*5c51f124SMoriah Waterland /* 210*5c51f124SMoriah Waterland * main methods with external entry points 211*5c51f124SMoriah Waterland */ 212*5c51f124SMoriah Waterland 213*5c51f124SMoriah Waterland /* 214*5c51f124SMoriah Waterland * Name: admin_lock 215*5c51f124SMoriah Waterland * Synopsis: main entry point for pkgadm "lock" subcommand 216*5c51f124SMoriah Waterland * Description: Control zone/package administrative locking 217*5c51f124SMoriah Waterland * Returns: 0 on success, non-zero otherwise. 218*5c51f124SMoriah Waterland */ 219*5c51f124SMoriah Waterland 220*5c51f124SMoriah Waterland int 221*5c51f124SMoriah Waterland admin_lock(int argc, char **argv) 222*5c51f124SMoriah Waterland { 223*5c51f124SMoriah Waterland FINDLOCK_T tResult; 224*5c51f124SMoriah Waterland LOCK_T theLock; 225*5c51f124SMoriah Waterland char *RFlag = "/"; /* altRoot */ 226*5c51f124SMoriah Waterland char *endptr; 227*5c51f124SMoriah Waterland char *kFlag = ""; /* key */ 228*5c51f124SMoriah Waterland char *oFlag = ""; /* object */ 229*5c51f124SMoriah Waterland char *p; 230*5c51f124SMoriah Waterland char c; 231*5c51f124SMoriah Waterland int aFlag = 0; /* acquire lock */ 232*5c51f124SMoriah Waterland int eFlag = 0; /* exclusive lock */ 233*5c51f124SMoriah Waterland int exclusive = 1; /* exclusive vs shared lock */ 234*5c51f124SMoriah Waterland int fd; 235*5c51f124SMoriah Waterland int qFlag = 0; /* quiet */ 236*5c51f124SMoriah Waterland int rFlag = 0; /* release lock */ 237*5c51f124SMoriah Waterland int result; 238*5c51f124SMoriah Waterland int sFlag = 0; /* shared lock */ 239*5c51f124SMoriah Waterland int tFlag = 0; /* test comparison */ 240*5c51f124SMoriah Waterland int wFlag = 0; /* wait */ 241*5c51f124SMoriah Waterland long WFlag = 0; /* wait timeout */ 242*5c51f124SMoriah Waterland pid_t pFlag = 0; /* process # */ 243*5c51f124SMoriah Waterland struct sigaction nact; 244*5c51f124SMoriah Waterland struct sigaction oact; 245*5c51f124SMoriah Waterland void (*funcSighup)(); 246*5c51f124SMoriah Waterland void (*funcSigint)(); 247*5c51f124SMoriah Waterland zoneid_t zFlag = -1; /* zone i.d. */ 248*5c51f124SMoriah Waterland 249*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":aek:o:p:qrR:stwW:z:")) != EOF) { 250*5c51f124SMoriah Waterland switch (c) { 251*5c51f124SMoriah Waterland case 'a': /* acquire lock */ 252*5c51f124SMoriah Waterland aFlag++; 253*5c51f124SMoriah Waterland break; 254*5c51f124SMoriah Waterland 255*5c51f124SMoriah Waterland case 'e': /* exclusive lock */ 256*5c51f124SMoriah Waterland eFlag++; 257*5c51f124SMoriah Waterland break; 258*5c51f124SMoriah Waterland 259*5c51f124SMoriah Waterland case 'k': /* lock-key */ 260*5c51f124SMoriah Waterland kFlag = optarg; 261*5c51f124SMoriah Waterland if (strlen(optarg) > LOCK_KEY_MAXLEN) { 262*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, 263*5c51f124SMoriah Waterland MSG_LOCK_kARG_TOOLONG, 264*5c51f124SMoriah Waterland strlen(optarg), LOCK_KEY_MAXLEN); 265*5c51f124SMoriah Waterland return (1); 266*5c51f124SMoriah Waterland } 267*5c51f124SMoriah Waterland break; 268*5c51f124SMoriah Waterland 269*5c51f124SMoriah Waterland case 'o': /* object */ 270*5c51f124SMoriah Waterland oFlag = optarg; 271*5c51f124SMoriah Waterland if (strlen(optarg) > LOCK_OBJECT_MAXLEN) { 272*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, 273*5c51f124SMoriah Waterland MSG_LOCK_oARG_TOOLONG, 274*5c51f124SMoriah Waterland strlen(optarg), LOCK_OBJECT_MAXLEN); 275*5c51f124SMoriah Waterland return (1); 276*5c51f124SMoriah Waterland } 277*5c51f124SMoriah Waterland break; 278*5c51f124SMoriah Waterland 279*5c51f124SMoriah Waterland case 'p': /* process i.d. */ 280*5c51f124SMoriah Waterland errno = 0; 281*5c51f124SMoriah Waterland endptr = 0; 282*5c51f124SMoriah Waterland pFlag = strtol(optarg, &endptr, 10); 283*5c51f124SMoriah Waterland if ((endptr != (char *)NULL) && (*endptr != '\0')) { 284*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_pFLAG_BADINT, 285*5c51f124SMoriah Waterland optarg, *endptr); 286*5c51f124SMoriah Waterland return (1); 287*5c51f124SMoriah Waterland } 288*5c51f124SMoriah Waterland if ((pFlag == 0) && (errno != 0)) { 289*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, 290*5c51f124SMoriah Waterland MSG_LOCK_pFLAG_ERROR, 291*5c51f124SMoriah Waterland optarg, strerror(errno)); 292*5c51f124SMoriah Waterland return (1); 293*5c51f124SMoriah Waterland } 294*5c51f124SMoriah Waterland break; 295*5c51f124SMoriah Waterland 296*5c51f124SMoriah Waterland case 'q': /* quiet */ 297*5c51f124SMoriah Waterland qFlag++; 298*5c51f124SMoriah Waterland break; 299*5c51f124SMoriah Waterland 300*5c51f124SMoriah Waterland case 'r': /* release lock */ 301*5c51f124SMoriah Waterland rFlag++; 302*5c51f124SMoriah Waterland break; 303*5c51f124SMoriah Waterland 304*5c51f124SMoriah Waterland case 'R': /* alternative root */ 305*5c51f124SMoriah Waterland /* if root directory is not absolute path, error */ 306*5c51f124SMoriah Waterland if (*optarg != '/') { 307*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, 308*5c51f124SMoriah Waterland MSG_LOCK_RARG_NOT_ABSOLUTE, optarg); 309*5c51f124SMoriah Waterland return (1); 310*5c51f124SMoriah Waterland } 311*5c51f124SMoriah Waterland 312*5c51f124SMoriah Waterland /* if root directory does not exist, create it */ 313*5c51f124SMoriah Waterland if (access(optarg, F_OK) != 0) { 314*5c51f124SMoriah Waterland 315*5c51f124SMoriah Waterland /* create top level root directory */ 316*5c51f124SMoriah Waterland if (mkdirp(optarg, 0755) != 0) { 317*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, 318*5c51f124SMoriah Waterland MSG_LOCK_ALTROOT_CANTCREATE, 319*5c51f124SMoriah Waterland optarg, strerror(errno)); 320*5c51f124SMoriah Waterland return (1); 321*5c51f124SMoriah Waterland } 322*5c51f124SMoriah Waterland } 323*5c51f124SMoriah Waterland 324*5c51f124SMoriah Waterland /* if $ALTROOT/tmp directory does not exist create it */ 325*5c51f124SMoriah Waterland p = pkgstrPrintf("%s/tmp", optarg); 326*5c51f124SMoriah Waterland if (access(p, F_OK) != 0) { 327*5c51f124SMoriah Waterland 328*5c51f124SMoriah Waterland /* create $ALTROOT/tmp directory */ 329*5c51f124SMoriah Waterland if (mkdirp(p, 0777) != 0) { 330*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, 331*5c51f124SMoriah Waterland MSG_LOCK_ALTROOT_CANTCREATE, 332*5c51f124SMoriah Waterland p, strerror(errno)); 333*5c51f124SMoriah Waterland return (1); 334*5c51f124SMoriah Waterland } 335*5c51f124SMoriah Waterland } 336*5c51f124SMoriah Waterland 337*5c51f124SMoriah Waterland /* if $ALTROOT/tmp directory cannot be created, exit */ 338*5c51f124SMoriah Waterland if (access(p, F_OK) != 0) { 339*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ALTROOT_NONEXIST, 340*5c51f124SMoriah Waterland optarg, strerror(errno)); 341*5c51f124SMoriah Waterland return (1); 342*5c51f124SMoriah Waterland } 343*5c51f124SMoriah Waterland 344*5c51f124SMoriah Waterland (void) free(p); 345*5c51f124SMoriah Waterland 346*5c51f124SMoriah Waterland RFlag = optarg; 347*5c51f124SMoriah Waterland break; 348*5c51f124SMoriah Waterland 349*5c51f124SMoriah Waterland case 's': /* shared */ 350*5c51f124SMoriah Waterland sFlag++; 351*5c51f124SMoriah Waterland break; 352*5c51f124SMoriah Waterland 353*5c51f124SMoriah Waterland case 't': /* test comparison */ 354*5c51f124SMoriah Waterland tFlag++; 355*5c51f124SMoriah Waterland break; 356*5c51f124SMoriah Waterland 357*5c51f124SMoriah Waterland case 'w': /* wait */ 358*5c51f124SMoriah Waterland wFlag++; 359*5c51f124SMoriah Waterland break; 360*5c51f124SMoriah Waterland 361*5c51f124SMoriah Waterland case 'W': /* wait with timeout */ 362*5c51f124SMoriah Waterland errno = 0; 363*5c51f124SMoriah Waterland endptr = 0; 364*5c51f124SMoriah Waterland WFlag = strtol(optarg, &endptr, 10); 365*5c51f124SMoriah Waterland if ((endptr != (char *)NULL) && (*endptr != '\0')) { 366*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_WFLAG_BADINT, 367*5c51f124SMoriah Waterland optarg, *endptr); 368*5c51f124SMoriah Waterland return (1); 369*5c51f124SMoriah Waterland } 370*5c51f124SMoriah Waterland if ((WFlag == 0) && (errno != 0)) { 371*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, 372*5c51f124SMoriah Waterland MSG_LOCK_WFLAG_ERROR, 373*5c51f124SMoriah Waterland optarg, strerror(errno)); 374*5c51f124SMoriah Waterland return (1); 375*5c51f124SMoriah Waterland } 376*5c51f124SMoriah Waterland wFlag++; 377*5c51f124SMoriah Waterland break; 378*5c51f124SMoriah Waterland 379*5c51f124SMoriah Waterland case 'z': /* zone i.d. */ 380*5c51f124SMoriah Waterland errno = 0; 381*5c51f124SMoriah Waterland endptr = 0; 382*5c51f124SMoriah Waterland zFlag = strtol(optarg, &endptr, 10); 383*5c51f124SMoriah Waterland if ((endptr != (char *)NULL) && (*endptr != '\0')) { 384*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_zFLAG_BADINT, 385*5c51f124SMoriah Waterland optarg, *endptr); 386*5c51f124SMoriah Waterland return (1); 387*5c51f124SMoriah Waterland } 388*5c51f124SMoriah Waterland if ((zFlag == 0) && (errno != 0)) { 389*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, 390*5c51f124SMoriah Waterland MSG_LOCK_zFLAG_ERROR, 391*5c51f124SMoriah Waterland optarg, strerror(errno)); 392*5c51f124SMoriah Waterland return (1); 393*5c51f124SMoriah Waterland } 394*5c51f124SMoriah Waterland break; 395*5c51f124SMoriah Waterland 396*5c51f124SMoriah Waterland case ':': 397*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt); 398*5c51f124SMoriah Waterland /* LINTED fallthrough on case statement */ 399*5c51f124SMoriah Waterland case '?': 400*5c51f124SMoriah Waterland 401*5c51f124SMoriah Waterland default: 402*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_USAGE); 403*5c51f124SMoriah Waterland return (1); 404*5c51f124SMoriah Waterland } 405*5c51f124SMoriah Waterland } 406*5c51f124SMoriah Waterland 407*5c51f124SMoriah Waterland /* 408*5c51f124SMoriah Waterland * validate arguments 409*5c51f124SMoriah Waterland */ 410*5c51f124SMoriah Waterland 411*5c51f124SMoriah Waterland /* if -t option is specified, override all other options */ 412*5c51f124SMoriah Waterland 413*5c51f124SMoriah Waterland if (tFlag) { 414*5c51f124SMoriah Waterland int rs; 415*5c51f124SMoriah Waterland int rx; 416*5c51f124SMoriah Waterland int a; 417*5c51f124SMoriah Waterland 418*5c51f124SMoriah Waterland /* only 2 or 3 args are valid */ 419*5c51f124SMoriah Waterland 420*5c51f124SMoriah Waterland a = argc-optind; 421*5c51f124SMoriah Waterland if ((a < 2) || (a > 3)) { 422*5c51f124SMoriah Waterland (void) fprintf(stderr, MSG_T_OPTION_ARGS, argc-optind); 423*5c51f124SMoriah Waterland return (1); 424*5c51f124SMoriah Waterland } 425*5c51f124SMoriah Waterland 426*5c51f124SMoriah Waterland /* if 3rd argument given, it is return value to check */ 427*5c51f124SMoriah Waterland 428*5c51f124SMoriah Waterland if (a == 3) { 429*5c51f124SMoriah Waterland rs = atoi(argv[optind+2]); 430*5c51f124SMoriah Waterland } 431*5c51f124SMoriah Waterland rx = _lockMatch(argv[optind+0], argv[optind+1]); 432*5c51f124SMoriah Waterland 433*5c51f124SMoriah Waterland /* if 3rd argument not given, code to check is code returned */ 434*5c51f124SMoriah Waterland 435*5c51f124SMoriah Waterland if (a == 2) { 436*5c51f124SMoriah Waterland rs = rx; 437*5c51f124SMoriah Waterland } 438*5c51f124SMoriah Waterland 439*5c51f124SMoriah Waterland /* report results */ 440*5c51f124SMoriah Waterland 441*5c51f124SMoriah Waterland if (a == 2) { 442*5c51f124SMoriah Waterland (void) fprintf(stderr, MSG_T_RESULT_TWO, 443*5c51f124SMoriah Waterland rx, argv[optind+0], argv[optind+1]); 444*5c51f124SMoriah Waterland return (rx); 445*5c51f124SMoriah Waterland } 446*5c51f124SMoriah Waterland 447*5c51f124SMoriah Waterland if (rx != rs) { 448*5c51f124SMoriah Waterland (void) fprintf(stderr, MSG_T_RESULT_THREE, 449*5c51f124SMoriah Waterland rs, rx, argv[optind+0], argv[optind+1]); 450*5c51f124SMoriah Waterland } 451*5c51f124SMoriah Waterland 452*5c51f124SMoriah Waterland /* always successful */ 453*5c51f124SMoriah Waterland 454*5c51f124SMoriah Waterland return (rx == rs ? 0 : 1); 455*5c51f124SMoriah Waterland } 456*5c51f124SMoriah Waterland 457*5c51f124SMoriah Waterland /* must be no non-option arguments left */ 458*5c51f124SMoriah Waterland 459*5c51f124SMoriah Waterland if ((argc-optind) > 0) { 460*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_USAGE); 461*5c51f124SMoriah Waterland return (1); 462*5c51f124SMoriah Waterland } 463*5c51f124SMoriah Waterland 464*5c51f124SMoriah Waterland /* -a and -r cannot be used together */ 465*5c51f124SMoriah Waterland 466*5c51f124SMoriah Waterland if (aFlag && rFlag) { 467*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ar_TOGETHER); 468*5c51f124SMoriah Waterland return (1); 469*5c51f124SMoriah Waterland } 470*5c51f124SMoriah Waterland 471*5c51f124SMoriah Waterland /* -e and -s cannot be used together */ 472*5c51f124SMoriah Waterland 473*5c51f124SMoriah Waterland if (eFlag && sFlag) { 474*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_es_TOGETHER); 475*5c51f124SMoriah Waterland return (1); 476*5c51f124SMoriah Waterland } 477*5c51f124SMoriah Waterland 478*5c51f124SMoriah Waterland /* -e can only be used if -a is used */ 479*5c51f124SMoriah Waterland 480*5c51f124SMoriah Waterland if (!aFlag && eFlag) { 481*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_e_without_a); 482*5c51f124SMoriah Waterland return (1); 483*5c51f124SMoriah Waterland } 484*5c51f124SMoriah Waterland 485*5c51f124SMoriah Waterland /* -s can only be used if -a is used */ 486*5c51f124SMoriah Waterland 487*5c51f124SMoriah Waterland if (!aFlag && sFlag) { 488*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_s_without_a); 489*5c51f124SMoriah Waterland return (1); 490*5c51f124SMoriah Waterland } 491*5c51f124SMoriah Waterland 492*5c51f124SMoriah Waterland /* 493*5c51f124SMoriah Waterland * perform the requested operation 494*5c51f124SMoriah Waterland */ 495*5c51f124SMoriah Waterland 496*5c51f124SMoriah Waterland /* 497*5c51f124SMoriah Waterland * hook SIGINT and SIGHUP interrupts into quit.c's trap handler 498*5c51f124SMoriah Waterland */ 499*5c51f124SMoriah Waterland 500*5c51f124SMoriah Waterland /* hold SIGINT/SIGHUP interrupts */ 501*5c51f124SMoriah Waterland 502*5c51f124SMoriah Waterland (void) sighold(SIGHUP); 503*5c51f124SMoriah Waterland (void) sighold(SIGINT); 504*5c51f124SMoriah Waterland 505*5c51f124SMoriah Waterland /* connect sigint_handler() to SIGINT */ 506*5c51f124SMoriah Waterland 507*5c51f124SMoriah Waterland nact.sa_handler = sigint_handler; 508*5c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 509*5c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 510*5c51f124SMoriah Waterland 511*5c51f124SMoriah Waterland if (sigaction(SIGINT, &nact, &oact) < 0) { 512*5c51f124SMoriah Waterland funcSigint = SIG_DFL; 513*5c51f124SMoriah Waterland } else { 514*5c51f124SMoriah Waterland funcSigint = oact.sa_handler; 515*5c51f124SMoriah Waterland } 516*5c51f124SMoriah Waterland 517*5c51f124SMoriah Waterland /* connect sighupt_handler() to SIGHUP */ 518*5c51f124SMoriah Waterland 519*5c51f124SMoriah Waterland nact.sa_handler = sighup_handler; 520*5c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 521*5c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 522*5c51f124SMoriah Waterland 523*5c51f124SMoriah Waterland if (sigaction(SIGHUP, &nact, &oact) < 0) { 524*5c51f124SMoriah Waterland funcSighup = SIG_DFL; 525*5c51f124SMoriah Waterland } else { 526*5c51f124SMoriah Waterland funcSighup = oact.sa_handler; 527*5c51f124SMoriah Waterland } 528*5c51f124SMoriah Waterland 529*5c51f124SMoriah Waterland /* release hold on signals */ 530*5c51f124SMoriah Waterland 531*5c51f124SMoriah Waterland (void) sigrelse(SIGHUP); 532*5c51f124SMoriah Waterland (void) sigrelse(SIGINT); 533*5c51f124SMoriah Waterland 534*5c51f124SMoriah Waterland /* open the lock file */ 535*5c51f124SMoriah Waterland 536*5c51f124SMoriah Waterland fd = _openLockFile(RFlag); 537*5c51f124SMoriah Waterland if (fd < 0) { 538*5c51f124SMoriah Waterland return (1); 539*5c51f124SMoriah Waterland } 540*5c51f124SMoriah Waterland 541*5c51f124SMoriah Waterland if (aFlag) { 542*5c51f124SMoriah Waterland /* set "exclusive" mode based on -e/-s flag used */ 543*5c51f124SMoriah Waterland 544*5c51f124SMoriah Waterland if (sFlag) { 545*5c51f124SMoriah Waterland exclusive = 0; 546*5c51f124SMoriah Waterland } else if (eFlag) { 547*5c51f124SMoriah Waterland exclusive = 1; 548*5c51f124SMoriah Waterland } 549*5c51f124SMoriah Waterland 550*5c51f124SMoriah Waterland /* acquire lock */ 551*5c51f124SMoriah Waterland 552*5c51f124SMoriah Waterland tResult = lock_acquire(&theLock, &fd, RFlag, kFlag, oFlag, 553*5c51f124SMoriah Waterland qFlag, wFlag, WFlag, exclusive, RFlag, pFlag, zFlag); 554*5c51f124SMoriah Waterland 555*5c51f124SMoriah Waterland switch (tResult) { 556*5c51f124SMoriah Waterland case FINDLOCK_LOCKACQUIRED: 557*5c51f124SMoriah Waterland (void) fprintf(stdout, "%s\n", 558*5c51f124SMoriah Waterland theLock._lrLock.lockKey); 559*5c51f124SMoriah Waterland result = 0; 560*5c51f124SMoriah Waterland break; 561*5c51f124SMoriah Waterland case FINDLOCK_LOCKED: 562*5c51f124SMoriah Waterland (void) fprintf(stdout, "%s\n", 563*5c51f124SMoriah Waterland theLock._lrLock.lockObject); 564*5c51f124SMoriah Waterland result = 1; 565*5c51f124SMoriah Waterland break; 566*5c51f124SMoriah Waterland default: 567*5c51f124SMoriah Waterland result = 1; 568*5c51f124SMoriah Waterland break; 569*5c51f124SMoriah Waterland } 570*5c51f124SMoriah Waterland 571*5c51f124SMoriah Waterland } else if (rFlag) { 572*5c51f124SMoriah Waterland /* release lock */ 573*5c51f124SMoriah Waterland result = lock_release(fd, kFlag, oFlag, qFlag); 574*5c51f124SMoriah Waterland } else { 575*5c51f124SMoriah Waterland /* lock status */ 576*5c51f124SMoriah Waterland result = lock_status(fd, kFlag, oFlag, qFlag); 577*5c51f124SMoriah Waterland } 578*5c51f124SMoriah Waterland 579*5c51f124SMoriah Waterland /* close the lock file */ 580*5c51f124SMoriah Waterland 581*5c51f124SMoriah Waterland (void) close(fd); 582*5c51f124SMoriah Waterland 583*5c51f124SMoriah Waterland /* return results of operation */ 584*5c51f124SMoriah Waterland 585*5c51f124SMoriah Waterland return (result); 586*5c51f124SMoriah Waterland } 587*5c51f124SMoriah Waterland 588*5c51f124SMoriah Waterland /* 589*5c51f124SMoriah Waterland * local main function implementation methods 590*5c51f124SMoriah Waterland */ 591*5c51f124SMoriah Waterland 592*5c51f124SMoriah Waterland /* 593*5c51f124SMoriah Waterland * Name: lock_acquire 594*5c51f124SMoriah Waterland * Description: implement lock acquisition implementing the wait/timeouts 595*5c51f124SMoriah Waterland * Calls _lock_acquire to attempt lock acquisition. 596*5c51f124SMoriah Waterland * Arguments: 597*5c51f124SMoriah Waterland * a_theLock - lock object filled with contents of existing lock 598*5c51f124SMoriah Waterland * a_fd - file descriptor opened on the lock file 599*5c51f124SMoriah Waterland * a_root - root of file system to manipulate locks on 600*5c51f124SMoriah Waterland * a_key - key associated with lock to acquire 601*5c51f124SMoriah Waterland * a_object - object associated with lock to acquire 602*5c51f124SMoriah Waterland * a_wait - wait if lock cannot be acquired flag: 603*5c51f124SMoriah Waterland * == 0 - do not wait 604*5c51f124SMoriah Waterland * != 0 - wait 605*5c51f124SMoriah Waterland * a_timeout - timeout if waiting to acquire busy lock: 606*5c51f124SMoriah Waterland * == 0 - no timeout (wait forever) 607*5c51f124SMoriah Waterland * != 0 - max # seconds to wait to acquire busy lock 608*5c51f124SMoriah Waterland * a_quiet - quiet mode enabled flag 609*5c51f124SMoriah Waterland * a_exclusive - exclusive/shared lock flag 610*5c51f124SMoriah Waterland * a_pid - if != 0 process i.d. to associate with this lock 611*5c51f124SMoriah Waterland * a_zid - if >= 0 - zone i.d. to associate with this lock 612*5c51f124SMoriah Waterland * Returns: int 613*5c51f124SMoriah Waterland * == 0 - successful 614*5c51f124SMoriah Waterland * != 0 - not successful 615*5c51f124SMoriah Waterland */ 616*5c51f124SMoriah Waterland 617*5c51f124SMoriah Waterland static FINDLOCK_T 618*5c51f124SMoriah Waterland lock_acquire(LOCK_T *a_theLock, int *a_fd, char *a_root, char *a_key, 619*5c51f124SMoriah Waterland char *a_object, int a_quiet, int a_wait, long a_timeout, 620*5c51f124SMoriah Waterland int a_exclusive, char *a_altRoot, pid_t a_pid, zoneid_t a_zid) 621*5c51f124SMoriah Waterland { 622*5c51f124SMoriah Waterland int notified = 0; 623*5c51f124SMoriah Waterland FINDLOCK_T result; 624*5c51f124SMoriah Waterland time_t timeout; 625*5c51f124SMoriah Waterland int closeOnExit = 0; 626*5c51f124SMoriah Waterland 627*5c51f124SMoriah Waterland /* reset the lock */ 628*5c51f124SMoriah Waterland 629*5c51f124SMoriah Waterland bzero(a_theLock, sizeof (LOCK_T)); 630*5c51f124SMoriah Waterland 631*5c51f124SMoriah Waterland /* open file if not open */ 632*5c51f124SMoriah Waterland 633*5c51f124SMoriah Waterland if ((*a_fd) < 0) { 634*5c51f124SMoriah Waterland (*a_fd) = _openLockFile(a_altRoot); 635*5c51f124SMoriah Waterland if ((*a_fd) < 0) { 636*5c51f124SMoriah Waterland return (FINDLOCK_ERROR); 637*5c51f124SMoriah Waterland } 638*5c51f124SMoriah Waterland closeOnExit++; 639*5c51f124SMoriah Waterland } 640*5c51f124SMoriah Waterland 641*5c51f124SMoriah Waterland /* compute time after which acquire times out */ 642*5c51f124SMoriah Waterland 643*5c51f124SMoriah Waterland timeout = time((time_t *)NULL) + a_timeout; 644*5c51f124SMoriah Waterland 645*5c51f124SMoriah Waterland for (;;) { 646*5c51f124SMoriah Waterland time_t curtime; 647*5c51f124SMoriah Waterland 648*5c51f124SMoriah Waterland /* attempt to aquire the lock */ 649*5c51f124SMoriah Waterland 650*5c51f124SMoriah Waterland result = _lock_acquire(a_theLock, *a_fd, a_key, a_object, 651*5c51f124SMoriah Waterland a_quiet, a_exclusive, a_pid, a_zid); 652*5c51f124SMoriah Waterland 653*5c51f124SMoriah Waterland /* return result if any result other than object is locked */ 654*5c51f124SMoriah Waterland 655*5c51f124SMoriah Waterland switch (result) { 656*5c51f124SMoriah Waterland case FINDLOCK_LOCKACQUIRED: 657*5c51f124SMoriah Waterland 658*5c51f124SMoriah Waterland /* close lock file if opened in this function */ 659*5c51f124SMoriah Waterland 660*5c51f124SMoriah Waterland if (closeOnExit) { 661*5c51f124SMoriah Waterland (void) close(*a_fd); 662*5c51f124SMoriah Waterland *a_fd = -1; 663*5c51f124SMoriah Waterland } 664*5c51f124SMoriah Waterland 665*5c51f124SMoriah Waterland return (FINDLOCK_LOCKACQUIRED); 666*5c51f124SMoriah Waterland 667*5c51f124SMoriah Waterland case FINDLOCK_FOUND: 668*5c51f124SMoriah Waterland case FINDLOCK_NOTFOUND: 669*5c51f124SMoriah Waterland case FINDLOCK_KEYMISMATCH: 670*5c51f124SMoriah Waterland case FINDLOCK_NOTLOCKED: 671*5c51f124SMoriah Waterland case FINDLOCK_ERROR: 672*5c51f124SMoriah Waterland default: 673*5c51f124SMoriah Waterland /* close lock file if opened in this function */ 674*5c51f124SMoriah Waterland 675*5c51f124SMoriah Waterland if (closeOnExit) { 676*5c51f124SMoriah Waterland (void) close(*a_fd); 677*5c51f124SMoriah Waterland *a_fd = -1; 678*5c51f124SMoriah Waterland } 679*5c51f124SMoriah Waterland 680*5c51f124SMoriah Waterland return (result); 681*5c51f124SMoriah Waterland 682*5c51f124SMoriah Waterland case FINDLOCK_LOCKED: 683*5c51f124SMoriah Waterland ; 684*5c51f124SMoriah Waterland /* FALLTHROUGH */ 685*5c51f124SMoriah Waterland } 686*5c51f124SMoriah Waterland 687*5c51f124SMoriah Waterland /* 688*5c51f124SMoriah Waterland * object locked OR SIGINT/SIGHUP interrupt received; 689*5c51f124SMoriah Waterland * return error if not waiting for lock OR signal received 690*5c51f124SMoriah Waterland */ 691*5c51f124SMoriah Waterland 692*5c51f124SMoriah Waterland if ((a_wait == 0) || (signal_received != 0)) { 693*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR, 694*5c51f124SMoriah Waterland MSG_LOCK_ACQUIRE_BUSY_FIRST, 695*5c51f124SMoriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR, 696*5c51f124SMoriah Waterland a_object, a_key, 697*5c51f124SMoriah Waterland a_theLock->_lrLock.lockObject, 698*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 699*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 700*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive != 701*5c51f124SMoriah Waterland a_exclusive ? "" : 702*5c51f124SMoriah Waterland MSG_LOCK_ACQUIRE_BUSY_ADDITIONAL); 703*5c51f124SMoriah Waterland 704*5c51f124SMoriah Waterland /* close lock file if opened in this function */ 705*5c51f124SMoriah Waterland 706*5c51f124SMoriah Waterland if (closeOnExit) { 707*5c51f124SMoriah Waterland (void) close(*a_fd); 708*5c51f124SMoriah Waterland *a_fd = -1; 709*5c51f124SMoriah Waterland } 710*5c51f124SMoriah Waterland 711*5c51f124SMoriah Waterland return (FINDLOCK_LOCKED); 712*5c51f124SMoriah Waterland } 713*5c51f124SMoriah Waterland 714*5c51f124SMoriah Waterland /* waiting for lock - if timeout specified see if time left */ 715*5c51f124SMoriah Waterland 716*5c51f124SMoriah Waterland if (a_timeout > 0) { 717*5c51f124SMoriah Waterland curtime = time((time_t *)NULL); 718*5c51f124SMoriah Waterland if (curtime > timeout) { 719*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR, 720*5c51f124SMoriah Waterland MSG_LOCK_ACQUIRE_TIMEDOUT, 721*5c51f124SMoriah Waterland a_exclusive ? 722*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 723*5c51f124SMoriah Waterland a_object, a_key); 724*5c51f124SMoriah Waterland 725*5c51f124SMoriah Waterland /* close lock file if opened in this function */ 726*5c51f124SMoriah Waterland 727*5c51f124SMoriah Waterland if (closeOnExit) { 728*5c51f124SMoriah Waterland (void) close(*a_fd); 729*5c51f124SMoriah Waterland *a_fd = -1; 730*5c51f124SMoriah Waterland } 731*5c51f124SMoriah Waterland 732*5c51f124SMoriah Waterland return (FINDLOCK_ERROR); 733*5c51f124SMoriah Waterland } 734*5c51f124SMoriah Waterland } 735*5c51f124SMoriah Waterland 736*5c51f124SMoriah Waterland /* 737*5c51f124SMoriah Waterland * waiting to aquire lock: 738*5c51f124SMoriah Waterland * - notify waiting (one time only) 739*5c51f124SMoriah Waterland * - close lock file 740*5c51f124SMoriah Waterland * - sleep 741*5c51f124SMoriah Waterland * - open lock file 742*5c51f124SMoriah Waterland * - try again 743*5c51f124SMoriah Waterland */ 744*5c51f124SMoriah Waterland 745*5c51f124SMoriah Waterland /* notify once */ 746*5c51f124SMoriah Waterland 747*5c51f124SMoriah Waterland if (notified++ == 0) { 748*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_WRN, 749*5c51f124SMoriah Waterland MSG_LOCK_ACQUIRE_WAITING, 750*5c51f124SMoriah Waterland a_object); 751*5c51f124SMoriah Waterland } 752*5c51f124SMoriah Waterland 753*5c51f124SMoriah Waterland /* close lock file */ 754*5c51f124SMoriah Waterland 755*5c51f124SMoriah Waterland (void) close(*a_fd); 756*5c51f124SMoriah Waterland 757*5c51f124SMoriah Waterland /* wait (sleep) */ 758*5c51f124SMoriah Waterland 759*5c51f124SMoriah Waterland (void) sleep(LOCK_SLEEP_INTERVAL); 760*5c51f124SMoriah Waterland 761*5c51f124SMoriah Waterland /* open the lock file and try again */ 762*5c51f124SMoriah Waterland 763*5c51f124SMoriah Waterland *a_fd = _openLockFile(a_root); 764*5c51f124SMoriah Waterland if (*a_fd < 0) { 765*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ACQUIRE_REOPEN_FAILED, 766*5c51f124SMoriah Waterland a_object); 767*5c51f124SMoriah Waterland 768*5c51f124SMoriah Waterland /* close lock file if opened in this function */ 769*5c51f124SMoriah Waterland 770*5c51f124SMoriah Waterland if (closeOnExit) { 771*5c51f124SMoriah Waterland (void) close(*a_fd); 772*5c51f124SMoriah Waterland *a_fd = -1; 773*5c51f124SMoriah Waterland } 774*5c51f124SMoriah Waterland 775*5c51f124SMoriah Waterland return (FINDLOCK_ERROR); 776*5c51f124SMoriah Waterland } 777*5c51f124SMoriah Waterland } 778*5c51f124SMoriah Waterland } 779*5c51f124SMoriah Waterland 780*5c51f124SMoriah Waterland /* 781*5c51f124SMoriah Waterland * Name: lock_release 782*5c51f124SMoriah Waterland * Description: implement lock release 783*5c51f124SMoriah Waterland * Arguments: 784*5c51f124SMoriah Waterland * a_fd - file descriptor opened on the lock file 785*5c51f124SMoriah Waterland * a_key - key associated with lock to release 786*5c51f124SMoriah Waterland * a_object - object associated with lock to release 787*5c51f124SMoriah Waterland * a_quiet - quiet mode enabled flag 788*5c51f124SMoriah Waterland * Returns: int 789*5c51f124SMoriah Waterland * == 0 - successful 790*5c51f124SMoriah Waterland * != 0 - not successful 791*5c51f124SMoriah Waterland */ 792*5c51f124SMoriah Waterland 793*5c51f124SMoriah Waterland static int 794*5c51f124SMoriah Waterland lock_release(int a_fd, char *a_key, char *a_object, int a_quiet) 795*5c51f124SMoriah Waterland { 796*5c51f124SMoriah Waterland RECORDNUM_T recordNum; 797*5c51f124SMoriah Waterland LOCK_T theLock; 798*5c51f124SMoriah Waterland FINDLOCK_T result; 799*5c51f124SMoriah Waterland 800*5c51f124SMoriah Waterland /* entry debugging info */ 801*5c51f124SMoriah Waterland 802*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_RELEASE_ENTRY, 803*5c51f124SMoriah Waterland a_key, a_object, a_quiet); 804*5c51f124SMoriah Waterland 805*5c51f124SMoriah Waterland /* find the lock to be released */ 806*5c51f124SMoriah Waterland 807*5c51f124SMoriah Waterland result = _findLock(&theLock, &recordNum, a_fd, a_object, a_key); 808*5c51f124SMoriah Waterland 809*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_RELEASE_FINDRESULT, 810*5c51f124SMoriah Waterland result, recordNum); 811*5c51f124SMoriah Waterland 812*5c51f124SMoriah Waterland /* determine how to release the lock if found */ 813*5c51f124SMoriah Waterland 814*5c51f124SMoriah Waterland switch (result) { 815*5c51f124SMoriah Waterland /* 816*5c51f124SMoriah Waterland * object is not locked but a key was specified 817*5c51f124SMoriah Waterland */ 818*5c51f124SMoriah Waterland case FINDLOCK_NOTLOCKED: 819*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR, 820*5c51f124SMoriah Waterland MSG_LOCK_RELEASE_NOTLOCKED, 821*5c51f124SMoriah Waterland a_object, a_key); 822*5c51f124SMoriah Waterland return (result); 823*5c51f124SMoriah Waterland 824*5c51f124SMoriah Waterland /* 825*5c51f124SMoriah Waterland * object is locked and no matching key was specified 826*5c51f124SMoriah Waterland */ 827*5c51f124SMoriah Waterland case FINDLOCK_LOCKED: 828*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR, 829*5c51f124SMoriah Waterland MSG_LOCK_RELEASE_LOCKED, 830*5c51f124SMoriah Waterland a_object, a_key); 831*5c51f124SMoriah Waterland return (result); 832*5c51f124SMoriah Waterland 833*5c51f124SMoriah Waterland /* 834*5c51f124SMoriah Waterland * object is not locked 835*5c51f124SMoriah Waterland */ 836*5c51f124SMoriah Waterland case FINDLOCK_NOTFOUND: 837*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR, 838*5c51f124SMoriah Waterland MSG_LOCK_RELEASE_NOTFOUND, 839*5c51f124SMoriah Waterland a_object, a_key); 840*5c51f124SMoriah Waterland return (result); 841*5c51f124SMoriah Waterland 842*5c51f124SMoriah Waterland /* 843*5c51f124SMoriah Waterland * object is locked and specified key does not match 844*5c51f124SMoriah Waterland */ 845*5c51f124SMoriah Waterland case FINDLOCK_KEYMISMATCH: 846*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR, 847*5c51f124SMoriah Waterland MSG_LOCK_RELEASE_KEYMISMATCH, 848*5c51f124SMoriah Waterland a_object); 849*5c51f124SMoriah Waterland return (result); 850*5c51f124SMoriah Waterland 851*5c51f124SMoriah Waterland /* 852*5c51f124SMoriah Waterland * error determining if object is locked 853*5c51f124SMoriah Waterland */ 854*5c51f124SMoriah Waterland case FINDLOCK_ERROR: 855*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR, 856*5c51f124SMoriah Waterland MSG_LOCK_RELEASE_ERROR, 857*5c51f124SMoriah Waterland a_object, a_key); 858*5c51f124SMoriah Waterland perror(LOCK_FILENAME); 859*5c51f124SMoriah Waterland return (result); 860*5c51f124SMoriah Waterland 861*5c51f124SMoriah Waterland /* 862*5c51f124SMoriah Waterland * object is locked and specified key matches 863*5c51f124SMoriah Waterland */ 864*5c51f124SMoriah Waterland case FINDLOCK_FOUND: 865*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_RELEASE_FOUND, 866*5c51f124SMoriah Waterland a_object, a_key); 867*5c51f124SMoriah Waterland (void) _decrementLockCount(a_fd, &theLock); 868*5c51f124SMoriah Waterland break; 869*5c51f124SMoriah Waterland 870*5c51f124SMoriah Waterland /* 871*5c51f124SMoriah Waterland * unknown return 872*5c51f124SMoriah Waterland */ 873*5c51f124SMoriah Waterland default: 874*5c51f124SMoriah Waterland result = FINDLOCK_ERROR; 875*5c51f124SMoriah Waterland break; 876*5c51f124SMoriah Waterland 877*5c51f124SMoriah Waterland } 878*5c51f124SMoriah Waterland return (result); 879*5c51f124SMoriah Waterland } 880*5c51f124SMoriah Waterland 881*5c51f124SMoriah Waterland /* 882*5c51f124SMoriah Waterland * Name: lock_status 883*5c51f124SMoriah Waterland * Description: implement lock status display/inquiry 884*5c51f124SMoriah Waterland * Arguments: 885*5c51f124SMoriah Waterland * a_fd - file descriptor opened on the lock file 886*5c51f124SMoriah Waterland * a_key - key associated with lock to look up 887*5c51f124SMoriah Waterland * a_object - object associated with lock to look up 888*5c51f124SMoriah Waterland * a_quiet - quiet mode enabled flag 889*5c51f124SMoriah Waterland * Returns: int 890*5c51f124SMoriah Waterland * == 0 - successful 891*5c51f124SMoriah Waterland * != 0 - not successful 892*5c51f124SMoriah Waterland */ 893*5c51f124SMoriah Waterland 894*5c51f124SMoriah Waterland static int 895*5c51f124SMoriah Waterland lock_status(int a_fd, char *a_key, char *a_object, int a_quiet) 896*5c51f124SMoriah Waterland { 897*5c51f124SMoriah Waterland ADMINLOCK_T *pll; 898*5c51f124SMoriah Waterland LOCK_T theLock; 899*5c51f124SMoriah Waterland RECORDNUM_T recordNum = 0; 900*5c51f124SMoriah Waterland char *pld; 901*5c51f124SMoriah Waterland int found = 0; 902*5c51f124SMoriah Waterland long pls; 903*5c51f124SMoriah Waterland 904*5c51f124SMoriah Waterland /* entry debugging info */ 905*5c51f124SMoriah Waterland 906*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_STATUS_ENTRY, 907*5c51f124SMoriah Waterland a_key, a_object); 908*5c51f124SMoriah Waterland 909*5c51f124SMoriah Waterland /* localize references to lock object */ 910*5c51f124SMoriah Waterland 911*5c51f124SMoriah Waterland pld = &theLock._lrLockData[0]; 912*5c51f124SMoriah Waterland pll = &theLock._lrLock; 913*5c51f124SMoriah Waterland pls = sizeof (theLock._lrLockData); 914*5c51f124SMoriah Waterland 915*5c51f124SMoriah Waterland bzero(pld, pls); 916*5c51f124SMoriah Waterland 917*5c51f124SMoriah Waterland /* read and process each lock */ 918*5c51f124SMoriah Waterland 919*5c51f124SMoriah Waterland for (; pread(a_fd, pld, pls, pls*recordNum) == pls; recordNum++) { 920*5c51f124SMoriah Waterland /* debug info on this lock */ 921*5c51f124SMoriah Waterland 922*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_STATUS_READRECORD, 923*5c51f124SMoriah Waterland recordNum, pll->lockCount, 924*5c51f124SMoriah Waterland pll->lockObject, pll->lockKey, pll->lockPid, 925*5c51f124SMoriah Waterland pll->lockZoneId); 926*5c51f124SMoriah Waterland 927*5c51f124SMoriah Waterland /* ignore if key specified and key does not match */ 928*5c51f124SMoriah Waterland 929*5c51f124SMoriah Waterland if ((*a_key != '\0') && 930*5c51f124SMoriah Waterland (strcmp(pll->lockKey, a_key) != 0)) { 931*5c51f124SMoriah Waterland continue; 932*5c51f124SMoriah Waterland } 933*5c51f124SMoriah Waterland 934*5c51f124SMoriah Waterland /* ignore if object specified and object does not match */ 935*5c51f124SMoriah Waterland 936*5c51f124SMoriah Waterland if ((*a_object != '\0') && 937*5c51f124SMoriah Waterland (strcmp(pll->lockObject, a_object) != 0)) { 938*5c51f124SMoriah Waterland continue; 939*5c51f124SMoriah Waterland } 940*5c51f124SMoriah Waterland 941*5c51f124SMoriah Waterland found++; 942*5c51f124SMoriah Waterland 943*5c51f124SMoriah Waterland /* process next lock if quiet operation */ 944*5c51f124SMoriah Waterland 945*5c51f124SMoriah Waterland if (a_quiet != 0) { 946*5c51f124SMoriah Waterland continue; 947*5c51f124SMoriah Waterland } 948*5c51f124SMoriah Waterland 949*5c51f124SMoriah Waterland /* output header if first lock object */ 950*5c51f124SMoriah Waterland 951*5c51f124SMoriah Waterland if (found == 1) { 952*5c51f124SMoriah Waterland (void) fprintf(stdout, 953*5c51f124SMoriah Waterland "%2s %2s %3s %8s %3s %9s %37s %s\n", 954*5c51f124SMoriah Waterland "i#", "l#", "cnt", "pid", "zid", "lock-type", 955*5c51f124SMoriah Waterland "---------------lock-key-------------", 956*5c51f124SMoriah Waterland "lock-object"); 957*5c51f124SMoriah Waterland } 958*5c51f124SMoriah Waterland 959*5c51f124SMoriah Waterland /* output status line for this lock object */ 960*5c51f124SMoriah Waterland 961*5c51f124SMoriah Waterland (void) fprintf(stdout, 962*5c51f124SMoriah Waterland "%2ld %2ld %3ld %8ld %3d %9s %37s %s\n", 963*5c51f124SMoriah Waterland recordNum, pll->lockRecordNum, pll->lockCount, 964*5c51f124SMoriah Waterland pll->lockPid, pll->lockZoneId, 965*5c51f124SMoriah Waterland pll->lockExclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR, 966*5c51f124SMoriah Waterland pll->lockKey, 967*5c51f124SMoriah Waterland *pll->lockObject == '\0' ? "*" : pll->lockObject); 968*5c51f124SMoriah Waterland } 969*5c51f124SMoriah Waterland 970*5c51f124SMoriah Waterland /* return == 0 if found, != 0 if not found */ 971*5c51f124SMoriah Waterland 972*5c51f124SMoriah Waterland return (found == 0 ? 1 : 0); 973*5c51f124SMoriah Waterland } 974*5c51f124SMoriah Waterland 975*5c51f124SMoriah Waterland /* 976*5c51f124SMoriah Waterland * local utility functions 977*5c51f124SMoriah Waterland */ 978*5c51f124SMoriah Waterland 979*5c51f124SMoriah Waterland /* 980*5c51f124SMoriah Waterland * Name: _lock_acquire 981*5c51f124SMoriah Waterland * Description: implement lock acquisition without wait/timeouts 982*5c51f124SMoriah Waterland * Arguments: 983*5c51f124SMoriah Waterland * a_theLock - lock object filled with contents of existing lock 984*5c51f124SMoriah Waterland * a_fd - file descriptor opened on the lock file 985*5c51f124SMoriah Waterland * a_key - key associated with lock to acquire 986*5c51f124SMoriah Waterland * a_object - object associated with lock to acquire 987*5c51f124SMoriah Waterland * a_quiet - quiet mode enabled flag 988*5c51f124SMoriah Waterland * a_exclusive - exclusive/shared lock flag 989*5c51f124SMoriah Waterland * a_pid - if != 0 process i.d. to associate with this lock 990*5c51f124SMoriah Waterland * a_zid - if >= 0 zone i.d. to associate with this lock 991*5c51f124SMoriah Waterland * Returns: FINDLOCK_T 992*5c51f124SMoriah Waterland */ 993*5c51f124SMoriah Waterland 994*5c51f124SMoriah Waterland static FINDLOCK_T 995*5c51f124SMoriah Waterland _lock_acquire(LOCK_T *a_theLock, int a_fd, char *a_key, 996*5c51f124SMoriah Waterland char *a_object, int a_quiet, int a_exclusive, pid_t a_pid, 997*5c51f124SMoriah Waterland zoneid_t a_zid) 998*5c51f124SMoriah Waterland { 999*5c51f124SMoriah Waterland RECORDNUM_T recordNum; 1000*5c51f124SMoriah Waterland FINDLOCK_T result; 1001*5c51f124SMoriah Waterland char key[LOCK_KEY_MAXLEN+1] = {'\0'}; 1002*5c51f124SMoriah Waterland 1003*5c51f124SMoriah Waterland /* entry debugging info */ 1004*5c51f124SMoriah Waterland 1005*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_ACQUIRE_ENTRY, 1006*5c51f124SMoriah Waterland a_key, a_object, a_quiet, a_exclusive); 1007*5c51f124SMoriah Waterland 1008*5c51f124SMoriah Waterland /* is the specified object already locked? */ 1009*5c51f124SMoriah Waterland 1010*5c51f124SMoriah Waterland for (;;) { 1011*5c51f124SMoriah Waterland result = _findLock(a_theLock, &recordNum, a_fd, a_object, 1012*5c51f124SMoriah Waterland a_key); 1013*5c51f124SMoriah Waterland 1014*5c51f124SMoriah Waterland if (result != FINDLOCK_LOCKED) { 1015*5c51f124SMoriah Waterland break; 1016*5c51f124SMoriah Waterland } 1017*5c51f124SMoriah Waterland 1018*5c51f124SMoriah Waterland if (_validateLock(a_fd, a_theLock, a_quiet) == B_TRUE) { 1019*5c51f124SMoriah Waterland break; 1020*5c51f124SMoriah Waterland } 1021*5c51f124SMoriah Waterland } 1022*5c51f124SMoriah Waterland 1023*5c51f124SMoriah Waterland 1024*5c51f124SMoriah Waterland /* debug info on result of find of lock */ 1025*5c51f124SMoriah Waterland 1026*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_ACQUIRE_FINDRESULT, 1027*5c51f124SMoriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR, 1028*5c51f124SMoriah Waterland result, recordNum); 1029*5c51f124SMoriah Waterland 1030*5c51f124SMoriah Waterland /* determine how to acquire the lock */ 1031*5c51f124SMoriah Waterland 1032*5c51f124SMoriah Waterland switch (result) { 1033*5c51f124SMoriah Waterland /* 1034*5c51f124SMoriah Waterland * object is not locked but a key was specified 1035*5c51f124SMoriah Waterland */ 1036*5c51f124SMoriah Waterland case FINDLOCK_NOTLOCKED: 1037*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR, 1038*5c51f124SMoriah Waterland MSG_LOCK_ACQUIRE_NOTLOCKED, 1039*5c51f124SMoriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR, 1040*5c51f124SMoriah Waterland a_object, a_key); 1041*5c51f124SMoriah Waterland break; 1042*5c51f124SMoriah Waterland 1043*5c51f124SMoriah Waterland /* 1044*5c51f124SMoriah Waterland * object is locked and no key was specified: 1045*5c51f124SMoriah Waterland * - if lock is exclusively held, return "locked" 1046*5c51f124SMoriah Waterland * - if exclusive lock requested, return "locked" 1047*5c51f124SMoriah Waterland * - otherwise lock is shared and shared lock requested, 1048*5c51f124SMoriah Waterland * - increment lock count and return the key 1049*5c51f124SMoriah Waterland */ 1050*5c51f124SMoriah Waterland case FINDLOCK_LOCKED: 1051*5c51f124SMoriah Waterland /* return error if current lock exclusive */ 1052*5c51f124SMoriah Waterland 1053*5c51f124SMoriah Waterland if (a_theLock->_lrLock.lockExclusive) { 1054*5c51f124SMoriah Waterland break; 1055*5c51f124SMoriah Waterland } 1056*5c51f124SMoriah Waterland 1057*5c51f124SMoriah Waterland /* return error if requesting exclusive lock */ 1058*5c51f124SMoriah Waterland 1059*5c51f124SMoriah Waterland if (a_exclusive) { 1060*5c51f124SMoriah Waterland break; 1061*5c51f124SMoriah Waterland } 1062*5c51f124SMoriah Waterland 1063*5c51f124SMoriah Waterland /* shared requesting shared - add to shared lock */ 1064*5c51f124SMoriah Waterland 1065*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, 1066*5c51f124SMoriah Waterland MSG_LOCK_ACQUIRE_LOCKED_SHARED, 1067*5c51f124SMoriah Waterland a_object, a_key); 1068*5c51f124SMoriah Waterland 1069*5c51f124SMoriah Waterland /* increment shared lock count */ 1070*5c51f124SMoriah Waterland 1071*5c51f124SMoriah Waterland if (_incrementLockCount(a_fd, a_theLock) == 0) { 1072*5c51f124SMoriah Waterland result = FINDLOCK_LOCKACQUIRED; 1073*5c51f124SMoriah Waterland } else { 1074*5c51f124SMoriah Waterland result = FINDLOCK_ERROR; 1075*5c51f124SMoriah Waterland } 1076*5c51f124SMoriah Waterland 1077*5c51f124SMoriah Waterland break; 1078*5c51f124SMoriah Waterland 1079*5c51f124SMoriah Waterland /* 1080*5c51f124SMoriah Waterland * object is not locked 1081*5c51f124SMoriah Waterland */ 1082*5c51f124SMoriah Waterland case FINDLOCK_NOTFOUND: 1083*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, 1084*5c51f124SMoriah Waterland MSG_LOCK_ACQUIRE_NOTFOUND, 1085*5c51f124SMoriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR, 1086*5c51f124SMoriah Waterland a_object); 1087*5c51f124SMoriah Waterland 1088*5c51f124SMoriah Waterland if (_addLock(key, a_fd, a_object, a_exclusive, 1089*5c51f124SMoriah Waterland a_pid, a_zid) == 0) { 1090*5c51f124SMoriah Waterland (void) strncpy(a_theLock->_lrLock.lockKey, key, 1091*5c51f124SMoriah Waterland sizeof (a_theLock->_lrLock.lockKey)); 1092*5c51f124SMoriah Waterland result = FINDLOCK_LOCKACQUIRED; 1093*5c51f124SMoriah Waterland } else { 1094*5c51f124SMoriah Waterland result = FINDLOCK_ERROR; 1095*5c51f124SMoriah Waterland } 1096*5c51f124SMoriah Waterland break; 1097*5c51f124SMoriah Waterland 1098*5c51f124SMoriah Waterland /* 1099*5c51f124SMoriah Waterland * object is locked, key specified, specified key does not match 1100*5c51f124SMoriah Waterland */ 1101*5c51f124SMoriah Waterland case FINDLOCK_KEYMISMATCH: 1102*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR, 1103*5c51f124SMoriah Waterland MSG_LOCK_ACQUIRE_KEYMISMATCH, 1104*5c51f124SMoriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR, 1105*5c51f124SMoriah Waterland a_object); 1106*5c51f124SMoriah Waterland break; 1107*5c51f124SMoriah Waterland 1108*5c51f124SMoriah Waterland /* 1109*5c51f124SMoriah Waterland * error determining if object is locked 1110*5c51f124SMoriah Waterland */ 1111*5c51f124SMoriah Waterland case FINDLOCK_ERROR: 1112*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ACQUIRE_ERROR, 1113*5c51f124SMoriah Waterland a_object, a_key, strerror(errno)); 1114*5c51f124SMoriah Waterland break; 1115*5c51f124SMoriah Waterland 1116*5c51f124SMoriah Waterland /* 1117*5c51f124SMoriah Waterland * object is locked and specified key matches 1118*5c51f124SMoriah Waterland */ 1119*5c51f124SMoriah Waterland case FINDLOCK_FOUND: 1120*5c51f124SMoriah Waterland /* return locked if object currently locked */ 1121*5c51f124SMoriah Waterland if (a_exclusive != a_theLock->_lrLock.lockExclusive) { 1122*5c51f124SMoriah Waterland result = FINDLOCK_LOCKED; 1123*5c51f124SMoriah Waterland break; 1124*5c51f124SMoriah Waterland } 1125*5c51f124SMoriah Waterland 1126*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_ACQUIRE_FOUND_INC, 1127*5c51f124SMoriah Waterland a_object, a_key, 1128*5c51f124SMoriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR); 1129*5c51f124SMoriah Waterland 1130*5c51f124SMoriah Waterland /* increment shared lock */ 1131*5c51f124SMoriah Waterland 1132*5c51f124SMoriah Waterland if (_incrementLockCount(a_fd, a_theLock) == 0) { 1133*5c51f124SMoriah Waterland result = FINDLOCK_LOCKACQUIRED; 1134*5c51f124SMoriah Waterland } else { 1135*5c51f124SMoriah Waterland result = FINDLOCK_ERROR; 1136*5c51f124SMoriah Waterland } 1137*5c51f124SMoriah Waterland break; 1138*5c51f124SMoriah Waterland 1139*5c51f124SMoriah Waterland /* 1140*5c51f124SMoriah Waterland * unknown return 1141*5c51f124SMoriah Waterland */ 1142*5c51f124SMoriah Waterland default: 1143*5c51f124SMoriah Waterland result = FINDLOCK_ERROR; 1144*5c51f124SMoriah Waterland break; 1145*5c51f124SMoriah Waterland } 1146*5c51f124SMoriah Waterland 1147*5c51f124SMoriah Waterland return (result); 1148*5c51f124SMoriah Waterland } 1149*5c51f124SMoriah Waterland 1150*5c51f124SMoriah Waterland /* 1151*5c51f124SMoriah Waterland * Name: _openLockFile 1152*5c51f124SMoriah Waterland * Description: open the lock file, acquiring exclusive record locks 1153*5c51f124SMoriah Waterland * Arguments: 1154*5c51f124SMoriah Waterland * a_root - root of file system to manipulate locks on 1155*5c51f124SMoriah Waterland * Returns: int 1156*5c51f124SMoriah Waterland * >= 0 - successful - file descriptor lock file opened on 1157*5c51f124SMoriah Waterland * < 0 - not successful 1158*5c51f124SMoriah Waterland */ 1159*5c51f124SMoriah Waterland 1160*5c51f124SMoriah Waterland static int 1161*5c51f124SMoriah Waterland _openLockFile(char *a_root) 1162*5c51f124SMoriah Waterland { 1163*5c51f124SMoriah Waterland WAITER_T waiter; 1164*5c51f124SMoriah Waterland char lockpath[MAXPATHLEN]; 1165*5c51f124SMoriah Waterland int fd; 1166*5c51f124SMoriah Waterland int result; 1167*5c51f124SMoriah Waterland 1168*5c51f124SMoriah Waterland /* entry debugging info */ 1169*5c51f124SMoriah Waterland 1170*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_ENTRY, 1171*5c51f124SMoriah Waterland a_root, LOCK_FILENAME); 1172*5c51f124SMoriah Waterland 1173*5c51f124SMoriah Waterland /* generate path to lock directory */ 1174*5c51f124SMoriah Waterland 1175*5c51f124SMoriah Waterland (void) snprintf(lockpath, sizeof (lockpath), "%s/%s", 1176*5c51f124SMoriah Waterland a_root, LOCK_DIRECTORY); 1177*5c51f124SMoriah Waterland 1178*5c51f124SMoriah Waterland if (access(lockpath, F_OK) != 0) { 1179*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ROOTDIR_INVALID, 1180*5c51f124SMoriah Waterland lockpath, strerror(errno)); 1181*5c51f124SMoriah Waterland return (-1); 1182*5c51f124SMoriah Waterland } 1183*5c51f124SMoriah Waterland 1184*5c51f124SMoriah Waterland /* generate path to lock file */ 1185*5c51f124SMoriah Waterland 1186*5c51f124SMoriah Waterland (void) snprintf(lockpath, sizeof (lockpath), 1187*5c51f124SMoriah Waterland "%s/%s", a_root, LOCK_FILENAME); 1188*5c51f124SMoriah Waterland 1189*5c51f124SMoriah Waterland /* wait for open to succeed up to limits */ 1190*5c51f124SMoriah Waterland 1191*5c51f124SMoriah Waterland for (waiter = WAITER_INITIAL; 1192*5c51f124SMoriah Waterland waiter < WAITER_MAX; 1193*5c51f124SMoriah Waterland waiter = WAITER_NEXT(waiter)) { 1194*5c51f124SMoriah Waterland 1195*5c51f124SMoriah Waterland /* LINTED O_CREAT without O_EXCL specified in call to open() */ 1196*5c51f124SMoriah Waterland fd = open(lockpath, O_CREAT|O_RDWR, LOCK_FILEMODE); 1197*5c51f124SMoriah Waterland 1198*5c51f124SMoriah Waterland /* break out of loop if file opened */ 1199*5c51f124SMoriah Waterland 1200*5c51f124SMoriah Waterland if (fd >= 0) { 1201*5c51f124SMoriah Waterland break; 1202*5c51f124SMoriah Waterland } 1203*5c51f124SMoriah Waterland 1204*5c51f124SMoriah Waterland /* failed - exit loop if due to access (permissions) failure */ 1205*5c51f124SMoriah Waterland 1206*5c51f124SMoriah Waterland if (errno == EACCES) { 1207*5c51f124SMoriah Waterland break; 1208*5c51f124SMoriah Waterland } 1209*5c51f124SMoriah Waterland 1210*5c51f124SMoriah Waterland /* file is busy - wait and try again */ 1211*5c51f124SMoriah Waterland 1212*5c51f124SMoriah Waterland if (waiter == WAITER_INITIAL) { 1213*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, 1214*5c51f124SMoriah Waterland MSG_LOCK_OPENFILE_SLEEPING, 1215*5c51f124SMoriah Waterland strerror(errno), waiter); 1216*5c51f124SMoriah Waterland } 1217*5c51f124SMoriah Waterland 1218*5c51f124SMoriah Waterland (void) sleep(waiter); 1219*5c51f124SMoriah Waterland } 1220*5c51f124SMoriah Waterland 1221*5c51f124SMoriah Waterland /* if open filed generate error message and return error */ 1222*5c51f124SMoriah Waterland 1223*5c51f124SMoriah Waterland if (fd < 0) { 1224*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_FAILURE, 1225*5c51f124SMoriah Waterland strerror(errno)); 1226*5c51f124SMoriah Waterland perror(lockpath); 1227*5c51f124SMoriah Waterland return (-1); 1228*5c51f124SMoriah Waterland } 1229*5c51f124SMoriah Waterland 1230*5c51f124SMoriah Waterland /* 1231*5c51f124SMoriah Waterland * lock file opened - acquire exclusive section lock on entire file; 1232*5c51f124SMoriah Waterland * wait for lockf to succeed up to limits 1233*5c51f124SMoriah Waterland */ 1234*5c51f124SMoriah Waterland 1235*5c51f124SMoriah Waterland for (waiter = WAITER_INITIAL; 1236*5c51f124SMoriah Waterland waiter < WAITER_MAX; 1237*5c51f124SMoriah Waterland waiter = WAITER_NEXT(waiter)) { 1238*5c51f124SMoriah Waterland 1239*5c51f124SMoriah Waterland /* acquire exclusive section lock on entire file */ 1240*5c51f124SMoriah Waterland 1241*5c51f124SMoriah Waterland result = lockf(fd, F_LOCK, 0xFFFFF); 1242*5c51f124SMoriah Waterland 1243*5c51f124SMoriah Waterland /* break out of loop if entire file locked */ 1244*5c51f124SMoriah Waterland 1245*5c51f124SMoriah Waterland if (result == 0) { 1246*5c51f124SMoriah Waterland break; 1247*5c51f124SMoriah Waterland } 1248*5c51f124SMoriah Waterland 1249*5c51f124SMoriah Waterland /* file is busy - wait and try again */ 1250*5c51f124SMoriah Waterland 1251*5c51f124SMoriah Waterland if (waiter == WAITER_INITIAL) { 1252*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_SLEEP2, 1253*5c51f124SMoriah Waterland strerror(errno), waiter); 1254*5c51f124SMoriah Waterland } 1255*5c51f124SMoriah Waterland 1256*5c51f124SMoriah Waterland (void) sleep(waiter); 1257*5c51f124SMoriah Waterland } 1258*5c51f124SMoriah Waterland 1259*5c51f124SMoriah Waterland /* if section lock failed generate error message and return error */ 1260*5c51f124SMoriah Waterland 1261*5c51f124SMoriah Waterland if (result < 0) { 1262*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_FAIL2, 1263*5c51f124SMoriah Waterland strerror(errno)); 1264*5c51f124SMoriah Waterland perror(lockpath); 1265*5c51f124SMoriah Waterland (void) close(fd); 1266*5c51f124SMoriah Waterland return (-1); 1267*5c51f124SMoriah Waterland } 1268*5c51f124SMoriah Waterland 1269*5c51f124SMoriah Waterland /* file opened and locked - return success */ 1270*5c51f124SMoriah Waterland 1271*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_SUCCESS, fd); 1272*5c51f124SMoriah Waterland 1273*5c51f124SMoriah Waterland return (fd); 1274*5c51f124SMoriah Waterland } 1275*5c51f124SMoriah Waterland 1276*5c51f124SMoriah Waterland /* 1277*5c51f124SMoriah Waterland * Name: _lockMatch 1278*5c51f124SMoriah Waterland * Description: Compare two lock objects using file name match criteria 1279*5c51f124SMoriah Waterland * Arguments: 1280*5c51f124SMoriah Waterland * a_s1Lock - first lock object to compare against the second 1281*5c51f124SMoriah Waterland * a_s2Lock - second lock object to compare against the first 1282*5c51f124SMoriah Waterland * Returns: 1283*5c51f124SMoriah Waterland * == 0 - the locks match at some level 1284*5c51f124SMoriah Waterland * != 0 - the locks do not match at any level 1285*5c51f124SMoriah Waterland */ 1286*5c51f124SMoriah Waterland 1287*5c51f124SMoriah Waterland static int 1288*5c51f124SMoriah Waterland _lockMatch(char *a_s1Lock, char *a_s2Lock) 1289*5c51f124SMoriah Waterland { 1290*5c51f124SMoriah Waterland boolean_t s1Sfx = B_FALSE; 1291*5c51f124SMoriah Waterland boolean_t s2Sfx = B_FALSE; 1292*5c51f124SMoriah Waterland char *final1Lock = (char *)NULL; 1293*5c51f124SMoriah Waterland char *final2Lock = (char *)NULL; 1294*5c51f124SMoriah Waterland char s1Buf[MAXPATHLEN] = {'\0'}; 1295*5c51f124SMoriah Waterland char s1Prefix[MAXPATHLEN] = {'\0'}; 1296*5c51f124SMoriah Waterland char s2Buf[MAXPATHLEN] = {'\0'}; 1297*5c51f124SMoriah Waterland char s2Prefix[MAXPATHLEN] = {'\0'}; 1298*5c51f124SMoriah Waterland int result = 0; 1299*5c51f124SMoriah Waterland int s1Cnt; 1300*5c51f124SMoriah Waterland int s2Cnt; 1301*5c51f124SMoriah Waterland 1302*5c51f124SMoriah Waterland /* entry assertions */ 1303*5c51f124SMoriah Waterland 1304*5c51f124SMoriah Waterland assert(a_s1Lock != (char *)NULL); 1305*5c51f124SMoriah Waterland assert(a_s2Lock != (char *)NULL); 1306*5c51f124SMoriah Waterland 1307*5c51f124SMoriah Waterland /* entry debugging info */ 1308*5c51f124SMoriah Waterland 1309*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_ENTRY, a_s1Lock, a_s2Lock); 1310*5c51f124SMoriah Waterland 1311*5c51f124SMoriah Waterland /* 1312*5c51f124SMoriah Waterland * attempt to find a common anchor between the two locks; that is, 1313*5c51f124SMoriah Waterland * find the first node in the first lock that matches any node 1314*5c51f124SMoriah Waterland * in the second lock; for example: 1315*5c51f124SMoriah Waterland * --> a/b/c vs b/c/d 1316*5c51f124SMoriah Waterland * -> common anchor is "b"; comparison would expand to: 1317*5c51f124SMoriah Waterland * --> a/b/c/? vs ?/b/c/d 1318*5c51f124SMoriah Waterland */ 1319*5c51f124SMoriah Waterland 1320*5c51f124SMoriah Waterland /* process each node in the first lock */ 1321*5c51f124SMoriah Waterland 1322*5c51f124SMoriah Waterland for (s1Cnt = 0; ; s1Cnt++) { 1323*5c51f124SMoriah Waterland /* get next first lock node */ 1324*5c51f124SMoriah Waterland 1325*5c51f124SMoriah Waterland pkgstrGetToken_r((char *)NULL, a_s1Lock, s1Cnt, "/", 1326*5c51f124SMoriah Waterland s1Buf, sizeof (s1Buf)); 1327*5c51f124SMoriah Waterland 1328*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_FSTNODE, s1Cnt, s1Buf); 1329*5c51f124SMoriah Waterland 1330*5c51f124SMoriah Waterland /* exit if no more nodes left */ 1331*5c51f124SMoriah Waterland 1332*5c51f124SMoriah Waterland if (s1Buf[0] == '\0') { 1333*5c51f124SMoriah Waterland break; 1334*5c51f124SMoriah Waterland } 1335*5c51f124SMoriah Waterland 1336*5c51f124SMoriah Waterland /* discover "." prefix for this node */ 1337*5c51f124SMoriah Waterland 1338*5c51f124SMoriah Waterland pkgstrGetToken_r((char *)NULL, s1Buf, 0, ".", s1Prefix, 1339*5c51f124SMoriah Waterland sizeof (s1Prefix)); 1340*5c51f124SMoriah Waterland 1341*5c51f124SMoriah Waterland s1Sfx = (strlen(s1Prefix) == strlen(s1Buf) ? B_FALSE : B_TRUE); 1342*5c51f124SMoriah Waterland 1343*5c51f124SMoriah Waterland /* search each second lock node; look for the first node lock */ 1344*5c51f124SMoriah Waterland 1345*5c51f124SMoriah Waterland for (s2Cnt = 0; ; s2Cnt++) { 1346*5c51f124SMoriah Waterland /* get next second lock node */ 1347*5c51f124SMoriah Waterland 1348*5c51f124SMoriah Waterland pkgstrGetToken_r((char *)NULL, a_s2Lock, s2Cnt, "/", 1349*5c51f124SMoriah Waterland s2Buf, sizeof (s2Buf)); 1350*5c51f124SMoriah Waterland 1351*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SCNDNODE, s2Cnt, 1352*5c51f124SMoriah Waterland s2Buf); 1353*5c51f124SMoriah Waterland 1354*5c51f124SMoriah Waterland /* exit if no nodes left */ 1355*5c51f124SMoriah Waterland 1356*5c51f124SMoriah Waterland if (s2Buf[0] == '\0') { 1357*5c51f124SMoriah Waterland break; 1358*5c51f124SMoriah Waterland } 1359*5c51f124SMoriah Waterland 1360*5c51f124SMoriah Waterland /* discover "." prefix for this node */ 1361*5c51f124SMoriah Waterland 1362*5c51f124SMoriah Waterland pkgstrGetToken_r((char *)NULL, s2Buf, 0, ".", s2Prefix, 1363*5c51f124SMoriah Waterland sizeof (s2Prefix)); 1364*5c51f124SMoriah Waterland 1365*5c51f124SMoriah Waterland s2Sfx = (strlen(s2Prefix) == 1366*5c51f124SMoriah Waterland strlen(s2Buf) ? B_FALSE : B_TRUE); 1367*5c51f124SMoriah Waterland 1368*5c51f124SMoriah Waterland /* 1369*5c51f124SMoriah Waterland * process this pair of nodes: 1370*5c51f124SMoriah Waterland * if both nodes do not have a prefix, then directly 1371*5c51f124SMoriah Waterland * compare the nodes (e.g. a/b vs c/d: a vs c, b vs d) 1372*5c51f124SMoriah Waterland * and break out of the loop if there is a match; 1373*5c51f124SMoriah Waterland * otherwise, compare prefixes and break out of the 1374*5c51f124SMoriah Waterland * loop if there is a match (e.g. a.* / b.* vs 1375*5c51f124SMoriah Waterland * vs c.* / d.*: a.* vs c.*, a.* vs d.*, b.* vs c.*, 1376*5c51f124SMoriah Waterland * b.* vs d.*). 1377*5c51f124SMoriah Waterland */ 1378*5c51f124SMoriah Waterland 1379*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_NODES, s1Buf, 1380*5c51f124SMoriah Waterland s1Prefix, s1Sfx, s2Buf, s2Prefix, s2Sfx); 1381*5c51f124SMoriah Waterland 1382*5c51f124SMoriah Waterland if ((s1Sfx == B_FALSE) || (s2Sfx == B_FALSE)) { 1383*5c51f124SMoriah Waterland /* one doesnt have a prefix direct comparison */ 1384*5c51f124SMoriah Waterland 1385*5c51f124SMoriah Waterland if (strcmp(s1Buf, s2Buf) == 0) { 1386*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, 1387*5c51f124SMoriah Waterland MSG_LCKMCH_DIRMCH, 1388*5c51f124SMoriah Waterland s1Buf, s2Buf); 1389*5c51f124SMoriah Waterland break; 1390*5c51f124SMoriah Waterland } 1391*5c51f124SMoriah Waterland 1392*5c51f124SMoriah Waterland /* nodes do not directly match, continue */ 1393*5c51f124SMoriah Waterland 1394*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_DIRNOMCH, 1395*5c51f124SMoriah Waterland s1Buf, s2Buf); 1396*5c51f124SMoriah Waterland continue; 1397*5c51f124SMoriah Waterland } 1398*5c51f124SMoriah Waterland 1399*5c51f124SMoriah Waterland /* both have prefix, compare prefixes */ 1400*5c51f124SMoriah Waterland 1401*5c51f124SMoriah Waterland if (strcmp(s1Prefix, s2Prefix) == 0) { 1402*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_PFXMCH, 1403*5c51f124SMoriah Waterland s1Prefix, s2Prefix); 1404*5c51f124SMoriah Waterland break; 1405*5c51f124SMoriah Waterland } 1406*5c51f124SMoriah Waterland 1407*5c51f124SMoriah Waterland /* prefixes do not match, continue */ 1408*5c51f124SMoriah Waterland 1409*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_PFXNOMCH, s1Prefix, 1410*5c51f124SMoriah Waterland s2Prefix); 1411*5c51f124SMoriah Waterland } 1412*5c51f124SMoriah Waterland 1413*5c51f124SMoriah Waterland /* 1414*5c51f124SMoriah Waterland * match found if not at the end of the second lock node list, 1415*5c51f124SMoriah Waterland * break out of loop because some match between the two lock 1416*5c51f124SMoriah Waterland * objects has been found 1417*5c51f124SMoriah Waterland */ 1418*5c51f124SMoriah Waterland 1419*5c51f124SMoriah Waterland if (s2Buf[0] != '\0') { 1420*5c51f124SMoriah Waterland break; 1421*5c51f124SMoriah Waterland } 1422*5c51f124SMoriah Waterland } 1423*5c51f124SMoriah Waterland 1424*5c51f124SMoriah Waterland /* 1425*5c51f124SMoriah Waterland * at this point, either a match has been found between the nodes in 1426*5c51f124SMoriah Waterland * the two lock objects, or there is no commonality at all between 1427*5c51f124SMoriah Waterland * the two lock objects. 1428*5c51f124SMoriah Waterland * 1429*5c51f124SMoriah Waterland * s1Buf[0] == '\0' && s2Buf[0] == '\0': 1430*5c51f124SMoriah Waterland * --> nothing in first lock matches anything in second lock: 1431*5c51f124SMoriah Waterland * ----> (s1Cnt == 1) || (s2Cnt == 1) && (s1Sfx == B_FALSE) 1432*5c51f124SMoriah Waterland * ----> || (s2Sfx == B_FALSE) 1433*5c51f124SMoriah Waterland * --------> an absolute lock do not match 1434*5c51f124SMoriah Waterland * ----> else both object locks have nothing in common - match 1435*5c51f124SMoriah Waterland * 1436*5c51f124SMoriah Waterland * s2Buf[0] != '\0' && s1Buf[0] != '\0' && s1Cnt > 0 && s2Cnt > 0 1437*5c51f124SMoriah Waterland * --> locks have incompatible overlaps - no match, such as: 1438*5c51f124SMoriah Waterland * ----> a.* / b.* / c.* / d.* and y.* / b.* / c.* 1439*5c51f124SMoriah Waterland * 1440*5c51f124SMoriah Waterland * s1Cnt == 0 && s2Cnt == 0: 1441*5c51f124SMoriah Waterland * --> locks begin with same node - do comparison 1442*5c51f124SMoriah Waterland * 1443*5c51f124SMoriah Waterland * s1Cnt != 0 && s2Cnt == 0 && s2Buf[0] != '\0' 1444*5c51f124SMoriah Waterland * --> second lock is subset of first lock 1445*5c51f124SMoriah Waterland * 1446*5c51f124SMoriah Waterland * s2Cnt == 0 && s2Buf[0] != '\0': 1447*5c51f124SMoriah Waterland * --> s1Buf[s1Cnt] matches s2Buf[0] - second is subset of first 1448*5c51f124SMoriah Waterland * 1449*5c51f124SMoriah Waterland * s2Cnt != 0 && s1Cnt == 0 && s1Buf[0] != '\0': 1450*5c51f124SMoriah Waterland * --> first lock is subset of second lock 1451*5c51f124SMoriah Waterland * 1452*5c51f124SMoriah Waterland */ 1453*5c51f124SMoriah Waterland 1454*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_FSTLCK, s1Cnt, s1Buf, 1455*5c51f124SMoriah Waterland s1Prefix, s1Sfx); 1456*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SCNDLCK, s2Cnt, s2Buf, 1457*5c51f124SMoriah Waterland s2Prefix, s2Sfx); 1458*5c51f124SMoriah Waterland 1459*5c51f124SMoriah Waterland /* process any direct comparisons that might be possible */ 1460*5c51f124SMoriah Waterland 1461*5c51f124SMoriah Waterland if ((s1Buf[0] == '\0') && (s2Buf[0] == '\0')) { 1462*5c51f124SMoriah Waterland /* nothing in first matches anything in second lock */ 1463*5c51f124SMoriah Waterland 1464*5c51f124SMoriah Waterland if (((s1Cnt == 1) || (s2Cnt == 1)) && 1465*5c51f124SMoriah Waterland ((s1Sfx == B_FALSE) || (s2Sfx == B_FALSE))) { 1466*5c51f124SMoriah Waterland /* two absolute locks match (e.g. 'file' and 'dir') */ 1467*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_ABSNOMCH, a_s1Lock, 1468*5c51f124SMoriah Waterland a_s2Lock); 1469*5c51f124SMoriah Waterland return (1); 1470*5c51f124SMoriah Waterland } 1471*5c51f124SMoriah Waterland 1472*5c51f124SMoriah Waterland /* two object locks have nothing in common: match */ 1473*5c51f124SMoriah Waterland 1474*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_OBJMCH, a_s1Lock, a_s2Lock); 1475*5c51f124SMoriah Waterland 1476*5c51f124SMoriah Waterland return (0); 1477*5c51f124SMoriah Waterland } 1478*5c51f124SMoriah Waterland 1479*5c51f124SMoriah Waterland if ((s2Buf[0] != '\0') && (s1Buf[0] != '\0') && 1480*5c51f124SMoriah Waterland (s1Cnt > 0) && (s2Cnt > 0)) { 1481*5c51f124SMoriah Waterland /* incompatible overlapping objects */ 1482*5c51f124SMoriah Waterland 1483*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_OVLPNOMCH, a_s1Lock, a_s2Lock, 1484*5c51f124SMoriah Waterland s1Cnt+1, s1Buf); 1485*5c51f124SMoriah Waterland 1486*5c51f124SMoriah Waterland return (1); 1487*5c51f124SMoriah Waterland } 1488*5c51f124SMoriah Waterland 1489*5c51f124SMoriah Waterland /* 1490*5c51f124SMoriah Waterland * must compare each node of each lock to determine match; 1491*5c51f124SMoriah Waterland * start off at the first byte of both locks 1492*5c51f124SMoriah Waterland */ 1493*5c51f124SMoriah Waterland 1494*5c51f124SMoriah Waterland final1Lock = a_s1Lock; 1495*5c51f124SMoriah Waterland final2Lock = a_s2Lock; 1496*5c51f124SMoriah Waterland 1497*5c51f124SMoriah Waterland if ((s1Cnt == 0) && (s2Cnt == 0)) { 1498*5c51f124SMoriah Waterland /* both have first match - start comparison from the begining */ 1499*5c51f124SMoriah Waterland 1500*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SAME, a_s1Lock, a_s2Lock, 1501*5c51f124SMoriah Waterland s1Buf); 1502*5c51f124SMoriah Waterland 1503*5c51f124SMoriah Waterland } else if ((s1Cnt != 0) && (s2Cnt == 0) && (s2Buf[0] != '\0')) { 1504*5c51f124SMoriah Waterland /* second lock begins somewhere inside of the first lock */ 1505*5c51f124SMoriah Waterland 1506*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SCNDSUB, a_s2Lock, a_s1Lock, 1507*5c51f124SMoriah Waterland s1Cnt+1, s1Buf); 1508*5c51f124SMoriah Waterland 1509*5c51f124SMoriah Waterland /* advance first lock to matching node in second lock */ 1510*5c51f124SMoriah Waterland 1511*5c51f124SMoriah Waterland if (strchr(a_s1Lock, '/') != (char *)NULL) { 1512*5c51f124SMoriah Waterland for (; s1Cnt > 0 && (*final1Lock != '\0'); 1513*5c51f124SMoriah Waterland final1Lock++) { 1514*5c51f124SMoriah Waterland if (*final1Lock == '/') { 1515*5c51f124SMoriah Waterland s1Cnt--; 1516*5c51f124SMoriah Waterland } 1517*5c51f124SMoriah Waterland } 1518*5c51f124SMoriah Waterland } 1519*5c51f124SMoriah Waterland } else if ((s2Cnt != 0) && (s1Cnt == 0) && (s1Buf[0] != '\0')) { 1520*5c51f124SMoriah Waterland /* first lock begins somewhere inside of the second lock */ 1521*5c51f124SMoriah Waterland 1522*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_FRSTSUB, a_s1Lock, a_s2Lock, 1523*5c51f124SMoriah Waterland s2Cnt+1, s2Buf); 1524*5c51f124SMoriah Waterland 1525*5c51f124SMoriah Waterland /* advance second lock to matching node in first lock */ 1526*5c51f124SMoriah Waterland 1527*5c51f124SMoriah Waterland if (strchr(a_s2Lock, '/') != (char *)NULL) { 1528*5c51f124SMoriah Waterland for (; s2Cnt > 0 && (*final2Lock != '\0'); 1529*5c51f124SMoriah Waterland final2Lock++) { 1530*5c51f124SMoriah Waterland if (*final2Lock == '/') { 1531*5c51f124SMoriah Waterland s2Cnt--; 1532*5c51f124SMoriah Waterland } 1533*5c51f124SMoriah Waterland } 1534*5c51f124SMoriah Waterland } 1535*5c51f124SMoriah Waterland } else { 1536*5c51f124SMoriah Waterland /* unknown condition (probably impossible): directly compare */ 1537*5c51f124SMoriah Waterland 1538*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LCKMCH_DONTKNOW, a_s1Lock, a_s2Lock); 1539*5c51f124SMoriah Waterland } 1540*5c51f124SMoriah Waterland 1541*5c51f124SMoriah Waterland /* 1542*5c51f124SMoriah Waterland * locks have common node - compare from that node forward 1543*5c51f124SMoriah Waterland */ 1544*5c51f124SMoriah Waterland 1545*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_READY, final1Lock, final2Lock); 1546*5c51f124SMoriah Waterland 1547*5c51f124SMoriah Waterland /* compare each node (prefix) - success when no more nodes to compare */ 1548*5c51f124SMoriah Waterland 1549*5c51f124SMoriah Waterland for (s1Cnt = 0; ; s1Cnt++) { 1550*5c51f124SMoriah Waterland /* get next node from first lock */ 1551*5c51f124SMoriah Waterland 1552*5c51f124SMoriah Waterland pkgstrGetToken_r((char *)NULL, final1Lock, s1Cnt, "/", s1Buf, 1553*5c51f124SMoriah Waterland sizeof (s1Buf)); 1554*5c51f124SMoriah Waterland 1555*5c51f124SMoriah Waterland /* success if at end of lock */ 1556*5c51f124SMoriah Waterland 1557*5c51f124SMoriah Waterland if (s1Buf[0] == '\0') { 1558*5c51f124SMoriah Waterland break; 1559*5c51f124SMoriah Waterland } 1560*5c51f124SMoriah Waterland 1561*5c51f124SMoriah Waterland /* get next node from second lock */ 1562*5c51f124SMoriah Waterland 1563*5c51f124SMoriah Waterland pkgstrGetToken_r((char *)NULL, final2Lock, s1Cnt, "/", s2Buf, 1564*5c51f124SMoriah Waterland sizeof (s2Buf)); 1565*5c51f124SMoriah Waterland 1566*5c51f124SMoriah Waterland /* success if at end of lock */ 1567*5c51f124SMoriah Waterland 1568*5c51f124SMoriah Waterland if (s2Buf[0] == '\0') { 1569*5c51f124SMoriah Waterland break; 1570*5c51f124SMoriah Waterland } 1571*5c51f124SMoriah Waterland 1572*5c51f124SMoriah Waterland /* compare both nodes */ 1573*5c51f124SMoriah Waterland 1574*5c51f124SMoriah Waterland result = fnmatch(s1Buf, s2Buf, 0); 1575*5c51f124SMoriah Waterland if (result != 0) { 1576*5c51f124SMoriah Waterland result = fnmatch(s2Buf, s1Buf, 0); 1577*5c51f124SMoriah Waterland } 1578*5c51f124SMoriah Waterland 1579*5c51f124SMoriah Waterland /* failure if nodes do not match */ 1580*5c51f124SMoriah Waterland 1581*5c51f124SMoriah Waterland if (result != 0) { 1582*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_NODEFAIL, 1583*5c51f124SMoriah Waterland s1Cnt, s1Buf, s2Buf); 1584*5c51f124SMoriah Waterland return (1); 1585*5c51f124SMoriah Waterland } 1586*5c51f124SMoriah Waterland 1587*5c51f124SMoriah Waterland /* nodes match, continue and compare next set of nodes */ 1588*5c51f124SMoriah Waterland 1589*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_NODEOK, s1Cnt, s1Buf, s2Buf); 1590*5c51f124SMoriah Waterland } 1591*5c51f124SMoriah Waterland 1592*5c51f124SMoriah Waterland /* no more nodes to compare - locks match */ 1593*5c51f124SMoriah Waterland 1594*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_MATCHOK, final1Lock, final2Lock); 1595*5c51f124SMoriah Waterland 1596*5c51f124SMoriah Waterland return (0); 1597*5c51f124SMoriah Waterland } 1598*5c51f124SMoriah Waterland 1599*5c51f124SMoriah Waterland /* 1600*5c51f124SMoriah Waterland * Name: _findLock 1601*5c51f124SMoriah Waterland * Description: Locate specified lock in lock file 1602*5c51f124SMoriah Waterland * Arguments: 1603*5c51f124SMoriah Waterland * a_theLock - lock object filled with contents of lock (if found) 1604*5c51f124SMoriah Waterland * r_recordNum - will contain record number if lock found 1605*5c51f124SMoriah Waterland * - will be RECORDNUM_NONE if lock not found 1606*5c51f124SMoriah Waterland * a_fd - file descriptor opened on the lock file 1607*5c51f124SMoriah Waterland * a_key - key associated with lock to look up 1608*5c51f124SMoriah Waterland * a_object - object associated with lock to look up 1609*5c51f124SMoriah Waterland * Returns: 1610*5c51f124SMoriah Waterland * FINDLOCK_FOUND - specified lock found; a_theLock contains contents 1611*5c51f124SMoriah Waterland * of found lock, r_recordNum contain record number of lock 1612*5c51f124SMoriah Waterland * FINDLOCK_ERROR - failed - error occurred looking up the lock 1613*5c51f124SMoriah Waterland * FINDLOCK_NOTFOUND - specified object is not locked 1614*5c51f124SMoriah Waterland * FINDLOCK_KEYMISMATCH - object lock found but specified key doesnt match 1615*5c51f124SMoriah Waterland * FINDLOCK_LOCKED - object lock found but no key specified 1616*5c51f124SMoriah Waterland * FINDLOCK_NOTLOCKED - object not locked 1617*5c51f124SMoriah Waterland */ 1618*5c51f124SMoriah Waterland 1619*5c51f124SMoriah Waterland static FINDLOCK_T 1620*5c51f124SMoriah Waterland _findLock(LOCK_T *a_theLock, RECORDNUM_T *r_recordNum, 1621*5c51f124SMoriah Waterland int a_fd, char *a_object, char *a_key) 1622*5c51f124SMoriah Waterland { 1623*5c51f124SMoriah Waterland ADMINLOCK_T *pll; 1624*5c51f124SMoriah Waterland char *pld; 1625*5c51f124SMoriah Waterland int recordNum = 0; 1626*5c51f124SMoriah Waterland long pls; 1627*5c51f124SMoriah Waterland off_t pos; 1628*5c51f124SMoriah Waterland 1629*5c51f124SMoriah Waterland /* reset returned record number to "none" */ 1630*5c51f124SMoriah Waterland 1631*5c51f124SMoriah Waterland *r_recordNum = RECORDNUM_NONE; 1632*5c51f124SMoriah Waterland 1633*5c51f124SMoriah Waterland /* localize references to lock object */ 1634*5c51f124SMoriah Waterland 1635*5c51f124SMoriah Waterland pld = &a_theLock->_lrLockData[0]; 1636*5c51f124SMoriah Waterland pll = &a_theLock->_lrLock; 1637*5c51f124SMoriah Waterland pls = sizeof (a_theLock->_lrLockData); 1638*5c51f124SMoriah Waterland 1639*5c51f124SMoriah Waterland /* zero out returned lock data */ 1640*5c51f124SMoriah Waterland 1641*5c51f124SMoriah Waterland bzero(pld, pls); 1642*5c51f124SMoriah Waterland 1643*5c51f124SMoriah Waterland /* debug info before processing lock file */ 1644*5c51f124SMoriah Waterland 1645*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_ENTRY, 1646*5c51f124SMoriah Waterland a_object, a_key); 1647*5c51f124SMoriah Waterland 1648*5c51f124SMoriah Waterland /* rewind to beginning of lock file */ 1649*5c51f124SMoriah Waterland 1650*5c51f124SMoriah Waterland pos = lseek(a_fd, 0L, SEEK_SET); 1651*5c51f124SMoriah Waterland if (pos == (off_t)-1) { 1652*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_FINDLOCK_LSEEK_FAILURE, 1653*5c51f124SMoriah Waterland a_object, a_key, strerror(errno)); 1654*5c51f124SMoriah Waterland return (FINDLOCK_ERROR); 1655*5c51f124SMoriah Waterland } 1656*5c51f124SMoriah Waterland 1657*5c51f124SMoriah Waterland /* read and process each lock */ 1658*5c51f124SMoriah Waterland 1659*5c51f124SMoriah Waterland for (; pread(a_fd, pld, pls, pls*recordNum) == pls; recordNum++) { 1660*5c51f124SMoriah Waterland /* debug info on this lock */ 1661*5c51f124SMoriah Waterland 1662*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_READRECORD, 1663*5c51f124SMoriah Waterland recordNum, pll->lockCount, 1664*5c51f124SMoriah Waterland pll->lockObject, pll->lockKey, pll->lockPid, 1665*5c51f124SMoriah Waterland pll->lockZoneId); 1666*5c51f124SMoriah Waterland 1667*5c51f124SMoriah Waterland /* continue if object is not the one we are looking for */ 1668*5c51f124SMoriah Waterland 1669*5c51f124SMoriah Waterland if (_lockMatch(a_object, pll->lockObject) != 0) { 1670*5c51f124SMoriah Waterland continue; 1671*5c51f124SMoriah Waterland } 1672*5c51f124SMoriah Waterland 1673*5c51f124SMoriah Waterland /* 1674*5c51f124SMoriah Waterland * object found; return locked if searching for no key 1675*5c51f124SMoriah Waterland */ 1676*5c51f124SMoriah Waterland 1677*5c51f124SMoriah Waterland if (*a_key == '\0') { 1678*5c51f124SMoriah Waterland /* no key specified - object is locked */ 1679*5c51f124SMoriah Waterland *r_recordNum = recordNum; 1680*5c51f124SMoriah Waterland return (FINDLOCK_LOCKED); 1681*5c51f124SMoriah Waterland } 1682*5c51f124SMoriah Waterland 1683*5c51f124SMoriah Waterland /* 1684*5c51f124SMoriah Waterland * object found and keys present; see if keys match 1685*5c51f124SMoriah Waterland */ 1686*5c51f124SMoriah Waterland 1687*5c51f124SMoriah Waterland if (strcmp(pll->lockKey, a_key) != 0) { 1688*5c51f124SMoriah Waterland /* keys do not match */ 1689*5c51f124SMoriah Waterland *r_recordNum = recordNum; 1690*5c51f124SMoriah Waterland return (FINDLOCK_KEYMISMATCH); 1691*5c51f124SMoriah Waterland } 1692*5c51f124SMoriah Waterland 1693*5c51f124SMoriah Waterland /* object found and keys match - return match */ 1694*5c51f124SMoriah Waterland 1695*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_FOUND); 1696*5c51f124SMoriah Waterland 1697*5c51f124SMoriah Waterland *r_recordNum = recordNum; 1698*5c51f124SMoriah Waterland return (FINDLOCK_FOUND); 1699*5c51f124SMoriah Waterland } 1700*5c51f124SMoriah Waterland 1701*5c51f124SMoriah Waterland /* object not locked - return error if key supplied */ 1702*5c51f124SMoriah Waterland 1703*5c51f124SMoriah Waterland if (*a_key != '\0') { 1704*5c51f124SMoriah Waterland return (FINDLOCK_NOTLOCKED); 1705*5c51f124SMoriah Waterland } 1706*5c51f124SMoriah Waterland 1707*5c51f124SMoriah Waterland /* object not locked and key not supplied - no lock found */ 1708*5c51f124SMoriah Waterland 1709*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_NOTFOUND); 1710*5c51f124SMoriah Waterland 1711*5c51f124SMoriah Waterland return (FINDLOCK_NOTFOUND); 1712*5c51f124SMoriah Waterland } 1713*5c51f124SMoriah Waterland 1714*5c51f124SMoriah Waterland /* 1715*5c51f124SMoriah Waterland * Name: _addLock 1716*5c51f124SMoriah Waterland * Description: Add a new lock to the lock file 1717*5c51f124SMoriah Waterland * Arguments: 1718*5c51f124SMoriah Waterland * r_key - if lock acquired key is placed here 1719*5c51f124SMoriah Waterland * a_fd - file descriptor opened on the lock file 1720*5c51f124SMoriah Waterland * a_object - object to lock 1721*5c51f124SMoriah Waterland * a_exclusive - type of lock to add: 1722*5c51f124SMoriah Waterland * == 0 - shared lock 1723*5c51f124SMoriah Waterland * != 0 - exclusive lock 1724*5c51f124SMoriah Waterland * a_pid - if != 0 process i.d. to associate with this lock 1725*5c51f124SMoriah Waterland * a_zid - if >= 0 zone i.d. to associate with this lock 1726*5c51f124SMoriah Waterland * Returns: int 1727*5c51f124SMoriah Waterland * == 0 - success 1728*5c51f124SMoriah Waterland * != 0 - failure 1729*5c51f124SMoriah Waterland */ 1730*5c51f124SMoriah Waterland 1731*5c51f124SMoriah Waterland static int 1732*5c51f124SMoriah Waterland _addLock(char *r_key, int a_fd, char *a_object, int a_exclusive, pid_t a_pid, 1733*5c51f124SMoriah Waterland zoneid_t a_zid) 1734*5c51f124SMoriah Waterland { 1735*5c51f124SMoriah Waterland LOCK_T theLock; 1736*5c51f124SMoriah Waterland char *key; 1737*5c51f124SMoriah Waterland off_t pos; 1738*5c51f124SMoriah Waterland ssize_t result; 1739*5c51f124SMoriah Waterland 1740*5c51f124SMoriah Waterland /* get unique i.d. for this lock */ 1741*5c51f124SMoriah Waterland 1742*5c51f124SMoriah Waterland key = _getUniqueId(); 1743*5c51f124SMoriah Waterland 1744*5c51f124SMoriah Waterland /* determine record number for next record in lock file */ 1745*5c51f124SMoriah Waterland 1746*5c51f124SMoriah Waterland pos = lseek(a_fd, 0L, SEEK_END); 1747*5c51f124SMoriah Waterland if (pos == (off_t)-1) { 1748*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ADDLOCK_LSEEK_FAILURE, 1749*5c51f124SMoriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR, 1750*5c51f124SMoriah Waterland a_object, strerror(errno)); 1751*5c51f124SMoriah Waterland return (1); 1752*5c51f124SMoriah Waterland } 1753*5c51f124SMoriah Waterland 1754*5c51f124SMoriah Waterland /* allocate storace for this lock */ 1755*5c51f124SMoriah Waterland 1756*5c51f124SMoriah Waterland bzero(&theLock, sizeof (theLock)); 1757*5c51f124SMoriah Waterland 1758*5c51f124SMoriah Waterland /* fill in components of the lock */ 1759*5c51f124SMoriah Waterland 1760*5c51f124SMoriah Waterland (void) strlcpy(theLock._lrLock.lockObject, a_object, 1761*5c51f124SMoriah Waterland LOCK_OBJECT_MAXLEN); 1762*5c51f124SMoriah Waterland (void) strlcpy(theLock._lrLock.lockKey, key, LOCK_KEY_MAXLEN); 1763*5c51f124SMoriah Waterland theLock._lrLock.lockCount = 1; 1764*5c51f124SMoriah Waterland theLock._lrLock.lockPid = (a_pid > 0 ? a_pid : 0); 1765*5c51f124SMoriah Waterland theLock._lrLock.lockRecordNum = (pos == 0 ? 0 : (pos/sizeof (LOCK_T))); 1766*5c51f124SMoriah Waterland theLock._lrLock.lockExclusive = a_exclusive; 1767*5c51f124SMoriah Waterland theLock._lrLock.lockZoneId = (a_zid >= 0 ? a_zid : -1); 1768*5c51f124SMoriah Waterland 1769*5c51f124SMoriah Waterland /* debug info on new lock */ 1770*5c51f124SMoriah Waterland 1771*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_ADDLOCK_ADDING, 1772*5c51f124SMoriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR, 1773*5c51f124SMoriah Waterland pos, theLock._lrLock.lockObject, theLock._lrLock.lockKey, 1774*5c51f124SMoriah Waterland theLock._lrLock.lockPid, theLock._lrLock.lockZoneId); 1775*5c51f124SMoriah Waterland 1776*5c51f124SMoriah Waterland /* write the new lock record to the end of the lock file */ 1777*5c51f124SMoriah Waterland 1778*5c51f124SMoriah Waterland result = pwrite(a_fd, &theLock, LOCK_SIZE, pos); 1779*5c51f124SMoriah Waterland if (result != LOCK_SIZE) { 1780*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ADDLOCK_PWRITE_FAILURE, 1781*5c51f124SMoriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR, 1782*5c51f124SMoriah Waterland a_object, strerror(errno)); 1783*5c51f124SMoriah Waterland return (1); 1784*5c51f124SMoriah Waterland } 1785*5c51f124SMoriah Waterland 1786*5c51f124SMoriah Waterland /* output the key assigned to standard out */ 1787*5c51f124SMoriah Waterland 1788*5c51f124SMoriah Waterland (void) strncpy(r_key, key, LOCK_KEY_MAXLEN); 1789*5c51f124SMoriah Waterland 1790*5c51f124SMoriah Waterland return (0); 1791*5c51f124SMoriah Waterland } 1792*5c51f124SMoriah Waterland 1793*5c51f124SMoriah Waterland static int 1794*5c51f124SMoriah Waterland _incrementLockCount(int a_fd, LOCK_T *a_theLock) 1795*5c51f124SMoriah Waterland { 1796*5c51f124SMoriah Waterland ADMINLOCK_T *pll; 1797*5c51f124SMoriah Waterland char *pld; 1798*5c51f124SMoriah Waterland long pls; 1799*5c51f124SMoriah Waterland ssize_t result; 1800*5c51f124SMoriah Waterland 1801*5c51f124SMoriah Waterland /* localize references to lock object */ 1802*5c51f124SMoriah Waterland 1803*5c51f124SMoriah Waterland pld = &a_theLock->_lrLockData[0]; 1804*5c51f124SMoriah Waterland pll = &a_theLock->_lrLock; 1805*5c51f124SMoriah Waterland pls = sizeof (a_theLock->_lrLockData); 1806*5c51f124SMoriah Waterland 1807*5c51f124SMoriah Waterland /* debug info on incrementing lock */ 1808*5c51f124SMoriah Waterland 1809*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_INCLOCK_ENTRY, 1810*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 1811*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 1812*5c51f124SMoriah Waterland pll->lockRecordNum, pll->lockCount); 1813*5c51f124SMoriah Waterland 1814*5c51f124SMoriah Waterland /* increment lock count */ 1815*5c51f124SMoriah Waterland 1816*5c51f124SMoriah Waterland pll->lockCount++; 1817*5c51f124SMoriah Waterland 1818*5c51f124SMoriah Waterland /* write out updated lock */ 1819*5c51f124SMoriah Waterland 1820*5c51f124SMoriah Waterland result = pwrite(a_fd, pld, pls, pll->lockRecordNum*pls); 1821*5c51f124SMoriah Waterland if (result != pls) { 1822*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_INCLOCK_PWRITE_FAILURE, 1823*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 1824*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 1825*5c51f124SMoriah Waterland a_theLock->_lrLock.lockObject, 1826*5c51f124SMoriah Waterland strerror(errno)); 1827*5c51f124SMoriah Waterland return (1); 1828*5c51f124SMoriah Waterland } 1829*5c51f124SMoriah Waterland 1830*5c51f124SMoriah Waterland /* debug info lock incremented */ 1831*5c51f124SMoriah Waterland 1832*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_INCLOCK_DONE, 1833*5c51f124SMoriah Waterland pll->lockRecordNum, pll->lockCount, 1834*5c51f124SMoriah Waterland pll->lockObject, pll->lockKey); 1835*5c51f124SMoriah Waterland 1836*5c51f124SMoriah Waterland return (0); 1837*5c51f124SMoriah Waterland } 1838*5c51f124SMoriah Waterland 1839*5c51f124SMoriah Waterland /* 1840*5c51f124SMoriah Waterland * Name: _validateLock 1841*5c51f124SMoriah Waterland * Description: determine if a specified lock is valid; if the lock is not valid 1842*5c51f124SMoriah Waterland * then remove the lock 1843*5c51f124SMoriah Waterland * Arguments: a_fd - file descriptor opened on the lock file 1844*5c51f124SMoriah Waterland * a_theLock - lock object to validate 1845*5c51f124SMoriah Waterland * Returns: boolean_t 1846*5c51f124SMoriah Waterland * B_TRUE - the lock is valid 1847*5c51f124SMoriah Waterland * B_FALSE - the lock is not valid and has been removed 1848*5c51f124SMoriah Waterland */ 1849*5c51f124SMoriah Waterland 1850*5c51f124SMoriah Waterland static boolean_t 1851*5c51f124SMoriah Waterland _validateLock(int a_fd, LOCK_T *a_theLock, int a_quiet) 1852*5c51f124SMoriah Waterland { 1853*5c51f124SMoriah Waterland ADMINLOCK_T *pll; 1854*5c51f124SMoriah Waterland char *pld; 1855*5c51f124SMoriah Waterland long pls; 1856*5c51f124SMoriah Waterland char path[MAXPATHLEN]; 1857*5c51f124SMoriah Waterland 1858*5c51f124SMoriah Waterland /* localize references to lock object */ 1859*5c51f124SMoriah Waterland 1860*5c51f124SMoriah Waterland pld = &a_theLock->_lrLockData[0]; 1861*5c51f124SMoriah Waterland pll = &a_theLock->_lrLock; 1862*5c51f124SMoriah Waterland pls = sizeof (a_theLock->_lrLockData); 1863*5c51f124SMoriah Waterland 1864*5c51f124SMoriah Waterland /* return true if no process i.d. associated with lock */ 1865*5c51f124SMoriah Waterland 1866*5c51f124SMoriah Waterland if (pll->lockPid <= 0) { 1867*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_NOPID, pll->lockObject); 1868*5c51f124SMoriah Waterland return (B_TRUE); 1869*5c51f124SMoriah Waterland } 1870*5c51f124SMoriah Waterland 1871*5c51f124SMoriah Waterland /* see if the zone i.d. matches */ 1872*5c51f124SMoriah Waterland 1873*5c51f124SMoriah Waterland if (pll->lockZoneId != getzoneid()) { 1874*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_BADZID, pll->lockObject, 1875*5c51f124SMoriah Waterland pll->lockZoneId, getzoneid()); 1876*5c51f124SMoriah Waterland return (B_TRUE); 1877*5c51f124SMoriah Waterland } else { 1878*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_ZIDOK, pll->lockObject, 1879*5c51f124SMoriah Waterland pll->lockZoneId, getzoneid()); 1880*5c51f124SMoriah Waterland } 1881*5c51f124SMoriah Waterland 1882*5c51f124SMoriah Waterland /* see if the process is still active */ 1883*5c51f124SMoriah Waterland 1884*5c51f124SMoriah Waterland pkgstrPrintf_r(path, sizeof (path), "/proc/%d", pll->lockPid); 1885*5c51f124SMoriah Waterland if (access(path, F_OK) == 0) { 1886*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_OK, pll->lockObject, 1887*5c51f124SMoriah Waterland pll->lockPid, path); 1888*5c51f124SMoriah Waterland return (B_TRUE); 1889*5c51f124SMoriah Waterland } 1890*5c51f124SMoriah Waterland 1891*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_NOTOK, pll->lockObject, pll->lockPid, 1892*5c51f124SMoriah Waterland path); 1893*5c51f124SMoriah Waterland 1894*5c51f124SMoriah Waterland /* delete this lock */ 1895*5c51f124SMoriah Waterland 1896*5c51f124SMoriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_WRN, 1897*5c51f124SMoriah Waterland MSG_VALID_STALE, pll->lockObject, pll->lockPid, 1898*5c51f124SMoriah Waterland pll->lockZoneId); 1899*5c51f124SMoriah Waterland 1900*5c51f124SMoriah Waterland _decrementLockCount(a_fd, a_theLock); 1901*5c51f124SMoriah Waterland 1902*5c51f124SMoriah Waterland return (B_FALSE); 1903*5c51f124SMoriah Waterland } 1904*5c51f124SMoriah Waterland 1905*5c51f124SMoriah Waterland static int 1906*5c51f124SMoriah Waterland _decrementLockCount(int a_fd, LOCK_T *a_theLock) 1907*5c51f124SMoriah Waterland { 1908*5c51f124SMoriah Waterland ADMINLOCK_T *pll; 1909*5c51f124SMoriah Waterland LOCK_T tmpLock; 1910*5c51f124SMoriah Waterland RECORDNUM_T lastRecord; 1911*5c51f124SMoriah Waterland char *pld; 1912*5c51f124SMoriah Waterland long pls; 1913*5c51f124SMoriah Waterland off_t lastPos; 1914*5c51f124SMoriah Waterland ssize_t result; 1915*5c51f124SMoriah Waterland int res; 1916*5c51f124SMoriah Waterland 1917*5c51f124SMoriah Waterland /* localize references to lock object */ 1918*5c51f124SMoriah Waterland 1919*5c51f124SMoriah Waterland pld = &a_theLock->_lrLockData[0]; 1920*5c51f124SMoriah Waterland pll = &a_theLock->_lrLock; 1921*5c51f124SMoriah Waterland pls = sizeof (a_theLock->_lrLockData); 1922*5c51f124SMoriah Waterland 1923*5c51f124SMoriah Waterland /* decrement lock count */ 1924*5c51f124SMoriah Waterland 1925*5c51f124SMoriah Waterland pll->lockCount--; 1926*5c51f124SMoriah Waterland 1927*5c51f124SMoriah Waterland /* if lock count > 0 then write out and leave locked */ 1928*5c51f124SMoriah Waterland 1929*5c51f124SMoriah Waterland if (pll->lockCount > 0) { 1930*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_DECING, 1931*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 1932*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 1933*5c51f124SMoriah Waterland pll->lockRecordNum, pll->lockCount); 1934*5c51f124SMoriah Waterland 1935*5c51f124SMoriah Waterland result = pwrite(a_fd, pld, pls, pll->lockRecordNum*pls); 1936*5c51f124SMoriah Waterland if (result != pls) { 1937*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_PWRITE_FAILURE, 1938*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 1939*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 1940*5c51f124SMoriah Waterland a_theLock->_lrLock.lockObject, 1941*5c51f124SMoriah Waterland strerror(errno)); 1942*5c51f124SMoriah Waterland return (1); 1943*5c51f124SMoriah Waterland } 1944*5c51f124SMoriah Waterland 1945*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_DONE, 1946*5c51f124SMoriah Waterland pll->lockRecordNum, pll->lockCount, 1947*5c51f124SMoriah Waterland pll->lockObject, pll->lockKey); 1948*5c51f124SMoriah Waterland 1949*5c51f124SMoriah Waterland return (0); 1950*5c51f124SMoriah Waterland } 1951*5c51f124SMoriah Waterland 1952*5c51f124SMoriah Waterland /* 1953*5c51f124SMoriah Waterland * lock count zero - erase the record 1954*5c51f124SMoriah Waterland */ 1955*5c51f124SMoriah Waterland 1956*5c51f124SMoriah Waterland /* find last record in the lock file */ 1957*5c51f124SMoriah Waterland 1958*5c51f124SMoriah Waterland lastPos = lseek(a_fd, 0L, SEEK_END); /* get size of lock file */ 1959*5c51f124SMoriah Waterland if (lastPos == (off_t)-1) { 1960*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_LSEEK_FAILURE, 1961*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 1962*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 1963*5c51f124SMoriah Waterland a_theLock->_lrLock.lockObject, 1964*5c51f124SMoriah Waterland strerror(errno)); 1965*5c51f124SMoriah Waterland return (1); 1966*5c51f124SMoriah Waterland } 1967*5c51f124SMoriah Waterland 1968*5c51f124SMoriah Waterland lastRecord = (lastPos/pls)-1; /* convert size to record # */ 1969*5c51f124SMoriah Waterland 1970*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_REMOVE, 1971*5c51f124SMoriah Waterland lastPos, lastRecord, pll->lockRecordNum); 1972*5c51f124SMoriah Waterland 1973*5c51f124SMoriah Waterland /* see if removing last record of file */ 1974*5c51f124SMoriah Waterland 1975*5c51f124SMoriah Waterland if (lastRecord == pll->lockRecordNum) { 1976*5c51f124SMoriah Waterland /* debug info removing last record */ 1977*5c51f124SMoriah Waterland 1978*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_LASTONE, 1979*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 1980*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 1981*5c51f124SMoriah Waterland lastRecord, lastPos-pls); 1982*5c51f124SMoriah Waterland 1983*5c51f124SMoriah Waterland /* removing last record of file, truncate */ 1984*5c51f124SMoriah Waterland 1985*5c51f124SMoriah Waterland res = ftruncate(a_fd, lastPos-pls); 1986*5c51f124SMoriah Waterland if (res == -1) { 1987*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_FTRUNCATE_FAILURE, 1988*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 1989*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 1990*5c51f124SMoriah Waterland a_theLock->_lrLock.lockObject, 1991*5c51f124SMoriah Waterland strerror(errno)); 1992*5c51f124SMoriah Waterland return (1); 1993*5c51f124SMoriah Waterland } 1994*5c51f124SMoriah Waterland return (0); 1995*5c51f124SMoriah Waterland } 1996*5c51f124SMoriah Waterland 1997*5c51f124SMoriah Waterland /* 1998*5c51f124SMoriah Waterland * not removing last record of file: 1999*5c51f124SMoriah Waterland * read last record, truncate file one record, 2000*5c51f124SMoriah Waterland * replace record to be removed with last record read 2001*5c51f124SMoriah Waterland */ 2002*5c51f124SMoriah Waterland 2003*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_REMOVING, 2004*5c51f124SMoriah Waterland pll->lockRecordNum, lastRecord, lastPos-pls); 2005*5c51f124SMoriah Waterland 2006*5c51f124SMoriah Waterland /* read in the last record */ 2007*5c51f124SMoriah Waterland 2008*5c51f124SMoriah Waterland result = pread(a_fd, tmpLock._lrLockData, pls, lastRecord*pls); 2009*5c51f124SMoriah Waterland if (result != pls) { 2010*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_PREAD_FAILURE, 2011*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 2012*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 2013*5c51f124SMoriah Waterland a_theLock->_lrLock.lockObject, 2014*5c51f124SMoriah Waterland strerror(errno)); 2015*5c51f124SMoriah Waterland return (1); 2016*5c51f124SMoriah Waterland 2017*5c51f124SMoriah Waterland } 2018*5c51f124SMoriah Waterland 2019*5c51f124SMoriah Waterland /* truncate lock file removing the last record (just read in) */ 2020*5c51f124SMoriah Waterland 2021*5c51f124SMoriah Waterland res = ftruncate(a_fd, lastPos-pls); 2022*5c51f124SMoriah Waterland if (res == -1) { 2023*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_FTRUNCATE_FAILURE, 2024*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 2025*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 2026*5c51f124SMoriah Waterland a_theLock->_lrLock.lockObject, 2027*5c51f124SMoriah Waterland strerror(errno)); 2028*5c51f124SMoriah Waterland return (1); 2029*5c51f124SMoriah Waterland } 2030*5c51f124SMoriah Waterland 2031*5c51f124SMoriah Waterland /* update record to indicate its new position in the lock file */ 2032*5c51f124SMoriah Waterland 2033*5c51f124SMoriah Waterland tmpLock._lrLock.lockRecordNum = pll->lockRecordNum; 2034*5c51f124SMoriah Waterland 2035*5c51f124SMoriah Waterland /* write out the updated record to the new location */ 2036*5c51f124SMoriah Waterland 2037*5c51f124SMoriah Waterland result = pwrite(a_fd, tmpLock._lrLockData, pls, pll->lockRecordNum*pls); 2038*5c51f124SMoriah Waterland if (result != pls) { 2039*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_PWRITE_FAILURE, 2040*5c51f124SMoriah Waterland a_theLock->_lrLock.lockExclusive ? 2041*5c51f124SMoriah Waterland MSG_LOCK_EXC : MSG_LOCK_SHR, 2042*5c51f124SMoriah Waterland a_theLock->_lrLock.lockObject, 2043*5c51f124SMoriah Waterland strerror(errno)); 2044*5c51f124SMoriah Waterland return (1); 2045*5c51f124SMoriah Waterland } 2046*5c51f124SMoriah Waterland 2047*5c51f124SMoriah Waterland return (0); 2048*5c51f124SMoriah Waterland } 2049*5c51f124SMoriah Waterland 2050*5c51f124SMoriah Waterland /* 2051*5c51f124SMoriah Waterland * Name: _getUniqueId 2052*5c51f124SMoriah Waterland * Description: Generate a unique ID that can be used as a key for a new lock 2053*5c51f124SMoriah Waterland * Arguments: None 2054*5c51f124SMoriah Waterland * Returns: char * 2055*5c51f124SMoriah Waterland * == NULL - error, no key generated 2056*5c51f124SMoriah Waterland * != NULL - generated key 2057*5c51f124SMoriah Waterland * NOTE: Any results returned is placed in new storage for the 2058*5c51f124SMoriah Waterland * calling method. The caller must use 'lu_memFree' to dispose 2059*5c51f124SMoriah Waterland * of the storage once the results are no longer needed. 2060*5c51f124SMoriah Waterland */ 2061*5c51f124SMoriah Waterland 2062*5c51f124SMoriah Waterland static char * 2063*5c51f124SMoriah Waterland _getUniqueId(void) 2064*5c51f124SMoriah Waterland { 2065*5c51f124SMoriah Waterland char *args[10]; 2066*5c51f124SMoriah Waterland char *execResults; 2067*5c51f124SMoriah Waterland char newkey[LOCK_KEY_MAXLEN]; 2068*5c51f124SMoriah Waterland hrtime_t hretime; 2069*5c51f124SMoriah Waterland int b; 2070*5c51f124SMoriah Waterland int execStatus; 2071*5c51f124SMoriah Waterland struct tm tstruct; 2072*5c51f124SMoriah Waterland time_t thetime; 2073*5c51f124SMoriah Waterland 2074*5c51f124SMoriah Waterland /* 2075*5c51f124SMoriah Waterland * try and use makeuuid to generate a unique i.d. Such a unique i.d. 2076*5c51f124SMoriah Waterland * will look like: 2077*5c51f124SMoriah Waterland * 7814e3c1-1dd2-11b2-9fe8-000d560ddc82 2078*5c51f124SMoriah Waterland */ 2079*5c51f124SMoriah Waterland 2080*5c51f124SMoriah Waterland args[0] = "makeuuid"; 2081*5c51f124SMoriah Waterland args[1] = (char *)NULL; 2082*5c51f124SMoriah Waterland 2083*5c51f124SMoriah Waterland b = e_ExecCmdList(&execStatus, &execResults, (char *)NULL, 2084*5c51f124SMoriah Waterland "/usr/bin/makeuuid", (char *)NULL); 2085*5c51f124SMoriah Waterland 2086*5c51f124SMoriah Waterland if ((b == 0) && (execStatus == 0) && (*execResults != '\0')) { 2087*5c51f124SMoriah Waterland char *p; 2088*5c51f124SMoriah Waterland p = strpbrk(execResults, " \t\n"); 2089*5c51f124SMoriah Waterland if (p != (char *)NULL) { 2090*5c51f124SMoriah Waterland *p = '\0'; 2091*5c51f124SMoriah Waterland } 2092*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_GENUID_MAKEUUID, 2093*5c51f124SMoriah Waterland execResults); 2094*5c51f124SMoriah Waterland return (execResults); 2095*5c51f124SMoriah Waterland } 2096*5c51f124SMoriah Waterland 2097*5c51f124SMoriah Waterland /* 2098*5c51f124SMoriah Waterland * cannot run makeuuid - generate own unique key - the key is the 2099*5c51f124SMoriah Waterland * same length as unique uid but contains different information that 2100*5c51f124SMoriah Waterland * is as unique as can be made - include current hires time (nanosecond 2101*5c51f124SMoriah Waterland * real timer. Such a unique i.d. will look like: 2102*5c51f124SMoriah Waterland * 0203104092-1145345-0004e94d6af481a0 2103*5c51f124SMoriah Waterland */ 2104*5c51f124SMoriah Waterland 2105*5c51f124SMoriah Waterland hretime = gethrtime(); 2106*5c51f124SMoriah Waterland 2107*5c51f124SMoriah Waterland thetime = time((time_t *)NULL); 2108*5c51f124SMoriah Waterland (void) localtime_r(&thetime, &tstruct); 2109*5c51f124SMoriah Waterland 2110*5c51f124SMoriah Waterland (void) snprintf(newkey, sizeof (newkey), 2111*5c51f124SMoriah Waterland "%02d%02d%02d%03d-%02d%02d%02d%d-%016llx", tstruct.tm_mday, 2112*5c51f124SMoriah Waterland tstruct.tm_mon, tstruct.tm_year, tstruct.tm_yday, 2113*5c51f124SMoriah Waterland tstruct.tm_hour, tstruct.tm_min, tstruct.tm_sec, 2114*5c51f124SMoriah Waterland tstruct.tm_wday, hretime); 2115*5c51f124SMoriah Waterland 2116*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_GENUID_INTERNAL, newkey); 2117*5c51f124SMoriah Waterland return (strdup(newkey)); 2118*5c51f124SMoriah Waterland } 2119*5c51f124SMoriah Waterland 2120*5c51f124SMoriah Waterland /* 2121*5c51f124SMoriah Waterland * Name: sigint_handler 2122*5c51f124SMoriah Waterland * Synopsis: SIGINT interrupt handler 2123*5c51f124SMoriah Waterland * Description: Catch the "SIGINT" signal; increment signal_received 2124*5c51f124SMoriah Waterland * global variable, 2125*5c51f124SMoriah Waterland * Arguments: signo - [RO, *RO] - (int) 2126*5c51f124SMoriah Waterland * Signal number that was caught 2127*5c51f124SMoriah Waterland * Returns: void 2128*5c51f124SMoriah Waterland */ 2129*5c51f124SMoriah Waterland 2130*5c51f124SMoriah Waterland static void 2131*5c51f124SMoriah Waterland sigint_handler(int a_signo) 2132*5c51f124SMoriah Waterland { 2133*5c51f124SMoriah Waterland signal_received++; 2134*5c51f124SMoriah Waterland } 2135*5c51f124SMoriah Waterland 2136*5c51f124SMoriah Waterland /* 2137*5c51f124SMoriah Waterland * Name: sighup_handler 2138*5c51f124SMoriah Waterland * Synopsis: SIGHUP interrupt handler 2139*5c51f124SMoriah Waterland * Description: Catch the "SIGHUP" signal; increment signal_received 2140*5c51f124SMoriah Waterland * global variable, 2141*5c51f124SMoriah Waterland * Arguments: signo - [RO, *RO] - (int) 2142*5c51f124SMoriah Waterland * Signal number that was caught 2143*5c51f124SMoriah Waterland * Returns: void 2144*5c51f124SMoriah Waterland */ 2145*5c51f124SMoriah Waterland 2146*5c51f124SMoriah Waterland static void 2147*5c51f124SMoriah Waterland sighup_handler(int a_signo) 2148*5c51f124SMoriah Waterland { 2149*5c51f124SMoriah Waterland signal_received++; 2150*5c51f124SMoriah Waterland } 2151