xref: /illumos-gate/usr/src/cmd/svr4pkg/pkgadm/lock.c (revision ef150c2b)
15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland  * CDDL HEADER START
35c51f124SMoriah Waterland  *
45c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland  *
85c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland  * See the License for the specific language governing permissions
115c51f124SMoriah Waterland  * and limitations under the License.
125c51f124SMoriah Waterland  *
135c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland  *
195c51f124SMoriah Waterland  * CDDL HEADER END
205c51f124SMoriah Waterland  */
215c51f124SMoriah Waterland 
2232991bedSPeter Tribble /*
2332991bedSPeter Tribble  * Copyright (c) 2017 Peter Tribble.
2432991bedSPeter Tribble  */
2532991bedSPeter Tribble 
265c51f124SMoriah Waterland /*
275c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
285c51f124SMoriah Waterland  * Use is subject to license terms.
295c51f124SMoriah Waterland  */
305c51f124SMoriah Waterland 
315c51f124SMoriah Waterland 
325c51f124SMoriah Waterland /*
335c51f124SMoriah Waterland  * Module: lock.c
345c51f124SMoriah Waterland  * Program: pkgadm (/usr/bin/pkgadm)
355c51f124SMoriah Waterland  * Synopsis: implements the zone/package administrative lock interface
365c51f124SMoriah Waterland  * Public methods:
375c51f124SMoriah Waterland  *	admin_lock
385c51f124SMoriah Waterland  * Usage:
395c51f124SMoriah Waterland  *  Acquire: -a [ -e | -s ] [ -o obj ] [ -k key ] [ -R root ] [ -q ] \
405c51f124SMoriah Waterland  *		[ -w ] [ -W timeout ]
415c51f124SMoriah Waterland  *  Release: -r -o object -k key [ -R altRoot ] [ -q ]
425c51f124SMoriah Waterland  *  Status: [ -o object ] [ -k key ] [ -R altRoot ] [ -q ]
435c51f124SMoriah Waterland  */
445c51f124SMoriah Waterland 
455c51f124SMoriah Waterland /* enable extentions to standard Unix libraries */
465c51f124SMoriah Waterland 
475c51f124SMoriah Waterland #define	__EXTENSIONS__
485c51f124SMoriah Waterland 
495c51f124SMoriah Waterland /* unix system includes */
505c51f124SMoriah Waterland 
515c51f124SMoriah Waterland #include <stdio.h>
525c51f124SMoriah Waterland #include <stdarg.h>
535c51f124SMoriah Waterland #include <stdlib.h>
545c51f124SMoriah Waterland #include <string.h>
555c51f124SMoriah Waterland #include <strings.h>
565c51f124SMoriah Waterland #include <sys/types.h>
575c51f124SMoriah Waterland #include <wait.h>
585c51f124SMoriah Waterland #include <sys/stat.h>
595c51f124SMoriah Waterland #include <fcntl.h>
605c51f124SMoriah Waterland #include <unistd.h>
615c51f124SMoriah Waterland #include <signal.h>
625c51f124SMoriah Waterland #include <locale.h>
635c51f124SMoriah Waterland #include <libgen.h>
645c51f124SMoriah Waterland #include <sys/param.h>
655c51f124SMoriah Waterland #include <errno.h>
665c51f124SMoriah Waterland #include <assert.h>
675c51f124SMoriah Waterland #include <time.h>
685c51f124SMoriah Waterland #include <fnmatch.h>
695c51f124SMoriah Waterland #include <zone.h>
705c51f124SMoriah Waterland 
715c51f124SMoriah Waterland /* local includes */
725c51f124SMoriah Waterland 
735c51f124SMoriah Waterland #include <libinst.h>
745c51f124SMoriah Waterland #include <pkglib.h>
755c51f124SMoriah Waterland #include "pkgadm.h"
765c51f124SMoriah Waterland #include "pkgadm_msgs.h"
775c51f124SMoriah Waterland 
785c51f124SMoriah Waterland /* definition and conversion of sleep units */
795c51f124SMoriah Waterland 
805c51f124SMoriah Waterland #define	SECONDS(x)		((unsigned int)(x))
815c51f124SMoriah Waterland #define	MINUTES(x)		((unsigned int)(seconds(x)*60))
825c51f124SMoriah Waterland 
835c51f124SMoriah Waterland /* define how waits are timed */
845c51f124SMoriah Waterland 
855c51f124SMoriah Waterland #define	WAITER_INITIAL		SECONDS(1)
865c51f124SMoriah Waterland #define	WAITER_MAX		SECONDS(60)
875c51f124SMoriah Waterland #define	WAITER_NEXT(x)		((x)*2)
885c51f124SMoriah Waterland 
895c51f124SMoriah Waterland typedef unsigned int		WAITER_T;
905c51f124SMoriah Waterland 
915c51f124SMoriah Waterland /*
925c51f124SMoriah Waterland  * The administrative lock file resides in /tmp
935c51f124SMoriah Waterland  * It does not survive a reboot
945c51f124SMoriah Waterland  * It consists of fixed length records
955c51f124SMoriah Waterland  * Each record has the following information:
96014740deSToomas Soome  *	record number - record position within the lock file
97014740deSToomas Soome  *	lock count - number of lock holders maintaining this lock
98014740deSToomas Soome  *	lock object - object being locked
99014740deSToomas Soome  *	lock key - key needed to manipulate existing lock
1005c51f124SMoriah Waterland  *	lock exclusive - is the lock exclusive (single locker only)
1015c51f124SMoriah Waterland  */
1025c51f124SMoriah Waterland 
1035c51f124SMoriah Waterland #define	LOCK_OBJECT_MAXLEN	512-1
1045c51f124SMoriah Waterland #define	LOCK_KEY_MAXLEN		37
1055c51f124SMoriah Waterland 
1065c51f124SMoriah Waterland #define	LOCK_DIRECTORY		"/tmp"
1075c51f124SMoriah Waterland 
1085c51f124SMoriah Waterland /*
1095c51f124SMoriah Waterland  * this is the "well known name" of the lock file that is used by the
1105c51f124SMoriah Waterland  * package, patch, and zone administration commands to synchronize their
1115c51f124SMoriah Waterland  * various efforts - it must live in a temporary directory that is cleared
1125c51f124SMoriah Waterland  * on system reboot but it is NOT a temporary file in that it survives
1135c51f124SMoriah Waterland  * the process that creates and updates it - if the format of the lock
1145c51f124SMoriah Waterland  * file ever changes, this path should be updated with a later "uuid"
1155c51f124SMoriah Waterland  * so that previous (incompatible) pkgadm's will not use the later data.
1165c51f124SMoriah Waterland  */
1175c51f124SMoriah Waterland 
1185c51f124SMoriah Waterland #define	LOCK_FILENAME	\
1195c51f124SMoriah Waterland 	"/tmp/.ai.pkg.zone.lock-afdb66cf-1dd1-11b2-a049-000d560ddc3e"
1205c51f124SMoriah Waterland 
1215c51f124SMoriah Waterland /* mode to use for LOCK_FILENAME */
1225c51f124SMoriah Waterland 
1235c51f124SMoriah Waterland #define	LOCK_FILEMODE	\
1245c51f124SMoriah Waterland 	(S_ISGID|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
1255c51f124SMoriah Waterland 
1265c51f124SMoriah Waterland #define	LOCK_SLEEP_INTERVAL	SECONDS(2)
1275c51f124SMoriah Waterland 
1285c51f124SMoriah Waterland /* lock contents types */
1295c51f124SMoriah Waterland 
1305c51f124SMoriah Waterland typedef unsigned long RECORDNUM_T;
1315c51f124SMoriah Waterland 
1325c51f124SMoriah Waterland #define	RECORDNUM_NONE	0xFFFFFFFF
1335c51f124SMoriah Waterland 
1345c51f124SMoriah Waterland /* actual lock data */
1355c51f124SMoriah Waterland 
1365c51f124SMoriah Waterland struct _adminLock
1375c51f124SMoriah Waterland {
1385c51f124SMoriah Waterland 	RECORDNUM_T	lockRecordNum;
1395c51f124SMoriah Waterland 	unsigned long	lockCount;
1405c51f124SMoriah Waterland 	unsigned long	lockExclusive;
1415c51f124SMoriah Waterland 	pid_t		lockPid;
1425c51f124SMoriah Waterland 	zoneid_t	lockZoneId;
1435c51f124SMoriah Waterland 	char		lockKey[LOCK_KEY_MAXLEN+1];
1445c51f124SMoriah Waterland 	char		lockObject[LOCK_OBJECT_MAXLEN+1];
1455c51f124SMoriah Waterland };
1465c51f124SMoriah Waterland 
1475c51f124SMoriah Waterland typedef struct _adminLock ADMINLOCK_T;
1485c51f124SMoriah Waterland 
1495c51f124SMoriah Waterland /* size of an individual "lock" */
1505c51f124SMoriah Waterland 
1515c51f124SMoriah Waterland #define	LOCK_SIZE		sizeof (ADMINLOCK_T)
1525c51f124SMoriah Waterland 
1535c51f124SMoriah Waterland /* union to allow lock to be accessed as raw or structured data */
1545c51f124SMoriah Waterland 
1555c51f124SMoriah Waterland union _lockRecord
1565c51f124SMoriah Waterland {
1575c51f124SMoriah Waterland 	char		_lrLockData[LOCK_SIZE];
1585c51f124SMoriah Waterland 	ADMINLOCK_T	_lrLock;
1595c51f124SMoriah Waterland };
1605c51f124SMoriah Waterland 
1615c51f124SMoriah Waterland typedef union _lockRecord LOCK_T;
1625c51f124SMoriah Waterland 
1635c51f124SMoriah Waterland /* return codes from "_findLock" */
1645c51f124SMoriah Waterland 
1655c51f124SMoriah Waterland typedef unsigned long FINDLOCK_T;
1665c51f124SMoriah Waterland 
1675c51f124SMoriah Waterland #define	FINDLOCK_FOUND		((FINDLOCK_T)0)
1685c51f124SMoriah Waterland #define	FINDLOCK_ERROR		((FINDLOCK_T)-1)
1695c51f124SMoriah Waterland #define	FINDLOCK_NOTFOUND	((FINDLOCK_T)-2)
1705c51f124SMoriah Waterland #define	FINDLOCK_KEYMISMATCH	((FINDLOCK_T)-3)
1715c51f124SMoriah Waterland #define	FINDLOCK_LOCKED		((FINDLOCK_T)-4)
1725c51f124SMoriah Waterland #define	FINDLOCK_NOTLOCKED	((FINDLOCK_T)-5)
1735c51f124SMoriah Waterland #define	FINDLOCK_LOCKACQUIRED	((FINDLOCK_T)-6)
1745c51f124SMoriah Waterland 
1755c51f124SMoriah Waterland /*
1765c51f124SMoriah Waterland  * Forward declarations
1775c51f124SMoriah Waterland  */
1785c51f124SMoriah Waterland 
1795c51f124SMoriah Waterland /* local main function implementation methods */
1805c51f124SMoriah Waterland 
1815c51f124SMoriah Waterland static FINDLOCK_T	lock_acquire(LOCK_T *a_lock, int *a_fd, char *a_root,
1825c51f124SMoriah Waterland 				char *a_key, char *a_object, int a_quiet,
1835c51f124SMoriah Waterland 				int a_wait, long a_timeout, int a_exclusive,
1845c51f124SMoriah Waterland 				char *a_altRoot, pid_t a_pid, zoneid_t a_zid);
1855c51f124SMoriah Waterland static int		lock_release(int a_fd, char *a_key, char *a_object,
1865c51f124SMoriah Waterland 				int a_quiet);
1875c51f124SMoriah Waterland static int		lock_status(int a_fd, char *a_key, char *a_object,
1885c51f124SMoriah Waterland 				int a_quiet);
1895c51f124SMoriah Waterland 
1905c51f124SMoriah Waterland /* local utility functions */
1915c51f124SMoriah Waterland 
1925c51f124SMoriah Waterland static int		_lockMatch(char *a_s1Lock, char *a_s2Lock);
1935c51f124SMoriah Waterland static FINDLOCK_T	_findLock(LOCK_T *a_theLock, RECORDNUM_T *r_recordNum,
1945c51f124SMoriah Waterland 				int a_fd, char *a_object, char *a_key);
1955c51f124SMoriah Waterland static int		_decrementLockCount(int a_fd, LOCK_T *a_theLock);
1965c51f124SMoriah Waterland static int		_addLock(char *r_key, int a_fd, char *a_object,
1975c51f124SMoriah Waterland 				int a_exclusive, pid_t a_pid, zoneid_t a_zid);
1985c51f124SMoriah Waterland static int		_incrementLockCount(int a_fd, LOCK_T *a_theLock);
1995c51f124SMoriah Waterland static FINDLOCK_T	_lock_acquire(LOCK_T *a_lock, int a_fd, char *a_key,
2005c51f124SMoriah Waterland 				char *a_object, int a_quiet, int a_exclusive,
2015c51f124SMoriah Waterland 				pid_t a_pid, zoneid_t a_zid);
2025c51f124SMoriah Waterland static char		*_getUniqueId(void);
2035c51f124SMoriah Waterland static int		_openLockFile(char *a_root);
2045c51f124SMoriah Waterland static void		sighup_handler(int a_signo);
2055c51f124SMoriah Waterland static void		sigint_handler(int a_signo);
2065c51f124SMoriah Waterland static boolean_t	_validateLock(int a_fd, LOCK_T *a_theLock, int a_quiet);
2075c51f124SMoriah Waterland 
2085c51f124SMoriah Waterland static int		signal_received = 0;
2095c51f124SMoriah Waterland 
2105c51f124SMoriah Waterland /*
2115c51f124SMoriah Waterland  * main methods with external entry points
2125c51f124SMoriah Waterland  */
2135c51f124SMoriah Waterland 
2145c51f124SMoriah Waterland /*
2155c51f124SMoriah Waterland  * Name:	admin_lock
2165c51f124SMoriah Waterland  * Synopsis:	main entry point for pkgadm "lock" subcommand
2175c51f124SMoriah Waterland  * Description:	Control zone/package administrative locking
2185c51f124SMoriah Waterland  * Returns: 0 on success, non-zero otherwise.
2195c51f124SMoriah Waterland  */
2205c51f124SMoriah Waterland 
2215c51f124SMoriah Waterland int
admin_lock(int argc,char ** argv)2225c51f124SMoriah Waterland admin_lock(int argc, char **argv)
2235c51f124SMoriah Waterland {
2245c51f124SMoriah Waterland 	FINDLOCK_T		tResult;
2255c51f124SMoriah Waterland 	LOCK_T			theLock;
2265c51f124SMoriah Waterland 	char			*RFlag = "/";	/* altRoot */
2275c51f124SMoriah Waterland 	char			*endptr;
2285c51f124SMoriah Waterland 	char			*kFlag = "";	/* key */
2295c51f124SMoriah Waterland 	char			*oFlag = "";	/* object */
2305c51f124SMoriah Waterland 	char			*p;
231*ef150c2bSRichard Lowe 	int			c;
2325c51f124SMoriah Waterland 	int			aFlag = 0;	/* acquire lock */
2335c51f124SMoriah Waterland 	int			eFlag = 0;	/* exclusive lock */
2345c51f124SMoriah Waterland 	int			exclusive = 1;	/* exclusive vs shared lock */
2355c51f124SMoriah Waterland 	int			fd;
2365c51f124SMoriah Waterland 	int			qFlag = 0;	/* quiet */
2375c51f124SMoriah Waterland 	int			rFlag = 0;	/* release lock */
2385c51f124SMoriah Waterland 	int			result;
2395c51f124SMoriah Waterland 	int			sFlag = 0;	/* shared lock */
2405c51f124SMoriah Waterland 	int			tFlag = 0;	/* test comparison */
2415c51f124SMoriah Waterland 	int			wFlag = 0;	/* wait */
2425c51f124SMoriah Waterland 	long			WFlag = 0;	/* wait timeout */
2435c51f124SMoriah Waterland 	pid_t			pFlag = 0;	/* process # */
2445c51f124SMoriah Waterland 	struct sigaction	nact;
2455c51f124SMoriah Waterland 	struct sigaction	oact;
2465c51f124SMoriah Waterland 	zoneid_t		zFlag = -1;	/* zone i.d. */
2475c51f124SMoriah Waterland 
2485c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":aek:o:p:qrR:stwW:z:")) != EOF) {
2495c51f124SMoriah Waterland 		switch (c) {
2505c51f124SMoriah Waterland 		case 'a':	/* acquire lock */
2515c51f124SMoriah Waterland 			aFlag++;
2525c51f124SMoriah Waterland 			break;
2535c51f124SMoriah Waterland 
2545c51f124SMoriah Waterland 		case 'e':	/* exclusive lock */
2555c51f124SMoriah Waterland 			eFlag++;
2565c51f124SMoriah Waterland 			break;
2575c51f124SMoriah Waterland 
2585c51f124SMoriah Waterland 		case 'k':	/* lock-key */
2595c51f124SMoriah Waterland 			kFlag = optarg;
2605c51f124SMoriah Waterland 			if (strlen(optarg) > LOCK_KEY_MAXLEN) {
2615c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR,
262708dafbfSAlexander Pyhalov 				    MSG_LOCK_kARG_TOOLONG,
263708dafbfSAlexander Pyhalov 				    strlen(optarg), LOCK_KEY_MAXLEN);
2645c51f124SMoriah Waterland 				return (1);
2655c51f124SMoriah Waterland 			}
2665c51f124SMoriah Waterland 			break;
2675c51f124SMoriah Waterland 
2685c51f124SMoriah Waterland 		case 'o':	/* object */
2695c51f124SMoriah Waterland 			oFlag = optarg;
2705c51f124SMoriah Waterland 			if (strlen(optarg) > LOCK_OBJECT_MAXLEN) {
2715c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR,
272708dafbfSAlexander Pyhalov 				    MSG_LOCK_oARG_TOOLONG,
273708dafbfSAlexander Pyhalov 				    strlen(optarg), LOCK_OBJECT_MAXLEN);
2745c51f124SMoriah Waterland 				return (1);
2755c51f124SMoriah Waterland 			}
2765c51f124SMoriah Waterland 			break;
2775c51f124SMoriah Waterland 
2785c51f124SMoriah Waterland 		case 'p':	/* process i.d. */
2795c51f124SMoriah Waterland 			errno = 0;
2805c51f124SMoriah Waterland 			endptr = 0;
2815c51f124SMoriah Waterland 			pFlag = strtol(optarg, &endptr, 10);
2825c51f124SMoriah Waterland 			if ((endptr != (char *)NULL) && (*endptr != '\0')) {
2835c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR, MSG_LOCK_pFLAG_BADINT,
284708dafbfSAlexander Pyhalov 				    optarg, *endptr);
2855c51f124SMoriah Waterland 				return (1);
2865c51f124SMoriah Waterland 			}
2875c51f124SMoriah Waterland 			if ((pFlag == 0) && (errno != 0)) {
2885c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR,
289708dafbfSAlexander Pyhalov 				    MSG_LOCK_pFLAG_ERROR,
290708dafbfSAlexander Pyhalov 				    optarg,  strerror(errno));
2915c51f124SMoriah Waterland 				return (1);
2925c51f124SMoriah Waterland 			}
2935c51f124SMoriah Waterland 			break;
2945c51f124SMoriah Waterland 
2955c51f124SMoriah Waterland 		case 'q':	/* quiet */
2965c51f124SMoriah Waterland 			qFlag++;
2975c51f124SMoriah Waterland 			break;
2985c51f124SMoriah Waterland 
2995c51f124SMoriah Waterland 		case 'r':	/* release lock */
3005c51f124SMoriah Waterland 			rFlag++;
3015c51f124SMoriah Waterland 			break;
3025c51f124SMoriah Waterland 
3035c51f124SMoriah Waterland 		case 'R':	/* alternative root */
3045c51f124SMoriah Waterland 			/* if root directory is not absolute path, error */
3055c51f124SMoriah Waterland 			if (*optarg != '/') {
3065c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR,
307708dafbfSAlexander Pyhalov 				    MSG_LOCK_RARG_NOT_ABSOLUTE, optarg);
3085c51f124SMoriah Waterland 				return (1);
3095c51f124SMoriah Waterland 			}
3105c51f124SMoriah Waterland 
3115c51f124SMoriah Waterland 			/* if root directory does not exist, create it */
3125c51f124SMoriah Waterland 			if (access(optarg, F_OK) != 0) {
3135c51f124SMoriah Waterland 
3145c51f124SMoriah Waterland 				/* create top level root directory */
3155c51f124SMoriah Waterland 				if (mkdirp(optarg, 0755) != 0) {
3165c51f124SMoriah Waterland 					log_msg(LOG_MSG_ERR,
317708dafbfSAlexander Pyhalov 					    MSG_LOCK_ALTROOT_CANTCREATE,
318708dafbfSAlexander Pyhalov 					    optarg, strerror(errno));
3195c51f124SMoriah Waterland 					return (1);
3205c51f124SMoriah Waterland 				}
3215c51f124SMoriah Waterland 			}
3225c51f124SMoriah Waterland 
3235c51f124SMoriah Waterland 			/* if $ALTROOT/tmp directory does not exist create it */
3245c51f124SMoriah Waterland 			p = pkgstrPrintf("%s/tmp", optarg);
3255c51f124SMoriah Waterland 			if (access(p, F_OK) != 0) {
3265c51f124SMoriah Waterland 
3275c51f124SMoriah Waterland 				/* create $ALTROOT/tmp directory */
3285c51f124SMoriah Waterland 				if (mkdirp(p, 0777) != 0) {
3295c51f124SMoriah Waterland 					log_msg(LOG_MSG_ERR,
330708dafbfSAlexander Pyhalov 					    MSG_LOCK_ALTROOT_CANTCREATE,
331708dafbfSAlexander Pyhalov 					    p, strerror(errno));
3325c51f124SMoriah Waterland 					return (1);
3335c51f124SMoriah Waterland 				}
3345c51f124SMoriah Waterland 			}
3355c51f124SMoriah Waterland 
3365c51f124SMoriah Waterland 			/* if $ALTROOT/tmp directory cannot be created, exit */
3375c51f124SMoriah Waterland 			if (access(p, F_OK) != 0) {
3385c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR, MSG_LOCK_ALTROOT_NONEXIST,
339708dafbfSAlexander Pyhalov 				    optarg, strerror(errno));
3405c51f124SMoriah Waterland 				return (1);
3415c51f124SMoriah Waterland 			}
3425c51f124SMoriah Waterland 
3435c51f124SMoriah Waterland 			(void) free(p);
3445c51f124SMoriah Waterland 
3455c51f124SMoriah Waterland 			RFlag = optarg;
3465c51f124SMoriah Waterland 			break;
3475c51f124SMoriah Waterland 
3485c51f124SMoriah Waterland 		case 's':	/* shared */
3495c51f124SMoriah Waterland 			sFlag++;
3505c51f124SMoriah Waterland 			break;
3515c51f124SMoriah Waterland 
3525c51f124SMoriah Waterland 		case 't':	/* test comparison */
3535c51f124SMoriah Waterland 			tFlag++;
3545c51f124SMoriah Waterland 			break;
3555c51f124SMoriah Waterland 
3565c51f124SMoriah Waterland 		case 'w':	/* wait */
3575c51f124SMoriah Waterland 			wFlag++;
3585c51f124SMoriah Waterland 			break;
3595c51f124SMoriah Waterland 
3605c51f124SMoriah Waterland 		case 'W':	/* wait with timeout */
3615c51f124SMoriah Waterland 			errno = 0;
3625c51f124SMoriah Waterland 			endptr = 0;
3635c51f124SMoriah Waterland 			WFlag = strtol(optarg, &endptr, 10);
3645c51f124SMoriah Waterland 			if ((endptr != (char *)NULL) && (*endptr != '\0')) {
3655c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR, MSG_LOCK_WFLAG_BADINT,
366708dafbfSAlexander Pyhalov 				    optarg, *endptr);
3675c51f124SMoriah Waterland 				return (1);
3685c51f124SMoriah Waterland 			}
3695c51f124SMoriah Waterland 			if ((WFlag == 0) && (errno != 0)) {
3705c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR,
371708dafbfSAlexander Pyhalov 				    MSG_LOCK_WFLAG_ERROR,
372708dafbfSAlexander Pyhalov 				    optarg,  strerror(errno));
3735c51f124SMoriah Waterland 				return (1);
3745c51f124SMoriah Waterland 			}
3755c51f124SMoriah Waterland 			wFlag++;
3765c51f124SMoriah Waterland 			break;
3775c51f124SMoriah Waterland 
3785c51f124SMoriah Waterland 		case 'z':	/* zone i.d. */
3795c51f124SMoriah Waterland 			errno = 0;
3805c51f124SMoriah Waterland 			endptr = 0;
3815c51f124SMoriah Waterland 			zFlag = strtol(optarg, &endptr, 10);
3825c51f124SMoriah Waterland 			if ((endptr != (char *)NULL) && (*endptr != '\0')) {
3835c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR, MSG_LOCK_zFLAG_BADINT,
384708dafbfSAlexander Pyhalov 				    optarg, *endptr);
3855c51f124SMoriah Waterland 				return (1);
3865c51f124SMoriah Waterland 			}
3875c51f124SMoriah Waterland 			if ((zFlag == 0) && (errno != 0)) {
3885c51f124SMoriah Waterland 				log_msg(LOG_MSG_ERR,
389708dafbfSAlexander Pyhalov 				    MSG_LOCK_zFLAG_ERROR,
390708dafbfSAlexander Pyhalov 				    optarg,  strerror(errno));
3915c51f124SMoriah Waterland 				return (1);
3925c51f124SMoriah Waterland 			}
3935c51f124SMoriah Waterland 			break;
3945c51f124SMoriah Waterland 
3955c51f124SMoriah Waterland 		case ':':
3965c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt);
39726ec61e2SToomas Soome 			/* FALLTHROUGH */
3985c51f124SMoriah Waterland 		case '?':
3995c51f124SMoriah Waterland 
4005c51f124SMoriah Waterland 		default:
4015c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, MSG_USAGE);
4025c51f124SMoriah Waterland 			return (1);
4035c51f124SMoriah Waterland 		}
4045c51f124SMoriah Waterland 	}
4055c51f124SMoriah Waterland 
4065c51f124SMoriah Waterland 	/*
4075c51f124SMoriah Waterland 	 * validate arguments
4085c51f124SMoriah Waterland 	 */
4095c51f124SMoriah Waterland 
4105c51f124SMoriah Waterland 	/* if -t option is specified, override all other options */
4115c51f124SMoriah Waterland 
4125c51f124SMoriah Waterland 	if (tFlag) {
413014740deSToomas Soome 		int	rs = 0;
4145c51f124SMoriah Waterland 		int	rx;
4155c51f124SMoriah Waterland 		int	a;
4165c51f124SMoriah Waterland 
4175c51f124SMoriah Waterland 		/* only 2 or 3 args are valid */
4185c51f124SMoriah Waterland 
4195c51f124SMoriah Waterland 		a = argc-optind;
4205c51f124SMoriah Waterland 		if ((a < 2) || (a > 3)) {
4215c51f124SMoriah Waterland 			(void) fprintf(stderr, MSG_T_OPTION_ARGS, argc-optind);
4225c51f124SMoriah Waterland 			return (1);
4235c51f124SMoriah Waterland 		}
4245c51f124SMoriah Waterland 
4255c51f124SMoriah Waterland 		/* if 3rd argument given, it is return value to check */
4265c51f124SMoriah Waterland 
4275c51f124SMoriah Waterland 		if (a == 3) {
4285c51f124SMoriah Waterland 			rs = atoi(argv[optind+2]);
4295c51f124SMoriah Waterland 		}
4305c51f124SMoriah Waterland 		rx = _lockMatch(argv[optind+0], argv[optind+1]);
4315c51f124SMoriah Waterland 
4325c51f124SMoriah Waterland 		/* if 3rd argument not given, code to check is code returned */
4335c51f124SMoriah Waterland 
4345c51f124SMoriah Waterland 		if (a == 2) {
4355c51f124SMoriah Waterland 			rs = rx;
4365c51f124SMoriah Waterland 		}
4375c51f124SMoriah Waterland 
4385c51f124SMoriah Waterland 		/* report results */
4395c51f124SMoriah Waterland 
4405c51f124SMoriah Waterland 		if (a == 2) {
4415c51f124SMoriah Waterland 			(void) fprintf(stderr, MSG_T_RESULT_TWO,
442708dafbfSAlexander Pyhalov 			    rx, argv[optind+0], argv[optind+1]);
4435c51f124SMoriah Waterland 			return (rx);
4445c51f124SMoriah Waterland 		}
4455c51f124SMoriah Waterland 
4465c51f124SMoriah Waterland 		if (rx != rs) {
4475c51f124SMoriah Waterland 			(void) fprintf(stderr, MSG_T_RESULT_THREE,
448708dafbfSAlexander Pyhalov 			    rs, rx, argv[optind+0], argv[optind+1]);
4495c51f124SMoriah Waterland 		}
4505c51f124SMoriah Waterland 
4515c51f124SMoriah Waterland 		/* always successful */
4525c51f124SMoriah Waterland 
4535c51f124SMoriah Waterland 		return (rx == rs ? 0 : 1);
4545c51f124SMoriah Waterland 	}
4555c51f124SMoriah Waterland 
4565c51f124SMoriah Waterland 	/* must be no non-option arguments left */
4575c51f124SMoriah Waterland 
4585c51f124SMoriah Waterland 	if ((argc-optind) > 0) {
4595c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_USAGE);
4605c51f124SMoriah Waterland 		return (1);
4615c51f124SMoriah Waterland 	}
4625c51f124SMoriah Waterland 
4635c51f124SMoriah Waterland 	/* -a and -r cannot be used together */
4645c51f124SMoriah Waterland 
4655c51f124SMoriah Waterland 	if (aFlag && rFlag) {
4665c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_ar_TOGETHER);
4675c51f124SMoriah Waterland 		return (1);
4685c51f124SMoriah Waterland 	}
4695c51f124SMoriah Waterland 
4705c51f124SMoriah Waterland 	/* -e and -s cannot be used together */
4715c51f124SMoriah Waterland 
4725c51f124SMoriah Waterland 	if (eFlag && sFlag) {
4735c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_es_TOGETHER);
4745c51f124SMoriah Waterland 		return (1);
4755c51f124SMoriah Waterland 	}
4765c51f124SMoriah Waterland 
4775c51f124SMoriah Waterland 	/* -e can only be used if -a is used */
4785c51f124SMoriah Waterland 
4795c51f124SMoriah Waterland 	if (!aFlag && eFlag) {
4805c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_e_without_a);
4815c51f124SMoriah Waterland 		return (1);
4825c51f124SMoriah Waterland 	}
4835c51f124SMoriah Waterland 
4845c51f124SMoriah Waterland 	/* -s can only be used if -a is used */
4855c51f124SMoriah Waterland 
4865c51f124SMoriah Waterland 	if (!aFlag && sFlag) {
4875c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_s_without_a);
4885c51f124SMoriah Waterland 		return (1);
4895c51f124SMoriah Waterland 	}
4905c51f124SMoriah Waterland 
4915c51f124SMoriah Waterland 	/*
4925c51f124SMoriah Waterland 	 * perform the requested operation
4935c51f124SMoriah Waterland 	 */
4945c51f124SMoriah Waterland 
4955c51f124SMoriah Waterland 	/*
4965c51f124SMoriah Waterland 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
4975c51f124SMoriah Waterland 	 */
4985c51f124SMoriah Waterland 
4995c51f124SMoriah Waterland 	/* hold SIGINT/SIGHUP interrupts */
5005c51f124SMoriah Waterland 
5015c51f124SMoriah Waterland 	(void) sighold(SIGHUP);
5025c51f124SMoriah Waterland 	(void) sighold(SIGINT);
5035c51f124SMoriah Waterland 
5045c51f124SMoriah Waterland 	/* connect sigint_handler() to SIGINT */
5055c51f124SMoriah Waterland 
5065c51f124SMoriah Waterland 	nact.sa_handler = sigint_handler;
5075c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
5085c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
5095c51f124SMoriah Waterland 
5104f39e64dSToomas Soome 	(void) sigaction(SIGINT, &nact, &oact);
5115c51f124SMoriah Waterland 
5124f39e64dSToomas Soome 	/* connect sighup_handler() to SIGHUP */
5135c51f124SMoriah Waterland 
5145c51f124SMoriah Waterland 	nact.sa_handler = sighup_handler;
5155c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
5165c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
5175c51f124SMoriah Waterland 
5184f39e64dSToomas Soome 	(void) sigaction(SIGHUP, &nact, &oact);
5195c51f124SMoriah Waterland 
5205c51f124SMoriah Waterland 	/* release hold on signals */
5215c51f124SMoriah Waterland 
5225c51f124SMoriah Waterland 	(void) sigrelse(SIGHUP);
5235c51f124SMoriah Waterland 	(void) sigrelse(SIGINT);
5245c51f124SMoriah Waterland 
5255c51f124SMoriah Waterland 	/* open the lock file */
5265c51f124SMoriah Waterland 
5275c51f124SMoriah Waterland 	fd = _openLockFile(RFlag);
5285c51f124SMoriah Waterland 	if (fd < 0) {
5295c51f124SMoriah Waterland 		return (1);
5305c51f124SMoriah Waterland 	}
5315c51f124SMoriah Waterland 
5325c51f124SMoriah Waterland 	if (aFlag) {
5335c51f124SMoriah Waterland 		/* set "exclusive" mode based on -e/-s flag used */
5345c51f124SMoriah Waterland 
5355c51f124SMoriah Waterland 		if (sFlag) {
5365c51f124SMoriah Waterland 			exclusive = 0;
5375c51f124SMoriah Waterland 		} else if (eFlag) {
5385c51f124SMoriah Waterland 			exclusive = 1;
5395c51f124SMoriah Waterland 		}
5405c51f124SMoriah Waterland 
5415c51f124SMoriah Waterland 		/* acquire lock */
5425c51f124SMoriah Waterland 
5435c51f124SMoriah Waterland 		tResult = lock_acquire(&theLock, &fd, RFlag, kFlag, oFlag,
544708dafbfSAlexander Pyhalov 		    qFlag, wFlag, WFlag, exclusive, RFlag, pFlag, zFlag);
5455c51f124SMoriah Waterland 
5465c51f124SMoriah Waterland 		switch (tResult) {
5475c51f124SMoriah Waterland 		case FINDLOCK_LOCKACQUIRED:
5485c51f124SMoriah Waterland 			(void) fprintf(stdout, "%s\n",
549708dafbfSAlexander Pyhalov 			    theLock._lrLock.lockKey);
5505c51f124SMoriah Waterland 			result = 0;
5515c51f124SMoriah Waterland 			break;
5525c51f124SMoriah Waterland 		case FINDLOCK_LOCKED:
5535c51f124SMoriah Waterland 			(void) fprintf(stdout, "%s\n",
554708dafbfSAlexander Pyhalov 			    theLock._lrLock.lockObject);
5555c51f124SMoriah Waterland 			result = 1;
5565c51f124SMoriah Waterland 			break;
5575c51f124SMoriah Waterland 		default:
5585c51f124SMoriah Waterland 			result = 1;
5595c51f124SMoriah Waterland 			break;
5605c51f124SMoriah Waterland 		}
5615c51f124SMoriah Waterland 
5625c51f124SMoriah Waterland 	} else if (rFlag) {
5635c51f124SMoriah Waterland 		/* release lock */
5645c51f124SMoriah Waterland 		result = lock_release(fd, kFlag, oFlag, qFlag);
5655c51f124SMoriah Waterland 	} else {
5665c51f124SMoriah Waterland 		/* lock status */
5675c51f124SMoriah Waterland 		result = lock_status(fd, kFlag, oFlag, qFlag);
5685c51f124SMoriah Waterland 	}
5695c51f124SMoriah Waterland 
5705c51f124SMoriah Waterland 	/* close the lock file */
5715c51f124SMoriah Waterland 
5725c51f124SMoriah Waterland 	(void) close(fd);
5735c51f124SMoriah Waterland 
5745c51f124SMoriah Waterland 	/* return results of operation */
5755c51f124SMoriah Waterland 
5765c51f124SMoriah Waterland 	return (result);
5775c51f124SMoriah Waterland }
5785c51f124SMoriah Waterland 
5795c51f124SMoriah Waterland /*
5805c51f124SMoriah Waterland  * local main function implementation methods
5815c51f124SMoriah Waterland  */
5825c51f124SMoriah Waterland 
5835c51f124SMoriah Waterland /*
5845c51f124SMoriah Waterland  * Name:	lock_acquire
5855c51f124SMoriah Waterland  * Description:	implement lock acquisition implementing the wait/timeouts
5865c51f124SMoriah Waterland  *		Calls _lock_acquire to attempt lock acquisition.
5875c51f124SMoriah Waterland  * Arguments:
5885c51f124SMoriah Waterland  *	a_theLock - lock object filled with contents of existing lock
5895c51f124SMoriah Waterland  *	a_fd - file descriptor opened on the lock file
5905c51f124SMoriah Waterland  *	a_root - root of file system to manipulate locks on
5915c51f124SMoriah Waterland  *	a_key - key associated with lock to acquire
5925c51f124SMoriah Waterland  *	a_object - object associated with lock to acquire
5935c51f124SMoriah Waterland  *	a_wait - wait if lock cannot be acquired flag:
5945c51f124SMoriah Waterland  *			== 0 - do not wait
5955c51f124SMoriah Waterland  *			!= 0 - wait
5965c51f124SMoriah Waterland  *	a_timeout - timeout if waiting to acquire busy lock:
5975c51f124SMoriah Waterland  *			== 0 - no timeout (wait forever)
5985c51f124SMoriah Waterland  *			!= 0 - max # seconds to wait to acquire busy lock
5995c51f124SMoriah Waterland  *	a_quiet - quiet mode enabled flag
6005c51f124SMoriah Waterland  *	a_exclusive - exclusive/shared lock flag
6015c51f124SMoriah Waterland  *	a_pid - if != 0 process i.d. to associate with this lock
6025c51f124SMoriah Waterland  *	a_zid - if >= 0 - zone i.d. to associate with this lock
6035c51f124SMoriah Waterland  * Returns: int
6045c51f124SMoriah Waterland  *		== 0 - successful
6055c51f124SMoriah Waterland  *		!= 0 - not successful
6065c51f124SMoriah Waterland  */
6075c51f124SMoriah Waterland 
6085c51f124SMoriah Waterland static FINDLOCK_T
lock_acquire(LOCK_T * a_theLock,int * a_fd,char * a_root,char * a_key,char * a_object,int a_quiet,int a_wait,long a_timeout,int a_exclusive,char * a_altRoot,pid_t a_pid,zoneid_t a_zid)6095c51f124SMoriah Waterland lock_acquire(LOCK_T *a_theLock, int *a_fd, char *a_root, char *a_key,
610708dafbfSAlexander Pyhalov     char *a_object, int a_quiet, int a_wait, long a_timeout,
611708dafbfSAlexander Pyhalov     int a_exclusive, char *a_altRoot, pid_t a_pid, zoneid_t a_zid)
6125c51f124SMoriah Waterland {
6135c51f124SMoriah Waterland 	int		notified = 0;
6145c51f124SMoriah Waterland 	FINDLOCK_T	result;
6155c51f124SMoriah Waterland 	time_t		timeout;
6165c51f124SMoriah Waterland 	int		closeOnExit = 0;
6175c51f124SMoriah Waterland 
6185c51f124SMoriah Waterland 	/* reset the lock */
6195c51f124SMoriah Waterland 
6205c51f124SMoriah Waterland 	bzero(a_theLock, sizeof (LOCK_T));
6215c51f124SMoriah Waterland 
6225c51f124SMoriah Waterland 	/* open file if not open */
6235c51f124SMoriah Waterland 
6245c51f124SMoriah Waterland 	if ((*a_fd) < 0) {
6255c51f124SMoriah Waterland 		(*a_fd) = _openLockFile(a_altRoot);
6265c51f124SMoriah Waterland 		if ((*a_fd) < 0) {
6275c51f124SMoriah Waterland 			return (FINDLOCK_ERROR);
6285c51f124SMoriah Waterland 		}
6295c51f124SMoriah Waterland 		closeOnExit++;
6305c51f124SMoriah Waterland 	}
6315c51f124SMoriah Waterland 
6325c51f124SMoriah Waterland 	/* compute time after which acquire times out */
6335c51f124SMoriah Waterland 
6345c51f124SMoriah Waterland 	timeout = time((time_t *)NULL) + a_timeout;
6355c51f124SMoriah Waterland 
6365c51f124SMoriah Waterland 	for (;;) {
6375c51f124SMoriah Waterland 		time_t	curtime;
6385c51f124SMoriah Waterland 
6395c51f124SMoriah Waterland 		/* attempt to aquire the lock */
6405c51f124SMoriah Waterland 
6415c51f124SMoriah Waterland 		result = _lock_acquire(a_theLock, *a_fd, a_key, a_object,
642708dafbfSAlexander Pyhalov 		    a_quiet, a_exclusive, a_pid, a_zid);
6435c51f124SMoriah Waterland 
6445c51f124SMoriah Waterland 		/* return result if any result other than object is locked */
6455c51f124SMoriah Waterland 
6465c51f124SMoriah Waterland 		switch (result) {
6475c51f124SMoriah Waterland 		case FINDLOCK_LOCKACQUIRED:
6485c51f124SMoriah Waterland 
6495c51f124SMoriah Waterland 			/* close lock file if opened in this function */
6505c51f124SMoriah Waterland 
6515c51f124SMoriah Waterland 			if (closeOnExit) {
6525c51f124SMoriah Waterland 				(void) close(*a_fd);
6535c51f124SMoriah Waterland 				*a_fd = -1;
6545c51f124SMoriah Waterland 			}
6555c51f124SMoriah Waterland 
6565c51f124SMoriah Waterland 			return (FINDLOCK_LOCKACQUIRED);
6575c51f124SMoriah Waterland 
6585c51f124SMoriah Waterland 		case FINDLOCK_FOUND:
6595c51f124SMoriah Waterland 		case FINDLOCK_NOTFOUND:
6605c51f124SMoriah Waterland 		case FINDLOCK_KEYMISMATCH:
6615c51f124SMoriah Waterland 		case FINDLOCK_NOTLOCKED:
6625c51f124SMoriah Waterland 		case FINDLOCK_ERROR:
6635c51f124SMoriah Waterland 		default:
6645c51f124SMoriah Waterland 			/* close lock file if opened in this function */
6655c51f124SMoriah Waterland 
6665c51f124SMoriah Waterland 			if (closeOnExit) {
6675c51f124SMoriah Waterland 				(void) close(*a_fd);
6685c51f124SMoriah Waterland 				*a_fd = -1;
6695c51f124SMoriah Waterland 			}
6705c51f124SMoriah Waterland 
6715c51f124SMoriah Waterland 			return (result);
6725c51f124SMoriah Waterland 
6735c51f124SMoriah Waterland 		case FINDLOCK_LOCKED:
6745c51f124SMoriah Waterland 			;
6755c51f124SMoriah Waterland 			/* FALLTHROUGH */
6765c51f124SMoriah Waterland 		}
6775c51f124SMoriah Waterland 
6785c51f124SMoriah Waterland 		/*
6795c51f124SMoriah Waterland 		 * object locked OR SIGINT/SIGHUP interrupt received;
6805c51f124SMoriah Waterland 		 * return error if not waiting for lock OR signal received
6815c51f124SMoriah Waterland 		 */
6825c51f124SMoriah Waterland 
6835c51f124SMoriah Waterland 		if ((a_wait == 0) || (signal_received != 0)) {
6845c51f124SMoriah Waterland 			log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
685708dafbfSAlexander Pyhalov 			    MSG_LOCK_ACQUIRE_BUSY_FIRST,
686708dafbfSAlexander Pyhalov 			    a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
687708dafbfSAlexander Pyhalov 			    a_object, a_key,
688708dafbfSAlexander Pyhalov 			    a_theLock->_lrLock.lockObject,
689708dafbfSAlexander Pyhalov 			    a_theLock->_lrLock.lockExclusive ?
690708dafbfSAlexander Pyhalov 			    MSG_LOCK_EXC : MSG_LOCK_SHR,
691708dafbfSAlexander Pyhalov 			    a_theLock->_lrLock.lockExclusive !=
692708dafbfSAlexander Pyhalov 			    a_exclusive ? "" :
693708dafbfSAlexander Pyhalov 			    MSG_LOCK_ACQUIRE_BUSY_ADDITIONAL);
6945c51f124SMoriah Waterland 
6955c51f124SMoriah Waterland 			/* close lock file if opened in this function */
6965c51f124SMoriah Waterland 
6975c51f124SMoriah Waterland 			if (closeOnExit) {
6985c51f124SMoriah Waterland 				(void) close(*a_fd);
6995c51f124SMoriah Waterland 				*a_fd = -1;
7005c51f124SMoriah Waterland 			}
7015c51f124SMoriah Waterland 
7025c51f124SMoriah Waterland 			return (FINDLOCK_LOCKED);
7035c51f124SMoriah Waterland 		}
7045c51f124SMoriah Waterland 
7055c51f124SMoriah Waterland 		/* waiting for lock - if timeout specified see if time left */
7065c51f124SMoriah Waterland 
7075c51f124SMoriah Waterland 		if (a_timeout > 0) {
7085c51f124SMoriah Waterland 			curtime = time((time_t *)NULL);
7095c51f124SMoriah Waterland 			if (curtime > timeout) {
7105c51f124SMoriah Waterland 				log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
711708dafbfSAlexander Pyhalov 				    MSG_LOCK_ACQUIRE_TIMEDOUT,
712708dafbfSAlexander Pyhalov 				    a_exclusive ?
713708dafbfSAlexander Pyhalov 				    MSG_LOCK_EXC : MSG_LOCK_SHR,
714708dafbfSAlexander Pyhalov 				    a_object, a_key);
7155c51f124SMoriah Waterland 
7165c51f124SMoriah Waterland 				/* close lock file if opened in this function */
7175c51f124SMoriah Waterland 
7185c51f124SMoriah Waterland 				if (closeOnExit) {
7195c51f124SMoriah Waterland 					(void) close(*a_fd);
7205c51f124SMoriah Waterland 					*a_fd = -1;
7215c51f124SMoriah Waterland 				}
7225c51f124SMoriah Waterland 
7235c51f124SMoriah Waterland 				return (FINDLOCK_ERROR);
7245c51f124SMoriah Waterland 			}
7255c51f124SMoriah Waterland 		}
7265c51f124SMoriah Waterland 
7275c51f124SMoriah Waterland 		/*
7285c51f124SMoriah Waterland 		 * waiting to aquire lock:
7295c51f124SMoriah Waterland 		 * - notify waiting (one time only)
7305c51f124SMoriah Waterland 		 * - close lock file
7315c51f124SMoriah Waterland 		 * - sleep
7325c51f124SMoriah Waterland 		 * - open lock file
7335c51f124SMoriah Waterland 		 * - try again
7345c51f124SMoriah Waterland 		 */
7355c51f124SMoriah Waterland 
7365c51f124SMoriah Waterland 		/* notify once */
7375c51f124SMoriah Waterland 
7385c51f124SMoriah Waterland 		if (notified++ == 0) {
7395c51f124SMoriah Waterland 			log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_WRN,
740708dafbfSAlexander Pyhalov 			    MSG_LOCK_ACQUIRE_WAITING,
741708dafbfSAlexander Pyhalov 			    a_object);
7425c51f124SMoriah Waterland 		}
7435c51f124SMoriah Waterland 
7445c51f124SMoriah Waterland 		/* close lock file */
7455c51f124SMoriah Waterland 
7465c51f124SMoriah Waterland 		(void) close(*a_fd);
7475c51f124SMoriah Waterland 
7485c51f124SMoriah Waterland 		/* wait (sleep) */
7495c51f124SMoriah Waterland 
7505c51f124SMoriah Waterland 		(void) sleep(LOCK_SLEEP_INTERVAL);
7515c51f124SMoriah Waterland 
7525c51f124SMoriah Waterland 		/* open the lock file and try again */
7535c51f124SMoriah Waterland 
7545c51f124SMoriah Waterland 		*a_fd = _openLockFile(a_root);
7555c51f124SMoriah Waterland 		if (*a_fd < 0) {
7565c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, MSG_LOCK_ACQUIRE_REOPEN_FAILED,
757708dafbfSAlexander Pyhalov 			    a_object);
7585c51f124SMoriah Waterland 
7595c51f124SMoriah Waterland 			/* close lock file if opened in this function */
7605c51f124SMoriah Waterland 
7615c51f124SMoriah Waterland 			if (closeOnExit) {
7625c51f124SMoriah Waterland 				(void) close(*a_fd);
7635c51f124SMoriah Waterland 				*a_fd = -1;
7645c51f124SMoriah Waterland 			}
7655c51f124SMoriah Waterland 
7665c51f124SMoriah Waterland 			return (FINDLOCK_ERROR);
7675c51f124SMoriah Waterland 		}
7685c51f124SMoriah Waterland 	}
7695c51f124SMoriah Waterland }
7705c51f124SMoriah Waterland 
7715c51f124SMoriah Waterland /*
7725c51f124SMoriah Waterland  * Name:	lock_release
7735c51f124SMoriah Waterland  * Description:	implement lock release
7745c51f124SMoriah Waterland  * Arguments:
7755c51f124SMoriah Waterland  *	a_fd - file descriptor opened on the lock file
7765c51f124SMoriah Waterland  *	a_key - key associated with lock to release
7775c51f124SMoriah Waterland  *	a_object - object associated with lock to release
7785c51f124SMoriah Waterland  *	a_quiet - quiet mode enabled flag
7795c51f124SMoriah Waterland  * Returns: int
7805c51f124SMoriah Waterland  *		== 0 - successful
7815c51f124SMoriah Waterland  *		!= 0 - not successful
7825c51f124SMoriah Waterland  */
7835c51f124SMoriah Waterland 
7845c51f124SMoriah Waterland static int
lock_release(int a_fd,char * a_key,char * a_object,int a_quiet)7855c51f124SMoriah Waterland lock_release(int a_fd, char *a_key, char *a_object, int a_quiet)
7865c51f124SMoriah Waterland {
7875c51f124SMoriah Waterland 	RECORDNUM_T	recordNum;
7885c51f124SMoriah Waterland 	LOCK_T		theLock;
7895c51f124SMoriah Waterland 	FINDLOCK_T	result;
7905c51f124SMoriah Waterland 
7915c51f124SMoriah Waterland 	/* entry debugging info */
7925c51f124SMoriah Waterland 
7935c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_RELEASE_ENTRY,
794708dafbfSAlexander Pyhalov 	    a_key, a_object, a_quiet);
7955c51f124SMoriah Waterland 
7965c51f124SMoriah Waterland 	/* find the lock to be released */
7975c51f124SMoriah Waterland 
7985c51f124SMoriah Waterland 	result = _findLock(&theLock, &recordNum, a_fd, a_object, a_key);
7995c51f124SMoriah Waterland 
8005c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_RELEASE_FINDRESULT,
801708dafbfSAlexander Pyhalov 	    result, recordNum);
8025c51f124SMoriah Waterland 
8035c51f124SMoriah Waterland 	/* determine how to release the lock if found */
8045c51f124SMoriah Waterland 
8055c51f124SMoriah Waterland 	switch (result) {
8065c51f124SMoriah Waterland 		/*
8075c51f124SMoriah Waterland 		 * object is not locked but a key was specified
8085c51f124SMoriah Waterland 		 */
8095c51f124SMoriah Waterland 		case FINDLOCK_NOTLOCKED:
8105c51f124SMoriah Waterland 			log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
811708dafbfSAlexander Pyhalov 			    MSG_LOCK_RELEASE_NOTLOCKED,
812708dafbfSAlexander Pyhalov 			    a_object, a_key);
8135c51f124SMoriah Waterland 			return (result);
8145c51f124SMoriah Waterland 
8155c51f124SMoriah Waterland 		/*
8165c51f124SMoriah Waterland 		 * object is locked and no matching key was specified
8175c51f124SMoriah Waterland 		 */
8185c51f124SMoriah Waterland 		case FINDLOCK_LOCKED:
8195c51f124SMoriah Waterland 			log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
820708dafbfSAlexander Pyhalov 			    MSG_LOCK_RELEASE_LOCKED,
821708dafbfSAlexander Pyhalov 			    a_object, a_key);
8225c51f124SMoriah Waterland 			return (result);
8235c51f124SMoriah Waterland 
8245c51f124SMoriah Waterland 		/*
8255c51f124SMoriah Waterland 		 * object is not locked
8265c51f124SMoriah Waterland 		 */
8275c51f124SMoriah Waterland 		case FINDLOCK_NOTFOUND:
8285c51f124SMoriah Waterland 			log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
829708dafbfSAlexander Pyhalov 			    MSG_LOCK_RELEASE_NOTFOUND,
830708dafbfSAlexander Pyhalov 			    a_object, a_key);
8315c51f124SMoriah Waterland 			return (result);
8325c51f124SMoriah Waterland 
8335c51f124SMoriah Waterland 		/*
8345c51f124SMoriah Waterland 		 * object is locked and specified key does not match
8355c51f124SMoriah Waterland 		 */
8365c51f124SMoriah Waterland 		case FINDLOCK_KEYMISMATCH:
8375c51f124SMoriah Waterland 			log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
838708dafbfSAlexander Pyhalov 			    MSG_LOCK_RELEASE_KEYMISMATCH,
839708dafbfSAlexander Pyhalov 			    a_object);
8405c51f124SMoriah Waterland 			return (result);
8415c51f124SMoriah Waterland 
8425c51f124SMoriah Waterland 		/*
8435c51f124SMoriah Waterland 		 * error determining if object is locked
8445c51f124SMoriah Waterland 		 */
8455c51f124SMoriah Waterland 		case FINDLOCK_ERROR:
8465c51f124SMoriah Waterland 			log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
847708dafbfSAlexander Pyhalov 			    MSG_LOCK_RELEASE_ERROR,
848708dafbfSAlexander Pyhalov 			    a_object, a_key);
8495c51f124SMoriah Waterland 			perror(LOCK_FILENAME);
8505c51f124SMoriah Waterland 			return (result);
8515c51f124SMoriah Waterland 
8525c51f124SMoriah Waterland 		/*
8535c51f124SMoriah Waterland 		 * object is locked and specified key matches
8545c51f124SMoriah Waterland 		 */
8555c51f124SMoriah Waterland 		case FINDLOCK_FOUND:
8565c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, MSG_LOCK_RELEASE_FOUND,
857708dafbfSAlexander Pyhalov 			    a_object, a_key);
8585c51f124SMoriah Waterland 			(void) _decrementLockCount(a_fd, &theLock);
8595c51f124SMoriah Waterland 			break;
8605c51f124SMoriah Waterland 
8615c51f124SMoriah Waterland 		/*
8625c51f124SMoriah Waterland 		 * unknown return
8635c51f124SMoriah Waterland 		 */
8645c51f124SMoriah Waterland 		default:
8655c51f124SMoriah Waterland 			result = FINDLOCK_ERROR;
8665c51f124SMoriah Waterland 			break;
8675c51f124SMoriah Waterland 
8685c51f124SMoriah Waterland 	}
8695c51f124SMoriah Waterland 	return (result);
8705c51f124SMoriah Waterland }
8715c51f124SMoriah Waterland 
8725c51f124SMoriah Waterland /*
8735c51f124SMoriah Waterland  * Name:	lock_status
8745c51f124SMoriah Waterland  * Description:	implement lock status display/inquiry
8755c51f124SMoriah Waterland  * Arguments:
8765c51f124SMoriah Waterland  *	a_fd - file descriptor opened on the lock file
8775c51f124SMoriah Waterland  *	a_key - key associated with lock to look up
8785c51f124SMoriah Waterland  *	a_object - object associated with lock to look up
8795c51f124SMoriah Waterland  *	a_quiet - quiet mode enabled flag
8805c51f124SMoriah Waterland  * Returns: int
8815c51f124SMoriah Waterland  *		== 0 - successful
8825c51f124SMoriah Waterland  *		!= 0 - not successful
8835c51f124SMoriah Waterland  */
8845c51f124SMoriah Waterland 
8855c51f124SMoriah Waterland static int
lock_status(int a_fd,char * a_key,char * a_object,int a_quiet)8865c51f124SMoriah Waterland lock_status(int a_fd, char *a_key, char *a_object, int a_quiet)
8875c51f124SMoriah Waterland {
8885c51f124SMoriah Waterland 	ADMINLOCK_T	*pll;
8895c51f124SMoriah Waterland 	LOCK_T		theLock;
8905c51f124SMoriah Waterland 	RECORDNUM_T	recordNum = 0;
8915c51f124SMoriah Waterland 	char		*pld;
8925c51f124SMoriah Waterland 	int		found = 0;
8935c51f124SMoriah Waterland 	long		pls;
8945c51f124SMoriah Waterland 
8955c51f124SMoriah Waterland 	/* entry debugging info */
8965c51f124SMoriah Waterland 
8975c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_STATUS_ENTRY,
898708dafbfSAlexander Pyhalov 	    a_key, a_object);
8995c51f124SMoriah Waterland 
9005c51f124SMoriah Waterland 	/* localize references to lock object */
9015c51f124SMoriah Waterland 
9025c51f124SMoriah Waterland 	pld = &theLock._lrLockData[0];
9035c51f124SMoriah Waterland 	pll = &theLock._lrLock;
9045c51f124SMoriah Waterland 	pls = sizeof (theLock._lrLockData);
9055c51f124SMoriah Waterland 
9065c51f124SMoriah Waterland 	bzero(pld, pls);
9075c51f124SMoriah Waterland 
9085c51f124SMoriah Waterland 	/* read and process each lock */
9095c51f124SMoriah Waterland 
9105c51f124SMoriah Waterland 	for (; pread(a_fd, pld, pls, pls*recordNum) == pls; recordNum++) {
9115c51f124SMoriah Waterland 		/* debug info on this lock */
9125c51f124SMoriah Waterland 
9135c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LOCK_STATUS_READRECORD,
914708dafbfSAlexander Pyhalov 		    recordNum, pll->lockCount,
915708dafbfSAlexander Pyhalov 		    pll->lockObject, pll->lockKey, pll->lockPid,
916708dafbfSAlexander Pyhalov 		    pll->lockZoneId);
9175c51f124SMoriah Waterland 
9185c51f124SMoriah Waterland 		/* ignore if key specified and key does not match */
9195c51f124SMoriah Waterland 
9205c51f124SMoriah Waterland 		if ((*a_key != '\0') &&
921708dafbfSAlexander Pyhalov 		    (strcmp(pll->lockKey, a_key) != 0)) {
9225c51f124SMoriah Waterland 			continue;
9235c51f124SMoriah Waterland 		}
9245c51f124SMoriah Waterland 
9255c51f124SMoriah Waterland 		/* ignore if object specified and object does not match */
9265c51f124SMoriah Waterland 
9275c51f124SMoriah Waterland 		if ((*a_object != '\0') &&
928708dafbfSAlexander Pyhalov 		    (strcmp(pll->lockObject, a_object) != 0)) {
9295c51f124SMoriah Waterland 			continue;
9305c51f124SMoriah Waterland 		}
9315c51f124SMoriah Waterland 
9325c51f124SMoriah Waterland 		found++;
9335c51f124SMoriah Waterland 
9345c51f124SMoriah Waterland 		/* process next lock if quiet operation */
9355c51f124SMoriah Waterland 
9365c51f124SMoriah Waterland 		if (a_quiet != 0) {
9375c51f124SMoriah Waterland 			continue;
9385c51f124SMoriah Waterland 		}
9395c51f124SMoriah Waterland 
9405c51f124SMoriah Waterland 		/* output header if first lock object */
9415c51f124SMoriah Waterland 
9425c51f124SMoriah Waterland 		if (found == 1) {
9435c51f124SMoriah Waterland 			(void) fprintf(stdout,
944708dafbfSAlexander Pyhalov 			    "%2s %2s %3s %8s %3s %9s %37s %s\n",
945708dafbfSAlexander Pyhalov 			    "i#", "l#", "cnt", "pid", "zid", "lock-type",
946708dafbfSAlexander Pyhalov 			    "---------------lock-key-------------",
947708dafbfSAlexander Pyhalov 			    "lock-object");
9485c51f124SMoriah Waterland 		}
9495c51f124SMoriah Waterland 
9505c51f124SMoriah Waterland 		/* output status line for this lock object */
9515c51f124SMoriah Waterland 
9525c51f124SMoriah Waterland 		(void) fprintf(stdout,
953708dafbfSAlexander Pyhalov 		    "%2ld %2ld %3ld %8ld %3d %9s %37s %s\n",
954708dafbfSAlexander Pyhalov 		    recordNum, pll->lockRecordNum, pll->lockCount,
955708dafbfSAlexander Pyhalov 		    pll->lockPid, pll->lockZoneId,
956708dafbfSAlexander Pyhalov 		    pll->lockExclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
957708dafbfSAlexander Pyhalov 		    pll->lockKey,
958708dafbfSAlexander Pyhalov 		    *pll->lockObject == '\0' ? "*" : pll->lockObject);
9595c51f124SMoriah Waterland 	}
9605c51f124SMoriah Waterland 
9615c51f124SMoriah Waterland 	/* return == 0 if found, != 0 if not found */
9625c51f124SMoriah Waterland 
9635c51f124SMoriah Waterland 	return (found == 0 ? 1 : 0);
9645c51f124SMoriah Waterland }
9655c51f124SMoriah Waterland 
9665c51f124SMoriah Waterland /*
9675c51f124SMoriah Waterland  * local utility functions
9685c51f124SMoriah Waterland  */
9695c51f124SMoriah Waterland 
9705c51f124SMoriah Waterland /*
9715c51f124SMoriah Waterland  * Name:	_lock_acquire
9725c51f124SMoriah Waterland  * Description:	implement lock acquisition without wait/timeouts
9735c51f124SMoriah Waterland  * Arguments:
9745c51f124SMoriah Waterland  *	a_theLock - lock object filled with contents of existing lock
9755c51f124SMoriah Waterland  *	a_fd - file descriptor opened on the lock file
9765c51f124SMoriah Waterland  *	a_key - key associated with lock to acquire
9775c51f124SMoriah Waterland  *	a_object - object associated with lock to acquire
9785c51f124SMoriah Waterland  *	a_quiet - quiet mode enabled flag
9795c51f124SMoriah Waterland  *	a_exclusive - exclusive/shared lock flag
9805c51f124SMoriah Waterland  *	a_pid - if != 0 process i.d. to associate with this lock
9815c51f124SMoriah Waterland  *	a_zid - if >= 0 zone i.d. to associate with this lock
9825c51f124SMoriah Waterland  * Returns: FINDLOCK_T
9835c51f124SMoriah Waterland  */
9845c51f124SMoriah Waterland 
9855c51f124SMoriah Waterland static FINDLOCK_T
_lock_acquire(LOCK_T * a_theLock,int a_fd,char * a_key,char * a_object,int a_quiet,int a_exclusive,pid_t a_pid,zoneid_t a_zid)9865c51f124SMoriah Waterland _lock_acquire(LOCK_T *a_theLock, int a_fd, char *a_key,
987708dafbfSAlexander Pyhalov     char *a_object, int a_quiet, int a_exclusive, pid_t a_pid,
988708dafbfSAlexander Pyhalov     zoneid_t a_zid)
9895c51f124SMoriah Waterland {
9905c51f124SMoriah Waterland 	RECORDNUM_T	recordNum;
9915c51f124SMoriah Waterland 	FINDLOCK_T	result;
9925c51f124SMoriah Waterland 	char		key[LOCK_KEY_MAXLEN+1] = {'\0'};
9935c51f124SMoriah Waterland 
9945c51f124SMoriah Waterland 	/* entry debugging info */
9955c51f124SMoriah Waterland 
9965c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_ACQUIRE_ENTRY,
997708dafbfSAlexander Pyhalov 	    a_key, a_object, a_quiet, a_exclusive);
9985c51f124SMoriah Waterland 
9995c51f124SMoriah Waterland 	/* is the specified object already locked? */
10005c51f124SMoriah Waterland 
10015c51f124SMoriah Waterland 	for (;;) {
10025c51f124SMoriah Waterland 		result = _findLock(a_theLock, &recordNum, a_fd, a_object,
1003708dafbfSAlexander Pyhalov 		    a_key);
10045c51f124SMoriah Waterland 
10055c51f124SMoriah Waterland 		if (result != FINDLOCK_LOCKED) {
10065c51f124SMoriah Waterland 			break;
10075c51f124SMoriah Waterland 		}
10085c51f124SMoriah Waterland 
10095c51f124SMoriah Waterland 		if (_validateLock(a_fd, a_theLock, a_quiet) == B_TRUE) {
10105c51f124SMoriah Waterland 			break;
10115c51f124SMoriah Waterland 		}
10125c51f124SMoriah Waterland 	}
10135c51f124SMoriah Waterland 
10145c51f124SMoriah Waterland 
10155c51f124SMoriah Waterland 	/* debug info on result of find of lock */
10165c51f124SMoriah Waterland 
10175c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_ACQUIRE_FINDRESULT,
1018708dafbfSAlexander Pyhalov 	    a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
1019708dafbfSAlexander Pyhalov 	    result, recordNum);
10205c51f124SMoriah Waterland 
10215c51f124SMoriah Waterland 	/* determine how to acquire the lock */
10225c51f124SMoriah Waterland 
10235c51f124SMoriah Waterland 	switch (result) {
10245c51f124SMoriah Waterland 		/*
10255c51f124SMoriah Waterland 		 * object is not locked but a key was specified
10265c51f124SMoriah Waterland 		 */
10275c51f124SMoriah Waterland 		case FINDLOCK_NOTLOCKED:
10285c51f124SMoriah Waterland 			log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
1029708dafbfSAlexander Pyhalov 			    MSG_LOCK_ACQUIRE_NOTLOCKED,
1030708dafbfSAlexander Pyhalov 			    a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
1031708dafbfSAlexander Pyhalov 			    a_object, a_key);
10325c51f124SMoriah Waterland 			break;
10335c51f124SMoriah Waterland 
10345c51f124SMoriah Waterland 		/*
10355c51f124SMoriah Waterland 		 * object is locked and no key was specified:
10365c51f124SMoriah Waterland 		 * - if lock is exclusively held, return "locked"
10375c51f124SMoriah Waterland 		 * - if exclusive lock requested, return "locked"
10385c51f124SMoriah Waterland 		 * - otherwise lock is shared and shared lock requested,
10395c51f124SMoriah Waterland 		 *   - increment lock count and return the key
10405c51f124SMoriah Waterland 		 */
10415c51f124SMoriah Waterland 		case FINDLOCK_LOCKED:
10425c51f124SMoriah Waterland 			/* return error if current lock exclusive */
10435c51f124SMoriah Waterland 
10445c51f124SMoriah Waterland 			if (a_theLock->_lrLock.lockExclusive) {
10455c51f124SMoriah Waterland 				break;
10465c51f124SMoriah Waterland 			}
10475c51f124SMoriah Waterland 
10485c51f124SMoriah Waterland 			/* return error if requesting exclusive lock */
10495c51f124SMoriah Waterland 
10505c51f124SMoriah Waterland 			if (a_exclusive) {
10515c51f124SMoriah Waterland 				break;
10525c51f124SMoriah Waterland 			}
10535c51f124SMoriah Waterland 
10545c51f124SMoriah Waterland 			/* shared requesting shared - add to shared lock */
10555c51f124SMoriah Waterland 
10565c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG,
1057708dafbfSAlexander Pyhalov 			    MSG_LOCK_ACQUIRE_LOCKED_SHARED,
1058708dafbfSAlexander Pyhalov 			    a_object, a_key);
10595c51f124SMoriah Waterland 
10605c51f124SMoriah Waterland 			/* increment shared lock count */
10615c51f124SMoriah Waterland 
10625c51f124SMoriah Waterland 			if (_incrementLockCount(a_fd, a_theLock) == 0) {
10635c51f124SMoriah Waterland 				result = FINDLOCK_LOCKACQUIRED;
10645c51f124SMoriah Waterland 			} else {
10655c51f124SMoriah Waterland 				result = FINDLOCK_ERROR;
10665c51f124SMoriah Waterland 			}
10675c51f124SMoriah Waterland 
10685c51f124SMoriah Waterland 			break;
10695c51f124SMoriah Waterland 
10705c51f124SMoriah Waterland 		/*
10715c51f124SMoriah Waterland 		 * object is not locked
10725c51f124SMoriah Waterland 		 */
10735c51f124SMoriah Waterland 		case FINDLOCK_NOTFOUND:
10745c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG,
1075708dafbfSAlexander Pyhalov 			    MSG_LOCK_ACQUIRE_NOTFOUND,
1076708dafbfSAlexander Pyhalov 			    a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
1077708dafbfSAlexander Pyhalov 			    a_object);
10785c51f124SMoriah Waterland 
10795c51f124SMoriah Waterland 			if (_addLock(key, a_fd, a_object, a_exclusive,
1080708dafbfSAlexander Pyhalov 			    a_pid, a_zid) == 0) {
10815c51f124SMoriah Waterland 				(void) strncpy(a_theLock->_lrLock.lockKey, key,
1082708dafbfSAlexander Pyhalov 				    sizeof (a_theLock->_lrLock.lockKey));
10835c51f124SMoriah Waterland 				result = FINDLOCK_LOCKACQUIRED;
10845c51f124SMoriah Waterland 			} else {
10855c51f124SMoriah Waterland 				result = FINDLOCK_ERROR;
10865c51f124SMoriah Waterland 			}
10875c51f124SMoriah Waterland 			break;
10885c51f124SMoriah Waterland 
10895c51f124SMoriah Waterland 		/*
10905c51f124SMoriah Waterland 		 * object is locked, key specified, specified key does not match
10915c51f124SMoriah Waterland 		 */
10925c51f124SMoriah Waterland 		case FINDLOCK_KEYMISMATCH:
10935c51f124SMoriah Waterland 			log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
1094708dafbfSAlexander Pyhalov 			    MSG_LOCK_ACQUIRE_KEYMISMATCH,
1095708dafbfSAlexander Pyhalov 			    a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
1096708dafbfSAlexander Pyhalov 			    a_object);
10975c51f124SMoriah Waterland 			break;
10985c51f124SMoriah Waterland 
10995c51f124SMoriah Waterland 		/*
11005c51f124SMoriah Waterland 		 * error determining if object is locked
11015c51f124SMoriah Waterland 		 */
11025c51f124SMoriah Waterland 		case FINDLOCK_ERROR:
11035c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, MSG_LOCK_ACQUIRE_ERROR,
1104708dafbfSAlexander Pyhalov 			    a_object, a_key, strerror(errno));
11055c51f124SMoriah Waterland 			break;
11065c51f124SMoriah Waterland 
11075c51f124SMoriah Waterland 		/*
11085c51f124SMoriah Waterland 		 * object is locked and specified key matches
11095c51f124SMoriah Waterland 		 */
11105c51f124SMoriah Waterland 		case FINDLOCK_FOUND:
11115c51f124SMoriah Waterland 			/* return locked if object currently locked */
11125c51f124SMoriah Waterland 			if (a_exclusive != a_theLock->_lrLock.lockExclusive) {
11135c51f124SMoriah Waterland 				result = FINDLOCK_LOCKED;
11145c51f124SMoriah Waterland 				break;
11155c51f124SMoriah Waterland 			}
11165c51f124SMoriah Waterland 
11175c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, MSG_LOCK_ACQUIRE_FOUND_INC,
1118708dafbfSAlexander Pyhalov 			    a_object, a_key,
1119708dafbfSAlexander Pyhalov 			    a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR);
11205c51f124SMoriah Waterland 
11215c51f124SMoriah Waterland 			/* increment shared lock */
11225c51f124SMoriah Waterland 
11235c51f124SMoriah Waterland 			if (_incrementLockCount(a_fd, a_theLock) == 0) {
11245c51f124SMoriah Waterland 				result = FINDLOCK_LOCKACQUIRED;
11255c51f124SMoriah Waterland 			} else {
11265c51f124SMoriah Waterland 				result = FINDLOCK_ERROR;
11275c51f124SMoriah Waterland 			}
11285c51f124SMoriah Waterland 			break;
11295c51f124SMoriah Waterland 
11305c51f124SMoriah Waterland 		/*
11315c51f124SMoriah Waterland 		 * unknown return
11325c51f124SMoriah Waterland 		 */
11335c51f124SMoriah Waterland 		default:
11345c51f124SMoriah Waterland 			result = FINDLOCK_ERROR;
11355c51f124SMoriah Waterland 			break;
11365c51f124SMoriah Waterland 	}
11375c51f124SMoriah Waterland 
11385c51f124SMoriah Waterland 	return (result);
11395c51f124SMoriah Waterland }
11405c51f124SMoriah Waterland 
11415c51f124SMoriah Waterland /*
11425c51f124SMoriah Waterland  * Name:	_openLockFile
11435c51f124SMoriah Waterland  * Description:	open the lock file, acquiring exclusive record locks
11445c51f124SMoriah Waterland  * Arguments:
11455c51f124SMoriah Waterland  *	a_root - root of file system to manipulate locks on
11465c51f124SMoriah Waterland  * Returns: int
11475c51f124SMoriah Waterland  *		>= 0 - successful - file descriptor lock file opened on
11485c51f124SMoriah Waterland  *		< 0 - not successful
11495c51f124SMoriah Waterland  */
11505c51f124SMoriah Waterland 
11515c51f124SMoriah Waterland static int
_openLockFile(char * a_root)11525c51f124SMoriah Waterland _openLockFile(char *a_root)
11535c51f124SMoriah Waterland {
11545c51f124SMoriah Waterland 	WAITER_T	waiter;
11555c51f124SMoriah Waterland 	char		lockpath[MAXPATHLEN];
11565c51f124SMoriah Waterland 	int		fd;
11575c51f124SMoriah Waterland 	int		result;
11585c51f124SMoriah Waterland 
11595c51f124SMoriah Waterland 	/* entry debugging info */
11605c51f124SMoriah Waterland 
11615c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_ENTRY,
1162708dafbfSAlexander Pyhalov 	    a_root, LOCK_FILENAME);
11635c51f124SMoriah Waterland 
11645c51f124SMoriah Waterland 	/* generate path to lock directory */
11655c51f124SMoriah Waterland 
11665c51f124SMoriah Waterland 	(void) snprintf(lockpath, sizeof (lockpath), "%s/%s",
1167708dafbfSAlexander Pyhalov 	    a_root, LOCK_DIRECTORY);
11685c51f124SMoriah Waterland 
11695c51f124SMoriah Waterland 	if (access(lockpath, F_OK) != 0) {
11705c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_ROOTDIR_INVALID,
1171708dafbfSAlexander Pyhalov 		    lockpath, strerror(errno));
11725c51f124SMoriah Waterland 		return (-1);
11735c51f124SMoriah Waterland 	}
11745c51f124SMoriah Waterland 
11755c51f124SMoriah Waterland 	/* generate path to lock file */
11765c51f124SMoriah Waterland 
11775c51f124SMoriah Waterland 	(void) snprintf(lockpath, sizeof (lockpath),
1178708dafbfSAlexander Pyhalov 	    "%s/%s", a_root, LOCK_FILENAME);
11795c51f124SMoriah Waterland 
11805c51f124SMoriah Waterland 	/* wait for open to succeed up to limits */
11815c51f124SMoriah Waterland 
11825c51f124SMoriah Waterland 	for (waiter = WAITER_INITIAL;
1183708dafbfSAlexander Pyhalov 	    waiter < WAITER_MAX;
1184708dafbfSAlexander Pyhalov 	    waiter = WAITER_NEXT(waiter)) {
11855c51f124SMoriah Waterland 
11865c51f124SMoriah Waterland 		/* LINTED O_CREAT without O_EXCL specified in call to open() */
11875c51f124SMoriah Waterland 		fd = open(lockpath, O_CREAT|O_RDWR, LOCK_FILEMODE);
11885c51f124SMoriah Waterland 
11895c51f124SMoriah Waterland 		/* break out of loop if file opened */
11905c51f124SMoriah Waterland 
11915c51f124SMoriah Waterland 		if (fd >= 0) {
11925c51f124SMoriah Waterland 			break;
11935c51f124SMoriah Waterland 		}
11945c51f124SMoriah Waterland 
11955c51f124SMoriah Waterland 		/* failed - exit loop if due to access (permissions) failure */
11965c51f124SMoriah Waterland 
11975c51f124SMoriah Waterland 		if (errno == EACCES) {
11985c51f124SMoriah Waterland 			break;
11995c51f124SMoriah Waterland 		}
12005c51f124SMoriah Waterland 
12015c51f124SMoriah Waterland 		/* file is busy - wait and try again */
12025c51f124SMoriah Waterland 
12035c51f124SMoriah Waterland 		if (waiter == WAITER_INITIAL) {
12045c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG,
1205708dafbfSAlexander Pyhalov 			    MSG_LOCK_OPENFILE_SLEEPING,
1206708dafbfSAlexander Pyhalov 			    strerror(errno), waiter);
12075c51f124SMoriah Waterland 		}
12085c51f124SMoriah Waterland 
12095c51f124SMoriah Waterland 		(void) sleep(waiter);
12105c51f124SMoriah Waterland 	}
12115c51f124SMoriah Waterland 
12125c51f124SMoriah Waterland 	/* if open filed generate error message and return error */
12135c51f124SMoriah Waterland 
12145c51f124SMoriah Waterland 	if (fd < 0) {
12155c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_FAILURE,
1216708dafbfSAlexander Pyhalov 		    strerror(errno));
12175c51f124SMoriah Waterland 		perror(lockpath);
12185c51f124SMoriah Waterland 		return (-1);
12195c51f124SMoriah Waterland 	}
12205c51f124SMoriah Waterland 
12215c51f124SMoriah Waterland 	/*
12225c51f124SMoriah Waterland 	 * lock file opened - acquire exclusive section lock on entire file;
12235c51f124SMoriah Waterland 	 * wait for lockf to succeed up to limits
12245c51f124SMoriah Waterland 	 */
12255c51f124SMoriah Waterland 
12265c51f124SMoriah Waterland 	for (waiter = WAITER_INITIAL;
1227708dafbfSAlexander Pyhalov 	    waiter < WAITER_MAX;
1228708dafbfSAlexander Pyhalov 	    waiter = WAITER_NEXT(waiter)) {
12295c51f124SMoriah Waterland 
12305c51f124SMoriah Waterland 		/* acquire exclusive section lock on entire file */
12315c51f124SMoriah Waterland 
12325c51f124SMoriah Waterland 		result = lockf(fd, F_LOCK, 0xFFFFF);
12335c51f124SMoriah Waterland 
12345c51f124SMoriah Waterland 		/* break out of loop if entire file locked */
12355c51f124SMoriah Waterland 
12365c51f124SMoriah Waterland 		if (result == 0) {
12375c51f124SMoriah Waterland 			break;
12385c51f124SMoriah Waterland 		}
12395c51f124SMoriah Waterland 
12405c51f124SMoriah Waterland 		/* file is busy - wait and try again */
12415c51f124SMoriah Waterland 
12425c51f124SMoriah Waterland 		if (waiter == WAITER_INITIAL) {
12435c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_SLEEP2,
1244708dafbfSAlexander Pyhalov 			    strerror(errno), waiter);
12455c51f124SMoriah Waterland 		}
12465c51f124SMoriah Waterland 
12475c51f124SMoriah Waterland 		(void) sleep(waiter);
12485c51f124SMoriah Waterland 	}
12495c51f124SMoriah Waterland 
12505c51f124SMoriah Waterland 	/* if section lock failed generate error message and return error */
12515c51f124SMoriah Waterland 
12525c51f124SMoriah Waterland 	if (result < 0) {
12535c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_FAIL2,
1254708dafbfSAlexander Pyhalov 		    strerror(errno));
12555c51f124SMoriah Waterland 		perror(lockpath);
12565c51f124SMoriah Waterland 		(void) close(fd);
12575c51f124SMoriah Waterland 		return (-1);
12585c51f124SMoriah Waterland 	}
12595c51f124SMoriah Waterland 
12605c51f124SMoriah Waterland 	/* file opened and locked - return success */
12615c51f124SMoriah Waterland 
12625c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_SUCCESS, fd);
12635c51f124SMoriah Waterland 
12645c51f124SMoriah Waterland 	return (fd);
12655c51f124SMoriah Waterland }
12665c51f124SMoriah Waterland 
12675c51f124SMoriah Waterland /*
12685c51f124SMoriah Waterland  * Name:	_lockMatch
12695c51f124SMoriah Waterland  * Description:	Compare two lock objects using file name match criteria
12705c51f124SMoriah Waterland  * Arguments:
12715c51f124SMoriah Waterland  *	a_s1Lock - first lock object to compare against the second
12725c51f124SMoriah Waterland  *	a_s2Lock - second lock object to compare against the first
12735c51f124SMoriah Waterland  * Returns:
1274014740deSToomas Soome  *	== 0 - the locks match at some level
12755c51f124SMoriah Waterland  *	!= 0 - the locks do not match at any level
12765c51f124SMoriah Waterland  */
12775c51f124SMoriah Waterland 
12785c51f124SMoriah Waterland static int
_lockMatch(char * a_s1Lock,char * a_s2Lock)12795c51f124SMoriah Waterland _lockMatch(char *a_s1Lock, char *a_s2Lock)
12805c51f124SMoriah Waterland {
12815c51f124SMoriah Waterland 	boolean_t	s1Sfx = B_FALSE;
12825c51f124SMoriah Waterland 	boolean_t	s2Sfx = B_FALSE;
12835c51f124SMoriah Waterland 	char		*final1Lock = (char *)NULL;
12845c51f124SMoriah Waterland 	char		*final2Lock = (char *)NULL;
12855c51f124SMoriah Waterland 	char		s1Buf[MAXPATHLEN] = {'\0'};
12865c51f124SMoriah Waterland 	char		s1Prefix[MAXPATHLEN] = {'\0'};
12875c51f124SMoriah Waterland 	char		s2Buf[MAXPATHLEN] = {'\0'};
12885c51f124SMoriah Waterland 	char		s2Prefix[MAXPATHLEN] = {'\0'};
12895c51f124SMoriah Waterland 	int		result = 0;
12905c51f124SMoriah Waterland 	int		s1Cnt;
1291014740deSToomas Soome 	int		s2Cnt = 0;
12925c51f124SMoriah Waterland 
12935c51f124SMoriah Waterland 	/* entry assertions */
12945c51f124SMoriah Waterland 
12955c51f124SMoriah Waterland 	assert(a_s1Lock != (char *)NULL);
12965c51f124SMoriah Waterland 	assert(a_s2Lock != (char *)NULL);
12975c51f124SMoriah Waterland 
12985c51f124SMoriah Waterland 	/* entry debugging info */
12995c51f124SMoriah Waterland 
13005c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_ENTRY, a_s1Lock, a_s2Lock);
13015c51f124SMoriah Waterland 
13025c51f124SMoriah Waterland 	/*
13035c51f124SMoriah Waterland 	 * attempt to find a common anchor between the two locks; that is,
13045c51f124SMoriah Waterland 	 * find the first node in the first lock that matches any node
13055c51f124SMoriah Waterland 	 * in the second lock; for example:
13065c51f124SMoriah Waterland 	 * --> a/b/c vs b/c/d
13075c51f124SMoriah Waterland 	 * -> common anchor is "b"; comparison would expand to:
13085c51f124SMoriah Waterland 	 * --> a/b/c/? vs ?/b/c/d
13095c51f124SMoriah Waterland 	 */
13105c51f124SMoriah Waterland 
13115c51f124SMoriah Waterland 	/* process each node in the first lock */
13125c51f124SMoriah Waterland 
13135c51f124SMoriah Waterland 	for (s1Cnt = 0; ; s1Cnt++) {
13145c51f124SMoriah Waterland 		/* get next first lock node */
13155c51f124SMoriah Waterland 
13165c51f124SMoriah Waterland 		pkgstrGetToken_r((char *)NULL, a_s1Lock, s1Cnt, "/",
1317708dafbfSAlexander Pyhalov 		    s1Buf, sizeof (s1Buf));
13185c51f124SMoriah Waterland 
13195c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_FSTNODE, s1Cnt, s1Buf);
13205c51f124SMoriah Waterland 
13215c51f124SMoriah Waterland 		/* exit if no more nodes left */
13225c51f124SMoriah Waterland 
13235c51f124SMoriah Waterland 		if (s1Buf[0] == '\0') {
13245c51f124SMoriah Waterland 			break;
13255c51f124SMoriah Waterland 		}
13265c51f124SMoriah Waterland 
13275c51f124SMoriah Waterland 		/* discover "." prefix for this node */
13285c51f124SMoriah Waterland 
13295c51f124SMoriah Waterland 		pkgstrGetToken_r((char *)NULL, s1Buf, 0, ".", s1Prefix,
1330708dafbfSAlexander Pyhalov 		    sizeof (s1Prefix));
13315c51f124SMoriah Waterland 
13325c51f124SMoriah Waterland 		s1Sfx = (strlen(s1Prefix) == strlen(s1Buf) ? B_FALSE : B_TRUE);
13335c51f124SMoriah Waterland 
13345c51f124SMoriah Waterland 		/* search each second lock node; look for the first node lock */
13355c51f124SMoriah Waterland 
13365c51f124SMoriah Waterland 		for (s2Cnt = 0; ; s2Cnt++) {
13375c51f124SMoriah Waterland 			/* get next second lock node */
13385c51f124SMoriah Waterland 
13395c51f124SMoriah Waterland 			pkgstrGetToken_r((char *)NULL, a_s2Lock, s2Cnt, "/",
1340708dafbfSAlexander Pyhalov 			    s2Buf, sizeof (s2Buf));
13415c51f124SMoriah Waterland 
13425c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SCNDNODE, s2Cnt,
1343708dafbfSAlexander Pyhalov 			    s2Buf);
13445c51f124SMoriah Waterland 
13455c51f124SMoriah Waterland 			/* exit if no nodes left */
13465c51f124SMoriah Waterland 
13475c51f124SMoriah Waterland 			if (s2Buf[0] == '\0') {
13485c51f124SMoriah Waterland 				break;
13495c51f124SMoriah Waterland 			}
13505c51f124SMoriah Waterland 
13515c51f124SMoriah Waterland 			/* discover "." prefix for this node */
13525c51f124SMoriah Waterland 
13535c51f124SMoriah Waterland 			pkgstrGetToken_r((char *)NULL, s2Buf, 0, ".", s2Prefix,
1354708dafbfSAlexander Pyhalov 			    sizeof (s2Prefix));
13555c51f124SMoriah Waterland 
13565c51f124SMoriah Waterland 			s2Sfx = (strlen(s2Prefix) ==
1357708dafbfSAlexander Pyhalov 			    strlen(s2Buf) ? B_FALSE : B_TRUE);
13585c51f124SMoriah Waterland 
13595c51f124SMoriah Waterland 			/*
13605c51f124SMoriah Waterland 			 * process this pair of nodes:
13615c51f124SMoriah Waterland 			 * if both nodes do not have a prefix, then directly
13625c51f124SMoriah Waterland 			 * compare the nodes (e.g. a/b vs c/d: a vs c, b vs d)
13635c51f124SMoriah Waterland 			 * and break out of the loop if there is a match;
13645c51f124SMoriah Waterland 			 * otherwise, compare prefixes and break out of the
13655c51f124SMoriah Waterland 			 * loop if there is a match (e.g. a.* / b.* vs
13665c51f124SMoriah Waterland 			 * vs c.* / d.*: a.* vs c.*, a.* vs d.*, b.* vs c.*,
13675c51f124SMoriah Waterland 			 * b.* vs d.*).
13685c51f124SMoriah Waterland 			 */
13695c51f124SMoriah Waterland 
13705c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_NODES, s1Buf,
1371708dafbfSAlexander Pyhalov 			    s1Prefix, s1Sfx, s2Buf, s2Prefix, s2Sfx);
13725c51f124SMoriah Waterland 
13735c51f124SMoriah Waterland 			if ((s1Sfx == B_FALSE) || (s2Sfx == B_FALSE)) {
13745c51f124SMoriah Waterland 				/* one doesnt have a prefix direct comparison */
13755c51f124SMoriah Waterland 
13765c51f124SMoriah Waterland 				if (strcmp(s1Buf, s2Buf) == 0) {
13775c51f124SMoriah Waterland 					log_msg(LOG_MSG_DEBUG,
1378708dafbfSAlexander Pyhalov 					    MSG_LCKMCH_DIRMCH,
1379708dafbfSAlexander Pyhalov 					    s1Buf, s2Buf);
13805c51f124SMoriah Waterland 					break;
13815c51f124SMoriah Waterland 				}
13825c51f124SMoriah Waterland 
13835c51f124SMoriah Waterland 				/* nodes do not directly match, continue */
13845c51f124SMoriah Waterland 
13855c51f124SMoriah Waterland 				log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_DIRNOMCH,
1386708dafbfSAlexander Pyhalov 				    s1Buf, s2Buf);
13875c51f124SMoriah Waterland 				continue;
13885c51f124SMoriah Waterland 			}
13895c51f124SMoriah Waterland 
13905c51f124SMoriah Waterland 			/* both have prefix, compare prefixes */
13915c51f124SMoriah Waterland 
13925c51f124SMoriah Waterland 			if (strcmp(s1Prefix, s2Prefix) == 0) {
13935c51f124SMoriah Waterland 				log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_PFXMCH,
1394708dafbfSAlexander Pyhalov 				    s1Prefix, s2Prefix);
13955c51f124SMoriah Waterland 				break;
13965c51f124SMoriah Waterland 			}
13975c51f124SMoriah Waterland 
13985c51f124SMoriah Waterland 			/* prefixes do not match, continue */
13995c51f124SMoriah Waterland 
14005c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_PFXNOMCH, s1Prefix,
1401708dafbfSAlexander Pyhalov 			    s2Prefix);
14025c51f124SMoriah Waterland 		}
14035c51f124SMoriah Waterland 
14045c51f124SMoriah Waterland 		/*
14055c51f124SMoriah Waterland 		 * match found if not at the end of the second lock node list,
14065c51f124SMoriah Waterland 		 * break out of loop because some match between the two lock
14075c51f124SMoriah Waterland 		 * objects has been found
14085c51f124SMoriah Waterland 		 */
14095c51f124SMoriah Waterland 
14105c51f124SMoriah Waterland 		if (s2Buf[0] != '\0') {
14115c51f124SMoriah Waterland 			break;
14125c51f124SMoriah Waterland 		}
14135c51f124SMoriah Waterland 	}
14145c51f124SMoriah Waterland 
14155c51f124SMoriah Waterland 	/*
14165c51f124SMoriah Waterland 	 * at this point, either a match has been found between the nodes in
14175c51f124SMoriah Waterland 	 * the two lock objects, or there is no commonality at all between
14185c51f124SMoriah Waterland 	 * the two lock objects.
14195c51f124SMoriah Waterland 	 *
14205c51f124SMoriah Waterland 	 * s1Buf[0] == '\0' && s2Buf[0] == '\0':
14215c51f124SMoriah Waterland 	 * --> nothing in first lock matches anything in second lock:
14225c51f124SMoriah Waterland 	 * ----> (s1Cnt == 1) || (s2Cnt == 1) && (s1Sfx == B_FALSE)
14235c51f124SMoriah Waterland 	 * ----> || (s2Sfx == B_FALSE)
14245c51f124SMoriah Waterland 	 * --------> an absolute lock do not match
14255c51f124SMoriah Waterland 	 * ----> else both object locks have nothing in common - match
14265c51f124SMoriah Waterland 	 *
14275c51f124SMoriah Waterland 	 * s2Buf[0] != '\0' && s1Buf[0] != '\0' && s1Cnt > 0 && s2Cnt > 0
14285c51f124SMoriah Waterland 	 * --> locks have incompatible overlaps - no match, such as:
14295c51f124SMoriah Waterland 	 * ---->  a.* / b.* / c.* / d.*   and   y.* / b.* / c.*
14305c51f124SMoriah Waterland 	 *
14315c51f124SMoriah Waterland 	 * s1Cnt == 0 && s2Cnt == 0:
14325c51f124SMoriah Waterland 	 * --> locks begin with same node - do comparison
14335c51f124SMoriah Waterland 	 *
14345c51f124SMoriah Waterland 	 * s1Cnt != 0 && s2Cnt == 0 && s2Buf[0] != '\0'
14355c51f124SMoriah Waterland 	 * --> second lock is subset of first lock
14365c51f124SMoriah Waterland 	 *
14375c51f124SMoriah Waterland 	 * s2Cnt == 0 && s2Buf[0] != '\0':
14385c51f124SMoriah Waterland 	 * --> s1Buf[s1Cnt] matches s2Buf[0] - second is subset of first
14395c51f124SMoriah Waterland 	 *
14405c51f124SMoriah Waterland 	 * s2Cnt != 0 && s1Cnt == 0 && s1Buf[0] != '\0':
14415c51f124SMoriah Waterland 	 * --> first lock is subset of second lock
14425c51f124SMoriah Waterland 	 *
14435c51f124SMoriah Waterland 	 */
14445c51f124SMoriah Waterland 
14455c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_FSTLCK, s1Cnt, s1Buf,
1446708dafbfSAlexander Pyhalov 	    s1Prefix, s1Sfx);
14475c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SCNDLCK, s2Cnt, s2Buf,
1448708dafbfSAlexander Pyhalov 	    s2Prefix, s2Sfx);
14495c51f124SMoriah Waterland 
14505c51f124SMoriah Waterland 	/* process any direct comparisons that might be possible */
14515c51f124SMoriah Waterland 
14525c51f124SMoriah Waterland 	if ((s1Buf[0] == '\0') && (s2Buf[0] == '\0')) {
14535c51f124SMoriah Waterland 		/* nothing in first matches anything in second lock */
14545c51f124SMoriah Waterland 
14555c51f124SMoriah Waterland 		if (((s1Cnt == 1) || (s2Cnt == 1)) &&
1456708dafbfSAlexander Pyhalov 		    ((s1Sfx == B_FALSE) || (s2Sfx == B_FALSE))) {
14575c51f124SMoriah Waterland 			/* two absolute locks match (e.g. 'file' and 'dir') */
14585c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_ABSNOMCH, a_s1Lock,
1459708dafbfSAlexander Pyhalov 			    a_s2Lock);
14605c51f124SMoriah Waterland 			return (1);
14615c51f124SMoriah Waterland 		}
14625c51f124SMoriah Waterland 
14635c51f124SMoriah Waterland 		/* two object locks have nothing in common: match */
14645c51f124SMoriah Waterland 
14655c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_OBJMCH, a_s1Lock, a_s2Lock);
14665c51f124SMoriah Waterland 
14675c51f124SMoriah Waterland 		return (0);
14685c51f124SMoriah Waterland 	}
14695c51f124SMoriah Waterland 
14705c51f124SMoriah Waterland 	if ((s2Buf[0] != '\0') && (s1Buf[0] != '\0') &&
1471708dafbfSAlexander Pyhalov 	    (s1Cnt > 0) && (s2Cnt > 0)) {
14725c51f124SMoriah Waterland 		/* incompatible overlapping objects */
14735c51f124SMoriah Waterland 
14745c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_OVLPNOMCH, a_s1Lock, a_s2Lock,
1475708dafbfSAlexander Pyhalov 		    s1Cnt+1, s1Buf);
14765c51f124SMoriah Waterland 
14775c51f124SMoriah Waterland 		return (1);
14785c51f124SMoriah Waterland 	}
14795c51f124SMoriah Waterland 
14805c51f124SMoriah Waterland 	/*
14815c51f124SMoriah Waterland 	 * must compare each node of each lock to determine match;
14825c51f124SMoriah Waterland 	 * start off at the first byte of both locks
14835c51f124SMoriah Waterland 	 */
14845c51f124SMoriah Waterland 
14855c51f124SMoriah Waterland 	final1Lock = a_s1Lock;
14865c51f124SMoriah Waterland 	final2Lock = a_s2Lock;
14875c51f124SMoriah Waterland 
14885c51f124SMoriah Waterland 	if ((s1Cnt == 0) && (s2Cnt == 0)) {
14895c51f124SMoriah Waterland 		/* both have first match - start comparison from the begining */
14905c51f124SMoriah Waterland 
14915c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SAME, a_s1Lock, a_s2Lock,
1492708dafbfSAlexander Pyhalov 		    s1Buf);
14935c51f124SMoriah Waterland 
14945c51f124SMoriah Waterland 	} else if ((s1Cnt != 0) && (s2Cnt == 0) && (s2Buf[0] != '\0')) {
14955c51f124SMoriah Waterland 		/* second lock begins somewhere inside of the first lock */
14965c51f124SMoriah Waterland 
14975c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SCNDSUB, a_s2Lock, a_s1Lock,
1498708dafbfSAlexander Pyhalov 		    s1Cnt+1, s1Buf);
14995c51f124SMoriah Waterland 
15005c51f124SMoriah Waterland 		/* advance first lock to matching node in second lock */
15015c51f124SMoriah Waterland 
15025c51f124SMoriah Waterland 		if (strchr(a_s1Lock, '/') != (char *)NULL) {
15035c51f124SMoriah Waterland 			for (; s1Cnt > 0 && (*final1Lock != '\0');
1504708dafbfSAlexander Pyhalov 			    final1Lock++) {
15055c51f124SMoriah Waterland 				if (*final1Lock == '/') {
15065c51f124SMoriah Waterland 					s1Cnt--;
15075c51f124SMoriah Waterland 				}
15085c51f124SMoriah Waterland 			}
15095c51f124SMoriah Waterland 		}
15105c51f124SMoriah Waterland 	} else if ((s2Cnt != 0) && (s1Cnt == 0) && (s1Buf[0] != '\0')) {
15115c51f124SMoriah Waterland 		/* first lock begins somewhere inside of the second lock */
15125c51f124SMoriah Waterland 
15135c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_FRSTSUB, a_s1Lock, a_s2Lock,
1514708dafbfSAlexander Pyhalov 		    s2Cnt+1, s2Buf);
15155c51f124SMoriah Waterland 
15165c51f124SMoriah Waterland 		/* advance second lock to matching node in first lock */
15175c51f124SMoriah Waterland 
15185c51f124SMoriah Waterland 		if (strchr(a_s2Lock, '/') != (char *)NULL) {
15195c51f124SMoriah Waterland 			for (; s2Cnt > 0 && (*final2Lock != '\0');
1520708dafbfSAlexander Pyhalov 			    final2Lock++) {
15215c51f124SMoriah Waterland 				if (*final2Lock == '/') {
15225c51f124SMoriah Waterland 					s2Cnt--;
15235c51f124SMoriah Waterland 				}
15245c51f124SMoriah Waterland 			}
15255c51f124SMoriah Waterland 		}
15265c51f124SMoriah Waterland 	} else {
15275c51f124SMoriah Waterland 		/* unknown condition (probably impossible): directly compare */
15285c51f124SMoriah Waterland 
15295c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LCKMCH_DONTKNOW, a_s1Lock, a_s2Lock);
15305c51f124SMoriah Waterland 	}
15315c51f124SMoriah Waterland 
15325c51f124SMoriah Waterland 	/*
15335c51f124SMoriah Waterland 	 * locks have common node - compare from that node forward
15345c51f124SMoriah Waterland 	 */
15355c51f124SMoriah Waterland 
15365c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_READY, final1Lock, final2Lock);
15375c51f124SMoriah Waterland 
15385c51f124SMoriah Waterland 	/* compare each node (prefix) - success when no more nodes to compare */
15395c51f124SMoriah Waterland 
15405c51f124SMoriah Waterland 	for (s1Cnt = 0; ; s1Cnt++) {
15415c51f124SMoriah Waterland 		/* get next node from first lock */
15425c51f124SMoriah Waterland 
15435c51f124SMoriah Waterland 		pkgstrGetToken_r((char *)NULL, final1Lock, s1Cnt, "/", s1Buf,
1544708dafbfSAlexander Pyhalov 		    sizeof (s1Buf));
15455c51f124SMoriah Waterland 
15465c51f124SMoriah Waterland 		/* success if at end of lock */
15475c51f124SMoriah Waterland 
15485c51f124SMoriah Waterland 		if (s1Buf[0] == '\0') {
15495c51f124SMoriah Waterland 			break;
15505c51f124SMoriah Waterland 		}
15515c51f124SMoriah Waterland 
15525c51f124SMoriah Waterland 		/* get next node from second lock */
15535c51f124SMoriah Waterland 
15545c51f124SMoriah Waterland 		pkgstrGetToken_r((char *)NULL, final2Lock, s1Cnt, "/", s2Buf,
1555708dafbfSAlexander Pyhalov 		    sizeof (s2Buf));
15565c51f124SMoriah Waterland 
15575c51f124SMoriah Waterland 		/* success if at end of lock */
15585c51f124SMoriah Waterland 
15595c51f124SMoriah Waterland 		if (s2Buf[0] == '\0') {
15605c51f124SMoriah Waterland 			break;
15615c51f124SMoriah Waterland 		}
15625c51f124SMoriah Waterland 
15635c51f124SMoriah Waterland 		/* compare both nodes */
15645c51f124SMoriah Waterland 
15655c51f124SMoriah Waterland 		result = fnmatch(s1Buf, s2Buf, 0);
15665c51f124SMoriah Waterland 		if (result != 0) {
15675c51f124SMoriah Waterland 			result = fnmatch(s2Buf, s1Buf, 0);
15685c51f124SMoriah Waterland 		}
15695c51f124SMoriah Waterland 
15705c51f124SMoriah Waterland 		/* failure if nodes do not match */
15715c51f124SMoriah Waterland 
15725c51f124SMoriah Waterland 		if (result != 0) {
15735c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_NODEFAIL,
1574708dafbfSAlexander Pyhalov 			    s1Cnt, s1Buf, s2Buf);
15755c51f124SMoriah Waterland 			return (1);
15765c51f124SMoriah Waterland 		}
15775c51f124SMoriah Waterland 
15785c51f124SMoriah Waterland 		/* nodes match, continue and compare next set of nodes */
15795c51f124SMoriah Waterland 
15805c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_NODEOK, s1Cnt, s1Buf, s2Buf);
15815c51f124SMoriah Waterland 	}
15825c51f124SMoriah Waterland 
15835c51f124SMoriah Waterland 	/* no more nodes to compare - locks match */
15845c51f124SMoriah Waterland 
15855c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_MATCHOK, final1Lock, final2Lock);
15865c51f124SMoriah Waterland 
15875c51f124SMoriah Waterland 	return (0);
15885c51f124SMoriah Waterland }
15895c51f124SMoriah Waterland 
15905c51f124SMoriah Waterland /*
15915c51f124SMoriah Waterland  * Name:	_findLock
15925c51f124SMoriah Waterland  * Description:	Locate specified lock in lock file
15935c51f124SMoriah Waterland  * Arguments:
15945c51f124SMoriah Waterland  *	a_theLock - lock object filled with contents of lock (if found)
15955c51f124SMoriah Waterland  *	r_recordNum - will contain record number if lock found
15965c51f124SMoriah Waterland  *		- will be RECORDNUM_NONE if lock not found
15975c51f124SMoriah Waterland  *	a_fd - file descriptor opened on the lock file
15985c51f124SMoriah Waterland  *	a_key - key associated with lock to look up
15995c51f124SMoriah Waterland  *	a_object - object associated with lock to look up
16005c51f124SMoriah Waterland  * Returns:
16015c51f124SMoriah Waterland  *	FINDLOCK_FOUND - specified lock found; a_theLock contains contents
16025c51f124SMoriah Waterland  *		of found lock, r_recordNum contain record number of lock
16035c51f124SMoriah Waterland  *	FINDLOCK_ERROR - failed - error occurred looking up the lock
16045c51f124SMoriah Waterland  *	FINDLOCK_NOTFOUND - specified object is not locked
16055c51f124SMoriah Waterland  *	FINDLOCK_KEYMISMATCH - object lock found but specified key doesnt match
16065c51f124SMoriah Waterland  *	FINDLOCK_LOCKED - object lock found but no key specified
16075c51f124SMoriah Waterland  *	FINDLOCK_NOTLOCKED - object not locked
16085c51f124SMoriah Waterland  */
16095c51f124SMoriah Waterland 
16105c51f124SMoriah Waterland static FINDLOCK_T
_findLock(LOCK_T * a_theLock,RECORDNUM_T * r_recordNum,int a_fd,char * a_object,char * a_key)16115c51f124SMoriah Waterland _findLock(LOCK_T *a_theLock, RECORDNUM_T *r_recordNum,
1612708dafbfSAlexander Pyhalov     int a_fd, char *a_object, char *a_key)
16135c51f124SMoriah Waterland {
16145c51f124SMoriah Waterland 	ADMINLOCK_T	*pll;
16155c51f124SMoriah Waterland 	char		*pld;
16165c51f124SMoriah Waterland 	int		recordNum = 0;
16175c51f124SMoriah Waterland 	long		pls;
16185c51f124SMoriah Waterland 	off_t		pos;
16195c51f124SMoriah Waterland 
16205c51f124SMoriah Waterland 	/* reset returned record number to "none" */
16215c51f124SMoriah Waterland 
16225c51f124SMoriah Waterland 	*r_recordNum = RECORDNUM_NONE;
16235c51f124SMoriah Waterland 
16245c51f124SMoriah Waterland 	/* localize references to lock object */
16255c51f124SMoriah Waterland 
16265c51f124SMoriah Waterland 	pld = &a_theLock->_lrLockData[0];
16275c51f124SMoriah Waterland 	pll = &a_theLock->_lrLock;
16285c51f124SMoriah Waterland 	pls = sizeof (a_theLock->_lrLockData);
16295c51f124SMoriah Waterland 
16305c51f124SMoriah Waterland 	/* zero out returned lock data */
16315c51f124SMoriah Waterland 
16325c51f124SMoriah Waterland 	bzero(pld, pls);
16335c51f124SMoriah Waterland 
16345c51f124SMoriah Waterland 	/* debug info before processing lock file */
16355c51f124SMoriah Waterland 
16365c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_ENTRY,
1637708dafbfSAlexander Pyhalov 	    a_object, a_key);
16385c51f124SMoriah Waterland 
16395c51f124SMoriah Waterland 	/* rewind to beginning of lock file */
16405c51f124SMoriah Waterland 
16415c51f124SMoriah Waterland 	pos = lseek(a_fd, 0L, SEEK_SET);
16425c51f124SMoriah Waterland 	if (pos == (off_t)-1) {
16435c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_FINDLOCK_LSEEK_FAILURE,
1644708dafbfSAlexander Pyhalov 		    a_object, a_key, strerror(errno));
16455c51f124SMoriah Waterland 		return (FINDLOCK_ERROR);
16465c51f124SMoriah Waterland 	}
16475c51f124SMoriah Waterland 
16485c51f124SMoriah Waterland 	/* read and process each lock */
16495c51f124SMoriah Waterland 
16505c51f124SMoriah Waterland 	for (; pread(a_fd, pld, pls, pls*recordNum) == pls; recordNum++) {
16515c51f124SMoriah Waterland 		/* debug info on this lock */
16525c51f124SMoriah Waterland 
16535c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_READRECORD,
1654708dafbfSAlexander Pyhalov 		    recordNum, pll->lockCount,
1655708dafbfSAlexander Pyhalov 		    pll->lockObject, pll->lockKey, pll->lockPid,
1656708dafbfSAlexander Pyhalov 		    pll->lockZoneId);
16575c51f124SMoriah Waterland 
16585c51f124SMoriah Waterland 		/* continue if object is not the one we are looking for */
16595c51f124SMoriah Waterland 
16605c51f124SMoriah Waterland 		if (_lockMatch(a_object, pll->lockObject) != 0) {
16615c51f124SMoriah Waterland 			continue;
16625c51f124SMoriah Waterland 		}
16635c51f124SMoriah Waterland 
16645c51f124SMoriah Waterland 		/*
16655c51f124SMoriah Waterland 		 * object found; return locked if searching for no key
16665c51f124SMoriah Waterland 		 */
16675c51f124SMoriah Waterland 
16685c51f124SMoriah Waterland 		if (*a_key == '\0') {
16695c51f124SMoriah Waterland 			/* no key specified - object is locked */
16705c51f124SMoriah Waterland 			*r_recordNum = recordNum;
16715c51f124SMoriah Waterland 			return (FINDLOCK_LOCKED);
16725c51f124SMoriah Waterland 		}
16735c51f124SMoriah Waterland 
16745c51f124SMoriah Waterland 		/*
16755c51f124SMoriah Waterland 		 * object found and keys present; see if keys match
16765c51f124SMoriah Waterland 		 */
16775c51f124SMoriah Waterland 
16785c51f124SMoriah Waterland 		if (strcmp(pll->lockKey, a_key) != 0) {
16795c51f124SMoriah Waterland 			/* keys do not match */
16805c51f124SMoriah Waterland 			*r_recordNum = recordNum;
16815c51f124SMoriah Waterland 			return (FINDLOCK_KEYMISMATCH);
16825c51f124SMoriah Waterland 		}
16835c51f124SMoriah Waterland 
16845c51f124SMoriah Waterland 		/* object found and keys match - return match */
16855c51f124SMoriah Waterland 
16865c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_FOUND);
16875c51f124SMoriah Waterland 
16885c51f124SMoriah Waterland 		*r_recordNum = recordNum;
16895c51f124SMoriah Waterland 		return (FINDLOCK_FOUND);
16905c51f124SMoriah Waterland 	}
16915c51f124SMoriah Waterland 
16925c51f124SMoriah Waterland 	/* object not locked - return error if key supplied */
16935c51f124SMoriah Waterland 
16945c51f124SMoriah Waterland 	if (*a_key != '\0') {
16955c51f124SMoriah Waterland 		return (FINDLOCK_NOTLOCKED);
16965c51f124SMoriah Waterland 	}
16975c51f124SMoriah Waterland 
16985c51f124SMoriah Waterland 	/* object not locked and key not supplied - no lock found */
16995c51f124SMoriah Waterland 
17005c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_NOTFOUND);
17015c51f124SMoriah Waterland 
17025c51f124SMoriah Waterland 	return (FINDLOCK_NOTFOUND);
17035c51f124SMoriah Waterland }
17045c51f124SMoriah Waterland 
17055c51f124SMoriah Waterland /*
17065c51f124SMoriah Waterland  * Name:	_addLock
17075c51f124SMoriah Waterland  * Description:	Add a new lock to the lock file
17085c51f124SMoriah Waterland  * Arguments:
17095c51f124SMoriah Waterland  *	r_key - if lock acquired key is placed here
17105c51f124SMoriah Waterland  *	a_fd - file descriptor opened on the lock file
17115c51f124SMoriah Waterland  *	a_object - object to lock
17125c51f124SMoriah Waterland  *	a_exclusive - type of lock to add:
17135c51f124SMoriah Waterland  *		== 0 - shared lock
17145c51f124SMoriah Waterland  *		!= 0 - exclusive lock
17155c51f124SMoriah Waterland  *	a_pid - if != 0 process i.d. to associate with this lock
17165c51f124SMoriah Waterland  *	a_zid - if >= 0 zone i.d. to associate with this lock
17175c51f124SMoriah Waterland  * Returns:	int
17185c51f124SMoriah Waterland  *			== 0 - success
17195c51f124SMoriah Waterland  *			!= 0 - failure
17205c51f124SMoriah Waterland  */
17215c51f124SMoriah Waterland 
17225c51f124SMoriah Waterland static int
_addLock(char * r_key,int a_fd,char * a_object,int a_exclusive,pid_t a_pid,zoneid_t a_zid)17235c51f124SMoriah Waterland _addLock(char *r_key, int a_fd, char *a_object, int a_exclusive, pid_t a_pid,
1724708dafbfSAlexander Pyhalov     zoneid_t a_zid)
17255c51f124SMoriah Waterland {
17265c51f124SMoriah Waterland 	LOCK_T	theLock;
17275c51f124SMoriah Waterland 	char	*key;
17285c51f124SMoriah Waterland 	off_t	pos;
17295c51f124SMoriah Waterland 	ssize_t	result;
17305c51f124SMoriah Waterland 
17315c51f124SMoriah Waterland 	/* get unique i.d. for this lock */
17325c51f124SMoriah Waterland 
17335c51f124SMoriah Waterland 	key = _getUniqueId();
17345c51f124SMoriah Waterland 
17355c51f124SMoriah Waterland 	/* determine record number for next record in lock file */
17365c51f124SMoriah Waterland 
17375c51f124SMoriah Waterland 	pos = lseek(a_fd, 0L, SEEK_END);
17385c51f124SMoriah Waterland 	if (pos == (off_t)-1) {
17395c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_ADDLOCK_LSEEK_FAILURE,
1740708dafbfSAlexander Pyhalov 		    a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
1741708dafbfSAlexander Pyhalov 		    a_object, strerror(errno));
17425c51f124SMoriah Waterland 		return (1);
17435c51f124SMoriah Waterland 	}
17445c51f124SMoriah Waterland 
17455c51f124SMoriah Waterland 	/* allocate storace for this lock */
17465c51f124SMoriah Waterland 
17475c51f124SMoriah Waterland 	bzero(&theLock, sizeof (theLock));
17485c51f124SMoriah Waterland 
17495c51f124SMoriah Waterland 	/* fill in components of the lock */
17505c51f124SMoriah Waterland 
17515c51f124SMoriah Waterland 	(void) strlcpy(theLock._lrLock.lockObject, a_object,
1752708dafbfSAlexander Pyhalov 	    LOCK_OBJECT_MAXLEN);
17535c51f124SMoriah Waterland 	(void) strlcpy(theLock._lrLock.lockKey, key, LOCK_KEY_MAXLEN);
17545c51f124SMoriah Waterland 	theLock._lrLock.lockCount = 1;
17555c51f124SMoriah Waterland 	theLock._lrLock.lockPid = (a_pid > 0 ? a_pid : 0);
17565c51f124SMoriah Waterland 	theLock._lrLock.lockRecordNum = (pos == 0 ? 0 : (pos/sizeof (LOCK_T)));
17575c51f124SMoriah Waterland 	theLock._lrLock.lockExclusive = a_exclusive;
17585c51f124SMoriah Waterland 	theLock._lrLock.lockZoneId = (a_zid >= 0 ? a_zid : -1);
17595c51f124SMoriah Waterland 
17605c51f124SMoriah Waterland 	/* debug info on new lock */
17615c51f124SMoriah Waterland 
17625c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_ADDLOCK_ADDING,
1763708dafbfSAlexander Pyhalov 	    a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
1764708dafbfSAlexander Pyhalov 	    pos, theLock._lrLock.lockObject, theLock._lrLock.lockKey,
1765708dafbfSAlexander Pyhalov 	    theLock._lrLock.lockPid, theLock._lrLock.lockZoneId);
17665c51f124SMoriah Waterland 
17675c51f124SMoriah Waterland 	/* write the new lock record to the end of the lock file */
17685c51f124SMoriah Waterland 
17695c51f124SMoriah Waterland 	result = pwrite(a_fd, &theLock, LOCK_SIZE, pos);
17705c51f124SMoriah Waterland 	if (result != LOCK_SIZE) {
17715c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_ADDLOCK_PWRITE_FAILURE,
1772708dafbfSAlexander Pyhalov 		    a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
1773708dafbfSAlexander Pyhalov 		    a_object, strerror(errno));
17745c51f124SMoriah Waterland 		return (1);
17755c51f124SMoriah Waterland 	}
17765c51f124SMoriah Waterland 
17775c51f124SMoriah Waterland 	/* output the key assigned to standard out */
17785c51f124SMoriah Waterland 
17795c51f124SMoriah Waterland 	(void) strncpy(r_key, key, LOCK_KEY_MAXLEN);
17805c51f124SMoriah Waterland 
17815c51f124SMoriah Waterland 	return (0);
17825c51f124SMoriah Waterland }
17835c51f124SMoriah Waterland 
17845c51f124SMoriah Waterland static int
_incrementLockCount(int a_fd,LOCK_T * a_theLock)17855c51f124SMoriah Waterland _incrementLockCount(int a_fd, LOCK_T *a_theLock)
17865c51f124SMoriah Waterland {
17875c51f124SMoriah Waterland 	ADMINLOCK_T	*pll;
17885c51f124SMoriah Waterland 	char		*pld;
17895c51f124SMoriah Waterland 	long		pls;
17905c51f124SMoriah Waterland 	ssize_t		result;
17915c51f124SMoriah Waterland 
17925c51f124SMoriah Waterland 	/* localize references to lock object */
17935c51f124SMoriah Waterland 
17945c51f124SMoriah Waterland 	pld = &a_theLock->_lrLockData[0];
17955c51f124SMoriah Waterland 	pll = &a_theLock->_lrLock;
17965c51f124SMoriah Waterland 	pls = sizeof (a_theLock->_lrLockData);
17975c51f124SMoriah Waterland 
17985c51f124SMoriah Waterland 	/* debug info on incrementing lock */
17995c51f124SMoriah Waterland 
18005c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_INCLOCK_ENTRY,
1801708dafbfSAlexander Pyhalov 	    a_theLock->_lrLock.lockExclusive ?
1802708dafbfSAlexander Pyhalov 	    MSG_LOCK_EXC : MSG_LOCK_SHR,
1803708dafbfSAlexander Pyhalov 	    pll->lockRecordNum, pll->lockCount);
18045c51f124SMoriah Waterland 
18055c51f124SMoriah Waterland 	/* increment lock count */
18065c51f124SMoriah Waterland 
18075c51f124SMoriah Waterland 	pll->lockCount++;
18085c51f124SMoriah Waterland 
18095c51f124SMoriah Waterland 	/* write out updated lock */
18105c51f124SMoriah Waterland 
18115c51f124SMoriah Waterland 	result = pwrite(a_fd, pld, pls, pll->lockRecordNum*pls);
18125c51f124SMoriah Waterland 	if (result != pls) {
18135c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_INCLOCK_PWRITE_FAILURE,
1814708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockExclusive ?
1815708dafbfSAlexander Pyhalov 		    MSG_LOCK_EXC : MSG_LOCK_SHR,
1816708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockObject,
1817708dafbfSAlexander Pyhalov 		    strerror(errno));
18185c51f124SMoriah Waterland 		return (1);
18195c51f124SMoriah Waterland 	}
18205c51f124SMoriah Waterland 
18215c51f124SMoriah Waterland 	/* debug info lock incremented */
18225c51f124SMoriah Waterland 
18235c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_INCLOCK_DONE,
1824708dafbfSAlexander Pyhalov 	    pll->lockRecordNum, pll->lockCount,
1825708dafbfSAlexander Pyhalov 	    pll->lockObject, pll->lockKey);
18265c51f124SMoriah Waterland 
18275c51f124SMoriah Waterland 	return (0);
18285c51f124SMoriah Waterland }
18295c51f124SMoriah Waterland 
18305c51f124SMoriah Waterland /*
18315c51f124SMoriah Waterland  * Name:	_validateLock
18325c51f124SMoriah Waterland  * Description:	determine if a specified lock is valid; if the lock is not valid
18335c51f124SMoriah Waterland  *		then remove the lock
18345c51f124SMoriah Waterland  * Arguments:	a_fd - file descriptor opened on the lock file
18355c51f124SMoriah Waterland  *		a_theLock - lock object to validate
18365c51f124SMoriah Waterland  * Returns:	boolean_t
18375c51f124SMoriah Waterland  *			B_TRUE - the lock is valid
18385c51f124SMoriah Waterland  *			B_FALSE - the lock is not valid and has been removed
18395c51f124SMoriah Waterland  */
18405c51f124SMoriah Waterland 
18415c51f124SMoriah Waterland static boolean_t
_validateLock(int a_fd,LOCK_T * a_theLock,int a_quiet)18425c51f124SMoriah Waterland _validateLock(int a_fd, LOCK_T *a_theLock, int a_quiet)
18435c51f124SMoriah Waterland {
18445c51f124SMoriah Waterland 	ADMINLOCK_T	*pll;
18455c51f124SMoriah Waterland 	char		path[MAXPATHLEN];
18465c51f124SMoriah Waterland 
18475c51f124SMoriah Waterland 	/* localize references to lock object */
18485c51f124SMoriah Waterland 
18495c51f124SMoriah Waterland 	pll = &a_theLock->_lrLock;
18505c51f124SMoriah Waterland 
18515c51f124SMoriah Waterland 	/* return true if no process i.d. associated with lock */
18525c51f124SMoriah Waterland 
18535c51f124SMoriah Waterland 	if (pll->lockPid <= 0) {
18545c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_VALID_NOPID, pll->lockObject);
18555c51f124SMoriah Waterland 		return (B_TRUE);
18565c51f124SMoriah Waterland 	}
18575c51f124SMoriah Waterland 
18585c51f124SMoriah Waterland 	/* see if the zone i.d. matches */
18595c51f124SMoriah Waterland 
18605c51f124SMoriah Waterland 	if (pll->lockZoneId != getzoneid()) {
18615c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_VALID_BADZID, pll->lockObject,
1862708dafbfSAlexander Pyhalov 		    pll->lockZoneId, getzoneid());
18635c51f124SMoriah Waterland 		return (B_TRUE);
18645c51f124SMoriah Waterland 	} else {
18655c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_VALID_ZIDOK, pll->lockObject,
1866708dafbfSAlexander Pyhalov 		    pll->lockZoneId, getzoneid());
18675c51f124SMoriah Waterland 	}
18685c51f124SMoriah Waterland 
18695c51f124SMoriah Waterland 	/* see if the process is still active */
18705c51f124SMoriah Waterland 
18715c51f124SMoriah Waterland 	pkgstrPrintf_r(path, sizeof (path), "/proc/%d", pll->lockPid);
18725c51f124SMoriah Waterland 	if (access(path, F_OK) == 0) {
18735c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_VALID_OK, pll->lockObject,
1874708dafbfSAlexander Pyhalov 		    pll->lockPid, path);
18755c51f124SMoriah Waterland 		return (B_TRUE);
18765c51f124SMoriah Waterland 	}
18775c51f124SMoriah Waterland 
18785c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_VALID_NOTOK, pll->lockObject, pll->lockPid,
1879708dafbfSAlexander Pyhalov 	    path);
18805c51f124SMoriah Waterland 
18815c51f124SMoriah Waterland 	/* delete this lock */
18825c51f124SMoriah Waterland 
18835c51f124SMoriah Waterland 	log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_WRN,
1884708dafbfSAlexander Pyhalov 	    MSG_VALID_STALE, pll->lockObject, pll->lockPid,
1885708dafbfSAlexander Pyhalov 	    pll->lockZoneId);
18865c51f124SMoriah Waterland 
18875c51f124SMoriah Waterland 	_decrementLockCount(a_fd, a_theLock);
18885c51f124SMoriah Waterland 
18895c51f124SMoriah Waterland 	return (B_FALSE);
18905c51f124SMoriah Waterland }
18915c51f124SMoriah Waterland 
18925c51f124SMoriah Waterland static int
_decrementLockCount(int a_fd,LOCK_T * a_theLock)18935c51f124SMoriah Waterland _decrementLockCount(int a_fd, LOCK_T *a_theLock)
18945c51f124SMoriah Waterland {
18955c51f124SMoriah Waterland 	ADMINLOCK_T	*pll;
18965c51f124SMoriah Waterland 	LOCK_T		tmpLock;
18975c51f124SMoriah Waterland 	RECORDNUM_T	lastRecord;
18985c51f124SMoriah Waterland 	char		*pld;
18995c51f124SMoriah Waterland 	long		pls;
19005c51f124SMoriah Waterland 	off_t		lastPos;
19015c51f124SMoriah Waterland 	ssize_t		result;
19025c51f124SMoriah Waterland 	int		res;
19035c51f124SMoriah Waterland 
19045c51f124SMoriah Waterland 	/* localize references to lock object */
19055c51f124SMoriah Waterland 
19065c51f124SMoriah Waterland 	pld = &a_theLock->_lrLockData[0];
19075c51f124SMoriah Waterland 	pll = &a_theLock->_lrLock;
19085c51f124SMoriah Waterland 	pls = sizeof (a_theLock->_lrLockData);
19095c51f124SMoriah Waterland 
19105c51f124SMoriah Waterland 	/* decrement lock count */
19115c51f124SMoriah Waterland 
19125c51f124SMoriah Waterland 	pll->lockCount--;
19135c51f124SMoriah Waterland 
19145c51f124SMoriah Waterland 	/* if lock count > 0 then write out and leave locked */
19155c51f124SMoriah Waterland 
19165c51f124SMoriah Waterland 	if (pll->lockCount > 0) {
19175c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_DECING,
1918708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockExclusive ?
1919708dafbfSAlexander Pyhalov 		    MSG_LOCK_EXC : MSG_LOCK_SHR,
1920708dafbfSAlexander Pyhalov 		    pll->lockRecordNum, pll->lockCount);
19215c51f124SMoriah Waterland 
19225c51f124SMoriah Waterland 		result = pwrite(a_fd, pld, pls, pll->lockRecordNum*pls);
19235c51f124SMoriah Waterland 		if (result != pls) {
19245c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_PWRITE_FAILURE,
1925708dafbfSAlexander Pyhalov 			    a_theLock->_lrLock.lockExclusive ?
1926708dafbfSAlexander Pyhalov 			    MSG_LOCK_EXC : MSG_LOCK_SHR,
1927708dafbfSAlexander Pyhalov 			    a_theLock->_lrLock.lockObject,
1928708dafbfSAlexander Pyhalov 			    strerror(errno));
19295c51f124SMoriah Waterland 			return (1);
19305c51f124SMoriah Waterland 		}
19315c51f124SMoriah Waterland 
19325c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_DONE,
1933708dafbfSAlexander Pyhalov 		    pll->lockRecordNum, pll->lockCount,
1934708dafbfSAlexander Pyhalov 		    pll->lockObject, pll->lockKey);
19355c51f124SMoriah Waterland 
19365c51f124SMoriah Waterland 		return (0);
19375c51f124SMoriah Waterland 	}
19385c51f124SMoriah Waterland 
19395c51f124SMoriah Waterland 	/*
19405c51f124SMoriah Waterland 	 * lock count zero - erase the record
19415c51f124SMoriah Waterland 	 */
19425c51f124SMoriah Waterland 
19435c51f124SMoriah Waterland 	/* find last record in the lock file */
19445c51f124SMoriah Waterland 
19455c51f124SMoriah Waterland 	lastPos = lseek(a_fd, 0L, SEEK_END);	/* get size of lock file */
19465c51f124SMoriah Waterland 	if (lastPos == (off_t)-1) {
19475c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_LSEEK_FAILURE,
1948708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockExclusive ?
1949708dafbfSAlexander Pyhalov 		    MSG_LOCK_EXC : MSG_LOCK_SHR,
1950708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockObject,
1951708dafbfSAlexander Pyhalov 		    strerror(errno));
19525c51f124SMoriah Waterland 		return (1);
19535c51f124SMoriah Waterland 	}
19545c51f124SMoriah Waterland 
19555c51f124SMoriah Waterland 	lastRecord = (lastPos/pls)-1;	/* convert size to record # */
19565c51f124SMoriah Waterland 
19575c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_REMOVE,
1958708dafbfSAlexander Pyhalov 	    lastPos, lastRecord, pll->lockRecordNum);
19595c51f124SMoriah Waterland 
19605c51f124SMoriah Waterland 	/* see if removing last record of file */
19615c51f124SMoriah Waterland 
19625c51f124SMoriah Waterland 	if (lastRecord == pll->lockRecordNum) {
19635c51f124SMoriah Waterland 		/* debug info removing last record */
19645c51f124SMoriah Waterland 
19655c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_LASTONE,
1966708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockExclusive ?
1967708dafbfSAlexander Pyhalov 		    MSG_LOCK_EXC : MSG_LOCK_SHR,
1968708dafbfSAlexander Pyhalov 		    lastRecord, lastPos-pls);
19695c51f124SMoriah Waterland 
19705c51f124SMoriah Waterland 		/* removing last record of file, truncate */
19715c51f124SMoriah Waterland 
19725c51f124SMoriah Waterland 		res = ftruncate(a_fd, lastPos-pls);
19735c51f124SMoriah Waterland 		if (res == -1) {
19745c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_FTRUNCATE_FAILURE,
1975708dafbfSAlexander Pyhalov 			    a_theLock->_lrLock.lockExclusive ?
1976708dafbfSAlexander Pyhalov 			    MSG_LOCK_EXC : MSG_LOCK_SHR,
1977708dafbfSAlexander Pyhalov 			    a_theLock->_lrLock.lockObject,
1978708dafbfSAlexander Pyhalov 			    strerror(errno));
1979708dafbfSAlexander Pyhalov 			return (1);
19805c51f124SMoriah Waterland 		}
19815c51f124SMoriah Waterland 		return (0);
19825c51f124SMoriah Waterland 	}
19835c51f124SMoriah Waterland 
19845c51f124SMoriah Waterland 	/*
19855c51f124SMoriah Waterland 	 * not removing last record of file:
19865c51f124SMoriah Waterland 	 * read last record, truncate file one record,
19875c51f124SMoriah Waterland 	 * replace record to be removed with last record read
19885c51f124SMoriah Waterland 	 */
19895c51f124SMoriah Waterland 
19905c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_REMOVING,
1991708dafbfSAlexander Pyhalov 	    pll->lockRecordNum, lastRecord, lastPos-pls);
19925c51f124SMoriah Waterland 
19935c51f124SMoriah Waterland 	/* read in the last record */
19945c51f124SMoriah Waterland 
19955c51f124SMoriah Waterland 	result = pread(a_fd, tmpLock._lrLockData, pls, lastRecord*pls);
19965c51f124SMoriah Waterland 	if (result != pls) {
19975c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_PREAD_FAILURE,
1998708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockExclusive ?
1999708dafbfSAlexander Pyhalov 		    MSG_LOCK_EXC : MSG_LOCK_SHR,
2000708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockObject,
2001708dafbfSAlexander Pyhalov 		    strerror(errno));
20025c51f124SMoriah Waterland 		return (1);
20035c51f124SMoriah Waterland 
20045c51f124SMoriah Waterland 	}
20055c51f124SMoriah Waterland 
20065c51f124SMoriah Waterland 	/* truncate lock file removing the last record (just read in) */
20075c51f124SMoriah Waterland 
20085c51f124SMoriah Waterland 	res = ftruncate(a_fd, lastPos-pls);
20095c51f124SMoriah Waterland 	if (res == -1) {
20105c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_FTRUNCATE_FAILURE,
2011708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockExclusive ?
2012708dafbfSAlexander Pyhalov 		    MSG_LOCK_EXC : MSG_LOCK_SHR,
2013708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockObject,
2014708dafbfSAlexander Pyhalov 		    strerror(errno));
20155c51f124SMoriah Waterland 			return (1);
20165c51f124SMoriah Waterland 	}
20175c51f124SMoriah Waterland 
20185c51f124SMoriah Waterland 	/* update record to indicate its new position in the lock file */
20195c51f124SMoriah Waterland 
20205c51f124SMoriah Waterland 	tmpLock._lrLock.lockRecordNum = pll->lockRecordNum;
20215c51f124SMoriah Waterland 
20225c51f124SMoriah Waterland 	/* write out the updated record to the new location */
20235c51f124SMoriah Waterland 
20245c51f124SMoriah Waterland 	result = pwrite(a_fd, tmpLock._lrLockData, pls, pll->lockRecordNum*pls);
20255c51f124SMoriah Waterland 	if (result != pls) {
20265c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_PWRITE_FAILURE,
2027708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockExclusive ?
2028708dafbfSAlexander Pyhalov 		    MSG_LOCK_EXC : MSG_LOCK_SHR,
2029708dafbfSAlexander Pyhalov 		    a_theLock->_lrLock.lockObject,
2030708dafbfSAlexander Pyhalov 		    strerror(errno));
20315c51f124SMoriah Waterland 		return (1);
20325c51f124SMoriah Waterland 	}
20335c51f124SMoriah Waterland 
20345c51f124SMoriah Waterland 	return (0);
20355c51f124SMoriah Waterland }
20365c51f124SMoriah Waterland 
20375c51f124SMoriah Waterland /*
20385c51f124SMoriah Waterland  * Name:	_getUniqueId
20395c51f124SMoriah Waterland  * Description:	Generate a unique ID that can be used as a key for a new lock
20405c51f124SMoriah Waterland  * Arguments:	None
20415c51f124SMoriah Waterland  * Returns:	char *
20425c51f124SMoriah Waterland  *			== NULL - error, no key generated
20435c51f124SMoriah Waterland  *			!= NULL - generated key
2044014740deSToomas Soome  * NOTE:	Any results returned is placed in new storage for the
20455c51f124SMoriah Waterland  *		calling method. The caller must use 'lu_memFree' to dispose
20465c51f124SMoriah Waterland  *		of the storage once the results are no longer needed.
20475c51f124SMoriah Waterland  */
20485c51f124SMoriah Waterland 
20495c51f124SMoriah Waterland static char *
_getUniqueId(void)20505c51f124SMoriah Waterland _getUniqueId(void)
20515c51f124SMoriah Waterland {
20525c51f124SMoriah Waterland 	char		newkey[LOCK_KEY_MAXLEN];
20535c51f124SMoriah Waterland 	hrtime_t	hretime;
20545c51f124SMoriah Waterland 	struct tm	tstruct;
20555c51f124SMoriah Waterland 	time_t		thetime;
20565c51f124SMoriah Waterland 
20575c51f124SMoriah Waterland 	/*
2058708dafbfSAlexander Pyhalov 	 * generate own unique key - the key is the
20595c51f124SMoriah Waterland 	 * same length as unique uid but contains different information that
20605c51f124SMoriah Waterland 	 * is as unique as can be made - include current hires time (nanosecond
2061708dafbfSAlexander Pyhalov 	 * real timer). Such a unique i.d. will look like:
2062014740deSToomas Soome 	 *	0203104092-1145345-0004e94d6af481a0
20635c51f124SMoriah Waterland 	 */
20645c51f124SMoriah Waterland 
20655c51f124SMoriah Waterland 	hretime = gethrtime();
20665c51f124SMoriah Waterland 
20675c51f124SMoriah Waterland 	thetime = time((time_t *)NULL);
20685c51f124SMoriah Waterland 	(void) localtime_r(&thetime, &tstruct);
20695c51f124SMoriah Waterland 
20705c51f124SMoriah Waterland 	(void) snprintf(newkey, sizeof (newkey),
2071708dafbfSAlexander Pyhalov 	    "%02d%02d%02d%03d-%02d%02d%02d%d-%016llx", tstruct.tm_mday,
2072708dafbfSAlexander Pyhalov 	    tstruct.tm_mon, tstruct.tm_year, tstruct.tm_yday,
2073708dafbfSAlexander Pyhalov 	    tstruct.tm_hour, tstruct.tm_min, tstruct.tm_sec,
2074708dafbfSAlexander Pyhalov 	    tstruct.tm_wday, hretime);
20755c51f124SMoriah Waterland 
20765c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, MSG_LOCK_GENUID_INTERNAL, newkey);
20775c51f124SMoriah Waterland 	return (strdup(newkey));
20785c51f124SMoriah Waterland }
20795c51f124SMoriah Waterland 
20805c51f124SMoriah Waterland /*
20815c51f124SMoriah Waterland  * Name:	sigint_handler
20825c51f124SMoriah Waterland  * Synopsis:	SIGINT interrupt handler
20835c51f124SMoriah Waterland  * Description:	Catch the "SIGINT" signal; increment signal_received
20845c51f124SMoriah Waterland  *		global variable,
20855c51f124SMoriah Waterland  * Arguments:	signo - [RO, *RO] - (int)
20865c51f124SMoriah Waterland  *			Signal number that was caught
20875c51f124SMoriah Waterland  * Returns:	void
20885c51f124SMoriah Waterland  */
20895c51f124SMoriah Waterland 
20905c51f124SMoriah Waterland static void
sigint_handler(int a_signo)20915c51f124SMoriah Waterland sigint_handler(int a_signo)
20925c51f124SMoriah Waterland {
20935c51f124SMoriah Waterland 	signal_received++;
20945c51f124SMoriah Waterland }
20955c51f124SMoriah Waterland 
20965c51f124SMoriah Waterland /*
20975c51f124SMoriah Waterland  * Name:	sighup_handler
20985c51f124SMoriah Waterland  * Synopsis:	SIGHUP interrupt handler
20995c51f124SMoriah Waterland  * Description:	Catch the "SIGHUP" signal; increment signal_received
21005c51f124SMoriah Waterland  *		global variable,
21015c51f124SMoriah Waterland  * Arguments:	signo - [RO, *RO] - (int)
21025c51f124SMoriah Waterland  *			Signal number that was caught
21035c51f124SMoriah Waterland  * Returns:	void
21045c51f124SMoriah Waterland  */
21055c51f124SMoriah Waterland 
21065c51f124SMoriah Waterland static void
sighup_handler(int a_signo)21075c51f124SMoriah Waterland sighup_handler(int a_signo)
21085c51f124SMoriah Waterland {
21095c51f124SMoriah Waterland 	signal_received++;
21105c51f124SMoriah Waterland }
2111