Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package dd_rescue for openSUSE:Factory checked in at 2025-12-09 12:45:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dd_rescue (Old) and /work/SRC/openSUSE:Factory/.dd_rescue.new.1939 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "dd_rescue" Tue Dec 9 12:45:44 2025 rev:67 rq:1321544 version:1.99.22 Changes: -------- --- /work/SRC/openSUSE:Factory/dd_rescue/dd_rescue.changes 2025-03-15 16:15:22.190275928 +0100 +++ /work/SRC/openSUSE:Factory/.dd_rescue.new.1939/dd_rescue.changes 2025-12-09 12:46:35.054384185 +0100 @@ -1,0 +2,9 @@ +Sun Dec 7 15:04:37 CET 2025 - [email protected] + +- Update to dd_rescue-1.99.22: + * Improved calculation of average rate (harmonic mean). + * New option -@/--sparse_nonslow (to selectively overwrite with + zeros). + * Better PRNG initialization on arm-v8.5-a+rng supporting CPUs. + +------------------------------------------------------------------- Old: ---- dd_rescue-1.99.21.tar.bz2 dd_rescue-1.99.21.tar.bz2.asc New: ---- dd_rescue-1.99.22.tar.bz2 dd_rescue-1.99.22.tar.bz2.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ dd_rescue.spec ++++++ --- /var/tmp/diff_new_pack.edcHsT/_old 2025-12-09 12:46:44.858798556 +0100 +++ /var/tmp/diff_new_pack.edcHsT/_new 2025-12-09 12:46:44.862798725 +0100 @@ -21,7 +21,7 @@ %define _lto_cflags %{nil} %endif Name: dd_rescue -Version: 1.99.21 +Version: 1.99.22 Release: 0 Summary: Data copying in the presence of I/O Errors License: GPL-2.0-only OR GPL-3.0-only ++++++ dd_rescue-1.99.21.tar.bz2 -> dd_rescue-1.99.22.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/Makefile new/dd_rescue-1.99.22/Makefile --- old/dd_rescue-1.99.21/Makefile 2025-03-14 17:40:10.516737617 +0100 +++ new/dd_rescue-1.99.22/Makefile 2025-12-07 18:50:24.911983400 +0100 @@ -1,10 +1,11 @@ # (c) [email protected], 99/10/09, GNU GPL # (c) [email protected], 2010 -- 2021, GNU GPL v2 or v3 -VERSION = 1.99.21 +VERSION = 1.99.22 DESTDIR = -SRCDIR ?= . +THISMKFILE := $(lastword $(MAKEFILE_LIST)) +SRCDIR ?= $(dir $(THISMKFILE)) CC = gcc SHELL := bash @@ -192,7 +193,7 @@ else CFLAGS += -DNO_SHA endif -endif +endif # ISX86 MACH := $(shell uname -m |sed 's/armv\([0-9]*\)[a-z]*/armv\1/') ISARM := $(shell uname -m | grep '^arm') @@ -213,13 +214,20 @@ endif # ARMv7/8 endif # ARM ifeq ($(MACH),aarch64) +HAVE_RNG := $(shell echo "" | $(CC) -march=armv8.5-a+crypto+rng -xc - 2>&1 | grep unknown || echo 1) LIB = lib64 - OBJECTS2 = find_nonzero_arm64.o + OBJECTS2 = find_nonzero_arm64.o rdrand.o #POBJECTS2 = find_nonzero.po find_nonzero_arm64.po AES_ARM64_O = aes_arm64.o AES_ARM64_PO = aes_arm64.po CFLAGS += -DHAVE_AES_ARM64 +ifeq ($(HAVE_RNG),1) + #ARCHFLAGS += -march=armv8.5-a+crypto+rng + ARCHFLAGS += -march=armv8-a+crypto +else ARCHFLAGS += -march=armv8-a+crypto + CFLAGS += -DNO_RNDR +endif SHAFLAGS = -march=armv8-a+crypto endif @@ -243,6 +251,9 @@ $(SRCDIR)/configure && touch config.h test -e test_crypt.sh || ln -s $(SRCDIR)/test_crypt.sh . test -e test_lzo_fuzz.sh || ln -s $(SRCDIR)/test_lzo_fuzz.sh . + test -e test_lzo_dec.sh || ln -s $(SRCDIR)/test_lzo_dec.sh . + test -e test_sparse.sh || ln -s $(SRCDIR)/test_sparse.sh . + test -e test_sparse_compress_crypt.sh || ln -s $(SRCDIR)/test_sparse_compress_crypt.sh . test -e calchmac.py || ln -s $(SRCDIR)/calchmac.py . $(SRCDIR)/configure: $(SRCDIR)/configure.ac @@ -383,6 +394,9 @@ rdrand.o: $(SRCDIR)/rdrand.c $(CC) $(CFLAGS) $(PIE) -mrdrnd -maes -mavx2 -mvaes -c $< +rdrand_main.o: $(SRCDIR)/rdrand.c + $(CC) $(CFLAGS) $(PIE) -mrdrnd -maes -mavx2 -mvaes -o $@ -D RDRAND_MAIN -c $< + rdrand.po: $(SRCDIR)/rdrand.c $(CC) $(CFLAGS) $(PIC) -mrdrnd -maes -mavx2 -mvaes -o $@ -c $< else @@ -390,14 +404,31 @@ rdrand.o: $(SRCDIR)/rdrand.c $(CC) $(CFLAGS) $(PIE) -mrdrnd -maes -msse4.1 -c $< +rdrand_main.o: $(SRCDIR)/rdrand.c + $(CC) $(CFLAGS) $(PIE) -mrdrnd -maes -msse4.1 -o $@ -D RDRAND_MAIN -c $< + rdrand.po: $(SRCDIR)/rdrand.c $(CC) $(CFLAGS) $(PIC) -mrdrnd -maes -msse4.1 -o $@ -c $< else +ifeq ($(ISX86),1) rdrand.o: $(SRCDIR)/rdrand.c $(CC) $(CFLAGS) $(PIE) -maes -msse4.1 -c $< +rdrand_main.o: $(SRCDIR)/rdrand.c + $(CC) $(CFLAGS) $(PIE) -maes -msse4.1 -o $@ -D RDRAND_MAIN -c $< + rdrand.po: $(SRCDIR)/rdrand.c $(CC) $(CFLAGS) $(PIC) -maes -msse4.1 -o $@ -c $< +else +rdrand.o: $(SRCDIR)/rdrand.c + $(CC) $(CFLAGS) $(PIE) $(ARCHFLAGS) -c $< + +rdrand_main.o: $(SRCDIR)/rdrand.c + $(CC) $(CFLAGS) $(PIE) $(ARCHFLAGS) -o $@ -D RDRAND_MAIN -c $< + +rdrand.po: $(SRCDIR)/rdrand.c + $(CC) $(CFLAGS) $(PIC) $(ARCHFLAGS) -o $@ -c $< +endif endif endif @@ -438,6 +469,9 @@ fuzz_lzo: fuzz_lzo.o $(CC) -o $@ $(CFLAGS) $(LDPIE) $^ -llzo2 +rdrand: rdrand_main.o archdep.o + $(CC) -o $@ $^ + # More dd_rescue variants libfalloc-dl: dd_rescue @@ -536,7 +570,7 @@ mkdir -p $(INSTALLDIR) $(INSTALL) $(INSTALLFLAGS) $(INSTASROOT) -m 755 $(BINTARGETS) $(INSTALLDIR) #$(INSTALL) $(INSTASROOT) -m 755 -d $(DOCDIR)/dd_rescue - #$(INSTALL) $(INSTASROOT) -g root -m 644 README.dd_rescue $(DOCDIR)/dd_rescue/ + #$(INSTALL) $(INSTASROOT) -m 644 README.dd_rescue $(DOCDIR)/dd_rescue/ mkdir -p $(INSTALLLIBDIR) $(INSTALL) $(INSTALLFLAGS) $(INSTASROOT) -m 755 $(LIBTARGETS) $(INSTALLLIBDIR) ln -sf libddr_hash.so $(INSTALLLIBDIR)/libddr_MD5.so diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/README.dd_rescue new/dd_rescue-1.99.22/README.dd_rescue --- old/dd_rescue-1.99.21/README.dd_rescue 2025-03-14 17:40:10.520737718 +0100 +++ new/dd_rescue-1.99.22/README.dd_rescue 2025-12-07 14:13:21.363927040 +0100 @@ -236,8 +236,23 @@ exposing sensitive data). * 1.99.21 was made safe against interrupted and short read/write calls and the option -H allows to test for this. (This only worked partically before.) +* 1.99.22 brought better PRNG initialization on arm-v8.5a-rng. The reported + rate is calculated better. The -@/--sparse-nonslow option allows to write + 0s only when the reads take long (for refreshing SSDs). +Building +-------- +Just use `make` to compile dd_rescue and its plugins. +You can do so from another directory. E.g. + mkdir x86_64-linux-gcc15 + cd x86_64-linux-gcc15 + make -f ../Makefile CC=gcc15 LD=gcc15 -j8 all +The all target build a few additional binaries. +Some of them are also build by the check target which in addition +runs a number of tests. +The usual parameter CC= EXTRA_CFLAGS= ... are supported. + Copyright --------- This program is protected by the GNU General Public License (GPL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/REL-ID new/dd_rescue-1.99.22/REL-ID --- old/dd_rescue-1.99.21/REL-ID 2025-03-14 17:51:28.621171757 +0100 +++ new/dd_rescue-1.99.22/REL-ID 2025-12-07 19:13:38.988580600 +0100 @@ -1 +1 @@ -DD_RESCUE_1_99_21 +DD_RESCUE_1_99_22 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/archdep.c new/dd_rescue-1.99.22/archdep.c --- old/dd_rescue-1.99.21/archdep.c 2024-10-01 09:23:11.341019113 +0200 +++ new/dd_rescue-1.99.22/archdep.c 2025-12-07 18:04:51.771044214 +0100 @@ -243,5 +243,26 @@ : : "v0", "v1", "v12"); } + +#ifndef NO_RNDR +//#define SYS_RNDR_EL0 0x001b2400 +//#define SYS_RNDRRS_EL0 0x001b2420 + +void probe_arm8rndr() +{ + unsigned char ok; + unsigned long rnd; + asm volatile( + " .arch armv8.5-a+rng+crypto \n" + " mrs %0, rndr \n" + " cset %w1, ne \n" + " .arch armv8-a+crypto \n" + : "=r"(rnd), "=r"(ok) + : + : "cc"); + if (!ok) + raise(SIGILL); // have_arm8rndr = 0; +} +#endif /* NO_RNDR */ #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/archdep.h new/dd_rescue-1.99.22/archdep.h --- old/dd_rescue-1.99.21/archdep.h 2024-09-29 22:04:28.872492236 +0200 +++ new/dd_rescue-1.99.22/archdep.h 2025-12-07 14:54:16.558986657 +0100 @@ -19,6 +19,7 @@ #define HAVE_OPT #define have_arm8sha 0 #define have_arm8crypto 0 +#define have_arm8rndr 0 #ifdef __i386__ extern char have_sse2; @@ -133,6 +134,8 @@ void probe_arm8sha_32(); extern char have_arm8crypto; void probe_arm8crypto_32(); +#define have_arm8rndr 0 +//void probe_arm8rndr_32(); #define ARCH_DECLS char have_arm8crypto, have_arm8sha; #define ARCH_DETECT have_arm8crypto = detect2("aes", probe_arm8crypto_32); have_arm8sha = detect2("sha", probe_arm8sha_32) #define FIND_NONZERO_OPT(x,y) find_nonzero_arm6(x,y) @@ -153,8 +156,16 @@ void probe_arm8sha(); extern char have_arm8crypto; void probe_arm8crypto(); +#ifndef NO_RNDR +extern char have_arm8rndr; +void probe_arm8rndr(); +#define ARCH_DECLS char have_arm8crypto, have_arm8sha, have_arm8rndr; +#define ARCH_DETECT have_arm8crypto = detect2("aes", probe_arm8crypto); have_arm8sha = detect2("sha", probe_arm8sha); have_arm8rndr = detect2("rng", probe_arm8rndr); +#else +#define have_arm8rndr 0 #define ARCH_DECLS char have_arm8crypto, have_arm8sha; -#define ARCH_DETECT have_arm8crypto = detect2("aes", probe_arm8crypto); have_arm8sha = detect2("sha", probe_arm8sha) +#define ARCH_DETECT have_arm8crypto = detect2("aes", probe_arm8crypto); have_arm8sha = detect2("sha", probe_arm8sha); +#endif #define FIND_NONZERO_OPT(x,y) find_nonzero_arm8(x,y) #define OPT_STR "arm8" #define OPT_STR2 "arm8" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/dd_rescue.1 new/dd_rescue-1.99.22/dd_rescue.1 --- old/dd_rescue-1.99.21/dd_rescue.1 2025-03-14 17:40:10.520737718 +0100 +++ new/dd_rescue-1.99.22/dd_rescue.1 2025-12-07 14:18:25.503462182 +0100 @@ -1,4 +1,4 @@ -.TH dd_rescue 1 "2017-06-23" "Kurt Garloff" "Data recovery and protection tool" +.TH dd_rescue 1 "2025-06-24" "Kurt Garloff" "Data recovery and protection tool" . .SH NAME dd_rescue \- Data recovery and protection tool @@ -291,6 +291,19 @@ This option may be useful for devices, where e.g. writes should be avoided (e.g. because they may impact the remaining lifetime or because they are very slow compared to reads). +.TP 8 +.BI \-@\ readtime \fR,\ \fB\-\-sparse_nonslow=readtime +is an optimization for sparse copies. When +.BB dd_rescue +is used to scrub a device (or partition) by overwriting itself, option -a +(--sparse) may well be used to avoid writing zeros over unallocated space +(on e.g. SSDs). If blocks however have been allocated before and are +all-zeros, and they are very slow to read, we might want to make an exception +and overwrite these with zeros again. +.BB dd_rescue +can detect this by reads being slow. So using this option, a limit (in seconds) +can be set for the time reads may take before zero writes are performed in +sparse mode. You may want to set this to 3 or so when reviving SSDs. . .SS Other optimization .TP 8 @@ -511,8 +524,9 @@ number will be used to seed the C library's PRNG. For the RC4 method, the C library's PRNG then generates the 256 bytes to seed it. This creates repeatable PRNG data. The RANDSEED value of 0 is special; it will create -a seedval that's based on the current time and the process' PID and should -be different for multiple runs of +a seedval that's based on the current time and the process' PID with CPU +randomness mixed in (if available) and should be different for multiple +runs of .B dd_rescue . .br If @@ -893,11 +907,11 @@ on the command line will cause read and write havoc by returning short reads and writes and by returning an indication that a read or write has to be redone as the system call was interrupted or would block. -The percentage given will be evenly split between interrupted calls -and short reads/writes. According to the GNU libc documentation, such -things can happen; the fact they only do happen seldomly and only under -certain circumstances makes it hard to test, thus this option to force -it to randomly happen. (This has led to bug fixes in 1.99.21.) +The percentage given will applied to both interrupted calls and short +reads/writes. According to the GNU libc documentation, such things can +happen; the fact they only do happen seldomly and only under certain +circumstances makes it hard to test, thus this option to force it to +randomly happen. (This has led to bug fixes in 1.99.21.) .br .SH BUGS/LIMITATIONS The source code does use the 64bit functions provided by glibc for file @@ -1033,6 +1047,13 @@ 1.99 support for ARMv8 crypto acceleration. 1.99.5 brought ratecontrol. 1.99.6 brought S3 style multipart checksums. +1.99.7-12 brought more crypto performance tuning and +compatibility with openSSL-1.1 and -3.0. +1.99.13-16 brought further optimizations, incl. sha256 acceleration. +1.99.17 introduced support for liblzma (xz). +1.99.18-19 further improved it, with support for holes. +1.99.20-21 hardened complex plugin chains and systematically handled +issues when retries are necessary also in the write path. .PP Some additional information can be found on .br diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/dd_rescue.c new/dd_rescue-1.99.22/dd_rescue.c --- old/dd_rescue-1.99.21/dd_rescue.c 2025-03-14 17:40:10.524737818 +0100 +++ new/dd_rescue-1.99.22/dd_rescue.c 2025-12-07 13:29:02.893188128 +0100 @@ -222,6 +222,12 @@ # define cpu_relax() while (0) {} #endif +#ifdef HAVE_SCHED_YIELD +# define SCHED_YIELD() sched_yield() +#else +# define SCHED_YIELD() cpu_relax() +#endif + /* fwd decls */ int cleanup(char); @@ -252,7 +258,7 @@ static unsigned int pagesize; /* Rate limit for status updates */ -float printint = 0.1; +const float printint = 0.1; char in_report; FILE *logfd; @@ -360,7 +366,7 @@ const struct timeval* const t1) { return (float) (t2->tv_sec - t1->tv_sec ) + - (float) (t2->tv_usec - t1->tv_usec) * 5e-7; + (float) (t2->tv_usec - t1->tv_usec) * 1e-6 + 1e-7; } @@ -1114,17 +1120,30 @@ float maxrate = 0.0; void doprint(FILE* const file, const unsigned int bs, const clock_t cl, const float t1, const float t2, const int sync, - opt_t *op, fstate_t *fst, progress_t *prg, dpopt_t *dop) + opt_t *op, fstate_t *fst, progress_t *prg, dpopt_t *dop, + unsigned int incctr) { - float avgrate = (float)prg->xfer/t1; - float currate = (float)(prg->xfer-prg->lxfer)/t2; + static unsigned int ctr = 0; + /* 1+ is there to avoid div by zero, difftimevtv also never returns zero */ + float avgrate = (float)(1+prg->xfer)/t1; + float currate = (float)(1+prg->xfer-prg->lxfer)/t2; const char *bold = BOLD, *norm = NORM; - if (!floatrate4) { - floatrate4 = currate; - floatrate32 = currate; + /* We have two different moving averages + * floatrate4 does have the last 9 rates constitute over 90% of the result + * floatrate32 takes the last 73 values to get over 90%. + * On startup, we blend in the unweidghed total average. + */ + if (ctr < 4) { + floatrate4 = 4./(3./avgrate + 1./currate); + floatrate32 = 32./(31./avgrate + 1./currate); + ctr += incctr; + } else if (ctr < 32) { + floatrate4 = 4./(3./floatrate4 + 1./currate); + floatrate32 = 32./(31./avgrate + 1./currate); + ctr += incctr; } else { - floatrate4 = (floatrate4 * 3 + currate)/ 4; - floatrate32 = (floatrate32*31 + currate)/32; + floatrate4 = 4./(3./floatrate4 + 1./currate); + floatrate32 = 32./(31./floatrate32 + 1./currate); } if (floatrate4 > maxrate) maxrate = floatrate4; @@ -1232,7 +1251,7 @@ t1w += difftimetv(¤ttime, &wtime); } else { ++w2; - sched_yield(); + SCHED_YIELD(); gettimeofday(¤ttime, NULL); t2w += difftimetv(¤ttime, &wtime); } @@ -1246,7 +1265,7 @@ w2, w2? t2w/w2: 0.0, w3); } /* Idea: Could save last not printed status and print on err */ - if (t2 < printint && !sync && !in_report) { + if (((t2 < printint/4) || (t2 < printint && floatrate4 > 10000)) && !sync && !in_report) { /* We need to update more than 10x per second if copy time * is less than 8s resulting in a file size of 8*maxrate */ if (fst->estxfer && (!maxrate || fst->estxfer < maxrate*8)) @@ -1262,9 +1281,9 @@ } if (file1) - doprint(file1, bs, cl, t1, t2, sync, op, fst, prg, dop); + doprint(file1, bs, cl, t1, t2, sync, op, fst, prg, dop, 1); if (file2) - doprint(file2, bs, cl, t1, t2, sync, op, fst, prg, dop); + doprint(file2, bs, cl, t1, t2, sync, op, fst, prg, dop, file1? 0: 1); if (1 || sync) { memcpy(&lasttime, ¤ttime, sizeof(lasttime)); prg->lxfer = prg->xfer; @@ -1511,6 +1530,7 @@ fplog(stderr, WARN, "extend/truncate %s (%skiB): %s!\n", nm, fmt_kiB(fst->opos, !nocol), strerror(errno)); } + SCHED_YIELD(); return err; } @@ -1646,10 +1666,16 @@ return ln; } -/** is the block zero ? */ +/** is the block zero ? + * returns the amount of bytes at the beginning of blk that are zero + */ +static int slowread = 0; + static ssize_t blockiszero(const unsigned char* blk, const size_t ln, opt_t *op, repeat_t *rep) { + if (op->sparse_nonslow && slowread) + return 0; if (op->i_repeat && rep->i_rep_zero) return rep->i_rep_zero; if (!ln || *blk) @@ -1858,7 +1884,7 @@ if (err == -1) wr++; if (!err) - sched_yield(); + SCHED_YIELD(); } while ((err == -1 && (errno == EINTR || errno == EAGAIN)) || (err >= 0 && (errno == 0 || errno == EINTR || errno == EAGAIN) && wr < towrite &&!*retry)); if (errno == EINTR || errno == EAGAIN) @@ -1882,9 +1908,7 @@ if (rc && errno != EINVAL && !fst->o_chr) fplog(stderr, WARN, "sync %s (%sskiB): %s! \n", op->oname, fmt_kiB(fst->ipos, !nocol), strerror(errno)); -#ifdef HAVE_SCHED_YIELD - sched_yield(); -#endif + SCHED_YIELD(); wr = 0; int off; if (op->reverse) { @@ -2308,9 +2332,24 @@ down, down, down, down); #endif while ((toread = blockxfer(max, op->hardbs, op, fst, prg)) > 0 && !interrupted) { + struct timeval before, after; + ssize_t rd; int eno; - ssize_t rd = readblock(toread, op, fst, rep, dop, dst); + if (op->verbose || op->sparse_nonslow) + gettimeofday(&before, NULL); + rd = readblock(toread, op, fst, rep, dop, dst); eno = errno; + if (op->verbose || op->sparse_nonslow) { + gettimeofday(&after, NULL); + const float rdtm = difftimetv(&after, &before); + if (rdtm*1024 > op->maxreadtm) { + if (op->verbose) + fplog(stderr, INFO, "read (%s kiB) took %.3fs\n", + fmt_int(10, 1, 1024, rd, BOLD, NORM, 1), rdtm); + slowread = 1; + } else + slowread = 0; + } /* EOF */ if (rd == 0 && !eno) { @@ -2413,10 +2452,10 @@ if (op->syncfreq && !(fst->ipos % (op->syncfreq*op->softbs/2))) printstatus((op->quiet? 0: stderr), 0, op->hardbs, 1, op, fst, prg, dop); /* else print regularly acc. to updstat if not quiet */ - else if (!op->quiet && !(fst->ipos % (updstat*op->softbs/2))) + else if (!op->quiet && !(prg->xfer % (updstat*op->softbs/2))) printstatus(stderr, 0, op->hardbs, 0, op, fst, prg, dop); /* even if quiet, we need to call the printstatus if we do rate limiting */ - else if (op->quiet && op->maxkbs && !(fst->ipos % (updstat*op->softbs/2))) + else if (op->quiet && op->maxkbs && !(prg->xfer % (updstat*op->softbs/2))) printstatus(0, 0, op->hardbs, 0, op, fst, prg, dop); } /* remain */ return errs; @@ -2444,9 +2483,24 @@ } errno = 0; while ((toread = blockxfer(max, op->softbs, op, fst, prg)) > 0 && !interrupted) { + struct timeval before, after; + ssize_t rd; int err; - ssize_t rd = readblock(toread, op, fst, rep, dop, dst); + if (op->verbose || op->sparse_nonslow) + gettimeofday(&before, NULL); + rd = readblock(toread, op, fst, rep, dop, dst); eno = errno; + if (op->verbose || op->sparse_nonslow) { + gettimeofday(&after, NULL); + const float rdtm = difftimetv(&after, &before); + if (rdtm*1024 > op->maxreadtm) { + if (op->verbose) + fplog(stderr, INFO, "read (%s kiB) took %.3fs\n", + fmt_int(10, 1, 1024, rd, BOLD, NORM, 1), rdtm); + slowread = 1; + } else + slowread = 0; + } /* EOF */ if (rd == 0 && !eno) { @@ -2542,10 +2596,10 @@ if (op->syncfreq && !(fst->ipos % (op->syncfreq*op->softbs))) printstatus((op->quiet? 0: stderr), 0, op->softbs, 1, op, fst, prg, dop); /* else print regularly acc. to updstat if not quiet */ - else if (!op->quiet && !(fst->ipos % (2*updstat*op->softbs))) + else if (!op->quiet && !(prg->xfer % (updstat*op->softbs))) printstatus(stderr, 0, op->softbs, 0, op, fst, prg, dop); /* even if quiet, we need to call the printstatus if we do rate limiting */ - else if (op->quiet && op->maxkbs && !(fst->ipos % (2*updstat*op->softbs))) + else if (op->quiet && op->maxkbs && !(prg->xfer % (updstat*op->softbs))) printstatus(0, 0, op->softbs, 0, op, fst, prg, dop); } /* remain */ return errs; @@ -2623,9 +2677,9 @@ advancepos(0, 0, 0, op, fst, prg); if (op->syncfreq && !(prg->xfer % (op->syncfreq*op->softbs))) printstatus((op->quiet? 0: stderr), 0, op->softbs, 1, op, fst, prg, dop); - else if (!op->quiet && !(prg->xfer % (2*updstat*op->softbs))) + else if (!op->quiet && !(prg->xfer % (updstat*op->softbs))) printstatus(stderr, 0, op->softbs, 0, op, fst, prg, dop); - else if (op->quiet && op->maxkbs && !(prg->xfer % (2*updstat*op->softbs))) + else if (op->quiet && op->maxkbs && !(prg->xfer % (updstat*op->softbs))) printstatus(0, 0, op->softbs, 0, op, fst, prg, dop); } close(fd_pipe[0]); close(fd_pipe[1]); @@ -2817,6 +2871,8 @@ fprintf(stderr, "sha "); if (have_arm8crypto) fprintf(stderr, "aes "); + if (have_arm8rndr) + fprintf(stderr, "rndr "); #endif fprintf(stderr, "%s", OPT_STR); fprintf(stderr, ")\n"); @@ -2843,6 +2899,7 @@ {"splice", 0, NULL, 'k'}, {"fallocate", 0, NULL, 'P'}, {"abort_we", 0, NULL, 'w'}, {"avoidwrite", 0, NULL, 'W'}, {"sparse", 0, NULL, 'a'}, {"alwayswrite", 0, NULL, 'A'}, + {"sparse_nonslow", 1, NULL, '@'}, {"interactive", 0, NULL, 'i'}, {"force", 0, NULL, 'f'}, {"preserve", 0, NULL, 'p'}, {"outfile", 1, NULL, 'Y'}, {"random", 1, NULL, 'z'}, {"frandom", 1, NULL, 'Z'}, @@ -3169,9 +3226,9 @@ IOHAVOC_INIT(0, 0, 0); #ifdef LACK_GETOPT_LONG - while ((c = getopt(argc, argv, ":rtTfihqvVwWaAdDkMRpPuc:b:B:m:e:s:S:l:L:o:y:z:Z:2:3:4:xY:F:C:E:H:")) != -1) + while ((c = getopt(argc, argv, ":rtTfihqvVwWaAdDkMRpPuc:b:B:m:e:s:S:l:L:o:y:z:Z:2:3:4:xY:F:C:E:H:@:")) != -1) #else - while ((c = getopt_long(argc, argv, ":rtTfihqvVwWaAdDkMRpPuc:b:B:m:e:s:S:l:L:o:y:z:Z:2:3:4:xY:F:C:E:H:", longopts, NULL)) != -1) + while ((c = getopt_long(argc, argv, ":rtTfihqvVwWaAdDkMRpPuc:b:B:m:e:s:S:l:L:o:y:z:Z:2:3:4:xY:F:C:E:H:@:", longopts, NULL)) != -1) #endif { switch (c) { @@ -3197,6 +3254,7 @@ case 'A': op->nosparse = 1; op->sparse = 0; break; case 'w': op->abwrerr = 1; break; case 'W': op->avoidwrite = 1; break; + case '@': op->sparse_nonslow = 1; op->maxreadtm = 1024*atof(optarg); break; case 'h': printlonghelp(); cleanup(1); exit(0); break; case 'V': printversion(); cleanup(1); exit(0); break; case 'v': op->quiet = 0; op->verbose = 1; ddr_loglevel = 0; break; @@ -3577,7 +3635,11 @@ updstat = upd; } } - +#if 0 + if (op->verbose) + fplog(stderr, DEBUG, "Update progress every %i kiB\n", + updstat*op->softbs/1024); +#endif } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/ddr_ctrl.h new/dd_rescue-1.99.22/ddr_ctrl.h --- old/dd_rescue-1.99.21/ddr_ctrl.h 2025-01-19 20:09:25.013401412 +0100 +++ new/dd_rescue-1.99.22/ddr_ctrl.h 2025-06-23 14:36:59.124684157 +0200 @@ -28,6 +28,8 @@ char extend, rmvtrim, i_repeat; char preserve_force; unsigned int maxkbs; /* from 1kB/s to 4TB/s */ + int maxreadtm; /* in 1024th of secs */ + char sparse_nonslow; } opt_t; extern char nocol; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/iohavoc.h new/dd_rescue-1.99.22/iohavoc.h --- old/dd_rescue-1.99.21/iohavoc.h 2025-03-14 17:42:43.024528387 +0100 +++ new/dd_rescue-1.99.22/iohavoc.h 2025-11-23 18:51:47.141275339 +0100 @@ -21,7 +21,7 @@ #define _IOHAVOC_H //#define _FILE_OFFSET_BITS 64 -#include <random.h> +#include "random.h" #include <unistd.h> #include <errno.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/random.c new/dd_rescue-1.99.22/random.c --- old/dd_rescue-1.99.21/random.c 2022-07-25 17:45:07.563736254 +0200 +++ new/dd_rescue-1.99.22/random.c 2025-12-07 13:58:34.387469622 +0100 @@ -38,7 +38,9 @@ } -#if (defined(__x86_64__) || defined(__i386__)) && !defined(NO_RDRND) +#if (defined(__x86_64__) || defined(__aarch64__)) && !defined(NO_RDRAND) +unsigned long rdrand64(); +#elif defined(__i386__) && !defined(NO_RDRND) unsigned int rdrand32(); #else #define BSWAP32(x) ((x<<24) | ((x<<8)&0x00ff0000) | ((x>>8)&0x0000ff00) | (x>>24)) @@ -48,7 +50,9 @@ { struct timeval tv; gettimeofday(&tv, NULL); -#if (defined(__x86_64__) || defined(__i386__)) && !defined(NO_RDRND) +#if (defined(__x86_64__) || defined(__aarch64__)) && !defined(NO_RDRAND) + unsigned long hwrnd = rdrand64(); +#elif defined(__i386__) && !defined(NO_RDRAND) unsigned int hwrnd = rdrand32(); #else /* Some randomness due to ASLR ... */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/rdrand.c new/dd_rescue-1.99.22/rdrand.c --- old/dd_rescue-1.99.21/rdrand.c 2024-09-28 23:45:36.182707983 +0200 +++ new/dd_rescue-1.99.22/rdrand.c 2025-12-07 18:06:28.636460354 +0100 @@ -53,18 +53,40 @@ #endif #endif /* __x86_64__ */ +#elif defined(__aarch64__) +#define BSWAP32(x) ((x<<24) | ((x<<8)&0x00ff0000) | ((x>>8)&0x0000ff00) | (x>>24)) +unsigned long rdrand64() +{ + unsigned long val = (unsigned long)&rdrand64; + //val = (unsigned long)BSWAP32((unsigned int)val&0xffffffff)<<32 | BSWAP32((unsigned int)(val>>32)); +#ifndef NO_RNDR + if (have_arm8rndr) { + unsigned long rnd; + asm volatile ( + " .arch armv8.5-a+rng+crypto \n" + " mrs %0, rndr \n" + " .arch armv8-a+crypto \n" + : "=r"(rnd) + : + : "cc"); + val ^= rnd; + } +#endif + return val; +} #endif /* x86 */ #ifdef RDRAND_MAIN #include <stdio.h> int main(int argc, char* argv[]) { -#ifdef __x86_64__ + detect_cpu_cap(); +#if __WORDSIZE == 64 unsigned long rnd = rdrand64(); - printf("%lu\n", rnd); + printf("0x%016lx\n", rnd); #else unsigned int rnd = rdrand32(); - printf("%u\n", rnd); + printf("0x%08x\n", rnd); #endif return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue-1.99.21/test_aes.c new/dd_rescue-1.99.22/test_aes.c --- old/dd_rescue-1.99.21/test_aes.c 2025-03-14 17:40:10.528737918 +0100 +++ new/dd_rescue-1.99.22/test_aes.c 2025-12-07 10:22:40.127286558 +0100 @@ -351,8 +351,8 @@ have_sse2, have_sse42, have_aesni, have_rdrand, have_sha256, have_avx2, have_vaes); #elif defined(__arm__) || defined(__aarch64__) //have_arm8crypto = 1; - printf("CPU Features: AES Arm8 %i SHA Arm8 %i\n", - have_arm8crypto, have_arm8sha); + printf("CPU Features: AES Arm8 %i SHA Arm8 %i RNDR Arm8 %i\n", + have_arm8crypto, have_arm8sha, have_arm8rndr); #endif crypto = secmem_init(); /*
