Hi, I have a new version of the namespace patches which actually works :)

All comments(good and mostly bad :) ) is greatly appreciated.

Best regards,
Marian

On 04/03/2014 04:48 PM, Marian Marinov wrote:
> Hello guys,
> I'm working a lot with Linux Containers(LXC) and find it extremely nice to have the ability to rsync files from the host machine to the container without the need of SSH.
>
> What I did was a simple patch, which added the new option --mount-ns-pid=PID and also added a call to setns() in the > do_fork() function.
>
> The idea is, that rsync will use the PID to create a path (/proc/PID/ns/mnt), open that path and give the file descriptor to setns(), which in turn will switch to the new mount namespace and so, the file operations will be done in > the new mount namespace instead of the host's own mount namespace.
>
> Are you interested in such functionality for rsync?
>
> If you are interested, can we discuss the questions bellow?
>
> - Can someone tell me what is the accepted way of accepting patches?
> I currently have the patches done for the 3.0.9 branch and for 3.1.0 branch.
>
> - setns() is found only on newer libc versions.
> I have copied the implementation from the LXC project, but with a small change, if setns is not supported on the > machine at all it returns error. I have placed the implementation in rsync.h, but what would be the proper place for it?
>
> - should I add configure option for this new functionality?
>
> Thank you, for your comments.
>
> Best regards,
> Marian
>From a6924ebed66298c02861130acfce73b0b1397aa5 Mon Sep 17 00:00:00 2001
From: Marian Marinov <m...@yuhu.biz>
Date: Thu, 3 Apr 2014 08:37:17 +0300
Subject: [PATCH 1/3] options.c: Add the --mount-ns-pid option This option is
 used to give a PID from which Rsync must get the mount namespace to which to
 switch to. This is used for copying files to directories in different mount
 namespaces.

---
 options.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/options.c b/options.c
index dc9e62a..7acf01b 100644
--- a/options.c
+++ b/options.c
@@ -122,6 +122,7 @@ int blocking_io = -1;
 int checksum_seed = 0;
 int inplace = 0;
 int delay_updates = 0;
+int mount_ns_pid = 0;
 long block_size = 0; /* "long" because popt can't set an int32. */
 char *skip_compress = NULL;
 item_list dparam_list = EMPTY_ITEM_LIST;
@@ -790,6 +791,7 @@ void usage(enum logcode F)
   rprintf(F,"     --log-file-format=FMT   log updates using the specified FMT\n");
   rprintf(F,"     --password-file=FILE    read daemon-access password from FILE\n");
   rprintf(F,"     --list-only             list the files instead of copying them\n");
+  rprintf(F,"     --mount-ns-pid=PID      pid of the mount namespace to change to\n");
   rprintf(F,"     --bwlimit=RATE          limit socket I/O bandwidth\n");
 #ifdef HAVE_SETVBUF
   rprintf(F,"     --outbuf=N|L|B          set output buffering to None, Line, or Block\n");
@@ -1035,6 +1037,7 @@ static struct poptOption long_options[] = {
   {"outbuf",           0,  POPT_ARG_STRING, &outbuf_mode, 0, 0, 0 },
 #endif
   {"remote-option",   'M', POPT_ARG_STRING, 0, 'M', 0, 0 },
+  {"mount-ns-pid",     0,  POPT_ARG_INT,    &mount_ns_pid, 0, 0, 0 },
   {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
   {"checksum-seed",    0,  POPT_ARG_INT,    &checksum_seed, 0, 0, 0 },
   {"server",           0,  POPT_ARG_NONE,   0, OPT_SERVER, 0, 0 },
-- 
1.8.4

>From c56a6827531642626f8deaeec344af933fa68f52 Mon Sep 17 00:00:00 2001
From: Marian Marinov <m...@yuhu.biz>
Date: Sat, 12 Apr 2014 02:57:25 +0300
Subject: [PATCH 2/3] rsync.h: Added setns support for machines with older libc

---
 rsync.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/rsync.h b/rsync.h
index 205029b..5be3108 100644
--- a/rsync.h
+++ b/rsync.h
@@ -1291,3 +1291,23 @@ char *getpass(const char *prompt);
 #ifdef MAINTAINER_MODE
 const char *get_panic_action(void);
 #endif
+
+// This is a hack to make rsync build with setns for x86_64 architecture
+// We should fix the headers
+#define __NR_setns 308
+
+/* Define setns() if missing from the C library */
+#ifndef HAVE_SETNS
+static inline int setns(int fd, int nstype)
+{
+#ifdef __NR_setns
+	return syscall(__NR_setns, fd, nstype);
+#elif defined(__NR_set_ns)
+	return syscall(__NR_set_ns, fd, nstype);
+#else
+#error No setns implementation found
+	errno = ENOSYS;
+	return -1;
+#endif
+}
+#endif
-- 
1.8.4

>From 03ca519acaa9b00a802b32b9962a5eddbfab0fa9 Mon Sep 17 00:00:00 2001
From: Marian Marinov <m...@yuhu.biz>
Date: Sat, 12 Apr 2014 02:57:48 +0300
Subject: [PATCH 3/3] main.c: Added handling of the mount_ns_pid option. We now
 change the mount namespace just before we try to change the directory for the
 first time.

---
 main.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/main.c b/main.c
index e7a13f7..2e91874 100644
--- a/main.c
+++ b/main.c
@@ -1568,6 +1568,19 @@ int main(int argc,char *argv[])
 	SIGACTION(SIGXFSZ, SIG_IGN);
 #endif
 
+	/* Change the mount namespace here, so both the parent and child
+	 * processes can share the same new mount namespace. */
+	if (mount_ns_pid != 0) {
+		char path[26] = {0};
+		int ret = 0;
+		int fd = -1;
+		ret = snprintf(path, 26, "/proc/%d/ns/mnt", mount_ns_pid);
+		if (ret < 0)
+			return -1;
+		fd = open(path, O_NONBLOCK);
+		ret = setns(fd, 0);
+	}
+
 	/* Initialize change_dir() here because on some old systems getcwd
 	 * (implemented by forking "pwd" and reading its output) doesn't
 	 * work when there are other child processes.  Also, on all systems
-- 
1.8.4

-- 
Please use reply-all for most replies to avoid omitting the mailing list.
To unsubscribe or change options: https://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html

Reply via email to