#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#
import errno
import fcntl
import os
import platform
"""A class that provides generic lockfile support. This
allows Python processes to perform inter-process locking
using the filesystem."""
"""Create a LockFile object. The 'filepath' argument
should be the path to the file that will be used as the
lockfile. If the caller may supply the following
optional arguments:
set_lockstr - A function that returns a string. This
is called when the lock operation wants to write
implementation specific text into the lock file.
get_lockstr - A function that takes a string and returns
a dictionary. This function must be able to parse
the lock string created by set_lockstr. The dictionary
object is passed as **kwargs to 'failure_exc' if
the lock is non-blocking and fails.
failure_exc - If a non-blocking lock acquisition fails,
this exception will be raised. It should allow the
caller to specify a kwargs argument, but not all
invocations will provide kwargs.
provide_mutex - By default, the LockFile object
will use a mutex to sychronize access for threads in
the current process. If the caller is already providing
mutual exclusion to the LockFile object, this should
be set to False."""
if failure_exc:
else:
if provide_mutex:
else:
if self._provide_mutex:
"""Lock the lockfile, to prevent access from other
processes. If blocking is False, this method will
return an exception, instead of blocking, if the lock
is held. If the lockfile cannot be opened,
this method may return an EnvironmentError."""
#
# The password locking in cfgfiles.py depends on the behavior
# of this function, which imitates that of libc's lckpwdf(3C).
# If this function is changed, it either needs to continue to be
# compatible with lckpwdf, or changes to cfgfiles.py must be
# made.
#
# Lock acquisition failed.
if not rval:
raise self._failure_exc()
if not blocking:
# Attempt an initial open of the lock file.
lf = None
# Caller should catch EACCES and EROFS.
try:
# If the file is a symlink we catch an exception
# and do not update the file.
except OSError as e:
raise api_errors.UnexpectedLinkError(
e.errno)
raise e
except:
raise
# Attempt to lock the file.
try:
except IOError as e:
raise
# If the lock failed (because it is likely contended),
# then extract the information about the lock acquirer
# and raise an exception.
if self._get_lockstr:
else:
lock_dict = {}
# Store information about the lock acquirer and write it.
try:
lock_str = None
if self._set_lockstr:
if lock_str:
except:
raise
"""Unlocks the LockFile."""
# To avoid race conditions with the next caller
# waiting for the lock file, it is simply
# truncated instead of removed.
try:
except EnvironmentError:
# If fcntl, or the file operations returned
# an exception, drop the lock. Do not catch
# the exception that could escape from
# releasing the lock.
raise
finally:
else:
if self._provide_mutex:
"""Generic exception class used by LockFile. Raised
in non-blocking mode when file or thread is already locked."""
if args:
else:
errstr = "Unable to lock file"
return errstr
lockdict = {}
try:
return lockdict
except ValueError:
return lockdict
def client_lock_set_str():
lock_dict = {}
try:
return lock_dict
except ValueError:
return lock_dict
def generic_lock_set_str():