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