git » dm-csum-tools » commit f927376

Initial commit

author Alberto Bertogli
2009-10-28 00:35:58 UTC
committer Alberto Bertogli
2009-10-28 00:35:58 UTC

Initial commit

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>

mk-dm-csum.c +148 -0

diff --git a/mk-dm-csum.c b/mk-dm-csum.c
new file mode 100644
index 0000000..182def9
--- /dev/null
+++ b/mk-dm-csum.c
@@ -0,0 +1,148 @@
+
+/* Formats the given file for use by dm-csum */
+
+/* Needed to use pwrite() and strtoll() */
+#define _XOPEN_SOURCE 600
+
+#include <stdio.h>		/* printf() */
+#include <stdlib.h>		/* malloc() */
+#include <unistd.h>		/* pwrite() and friends */
+#include <sys/types.h>		/* open() */
+#include <sys/stat.h>		/* open() */
+#include <fcntl.h>		/* open() */
+#include <stdint.h>		/* uint8_t and friends */
+#include <string.h>		/* memset() */
+
+
+/* simple definitions so we can copy-paste the structs from the kernel */
+#define u8 uint8_t
+#define __be16 uint16_t
+#define __be32 uint32_t
+
+/*
+ * Copied from the kernel definition, MUST match
+ */
+
+#define RESERVED_INITIAL_SECTORS_D 1
+#define RESERVED_INITIAL_SECTORS_M 1
+#define SECTORS_PER_IMD 62
+
+struct imd_tuple {
+        __be16 crc;
+        __be16 flags;
+        __be32 tag;
+} __attribute__ ((packed));
+
+struct imd_sector_header {
+        u8 last_updated;
+        u8 unused1;
+        __be16 crc;
+        __be32 unused3;
+} __attribute__ ((packed));
+
+
+/* Format function to use when imd and data are on the same device */
+int format_same(int fd, off_t total_size) {
+	int r;
+	off_t off;
+	unsigned char buf[1024];
+	struct imd_sector_header *m1, *m2;
+
+	memset(buf, 0, sizeof(buf));
+
+	m1 = (struct imd_sector_header *) buf;
+	m2 = (struct imd_sector_header *) (buf + 512);
+
+	m1->last_updated = 2;
+	m2->last_updated = 1;
+
+	off = RESERVED_INITIAL_SECTORS_D * 512;
+
+	while (off < total_size) {
+		r = pwrite(fd, buf, 1024, off);
+		if (r != 1024)
+			return -1;
+		off += 1024 + SECTORS_PER_IMD * 512;
+	}
+
+	return 0;
+}
+
+int format_diff(int data_fd, int imd_fd, off_t total_size)
+{
+	printf("Not implemented yet\n");
+	return 0;
+}
+
+void usage()
+{
+	printf("Use: mk-dm-csum same <device> [data length]\n");
+	printf(" or: mk-dm-csum diff <data device> <imd device> [data length]\n");
+	printf("\n");
+	printf("Note: data length is in bytes, and will be rounded down to\n");
+	printf("an appropriate bound.\n");
+}
+
+int main(int argc, char **argv)
+{
+	int fd = -1, imd_fd = -1;
+	long long total_size;
+	int same;
+
+	if (argc < 3) {
+		usage();
+		return 1;
+	}
+
+	if (strcmp(argv[1], "same") == 0) {
+		same = 1;
+	} else if (strcmp(argv[1], "diff") == 0) {
+		/* TODO */
+		same = 0;
+		printf("Error: not implemented yet.\n");
+		return 1;
+	} else {
+		usage();
+		return 1;
+	}
+
+	fd = open(argv[2], O_WRONLY);
+	if (fd < 0) {
+		perror("Error opening device");
+		return 1;
+	}
+
+	if (argc >= 4) {
+		total_size = strtoll(argv[3], NULL, 0);
+	} else {
+		total_size = lseek(fd, 0, SEEK_END);
+		if (total_size == -1) {
+			perror("Error finding out the size");
+			return 1;
+		}
+	}
+
+	/* round down to a multiple of SECTORS_PER_IMD */
+	total_size -= total_size % SECTORS_PER_IMD;
+	printf("Effective total size: %llu\n", total_size);
+
+	if (same) {
+		if (format_same(fd, total_size) != 0) {
+			perror("Error formatting");
+			return 2;
+		}
+	} else {
+		if (format_diff(fd, imd_fd, total_size) != 0) {
+			perror("Error formatting");
+			return 2;
+		}
+	}
+
+	if (fsync(fd) != 0) {
+		perror("Error syncing data to disk");
+		return 3;
+	}
+
+	return 0;
+}
+