All of lore.kernel.org
 help / color / mirror / Atom feed
From: Darshak Shah <darshaks@linux.vnet.ibm.com>
To: Garrett Cooper <yanegomi@gmail.com>
Cc: ltp-list@lists.sourceforge.net
Subject: Re: [LTP] [PATCH] close file descriptors and munmap pages.
Date: Fri, 02 Jul 2010 12:48:43 +0530	[thread overview]
Message-ID: <4C2D92D3.8070001@linux.vnet.ibm.com> (raw)
In-Reply-To: <AANLkTiko2hqAdNNyr6RmmE_sQhEmY71PqjdOzSdcoudc@mail.gmail.com>

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

On 07/02/2010 12:07 PM, Garrett Cooper wrote:
> On Thu, Jul 1, 2010 at 11:25 PM, Darshak Shah
> <darshaks@linux.vnet.ibm.com>  wrote:
>    
>> On 07/01/2010 10:36 PM, Subrata Modak wrote:
>>      
>>> Probably, you would need to fix these:
>>>
>>> patching file testcases/kernel/syscalls/open/open10.c
>>> Hunk #1 FAILED at 282.
>>> Hunk #2 FAILED at 311.
>>> Hunk #3 FAILED at 359.
>>> Hunk #4 FAILED at 389.
>>> Hunk #5 FAILED at 440.
>>> 5 out of 5 hunks FAILED -- saving rejects to file
>>> testcases/kernel/syscalls/open/open10.c.rej
>>> patching file testcases/kernel/syscalls/splice/splice02.c
>>> patch: **** malformed patch at line 229: Passed");
>>>        
>> Dear Subrata,
>>
>> I downloaded the latest ltp from
>> http://ltp.git.sourceforge.net/git/gitweb.cgi?p=ltp/ltp-dev.git;a=tree
>> I used the "snapshot" to download the tgz and patched as following.
>>
>> The patch seems to apply correctly.
>>      
>      Please attach the patch as a file as well as inline. Some MTAs and
> mail clients (like gmail for me) screw up whitespace and other fuzz in
> patches when folks include it inline in email.
> Thanks!
> -Garrett
>    
Attached.

[-- Attachment #2: close-open-fds.diff --]
[-- Type: text/x-patch, Size: 15692 bytes --]

Index: ltp-full-20091231/testcases/kernel/syscalls/open/open10.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/syscalls/open/open10.c
+++ ltp-full-20091231/testcases/kernel/syscalls/open/open10.c
@@ -282,6 +282,7 @@ int main(int ac, char *av[])
 			tst_resm(TFAIL|TERRNO, "open(%s) failed", nosetgid_A);
 			local_flag = FAILED;
 		}
+		close(ret);
 
 		if ((ret = stat(nosetgid_A, &buf)) < 0) {
 			tst_resm(TFAIL|TERRNO, "stat(%s) failed", nosetgid_A);
@@ -310,6 +311,7 @@ int main(int ac, char *av[])
 			tst_resm(TFAIL|TERRNO, "open(%s) failed", setgid_A);
 			local_flag = FAILED;
 		}
+		close(ret);
 
 		if ((ret = stat(setgid_A, &buf)) < 0) {
 			tst_resm(TFAIL|TERRNO, "stat(%s) failed", setgid_A);
@@ -357,6 +359,7 @@ int main(int ac, char *av[])
 			tst_resm(TFAIL|TERRNO, "open(%s) failed", nosetgid_B);
 			local_flag = FAILED;
 		}
+		close(ret);
 
 		if ((ret = stat(nosetgid_B, &buf)) < 0) {
 			tst_resm(TFAIL|TERRNO, "stat(%s) failed", nosetgid_B);
@@ -386,6 +389,7 @@ int main(int ac, char *av[])
 			tst_resm(TFAIL|TERRNO, "open(%s) failed", setgid_B);
 			local_flag = FAILED;
 		}
+		close(ret);
 
 		if ((ret = stat(setgid_B, &buf)) < 0) {
 			tst_resm(TFAIL|TERRNO, "stat(%s) failed", setgid_B);
@@ -436,6 +440,7 @@ int main(int ac, char *av[])
 			tst_resm(TFAIL|TERRNO, "open(%s) failed", root_setgid_B);
 			local_flag = FAILED;
 		}
+		close(ret);
 
 		if ((ret = stat(root_setgid_B, &buf)) < 0) {
 			tst_resm(TFAIL|TERRNO, "stat(%s) failed", root_setgid_B);
Index: ltp-full-20091231/testcases/kernel/syscalls/splice/splice02.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/syscalls/splice/splice02.c
+++ ltp-full-20091231/testcases/kernel/syscalls/splice/splice02.c
@@ -148,6 +148,7 @@ int main(int ac, char **av) {
 	    } else
             if (TEST_RETURN == 0){
 							tst_resm(TPASS, "splice() system call Passed");
+		close(fd);
 	        cleanup();
 	        tst_exit();
 	    }
Index: ltp-full-20091231/testcases/kernel/io/direct_io/diotest2.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/io/direct_io/diotest2.c
+++ ltp-full-20091231/testcases/kernel/io/direct_io/diotest2.c
@@ -275,6 +275,7 @@ static void setup(void)
 	if ((fd1 = open(filename, O_DIRECT, 0600)) < 0) {
 		tst_brkm(TCONF, cleanup, "O_DIRECT is not supported by this filesystem. %s", strerror(errno));
 	}
+	close(fd1);
 
 }
 
Index: ltp-full-20091231/testcases/kernel/io/direct_io/diotest3.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/io/direct_io/diotest3.c
+++ ltp-full-20091231/testcases/kernel/io/direct_io/diotest3.c
@@ -363,6 +363,7 @@ static void setup(void)
 	if ((fd1 = open(filename, O_DIRECT, 0600)) < 0) {
 		tst_brkm(TCONF, cleanup, "O_DIRECT is not supported by this filesystem. %s", strerror(errno));
 	}
+	close(fd1);
 }
 
 static void cleanup(void)
Index: ltp-full-20091231/testcases/kernel/io/direct_io/diotest5.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/io/direct_io/diotest5.c
+++ ltp-full-20091231/testcases/kernel/io/direct_io/diotest5.c
@@ -309,6 +309,7 @@ static void setup(void)
 	if ((fd1 = open(filename, O_DIRECT, 0600)) < 0) {
 		tst_brkm(TCONF, cleanup, "O_DIRECT is not supported by this filesystem. %s", strerror(errno));
 	}
+	close(fd1);
 }
 
 static void cleanup(void)
Index: ltp-full-20091231/testcases/kernel/io/direct_io/diotest6.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/io/direct_io/diotest6.c
+++ ltp-full-20091231/testcases/kernel/io/direct_io/diotest6.c
@@ -387,6 +387,7 @@ static void setup(void)
 	if ((fd1 = open(filename, O_DIRECT, 0600)) < 0) {
 		tst_brkm(TCONF, cleanup, "O_DIRECT is not supported by this filesystem. %s", strerror(errno));
 	}
+	close(fd1);
 }
 
 static void cleanup(void)
Index: ltp-full-20091231/testcases/kernel/mem/mmapstress/mmapstress02.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/mem/mmapstress/mmapstress02.c
+++ ltp-full-20091231/testcases/kernel/mem/mmapstress/mmapstress02.c
@@ -165,6 +165,10 @@ main(int argc, char *argv[]) {
 		CLEANERROR("close failed");
 		anyfail();
 	}
+	if (munmap(mmapaddr, pagesize) == -1) {
+		CLEANERROR("munmap failed");
+		anyfail();
+	}
 	if (unlink(tmpname) == -1) {
 		ERROR("unlink failed");
 		anyfail();
Index: ltp-full-20091231/testcases/kernel/mem/mmapstress/mmapstress01.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/mem/mmapstress/mmapstress01.c
+++ ltp-full-20091231/testcases/kernel/mem/mmapstress/mmapstress01.c
@@ -590,7 +590,11 @@ child_mapper(char *file, unsigned procno
 			anyfail();
 		}
 	}
-
+	if (munmap(maddr, mapsize) == -1) {
+		perror("munmap failed");
+		local_flag = FAILED;
+		anyfail();
+	}
 	exit(0);
 }
 
@@ -694,6 +698,7 @@ fileokay(char *file, uchar_t *expbuf)
 			}
 		}
 	}
+	close(fd);
 				
 	return 1;
 }
Index: ltp-full-20091231/testcases/kernel/mem/mmapstress/mmapstress05.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/mem/mmapstress/mmapstress05.c
+++ ltp-full-20091231/testcases/kernel/mem/mmapstress/mmapstress05.c
@@ -61,6 +61,15 @@ void ok_exit();
 #define ERROR(M)	(void)fprintf(stderr, "%s:  errno = %d; " M "\n", \
 				progname, errno);
 #define CLEAN	(void)close(fd); \
+		if (munmap(mmapaddr+pagesize, pagesize) == -1) { \
+			ERROR("munmap failed"); \
+		} \
+		if (munmap(mmapaddr, pagesize) == -1) { \
+			ERROR("munmap failed"); \
+		} \
+		if (munmap(mmapaddr+2*pagesize, pagesize) == -1) { \
+			ERROR("munmap failed"); \
+		} \
 		if (unlink(tmpname)) { \
 			ERROR("couldn't clean up temp file"); \
 		}
Index: ltp-full-20091231/testcases/kernel/mem/mmapstress/mmapstress10.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/mem/mmapstress/mmapstress10.c
+++ ltp-full-20091231/testcases/kernel/mem/mmapstress/mmapstress10.c
@@ -154,6 +154,15 @@ unsigned do_offset = 0;
 unsigned pattern = 0;
 char filename[64];
 
+void clean_mapper(int sig);
+void clean_writer(int sig);
+
+int fd_mapper = 0;
+caddr_t maddr_mapper;
+size_t mapsize_mapper;
+
+int fd_writer = 0;
+
 int
 main(int argc, char *argv[])
 {
@@ -484,8 +493,8 @@ main(int argc, char *argv[])
 
 cleanup:
 	for (i = 0; i < nprocs; i++)
-		(void)kill(pidarray[i], SIGKILL);
-	(void)kill(wr_pid, SIGKILL);
+		(void)kill(pidarray[i], SIGUSR1);
+	(void)kill(wr_pid, SIGUSR1);
 
 	while (wait(&wait_stat) != -1 || errno != ECHILD)
 		continue;
@@ -531,9 +540,7 @@ child_mapper(char *file, unsigned procno
 	off_t offset;
 #endif /* LARGE_FILE */
 	size_t validsize;
-	size_t mapsize;
-	caddr_t maddr, paddr;
-	int fd;
+	caddr_t paddr;
 	int pagesize = sysconf(_SC_PAGE_SIZE);
 	unsigned randpage;
 	unsigned int seed;
@@ -542,25 +549,38 @@ child_mapper(char *file, unsigned procno
 	unsigned mappages;
 	unsigned mapflags;
 	unsigned i;
+	struct sigaction sa_mapper;
 
 	mapflags = MAP_SHARED;
 
 	seed = initrand();		/* initialize random seed */
 
+	sa_mapper.sa_handler = clean_mapper;
+	sa_mapper.sa_flags = 0;
+	if (sigemptyset(&sa_mapper.sa_mask)) {
+		perror("sigempty error");
+                anyfail();
+	}
+
+	if (sigaction(SIGUSR1, &sa_mapper, 0) == -1) {
+		perror("sigaction error SIGUSR1");
+                anyfail();
+	}
+
 
 #ifdef LARGE_FILE
-	if ((fd = open64(file, O_RDWR)) == -1) {
+	if ((fd_mapper = open64(file, O_RDWR)) == -1) {
 #else /* LARGE_FILE */
-	if ((fd = open(file, O_RDWR)) == -1) {
+	if ((fd_mapper = open(file, O_RDWR)) == -1) {
 #endif /* LARGE_FILE */
 		perror("open error");
                 anyfail();
 	}
 
 #ifdef LARGE_FILE
-	if (fstat64(fd, &statbuf) == -1) {
+	if (fstat64(fd_mapper, &statbuf) == -1) {
 #else /* LARGE_FILE */
-	if (fstat(fd, &statbuf) == -1) {
+	if (fstat(fd_mapper, &statbuf) == -1) {
 #endif /* LARGE_FILE */
 		perror("stat error");
                 anyfail();
@@ -571,29 +591,29 @@ child_mapper(char *file, unsigned procno
 		fprintf(stderr, "size_t overflow when setting up map\n");
                 anyfail();
 	}
-	mapsize = (size_t)(statbuf.st_size - sparseoffset);
-	mappages = roundup(mapsize, pagesize) / pagesize;
+	mapsize_mapper = (size_t)(statbuf.st_size - sparseoffset);
+	mappages = roundup(mapsize_mapper, pagesize) / pagesize;
 	offset = sparseoffset;
 	if (do_offset) {
 		int pageoffset = lrand48() % mappages;
 		int byteoffset = pageoffset * pagesize;
 		offset += byteoffset;
-		mapsize -= byteoffset;
+		mapsize_mapper -= byteoffset;
 		mappages -= pageoffset;
 	}
 
 #ifdef LARGE_FILE
-	if ((maddr = mmap64(0, mapsize, PROT_READ|PROT_WRITE,
-			mapflags, fd, offset)) == (caddr_t)-1) {
+	if ((maddr_mapper = mmap64(0, mapsize_mapper, PROT_READ|PROT_WRITE,
+			mapflags, fd_mapper, offset)) == (caddr_t)-1) {
 #else /* LARGE_FILE */
-	if ((maddr = mmap(0, mapsize, PROT_READ|PROT_WRITE,
-			mapflags, fd, offset)) == (caddr_t)-1) {
+	if ((maddr_mapper = mmap(0, mapsize_mapper, PROT_READ|PROT_WRITE,
+			mapflags, fd_mapper, offset)) == (caddr_t)-1) {
 #endif /* LARGE_FILE */
 		perror("mmap error");
                 anyfail();
 	}
 
-	(void)close(fd);
+	(void)close(fd_mapper);
 
 	nloops = (randloops) ? (lrand48() % MAXLOOPS) : MAXLOOPS;
 
@@ -601,12 +621,12 @@ child_mapper(char *file, unsigned procno
 #ifdef LARGE_FILE
 		(void)printf("child %d (pid %ld): seed %d, fsize %Ld, "
 			"mapsize %d, off %Ld, loop %d\n",
-			procno, getpid(), seed, filesize, mapsize,
+			procno, getpid(), seed, filesize, mapsize_mapper,
 			offset/pagesize, nloops);
 #else /* LARGE_FILE */
 		(void)printf("child %d (pid %d): seed %d, fsize %ld, "
 			"mapsize %ld, off %ld, loop %d\n",
-			procno, getpid(), seed, filesize, (long)mapsize,
+			procno, getpid(), seed, filesize, (long)mapsize_mapper,
 			offset/pagesize, nloops);
 #endif /* LARGE_FILE */
 	}
@@ -616,13 +636,13 @@ child_mapper(char *file, unsigned procno
 	 */
 	for (loopcnt = 0; loopcnt < nloops; loopcnt++) {
 		randpage = lrand48() % mappages;
-		paddr = maddr + (randpage * pagesize);	 /* page address */
+		paddr = maddr_mapper + (randpage * pagesize);	 /* page address */
 
 		if (randpage < mappages - 1
-		    || !(mapsize % pagesize))
+		    || !(mapsize_mapper % pagesize))
 			validsize = pagesize;
 		else
-			validsize = mapsize % pagesize;
+			validsize = mapsize_mapper % pagesize;
 
 		/*
 		 * Because one child is mapping file in extend mode,
@@ -652,14 +672,17 @@ child_mapper(char *file, unsigned procno
 		 * Exercise msync() as well!
 		 */
 		randpage = lrand48() % mappages;
-		paddr = maddr + (randpage * pagesize);	 /* page address */
+		paddr = maddr_mapper + (randpage * pagesize);	 /* page address */
 		if (msync(paddr, (mappages - randpage)*pagesize,
 		    MS_SYNC) == -1) {
 			perror("msync error");
                         anyfail();
 		}
 	}
-
+	if ( munmap(maddr_mapper,mapsize_mapper) == -1 ) {
+		perror("munmap failed");
+		anyfail();
+	}
 	exit(0);
 }
 
@@ -675,7 +698,20 @@ child_mapper(char *file, unsigned procno
 void
 child_writer(char *file, uchar_t *buf)	/* buf already set up in main */
 {
-	int fd;
+	struct sigaction sa_writer;
+
+	sa_writer.sa_handler = clean_writer;
+	sa_writer.sa_flags = 0;
+	if (sigemptyset(&sa_writer.sa_mask)) {
+		perror("sigempty error");
+                anyfail();
+	}
+
+	if (sigaction(SIGUSR1, &sa_writer, 0) == -1) {
+		perror("sigaction error SIGUSR1");
+                anyfail();
+	}
+
 #ifdef LARGE_FILE
 	struct stat64 statbuf;
 	off64_t off;
@@ -688,18 +724,18 @@ child_writer(char *file, uchar_t *buf)	/
 	int cnt;
 
 #ifdef LARGE_FILE
-	if ((fd = open64(file, O_RDWR)) == -1) {
+	if ((fd_writer = open64(file, O_RDWR)) == -1) {
 #else /* LARGE_FILE */
-	if ((fd = open(file, O_RDWR)) == -1) {
+	if ((fd_writer = open(file, O_RDWR)) == -1) {
 #endif /* LARGE_FILE */
 		perror("open error");
                 anyfail();
 	}
 
 #ifdef LARGE_FILE
-	if ((off = lseek64(fd, 0, SEEK_END)) == -1) {
+	if ((off = lseek64(fd_writer, 0, SEEK_END)) == -1) {
 #else /* LARGE_FILE */
-	if ((off = lseek(fd, 0, SEEK_END)) == -1) {
+	if ((off = lseek(fd_writer, 0, SEEK_END)) == -1) {
 #endif /* LARGE_FILE */
 		perror("lseek error");
                 anyfail();
@@ -708,9 +744,9 @@ child_writer(char *file, uchar_t *buf)	/
 
 	for (;;) {
 #ifdef LARGE_FILE
-		if (fstat64(fd, &statbuf) == -1) {
+		if (fstat64(fd_writer, &statbuf) == -1) {
 #else /* LARGE_FILE */
-		if (fstat(fd, &statbuf) == -1) {
+		if (fstat(fd_writer, &statbuf) == -1) {
 #endif /* LARGE_FILE */
 			perror("fstat error");
                         anyfail();
@@ -734,7 +770,7 @@ child_writer(char *file, uchar_t *buf)	/
 
 		p = buf + (off % pagesize);
 
-		if ((cnt = write(fd, p, growsize)) != growsize) {
+		if ((cnt = write(fd_writer, p, growsize)) != growsize) {
 			if (cnt == -1)
 				perror("write error");
 			else
@@ -747,12 +783,13 @@ child_writer(char *file, uchar_t *buf)	/
 
 		(void)sleep(sleeptime);
 		if (dosync) {
-			if (fsync(fd) == -1) {
+			if (fsync(fd_writer) == -1) {
 				perror("fsync error");
                                 anyfail();
 			}
 		}
 	}
+	close(fd_writer);
 }
 
 
@@ -814,6 +851,7 @@ fileokay(char *file, uchar_t *expbuf)
 		cnt = read(fd, (char *)readbuf, pagesize);
 		if (cnt == -1) {
 			perror("read error");
+			close(fd);
 			return 0;
 		} else if (cnt != pagesize) {
 			/*
@@ -822,6 +860,7 @@ fileokay(char *file, uchar_t *expbuf)
 			if ((i * pagesize) + cnt != mapsize) {
 				(void)fprintf(stderr, "read %d of %ld bytes\n",
 					(i*pagesize)+cnt, (long)mapsize);
+				close(fd);
 				return 0;
 			}
 		}
@@ -841,6 +880,7 @@ fileokay(char *file, uchar_t *expbuf)
 				(void)fprintf(stderr, ", pg %d off %d, "
 					"(fsize %ld)\n", i, j, statbuf.st_size);
 #endif /* LARGE_FILE */
+				close(fd);
 				return 0;
 			}
 		}
@@ -866,6 +906,21 @@ clean_up_file(int sig)
 	exit(1);
 }
 
+void clean_mapper(int sig)
+{
+	if (fd_mapper)
+		close(fd_mapper);
+	munmap(maddr_mapper,mapsize_mapper);
+	exit (0);
+}
+
+void clean_writer(int sig)
+{
+	if (fd_writer)
+		close(fd_writer);
+	exit(0);
+}
+
 unsigned int
 initrand(void)
 {
@@ -887,7 +942,6 @@ initrand(void)
 	return (seed);
 }
 
-
 /*****  LTP Port        *****/
 void ok_exit()
 {
Index: ltp-full-20091231/testcases/kernel/syscalls/ppoll/ppoll01.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/syscalls/ppoll/ppoll01.c
+++ ltp-full-20091231/testcases/kernel/syscalls/ppoll/ppoll01.c
@@ -378,8 +378,10 @@ static int do_test(struct test_case *tc)
 	}
 	result |= (sys_errno != tc->err) || !cmp_ok;
 	PRINT_RESULT_CMP(sys_ret >= 0, tc->ret, tc->err, sys_ret, sys_errno, cmp_ok);
-	cleanup: if (fd >= 0)
+	cleanup: if (fd >= 0) {
+		close(fd);
 		cleanup_file(fpath);
+	}
 
 	sigemptyset(&sigmask);
 	sigprocmask(SIG_SETMASK, &sigmask, NULL);
Index: ltp-full-20091231/testcases/kernel/syscalls/utimes/utimes01.c
===================================================================
--- ltp-full-20091231.orig/testcases/kernel/syscalls/utimes/utimes01.c
+++ ltp-full-20091231/testcases/kernel/syscalls/utimes/utimes01.c
@@ -234,6 +234,8 @@ static int do_test(struct test_case *tc)
         TEST(rc = setup_file(TESTDIR, "test.file", fpath));
         if (rc < 0)
                 return 1;
+	/* The test just needs the file, so no need to keep it open. */
+	close(rc);
 
 	/*
          * Change effective user id

[-- Attachment #3: Type: text/plain, Size: 235 bytes --]

------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first

[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

  reply	other threads:[~2010-07-02  7:18 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-01 12:05 [LTP] [PATCH] close file descriptors and munmap pages Darshak Shah
2010-07-01 17:06 ` Subrata Modak
2010-07-02  6:25   ` Darshak Shah
2010-07-02  6:37     ` Garrett Cooper
2010-07-02  7:18       ` Darshak Shah [this message]
2010-07-03 18:00         ` Subrata Modak

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=4C2D92D3.8070001@linux.vnet.ibm.com \
    --to=darshaks@linux.vnet.ibm.com \
    --cc=ltp-list@lists.sourceforge.net \
    --cc=yanegomi@gmail.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.