From mboxrd@z Thu Jan 1 00:00:00 1970 From: bmarzins@sourceware.org Date: 26 Jun 2006 17:29:33 -0000 Subject: [Cluster-devel] cluster/gnbd bin/Makefile tools/gnbd_export/Ma ... Message-ID: <20060626172933.22528.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 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); }