Skip to content

Commit

Permalink
WIP: Use cxx-rs for core.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
cgwalters committed Dec 11, 2020
1 parent 0c7de65 commit 175cc1e
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 52 deletions.
39 changes: 39 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ serde_derive = "1.0.118"
serde_json = "1.0.60"
serde_yaml = "0.8.14"
libc = "0.2.81"
cxx = "1.0"
nix = "0.19.1"
glib-sys = "0.10.1"
glib = "0.10.3"
Expand Down
11 changes: 11 additions & 0 deletions Makefile-libpriv.am
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ librpmostreepriv_la_CXXFLAGS = $(AM_CXXFLAGS) $(rpmostreepriv_common_cflags)

librpmostreepriv_la_LIBADD = \
$(PKGDEP_RPMOSTREE_LIBS) \
-lstdc++ \
libglnx.la \
$(CAP_LIBS) \
$(NULL)
Expand All @@ -109,3 +110,13 @@ AM_V_GPERF_0 = @echo " GPERF " $@;
src/%.c: src/%.gperf Makefile
$(AM_V_at)$(MKDIR_P) $(dir $@)
$(AM_V_GPERF)$(GPERF) < $< > $@.tmp && mv $@.tmp $@

# Also we now use cxx.rs
rpmostree-cxxrs.h: rust/src/lib.rs
$(AM_V_GEN) cxxbridge rust/src/lib.rs --header > $@
rpmostree-cxxrs.cxx: rust/src/lib.rs
$(AM_V_GEN) cxxbridge --include rpmostree-cxxrs.h rust/src/lib.rs > $@
cxxrs_sources = rpmostree-cxxrs.h rpmostree-cxxrs.cxx
librpmostreepriv_la_SOURCES += $(cxxrs_sources)
BUILT_SOURCES += $(cxxrs_sources)
GITIGNOREFILES += $(cxxrs_sources)
4 changes: 4 additions & 0 deletions ci/installdeps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ set -xeuo pipefail
dn=$(dirname $0)
. ${dn}/libbuild.sh

if ! command -v cxxbridge; then
cargo install --root=/usr cxxbridge-cmd
fi

if [ -n "${SKIP_INSTALLDEPS:-}" ]; then
exit 0
fi
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ CC_CHECK_FLAGS_APPEND([WARN_CFLAGS], [CFLAGS], [\
-Werror=parenthesis \
-Werror=undef \
-Werror=misleading-indentation \
-Werror=missing-include-dirs -Werror=aggregate-return \
-Werror=missing-include-dirs \
-Wstrict-aliasing=2 \
-Werror=unused-result \
])])
Expand Down
77 changes: 37 additions & 40 deletions rust/src/core.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub use self::ffi::*;
use crate::ffiutil;
use anyhow::Result;
use ffiutil::ffi_view_openat_dir;
use openat_ext::OpenatDirExt;

/// Guard for running logic in a context with temporary /etc.
Expand All @@ -13,27 +14,27 @@ pub struct TempEtcGuard {
renamed_etc: bool,
}

impl TempEtcGuard {
/// Create a context with a temporary /etc, and return a guard to it.
pub fn undo_usretc(rootfs: openat::Dir) -> anyhow::Result<Self> {
let has_usretc = rootfs.exists("usr/etc")?;
if has_usretc {
// In general now, we place contents in /etc when running scripts
rootfs.local_rename("usr/etc", "etc")?;
// But leave a compat symlink, as we used to bind mount, so scripts
// could still use that too.
rootfs.symlink("usr/etc", "../etc")?;
}

let guard = Self {
rootfs,
renamed_etc: has_usretc,
};
Ok(guard)
pub fn prepare_tempetc_guard(rootfs: i32) -> Result<Box<TempEtcGuard>> {
let rootfs = ffi_view_openat_dir(rootfs);
let has_usretc = rootfs.exists("usr/etc")?;
let mut renamed_etc = false;
if has_usretc {
// In general now, we place contents in /etc when running scripts
rootfs.local_rename("usr/etc", "etc")?;
// But leave a compat symlink, as we used to bind mount, so scripts
// could still use that too.
rootfs.symlink("usr/etc", "../etc")?;
renamed_etc = true;
}
Ok(Box::new(TempEtcGuard {
rootfs,
renamed_etc,
}))
}

impl TempEtcGuard {
/// Remove the temporary /etc, and destroy the guard.
pub fn redo_usretc(self) -> anyhow::Result<()> {
pub fn undo(&self) -> anyhow::Result<()> {
if self.renamed_etc {
/* Remove the symlink and swap back */
self.rootfs.remove_file("usr/etc")?;
Expand All @@ -43,28 +44,24 @@ impl TempEtcGuard {
}
}

mod ffi {
#[cfg(test)]
mod test {
use super::*;
use glib_sys::GError;

#[no_mangle]
pub extern "C" fn ror_tempetc_undo_usretc(
rootfs: libc::c_int,
gerror: *mut *mut GError,
) -> *mut TempEtcGuard {
let fd = ffiutil::ffi_view_openat_dir(rootfs);
let res = TempEtcGuard::undo_usretc(fd).map(Box::new);
ffiutil::ptr_glib_error(res, gerror)
}
use std::os::unix::prelude::*;

#[no_mangle]
pub extern "C" fn ror_tempetc_redo_usretc(
guard_ptr: *mut TempEtcGuard,
gerror: *mut *mut GError,
) -> libc::c_int {
assert!(!guard_ptr.is_null());
let guard = unsafe { Box::from_raw(guard_ptr) };
let res = guard.redo_usretc();
ffiutil::int_glib_error(res, gerror)
#[test]
fn basic() -> Result<()> {
let td = tempfile::tempdir()?;
let d = openat::Dir::open(td.path())?;
let g = super::prepare_tempetc_guard(d.as_raw_fd())?;
g.undo()?;
d.ensure_dir_all("usr/etc/foo", 0o755)?;
assert!(!d.exists("etc/foo")?);
let g = super::prepare_tempetc_guard(d.as_raw_fd())?;
assert!(d.exists("etc/foo")?);
g.undo()?;
assert!(!d.exists("etc")?);
assert!(d.exists("usr/etc/foo")?);
Ok(())
}
}
15 changes: 14 additions & 1 deletion rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,24 @@
mod ffiutil;
mod includes;

mod core;
use crate::core::*;

#[cxx::bridge(namespace = "rpmostreecxx")]
mod ffi {
// core.rs
extern "Rust" {
type TempEtcGuard;

fn prepare_tempetc_guard(rootfs: i32) -> Result<Box<TempEtcGuard>>;
fn undo(self: &TempEtcGuard) -> Result<()>;
}
}

mod cliwrap;
pub use cliwrap::*;
mod composepost;
pub use self::composepost::*;
mod core;
mod history;
pub use self::history::*;
mod journal;
Expand Down
8 changes: 3 additions & 5 deletions src/libpriv/rpmostree-core.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "rpmostree-importer.h"
#include "rpmostree-output.h"
#include "rpmostree-rust.h"
#include "rpmostree-cxxrs.h"

#define RPMOSTREE_MESSAGE_COMMIT_STATS SD_ID128_MAKE(e6,37,2e,38,41,21,42,a9,bc,13,b6,32,b3,f8,93,44)
#define RPMOSTREE_MESSAGE_SELINUX_RELABEL SD_ID128_MAKE(5a,e0,56,34,f2,d7,49,3b,b1,58,79,b7,0c,02,e6,5d)
Expand Down Expand Up @@ -4322,9 +4323,7 @@ rpmostree_context_assemble (RpmOstreeContext *self,
gboolean skip_sanity_check = FALSE;
g_variant_dict_lookup (self->spec->dict, "skip-sanity-check", "b", &skip_sanity_check);

RORTempEtcGuard * etc_guard = ror_tempetc_undo_usretc (tmprootfs_dfd, error);
if (etc_guard == NULL)
return FALSE;
auto etc_guard = rpmostreecxx::prepare_tempetc_guard (tmprootfs_dfd);

/* NB: we're not running scripts right now for removals, so this is only for overlays and
* replacements */
Expand Down Expand Up @@ -4576,8 +4575,7 @@ rpmostree_context_assemble (RpmOstreeContext *self,
}

/* Undo the /etc move above */
if (!ror_tempetc_redo_usretc (etc_guard, error))
return FALSE;
etc_guard->undo();

/* And clean up var/tmp, we don't want it in commits */
if (!glnx_shutil_rm_rf_at (tmprootfs_dfd, "var/tmp", cancellable, error))
Expand Down
9 changes: 4 additions & 5 deletions src/libpriv/rpmostree-kernel.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "rpmostree-kernel.h"
#include "rpmostree-bwrap.h"
#include "rpmostree-rust.h"
#include "rpmostree-cxxrs.h"
#include "rpmostree-util.h"

static const char usrlib_ostreeboot[] = "usr/lib/ostree-boot";
Expand Down Expand Up @@ -530,9 +531,8 @@ rpmostree_run_dracut (int rootfs_dfd,
* today. Though maybe in the future we should add it, but
* in the end we want to use systemd-sysusers of course.
**/
RORTempEtcGuard * etc_guard = ror_tempetc_undo_usretc (rootfs_dfd, error);
if (etc_guard == NULL)
return FALSE;
auto etc_guard = rpmostreecxx::prepare_tempetc_guard (rootfs_dfd);

gboolean have_passwd = FALSE;
if (!rpmostree_passwd_prepare_rpm_layering (rootfs_dfd,
NULL,
Expand Down Expand Up @@ -645,8 +645,7 @@ rpmostree_run_dracut (int rootfs_dfd,
if (have_passwd && !rpmostree_passwd_complete_rpm_layering (rootfs_dfd, error))
return FALSE;

if (!ror_tempetc_redo_usretc (etc_guard, error))
return FALSE;
etc_guard->undo();

*out_initramfs_tmpf = tmpf; tmpf.initialized = FALSE; /* Transfer */
return TRUE;
Expand Down

0 comments on commit 175cc1e

Please sign in to comment.