Thanks for the suggestion, but this should be fixed in the kernel, and not
changed here.  The lseek is sometimes needed to be able to skip over bad
blocks of e.g., a raw disk device, in which case a read would not work.

Would you please forward your report to the kernel maintainers and
maybe to the amanda developers?

In case you want to investigate a little first, here's a little
program that should help.  When I run it on a Linux2.2.5 system
with an exabyte tape drive, it exits successfully.

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int
main (int argc, char **argv)
{
  off_t offset;
  int fd;
  size_t n_read;
  char buf[16 * 32768];

  const char *tape_dev = (argc < 2 ? "/dev/st0" : argv[1]);
  int block_size = (argc < 3 ? 32768 : atoi(argv[2]));
  int i;

  if ((fd = open (tape_dev, O_WRONLY)) < 0)
    exit (1);
  if ((offset = lseek (fd, 0, SEEK_SET)) != (off_t) 0)
    exit (2);
  for (i = 0; i < 4; i++)
    {
      char b[2];
      b[0] = '0' + i;
      b[1] = 0;
      strcpy (&buf[i * 32768], b);
    }

  if (write (fd, buf, sizeof buf) != sizeof buf)
    {
      perror ("write");
      exit (3);
    }
  close (fd);

  if ((fd = open (tape_dev, O_RDONLY)) < 0)
    exit (10);

  for (i = 0; i < 4; i++)
    {
      if ((offset = lseek (fd, i * block_size, SEEK_SET))
          != (off_t) (i * block_size))
        exit (6);

      if ((n_read = read (fd, buf, block_size)) != block_size)
        {
          perror ("read2");
          printf ("read %d bytes (expected %d)\n", n_read, block_size);
          exit (7);
        }
      if (buf[0] != '0' + i || buf[1] != 0)
        exit (8);
    }

  exit (0);
}

  $ gcc -Wall k.c; ./a.out /dev/st0 32768 && echo ok || echo failed
  ok

Regards,
Jim

[EMAIL PROTECTED] (Roman Fietze) writes:
| Hello,
|
| I had problems using dd directly on a tape device with "skip=nnn" on
| Linux 2.2.14, because seek does not seem to report an error on a tape
| device. This was necessary to access Amanda backups with standard
| UNIX/Linux tools.
|
| My change does a read when skips have to made and if the input is not
| a regular file. This way dd's skip works on all inputs including
| pipes and devices. I do not know how other systems handle seeks on
| pipes and devices, so this change might only be necessary on Linux
| (or maybe Linux has to change the way how seeks on devices are
| handled, at least it should return an error).
|
|
|
| *** ../../fileutils-4.0/src/dd.c        Sat Sep 19 19:09:23 1998
| --- dd.c        Tue Mar  7 17:09:54 2000
| ***************
| *** 814,819 ****
| --- 814,820 ----
|        operation, fall back on using read.  */
|     o = records * blocksize;
|     if (o / blocksize != records
| +       || !S_ISREG(stats.st_mode)
|         || lseek (fdesc, o, SEEK_SET) == -1)
|       {
|         while (records-- > 0)
|
|
| Roman
|
| --
| Roman Fietze (Mail Code 5023)       Heidelberg Digital Finishing GmbH
| [EMAIL PROTECTED]                       [EMAIL PROTECTED]

Reply via email to