diff --git a/Cargo.toml b/Cargo.toml
index 4633410ed5..4462f55613 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,7 +31,7 @@ name = "integration"
path = "rust-bindings/tests/tests.rs"
[workspace]
-members = [".", "rust-bindings/sys"]
+members = [".", "src/sysroot-rs", "rust-bindings/sys"]
[dependencies]
base64 = "0.20.0"
diff --git a/Makefile-sysroot-rs.am b/Makefile-sysroot-rs.am
new file mode 100644
index 0000000000..8a48152685
--- /dev/null
+++ b/Makefile-sysroot-rs.am
@@ -0,0 +1,23 @@
+# Makefile for Rust lib
+#
+# SPDX-License-Identifier: LGPL-2.0+
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see .
+
+
+target/release/libostreesysrs.so: src/sysroot-rs/src/lib.rs
+ cargo build --release --workspace
+
+libostreesysrs_DATA = target/release/libostreesysrs.so
+libostreesysrsdir = $(pkglibexecdir)
diff --git a/Makefile.am b/Makefile.am
index 19abc0c1e1..ba9db0d759 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -134,6 +134,7 @@ include Makefile-switchroot.am
if BUILDOPT_FUSE
include src/rofiles-fuse/Makefile-inc.am
endif
+include Makefile-sysroot-rs.am
include Makefile-tests.am
include Makefile-boot.am
include Makefile-man.am
diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c
index 91b63f945a..498a17e7d8 100644
--- a/src/libostree/ostree-sysroot.c
+++ b/src/libostree/ostree-sysroot.c
@@ -21,6 +21,7 @@
#include "config.h"
#include "otutil.h"
+#include
#include
#include
#include
@@ -76,6 +77,29 @@ enum
G_DEFINE_TYPE (OstreeSysroot, ostree_sysroot, G_TYPE_OBJECT)
+static void *
+load_sysroot_rs (void)
+{
+ static gssize initialized = 0;
+ static void *sysrootrs = NULL;
+ if (g_once_init_enter (&initialized))
+ {
+ const char *uninstalled = g_getenv ("OSTREE_UNINSTALLED");
+ g_autofree char *path = NULL;
+ if (uninstalled)
+ path = g_strdup_printf ("%s/target/release/libostreesysrs.so", uninstalled);
+ else
+ path = g_strdup_printf ("%s/libostreesysrs.so", PKGLIBEXECDIR);
+ sysrootrs = dlopen (path, RTLD_NOW);
+ if (sysrootrs == NULL)
+ {
+ errx (EXIT_FAILURE, "failed to initialize libostreesysrs.so: %s", dlerror ());
+ }
+ g_once_init_leave (&initialized, 1);
+ }
+ return sysrootrs;
+}
+
static void
ostree_sysroot_finalize (GObject *object)
{
@@ -447,11 +471,16 @@ ostree_sysroot_is_booted (OstreeSysroot *self)
gboolean
_ostree_sysroot_bump_mtime (OstreeSysroot *self, GError **error)
{
+ void *lib = load_sysroot_rs ();
+ int (*f) (int fd) = dlsym (lib, "_ostreesys_bump_mtime");
+ g_assert (f);
+
/* Allow other systems to monitor for changes */
- if (utimensat (self->sysroot_fd, "ostree/deploy", NULL, 0) < 0)
+ int r = f (self->sysroot_fd);
+ if (r < 0)
{
- glnx_set_prefix_error_from_errno (error, "%s", "futimens");
- return FALSE;
+ errno = r;
+ return glnx_throw_errno_prefix (error, "futimens");
}
return TRUE;
}
diff --git a/src/sysroot-rs/Cargo.toml b/src/sysroot-rs/Cargo.toml
new file mode 100644
index 0000000000..35345a9356
--- /dev/null
+++ b/src/sysroot-rs/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+description = "Internal Rust sysroot code"
+edition = "2021"
+keywords = ["ostree", "libostree"]
+license = "MIT"
+name = "ostreesysrs"
+readme = "rust-bindings/README.md"
+repository = "https://github.com/ostreedev/ostree"
+rust-version = "1.70.0"
+version = "0.0.0"
+publish = false
+
+[lib]
+name = "ostreesysrs"
+crate-type = ["cdylib"]
+
+[dependencies]
+ostree = { package = "ostree", path = "../..", version = "0.19", features = ["v2022_6"] }
+libc = "0.2"
+rustix = { version = "0.38", features = ["fs"] }
diff --git a/src/sysroot-rs/src/lib.rs b/src/sysroot-rs/src/lib.rs
new file mode 100644
index 0000000000..5c03e9d98d
--- /dev/null
+++ b/src/sysroot-rs/src/lib.rs
@@ -0,0 +1,17 @@
+#[no_mangle]
+pub extern "C" fn _ostreesys_bump_mtime(fd: libc::c_int) -> libc::c_int {
+ let fd = unsafe { std::os::fd::BorrowedFd::borrow_raw(fd) };
+ let now = rustix::fs::Timespec {
+ tv_sec: 0,
+ tv_nsec: rustix::fs::UTIME_NOW,
+ };
+ let ts = rustix::fs::Timestamps {
+ last_access: now.clone(),
+ last_modification: now.clone(),
+ };
+ if let Err(e) = rustix::fs::utimensat(fd, "ostree/deploy", &ts, rustix::fs::AtFlags::empty()) {
+ e.raw_os_error().into()
+ } else {
+ 0
+ }
+}