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;

Reply via email to