Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian....@packages.debian.org
Usertags: pu
X-Debbugs-Cc: ninja-bu...@packages.debian.org
Control: affects -1 + src:ninja-build
[ Reason ]
ninja fails on 32 bit architectures with files that have a >32bit inode.
[ Impact ]
This mostly affects automated builds / CI systems since such
large inode numbers typically appear when using overlayfs.
[ Tests ]
* Builds fine on amd64 and i386 (including unit tests)
* autopkgtest runs fine on amd64
* Rebuilt a couple of reverse build-deps on i386 and amd64, no failures
* Simon has verified the fix is effective on bookworm
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1041897#34
[ Risks ]
The change is pretty limited only touching stat() calls.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in (old)stable
[x] the issue is verified as fixed in unstable
[ Changes ]
Cherry-pick upstream fix that essentially replaces stat() with stat64()
when largefile is enabled.
[ Other info ]
The change was already part of testing before it was replaced with a new
upstream version.
Thus I'm proposing a rebuild of that package.
diff -Nru ninja-build-1.11.1/debian/changelog
ninja-build-1.11.1/debian/changelog
--- ninja-build-1.11.1/debian/changelog 2022-09-02 12:31:31.000000000 +0200
+++ ninja-build-1.11.1/debian/changelog 2024-10-19 18:02:37.000000000 +0200
@@ -1,3 +1,16 @@
+ninja-build (1.11.1-2~deb12u1) bookworm; urgency=medium
+
+ * Rebuild for bookworm.
+
+ -- Felix Geyer <fge...@debian.org> Sat, 19 Oct 2024 18:02:37 +0200
+
+ninja-build (1.11.1-2) unstable; urgency=medium
+
+ * Support large inode numbers on 32-bit systems. (Closes: #1041897)
+ - Cherry-pick upstream commit as support_32bit_system_like_i386.patch
+
+ -- Felix Geyer <fge...@debian.org> Sun, 03 Sep 2023 16:34:04 +0200
+
ninja-build (1.11.1-1) unstable; urgency=medium
* New upstream release.
diff -Nru ninja-build-1.11.1/debian/patches/series
ninja-build-1.11.1/debian/patches/series
--- ninja-build-1.11.1/debian/patches/series 1970-01-01 01:00:00.000000000
+0100
+++ ninja-build-1.11.1/debian/patches/series 2024-10-19 18:02:30.000000000
+0200
@@ -0,0 +1 @@
+support_32bit_system_like_i386.patch
diff -Nru
ninja-build-1.11.1/debian/patches/support_32bit_system_like_i386.patch
ninja-build-1.11.1/debian/patches/support_32bit_system_like_i386.patch
--- ninja-build-1.11.1/debian/patches/support_32bit_system_like_i386.patch
1970-01-01 01:00:00.000000000 +0100
+++ ninja-build-1.11.1/debian/patches/support_32bit_system_like_i386.patch
2024-10-19 18:02:30.000000000 +0200
@@ -0,0 +1,187 @@
+From 7bba11ae704efc84cac5fde5e9be53f653f237d1 Mon Sep 17 00:00:00 2001
+From: Ma Aiguo <maai...@uniontech.com>
+Date: Sun, 9 Oct 2022 17:50:29 +0800
+Subject: [PATCH] support 32bit system like i386 (#829)
+
+---
+ src/build_log_test.cc | 6 +++++-
+ src/deps_log_test.cc | 43 ++++++++++++++++++++++++++++++++++++++++---
+ src/disk_interface.cc | 5 +++++
+ src/util.cc | 5 +++++
+ 4 files changed, 55 insertions(+), 4 deletions(-)
+
+diff --git a/src/build_log_test.cc b/src/build_log_test.cc
+index 37182994d2..f03100d809 100644
+--- a/src/build_log_test.cc
++++ b/src/build_log_test.cc
+@@ -133,9 +133,13 @@ TEST_F(BuildLogTest, Truncate) {
+ log1.RecordCommand(state_.edges_[1], 20, 25);
+ log1.Close();
+ }
+-
++#ifdef __USE_LARGEFILE64
++ struct stat64 statbuf;
++ ASSERT_EQ(0, stat64(kTestFilename, &statbuf));
++#else
+ struct stat statbuf;
+ ASSERT_EQ(0, stat(kTestFilename, &statbuf));
++#endif
+ ASSERT_GT(statbuf.st_size, 0);
+
+ // For all possible truncations of the input file, assert that we don't
+diff --git a/src/deps_log_test.cc b/src/deps_log_test.cc
+index 13fcc788b6..cb1c925532 100644
+--- a/src/deps_log_test.cc
++++ b/src/deps_log_test.cc
+@@ -138,9 +138,13 @@ TEST_F(DepsLogTest, DoubleEntry) {
+ deps.push_back(state.GetNode("bar.h", 0));
+ log.RecordDeps(state.GetNode("out.o", 0), 1, deps);
+ log.Close();
+-
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ ASSERT_EQ(0, stat64(kTestFilename, &st));
++#else
+ struct stat st;
+ ASSERT_EQ(0, stat(kTestFilename, &st));
++#endif
+ file_size = (int)st.st_size;
+ ASSERT_GT(file_size, 0);
+ }
+@@ -160,9 +164,13 @@ TEST_F(DepsLogTest, DoubleEntry) {
+ deps.push_back(state.GetNode("bar.h", 0));
+ log.RecordDeps(state.GetNode("out.o", 0), 1, deps);
+ log.Close();
+-
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ ASSERT_EQ(0, stat64(kTestFilename, &st));
++#else
+ struct stat st;
+ ASSERT_EQ(0, stat(kTestFilename, &st));
++#endif
+ int file_size_2 = (int)st.st_size;
+ ASSERT_EQ(file_size, file_size_2);
+ }
+@@ -198,9 +206,13 @@ TEST_F(DepsLogTest, Recompact) {
+ log.RecordDeps(state.GetNode("other_out.o", 0), 1, deps);
+
+ log.Close();
+-
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ ASSERT_EQ(0, stat64(kTestFilename, &st));
++#else
+ struct stat st;
+ ASSERT_EQ(0, stat(kTestFilename, &st));
++#endif
+ file_size = (int)st.st_size;
+ ASSERT_GT(file_size, 0);
+ }
+@@ -222,8 +234,13 @@ TEST_F(DepsLogTest, Recompact) {
+ log.RecordDeps(state.GetNode("out.o", 0), 1, deps);
+ log.Close();
+
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ ASSERT_EQ(0, stat64(kTestFilename, &st));
++#else
+ struct stat st;
+ ASSERT_EQ(0, stat(kTestFilename, &st));
++#endif
+ file_size_2 = (int)st.st_size;
+ // The file should grow to record the new deps.
+ ASSERT_GT(file_size_2, file_size);
+@@ -273,8 +290,13 @@ TEST_F(DepsLogTest, Recompact) {
+ ASSERT_EQ(other_out, log.nodes()[other_out->id()]);
+
+ // The file should have shrunk a bit for the smaller deps.
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ ASSERT_EQ(0, stat64(kTestFilename, &st));
++#else
+ struct stat st;
+ ASSERT_EQ(0, stat(kTestFilename, &st));
++#endif
+ file_size_3 = (int)st.st_size;
+ ASSERT_LT(file_size_3, file_size_2);
+ }
+@@ -317,8 +339,13 @@ TEST_F(DepsLogTest, Recompact) {
+ ASSERT_EQ(-1, state.LookupNode("baz.h")->id());
+
+ // The file should have shrunk more.
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ ASSERT_EQ(0, stat64(kTestFilename, &st));
++#else
+ struct stat st;
+ ASSERT_EQ(0, stat(kTestFilename, &st));
++#endif
+ int file_size_4 = (int)st.st_size;
+ ASSERT_LT(file_size_4, file_size_3);
+ }
+@@ -374,8 +401,13 @@ TEST_F(DepsLogTest, Truncated) {
+ }
+
+ // Get the file size.
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ ASSERT_EQ(0, stat64(kTestFilename, &st));
++#else
+ struct stat st;
+ ASSERT_EQ(0, stat(kTestFilename, &st));
++#endif
+
+ // Try reloading at truncated sizes.
+ // Track how many nodes/deps were found; they should decrease with
+@@ -434,8 +466,13 @@ TEST_F(DepsLogTest, TruncatedRecovery) {
+
+ // Shorten the file, corrupting the last record.
+ {
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ ASSERT_EQ(0, stat64(kTestFilename, &st));
++#else
+ struct stat st;
+ ASSERT_EQ(0, stat(kTestFilename, &st));
++#endif
+ string err;
+ ASSERT_TRUE(Truncate(kTestFilename, st.st_size - 2, &err));
+ }
+diff --git a/src/disk_interface.cc b/src/disk_interface.cc
+index e64bb43f32..7277c3e912 100644
+--- a/src/disk_interface.cc
++++ b/src/disk_interface.cc
+@@ -194,9 +194,14 @@ TimeStamp RealDiskInterface::Stat(const string& path,
string* err) const {
+ }
+ DirCache::iterator di = ci->second.find(base);
+ return di != ci->second.end() ? di->second : 0;
++#else
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ if (stat64(path.c_str(), &st) < 0) {
+ #else
+ struct stat st;
+ if (stat(path.c_str(), &st) < 0) {
++#endif
+ if (errno == ENOENT || errno == ENOTDIR)
+ return 0;
+ *err = "stat(" + path + "): " + strerror(errno);
+diff --git a/src/util.cc b/src/util.cc
+index ef5f103305..eefa3f50cd 100644
+--- a/src/util.cc
++++ b/src/util.cc
+@@ -369,8 +369,13 @@ int ReadFile(const string& path, string* contents,
string* err) {
+ return -errno;
+ }
+
++#ifdef __USE_LARGEFILE64
++ struct stat64 st;
++ if (fstat64(fileno(f), &st) < 0) {
++#else
+ struct stat st;
+ if (fstat(fileno(f), &st) < 0) {
++#endif
+ err->assign(strerror(errno));
+ fclose(f);
+ return -errno;