Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seek after write on block device fails #13977

Closed
p5pRT opened this issue Jul 10, 2014 · 9 comments
Closed

Seek after write on block device fails #13977

p5pRT opened this issue Jul 10, 2014 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 10, 2014

Migrated from rt.perl.org#122263 (status was 'rejected')

Searchable as RT122263$

@p5pRT
Copy link
Author

p5pRT commented Jul 10, 2014

From afresh1@openbsd.org

Created by afresh1@openbsd.org

Trying to seek and write to a block device (directly to the raw USB disk)
fails with "Invalid Argument". Writing to a file or /dev/null succeeds.

Here is a short test program to reproduce it in both perl 5.18.2 and blead.

If you uncomment the first seek, that one succeeds.
If I open the device for write ('>'), the second also succeeds.

#!/usr/bin/perl

use Fcntl qw/SEEK_SET/;

$| = 1;
my $devpath = "/dev/rsd1c";
open(my $dev, '+<', $devpath) or die "open​: $!";

#seek($dev, 0, SEEK_SET) or die "seek1​: $!";
print $dev "\0" or die "print​: $!";
seek($dev, 0, SEEK_SET) or die "seek2​: $!";
exit;

Results in
seek2​: Invalid argument at ../seek_fails.pl line 11.

17275 perl CALL read(0x3,0x55c7a558000,0x2000)
17275 perl RET read 0
17275 perl CALL close(0x3)
17275 perl RET close 0
17275 perl CALL open(0x55c815694d0,0x2<O_RDWR>)
17275 perl NAMI "/dev/rsd1c"
17275 perl RET open 3
17275 perl CALL ioctl(0x3,TIOCGETA,0x7f7ffffc3460)
17275 perl RET ioctl -1 errno 25 Inappropriate ioctl for device
17275 perl CALL lseek(0x3,0,SEEK_CUR)
17275 perl RET lseek 0
17275 perl CALL fstat(0x3,0x55c7bf904c0)
17275 perl STRU struct stat { dev=1056, ino=78141, mode=crw-r----- , nlink=1, uid=0, gid=5, rdev=3346, atime=1404997395.598203946, mtime=1405001846.591111454, ctime=1405001846.591111454, size=0, blocks=0, blksize=65536, flags=0x0, gen=0xea395e02 }
17275 perl RET fstat 0
17275 perl CALL fcntl(0x3,F_SETFD,FD_CLOEXEC)
17275 perl RET fcntl 0
17275 perl CALL write(0x3,0x55c7a558000,0x1)
17275 perl RET write -1 errno 22 Invalid argument
17275 perl CALL issetugid()
17275 perl RET issetugid 0
17275 perl CALL open(0x7f7ffffc3230,0x10000<O_RDONLY|O_CLOEXEC>)
17275 perl NAMI "/usr/share/nls/C/libc.cat"
17275 perl RET open 4
17275 perl CALL fstat(0x4,0x7f7ffffc3160)
17275 perl STRU struct stat { dev=1061, ino=213259, mode=-r--r--r-- , nlink=1, uid=0, gid=7, rdev=868374, atime=1404826991.360913194, mtime=1404090328, ctime=1404171061.141608098, size=4080, blocks=8, blksize=16384, flags=0x0, gen=0x495b9f4 }
17275 perl RET fstat 0
17275 perl CALL mmap(0,0xff0,0x1<PROT_READ>,0x1<MAP_SHARED>,0x4,0)
17275 perl RET mmap 5894854905856/0x55c80bb9000
17275 perl CALL close(0x4)
17275 perl RET close 0
17275 perl CALL munmap(0x55c80bb9000,0xff0)
17275 perl RET munmap 0
17275 perl CALL write(0x2,0x55c79020000,0x35)
17275 perl GIO fd 2 wrote 53 bytes
  "seek2​: Invalid argument at ../seek_fails.pl line 11.
  "
17275 perl RET write 53/0x35
17275 perl CALL close(0x3)
17275 perl RET close 0
17275 perl CALL munmap(0x55c76a39000,0x1000)
17275 perl RET munmap 0
17275 perl CALL exit(0x16)
(END)

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.21.2:

Configured by afresh1 at Thu Jul 10 02:49:53 PDT 2014.

Summary of my perl5 (revision 5 version 21 subversion 2) configuration:
  Local Commit: bcae077cb912e777be66e348a59661e67fba376e
  Ancestor: cdf175f7f80eedf9ecae198d41dded383592465d
  Platform:
    osname=openbsd, osvers=5.5, archname=OpenBSD.amd64-openbsd
    uname='openbsd trillian.home.hewus.com 5.5 generic.mp#245 amd64 '
    config_args='-de -Dusedevel'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_FORTIFY_SOURCE=2',
    optimize='-O2',
    cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.2.1 20070719 ', gccosandvers='openbsd5.5'
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags ='-Wl,-E  -fstack-protector -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib
    libs=-lgdbm -lm -lutil -lc
    perllibs=-lm -lutil -lc
    libc=/usr/lib/libc.so.76.0, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-DPIC -fPIC ', lddlflags='-shared -fPIC  -L/usr/local/lib -fstack-protector'

Locally applied patches:
    aa93ad8ec8c9ed2094fefe11a0724bc0c977f5fd
    bcae077cb912e777be66e348a59661e67fba376e


@INC for perl 5.21.2:
    lib
    /usr/local/lib/perl5/site_perl/5.21.2/OpenBSD.amd64-openbsd
    /usr/local/lib/perl5/site_perl/5.21.2
    /usr/local/lib/perl5/5.21.2/OpenBSD.amd64-openbsd
    /usr/local/lib/perl5/5.21.2
    .


Environment for perl 5.21.2:
    HOME=/home/afresh1
    LANG (unset)
    LANGUAGE (unset)
    LC_CTYPE=en_US.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/afresh1/.plenv/bin:/home/afresh1/bin:/home/afresh1/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/usr/games:/home/afresh1/.plenv/bin:.
    PERL_BADLANG (unset)
    SHELL=/bin/ksh

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2014

From 2bfjdsla52kztwejndzdstsxl9athp@gmail.com

This has nothing to do with perl.

Trying to seek and write to a block device (directly to the raw USB disk)
fails with "Invalid Argument".

17275 perl CALL write(0x3,0x55c7a558000,0x1)
17275 perl RET write -1 errno 22 Invalid argument

Raw disk device I/O must be block aligned. Writing a single byte
will always fail (except in the unlikely case that the disk has
a block size of 1).

/Bo Lindbergh

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2014

From andrew@afresh1.com

On Fri, Jul 11, 2014 at 02​:00​:40AM +0200, Bo Lindbergh wrote​:

This has nothing to do with perl.

Trying to seek and write to a block device (directly to the raw USB disk)
fails with "Invalid Argument".

17275 perl CALL write(0x3,0x55c7a558000,0x1)
17275 perl RET write -1 errno 22 Invalid argument

Raw disk device I/O must be block aligned. Writing a single byte
will always fail (except in the unlikely case that the disk has
a block size of 1).

Sounds reasonable and this does succeed​:

print $dev "\0" x 512 or die "print​: $!";
seek($dev, 0, SEEK_SET) or die "seek2​: $!";

Perhaps a case of a misleading error message, as it seems the print should not
return true if the write failed.

On Thu, Jul 10, 2014 at 07​:35​:10AM -0700, via RT wrote​:

print $dev "\0" or die "print​: $!";
seek($dev, 0, SEEK_SET) or die "seek2​: $!";
exit;

Results in
seek2​: Invalid argument at ../seek_fails.pl line 11.

I will instead complain that the error is "seek2​:..." not "print​:..."

Not sure I can update the ticket though.

l8rZ,
--
andrew - http​://afresh1.com

Adding manpower to a late software project makes it later.

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2014

From @iabyn

On Fri, Jul 11, 2014 at 12​:07​:37AM -0700, Andrew Fresh wrote​:

On Fri, Jul 11, 2014 at 02​:00​:40AM +0200, Bo Lindbergh wrote​:

This has nothing to do with perl.

Trying to seek and write to a block device (directly to the raw USB disk)
fails with "Invalid Argument".

17275 perl CALL write(0x3,0x55c7a558000,0x1)
17275 perl RET write -1 errno 22 Invalid argument

Raw disk device I/O must be block aligned. Writing a single byte
will always fail (except in the unlikely case that the disk has
a block size of 1).

Sounds reasonable and this does succeed​:

print $dev "\0" x 512 or die "print​: $!";
seek($dev, 0, SEEK_SET) or die "seek2​: $!";

Perhaps a case of a misleading error message, as it seems the print should not
return true if the write failed.

print() does buffered output. The underlying write() system call will not
be performed until seek() flushes the buffer. If you replace print() with
syswrite(), you'll get the error earlier.

--
Never do today what you can put off till tomorrow.

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2014

From andrew@afresh1.com

On Fri, Jul 11, 2014 at 11​:47​:10AM +0100, Dave Mitchell wrote​:

print() does buffered output. The underlying write() system call will not
be performed until seek() flushes the buffer. If you replace print() with
syswrite(), you'll get the error earlier.

I see. I would have expected that

On Thu, Jul 10, 2014 at 07​:35​:10AM -0700, via RT wrote​:

$| = 1;

would have reduced that buffering, at least to be line buffered.

So I guess there is no good fix in this case.

l8rZ,
--
andrew - http​://afresh1.com

At the source of every error which is blamed on the computer, you
will find at least two human errors, including the error of blaming
it on the computer.

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2014

From @Leont

On Fri, Jul 11, 2014 at 1​:29 PM, Andrew Fresh <andrew@​afresh1.com> wrote​:

On Fri, Jul 11, 2014 at 11​:47​:10AM +0100, Dave Mitchell wrote​:

print() does buffered output. The underlying write() system call will not
be performed until seek() flushes the buffer. If you replace print() with
syswrite(), you'll get the error earlier.

I see. I would have expected that

On Thu, Jul 10, 2014 at 07​:35​:10AM -0700, via RT wrote​:

$| = 1;

would have reduced that buffering, at least to be line buffered.

So I guess there is no good fix in this case.

$| affects the current default filehandle (which defaults to STDOUT).
«$dev->autoflush(1)» would do what you meant (though you'd need to load
IO​::Handle/FileHandle first on <5.14).

Leon

@p5pRT
Copy link
Author

p5pRT commented Oct 21, 2014

From @tonycoz

On Thu Jul 10 17​:01​:20 2014, 2bfjdsla52kztwejndzdstsxl9athp@​gmail.com wrote​:

This has nothing to do with perl.

Trying to seek and write to a block device (directly to the raw USB disk)
fails with "Invalid Argument".

17275 perl CALL write(0x3,0x55c7a558000,0x1)
17275 perl RET write -1 errno 22 Invalid argument

Raw disk device I/O must be block aligned. Writing a single byte
will always fail (except in the unlikely case that the disk has
a block size of 1).

And so, rejecting this ticket.

Tony

@p5pRT
Copy link
Author

p5pRT commented Oct 21, 2014

@tonycoz - Status changed from 'open' to 'rejected'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant