Skip to content

Commit 6663e6f

Browse files
authored
Merge pull request #1078 from cgwalters/export-tar-hardlink-fix
tar/export: Fix error with zero-sized hardlinked files
2 parents 5e0df36 + 0b04cc4 commit 6663e6f

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

ostree-ext/src/tar/export.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,11 @@ impl<'a, W: std::io::Write> OstreeTarWriter<'a, W> {
430430
let mode = meta.attribute_uint32("unix::mode");
431431
h.set_mode(self.filter_mode(mode));
432432
if instream.is_some() {
433+
h.set_entry_type(tar::EntryType::Regular);
433434
h.set_size(meta.size() as u64);
435+
} else {
436+
h.set_entry_type(tar::EntryType::Symlink);
437+
h.set_size(0);
434438
}
435439
if !self.wrote_content.contains(checksum) {
436440
let inserted = self.wrote_content.insert(checksum.to_string());
@@ -445,8 +449,6 @@ impl<'a, W: std::io::Write> OstreeTarWriter<'a, W> {
445449
if let Some(instream) = instream {
446450
ensure!(meta.file_type() == gio::FileType::Regular);
447451

448-
h.set_entry_type(tar::EntryType::Regular);
449-
h.set_size(meta.size() as u64);
450452
let mut instream = BufReader::with_capacity(BUF_CAPACITY, instream.into_read());
451453
self.out
452454
.append_data(&mut h, &path, &mut instream)
@@ -461,8 +463,6 @@ impl<'a, W: std::io::Write> OstreeTarWriter<'a, W> {
461463
.to_str()
462464
.ok_or_else(|| anyhow!("Invalid UTF-8 symlink target: {target:?}"))?;
463465
let context = || format!("Writing content symlink: {}", checksum);
464-
h.set_entry_type(tar::EntryType::Symlink);
465-
h.set_size(0);
466466
// Handle //chkconfig, see above
467467
if symlink_is_denormal(target) {
468468
h.set_link_name_literal(target).with_context(context)?;
@@ -501,15 +501,20 @@ impl<'a, W: std::io::Write> OstreeTarWriter<'a, W> {
501501
mut h: tar::Header,
502502
dest: &Utf8Path,
503503
) -> Result<()> {
504-
// Query the original size first
505-
let size = h.size().context("Querying size for hardlink append")?;
506504
// Don't create hardlinks to zero-sized files, it's much more likely
507505
// to result in generated tar streams from container builds resulting
508506
// in a modified linked-to file in /sysroot, which we don't currently handle.
509507
// And in the case where the input is *not* zero sized, we still output
510508
// a hardlink of size zero, as this is what is normal.
509+
let is_regular_zerosized = if h.entry_type() == tar::EntryType::Regular {
510+
let size = h.size().context("Querying size for hardlink append")?;
511+
size == 0
512+
} else {
513+
false
514+
};
515+
// Link sizes shoud always be zero
511516
h.set_size(0);
512-
if h.entry_type() == tar::EntryType::Regular && size == 0 {
517+
if is_regular_zerosized {
513518
self.out.append_data(&mut h, dest, &mut std::io::empty())?;
514519
} else {
515520
h.set_entry_type(tar::EntryType::Link);
@@ -549,7 +554,8 @@ impl<'a, W: std::io::Write> OstreeTarWriter<'a, W> {
549554
let (objpath, h) = self.append_content(checksum)?;
550555
let subpath = &dirpath.join(name);
551556
let subpath = map_path(subpath);
552-
self.append_content_hardlink(&objpath, h, &subpath)?;
557+
self.append_content_hardlink(&objpath, h, &subpath)
558+
.with_context(|| format!("Hardlinking {checksum} to {subpath}"))?;
553559
}
554560
}
555561

0 commit comments

Comments
 (0)