# include <readline/readline.h>
#endif
#include <libgen.h>
+#include <sys/time.h>
#include "c.h"
#include "xalloc.h"
#include "all-io.h"
#include "rpmatch.h"
#include "optutils.h"
+#include "ttyutils.h"
#include "libfdisk.h"
#include "fdisk-list.h"
append : 1, /* don't create new PT, append partitions only */
json : 1, /* JSON dump */
movedata: 1, /* move data after resize */
+ movefsync: 1, /* use fsync() afetr each write() */
notell : 1, /* don't tell kernel aout new PT */
noact : 1; /* do not write to device */
};
char *devname = NULL, *typescript = NULL, *buf = NULL;
FILE *f = NULL;
int ok = 0, fd, backward = 0;
- fdisk_sector_t nsectors, from, to, step, i;
+ fdisk_sector_t nsectors, from, to, step, i, prev;
size_t io, ss, step_bytes, cc;
uintmax_t src, dst;
- int errsv;
+ int errsv, progress = 0;
+ struct timeval prev_time;
+ uint64_t bytes_per_sec = 0;
assert(sf->movedata);
printf(_(" step size: %zu bytes\n"), step_bytes);
putchar('\n');
fflush(stdout);
+
+ if (isatty(fileno(stdout)))
+ progress = 1;
}
if (sf->interactive) {
DBG(MISC, ul_debug(" initial: src=%ju dst=%ju", src, dst));
+ gettimeofday(&prev_time, NULL);
+ prev = 0;
+
for (cc = 1, i = 0; i < nsectors; i += step, cc++) {
ssize_t rc;
rc = write(fd, buf, step_bytes);
if (rc < 0 || rc != (ssize_t) step_bytes)
goto fail;
- fsync(fd);
+ if (sf->movefsync)
+ fsync(fd);
}
/* write log */
if (f)
fprintf(f, "%05zu: %12ju %12ju\n", cc, src, dst);
-#if defined(POSIX_FADV_DONTNEED) && defined(HAVE_POSIX_FADVISE)
- if (!sf->noact)
- posix_fadvise(fd, src, step_bytes, POSIX_FADV_DONTNEED);
-#endif
+ if (progress && i % 10 == 0) {
+ unsigned int elapsed = 0; /* usec */
+ struct timeval cur_time;
+
+ gettimeofday(&cur_time, NULL);
+ if (cur_time.tv_sec - prev_time.tv_sec > 1) {
+ elapsed = ((cur_time.tv_sec - prev_time.tv_sec) * 1000000) +
+ (cur_time.tv_usec - prev_time.tv_usec);
+
+ bytes_per_sec = ((i - prev) * ss) / elapsed; /* per usec */
+ bytes_per_sec *= 1000000; /* per sec */
+
+ prev_time = cur_time;
+ prev = i;
+ }
+
+ if (bytes_per_sec)
+ fprintf(stdout, _("Moved %ju from %ju sectors (%.3f%%, %.1f MiB/s)."),
+ i + 1, nsectors,
+ 100.0 / ((double) nsectors/(i+1)),
+ (double) (bytes_per_sec / (1024 * 1024)));
+ else
+ fprintf(stdout, _("Moved %ju from %ju sectors (%.3f%%)."),
+ i + 1, nsectors,
+ 100.0 / ((double) nsectors/(i+1)));
+ fflush(stdout);
+ fputc('\r', stdout);
+
+ }
+
if (!backward)
src += step_bytes, dst += step_bytes;
}
+ if (progress) {
+ int x = get_terminal_width(80);
+ for (; x > 0; x--)
+ fputc(' ', stdout);
+ fflush(stdout);
+ fputc('\r', stdout);
+ fprintf(stdout, _("Moved %ju from %ju sectors (%.3f%%)."),
+ i, nsectors,
+ 100.0 / ((double) nsectors/(i+1)));
+ fputc('\n', stdout);
+ }
if (f)
fclose(f);
free(buf);
fputs(_(" -b, --backup backup partition table sectors (see -O)\n"), out);
fputs(_(" --bytes print SIZE in bytes rather than in human readable format\n"), out);
fputs(_(" --move-data[=<typescript>] move partition data after relocation (requires -N)\n"), out);
+ fputs(_(" --move-use-fsync use fsync after each write when move data\n"), out);
fputs(_(" -f, --force disable all consistency checking\n"), out);
fprintf(out,
_(" --color[=<when>] colorize output (%s, %s or %s)\n"), "auto", "always", "never");
OPT_BYTES,
OPT_COLOR,
OPT_MOVEDATA,
+ OPT_MOVEFSYNC,
OPT_DELETE,
OPT_NOTELL
};
{ "no-reread", no_argument, NULL, OPT_NOREREAD },
{ "no-tell-kernel", no_argument, NULL, OPT_NOTELL },
{ "move-data", optional_argument, NULL, OPT_MOVEDATA },
+ { "move-use-fsync", no_argument, NULL, OPT_MOVEFSYNC },
{ "output", required_argument, NULL, 'o' },
{ "partno", required_argument, NULL, 'N' },
{ "reorder", no_argument, NULL, 'r' },
sf->movedata = 1;
sf->move_typescript = optarg;
break;
+ case OPT_MOVEFSYNC:
+ sf->movefsync = 1;
+ break;
case OPT_DELETE:
sf->act = ACT_DELETE;
break;