lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:	Tue, 1 May 2007 12:54:03 -0700 (PDT)
From:	Jim Garlick <garlick@...l.gov>
To:	tytso@....edu
cc:	adilger@...sterfs.com, linux-ext4@...r.kernel.org
Subject: [PATCH] add I/O stats to e2fsck -tt

This patch instruments the libext2fs unix I/O manager and adds bytes 
read/written and data rate to e2fsck -tt pass/overall timing output.

Signed-off-by: Jim Garlick <garlick@...l.gov>

Index: e2fsprogs+chaos/lib/ext2fs/unix_io.c
===================================================================
--- e2fsprogs+chaos.orig/lib/ext2fs/unix_io.c
+++ e2fsprogs+chaos/lib/ext2fs/unix_io.c
@@ -70,6 +70,7 @@ struct unix_private_data {
  	int	access_time;
  	ext2_loff_t offset;
  	struct unix_cache cache[CACHE_SIZE];
+	struct struct_io_stats io_stats;
  };

  static errcode_t unix_open(const char *name, int flags, io_channel *channel);
@@ -84,6 +85,8 @@ static errcode_t unix_write_byte(io_chan
  				int size, const void *data);
  static errcode_t unix_set_option(io_channel channel, const char *option,
  				 const char *arg);
+static errcode_t unix_get_stats(io_channel channel, 
+				struct struct_io_stats *stats);

  static void reuse_cache(io_channel channel, struct unix_private_data *data,
  		 struct unix_cache *cache, unsigned long block);
@@ -110,11 +113,29 @@ static struct struct_io_manager struct_u
  #else
  	unix_write_byte,
  #endif
-	unix_set_option
+	unix_set_option,
+	unix_get_stats,
  };

  io_manager unix_io_manager = &struct_unix_manager;

+static errcode_t unix_get_stats(io_channel channel, 
+				struct struct_io_stats *stats)
+{
+	errcode_t 	retval = 0;
+
+	struct unix_private_data *data;
+
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+	data = (struct unix_private_data *) channel->private_data;
+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+
+	if (stats)
+		*stats = data->io_stats;
+
+	return retval;
+}
+
  /*
   * Here are the raw I/O functions
   */
@@ -130,6 +151,7 @@ static errcode_t raw_read_blk(io_channel
  	int		actual = 0;

  	size = (count < 0) ? -count : count * channel->block_size;
+	data->io_stats.reads += size;
  	location = ((ext2_loff_t) block * channel->block_size) + data->offset;
  	if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
  		retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
@@ -168,6 +190,7 @@ static errcode_t raw_read_blk(io_channel
  	char		sector[BLOCKALIGN];

  	size = (count < 0) ? -count : count * channel->block_size;
+	data->io_stats.reads += size;
  	location = ((ext2_loff_t) block * channel->block_size) + data->offset;
  #ifdef DEBUG
  	printf("count=%d, size=%d, block=%lu, blk_size=%d, location=%llx\n",
@@ -224,6 +247,7 @@ static errcode_t raw_write_blk(io_channe
  		else
  			size = count * channel->block_size;
  	}
+	data->io_stats.writes += size;

  	location = ((ext2_loff_t) block * channel->block_size) + data->offset;
  	if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
Index: e2fsprogs+chaos/lib/ext2fs/ext2_io.h
===================================================================
--- e2fsprogs+chaos.orig/lib/ext2fs/ext2_io.h
+++ e2fsprogs+chaos/lib/ext2fs/ext2_io.h
@@ -55,6 +55,11 @@ struct struct_io_channel {
  	void		*app_data;
  };

+struct struct_io_stats {
+	unsigned long long reads;
+	unsigned long long writes;
+};
+
  struct struct_io_manager {
  	errcode_t magic;
  	const char *name;
@@ -70,6 +75,8 @@ struct struct_io_manager {
  				int count, const void *data);
  	errcode_t (*set_option)(io_channel channel, const char *option,
  				const char *arg);
+	errcode_t (*get_stats)(io_channel channel, 
+				struct struct_io_stats *io_stats);
  	int		reserved[14];
  };

Index: e2fsprogs+chaos/e2fsck/e2fsck.h
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/e2fsck.h
+++ e2fsprogs+chaos/e2fsck/e2fsck.h
@@ -135,6 +135,7 @@ struct resource_track {
  	struct timeval user_start;
  	struct timeval system_start;
  	void	*brk_start;
+	struct struct_io_stats io_start;
  };
  #endif

@@ -473,8 +474,10 @@ extern void preenhalt(e2fsck_t ctx);
  extern char *string_copy(e2fsck_t ctx, const char *str, int len);
  #ifdef RESOURCE_TRACK
  extern void print_resource_track(const char *desc,
-				 struct resource_track *track);
-extern void init_resource_track(struct resource_track *track);
+				 struct resource_track *track,
+				 io_channel channel);
+extern void init_resource_track(struct resource_track *track, 
+				io_channel channel);
  #endif
  extern int inode_has_valid_blocks(struct ext2_inode *inode);
  extern void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
Index: e2fsprogs+chaos/e2fsck/util.c
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/util.c
+++ e2fsprogs+chaos/e2fsck/util.c
@@ -274,7 +274,7 @@ void preenhalt(e2fsck_t ctx)
  }

  #ifdef RESOURCE_TRACK
-void init_resource_track(struct resource_track *track)
+void init_resource_track(struct resource_track *track, io_channel channel)
  {
  #ifdef HAVE_GETRUSAGE
  	struct rusage r;
@@ -293,6 +293,9 @@ void init_resource_track(struct resource
  	track->user_start.tv_sec = track->user_start.tv_usec = 0;
  	track->system_start.tv_sec = track->system_start.tv_usec = 0;
  #endif
+	memset(&track->io_start, 0, sizeof(struct struct_io_stats));
+	if (channel && channel->manager && channel->manager->get_stats)
+		channel->manager->get_stats(channel, &track->io_start);
  }

  #ifdef __GNUC__
@@ -308,7 +311,8 @@ static _INLINE_ float timeval_subtract(s
  		((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
  }

-void print_resource_track(const char *desc, struct resource_track *track)
+void print_resource_track(const char *desc, struct resource_track *track,
+	io_channel channel)
  {
  #ifdef HAVE_GETRUSAGE
  	struct rusage r;
@@ -345,6 +349,21 @@ void print_resource_track(const char *de
  	printf(_("elapsed time: %6.3f\n"),
  	       timeval_subtract(&time_end, &track->time_start));
  #endif
+#define mbytes(x)	(((x) + 1048575) / 1048576)
+	if (channel && channel->manager && channel->manager->get_stats) {
+		struct struct_io_stats delta;
+
+		if (desc)
+			printf("%s: ", desc);
+
+		channel->manager->get_stats(channel, &delta);
+		delta.reads -= track->io_start.reads;
+		delta.writes -= track->io_start.writes;
+		printf("I/O read: %dmb, write: %dmb, rate: %.2fmb/s\n",
+			mbytes(delta.reads), mbytes(delta.writes),
+			(double)mbytes(delta.reads + delta.writes) /
+			 timeval_subtract(&time_end, &track->time_start));
+	}
  }
  #endif /* RESOURCE_TRACK */

Index: e2fsprogs+chaos/e2fsck/pass5.c
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/pass5.c
+++ e2fsprogs+chaos/e2fsck/pass5.c
@@ -30,7 +30,7 @@ void e2fsck_pass5(e2fsck_t ctx)
  #endif

  #ifdef RESOURCE_TRACK
-	init_resource_track(&rtrack);
+	init_resource_track(&rtrack, ctx->fs->io);
  #endif

  	clear_problem_context(&pctx);
@@ -67,7 +67,7 @@ void e2fsck_pass5(e2fsck_t ctx)
  #ifdef RESOURCE_TRACK
  	if (ctx->options & E2F_OPT_TIME2) {
  		e2fsck_clear_progbar(ctx);
-		print_resource_track(_("Pass 5"), &rtrack);
+		print_resource_track(_("Pass 5"), &rtrack, ctx->fs->io);
  	}
  #endif
  }
Index: e2fsprogs+chaos/e2fsck/unix.c
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/unix.c
+++ e2fsprogs+chaos/e2fsck/unix.c
@@ -956,7 +956,7 @@ int main (int argc, char *argv[])
  	reserve_stdio_fds();

  #ifdef RESOURCE_TRACK
-	init_resource_track(&ctx->global_rtrack);
+	init_resource_track(&ctx->global_rtrack, NULL);
  #endif

  	if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
@@ -1289,16 +1289,16 @@ restart:
  	}

  	e2fsck_write_bitmaps(ctx);
- 
+#ifdef RESOURCE_TRACK
+	io_channel_flush(ctx->fs->io);
+	if (ctx->options & E2F_OPT_TIME)
+		print_resource_track(NULL, &ctx->global_rtrack, ctx->fs->io);
+#endif
  	ext2fs_close(fs);
  	ctx->fs = NULL;
  	free(ctx->filesystem_name);
  	free(ctx->journal_name);

-#ifdef RESOURCE_TRACK
-	if (ctx->options & E2F_OPT_TIME)
-		print_resource_track(NULL, &ctx->global_rtrack);
-#endif
  	e2fsck_free_context(ctx);
  	remove_error_table(&et_ext2_error_table);
  	remove_error_table(&et_prof_error_table);
Index: e2fsprogs+chaos/e2fsck/swapfs.c
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/swapfs.c
+++ e2fsprogs+chaos/e2fsck/swapfs.c
@@ -223,7 +223,7 @@ void swap_filesys(e2fsck_t ctx)
  #ifdef RESOURCE_TRACK
  	struct resource_track	rtrack;

-	init_resource_track(&rtrack);
+	init_resource_track(&rtrack, ctx->fs->io);
  #endif

  	if (!(ctx->options & E2F_OPT_PREEN))
@@ -269,7 +269,7 @@ void swap_filesys(e2fsck_t ctx)

  #ifdef RESOURCE_TRACK
  	if (ctx->options & E2F_OPT_TIME2)
-		print_resource_track(_("Byte swap"), &rtrack);
+		print_resource_track(_("Byte swap"), &rtrack, fs->io);
  #endif
  }

Index: e2fsprogs+chaos/e2fsck/pass1.c
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/pass1.c
+++ e2fsprogs+chaos/e2fsck/pass1.c
@@ -402,7 +402,7 @@ void e2fsck_pass1(e2fsck_t ctx)
  	int		inode_size;

  #ifdef RESOURCE_TRACK
-	init_resource_track(&rtrack);
+	init_resource_track(&rtrack, ctx->fs->io);
  #endif
  	clear_problem_context(&pctx);

@@ -979,7 +979,7 @@ endit:
  #ifdef RESOURCE_TRACK
  	if (ctx->options & E2F_OPT_TIME2) {
  		e2fsck_clear_progbar(ctx);
-		print_resource_track(_("Pass 1"), &rtrack);
+		print_resource_track(_("Pass 1"), &rtrack, ctx->fs->io);
  	}
  #endif
  }
Index: e2fsprogs+chaos/e2fsck/pass2.c
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/pass2.c
+++ e2fsprogs+chaos/e2fsck/pass2.c
@@ -103,7 +103,7 @@ void e2fsck_pass2(e2fsck_t ctx)
  	int			bad_dir;

  #ifdef RESOURCE_TRACK
-	init_resource_track(&rtrack);
+	init_resource_track(&rtrack, ctx->fs->io);
  #endif

  	clear_problem_context(&cd.pctx);
@@ -293,7 +293,7 @@ void e2fsck_pass2(e2fsck_t ctx)
  #ifdef RESOURCE_TRACK
  	if (ctx->options & E2F_OPT_TIME2) {
  		e2fsck_clear_progbar(ctx);
-		print_resource_track(_("Pass 2"), &rtrack);
+		print_resource_track(_("Pass 2"), &rtrack, fs->io);
  	}
  #endif
  }
Index: e2fsprogs+chaos/e2fsck/pass3.c
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/pass3.c
+++ e2fsprogs+chaos/e2fsck/pass3.c
@@ -61,7 +61,7 @@ void e2fsck_pass3(e2fsck_t ctx)
  	unsigned long maxdirs, count;

  #ifdef RESOURCE_TRACK
-	init_resource_track(&rtrack);
+	init_resource_track(&rtrack, ctx->fs->io);
  #endif

  	clear_problem_context(&pctx);
@@ -87,7 +87,8 @@ void e2fsck_pass3(e2fsck_t ctx)
  #ifdef RESOURCE_TRACK
  	if (ctx->options & E2F_OPT_TIME) {
  		e2fsck_clear_progbar(ctx);
-		print_resource_track(_("Peak memory"), &ctx->global_rtrack);
+		print_resource_track(_("Peak memory"), &ctx->global_rtrack,
+					NULL);
  	}
  #endif

@@ -140,7 +141,7 @@ abort_exit:
  #ifdef RESOURCE_TRACK
  	if (ctx->options & E2F_OPT_TIME2) {
  		e2fsck_clear_progbar(ctx);
-		print_resource_track(_("Pass 3"), &rtrack);
+		print_resource_track(_("Pass 3"), &rtrack, ctx->fs->io);
  	}
  #endif
  }
Index: e2fsprogs+chaos/e2fsck/pass4.c
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/pass4.c
+++ e2fsprogs+chaos/e2fsck/pass4.c
@@ -104,7 +104,7 @@ void e2fsck_pass4(e2fsck_t ctx)
  	int	group, maxgroup;

  #ifdef RESOURCE_TRACK
-	init_resource_track(&rtrack);
+	init_resource_track(&rtrack, ctx->fs->io);
  #endif

  #ifdef MTRACE
@@ -189,7 +189,7 @@ errout:
  #ifdef RESOURCE_TRACK
  	if (ctx->options & E2F_OPT_TIME2) {
  		e2fsck_clear_progbar(ctx);
-		print_resource_track(_("Pass 4"), &rtrack);
+		print_resource_track(_("Pass 4"), &rtrack, ctx->fs->io);
  	}
  #endif
  }
Index: e2fsprogs+chaos/e2fsck/rehash.c
===================================================================
--- e2fsprogs+chaos.orig/e2fsck/rehash.c
+++ e2fsprogs+chaos/e2fsck/rehash.c
@@ -777,7 +777,7 @@ void e2fsck_rehash_directories(e2fsck_t
  	int			i, cur, max, all_dirs, dir_index, first = 1;

  #ifdef RESOURCE_TRACK
-	init_resource_track(&rtrack);
+	init_resource_track(&rtrack, ctx->fs->io);
  #endif

  	all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
@@ -843,7 +843,7 @@ void e2fsck_rehash_directories(e2fsck_t
  #ifdef RESOURCE_TRACK
  	if (ctx->options & E2F_OPT_TIME2) {
  		e2fsck_clear_progbar(ctx);
-		print_resource_track("Pass 3A", &rtrack);
+		print_resource_track("Pass 3A", &rtrack, ctx->fs->io);
  	}
  #endif
  }
-
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ