lib/zfs_mgmt.rb in zfs_mgmt-0.4.7 vs lib/zfs_mgmt.rb in zfs_mgmt-0.4.8
- old
+ new
@@ -6,10 +6,11 @@
require 'date'
require 'logger'
require 'text-table'
require 'open3'
require 'filesize'
+require 'timeout'
$logger = Logger.new(STDERR, progname: 'zfs_mgmt')
$date_patterns = {
'hourly' => '%F Hour %H',
@@ -35,10 +36,12 @@
$properties_xlate = {
'userrefs' => ->(x) { x.to_i },
'creation' => ->(x) { x.to_i },
}
+$lock = nil
+
module ZfsMgmt
class << self
attr_accessor :global_options
end
class ZfsGetError < StandardError
@@ -684,8 +687,44 @@
unless props['zfsmgmt:destination']
$logger.error("#{zfs}: you must specify a destination zfs path via the user property zfsmgmt:destination, even if using --destination on the command line, skipping")
next
end
zfs_send(options,zfs,props,snaps)
+ end
+ end
+ def self.lock(options)
+ # open lock file, try to lock file until lock_wait has expired or
+ # lock is obtained, write pid?
+ return nil unless options[:lock]
+ begin
+ lock = File.open(options[:lock_file], File::RDWR|File::CREAT, 0644)
+ rescue Errno::ENOENT => error
+ $logger.error("unable to open lock file (#{options[:lock_file]}), possibly the directory doesn't exist")
+ raise
+ end
+ if options[:lock_wait] > 0
+ begin
+ status = Timeout::timeout(options[:lock_wait]) do
+ return lock if lock.flock(File::LOCK_EX)
+ $logger.error("flock of #{options[:lock_file]} failed")
+ raise "flock failed"
+ end
+ rescue Timeout::Error => error
+ $logger.error("timed out waiting to lock")
+ raise
+ end
+ else
+ # zero is wait forever!
+ return lock if lock.flock(File::LOCK_EX)
+ $logger.error("flock of #{options[:lock_file]} failed")
+ raise "flock failed"
+ end
+ $logger.error("unable to obtain lock")
+ raise "unknown failure in locking file"
+ end
+ def self.unlock(lock)
+ unless lock.nil?
+ lock.flock(File::LOCK_UN)
+ lock.close()
end
end
end