summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Ledford <dledford@redhat.com>2010-04-16 17:53:45 -0400
committerDoug Ledford <dledford@redhat.com>2010-04-16 17:53:45 -0400
commit0dba81619de300d36684371b7aaf22e69da1df91 (patch)
tree7d3e3f69b2ea597f11aad82d2140d58c8b639791
parenteda79540d4fee8b0f2eb872eed9e372091714379 (diff)
downloadmdadm-0dba81619de300d36684371b7aaf22e69da1df91.tar.gz
mdadm-0dba81619de300d36684371b7aaf22e69da1df91.tar.xz
mdadm-0dba81619de300d36684371b7aaf22e69da1df91.zip
Add check_clean() function
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--Incremental.c16
-rw-r--r--mdadm.h1
-rw-r--r--util.c29
3 files changed, 40 insertions, 6 deletions
diff --git a/Incremental.c b/Incremental.c
index 8bc455d..d3dd0c3 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -941,7 +941,7 @@ static int IncrementalNewDisk(char *devname, int verbose, int export,
struct domain_ent *domain)
{
struct stat stb;
- int dfd;
+ int dfd, rv;
dfd = dev_open_check(devname, O_RDONLY|O_EXCL, &stb);
if (dfd < 0)
@@ -954,8 +954,11 @@ static int IncrementalNewDisk(char *devname, int verbose, int export,
close(dfd);
return 1;
}
- if (domain->handler->check_table(dfd, verbose, export, domain) == 0)
+
+ if (domain->handler->check_table(dfd, verbose, export, domain) == 0) {
+ close(dfd);
return 0;
+ }
/*
* OK, at this point we have a valid block device without a
* superblock, the partition table doesn't match, and we are a
@@ -965,10 +968,11 @@ static int IncrementalNewDisk(char *devname, int verbose, int export,
* last 4k of the device must be one of three patterns: 0x00, 0x5a,
* or 0xff.
*/
- if (force(domain))
- return domain->handler->write_table(dfd, verbose, export,
- domain);
- return 0;
+ if (check_clean(dfd) || force(domain)) {
+ rv = domain->handler->write_table(dfd, verbose, export, domain);
+ }
+ close(dfd);
+ return rv;
}
/*
diff --git a/mdadm.h b/mdadm.h
index 118056d..b1e74db 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -893,6 +893,7 @@ extern int parse_layout_faulty(char *layout);
extern int check_ext2(int fd, char *name);
extern int check_reiser(int fd, char *name);
extern int check_raid(int fd, char *name);
+extern int check_clean(int fd);
extern int check_partitions(int fd, char *dname, unsigned long long freesize);
extern int get_mdp_major(void);
diff --git a/util.c b/util.c
index b9c428b..3c8dbcb 100644
--- a/util.c
+++ b/util.c
@@ -511,6 +511,35 @@ int check_raid(int fd, char *name)
return 1;
}
+int check_clean(int dfd)
+{
+ void *head, *tail, *pattern;
+ int i=0, head_clean=0, tail_clean=0;
+ unsigned char patterns[]={0x00,0x5a,0xff};
+
+ head = malloc(4096);
+ tail = malloc(4096);
+ pattern = malloc(4096);
+ if (!head || !tail || !pattern)
+ return 0;
+ if (lseek(dfd, 0, SEEK_SET) == -1)
+ return 0;
+ if (read(dfd, head, 4096) != 4096)
+ return 0;
+ if (lseek(dfd, -4096, SEEK_END) == -1)
+ return 0;
+ if (read(dfd, tail, 4096) != 4096)
+ return 0;
+ while (i < 3) {
+ memset(pattern, patterns[i++], 4096);
+ if (memcmp(head, pattern, 4096) == 0)
+ head_clean++;
+ if (memcmp(tail, pattern, 4096) == 0)
+ tail_clean++;
+ }
+ return (head_clean && tail_clean);
+}
+
int ask(char *mesg)
{
char *add = "";