Bug 34211 - RPM fails on multiply-linked empty file
RPM fails on multiply-linked empty file
Status: CLOSED RAWHIDE
Product: Red Hat Linux
Classification: Retired
Component: rpm (Show other bugs)
7.0
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jeff Johnson
David Lawrence
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2001-03-31 04:14 EST by Paul Menage
Modified: 2007-04-18 12:32 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2001-03-31 04:14:42 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Paul Menage 2001-03-31 04:14:18 EST
From Bugzilla Helper:
User-Agent: Mozilla/4.7 [en] (X11; I; Linux 2.2.12-20 i686)


RPM fails to install an RPM containing an empty inode with multiple hard
links - it gives the error 

"unpacking of archive failed: cpio: Missing hard link"

This appears to be for the following reason:

When rpm/cpio packages a multiply-linked inode, it only stores the data
with one of the inode instances; the others are stored as empty entries in
the archive. When unpacking an archive, rpm/cpio keeps track of multiply
linked inodes, and only actually installs the inode when it finds the entry
bearing the data. The fault appears to be in lib/cpio.c:
            
if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size &&
    li->createdPath == -1) {
    /* defer file creation */
} else if ...

In the case of a multiply linked empty inode, *all* the entries for that
inode will have size zero, and hence rpm will never actually create the
inode and its links, and instead reports an error at the end on the grounds
that it never found the data. cpio has no trouble with such an archive.

Fix: The following patches against 3.0.3 and 4.0.2 force rpm to create the
empty inode if the last entry for that inode is seen and all the entries
for that inode are of size zero:

Patch for RPM 3.0.3:
--- lib/cpio.c.orig     Fri Sep 24 14:53:08 1999
+++ lib/cpio.c  Sat Mar 31 01:09:41 2001
@@ -640,7 +640,7 @@
            }
 
            if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size &&
-               li->createdPath == -1) {
+               li->createdPath == -1 && linkNum < (li->nlink - 1)) {
                /* defer file creation */
            } else if ((ch.nlink > 1) && S_ISREG(ch.mode) && 
                       (li->createdPath != -1)) {


Patch for RPM 4.0.2:
--- lib/cpio.c~ Fri Feb 23 11:52:27 2001
+++ lib/cpio.c	Sat Mar 31 01:04:34 2001
@@ -815,7 +815,7 @@
 	    }
 
 	    if ((st->st_nlink > 1) && S_ISREG(st->st_mode) &&  !st->st_size &&
-		li->createdPath == -1) {
+               li->createdPath == -1 && li->linksLeft < li->nlink) {
 		/* defer file creation */
 	    } else if ((st->st_nlink > 1) && S_ISREG(st->st_mode) &&
 		       (li->createdPath != -1)) {


Reproducible: Always
Steps to Reproduce:
Build an RPM using the following minimal spec file:

Summary: Test
Name: test
Group: Test
License: GPL
Version: 0
Release: 0
%description
Test

%build

%install

mkdir -p $RPM_BUILD_ROOT
cd $RPM_BUILD_ROOT
touch foo
ln foo bar

%files
/foo
/bar

	

Actual Results:  
[root@asl-3 /root]# rpm -i test-0-0.i386.rpm 
unpacking of archive failed: cpio: Missing hard link
[root@asl-3 /root]#
Comment 1 Jeff Johnson 2001-04-02 10:50:48 EDT
Yup, known mis-behavior with zero length hardlinks, thanks for the patch.

Will be checked in on rpm-4_0 and rpm-3_0_5 branches, already fixed
(by a rewrite of cpio.c) on top of stack.

Note You need to log in before you can comment on or make changes to this bug.