From: bmarzins@sourceware.org
To: dm-cvs@sourceware.org, dm-devel@redhat.com
Subject: multipath-tools libmultipath/config.c libmulti ...
Date: 15 Dec 2007 00:27:41 -0000 [thread overview]
Message-ID: <20071215002741.21134.qmail@sourceware.org> (raw)
CVSROOT: /cvs/dm
Module name: multipath-tools
Branch: RHEL5_FC6
Changes by: bmarzins@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;
}
next reply other threads:[~2007-12-15 0:27 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-15 0:27 bmarzins [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-07-11 23:03 multipath-tools libmultipath/config.c libmulti bmarzins
2011-10-27 21:36 bmarzins
2007-11-10 0:02 bmarzins
2006-12-01 23:45 bmarzins
2006-11-30 23:25 bmarzins
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071215002741.21134.qmail@sourceware.org \
--to=bmarzins@sourceware.org \
--cc=dm-cvs@sourceware.org \
--cc=dm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.