Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libstorage-ng for openSUSE:Factory checked in at 2026-10-31 23:06:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libstorage-ng (Old) and /work/SRC/openSUSE:Factory/.libstorage-ng.new.1255 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libstorage-ng" Sat Oct 31 23:06:38 2026 rev:360 rq:1393877 version:4.5.367 Changes: -------- --- /work/SRC/openSUSE:Factory/libstorage-ng/libstorage-ng.changes 2026-10-28 17:45:45.717090826 +0100 +++ /work/SRC/openSUSE:Factory/.libstorage-ng.new.1255/libstorage-ng.changes 2026-10-31 23:06:40.834733336 +0100 @@ -1,0 +2,11 @@ +Fri Oct 30 11:15:17 UTC 2026 - [email protected] + +- merge gh#openSUSE/libstorage-ng#1102 +- Do not call the logger during the garbage collection in the Ruby + bindings +- Remove unnecessary cast +- Make the logger-gc test independent of the garbage collector timing +- Do not sweep lazily in the logger-gc test +- 4.5.367 + +-------------------------------------------------------------------- Old: ---- libstorage-ng-4.5.366.tar.xz New: ---- libstorage-ng-4.5.367.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libstorage-ng.spec ++++++ --- /var/tmp/diff_new_pack.92iVwL/_old 2026-10-31 23:06:41.696768950 +0100 +++ /var/tmp/diff_new_pack.92iVwL/_new 2026-10-31 23:06:41.697768992 +0100 @@ -18,7 +18,7 @@ %define libname %{name}1 Name: libstorage-ng -Version: 4.5.366 +Version: 4.5.367 Release: 0 Summary: Library for storage management License: GPL-2.0-only ++++++ libstorage-ng-4.5.366.tar.xz -> libstorage-ng-4.5.367.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libstorage-ng-4.5.366/VERSION new/libstorage-ng-4.5.367/VERSION --- old/libstorage-ng-4.5.366/VERSION 2026-10-27 14:47:27.000000000 +0100 +++ new/libstorage-ng-4.5.367/VERSION 2026-10-30 12:15:17.000000000 +0100 @@ -1 +1 @@ -4.5.366 +4.5.367 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libstorage-ng-4.5.366/bindings/ruby/storage-ruby.i new/libstorage-ng-4.5.367/bindings/ruby/storage-ruby.i --- old/libstorage-ng-4.5.366/bindings/ruby/storage-ruby.i 2026-10-27 14:47:27.000000000 +0100 +++ new/libstorage-ng-4.5.367/bindings/ruby/storage-ruby.i 2026-10-30 12:15:17.000000000 +0100 @@ -4,8 +4,86 @@ %{ #include <sstream> + +#include "storage/Utils/Logger.h" + +namespace storage +{ + + /** + * Logger that is set as the current logger instead of the logger set from Ruby (usually a + * director object). + * + * Since SWIG 4.5 the destructor of a wrapped object, e.g. of a Storage, can be run by the + * garbage collector of Ruby while sweeping. Destructors can log and, since the logger is + * implemented in Ruby, that executes Ruby code, which is not allowed during the garbage + * collection (Ruby aborts with "object allocation during garbage collection phase"). + * + * So during the garbage collection nothing is logged and the logger from Ruby is not called. + */ + class GcSafeLogger : public Logger + { + public: + + Logger* get_target() const { return target; } + void set_target(Logger* target) { this->target = target; } + + virtual bool test(LogLevel log_level, const std::string& component) override + { + if (!target || rb_during_gc()) + return false; + + return target->test(log_level, component); + } + + virtual void write(LogLevel log_level, const std::string& component, const std::string& file, + int line, const std::string& function, const std::string& content) override + { + if (!target || rb_during_gc()) + return; + + target->write(log_level, component, file, line, function, content); + } + + private: + + Logger* target = nullptr; + + }; + + + static GcSafeLogger gc_safe_logger; + + + Logger* get_ruby_logger() + { + return gc_safe_logger.get_target(); + } + + + void set_ruby_logger(Logger* logger) + { + gc_safe_logger.set_target(logger); + + set_logger(logger ? &gc_safe_logger : nullptr); + } + +} %} +// Storage.logger and Storage.logger= use the GcSafeLogger. The wrapper code (argument +// conversion, return value) is not changed, only the called function. + +%feature("action") storage::get_logger +{ + result = storage::get_ruby_logger(); +} + +%feature("action") storage::set_logger +{ + storage::set_ruby_logger(arg1); +} + %rename("empty?") "empty"; %rename("%(regex:/^(get_)(.*)/\\2/)s") ""; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libstorage-ng-4.5.366/bindings/ruby/testsuite/Makefile.am new/libstorage-ng-4.5.367/bindings/ruby/testsuite/Makefile.am --- old/libstorage-ng-4.5.366/bindings/ruby/testsuite/Makefile.am 2026-10-27 14:47:27.000000000 +0100 +++ new/libstorage-ng-4.5.367/bindings/ruby/testsuite/Makefile.am 2026-10-30 12:15:17.000000000 +0100 @@ -3,7 +3,7 @@ # check_SCRIPTS = polymorphism.rb sid.rb all-types.rb logger.rb function-call.rb \ - to_s.rb + to_s.rb logger-gc.rb TESTS = $(check_SCRIPTS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libstorage-ng-4.5.366/bindings/ruby/testsuite/logger-gc.rb new/libstorage-ng-4.5.367/bindings/ruby/testsuite/logger-gc.rb --- old/libstorage-ng-4.5.366/bindings/ruby/testsuite/logger-gc.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/libstorage-ng-4.5.367/bindings/ruby/testsuite/logger-gc.rb 2026-10-30 12:15:17.000000000 +0100 @@ -0,0 +1,80 @@ +#!/usr/bin/ruby + +require 'test/unit' +require 'tmpdir' +require 'storage' + + +# Destructors of wrapped objects can be run by the garbage collector (since SWIG 4.5 even +# while sweeping) and they can log, e.g. the destructor of Storage logs if the temporary +# directory cannot be removed. The logger is implemented in Ruby and Ruby code must not be run +# during the garbage collection. + +class MyLogger < Storage::Logger + + attr_reader :lines + + def initialize + super + @lines = 0 + end + + def write(level, component, filename, line, function, content) + @lines += 1 + end + +end + + +class TestLoggerGc < Test::Unit::TestCase + + def new_storage + environment = Storage::Environment.new(true, Storage::ProbeMode_NONE, Storage::TargetMode_DIRECT) + Storage::Storage.new(environment) + end + + def test_logging_in_destructor_during_gc + + Dir.mktmpdir do |tmpdir| + + old_tmpdir = ENV['TMPDIR'] + ENV['TMPDIR'] = tmpdir + + begin + + logger = MyLogger.new + Storage::logger = logger + + # The storage objects are kept in a list so that the garbage collector cannot destroy any of + # them before all temporary directories are removed. + storages = Array.new(20) { new_storage } + + # The temporary directories of the storage objects are removed so that their destructors + # log an error. + Dir.children(tmpdir).each { |name| Dir.rmdir(File.join(tmpdir, name)) } + + storages.clear + + # The storage objects are destroyed by the garbage collector. + GC.start + + # Logging still works after the garbage collection. + + assert_not_nil(Storage::logger) + + lines = logger.lines + storage = new_storage + assert(logger.lines > lines) + + ensure + + Storage::logger = nil + ENV['TMPDIR'] = old_tmpdir + + end + + end + + end + +end
