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