[dm-devel] multipath-tools libmultipath/config.c libmulti ...
bmarzins at sourceware.org
bmarzins at sourceware.org
Sat Dec 15 00:27:41 UTC 2007
CVSROOT: /cvs/dm
Module name: multipath-tools
Branch: RHEL5_FC6
Changes by: bmarzins at sourceware.org 2007-12-15 00:27:40
Modified files:
libmultipath : config.c config.h dict.c
multipathd : Makefile main.c
Added files:
multipathd : clone_platform.h copy.c copy.h
Log message:
Add private namespace and callout cache support back to multipath. This seems
less invasive than the libprio work in upstream, which will go into the next
major release. Fixes bz #355961
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/libmultipath/config.c.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.19.2.3&r2=1.19.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/libmultipath/config.h.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.18.2.1&r2=1.18.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/libmultipath/dict.c.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.17.2.2&r2=1.17.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/multipathd/clone_platform.h.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=NONE&r2=1.4.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/multipathd/copy.c.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=NONE&r2=1.5.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/multipathd/copy.h.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=NONE&r2=1.4.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/multipathd/Makefile.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.14&r2=1.14.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/multipathd/main.c.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.69.2.2&r2=1.69.2.3
--- multipath-tools/libmultipath/config.c 2007/11/10 00:01:59 1.19.2.3
+++ multipath-tools/libmultipath/config.c 2007/12/15 00:27:39 1.19.2.4
@@ -20,6 +20,57 @@
#include "blacklist.h"
#include "defaults.h"
+/*
+ * helper function to draw a list of callout binaries found in the config file
+ */
+extern int
+push_callout(char * callout)
+{
+#if DAEMON
+ int i;
+ char *bin;
+ char *p;
+
+ /*
+ * purge command line arguments
+ */
+ p = callout;
+
+ while (*p != ' ' && *p != '\0')
+ p++;
+
+ if (!conf->binvec)
+ conf->binvec = vector_alloc();
+
+
+ if (!conf->binvec)
+ return 1;
+
+ /*
+ * if this callout is already stored in binvec, don't store it twice
+ */
+ vector_foreach_slot (conf->binvec, bin, i)
+ if (memcmp(bin, callout, p - callout) == 0)
+ return 0;
+
+ /*
+ * else, store it
+ */
+ bin = MALLOC((p - callout) + 1);
+
+ if (!bin)
+ return 1;
+
+ strncpy(bin, callout, p - callout);
+
+ if (!vector_alloc_slot(conf->binvec))
+ return 1;
+
+ vector_set_slot(conf->binvec, bin);
+#endif
+ return 0;
+}
+
static struct hwentry *
find_hwe_strmatch (vector hwtable, char * vendor, char * product)
{
@@ -255,10 +306,12 @@
if (!dhwe->product || !(hwe->product = set_param_str(dhwe->product)))
goto out;
- if (dhwe->getuid && !(hwe->getuid = set_param_str(dhwe->getuid)))
+ if (dhwe->getuid && (!(hwe->getuid = set_param_str(dhwe->getuid)) ||
+ push_callout(dhwe->getuid)))
goto out;
- if (dhwe->getprio && !(hwe->getprio = set_param_str(dhwe->getprio)))
+ if (dhwe->getprio && (!(hwe->getprio = set_param_str(dhwe->getprio)) ||
+ push_callout(dhwe->getprio)))
goto out;
if (dhwe->features && !(hwe->features = set_param_str(dhwe->features)))
@@ -337,6 +390,7 @@
free_mptable(conf->mptable);
free_hwtable(conf->hwtable);
free_keywords(conf->keywords);
+ free_strvec(conf->binvec);
FREE(conf);
}
@@ -435,8 +489,11 @@
if (conf->udev_dir == NULL)
conf->udev_dir = set_default(DEFAULT_UDEVDIR);
- if (conf->getuid == NULL)
+ if (conf->getuid == NULL){
conf->getuid = set_default(DEFAULT_GETUID);
+ if (push_callout(conf->getuid))
+ goto out;
+ }
if (conf->features == NULL)
conf->features = set_default(DEFAULT_FEATURES);
--- multipath-tools/libmultipath/config.h 2007/01/10 20:08:08 1.18.2.1
+++ multipath-tools/libmultipath/config.h 2007/12/15 00:27:39 1.18.2.2
@@ -76,6 +76,7 @@
vector keywords;
vector mptable;
vector hwtable;
+ vector binvec;
vector blist_devnode;
vector blist_wwid;
@@ -87,6 +88,8 @@
struct config * conf;
+extern int push_callout(char * callout);
+
struct hwentry * find_hwe (vector hwtable, char * vendor, char * product);
struct mpentry * find_mpe (char * wwid);
char * get_mpe_wwid (char * alias);
--- multipath-tools/libmultipath/dict.c 2007/11/10 00:01:59 1.17.2.2
+++ multipath-tools/libmultipath/dict.c 2007/12/15 00:27:39 1.17.2.3
@@ -78,7 +78,7 @@
if (!conf->getuid)
return 1;
- return 0;
+ return push_callout(conf->getuid);
}
static int
@@ -93,9 +93,10 @@
!strcmp(conf->getprio, "none")) {
FREE(conf->getprio);
conf->getprio = NULL;
+ return 0;
}
- return 0;
+ return push_callout(conf->getprio);
}
static int
@@ -510,7 +511,7 @@
if (!hwe->getuid)
return 1;
- return 0;
+ return push_callout(hwe->getuid);
}
static int
@@ -597,9 +598,10 @@
if (strlen(hwe->getprio) == 4 && !strcmp(hwe->getprio, "none")) {
FREE(hwe->getprio);
hwe->getprio = NULL;
+ return 0;
}
- return 0;
+ return push_callout(hwe->getprio);
}
static int
--- multipath-tools/multipathd/Makefile 2006/06/06 18:32:44 1.14
+++ multipath-tools/multipathd/Makefile 2007/12/15 00:27:39 1.14.2.1
@@ -19,7 +19,7 @@
#
# object files
#
-OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o \
+OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o copy.o cli_handlers.o \
$(MULTIPATHLIB)-glibc.a $(CHECKERSLIB)-glibc.a \
--- multipath-tools/multipathd/main.c 2007/06/15 19:03:02 1.69.2.2
+++ multipath-tools/multipathd/main.c 2007/12/15 00:27:40 1.69.2.3
@@ -10,6 +10,7 @@
#include <wait.h>
#include <sys/mman.h>
#include <sys/types.h>
+#include <sys/mount.h>
#include <fcntl.h>
#include <errno.h>
@@ -57,10 +58,14 @@
#include "cli_handlers.h"
#include "lock.h"
#include "waiter.h"
+#include "clone_platform.h"
+#include "copy.h"
#define FILE_NAME_SIZE 256
#define CMDSIZE 160
+#define CALLOUT_DIR "/var/cache/multipathd"
+
#define LOG_MSG(a,b) \
if (strlen(b)) condlog(a, "%s: %s", pp->dev, b);
@@ -746,6 +751,9 @@
if (status != 0)
fprintf(stderr, "bad exit status. see daemon.log\n");
+ condlog(3, "umount ramfs");
+ umount(CALLOUT_DIR);
+
condlog(3, "unlink pidfile");
unlink(DEFAULT_PIDFILE);
@@ -1179,6 +1187,108 @@
return NULL;
}
+
+#ifdef CLONE_NEWNS
+static int
+prepare_namespace(void)
+{
+ mode_t mode = S_IRWXU;
+ struct stat * buf;
+ char ramfs_args[64];
+ int i;
+ int fd;
+ char * bin;
+ size_t size = 10;
+ struct stat statbuf;
+
+ if (!conf->binvec)
+ return 0;
+ buf = (struct stat *)MALLOC(sizeof(struct stat));
+
+ /*
+ * create a temp mount point for ramfs
+ */
+ if (stat(CALLOUT_DIR, buf) < 0) {
+ if (mkdir(CALLOUT_DIR, mode) < 0) {
+ condlog(0, "cannot create " CALLOUT_DIR);
+ FREE(buf);
+ return -1;
+ }
+ condlog(4, "created " CALLOUT_DIR);
+ }
+ FREE(buf);
+
+ /*
+ * compute the optimal ramdisk size
+ */
+ vector_foreach_slot (conf->binvec, bin,i) {
+ if ((fd = open(bin, O_RDONLY)) < 0) {
+ condlog(0, "cannot open %s : %s\n", bin,
+ strerror(errno));
+ continue;
+ }
+ if (fstat(fd, &statbuf) < 0) {
+ condlog(0, "cannot stat %s", bin);
+ return -1;
+ }
+ size += statbuf.st_size;
+ close(fd);
+ }
+ condlog(3, "ramfs maxsize is %u", (unsigned int) size);
+
+ /*
+ * mount the ramfs
+ */
+ if (safe_sprintf(ramfs_args, "maxsize=%u", (unsigned int) size)) {
+ condlog(0, "ramfs_args too small\n");
+ return -1;
+ }
+ if (mount(NULL, CALLOUT_DIR, "ramfs", MS_SYNCHRONOUS, ramfs_args) < 0) {
+ condlog(0, "cannot mount ramfs on " CALLOUT_DIR);
+ return -1;
+ }
+ condlog(4, "mount ramfs on " CALLOUT_DIR);
+
+ /*
+ * populate the ramfs with callout binaries
+ */
+ vector_foreach_slot (conf->binvec, bin,i) {
+ if (copytodir(bin, CALLOUT_DIR) < 0) {
+ condlog(0, "cannot copy %s in ramfs : %s", bin,
+ strerror(errno));
+ continue;
+ }
+ condlog(4, "cp %s in ramfs", bin);
+ }
+ free_strvec(conf->binvec);
+ conf->binvec = NULL;
+
+ /*
+ * bind the ramfs to :
+ * /sbin : default home of multipath ...
+ * /bin : default home of scsi_id ...
+ * /tmp : home of scsi_id temp files
+ */
+ if (mount(CALLOUT_DIR, "/sbin", NULL, MS_BIND, NULL) < 0) {
+ condlog(0, "cannot bind ramfs on /sbin");
+ return -1;
+ }
+ condlog(4, "bind ramfs on /sbin");
+ if (mount(CALLOUT_DIR, "/bin", NULL, MS_BIND, NULL) < 0) {
+ condlog(0, "cannot bind ramfs on /bin");
+ return -1;
+ }
+ condlog(4, "bind ramfs on /bin");
+ if (mount(CALLOUT_DIR, "/tmp", NULL, MS_BIND, NULL) < 0) {
+ condlog(0, "cannot bind ramfs on /tmp");
+ return -1;
+ }
+ condlog(4, "bind ramfs on /tmp");
+
+ return 0;
+}
+#endif
+
static void *
signal_set(int signo, void (*func) (int))
{
@@ -1263,13 +1373,46 @@
fclose(fp);
}
+static void
+setup_daemon(void)
+{
+ int in_fd, out_fd;
+
+ in_fd = open("/dev/null", O_RDONLY);
+ if (in_fd < 0){
+ fprintf(stderr, "cannot open /dev/null for input : %s\n",
+ strerror(errno));
+ _exit(0);
+ }
+ out_fd = open("/dev/console", O_WRONLY);
+ if (out_fd < 0){
+ fprintf(stderr, "cannot open /dev/console for output : %s\n",
+ strerror(errno));
+ _exit(0);
+ }
+
+ close(STDIN_FILENO);
+ dup(in_fd);
+ close(STDOUT_FILENO);
+ dup(out_fd);
+ close(STDERR_FILENO);
+ dup(out_fd);
+
+ close(in_fd);
+ close(out_fd);
+ chdir("/");
+ umask(0);
+}
+
static int
child (void * param)
{
pthread_t check_thr, uevent_thr, uxlsnr_thr;
pthread_attr_t attr;
struct vectors * vecs;
+ unsigned long new_ns = (unsigned long)param;
+ setup_daemon();
mlockall(MCL_CURRENT | MCL_FUTURE);
if (logsink)
@@ -1309,6 +1452,12 @@
condlog(0, "can not find sysfs mount point");
exit(1);
}
+#ifdef CLONE_NEWNS
+ if (new_ns && prepare_namespace() < 0) {
+ condlog(0, "cannot prepare namespace");
+ exit(1);
+ }
+#endif
/*
* fetch and configure both paths and multipaths
@@ -1376,7 +1525,9 @@
daemonize(void)
{
int pid;
- int in_fd, out_fd;
+#ifdef CLONE_NEWNS
+ void *child_stack;
+#endif
if( (pid = fork()) < 0){
fprintf(stderr, "Failed first fork : %s\n", strerror(errno));
@@ -1387,36 +1538,37 @@
setsid();
- if ( (pid = fork()) < 0)
- fprintf(stderr, "Failed second fork : %s\n", strerror(errno));
- else if (pid != 0)
- _exit(0);
+#ifdef CLONE_NEWNS
- in_fd = open("/dev/null", O_RDONLY);
- if (in_fd < 0){
- fprintf(stderr, "cannot open /dev/null for input : %s\n",
+ child_stack = (void *)malloc(CHILD_STACK_SIZE);
+ if (!child_stack) {
+ fprintf(stderr, "Failed to allocate child stack : %s\n",
strerror(errno));
- _exit(0);
+ _exit(1);
}
- out_fd = open("/dev/console", O_WRONLY);
- if (out_fd < 0){
- fprintf(stderr, "cannot open /dev/console for output : %s\n",
- strerror(errno));
- _exit(0);
+# if defined(__hppa__) || defined(__powerpc64__)
+ pid = clone(child, child_stack, CLONE_NEWNS, (void *)1);
+# elif defined(__ia64__)
+ pid = clone2(child, child_stack, CHILD_STACK_SIZE, CLONE_NEWNS,
+ (void *)1, NULL, NULL, NULL);
+# else
+ pid = clone(child, child_stack + CHILD_STACK_SIZE, CLONE_NEWNS,
+ (void *)1);
+# endif
+ if (pid < 0) {
+ fprintf(stderr, "Clone failed : %s\n", strerror(errno));
+ _exit(1);
+ }
+ _exit(0);
+#else
+ if ( (pid = fork()) < 0){
+ fprintf(stderr, "Failed second fork : %s\n", strerror(errno));
+ _exit(1);
}
-
- close(STDIN_FILENO);
- dup(in_fd);
- close(STDOUT_FILENO);
- dup(out_fd);
- close(STDERR_FILENO);
- dup(out_fd);
-
- close(in_fd);
- close(out_fd);
- chdir("/");
- umask(0);
- return 0;
+ if (pid != 0)
+ _exit(0);
+ return child((void *)0);
+#endif
}
int
@@ -1466,18 +1618,14 @@
}
if (!logsink)
- err = 0;
- else
+ return child((void *)0);
+ else{
err = daemonize();
+ }
if (err < 0)
- /* error */
- exit(1);
- else if (err > 0)
- /* parent dies */
- exit(0);
- else
- /* child lives */
- return (child(NULL));
+ return 1;
+ /* parent dies */
+ return 0;
}
More information about the dm-devel
mailing list