15

Is there any way to make it so that when programs try to perform seek() operations on a named pipe it will come back successful (but act as if the pipe was an empty file) instead of 'Illegal seek'?

I have every last little bit of logging on my system stored in an SQLite database, I don't have files anywhere. However there are a few programs that have trouble with this. There are 2 specific cases;

  • A program wants to write to a log file which syslog-ng has created as a named pipe and is reading from. The program wants to perform a seek() for some reason and then fails.
  • A program (such as denyhosts or fail2ban) wants to read from a log file which syslog-ng has created as a named pipe and is writing to. The program wants to performs a seek() on it and fails.

Ideally I'd just like these seeks to behave as if the named pipe were just an empty file. I can't see any reason why a program writing a log would need to perform a seek anyway, it should just open the file for append and start writing. I can see why a program reading would want to seek, so that it could resume from its last position, and so I would like it to behave as if the file were empty (like it had been truncated).

So is there some option that can be set on named pipes to get them to behave this way? If not is there a mode that can be set when syslog-ng opens the pipe to have it behave this way (I'm open to making code changes)? Or am I up a creek?

2 Answers 2

11

Seekable pipes have been proposed for the Linux kernel, but I'm not aware of a working patch to implement them.

You could use an LD_PRELOAD'ed library that overrides the lseek call on specific files. I don't know of any off-the-shelf wrapper for this purpose. Shadowfs might help in writing one.

3
  • 1
    I'll try the LD_PRELOAD route. Not the greatest solution, but should be doable.
    – phemmer
    Feb 5, 2012 at 17:47
  • 1
    Btw, would having seekable pipe be necessary for less to be able to follow pipe the same way it can follow file? I'm asking in the context of Follow a pipe using less? question (you might prefer to answer there). Jan 29, 2015 at 15:31
  • 1
    @PiotrDobrogost In the context of the F command in less, it would be enough for less to refresh the screen if it doesn't get any output for a second or so. Making pipes seekable wouldn't help: the relevant difference there is that F goes to the end of the file, then waits for data to appear past the end — but for a pipe, the end of file only comes when the writer closes the file. Jan 29, 2015 at 17:34
0

If the application is calling seek, then it is either broken, or is not meant to work on pipes. If the former, then it needs fixed. If the latter, then it expects the seek to actually work, so lieing and claiming it worked when it did not will almost certainly cause incorrect operation.

Also if the log file is replaced with a named pipe, then only one process could read from it at a time. It should be a socket instead.

4
  • 2
    Not meant to work on pipes doesnt mean cant work on pipes. What if the application is simply doing a SEEK_END to get to the end of the file? Or maybe its doing a SEEK_CUR to find the current location. Neither of these would cause any issues if I lied to the program about the results of the seek. The only place that would break is if the application was trying to go back and overwrite data already written which it shouldnt be doing with log files. And yes, I am aware of the one-process-per-pipe limitation. This will not be a problem.
    – phemmer
    Feb 5, 2012 at 23:17
  • 1
    If all it does is seek to the end to append, then it should just be opening the file in append mode, so it falls into the broken category. Applications don't try to find the current location unless they need to be able to seek somewhere else, and then return to the current location, so it falls into the "you'll break it by silently failing" category. It is very unlikely that a program calls seek but doesn't really need it to work ( and if it does, it falls in the broken category ).
    – psusi
    Feb 6, 2012 at 4:08
  • 1
    Not true. Many applications seek to the end of the file in case some other program has written to the file since it last did. Otherwise writing where its currently at would clobber the other program's changes. And if its reading from the file, it might want to use SEEK_CUR to get its current location so that when the program starts back up, it can resume where it left off.
    – phemmer
    Feb 6, 2012 at 5:00
  • 1
    @Patrick, for the former, if it is appending it should be reopening the file in append mode. In this case you are talking about reading, in which case, it doesn't make sense to skip new data it hasn't read yet ( and silently ignoring the seek would break that ). As for the latter, if it is trying to use seek to return to the same position after closing and reopening the file that will break on a pipe if you silently ignore the seek, since when it closes the pipe the server gets a SIGPIPE, which presumably makes it reset so the next client that opens the pipe starts at the beginning.
    – psusi
    Feb 6, 2012 at 23:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .