5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER START
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The contents of this file are subject to the terms of the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Common Development and Distribution License (the "License").
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You may not use this file except in compliance with the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * or http://www.opensolaris.org/os/licensing.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * See the License for the specific language governing permissions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and limitations under the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If applicable, add the following below this CDDL HEADER, with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER END
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Program: pkgadm (/usr/bin/pkgadm)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Synopsis: implements the zone/package administrative lock interface
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Public methods:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Acquire: -a [ -e | -s ] [ -o obj ] [ -k key ] [ -R root ] [ -q ] \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * [ -w ] [ -W timeout ]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Release: -r -o object -k key [ -R altRoot ] [ -q ]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Status: [ -o object ] [ -k key ] [ -R altRoot ] [ -q ]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* enable extentions to standard Unix libraries */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* unix system includes */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* local includes */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* definition and conversion of sleep units */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MINUTES(x) ((unsigned int)(seconds(x)*60))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* define how waits are timed */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The administrative lock file resides in /tmp
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * It does not survive a reboot
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * It consists of fixed length records
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Each record has the following information:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * record number - record position within the lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * lock count - number of lock holders maintaining this lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * lock object - object being locked
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * lock key - key needed to manipulate existing lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * lock exclusive - is the lock exclusive (single locker only)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * this is the "well known name" of the lock file that is used by the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * package, patch, and zone administration commands to synchronize their
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * various efforts - it must live in a temporary directory that is cleared
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * on system reboot but it is NOT a temporary file in that it survives
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the process that creates and updates it - if the format of the lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file ever changes, this path should be updated with a later "uuid"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * so that previous (incompatible) pkgadm's will not use the later data.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "/tmp/.ai.pkg.zone.lock-afdb66cf-1dd1-11b2-a049-000d560ddc3e"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* mode to use for LOCK_FILENAME */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (S_ISGID|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* lock contents types */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* actual lock data */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* size of an individual "lock" */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* union to allow lock to be accessed as raw or structured data */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* return codes from "_findLock" */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define FINDLOCK_KEYMISMATCH ((FINDLOCK_T)-3)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define FINDLOCK_LOCKACQUIRED ((FINDLOCK_T)-6)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Forward declarations
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* local main function implementation methods */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic FINDLOCK_T lock_acquire(LOCK_T *a_lock, int *a_fd, char *a_root,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int a_wait, long a_timeout, int a_exclusive,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *a_altRoot, pid_t a_pid, zoneid_t a_zid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int lock_release(int a_fd, char *a_key, char *a_object,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int lock_status(int a_fd, char *a_key, char *a_object,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* local utility functions */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int _lockMatch(char *a_s1Lock, char *a_s2Lock);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic FINDLOCK_T _findLock(LOCK_T *a_theLock, RECORDNUM_T *r_recordNum,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int _decrementLockCount(int a_fd, LOCK_T *a_theLock);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int _addLock(char *r_key, int a_fd, char *a_object,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int a_exclusive, pid_t a_pid, zoneid_t a_zid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int _incrementLockCount(int a_fd, LOCK_T *a_theLock);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic FINDLOCK_T _lock_acquire(LOCK_T *a_lock, int a_fd, char *a_key,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *a_object, int a_quiet, int a_exclusive,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *_getUniqueId(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic boolean_t _validateLock(int a_fd, LOCK_T *a_theLock, int a_quiet);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * main methods with external entry points
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: admin_lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Synopsis: main entry point for pkgadm "lock" subcommand
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Control zone/package administrative locking
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: 0 on success, non-zero otherwise.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int exclusive = 1; /* exclusive vs shared lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while ((c = getopt(argc, argv, ":aek:o:p:qrR:stwW:z:")) != EOF) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((endptr != (char *)NULL) && (*endptr != '\0')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_pFLAG_BADINT,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if root directory is not absolute path, error */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if root directory does not exist, create it */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* create top level root directory */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if $ALTROOT/tmp directory does not exist create it */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* create $ALTROOT/tmp directory */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if $ALTROOT/tmp directory cannot be created, exit */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ALTROOT_NONEXIST,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((endptr != (char *)NULL) && (*endptr != '\0')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_WFLAG_BADINT,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((endptr != (char *)NULL) && (*endptr != '\0')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_zFLAG_BADINT,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* LINTED fallthrough on case statement */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * validate arguments
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if -t option is specified, override all other options */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* only 2 or 3 args are valid */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fprintf(stderr, MSG_T_OPTION_ARGS, argc-optind);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if 3rd argument given, it is return value to check */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (a == 3) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rx = _lockMatch(argv[optind+0], argv[optind+1]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if 3rd argument not given, code to check is code returned */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (a == 2) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* report results */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (a == 2) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* always successful */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* must be no non-option arguments left */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* -a and -r cannot be used together */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ar_TOGETHER);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* -e and -s cannot be used together */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_es_TOGETHER);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* -e can only be used if -a is used */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_e_without_a);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* -s can only be used if -a is used */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_s_without_a);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * perform the requested operation
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* hold SIGINT/SIGHUP interrupts */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* connect sigint_handler() to SIGINT */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* connect sighupt_handler() to SIGHUP */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* release hold on signals */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* open the lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* set "exclusive" mode based on -e/-s flag used */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* acquire lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tResult = lock_acquire(&theLock, &fd, RFlag, kFlag, oFlag,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland qFlag, wFlag, WFlag, exclusive, RFlag, pFlag, zFlag);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* release lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = lock_release(fd, kFlag, oFlag, qFlag);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* lock status */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = lock_status(fd, kFlag, oFlag, qFlag);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* close the lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* return results of operation */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * local main function implementation methods
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: lock_acquire
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: implement lock acquisition implementing the wait/timeouts
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Calls _lock_acquire to attempt lock acquisition.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_theLock - lock object filled with contents of existing lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_fd - file descriptor opened on the lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_root - root of file system to manipulate locks on
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_key - key associated with lock to acquire
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_object - object associated with lock to acquire
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_wait - wait if lock cannot be acquired flag:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - do not wait
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != 0 - wait
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_timeout - timeout if waiting to acquire busy lock:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - no timeout (wait forever)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != 0 - max # seconds to wait to acquire busy lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_quiet - quiet mode enabled flag
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_exclusive - exclusive/shared lock flag
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_pid - if != 0 process i.d. to associate with this lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_zid - if >= 0 - zone i.d. to associate with this lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - successful
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != 0 - not successful
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandlock_acquire(LOCK_T *a_theLock, int *a_fd, char *a_root, char *a_key,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *a_object, int a_quiet, int a_wait, long a_timeout,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int a_exclusive, char *a_altRoot, pid_t a_pid, zoneid_t a_zid)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* reset the lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* open file if not open */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((*a_fd) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((*a_fd) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* compute time after which acquire times out */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland timeout = time((time_t *)NULL) + a_timeout;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* attempt to aquire the lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = _lock_acquire(a_theLock, *a_fd, a_key, a_object,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* return result if any result other than object is locked */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* close lock file if opened in this function */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* close lock file if opened in this function */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* FALLTHROUGH */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object locked OR SIGINT/SIGHUP interrupt received;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * return error if not waiting for lock OR signal received
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((a_wait == 0) || (signal_received != 0)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* close lock file if opened in this function */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* waiting for lock - if timeout specified see if time left */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* close lock file if opened in this function */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * waiting to aquire lock:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - notify waiting (one time only)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - close lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - open lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - try again
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* notify once */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_WRN,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* close lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* wait (sleep) */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* open the lock file and try again */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ACQUIRE_REOPEN_FAILED,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* close lock file if opened in this function */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: lock_release
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: implement lock release
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_fd - file descriptor opened on the lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_key - key associated with lock to release
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_object - object associated with lock to release
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_quiet - quiet mode enabled flag
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - successful
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != 0 - not successful
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandlock_release(int a_fd, char *a_key, char *a_object, int a_quiet)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* entry debugging info */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_RELEASE_ENTRY,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* find the lock to be released */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = _findLock(&theLock, &recordNum, a_fd, a_object, a_key);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_RELEASE_FINDRESULT,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* determine how to release the lock if found */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is not locked but a key was specified
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is locked and no matching key was specified
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is not locked
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is locked and specified key does not match
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * error determining if object is locked
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is locked and specified key matches
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_RELEASE_FOUND,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) _decrementLockCount(a_fd, &theLock);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * unknown return
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: lock_status
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: implement lock status display/inquiry
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_fd - file descriptor opened on the lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_key - key associated with lock to look up
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_object - object associated with lock to look up
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_quiet - quiet mode enabled flag
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - successful
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != 0 - not successful
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandlock_status(int a_fd, char *a_key, char *a_object, int a_quiet)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* entry debugging info */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_STATUS_ENTRY,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* localize references to lock object */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* read and process each lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (; pread(a_fd, pld, pls, pls*recordNum) == pls; recordNum++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* debug info on this lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_STATUS_READRECORD,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pll->lockObject, pll->lockKey, pll->lockPid,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* ignore if key specified and key does not match */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* ignore if object specified and object does not match */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (strcmp(pll->lockObject, a_object) != 0)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* process next lock if quiet operation */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* output header if first lock object */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "%2s %2s %3s %8s %3s %9s %37s %s\n",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "i#", "l#", "cnt", "pid", "zid", "lock-type",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "---------------lock-key-------------",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "lock-object");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* output status line for this lock object */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "%2ld %2ld %3ld %8ld %3d %9s %37s %s\n",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland recordNum, pll->lockRecordNum, pll->lockCount,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pll->lockExclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pll->lockObject == '\0' ? "*" : pll->lockObject);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* return == 0 if found, != 0 if not found */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * local utility functions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: _lock_acquire
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: implement lock acquisition without wait/timeouts
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_theLock - lock object filled with contents of existing lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_fd - file descriptor opened on the lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_key - key associated with lock to acquire
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_object - object associated with lock to acquire
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_quiet - quiet mode enabled flag
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_exclusive - exclusive/shared lock flag
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_pid - if != 0 process i.d. to associate with this lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_zid - if >= 0 zone i.d. to associate with this lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: FINDLOCK_T
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland_lock_acquire(LOCK_T *a_theLock, int a_fd, char *a_key,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *a_object, int a_quiet, int a_exclusive, pid_t a_pid,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* entry debugging info */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_ACQUIRE_ENTRY,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* is the specified object already locked? */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = _findLock(a_theLock, &recordNum, a_fd, a_object,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (_validateLock(a_fd, a_theLock, a_quiet) == B_TRUE) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* debug info on result of find of lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_ACQUIRE_FINDRESULT,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* determine how to acquire the lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is not locked but a key was specified
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is locked and no key was specified:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - if lock is exclusively held, return "locked"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - if exclusive lock requested, return "locked"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - otherwise lock is shared and shared lock requested,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - increment lock count and return the key
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* return error if current lock exclusive */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* return error if requesting exclusive lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* shared requesting shared - add to shared lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* increment shared lock count */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (_incrementLockCount(a_fd, a_theLock) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is not locked
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (_addLock(key, a_fd, a_object, a_exclusive,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strncpy(a_theLock->_lrLock.lockKey, key,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is locked, key specified, specified key does not match
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_ERR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * error determining if object is locked
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ACQUIRE_ERROR,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object is locked and specified key matches
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* return locked if object currently locked */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (a_exclusive != a_theLock->_lrLock.lockExclusive) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_ACQUIRE_FOUND_INC,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland a_exclusive ? MSG_LOCK_EXC : MSG_LOCK_SHR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* increment shared lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (_incrementLockCount(a_fd, a_theLock) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * unknown return
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: _openLockFile
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: open the lock file, acquiring exclusive record locks
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_root - root of file system to manipulate locks on
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - successful - file descriptor lock file opened on
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - not successful
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* entry debugging info */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_ENTRY,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* generate path to lock directory */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) snprintf(lockpath, sizeof (lockpath), "%s/%s",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ROOTDIR_INVALID,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* generate path to lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) snprintf(lockpath, sizeof (lockpath),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* wait for open to succeed up to limits */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* LINTED O_CREAT without O_EXCL specified in call to open() */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fd = open(lockpath, O_CREAT|O_RDWR, LOCK_FILEMODE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* break out of loop if file opened */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* failed - exit loop if due to access (permissions) failure */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* file is busy - wait and try again */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if open filed generate error message and return error */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * lock file opened - acquire exclusive section lock on entire file;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * wait for lockf to succeed up to limits
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* acquire exclusive section lock on entire file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* break out of loop if entire file locked */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* file is busy - wait and try again */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_SLEEP2,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if section lock failed generate error message and return error */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_FAIL2,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* file opened and locked - return success */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_OPENFILE_SUCCESS, fd);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: _lockMatch
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Compare two lock objects using file name match criteria
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_s1Lock - first lock object to compare against the second
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_s2Lock - second lock object to compare against the first
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - the locks match at some level
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != 0 - the locks do not match at any level
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* entry assertions */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* entry debugging info */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_ENTRY, a_s1Lock, a_s2Lock);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * attempt to find a common anchor between the two locks; that is,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * find the first node in the first lock that matches any node
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in the second lock; for example:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --> a/b/c vs b/c/d
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -> common anchor is "b"; comparison would expand to:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --> a/b/c/? vs ?/b/c/d
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* process each node in the first lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* get next first lock node */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgstrGetToken_r((char *)NULL, a_s1Lock, s1Cnt, "/",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_FSTNODE, s1Cnt, s1Buf);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* exit if no more nodes left */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* discover "." prefix for this node */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgstrGetToken_r((char *)NULL, s1Buf, 0, ".", s1Prefix,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland s1Sfx = (strlen(s1Prefix) == strlen(s1Buf) ? B_FALSE : B_TRUE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* search each second lock node; look for the first node lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* get next second lock node */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgstrGetToken_r((char *)NULL, a_s2Lock, s2Cnt, "/",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SCNDNODE, s2Cnt,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* exit if no nodes left */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* discover "." prefix for this node */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgstrGetToken_r((char *)NULL, s2Buf, 0, ".", s2Prefix,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * process this pair of nodes:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * if both nodes do not have a prefix, then directly
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * compare the nodes (e.g. a/b vs c/d: a vs c, b vs d)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and break out of the loop if there is a match;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * otherwise, compare prefixes and break out of the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * loop if there is a match (e.g. a.* / b.* vs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * vs c.* / d.*: a.* vs c.*, a.* vs d.*, b.* vs c.*,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * b.* vs d.*).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_NODES, s1Buf,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((s1Sfx == B_FALSE) || (s2Sfx == B_FALSE)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* one doesnt have a prefix direct comparison */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* nodes do not directly match, continue */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_DIRNOMCH,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* both have prefix, compare prefixes */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* prefixes do not match, continue */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_PFXNOMCH, s1Prefix,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * match found if not at the end of the second lock node list,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * break out of loop because some match between the two lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * objects has been found
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * at this point, either a match has been found between the nodes in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the two lock objects, or there is no commonality at all between
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the two lock objects.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * s1Buf[0] == '\0' && s2Buf[0] == '\0':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --> nothing in first lock matches anything in second lock:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ----> (s1Cnt == 1) || (s2Cnt == 1) && (s1Sfx == B_FALSE)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ----> || (s2Sfx == B_FALSE)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --------> an absolute lock do not match
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ----> else both object locks have nothing in common - match
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * s2Buf[0] != '\0' && s1Buf[0] != '\0' && s1Cnt > 0 && s2Cnt > 0
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --> locks have incompatible overlaps - no match, such as:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ----> a.* / b.* / c.* / d.* and y.* / b.* / c.*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * s1Cnt == 0 && s2Cnt == 0:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --> locks begin with same node - do comparison
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * s1Cnt != 0 && s2Cnt == 0 && s2Buf[0] != '\0'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --> second lock is subset of first lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * s2Cnt == 0 && s2Buf[0] != '\0':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --> s1Buf[s1Cnt] matches s2Buf[0] - second is subset of first
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * s2Cnt != 0 && s1Cnt == 0 && s1Buf[0] != '\0':
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --> first lock is subset of second lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_FSTLCK, s1Cnt, s1Buf,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SCNDLCK, s2Cnt, s2Buf,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* process any direct comparisons that might be possible */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((s1Buf[0] == '\0') && (s2Buf[0] == '\0')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* nothing in first matches anything in second lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ((s1Sfx == B_FALSE) || (s2Sfx == B_FALSE))) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* two absolute locks match (e.g. 'file' and 'dir') */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_ABSNOMCH, a_s1Lock,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* two object locks have nothing in common: match */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_OBJMCH, a_s1Lock, a_s2Lock);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((s2Buf[0] != '\0') && (s1Buf[0] != '\0') &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* incompatible overlapping objects */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_OVLPNOMCH, a_s1Lock, a_s2Lock,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * must compare each node of each lock to determine match;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * start off at the first byte of both locks
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* both have first match - start comparison from the begining */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SAME, a_s1Lock, a_s2Lock,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if ((s1Cnt != 0) && (s2Cnt == 0) && (s2Buf[0] != '\0')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* second lock begins somewhere inside of the first lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_SCNDSUB, a_s2Lock, a_s1Lock,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* advance first lock to matching node in second lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strchr(a_s1Lock, '/') != (char *)NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if ((s2Cnt != 0) && (s1Cnt == 0) && (s1Buf[0] != '\0')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* first lock begins somewhere inside of the second lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_FRSTSUB, a_s1Lock, a_s2Lock,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* advance second lock to matching node in first lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strchr(a_s2Lock, '/') != (char *)NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* unknown condition (probably impossible): directly compare */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LCKMCH_DONTKNOW, a_s1Lock, a_s2Lock);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * locks have common node - compare from that node forward
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_READY, final1Lock, final2Lock);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* compare each node (prefix) - success when no more nodes to compare */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* get next node from first lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgstrGetToken_r((char *)NULL, final1Lock, s1Cnt, "/", s1Buf,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* success if at end of lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* get next node from second lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgstrGetToken_r((char *)NULL, final2Lock, s1Cnt, "/", s2Buf,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* success if at end of lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* compare both nodes */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* failure if nodes do not match */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_NODEFAIL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* nodes match, continue and compare next set of nodes */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_NODEOK, s1Cnt, s1Buf, s2Buf);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* no more nodes to compare - locks match */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LCKMCH_MATCHOK, final1Lock, final2Lock);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: _findLock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Locate specified lock in lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_theLock - lock object filled with contents of lock (if found)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * r_recordNum - will contain record number if lock found
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - will be RECORDNUM_NONE if lock not found
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_fd - file descriptor opened on the lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_key - key associated with lock to look up
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_object - object associated with lock to look up
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * FINDLOCK_FOUND - specified lock found; a_theLock contains contents
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of found lock, r_recordNum contain record number of lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * FINDLOCK_ERROR - failed - error occurred looking up the lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * FINDLOCK_NOTFOUND - specified object is not locked
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * FINDLOCK_KEYMISMATCH - object lock found but specified key doesnt match
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * FINDLOCK_LOCKED - object lock found but no key specified
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * FINDLOCK_NOTLOCKED - object not locked
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland_findLock(LOCK_T *a_theLock, RECORDNUM_T *r_recordNum,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* reset returned record number to "none" */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* localize references to lock object */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* zero out returned lock data */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* debug info before processing lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_ENTRY,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* rewind to beginning of lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_FINDLOCK_LSEEK_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* read and process each lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (; pread(a_fd, pld, pls, pls*recordNum) == pls; recordNum++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* debug info on this lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_READRECORD,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pll->lockObject, pll->lockKey, pll->lockPid,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* continue if object is not the one we are looking for */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (_lockMatch(a_object, pll->lockObject) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object found; return locked if searching for no key
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* no key specified - object is locked */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * object found and keys present; see if keys match
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* keys do not match */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* object found and keys match - return match */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_FOUND);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* object not locked - return error if key supplied */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* object not locked and key not supplied - no lock found */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_FINDLOCK_NOTFOUND);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: _addLock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Add a new lock to the lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * r_key - if lock acquired key is placed here
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_fd - file descriptor opened on the lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_object - object to lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_exclusive - type of lock to add:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - shared lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != 0 - exclusive lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_pid - if != 0 process i.d. to associate with this lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_zid - if >= 0 zone i.d. to associate with this lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - success
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != 0 - failure
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland_addLock(char *r_key, int a_fd, char *a_object, int a_exclusive, pid_t a_pid,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* get unique i.d. for this lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* determine record number for next record in lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ADDLOCK_LSEEK_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* allocate storace for this lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* fill in components of the lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strlcpy(theLock._lrLock.lockObject, a_object,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strlcpy(theLock._lrLock.lockKey, key, LOCK_KEY_MAXLEN);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland theLock._lrLock.lockPid = (a_pid > 0 ? a_pid : 0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland theLock._lrLock.lockRecordNum = (pos == 0 ? 0 : (pos/sizeof (LOCK_T)));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland theLock._lrLock.lockExclusive = a_exclusive;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland theLock._lrLock.lockZoneId = (a_zid >= 0 ? a_zid : -1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* debug info on new lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_ADDLOCK_ADDING,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pos, theLock._lrLock.lockObject, theLock._lrLock.lockKey,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland theLock._lrLock.lockPid, theLock._lrLock.lockZoneId);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* write the new lock record to the end of the lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = pwrite(a_fd, &theLock, LOCK_SIZE, pos);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_ADDLOCK_PWRITE_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* output the key assigned to standard out */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strncpy(r_key, key, LOCK_KEY_MAXLEN);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland_incrementLockCount(int a_fd, LOCK_T *a_theLock)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* localize references to lock object */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* debug info on incrementing lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_INCLOCK_ENTRY,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* increment lock count */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* write out updated lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = pwrite(a_fd, pld, pls, pll->lockRecordNum*pls);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_INCLOCK_PWRITE_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* debug info lock incremented */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_INCLOCK_DONE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: _validateLock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: determine if a specified lock is valid; if the lock is not valid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * then remove the lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: a_fd - file descriptor opened on the lock file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_theLock - lock object to validate
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: boolean_t
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * B_TRUE - the lock is valid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * B_FALSE - the lock is not valid and has been removed
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland_validateLock(int a_fd, LOCK_T *a_theLock, int a_quiet)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* localize references to lock object */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* return true if no process i.d. associated with lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_NOPID, pll->lockObject);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* see if the zone i.d. matches */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_BADZID, pll->lockObject,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_ZIDOK, pll->lockObject,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* see if the process is still active */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgstrPrintf_r(path, sizeof (path), "/proc/%d", pll->lockPid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_OK, pll->lockObject,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_VALID_NOTOK, pll->lockObject, pll->lockPid,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* delete this lock */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(a_quiet ? LOG_MSG_DEBUG : LOG_MSG_WRN,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland MSG_VALID_STALE, pll->lockObject, pll->lockPid,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland_decrementLockCount(int a_fd, LOCK_T *a_theLock)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* localize references to lock object */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* decrement lock count */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if lock count > 0 then write out and leave locked */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_DECING,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = pwrite(a_fd, pld, pls, pll->lockRecordNum*pls);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_PWRITE_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_DONE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * lock count zero - erase the record
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* find last record in the lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland lastPos = lseek(a_fd, 0L, SEEK_END); /* get size of lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_LSEEK_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland lastRecord = (lastPos/pls)-1; /* convert size to record # */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_REMOVE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* see if removing last record of file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* debug info removing last record */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_LASTONE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* removing last record of file, truncate */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_FTRUNCATE_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * not removing last record of file:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * read last record, truncate file one record,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * replace record to be removed with last record read
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_DECLOCK_REMOVING,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pll->lockRecordNum, lastRecord, lastPos-pls);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* read in the last record */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = pread(a_fd, tmpLock._lrLockData, pls, lastRecord*pls);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_PREAD_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* truncate lock file removing the last record (just read in) */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_FTRUNCATE_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* update record to indicate its new position in the lock file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpLock._lrLock.lockRecordNum = pll->lockRecordNum;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* write out the updated record to the new location */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = pwrite(a_fd, tmpLock._lrLockData, pls, pll->lockRecordNum*pls);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_ERR, MSG_LOCK_DECLOCK_PWRITE_FAILURE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: _getUniqueId
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Generate a unique ID that can be used as a key for a new lock
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: None
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: char *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == NULL - error, no key generated
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != NULL - generated key
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NOTE: Any results returned is placed in new storage for the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * calling method. The caller must use 'lu_memFree' to dispose
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of the storage once the results are no longer needed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * try and use makeuuid to generate a unique i.d. Such a unique i.d.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * will look like:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 7814e3c1-1dd2-11b2-9fe8-000d560ddc82
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland b = e_ExecCmdList(&execStatus, &execResults, (char *)NULL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((b == 0) && (execStatus == 0) && (*execResults != '\0')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (p != (char *)NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_GENUID_MAKEUUID,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cannot run makeuuid - generate own unique key - the key is the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * same length as unique uid but contains different information that
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * is as unique as can be made - include current hires time (nanosecond
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * real timer. Such a unique i.d. will look like:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0203104092-1145345-0004e94d6af481a0
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "%02d%02d%02d%03d-%02d%02d%02d%d-%016llx", tstruct.tm_mday,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tstruct.tm_mon, tstruct.tm_year, tstruct.tm_yday,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tstruct.tm_hour, tstruct.tm_min, tstruct.tm_sec,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland log_msg(LOG_MSG_DEBUG, MSG_LOCK_GENUID_INTERNAL, newkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: sigint_handler
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Synopsis: SIGINT interrupt handler
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Catch the "SIGINT" signal; increment signal_received
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * global variable,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: signo - [RO, *RO] - (int)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Signal number that was caught
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: sighup_handler
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Synopsis: SIGHUP interrupt handler
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Catch the "SIGHUP" signal; increment signal_received
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * global variable,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: signo - [RO, *RO] - (int)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Signal number that was caught
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: void