/* mdread --- read a recognizable, predictable pattern on a block device */

# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <stdio.h>
# include <stdlib.h>
# include <errno.h>
# include <string.h>

# define BLOCK_SIZE		(32*1024)
# define LONGS_PER_BLOCK	(BLOCK_SIZE / sizeof (long))

static long get_size (char *devname);

char *progname = "mdread";

main (int argc, char **argv)
{
	long buf[LONGS_PER_BLOCK];
	long i, nblocks;
	int fd;
	char *devname;

	if (argc != 2) {
		fprintf (stderr, "Usage: %s <device>\n", progname);
		exit (1);
	}

	devname = argv[1];

	fd = open (devname, O_RDONLY);
	if (fd < 0) {
		fprintf (stderr, "%s: can't open %s (%s)\n", progname,
		    devname, strerror (errno));
		exit (2);
	}

	nblocks = get_size (devname);

	if (nblocks <= 0) {
		fprintf (stderr, 
		    "%s: %s has %ld blocks; perhaps raidstart is needed?\n",
		    progname, devname, nblocks);
		exit (3);
	}

	for (i = 0; i < nblocks; i++) {
		if (read (fd, (char *) buf, sizeof (buf)) < 0) {
			fprintf (stderr, "%s: read failed (%s)\n", progname,
			    strerror (errno));
			abort ();
		}
#if 0
		printf ("block = %d, *bblock = %ld\n", i, *buf);
#endif

		if (buf[0] != i)
			printf ("block %4ld: *buf = %ld\n", i, *buf);

	}

	close (fd);

	exit (0);
}

/* get_size --- return the size of fd in blocks */

static long
get_size (char *devname)
{
	int fd;
	long nbytes;

	/* stat on a block device returns zero (Duh!), so we must open it,
	** and lseek to the end.  However, lseek also turns off read-ahead
	** which we definatly want, so we open the device a 2nd time to
	** avoid that.
	*/

	fd = open (devname, O_RDONLY);
	if (fd < 0) {
		fprintf (stderr, 
		    "%s (get_size): can't open %s for reading (%s)\n",
		    progname, devname, strerror (errno));
		exit (3);
	}

	nbytes = lseek (fd, 0L, SEEK_END);
	if (nbytes < 0) {
		fprintf (stderr, "%s (get_size): lseek failed (%s)\n",
		    progname, strerror (errno));
		exit (4);
	}

	close (fd);

	return (nbytes / BLOCK_SIZE);
}
