[PATCH] yet more extras/multipath

* implement a reschedule flag in /var/run. Last thing the prog do before
exit is check if a call to multipath was done (but canceled by
/var/run/multipath.run check) during its execution. If so restart the
main loop.
* implement a blacklist of sysfs bdev to not bother with for now (hd,
md, dm, sr, scd, ram, raw). This avoid sending SG_IO to unappropiate
devices.

Compiles & survive "while true;do (./multipath -v &);done"
This commit is contained in:
christophe.varoqui@free.fr 2003-12-07 08:50:19 -08:00 committed by Greg KH
parent d877515791
commit a652254ddb

View file

@ -195,6 +195,31 @@ basename(char * str1, char * str2)
strcpy(str2, ++p); strcpy(str2, ++p);
} }
static int
blacklist (char * dev) {
int i;
static struct {
char * headstr;
int lengh;
} blist[] = {
{"cciss", 5},
{"hd", 2},
{"md", 2},
{"dm", 2},
{"sr", 2},
{"scd", 3},
{"ram", 3},
{"raw", 3},
{NULL, 0},
};
for (i = 0; blist[i].lengh; i++) {
if (strncmp(dev, blist[i].headstr, blist[i].lengh))
return 1;
}
return 0;
}
static int static int
get_all_paths_sysfs(struct env * conf, struct path * all_paths) get_all_paths_sysfs(struct env * conf, struct path * all_paths)
{ {
@ -211,6 +236,8 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths)
sdir = sysfs_open_directory(block_path); sdir = sysfs_open_directory(block_path);
sysfs_read_directory(sdir); sysfs_read_directory(sdir);
dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) {
if (blacklist(devp->name))
continue;
sysfs_read_directory(devp); sysfs_read_directory(devp);
if(devp->links == NULL) if(devp->links == NULL)
continue; continue;
@ -661,7 +688,7 @@ usage(char * progname)
} }
static int static int
running(char * run) { filepresent(char * run) {
struct stat buf; struct stat buf;
if(!stat(run, &buf)) if(!stat(run, &buf))
@ -673,6 +700,7 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char * run = "/var/run/multipath.run"; char * run = "/var/run/multipath.run";
char * resched = "/var/run/multipath.reschedule";
struct multipath * mp; struct multipath * mp;
struct path * all_paths; struct path * all_paths;
struct scsi_dev * all_scsi_ids; struct scsi_dev * all_scsi_ids;
@ -715,18 +743,17 @@ main(int argc, char *argv[])
} }
if (running(run)) { if (filepresent(run)) {
if (conf.verbose) { if (conf.verbose) {
fprintf(stderr, "Already running.\n"); fprintf(stderr, "Already running.\n");
fprintf(stderr, "If you know what you do, please "); fprintf(stderr, "If you know what you do, please ");
fprintf(stderr, "remove %s\n", run); fprintf(stderr, "remove %s\n", run);
} }
/* leave a trace that we were called while already running */
open(resched, O_CREAT);
return 1; return 1;
} }
if(!open(run, O_CREAT))
exit(1);
/* dynamic allocations */ /* dynamic allocations */
mp = malloc(conf.max_devs * sizeof(struct multipath)); mp = malloc(conf.max_devs * sizeof(struct multipath));
all_paths = malloc(conf.max_devs * sizeof(struct path)); all_paths = malloc(conf.max_devs * sizeof(struct path));
@ -735,6 +762,9 @@ main(int argc, char *argv[])
unlink(run); unlink(run);
exit(1); exit(1);
} }
start:
if(!open(run, O_CREAT))
exit(1);
if (!conf.with_sysfs) { if (!conf.with_sysfs) {
get_all_scsi_ids(&conf, all_scsi_ids); get_all_scsi_ids(&conf, all_scsi_ids);
@ -764,5 +794,12 @@ main(int argc, char *argv[])
} }
} }
unlink(run); unlink(run);
/* start again if we were ask to during this process run */
/* ie. do not loose an event-asked run */
if (filepresent(resched)) {
unlink(resched);
goto start;
}
exit(0); exit(0);
} }