On Fri, Jan 15, 2010 at 08:06:54PM -0800, Carl Miller wrote: > cramfs takes a shortcut with device nodes, and assigns them all inode 1. > When using cpio to copy files out of a cramfs image, cpio turns the second > and all subsequent copied device nodes into hard links to the first copied > out device node, based on them all having the same st_dev and st_ino. The > resulting archive does not extract properly, because you cannot make a > hard link to a device node. > > Solution: when checking for hard links during copy-out, take the file > type into account. The test should be changed from "st_devs equal and > st_inos equal" to "st_devs equal and st_inos equal and not block device > and not char device". > > > > > r...@mithrandir:/tmp/unpack# mkdir mnt_228 > r...@mithrandir:/tmp/unpack# mount -t cramfs -o ro,nodev,noexec,loop > /usr/local/isengard/share/builds/build228/disk_fs.img mnt_228 > r...@mithrandir:/tmp/unpack# ls -l mnt_228/dev/loop? > brw-r--r-- 1 root root 7, 0 1969-12-31 16:00 mnt_228/dev/loop0 > brw-r--r-- 1 root root 7, 1 1969-12-31 16:00 mnt_228/dev/loop1 > brw-r--r-- 1 root root 7, 2 1969-12-31 16:00 mnt_228/dev/loop2 > brw-r--r-- 1 root root 7, 3 1969-12-31 16:00 mnt_228/dev/loop3 > r...@mithrandir:/tmp/unpack# cd mnt_228 > r...@mithrandir:/tmp/unpack/mnt_228# ( echo "dev" ; echo "dev/loop0" ; echo > "dev/loop1" ; echo "dev/loop2" ; echo "dev/loop3" ) | cpio -o -F > /tmp/looptest.tar -H ustar --quiet > r...@mithrandir:/tmp/unpack/mnt_228# tar -tf /tmp/looptest.tar > tar: Record size = 7 blocks > dev/ > dev/loop0/ > dev/loop1/ > dev/loop2/ > dev/loop3/ > r...@mithrandir:/tmp/unpack/mnt_228# cd .. > r...@mithrandir:/tmp/unpack# tar -xvf /tmp/looptest.tar > tar: Record size = 7 blocks > dev/ > dev/loop0/ > tar: dev/loop0: implausibly old time stamp 1969-12-31 16:00:00 > dev/loop1/ > tar: dev/loop1: Cannot hard link to `dev/loop0/': Not a directory > dev/loop2/ > tar: dev/loop2: Cannot hard link to `dev/loop0/': Not a directory > dev/loop3/ > tar: dev/loop3: Cannot hard link to `dev/loop0/': Not a directory > tar: dev: implausibly old time stamp 1969-12-31 16:00:00 > tar: Exiting with failure status due to previous errors > r...@mithrandir:/tmp/unpack# ls -l dev > total 0 > brw-r--r-- 1 root root 7, 0 1969-12-31 16:00 loop0
You mean something like this? diff --git a/src/copyout.c b/src/copyout.c index 98f3895..f0741f7 100644 --- a/src/copyout.c +++ b/src/copyout.c @@ -121,7 +121,9 @@ count_defered_links_to_dev_ino (struct cpio_file_stat *file_hdr) for (d = deferouts; d != NULL; d = d->next) { if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj) - && (d->header.c_dev_min == min) ) + && (d->header.c_dev_min == min) + && ((d->header.c_mode & CP_IFBLK) != CP_IFBLK) + && ((d->header.c_mode & CP_IFCHR) != CP_IFCHR) ) ++count; } return count; @@ -178,7 +180,9 @@ writeout_other_defers (struct cpio_file_stat *file_hdr, int out_des) while (d != NULL) { if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj) - && (d->header.c_dev_min == min) ) + && (d->header.c_dev_min == min) + && ((d->header.c_mode & CP_IFBLK) != CP_IFBLK) + && ((d->header.c_mode & CP_IFCHR) != CP_IFCHR) ) { struct deferment *d_free; d->header.c_filesize = 0; -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org