Bug 34211 - RPM fails on multiply-linked empty file
Summary: RPM fails on multiply-linked empty file
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: rpm
Version: 7.0
Hardware: i386
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jeff Johnson
QA Contact: David Lawrence
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2001-03-31 09:14 UTC by Paul Menage
Modified: 2007-04-18 16:32 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2001-03-31 09:14:42 UTC
Embargoed:


Attachments (Terms of Use)

Description Paul Menage 2001-03-31 09:14:18 UTC
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 14:50:48 UTC
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.