diff options
author | christophe.varoqui@free.fr <christophe.varoqui@free.fr> | 2003-12-07 08:50:19 -0800 |
---|---|---|
committer | Greg KH <gregkh@suse.de> | 2005-04-26 21:13:06 -0700 |
commit | a652254ddba3f77abf63f732c42c3a0136dc03d2 (patch) | |
tree | c269e0cd5dfb28104b739b33cdfb32d83431fb75 /extras/multipath | |
parent | d877515791ae4d625d396cdb3a35903cdbf6fde6 (diff) |
[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"
Diffstat (limited to 'extras/multipath')
-rw-r--r-- | extras/multipath/main.c | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 9bceb265ba..bc65899ce1 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -196,6 +196,31 @@ basename(char * str1, char * str2) } 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 get_all_paths_sysfs(struct env * conf, struct path * all_paths) { int k=0; @@ -211,6 +236,8 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) sdir = sysfs_open_directory(block_path); sysfs_read_directory(sdir); dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { + if (blacklist(devp->name)) + continue; sysfs_read_directory(devp); if(devp->links == NULL) continue; @@ -661,7 +688,7 @@ usage(char * progname) } static int -running(char * run) { +filepresent(char * run) { struct stat buf; if(!stat(run, &buf)) @@ -673,6 +700,7 @@ int main(int argc, char *argv[]) { char * run = "/var/run/multipath.run"; + char * resched = "/var/run/multipath.reschedule"; struct multipath * mp; struct path * all_paths; struct scsi_dev * all_scsi_ids; @@ -715,18 +743,17 @@ main(int argc, char *argv[]) } - if (running(run)) { + if (filepresent(run)) { if (conf.verbose) { fprintf(stderr, "Already running.\n"); fprintf(stderr, "If you know what you do, please "); fprintf(stderr, "remove %s\n", run); } + /* leave a trace that we were called while already running */ + open(resched, O_CREAT); return 1; } - if(!open(run, O_CREAT)) - exit(1); - /* dynamic allocations */ mp = malloc(conf.max_devs * sizeof(struct multipath)); all_paths = malloc(conf.max_devs * sizeof(struct path)); @@ -735,6 +762,9 @@ main(int argc, char *argv[]) unlink(run); exit(1); } +start: + if(!open(run, O_CREAT)) + exit(1); if (!conf.with_sysfs) { get_all_scsi_ids(&conf, all_scsi_ids); @@ -764,5 +794,12 @@ main(int argc, char *argv[]) } } 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); } |