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 .ioclass import IoClassesInfo, IoClassInfo
from .stats.shared import UsageStats, RequestsStats, BlocksStats, ErrorsStats
from .ctx import OcfCtx
class Backfill(Structure):
@ -474,7 +475,7 @@ class Cache:
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
)
@ -500,7 +501,7 @@ class Cache:
def load_cache(self, device, open_cores=True):
self.configure_device(device, open_cores=open_cores)
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
)
@ -509,8 +510,11 @@ class Cache:
raise OcfError("Loading cache device failed", c.results["error"])
@classmethod
def load_from_device(cls, device, name="cache", open_cores=True):
c = cls(name=name, owner=device.owner)
def load_from_device(cls, device, owner=None, name="cache", open_cores=True):
if owner is None:
owner = OcfCtx.get_default()
c = cls(name=name, owner=owner)
c.start_cache()
try:
@ -522,8 +526,11 @@ class Cache:
return c
@classmethod
def start_on_device(cls, device, **kwargs):
c = cls(owner=device.owner, **kwargs)
def start_on_device(cls, device, owner=None, **kwargs):
if owner is None:
owner = OcfCtx.get_default()
c = cls(owner=owner, **kwargs)
c.start_cache()
try:

View File

@ -4,6 +4,7 @@
#
from ctypes import c_void_p, Structure, c_char_p, cast, pointer, byref, c_int
import weakref
from .logger import LoggerOps, Logger
from .data import DataOps, Data
@ -27,6 +28,8 @@ class OcfCtxCfg(Structure):
class OcfCtx:
default = None
def __init__(self, lib, name, logger, data, cleaner):
self.logger = logger
self.data = data
@ -51,10 +54,29 @@ class OcfCtx:
if result != 0:
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):
self.volume_types[self.volume_types_count] = volume_type
volume_type.type_id = self.volume_types_count
volume_type.owner = self
result = self.lib.ocf_ctx_register_volume_type(
self.ctx_handle,
@ -90,26 +112,8 @@ class OcfCtx:
self.cleanup_volume_types()
self.lib.ocf_ctx_put(self.ctx_handle)
self.cfg = 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,
)
if type(self).default and type(self).default() == self:
type(self).default = None
lib = OcfLib.getInstance()

View File

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