Create arrays via metadata-update
Support creating arrays inside an active ddf container by sending a metadata update over a pipe to mdmon.
This commit is contained in:
parent
bfa44e2e7a
commit
edd8d13c02
17
Create.c
17
Create.c
|
@ -573,12 +573,13 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
return 1;
|
||||
}
|
||||
if (mdmon_running(st->container_dev)) {
|
||||
fprintf(stderr, Name ": mdmon already running "
|
||||
"for %s - sorry\n",
|
||||
devnum2devname(st->container_dev));
|
||||
return 1;
|
||||
}
|
||||
need_mdmon = 1;
|
||||
if (verbose)
|
||||
fprintf(stderr, Name ": reusing mdmon "
|
||||
"for %s.\n",
|
||||
devnum2devname(st->container_dev));
|
||||
st->update_tail = &st->updates;
|
||||
} else
|
||||
need_mdmon = 1;
|
||||
}
|
||||
if ((vers % 100) < 2 ||
|
||||
sra == NULL ||
|
||||
|
@ -707,8 +708,10 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
}
|
||||
if (dv == moved_disk && dnum != insert_point) break;
|
||||
}
|
||||
if (pass == 1)
|
||||
if (pass == 1) {
|
||||
st->ss->write_init_super(st);
|
||||
flush_metadata_updates(st);
|
||||
}
|
||||
}
|
||||
free(infos);
|
||||
st->ss->free_super(st);
|
||||
|
|
22
managemon.c
22
managemon.c
|
@ -428,9 +428,25 @@ void manage(struct mdstat_ent *mdstat, struct supertype *container)
|
|||
}
|
||||
}
|
||||
|
||||
static int handle_message(struct supertype *container, struct metadata_update *msg)
|
||||
static void handle_message(struct supertype *container, struct metadata_update *msg)
|
||||
{
|
||||
return -1;
|
||||
/* queue this metadata update through to the monitor */
|
||||
|
||||
struct metadata_update *mu;
|
||||
|
||||
if (msg->len == 0) {
|
||||
wait_update_handled();
|
||||
} else {
|
||||
mu = malloc(sizeof(*mu));
|
||||
mu->len = msg->len;
|
||||
mu->buf = msg->buf;
|
||||
msg->buf = NULL;
|
||||
mu->space = NULL;
|
||||
mu->next = NULL;
|
||||
if (container->ss->prepare_update)
|
||||
container->ss->prepare_update(container, mu);
|
||||
queue_metadata_update(mu);
|
||||
}
|
||||
}
|
||||
|
||||
void read_sock(struct supertype *container)
|
||||
|
@ -460,8 +476,6 @@ void read_sock(struct supertype *container)
|
|||
} else
|
||||
terminate = 1;
|
||||
|
||||
if (msg.buf)
|
||||
free(msg.buf);
|
||||
} while (!terminate);
|
||||
|
||||
close(fd);
|
||||
|
|
14
mdadm.h
14
mdadm.h
|
@ -542,6 +542,8 @@ extern struct superswitch {
|
|||
void (*sync_metadata)(struct supertype *st);
|
||||
void (*process_update)(struct supertype *st,
|
||||
struct metadata_update *update);
|
||||
void (*prepare_update)(struct supertype *st,
|
||||
struct metadata_update *update);
|
||||
|
||||
/* activate_spare will check if the array is degraded and, if it
|
||||
* is, try to find some spare space in the container.
|
||||
|
@ -559,6 +561,13 @@ extern struct superswitch {
|
|||
|
||||
extern struct superswitch super_imsm;
|
||||
|
||||
struct metadata_update {
|
||||
int len;
|
||||
char *buf;
|
||||
void *space; /* allocated space that monitor will use */
|
||||
struct metadata_update *next;
|
||||
};
|
||||
|
||||
/* A supertype holds a particular collection of metadata.
|
||||
* It identifies the metadata type by the superswitch, and the particular
|
||||
* sub-version of that metadata type.
|
||||
|
@ -579,6 +588,9 @@ struct supertype {
|
|||
void *sb;
|
||||
void *info;
|
||||
|
||||
struct metadata_update *updates;
|
||||
struct metadata_update **update_tail;
|
||||
|
||||
/* extra stuff used by mdmon */
|
||||
struct active_array *arrays;
|
||||
int sock; /* listen to external programs */
|
||||
|
@ -738,6 +750,8 @@ extern unsigned long long get_component_size(int fd);
|
|||
extern void remove_partitions(int fd);
|
||||
extern unsigned long long calc_array_size(int level, int raid_disks, int layout,
|
||||
int chunksize, unsigned long long devsize);
|
||||
extern int flush_metadata_updates(struct supertype *st);
|
||||
extern void append_metadata_update(struct supertype *st, void *buf, int len);
|
||||
|
||||
|
||||
extern char *human_size(long long bytes);
|
||||
|
|
6
mdmon.h
6
mdmon.h
|
@ -41,12 +41,6 @@ struct active_array {
|
|||
* superswitch. All common code sees them as opaque
|
||||
* blobs.
|
||||
*/
|
||||
struct metadata_update {
|
||||
int len;
|
||||
char *buf;
|
||||
void *space; /* allocated space that monitor will use */
|
||||
struct metadata_update *next;
|
||||
};
|
||||
extern struct metadata_update *update_queue, *update_queue_handled;
|
||||
|
||||
#define MD_MAJOR 9
|
||||
|
|
46
super-ddf.c
46
super-ddf.c
|
@ -2122,7 +2122,32 @@ static int __write_init_super_ddf(struct supertype *st, int do_close)
|
|||
|
||||
static int write_init_super_ddf(struct supertype *st)
|
||||
{
|
||||
return __write_init_super_ddf(st, 1);
|
||||
|
||||
if (st->update_tail) {
|
||||
/* queue the virtual_disk and vd_config as metadata updates */
|
||||
struct virtual_disk *vd;
|
||||
struct vd_config *vc;
|
||||
struct ddf_super *ddf = st->sb;
|
||||
int len;
|
||||
|
||||
/* First the virtual disk. We have a slightly fake header */
|
||||
len = sizeof(struct virtual_disk) + sizeof(struct virtual_entry);
|
||||
vd = malloc(len);
|
||||
*vd = *ddf->virt;
|
||||
vd->entries[0] = ddf->virt->entries[ddf->currentconf->vcnum];
|
||||
vd->populated_vdes = __cpu_to_be16(ddf->currentconf->vcnum);
|
||||
append_metadata_update(st, vd, len);
|
||||
|
||||
/* Then the vd_config */
|
||||
len = ddf->conf_rec_len * 512;
|
||||
vc = malloc(len);
|
||||
memcpy(vc, &ddf->currentconf->conf, len);
|
||||
append_metadata_update(st, vc, len);
|
||||
|
||||
/* FIXME I need to close the fds! */
|
||||
return 0;
|
||||
} else
|
||||
return __write_init_super_ddf(st, 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2812,7 +2837,7 @@ static void ddf_process_update(struct supertype *st,
|
|||
printf("len %d %d\n", update->len, ddf->conf_rec_len);
|
||||
|
||||
mppe = __be16_to_cpu(ddf->anchor.max_primary_element_entries);
|
||||
if (update->len != ddf->conf_rec_len)
|
||||
if (update->len != ddf->conf_rec_len * 512)
|
||||
return;
|
||||
vc = (struct vd_config*)update->buf;
|
||||
for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
|
||||
|
@ -2830,7 +2855,7 @@ static void ddf_process_update(struct supertype *st,
|
|||
vcl = update->space;
|
||||
update->space = NULL;
|
||||
vcl->next = ddf->conflist;
|
||||
vcl->conf = *vc;
|
||||
memcpy(&vcl->conf, vc, update->len);
|
||||
vcl->lba_offset = (__u64*)
|
||||
&vcl->conf.phys_refnum[mppe];
|
||||
ddf->conflist = vcl;
|
||||
|
@ -2876,6 +2901,20 @@ static void ddf_process_update(struct supertype *st,
|
|||
}
|
||||
}
|
||||
|
||||
static void ddf_prepare_update(struct supertype *st,
|
||||
struct metadata_update *update)
|
||||
{
|
||||
/* This update arrived at managemon.
|
||||
* We are about to pass it to monitor.
|
||||
* If a malloc is needed, do it here.
|
||||
*/
|
||||
struct ddf_super *ddf = st->sb;
|
||||
__u32 *magic = (__u32*)update->buf;
|
||||
if (*magic == DDF_VD_CONF_MAGIC)
|
||||
update->space = malloc(offsetof(struct vcl, conf)
|
||||
+ ddf->conf_rec_len * 512);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the array 'a' is degraded but not failed.
|
||||
* If it is, find as many spares as are available and needed and
|
||||
|
@ -3106,6 +3145,7 @@ struct superswitch super_ddf = {
|
|||
.set_disk = ddf_set_disk,
|
||||
.sync_metadata = ddf_sync_metadata,
|
||||
.process_update = ddf_process_update,
|
||||
.prepare_update = ddf_prepare_update,
|
||||
.activate_spare = ddf_activate_spare,
|
||||
|
||||
};
|
||||
|
|
43
util.c
43
util.c
|
@ -29,7 +29,9 @@
|
|||
|
||||
#include "mdadm.h"
|
||||
#include "md_p.h"
|
||||
#include <sys/socket.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/un.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <signal.h>
|
||||
|
@ -1065,6 +1067,47 @@ int signal_mdmon(int devnum)
|
|||
}
|
||||
|
||||
|
||||
int flush_metadata_updates(struct supertype *st)
|
||||
{
|
||||
int sfd;
|
||||
if (!st->updates) {
|
||||
st->update_tail = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sfd = connect_monitor(devnum2devname(st->container_dev));
|
||||
if (sfd < 0)
|
||||
return -1;
|
||||
|
||||
while (st->updates) {
|
||||
struct metadata_update *mu = st->updates;
|
||||
st->updates = mu->next;
|
||||
|
||||
send_message(sfd, mu, 0);
|
||||
wait_reply(sfd, 0);
|
||||
free(mu->buf);
|
||||
free(mu);
|
||||
}
|
||||
ack(sfd, 0);
|
||||
wait_reply(sfd, 0);
|
||||
close(sfd);
|
||||
st->update_tail = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void append_metadata_update(struct supertype *st, void *buf, int len)
|
||||
{
|
||||
|
||||
struct metadata_update *mu = malloc(sizeof(*mu));
|
||||
|
||||
mu->buf = buf;
|
||||
mu->len = len;
|
||||
mu->space = NULL;
|
||||
mu->next = NULL;
|
||||
*st->update_tail = mu;
|
||||
st->update_tail = &mu->next;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __TINYC__
|
||||
/* tinyc doesn't optimize this check in ioctl.h out ... */
|
||||
|
|
Loading…
Reference in New Issue