#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>
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 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;
}