|
|
|
From c146b5840bbd7ad89c8a8de6192590ad0595a977 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
|
|
|
Date: Thu, 7 Apr 2016 18:19:58 -0500
|
|
|
|
Subject: [PATCH] Add libmpathcmd library and use it internally
|
|
|
|
|
|
|
|
Other programs would like to communicate with multipathd to issue
|
|
|
|
command or check status. Instead of having them exec multipathd,
|
|
|
|
I've pulled the code that sends commands and receives replies from
|
|
|
|
multipathd into its own library. I've made the multipath tools use
|
|
|
|
this library internally as well.
|
|
|
|
|
|
|
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
|
|
|
---
|
|
|
|
Makefile | 1
|
|
|
|
Makefile.inc | 2
|
|
|
|
libmpathcmd/Makefile | 32 +++++++
|
|
|
|
libmpathcmd/mpath_cmd.c | 178 +++++++++++++++++++++++++++++++++++++++
|
|
|
|
libmpathcmd/mpath_cmd.h | 125 +++++++++++++++++++++++++++
|
|
|
|
libmpathpersist/Makefile | 5 -
|
|
|
|
libmpathpersist/mpath_updatepr.c | 30 +++---
|
|
|
|
libmultipath/Makefile | 4
|
|
|
|
libmultipath/config.c | 1
|
|
|
|
libmultipath/configure.c | 10 +-
|
|
|
|
libmultipath/uxsock.c | 88 +++----------------
|
|
|
|
libmultipath/uxsock.h | 6 -
|
|
|
|
mpathpersist/Makefile | 2
|
|
|
|
multipath/Makefile | 5 -
|
|
|
|
multipathd/Makefile | 4
|
|
|
|
multipathd/uxclnt.c | 13 +-
|
|
|
|
multipathd/uxlsnr.c | 9 -
|
|
|
|
17 files changed, 401 insertions(+), 114 deletions(-)
|
|
|
|
create mode 100644 libmpathcmd/Makefile
|
|
|
|
create mode 100644 libmpathcmd/mpath_cmd.c
|
|
|
|
create mode 100644 libmpathcmd/mpath_cmd.h
|
|
|
|
|
|
|
|
Index: multipath-tools-130222/Makefile
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/Makefile
|
|
|
|
+++ multipath-tools-130222/Makefile
|
|
|
|
@@ -20,6 +20,7 @@ export KRNLSRC
|
|
|
|
export KRNLOBJ
|
|
|
|
|
|
|
|
BUILDDIRS = \
|
|
|
|
+ libmpathcmd \
|
|
|
|
libmultipath \
|
|
|
|
libmultipath/prioritizers \
|
|
|
|
libmultipath/checkers \
|
|
|
|
Index: multipath-tools-130222/Makefile.inc
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/Makefile.inc
|
|
|
|
+++ multipath-tools-130222/Makefile.inc
|
|
|
|
@@ -34,6 +34,8 @@ syslibdir = $(prefix)/usr/$(LIB)
|
|
|
|
libdir = $(prefix)/usr/$(LIB)/multipath
|
|
|
|
unitdir = $(prefix)/lib/systemd/system
|
|
|
|
mpathpersistdir = $(TOPDIR)/libmpathpersist
|
|
|
|
+includedir = $(prefix)/usr/include
|
|
|
|
+mpathcmddir = $(TOPDIR)/libmpathcmd
|
|
|
|
|
|
|
|
GZIP = /bin/gzip -9 -c
|
|
|
|
INSTALL_PROGRAM = install
|
|
|
|
Index: multipath-tools-130222/libmpathcmd/Makefile
|
|
|
|
===================================================================
|
|
|
|
--- /dev/null
|
|
|
|
+++ multipath-tools-130222/libmpathcmd/Makefile
|
|
|
|
@@ -0,0 +1,32 @@
|
|
|
|
+# Makefile
|
|
|
|
+#
|
|
|
|
+include ../Makefile.inc
|
|
|
|
+
|
|
|
|
+SONAME=0
|
|
|
|
+DEVLIB = libmpathcmd.so
|
|
|
|
+LIBS = $(DEVLIB).$(SONAME)
|
|
|
|
+
|
|
|
|
+CFLAGS += -fPIC
|
|
|
|
+
|
|
|
|
+OBJS = mpath_cmd.o
|
|
|
|
+
|
|
|
|
+all: $(LIBS)
|
|
|
|
+
|
|
|
|
+$(LIBS): $(OBJS)
|
|
|
|
+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ $(CFLAGS) -o $@ $(OBJS) $(LIBDEPS)
|
|
|
|
+ ln -sf $@ $(DEVLIB)
|
|
|
|
+
|
|
|
|
+install: $(LIBS)
|
|
|
|
+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
|
|
|
|
+ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
|
|
|
|
+ ln -sf $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB)
|
|
|
|
+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir)
|
|
|
|
+ $(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir)
|
|
|
|
+
|
|
|
|
+uninstall:
|
|
|
|
+ rm -f $(DESTDIR)$(syslibdir)/$(LIBS)
|
|
|
|
+ rm -f $(DESTDIR)$(syslibdir)/$(DEVLIB)
|
|
|
|
+ rm -f $(DESTDIR)$(includedir)/mpath_cmd.h
|
|
|
|
+
|
|
|
|
+clean:
|
|
|
|
+ rm -f core *.a *.o *.gz *.so *.so.*
|
|
|
|
Index: multipath-tools-130222/libmpathcmd/mpath_cmd.c
|
|
|
|
===================================================================
|
|
|
|
--- /dev/null
|
|
|
|
+++ multipath-tools-130222/libmpathcmd/mpath_cmd.c
|
|
|
|
@@ -0,0 +1,178 @@
|
|
|
|
+#include <stdlib.h>
|
|
|
|
+#include <unistd.h>
|
|
|
|
+#include <stdio.h>
|
|
|
|
+#include <sys/types.h>
|
|
|
|
+#include <sys/socket.h>
|
|
|
|
+#include <sys/un.h>
|
|
|
|
+#include <poll.h>
|
|
|
|
+#include <string.h>
|
|
|
|
+#include <errno.h>
|
|
|
|
+
|
|
|
|
+#include "mpath_cmd.h"
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * keep reading until its all read
|
|
|
|
+ */
|
|
|
|
+static ssize_t read_all(int fd, void *buf, size_t len, unsigned int timeout)
|
|
|
|
+{
|
|
|
|
+ size_t total = 0;
|
|
|
|
+ ssize_t n;
|
|
|
|
+ int ret;
|
|
|
|
+ struct pollfd pfd;
|
|
|
|
+
|
|
|
|
+ while (len) {
|
|
|
|
+ pfd.fd = fd;
|
|
|
|
+ pfd.events = POLLIN;
|
|
|
|
+ ret = poll(&pfd, 1, timeout);
|
|
|
|
+ if (!ret) {
|
|
|
|
+ errno = ETIMEDOUT;
|
|
|
|
+ return -1;
|
|
|
|
+ } else if (ret < 0) {
|
|
|
|
+ if (errno == EINTR)
|
|
|
|
+ continue;
|
|
|
|
+ return -1;
|
|
|
|
+ } else if (!(pfd.revents & POLLIN))
|
|
|
|
+ continue;
|
|
|
|
+ n = read(fd, buf, len);
|
|
|
|
+ if (n < 0) {
|
|
|
|
+ if ((errno == EINTR) || (errno == EAGAIN))
|
|
|
|
+ continue;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (!n)
|
|
|
|
+ return total;
|
|
|
|
+ buf = n + (char *)buf;
|
|
|
|
+ len -= n;
|
|
|
|
+ total += n;
|
|
|
|
+ }
|
|
|
|
+ return total;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * keep writing until it's all sent
|
|
|
|
+ */
|
|
|
|
+static size_t write_all(int fd, const void *buf, size_t len)
|
|
|
|
+{
|
|
|
|
+ size_t total = 0;
|
|
|
|
+
|
|
|
|
+ while (len) {
|
|
|
|
+ ssize_t n = write(fd, buf, len);
|
|
|
|
+ if (n < 0) {
|
|
|
|
+ if ((errno == EINTR) || (errno == EAGAIN))
|
|
|
|
+ continue;
|
|
|
|
+ return total;
|
|
|
|
+ }
|
|
|
|
+ if (!n)
|
|
|
|
+ return total;
|
|
|
|
+ buf = n + (char *)buf;
|
|
|
|
+ len -= n;
|
|
|
|
+ total += n;
|
|
|
|
+ }
|
|
|
|
+ return total;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * connect to a unix domain socket
|
|
|
|
+ */
|
|
|
|
+int mpath_connect(void)
|
|
|
|
+{
|
|
|
|
+ int fd, len;
|
|
|
|
+ struct sockaddr_un addr;
|
|
|
|
+
|
|
|
|
+ memset(&addr, 0, sizeof(addr));
|
|
|
|
+ addr.sun_family = AF_LOCAL;
|
|
|
|
+ addr.sun_path[0] = '\0';
|
|
|
|
+ len = strlen(DEFAULT_SOCKET) + 1 + sizeof(sa_family_t);
|
|
|
|
+ strncpy(&addr.sun_path[1], DEFAULT_SOCKET, len);
|
|
|
|
+
|
|
|
|
+ fd = socket(AF_LOCAL, SOCK_STREAM, 0);
|
|
|
|
+ if (fd == -1)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ if (connect(fd, (struct sockaddr *)&addr, len) == -1) {
|
|
|
|
+ close(fd);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return fd;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int mpath_disconnect(int fd)
|
|
|
|
+{
|
|
|
|
+ return close(fd);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+ssize_t mpath_recv_reply_len(int fd, unsigned int timeout)
|
|
|
|
+{
|
|
|
|
+ size_t len;
|
|
|
|
+ ssize_t ret;
|
|
|
|
+
|
|
|
|
+ ret = read_all(fd, &len, sizeof(len), timeout);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ return ret;
|
|
|
|
+ if (ret != sizeof(len)) {
|
|
|
|
+ errno = EIO;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ return len;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int mpath_recv_reply_data(int fd, char *reply, size_t len,
|
|
|
|
+ unsigned int timeout)
|
|
|
|
+{
|
|
|
|
+ ssize_t ret;
|
|
|
|
+
|
|
|
|
+ ret = read_all(fd, reply, len, timeout);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ return ret;
|
|
|
|
+ if (ret != len) {
|
|
|
|
+ errno = EIO;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ reply[len - 1] = '\0';
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int mpath_recv_reply(int fd, char **reply, unsigned int timeout)
|
|
|
|
+{
|
|
|
|
+ int err;
|
|
|
|
+ ssize_t len;
|
|
|
|
+
|
|
|
|
+ *reply = NULL;
|
|
|
|
+ len = mpath_recv_reply_len(fd, timeout);
|
|
|
|
+ if (len <= 0)
|
|
|
|
+ return -1;
|
|
|
|
+ *reply = malloc(len);
|
|
|
|
+ if (!*reply)
|
|
|
|
+ return -1;
|
|
|
|
+ err = mpath_recv_reply_data(fd, *reply, len, timeout);
|
|
|
|
+ if (err) {
|
|
|
|
+ free(*reply);
|
|
|
|
+ *reply = NULL;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int mpath_send_cmd(int fd, const char *cmd)
|
|
|
|
+{
|
|
|
|
+ size_t len;
|
|
|
|
+
|
|
|
|
+ if (cmd != NULL)
|
|
|
|
+ len = strlen(cmd) + 1;
|
|
|
|
+ else
|
|
|
|
+ len = 0;
|
|
|
|
+ if (write_all(fd, &len, sizeof(len)) != sizeof(len))
|
|
|
|
+ return -1;
|
|
|
|
+ if (len && write_all(fd, cmd, len) != len)
|
|
|
|
+ return -1;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int mpath_process_cmd(int fd, const char *cmd, char **reply,
|
|
|
|
+ unsigned int timeout)
|
|
|
|
+{
|
|
|
|
+ if (mpath_send_cmd(fd, cmd) != 0)
|
|
|
|
+ return -1;
|
|
|
|
+ return mpath_recv_reply(fd, reply, timeout);
|
|
|
|
+}
|
|
|
|
Index: multipath-tools-130222/libmpathcmd/mpath_cmd.h
|
|
|
|
===================================================================
|
|
|
|
--- /dev/null
|
|
|
|
+++ multipath-tools-130222/libmpathcmd/mpath_cmd.h
|
|
|
|
@@ -0,0 +1,125 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright (C) 2015 Red Hat, Inc.
|
|
|
|
+ *
|
|
|
|
+ * This file is part of the device-mapper multipath userspace tools.
|
|
|
|
+ *
|
|
|
|
+ * This program is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser 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 LIB_MPATH_CMD_H
|
|
|
|
+#define LIB_MPATH_CMD_H
|
|
|
|
+
|
|
|
|
+#ifdef __cpluscplus
|
|
|
|
+extern "C" {
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd"
|
|
|
|
+#define DEFAULT_REPLY_TIMEOUT 10000
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * DESCRIPTION:
|
|
|
|
+ * Connect to the running multipathd daemon. On systems with the
|
|
|
|
+ * multipathd.socket systemd unit file installed, this command will
|
|
|
|
+ * start multipathd if it is not already running. This function
|
|
|
|
+ * must be run before any of the others in this library
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * A file descriptor on success. -1 on failure (with errno set).
|
|
|
|
+ */
|
|
|
|
+int mpath_connect(void);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * DESCRIPTION:
|
|
|
|
+ * Disconnect from the multipathd daemon. This function must be
|
|
|
|
+ * run after after processing all the multipath commands.
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * 0 on success. -1 on failure (with errno set).
|
|
|
|
+ */
|
|
|
|
+int mpath_disconnect(int fd);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * DESCRIPTION
|
|
|
|
+ * Send multipathd a command and return the reply. This function
|
|
|
|
+ * does the same as calling mpath_send_cmd() and then
|
|
|
|
+ * mpath_recv_reply()
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * 0 on successs, and reply will either be NULL (if there was no
|
|
|
|
+ * reply data), or point to the reply string, which must be freed by
|
|
|
|
+ * the caller. -1 on failure (with errno set).
|
|
|
|
+ */
|
|
|
|
+int mpath_process_cmd(int fd, const char *cmd, char **reply,
|
|
|
|
+ unsigned int timeout);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * DESCRIPTION:
|
|
|
|
+ * Send a command to multipathd
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * 0 on success. -1 on failure (with errno set)
|
|
|
|
+ */
|
|
|
|
+int mpath_send_cmd(int fd, const char *cmd);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * DESCRIPTION:
|
|
|
|
+ * Return a reply from multipathd for a previously sent command.
|
|
|
|
+ * This is equivalent to calling mpath_recv_reply_len(), allocating
|
|
|
|
+ * a buffer of the appropriate size, and then calling
|
|
|
|
+ * mpath_recv_reply_data() with that buffer.
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * 0 on success, and reply will either be NULL (if there was no
|
|
|
|
+ * reply data), or point to the reply string, which must be freed by
|
|
|
|
+ * the caller, -1 on failure (with errno set).
|
|
|
|
+ */
|
|
|
|
+int mpath_recv_reply(int fd, char **reply, unsigned int timeout);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * DESCRIPTION:
|
|
|
|
+ * Return the size of the upcoming reply data from the sent multipath
|
|
|
|
+ * command. This must be called before calling mpath_recv_reply_data().
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * The required size of the reply data buffer on success. -1 on
|
|
|
|
+ * failure (with errno set).
|
|
|
|
+ */
|
|
|
|
+ssize_t mpath_recv_reply_len(int fd, unsigned int timeout);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * DESCRIPTION:
|
|
|
|
+ * Return the reply data from the sent multipath command.
|
|
|
|
+ * mpath_recv_reply_len must be called first. reply must point to a
|
|
|
|
+ * buffer of len size.
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * 0 on success, and reply will contain the reply data string. -1
|
|
|
|
+ * on failure (with errno set).
|
|
|
|
+ */
|
|
|
|
+int mpath_recv_reply_data(int fd, char *reply, size_t len,
|
|
|
|
+ unsigned int timeout);
|
|
|
|
+
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+#endif /* LIB_MPATH_CMD_H */
|
|
|
|
Index: multipath-tools-130222/libmpathpersist/Makefile
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/libmpathpersist/Makefile
|
|
|
|
+++ multipath-tools-130222/libmpathpersist/Makefile
|
|
|
|
@@ -10,8 +10,9 @@ DEVLIB = libmpathpersist.so
|
|
|
|
LIBS = $(DEVLIB).$(SONAME)
|
|
|
|
|
|
|
|
|
|
|
|
-CFLAGS += -fPIC -I$(multipathdir) -I$(mpathpersistdir)
|
|
|
|
-LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath
|
|
|
|
+CFLAGS += -fPIC -I$(multipathdir) -I$(mpathpersistdir) -I$(mpathcmddir)
|
|
|
|
+LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \
|
|
|
|
+ -L$(mpathcmddir) -lmpathcmd
|
|
|
|
|
|
|
|
OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o
|
|
|
|
|
|
|
|
Index: multipath-tools-130222/libmpathpersist/mpath_updatepr.c
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/libmpathpersist/mpath_updatepr.c
|
|
|
|
+++ multipath-tools-130222/libmpathpersist/mpath_updatepr.c
|
|
|
|
@@ -12,9 +12,9 @@
|
|
|
|
#include <sys/poll.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <debug.h>
|
|
|
|
+#include <mpath_cmd.h>
|
|
|
|
+#include <uxsock.h>
|
|
|
|
#include "memory.h"
|
|
|
|
-#include "../libmultipath/uxsock.h"
|
|
|
|
-#include "../libmultipath/defaults.h"
|
|
|
|
|
|
|
|
unsigned long mem_allocated; /* Total memory used in Bytes */
|
|
|
|
|
|
|
|
@@ -23,10 +23,9 @@ int update_prflag(char * arg1, char * ar
|
|
|
|
int fd;
|
|
|
|
char str[64];
|
|
|
|
char *reply;
|
|
|
|
- size_t len;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
- fd = ux_socket_connect(DEFAULT_SOCKET);
|
|
|
|
+ fd = mpath_connect();
|
|
|
|
if (fd == -1) {
|
|
|
|
condlog (0, "ux socket connect error");
|
|
|
|
return 1 ;
|
|
|
|
@@ -34,18 +33,23 @@ int update_prflag(char * arg1, char * ar
|
|
|
|
|
|
|
|
snprintf(str,sizeof(str),"map %s %s", arg1, arg2);
|
|
|
|
condlog (2, "%s: pr flag message=%s", arg1, str);
|
|
|
|
- send_packet(fd, str, strlen(str) + 1);
|
|
|
|
- recv_packet(fd, &reply, &len);
|
|
|
|
-
|
|
|
|
- condlog (2, "%s: message=%s reply=%s", arg1, str, reply);
|
|
|
|
- if (!reply || strncmp(reply,"ok", 2) == 0)
|
|
|
|
- ret = -1;
|
|
|
|
- else if (strncmp(reply, "fail", 4) == 0)
|
|
|
|
+ send_packet(fd, str);
|
|
|
|
+ ret = recv_packet(fd, &reply);
|
|
|
|
+ if (ret < 0) {
|
|
|
|
+ condlog(2, "%s: message=%s recv error=%d", arg1, str, errno);
|
|
|
|
ret = -2;
|
|
|
|
- else{
|
|
|
|
- ret = atoi(reply);
|
|
|
|
+ } else {
|
|
|
|
+ condlog (2, "%s: message=%s reply=%s", arg1, str, reply);
|
|
|
|
+ if (!reply || strncmp(reply,"ok", 2) == 0)
|
|
|
|
+ ret = -1;
|
|
|
|
+ else if (strncmp(reply, "fail", 4) == 0)
|
|
|
|
+ ret = -2;
|
|
|
|
+ else{
|
|
|
|
+ ret = atoi(reply);
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
free(reply);
|
|
|
|
+ mpath_disconnect(fd);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
Index: multipath-tools-130222/libmultipath/Makefile
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/libmultipath/Makefile
|
|
|
|
+++ multipath-tools-130222/libmultipath/Makefile
|
|
|
|
@@ -7,8 +7,8 @@ include ../Makefile.inc
|
|
|
|
SONAME=0
|
|
|
|
DEVLIB = libmultipath.so
|
|
|
|
LIBS = $(DEVLIB).$(SONAME)
|
|
|
|
-LIBDEPS = -lpthread -ldl -ldevmapper -ludev
|
|
|
|
-CFLAGS += -fPIC
|
|
|
|
+LIBDEPS = -lpthread -ldl -ldevmapper -ludev -L$(mpathcmddir) -lmpathcmd
|
|
|
|
+CFLAGS += -fPIC -I$(mpathcmddir)
|
|
|
|
|
|
|
|
OBJS = memory.o parser.o vector.o devmapper.o \
|
|
|
|
hwtable.o blacklist.o util.o dmparser.o config.o \
|
|
|
|
Index: multipath-tools-130222/libmultipath/config.c
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/libmultipath/config.c
|
|
|
|
+++ multipath-tools-130222/libmultipath/config.c
|
|
|
|
@@ -25,6 +25,7 @@
|
|
|
|
#include "prio.h"
|
|
|
|
#include "devmapper.h"
|
|
|
|
#include "version.h"
|
|
|
|
+#include "mpath_cmd.h"
|
|
|
|
|
|
|
|
static int
|
|
|
|
hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2)
|
|
|
|
Index: multipath-tools-130222/libmultipath/configure.c
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/libmultipath/configure.c
|
|
|
|
+++ multipath-tools-130222/libmultipath/configure.c
|
|
|
|
@@ -14,6 +14,7 @@
|
|
|
|
#include <errno.h>
|
|
|
|
#include <libdevmapper.h>
|
|
|
|
#include <libudev.h>
|
|
|
|
+#include <mpath_cmd.h>
|
|
|
|
|
|
|
|
#include "checkers.h"
|
|
|
|
#include "vector.h"
|
|
|
|
@@ -752,16 +753,15 @@ check_daemon(void)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
char *reply;
|
|
|
|
- size_t len;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
- fd = ux_socket_connect(DEFAULT_SOCKET);
|
|
|
|
+ fd = mpath_connect();
|
|
|
|
if (fd == -1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
- if (send_packet(fd, "show daemon", 12) != 0)
|
|
|
|
+ if (send_packet(fd, "show daemon") != 0)
|
|
|
|
goto out;
|
|
|
|
- if (recv_packet(fd, &reply, &len) != 0)
|
|
|
|
+ if (recv_packet(fd, &reply) != 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
if (strstr(reply, "shutdown"))
|
|
|
|
@@ -772,7 +772,7 @@ check_daemon(void)
|
|
|
|
out_free:
|
|
|
|
FREE(reply);
|
|
|
|
out:
|
|
|
|
- close(fd);
|
|
|
|
+ mpath_disconnect(fd);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
Index: multipath-tools-130222/libmultipath/uxsock.c
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/libmultipath/uxsock.c
|
|
|
|
+++ multipath-tools-130222/libmultipath/uxsock.c
|
|
|
|
@@ -16,37 +16,10 @@
|
|
|
|
#include <sys/poll.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <errno.h>
|
|
|
|
+#include <mpath_cmd.h>
|
|
|
|
|
|
|
|
#include "memory.h"
|
|
|
|
#include "uxsock.h"
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * connect to a unix domain socket
|
|
|
|
- */
|
|
|
|
-int ux_socket_connect(const char *name)
|
|
|
|
-{
|
|
|
|
- int fd, len;
|
|
|
|
- struct sockaddr_un addr;
|
|
|
|
-
|
|
|
|
- memset(&addr, 0, sizeof(addr));
|
|
|
|
- addr.sun_family = AF_LOCAL;
|
|
|
|
- addr.sun_path[0] = '\0';
|
|
|
|
- len = strlen(name) + 1 + sizeof(sa_family_t);
|
|
|
|
- strncpy(&addr.sun_path[1], name, len);
|
|
|
|
-
|
|
|
|
- fd = socket(AF_LOCAL, SOCK_STREAM, 0);
|
|
|
|
- if (fd == -1) {
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (connect(fd, (struct sockaddr *)&addr, len) == -1) {
|
|
|
|
- close(fd);
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return fd;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
|
|
* create a unix domain socket and start listening on it
|
|
|
|
* return a file descriptor open on the socket
|
|
|
|
@@ -102,32 +75,9 @@ size_t write_all(int fd, const void *buf
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
- * keep reading until its all read
|
|
|
|
- */
|
|
|
|
-size_t read_all(int fd, void *buf, size_t len)
|
|
|
|
-{
|
|
|
|
- size_t total = 0;
|
|
|
|
-
|
|
|
|
- while (len) {
|
|
|
|
- ssize_t n = read(fd, buf, len);
|
|
|
|
- if (n < 0) {
|
|
|
|
- if ((errno == EINTR) || (errno == EAGAIN))
|
|
|
|
- continue;
|
|
|
|
- return total;
|
|
|
|
- }
|
|
|
|
- if (!n)
|
|
|
|
- return total;
|
|
|
|
- buf = n + (char *)buf;
|
|
|
|
- len -= n;
|
|
|
|
- total += n;
|
|
|
|
- }
|
|
|
|
- return total;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
* send a packet in length prefix format
|
|
|
|
*/
|
|
|
|
-int send_packet(int fd, const char *buf, size_t len)
|
|
|
|
+int send_packet(int fd, const char *buf)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
sigset_t set, old;
|
|
|
|
@@ -137,10 +87,7 @@ int send_packet(int fd, const char *buf,
|
|
|
|
sigaddset(&set, SIGPIPE);
|
|
|
|
pthread_sigmask(SIG_BLOCK, &set, &old);
|
|
|
|
|
|
|
|
- if (write_all(fd, &len, sizeof(len)) != sizeof(len))
|
|
|
|
- ret = -1;
|
|
|
|
- if (!ret && write_all(fd, buf, len) != len)
|
|
|
|
- ret = -1;
|
|
|
|
+ ret = mpath_send_cmd(fd, buf);
|
|
|
|
|
|
|
|
/* And unblock it again */
|
|
|
|
pthread_sigmask(SIG_SETMASK, &old, NULL);
|
|
|
|
@@ -151,25 +98,24 @@ int send_packet(int fd, const char *buf,
|
|
|
|
/*
|
|
|
|
* receive a packet in length prefix format
|
|
|
|
*/
|
|
|
|
-int recv_packet(int fd, char **buf, size_t *len)
|
|
|
|
+int recv_packet(int fd, char **buf)
|
|
|
|
{
|
|
|
|
- if (read_all(fd, len, sizeof(*len)) != sizeof(*len)) {
|
|
|
|
- (*buf) = NULL;
|
|
|
|
- *len = 0;
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
- if (len == 0) {
|
|
|
|
- (*buf) = NULL;
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- (*buf) = MALLOC(*len);
|
|
|
|
+ int err;
|
|
|
|
+ ssize_t len;
|
|
|
|
+ unsigned int timeout = DEFAULT_REPLY_TIMEOUT;
|
|
|
|
+
|
|
|
|
+ *buf = NULL;
|
|
|
|
+ len = mpath_recv_reply_len(fd, timeout);
|
|
|
|
+ if (len <= 0)
|
|
|
|
+ return len;
|
|
|
|
+ (*buf) = MALLOC(len);
|
|
|
|
if (!*buf)
|
|
|
|
- return -1;
|
|
|
|
- if (read_all(fd, *buf, *len) != *len) {
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ err = mpath_recv_reply_data(fd, *buf, len, timeout);
|
|
|
|
+ if (err) {
|
|
|
|
FREE(*buf);
|
|
|
|
(*buf) = NULL;
|
|
|
|
- *len = 0;
|
|
|
|
- return -1;
|
|
|
|
+ return err;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
Index: multipath-tools-130222/libmultipath/uxsock.h
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/libmultipath/uxsock.h
|
|
|
|
+++ multipath-tools-130222/libmultipath/uxsock.h
|
|
|
|
@@ -1,7 +1,5 @@
|
|
|
|
/* some prototypes */
|
|
|
|
-int ux_socket_connect(const char *name);
|
|
|
|
int ux_socket_listen(const char *name);
|
|
|
|
-int send_packet(int fd, const char *buf, size_t len);
|
|
|
|
-int recv_packet(int fd, char **buf, size_t *len);
|
|
|
|
+int send_packet(int fd, const char *buf);
|
|
|
|
+int recv_packet(int fd, char **buf);
|
|
|
|
size_t write_all(int fd, const void *buf, size_t len);
|
|
|
|
-size_t read_all(int fd, void *buf, size_t len);
|
|
|
|
Index: multipath-tools-130222/mpathpersist/Makefile
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/mpathpersist/Makefile
|
|
|
|
+++ multipath-tools-130222/mpathpersist/Makefile
|
|
|
|
@@ -5,7 +5,7 @@ include ../Makefile.inc
|
|
|
|
OBJS = main.o
|
|
|
|
|
|
|
|
CFLAGS += -I$(multipathdir) -I$(mpathpersistdir)
|
|
|
|
-LDFLAGS += -lpthread -ldevmapper -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath -ludev
|
|
|
|
+LDFLAGS += -lpthread -ldevmapper -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -L$(mpathcmddir) -lmpathcmd -lmultipath -ludev
|
|
|
|
|
|
|
|
EXEC = mpathpersist
|
|
|
|
|
|
|
|
Index: multipath-tools-130222/multipath/Makefile
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/multipath/Makefile
|
|
|
|
+++ multipath-tools-130222/multipath/Makefile
|
|
|
|
@@ -6,8 +6,9 @@ include ../Makefile.inc
|
|
|
|
|
|
|
|
OBJS = main.o
|
|
|
|
|
|
|
|
-CFLAGS += -fPIC -I$(multipathdir)
|
|
|
|
-LDFLAGS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath -ludev
|
|
|
|
+CFLAGS += -I$(multipathdir) -I$(mpathcmddir)
|
|
|
|
+LDFLAGS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath -ludev \
|
|
|
|
+ -L$(mpathcmddir) -lmpathcmd
|
|
|
|
|
|
|
|
EXEC = multipath
|
|
|
|
|
|
|
|
Index: multipath-tools-130222/multipathd/Makefile
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/multipathd/Makefile
|
|
|
|
+++ multipath-tools-130222/multipathd/Makefile
|
|
|
|
@@ -5,10 +5,10 @@ include ../Makefile.inc
|
|
|
|
#
|
|
|
|
# basic flags setting
|
|
|
|
#
|
|
|
|
-CFLAGS += -fPIE -DPIE -I$(multipathdir) -I$(mpathpersistdir)
|
|
|
|
+CFLAGS += -fPIE -DPIE -I$(multipathdir) -I$(mpathpersistdir) -I$(mpathcmddir)
|
|
|
|
LDFLAGS += -lpthread -ldevmapper -lreadline -ludev -ldl \
|
|
|
|
-L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \
|
|
|
|
- -Wl,-z,now -pie
|
|
|
|
+ -L$(mpathcmddir) -lmpathcmd -Wl,-z,now -pie
|
|
|
|
|
|
|
|
#
|
|
|
|
# debuging stuff
|
|
|
|
Index: multipath-tools-130222/multipathd/uxclnt.c
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/multipathd/uxclnt.c
|
|
|
|
+++ multipath-tools-130222/multipathd/uxclnt.c
|
|
|
|
@@ -17,6 +17,7 @@
|
|
|
|
#include <readline/readline.h>
|
|
|
|
#include <readline/history.h>
|
|
|
|
|
|
|
|
+#include <mpath_cmd.h>
|
|
|
|
#include <uxsock.h>
|
|
|
|
#include <memory.h>
|
|
|
|
#include <defaults.h>
|
|
|
|
@@ -49,7 +50,6 @@ static void process(int fd)
|
|
|
|
rl_readline_name = "multipathd";
|
|
|
|
rl_completion_entry_function = key_generator;
|
|
|
|
while ((line = readline("multipathd> "))) {
|
|
|
|
- size_t len;
|
|
|
|
size_t llen = strlen(line);
|
|
|
|
|
|
|
|
if (!llen) {
|
|
|
|
@@ -61,8 +61,8 @@ static void process(int fd)
|
|
|
|
if (!strncmp(line, "quit", 4) && llen == 4)
|
|
|
|
break;
|
|
|
|
|
|
|
|
- if (send_packet(fd, line, llen + 1) != 0) break;
|
|
|
|
- if (recv_packet(fd, &reply, &len) != 0) break;
|
|
|
|
+ if (send_packet(fd, line) != 0) break;
|
|
|
|
+ if (recv_packet(fd, &reply) != 0) break;
|
|
|
|
|
|
|
|
print_reply(reply);
|
|
|
|
|
|
|
|
@@ -77,13 +77,12 @@ static void process(int fd)
|
|
|
|
static void process_req(int fd, char * inbuf)
|
|
|
|
{
|
|
|
|
char *reply;
|
|
|
|
- size_t len;
|
|
|
|
|
|
|
|
- if (send_packet(fd, inbuf, strlen(inbuf) + 1) != 0) {
|
|
|
|
+ if (send_packet(fd, inbuf) != 0) {
|
|
|
|
printf("cannot send packet\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
- if (recv_packet(fd, &reply, &len) != 0)
|
|
|
|
+ if (recv_packet(fd, &reply) != 0)
|
|
|
|
printf("error receiving packet\n");
|
|
|
|
else {
|
|
|
|
printf("%s", reply);
|
|
|
|
@@ -98,7 +97,7 @@ int uxclnt(char * inbuf)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
- fd = ux_socket_connect(DEFAULT_SOCKET);
|
|
|
|
+ fd = mpath_connect();
|
|
|
|
if (fd == -1) {
|
|
|
|
perror("ux_socket_connect");
|
|
|
|
exit(1);
|
|
|
|
Index: multipath-tools-130222/multipathd/uxlsnr.c
|
|
|
|
===================================================================
|
|
|
|
--- multipath-tools-130222.orig/multipathd/uxlsnr.c
|
|
|
|
+++ multipath-tools-130222/multipathd/uxlsnr.c
|
|
|
|
@@ -29,6 +29,7 @@
|
|
|
|
#include <structs_vec.h>
|
|
|
|
#include <uxsock.h>
|
|
|
|
#include <defaults.h>
|
|
|
|
+#include <mpath_cmd.h>
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
#include "cli.h"
|
|
|
|
@@ -108,7 +109,6 @@ void * uxsock_listen(int (*uxsock_trigge
|
|
|
|
void * trigger_data)
|
|
|
|
{
|
|
|
|
int ux_sock;
|
|
|
|
- size_t len;
|
|
|
|
int rlen;
|
|
|
|
char *inbuf;
|
|
|
|
char *reply;
|
|
|
|
@@ -171,16 +171,15 @@ void * uxsock_listen(int (*uxsock_trigge
|
|
|
|
struct client *next = c->next;
|
|
|
|
|
|
|
|
if (polls[i].revents & POLLIN) {
|
|
|
|
- if (recv_packet(c->fd, &inbuf, &len) != 0) {
|
|
|
|
+ if (recv_packet(c->fd, &inbuf) != 0) {
|
|
|
|
dead_client(c);
|
|
|
|
} else {
|
|
|
|
- inbuf[len - 1] = 0;
|
|
|
|
condlog(4, "Got request [%s]", inbuf);
|
|
|
|
uxsock_trigger(inbuf, &reply, &rlen,
|
|
|
|
trigger_data);
|
|
|
|
if (reply) {
|
|
|
|
- if (send_packet(c->fd, reply,
|
|
|
|
- rlen) != 0) {
|
|
|
|
+ if (send_packet(c->fd,
|
|
|
|
+ reply) != 0) {
|
|
|
|
dead_client(c);
|
|
|
|
}
|
|
|
|
condlog(4, "Reply [%d bytes]",
|