From: Pavel Emelyanov <xemul-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
To: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>,
Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>,
Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>,
Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>,
Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Cyrill Gorcunov
<gorcunov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
Linux Containers
<containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org>,
Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
Subject: [PATCH 7/7] binfmt: Introduce the binfmt_img exec handler
Date: Fri, 15 Jul 2011 17:48:09 +0400 [thread overview]
Message-ID: <4E204519.3040804@parallels.com> (raw)
In-Reply-To: <4E204466.8010204-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
When being execve-ed the handler reads registers, mappings and provided
memory pages from image and just assigns this state on current task. This
simple functionality can be used to restore a task, whose state whas read
from e.g. /proc/<pid>/dump file before.
As I said before, the mentioned proc file format is designed to be as
simple as possible. Can (and should) be redesigned (ELF?).
Signed-off-by: Pavel Emelyanov <xemul-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
---
fs/Kconfig.binfmt | 6 +
fs/Makefile | 1 +
fs/binfmt_img.c | 324 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 331 insertions(+), 0 deletions(-)
create mode 100644 fs/binfmt_img.c
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 79e2ca7..0b2f48e 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -161,3 +161,9 @@ config BINFMT_MISC
You may say M here for module support and later load the module when
you have use for it; the module is called binfmt_misc. If you
don't know what to answer at this point, say Y.
+
+config BINFMT_IMG
+ tristate "Kernel support for IMG binaries"
+ depends on X86
+ help
+ Say M/Y here to enable support for checkpoint-restore images execution
diff --git a/fs/Makefile b/fs/Makefile
index fb68c2b..8221719 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_NFSD_DEPRECATED) += nfsctl.o
obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o
obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o
obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o
+obj-$(CONFIG_BINFMT_IMG) += binfmt_img.o
# binfmt_script is always there
obj-y += binfmt_script.o
diff --git a/fs/binfmt_img.c b/fs/binfmt_img.c
new file mode 100644
index 0000000..9b09797
--- /dev/null
+++ b/fs/binfmt_img.c
@@ -0,0 +1,324 @@
+#include <linux/binfmt_img.h>
+#include <linux/module.h>
+#include <linux/binfmts.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/highmem.h>
+#include <asm/tlbflush.h>
+#include <asm/desc.h>
+
+/*
+ * The binary handler to save and restore a single task state
+ */
+
+static int img_check_header(void *buf)
+{
+ struct binfmt_img_header *hdr = buf;
+
+ if (hdr->magic != BINFMT_IMG_MAGIC)
+ return -ENOEXEC;
+
+ if (hdr->version != BINFMT_IMG_VERS_0)
+ return -EINVAL;
+
+ return sizeof(*hdr);
+}
+
+static unsigned short decode_segment(__u16 seg)
+{
+ if (seg == CKPT_X86_SEG_NULL)
+ return 0;
+
+ if (seg == CKPT_X86_SEG_USER64_CS)
+ return __USER_CS;
+ if (seg == CKPT_X86_SEG_USER64_DS)
+ return __USER_DS;
+#ifdef CONFIG_COMPAT
+ if (seg == CKPT_X86_SEG_USER32_CS)
+ return __USER32_CS;
+ if (seg == CKPT_X86_SEG_USER32_DS)
+ return __USER32_DS;
+#endif
+
+ if (seg & CKPT_X86_SEG_TLS) {
+ seg &= ~CKPT_X86_SEG_TLS;
+ return ((GDT_ENTRY_TLS_MIN + seg) << 3) | 3;
+ }
+ if (seg & CKPT_X86_SEG_LDT) {
+ seg &= ~CKPT_X86_SEG_LDT;
+ return (seg << 3) | 7;
+ }
+ BUG();
+}
+
+static void decode_tls(struct desc_struct *d, __u64 val)
+{
+ d->a = (unsigned int)(val >> 32);
+ d->b = (unsigned int)(val & 0xFFFFFFFF);
+}
+
+static int img_restore_regs(struct linux_binprm *bprm, loff_t off, struct pt_regs *regs)
+{
+ int ret, i;
+ struct binfmt_regs_image regi;
+ struct thread_struct *th = ¤t->thread;
+ unsigned short seg;
+
+ ret = kernel_read(bprm->file, off, (char *)®i, sizeof(regi));
+ if (ret != sizeof(regi))
+ return -EIO;
+
+ regs->r15 = regi.r15;
+ regs->r14 = regi.r14;
+ regs->r13 = regi.r13;
+ regs->r12 = regi.r12;
+ regs->r11 = regi.r11;
+ regs->r10 = regi.r10;
+ regs->r9 = regi.r9;
+ regs->r8 = regi.r8;
+ regs->ax = regi.ax;
+ regs->orig_ax = regi.orig_ax;
+ regs->bx = regi.bx;
+ regs->cx = regi.cx;
+ regs->dx = regi.dx;
+ regs->si = regi.si;
+ regs->di = regi.di;
+ regs->ip = regi.ip;
+ regs->flags = regi.flags;
+ regs->bp = regi.bp;
+ regs->sp = regi.sp;
+
+ regs->cs = decode_segment(regi.cs);
+ regs->ss = decode_segment(regi.ss);
+
+ th->usersp = regi.sp;
+ th->ds = decode_segment(regi.ds);
+ th->es = decode_segment(regi.es);
+ th->fsindex = decode_segment(regi.fsindex);
+ th->gsindex = decode_segment(regi.gsindex);
+
+ th->fs = regi.fs;
+ th->gs = regi.gs;
+
+ BUILD_BUG_ON(GDT_ENTRY_TLS_ENTRIES != CKPT_TLS_ENTRIES);
+ for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
+ decode_tls(&th->tls_array[i], regi.tls[i]);
+
+ load_TLS(th, smp_processor_id());
+
+ seg = th->fsindex;
+ loadsegment(fs, seg);
+ savesegment(fs, seg);
+ if (seg != th->fsindex) {
+ printk("ERROR saving fs selector want %x, has %x\n",
+ (unsigned int)th->fsindex, (unsigned int)seg);
+ return -EFAULT;
+ }
+
+ if (th->fs)
+ wrmsrl(MSR_FS_BASE, th->fs);
+ load_gs_index(th->gsindex);
+ if (th->gs)
+ wrmsrl(MSR_KERNEL_GS_BASE, th->gs);
+
+ return sizeof(regi);
+}
+
+static int img_restore_mm(struct linux_binprm *bprm, loff_t off)
+{
+ int ret;
+ struct binfmt_mm_image mmi;
+ struct mm_struct *mm = current->mm;
+
+ ret = kernel_read(bprm->file, off, (char *)&mmi, sizeof(mmi));
+ if (ret != sizeof(mmi))
+ return -EIO;
+
+ mm->flags = mmi.flags;
+ mm->def_flags = mmi.def_flags;
+ mm->start_code = mmi.start_code;
+ mm->end_code = mmi.end_code;
+ mm->start_data = mmi.start_data;
+ mm->end_data = mmi.end_data;
+ mm->start_brk = mmi.start_brk;
+ mm->brk = mmi.brk;
+ mm->start_stack = mmi.start_stack;
+ mm->arg_start = mmi.arg_start;
+ mm->arg_end = mmi.arg_end;
+ mm->env_start = mmi.env_start;
+ mm->env_end = mmi.env_end;
+
+ if (mmi.exe_fd != 0) {
+ struct file *f;
+
+ f = fget(mmi.exe_fd);
+ if (f == NULL)
+ return -EBADF;
+
+ fput(mm->exe_file);
+ mm->exe_file = f;
+ }
+
+ return sizeof(mmi);
+}
+
+static int img_restore_vmas(struct linux_binprm *bprm, loff_t off)
+{
+ int ret;
+ struct mm_struct *mm = current->mm;
+ int len = 0;
+
+ do_munmap(mm, 0, TASK_SIZE);
+
+ while (1) {
+ struct binfmt_vma_image vmai;
+ unsigned long addr;
+ struct file *file = NULL;
+
+ len += sizeof(vmai);
+
+ ret = kernel_read(bprm->file, off, (char *)&vmai, sizeof(vmai));
+ if (ret != sizeof(vmai))
+ return -EIO;
+
+ if (vmai.start == 0 && vmai.end == 0)
+ break;
+
+ if (vmai.fd != 0) {
+ file = fget(vmai.fd);
+ if (file == NULL)
+ return -EBADF;
+ } else
+ vmai.flags |= MAP_ANONYMOUS;
+
+ if (vmai.start <= mm->start_stack && vmai.end >= mm->start_stack)
+ vmai.flags |= MAP_GROWSDOWN;
+
+ addr = do_mmap_pgoff(file, vmai.start, vmai.end - vmai.start,
+ vmai.prot, vmai.flags | MAP_FIXED, vmai.pgoff);
+
+ if (vmai.fd) {
+ fput(file);
+ do_close(vmai.fd);
+ }
+
+ if ((long)addr < 0 || (addr != vmai.start))
+ return -ENXIO;
+
+ off += sizeof(vmai);
+ }
+
+ return len;
+}
+
+static int img_restore_pages(struct linux_binprm *bprm, loff_t off)
+{
+ int ret;
+ struct mm_struct *mm = current->mm;
+ int len = 0;
+
+ while (1) {
+ struct binfmt_page_image pgi;
+ struct vm_area_struct *vma;
+ struct page *page;
+ void *pg_data;
+
+ ret = kernel_read(bprm->file, off, (char *)&pgi, sizeof(pgi));
+ if (ret != sizeof(pgi))
+ return -EIO;
+
+ len += sizeof(pgi);
+ if (pgi.vaddr == 0)
+ break;
+
+ vma = find_vma(mm, pgi.vaddr);
+ if (vma == NULL)
+ return -ESRCH;
+
+ ret = get_user_pages(current, current->mm, (unsigned long)pgi.vaddr,
+ 1, 1, 1, &page, NULL);
+ if (ret != 1)
+ return -EFAULT;
+
+ pg_data = kmap(page);
+ ret = kernel_read(bprm->file, off + sizeof(pgi), pg_data, PAGE_SIZE);
+ kunmap(page);
+ put_page(page);
+
+ if (ret != PAGE_SIZE)
+ return -EFAULT;
+
+ len += PAGE_SIZE;
+ off += sizeof(pgi) + PAGE_SIZE;
+ }
+
+ return len;
+}
+
+static int img_restore_mem(struct linux_binprm *bprm, loff_t off)
+{
+ int ret;
+ loff_t len = off;
+
+ ret = img_restore_mm(bprm, len);
+ if (ret < 0)
+ return ret;
+
+ len += ret;
+ ret = img_restore_vmas(bprm, len);
+ if (ret < 0)
+ return ret;
+
+ len += ret;
+ ret = img_restore_pages(bprm, len);
+ if (ret < 0)
+ return ret;
+
+ len += ret;
+ return len;
+
+}
+
+static int img_load_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+{
+ int ret;
+ loff_t len = 0;
+
+ ret = img_check_header(bprm->buf);
+ if (ret < 0)
+ return ret;
+
+ len += ret;
+ ret = img_restore_regs(bprm, len, regs);
+ if (ret < 0)
+ return ret;
+
+ len += ret;
+ ret = img_restore_mem(bprm, len);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static struct linux_binfmt img_binfmt = {
+ .module = THIS_MODULE,
+ .load_binary = img_load_binary,
+};
+
+static __init int img_binfmt_init(void)
+{
+ return register_binfmt(&img_binfmt);
+}
+
+static __exit void img_binfmt_exit(void)
+{
+ unregister_binfmt(&img_binfmt);
+}
+
+module_init(img_binfmt_init);
+module_exit(img_binfmt_exit);
+MODULE_LICENSE("GPL");
--
1.5.5.6
next prev parent reply other threads:[~2011-07-15 13:48 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-15 13:45 [RFC][PATCH 0/7 + tools] Checkpoint/restore mostly in the userspace Pavel Emelyanov
[not found] ` <4E204466.8010204-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-15 13:45 ` [PATCH 0/1] proc: Introduce the /proc/<pid>/mfd/ directory Pavel Emelyanov
[not found] ` <4E20448A.5010207-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-21 7:21 ` Tejun Heo
2011-07-15 13:46 ` [PATCH 2/7] vfs: Introduce the fd closing helper Pavel Emelyanov
[not found] ` <4E2044A7.4030103-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-21 15:47 ` Serge E. Hallyn
2011-07-15 13:46 ` [PATCH 3/7] proc: Introduce the Children: line in /proc/<pid>/status Pavel Emelyanov
[not found] ` <4E2044C3.7050506-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-21 6:54 ` Tejun Heo
[not found] ` <20110721065436.GT3455-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
2011-07-23 8:06 ` Pavel Emelyanov
[not found] ` <4E2A8116.1040309-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-23 8:41 ` Tejun Heo
[not found] ` <20110723084110.GG21089-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2011-07-23 8:45 ` Pavel Emelyanov
[not found] ` <4E2A8A0E.5030208-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-23 8:50 ` Tejun Heo
[not found] ` <20110723085014.GI21089-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2011-07-23 8:51 ` Pavel Emelyanov
2011-07-21 15:54 ` Serge E. Hallyn
2011-07-15 13:47 ` [PATCH 4/7] vfs: Add ->statfs callback for pipefs Pavel Emelyanov
[not found] ` <4E2044D6.3060205-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-21 6:59 ` Tejun Heo
2011-07-21 15:59 ` Serge E. Hallyn
2011-07-15 13:47 ` [PATCH 5/7] clone: Introduce the CLONE_CHILD_USEPID functionality Pavel Emelyanov
[not found] ` <4E2044EB.20001-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-21 16:04 ` Serge E. Hallyn
[not found] ` <20110721160459.GD19012-7LNsyQBKDXoIagZqoN9o3w@public.gmane.org>
2011-07-22 23:08 ` Matt Helsley
[not found] ` <20110722230848.GB16940-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-23 8:09 ` Pavel Emelyanov
2011-07-15 13:47 ` [PATCH 6/7] proc: Introduce the /proc/<pid>/dump file Pavel Emelyanov
[not found] ` <4E204500.6040800-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-16 22:57 ` Kirill A. Shutemov
[not found] ` <20110716225709.GA25606-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>
2011-07-17 8:06 ` Cyrill Gorcunov
2011-07-21 6:44 ` Tejun Heo
[not found] ` <20110721064408.GR3455-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
2011-07-23 8:11 ` Pavel Emelyanov
[not found] ` <4E2A8239.5060908-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-23 8:37 ` Tejun Heo
[not found] ` <20110723083711.GF21089-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2011-07-23 8:49 ` Pavel Emelyanov
[not found] ` <4E2A8B12.4010709-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-23 8:58 ` Tejun Heo
2011-07-15 13:48 ` Pavel Emelyanov [this message]
[not found] ` <4E204519.3040804-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-21 6:51 ` [PATCH 7/7] binfmt: Introduce the binfmt_img exec handler Tejun Heo
[not found] ` <20110721065127.GS3455-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
2011-07-22 22:46 ` Matt Helsley
[not found] ` <20110722224617.GA16940-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-23 8:17 ` Pavel Emelyanov
[not found] ` <4E2A83AC.6090504-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-23 8:45 ` Tejun Heo
[not found] ` <20110723084529.GH21089-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2011-07-23 8:51 ` Pavel Emelyanov
[not found] ` <4E2A8B7D.8010807-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-23 9:04 ` Tejun Heo
2011-07-15 13:49 ` [TOOLS] To make use of the patches Pavel Emelyanov
[not found] ` <4E204554.6040901-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-22 23:45 ` Matt Helsley
[not found] ` <20110722234558.GD16940-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-23 8:32 ` Pavel Emelyanov
[not found] ` <4E2A8704.3030306-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2011-07-27 23:00 ` Matt Helsley
[not found] ` <20110727230003.GE15501-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-28 8:23 ` James Bottomley
2011-07-23 0:40 ` Reply #2: " Matt Helsley
[not found] ` <20110723004045.GC21563-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-23 8:33 ` Pavel Emelyanov
2011-07-15 15:01 ` [RFC][PATCH 0/7 + tools] Checkpoint/restore mostly in the userspace Tejun Heo
2011-07-18 13:27 ` Serge E. Hallyn
[not found] ` <20110718132759.GB8127-7LNsyQBKDXoIagZqoN9o3w@public.gmane.org>
2011-07-23 8:43 ` Pavel Emelyanov
2011-07-23 0:25 ` Matt Helsley
[not found] ` <20110723002558.GE16940-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-23 3:29 ` Matt Helsley
[not found] ` <20110723032945.GD21563-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-23 4:58 ` Tejun Heo
[not found] ` <20110723045842.GD21089-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2011-07-26 18:11 ` Matt Helsley
[not found] ` <20110726181128.GD14808-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-26 22:45 ` Tejun Heo
[not found] ` <20110726224525.GC28497-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2011-07-26 23:07 ` Matt Helsley
2011-07-23 3:53 ` Tejun Heo
[not found] ` <CAOS58YPqLSYi2xECUk4O5GG3s6aokT=VykmkL6UnAOzyHXNAgQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-26 22:59 ` Matt Helsley
[not found] ` <20110726225911.GF14808-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-26 23:46 ` Tejun Heo
[not found] ` <20110726234657.GD28497-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2011-07-27 0:53 ` Matt Helsley
[not found] ` <20110727005341.GB15501-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-27 10:12 ` Tejun Heo
[not found] ` <20110727101228.GY2622-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
2011-07-27 22:26 ` Matt Helsley
2011-07-23 5:10 ` Tejun Heo
[not found] ` <20110723051005.GE21089-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2011-07-26 22:02 ` Matt Helsley
[not found] ` <20110726220215.GE14808-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-26 22:21 ` Tejun Heo
[not found] ` <20110726222109.GB28497-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2011-07-27 0:06 ` Matt Helsley
[not found] ` <20110727000651.GA15501-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-27 12:01 ` Tejun Heo
[not found] ` <20110727120114.GZ2622-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
2011-07-27 21:35 ` Matt Helsley
[not found] ` <20110727213510.GC15501-52DBMbEzqgQ/wnmkkaCWp/UQ3DHhIser@public.gmane.org>
2011-07-28 7:21 ` Tejun Heo
[not found] ` <20110728072141.GB2622-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
2011-07-28 7:23 ` Tejun Heo
2011-07-28 8:37 ` James Bottomley
2011-07-28 9:10 ` Tejun Heo
2011-07-23 8:39 ` Pavel Emelyanov
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=4E204519.3040804@parallels.com \
--to=xemul-bzqdu9zft3wakbo8gow8eq@public.gmane.org \
--cc=containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org \
--cc=dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org \
--cc=glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org \
--cc=gorcunov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org \
--cc=orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org \
--cc=serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org \
--cc=tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
/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.