Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | If we run builds on a filesystem with 64 bit inodes like XFS, we need to |
| 2 | map the inode numbers to something 32 bit since the cpio header only allows |
| 3 | for 32 bit inode values. If we don't do this: |
| 4 | |
| 5 | #define SET_NUM_FIELD(phys, val, space) \ |
| 6 | sprintf(space, "%8.8lx", (unsigned long) (val)); \ |
| 7 | memcpy(phys, space, 8) |
| 8 | |
| 9 | from cpio.c will print larger that 8 character values and then truncate the |
| 10 | LSBs. This generates cpio files where hardlinked files may have the same |
| 11 | inode number. The resulting rpms are then corrupted. |
| 12 | |
| 13 | There is a separate patch for the crash the identical inode numbers causes |
| 14 | when extracting the rpm. |
| 15 | |
| 16 | Patch taken from http://git.pld-linux.org/?p=packages/rpm.git;a=commitdiff;h=10526c23aac60b7b636e4c93862887dbef8e8f15 |
| 17 | |
| 18 | RP 2014/6/10 |
| 19 | |
| 20 | Upstream-Status: Pending |
| 21 | |
| 22 | Index: rpm-5.4.14/build/files.c |
| 23 | =================================================================== |
| 24 | --- rpm-5.4.14.orig/build/files.c |
| 25 | +++ rpm-5.4.14/build/files.c |
| 26 | @@ -1328,6 +1328,26 @@ static rpmuint32_t getDigestAlgo(Header |
| 27 | return dalgo; |
| 28 | } |
| 29 | |
| 30 | +static int isHardLink(FileListRec flp, FileListRec tlp) |
| 31 | +{ |
| 32 | + return ((S_ISREG(flp->fl_mode) && S_ISREG(tlp->fl_mode)) && |
| 33 | + ((flp->fl_nlink > 1) && (flp->fl_nlink == tlp->fl_nlink)) && |
| 34 | + (flp->fl_ino == tlp->fl_ino) && |
| 35 | + (flp->fl_dev == tlp->fl_dev)); |
| 36 | +} |
| 37 | + |
| 38 | +static int seenHardLink(FileList fl, FileListRec flp, ino_t *fileid) |
| 39 | +{ |
| 40 | + FileListRec ilp; |
| 41 | + for (ilp = fl->fileList; ilp < flp; ilp++) { |
| 42 | + if (isHardLink(flp, ilp)) { |
| 43 | + *fileid = ilp - fl->fileList; |
| 44 | + return 1; |
| 45 | + } |
| 46 | + } |
| 47 | + return 0; |
| 48 | +} |
| 49 | + |
| 50 | /** |
| 51 | * Add file entries to header. |
| 52 | * @todo Should directories have %doc/%config attributes? (#14531) |
| 53 | @@ -1374,6 +1394,7 @@ memset(buf, 0, sizeof(buf)); /* XXX valg |
| 54 | |
| 55 | for (i = 0, flp = fl->fileList; i < fl->fileListRecsUsed; i++, flp++) { |
| 56 | const char *s; |
| 57 | + ino_t fileid = flp - fl->fileList; |
| 58 | |
| 59 | /* Merge duplicate entries. */ |
| 60 | while (i < (fl->fileListRecsUsed - 1) && |
| 61 | @@ -1436,6 +1457,13 @@ memset(buf, 0, sizeof(buf)); /* XXX valg |
| 62 | /* Leave room for both dirname and basename NUL's */ |
| 63 | dpathlen += (strlen(flp->diskURL) + 2); |
| 64 | |
| 65 | + /* Excludes and dupes have been filtered out by now. */ |
| 66 | + if (S_ISREG(flp->fl_mode)) { |
| 67 | + if (flp->fl_nlink == 1 || !seenHardLink(fl, flp, &fileid)) { |
| 68 | + fl->totalFileSize += flp->fl_size; |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | /* |
| 73 | * Make the header, the OLDFILENAMES will get converted to a |
| 74 | * compressed file list write before we write the actual package to |
| 75 | @@ -1518,7 +1546,11 @@ memset(buf, 0, sizeof(buf)); /* XXX valg |
| 76 | |
| 77 | /* XXX Hash instead of 64b->32b truncate to prevent aliasing. */ |
| 78 | { ino_t _ino = flp->fl_ino; |
| 79 | + /* don't use hash here, as hash collisions which happen on large packages |
| 80 | + cause bus errors in rpmbuild |
| 81 | ui32 = hashFunctionString(0, &_ino, sizeof(_ino)); |
| 82 | + */ |
| 83 | + ui32 = fileid + 1; |
| 84 | } |
| 85 | he->tag = RPMTAG_FILEINODES; |
| 86 | he->t = RPM_UINT32_TYPE; |
| 87 | @@ -1751,39 +1783,6 @@ if (_rpmbuildFlags & 4) { |
| 88 | IOSM_MAP_TYPE | IOSM_MAP_MODE | IOSM_MAP_UID | IOSM_MAP_GID; |
| 89 | if (isSrc) |
| 90 | fi->fmapflags[i] |= IOSM_FOLLOW_SYMLINKS; |
| 91 | - |
| 92 | - if (S_ISREG(flp->fl_mode)) { |
| 93 | - int bingo = 1; |
| 94 | - /* Hard links need be tallied only once. */ |
| 95 | - if (flp->fl_nlink > 1) { |
| 96 | - FileListRec jlp = flp + 1; |
| 97 | - int j = i + 1; |
| 98 | - for (; (unsigned)j < fi->fc; j++, jlp++) { |
| 99 | - /* follow outer loop logic */ |
| 100 | - while (((jlp - fl->fileList) < (fl->fileListRecsUsed - 1)) && |
| 101 | - !strcmp(jlp->fileURL, jlp[1].fileURL)) |
| 102 | - jlp++; |
| 103 | - if (jlp->flags & RPMFILE_EXCLUDE) { |
| 104 | - j--; |
| 105 | - /*@innercontinue@*/ continue; |
| 106 | - } |
| 107 | - if (jlp->flags & RPMFILE_GHOST) |
| 108 | - /*@innercontinue@*/ continue; |
| 109 | - if (!S_ISREG(jlp->fl_mode)) |
| 110 | - /*@innercontinue@*/ continue; |
| 111 | - if (flp->fl_nlink != jlp->fl_nlink) |
| 112 | - /*@innercontinue@*/ continue; |
| 113 | - if (flp->fl_ino != jlp->fl_ino) |
| 114 | - /*@innercontinue@*/ continue; |
| 115 | - if (flp->fl_dev != jlp->fl_dev) |
| 116 | - /*@innercontinue@*/ continue; |
| 117 | - bingo = 0; /* don't tally hardlink yet. */ |
| 118 | - /*@innerbreak@*/ break; |
| 119 | - } |
| 120 | - } |
| 121 | - if (bingo) |
| 122 | - fl->totalFileSize += flp->fl_size; |
| 123 | - } |
| 124 | } |
| 125 | |
| 126 | ui32 = fl->totalFileSize; |
| 127 | Index: rpm-5.4.14/lib/fsm.c |
| 128 | =================================================================== |
| 129 | --- rpm-5.4.14.orig/lib/fsm.c |
| 130 | +++ rpm-5.4.14/lib/fsm.c |
| 131 | @@ -904,6 +904,7 @@ int fsmMapAttrs(IOSM_t fsm) |
| 132 | |
| 133 | if (fi && i >= 0 && i < (int) fi->fc) { |
| 134 | mode_t perms = (S_ISDIR(st->st_mode) ? fi->dperms : fi->fperms); |
| 135 | + ino_t finalInode = (fi->finodes ? (ino_t)fi->finodes[i] : 0); |
| 136 | mode_t finalMode = (fi->fmodes ? (mode_t)fi->fmodes[i] : perms); |
| 137 | dev_t finalRdev = (dev_t)(fi->frdevs ? fi->frdevs[i] : 0); |
| 138 | rpmuint32_t finalMtime = (fi->fmtimes ? fi->fmtimes[i] : 0); |
| 139 | @@ -943,6 +944,7 @@ int fsmMapAttrs(IOSM_t fsm) |
| 140 | if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) |
| 141 | && st->st_nlink == 0) |
| 142 | st->st_nlink = 1; |
| 143 | + st->st_ino = finalInode; |
| 144 | st->st_rdev = finalRdev; |
| 145 | st->st_mtime = finalMtime; |
| 146 | } |