[dm-devel] [PATCH RFC 2/2] user space program for dm-evt netlink messages

Mike Anderson andmike at us.ibm.com
Wed Nov 9 07:57:44 UTC 2005


 This patch adds a user space program the listens for netlink messages
 sent by the dm-mp dm_evt hardware handler.

 Signed-off-by: Mike Anderson <andmike at us.ibm.com>

 ---

 Makefile  |   30 ++++++++++
 dm_evtd.c |  177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 dm_evtd.h |   46 ++++++++++++++++
 3 files changed, 253 insertions(+)

--- /dev/null	2005-11-08 02:47:22.640591000 -0800
+++ dm_evtd/dm_evtd.c	2005-11-07 13:04:02.000000000 -0800
@@ -0,0 +1,177 @@
+/*
+ * Device Mapper Event User Space Daemon (dm-evtd)
+ *
+ * Copyright (C) 2005 IBM Corporation
+ * Copyright (C) 2005 Mike Anderson <andmike at us.ibm.com>
+ *
+ * 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 of the License, 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+/*
+ * This program is a proto example of using the dm-evt hardward handler
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/user.h>
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <time.h>
+#include "dm_evtd.h"
+
+static int socket_open(int *sock)
+{
+	struct sockaddr_nl snl;
+	int err = -1;
+
+	memset(&snl, 0x00, sizeof(snl));
+	snl.nl_family = AF_NETLINK;
+	snl.nl_pid = getpid();
+	snl.nl_groups = 0; /* not in mcast groups */
+
+	*sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_DM_EVENT);
+	if (*sock == -1) {
+		fprintf(stderr, "%s: socket failed (%s)\n", __FUNCTION__,
+			strerror(errno));
+		goto sock_failed;
+	}
+
+	err = bind(*sock, (struct sockaddr *) &snl,
+		      sizeof(snl));
+	if (err < 0) {
+		fprintf(stderr, "%s: bind failed (%s)\n", __FUNCTION__,
+		       strerror(errno));
+		goto bind_failed;
+	}
+
+	return err;
+bind_failed:
+	close(*sock);
+sock_failed:
+	return err;
+}
+
+static int evt_connect(int socket, unsigned short type)
+{
+	struct nlmsghdr *nlh;
+	struct sockaddr_nl addr;
+	struct msghdr msg;
+	struct iovec iov;
+	int err = -1;
+
+	nlh = calloc(1, sizeof(*nlh));
+	if (!nlh) {
+		fprintf(stderr, "%s: calloc failed (%s)\n", __FUNCTION__,
+			strerror(errno));
+		goto calloc_failed;
+	}
+
+	nlh->nlmsg_len = NLMSG_SPACE(0);
+	nlh->nlmsg_pid = getpid();
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_type = type;
+
+	memset(&addr, 0, sizeof(addr));
+	addr.nl_family = AF_NETLINK;
+	addr.nl_pid = 0;
+	addr.nl_groups = 0;
+
+	iov.iov_base = (void*)nlh;
+	iov.iov_len = nlh->nlmsg_len;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_name= (void*)&addr;
+	msg.msg_namelen = sizeof(addr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	err = sendmsg(socket, &msg, 0);
+
+	if (err <= 0)
+		fprintf(stderr, "%s: sendmsg failed (%s)\n", __FUNCTION__,
+			strerror(errno));
+
+calloc_failed:
+	return err;
+}
+
+static int evt_read(int socket, char *data, int count, int flags)
+{
+	int err;
+	struct iovec iov;
+	static struct sockaddr_nl addr;
+	struct msghdr msg;
+
+	iov.iov_base = data;
+	iov.iov_len = count;
+	memset(iov.iov_base, 0, iov.iov_len);
+
+	memset(&addr, 0, sizeof(addr));
+	addr.nl_family = AF_NETLINK;
+	addr.nl_pid = 0;
+	addr.nl_groups = 0;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_name= (void*)&addr;
+	msg.msg_namelen = sizeof(addr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	err = recvmsg(socket, &msg, flags);
+	if (err <= 0) {
+		fprintf(stderr, "%s: recvmsg failed (%s)\n", __FUNCTION__,
+			strerror(errno));
+	}
+
+	return err;
+}
+
+int main (int argc, char *argv[])
+{
+	int err, socket = -1;
+	void *msg;
+	struct dm_evt_msg *evt_msg;
+	struct nlmsghdr *nlh;
+
+	err = socket_open(&socket);
+	if (err)
+		exit(1);
+	err = evt_connect(socket, NLMSG_NOOP);
+
+	msg = calloc(1, NLMSG_SPACE(sizeof(struct dm_evt_msg)));
+	do {
+		err = evt_read(socket, msg, 
+			       NLMSG_SPACE(sizeof(struct dm_evt_msg)),
+			       0);
+		if (err <= 0)
+			break;
+		nlh = (struct nlmsghdr *)msg;
+		evt_msg = NLMSG_DATA(nlh);
+
+		fprintf(stdout,"[DM_EVT]: dm_name: %s, blk_err: 0x%x,"
+			" Time: %s", evt_msg->dm_name,
+			evt_msg->u.patherr.blk_err, 
+			ctime((time_t *)&evt_msg->tv_sec));
+
+		bzero(msg, NLMSG_SPACE(sizeof(struct dm_evt_msg)));
+	} while (1);
+
+	exit(err == 0 ? 0 : 1);
+}
--- /dev/null	2005-11-08 02:47:22.640591000 -0800
+++ dm_evtd/dm_evtd.h	2005-11-07 11:42:41.000000000 -0800
@@ -0,0 +1,46 @@
+/*
+ * Device Mapper Event Handler
+ *
+ * Copyright (C) 2005 IBM Corporation
+ * Copyright (C) 2005 Mike Anderson <andmike at us.ibm.com>
+ *
+ * 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 of the License, 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+#ifndef DM_EVENT_H
+#define DM_EVENT_H
+#include <stdint.h>
+
+#define EVT_DM_NAME_LEN 16
+
+#define DM_EVENT_BASE	10
+enum dm_evt_e {
+	DM_EVENT_UNKOWN		= 0,
+	DM_EVENT_PATH_ERR	= DM_EVENT_BASE + 1,
+};
+
+struct dm_evt_msg {
+	uint8_t dm_name[EVT_DM_NAME_LEN];
+	uint64_t tv_sec;
+	uint64_t tv_usec;
+
+	union {
+		struct msg_path_err {
+			uint32_t blk_err; /* BLKERR Values */
+		} patherr;
+	} u;
+} __attribute__((aligned(sizeof(uint64_t))));
+
+#endif
--- /dev/null	2005-11-08 02:47:22.640591000 -0800
+++ dm_evtd/Makefile	2005-11-08 22:13:36.000000000 -0800
@@ -0,0 +1,30 @@
+# Make variables (CC, etc...)
+AS              = $(CROSS_COMPILE)as
+LD              = $(CROSS_COMPILE)ld
+CC              = $(CROSS_COMPILE)gcc
+CPP             = $(CC) -E
+AR              = $(CROSS_COMPILE)ar
+NM              = $(CROSS_COMPILE)nm
+STRIP           = $(CROSS_COMPILE)strip
+OBJCOPY         = $(CROSS_COMPILE)objcopy
+OBJDUMP         = $(CROSS_COMPILE)objdump
+
+CFLAGS		+= -fno-builtin -Wall -Wchar-subscripts -Wundef \
+		   -Wstrict-prototypes -Wpointer-arith -Wsign-compare
+CFLAGS		+= -DNETLINK_DM_EVENT=17
+
+ifeq ($(strip $(DEBUG)),true)
+CFLAGS		+= -O1 -g
+else
+CFLAGS		+= -Os
+endif
+
+PROGRAM	= dm_evtd
+
+all: $(PROGRAM)
+
+dm_evtd: dm_evtd.o
+	$(CC) $^ -o $@
+
+clean:
+	rm -f *.o $(PROGRAM)




More information about the dm-devel mailing list