summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Ledford <dledford@redhat.com>2010-04-15 18:13:36 -0400
committerDoug Ledford <dledford@redhat.com>2010-04-15 18:13:36 -0400
commit4339ce40dc81b624f2d87ba7207b5bfc131831ea (patch)
tree2e1ba2f53e835c1438e1577ea5719dfdd0808739
parent884a1cc4b343a9a26cf89c21f59133536309b10b (diff)
downloadmdadm-4339ce40dc81b624f2d87ba7207b5bfc131831ea.tar.gz
mdadm-4339ce40dc81b624f2d87ba7207b5bfc131831ea.tar.xz
mdadm-4339ce40dc81b624f2d87ba7207b5bfc131831ea.zip
Initial support for new disk hot plug actions. Nowhere near complete,
just the initial stages. Added support for the call to mdadm.c, some sanity checks on how we are called, some of the initial easy sanity checks that kick us out of the new function, etc. Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--Incremental.c57
-rw-r--r--mdadm.c32
-rw-r--r--mdadm.h1
3 files changed, 85 insertions, 5 deletions
diff --git a/Incremental.c b/Incremental.c
index ed29488..1fcc4f0 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -882,3 +882,60 @@ int IncrementalRemove(char *devname, int verbose)
devlist.disposition = 'r';
return Manage_subdevs(ent->dev, mdfd, &devlist, verbose);
}
+
+/*
+ * IncrementalNewDisk - Check to see if the passed in device belongs to any
+ * DOMAIN entries from the config file, and if so, perform the required
+ * action.
+ *
+ * @devname - The device we are supposed to examine. This is a currently
+ * non-raid device, decide if we should claim it and if so, perform the
+ * required actions.
+ *
+ * Special note: Due to limitations of the whole hotplug model, any time we
+ * have a partitioned device, the bare drive will get called into this
+ * function because only the partitions will register as already being raid
+ * members, the bare drive itself won't. We need to be smart enough here
+ * so that even if we have a DOMAIN line that says partition, that we don't
+ * actually do the partitioning if the right partition table is already there.
+ */
+int IncrementalNewDisk(char *devname, int verbose, int export)
+{
+ struct mdstat_ent *mdstat, *md;
+ struct domain_ent *domain;
+
+ domain = conf_get_domain(devname);
+ if (!domain)
+ return 0;
+ if ((domain->action & action_mask) <= incremental)
+ /* Nothing to do. We only get called in the case that there
+ * is no current superblock on the device in question, and
+ * since our matching domain says we should either ignore or
+ * use devices incrementally, they have to already have a
+ * superblock. Since we don't, we're done.
+ */
+ return 0;
+ if (domain->action == partition) {
+ /* Special case. Basically, we can only put this action on
+ * whole disk devices, and since we are partitioning them,
+ * the whole device necessarily won't ever be part of an
+ * array, so we will never have any arrays in our domain, ever.
+ * As such, we have to figure out what to do from other
+ * hints.
+ */
+ /* We haven't filled this out yet */
+ return 0;
+ }
+ mdstat = arrays_in_domain(devname, domain);
+ if (!mdstat) {
+ /* As a technical design decision, we *must* have at least one
+ * array in our domain that we can add this device to or else
+ * we simply can't do anything with this device.
+ */
+ printf("No arrays found in domain!\n");
+ return 1;
+ }
+ for (md = mdstat; md; md = md->next)
+ printf(Name ": %s\n", md->dev);
+ return 0;
+}
diff --git a/mdadm.c b/mdadm.c
index 6690546..35d1f7d 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -73,6 +73,7 @@ int main(int argc, char *argv[])
int test = 0;
int export = 0;
int assume_clean = 0;
+ int new_disk = 0;
char *symlinks = NULL;
/* autof indicates whether and how to create device node.
* bottom 3 bits are style. Rest (when shifted) are number of parts
@@ -910,6 +911,9 @@ int main(int argc, char *argv[])
case O(INCREMENTAL, 'r'):
rebuild_map = 1;
continue;
+ case O(INCREMENTAL, 'g'):
+ new_disk = 1;
+ continue;
}
/* We have now processed all the valid options. Anything else is
* an error
@@ -1514,6 +1518,11 @@ int main(int argc, char *argv[])
if (rebuild_map) {
RebuildMap();
}
+ if (export && !new_disk) {
+ fprintf(stderr, Name
+ ": --incremental --export only supported with --grab.\n");
+ break;
+ }
if (scan) {
if (runstop <= 0) {
fprintf(stderr, Name
@@ -1525,8 +1534,18 @@ int main(int argc, char *argv[])
": --incremental --scan --fail not supported.\n");
break;
}
+ if (new_disk > 0) {
+ fprintf(stderr, Name
+ ": --incremental --scan --grab not supported.\n");
+ break;
+ }
rv = IncrementalScan(verbose);
}
+ if (devmode == 'f' && new_disk) {
+ fprintf(stderr, Name
+ ": --incremental --fail --grab makes no sense.\n");
+ break;
+ }
if (!devlist) {
if (!rebuild_map && !scan) {
fprintf(stderr, Name
@@ -1541,12 +1560,15 @@ int main(int argc, char *argv[])
rv = 1;
break;
}
- if (devmode == 'f') {
+ if (devmode == 'f')
rv = IncrementalRemove(devlist->devname, verbose-quiet);
- break;
- }
- rv = Incremental(devlist->devname, verbose-quiet, runstop,
- ss, homehost, require_homehost, autof);
+ else if (new_disk > 0)
+ rv = IncrementalNewDisk(devlist->devname, verbose-quiet,
+ export);
+ else
+ rv = Incremental(devlist->devname, verbose-quiet,
+ runstop, ss, homehost,
+ require_homehost, autof);
break;
case AUTODETECT:
autodetect();
diff --git a/mdadm.h b/mdadm.h
index 0246516..baf5ddd 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -853,6 +853,7 @@ extern int Incremental_container(struct supertype *st, char *devname,
extern void RebuildMap(void);
extern int IncrementalScan(int verbose);
extern int IncrementalRemove(char *devname, int verbose);
+extern int IncrementalNewDisk(char *devname, int verbose, int export);
extern int CreateBitmap(char *filename, int force, char uuid[16],
unsigned long chunksize, unsigned long daemon_sleep,
unsigned long write_behind,