#include <string.h>
#include <limits.h>
#include <stdio.h>
+#include <signal.h>
+
#include "debug.h"
#include "uxsock.h"
#include "alias.h"
return 0;
}
+static void
+sigalrm(int sig)
+{
+ /* do nothing */
+}
+
static int
lock_bindings_file(int fd)
{
+ struct sigaction act, oldact;
+ sigset_t set, oldset;
struct flock lock;
- int retrys = BINDINGS_FILE_RETRYS;
+ int err;
memset(&lock, 0, sizeof(lock));
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
- while (fcntl(fd, F_SETLK, &lock) < 0) {
- if (errno != EACCES && errno != EAGAIN) {
- condlog(0, "Cannot lock bindings file : %s",
- strerror(errno));
- return -1;
- } else {
- condlog(0, "Bindings file is currently locked");
- if ((retrys--) == 0)
- return -1;
- }
- /* because I'm paranoid */
- memset(&lock, 0, sizeof(lock));
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
-
- condlog(0, "retrying");
- sleep(1);
+ act.sa_handler = sigalrm;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ sigemptyset(&set);
+ sigaddset(&set, SIGALRM);
+
+ sigaction(SIGALRM, &act, &oldact);
+ sigprocmask(SIG_UNBLOCK, &set, &oldset);
+
+ alarm(BINDINGS_FILE_TIMEOUT);
+ err = fcntl(fd, F_SETLKW, &lock);
+ alarm(0);
+
+ if (err) {
+ if (errno != EINTR)
+ condlog(0, "Cannot lock bindings file : %s");
+ else
+ condlog(0, "Bindings file is locked. Giving up.");
}
- return 0;
+
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ sigaction(SIGALRM, &oldact, NULL);
+ return err;
+
}
}
char *
-get_user_friendly_alias(char *wwid)
+get_user_friendly_alias(char *wwid, char *file)
{
char *alias;
int fd, id;
return NULL;
}
- fd = open_bindings_file(BINDINGS_FILE_NAME);
+ fd = open_bindings_file(file);
if (fd < 0)
return NULL;
id = lookup_binding(fd, wwid, &alias);
}
char *
-get_user_friendly_wwid(char *alias)
+get_user_friendly_wwid(char *alias, char *file)
{
char *wwid;
int fd, id;
return NULL;
}
- fd = open_bindings_file(BINDINGS_FILE_NAME);
+ fd = open_bindings_file(file);
if (fd < 0)
return NULL;
id = rlookup_binding(fd, &wwid, alias);
-#define BINDINGS_FILE_NAME "/var/lib/multipath/bindings"
-#define BINDINGS_FILE_RETRYS 3
+#define BINDINGS_FILE_TIMEOUT 3
#define BINDINGS_FILE_HEADER \
"# Multipath bindings, Version : 1.0\n" \
"# NOTE: this file is automatically maintained by the multipath program.\n" \
"# alias wwid\n" \
"#\n"
-
-char *get_user_friendly_alias(char *wwid);
-char *get_user_friendly_wwid(char *alias);
+char *get_user_friendly_alias(char *wwid, char *file);
+char *get_user_friendly_wwid(char *alias, char *file);
/*
* may be a binding
*/
- refwwid = get_user_friendly_wwid(conf->dev);
+ refwwid = get_user_friendly_wwid(conf->dev,
+ conf->bindings_file);
if (refwwid)
return refwwid;
"\t\t\t[-p failover|multibus|group_by_serial|group_by_prio]\n" \
"\t\t\t[device]\n" \
"\n" \
- "\t-v level\tverbosty level\n" \
+ "\t-v level\tverbosity level\n" \
"\t 0\t\t\tno output\n" \
"\t 1\t\t\tprint created devmap names only\n" \
"\t 2\t\t\tdefault verbosity\n" \
"\t 3\t\t\tprint debug information\n" \
+ "\t-b file\t\tbindings file location\n" \
"\t-d\t\tdry run, do not create or update devmaps\n" \
"\t-l\t\tshow multipath topology (sysfs and DM info)\n" \
"\t-ll\t\tshow multipath topology (maximum info)\n" \
if (load_config(DEFAULT_CONFIGFILE))
exit(1);
- while ((arg = getopt(argc, argv, ":qdl::Ffi:M:v:p:")) != EOF ) {
+ while ((arg = getopt(argc, argv, ":qdl::Ffi:M:v:p:b:")) != EOF ) {
switch(arg) {
case 1: printf("optarg : %s\n",optarg);
break;
conf->verbosity = atoi(optarg);
break;
+ case 'b':
+ conf->bindings_file = optarg;
+ break;
case 'd':
conf->dry_run = 1;
break;