Fix pyocf Ctx ownership

Signed-off-by: Jan Musial <jan.musial@intel.com>
This commit is contained in:
Jan Musial 2021-09-09 10:18:03 +02:00
parent da59a1c9aa
commit 4c9d4fe24e
3 changed files with 41 additions and 30 deletions

View File

@ -37,6 +37,7 @@ from .queue import Queue
from .stats.cache import CacheInfo from .stats.cache import CacheInfo
from .ioclass import IoClassesInfo, IoClassInfo from .ioclass import IoClassesInfo, IoClassInfo
from .stats.shared import UsageStats, RequestsStats, BlocksStats, ErrorsStats from .stats.shared import UsageStats, RequestsStats, BlocksStats, ErrorsStats
from .ctx import OcfCtx
class Backfill(Structure): class Backfill(Structure):
@ -474,7 +475,7 @@ class Cache:
c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]) c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)])
device.owner.lib.ocf_mngt_cache_attach( self.owner.lib.ocf_mngt_cache_attach(
self.cache_handle, byref(self.dev_cfg), c, None self.cache_handle, byref(self.dev_cfg), c, None
) )
@ -500,7 +501,7 @@ class Cache:
def load_cache(self, device, open_cores=True): def load_cache(self, device, open_cores=True):
self.configure_device(device, open_cores=open_cores) self.configure_device(device, open_cores=open_cores)
c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]) c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)])
device.owner.lib.ocf_mngt_cache_load( self.owner.lib.ocf_mngt_cache_load(
self.cache_handle, byref(self.dev_cfg), c, None self.cache_handle, byref(self.dev_cfg), c, None
) )
@ -509,8 +510,11 @@ class Cache:
raise OcfError("Loading cache device failed", c.results["error"]) raise OcfError("Loading cache device failed", c.results["error"])
@classmethod @classmethod
def load_from_device(cls, device, name="cache", open_cores=True): def load_from_device(cls, device, owner=None, name="cache", open_cores=True):
c = cls(name=name, owner=device.owner) if owner is None:
owner = OcfCtx.get_default()
c = cls(name=name, owner=owner)
c.start_cache() c.start_cache()
try: try:
@ -522,8 +526,11 @@ class Cache:
return c return c
@classmethod @classmethod
def start_on_device(cls, device, **kwargs): def start_on_device(cls, device, owner=None, **kwargs):
c = cls(owner=device.owner, **kwargs) if owner is None:
owner = OcfCtx.get_default()
c = cls(owner=owner, **kwargs)
c.start_cache() c.start_cache()
try: try:

View File

@ -4,6 +4,7 @@
# #
from ctypes import c_void_p, Structure, c_char_p, cast, pointer, byref, c_int from ctypes import c_void_p, Structure, c_char_p, cast, pointer, byref, c_int
import weakref
from .logger import LoggerOps, Logger from .logger import LoggerOps, Logger
from .data import DataOps, Data from .data import DataOps, Data
@ -27,6 +28,8 @@ class OcfCtxCfg(Structure):
class OcfCtx: class OcfCtx:
default = None
def __init__(self, lib, name, logger, data, cleaner): def __init__(self, lib, name, logger, data, cleaner):
self.logger = logger self.logger = logger
self.data = data self.data = data
@ -51,10 +54,29 @@ class OcfCtx:
if result != 0: if result != 0:
raise OcfError("Context initialization failed", result) raise OcfError("Context initialization failed", result)
if self.default is None or self.default() is None:
type(self).default = weakref.ref(self)
@classmethod
def with_defaults(cls, logger):
return cls(
OcfLib.getInstance(),
b"PyOCF default ctx",
logger,
Data,
Cleaner,
)
@classmethod
def get_default(cls):
if cls.default is None or cls.default() is None:
raise Exception("No context instantiated yet")
return cls.default()
def register_volume_type(self, volume_type): def register_volume_type(self, volume_type):
self.volume_types[self.volume_types_count] = volume_type self.volume_types[self.volume_types_count] = volume_type
volume_type.type_id = self.volume_types_count volume_type.type_id = self.volume_types_count
volume_type.owner = self
result = self.lib.ocf_ctx_register_volume_type( result = self.lib.ocf_ctx_register_volume_type(
self.ctx_handle, self.ctx_handle,
@ -90,26 +112,8 @@ class OcfCtx:
self.cleanup_volume_types() self.cleanup_volume_types()
self.lib.ocf_ctx_put(self.ctx_handle) self.lib.ocf_ctx_put(self.ctx_handle)
if type(self).default and type(self).default() == self:
self.cfg = None type(self).default = None
self.logger = None
self.data = None
self.cleaner = None
Queue._instances_ = {}
Volume._instances_ = {}
Volume._uuid_ = {}
Data._instances_ = {}
Logger._instances_ = {}
def get_default_ctx(logger):
return OcfCtx(
OcfLib.getInstance(),
b"PyOCF default ctx",
logger,
Data,
Cleaner,
)
lib = OcfLib.getInstance() lib = OcfLib.getInstance()

View File

@ -11,7 +11,7 @@ import gc
sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir)) sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir))
from pyocf.types.logger import LogLevel, DefaultLogger, BufferLogger from pyocf.types.logger import LogLevel, DefaultLogger, BufferLogger
from pyocf.types.volume import Volume, ErrorDevice from pyocf.types.volume import Volume, ErrorDevice
from pyocf.types.ctx import get_default_ctx from pyocf.types.ctx import OcfCtx
def pytest_configure(config): def pytest_configure(config):
@ -20,7 +20,7 @@ def pytest_configure(config):
@pytest.fixture() @pytest.fixture()
def pyocf_ctx(): def pyocf_ctx():
c = get_default_ctx(DefaultLogger(LogLevel.WARN)) c = OcfCtx.with_defaults(DefaultLogger(LogLevel.WARN))
c.register_volume_type(Volume) c.register_volume_type(Volume)
c.register_volume_type(ErrorDevice) c.register_volume_type(ErrorDevice)
yield c yield c
@ -31,7 +31,7 @@ def pyocf_ctx():
@pytest.fixture() @pytest.fixture()
def pyocf_ctx_log_buffer(): def pyocf_ctx_log_buffer():
logger = BufferLogger(LogLevel.DEBUG) logger = BufferLogger(LogLevel.DEBUG)
c = get_default_ctx(logger) c = OcfCtx.with_defaults(logger)
c.register_volume_type(Volume) c.register_volume_type(Volume)
c.register_volume_type(ErrorDevice) c.register_volume_type(ErrorDevice)
yield logger yield logger