aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/rpm/rpm/rpm-payload-use-hashed-inode.patch
blob: 9cd02a0f9249b260baa66b5acbf502d0c021febf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
If we run builds on a filesystem with 64 bit inodes like XFS, we need to
map the inode numbers to something 32 bit since the cpio header only allows
for 32 bit inode values. If we don't do this:

#define SET_NUM_FIELD(phys, val, space) \
        sprintf(space, "%8.8lx", (unsigned long) (val)); \
        memcpy(phys, space, 8)

from cpio.c will print larger that 8 character values and then truncate the 
LSBs. This generates cpio files where hardlinked files may have the same
inode number. The resulting rpms are then corrupted.

There is a separate patch for the crash the identical inode numbers causes
when extracting the rpm.

Patch taken from http://git.pld-linux.org/?p=packages/rpm.git;a=commitdiff;h=10526c23aac60b7b636e4c93862887dbef8e8f15

RP 2014/6/10

Upstream-Status: Pending

Index: rpm-5.4.14/build/files.c
===================================================================
--- rpm-5.4.14.orig/build/files.c
+++ rpm-5.4.14/build/files.c
@@ -1328,6 +1328,26 @@ static rpmuint32_t getDigestAlgo(Header
     return dalgo;
 }
 
+static int isHardLink(FileListRec flp, FileListRec tlp)
+{
+    return ((S_ISREG(flp->fl_mode) && S_ISREG(tlp->fl_mode)) &&
+            ((flp->fl_nlink > 1) && (flp->fl_nlink == tlp->fl_nlink)) &&
+            (flp->fl_ino == tlp->fl_ino) &&
+            (flp->fl_dev == tlp->fl_dev));
+}
+
+static int seenHardLink(FileList fl, FileListRec flp, ino_t *fileid)
+{
+    FileListRec ilp;
+    for (ilp = fl->fileList; ilp < flp; ilp++) {
+        if (isHardLink(flp, ilp)) {
+            *fileid = ilp - fl->fileList;
+            return 1;
+        }
+    }
+    return 0;
+}
+
 /**
  * Add file entries to header.
  * @todo Should directories have %doc/%config attributes? (#14531)
@@ -1374,6 +1394,7 @@ memset(buf, 0, sizeof(buf));	/* XXX valg
 
     for (i = 0, flp = fl->fileList; i < fl->fileListRecsUsed; i++, flp++) {
 	const char *s;
+	ino_t fileid = flp - fl->fileList;
 
  	/* Merge duplicate entries. */
 	while (i < (fl->fileListRecsUsed - 1) &&
@@ -1436,6 +1457,13 @@ memset(buf, 0, sizeof(buf));	/* XXX valg
 	/* Leave room for both dirname and basename NUL's */
 	dpathlen += (strlen(flp->diskURL) + 2);
 
+	/* Excludes and dupes have been filtered out by now. */
+	if (S_ISREG(flp->fl_mode)) {
+	    if (flp->fl_nlink == 1 || !seenHardLink(fl, flp, &fileid)) {
+		fl->totalFileSize += flp->fl_size;
+	    }
+	}
+
 	/*
 	 * Make the header, the OLDFILENAMES will get converted to a 
 	 * compressed file list write before we write the actual package to
@@ -1518,7 +1546,11 @@ memset(buf, 0, sizeof(buf));	/* XXX valg
 
 	/* XXX Hash instead of 64b->32b truncate to prevent aliasing. */
 	{   ino_t _ino = flp->fl_ino;
+	/* don't use hash here, as hash collisions which happen on large packages
+	   cause bus errors in rpmbuild
 	    ui32 = hashFunctionString(0, &_ino, sizeof(_ino));
+	*/
+	    ui32 = fileid + 1;
 	}
 	he->tag = RPMTAG_FILEINODES;
 	he->t = RPM_UINT32_TYPE;
@@ -1751,39 +1783,6 @@ if (_rpmbuildFlags & 4) {
 		IOSM_MAP_TYPE | IOSM_MAP_MODE | IOSM_MAP_UID | IOSM_MAP_GID;
 	if (isSrc)
 	    fi->fmapflags[i] |= IOSM_FOLLOW_SYMLINKS;
-
-	if (S_ISREG(flp->fl_mode)) {
-	    int bingo = 1;
-	    /* Hard links need be tallied only once. */
-	    if (flp->fl_nlink > 1) {
-		FileListRec jlp = flp + 1;
-		int j = i + 1;
-		for (; (unsigned)j < fi->fc; j++, jlp++) {
-		    /* follow outer loop logic */
-		    while (((jlp - fl->fileList) < (fl->fileListRecsUsed - 1)) &&
-			    !strcmp(jlp->fileURL, jlp[1].fileURL))
-			jlp++;
-		    if (jlp->flags & RPMFILE_EXCLUDE) {
-			j--;
-			/*@innercontinue@*/ continue;
-		    }
-		    if (jlp->flags & RPMFILE_GHOST)
-		        /*@innercontinue@*/ continue;
-		    if (!S_ISREG(jlp->fl_mode))
-			/*@innercontinue@*/ continue;
-		    if (flp->fl_nlink != jlp->fl_nlink)
-			/*@innercontinue@*/ continue;
-		    if (flp->fl_ino != jlp->fl_ino)
-			/*@innercontinue@*/ continue;
-		    if (flp->fl_dev != jlp->fl_dev)
-			/*@innercontinue@*/ continue;
-		    bingo = 0;	/* don't tally hardlink yet. */
-		    /*@innerbreak@*/ break;
-		}
-	    }
-	    if (bingo)
-		fl->totalFileSize += flp->fl_size;
-	}
     }
 
     ui32 = fl->totalFileSize;
Index: rpm-5.4.14/lib/fsm.c
===================================================================
--- rpm-5.4.14.orig/lib/fsm.c
+++ rpm-5.4.14/lib/fsm.c
@@ -904,6 +904,7 @@ int fsmMapAttrs(IOSM_t fsm)
 
     if (fi && i >= 0 && i < (int) fi->fc) {
 	mode_t perms = (S_ISDIR(st->st_mode) ? fi->dperms : fi->fperms);
+	ino_t finalInode = (fi->finodes ? (ino_t)fi->finodes[i] : 0);
 	mode_t finalMode = (fi->fmodes ? (mode_t)fi->fmodes[i] : perms);
 	dev_t finalRdev = (dev_t)(fi->frdevs ? fi->frdevs[i] : 0);
 	rpmuint32_t finalMtime = (fi->fmtimes ? fi->fmtimes[i] : 0);
@@ -943,6 +944,7 @@ int fsmMapAttrs(IOSM_t fsm)
 	    if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
 	    && st->st_nlink == 0)
 		st->st_nlink = 1;
+	    st->st_ino = finalInode;
 	    st->st_rdev = finalRdev;
 	    st->st_mtime = finalMtime;
 	}