From owner-freebsd-stable@FreeBSD.ORG Thu Jun 7 05:01:57 2007 Return-Path: X-Original-To: freebsd-stable@freebsd.org Delivered-To: freebsd-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B408F16A400 for ; Thu, 7 Jun 2007 05:01:57 +0000 (UTC) (envelope-from kientzle@freebsd.org) Received: from kientzle.com (h-66-166-149-50.snvacaid.covad.net [66.166.149.50]) by mx1.freebsd.org (Postfix) with ESMTP id 6B24913C487 for ; Thu, 7 Jun 2007 05:01:57 +0000 (UTC) (envelope-from kientzle@freebsd.org) Received: from [10.0.0.222] (p54.kientzle.com [66.166.149.54]) by kientzle.com (8.12.9/8.12.9) with ESMTP id l5751BH7020603; Wed, 6 Jun 2007 22:01:19 -0700 (PDT) (envelope-from kientzle@freebsd.org) Message-ID: <46679117.5060909@freebsd.org> Date: Wed, 06 Jun 2007 22:01:11 -0700 From: Tim Kientzle User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7.12) Gecko/20060422 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Robin Gruyters References: <20070601114047.z6qgi686os4ogw4o@server.yirdis.nl> <46658EEB.5000008@freebsd.org> <20070606084406.8v6nkbtv9csgs880@server.yirdis.nl> <200706061715.06603.doconnor@gsoft.com.au> <20070606095820.83tast6s0804osos@server.yirdis.nl> In-Reply-To: <20070606095820.83tast6s0804osos@server.yirdis.nl> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-stable@freebsd.org Subject: Re: Unrecognized archive format with RELENG_6_2 and RELENG_6 X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Jun 2007 05:01:57 -0000 >>> After that I try to read/list the tar from tape with tar -t: >>> $ sudo tar -tf /dev/sa0 >>> archive.dmp >>> tar: Unrecognized archive format: Inappropriate file type or format >>> >>> But when I extract the archive from tape, it works perfectly: >>> $ sudo tar -xvf /dev/sa0 >> >> Using dd to feed tar does work though. (I think this agrees with Robin's >> findings although the fact that it works with -z is curious) >> >> This is a Tandberg TS400 (LTO2 drive, LTO1 tape) >> > idd, same problem here. When using -z option, works perfectly. Without > it, it fails. > > Our tapedrive is a "HP C7438A V312". (DAT) Please try the following: sudo ktrace tar -tf /dev/sa0 Then run 'kdump | less' and see if you can find a pair of 'lseek' calls, which will probably look something like this: 53127 bsdtar CALL lseek(0x3,0,0,0,0x1) 53127 bsdtar RET lseek 6656000/0x659000 53127 bsdtar CALL lseek(0x3,0,0x70800,0,0x1) 53127 bsdtar RET lseek 7116800/0x6c9800 Note: The third argument is the amount to seek; the return value is the new offset. This sequence (first seek '0' to get the current offset, then seek by more than zero) is how tar asks the driver if it supports seeking. This example is reading from a disk file, so the file offset does change; the seek worked. I believe you'll find that the SCSI tape driver in 6.2 lies: It does not actually seek, but the two lseek calls return different values. As a result, tar believes that the body of the tar entry has been skipped when it hasn't. This doesn't occur with tar from 6.1 because the seek optimization was added after that; it doesn't happen with compressed archives because you cannot seek in compressed files. I believe the "right" fix is to get the driver fixed. If it does not seek, it shouldn't claim that it does. A bad hack is to break the "file_skip()" function in libarchive/archive_read_open_filename.c, as below: Index: lib/libarchive/archive_read_open_filename.c =================================================================== --- lib/libarchive/archive_read_open_filename.c (revision 124) +++ lib/libarchive/archive_read_open_filename.c (working copy) @@ -165,6 +165,8 @@ struct read_file_data *mine = (struct read_file_data *)client_data; off_t old_offset, new_offset; + return (0); + /* Reduce request to the next smallest multiple of block_size */ request = (request / mine->block_size) * mine->block_size; /*