All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2) posix-timers: make it configurable
@ 2016-09-14 20:46 Nicolas Pitre
  2016-09-14 20:58 ` Josh Triplett
  2016-09-14 22:34 ` kbuild test robot
  0 siblings, 2 replies; 5+ messages in thread
From: Nicolas Pitre @ 2016-09-14 20:46 UTC (permalink / raw)
  To: Thomas Gleixner, John Stultz; +Cc: Josh Triplett, Richard Cochran, linux-kernel

Many embedded systems typically don't need them.  This removes about
22KB from the kernel binary size on ARM when configured out.

Corresponding syscalls are routed to a stub logging the attempt to
use those syscalls which should be enough of a clue if they were
disabled without proper consideration. They are: timer_create,
timer_gettime: timer_getoverrun, timer_settime, timer_delete,
clock_adjtime.

The clock_settime, clock_gettime, clock_getres and clock_nanosleep syscalls
are replaced by simple wrappers compatible with CLOCK_REALTIME,
CLOCK_MONOTONIC and CLOCK_BOOTTIME only.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---

Changes from RFC/v1:

- Stubbed-out functions moved to static inlines.
- The timer signal handling code is now removed.
- The list of removed syscalls is explicitly documented.
- The clock_settime, clock_gettime, clock_getres and clock_nanosleep 
  syscalls are minimally preserved as this required very little code.

I'm now able to boot a copy of Fedora 21 with this patch and 
CONFIG_POSIX_TIMERS=n with no apparent issues.

diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index ee3de3421f..00e6098e9a 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -6,7 +6,7 @@ menu "PTP clock support"
 
 config PTP_1588_CLOCK
 	tristate "PTP clock support"
-	depends on NET
+	depends on NET && POSIX_TIMERS
 	select PPS
 	select NET_PTP_CLASSIFY
 	help
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 62d44c1760..9a193243f2 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -118,6 +118,8 @@ struct k_clock {
 extern struct k_clock clock_posix_cpu;
 extern struct k_clock clock_posix_dynamic;
 
+#ifdef CONFIG_POSIX_TIMERS
+
 void posix_timers_register_clock(const clockid_t clock_id, struct k_clock *new_clock);
 
 /* function to call to trigger timer event */
@@ -135,4 +137,26 @@ long clock_nanosleep_restart(struct restart_block *restart_block);
 
 void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
 
+#else
+
+#include <linux/random.h>
+
+static inline void posix_timers_register_clock(const clockid_t clock_id,
+					       struct k_clock *new_clock) {}
+static inline int posix_timer_event(struct k_itimer *timr, int si_private)
+{ return 0; }
+static inline void run_posix_cpu_timers(struct task_struct *task) {}
+static inline void posix_cpu_timers_exit(struct task_struct *task)
+{
+	add_device_randomness((const void*) &task->se.sum_exec_runtime,
+			      sizeof(unsigned long long));
+}
+static inline void posix_cpu_timers_exit_group(struct task_struct *task) {}
+static inline void set_process_cpu_timer(struct task_struct *task,
+		unsigned int clock_idx, cputime_t *newval, cputime_t *oldval) {}
+static inline void update_rlimit_cpu(struct task_struct *task,
+				     unsigned long rlim_new) {}
+
+#endif
+
 #endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 54182d52a0..39a1d6d3f5 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2924,8 +2924,13 @@ static inline void exit_thread(struct task_struct *tsk)
 extern void exit_files(struct task_struct *);
 extern void __cleanup_sighand(struct sighand_struct *);
 
+#ifdef CONFIG_POSIX_TIMERS
 extern void exit_itimers(struct signal_struct *);
 extern void flush_itimer_signals(void);
+#else
+static inline void exit_itimers(struct signal_struct *s) {}
+static inline void flush_itimer_signals(void) {}
+#endif
 
 extern void do_group_exit(int);
 
@@ -3382,7 +3387,12 @@ static __always_inline bool need_resched(void)
  * Thread group CPU time accounting.
  */
 void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times);
+#ifdef CONFIG_POSIX_TIMERS
 void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times);
+#else
+static inline void thread_group_cputimer(struct task_struct *tsk,
+					 struct task_cputime *times) {}
+#endif
 
 /*
  * Reevaluate whether the task has signals pending delivery.
diff --git a/kernel/signal.c b/kernel/signal.c
index af21afc00d..ea75065e29 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -427,6 +427,7 @@ void flush_signals(struct task_struct *t)
 	spin_unlock_irqrestore(&t->sighand->siglock, flags);
 }
 
+#ifdef CONFIG_POSIX_TIMERS
 static void __flush_itimer_signals(struct sigpending *pending)
 {
 	sigset_t signal, retain;
@@ -460,6 +461,7 @@ void flush_itimer_signals(void)
 	__flush_itimer_signals(&tsk->signal->shared_pending);
 	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
 }
+#endif
 
 void ignore_signals(struct task_struct *t)
 {
@@ -611,6 +613,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
 		 */
 		current->jobctl |= JOBCTL_STOP_DEQUEUED;
 	}
+#ifdef CONFIG_POSIX_TIMERS
 	if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) {
 		/*
 		 * Release the siglock to ensure proper locking order
@@ -622,6 +625,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
 		do_schedule_next_timer(info);
 		spin_lock(&tsk->sighand->siglock);
 	}
+#endif
 	return signr;
 }
 
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index 62824f2fe4..62504a2c9f 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -195,3 +195,21 @@ config HIGH_RES_TIMERS
 
 endmenu
 endif
+
+config POSIX_TIMERS
+	bool "Posix Clocks & timers" if EMBEDDED
+	default y
+	help
+	  This includes native support for POSIX timers to the kernel.
+	  Most embedded systems may have no use for them and therefore they
+	  can be configured out to reduce the size of the kernel image.
+
+	  When this option is disabled, the following syscalls won't be
+	  available: timer_create, timer_gettime: timer_getoverrun,
+	  timer_settime, timer_delete, clock_adjtime. Furthermore, the
+	  clock_settime, clock_gettime, clock_getres and clock_nanosleep
+	  syscalls will be limited to CLOCK_REALTIME and CLOCK_MONOTONIC
+	  only.
+
+	  If unsure say y.
+
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index 49eca0beed..fc26c308f5 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -1,6 +1,12 @@
-obj-y += time.o timer.o hrtimer.o itimer.o posix-timers.o posix-cpu-timers.o
+obj-y += time.o timer.o hrtimer.o itimer.o
 obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o
-obj-y += timeconv.o timecounter.o posix-clock.o alarmtimer.o
+obj-y += timeconv.o timecounter.o alarmtimer.o
+
+ifeq ($(CONFIG_POSIX_TIMERS),y)
+ obj-y += posix-timers.o posix-cpu-timers.o posix-clock.o
+else
+ obj-y += posix-stubs.o
+endif
 
 obj-$(CONFIG_GENERIC_CLOCKEVENTS)		+= clockevents.o tick-common.o
 ifeq ($(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST),y)
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c
new file mode 100644
index 0000000000..442b0a92e0
--- /dev/null
+++ b/kernel/time/posix-stubs.c
@@ -0,0 +1,110 @@
+/*
+ * Dummy stubs used when CONFIG_POSIX_TIMERS=n
+ *
+ * Created by:  Nicolas Pitre, July 2016
+ * Copyright:   (C) 2016 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/syscalls.h>
+#include <linux/ktime.h>
+#include <linux/timekeeping.h>
+
+asmlinkage long sys_ni_posix_timers(void)
+{
+	pr_err_once("process %d (%s) attempted a POSIX timer syscall "
+		    "while CONFIG_POSIX_TIMERS is not set\n",
+		    current->pid, current->comm);
+	return -ENOSYS;
+}
+
+#define SYS_NI(name)  SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers)
+
+SYS_NI(timer_create);
+SYS_NI(timer_gettime);
+SYS_NI(timer_getoverrun);
+SYS_NI(timer_settime);
+SYS_NI(timer_delete);
+SYS_NI(clock_adjtime);
+
+/*
+ * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
+ * as it is easy to remain compatible with little code. CLOCK_BOOTTIME
+ * is also included for convenience as at least systemd uses it.
+ */
+
+SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
+		const struct timespec __user *, tp)
+{
+	struct timespec new_tp;
+
+	if (which_clock != CLOCK_REALTIME)
+		return -EINVAL;
+	if (copy_from_user(&new_tp, tp, sizeof (*tp)))
+		return -EFAULT;
+	return do_sys_settimeofday(&new_tp, NULL);
+}
+
+SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
+		struct timespec __user *,tp)
+{
+	struct timespec kernel_tp;
+
+	switch (which_clock) {
+	case CLOCK_REALTIME: ktime_get_real_ts(&kernel_tp); break;
+	case CLOCK_MONOTONIC: ktime_get_ts(&kernel_tp); break;
+	case CLOCK_BOOTTIME: get_monotonic_boottime(&kernel_tp); break;
+	default: return -EINVAL;
+	}
+	if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))
+		return -EFAULT;
+	return 0;
+}
+
+SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
+{
+	struct timespec rtn_tp = {
+		.tv_sec = 0,
+		.tv_nsec = hrtimer_resolution,
+	};
+
+	switch (which_clock) {
+	case CLOCK_REALTIME:
+	case CLOCK_MONOTONIC:
+	case CLOCK_BOOTTIME:
+		if (copy_to_user(tp, &rtn_tp, sizeof(rtn_tp)))
+			return -EFAULT;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
+		const struct timespec __user *, rqtp,
+		struct timespec __user *, rmtp)
+{
+	struct timespec t;
+
+	switch (which_clock) {
+	case CLOCK_REALTIME:
+	case CLOCK_MONOTONIC:
+	case CLOCK_BOOTTIME:
+		if (copy_from_user(&t, rqtp, sizeof (struct timespec)))
+			return -EFAULT;
+		if (!timespec_valid(&t))
+			return -EINVAL;
+		return hrtimer_nanosleep(&t, rmtp, flags & TIMER_ABSTIME ?
+					 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
+					 which_clock);
+	default:
+		return -EINVAL;
+	}
+}

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2) posix-timers: make it configurable
  2016-09-14 20:46 [PATCH v2) posix-timers: make it configurable Nicolas Pitre
@ 2016-09-14 20:58 ` Josh Triplett
  2016-09-14 21:09   ` Nicolas Pitre
  2016-09-14 22:34 ` kbuild test robot
  1 sibling, 1 reply; 5+ messages in thread
From: Josh Triplett @ 2016-09-14 20:58 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Thomas Gleixner, John Stultz, Richard Cochran, linux-kernel

On Wed, Sep 14, 2016 at 04:46:54PM -0400, Nicolas Pitre wrote:
> Many embedded systems typically don't need them.  This removes about
> 22KB from the kernel binary size on ARM when configured out.
> 
> Corresponding syscalls are routed to a stub logging the attempt to
> use those syscalls which should be enough of a clue if they were
> disabled without proper consideration. They are: timer_create,
> timer_gettime: timer_getoverrun, timer_settime, timer_delete,
> clock_adjtime.
> 
> The clock_settime, clock_gettime, clock_getres and clock_nanosleep syscalls
> are replaced by simple wrappers compatible with CLOCK_REALTIME,
> CLOCK_MONOTONIC and CLOCK_BOOTTIME only.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
> 
> Changes from RFC/v1:
> 
> - Stubbed-out functions moved to static inlines.
> - The timer signal handling code is now removed.
> - The list of removed syscalls is explicitly documented.
> - The clock_settime, clock_gettime, clock_getres and clock_nanosleep 
>   syscalls are minimally preserved as this required very little code.
> 
> I'm now able to boot a copy of Fedora 21 with this patch and 
> CONFIG_POSIX_TIMERS=n with no apparent issues.

This looks quite reasonable.

Does booting a standard distro really require providing clock_settime?

I'd still prefer to see the special-case sys_ni support dropped,
especially since the most common syscalls now remain.  However, if
others want to see it kept, I won't object too strongly; whoever ends up
implementing a common (and optional) version of that infrastructure for
all syscalls can fold this into it.

- Josh Triplett

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2) posix-timers: make it configurable
  2016-09-14 20:58 ` Josh Triplett
@ 2016-09-14 21:09   ` Nicolas Pitre
  2016-09-14 22:16     ` Josh Triplett
  0 siblings, 1 reply; 5+ messages in thread
From: Nicolas Pitre @ 2016-09-14 21:09 UTC (permalink / raw)
  To: Josh Triplett; +Cc: Thomas Gleixner, John Stultz, Richard Cochran, linux-kernel

On Wed, 14 Sep 2016, Josh Triplett wrote:

> On Wed, Sep 14, 2016 at 04:46:54PM -0400, Nicolas Pitre wrote:
> > Many embedded systems typically don't need them.  This removes about
> > 22KB from the kernel binary size on ARM when configured out.
> > 
> > Corresponding syscalls are routed to a stub logging the attempt to
> > use those syscalls which should be enough of a clue if they were
> > disabled without proper consideration. They are: timer_create,
> > timer_gettime: timer_getoverrun, timer_settime, timer_delete,
> > clock_adjtime.
> > 
> > The clock_settime, clock_gettime, clock_getres and clock_nanosleep syscalls
> > are replaced by simple wrappers compatible with CLOCK_REALTIME,
> > CLOCK_MONOTONIC and CLOCK_BOOTTIME only.
> > 
> > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > ---
> > 
> > Changes from RFC/v1:
> > 
> > - Stubbed-out functions moved to static inlines.
> > - The timer signal handling code is now removed.
> > - The list of removed syscalls is explicitly documented.
> > - The clock_settime, clock_gettime, clock_getres and clock_nanosleep 
> >   syscalls are minimally preserved as this required very little code.
> > 
> > I'm now able to boot a copy of Fedora 21 with this patch and 
> > CONFIG_POSIX_TIMERS=n with no apparent issues.
> 
> This looks quite reasonable.
> 
> Does booting a standard distro really require providing clock_settime?

I don't know.  Maybe some date(1) implementation uses it. It is however 
so small that there is no real advantage in explicitly removing it.

> I'd still prefer to see the special-case sys_ni support dropped,
> especially since the most common syscalls now remain.  However, if
> others want to see it kept, I won't object too strongly; whoever ends up
> implementing a common (and optional) version of that infrastructure for
> all syscalls can fold this into it.

Personally, I'd prefer to see more of those configurable syscalls before 
introducing such infrastructure.


Nicolas

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2) posix-timers: make it configurable
  2016-09-14 21:09   ` Nicolas Pitre
@ 2016-09-14 22:16     ` Josh Triplett
  0 siblings, 0 replies; 5+ messages in thread
From: Josh Triplett @ 2016-09-14 22:16 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Thomas Gleixner, John Stultz, Richard Cochran, linux-kernel

On Wed, Sep 14, 2016 at 05:09:53PM -0400, Nicolas Pitre wrote:
> On Wed, 14 Sep 2016, Josh Triplett wrote:
> 
> > On Wed, Sep 14, 2016 at 04:46:54PM -0400, Nicolas Pitre wrote:
> > > Many embedded systems typically don't need them.  This removes about
> > > 22KB from the kernel binary size on ARM when configured out.
> > > 
> > > Corresponding syscalls are routed to a stub logging the attempt to
> > > use those syscalls which should be enough of a clue if they were
> > > disabled without proper consideration. They are: timer_create,
> > > timer_gettime: timer_getoverrun, timer_settime, timer_delete,
> > > clock_adjtime.
> > > 
> > > The clock_settime, clock_gettime, clock_getres and clock_nanosleep syscalls
> > > are replaced by simple wrappers compatible with CLOCK_REALTIME,
> > > CLOCK_MONOTONIC and CLOCK_BOOTTIME only.
> > > 
> > > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > > ---
> > > 
> > > Changes from RFC/v1:
> > > 
> > > - Stubbed-out functions moved to static inlines.
> > > - The timer signal handling code is now removed.
> > > - The list of removed syscalls is explicitly documented.
> > > - The clock_settime, clock_gettime, clock_getres and clock_nanosleep 
> > >   syscalls are minimally preserved as this required very little code.
> > > 
> > > I'm now able to boot a copy of Fedora 21 with this patch and 
> > > CONFIG_POSIX_TIMERS=n with no apparent issues.
> > 
> > This looks quite reasonable.
> > 
> > Does booting a standard distro really require providing clock_settime?
> 
> I don't know.  Maybe some date(1) implementation uses it. It is however 
> so small that there is no real advantage in explicitly removing it.

True at the moment, though dropping it may in the future allow dropping
more of the underlying time infrastructure itself.

> > I'd still prefer to see the special-case sys_ni support dropped,
> > especially since the most common syscalls now remain.  However, if
> > others want to see it kept, I won't object too strongly; whoever ends up
> > implementing a common (and optional) version of that infrastructure for
> > all syscalls can fold this into it.
> 
> Personally, I'd prefer to see more of those configurable syscalls before 
> introducing such infrastructure.

See kernel/sys_ni.c for a *long* list of configurable syscalls,
including widely used syscalls.  (Sockets, UIDs/GIDs, futexes, epoll,
etc)  Those already seem like enough to justify a "this application
wanted to call this syscall but couldn't" mechanism.

- Josh Triplett

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2) posix-timers: make it configurable
  2016-09-14 20:46 [PATCH v2) posix-timers: make it configurable Nicolas Pitre
  2016-09-14 20:58 ` Josh Triplett
@ 2016-09-14 22:34 ` kbuild test robot
  1 sibling, 0 replies; 5+ messages in thread
From: kbuild test robot @ 2016-09-14 22:34 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: kbuild-all, Thomas Gleixner, John Stultz, Josh Triplett,
	Richard Cochran, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2498 bytes --]

Hi Nicolas,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.8-rc6 next-20160914]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Nicolas-Pitre/PATCH-v2-posix-timers-make-it-configurable/20160915-045004
config: sparc64-allnoconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=sparc64 

All errors (new ones prefixed by >>):

   kernel/compat.c: In function 'compat_clock_nanosleep_restart':
>> kernel/compat.c:824:8: error: implicit declaration of function 'clock_nanosleep_restart' [-Werror=implicit-function-declaration]
     err = clock_nanosleep_restart(restart);
           ^
   cc1: some warnings being treated as errors

vim +/clock_nanosleep_restart +824 kernel/compat.c

1711ef38 Toyo Abe        2006-09-29  818  	struct timespec tu;
dce44e03 H. Peter Anvin  2014-02-02  819  	struct compat_timespec __user *rmtp = restart->nanosleep.compat_rmtp;
1711ef38 Toyo Abe        2006-09-29  820  
029a07e0 Thomas Gleixner 2008-02-10  821  	restart->nanosleep.rmtp = (struct timespec __user *) &tu;
1711ef38 Toyo Abe        2006-09-29  822  	oldfs = get_fs();
1711ef38 Toyo Abe        2006-09-29  823  	set_fs(KERNEL_DS);
1711ef38 Toyo Abe        2006-09-29 @824  	err = clock_nanosleep_restart(restart);
1711ef38 Toyo Abe        2006-09-29  825  	set_fs(oldfs);
1711ef38 Toyo Abe        2006-09-29  826  
1711ef38 Toyo Abe        2006-09-29  827  	if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&

:::::: The code at line 824 was first introduced by commit
:::::: 1711ef3866b0360e102327389fe4b76c849bbe83 [PATCH] posix-timers: Fix clock_nanosleep() doesn't return the remaining time in compatibility mode

:::::: TO: Toyo Abe <toyoa@mvista.com>
:::::: CC: Linus Torvalds <torvalds@g5.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 5003 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-09-14 22:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-14 20:46 [PATCH v2) posix-timers: make it configurable Nicolas Pitre
2016-09-14 20:58 ` Josh Triplett
2016-09-14 21:09   ` Nicolas Pitre
2016-09-14 22:16     ` Josh Triplett
2016-09-14 22:34 ` kbuild test robot

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.