#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>
snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d:%d",
(int)getpid(), major, minor);
if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) {
- fd = open(devname, flags);
+ fd = open(devname, flags|O_DIRECT);
unlink(devname);
}
} else
- fd = open(dev, flags);
+ fd = open(dev, flags|O_DIRECT);
return fd;
}
int devnum;
if (subarray)
*subarray++ = '\0';
- if (strncmp(dev, "md_d", 4) == 0)
- devnum = -1-atoi(dev+4);
- else
- devnum = atoi(dev+2);
+ devnum = devname2devnum(dev);
subarray = strdup(subarray);
if (sra)
sysfs_free(sra);
{
struct supertype *st;
+ if (!orig)
+ return orig;
st = malloc(sizeof(*st));
if (!st)
return st;
return strdup(name);
}
+int devname2devnum(char *name)
+{
+ char *ep;
+ int num;
+ if (strncmp(name, "md_d", 4)==0)
+ num = -1-strtoul(name+4, &ep, 10);
+ else
+ num = strtoul(name+2, &ep, 10);
+ return num;
+}
+
int fd2devnum(int fd)
{
struct stat stb;
return 0;
}
+int start_mdmon(int devnum)
+{
+ int i;
+ int len;
+ char pathbuf[1024];
+ char *paths[4] = {
+ pathbuf,
+ "/sbin/mdmon",
+ "mdmon",
+ NULL
+ };
+
+ if (env_no_mdmon())
+ return 0;
+
+ len = readlink("/proc/self/exe", pathbuf, sizeof(pathbuf));
+ if (len > 0) {
+ char *sl;
+ pathbuf[len] = 0;
+ sl = strrchr(pathbuf, '/');
+ if (sl)
+ sl++;
+ else
+ sl = pathbuf;
+ strcpy(sl, "mdmon");
+ } else
+ pathbuf[0] = '\0';
+
+ switch(fork()) {
+ case 0:
+ /* FIXME yuk. CLOSE_EXEC?? */
+ for (i=3; i < 100; i++)
+ close(i);
+ for (i=0; paths[i]; i++)
+ if (paths[i][0])
+ execl(paths[i], "mdmon",
+ map_dev(dev2major(devnum),
+ dev2minor(devnum),
+ 1), NULL);
+ exit(1);
+ case -1: fprintf(stderr, Name ": cannot run mdmon. "
+ "Array remains readonly\n");
+ return -1;
+ default: ; /* parent - good */
+ }
+ return 0;
+}
+
+int env_no_mdmon(void)
+{
+ char *val = getenv("MDADM_NO_MDMON");
+
+ if (val && atoi(val) == 1)
+ return 1;
+
+ return 0;
+}
+
+
+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__