* [Cluster-devel] cluster/cman/qdisk Makefile README disk.c disk ...
@ 2006-06-23 16:01 lhh
0 siblings, 0 replies; 3+ messages in thread
From: lhh @ 2006-06-23 16:01 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: cluster
Branch: RHEL4
Changes by: lhh at sourceware.org 2006-06-23 16:01:02
Modified files:
cman/qdisk : Makefile README disk.c disk.h main.c
Added files:
cman/qdisk : mkqdisk.c proc.c
Log message:
Implements 'label' support for qdisk. Uses /proc/partitions for device
info & scans devices for signatures. Useful in environments where a
device is present but maybe numbered differently on different nodes
depending on the host/SAN configuration.
Also adds initialization utility which must be run before qdiskd will
use a given partition.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/mkqdisk.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/proc.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.2.1&r2=1.1.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/README.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.2.1&r2=1.1.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/disk.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.2.2&r2=1.1.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/disk.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.2.1&r2=1.1.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/main.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.2.1&r2=1.1.2.2
--- cluster/cman/qdisk/Makefile 2006/05/18 14:52:49 1.1.2.1
+++ cluster/cman/qdisk/Makefile 2006/06/23 16:01:02 1.1.2.2
@@ -19,26 +19,31 @@
CFLAGS +=-I${incdir} -I${top_srcdir}/config \
-Wall -Werror -Wstrict-prototypes -Wshadow -D_GNU_SOURCE -g
-TARGET=qdiskd
+TARGET=qdiskd mkqdisk
all: ${TARGET}
copytobin: all
cp ${TARGET} ${top_srcdir}/bin
-install: qdiskd
+install: ${TARGET}
install -d ${sbindir}
- install qdiskd ${sbindir}
+ install ${TARGET} ${sbindir}
qdiskd: disk.o crc32.o disk_util.o main.o score.o bitmap.o clulog.o \
- gettid.o ../lib/libcman.a
+ gettid.o proc.o ../lib/libcman.a
gcc -o $@ $^ -lpthread -L../lib -lccs
+mkqdisk: disk.o crc32.o disk_util.o \
+ proc.o mkqdisk.o
+ gcc -o $@ $^
+
+
%.o: %.c
$(CC) -c -o $@ $^ $(INCLUDES) $(CFLAGS)
clean:
- rm -f *.o qdiskd
+ rm -f *.o ${TARGET}
uninstall:
- ${UNINSTALL} qdiskd ${sbindir}
+ ${UNINSTALL} ${TARGET} ${sbindir}
--- cluster/cman/qdisk/README 2006/05/18 14:52:49 1.1.2.1
+++ cluster/cman/qdisk/README 2006/06/23 16:01:02 1.1.2.2
@@ -213,8 +213,16 @@
min_score="3" Absolute minimum score to be consider one's
self "alive". If omitted, or set to 0, the
default function "floor((n+1)/2)" is used.
- device="/dev/sda1"/> This is the device the quorum daemon will use.
+ device="/dev/sda1" This is the device the quorum daemon will use.
This device must be the same on all nodes.
+ label="mylabel"/> This overrides the device field if present.
+ If specified, the quorum daemon will read
+ /proc/partitions and check for qdisk signatures
+ on every block device found, comparing the label
+ against the specified label. This is useful in
+ configurations where the block device name
+ differs on a per-node basis.
+
3.2. The <heuristic> tag
@@ -249,3 +257,18 @@
* The worst-case for improperly configured quorum heuristics is a race
to fence where two partitions simultaneously try to kill each other.
+3.5. Creating a quorum disk partition
+
+3.5.1. The mkqdisk utility.
+
+The mkqdisk utility can create and list currently configured quorum disks
+visible to the local node.
+
+ mkqdisk -L List available quorum disks.
+
+ mkqdisk -f <label> Find a quorum device by the given label.
+
+ mkqdisk -c <device> -l <label>
+ Initialize <device> and name it <label>. This
+ will destroy all data on the device, so be careful
+ when running this command.
--- cluster/cman/qdisk/disk.c 2006/05/22 17:32:42 1.1.2.2
+++ cluster/cman/qdisk/disk.c 2006/06/23 16:01:02 1.1.2.3
@@ -336,7 +336,8 @@
"diskRawReadShadow: can't seek to offset %d.\n",
(int) readOffset);
#endif
- return ENODATA;
+ errno = ENODATA;
+ return -1;
}
ret = diskRawRead(fd, buf, len);
@@ -345,7 +346,8 @@
fprintf(stderr, "diskRawReadShadow: aligned read "
"returned %d, not %d.\n", ret, len);
#endif
- return ENODATA;
+ errno = ENODATA;
+ return -1;
}
/* Decode the header portion so we can run a checksum on it. */
@@ -360,7 +362,8 @@
"fd = %d offset = %d len = %d\n", fd,
(int) readOffset, len);
#endif
- return EPROTO;
+ errno = EPROTO;
+ return -1;
}
return 0;
@@ -655,7 +658,7 @@
static int
-header_init(int fd, char *clustername)
+header_init(int fd, char *label)
{
quorum_header_t qh;
@@ -675,6 +678,9 @@
return -1;
}
+ /* Copy in the cluster/label name */
+ snprintf(qh.qh_cluster, sizeof(qh.qh_cluster)-1, label);
+
if ((qh.qh_timestamp = (uint64_t)time(NULL)) <= 0) {
perror("time");
return -1;
@@ -691,7 +697,7 @@
int
-qdisk_init(char *partname, char *clustername)
+qdisk_init(char *partname, char *label)
{
int fd;
status_block_t ps, wps;
@@ -710,7 +716,7 @@
return -1;
}
- if (header_init(fd, clustername) < 0) {
+ if (header_init(fd, label) < 0) {
return -1;
}
--- cluster/cman/qdisk/disk.h 2006/05/18 14:52:49 1.1.2.1
+++ cluster/cman/qdisk/disk.h 2006/06/23 16:01:02 1.1.2.2
@@ -238,6 +238,7 @@
int qc_unused;
cman_handle_t qc_ch;
char *qc_device;
+ char *qc_label;
char *qc_status_file;
} qd_ctx;
@@ -259,4 +260,10 @@
int qd_init(qd_ctx *ctx, cman_handle_t ch, int me);
void qd_destroy(qd_ctx *ctx);
+/* proc.c */
+int find_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);
+
+
#endif
--- cluster/cman/qdisk/main.c 2006/05/18 14:52:49 1.1.2.1
+++ cluster/cman/qdisk/main.c 2006/06/23 16:01:02 1.1.2.2
@@ -880,6 +880,12 @@
ctx->qc_device = val;
}
+ /* Get label (overrides device) */
+ snprintf(query, sizeof(query), "/cluster/quorumd/@label");
+ if (ccs_get(ccsfd, query, &val) == 0) {
+ ctx->qc_label = val;
+ }
+
/* Get status file */
snprintf(query, sizeof(query), "/cluster/quorumd/@status_file");
if (ccs_get(ccsfd, query, &val) == 0) {
@@ -917,6 +923,7 @@
node_info_t ni[MAX_NODES_DISK];
struct h_data h[10];
char debug = 0, foreground = 0;
+ char device[128];
while ((rv = getopt(argc, argv, "fd")) != EOF) {
switch (rv) {
@@ -958,6 +965,32 @@
return -1;
}
+ if (ctx.qc_label) {
+ if (find_partitions("/proc/partitions",
+ ctx.qc_label, device,
+ sizeof(device), 0) != 0) {
+ clulog_and_print(LOG_CRIT, "Unable to match label"
+ " '%s' to any device\n",
+ ctx.qc_label);
+ return -1;
+ }
+
+ if (ctx.qc_device)
+ free(ctx.qc_device);
+
+ ctx.qc_device = strdup(device);
+
+ clulog(LOG_INFO, "Quorum Partition: %s Label: %s\n",
+ ctx.qc_device, ctx.qc_label);
+ } else if (ctx.qc_device) {
+ if (check_device(ctx.qc_device, NULL, NULL) != 0) {
+ clulog(LOG_CRIT,
+ "Specified partition %s does not have a "
+ "qdisk label\n", ctx.qc_device);
+ return -1;
+ }
+ }
+
if (!foreground)
daemon(0,0);
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Cluster-devel] cluster/cman/qdisk Makefile README disk.c disk ...
@ 2006-06-23 16:02 lhh
0 siblings, 0 replies; 3+ messages in thread
From: lhh @ 2006-06-23 16:02 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: cluster
Branch: RHEL4U4
Changes by: lhh at sourceware.org 2006-06-23 16:02:01
Modified files:
cman/qdisk : Makefile README disk.c disk.h main.c
Added files:
cman/qdisk : mkqdisk.c proc.c
Log message:
Implements 'label' support for qdisk. Uses /proc/partitions for device
info & scans devices for signatures. Useful in environments where a
device is present but maybe numbered differently on different nodes
depending on the host/SAN configuration.
Also adds initialization utility which must be run before qdiskd will
use a given partition.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/mkqdisk.c.diff?cvsroot=cluster&only_with_tag=RHEL4U4&r1=NONE&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/proc.c.diff?cvsroot=cluster&only_with_tag=RHEL4U4&r1=NONE&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL4U4&r1=1.1.2.1&r2=1.1.2.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/README.diff?cvsroot=cluster&only_with_tag=RHEL4U4&r1=1.1.2.1&r2=1.1.2.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/disk.c.diff?cvsroot=cluster&only_with_tag=RHEL4U4&r1=1.1.2.2&r2=1.1.2.2.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/disk.h.diff?cvsroot=cluster&only_with_tag=RHEL4U4&r1=1.1.2.1&r2=1.1.2.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/main.c.diff?cvsroot=cluster&only_with_tag=RHEL4U4&r1=1.1.2.1&r2=1.1.2.1.2.1
--- cluster/cman/qdisk/Makefile 2006/05/18 14:52:49 1.1.2.1
+++ cluster/cman/qdisk/Makefile 2006/06/23 16:02:01 1.1.2.1.2.1
@@ -19,26 +19,31 @@
CFLAGS +=-I${incdir} -I${top_srcdir}/config \
-Wall -Werror -Wstrict-prototypes -Wshadow -D_GNU_SOURCE -g
-TARGET=qdiskd
+TARGET=qdiskd mkqdisk
all: ${TARGET}
copytobin: all
cp ${TARGET} ${top_srcdir}/bin
-install: qdiskd
+install: ${TARGET}
install -d ${sbindir}
- install qdiskd ${sbindir}
+ install ${TARGET} ${sbindir}
qdiskd: disk.o crc32.o disk_util.o main.o score.o bitmap.o clulog.o \
- gettid.o ../lib/libcman.a
+ gettid.o proc.o ../lib/libcman.a
gcc -o $@ $^ -lpthread -L../lib -lccs
+mkqdisk: disk.o crc32.o disk_util.o \
+ proc.o mkqdisk.o
+ gcc -o $@ $^
+
+
%.o: %.c
$(CC) -c -o $@ $^ $(INCLUDES) $(CFLAGS)
clean:
- rm -f *.o qdiskd
+ rm -f *.o ${TARGET}
uninstall:
- ${UNINSTALL} qdiskd ${sbindir}
+ ${UNINSTALL} ${TARGET} ${sbindir}
--- cluster/cman/qdisk/README 2006/05/18 14:52:49 1.1.2.1
+++ cluster/cman/qdisk/README 2006/06/23 16:02:01 1.1.2.1.2.1
@@ -213,8 +213,16 @@
min_score="3" Absolute minimum score to be consider one's
self "alive". If omitted, or set to 0, the
default function "floor((n+1)/2)" is used.
- device="/dev/sda1"/> This is the device the quorum daemon will use.
+ device="/dev/sda1" This is the device the quorum daemon will use.
This device must be the same on all nodes.
+ label="mylabel"/> This overrides the device field if present.
+ If specified, the quorum daemon will read
+ /proc/partitions and check for qdisk signatures
+ on every block device found, comparing the label
+ against the specified label. This is useful in
+ configurations where the block device name
+ differs on a per-node basis.
+
3.2. The <heuristic> tag
@@ -249,3 +257,18 @@
* The worst-case for improperly configured quorum heuristics is a race
to fence where two partitions simultaneously try to kill each other.
+3.5. Creating a quorum disk partition
+
+3.5.1. The mkqdisk utility.
+
+The mkqdisk utility can create and list currently configured quorum disks
+visible to the local node.
+
+ mkqdisk -L List available quorum disks.
+
+ mkqdisk -f <label> Find a quorum device by the given label.
+
+ mkqdisk -c <device> -l <label>
+ Initialize <device> and name it <label>. This
+ will destroy all data on the device, so be careful
+ when running this command.
--- cluster/cman/qdisk/disk.c 2006/05/22 17:32:42 1.1.2.2
+++ cluster/cman/qdisk/disk.c 2006/06/23 16:02:01 1.1.2.2.2.1
@@ -336,7 +336,8 @@
"diskRawReadShadow: can't seek to offset %d.\n",
(int) readOffset);
#endif
- return ENODATA;
+ errno = ENODATA;
+ return -1;
}
ret = diskRawRead(fd, buf, len);
@@ -345,7 +346,8 @@
fprintf(stderr, "diskRawReadShadow: aligned read "
"returned %d, not %d.\n", ret, len);
#endif
- return ENODATA;
+ errno = ENODATA;
+ return -1;
}
/* Decode the header portion so we can run a checksum on it. */
@@ -360,7 +362,8 @@
"fd = %d offset = %d len = %d\n", fd,
(int) readOffset, len);
#endif
- return EPROTO;
+ errno = EPROTO;
+ return -1;
}
return 0;
@@ -655,7 +658,7 @@
static int
-header_init(int fd, char *clustername)
+header_init(int fd, char *label)
{
quorum_header_t qh;
@@ -675,6 +678,9 @@
return -1;
}
+ /* Copy in the cluster/label name */
+ snprintf(qh.qh_cluster, sizeof(qh.qh_cluster)-1, label);
+
if ((qh.qh_timestamp = (uint64_t)time(NULL)) <= 0) {
perror("time");
return -1;
@@ -691,7 +697,7 @@
int
-qdisk_init(char *partname, char *clustername)
+qdisk_init(char *partname, char *label)
{
int fd;
status_block_t ps, wps;
@@ -710,7 +716,7 @@
return -1;
}
- if (header_init(fd, clustername) < 0) {
+ if (header_init(fd, label) < 0) {
return -1;
}
--- cluster/cman/qdisk/disk.h 2006/05/18 14:52:49 1.1.2.1
+++ cluster/cman/qdisk/disk.h 2006/06/23 16:02:01 1.1.2.1.2.1
@@ -238,6 +238,7 @@
int qc_unused;
cman_handle_t qc_ch;
char *qc_device;
+ char *qc_label;
char *qc_status_file;
} qd_ctx;
@@ -259,4 +260,10 @@
int qd_init(qd_ctx *ctx, cman_handle_t ch, int me);
void qd_destroy(qd_ctx *ctx);
+/* proc.c */
+int find_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);
+
+
#endif
--- cluster/cman/qdisk/main.c 2006/05/18 14:52:49 1.1.2.1
+++ cluster/cman/qdisk/main.c 2006/06/23 16:02:01 1.1.2.1.2.1
@@ -880,6 +880,12 @@
ctx->qc_device = val;
}
+ /* Get label (overrides device) */
+ snprintf(query, sizeof(query), "/cluster/quorumd/@label");
+ if (ccs_get(ccsfd, query, &val) == 0) {
+ ctx->qc_label = val;
+ }
+
/* Get status file */
snprintf(query, sizeof(query), "/cluster/quorumd/@status_file");
if (ccs_get(ccsfd, query, &val) == 0) {
@@ -917,6 +923,7 @@
node_info_t ni[MAX_NODES_DISK];
struct h_data h[10];
char debug = 0, foreground = 0;
+ char device[128];
while ((rv = getopt(argc, argv, "fd")) != EOF) {
switch (rv) {
@@ -958,6 +965,32 @@
return -1;
}
+ if (ctx.qc_label) {
+ if (find_partitions("/proc/partitions",
+ ctx.qc_label, device,
+ sizeof(device), 0) != 0) {
+ clulog_and_print(LOG_CRIT, "Unable to match label"
+ " '%s' to any device\n",
+ ctx.qc_label);
+ return -1;
+ }
+
+ if (ctx.qc_device)
+ free(ctx.qc_device);
+
+ ctx.qc_device = strdup(device);
+
+ clulog(LOG_INFO, "Quorum Partition: %s Label: %s\n",
+ ctx.qc_device, ctx.qc_label);
+ } else if (ctx.qc_device) {
+ if (check_device(ctx.qc_device, NULL, NULL) != 0) {
+ clulog(LOG_CRIT,
+ "Specified partition %s does not have a "
+ "qdisk label\n", ctx.qc_device);
+ return -1;
+ }
+ }
+
if (!foreground)
daemon(0,0);
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Cluster-devel] cluster/cman/qdisk Makefile README disk.c disk ...
@ 2006-06-23 16:05 lhh
0 siblings, 0 replies; 3+ messages in thread
From: lhh @ 2006-06-23 16:05 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: cluster
Changes by: lhh at sourceware.org 2006-06-23 16:05:34
Modified files:
cman/qdisk : Makefile README disk.c disk.h main.c
Added files:
cman/qdisk : mkqdisk.c proc.c
Log message:
Implements 'label' support for qdisk. Uses /proc/partitions for device
info & scans devices for signatures. Useful in environments where a
device is present but maybe numbered differently on different nodes
depending on the host/SAN configuration.
Also adds initialization utility which must be run before qdiskd will
use a given partition.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/mkqdisk.c.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/proc.c.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/Makefile.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/README.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/disk.c.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/disk.h.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/qdisk/main.c.diff?cvsroot=cluster&r1=1.2&r2=1.3
--- cluster/cman/qdisk/mkqdisk.c 2006/06/23 16:01:02 1.1
+++ cluster/cman/qdisk/mkqdisk.c 2006/06/23 16:05:33 1.2
@@ -0,0 +1,92 @@
+/**
+ Copyright Red Hat, Inc. 2006
+
+ 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: Lon Hohberger <lhh@redhat.com>
+ */
+/**
+ @file Quorum disk utility
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <disk.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <platform.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+int
+main(int argc, char **argv)
+{
+ char device[128];
+ char *newdev = NULL, *newlabel = NULL;
+ int rv;
+
+ printf("mkqdisk v0.5\n");
+
+ while ((rv = getopt(argc, argv, "Lfc:l:h")) != EOF) {
+ switch (rv) {
+ case 'L':
+ /* List */
+ close(2);
+ return find_partitions("/proc/partitions",
+ NULL, NULL, 0, 1);
+ break;
+ case 'f':
+ close(2);
+ return find_partitions("/proc/partitions",
+ optarg, device,
+ sizeof(device), 0);
+ case 'c':
+ newdev = optarg;
+ break;
+ case 'l':
+ newlabel = optarg;
+ break;
+ case 'h':
+ printf("usage: mkqdisk -L | -f <label> | -c "
+ "<device> -l <label>\n");
+ return 0;
+ default:
+ break;
+ }
+ }
+
+ if (!newdev && !newlabel) {
+ printf("usage: mkqdisk -L | -f <label> | -c "
+ "<device> -l <label>\n");
+ return 1;
+ }
+
+ if (!newdev || !newlabel) {
+ printf("Both a device and a label are required\n");
+ return 1;
+ }
+
+ printf("Writing new quorum disk label '%s' to %s.\n",
+ newlabel, newdev);
+ printf("WARNING: About to destroy all data on %s; proceed [N/y] ? ",
+ newdev);
+ if (getc(stdin) != 'y') {
+ printf("Good thinking.\n");
+ return 0;
+ }
+
+ return qdisk_init(newdev, newlabel);
+}
--- cluster/cman/qdisk/proc.c 2006/06/23 16:01:02 1.1
+++ cluster/cman/qdisk/proc.c 2006/06/23 16:05:33 1.2
@@ -0,0 +1,128 @@
+/**
+ Copyright Red Hat, Inc. 2006
+
+ 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: Lon Hohberger <lhh@redhat.com>
+ */
+/**
+ @file Quorum disk /proc/partition scanning functions
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <disk.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <platform.h>
+#include <stdlib.h>
+#include <string.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,
+ char *devname, size_t devlen, int print)
+{
+ char line[4096];
+ FILE *fp;
+ int minor, major;
+ unsigned long long blkcnt;
+ char device[128];
+ char realdev[256];
+ quorum_header_t qh;
+
+ fp = fopen(partfile, "r");
+ if (!fp)
+ return -1;
+
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ if (strlen(line) > 128 + (22) /* 5 + 5 + 11 + 1 */) {
+ /*printf("Line too long!\n");*/
+ continue;
+ }
+
+ /* This line is taken from 2.6.15.4's proc line */
+ sscanf(line, "%4d %4d %10llu %s", &major, &minor,
+ &blkcnt, device);
+
+ if (strlen(device)) {
+ snprintf(realdev, sizeof(realdev),
+ "/dev/%s", device);
+ if (check_device(realdev, (char *)label, &qh) != 0)
+ continue;
+
+ if (print) {
+ printf("%s:\n", realdev);
+ printf("\tMagic: %08x\n", qh.qh_magic);
+ printf("\tLabel: %s\n", qh.qh_cluster);
+ printf("\tCreated: %s",
+ ctime((time_t *)&qh.qh_timestamp));
+ printf("\tHost: %s\n\n", qh.qh_updatehost);
+ }
+
+ if (devname && devlen) {
+ /* Got it */
+ strncpy(devname, realdev, devlen);
+ fclose(fp);
+ return 0;
+ }
+ }
+ }
+
+ fclose(fp);
+
+ if (print)
+ /* No errors if we're just printing stuff */
+ return 0;
+
+ errno = ENOENT;
+ return -1;
+}
--- cluster/cman/qdisk/Makefile 2006/05/31 21:07:06 1.3
+++ cluster/cman/qdisk/Makefile 2006/06/23 16:05:33 1.4
@@ -19,26 +19,30 @@
CFLAGS +=-I${ccsincdir} -I${incdir} -I${top_srcdir}/config \
-Wall -Werror -Wstrict-prototypes -Wshadow -D_GNU_SOURCE -g
-TARGET=qdiskd
+TARGET=qdiskd mkqdisk
all: ${TARGET}
copytobin: all
cp ${TARGET} ${top_srcdir}/bin
-install: qdiskd
+install: ${TARGET}
install -d ${sbindir}
- install qdiskd ${sbindir}
+ install ${TARGET} ${sbindir}
qdiskd: disk.o crc32.o disk_util.o main.o score.o bitmap.o clulog.o \
- gettid.o ../lib/libcman.a
+ gettid.o proc.o ../lib/libcman.a
gcc -o $@ $^ -lpthread -L../lib -L${ccslibdir} -lccs
+mkqdisk: disk.o crc32.o disk_util.o \
+ proc.o mkqdisk.o
+ gcc -o $@ $^
+
%.o: %.c
$(CC) -c -o $@ $^ $(INCLUDES) $(CFLAGS)
clean:
- rm -f *.o qdiskd
+ rm -f *.o ${TARGET}
uninstall:
- ${UNINSTALL} qdiskd ${sbindir}
+ ${UNINSTALL} ${TARGET} ${sbindir}
--- cluster/cman/qdisk/README 2006/05/19 14:41:35 1.2
+++ cluster/cman/qdisk/README 2006/06/23 16:05:33 1.3
@@ -213,8 +213,16 @@
min_score="3" Absolute minimum score to be consider one's
self "alive". If omitted, or set to 0, the
default function "floor((n+1)/2)" is used.
- device="/dev/sda1"/> This is the device the quorum daemon will use.
+ device="/dev/sda1" This is the device the quorum daemon will use.
This device must be the same on all nodes.
+ label="mylabel"/> This overrides the device field if present.
+ If specified, the quorum daemon will read
+ /proc/partitions and check for qdisk signatures
+ on every block device found, comparing the label
+ against the specified label. This is useful in
+ configurations where the block device name
+ differs on a per-node basis.
+
3.2. The <heuristic> tag
@@ -249,3 +257,18 @@
* The worst-case for improperly configured quorum heuristics is a race
to fence where two partitions simultaneously try to kill each other.
+3.5. Creating a quorum disk partition
+
+3.5.1. The mkqdisk utility.
+
+The mkqdisk utility can create and list currently configured quorum disks
+visible to the local node.
+
+ mkqdisk -L List available quorum disks.
+
+ mkqdisk -f <label> Find a quorum device by the given label.
+
+ mkqdisk -c <device> -l <label>
+ Initialize <device> and name it <label>. This
+ will destroy all data on the device, so be careful
+ when running this command.
--- cluster/cman/qdisk/disk.c 2006/05/22 17:33:22 1.3
+++ cluster/cman/qdisk/disk.c 2006/06/23 16:05:33 1.4
@@ -336,7 +336,8 @@
"diskRawReadShadow: can't seek to offset %d.\n",
(int) readOffset);
#endif
- return ENODATA;
+ errno = ENODATA;
+ return -1;
}
ret = diskRawRead(fd, buf, len);
@@ -345,7 +346,8 @@
fprintf(stderr, "diskRawReadShadow: aligned read "
"returned %d, not %d.\n", ret, len);
#endif
- return ENODATA;
+ errno = ENODATA;
+ return -1;
}
/* Decode the header portion so we can run a checksum on it. */
@@ -360,7 +362,8 @@
"fd = %d offset = %d len = %d\n", fd,
(int) readOffset, len);
#endif
- return EPROTO;
+ errno = EPROTO;
+ return -1;
}
return 0;
@@ -655,7 +658,7 @@
static int
-header_init(int fd, char *clustername)
+header_init(int fd, char *label)
{
quorum_header_t qh;
@@ -675,6 +678,9 @@
return -1;
}
+ /* Copy in the cluster/label name */
+ snprintf(qh.qh_cluster, sizeof(qh.qh_cluster)-1, label);
+
if ((qh.qh_timestamp = (uint64_t)time(NULL)) <= 0) {
perror("time");
return -1;
@@ -691,7 +697,7 @@
int
-qdisk_init(char *partname, char *clustername)
+qdisk_init(char *partname, char *label)
{
int fd;
status_block_t ps, wps;
@@ -710,7 +716,7 @@
return -1;
}
- if (header_init(fd, clustername) < 0) {
+ if (header_init(fd, label) < 0) {
return -1;
}
--- cluster/cman/qdisk/disk.h 2006/05/19 14:41:35 1.2
+++ cluster/cman/qdisk/disk.h 2006/06/23 16:05:33 1.3
@@ -238,6 +238,7 @@
int qc_unused;
cman_handle_t qc_ch;
char *qc_device;
+ char *qc_label;
char *qc_status_file;
} qd_ctx;
@@ -259,4 +260,10 @@
int qd_init(qd_ctx *ctx, cman_handle_t ch, int me);
void qd_destroy(qd_ctx *ctx);
+/* proc.c */
+int find_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);
+
+
#endif
--- cluster/cman/qdisk/main.c 2006/05/19 14:41:35 1.2
+++ cluster/cman/qdisk/main.c 2006/06/23 16:05:33 1.3
@@ -880,6 +880,12 @@
ctx->qc_device = val;
}
+ /* Get label (overrides device) */
+ snprintf(query, sizeof(query), "/cluster/quorumd/@label");
+ if (ccs_get(ccsfd, query, &val) == 0) {
+ ctx->qc_label = val;
+ }
+
/* Get status file */
snprintf(query, sizeof(query), "/cluster/quorumd/@status_file");
if (ccs_get(ccsfd, query, &val) == 0) {
@@ -917,6 +923,7 @@
node_info_t ni[MAX_NODES_DISK];
struct h_data h[10];
char debug = 0, foreground = 0;
+ char device[128];
while ((rv = getopt(argc, argv, "fd")) != EOF) {
switch (rv) {
@@ -958,6 +965,32 @@
return -1;
}
+ if (ctx.qc_label) {
+ if (find_partitions("/proc/partitions",
+ ctx.qc_label, device,
+ sizeof(device), 0) != 0) {
+ clulog_and_print(LOG_CRIT, "Unable to match label"
+ " '%s' to any device\n",
+ ctx.qc_label);
+ return -1;
+ }
+
+ if (ctx.qc_device)
+ free(ctx.qc_device);
+
+ ctx.qc_device = strdup(device);
+
+ clulog(LOG_INFO, "Quorum Partition: %s Label: %s\n",
+ ctx.qc_device, ctx.qc_label);
+ } else if (ctx.qc_device) {
+ if (check_device(ctx.qc_device, NULL, NULL) != 0) {
+ clulog(LOG_CRIT,
+ "Specified partition %s does not have a "
+ "qdisk label\n", ctx.qc_device);
+ return -1;
+ }
+ }
+
if (!foreground)
daemon(0,0);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2006-06-23 16:05 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-23 16:02 [Cluster-devel] cluster/cman/qdisk Makefile README disk.c disk lhh
-- strict thread matches above, loose matches on Subject: below --
2006-06-23 16:05 lhh
2006-06-23 16:01 lhh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).