Skip to content

Commit d44d81d

Browse files
lucabcgwalters
authored andcommitted
libpriv/importer: move tmpfiles.d entries buffering to Rust
This moves the RPM importer buffering logic for tmpfiles.d entries to Rust.
1 parent 939a63a commit d44d81d

File tree

3 files changed

+57
-18
lines changed

3 files changed

+57
-18
lines changed

rust/src/importer.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ pub struct RpmImporter {
6161
/// - [K] absolute full path of the file
6262
/// - [V] iterator index in RPM header for this file
6363
rpmfi_overrides: HashMap<String, u64>,
64+
/// Filepaths translated to tmpfiles.d entries.
65+
tmpfiles_entries: Vec<String>,
6466
}
6567

6668
/// Build a new RPM importer for a given package.
@@ -102,6 +104,7 @@ impl RpmImporter {
102104
pkg_name: pkg_name.to_string(),
103105
varlib_direntries: BTreeSet::new(),
104106
rpmfi_overrides: HashMap::new(),
107+
tmpfiles_entries: vec![],
105108
};
106109
Ok(importer)
107110
}
@@ -176,7 +179,7 @@ impl RpmImporter {
176179
/// Format tmpfiles.d lines for symlinked entries.
177180
// NOTE(lucab): destinations (dirname) can't be quoted as systemd just
178181
// parses the remainder of the line, and doesn't expand quotes.
179-
pub fn tmpfiles_symlink_entries(&self) -> Vec<String> {
182+
fn tmpfiles_symlink_entries(&self) -> Vec<String> {
180183
// /opt/ symlinks
181184
let opt_entries = self.opt_direntries.iter().map(|dirname| {
182185
let quoted = crate::maybe_shell_quote(&format!("/opt/{dirname}"));
@@ -251,6 +254,43 @@ impl RpmImporter {
251254
x => unreachable!("unknown commit result '{}' for path '{}'", x, path),
252255
}
253256
}
257+
258+
/// Translate a filepath to an equivalent tmpfiles.d line.
259+
pub fn translate_to_tmpfiles_entry(
260+
&mut self,
261+
abs_path: &str,
262+
mut file_info: Pin<&mut crate::FFIGFileInfo>,
263+
username: &str,
264+
groupname: &str,
265+
) -> CxxResult<()> {
266+
let file_info = file_info.gobj_wrap();
267+
let entry = translate_to_tmpfiles_d(abs_path, &file_info, username, groupname)?;
268+
self.tmpfiles_entries.push(entry);
269+
Ok(())
270+
}
271+
272+
/// Return whether this RPM has any auto-translated tmpfiles.d entries.
273+
pub fn has_tmpfiles_entries(&self) -> bool {
274+
self.tmpfiles_entries
275+
.len()
276+
.saturating_add(self.opt_direntries.len())
277+
.saturating_add(self.varlib_direntries.len())
278+
> 0
279+
}
280+
281+
/// Serialize all tmpfiles.d entries as a single configuration fragment.
282+
pub fn serialize_tmpfiles_content(&self) -> String {
283+
let mut buf = String::new();
284+
285+
let symlink_entries = self.tmpfiles_symlink_entries();
286+
let all_entries = symlink_entries.iter().chain(self.tmpfiles_entries.iter());
287+
288+
for entry in all_entries {
289+
buf.push_str(&entry);
290+
buf.push('\n');
291+
}
292+
buf
293+
}
254294
}
255295

256296
/// Canonicalize a path, e.g. replace `//` with `/` and `././` with `./`.

rust/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,6 @@ pub mod ffi {
349349
fn handle_translate_pathname(self: &mut RpmImporter, path: &str) -> String;
350350
fn ostree_branch(self: &RpmImporter) -> String;
351351
fn pkg_name(self: &RpmImporter) -> String;
352-
fn tmpfiles_symlink_entries(self: &RpmImporter) -> Vec<String>;
353352
fn doc_files_are_filtered(self: &RpmImporter) -> bool;
354353
fn doc_files_insert(self: &mut RpmImporter, path: &str);
355354
fn doc_files_contains(self: &RpmImporter, path: &str) -> bool;
@@ -363,6 +362,15 @@ pub mod ffi {
363362
path: &str,
364363
mut file_info: Pin<&mut GFileInfo>,
365364
) -> Result<bool>;
365+
fn translate_to_tmpfiles_entry(
366+
self: &mut RpmImporter,
367+
abs_path: &str,
368+
mut file_info: Pin<&mut GFileInfo>,
369+
username: &str,
370+
groupname: &str,
371+
) -> Result<()>;
372+
fn has_tmpfiles_entries(self: &RpmImporter) -> bool;
373+
fn serialize_tmpfiles_content(self: &RpmImporter) -> String;
366374

367375
fn tmpfiles_translate(
368376
abs_path: &str,

src/libpriv/rpmostree-importer.cxx

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ struct RpmOstreeImporter
6161
Header hdr;
6262
rpmfi fi;
6363
off_t cpio_offset;
64-
GString *tmpfiles_d;
6564
DnfPackage *pkg;
6665

6766
std::optional<rust::Box<rpmostreecxx::RpmImporter> > importer_rs;
@@ -80,7 +79,6 @@ rpmostree_importer_finalize (GObject *object)
8079
if (self->fi)
8180
(void)rpmfiFree (self->fi);
8281
glnx_close_fd (&self->fd);
83-
g_string_free (self->tmpfiles_d, TRUE);
8482
g_clear_object (&self->repo);
8583
g_clear_object (&self->sepolicy);
8684

@@ -101,7 +99,6 @@ static void
10199
rpmostree_importer_init (RpmOstreeImporter *self)
102100
{
103101
self->fd = -1;
104-
self->tmpfiles_d = g_string_new ("");
105102
self->importer_rs = std::nullopt;
106103
}
107104

@@ -497,13 +494,9 @@ compose_filter_cb (OstreeRepo *repo, const char *path, GFileInfo *file_info, gpo
497494
const char *group = NULL;
498495
get_rpmfi_override (self, path, &user, &group, NULL, NULL);
499496

500-
auto entry = ROSCXX_VAL (
501-
tmpfiles_translate (path, *file_info, user ?: "root", group ?: "root"), error);
502-
if (entry.has_value ())
503-
{
504-
g_string_append (self->tmpfiles_d, entry.value ().c_str ());
505-
g_string_append_c (self->tmpfiles_d, '\n');
506-
}
497+
CXX ((*self->importer_rs)
498+
->translate_to_tmpfiles_entry (path, *file_info, user ?: "root", group ?: "root"),
499+
error);
507500

508501
return OSTREE_REPO_COMMIT_FILTER_SKIP;
509502
}
@@ -607,9 +600,6 @@ import_rpm_to_repo (RpmOstreeImporter *self, char **out_csum, char **out_metadat
607600
return FALSE;
608601
}
609602

610-
for (auto &line : (*self->importer_rs)->tmpfiles_symlink_entries ())
611-
g_string_append_printf (self->tmpfiles_d, "%s\n", line.c_str ());
612-
613603
/* Handle any data we've accumulated to write to tmpfiles.d.
614604
* I originally tried to do this entirely in memory but things
615605
* like selinux labeling only happen as callbacks out of using
@@ -618,8 +608,9 @@ import_rpm_to_repo (RpmOstreeImporter *self, char **out_csum, char **out_metadat
618608
g_auto (GLnxTmpDir) tmpdir = {
619609
0,
620610
};
621-
if (self->tmpfiles_d->len > 0)
611+
if ((*self->importer_rs)->has_tmpfiles_entries ())
622612
{
613+
auto content = (*self->importer_rs)->serialize_tmpfiles_content ();
623614
auto pkg_name = (*self->importer_rs)->pkg_name ();
624615

625616
if (!glnx_mkdtemp ("rpm-ostree-import.XXXXXX", 0700, &tmpdir, error))
@@ -628,8 +619,8 @@ import_rpm_to_repo (RpmOstreeImporter *self, char **out_csum, char **out_metadat
628619
return FALSE;
629620
if (!glnx_file_replace_contents_at (
630621
tmpdir.fd, glnx_strjoina ("usr/lib/tmpfiles.d/", "pkg-", pkg_name.c_str (), ".conf"),
631-
(guint8 *)self->tmpfiles_d->str, self->tmpfiles_d->len, GLNX_FILE_REPLACE_NODATASYNC,
632-
cancellable, error))
622+
(guint8 *)content.data (), content.size (), GLNX_FILE_REPLACE_NODATASYNC, cancellable,
623+
error))
633624
return FALSE;
634625

635626
if (!ostree_repo_write_dfd_to_mtree (repo, tmpdir.fd, ".", mtree, modifier, cancellable,

0 commit comments

Comments
 (0)