[Cluster-devel] cluster/gnbd bin/Makefile tools/gnbd_export/Ma ...

bmarzins at sourceware.org bmarzins at sourceware.org
Mon Jun 26 17:29:33 UTC 2006


CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	bmarzins at sourceware.org	2006-06-26 17:29:32

Modified files:
	gnbd/bin       : Makefile 
	gnbd/tools/gnbd_export: Makefile gnbd_export.c 
	gnbd/tools/gnbd_import: gnbd_import.c 
Added files:
	gnbd/tools/gnbd_export: gnbd_get_uid 

Log message:
	fixing dm-multipath support for GNBD

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gnbd/bin/Makefile.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gnbd/tools/gnbd_export/gnbd_get_uid.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gnbd/tools/gnbd_export/Makefile.diff?cvsroot=cluster&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gnbd/tools/gnbd_export/gnbd_export.c.diff?cvsroot=cluster&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gnbd/tools/gnbd_import/gnbd_import.c.diff?cvsroot=cluster&r1=1.16&r2=1.17

--- cluster/gnbd/bin/Makefile	2004/06/25 17:12:19	1.2
+++ cluster/gnbd/bin/Makefile	2006/06/26 17:29:31	1.3
@@ -22,7 +22,8 @@
 	gnbd_recvd \
 	gnbd_serv \
 	gnbd_monitor \
-	gnbd_clusterd
+	gnbd_clusterd \
+	gnbd_get_uid
 
 include ${top_srcdir}/make/defines.mk
 
--- cluster/gnbd/tools/gnbd_export/gnbd_get_uid	2006/06/23 20:15:30	1.1
+++ cluster/gnbd/tools/gnbd_export/gnbd_get_uid	2006/06/26 17:29:31	1.2
@@ -0,0 +1,10 @@
+#!/bin/sh
+set -e
+
+base_uid=`/sbin/scsi_id -g -u -s /block/$1 2> /dev/null`
+if echo $1 | grep -q '^.*\/[^0-9]*[0-9]*$' > /dev/null 2>&1 ; then
+	part=`echo $1 | sed 's/^.*\/[^0-9]*\([0-9]*\)$/\1/'`
+	echo GNBD-${part}-${base_uid}
+else
+	echo GNBD--${base_uid}
+fi
--- cluster/gnbd/tools/gnbd_export/Makefile	2006/06/26 17:27:51	1.8
+++ cluster/gnbd/tools/gnbd_export/Makefile	2006/06/26 17:29:31	1.9
@@ -33,8 +33,9 @@
 gnbd_export: ${SOURCE}
 	${CC} ${CFLAGS} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@
 
-copytobin: all
+copytobin: all gnbd_get_uid
 	cp ${TARGET} ${top_srcdir}/bin
+	cp gnbd_get_uid ${top_srcdir}/bin
 
 clean:
 	rm -f *.o ${TARGET}
--- cluster/gnbd/tools/gnbd_export/gnbd_export.c	2006/06/26 17:27:51	1.9
+++ cluster/gnbd/tools/gnbd_export/gnbd_export.c	2006/06/26 17:29:31	1.10
@@ -40,7 +40,7 @@
 #define TIMEOUT_DEFAULT 60
 
 #define MAN_MSG "Please see man page for details.\n"
-#define DEFAULT_GETUID "/sbin/scsi_id -g -u -s /block/%n"
+#define DEFAULT_GETUID "/sbin/gnbd_get_uid %n"
 
 int start_gnbd_clusterd(void)
 {
@@ -313,7 +313,8 @@
       printf("   timeout : %u\n", info->timeout);
     else
       printf("   timeout : no\n");
-    printf("       uid : %s\n", info->uid);
+    if (info->uid[0] != '\0')
+      printf("       uid : %s\n", info->uid);
     printf("\n");
     info++;
   }
@@ -341,54 +342,102 @@
   *minor = minor(stat_buf.st_rdev);
 }
 
+char *get_sysfs_info(char *path) {
+  int fd;
+  int bytes;
+  int count = 0;
+
+  if ((fd = open(path, O_RDONLY)) < 0) {
+    printe("cannot open %s : %s\n", path, strerror(errno));
+    exit(1);
+  }
+  while (count < 4096) {
+    bytes = read(fd, &sysfs_buf[count], 4096 - count);
+    if (bytes < 0 && errno != EINTR) {
+      printe("cannot read from %s : %s\n", path, strerror(errno));
+      exit(1);
+    }
+    if (bytes == 0)
+      break;
+    count += bytes;
+  }
+  if (sysfs_buf[count - 1] == '\n' || count == 4096)
+    sysfs_buf[count - 1] = '\0';
+  else
+    sysfs_buf[count] = '\0';
+  close(fd);
+  return sysfs_buf;
+}
+    
 #define SYSFS_PATH_MAX 64
 #define SYSFS_PATH_BASE "/sys/block"
 #define SYSFS_PATH_BASE_SIZE 10
-char *get_sysfs_name(char *dev_t){
+int get_sysfs_majmin(char *dev, int *major, int *minor)
+{
   char path[SYSFS_PATH_MAX];
+  char *buf;
+
+  if (snprintf(path, SYSFS_PATH_MAX, "%s/%s/dev", SYSFS_PATH_BASE, dev) >=
+      SYSFS_PATH_MAX) {
+    printe("sysfs path name '%s/%s/dev' too long\n", SYSFS_PATH_BASE, dev);
+    exit(1);
+  }
+  buf = get_sysfs_info(path);
+  if (sscanf(buf, "%u:%u", major, minor) != 2){
+    printe("cannot parse %s entry '%s'\n", path, buf);
+    exit(1);
+  }
+  return 0;
+}
+
+int get_sysfs_range(char *dev, int *range)
+{
+  char path[SYSFS_PATH_MAX];
+  char *buf;
+
+  if (snprintf(path, SYSFS_PATH_MAX, "%s/%s/range", SYSFS_PATH_BASE, dev) >=
+      SYSFS_PATH_MAX) {
+    printe("sysfs path name '%s/%s/range' too long\n", SYSFS_PATH_BASE, dev);
+    exit(1);
+  }
+  buf = get_sysfs_info(path);
+  if (sscanf(buf, "%u", range) != 1){
+    printe("cannot parse %s etnry '%s'\n", path, buf);
+    exit(1);
+  }
+  return 0;
+}
+
+char *get_sysfs_name(int major, int minor){
   char *name = NULL;
   DIR *dir;
   struct dirent *dp;
 
-  memset(path, 0, sizeof(path));
-  strcpy(path, SYSFS_PATH_BASE);
-  dir = opendir(path);
+  dir = opendir(SYSFS_PATH_BASE);
   if (!dir) {
-    printe("cannot open /sys/block to find the device name for %s : %s\n",
-           dev_t, strerror(errno));
+    printe("cannot open %s to find the device name for %d:%d : %s\n",
+           SYSFS_PATH_BASE, major, minor, strerror(errno));
     exit(1);
   }
   while ((dp = readdir(dir))) {
-    int fd;
-    int bytes;
-    int count = 0;
-
+    int dev_major, dev_minor, dev_range;
     if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
       continue;
-    snprintf(path + SYSFS_PATH_BASE_SIZE,
-	     SYSFS_PATH_MAX - SYSFS_PATH_BASE_SIZE - 1, "/%s/dev", dp->d_name);
-    fd = open(path, O_RDONLY);
-    if (fd < 0) {
-      printe("cannot open %s to find device name for %s : %s\n", path, dev_t,
-             strerror(errno));
-      exit(1);
-    }
-    while (count < 4096){
-      bytes = read(fd, &sysfs_buf[count], 4096 - count);
-      if (bytes < 0 && errno != EINTR) {
-        printe("cannot read from %s: %s\n", path, strerror(errno));
-        exit(1);
+    get_sysfs_majmin(dp->d_name, &dev_major, &dev_minor);
+    get_sysfs_range(dp->d_name, &dev_range);
+    if (major == dev_major && minor >= dev_minor &&
+        minor < dev_minor + dev_range){
+      if (minor == dev_minor)
+        name = strdup(dp->d_name);
+      else {
+        name = malloc(SYSFS_PATH_MAX);
+        if (!name){
+          printe("cannot allocate memory for sysfs name : %s\n",
+                 strerror(errno));
+          exit(1);
+        }
+        sprintf(name, "%s/%s%d", dp->d_name, dp->d_name, minor - dev_minor);
       }
-      if (bytes == 0)
-         break;
-      count += bytes;
-    }
-    if (count == 4096)
-      sysfs_buf[4095] = 0;
-    else
-      sysfs_buf[count] = 0;
-    if (strcmp(dev_t, sysfs_buf) == 0){
-      name = strdup(dp->d_name);
       break;
     }
   }
@@ -397,7 +446,7 @@
     exit(1);
   }
   if (!name) {
-    printe("cannot find sysfs block device %s\n", dev_t);
+    printe("cannot find sysfs block device %d:%d\n", major, minor);
     exit(1);
   }
   return name;
@@ -569,8 +618,7 @@
         if (!name){
           if (major == -1)
             get_dev(path, &major, &minor);
-          sprintf(temp, "%d:%d\n", major, minor);
-          name = get_sysfs_name(temp);
+          name = get_sysfs_name(major, minor);
         }
         len = strlen(name);
         if (len > SPACE_LEFT){
@@ -627,7 +675,7 @@
 "  -u <uid>         manually set the Unique ID of a device (used with -e)\n"
 "  -U[command]      command to get the Unique ID of a device (used with -e)\n"
 "                   If no command is specificed, the default is\n"
-"                   \"/sbin/scsi_id -g -u -s /block/%%n\"\n"
+"                   \"/sbin/gnbd_get_uid %%n\"\n"
 "  -v               verbose output (useful with -l)\n"
 "  -V               version information\n");
   return 0;
--- cluster/gnbd/tools/gnbd_import/gnbd_import.c	2006/03/17 20:13:36	1.16
+++ cluster/gnbd/tools/gnbd_import/gnbd_import.c	2006/06/26 17:29:31	1.17
@@ -101,9 +101,10 @@
                      ssize_t request_data_size)
 {
   int sock_fd;
-  int n, total;
+  int n, total = 0;
   uint32_t msg;
 
+  *buf = NULL;
   sock_fd = connect_to_server(host, (uint16_t)server_port);
   if (sock_fd < 0){
     printe("cannot connect to server %s (%d) : %s\n", host, sock_fd,
@@ -136,13 +137,14 @@
     exit(1);
   }
   msg = be32_to_cpu(msg);
+  if (!msg)
+    goto exit;
   *buf = malloc(msg);
   if (*buf == NULL){
     printe("couldn't allocate memory for server reply : %s\n", strerror(errno));
     exit(1);
   }
   memset(*buf, 0, msg);
-  total = 0;
   while(total < msg){
     n = read(sock_fd, *buf + total, msg - total);
     if (n <= 0){
@@ -152,6 +154,7 @@
     }
     total += n;
   }
+exit:
   close(sock_fd);
   return total;
 }
@@ -170,6 +173,10 @@
     return 0;
 
   read_from_server(host, EXTERN_NODENAME_REQ, &serv_node);
+  if (!serv_node) {
+    printe("got empty server name\n");
+    return -1;
+  }
 
   snprintf(cmd, 256, "gnbd_monitor %d %d %s", minor_nr, timeout, serv_node);
   ret = system(cmd);
@@ -569,6 +576,46 @@
   }
 }
 
+
+#define MULTIPATH_SCRIPT "/etc/dev.d/block/multipath.dev"
+void run_multipath_code(int minor_nr, int add)
+{
+  int i_am_parent, fd;
+  char *envp[6];
+  char devpath[32];
+  char devname[32];
+
+  i_am_parent = daemonize();
+  if (i_am_parent < 0){
+    printm("cannot daemonize to exec multipath code : %s\n", strerror(errno));	
+    return;
+  }
+  if (i_am_parent)
+    return;
+  if ((fd = open("/dev/null", O_RDWR)) < 0) {
+    printm("cannot open /dev/null in daemon : %s\n", strerror(errno));
+    exit(1);
+  }
+  dup2(fd, 0);
+  dup2(fd, 1);
+  dup2(fd, 2);
+  if (fd > 2)
+    close(fd);
+  envp[0] = "HOME=/";
+  envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+  envp[2] = (add)? "ACTION=add" : "ACTION=remove";
+  snprintf(devpath, 31, "DEVPATH=/block/gnbd%d", minor_nr);
+  devpath[31] = '\0';
+  envp[3] = devpath;
+  snprintf(devname, 31, "DEVNAME=/dev/gnbd%d", minor_nr);
+  devname[31] = '\0';
+  envp[4] = devname;
+  envp[5] = NULL;
+  execle(MULTIPATH_SCRIPT, MULTIPATH_SCRIPT, NULL, envp);
+  log_verbose("cannot exec %s : %s", MULTIPATH_SCRIPT, strerror(errno));
+  exit(1);
+}
+
 void remove_gnbd(char *name, int minor, int pid)
 {
   int fd;
@@ -595,6 +642,7 @@
   if (pid > 0)
   	kill(pid, SIGKILL);
   cleanup_device(name, minor, fd);
+  run_multipath_code(minor, 0);
   close(fd);
 }
 
@@ -980,6 +1028,8 @@
   int size;
   int minor_nr;
   size = read_from_server(host, EXTERN_NAMES_REQ, &buf);
+  if (!size)
+    return;
   ptr = (import_info_t *)buf;
   while ((char *)ptr < buf + size){
     if (ptr->timeout != 0 && is_clustered == 0){
@@ -992,6 +1042,7 @@
         exit(1);
       if (start_receiver(minor_nr))
         exit(1);
+      run_multipath_code(minor_nr, 1);
     }
     ptr++;
   }
@@ -1003,10 +1054,12 @@
   import_info_t *ptr;
   int size;
   size = read_from_server(host, EXTERN_NAMES_REQ, &buf);
-  ptr = (import_info_t *)buf;
-  while ((char *)ptr < buf + size){
-    printf("%s\n", ptr->name);
-    ptr++;
+  if (size) {
+    ptr = (import_info_t *)buf;
+    while ((char *)ptr < buf + size){
+      printf("%s\n", ptr->name);
+      ptr++;
+    }
   }
   printf("\n");
   free(buf);
@@ -1018,10 +1071,12 @@
   node_req_t *ptr;
   int size;
   size = read_from_server(host, EXTERN_LIST_BANNED_REQ, &buf);
-  ptr = (node_req_t *)buf;
-  while ((char *)ptr < buf + size){
-    printf("%s\n", ptr->node_name);
-    ptr++;
+  if (size) {
+    ptr = (node_req_t *)buf;
+    while ((char *)ptr < buf + size){
+      printf("%s\n", ptr->node_name);
+      ptr++;
+    }
   }
   printf("\n");
   free(buf);
@@ -1067,7 +1122,7 @@
   sscanf(name, "/block/gnbd%d", &minor_nr);
   list_foreach(item, &gnbd_list){
     gnbd = list_entry(item, gnbd_info_t, list);
-    if (minor_nr >= 0 && minor_nr == gnbd->minor_nr);
+    if (minor_nr >= 0 && minor_nr == gnbd->minor_nr)
       break;
     if (strncmp(gnbd->name, name, 32) == 0)
       break;
@@ -1080,7 +1135,8 @@
   strncpy(req.name, gnbd->name, 32);
   req.name[31] = 0;
   talk_to_server(gnbd->server_name, EXTERN_UID_REQ, &uid, &req, sizeof(req));
-  printf("%s\n", uid);
+  if (uid)
+  	printf("%s\n", uid);
   free(uid);
 }
   




More information about the Cluster-devel mailing list