15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland * CDDL HEADER START
35c51f124SMoriah Waterland *
45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland *
85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland * See the License for the specific language governing permissions
115c51f124SMoriah Waterland * and limitations under the License.
125c51f124SMoriah Waterland *
135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland *
195c51f124SMoriah Waterland * CDDL HEADER END
205c51f124SMoriah Waterland */
215c51f124SMoriah Waterland
225c51f124SMoriah Waterland /*
235c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
245c51f124SMoriah Waterland * Use is subject to license terms.
255c51f124SMoriah Waterland */
265c51f124SMoriah Waterland
27*f5c2e7eaSTheo Schlossnagle /*
28*f5c2e7eaSTheo Schlossnagle * Copyright (c) 2012 by Delphix. All rights reserved.
29*f5c2e7eaSTheo Schlossnagle */
305c51f124SMoriah Waterland
315c51f124SMoriah Waterland /*
325c51f124SMoriah Waterland * Module: zones_locks.c
335c51f124SMoriah Waterland * Group: libinstzones
345c51f124SMoriah Waterland * Description: Provide "zones" locking interfaces for install consolidation
355c51f124SMoriah Waterland * code
365c51f124SMoriah Waterland *
375c51f124SMoriah Waterland * Public Methods:
385c51f124SMoriah Waterland *
395c51f124SMoriah Waterland * _z_acquire_lock - acquire a lock on an object on a zone
405c51f124SMoriah Waterland * _z_adjust_lock_object_for_rootpath - Given a lock object and a root path,
415c51f124SMoriah Waterland * if the root path is not
425c51f124SMoriah Waterland * _z_lock_zone - Acquire specified locks on specified zone
435c51f124SMoriah Waterland * _z_lock_zone_object - lock a single lock object in a specified zone
445c51f124SMoriah Waterland * _z_release_lock - release a lock held on a zone
455c51f124SMoriah Waterland * _z_unlock_zone - Released specified locks on specified zone
465c51f124SMoriah Waterland * _z_unlock_zone_object - unlock a single lock object in a specified zone
475c51f124SMoriah Waterland */
485c51f124SMoriah Waterland
495c51f124SMoriah Waterland /*
505c51f124SMoriah Waterland * System includes
515c51f124SMoriah Waterland */
525c51f124SMoriah Waterland
535c51f124SMoriah Waterland #include <stdio.h>
545c51f124SMoriah Waterland #include <stdlib.h>
555c51f124SMoriah Waterland #include <unistd.h>
565c51f124SMoriah Waterland #include <fcntl.h>
575c51f124SMoriah Waterland #include <ctype.h>
585c51f124SMoriah Waterland #include <sys/types.h>
595c51f124SMoriah Waterland #include <sys/param.h>
605c51f124SMoriah Waterland #include <string.h>
615c51f124SMoriah Waterland #include <strings.h>
625c51f124SMoriah Waterland #include <stdarg.h>
635c51f124SMoriah Waterland #include <limits.h>
645c51f124SMoriah Waterland #include <errno.h>
655c51f124SMoriah Waterland #include <time.h>
665c51f124SMoriah Waterland #include <stropts.h>
675c51f124SMoriah Waterland #include <libintl.h>
685c51f124SMoriah Waterland #include <locale.h>
695c51f124SMoriah Waterland #include <assert.h>
705c51f124SMoriah Waterland
715c51f124SMoriah Waterland /*
725c51f124SMoriah Waterland * local includes
735c51f124SMoriah Waterland */
745c51f124SMoriah Waterland
755c51f124SMoriah Waterland #include "instzones_lib.h"
765c51f124SMoriah Waterland #include "zones_strings.h"
775c51f124SMoriah Waterland
785c51f124SMoriah Waterland /*
795c51f124SMoriah Waterland * Private structures
805c51f124SMoriah Waterland */
815c51f124SMoriah Waterland
825c51f124SMoriah Waterland /*
835c51f124SMoriah Waterland * Library Function Prototypes
845c51f124SMoriah Waterland */
855c51f124SMoriah Waterland
865c51f124SMoriah Waterland /*
875c51f124SMoriah Waterland * Local Function Prototypes
885c51f124SMoriah Waterland */
895c51f124SMoriah Waterland
905c51f124SMoriah Waterland boolean_t _z_adjust_lock_object_for_rootpath(char **r_result,
915c51f124SMoriah Waterland char *a_lockObject);
925c51f124SMoriah Waterland boolean_t _z_acquire_lock(char **r_lockKey, char *a_zoneName,
935c51f124SMoriah Waterland char *a_lock, pid_t a_pid, boolean_t a_wait);
945c51f124SMoriah Waterland boolean_t _z_lock_zone(zoneListElement_t *a_zlst,
955c51f124SMoriah Waterland ZLOCKS_T a_lflags);
965c51f124SMoriah Waterland boolean_t _z_lock_zone_object(char **r_objectLocks,
975c51f124SMoriah Waterland char *a_zoneName, char *a_lockObject,
985c51f124SMoriah Waterland pid_t a_pid, char *a_waitingMsg,
995c51f124SMoriah Waterland char *a_busyMsg);
1005c51f124SMoriah Waterland boolean_t _z_release_lock(char *a_zoneName, char *a_lock,
1015c51f124SMoriah Waterland char *a_key, boolean_t a_wait);
1025c51f124SMoriah Waterland boolean_t _z_unlock_zone(zoneListElement_t *a_zlst,
1035c51f124SMoriah Waterland ZLOCKS_T a_lflags);
1045c51f124SMoriah Waterland boolean_t _z_unlock_zone_object(char **r_objectLocks,
1055c51f124SMoriah Waterland char *a_zoneName, char *a_lockObject,
1065c51f124SMoriah Waterland char *a_errMsg);
1075c51f124SMoriah Waterland
1085c51f124SMoriah Waterland /*
1095c51f124SMoriah Waterland * global internal (private) declarations
1105c51f124SMoriah Waterland */
1115c51f124SMoriah Waterland
1125c51f124SMoriah Waterland /*
1135c51f124SMoriah Waterland * *****************************************************************************
1145c51f124SMoriah Waterland * global external (public) functions
1155c51f124SMoriah Waterland * *****************************************************************************
1165c51f124SMoriah Waterland */
1175c51f124SMoriah Waterland
1185c51f124SMoriah Waterland /*
1195c51f124SMoriah Waterland * Name: _z_acquire_lock
1205c51f124SMoriah Waterland * Description: acquire a lock on an object on a zone
1215c51f124SMoriah Waterland * Arguments: r_lockKey - [RW, *RW] - (char *)
1225c51f124SMoriah Waterland * Pointer to handle to string representing the lock key
1235c51f124SMoriah Waterland * associated with the lock object to be acquired - this
1245c51f124SMoriah Waterland * key is returned when the lock is acquired and must be
1255c51f124SMoriah Waterland * provided when releasing the lock
1265c51f124SMoriah Waterland * == (char *)NULL - lock not acquired
1275c51f124SMoriah Waterland * a_zoneName - [RO, *RO] - (char *)
1285c51f124SMoriah Waterland * Pointer to string representing the name of the zone to
1295c51f124SMoriah Waterland * acquire the specified lock on
1305c51f124SMoriah Waterland * a_lockObject - [RO, *RO] - (char *)
1315c51f124SMoriah Waterland * Pointer to string representing the lock object to
1325c51f124SMoriah Waterland * acquire on the specified zone
1335c51f124SMoriah Waterland * a_pid - [RO, *RO] - (pid_t)
1345c51f124SMoriah Waterland * Process i.d. to associate with this lock
1355c51f124SMoriah Waterland * == 0 - no process i.d. associated with the lock
1365c51f124SMoriah Waterland * a_wait - [RO, *RO] - (int)
1375c51f124SMoriah Waterland * Determines what to do if the lock cannot be acquired:
1385c51f124SMoriah Waterland * == B_TRUE - wait for the lock to be acquired
1395c51f124SMoriah Waterland * == B_FALSE - do not wait for the lock to be acquired
1405c51f124SMoriah Waterland * Returns: boolean_t
1415c51f124SMoriah Waterland * B_TRUE - lock acquired
1425c51f124SMoriah Waterland * B_FALSE - lock not acquired
1435c51f124SMoriah Waterland */
1445c51f124SMoriah Waterland
1455c51f124SMoriah Waterland boolean_t
_z_acquire_lock(char ** r_lockKey,char * a_zoneName,char * a_lockObject,pid_t a_pid,boolean_t a_wait)1465c51f124SMoriah Waterland _z_acquire_lock(char **r_lockKey, char *a_zoneName, char *a_lockObject,
1475c51f124SMoriah Waterland pid_t a_pid, boolean_t a_wait)
1485c51f124SMoriah Waterland {
1495c51f124SMoriah Waterland argArray_t *args;
1505c51f124SMoriah Waterland boolean_t b;
1515c51f124SMoriah Waterland char *adjustedLockObject = (char *)NULL;
1525c51f124SMoriah Waterland char *p;
1535c51f124SMoriah Waterland char *results = (char *)NULL;
1545c51f124SMoriah Waterland int r;
1555c51f124SMoriah Waterland int status;
1565c51f124SMoriah Waterland
1575c51f124SMoriah Waterland /* entry assertions */
1585c51f124SMoriah Waterland
1595c51f124SMoriah Waterland assert(a_zoneName != (char *)NULL);
1605c51f124SMoriah Waterland assert(a_lockObject != (char *)NULL);
1615c51f124SMoriah Waterland assert(*a_lockObject != '\0');
1625c51f124SMoriah Waterland assert(r_lockKey != (char **)NULL);
1635c51f124SMoriah Waterland
1645c51f124SMoriah Waterland /* entry debugging info */
1655c51f124SMoriah Waterland
1665c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_APLK, a_zoneName, a_lockObject, a_pid);
1675c51f124SMoriah Waterland
1685c51f124SMoriah Waterland /* reset returned lock key handle */
1695c51f124SMoriah Waterland
1705c51f124SMoriah Waterland *r_lockKey = (char *)NULL;
1715c51f124SMoriah Waterland
1725c51f124SMoriah Waterland /*
1735c51f124SMoriah Waterland * Only one lock file must ever be used - the one located on the root
1745c51f124SMoriah Waterland * file system of the currently running Solaris instance. To allow for
1755c51f124SMoriah Waterland * alternative roots to be properly locked, adjust the lock object to
1765c51f124SMoriah Waterland * take root path into account; if necessary, the root path will be
1775c51f124SMoriah Waterland * prepended to the lock object.
1785c51f124SMoriah Waterland */
1795c51f124SMoriah Waterland
1805c51f124SMoriah Waterland b = _z_adjust_lock_object_for_rootpath(&adjustedLockObject,
1815c51f124SMoriah Waterland a_lockObject);
1825c51f124SMoriah Waterland if (!b) {
1835c51f124SMoriah Waterland return (B_FALSE);
1845c51f124SMoriah Waterland }
1855c51f124SMoriah Waterland
1865c51f124SMoriah Waterland /*
1875c51f124SMoriah Waterland * construct command arguments:
1885c51f124SMoriah Waterland * pkgadm lock -a -q -o adjustedLockObject [ -w -W timeout ]
1895c51f124SMoriah Waterland * [ -p a_pid -z zoneid ]
1905c51f124SMoriah Waterland */
1915c51f124SMoriah Waterland
1925c51f124SMoriah Waterland args = _z_new_args(20); /* generate new arg list */
1935c51f124SMoriah Waterland (void) _z_add_arg(args, PKGADM_CMD); /* pkgadm command */
1945c51f124SMoriah Waterland (void) _z_add_arg(args, "lock"); /* lock sub-command */
1955c51f124SMoriah Waterland (void) _z_add_arg(args, "-a"); /* acquire lock */
1965c51f124SMoriah Waterland (void) _z_add_arg(args, "-q"); /* quiet (no extra messages) */
1975c51f124SMoriah Waterland (void) _z_add_arg(args, "-o"); /* object to acquire */
1985c51f124SMoriah Waterland (void) _z_add_arg(args, "%s", adjustedLockObject);
1995c51f124SMoriah Waterland
2005c51f124SMoriah Waterland /* add [ -w -W timeout ] if waiting for lock */
2015c51f124SMoriah Waterland
2025c51f124SMoriah Waterland if (a_wait == B_TRUE) {
2035c51f124SMoriah Waterland (void) _z_add_arg(args, "-w"); /* wait */
2045c51f124SMoriah Waterland (void) _z_add_arg(args, "-W"); /* wait timeout */
2055c51f124SMoriah Waterland (void) _z_add_arg(args, "%ld",
2065c51f124SMoriah Waterland (long)MAX_RETRIES*RETRY_DELAY_SECS);
2075c51f124SMoriah Waterland }
2085c51f124SMoriah Waterland
2095c51f124SMoriah Waterland /* add process/zone i.d.s if process i.d. provided */
2105c51f124SMoriah Waterland
2115c51f124SMoriah Waterland if (a_pid > 0) {
2125c51f124SMoriah Waterland (void) _z_add_arg(args, "-p"); /* lock valid process i.d. */
213*f5c2e7eaSTheo Schlossnagle (void) _z_add_arg(args, "%lld", (long long)getpid());
2145c51f124SMoriah Waterland (void) _z_add_arg(args, "-z"); /* lock valid zone i.d. */
215*f5c2e7eaSTheo Schlossnagle (void) _z_add_arg(args, "%lld", (long long)getzoneid());
2165c51f124SMoriah Waterland }
2175c51f124SMoriah Waterland
2185c51f124SMoriah Waterland /* execute command */
2195c51f124SMoriah Waterland
2205c51f124SMoriah Waterland r = _z_zone_exec(&status, &results, (char *)NULL, PKGADM_CMD,
2215c51f124SMoriah Waterland _z_get_argv(args), a_zoneName, (int *)NULL);
2225c51f124SMoriah Waterland
2235c51f124SMoriah Waterland /* free generated argument list */
2245c51f124SMoriah Waterland
2255c51f124SMoriah Waterland _z_free_args(args);
2265c51f124SMoriah Waterland
2275c51f124SMoriah Waterland /* return error if failed to acquire */
2285c51f124SMoriah Waterland
2295c51f124SMoriah Waterland if ((r != 0) || (status != 0)) {
2305c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_APLK_EXIT, a_zoneName,
2315c51f124SMoriah Waterland adjustedLockObject, a_pid, r, status,
2325c51f124SMoriah Waterland results ? results : "");
2335c51f124SMoriah Waterland
2345c51f124SMoriah Waterland /* free up results if returned */
2355c51f124SMoriah Waterland if (results) {
2365c51f124SMoriah Waterland free(results);
2375c51f124SMoriah Waterland }
2385c51f124SMoriah Waterland
2395c51f124SMoriah Waterland /* free adjusted lock object */
2405c51f124SMoriah Waterland free(adjustedLockObject);
2415c51f124SMoriah Waterland
2425c51f124SMoriah Waterland /* return failure */
2435c51f124SMoriah Waterland return (B_FALSE);
2445c51f124SMoriah Waterland }
2455c51f124SMoriah Waterland
2465c51f124SMoriah Waterland /* return success if no results returned */
2475c51f124SMoriah Waterland
2485c51f124SMoriah Waterland if (results == (char *)NULL) {
2495c51f124SMoriah Waterland return (B_TRUE);
2505c51f124SMoriah Waterland }
2515c51f124SMoriah Waterland
2525c51f124SMoriah Waterland /* return the lock key */
2535c51f124SMoriah Waterland
2545c51f124SMoriah Waterland p = _z_strGetToken((char *)NULL, results, 0, "\n");
2555c51f124SMoriah Waterland _z_strRemoveLeadingWhitespace(&p);
2565c51f124SMoriah Waterland *r_lockKey = p;
2575c51f124SMoriah Waterland
2585c51f124SMoriah Waterland /* exit debugging info */
2595c51f124SMoriah Waterland
2605c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_APLK_RESULTS, a_zoneName, adjustedLockObject, p,
2615c51f124SMoriah Waterland results);
2625c51f124SMoriah Waterland
2635c51f124SMoriah Waterland /* free up results */
2645c51f124SMoriah Waterland
2655c51f124SMoriah Waterland free(results);
2665c51f124SMoriah Waterland
2675c51f124SMoriah Waterland /* free adjusted lock object */
2685c51f124SMoriah Waterland
2695c51f124SMoriah Waterland free(adjustedLockObject);
2705c51f124SMoriah Waterland
2715c51f124SMoriah Waterland /* return success */
2725c51f124SMoriah Waterland
2735c51f124SMoriah Waterland return (B_TRUE);
2745c51f124SMoriah Waterland }
2755c51f124SMoriah Waterland
2765c51f124SMoriah Waterland /*
2775c51f124SMoriah Waterland * Name: _z_adjust_lock_object_for_rootpath
2785c51f124SMoriah Waterland * Description: Given a lock object and a root path, if the root path is not
2795c51f124SMoriah Waterland * the current running system root, then alter the lock object
2805c51f124SMoriah Waterland * to contain a reference to the root path. Only one lock file must
2815c51f124SMoriah Waterland * ever be used to create and maintain locks - the lock file that
2825c51f124SMoriah Waterland * is located in /tmp on the root file system of the currently
2835c51f124SMoriah Waterland * running Solaris instance. To allow for alternative roots to be
2845c51f124SMoriah Waterland * properly locked, if necessary adjust the lock object to take
2855c51f124SMoriah Waterland * root path into account. If the root path does not indicate the
2865c51f124SMoriah Waterland * current running Solaris instance, then the root path will be
2875c51f124SMoriah Waterland * prepended to the lock object.
2885c51f124SMoriah Waterland * Arguments: r_result - [RW, *RW] - (char **)
2895c51f124SMoriah Waterland * Pointer to handle to character string that will contain
2905c51f124SMoriah Waterland * the lock object to use.
2915c51f124SMoriah Waterland * a_lockObject - [RO, *RO] - (char *)
2925c51f124SMoriah Waterland * Pointer to string representing the lock object to adjust
2935c51f124SMoriah Waterland * Returns: boolean_t
2945c51f124SMoriah Waterland * B_TRUE - lock object adjusted and returned
2955c51f124SMoriah Waterland * B_FALSE - unable to adjust lock object
2965c51f124SMoriah Waterland * NOTE: Any string returned is placed in new storage for the
2975c51f124SMoriah Waterland * calling function. The caller must use 'free' to dispose
2985c51f124SMoriah Waterland * of the storage once the string is no longer needed.
2995c51f124SMoriah Waterland *
3005c51f124SMoriah Waterland * A lock object has this form:
3015c51f124SMoriah Waterland *
3025c51f124SMoriah Waterland * name.value [ /name.value [ /name.value ... ] ]
3035c51f124SMoriah Waterland *
3045c51f124SMoriah Waterland * The "value is either a specific object or a "*", for example:
3055c51f124SMoriah Waterland *
3065c51f124SMoriah Waterland * package.test
3075c51f124SMoriah Waterland *
3085c51f124SMoriah Waterland * This locks the package "test"
3095c51f124SMoriah Waterland *
3105c51f124SMoriah Waterland * zone.* /package.*
3115c51f124SMoriah Waterland *
3125c51f124SMoriah Waterland * This locks all packages on all zones.
3135c51f124SMoriah Waterland *
3145c51f124SMoriah Waterland * zone.* /package.SUNWluu
3155c51f124SMoriah Waterland *
3165c51f124SMoriah Waterland * This locks the package SUNWluu on all zones.
3175c51f124SMoriah Waterland *
3185c51f124SMoriah Waterland * If a -R rootpath is specified, since there is only one lock file in
3195c51f124SMoriah Waterland * the current /tmp, the lock object is modified to include the root
3205c51f124SMoriah Waterland * path:
3215c51f124SMoriah Waterland *
3225c51f124SMoriah Waterland * rootpath.rootpath/zone.* /package.*
3235c51f124SMoriah Waterland *
3245c51f124SMoriah Waterland * locks all packages on all zones in the root path "?"
3255c51f124SMoriah Waterland *
3265c51f124SMoriah Waterland * The characters "/" and "*" and "." cannot be part of the "value"; that
3275c51f124SMoriah Waterland * is if "-R /tmp/gmg*dir.test-path" is specified, the final object
3285c51f124SMoriah Waterland * cannot be:
3295c51f124SMoriah Waterland *
3305c51f124SMoriah Waterland * rootpath./tmp/gmg*dir.test-path/zone.* /package.*
3315c51f124SMoriah Waterland *
3325c51f124SMoriah Waterland * This would be parsed as:
3335c51f124SMoriah Waterland *
3345c51f124SMoriah Waterland * "rootpath." "/tmp" "gmg*dir.test-path" "zone.*" "package.*"
3355c51f124SMoriah Waterland *
3365c51f124SMoriah Waterland * which is not correct.
3375c51f124SMoriah Waterland *
3385c51f124SMoriah Waterland * So the path is modified by the loop, in this case it would result in
3395c51f124SMoriah Waterland * this lock object:
3405c51f124SMoriah Waterland *
3415c51f124SMoriah Waterland * rootpath.-1tmp-1gmg-3dir-2test---path/zone.* /package.*
3425c51f124SMoriah Waterland *
3435c51f124SMoriah Waterland * This is parsed as:
3445c51f124SMoriah Waterland *
3455c51f124SMoriah Waterland * "rootpath.-1tmp-1gmg-3dir-2test---path" "zone.*" "package.*"
3465c51f124SMoriah Waterland *
3475c51f124SMoriah Waterland * which is then interpreted as:
3485c51f124SMoriah Waterland *
3495c51f124SMoriah Waterland * "rootpath./tmp/gmg*dir.test-path" "zone.*" "package.*"
3505c51f124SMoriah Waterland */
3515c51f124SMoriah Waterland
3525c51f124SMoriah Waterland boolean_t
_z_adjust_lock_object_for_rootpath(char ** r_result,char * a_lockObject)3535c51f124SMoriah Waterland _z_adjust_lock_object_for_rootpath(char **r_result, char *a_lockObject)
3545c51f124SMoriah Waterland {
3555c51f124SMoriah Waterland char realRootPath[PATH_MAX] = {'\0'};
3565c51f124SMoriah Waterland const char *a_rootPath;
3575c51f124SMoriah Waterland
3585c51f124SMoriah Waterland /* entry assertions */
3595c51f124SMoriah Waterland
3605c51f124SMoriah Waterland assert(r_result != (char **)NULL);
3615c51f124SMoriah Waterland assert(a_lockObject != (char *)NULL);
3625c51f124SMoriah Waterland assert(*a_lockObject != '\0');
3635c51f124SMoriah Waterland
3645c51f124SMoriah Waterland /* reset returned lock object handle */
3655c51f124SMoriah Waterland
3665c51f124SMoriah Waterland *r_result = (char *)NULL;
3675c51f124SMoriah Waterland
3685c51f124SMoriah Waterland /*
3695c51f124SMoriah Waterland * if root path points to "/" return a duplicate of the passed in
3705c51f124SMoriah Waterland * lock objects; otherwise, resolve root path and adjust lock object by
3715c51f124SMoriah Waterland * prepending the rootpath to the lock object (using LOBJ_ROOTPATH).
3725c51f124SMoriah Waterland */
3735c51f124SMoriah Waterland
3745c51f124SMoriah Waterland a_rootPath = _z_global_data._z_root_dir;
3755c51f124SMoriah Waterland if ((a_rootPath == (char *)NULL) ||
3765c51f124SMoriah Waterland (*a_rootPath == '\0') ||
3775c51f124SMoriah Waterland (strcmp(a_rootPath, "/") == 0)) {
3785c51f124SMoriah Waterland
3795c51f124SMoriah Waterland /* root path not specified or is only "/" - no -R specified */
3805c51f124SMoriah Waterland
3815c51f124SMoriah Waterland *r_result = _z_strdup(a_lockObject);
3825c51f124SMoriah Waterland } else {
3835c51f124SMoriah Waterland /*
3845c51f124SMoriah Waterland * root path is not "" or "/" - -R to an alternative root has
3855c51f124SMoriah Waterland * been specified; resolve all symbolic links and relative nodes
3865c51f124SMoriah Waterland * of path name and determine absolute path to the root path.
3875c51f124SMoriah Waterland */
3885c51f124SMoriah Waterland
3895c51f124SMoriah Waterland if (realpath(a_rootPath, realRootPath) == (char *)NULL) {
3905c51f124SMoriah Waterland /* cannot determine absolute path; use path specified */
3915c51f124SMoriah Waterland (void) strlcpy(realRootPath, a_rootPath,
3925c51f124SMoriah Waterland sizeof (realRootPath));
3935c51f124SMoriah Waterland }
3945c51f124SMoriah Waterland
3955c51f124SMoriah Waterland /*
3965c51f124SMoriah Waterland * if root path points to "/" duplicate existing lock object;
3975c51f124SMoriah Waterland * otherwise, resolve root path and adjust lock object by
3985c51f124SMoriah Waterland * prepending the rootpath to the lock object
3995c51f124SMoriah Waterland */
4005c51f124SMoriah Waterland
4015c51f124SMoriah Waterland if (strcmp(realRootPath, "/") == 0) {
4025c51f124SMoriah Waterland *r_result = _z_strdup(a_lockObject);
4035c51f124SMoriah Waterland } else {
4045c51f124SMoriah Waterland char *p1, *p2, *p3;
4055c51f124SMoriah Waterland
4065c51f124SMoriah Waterland /* prefix out /.* which cannot be part of lock object */
4075c51f124SMoriah Waterland
4085c51f124SMoriah Waterland p1 = _z_calloc((strlen(realRootPath)*2)+1);
4095c51f124SMoriah Waterland for (p3 = p1, p2 = realRootPath; *p2 != '\0'; p2++) {
4105c51f124SMoriah Waterland switch (*p2) {
4115c51f124SMoriah Waterland case '/': /* / becomes -1 */
4125c51f124SMoriah Waterland *p3++ = '-';
4135c51f124SMoriah Waterland *p3++ = '1';
4145c51f124SMoriah Waterland break;
4155c51f124SMoriah Waterland case '.': /* . becomes -2 */
4165c51f124SMoriah Waterland *p3++ = '-';
4175c51f124SMoriah Waterland *p3++ = '2';
4185c51f124SMoriah Waterland break;
4195c51f124SMoriah Waterland case '*': /* * becomes -3 */
4205c51f124SMoriah Waterland *p3++ = '-';
4215c51f124SMoriah Waterland *p3++ = '3';
4225c51f124SMoriah Waterland break;
4235c51f124SMoriah Waterland case '-': /* - becomes -- */
4245c51f124SMoriah Waterland *p3++ = '-';
4255c51f124SMoriah Waterland *p3++ = '-';
4265c51f124SMoriah Waterland break;
4275c51f124SMoriah Waterland default: /* do not prefix out char */
4285c51f124SMoriah Waterland *p3++ = *p2;
4295c51f124SMoriah Waterland break;
4305c51f124SMoriah Waterland }
4315c51f124SMoriah Waterland }
4325c51f124SMoriah Waterland
4335c51f124SMoriah Waterland /* create "realpath.%s" object */
4345c51f124SMoriah Waterland
4355c51f124SMoriah Waterland p2 = _z_strPrintf(LOBJ_ROOTPATH, p1);
4365c51f124SMoriah Waterland free(p1);
4375c51f124SMoriah Waterland if (p2 == (char *)NULL) {
4385c51f124SMoriah Waterland _z_program_error(ERR_MALLOC, "<path>", errno,
4395c51f124SMoriah Waterland strerror(errno));
4405c51f124SMoriah Waterland return (B_FALSE);
4415c51f124SMoriah Waterland }
4425c51f124SMoriah Waterland
4435c51f124SMoriah Waterland /* create "realpath.%s/..." final lock object */
4445c51f124SMoriah Waterland
4455c51f124SMoriah Waterland *r_result = _z_strPrintf("%s/%s", p2, a_lockObject);
4465c51f124SMoriah Waterland free(p2);
4475c51f124SMoriah Waterland if (*r_result == (char *)NULL) {
4485c51f124SMoriah Waterland _z_program_error(ERR_MALLOC, "<path>", errno,
4495c51f124SMoriah Waterland strerror(errno));
4505c51f124SMoriah Waterland return (B_FALSE);
4515c51f124SMoriah Waterland }
4525c51f124SMoriah Waterland }
4535c51f124SMoriah Waterland }
4545c51f124SMoriah Waterland
4555c51f124SMoriah Waterland /* exit debugging info */
4565c51f124SMoriah Waterland
4575c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ADJLCKOBJ_EXIT, a_lockObject, *r_result,
4585c51f124SMoriah Waterland a_rootPath ? a_rootPath : "",
4595c51f124SMoriah Waterland realRootPath ? realRootPath : "");
4605c51f124SMoriah Waterland
4615c51f124SMoriah Waterland /* return success */
4625c51f124SMoriah Waterland
4635c51f124SMoriah Waterland return (B_TRUE);
4645c51f124SMoriah Waterland }
4655c51f124SMoriah Waterland
4665c51f124SMoriah Waterland /*
4675c51f124SMoriah Waterland * Name: _z_lock_zone
4685c51f124SMoriah Waterland * Description: Acquire specified locks on specified zone
4695c51f124SMoriah Waterland * Arguments: a_zlst - [RO, *RW] - (zoneListElement_t *)
4705c51f124SMoriah Waterland * Pointer to zone list structure element describing
4715c51f124SMoriah Waterland * the zone the lock - the structure is updated with
4725c51f124SMoriah Waterland * the lock objects and keys if the locks are acquired
4735c51f124SMoriah Waterland * a_lflags - [RO, *RO] - (ZLOCKS_T)
4745c51f124SMoriah Waterland * Flags indicating which locks to acquire on the zone
4755c51f124SMoriah Waterland * Returns: boolean_t
4765c51f124SMoriah Waterland * == B_TRUE - locks successfully acquired
4775c51f124SMoriah Waterland * == B_FALSE - failed to acquire the locks
4785c51f124SMoriah Waterland */
4795c51f124SMoriah Waterland
4805c51f124SMoriah Waterland boolean_t
_z_lock_zone(zoneListElement_t * a_zlst,ZLOCKS_T a_lflags)4815c51f124SMoriah Waterland _z_lock_zone(zoneListElement_t *a_zlst, ZLOCKS_T a_lflags)
4825c51f124SMoriah Waterland {
4835c51f124SMoriah Waterland char *scratchName;
4845c51f124SMoriah Waterland boolean_t b;
4855c51f124SMoriah Waterland
4865c51f124SMoriah Waterland /* entry assertions */
4875c51f124SMoriah Waterland
4885c51f124SMoriah Waterland assert(a_zlst != (zoneListElement_t *)NULL);
4895c51f124SMoriah Waterland
4905c51f124SMoriah Waterland /* entry debugging info */
4915c51f124SMoriah Waterland
4925c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_ZONE, a_zlst->_zlName, a_lflags);
4935c51f124SMoriah Waterland
4945c51f124SMoriah Waterland scratchName = a_zlst->_zlScratchName == NULL ? a_zlst->_zlName :
4955c51f124SMoriah Waterland a_zlst->_zlScratchName;
4965c51f124SMoriah Waterland
4975c51f124SMoriah Waterland /*
4985c51f124SMoriah Waterland * acquire zone lock
4995c51f124SMoriah Waterland */
5005c51f124SMoriah Waterland
5015c51f124SMoriah Waterland if (a_lflags & ZLOCKS_ZONE_ADMIN) {
5025c51f124SMoriah Waterland /*
5035c51f124SMoriah Waterland * lock zone administration if not already locked
5045c51f124SMoriah Waterland * if the lock cannot be released, stop and return an error
5055c51f124SMoriah Waterland */
5065c51f124SMoriah Waterland
5075c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_ZONE_ZONEADM, a_zlst->_zlName,
5085c51f124SMoriah Waterland LOBJ_ZONEADMIN);
5095c51f124SMoriah Waterland
5105c51f124SMoriah Waterland b = _z_lock_zone_object(&a_zlst->_zlLockObjects,
5115c51f124SMoriah Waterland scratchName, LOBJ_ZONEADMIN, (pid_t)0,
5125c51f124SMoriah Waterland MSG_ZONES_LCK_ZONE_ZONEADM,
5135c51f124SMoriah Waterland ERR_ZONES_LCK_ZONE_ZONEADM);
5145c51f124SMoriah Waterland if (b == B_FALSE) {
5155c51f124SMoriah Waterland return (b);
5165c51f124SMoriah Waterland }
5175c51f124SMoriah Waterland }
5185c51f124SMoriah Waterland
5195c51f124SMoriah Waterland /*
5205c51f124SMoriah Waterland * acquire package lock
5215c51f124SMoriah Waterland */
5225c51f124SMoriah Waterland
5235c51f124SMoriah Waterland if (a_lflags & ZLOCKS_PKG_ADMIN) {
5245c51f124SMoriah Waterland
5255c51f124SMoriah Waterland /*
5265c51f124SMoriah Waterland * zone administration is locked; lock package administration if
5275c51f124SMoriah Waterland * not already locked; if the lock cannot be released, stop,
5285c51f124SMoriah Waterland * release the zone administration lock and return an error
5295c51f124SMoriah Waterland */
5305c51f124SMoriah Waterland
5315c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_ZONE_PKGADM, a_zlst->_zlName,
5325c51f124SMoriah Waterland LOBJ_PKGADMIN);
5335c51f124SMoriah Waterland
5345c51f124SMoriah Waterland b = _z_lock_zone_object(&a_zlst->_zlLockObjects,
5355c51f124SMoriah Waterland scratchName, LOBJ_PKGADMIN, (pid_t)0,
5365c51f124SMoriah Waterland MSG_ZONES_LCK_ZONE_PKGADM,
5375c51f124SMoriah Waterland ERR_ZONES_LCK_ZONE_PKGADM);
5385c51f124SMoriah Waterland if (b == B_FALSE) {
5395c51f124SMoriah Waterland (void) _z_unlock_zone(a_zlst, a_lflags);
5405c51f124SMoriah Waterland return (b);
5415c51f124SMoriah Waterland }
5425c51f124SMoriah Waterland }
5435c51f124SMoriah Waterland
5445c51f124SMoriah Waterland /*
5455c51f124SMoriah Waterland * all locks have been obtained - return success!
5465c51f124SMoriah Waterland */
5475c51f124SMoriah Waterland
5485c51f124SMoriah Waterland return (B_TRUE);
5495c51f124SMoriah Waterland }
5505c51f124SMoriah Waterland
5515c51f124SMoriah Waterland /*
5525c51f124SMoriah Waterland * Name: _z_lock_zone_object
5535c51f124SMoriah Waterland * Description: lock a single lock object in a specified zone
5545c51f124SMoriah Waterland * Arguments: r_objectLocks - [RW, *RW] - (char **)
5555c51f124SMoriah Waterland * Pointer to handle to character string containing a list
5565c51f124SMoriah Waterland * of all objects locked for this zone - this string will
5575c51f124SMoriah Waterland * have the key to release the specified object added to it
5585c51f124SMoriah Waterland * if the lock is acquired.
5595c51f124SMoriah Waterland * a_zoneName - [RO, *RO] - (char *)
5605c51f124SMoriah Waterland * Pointer to string representing the name of the zone to
5615c51f124SMoriah Waterland * acquire the specified lock on
5625c51f124SMoriah Waterland * a_lockObject - [RO, *RO] - (char *)
5635c51f124SMoriah Waterland * Pointer to string representing the lock object to
5645c51f124SMoriah Waterland * acquire on the specified zone
5655c51f124SMoriah Waterland * a_pid - [RO, *RO] - (pid_t)
5665c51f124SMoriah Waterland * Process i.d. to associate with this lock
5675c51f124SMoriah Waterland * == 0 - no process i.d. associated with the lock
5685c51f124SMoriah Waterland * a_waitingMsg - [RO, *RO] - (char *)
5695c51f124SMoriah Waterland * Localized message to be output if waiting for the lock
5705c51f124SMoriah Waterland * because the lock cannot be immediately be acquired
5715c51f124SMoriah Waterland * a_busyMsg - [RO, *RO] - (char *)
5725c51f124SMoriah Waterland * Localized message to be output if the lock cannot be
5735c51f124SMoriah Waterland * released
5745c51f124SMoriah Waterland * Returns: boolean_t
5755c51f124SMoriah Waterland * B_TRUE - lock released
5765c51f124SMoriah Waterland * B_FALSE - lock not released
5775c51f124SMoriah Waterland */
5785c51f124SMoriah Waterland
5795c51f124SMoriah Waterland boolean_t
_z_lock_zone_object(char ** r_objectLocks,char * a_zoneName,char * a_lockObject,pid_t a_pid,char * a_waitingMsg,char * a_busyMsg)5805c51f124SMoriah Waterland _z_lock_zone_object(char **r_objectLocks, char *a_zoneName, char *a_lockObject,
5815c51f124SMoriah Waterland pid_t a_pid, char *a_waitingMsg, char *a_busyMsg)
5825c51f124SMoriah Waterland {
5835c51f124SMoriah Waterland boolean_t b;
5845c51f124SMoriah Waterland char *p = (char *)NULL;
5855c51f124SMoriah Waterland char lockItem[LOCK_OBJECT_MAXLEN+LOCK_KEY_MAXLEN+4];
5865c51f124SMoriah Waterland char lockKey[LOCK_KEY_MAXLEN+2];
5875c51f124SMoriah Waterland char lockObject[LOCK_OBJECT_MAXLEN+2];
5885c51f124SMoriah Waterland int i;
5895c51f124SMoriah Waterland
5905c51f124SMoriah Waterland /* entry assertions */
5915c51f124SMoriah Waterland
5925c51f124SMoriah Waterland assert(r_objectLocks != (char **)NULL);
5935c51f124SMoriah Waterland assert(a_zoneName != (char *)NULL);
5945c51f124SMoriah Waterland assert(a_waitingMsg != (char *)NULL);
5955c51f124SMoriah Waterland assert(a_busyMsg != (char *)NULL);
5965c51f124SMoriah Waterland assert(a_lockObject != (char *)NULL);
5975c51f124SMoriah Waterland assert(*a_lockObject != '\0');
5985c51f124SMoriah Waterland
5995c51f124SMoriah Waterland /* entry debugging info */
6005c51f124SMoriah Waterland
6015c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_OBJ, a_lockObject, a_zoneName, a_pid,
6025c51f124SMoriah Waterland *r_objectLocks ? *r_objectLocks : "");
6035c51f124SMoriah Waterland
6045c51f124SMoriah Waterland /* if lock objects held search for object to lock */
6055c51f124SMoriah Waterland
6065c51f124SMoriah Waterland if (*r_objectLocks != (char *)NULL) {
6075c51f124SMoriah Waterland for (i = 0; ; i++) {
6085c51f124SMoriah Waterland /* get next object locked on this zone */
6095c51f124SMoriah Waterland _z_strGetToken_r((char *)NULL, *r_objectLocks, i, "\n",
6105c51f124SMoriah Waterland lockItem, sizeof (lockItem));
6115c51f124SMoriah Waterland
6125c51f124SMoriah Waterland /* break out of loop if no more locks in list */
6135c51f124SMoriah Waterland
6145c51f124SMoriah Waterland if (lockItem[0] == '\0') {
6155c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_OBJ_NOTHELD,
6165c51f124SMoriah Waterland a_lockObject, a_zoneName);
6175c51f124SMoriah Waterland break;
6185c51f124SMoriah Waterland }
6195c51f124SMoriah Waterland
6205c51f124SMoriah Waterland /* get object and key for this lock */
6215c51f124SMoriah Waterland _z_strGetToken_r((char *)NULL, lockItem, 0, "\t",
6225c51f124SMoriah Waterland lockObject, sizeof (lockObject));
6235c51f124SMoriah Waterland _z_strGetToken_r((char *)NULL, lockItem, 1, "\t",
6245c51f124SMoriah Waterland lockKey, sizeof (lockKey));
6255c51f124SMoriah Waterland
6265c51f124SMoriah Waterland /* return success if the lock is held */
6275c51f124SMoriah Waterland
6285c51f124SMoriah Waterland if (strcmp(lockObject, a_lockObject) == 0) {
6295c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_OBJ_FOUND,
6305c51f124SMoriah Waterland lockObject, lockKey);
6315c51f124SMoriah Waterland return (B_TRUE);
6325c51f124SMoriah Waterland }
6335c51f124SMoriah Waterland
6345c51f124SMoriah Waterland /* not the object to lock - scan next object */
6355c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_OBJ_NOTFOUND, lockObject,
6365c51f124SMoriah Waterland lockKey);
6375c51f124SMoriah Waterland }
6385c51f124SMoriah Waterland }
6395c51f124SMoriah Waterland
6405c51f124SMoriah Waterland /*
6415c51f124SMoriah Waterland * the object to lock is not held - acquire the lock
6425c51f124SMoriah Waterland */
6435c51f124SMoriah Waterland
6445c51f124SMoriah Waterland /* acquire object with no wait */
6455c51f124SMoriah Waterland b = _z_acquire_lock(&p, a_zoneName, a_lockObject, a_pid, B_FALSE);
6465c51f124SMoriah Waterland if (b == B_FALSE) {
6475c51f124SMoriah Waterland /* failure - output message and acquire with wait */
6485c51f124SMoriah Waterland _z_echo(a_waitingMsg, (long)MAX_RETRIES*RETRY_DELAY_SECS,
6495c51f124SMoriah Waterland a_zoneName, _z_global_data._z_root_dir);
6505c51f124SMoriah Waterland b = _z_acquire_lock(&p, a_zoneName, a_lockObject, a_pid,
6515c51f124SMoriah Waterland B_TRUE);
6525c51f124SMoriah Waterland }
6535c51f124SMoriah Waterland
6545c51f124SMoriah Waterland /* output error message and return failure if both acquires failed */
6555c51f124SMoriah Waterland if (b == B_FALSE) {
6565c51f124SMoriah Waterland _z_program_error(a_busyMsg, a_zoneName);
6575c51f124SMoriah Waterland return (b);
6585c51f124SMoriah Waterland }
6595c51f124SMoriah Waterland
6605c51f124SMoriah Waterland /* add object/key to held locks */
6615c51f124SMoriah Waterland
6625c51f124SMoriah Waterland _z_strPrintf_r(lockItem, sizeof (lockItem), "%s\t%s", a_lockObject, p);
6635c51f124SMoriah Waterland _z_strAddToken(r_objectLocks, lockItem, '\n');
6645c51f124SMoriah Waterland
6655c51f124SMoriah Waterland free(p);
6665c51f124SMoriah Waterland
6675c51f124SMoriah Waterland /* return success */
6685c51f124SMoriah Waterland return (B_TRUE);
6695c51f124SMoriah Waterland }
6705c51f124SMoriah Waterland
6715c51f124SMoriah Waterland /*
6725c51f124SMoriah Waterland * Name: _z_release_lock
6735c51f124SMoriah Waterland * Description: release a lock held on a zone
6745c51f124SMoriah Waterland * Arguments: a_zoneName - [RO, *RO] - (char *)
6755c51f124SMoriah Waterland * Pointer to string representing the name of the zone to
6765c51f124SMoriah Waterland * release the specified lock on
6775c51f124SMoriah Waterland * a_lockObject - [RO, *RO] - (char *)
6785c51f124SMoriah Waterland * Pointer to string representing the lock object to
6795c51f124SMoriah Waterland * release on the specified zone
6805c51f124SMoriah Waterland * a_lockKey - [RO, *RO] - (char *)
6815c51f124SMoriah Waterland * Pointer to string representing the lock key associated
6825c51f124SMoriah Waterland * with the lock object to be released - this key is
6835c51f124SMoriah Waterland * returned when the lock is acquired and must be provided
6845c51f124SMoriah Waterland * when releasing the lock
6855c51f124SMoriah Waterland * a_wait - [RO, *RO] - (int)
6865c51f124SMoriah Waterland * Determines what to do if the lock cannot be released:
6875c51f124SMoriah Waterland * == B_TRUE - wait for the lock to be released
6885c51f124SMoriah Waterland * == B_FALSE - do not wait for the lock to be released
6895c51f124SMoriah Waterland * Returns: boolean_t
6905c51f124SMoriah Waterland * B_TRUE - lock released
6915c51f124SMoriah Waterland * B_FALSE - lock not released
6925c51f124SMoriah Waterland */
6935c51f124SMoriah Waterland
6945c51f124SMoriah Waterland boolean_t
_z_release_lock(char * a_zoneName,char * a_lockObject,char * a_lockKey,boolean_t a_wait)6955c51f124SMoriah Waterland _z_release_lock(char *a_zoneName, char *a_lockObject, char *a_lockKey,
6965c51f124SMoriah Waterland boolean_t a_wait)
6975c51f124SMoriah Waterland {
6985c51f124SMoriah Waterland argArray_t *args;
6995c51f124SMoriah Waterland boolean_t b;
7005c51f124SMoriah Waterland char *adjustedLockObject = (char *)NULL;
7015c51f124SMoriah Waterland char *results = (char *)NULL;
7025c51f124SMoriah Waterland int r;
7035c51f124SMoriah Waterland int status;
7045c51f124SMoriah Waterland
7055c51f124SMoriah Waterland /* entry assertions */
7065c51f124SMoriah Waterland
7075c51f124SMoriah Waterland assert(a_zoneName != (char *)NULL);
7085c51f124SMoriah Waterland assert(a_lockObject != (char *)NULL);
7095c51f124SMoriah Waterland assert(*a_lockObject != '\0');
7105c51f124SMoriah Waterland assert(a_lockKey != (char *)NULL);
7115c51f124SMoriah Waterland assert(*a_lockKey != '\0');
7125c51f124SMoriah Waterland
7135c51f124SMoriah Waterland /* entry debugging info */
7145c51f124SMoriah Waterland
7155c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_RELK, a_zoneName, a_lockObject,
7165c51f124SMoriah Waterland a_lockKey ? a_lockKey : "");
7175c51f124SMoriah Waterland
7185c51f124SMoriah Waterland /*
7195c51f124SMoriah Waterland * Only one lock file must ever be used - the one located on the root
7205c51f124SMoriah Waterland * file system of the currently running Solaris instance. To allow for
7215c51f124SMoriah Waterland * alternative roots to be properly locked, adjust the lock object to
7225c51f124SMoriah Waterland * take root path into account; if necessary, the root path will be
7235c51f124SMoriah Waterland * prepended to the lock object.
7245c51f124SMoriah Waterland */
7255c51f124SMoriah Waterland
7265c51f124SMoriah Waterland b = _z_adjust_lock_object_for_rootpath(&adjustedLockObject,
7275c51f124SMoriah Waterland a_lockObject);
7285c51f124SMoriah Waterland if (!b) {
7295c51f124SMoriah Waterland return (B_FALSE);
7305c51f124SMoriah Waterland }
7315c51f124SMoriah Waterland
7325c51f124SMoriah Waterland /*
7335c51f124SMoriah Waterland * construct command arguments:
7345c51f124SMoriah Waterland * pkgadm lock -r -o adjustedLockObject -k a_lockKey [-w -W timeout]
7355c51f124SMoriah Waterland */
7365c51f124SMoriah Waterland
7375c51f124SMoriah Waterland args = _z_new_args(20); /* generate new arg list */
7385c51f124SMoriah Waterland (void) _z_add_arg(args, PKGADM_CMD); /* pkgadm command */
7395c51f124SMoriah Waterland (void) _z_add_arg(args, "lock"); /* lock sub-command */
7405c51f124SMoriah Waterland (void) _z_add_arg(args, "-r"); /* release lock */
7415c51f124SMoriah Waterland (void) _z_add_arg(args, "-o"); /* object to release */
7425c51f124SMoriah Waterland (void) _z_add_arg(args, "%s", adjustedLockObject);
7435c51f124SMoriah Waterland (void) _z_add_arg(args, "-k"); /* object's key */
7445c51f124SMoriah Waterland (void) _z_add_arg(args, "%s", a_lockKey);
7455c51f124SMoriah Waterland
7465c51f124SMoriah Waterland /* add [ -w -W timeout ] if waiting for lock */
7475c51f124SMoriah Waterland
7485c51f124SMoriah Waterland if (a_wait == B_TRUE) {
7495c51f124SMoriah Waterland (void) _z_add_arg(args, "-w"); /* wait */
7505c51f124SMoriah Waterland (void) _z_add_arg(args, "-W"); /* wait timeout */
7515c51f124SMoriah Waterland (void) _z_add_arg(args, "%ld",
7525c51f124SMoriah Waterland (long)MAX_RETRIES*RETRY_DELAY_SECS);
7535c51f124SMoriah Waterland }
7545c51f124SMoriah Waterland
7555c51f124SMoriah Waterland /* execute command */
7565c51f124SMoriah Waterland
7575c51f124SMoriah Waterland r = _z_zone_exec(&status, &results, (char *)NULL, PKGADM_CMD,
7585c51f124SMoriah Waterland _z_get_argv(args), a_zoneName, (int *)NULL);
7595c51f124SMoriah Waterland
7605c51f124SMoriah Waterland /* free generated argument list */
7615c51f124SMoriah Waterland
7625c51f124SMoriah Waterland _z_free_args(args);
7635c51f124SMoriah Waterland
7645c51f124SMoriah Waterland /* exit debugging info */
7655c51f124SMoriah Waterland
7665c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_RELK_EXIT, adjustedLockObject, a_lockKey,
7675c51f124SMoriah Waterland a_zoneName, r, status, results ? results : "");
7685c51f124SMoriah Waterland
7695c51f124SMoriah Waterland /* free adjusted lock object */
7705c51f124SMoriah Waterland
7715c51f124SMoriah Waterland free(adjustedLockObject);
7725c51f124SMoriah Waterland free(results);
7735c51f124SMoriah Waterland
7745c51f124SMoriah Waterland return (((r == 0) && (status == 0)) ? B_TRUE : B_FALSE);
7755c51f124SMoriah Waterland }
7765c51f124SMoriah Waterland
7775c51f124SMoriah Waterland
7785c51f124SMoriah Waterland
7795c51f124SMoriah Waterland /*
7805c51f124SMoriah Waterland * Name: _z_unlock_zone
7815c51f124SMoriah Waterland * Description: Released specified locks on specified zone
7825c51f124SMoriah Waterland * Arguments: a_zlst - [RO, *RW] - (zoneListElement_t *)
7835c51f124SMoriah Waterland * Pointer to zone list structure element describing
7845c51f124SMoriah Waterland * the zone the unlock - the structure is updated by
7855c51f124SMoriah Waterland * removing the lock object and key if the locks are
7865c51f124SMoriah Waterland * successfully released
7875c51f124SMoriah Waterland * a_lflags - [RO, *RO] - (ZLOCKS_T)
7885c51f124SMoriah Waterland * Flags indicating which locks to release on the zone
7895c51f124SMoriah Waterland * Returns: boolean_t
7905c51f124SMoriah Waterland * == B_TRUE - locks successfully released
7915c51f124SMoriah Waterland * == B_FALSE - failed to release the locks
7925c51f124SMoriah Waterland */
7935c51f124SMoriah Waterland
7945c51f124SMoriah Waterland boolean_t
_z_unlock_zone(zoneListElement_t * a_zlst,ZLOCKS_T a_lflags)7955c51f124SMoriah Waterland _z_unlock_zone(zoneListElement_t *a_zlst, ZLOCKS_T a_lflags)
7965c51f124SMoriah Waterland {
7975c51f124SMoriah Waterland char *scratchName;
7985c51f124SMoriah Waterland boolean_t b;
7995c51f124SMoriah Waterland boolean_t errors = B_FALSE;
8005c51f124SMoriah Waterland
8015c51f124SMoriah Waterland /* entry assertions */
8025c51f124SMoriah Waterland
8035c51f124SMoriah Waterland assert(a_zlst != (zoneListElement_t *)NULL);
8045c51f124SMoriah Waterland
8055c51f124SMoriah Waterland /* entry debugging info */
8065c51f124SMoriah Waterland
8075c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_ZONE, a_zlst->_zlName, a_lflags);
8085c51f124SMoriah Waterland
8095c51f124SMoriah Waterland scratchName = a_zlst->_zlScratchName == NULL ? a_zlst->_zlName :
8105c51f124SMoriah Waterland a_zlst->_zlScratchName;
8115c51f124SMoriah Waterland
8125c51f124SMoriah Waterland if (a_lflags & ZLOCKS_PKG_ADMIN) {
8135c51f124SMoriah Waterland /*
8145c51f124SMoriah Waterland * if locked, unlock package administration lock
8155c51f124SMoriah Waterland * if the lock cannot be released, continue anyway
8165c51f124SMoriah Waterland */
8175c51f124SMoriah Waterland
8185c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_ZONE_PKGADM, a_zlst->_zlName,
8195c51f124SMoriah Waterland LOBJ_PKGADMIN);
8205c51f124SMoriah Waterland
8215c51f124SMoriah Waterland b = _z_unlock_zone_object(&a_zlst->_zlLockObjects,
8225c51f124SMoriah Waterland scratchName, LOBJ_PKGADMIN,
8235c51f124SMoriah Waterland WRN_ZONES_ULK_ZONE_PKGADM);
8245c51f124SMoriah Waterland if (b == B_FALSE) {
8255c51f124SMoriah Waterland errors = B_TRUE;
8265c51f124SMoriah Waterland }
8275c51f124SMoriah Waterland }
8285c51f124SMoriah Waterland
8295c51f124SMoriah Waterland if (a_lflags & ZLOCKS_ZONE_ADMIN) {
8305c51f124SMoriah Waterland
8315c51f124SMoriah Waterland /*
8325c51f124SMoriah Waterland * if locked, unlock zone administration lock
8335c51f124SMoriah Waterland * if the lock cannot be released, continue anyway
8345c51f124SMoriah Waterland */
8355c51f124SMoriah Waterland
8365c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_ZONE_ZONEADM, a_zlst->_zlName,
8375c51f124SMoriah Waterland LOBJ_ZONEADMIN);
8385c51f124SMoriah Waterland
8395c51f124SMoriah Waterland b = _z_unlock_zone_object(&a_zlst->_zlLockObjects,
8405c51f124SMoriah Waterland scratchName, LOBJ_ZONEADMIN,
8415c51f124SMoriah Waterland WRN_ZONES_ULK_ZONE_ZONEADM);
8425c51f124SMoriah Waterland if (b == B_FALSE) {
8435c51f124SMoriah Waterland errors = B_TRUE;
8445c51f124SMoriah Waterland }
8455c51f124SMoriah Waterland }
8465c51f124SMoriah Waterland
8475c51f124SMoriah Waterland return (!errors);
8485c51f124SMoriah Waterland }
8495c51f124SMoriah Waterland
8505c51f124SMoriah Waterland /*
8515c51f124SMoriah Waterland * Name: _z_unlock_zone_object
8525c51f124SMoriah Waterland * Description: unlock a single lock object in a specified zone
8535c51f124SMoriah Waterland * Arguments: r_objectLocks - [RW, *RW] - (char **)
8545c51f124SMoriah Waterland * Pointer to handle to character string containing a list
8555c51f124SMoriah Waterland * of all objects locked for this zone - this string must
8565c51f124SMoriah Waterland * contain the key to release the specified object - if not
8575c51f124SMoriah Waterland * then the lock is not released - if so then the lock is
8585c51f124SMoriah Waterland * released and the key is removed from this list.
8595c51f124SMoriah Waterland * a_zoneName - [RO, *RO] - (char *)
8605c51f124SMoriah Waterland * Pointer to string representing the name of the zone to
8615c51f124SMoriah Waterland * release the specified lock on
8625c51f124SMoriah Waterland * a_lockObject - [RO, *RO] - (char *)
8635c51f124SMoriah Waterland * Pointer to string representing the lock object to
8645c51f124SMoriah Waterland * release on the specified zone
8655c51f124SMoriah Waterland * a_errMsg - [RO, *RO] - (char *)
8665c51f124SMoriah Waterland * Localized message to be output if the lock cannot be
8675c51f124SMoriah Waterland * released
8685c51f124SMoriah Waterland * Returns: boolean_t
8695c51f124SMoriah Waterland * B_TRUE - lock released
8705c51f124SMoriah Waterland * B_FALSE - lock not released
8715c51f124SMoriah Waterland */
8725c51f124SMoriah Waterland
8735c51f124SMoriah Waterland boolean_t
_z_unlock_zone_object(char ** r_objectLocks,char * a_zoneName,char * a_lockObject,char * a_errMsg)8745c51f124SMoriah Waterland _z_unlock_zone_object(char **r_objectLocks, char *a_zoneName,
8755c51f124SMoriah Waterland char *a_lockObject, char *a_errMsg)
8765c51f124SMoriah Waterland {
8775c51f124SMoriah Waterland boolean_t b;
8785c51f124SMoriah Waterland char lockItem[LOCK_OBJECT_MAXLEN+LOCK_KEY_MAXLEN+4];
8795c51f124SMoriah Waterland char lockKey[LOCK_KEY_MAXLEN+2];
8805c51f124SMoriah Waterland char lockObject[LOCK_OBJECT_MAXLEN+2];
8815c51f124SMoriah Waterland int i;
8825c51f124SMoriah Waterland
8835c51f124SMoriah Waterland /* entry assertions */
8845c51f124SMoriah Waterland
8855c51f124SMoriah Waterland assert(r_objectLocks != (char **)NULL);
8865c51f124SMoriah Waterland assert(a_zoneName != (char *)NULL);
8875c51f124SMoriah Waterland assert(a_errMsg != (char *)NULL);
8885c51f124SMoriah Waterland assert(a_lockObject != (char *)NULL);
8895c51f124SMoriah Waterland assert(*a_lockObject != '\0');
8905c51f124SMoriah Waterland
8915c51f124SMoriah Waterland /* entry debugging info */
8925c51f124SMoriah Waterland
8935c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_OBJ, a_lockObject, a_zoneName,
8945c51f124SMoriah Waterland *r_objectLocks ? *r_objectLocks : "");
8955c51f124SMoriah Waterland
8965c51f124SMoriah Waterland /* return success if no objects are locked */
8975c51f124SMoriah Waterland
8985c51f124SMoriah Waterland if (*r_objectLocks == (char *)NULL) {
8995c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_OBJ_NONE, a_zoneName);
9005c51f124SMoriah Waterland return (B_TRUE);
9015c51f124SMoriah Waterland }
9025c51f124SMoriah Waterland
9035c51f124SMoriah Waterland /* see if the specified lock is held on this zone */
9045c51f124SMoriah Waterland
9055c51f124SMoriah Waterland for (i = 0; ; i++) {
9065c51f124SMoriah Waterland /* get next object locked on this zone */
9075c51f124SMoriah Waterland _z_strGetToken_r((char *)NULL, *r_objectLocks, i, "\n",
9085c51f124SMoriah Waterland lockItem, sizeof (lockItem));
9095c51f124SMoriah Waterland
9105c51f124SMoriah Waterland /* return success if no more objects locked */
9115c51f124SMoriah Waterland if (lockItem[0] == '\0') {
9125c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_OBJ_NOTHELD, a_lockObject,
9135c51f124SMoriah Waterland a_zoneName);
9145c51f124SMoriah Waterland return (B_TRUE);
9155c51f124SMoriah Waterland }
9165c51f124SMoriah Waterland
9175c51f124SMoriah Waterland /* get object and key for this lock */
9185c51f124SMoriah Waterland _z_strGetToken_r((char *)NULL, lockItem, 0, "\t",
9195c51f124SMoriah Waterland lockObject, sizeof (lockObject));
9205c51f124SMoriah Waterland _z_strGetToken_r((char *)NULL, lockItem, 1, "\t",
9215c51f124SMoriah Waterland lockKey, sizeof (lockKey));
9225c51f124SMoriah Waterland
9235c51f124SMoriah Waterland /* break out of loop if object is the one to unlock */
9245c51f124SMoriah Waterland
9255c51f124SMoriah Waterland if (strcmp(lockObject, a_lockObject) == 0) {
9265c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_OBJ_FOUND, lockObject,
9275c51f124SMoriah Waterland lockKey);
9285c51f124SMoriah Waterland break;
9295c51f124SMoriah Waterland }
9305c51f124SMoriah Waterland
9315c51f124SMoriah Waterland /* not the object to unlock - scan next object */
9325c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_OBJ_NOTFOUND, lockObject, lockKey);
9335c51f124SMoriah Waterland }
9345c51f124SMoriah Waterland
9355c51f124SMoriah Waterland /*
9365c51f124SMoriah Waterland * the object to unlock is held - release the lock
9375c51f124SMoriah Waterland */
9385c51f124SMoriah Waterland
9395c51f124SMoriah Waterland /* release object with wait */
9405c51f124SMoriah Waterland
9415c51f124SMoriah Waterland b = _z_release_lock(a_zoneName, a_lockObject, lockKey, B_TRUE);
9425c51f124SMoriah Waterland if (b == B_FALSE) {
9435c51f124SMoriah Waterland /* failure - issue error message and return failure */
9445c51f124SMoriah Waterland _z_program_error(a_errMsg, a_zoneName);
9455c51f124SMoriah Waterland return (b);
9465c51f124SMoriah Waterland }
9475c51f124SMoriah Waterland
9485c51f124SMoriah Waterland /* remove object/key from held locks */
9495c51f124SMoriah Waterland
9505c51f124SMoriah Waterland _z_strRemoveToken(r_objectLocks, lockItem, "\n", 0);
9515c51f124SMoriah Waterland
9525c51f124SMoriah Waterland /* return success */
9535c51f124SMoriah Waterland
9545c51f124SMoriah Waterland return (B_TRUE);
9555c51f124SMoriah Waterland }
956