Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package mbuffer for openSUSE:Factory checked 
in at 2026-04-22 16:56:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mbuffer (Old)
 and      /work/SRC/openSUSE:Factory/.mbuffer.new.11940 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mbuffer"

Wed Apr 22 16:56:53 2026 rev:30 rq:1348540 version:20260301

Changes:
--------
--- /work/SRC/openSUSE:Factory/mbuffer/mbuffer.changes  2026-01-19 
18:42:38.881336631 +0100
+++ /work/SRC/openSUSE:Factory/.mbuffer.new.11940/mbuffer.changes       
2026-04-22 16:57:00.557576867 +0200
@@ -1,0 +2,10 @@
+Mon Apr 20 21:26:10 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 20260301:
+  * drop speed limitations at the start and end of transfer
+  * fix input stalling unintential in -M/-R mode
+  * fix: do not close an already closed file
+  * added dynamic speed adjustment with low speed
+  * add support to bind network input to a specific interface
+
+-------------------------------------------------------------------

Old:
----
  mbuffer-20251025.tgz

New:
----
  mbuffer-20260301.tgz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mbuffer.spec ++++++
--- /var/tmp/diff_new_pack.15whSQ/_old  2026-04-22 16:57:01.553618094 +0200
+++ /var/tmp/diff_new_pack.15whSQ/_new  2026-04-22 16:57:01.557618259 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           mbuffer
-Version:        20251025
+Version:        20260301
 Release:        0
 Summary:        Replacement for "buffer" with many more Features
 License:        GPL-3.0-or-later

++++++ mbuffer-20251025.tgz -> mbuffer-20260301.tgz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mbuffer-20251025/.hg_archival.txt 
new/mbuffer-20260301/.hg_archival.txt
--- old/mbuffer-20251025/.hg_archival.txt       2025-10-27 21:14:45.000000000 
+0100
+++ new/mbuffer-20260301/.hg_archival.txt       2026-03-01 16:47:32.000000000 
+0100
@@ -1,4 +1,4 @@
 repo: 6e3b485d74645931e2408ed1f57e659029b5639a
-node: d633a540b192a132bfe13faa3c5e861055ba5acf
+node: 3f8b8febe218721e3fcd1097b64d2d4324b156f5
 branch: default
-tag: R20251025
+tag: R20260301
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mbuffer-20251025/.hgtags new/mbuffer-20260301/.hgtags
--- old/mbuffer-20251025/.hgtags        2025-10-27 21:14:45.000000000 +0100
+++ new/mbuffer-20260301/.hgtags        2026-03-01 16:47:32.000000000 +0100
@@ -122,3 +122,5 @@
 cbd7b2d41454936d4bd2dcc44eaa189fb066133e R20241007
 220a607ab1f50fe5b42e04d86dff200bc680d575 R20250429
 13ae9bf1e1df470cdfd51c6b2433dc531eff0c0d R20250809
+d633a540b192a132bfe13faa3c5e861055ba5acf R20251025
+a9a9bba352d3bcf98dcb513f5c17c4e1140a8776 R20260221
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mbuffer-20251025/ChangeLog 
new/mbuffer-20260301/ChangeLog
--- old/mbuffer-20251025/ChangeLog      2025-10-27 21:14:45.000000000 +0100
+++ new/mbuffer-20260301/ChangeLog      2026-03-01 16:47:32.000000000 +0100
@@ -1,3 +1,12 @@
+20260301:
+- drop speed limitations at the start and end of transfer
+- fix input stalling unintential in -M/-R mode
+- fix: do not close an already closed file
+
+20260221:
+- added dynamic speed adjustment with low speed
+- add support to bind network input to a specific interface
+
 20251025:
 - updated config.sub, config.guess, and instal-sh
 - added MacOS support (submitted by Grady McBride)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mbuffer-20251025/input.c new/mbuffer-20260301/input.c
--- old/mbuffer-20251025/input.c        2025-10-27 21:14:45.000000000 +0100
+++ new/mbuffer-20260301/input.c        2026-03-01 16:47:32.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2000-2024, Thomas Maier-Komor
+ *  Copyright (C) 2000-2026, Thomas Maier-Komor
  *
  *  This file is part of mbuffer's source code.
  *
@@ -52,10 +52,10 @@
                int err;
 
                fd_set readfds;
-               FD_ZERO(&readfds);
-               FD_SET(TermQ[0],&readfds);
-               FD_SET(In,&readfds);
                do {
+                       FD_ZERO(&readfds);
+                       FD_SET(TermQ[0],&readfds);
+                       FD_SET(In,&readfds);
                        err = select(maxfd,&readfds,0,0,0);
                        debugiomsg("inputThread: select(%d, {%d,%d}, 0, 0, 0) = 
%d\n", maxfd,In,TermQ[0],err);
                        assert((err > 0) || (errno == EBADF || errno == EINTR));
@@ -362,7 +362,7 @@
        for (;;) {
                int err;
 
-               if (startread < 1) {
+               if ((startread < 1) && (MinSpeed == 0)) {
                        err = pthread_mutex_lock(&LowMut);
                        assert(err == 0);
                        counter_getvalue(&FullBlocks,&fill);
@@ -374,13 +374,14 @@
                                pthread_cleanup_pop(0);
                                ++FullCount;
                                debugmsg("inputThread: low watermark reached, 
continuing...\n");
+                               (void) clock_gettime(ClockSrc,&last);
                        }
                        err = pthread_mutex_unlock(&LowMut);
                        assert(err == 0);
                }
                if (Terminate) {        /* for async termination requests */
                        debugmsg("inputThread: terminating early upon 
request...\n");
-                       if (-1 == close(In))
+                       if ((-1 != In) && (-1 == close(In)))
                                errormsg("error closing input: 
%s\n",strerror(errno));
                        if (Status)
                                pthread_exit((void *)1);
@@ -391,8 +392,24 @@
                        debugmsg("inputThread: no more blocks\n");
                        return 0;
                }
-               if (MaxReadSpeed)
-                       xfer = enforceSpeedLimit(MaxReadSpeed,xfer,&last);
+               if ((0 != MaxReadSpeed) && (0 != Numout)) {
+                       unsigned long long speedlimit = MaxReadSpeed;
+                       if (MinSpeed != 0) {
+                               counter_getvalue(&FullBlocks,&fill);
+                               double frac = (double)fill/(double)Numblocks;
+                               if (frac >= StartWrite) {
+                                       speedlimit = MinSpeed;
+                               } else if (frac <= StartRead) {
+                                       speedlimit = MaxReadSpeed;
+                               } else {
+                                       unsigned long long speeddiff = 
MaxReadSpeed-MinSpeed;
+                                       double quot = 
((double)(frac-StartRead))/((double)(StartWrite-StartRead));
+                                       speedlimit = 
MaxReadSpeed-speeddiff*quot;
+                               }
+                               debugmsg("frac %f, input speed limit 
%llu\n",frac,speedlimit);
+                       }
+                       xfer = enforceSpeedLimit(speedlimit,xfer,&last);
+               }
                counter_post(&FullBlocks);
                if (startwrite > 0) {
                        err = pthread_mutex_lock(&HighMut);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mbuffer-20251025/mbuffer.1.in 
new/mbuffer-20260301/mbuffer.1.in
--- old/mbuffer-20251025/mbuffer.1.in   2025-10-27 21:14:45.000000000 +0100
+++ new/mbuffer-20260301/mbuffer.1.in   2026-03-01 16:47:32.000000000 +0100
@@ -66,10 +66,11 @@
 \fB\-\-truncate\fR
 Truncate next output file given via option \-o when opening it.
 .TP
-\fB\-I\fR <\fIport\fP>
+\fB\-I\fR <\fI[hostname:]port[@interface]\fP>
 Use network port \fIport\fP as input instead of the standard input. If
 given a hostname and a port in the form \fIhostname:port\fP, only the given
-host is allowed to connect.
+host is allowed to connect. If \fIinterface\fP is specified, connections are
+only accepted on the specified interface.
 .TP
 \fB\-O\fR <\fIhostname:port\fP>
 Write output to \fIhostname:port\fP instead of the standard output (will
@@ -106,6 +107,17 @@
 \fB\-R\fR <\fIrate\fP>
 Same as above only for setting the transfer limit for the writer.
 .TP 
+\fB\-M\fR <\fIrate\fP>
+Set minimum rate for dynamic transfer rate limitation.  The data rate is
+adjusted dynamically, between the high- and low-watermark values (-p and -P),
+which must also be provided.
+
+When used in input mode, data rate starts with the -r rate and declines to the
+-M rate based on the fill level of the buffer.
+
+When used in output mode, the data rate is adjusted similarly, but starting
+with the minimum rate and increasing to the -R rate for the output.
+.TP 
 \fB\-f\fR
 Overwrite output file if it exists already.
 .TP 
@@ -283,6 +295,15 @@
 \fImaster: \fPtar cf \- /tree_to_clone | mbuffer \-O clone0:8000 \-O 
clone1:8000
 .LP
 \fIclones: \fPmbuffer \-I master:8000 | tar xf \-
+.LP
+.LP
+Operating a drive tape with dynamic speed scaling:
+.LP
+tar cf - / | mbuffer -o /dev/tape -p20% -p80% -M 50M -R 120M
+.LP
+mbuffer -i /dev/tape -p20% -p80% -M 50M -r 120M | tar xf -
+.LP
+.LP
 .SH "EXITCODE"
 .LP
 mbuffer returns 0 upon success. Any kind of failure will yield a non-zero
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mbuffer-20251025/mbuffer.c 
new/mbuffer-20260301/mbuffer.c
--- old/mbuffer-20251025/mbuffer.c      2025-10-27 21:14:45.000000000 +0100
+++ new/mbuffer-20260301/mbuffer.c      2026-03-01 16:47:32.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2000-2025, Thomas Maier-Komor
+ *  Copyright (C) 2000-2026, Thomas Maier-Komor
  *
  *  This file is part of mbuffer's source code.
  *
@@ -189,6 +189,7 @@
                ErrorOccurred = 1;
                Terminate = 1;
                (void) close(In);
+               In = -1;
                if (TermQ[1] != -1)
                        if (-1 == write(TermQ[1],"0",1)) {}
                if (StartWrite > 0)
@@ -615,7 +616,8 @@
                out = open(outfile,mode,0666);
                if (-1 == out)
                        errormsg("error reopening output file: 
%s\n",strerror(errno));
-               enable_directio(out,outfile);
+               else
+                       enable_directio(out,outfile);
        } while (-1 == out);
        (void) clock_gettime(ClockSrc,&volstart);
        diff = volstart.tv_sec - now.tv_sec + (double) (volstart.tv_nsec - 
now.tv_nsec) * 1E-9;
@@ -855,8 +857,24 @@
                if (multipleSenders == 0) {
                        counter_post(&FreeBlocks);
                }
-               if (MaxWriteSpeed)
-                       xfer = enforceSpeedLimit(MaxWriteSpeed,xfer,&last);
+               if ((0 != MaxWriteSpeed) && (-1 == Finish)) {
+                       unsigned long long speedlimit = MaxWriteSpeed;
+                       if (MinSpeed) {
+                               counter_getvalue(&FullBlocks,&fill);
+                               double frac = (double)fill/(double)Numblocks;
+                               if (frac <= StartRead) {
+                                       speedlimit = MinSpeed;
+                               } else if (frac >= StartWrite) {
+                                       speedlimit = MaxWriteSpeed;
+                               } else {
+                                       unsigned long long speeddiff = 
MaxWriteSpeed-MinSpeed;
+                                       double quot = 
((double)(frac-StartRead))/((double)(StartWrite-StartRead));
+                                       speedlimit = speeddiff*quot+MinSpeed;
+                               }
+                               debugmsg("frac %f, output speed limit 
%llu\n",frac,speedlimit);
+                       }
+                       xfer = enforceSpeedLimit(speedlimit,xfer,&last);
+               }
                if (Pause)
                        (void) mt_usleep(Pause);
                if (Finish == at) {
@@ -1233,10 +1251,23 @@
                        infomsg("adjusting total buffer memory to 
%s",hBytes(Totalmem));
                }
        }
+       if ((MaxReadSpeed != 0) && (MaxWriteSpeed != 0))
+               fatal("Set either maximum read or maximum write speed.\n");
+       if (0 != MinSpeed) {
+               if ((0 == MaxReadSpeed) && (0 == MaxWriteSpeed))
+                       fatal("Minimum speed needs also a maximum speed. Please 
use -R or -r to set it.\n");
+               if ((1 == StartRead) && (0 == StartWrite)) {    // defaults not 
changed
+                       StartRead = 0.2;
+                       StartWrite = 0.8;
+                       debugmsg("minspeed is set, but -P/-p is at its 
defaults. Updated to -p %3.2g%%, -P %3.2g%%\n", StartRead, StartWrite);
+               }
+               if (StartRead >= StartWrite)
+                       fatal("High watermark must be higher than low watermark 
(-p %f < -P %f).\n",StartRead,StartWrite);
+       }
        if (Numblocks < 5)
                fatal("Number of blocks must be at least 5.\n");
-       if ((StartRead < 1) && (StartWrite > 0))
-               fatal("setting both low watermark and high watermark doesn't 
make any sense...\n");
+       if ((StartRead < 1) && (StartWrite > 0) && (0 == MinSpeed))
+               fatal("Low watermark and high watermark are either mutual 
exclusive or need minimum speed set as well (-M).\n");
        if ((NumSenders-Hashers > 0) && (Autoloader || OutVolsize))
                fatal("multi-volume support is unsupported with multiple 
outputs\n");
        if (Autoloader) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mbuffer-20251025/network.c 
new/mbuffer-20260301/network.c
--- old/mbuffer-20251025/network.c      2025-10-27 21:14:45.000000000 +0100
+++ new/mbuffer-20260301/network.c      2026-03-01 16:47:32.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2000-2025, Thomas Maier-Komor
+ *  Copyright (C) 2000-2026, Thomas Maier-Komor
  *
  *  This file is part of mbuffer's source code.
  *
@@ -50,8 +50,12 @@
 #define IPPROTO_TCP 6
 #endif
 
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 64
+#endif
+
 
-static void openNetworkInput(const char *host, const char *portstr);
+static void openNetworkInput(const char *host, const char *portstr, const char 
*ifstr);
 
 
 int32_t TCPBufSize = 0;
@@ -115,7 +119,7 @@
 
 void initNetworkInput(const char *addr)
 {
-       char *host, *portstr;
+       char *host, *portstr, *ifstr;
        int l;
 
        debugmsg("initNetworkInput(\"%s\")\n",addr);
@@ -126,6 +130,11 @@
        l = strlen(addr) + 1;
        host = alloca(l);
        memcpy(host,addr,l);
+       ifstr = strrchr(host,'@');
+       if (ifstr) {
+               *ifstr = 0;
+               ++ifstr;
+       }
        portstr = strrchr(host,':');
        if (portstr == 0) {
                portstr = host;
@@ -141,7 +150,7 @@
                *portstr = 0;
                ++portstr;
        }
-       openNetworkInput(host,portstr);
+       openNetworkInput(host,portstr,ifstr);
 }
 
 static const char *addrinfo2str(const struct addrinfo *ai, char *buf, size_t s)
@@ -167,20 +176,29 @@
 }
 
 
-static void openNetworkInput(const char *host, const char *portstr)
+static void openNetworkInput(const char *host, const char *portstr, const char 
*ifstr)
 {
        struct hostent *h = 0, *r = 0;
        const int reuse_addr = 1;
        int sock;
 
        uint16_t port = getServicePort(portstr);
-       debugmsg("openNetworkInput(\"%s\",%hu)\n",host?host:"<null>",port);
+       
debugmsg("openNetworkInput(\"%s\",%hu,\"%s\")\n",host?host:"<any>",port,ifstr?ifstr:"<any>");
        int family = AddrFam == AF_UNSPEC ? AF_INET6 : AddrFam;
        sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
        if (0 > sock)
                fatal("could not create socket for network input: 
%s\n",strerror(errno));
        if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, 
sizeof(reuse_addr)))
                warningmsg("cannot set socket to reuse address: 
%s\n",strerror(errno));
+#ifdef SO_BINDTODEVICE
+       if (ifstr) {
+               if (-1 == setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifstr, 
strlen(ifstr)))
+                       errormsg("cannot bind network input to network 
interface '%s'\n",ifstr);
+       }
+#else
+       if (ifstr)
+               errormsg("bind to network interface not supported on this 
system.\n");
+#endif
 #ifdef IPV6_V6ONLY
        if (AF_INET6 == AddrFam) {
                const int ipv6_only = 1;
@@ -208,9 +226,9 @@
                h = gethostbyname(host);
                if (0 == h)
 #ifdef HAVE_HSTRERROR
-                       fatal("could not resolve server hostname: 
%s\n",hstrerror(h_errno));
+                       fatal("could not resolve server hostname '%s': 
%s\n",host,hstrerror(h_errno));
 #else
-                       fatal("could not resolve server hostname: error code 
%d\n",h_errno);
+                       fatal("could not resolve server hostname '%s': error 
code %d\n",host,h_errno);
 #endif
 
        }
@@ -234,7 +252,6 @@
        debugmsg("listening on socket...\n");
        if (0 > listen(sock,1))         /* accept only 1 incoming connection */
                fatal("could not listen on socket for network input: 
%s\n",strerror(errno));
-       char peer[128];
        for (;;) {
                char addrbuf[sizeof(struct sockaddr_in6)];
                socklen_t clen = sizeof(addrbuf);
@@ -258,6 +275,7 @@
                } else {
                        abort();
                }
+               char peer[128];
                inet_ntop(af,caddr,peer,sizeof(peer));
                if (h == 0) {
                        expected = 1;   // any host is ok
@@ -265,7 +283,7 @@
                        debugmsg("checking connection from %s\n",peer);
                        char **p;
                        for (p = h->h_addr_list; *p; ++p) {
-                               char addrstr[64];
+                               char addrstr[INET6_ADDRSTRLEN];
                                
inet_ntop(h->h_addrtype,*p,addrstr,sizeof(addrstr));
                                debugmsg("checking against %s\n",addrstr);
                                if (0 == memcmp(caddr,*p,h->h_length)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mbuffer-20251025/settings.c 
new/mbuffer-20260301/settings.c
--- old/mbuffer-20251025/settings.c     2025-10-27 21:14:45.000000000 +0100
+++ new/mbuffer-20260301/settings.c     2026-03-01 16:47:32.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2000-2025, Thomas Maier-Komor
+ *  Copyright (C) 2000-2026, Thomas Maier-Komor
  *
  *  This file is part of mbuffer's source code.
  *
@@ -77,6 +77,7 @@
        Blocksize = 10240,      // fundamental I/O block size
        MaxReadSpeed = 0,
        MaxWriteSpeed = 0,
+       MinSpeed = 0,
        Totalmem = 0,
        OutVolsize = 0,
        Pause = 0;
@@ -431,6 +432,9 @@
                        } else if (strcasecmp(key,"maxreadspeed") == 0) {
                                MaxReadSpeed = value;
                                debugmsg("MaxReadSpeed = %lu\n",MaxReadSpeed);
+                       } else if (strcasecmp(key,"minspeed") == 0) {
+                               MinSpeed = value;
+                               debugmsg("MinSpeed = %lu\n",MinSpeed);
                        } else if (strcasecmp(key,"Totalmem") == 0) {
                                if (value >= 100) {
                                        Totalmem = value;
@@ -572,7 +576,7 @@
 {
        (void) fprintf(stderr,
                "mbuffer version " VERSION "\n"\
-               "Copyright 2001-2025 - T. Maier-Komor\n"\
+               "Copyright 2001-2026 - T. Maier-Komor\n"\
                "License: GPLv3 - see file LICENSE\n"\
                "This program comes with ABSOLUTELY NO WARRANTY!!!\n"
                "Donations via PayPal to [email protected] are welcome and 
support this work!\n"
@@ -622,6 +626,7 @@
                "-u <num>   : pause <num> microseconds after each write\n"
                "-r <rate>  : limit read rate to <rate> B/s, where <rate> can 
be given in b,k,M,G\n"
                "-R <rate>  : same as -r for writing; use either one, if your 
tape is too fast\n"
+               "-M <rate>  : set lowest data rate for automatic speed 
scaling\n"
                "-f         : overwrite existing files\n"
                "-a <time>  : device is autoloader which needs <time> seconds 
to reload\n"
                "-A <cmd>   : issue command <cmd> to request new volume from 
autoloader\n"
@@ -805,6 +810,9 @@
        } else if (!argcheck("-R",argv,&c,argc)) {
                MaxWriteSpeed = calcint(argv,c,0);
                debugmsg("MaxWriteSpeed = %lld\n",MaxWriteSpeed);
+       } else if (!argcheck("-M",argv,&c,argc)) {
+               MinSpeed = calcint(argv,c,0);
+               debugmsg("MinSpeed = %lld\n",MinSpeed);
        } else if (!argcheck("-n",argv,&c,argc)) {
                long nv = strtol(argv[c],0,0);
                if ((nv < 0) || ((nv == 0) && (errno == EINVAL)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mbuffer-20251025/settings.h 
new/mbuffer-20260301/settings.h
--- old/mbuffer-20251025/settings.h     2025-10-27 21:14:45.000000000 +0100
+++ new/mbuffer-20260301/settings.h     2026-03-01 16:47:32.000000000 +0100
@@ -62,6 +62,7 @@
        Blocksize,              /* fundamental I/O block size */
        MaxReadSpeed,
        MaxWriteSpeed,
+       MinSpeed,
        Totalmem,
        Pause,
        OutVolsize;

Reply via email to