module CephStorage # A reference to a Ceph pool # This is a collection of held open pool IOctx's for a given pool class Pool < ::CephRuby::Pool extend CephStorage::PoolWrapper include Multiton attr_accessor :cartridges, :cluster, :name, :close_lock, :pop_lock wrap_me :create, :exists?, :id, :auid=, :auid, :rados_block_device, :destroy, :stat, :flush_aio class << self protected :new end def initialize(cluster, name) log("init #{name}") self.close_lock = Mutex.new self.pop_lock = Mutex.new self.cluster = cluster self.name = name.to_s self.cartridges = [] end def rados_pool close_lock.synchronize {} h = pop return h unless block_given? begin yield(h) ensure push(h) end end def rados_pool=(pool) push(pool) end def storage_object(name, &block) CephStorage::StorageObject::RadosStorageObject.new(self, name, &block) end def storage_object_enumerator(&block) CephStorage::StorageObject::RadosStorageObjectEnumerator.new(self, &block) end def log(message) CephStorage.log("pool #{name} #{message}") end def size pop_lock.synchronize do cartridges.size end end def num_locked pop_lock.synchronize do cartridges.count { |c| c[:lock].locked? == true } end end def num_free pop_lock.synchronize do cartridges.count { |c| c[:lock].locked? == false } end end def close close_lock.synchronize do close_group(false) close_group(true) end end def path "ceph://#{cluster.cluster}/#{name}" end private def close_group(inuse) log("close pool objects with locked==#{inuse}") cartridges.select { |c| c[:lock].locked? == inuse }.each do |c| c[:pool].close cartridges.delete c end end def pop pop_lock.synchronize do cartridge = first_available_cartridge log("pop #{cartridge[:pool]}, #{cartridge[:lock].locked?}") cartridge[:lock].lock cartridge[:pool] end end def push(pool) log("push #{pool}") cartridge = cartridges.find { |c| c[:pool].equal?(pool) } cartridge[:lock].unlock if cartridge end def first_available_cartridge cartridge = cartridges.find { |c| c[:lock].locked? == false } cartridge = create_cartridge if cartridge.nil? cartridge end def create_cartridge log('create cartridge') cartridge = new_cartridge cartridges << cartridge cartridge end def new_cartridge { lock: Mutex.new, pool: new_pool } end def new_pool cluster.rados_cluster { |c| c.pool(name) } end end end