diff -Naurd cluster.orig/cman/qdisk/disk.c cluster/cman/qdisk/disk.c --- cluster.orig/cman/qdisk/disk.c 2007-10-29 01:21:40.000000000 -0400 +++ cluster/cman/qdisk/disk.c 2007-11-07 15:29:15.000000000 -0500 @@ -1,5 +1,5 @@ /* - Copyright Red Hat, Inc. 2002-2003, 2006 + Copyright Red Hat, Inc. 2002-2003, 2006-2007 Copyright Mission Critical Linux, 2000 This program is free software; you can redistribute it and/or modify it @@ -760,3 +760,63 @@ return 0; } +int +check_device(char *device, char *label, quorum_header_t *qh) +{ + int fd = -1, ret = -1; + quorum_header_t qh_local; + + if (!qh) + qh = &qh_local; + + fd = qdisk_validate(device); + if (fd < 0) { + perror("qdisk_verify"); + return -1; + } + + fd = qdisk_open(device); + if (fd < 0) { + perror("qdisk_open"); + return -1; + } + + if (qdisk_read(fd, OFFSET_HEADER, qh, sizeof(*qh)) == sizeof(*qh)) { + swab_quorum_header_t(qh); + if (qh->qh_magic == HEADER_MAGIC_NUMBER) { + if (!label || !strcmp(qh->qh_cluster, label)) { + ret = 0; + } + } + } + + qdisk_close(&fd); + + return ret; +} + +void print_qh(char *realdev, quorum_header_t *qh) +{ + time_t timestamp = qh->qh_timestamp; + printf("%s:\n", realdev); + printf("\tMagic: %08x\n", qh->qh_magic); + printf("\tLabel: %s\n", qh->qh_cluster); + printf("\tCreated: %s", + ctime((time_t *)×tamp)); + printf("\tHost: %s\n\n", qh->qh_updatehost); + + return; +} + +int find_partitions(const char *partfile, const char *label, char *devname, size_t devlen, int print) +{ + int ret; + + ret=find_sysfs_partitions("/sys/block", label, devname, devlen, print); + + if ((!ret) || (ret && print)) + return 0; + + return find_proc_partitions(partfile, label, devname, devlen, print); +} + diff -Naurd cluster.orig/cman/qdisk/disk.h cluster/cman/qdisk/disk.h --- cluster.orig/cman/qdisk/disk.h 2007-02-21 15:24:30.000000000 -0500 +++ cluster/cman/qdisk/disk.h 2007-11-07 15:23:12.000000000 -0500 @@ -218,6 +218,8 @@ int qdisk_validate(char *name); int qdisk_read(int fd, __off64_t ofs, void *buf, int len); int qdisk_write(int fd, __off64_t ofs, const void *buf, int len); +int check_device(char *device, char *label, quorum_header_t *qh); +void print_qh(char *realdev, quorum_header_t *qh); #define qdisk_nodeid_offset(nodeid) \ (OFFSET_FIRST_STATUS_BLOCK + (SPACE_PER_STATUS_BLOCK * (nodeid - 1))) @@ -277,9 +279,15 @@ void qd_destroy(qd_ctx *ctx); /* proc.c */ -int find_partitions(const char *partfile, const char *label, +int find_proc_partitions(const char *partfile, const char *label, char *devname, size_t devlen, int print); -int check_device(char *device, char *label, quorum_header_t *qh); +/* sysfs.c */ +int find_sysfs_partitions(const char *partfile, const char *label, + char *devname, size_t devlen, int print); +int sysfs_nodes_init(void); +/* disk.c */ +int find_partitions(const char *partfile, const char *label, + char *devname, size_t devlen, int print); #endif diff -Naurd cluster.orig/cman/qdisk/main.c cluster/cman/qdisk/main.c --- cluster.orig/cman/qdisk/main.c 2007-10-30 00:32:07.000000000 -0400 +++ cluster/cman/qdisk/main.c 2007-11-08 06:47:09.000000000 -0500 @@ -1412,7 +1412,12 @@ printf("QDisk services already running\n"); return 0; } - + + if (sysfs_nodes_init()) { + printf("QDisk was unable to init sysfs nodes\n"); + return 0; + } + while ((rv = getopt(argc, argv, "fdQ")) != EOF) { switch (rv) { case 'd': @@ -1491,6 +1496,7 @@ } if (ctx.qc_label) { + memset(device, 0, sizeof(device)); if (find_partitions("/proc/partitions", ctx.qc_label, device, sizeof(device), 0) != 0) { diff -Naurd cluster.orig/cman/qdisk/Makefile cluster/cman/qdisk/Makefile --- cluster.orig/cman/qdisk/Makefile 2007-08-29 23:16:33.000000000 -0400 +++ cluster/cman/qdisk/Makefile 2007-11-07 15:45:54.000000000 -0500 @@ -36,7 +36,8 @@ SHAREDOBJS= disk.o \ crc32.o \ disk_util.o \ - proc.o + proc.o \ + sysfs.o all: depends ${TARGET1} ${TARGET2} diff -Naurd cluster.orig/cman/qdisk/mkqdisk.c cluster/cman/qdisk/mkqdisk.c --- cluster.orig/cman/qdisk/mkqdisk.c 2006-11-21 09:50:49.000000000 -0500 +++ cluster/cman/qdisk/mkqdisk.c 2007-11-07 15:36:49.000000000 -0500 @@ -39,7 +39,12 @@ char *newdev = NULL, *newlabel = NULL; int rv; - printf("mkqdisk v0.5.1\n"); + printf("mkqdisk v" RELEASE_VERSION "\n"); + + if (sysfs_nodes_init()) { + printf("QDisk was unable to init sysfs nodes\n"); + return 0; + } while ((rv = getopt(argc, argv, "Lf:c:l:h")) != EOF) { switch (rv) { diff -Naurd cluster.orig/cman/qdisk/proc.c cluster/cman/qdisk/proc.c --- cluster.orig/cman/qdisk/proc.c 2007-09-11 08:40:16.000000000 -0400 +++ cluster/cman/qdisk/proc.c 2007-11-07 15:10:11.000000000 -0500 @@ -1,5 +1,5 @@ /** - Copyright Red Hat, Inc. 2006 + Copyright Red Hat, Inc. 2006-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -19,56 +19,16 @@ Author: Lon Hohberger */ /** - @file Quorum disk /proc/partition scanning functions + @file Quorum disk /proc/partition scanning function */ #include -#include -#include #include -#include -#include -#include #include +#include "disk.h" int -check_device(char *device, char *label, quorum_header_t *qh) -{ - int fd = -1, ret = -1; - quorum_header_t qh_local; - - if (!qh) - qh = &qh_local; - - fd = qdisk_validate(device); - if (fd < 0) { - perror("qdisk_verify"); - return -1; - } - - fd = qdisk_open(device); - if (fd < 0) { - perror("qdisk_open"); - return -1; - } - - if (qdisk_read(fd, OFFSET_HEADER, qh, sizeof(*qh)) == sizeof(*qh)) { - swab_quorum_header_t(qh); - if (qh->qh_magic == HEADER_MAGIC_NUMBER) { - if (!label || !strcmp(qh->qh_cluster, label)) { - ret = 0; - } - } - } - - qdisk_close(&fd); - - return ret; -} - - -int -find_partitions(const char *partfile, const char *label, +find_proc_partitions(const char *partfile, const char *label, char *devname, size_t devlen, int print) { char line[4096]; @@ -99,15 +59,8 @@ if (check_device(realdev, (char *)label, &qh) != 0) continue; - if (print) { - time_t timestamp = qh.qh_timestamp; - printf("%s:\n", realdev); - printf("\tMagic: %08x\n", qh.qh_magic); - printf("\tLabel: %s\n", qh.qh_cluster); - printf("\tCreated: %s", - ctime((time_t *)×tamp)); - printf("\tHost: %s\n\n", qh.qh_updatehost); - } + if (print) + print_qh(realdev, &qh); if (devname && devlen) { /* Got it */ diff -Naurd cluster.orig/cman/qdisk/sysfs.c cluster/cman/qdisk/sysfs.c --- cluster.orig/cman/qdisk/sysfs.c 1969-12-31 19:00:00.000000000 -0500 +++ cluster/cman/qdisk/sysfs.c 2007-11-08 06:52:24.000000000 -0500 @@ -0,0 +1,192 @@ +/** + Copyright Red Hat, Inc. 2007 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + MA 02139, USA. + + Author: Fabio M. Di Nitto + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "disk.h" + +#define DEVPATH "/dev/.qdiskd" + +int sysfs_nodes_init(void) +{ + DIR *dir; + struct dirent *de; + struct stat sb; + int flushme; + mode_t oldumask; + char *fn; + char path[256]; + + if (stat(DEVPATH, &sb)) { + if (errno != ENOENT) { + printf("ERROR: Unable to access " DEVPATH ". Please clean up manually\n"); + return -1; + } + flushme=0; + oldumask=umask(0); + if (mkdir(DEVPATH, S_IRWXU)) { + printf("ERROR: Unable to create " DEVPATH ". Please make sure to have permissions to create the directory\n"); + return -1; + } + umask(oldumask); + } else { + if (!S_ISDIR(sb.st_mode)) { + printf("ERROR: " DEVPATH " is not a directory. Please check and remove manually before running qdiskd\n"); + return -1; + } + flushme=1; + } + + /* at this point DEVPATH is either there or created and it is a directory */ + dir = opendir(DEVPATH); + + /* remove possible stale nodes */ + if (flushme) { + while ((de = readdir(dir))) { + fn = basename(de->d_name); + if (!fn) + continue; + + /* if the filename has our *cough*magic*cough* label + * we kill it. + */ + if (strstr(fn, "qdisk")) { + + snprintf(path, sizeof(path), DEVPATH "/%s", de->d_name); + + if (stat(path, &sb)) + continue; + + if (!S_ISBLK(sb.st_mode)) + continue; + + if (unlink(path)) { + printf("WARNING: Unable to unlink %s\n", path); + } + } + } + } + + closedir(dir); + + return 0; +} + +/* given a syspath, create a block device node. + * return a path to the created device or null on error. Remember to free the result. + */ +static char *create_node(char *sysfspath) +{ + char *node; + FILE *fd; + mode_t oldumask; + int major, minor, err; + dev_t device; + + node=malloc(256); + if (!node) + return node; + + fd = fopen(sysfspath, "r"); + if (!fd) { + printf("ERROR: Unable to open %s\n", sysfspath); + return NULL; + } else { + /* get the maj/min from sysfs */ + fscanf(fd, "%4d:%4d", &major, &minor); + fclose(fd); + device=makedev(major, minor); + snprintf(node, 256, DEVPATH "/qdisk-%d-%d", major, minor); + oldumask=umask(0); + err=mknod(node, S_IFBLK | S_IRUSR | S_IWUSR, device); + umask(oldumask); + if (!err) + return node; + } + + return NULL; +} + +int +find_sysfs_partitions(const char *partfile, const char *label, + char *devname, size_t devlen, int print) +{ + struct dirent **namelist; + struct stat sb; + char newpath[256]; + char *node; + int n; + quorum_header_t qh; + + n = scandir(partfile, &namelist, 0, alphasort); + if (n <= 0) + return -1; + + while (n--) { + /* filter out .. and . */ + if (strcmp(namelist[n]->d_name, ".") && strcmp(namelist[n]->d_name, "..")) { + snprintf(newpath, sizeof(newpath), "%s/%s", partfile, namelist[n]->d_name); + if (!lstat(newpath, &sb)) { + /* dive into directories */ + if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) { + if (!find_sysfs_partitions(newpath, label, devname, devlen, print)) { + if (devname && (strlen(devname) > 0)) + return 0; + } + } + /* check regular files (dev) */ + if (S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode)) { + if (!strcmp(namelist[n]->d_name, "dev")) { + node=create_node(newpath); + if (node) { + if (!check_device(node, (char *)label, &qh)) { + if (print) + print_qh(node, &qh); + + if (devname && devlen) { + strncpy(devname, node, devlen); + free(node); + return 0; + } + } + unlink(node); + free(node); + } + } + } + } + } + free(namelist[n]); + } + + errno = ENOENT; + return -1; +}