diff --git a/doc/userguide/capture-hardware/pcap-file.rst b/doc/userguide/capture-hardware/pcap-file.rst index d5ed628dde36..2d0dde98ca15 100644 --- a/doc/userguide/capture-hardware/pcap-file.rst +++ b/doc/userguide/capture-hardware/pcap-file.rst @@ -33,6 +33,10 @@ This can improve performance, especially for large files. The size can be specified through the command line option, see :ref:`--pcap-file-buffer-size ` +Setting ``buffer-size`` to ``0`` disables ``setvbuf`` buffering. This is the +explicit opt-out for non-seekable sources such as ``/dev/stdin`` or named +pipes, where buffering the underlying file descriptor is not supported. + Directory-related options ------------------------- diff --git a/doc/userguide/partials/options.rst b/doc/userguide/partials/options.rst index 5264db813337..bcbca0f62206 100644 --- a/doc/userguide/partials/options.rst +++ b/doc/userguide/partials/options.rst @@ -103,7 +103,8 @@ .. option:: --pcap-file-buffer-size Set read buffer size using ``setvbuf`` to speed up pcap reading. Valid values - are 4 KiB to 64 MiB. Default value is 128 KiB. Supported on Linux only. + are 0, which disables ``setvbuf`` buffering, or 4 KiB to 64 MiB. Default + value is 128 KiB. Supported on Linux only. .. option:: -i diff --git a/src/source-pcap-file-helper.c b/src/source-pcap-file-helper.c index e88db6d51547..70cb2f550bb5 100644 --- a/src/source-pcap-file-helper.c +++ b/src/source-pcap-file-helper.c @@ -271,10 +271,16 @@ TmEcode InitPcapFile(PcapFileFileVars *pfv) #if defined(HAVE_SETVBUF) && defined(OS_LINUX) if (pcap_g.read_buffer_size > 0) { - errno = 0; - if (setvbuf(pcap_file(pfv->pcap_handle), pfv->buffer, _IOFBF, pcap_g.read_buffer_size) < - 0) { - SCLogWarning("Failed to setvbuf on PCAP file handle: %s", strerror(errno)); + struct stat sb; + int fd = fileno(pcap_file(pfv->pcap_handle)); + if (fd >= 0 && fstat(fd, &sb) == 0 && !S_ISREG(sb.st_mode)) { + SCLogInfo("%s: skipping setvbuf, underlying fd is not a regular file", pfv->filename); + } else { + errno = 0; + if (setvbuf(pcap_file(pfv->pcap_handle), pfv->buffer, _IOFBF, + pcap_g.read_buffer_size) != 0) { + SCLogWarning("Failed to setvbuf on PCAP file handle: %s", strerror(errno)); + } } } #endif diff --git a/src/source-pcap-file.c b/src/source-pcap-file.c index 808fe27b69cb..b32a0cecea59 100644 --- a/src/source-pcap-file.c +++ b/src/source-pcap-file.c @@ -158,13 +158,19 @@ void PcapFileGlobalInit(void) if (SCConfGet("pcap-file.buffer-size", &str) == 1) { uint32_t value = 0; if (ParseSizeStringU32(str, &value) < 0) { - SCLogWarning("failed to parse pcap-file.buffer-size %s", str); - } - if (value >= PCAP_FILE_BUFFER_SIZE_MIN && value <= PCAP_FILE_BUFFER_SIZE_MAX) { - SCLogInfo("Pcap-file will use %u buffer size", value); + SCLogWarning("failed to parse pcap-file.buffer-size %s; keeping default %u", str, + PCAP_FILE_BUFFER_SIZE_DEFAULT); + } else if (value == 0 || + (value >= PCAP_FILE_BUFFER_SIZE_MIN && value <= PCAP_FILE_BUFFER_SIZE_MAX)) { + if (value == 0) { + SCLogInfo("Pcap-file buffering disabled"); + } else { + SCLogInfo("Pcap-file will use %u buffer size", value); + } pcap_g.read_buffer_size = value; } else { - SCLogWarning("pcap-file.buffer-size value of %u is invalid. Valid range is %u-%u", + SCLogWarning("pcap-file.buffer-size value of %u is invalid. Valid values are 0 to " + "disable buffering, or %u-%u", value, PCAP_FILE_BUFFER_SIZE_MIN, PCAP_FILE_BUFFER_SIZE_MAX); } }