Commit 6622add3 authored by Mark Fasheh's avatar Mark Fasheh

- add -h option to pretty-print numbers

parent 73cad0a0
......@@ -4,7 +4,7 @@ CFLAGS=-Wall -ggdb -D_FILE_OFFSET_BITS=64 -DVERSTRING=\"$(RELEASE)\"
MANPAGES=duperemove.8 btrfs-extent-same.8
DIST_SOURCES=csum-gcrypt.c csum-mhash.c csum.h duperemove.c hash-tree.c hash-tree.h results-tree.c results-tree.h kernel.h LICENSE list.h Makefile rbtree.c rbtree.h rbtree.txt README TODO dedupe.c dedupe.h btrfs-ioctl.h filerec.c filerec.h $(MANPAGES) btrfs-extent-same.c debug.h
DIST_SOURCES=csum-gcrypt.c csum-mhash.c csum.h duperemove.c hash-tree.c hash-tree.h results-tree.c results-tree.h kernel.h LICENSE list.h Makefile rbtree.c rbtree.h rbtree.txt README TODO dedupe.c dedupe.h btrfs-ioctl.h filerec.c filerec.h $(MANPAGES) btrfs-extent-same.c debug.h util.c util.h
DIST=duperemove-$(RELEASE)
DIST_TARBALL=$(DIST).tar.gz
TEMP_INSTALL_DIR:=$(shell mktemp -du -p .)
......@@ -21,7 +21,7 @@ endif
CFLAGS += $(crypt_CFLAGS)
LIBRARY_FLAGS += $(crypt_LIBS)
objects = duperemove.o rbtree.o hash-tree.o results-tree.o dedupe.o filerec.o $(hash_obj)
objects = duperemove.o rbtree.o hash-tree.o results-tree.o dedupe.o filerec.o util.o $(hash_obj)
progs = duperemove
all: $(progs) kernel.h list.h btrfs-ioctl.h debug.h
......
......@@ -21,7 +21,4 @@
could run in readonly mode, record dupes and then pass them later to
duperemove for potential deduplication.
- initialization cleanups/fixes
- add an option to pretty-print bytes as blocks, K, M, G, etc.
- Allow for flexible selection of dedupe target
......@@ -66,12 +66,16 @@ users on readonly snapshots.
\fB\-b size\fR
Use the specified block size. The default is \fB128K\fR.
.TP
\fB\-h\fR
Print numbers in human-readable format.
.TP
\fB\-v\fR
Be verbose.
.TP
\fB\-h\fR
\fB\-?, --help\fR
Prints help text.
.SH "FAQ"
......
......@@ -41,6 +41,7 @@
#include "hash-tree.h"
#include "results-tree.h"
#include "dedupe.h"
#include "util.h"
#include "debug.h"
/* exported via debug.h */
......@@ -143,9 +144,9 @@ static void print_dupes_table(struct results_tree *res)
printf("Start\t\tLength\t\tFilename\n");
list_for_each_entry(extent, &dext->de_extents, e_list) {
printf("%llu\t%llu\t\"%s\"\n",
(unsigned long long)extent->e_loff,
(unsigned long long)len,
printf("%s\t%s\t\"%s\"\n",
pretty_size(extent->e_loff),
pretty_size(len),
extent->e_file->filename);
}
......@@ -270,10 +271,10 @@ static int dedupe_extent_list(struct dupe_extents *dext, uint64_t *fiemap_bytes,
}
run_dedupe:
printf("Dedupe %d extents with target: (%"PRIu64", %"PRIu64"), "
"\"%s\"\n",
ctxt->num_queued, ctxt->orig_file_off, ctxt->orig_len,
ctxt->ioctl_file->filename);
printf("Dedupe %d extents with target: (%s, %s), \"%s\"\n",
ctxt->num_queued, pretty_size(ctxt->orig_file_off),
pretty_size(ctxt->orig_len), ctxt->ioctl_file->filename);
ret = dedupe_extents(ctxt);
if (ret) {
......@@ -343,9 +344,9 @@ static void dedupe_results(struct results_tree *res)
node = rb_next(node);
}
printf("Kernel processed %"PRIu64" bytes.\n"
"Comparison of extent info shows a net change of %"PRIu64
" shared bytes.\n", kern_bytes, fiemap_bytes);
printf("Kernel processed data: %s\nComparison of extent info "
"shows a net change in shared data of: %s\n",
pretty_size(kern_bytes), pretty_size(fiemap_bytes));
}
static int csum_whole_file(struct hash_tree *tree, struct filerec *file)
......@@ -436,9 +437,10 @@ static void usage(const char *prog)
printf("\t-A\t\tOpens files readonly when deduping. Primarily for use by privileged users on readonly snapshots\n");
printf("\t-b bsize\tUse bsize blocks. Default is %dk.\n",
DEFAULT_BLOCKSIZE / 1024);
printf("\t-h\t\tPrint numbers in human-readble format.\n");
printf("\t-v\t\tBe verbose.\n");
printf("\t--debug\t\tPrint debug messages, forces -v if selected.\n");
printf("\t-h\t\tPrints this help text.\n");
printf("\t--help\t\tPrints this help text.\n");
}
static int add_file(const char *name, int dirfd);
......@@ -585,61 +587,9 @@ out:
return 0;
}
/*
* parse_size() taken from btrfs-progs/util.c
*/
uint64_t parse_size(char *s)
{
int i;
char c;
uint64_t mult = 1;
for (i = 0; s && s[i] && isdigit(s[i]); i++) ;
if (!i) {
fprintf(stderr, "ERROR: size value is empty\n");
exit(50);
}
if (s[i]) {
c = tolower(s[i]);
switch (c) {
case 'e':
mult *= 1024;
/* fallthrough */
case 'p':
mult *= 1024;
/* fallthrough */
case 't':
mult *= 1024;
/* fallthrough */
case 'g':
mult *= 1024;
/* fallthrough */
case 'm':
mult *= 1024;
/* fallthrough */
case 'k':
mult *= 1024;
/* fallthrough */
case 'b':
break;
default:
fprintf(stderr, "ERROR: Unknown size descriptor "
"'%c'\n", c);
exit(1);
}
}
if (s[i] && s[i+1]) {
fprintf(stderr, "ERROR: Illegal suffix contains "
"character '%c' in wrong position\n",
s[i+1]);
exit(51);
}
return strtoull(s, NULL, 10) * mult;
}
enum {
DEBUG_OPTION = CHAR_MAX + 1,
HELP_OPTION,
};
/*
......@@ -650,6 +600,7 @@ static int parse_options(int argc, char **argv)
int i, c, numfiles;
static struct option long_ops[] = {
{ "debug", 0, 0, DEBUG_OPTION },
{ "help", 0, 0, HELP_OPTION },
{ 0, 0, 0, 0}
};
......@@ -682,6 +633,9 @@ static int parse_options(int argc, char **argv)
verbose = 1;
break;
case 'h':
human_readable = 1;
break;
case HELP_OPTION:
case '?':
default:
return 1;
......
/*
* util.c
*
* Copyright (C) 2014 SUSE except where noted. All rights reserved.
*
* Code taken from btrfs-progs/util.c is:
* Copyright (C) 2007 Oracle. All rights reserved.
* Copyright (C) 2008 Morey Roof. All rights reserved.
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* Authors: Mark Fasheh <mfasheh@suse.de>
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <inttypes.h>
#include "util.h"
int human_readable = 0;
uint64_t parse_size(char *s)
{
int i;
char c;
uint64_t mult = 1;
for (i = 0; s && s[i] && isdigit(s[i]); i++) ;
if (!i) {
fprintf(stderr, "ERROR: size value is empty\n");
exit(50);
}
if (s[i]) {
c = tolower(s[i]);
switch (c) {
case 'e':
mult *= 1024;
/* fallthrough */
case 'p':
mult *= 1024;
/* fallthrough */
case 't':
mult *= 1024;
/* fallthrough */
case 'g':
mult *= 1024;
/* fallthrough */
case 'm':
mult *= 1024;
/* fallthrough */
case 'k':
mult *= 1024;
/* fallthrough */
case 'b':
break;
default:
fprintf(stderr, "ERROR: Unknown size descriptor "
"'%c'\n", c);
exit(1);
}
}
if (s[i] && s[i+1]) {
fprintf(stderr, "ERROR: Illegal suffix contains "
"character '%c' in wrong position\n",
s[i+1]);
exit(51);
}
return strtoull(s, NULL, 10) * mult;
}
static char *size_strs[] = { "", "K", "M", "G", "T", "P", "E"};
int pretty_size_snprintf(uint64_t size, char *str, size_t str_bytes)
{
int num_divs = 0;
float fraction;
if (str_bytes == 0)
return 0;
if (!human_readable)
return snprintf(str, str_bytes, "%"PRIu64, size);
if (size < 1024){
fraction = size;
num_divs = 0;
} else {
uint64_t last_size = size;
num_divs = 0;
while(size >= 1024){
last_size = size;
size /= 1024;
num_divs ++;
}
if (num_divs >= ARRAY_SIZE(size_strs)) {
str[0] = '\0';
return -1;
}
fraction = (float)last_size / 1024;
}
return snprintf(str, str_bytes, "%.1f%s", fraction,
size_strs[num_divs]);
}
#ifndef __UTIL_H__
#define __UTIL_H__
#include <stdint.h>
/* controlled by user options, turns pretty print on if true. */
extern int human_readable;
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/*
* Code for parsing and printing human readable numbers is taken from
* btrfs-progs/util.c and modified locally to suit my purposes.
*/
uint64_t parse_size(char *s);
int pretty_size_snprintf(uint64_t size, char *str, size_t str_bytes);
#define pretty_size(size) \
({ \
static __thread char _str[32]; \
(void)pretty_size_snprintf((size), _str, sizeof(_str)); \
_str; \
})
#endif /* __UTIL_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment