#include "md_p.h"
#include <sys/socket.h>
#include <sys/utsname.h>
+#include <sys/wait.h>
#include <sys/un.h>
#include <ctype.h>
#include <dirent.h>
memcpy(a, b, 16);
}
+char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char sep)
+{
+ int i;
+ char uuid[16];
+ char *c = buf;
+ strcpy(c, "UUID-");
+ c += strlen(c);
+ copy_uuid(uuid, info->uuid, st->ss->swapuuid);
+ for (i=0; i<16; i++) {
+ if (i && (i&3)==0)
+ *c++ = sep;
+ sprintf(c,"%02x", (unsigned char)uuid[i]);
+ c+= 2;
+ }
+ return buf;
+}
+
#ifndef MDASSEMBLE
int check_ext2(int fd, char *name)
{
return data_disks * devsize;
}
-#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
int get_mdp_major(void)
{
static int mdp_major = -1;
return mdp_major;
}
-
-
+#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
char *get_md_name(int dev)
{
/* find /dev/md%d or /dev/md/%d or make a device /dev/.tmp.md%d */
sprintf(version, "%d.%d", vers, minor);
verstr = version;
}
- if (minor == -2 && verstr[0] == '/') {
+ if (minor == -2 && is_subarray(verstr)) {
char *dev = verstr+1;
subarray = strchr(dev, '/');
int devnum;
return -1;
}
+int add_disk(int mdfd, struct supertype *st,
+ struct mdinfo *sra, struct mdinfo *info)
+{
+ /* Add a device to an array, in one of 2 ways. */
+ int rv;
+#ifndef MDASSEMBLE
+ if (st->ss->external) {
+ rv = sysfs_add_disk(sra, info);
+ if (! rv) {
+ struct mdinfo *sd2;
+ for (sd2 = sra->devs; sd2; sd2=sd2->next)
+ if (sd2 == info)
+ break;
+ if (sd2 == NULL) {
+ sd2 = malloc(sizeof(*sd2));
+ *sd2 = *info;
+ sd2->next = sra->devs;
+ sra->devs = sd2;
+ }
+ }
+ } else
+#endif
+ rv = ioctl(mdfd, ADD_NEW_DISK, &info->disk);
+ return rv;
+}
+
+int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
+{
+ /* Initialise kernel's knowledge of array.
+ * This varies between externally managed arrays
+ * and older kernels
+ */
+ int vers = md_get_version(mdfd);
+ int rv;
+
+#ifndef MDASSEMBLE
+ if (st->ss->external)
+ rv = sysfs_set_array(info, vers);
+ else
+#endif
+ if ((vers % 100) >= 1) { /* can use different versions */
+ mdu_array_info_t inf;
+ memset(&inf, 0, sizeof(inf));
+ inf.major_version = info->array.major_version;
+ inf.minor_version = info->array.minor_version;
+ rv = ioctl(mdfd, SET_ARRAY_INFO, &inf);
+ } else
+ rv = ioctl(mdfd, SET_ARRAY_INFO, NULL);
+ return rv;
+}
+
char *devnum2devname(int num)
{
char name[100];
return num;
}
-int fd2devnum(int fd)
+int stat2devnum(struct stat *st)
{
- struct stat stb;
- if (fstat(fd, &stb) == 0 &&
- (S_IFMT&stb.st_mode)==S_IFBLK) {
- if (major(stb.st_rdev) == MD_MAJOR)
- return minor(stb.st_rdev);
+ if ((S_IFMT & st->st_mode) == S_IFBLK) {
+ if (major(st->st_rdev) == MD_MAJOR)
+ return minor(st->st_rdev);
else
- return -1- (minor(stb.st_rdev)>>6);
+ return -1- (minor(st->st_rdev)>>6);
}
return -1;
+
+}
+
+int fd2devnum(int fd)
+{
+ struct stat stb;
+ if (fstat(fd, &stb) == 0)
+ return stat2devnum(&stb);
+ return -1;
}
int mdmon_running(int devnum)
int start_mdmon(int devnum)
{
int i;
+ int len;
+ pid_t pid;
+ int status;
+ 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);
- execl("./mdmon", "mdmon",
- map_dev(dev2major(devnum),
- dev2minor(devnum),
- 1), NULL);
+ 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 */
+ default: /* parent - good */
+ pid = wait(&status);
+ if (pid < 0 || status != 0)
+ return -1;
}
return 0;
}
return 0;
}
-
+#ifndef MDASSEMBLE
int flush_metadata_updates(struct supertype *st)
{
int sfd;
*st->update_tail = mu;
st->update_tail = &mu->next;
}
-
+#endif /* MDASSEMBLE */
#ifdef __TINYC__
/* tinyc doesn't optimize this check in ioctl.h out ... */