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