<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://criu.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ptikhomirov</id>
	<title>CRIU - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://criu.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ptikhomirov"/>
	<link rel="alternate" type="text/html" href="https://criu.org/Special:Contributions/Ptikhomirov"/>
	<updated>2026-05-13T14:27:14Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.6</generator>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5610</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5610"/>
		<updated>2025-03-03T07:14:40Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Add support for checkpoint/restore of CORK-ed UDP socket */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@lists.linux.dev mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Add support for memory compression ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support compression for page images&lt;br /&gt;
 &lt;br /&gt;
We would like to support memory page files compression&lt;br /&gt;
in CRIU using one of the fastest algorithms (it's matter&lt;br /&gt;
of discussion which one to choose!).&lt;br /&gt;
&lt;br /&gt;
This task does not require any Linux kernel modifications&lt;br /&gt;
and scope is limited to CRIU itself. At the same time it's&lt;br /&gt;
complex enough as we need to touch memory dump/restore codepath&lt;br /&gt;
in CRIU and also handle many corner cases like page-server and stuff.&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Checkpointing of POSIX message queues ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Add support for checkpoint/restore of POSIX message queues&lt;br /&gt;
&lt;br /&gt;
POSIX message queues are a widely used inter-process communication mechanism. Message queues are implemented as files on a virtual filesystem (mqueue), where a file descriptor (message queue descriptor) is used to perform operations such as sending or receiving messages. To support checkpoint/restore of POSIX message queues, we need a kernel interface (similar to [https://github.com/checkpoint-restore/criu/commit/8ce9e947051e43430eb2ff06b96dddeba467b4fd MSG_PEEK]) that would enable the retrieval of messages from a queue without removing them. This project aims to implement such an interface that allows retrieving all messages and their priorities from a POSIX message queue.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/2285&lt;br /&gt;
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ipc/mqueue.c&lt;br /&gt;
* https://www.man7.org/tlpi/download/TLPI-52-POSIX_Message_Queues.pdf&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Add support for arm64 Guarded Control Stack (GCS) ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support arm64 Guarded Control Stack (GCS)&lt;br /&gt;
 &lt;br /&gt;
The arm64 Guarded Control Stack (GCS) feature provides support for&lt;br /&gt;
hardware protected stacks of return addresses, intended to provide&lt;br /&gt;
hardening against return oriented programming (ROP) attacks and to make&lt;br /&gt;
it easier to gather call stacks for applications such as profiling (taken from [1]).&lt;br /&gt;
We would like to support arm64 Guarded Control Stack (GCS) in CRIU, which means&lt;br /&gt;
that CRIU should be able to Checkpoint/Restore applications using GCS.&lt;br /&gt;
&lt;br /&gt;
This task should not require any Linux kernel modifications&lt;br /&gt;
but will require a lot of effort to understand Linux kernel and&lt;br /&gt;
glibc support patches. We have a good example of support for&lt;br /&gt;
x86 shadow stack [4] thanks to Mike.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [1] kernel support https://lore.kernel.org/all/20241001-arm64-gcs-v13-0-222b78d87eee@kernel.org&lt;br /&gt;
* [2] libc support https://inbox.sourceware.org/libc-alpha/20250117174119.3254972-1-yury.khrustalev@arm.com&lt;br /&gt;
* [3] libc tests https://inbox.sourceware.org/libc-alpha/20250210114538.1723249-1-yury.khrustalev@arm.com&lt;br /&gt;
* [4] x86 support (a great reference!) https://github.com/checkpoint-restore/criu/pull/2306&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (a lot of moving parts: Linux kernel / libc / CRIU)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;&lt;br /&gt;
* Mentors: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Coordinated checkpointing of distributed applications ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Enable coordinated container checkpointing with Kubernetes.&lt;br /&gt;
&lt;br /&gt;
Checkpointing support has been recently introduced in Kubernetes, where the&lt;br /&gt;
smallest deployable unit is a Pod (a group of containers).  Kubernetes is often&lt;br /&gt;
used to deploy applications that are distributed across multiple nodes.&lt;br /&gt;
However, checkpointing such distributed applications requires a coordination&lt;br /&gt;
mechanism to synchronize the checkpoint and restore operations. To address this&lt;br /&gt;
challenge, we have developed a new tool called &amp;lt;code&amp;gt;criu-coordinator&amp;lt;/code&amp;gt;&lt;br /&gt;
that relies on the action-script functionality of CRIU to enable synchronization&lt;br /&gt;
in distributed environments. This project aims to extend this tool to enable&lt;br /&gt;
seamless integration with the checkpointing functionality of Kubernetes.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu-coordinator&lt;br /&gt;
* https://lpc.events/event/18/contributions/1803/&lt;br /&gt;
* https://sched.co/1YeT4&lt;br /&gt;
* https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: Rust / Go / C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
&lt;br /&gt;
We already had a couple (3) of tries for this problem:&lt;br /&gt;
&lt;br /&gt;
* UDP_REPAIR approach didn't succeed: https://lore.kernel.org/netdev/721a2e32-c930-ad6b-5055-631b502ed11b@gmail.com/, https://lore.kernel.org/netdev/?q=udp_repair&lt;br /&gt;
* eBPF (CRIB) approach, socket queue iterator was not merged: https://lore.kernel.org/netdev/AM6PR03MB5848EDA002E3D7EACA7C6BDA99A52@AM6PR03MB5848.eurprd03.prod.outlook.com/, and we have general objections to CRIB approach https://lore.kernel.org/bpf/CAHk-=wjLWFa3i6+Tab67gnNumTYipj_HuheXr2RCq4zn0tCTzA@mail.gmail.com/&lt;br /&gt;
&lt;br /&gt;
We still have one idea we didn't try, as UDP allows packets to be lost on the way on restore we can somehow mark the socket to drop all data before UNCORK. This way we don't really need to restore contents of UDP CORK-ed sockets send queue.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* https://github.com/criupatchwork/criu/commit/a532312&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5609</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5609"/>
		<updated>2025-03-03T07:11:12Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Add support for checkpoint/restore of CORK-ed UDP socket */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@lists.linux.dev mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Add support for memory compression ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support compression for page images&lt;br /&gt;
 &lt;br /&gt;
We would like to support memory page files compression&lt;br /&gt;
in CRIU using one of the fastest algorithms (it's matter&lt;br /&gt;
of discussion which one to choose!).&lt;br /&gt;
&lt;br /&gt;
This task does not require any Linux kernel modifications&lt;br /&gt;
and scope is limited to CRIU itself. At the same time it's&lt;br /&gt;
complex enough as we need to touch memory dump/restore codepath&lt;br /&gt;
in CRIU and also handle many corner cases like page-server and stuff.&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Checkpointing of POSIX message queues ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Add support for checkpoint/restore of POSIX message queues&lt;br /&gt;
&lt;br /&gt;
POSIX message queues are a widely used inter-process communication mechanism. Message queues are implemented as files on a virtual filesystem (mqueue), where a file descriptor (message queue descriptor) is used to perform operations such as sending or receiving messages. To support checkpoint/restore of POSIX message queues, we need a kernel interface (similar to [https://github.com/checkpoint-restore/criu/commit/8ce9e947051e43430eb2ff06b96dddeba467b4fd MSG_PEEK]) that would enable the retrieval of messages from a queue without removing them. This project aims to implement such an interface that allows retrieving all messages and their priorities from a POSIX message queue.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/2285&lt;br /&gt;
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ipc/mqueue.c&lt;br /&gt;
* https://www.man7.org/tlpi/download/TLPI-52-POSIX_Message_Queues.pdf&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Add support for arm64 Guarded Control Stack (GCS) ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support arm64 Guarded Control Stack (GCS)&lt;br /&gt;
 &lt;br /&gt;
The arm64 Guarded Control Stack (GCS) feature provides support for&lt;br /&gt;
hardware protected stacks of return addresses, intended to provide&lt;br /&gt;
hardening against return oriented programming (ROP) attacks and to make&lt;br /&gt;
it easier to gather call stacks for applications such as profiling (taken from [1]).&lt;br /&gt;
We would like to support arm64 Guarded Control Stack (GCS) in CRIU, which means&lt;br /&gt;
that CRIU should be able to Checkpoint/Restore applications using GCS.&lt;br /&gt;
&lt;br /&gt;
This task should not require any Linux kernel modifications&lt;br /&gt;
but will require a lot of effort to understand Linux kernel and&lt;br /&gt;
glibc support patches. We have a good example of support for&lt;br /&gt;
x86 shadow stack [4] thanks to Mike.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [1] kernel support https://lore.kernel.org/all/20241001-arm64-gcs-v13-0-222b78d87eee@kernel.org&lt;br /&gt;
* [2] libc support https://inbox.sourceware.org/libc-alpha/20250117174119.3254972-1-yury.khrustalev@arm.com&lt;br /&gt;
* [3] libc tests https://inbox.sourceware.org/libc-alpha/20250210114538.1723249-1-yury.khrustalev@arm.com&lt;br /&gt;
* [4] x86 support (a great reference!) https://github.com/checkpoint-restore/criu/pull/2306&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (a lot of moving parts: Linux kernel / libc / CRIU)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;&lt;br /&gt;
* Mentors: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Coordinated checkpointing of distributed applications ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Enable coordinated container checkpointing with Kubernetes.&lt;br /&gt;
&lt;br /&gt;
Checkpointing support has been recently introduced in Kubernetes, where the&lt;br /&gt;
smallest deployable unit is a Pod (a group of containers).  Kubernetes is often&lt;br /&gt;
used to deploy applications that are distributed across multiple nodes.&lt;br /&gt;
However, checkpointing such distributed applications requires a coordination&lt;br /&gt;
mechanism to synchronize the checkpoint and restore operations. To address this&lt;br /&gt;
challenge, we have developed a new tool called &amp;lt;code&amp;gt;criu-coordinator&amp;lt;/code&amp;gt;&lt;br /&gt;
that relies on the action-script functionality of CRIU to enable synchronization&lt;br /&gt;
in distributed environments. This project aims to extend this tool to enable&lt;br /&gt;
seamless integration with the checkpointing functionality of Kubernetes.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu-coordinator&lt;br /&gt;
* https://lpc.events/event/18/contributions/1803/&lt;br /&gt;
* https://sched.co/1YeT4&lt;br /&gt;
* https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: Rust / Go / C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
&lt;br /&gt;
We already had a couple (3) of tries for this problem:&lt;br /&gt;
&lt;br /&gt;
* UDP_REPAIR approach didn't succeed: https://lore.kernel.org/netdev/721a2e32-c930-ad6b-5055-631b502ed11b@gmail.com/, https://lore.kernel.org/netdev/?q=udp_repair&lt;br /&gt;
* eBPF (CRIB) approach, socket queue iterator was not merged: https://lore.kernel.org/netdev/AM6PR03MB5848EDA002E3D7EACA7C6BDA99A52@AM6PR03MB5848.eurprd03.prod.outlook.com/, and we have general objections to CRIB approach https://lore.kernel.org/bpf/CAHk-=wjLWFa3i6+Tab67gnNumTYipj_HuheXr2RCq4zn0tCTzA@mail.gmail.com/&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* https://github.com/criupatchwork/criu/commit/a532312&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5608</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5608"/>
		<updated>2025-03-03T07:06:06Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Add support for checkpoint/restore of CORK-ed UDP socket */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@lists.linux.dev mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Add support for memory compression ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support compression for page images&lt;br /&gt;
 &lt;br /&gt;
We would like to support memory page files compression&lt;br /&gt;
in CRIU using one of the fastest algorithms (it's matter&lt;br /&gt;
of discussion which one to choose!).&lt;br /&gt;
&lt;br /&gt;
This task does not require any Linux kernel modifications&lt;br /&gt;
and scope is limited to CRIU itself. At the same time it's&lt;br /&gt;
complex enough as we need to touch memory dump/restore codepath&lt;br /&gt;
in CRIU and also handle many corner cases like page-server and stuff.&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Checkpointing of POSIX message queues ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Add support for checkpoint/restore of POSIX message queues&lt;br /&gt;
&lt;br /&gt;
POSIX message queues are a widely used inter-process communication mechanism. Message queues are implemented as files on a virtual filesystem (mqueue), where a file descriptor (message queue descriptor) is used to perform operations such as sending or receiving messages. To support checkpoint/restore of POSIX message queues, we need a kernel interface (similar to [https://github.com/checkpoint-restore/criu/commit/8ce9e947051e43430eb2ff06b96dddeba467b4fd MSG_PEEK]) that would enable the retrieval of messages from a queue without removing them. This project aims to implement such an interface that allows retrieving all messages and their priorities from a POSIX message queue.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/2285&lt;br /&gt;
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ipc/mqueue.c&lt;br /&gt;
* https://www.man7.org/tlpi/download/TLPI-52-POSIX_Message_Queues.pdf&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Add support for arm64 Guarded Control Stack (GCS) ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support arm64 Guarded Control Stack (GCS)&lt;br /&gt;
 &lt;br /&gt;
The arm64 Guarded Control Stack (GCS) feature provides support for&lt;br /&gt;
hardware protected stacks of return addresses, intended to provide&lt;br /&gt;
hardening against return oriented programming (ROP) attacks and to make&lt;br /&gt;
it easier to gather call stacks for applications such as profiling (taken from [1]).&lt;br /&gt;
We would like to support arm64 Guarded Control Stack (GCS) in CRIU, which means&lt;br /&gt;
that CRIU should be able to Checkpoint/Restore applications using GCS.&lt;br /&gt;
&lt;br /&gt;
This task should not require any Linux kernel modifications&lt;br /&gt;
but will require a lot of effort to understand Linux kernel and&lt;br /&gt;
glibc support patches. We have a good example of support for&lt;br /&gt;
x86 shadow stack [4] thanks to Mike.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [1] kernel support https://lore.kernel.org/all/20241001-arm64-gcs-v13-0-222b78d87eee@kernel.org&lt;br /&gt;
* [2] libc support https://inbox.sourceware.org/libc-alpha/20250117174119.3254972-1-yury.khrustalev@arm.com&lt;br /&gt;
* [3] libc tests https://inbox.sourceware.org/libc-alpha/20250210114538.1723249-1-yury.khrustalev@arm.com&lt;br /&gt;
* [4] x86 support (a great reference!) https://github.com/checkpoint-restore/criu/pull/2306&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (a lot of moving parts: Linux kernel / libc / CRIU)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;&lt;br /&gt;
* Mentors: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Coordinated checkpointing of distributed applications ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Enable coordinated container checkpointing with Kubernetes.&lt;br /&gt;
&lt;br /&gt;
Checkpointing support has been recently introduced in Kubernetes, where the&lt;br /&gt;
smallest deployable unit is a Pod (a group of containers).  Kubernetes is often&lt;br /&gt;
used to deploy applications that are distributed across multiple nodes.&lt;br /&gt;
However, checkpointing such distributed applications requires a coordination&lt;br /&gt;
mechanism to synchronize the checkpoint and restore operations. To address this&lt;br /&gt;
challenge, we have developed a new tool called &amp;lt;code&amp;gt;criu-coordinator&amp;lt;/code&amp;gt;&lt;br /&gt;
that relies on the action-script functionality of CRIU to enable synchronization&lt;br /&gt;
in distributed environments. This project aims to extend this tool to enable&lt;br /&gt;
seamless integration with the checkpointing functionality of Kubernetes.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu-coordinator&lt;br /&gt;
* https://lpc.events/event/18/contributions/1803/&lt;br /&gt;
* https://sched.co/1YeT4&lt;br /&gt;
* https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: Rust / Go / C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
&lt;br /&gt;
We already had a couple (3) of tries for this problem:&lt;br /&gt;
&lt;br /&gt;
* UDP_REPAIR approach didn't succeed: https://lore.kernel.org/netdev/721a2e32-c930-ad6b-5055-631b502ed11b@gmail.com/, https://lore.kernel.org/netdev/?q=udp_repair&lt;br /&gt;
* eBPF (CRIB) approach, socket queue iterator was not merged: https://lore.kernel.org/netdev/AM6PR03MB5848EDA002E3D7EACA7C6BDA99A52@AM6PR03MB5848.eurprd03.prod.outlook.com/ &lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* https://github.com/criupatchwork/criu/commit/a532312&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5607</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5607"/>
		<updated>2025-03-03T07:05:22Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Add support for checkpoint/restore of CORK-ed UDP socket */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@lists.linux.dev mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Add support for memory compression ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support compression for page images&lt;br /&gt;
 &lt;br /&gt;
We would like to support memory page files compression&lt;br /&gt;
in CRIU using one of the fastest algorithms (it's matter&lt;br /&gt;
of discussion which one to choose!).&lt;br /&gt;
&lt;br /&gt;
This task does not require any Linux kernel modifications&lt;br /&gt;
and scope is limited to CRIU itself. At the same time it's&lt;br /&gt;
complex enough as we need to touch memory dump/restore codepath&lt;br /&gt;
in CRIU and also handle many corner cases like page-server and stuff.&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Checkpointing of POSIX message queues ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Add support for checkpoint/restore of POSIX message queues&lt;br /&gt;
&lt;br /&gt;
POSIX message queues are a widely used inter-process communication mechanism. Message queues are implemented as files on a virtual filesystem (mqueue), where a file descriptor (message queue descriptor) is used to perform operations such as sending or receiving messages. To support checkpoint/restore of POSIX message queues, we need a kernel interface (similar to [https://github.com/checkpoint-restore/criu/commit/8ce9e947051e43430eb2ff06b96dddeba467b4fd MSG_PEEK]) that would enable the retrieval of messages from a queue without removing them. This project aims to implement such an interface that allows retrieving all messages and their priorities from a POSIX message queue.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/2285&lt;br /&gt;
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ipc/mqueue.c&lt;br /&gt;
* https://www.man7.org/tlpi/download/TLPI-52-POSIX_Message_Queues.pdf&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Add support for arm64 Guarded Control Stack (GCS) ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support arm64 Guarded Control Stack (GCS)&lt;br /&gt;
 &lt;br /&gt;
The arm64 Guarded Control Stack (GCS) feature provides support for&lt;br /&gt;
hardware protected stacks of return addresses, intended to provide&lt;br /&gt;
hardening against return oriented programming (ROP) attacks and to make&lt;br /&gt;
it easier to gather call stacks for applications such as profiling (taken from [1]).&lt;br /&gt;
We would like to support arm64 Guarded Control Stack (GCS) in CRIU, which means&lt;br /&gt;
that CRIU should be able to Checkpoint/Restore applications using GCS.&lt;br /&gt;
&lt;br /&gt;
This task should not require any Linux kernel modifications&lt;br /&gt;
but will require a lot of effort to understand Linux kernel and&lt;br /&gt;
glibc support patches. We have a good example of support for&lt;br /&gt;
x86 shadow stack [4] thanks to Mike.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [1] kernel support https://lore.kernel.org/all/20241001-arm64-gcs-v13-0-222b78d87eee@kernel.org&lt;br /&gt;
* [2] libc support https://inbox.sourceware.org/libc-alpha/20250117174119.3254972-1-yury.khrustalev@arm.com&lt;br /&gt;
* [3] libc tests https://inbox.sourceware.org/libc-alpha/20250210114538.1723249-1-yury.khrustalev@arm.com&lt;br /&gt;
* [4] x86 support (a great reference!) https://github.com/checkpoint-restore/criu/pull/2306&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (a lot of moving parts: Linux kernel / libc / CRIU)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;&lt;br /&gt;
* Mentors: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Coordinated checkpointing of distributed applications ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Enable coordinated container checkpointing with Kubernetes.&lt;br /&gt;
&lt;br /&gt;
Checkpointing support has been recently introduced in Kubernetes, where the&lt;br /&gt;
smallest deployable unit is a Pod (a group of containers).  Kubernetes is often&lt;br /&gt;
used to deploy applications that are distributed across multiple nodes.&lt;br /&gt;
However, checkpointing such distributed applications requires a coordination&lt;br /&gt;
mechanism to synchronize the checkpoint and restore operations. To address this&lt;br /&gt;
challenge, we have developed a new tool called &amp;lt;code&amp;gt;criu-coordinator&amp;lt;/code&amp;gt;&lt;br /&gt;
that relies on the action-script functionality of CRIU to enable synchronization&lt;br /&gt;
in distributed environments. This project aims to extend this tool to enable&lt;br /&gt;
seamless integration with the checkpointing functionality of Kubernetes.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu-coordinator&lt;br /&gt;
* https://lpc.events/event/18/contributions/1803/&lt;br /&gt;
* https://sched.co/1YeT4&lt;br /&gt;
* https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: Rust / Go / C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
We already had a couple (3) of tries for this problem:&lt;br /&gt;
&lt;br /&gt;
* UDP_REPAIR approach didn't succeed: https://lore.kernel.org/netdev/721a2e32-c930-ad6b-5055-631b502ed11b@gmail.com/, https://lore.kernel.org/netdev/?q=udp_repair&lt;br /&gt;
* eBPF (CRIB) approach, socket queue iterator was not merged: https://lore.kernel.org/netdev/AM6PR03MB5848EDA002E3D7EACA7C6BDA99A52@AM6PR03MB5848.eurprd03.prod.outlook.com/ &lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* https://github.com/criupatchwork/criu/commit/a532312&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5606</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5606"/>
		<updated>2025-03-03T07:04:57Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Add support for checkpoint/restore of CORK-ed UDP socket */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@lists.linux.dev mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Add support for memory compression ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support compression for page images&lt;br /&gt;
 &lt;br /&gt;
We would like to support memory page files compression&lt;br /&gt;
in CRIU using one of the fastest algorithms (it's matter&lt;br /&gt;
of discussion which one to choose!).&lt;br /&gt;
&lt;br /&gt;
This task does not require any Linux kernel modifications&lt;br /&gt;
and scope is limited to CRIU itself. At the same time it's&lt;br /&gt;
complex enough as we need to touch memory dump/restore codepath&lt;br /&gt;
in CRIU and also handle many corner cases like page-server and stuff.&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Checkpointing of POSIX message queues ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Add support for checkpoint/restore of POSIX message queues&lt;br /&gt;
&lt;br /&gt;
POSIX message queues are a widely used inter-process communication mechanism. Message queues are implemented as files on a virtual filesystem (mqueue), where a file descriptor (message queue descriptor) is used to perform operations such as sending or receiving messages. To support checkpoint/restore of POSIX message queues, we need a kernel interface (similar to [https://github.com/checkpoint-restore/criu/commit/8ce9e947051e43430eb2ff06b96dddeba467b4fd MSG_PEEK]) that would enable the retrieval of messages from a queue without removing them. This project aims to implement such an interface that allows retrieving all messages and their priorities from a POSIX message queue.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/2285&lt;br /&gt;
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ipc/mqueue.c&lt;br /&gt;
* https://www.man7.org/tlpi/download/TLPI-52-POSIX_Message_Queues.pdf&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Add support for arm64 Guarded Control Stack (GCS) ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support arm64 Guarded Control Stack (GCS)&lt;br /&gt;
 &lt;br /&gt;
The arm64 Guarded Control Stack (GCS) feature provides support for&lt;br /&gt;
hardware protected stacks of return addresses, intended to provide&lt;br /&gt;
hardening against return oriented programming (ROP) attacks and to make&lt;br /&gt;
it easier to gather call stacks for applications such as profiling (taken from [1]).&lt;br /&gt;
We would like to support arm64 Guarded Control Stack (GCS) in CRIU, which means&lt;br /&gt;
that CRIU should be able to Checkpoint/Restore applications using GCS.&lt;br /&gt;
&lt;br /&gt;
This task should not require any Linux kernel modifications&lt;br /&gt;
but will require a lot of effort to understand Linux kernel and&lt;br /&gt;
glibc support patches. We have a good example of support for&lt;br /&gt;
x86 shadow stack [4] thanks to Mike.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [1] kernel support https://lore.kernel.org/all/20241001-arm64-gcs-v13-0-222b78d87eee@kernel.org&lt;br /&gt;
* [2] libc support https://inbox.sourceware.org/libc-alpha/20250117174119.3254972-1-yury.khrustalev@arm.com&lt;br /&gt;
* [3] libc tests https://inbox.sourceware.org/libc-alpha/20250210114538.1723249-1-yury.khrustalev@arm.com&lt;br /&gt;
* [4] x86 support (a great reference!) https://github.com/checkpoint-restore/criu/pull/2306&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (a lot of moving parts: Linux kernel / libc / CRIU)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;&lt;br /&gt;
* Mentors: Mike Rapoport &amp;lt;rppt@kernel.org&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Coordinated checkpointing of distributed applications ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Enable coordinated container checkpointing with Kubernetes.&lt;br /&gt;
&lt;br /&gt;
Checkpointing support has been recently introduced in Kubernetes, where the&lt;br /&gt;
smallest deployable unit is a Pod (a group of containers).  Kubernetes is often&lt;br /&gt;
used to deploy applications that are distributed across multiple nodes.&lt;br /&gt;
However, checkpointing such distributed applications requires a coordination&lt;br /&gt;
mechanism to synchronize the checkpoint and restore operations. To address this&lt;br /&gt;
challenge, we have developed a new tool called &amp;lt;code&amp;gt;criu-coordinator&amp;lt;/code&amp;gt;&lt;br /&gt;
that relies on the action-script functionality of CRIU to enable synchronization&lt;br /&gt;
in distributed environments. This project aims to extend this tool to enable&lt;br /&gt;
seamless integration with the checkpointing functionality of Kubernetes.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu-coordinator&lt;br /&gt;
* https://lpc.events/event/18/contributions/1803/&lt;br /&gt;
* https://sched.co/1YeT4&lt;br /&gt;
* https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: Rust / Go / C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
We already had a couple (3) of tries for this problem:&lt;br /&gt;
* UDP_REPAIR approach didn't succeed: https://lore.kernel.org/netdev/721a2e32-c930-ad6b-5055-631b502ed11b@gmail.com/, https://lore.kernel.org/netdev/?q=udp_repair&lt;br /&gt;
* eBPF (CRIB) approach, socket queue iterator was not merged: https://lore.kernel.org/netdev/AM6PR03MB5848EDA002E3D7EACA7C6BDA99A52@AM6PR03MB5848.eurprd03.prod.outlook.com/ &lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* https://github.com/criupatchwork/criu/commit/a532312&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=LXC&amp;diff=5497</id>
		<title>LXC</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=LXC&amp;diff=5497"/>
		<updated>2024-07-01T04:33:37Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Checkpointing and restoring a container */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirements ==&lt;br /&gt;
&lt;br /&gt;
You should have built and installed a recent (&amp;gt;= 1.3.1) version of CRIU.&lt;br /&gt;
&lt;br /&gt;
== Checkpointing and restoring a container ==&lt;br /&gt;
&lt;br /&gt;
LXC upstream has begun to integrate checkpoint/restore support through the lxc-checkpoint tool. This functionality has been in the recent released version of LXC---LXC 1.1.0 , you can install the LXC 1.1.0 or you can check out the development version on Ubuntu by doing: &lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo add-apt-repository ppa:ubuntu-lxc/daily&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
sudo apt-get install lxc&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, create a container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 sudo lxc-create -t ubuntu -n u1 -- -r trusty -a amd64&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And add the following lines (as above) to its config:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat | sudo tee -a /var/lib/lxc/u1/config &amp;lt;&amp;lt; EOF&lt;br /&gt;
# hax for criu&lt;br /&gt;
lxc.console.path = none&lt;br /&gt;
lxc.tty.max = 0&lt;br /&gt;
lxc.cgroup.devices.deny = c 5:1 rwm&lt;br /&gt;
# on older lxc comment the above and uncomment the below&lt;br /&gt;
# lxc.console = none&lt;br /&gt;
# lxc.tty = 0&lt;br /&gt;
# lxc.cgroup.devices.deny = c 5:1 rwm&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, start, and checkpoint the container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo lxc-start -n u1&lt;br /&gt;
sleep 5s  # let the container get to a more interesting state&lt;br /&gt;
sudo lxc-checkpoint -s -D /tmp/checkpoint -n u1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, the container's state is stored in /tmp/checkpoint, and the filesystem is in /var/lib/lxc/u1/rootfs. You can restore the container by doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo lxc-checkpoint -r -D /tmp/checkpoint -n u1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then, get your container's IP and ssh in:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ubuntu@$(sudo lxc-info -i -H -n u1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
 &lt;br /&gt;
=== Error (mount.c:805): fusectl isn't empty: 8388625 ===&lt;br /&gt;
&lt;br /&gt;
Dumping of fuse filesystems is currently not supported. Empty the container's &amp;lt;code&amp;gt;/sys/fs/fuse/connections&amp;lt;/code&amp;gt; and try again.&lt;br /&gt;
&lt;br /&gt;
=== Error (mount.c:517): Mount 58 (master_id: 12 shared_id: 0) has unreachable sharing ===&lt;br /&gt;
&lt;br /&gt;
CRIU doesn't yet support shared mountpoints as LXC does; make sure your rootfs is on a non-shared mount.&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.youtube.com/watch?v=a9T2gcnQg2k&amp;amp;feature=youtu.be&amp;amp;t=18m8s The New New Thing: Turning Docker Tech into a Full Speed Hypervisor] - Talk of Tycho Andersen with demo of migration LXC container with Doom inside&lt;br /&gt;
* [https://github.com/tych0/presentations/blob/master/ods2014.md Demo script]&lt;br /&gt;
&lt;br /&gt;
[[Category: HOWTO]]&lt;br /&gt;
[[Category: Live migration]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5468</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5468"/>
		<updated>2024-03-26T03:11:25Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Add support for checkpoint/restore of CORK-ed UDP socket */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@openvz.org mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Add support for memory compression ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support compression for page images&lt;br /&gt;
 &lt;br /&gt;
We would like to support memory page files compression&lt;br /&gt;
in CRIU using one of the fastest algorithms (it's matter&lt;br /&gt;
of discussion which one to choose!).&lt;br /&gt;
&lt;br /&gt;
This task does not require any Linux kernel modifications&lt;br /&gt;
and scope is limited to CRIU itself. At the same time it's&lt;br /&gt;
complex enough as we need to touch memory dump/restore codepath&lt;br /&gt;
in CRIU and also handle many corner cases like page-server and stuff.&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* https://github.com/criupatchwork/criu/commit/a532312&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for pidfd file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of pidfd descriptors&lt;br /&gt;
&lt;br /&gt;
There is pidfd_open syscall which allows opening&lt;br /&gt;
a special PID file descriptor. A user can send a signal to&lt;br /&gt;
the process (pidfd_send_signal syscall), wait for the process&lt;br /&gt;
(poll() on pidfd).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have pidfd's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/801319/&lt;br /&gt;
* https://lwn.net/Articles/794707/&lt;br /&gt;
* https://github.com/torvalds/linux/blob/v5.16/kernel/fork.c#L1877&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Christian Brauner &amp;lt;christian@brauner.io&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Checkpointing of POSIX message queues ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Add support for checkpoint/restore of POSIX message queues&lt;br /&gt;
&lt;br /&gt;
POSIX message queues are a widely used inter-process communication mechanism. Message queues are implemented as files on a virtual filesystem (mqueue), where a file descriptor (message queue descriptor) is used to perform operations such as sending or receiving messages. To support checkpoint/restore of POSIX message queues, we need a kernel interface (similar to [https://github.com/checkpoint-restore/criu/commit/8ce9e947051e43430eb2ff06b96dddeba467b4fd MSG_PEEK]) that would enable the retrieval of messages from a queue without removing them. This project aims to implement such an interface that allows retrieving all messages and their priorities from a POSIX message queue.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/2285&lt;br /&gt;
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ipc/mqueue.c&lt;br /&gt;
* https://www.man7.org/tlpi/download/TLPI-52-POSIX_Message_Queues.pdf&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kubernetes operator for managing container checkpoints ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Develop a Kubernetes operator that automates the management of container checkpoints&lt;br /&gt;
&lt;br /&gt;
Container checkpointing has recently been introduced as an alpha feature in Kubernetes.&lt;br /&gt;
To enable this feature, the kubelet API was extended with an endpoint that enables the&lt;br /&gt;
creation of checkpoints for individual containers. By default, all container checkpoints&lt;br /&gt;
are stored as tar archives in &amp;lt;code&amp;gt;/var/lib/kubelet/checkpoints&amp;lt;/code&amp;gt; using the following&lt;br /&gt;
file name format: &amp;lt;code&amp;gt;checkpoint-&amp;lt;pod-name&amp;gt;_&amp;lt;namespace-name&amp;gt;-&amp;lt;container-name&amp;gt;-&amp;lt;timestamp&amp;gt;.tar&amp;lt;/code&amp;gt;.&lt;br /&gt;
However, the current implementation does not provide a mechanism for limiting the number&lt;br /&gt;
of checkpoints, which may lead to filling up all existing disk space. This project aims to&lt;br /&gt;
develop a Kubernetes operator that automates the management of checkpoints and provides&lt;br /&gt;
a garbage collection mechanism to discard obsolete checkpoints.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/checkpoint-restore-operator&lt;br /&gt;
* https://kubernetes.io/docs/reference/node/kubelet-checkpoint-api/&lt;br /&gt;
* https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/&lt;br /&gt;
* https://kubernetes.io/blog/2023/03/10/forensic-container-analysis/&lt;br /&gt;
* https://github.com/kubernetes/kubernetes/pull/115888&lt;br /&gt;
* https://github.com/kubernetes/enhancements/issues/2008&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: Go&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;, Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5467</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5467"/>
		<updated>2024-03-26T03:11:00Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Add support for memory compression */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@openvz.org mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Add support for memory compression ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support compression for page images&lt;br /&gt;
 &lt;br /&gt;
We would like to support memory page files compression&lt;br /&gt;
in CRIU using one of the fastest algorithms (it's matter&lt;br /&gt;
of discussion which one to choose!).&lt;br /&gt;
&lt;br /&gt;
This task does not require any Linux kernel modifications&lt;br /&gt;
and scope is limited to CRIU itself. At the same time it's&lt;br /&gt;
complex enough as we need to touch memory dump/restore codepath&lt;br /&gt;
in CRIU and also handle many corner cases like page-server and stuff.&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* https://github.com/criupatchwork/criu/commit/a532312&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for pidfd file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of pidfd descriptors&lt;br /&gt;
&lt;br /&gt;
There is pidfd_open syscall which allows opening&lt;br /&gt;
a special PID file descriptor. A user can send a signal to&lt;br /&gt;
the process (pidfd_send_signal syscall), wait for the process&lt;br /&gt;
(poll() on pidfd).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have pidfd's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/801319/&lt;br /&gt;
* https://lwn.net/Articles/794707/&lt;br /&gt;
* https://github.com/torvalds/linux/blob/v5.16/kernel/fork.c#L1877&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Christian Brauner &amp;lt;christian@brauner.io&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Checkpointing of POSIX message queues ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Add support for checkpoint/restore of POSIX message queues&lt;br /&gt;
&lt;br /&gt;
POSIX message queues are a widely used inter-process communication mechanism. Message queues are implemented as files on a virtual filesystem (mqueue), where a file descriptor (message queue descriptor) is used to perform operations such as sending or receiving messages. To support checkpoint/restore of POSIX message queues, we need a kernel interface (similar to [https://github.com/checkpoint-restore/criu/commit/8ce9e947051e43430eb2ff06b96dddeba467b4fd MSG_PEEK]) that would enable the retrieval of messages from a queue without removing them. This project aims to implement such an interface that allows retrieving all messages and their priorities from a POSIX message queue.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/2285&lt;br /&gt;
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ipc/mqueue.c&lt;br /&gt;
* https://www.man7.org/tlpi/download/TLPI-52-POSIX_Message_Queues.pdf&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kubernetes operator for managing container checkpoints ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Develop a Kubernetes operator that automates the management of container checkpoints&lt;br /&gt;
&lt;br /&gt;
Container checkpointing has recently been introduced as an alpha feature in Kubernetes.&lt;br /&gt;
To enable this feature, the kubelet API was extended with an endpoint that enables the&lt;br /&gt;
creation of checkpoints for individual containers. By default, all container checkpoints&lt;br /&gt;
are stored as tar archives in &amp;lt;code&amp;gt;/var/lib/kubelet/checkpoints&amp;lt;/code&amp;gt; using the following&lt;br /&gt;
file name format: &amp;lt;code&amp;gt;checkpoint-&amp;lt;pod-name&amp;gt;_&amp;lt;namespace-name&amp;gt;-&amp;lt;container-name&amp;gt;-&amp;lt;timestamp&amp;gt;.tar&amp;lt;/code&amp;gt;.&lt;br /&gt;
However, the current implementation does not provide a mechanism for limiting the number&lt;br /&gt;
of checkpoints, which may lead to filling up all existing disk space. This project aims to&lt;br /&gt;
develop a Kubernetes operator that automates the management of checkpoints and provides&lt;br /&gt;
a garbage collection mechanism to discard obsolete checkpoints.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/checkpoint-restore-operator&lt;br /&gt;
* https://kubernetes.io/docs/reference/node/kubelet-checkpoint-api/&lt;br /&gt;
* https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/&lt;br /&gt;
* https://kubernetes.io/blog/2023/03/10/forensic-container-analysis/&lt;br /&gt;
* https://github.com/kubernetes/kubernetes/pull/115888&lt;br /&gt;
* https://github.com/kubernetes/enhancements/issues/2008&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: Go&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;, Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5466</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5466"/>
		<updated>2024-03-26T03:10:26Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Add support for memory compression */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@openvz.org mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Add support for memory compression ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support compression for page images&lt;br /&gt;
 &lt;br /&gt;
We would like to support memory page files compression&lt;br /&gt;
in CRIU using one of the fastest algorithms (it's matter&lt;br /&gt;
of discussion which one to choose!).&lt;br /&gt;
&lt;br /&gt;
This task does not require any Linux kernel modifications&lt;br /&gt;
and scope is limited to CRIU itself. At the same time it's&lt;br /&gt;
complex enough as we need to touch memory dump/restore codepath&lt;br /&gt;
in CRIU and also handle many corner cases like page-server and stuff.&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* https://github.com/criupatchwork/criu/commit/a532312&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for pidfd file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of pidfd descriptors&lt;br /&gt;
&lt;br /&gt;
There is pidfd_open syscall which allows opening&lt;br /&gt;
a special PID file descriptor. A user can send a signal to&lt;br /&gt;
the process (pidfd_send_signal syscall), wait for the process&lt;br /&gt;
(poll() on pidfd).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have pidfd's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/801319/&lt;br /&gt;
* https://lwn.net/Articles/794707/&lt;br /&gt;
* https://github.com/torvalds/linux/blob/v5.16/kernel/fork.c#L1877&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Christian Brauner &amp;lt;christian@brauner.io&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Checkpointing of POSIX message queues ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Add support for checkpoint/restore of POSIX message queues&lt;br /&gt;
&lt;br /&gt;
POSIX message queues are a widely used inter-process communication mechanism. Message queues are implemented as files on a virtual filesystem (mqueue), where a file descriptor (message queue descriptor) is used to perform operations such as sending or receiving messages. To support checkpoint/restore of POSIX message queues, we need a kernel interface (similar to [https://github.com/checkpoint-restore/criu/commit/8ce9e947051e43430eb2ff06b96dddeba467b4fd MSG_PEEK]) that would enable the retrieval of messages from a queue without removing them. This project aims to implement such an interface that allows retrieving all messages and their priorities from a POSIX message queue.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/2285&lt;br /&gt;
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ipc/mqueue.c&lt;br /&gt;
* https://www.man7.org/tlpi/download/TLPI-52-POSIX_Message_Queues.pdf&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kubernetes operator for managing container checkpoints ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Develop a Kubernetes operator that automates the management of container checkpoints&lt;br /&gt;
&lt;br /&gt;
Container checkpointing has recently been introduced as an alpha feature in Kubernetes.&lt;br /&gt;
To enable this feature, the kubelet API was extended with an endpoint that enables the&lt;br /&gt;
creation of checkpoints for individual containers. By default, all container checkpoints&lt;br /&gt;
are stored as tar archives in &amp;lt;code&amp;gt;/var/lib/kubelet/checkpoints&amp;lt;/code&amp;gt; using the following&lt;br /&gt;
file name format: &amp;lt;code&amp;gt;checkpoint-&amp;lt;pod-name&amp;gt;_&amp;lt;namespace-name&amp;gt;-&amp;lt;container-name&amp;gt;-&amp;lt;timestamp&amp;gt;.tar&amp;lt;/code&amp;gt;.&lt;br /&gt;
However, the current implementation does not provide a mechanism for limiting the number&lt;br /&gt;
of checkpoints, which may lead to filling up all existing disk space. This project aims to&lt;br /&gt;
develop a Kubernetes operator that automates the management of checkpoints and provides&lt;br /&gt;
a garbage collection mechanism to discard obsolete checkpoints.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/checkpoint-restore-operator&lt;br /&gt;
* https://kubernetes.io/docs/reference/node/kubelet-checkpoint-api/&lt;br /&gt;
* https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/&lt;br /&gt;
* https://kubernetes.io/blog/2023/03/10/forensic-container-analysis/&lt;br /&gt;
* https://github.com/kubernetes/kubernetes/pull/115888&lt;br /&gt;
* https://github.com/kubernetes/enhancements/issues/2008&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: Go&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;, Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Prajwal S N &amp;lt;prajwalnadig21@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Validate_files_on_restore&amp;diff=5419</id>
		<title>Validate files on restore</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Validate_files_on_restore&amp;diff=5419"/>
		<updated>2023-08-28T05:33:39Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article describes what CRIU does to make sure it restores the correct set of files and how this file validation is implemented in CRIU. This project was completed under the [https://summerofcode.withgoogle.com/projects/#5773537320632320 GSoC 2020 program].&lt;br /&gt;
&lt;br /&gt;
Note: This is NOT merged to CRIU, see https://github.com/checkpoint-restore/criu/pull/1148&lt;br /&gt;
&lt;br /&gt;
== The previous implementation ==&lt;br /&gt;
Since CRIU doesn’t carry the contents of files into images while dumping (Except for ghost files), files that are being restored must be validated to make sure they are the “same” as they were during the dumping process (Especially true for ELF files since there is a risk of restoring executables or libraries of a different version). This was being done by only storing and comparing the size of the file. By itself, this isn’t a very strong check.&lt;br /&gt;
&lt;br /&gt;
== The current implementation ==&lt;br /&gt;
The file size method is used as a preliminary method, if it fails there’s no need to do any of the more intensive checks, instead it will immediately give out an error and stop restoring. Stronger checks are used only if it passes.&lt;br /&gt;
&lt;br /&gt;
The simplest and strongest check is to calculate the checksum for the entire file but this would be very intensive for large files and therefore not always feasible. A reasonable compromise would be to calculate the checksum only for certain parts of the file. This is the checksum method and it is one of the two methods that have been implemented in CRIU.&lt;br /&gt;
&lt;br /&gt;
The other method is the build-ID method. The build-ID is a &amp;quot;strongly unique embedded identifier&amp;quot; that (If present) is stored in a particular note section of ELF files.&lt;br /&gt;
&lt;br /&gt;
== Build-ID ==&lt;br /&gt;
The build-ID (If present) is stored in a note of type &amp;lt;code&amp;gt;NT_GNU_BUILD_ID&amp;lt;/code&amp;gt; in the ELF file. All notes are in the note section which is a program header of type &amp;lt;code&amp;gt;PT_NOTE&amp;lt;/code&amp;gt; in the ELF file. After the file has been mmap-ed, the first thing that needs to be done is to check whether the file is an ELF file or not. This is done by checking for the magic number. The next thing to do is to identify whether the file is a 32-bit ELF file or a 64-bit ELF file since the data types of the variables used to parse the ELF file will change depending on the bitness of the file (There are specific 32-bit and 64-bit variants of the data structures in &amp;lt;code&amp;gt;elf.h&amp;lt;/code&amp;gt;) but the procedure will remain the same.&lt;br /&gt;
&lt;br /&gt;
The position of the program headers is stored as an offset in &amp;lt;code&amp;gt;phoff&amp;lt;/code&amp;gt;. Since all the program headers are stored in an arbitrary order, each program header needs to be checked. If a program header of type &amp;lt;code&amp;gt;PT_NOTE&amp;lt;/code&amp;gt; is found, the position of this note section is stored as an offset in &amp;lt;code&amp;gt;p_offset&amp;lt;/code&amp;gt;. The notes are stored in an arbitrary order as well, so each note needs to be checked. If a note of type &amp;lt;code&amp;gt;NT_GNU_BUILD_ID&amp;lt;/code&amp;gt; is found, the build-ID is present in its description.&lt;br /&gt;
&lt;br /&gt;
== Checksum ==&lt;br /&gt;
CRC32C is used to calculate the checksum. The only difference between CRC32C and CRC32 is the polynomial being used. CRC32C uses the Castagnoli polynomial (0x82F63B78 in little-endian notation) and CRC32 uses 0xEDB88320 (In little-endian notation).&lt;br /&gt;
&lt;br /&gt;
The file is mapped 10 MB at a time and the checksum is calculated on the required bytes (Depending on the configuration set - Entire file, First N bytes of the file, or Every Nth byte of the file). N is the checksum parameter.&lt;br /&gt;
&lt;br /&gt;
Adding a new configuration is quite simple and only requires the iterator to be moved to the necessary bytes (0 refers to the first byte of the file and 1 refers to the second byte and so on):&lt;br /&gt;
# Input handling for the new configuration&lt;br /&gt;
# The &amp;lt;code&amp;gt;checksum_iterator_init&amp;lt;/code&amp;gt; function in ''&amp;quot;criu/files-reg.c”'' sets the initial iterator position (The first byte to calculate the checksum)&lt;br /&gt;
# The &amp;lt;code&amp;gt;checksum_iterator_next&amp;lt;/code&amp;gt; function in ''“criu/files-reg.c”'' moves the iterator to the next position (The next byte to calculate the checksum)&lt;br /&gt;
# The &amp;lt;code&amp;gt;checksum_iterator_stop&amp;lt;/code&amp;gt; function in ''“criu/files-reg.c”'' returns true when the iterator has reached its final position&lt;br /&gt;
There is a separate check in the &amp;lt;code&amp;gt;calculate_checksum&amp;lt;/code&amp;gt; function to make sure the iterator refers to a valid byte (Not negative and smaller than the total number of bytes in the file). If the iterator is outside the mapped region but still valid, the required region of the file will be mapped.&lt;br /&gt;
&lt;br /&gt;
== Using different validation methods and parameters ==&lt;br /&gt;
The build-ID method is much less intensive compared to the checksum method while still being a much stronger check than simply comparing the file size and is therefore the default. In other words, &amp;lt;code&amp;gt;--file-validation buildid&amp;lt;/code&amp;gt; will not make a difference as this is the default method.&lt;br /&gt;
&lt;br /&gt;
CRIU can also be configured to use the checksum method by default by using the &amp;lt;code&amp;gt;--file-validation option&amp;lt;/code&amp;gt;:&lt;br /&gt;
* &amp;lt;code&amp;gt;--file-validation checksum-full&amp;lt;/code&amp;gt; to calculate and use the checksum on the entire file.&lt;br /&gt;
* &amp;lt;code&amp;gt;--file-validation checksum&amp;lt;/code&amp;gt; to calculate and use the checksum on the first N bytes of the file. The parameter N is set by using the &amp;lt;code&amp;gt;--checksum-parameter&amp;lt;/code&amp;gt; option.&lt;br /&gt;
* &amp;lt;code&amp;gt;--file-validation checksum-period&amp;lt;/code&amp;gt; to calculate and use the checksum on every Nth byte of the file (Including the first byte of the file). The parameter N is set by using the &amp;lt;code&amp;gt;--checksum-parameter option&amp;lt;/code&amp;gt;.&lt;br /&gt;
By default, the checksum parameter N is set to 1024. If a method that doesn’t require the checksum parameter is being used, then the checksum parameter is simply ignored.&lt;br /&gt;
For example, to use the checksum method on the first 2048 bytes of the file: &amp;lt;code&amp;gt;--file-validation checksum --checksum-parameter 2048&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the build-ID method is being used and is inconclusive (Maybe because the ELF file doesn’t contain a build-ID), then the checksum method on the first 1024 bytes of the file is used as a fallback. If the checksum method is being used and is inconclusive, then the build-ID method is used as a fallback. If both are inconclusive, only the file size check is used (And a warning is put out to inform the user that only a weak check has been used for that particular file).&lt;br /&gt;
&lt;br /&gt;
To explicitly use only the file size check all the time, the following command-line option can be used: &amp;lt;code&amp;gt;--file-validation filesize&amp;lt;/code&amp;gt; (This is the fastest and least intensive check).&lt;br /&gt;
&lt;br /&gt;
== Performance impact ==&lt;br /&gt;
The values shown below are the average times it took to finish the ZDTM tests over multiple runs, and are only to indicate the impact each method has in general.&lt;br /&gt;
&lt;br /&gt;
Each test has 3 files (Of sizes: 0.09 MB, 2 MB and 0.17 MB approximately) and each test is run 3 times (In Host, Namespace and User Namespace). For each file the checksum/build-ID is obtained twice (During dump and restore) therefore the function to find checksum/build-ID is called 18 times overall per test.&lt;br /&gt;
&lt;br /&gt;
For reference, these tests were run on tmpfs (To remove any disk latency) and on an undervolted i5 4800H.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&lt;br /&gt;
|+zdtm/transition/shmem:&lt;br /&gt;
|-&lt;br /&gt;
|File Size&lt;br /&gt;
|3.782s&lt;br /&gt;
|-&lt;br /&gt;
|Build-ID&lt;br /&gt;
|4.153s (~9% increase)&lt;br /&gt;
|-&lt;br /&gt;
|Checksum (First 1024 bytes)&lt;br /&gt;
|4.465s (~18% increase)&lt;br /&gt;
|-&lt;br /&gt;
|Checksum (Entire File)&lt;br /&gt;
|4.722s (~24% increase)&lt;br /&gt;
|-&lt;br /&gt;
|Checksum (Every 1024th byte)&lt;br /&gt;
|4.498s (~19% increase)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&lt;br /&gt;
|+zdtm/static/maps04:&lt;br /&gt;
|-&lt;br /&gt;
|File Size&lt;br /&gt;
|35.317s&lt;br /&gt;
|-&lt;br /&gt;
|Build-ID&lt;br /&gt;
|35.720s (~1% increase)&lt;br /&gt;
|-&lt;br /&gt;
|Checksum (First 1024 bytes)&lt;br /&gt;
|35.919s (~2% increase)&lt;br /&gt;
|-&lt;br /&gt;
|Checksum (Entire File)&lt;br /&gt;
|36.679s (~4% increase)&lt;br /&gt;
|-&lt;br /&gt;
|Checksum (Every 1024th byte)&lt;br /&gt;
|36.476s (~3% increase)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Scope for improvement and future work ==&lt;br /&gt;
* Calculating the checksum can be made faster by using a lookup table.&lt;br /&gt;
&lt;br /&gt;
[[Category:Under the hood]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5388</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5388"/>
		<updated>2023-03-13T10:55:10Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Files on detached mounts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@openvz.org mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* https://github.com/criupatchwork/criu/commit/a532312&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for pidfd file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of pidfd descriptors&lt;br /&gt;
&lt;br /&gt;
There is pidfd_open syscall which allows opening&lt;br /&gt;
a special PID file descriptor. A user can send a signal to&lt;br /&gt;
the process (pidfd_send_signal syscall), wait for the process&lt;br /&gt;
(poll() on pidfd).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have pidfd's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/801319/&lt;br /&gt;
* https://lwn.net/Articles/794707/&lt;br /&gt;
* https://github.com/torvalds/linux/blob/v5.16/kernel/fork.c#L1877&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Christian Brauner &amp;lt;christian@brauner.io&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for memfd_secret file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of memfd_secret descriptors&lt;br /&gt;
&lt;br /&gt;
There is memfd_secret syscall which allows user to open&lt;br /&gt;
special memfd which is backed by special memory range which&lt;br /&gt;
is inaccessible by another processes (and the kernel too!).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have memfd_secret's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/865256/&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Mike Rapoport &amp;lt;mike.rapoport@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Forensic analysis of container checkpoints ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Extending go-crit with capabilities for forensic analysis&lt;br /&gt;
&lt;br /&gt;
The go-crit tool was created during GSoC 2022 to enable analysis of CRIU [[images]] with tools written in Go. It allows container management tools such as [https://github.com/checkpoint-restore/checkpointctl checkpointctl] and Podman to provide capabilities similar to CRIT. The goal of this project is to extend go-crit with functionality for forensic analysis of container checkpoints to provide a better user experience.&lt;br /&gt;
&lt;br /&gt;
The go-crit tool is still in its early stages of development. To effectively utilise this new feature, the checkpointctl tool would be extended to display information about the processes included in a container checkpoint and their runtime state (e.g., memory, open files, sockets, etc).&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://criu.org/CRIT_(Go_library)&lt;br /&gt;
* https://github.com/checkpoint-restore/go-criu/tree/master/crit&lt;br /&gt;
* https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: Go&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
* Suggested by: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=GSoC_completed_projects&amp;diff=5342</id>
		<title>GSoC completed projects</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=GSoC_completed_projects&amp;diff=5342"/>
		<updated>2023-01-25T07:28:44Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Support sparse ghosts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Restrict checks for open/mmaped files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Make sure the file opened (for fd or mapping) at restore is &amp;quot;the same&amp;quot; as it was on dump&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/pull/1123&lt;br /&gt;
&lt;br /&gt;
CRIU doesn't carry files contents (except for ghost ones) into images. Thus on dump it saves some &amp;quot;meta&amp;quot; for file to validate it's &amp;quot;the same&amp;quot; on restore. Currently this meta includes only the file size. The task is to add some cookie value that's somehow affected by file's contents. This is primarily needed to reduce the possibility to restore with wrong libraries.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/Category:Files&lt;br /&gt;
* https://en.wikipedia.org/wiki/File_verification&lt;br /&gt;
&lt;br /&gt;
=== Optimize the pre-dump algorithm ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Optimize the pre-dump algorithm to avoid pinning to many memory in RAM&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/commit/98608b90de0f853b1c8a6e15b312320e1441c359 &lt;br /&gt;
&lt;br /&gt;
Current [[CLI/cmd/pre-dump|pre-dump]] mode is used to write task memory contents into image&lt;br /&gt;
files w/o stopping the task for too long. It does this by stopping the task, infecting it and&lt;br /&gt;
draining all the memory into a set of pipes. Then the task is cured, resumed and the pipes'&lt;br /&gt;
contents is written into images (maybe a [[page server]]). Unfortunately, this approach creates&lt;br /&gt;
a big stress on the memory subsystem, as keeping all memory in pipes creates a lot of unreclaimable&lt;br /&gt;
memory (pages in pipes are not swappable), as well as the number of pipes themselves can be huge, as&lt;br /&gt;
one pipe doesn't store more than a fixed amount of data (see pipe(7) man page).&lt;br /&gt;
&lt;br /&gt;
A solution for this problem is to use a sys_read_process_vm() syscall, which will mitigate&lt;br /&gt;
all of the above. To do this we need to allocate a temporary buffer in criu, then walk the&lt;br /&gt;
target process vm by copying the memory piece-by-piece into it, then flush the data into image&lt;br /&gt;
(or page server), and repeat.&lt;br /&gt;
&lt;br /&gt;
Ideally there should be sys_splice_process_vm() syscall in the kernel, that does the same as&lt;br /&gt;
the read_process_vm does, but vmsplices the data&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Memory pre dump]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/351&lt;br /&gt;
* [[Memory dumping and restoring]], [[Memory changes tracking]]&lt;br /&gt;
* [http://man7.org/linux/man-pages/man2/process_vm_readv.2.html process_vm_readv(2)] [http://man7.org/linux/man-pages/man2/vmsplice.2.html vmsplice(2)] [https://lkml.org/lkml/2018/1/9/32 RFC for splice_process_vm syscall]&lt;br /&gt;
&lt;br /&gt;
=== Porting crit functionalities in GO ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Implement image view and manipulation in Go&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/go-criu/pull/66&lt;br /&gt;
 &lt;br /&gt;
CRIU's checkpoint images are stored on disk using protobuf. For easier analysis of checkpoint files CRIU has a tool called [[CRIT|CRiu Image Tool (CRIT)]]. It can display/decode CRIU image files from binary protobuf to JSON as well as encode JSON files back to the binary format. With closer integration of CRIU in container runtimes it becomes important to be able to view the CRIU output files. Either for manipulation before restoring or for reading checkpoint statistics (memory pages written to disk, memory pages skipped, process downtime).&lt;br /&gt;
&lt;br /&gt;
Currently CRIT is implemented in Python, for easier integration in other Go projects it is important to have image manipulation and analysis available from GO. This means we need a Go based library to read/modify/write/encode/decode CRIU's image files. Based on this library a Go based implementation of CRIT would be useful.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[CRIT (Go library)]]&lt;br /&gt;
* https://github.com/snprajwal/gsoc-2022&lt;br /&gt;
&lt;br /&gt;
=== Support sparse ghosts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' While sparse ghost files were in part supported for quiet some time, we still was not able to handle big sparse ghost files and highly fragmented sparse ghost files effectively.&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/pull/1944 https://github.com/checkpoint-restore/criu/pull/1963&lt;br /&gt;
&lt;br /&gt;
When criu dumps processes it also dumps files that are opened by them. It does this by saving file names by which the files are accessible. But sometimes files can have no names. It may happen if a task opened a file and then removed it. To dump this file criu cannot save its name (because the name doesn't exist). Instead criu saves the whole file. This is called &amp;quot;ghost file&amp;quot;. Since saving the whole file is very expensive (copying lots of data on disk) criu limits the maximum size of a ghost file. The latter is also not good, because there are &amp;quot;sparse&amp;quot; files, that are large in size, but may be small from the real disk usage perspective. The goal of the task is to support sparse ghost files, i.e. limit the size of the ghost not by its length but by disk usage and when copying the data detect the used blocks and save only those.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
 &lt;br /&gt;
*[https://en.wikipedia.org/wiki/Sparse_file Sparse files]&lt;br /&gt;
*[[Dumping files]]&lt;br /&gt;
*[[Invisible files]]&lt;br /&gt;
*[https://www.kernel.org/doc/html/latest/filesystems/fiemap.html Fiemap ioctl]&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=GSoC_completed_projects&amp;diff=5341</id>
		<title>GSoC completed projects</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=GSoC_completed_projects&amp;diff=5341"/>
		<updated>2023-01-25T07:28:14Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Restrict checks for open/mmaped files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Make sure the file opened (for fd or mapping) at restore is &amp;quot;the same&amp;quot; as it was on dump&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/pull/1123&lt;br /&gt;
&lt;br /&gt;
CRIU doesn't carry files contents (except for ghost ones) into images. Thus on dump it saves some &amp;quot;meta&amp;quot; for file to validate it's &amp;quot;the same&amp;quot; on restore. Currently this meta includes only the file size. The task is to add some cookie value that's somehow affected by file's contents. This is primarily needed to reduce the possibility to restore with wrong libraries.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/Category:Files&lt;br /&gt;
* https://en.wikipedia.org/wiki/File_verification&lt;br /&gt;
&lt;br /&gt;
=== Optimize the pre-dump algorithm ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Optimize the pre-dump algorithm to avoid pinning to many memory in RAM&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/commit/98608b90de0f853b1c8a6e15b312320e1441c359 &lt;br /&gt;
&lt;br /&gt;
Current [[CLI/cmd/pre-dump|pre-dump]] mode is used to write task memory contents into image&lt;br /&gt;
files w/o stopping the task for too long. It does this by stopping the task, infecting it and&lt;br /&gt;
draining all the memory into a set of pipes. Then the task is cured, resumed and the pipes'&lt;br /&gt;
contents is written into images (maybe a [[page server]]). Unfortunately, this approach creates&lt;br /&gt;
a big stress on the memory subsystem, as keeping all memory in pipes creates a lot of unreclaimable&lt;br /&gt;
memory (pages in pipes are not swappable), as well as the number of pipes themselves can be huge, as&lt;br /&gt;
one pipe doesn't store more than a fixed amount of data (see pipe(7) man page).&lt;br /&gt;
&lt;br /&gt;
A solution for this problem is to use a sys_read_process_vm() syscall, which will mitigate&lt;br /&gt;
all of the above. To do this we need to allocate a temporary buffer in criu, then walk the&lt;br /&gt;
target process vm by copying the memory piece-by-piece into it, then flush the data into image&lt;br /&gt;
(or page server), and repeat.&lt;br /&gt;
&lt;br /&gt;
Ideally there should be sys_splice_process_vm() syscall in the kernel, that does the same as&lt;br /&gt;
the read_process_vm does, but vmsplices the data&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Memory pre dump]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/351&lt;br /&gt;
* [[Memory dumping and restoring]], [[Memory changes tracking]]&lt;br /&gt;
* [http://man7.org/linux/man-pages/man2/process_vm_readv.2.html process_vm_readv(2)] [http://man7.org/linux/man-pages/man2/vmsplice.2.html vmsplice(2)] [https://lkml.org/lkml/2018/1/9/32 RFC for splice_process_vm syscall]&lt;br /&gt;
&lt;br /&gt;
=== Porting crit functionalities in GO ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Implement image view and manipulation in Go&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/go-criu/pull/66&lt;br /&gt;
 &lt;br /&gt;
CRIU's checkpoint images are stored on disk using protobuf. For easier analysis of checkpoint files CRIU has a tool called [[CRIT|CRiu Image Tool (CRIT)]]. It can display/decode CRIU image files from binary protobuf to JSON as well as encode JSON files back to the binary format. With closer integration of CRIU in container runtimes it becomes important to be able to view the CRIU output files. Either for manipulation before restoring or for reading checkpoint statistics (memory pages written to disk, memory pages skipped, process downtime).&lt;br /&gt;
&lt;br /&gt;
Currently CRIT is implemented in Python, for easier integration in other Go projects it is important to have image manipulation and analysis available from GO. This means we need a Go based library to read/modify/write/encode/decode CRIU's image files. Based on this library a Go based implementation of CRIT would be useful.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[CRIT (Go library)]]&lt;br /&gt;
* https://github.com/snprajwal/gsoc-2022&lt;br /&gt;
&lt;br /&gt;
=== Support sparse ghosts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' While sparse ghost files were in part supported for quiet some time, we still was not able to handle big sparse ghost files and highly fragmented sparse ghost files.&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/pull/1944 https://github.com/checkpoint-restore/criu/pull/1963&lt;br /&gt;
&lt;br /&gt;
When criu dumps processes it also dumps files that are opened by them. It does this by saving file names by which the files are accessible. But sometimes files can have no names. It may happen if a task opened a file and then removed it. To dump this file criu cannot save its name (because the name doesn't exist). Instead criu saves the whole file. This is called &amp;quot;ghost file&amp;quot;. Since saving the whole file is very expensive (copying lots of data on disk) criu limits the maximum size of a ghost file. The latter is also not good, because there are &amp;quot;sparse&amp;quot; files, that are large in size, but may be small from the real disk usage perspective. The goal of the task is to support sparse ghost files, i.e. limit the size of the ghost not by its length but by disk usage and when copying the data detect the used blocks and save only those.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
 &lt;br /&gt;
*[https://en.wikipedia.org/wiki/Sparse_file Sparse files]&lt;br /&gt;
*[[Dumping files]]&lt;br /&gt;
*[[Invisible files]]&lt;br /&gt;
*[https://www.kernel.org/doc/html/latest/filesystems/fiemap.html Fiemap ioctl]&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=GSoC_completed_projects&amp;diff=5340</id>
		<title>GSoC completed projects</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=GSoC_completed_projects&amp;diff=5340"/>
		<updated>2023-01-25T07:24:37Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: remove details for sparce ghost files&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Restrict checks for open/mmaped files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Make sure the file opened (for fd or mapping) at restore is &amp;quot;the same&amp;quot; as it was on dump&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/pull/1123&lt;br /&gt;
&lt;br /&gt;
CRIU doesn't carry files contents (except for ghost ones) into images. Thus on dump it saves some &amp;quot;meta&amp;quot; for file to validate it's &amp;quot;the same&amp;quot; on restore. Currently this meta includes only the file size. The task is to add some cookie value that's somehow affected by file's contents. This is primarily needed to reduce the possibility to restore with wrong libraries.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/Category:Files&lt;br /&gt;
* https://en.wikipedia.org/wiki/File_verification&lt;br /&gt;
&lt;br /&gt;
=== Optimize the pre-dump algorithm ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Optimize the pre-dump algorithm to avoid pinning to many memory in RAM&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/commit/98608b90de0f853b1c8a6e15b312320e1441c359 &lt;br /&gt;
&lt;br /&gt;
Current [[CLI/cmd/pre-dump|pre-dump]] mode is used to write task memory contents into image&lt;br /&gt;
files w/o stopping the task for too long. It does this by stopping the task, infecting it and&lt;br /&gt;
draining all the memory into a set of pipes. Then the task is cured, resumed and the pipes'&lt;br /&gt;
contents is written into images (maybe a [[page server]]). Unfortunately, this approach creates&lt;br /&gt;
a big stress on the memory subsystem, as keeping all memory in pipes creates a lot of unreclaimable&lt;br /&gt;
memory (pages in pipes are not swappable), as well as the number of pipes themselves can be huge, as&lt;br /&gt;
one pipe doesn't store more than a fixed amount of data (see pipe(7) man page).&lt;br /&gt;
&lt;br /&gt;
A solution for this problem is to use a sys_read_process_vm() syscall, which will mitigate&lt;br /&gt;
all of the above. To do this we need to allocate a temporary buffer in criu, then walk the&lt;br /&gt;
target process vm by copying the memory piece-by-piece into it, then flush the data into image&lt;br /&gt;
(or page server), and repeat.&lt;br /&gt;
&lt;br /&gt;
Ideally there should be sys_splice_process_vm() syscall in the kernel, that does the same as&lt;br /&gt;
the read_process_vm does, but vmsplices the data&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Memory pre dump]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/351&lt;br /&gt;
* [[Memory dumping and restoring]], [[Memory changes tracking]]&lt;br /&gt;
* [http://man7.org/linux/man-pages/man2/process_vm_readv.2.html process_vm_readv(2)] [http://man7.org/linux/man-pages/man2/vmsplice.2.html vmsplice(2)] [https://lkml.org/lkml/2018/1/9/32 RFC for splice_process_vm syscall]&lt;br /&gt;
&lt;br /&gt;
=== Porting crit functionalities in GO ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Implement image view and manipulation in Go&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/go-criu/pull/66&lt;br /&gt;
 &lt;br /&gt;
CRIU's checkpoint images are stored on disk using protobuf. For easier analysis of checkpoint files CRIU has a tool called [[CRIT|CRiu Image Tool (CRIT)]]. It can display/decode CRIU image files from binary protobuf to JSON as well as encode JSON files back to the binary format. With closer integration of CRIU in container runtimes it becomes important to be able to view the CRIU output files. Either for manipulation before restoring or for reading checkpoint statistics (memory pages written to disk, memory pages skipped, process downtime).&lt;br /&gt;
&lt;br /&gt;
Currently CRIT is implemented in Python, for easier integration in other Go projects it is important to have image manipulation and analysis available from GO. This means we need a Go based library to read/modify/write/encode/decode CRIU's image files. Based on this library a Go based implementation of CRIT would be useful.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[CRIT (Go library)]]&lt;br /&gt;
* https://github.com/snprajwal/gsoc-2022&lt;br /&gt;
&lt;br /&gt;
=== Support sparse ghosts ===&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/pull/1944 https://github.com/checkpoint-restore/criu/pull/1963&lt;br /&gt;
&lt;br /&gt;
When criu dumps processes it also dumps files that are opened by them. It does this by saving file names by which the files are accessible. But sometimes files can have no names. It may happen if a task opened a file and then removed it. To dump this file criu cannot save its name (because the name doesn't exist). Instead criu saves the whole file. This is called &amp;quot;ghost file&amp;quot;. Since saving the whole file is very expensive (copying lots of data on disk) criu limits the maximum size of a ghost file. The latter is also not good, because there are &amp;quot;sparse&amp;quot; files, that are large in size, but may be small from the real disk usage perspective. The goal of the task is to support sparse ghost files, i.e. limit the size of the ghost not by its length but by disk usage and when copying the data detect the used blocks and save only those.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
 &lt;br /&gt;
*[https://en.wikipedia.org/wiki/Sparse_file Sparse files]&lt;br /&gt;
*[[Dumping files]]&lt;br /&gt;
*[[Invisible files]]&lt;br /&gt;
*[https://www.kernel.org/doc/html/latest/filesystems/fiemap.html Fiemap ioctl]&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=GSoC_completed_projects&amp;diff=5339</id>
		<title>GSoC completed projects</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=GSoC_completed_projects&amp;diff=5339"/>
		<updated>2023-01-25T07:22:34Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: move support spare ghosts to done&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Restrict checks for open/mmaped files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Make sure the file opened (for fd or mapping) at restore is &amp;quot;the same&amp;quot; as it was on dump&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/pull/1123&lt;br /&gt;
&lt;br /&gt;
CRIU doesn't carry files contents (except for ghost ones) into images. Thus on dump it saves some &amp;quot;meta&amp;quot; for file to validate it's &amp;quot;the same&amp;quot; on restore. Currently this meta includes only the file size. The task is to add some cookie value that's somehow affected by file's contents. This is primarily needed to reduce the possibility to restore with wrong libraries.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/Category:Files&lt;br /&gt;
* https://en.wikipedia.org/wiki/File_verification&lt;br /&gt;
&lt;br /&gt;
=== Optimize the pre-dump algorithm ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Optimize the pre-dump algorithm to avoid pinning to many memory in RAM&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/commit/98608b90de0f853b1c8a6e15b312320e1441c359 &lt;br /&gt;
&lt;br /&gt;
Current [[CLI/cmd/pre-dump|pre-dump]] mode is used to write task memory contents into image&lt;br /&gt;
files w/o stopping the task for too long. It does this by stopping the task, infecting it and&lt;br /&gt;
draining all the memory into a set of pipes. Then the task is cured, resumed and the pipes'&lt;br /&gt;
contents is written into images (maybe a [[page server]]). Unfortunately, this approach creates&lt;br /&gt;
a big stress on the memory subsystem, as keeping all memory in pipes creates a lot of unreclaimable&lt;br /&gt;
memory (pages in pipes are not swappable), as well as the number of pipes themselves can be huge, as&lt;br /&gt;
one pipe doesn't store more than a fixed amount of data (see pipe(7) man page).&lt;br /&gt;
&lt;br /&gt;
A solution for this problem is to use a sys_read_process_vm() syscall, which will mitigate&lt;br /&gt;
all of the above. To do this we need to allocate a temporary buffer in criu, then walk the&lt;br /&gt;
target process vm by copying the memory piece-by-piece into it, then flush the data into image&lt;br /&gt;
(or page server), and repeat.&lt;br /&gt;
&lt;br /&gt;
Ideally there should be sys_splice_process_vm() syscall in the kernel, that does the same as&lt;br /&gt;
the read_process_vm does, but vmsplices the data&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Memory pre dump]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/351&lt;br /&gt;
* [[Memory dumping and restoring]], [[Memory changes tracking]]&lt;br /&gt;
* [http://man7.org/linux/man-pages/man2/process_vm_readv.2.html process_vm_readv(2)] [http://man7.org/linux/man-pages/man2/vmsplice.2.html vmsplice(2)] [https://lkml.org/lkml/2018/1/9/32 RFC for splice_process_vm syscall]&lt;br /&gt;
&lt;br /&gt;
=== Porting crit functionalities in GO ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Implement image view and manipulation in Go&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/go-criu/pull/66&lt;br /&gt;
 &lt;br /&gt;
CRIU's checkpoint images are stored on disk using protobuf. For easier analysis of checkpoint files CRIU has a tool called [[CRIT|CRiu Image Tool (CRIT)]]. It can display/decode CRIU image files from binary protobuf to JSON as well as encode JSON files back to the binary format. With closer integration of CRIU in container runtimes it becomes important to be able to view the CRIU output files. Either for manipulation before restoring or for reading checkpoint statistics (memory pages written to disk, memory pages skipped, process downtime).&lt;br /&gt;
&lt;br /&gt;
Currently CRIT is implemented in Python, for easier integration in other Go projects it is important to have image manipulation and analysis available from GO. This means we need a Go based library to read/modify/write/encode/decode CRIU's image files. Based on this library a Go based implementation of CRIT would be useful.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[CRIT (Go library)]]&lt;br /&gt;
* https://github.com/snprajwal/gsoc-2022&lt;br /&gt;
&lt;br /&gt;
=== Support sparse ghosts ===&lt;br /&gt;
&lt;br /&gt;
'''Merged:''' https://github.com/checkpoint-restore/criu/pull/1944 https://github.com/checkpoint-restore/criu/pull/1963&lt;br /&gt;
&lt;br /&gt;
When criu dumps processes it also dumps files that are opened by them. It does this by saving file names by which the files are accessible. But sometimes files can have no names. It may happen if a task opened a file and then removed it. To dump this file criu cannot save its name (because the name doesn't exist). Instead criu saves the whole file. This is called &amp;quot;ghost file&amp;quot;. Since saving the whole file is very expensive (copying lots of data on disk) criu limits the maximum size of a ghost file. The latter is also not good, because there are &amp;quot;sparse&amp;quot; files, that are large in size, but may be small from the real disk usage perspective. The goal of the task is to support sparse ghost files, i.e. limit the size of the ghost not by its length but by disk usage and when copying the data detect the used blocks and save only those.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
 &lt;br /&gt;
*[https://en.wikipedia.org/wiki/Sparse_file Sparse files]&lt;br /&gt;
*[[Dumping files]]&lt;br /&gt;
*[[Invisible files]]&lt;br /&gt;
*[https://www.kernel.org/doc/html/latest/filesystems/fiemap.html Fiemap ioctl]&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5338</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5338"/>
		<updated>2023-01-25T07:17:45Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: move sparce ghost files project to done&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@openvz.org mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Emelianov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelianov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for pidfd file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of pidfd descriptors&lt;br /&gt;
&lt;br /&gt;
There is pidfd_open syscall which allows opening&lt;br /&gt;
a special PID file descriptor. A user can send a signal to&lt;br /&gt;
the process (pidfd_send_signal syscall), wait for the process&lt;br /&gt;
(poll() on pidfd).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have pidfd's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/801319/&lt;br /&gt;
* https://lwn.net/Articles/794707/&lt;br /&gt;
* https://github.com/torvalds/linux/blob/v5.16/kernel/fork.c#L1877&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Christian Brauner &amp;lt;christian@brauner.io&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for memfd_secret file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of memfd_secret descriptors&lt;br /&gt;
&lt;br /&gt;
There is memfd_secret syscall which allows user to open&lt;br /&gt;
special memfd which is backed by special memory range which&lt;br /&gt;
is inaccessible by another processes (and the kernel too!).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have memfd_secret's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/865256/&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Mike Rapoport &amp;lt;mike.rapoport@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CGroup-v2 support ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' cgroup is a mechanism to organize processes hierarchically and distribute system resources along the hierarchy in a controlled and configurable manner. cgroup v2 is a new version of the cgroup file system. Unlike v1, cgroup v2 has only single hierarchy. CRIU has to dump/restore a container cgroup hierarchy along with all per-cgroup options. The cgroupv2 support in CRIU has to be compatible with Docker, containerd and cri-o.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[CGroups]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/252&lt;br /&gt;
* https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dump shmem in user-mode (unprivileged-mode) ===&lt;br /&gt;
&lt;br /&gt;
CRIU uses /proc/pid/map_files to dump and restore anonymous shared memory regions, but map_files is restricted to the global CAP_SYS_ADMIN capability. In most cases, it is possible to dump/restore shared memory region without map_files and we need to implement this in CRIU.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[User-mode]]&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt; / &amp;lt;alexander.mikhalitsyn@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander.mikhalitsyn@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
* Mentor: Pavel Emelianov &amp;lt;xemul@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelianov &amp;lt;xemul@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=GSoC_Students_Recommendations&amp;diff=5291</id>
		<title>GSoC Students Recommendations</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=GSoC_Students_Recommendations&amp;diff=5291"/>
		<updated>2022-05-23T21:28:02Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Takeoff */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:GSoC]]&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
The entry points for the community is the [https://github.com/checkpoint-restore GitHub checkpoint-restore project], [https://gitter.im/save-restore/CRIU Gitter] and &amp;lt;code&amp;gt;criu@openvz.org&amp;lt;/code&amp;gt; mailing list. Also, the [[Google Summer of Code Ideas|ideas]] page contains mentors' personal e-mails for each sub-project.&lt;br /&gt;
&lt;br /&gt;
== Takeoff ==&lt;br /&gt;
&lt;br /&gt;
Starting playing with CRIU is as simple as one, two, three:&lt;br /&gt;
&lt;br /&gt;
# Get the sources from [https://github.com/checkpoint-restore/criu]&lt;br /&gt;
# Build them with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
# Do your first C/R by running a simple test with &amp;lt;code&amp;gt;zdtm.py run -t zdtm/static/env00&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are links for further reading&lt;br /&gt;
&lt;br /&gt;
* [[Installation]]&lt;br /&gt;
* [[CLI]]&lt;br /&gt;
* [[Simple loop]]&lt;br /&gt;
* [[ZDTM test suite]]&lt;br /&gt;
&lt;br /&gt;
== Contributing ==&lt;br /&gt;
&lt;br /&gt;
When a new patch is ready, it can be submitted for merging either [[How_to_submit_patches|via the CRIU mailing list]] or via GitHub PR.&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=External_bind_mounts&amp;diff=5290</id>
		<title>External bind mounts</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=External_bind_mounts&amp;diff=5290"/>
		<updated>2022-05-16T09:41:25Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
One of typical external resources when dumping a container (especially LXC/Docker) is a mount point whose root sits outside of the container's root. This situation was intended to be resolved using [[plugins]] but turned out to be common enough to introduce a built-in way of handling it.&lt;br /&gt;
&lt;br /&gt;
== What is external bind mount ==&lt;br /&gt;
&lt;br /&gt;
The way to create such is simple as&lt;br /&gt;
&lt;br /&gt;
 mkdir /root&lt;br /&gt;
 mount --bind /foo /root/bar&lt;br /&gt;
 chroot /root&lt;br /&gt;
&lt;br /&gt;
This is it. From now on, the /bar file is a mountpoint whose root (the source) is not accessible directly.&lt;br /&gt;
&lt;br /&gt;
If you look at the /proc/$pid/mountinfo file of a task seeing such you would see smth like&lt;br /&gt;
&lt;br /&gt;
 11 23 8:3 /root / ... - ext4 /dev/sda1 ...&lt;br /&gt;
 23 34 8:3 /foo /bar ... - ext4 /dev/sda1 ...&lt;br /&gt;
&lt;br /&gt;
The columns 4 and 5 are root and mountpoint respectively. You can see, that the / is /root file from /dev/sda1 device and /bar file is a mountpoint with the root being /foo file from the same device.&lt;br /&gt;
&lt;br /&gt;
== How to teach CRIU to dump them ==&lt;br /&gt;
&lt;br /&gt;
By default CRIU doesn't dump such mountpoints, because there's no way CRIU will be able to restore it -- the root of these mounts is out of scope of what CRIU dumped. In the logs you would see a message like&lt;br /&gt;
&lt;br /&gt;
 34:/bar doesn't have a proper root mount&lt;br /&gt;
&lt;br /&gt;
which means the mountpoint /bar has inaccessible root.&lt;br /&gt;
&lt;br /&gt;
To dump and restore them there's the &amp;lt;code&amp;gt;--external mnt[KEY]:VAL&amp;lt;/code&amp;gt; option that sets up external mounts root mapping.&lt;br /&gt;
&lt;br /&gt;
On dump, KEY is a mountpoint inside container, and corresponding VAL is a string that will be written into the image as mountpoint's root value.&lt;br /&gt;
&lt;br /&gt;
On restore, KEY is the value from the image (VAL from dump), and the VAL is the path on host that will be bind-mounted into container (to the mountpoint path from image).&lt;br /&gt;
&lt;br /&gt;
For example, if we want to dump the task above we should call&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external mnt[/bar]:barmount&lt;br /&gt;
&lt;br /&gt;
The word &amp;lt;code&amp;gt;barmount&amp;lt;/code&amp;gt; is an arbitrary identifier, that will be put in the image file instead of the original root path&lt;br /&gt;
&lt;br /&gt;
 criu show -f mountpoints.img -F mnt_id,root,mountpoint&lt;br /&gt;
 mnt_id: 0x22 root: barmount mountpoint: /bar&lt;br /&gt;
&lt;br /&gt;
On restore we should tell CRIU where to bind mount the &amp;lt;code&amp;gt;barmount&amp;lt;/code&amp;gt; from like this&lt;br /&gt;
&lt;br /&gt;
 criu restore ... --external mnt[barmount]:/foo&lt;br /&gt;
&lt;br /&gt;
With this CRIU will bind mount the /foo into proper mountpoint.&lt;br /&gt;
&lt;br /&gt;
Note: Mounts from same superblock should remain mounts from same superblock after migration. Options `--external mnt[smth]:/smth` force criu to bindmount from the provided source, that can lead to mounts, which were from the same supperblock before dump, appear to be from different supperblock after restore, which is wrong so these option should be used carefully (can break sharing groups restore).&lt;br /&gt;
&lt;br /&gt;
== Auto detection ==&lt;br /&gt;
&lt;br /&gt;
In case one wants CRIU to autodetect and dump all the external bind mounts, and there is no need to change host mount points on restore, one can use a special syntax:&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external mnt[]:''flags''&lt;br /&gt;
&lt;br /&gt;
Note here is nothing inside square brackets, and the optional &amp;lt;code&amp;gt;:''flags''&amp;lt;/code&amp;gt; argument can contain the following characters:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;&lt;br /&gt;
: Also enable dumping of external master mounts (as in &amp;lt;code&amp;gt;mount --make-slave&amp;lt;/code&amp;gt;)&lt;br /&gt;
; &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;&lt;br /&gt;
: Also enable dumping of external shared mounts (as in &amp;lt;code&amp;gt;mount --make-shared&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
By default, neither master nor shared external mounts are dumped (if found, dump is aborted). Note if &amp;lt;code&amp;gt;''flags''&amp;lt;/code&amp;gt; are not given, semicolon is optional.&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]'&lt;br /&gt;
&lt;br /&gt;
Auto-detect and dump all external bind mounts.&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]:s'&lt;br /&gt;
&lt;br /&gt;
Auto-detect and dump all external bind mounts, including the shared ones.&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]:sm'&lt;br /&gt;
&lt;br /&gt;
Auto-detect and dump all external bind mounts, including the shared and the master ones.&lt;br /&gt;
&lt;br /&gt;
== Sharing ==&lt;br /&gt;
&lt;br /&gt;
External bindmounts can both have internal/external sharing. Please see the example:&lt;br /&gt;
&lt;br /&gt;
 # Preparation&lt;br /&gt;
 unshare -m --propagation private&lt;br /&gt;
 mkdir /external_mount_sharing_test&lt;br /&gt;
 mount -t tmpfs tmpfs /external_mount_sharing_test/&lt;br /&gt;
 mount --make-private /external_mount_sharing_test/&lt;br /&gt;
 cd /external_mount_sharing_test&lt;br /&gt;
 # Source of external mount&lt;br /&gt;
 mkdir external_mount&lt;br /&gt;
 mount -t tmpfs tmpfs-external external_mount/&lt;br /&gt;
 mount --make-shared external_mount/&lt;br /&gt;
 cat /proc/$$/mountinfo | grep external&lt;br /&gt;
 # 811 755 0:60 / /external_mount_sharing_test rw,relatime - tmpfs tmpfs rw&lt;br /&gt;
 # 812 811 0:62 / /external_mount_sharing_test/external_mount rw,relatime shared:290 - tmpfs tmpfs-external rw&lt;br /&gt;
 &lt;br /&gt;
 # Switch to CT mntns&lt;br /&gt;
 unshare -m --propagation unchanged sh&lt;br /&gt;
 mkdir root&lt;br /&gt;
 mount -t tmpfs tmpfs-root root/&lt;br /&gt;
 mkdir root/external_sharing root/internal_sharing root/proc&lt;br /&gt;
 &lt;br /&gt;
 # Create external mount&lt;br /&gt;
 mount --bind external_mount/ root/external_sharing&lt;br /&gt;
 mount --bind external_mount/ root/internal_sharing&lt;br /&gt;
 mount --make-private root/internal_sharing&lt;br /&gt;
 mount --make-shared root/internal_sharing&lt;br /&gt;
 &lt;br /&gt;
 # More preparations&lt;br /&gt;
 mount --bind /proc root/proc&lt;br /&gt;
 cd root&lt;br /&gt;
 mkdir bin lib64&lt;br /&gt;
 SH=$(which sh)&lt;br /&gt;
 cp $SH bin&lt;br /&gt;
 cp $(ldd $SH | grep &amp;quot;/lib64&amp;quot; | sed 's/^.*\(\/lib64\S*\)\s.*$/\1/') lib64&lt;br /&gt;
 CAT=$(which cat)&lt;br /&gt;
 cp $CAT bin&lt;br /&gt;
 cp $(ldd $CAT | grep &amp;quot;/lib64&amp;quot; | sed 's/^.*\(\/lib64\S*\)\s.*$/\1/') lib64&lt;br /&gt;
 PATH=$PATH:/bin&lt;br /&gt;
 chroot . sh&lt;br /&gt;
 cat /proc/$$/mountinfo&lt;br /&gt;
 # 843 841 0:63 / / rw,relatime - tmpfs tmpfs-root rw&lt;br /&gt;
 # 861 843 0:62 / /external_sharing rw,relatime shared:290 - tmpfs tmpfs-external rw&lt;br /&gt;
 # 898 843 0:62 / /internal_sharing rw,relatime shared:349 - tmpfs tmpfs-external rw&lt;br /&gt;
 # 899 843 0:5 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw&lt;br /&gt;
&lt;br /&gt;
Mounts 812 (on the host) and 861 (in a container) have the same sharing (shared group) - external sharing and mount 898 has it's own local shared group - internal sharing. Same is applicable for master_ids, if we convert them into slaves external/internal shared_id would convert to external/internal master_id.&lt;br /&gt;
&lt;br /&gt;
[https://criu.org/Mount-v2 Mount-v2] is introducing a better support of external sharing:&lt;br /&gt;
&lt;br /&gt;
- External sharing is not supported (converted to internal sharing after c/r) as reasonable container environments should not allow it due to security reasons, and implementing it's lookup would lead to bad performance (host mountinfo reading).&lt;br /&gt;
&lt;br /&gt;
- External slavery is supported for mountpoint external mounts and the root mount. It is detected when criu can't lookup master_id of the mount across shared_ids in container mount namespaces. CRIU relies that mountpoint external source provides right shared/slave mount to copy sharing from. Everything else is considered as internal sharing/slavery.&lt;br /&gt;
&lt;br /&gt;
== Old days ==&lt;br /&gt;
&lt;br /&gt;
For now the same behavior is configured with the &amp;lt;code&amp;gt;--ext-mount-map KEY:VAL&amp;lt;/code&amp;gt; option. Soon this option will be [[deprecation|deprecated]].&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:External]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=External_bind_mounts&amp;diff=5275</id>
		<title>External bind mounts</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=External_bind_mounts&amp;diff=5275"/>
		<updated>2022-04-28T11:17:22Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Sharing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
One of typical external resources when dumping a container (especially LXC/Docker) is a mount point whose root sits outside of the container's root. This situation was intended to be resolved using [[plugins]] but turned out to be common enough to introduce a built-in way of handling it.&lt;br /&gt;
&lt;br /&gt;
== What is external bind mount ==&lt;br /&gt;
&lt;br /&gt;
The way to create such is simple as&lt;br /&gt;
&lt;br /&gt;
 mkdir /root&lt;br /&gt;
 mount --bind /foo /root/bar&lt;br /&gt;
 chroot /root&lt;br /&gt;
&lt;br /&gt;
This is it. From now on, the /bar file is a mountpoint whose root (the source) is not accessible directly.&lt;br /&gt;
&lt;br /&gt;
If you look at the /proc/$pid/mountinfo file of a task seeing such you would see smth like&lt;br /&gt;
&lt;br /&gt;
 11 23 8:3 /root / ... - ext4 /dev/sda1 ...&lt;br /&gt;
 23 34 8:3 /foo /bar ... - ext4 /dev/sda1 ...&lt;br /&gt;
&lt;br /&gt;
The columns 4 and 5 are root and mountpoint respectively. You can see, that the / is /root file from /dev/sda1 device and /bar file is a mountpoint with the root being /foo file from the same device.&lt;br /&gt;
&lt;br /&gt;
== How to teach CRIU to dump them ==&lt;br /&gt;
&lt;br /&gt;
By default CRIU doesn't dump such mountpoints, because there's no way CRIU will be able to restore it -- the root of these mounts is out of scope of what CRIU dumped. In the logs you would see a message like&lt;br /&gt;
&lt;br /&gt;
 34:/bar doesn't have a proper root mount&lt;br /&gt;
&lt;br /&gt;
which means the mountpoint /bar has inaccessible root.&lt;br /&gt;
&lt;br /&gt;
To dump and restore them there's the &amp;lt;code&amp;gt;--external mnt[KEY]:VAL&amp;lt;/code&amp;gt; option that sets up external mounts root mapping.&lt;br /&gt;
&lt;br /&gt;
On dump, KEY is a mountpoint inside container, and corresponding VAL is a string that will be written into the image as mountpoint's root value.&lt;br /&gt;
&lt;br /&gt;
On restore, KEY is the value from the image (VAL from dump), and the VAL is the path on host that will be bind-mounted into container (to the mountpoint path from image).&lt;br /&gt;
&lt;br /&gt;
For example, if we want to dump the task above we should call&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external mnt[/bar]:barmount&lt;br /&gt;
&lt;br /&gt;
The word &amp;lt;code&amp;gt;barmount&amp;lt;/code&amp;gt; is an arbitrary identifier, that will be put in the image file instead of the original root path&lt;br /&gt;
&lt;br /&gt;
 criu show -f mountpoints.img -F mnt_id,root,mountpoint&lt;br /&gt;
 mnt_id: 0x22 root: barmount mountpoint: /bar&lt;br /&gt;
&lt;br /&gt;
On restore we should tell CRIU where to bind mount the &amp;lt;code&amp;gt;barmount&amp;lt;/code&amp;gt; from like this&lt;br /&gt;
&lt;br /&gt;
 criu restore ... --external mnt[barmount]:/foo&lt;br /&gt;
&lt;br /&gt;
With this CRIU will bind mount the /foo into proper mountpoint.&lt;br /&gt;
&lt;br /&gt;
== Auto detection ==&lt;br /&gt;
&lt;br /&gt;
In case one wants CRIU to autodetect and dump all the external bind mounts, and there is no need to change host mount points on restore, one can use a special syntax:&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external mnt[]:''flags''&lt;br /&gt;
&lt;br /&gt;
Note here is nothing inside square brackets, and the optional &amp;lt;code&amp;gt;:''flags''&amp;lt;/code&amp;gt; argument can contain the following characters:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;&lt;br /&gt;
: Also enable dumping of external master mounts (as in &amp;lt;code&amp;gt;mount --make-slave&amp;lt;/code&amp;gt;)&lt;br /&gt;
; &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;&lt;br /&gt;
: Also enable dumping of external shared mounts (as in &amp;lt;code&amp;gt;mount --make-shared&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
By default, neither master nor shared external mounts are dumped (if found, dump is aborted). Note if &amp;lt;code&amp;gt;''flags''&amp;lt;/code&amp;gt; are not given, semicolon is optional.&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]'&lt;br /&gt;
&lt;br /&gt;
Auto-detect and dump all external bind mounts.&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]:s'&lt;br /&gt;
&lt;br /&gt;
Auto-detect and dump all external bind mounts, including the shared ones.&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]:sm'&lt;br /&gt;
&lt;br /&gt;
Auto-detect and dump all external bind mounts, including the shared and the master ones.&lt;br /&gt;
&lt;br /&gt;
== Sharing ==&lt;br /&gt;
&lt;br /&gt;
External bindmounts can both have internal/external sharing. Please see the example:&lt;br /&gt;
&lt;br /&gt;
 # Preparation&lt;br /&gt;
 unshare -m --propagation private&lt;br /&gt;
 mkdir /external_mount_sharing_test&lt;br /&gt;
 mount -t tmpfs tmpfs /external_mount_sharing_test/&lt;br /&gt;
 mount --make-private /external_mount_sharing_test/&lt;br /&gt;
 cd /external_mount_sharing_test&lt;br /&gt;
 # Source of external mount&lt;br /&gt;
 mkdir external_mount&lt;br /&gt;
 mount -t tmpfs tmpfs-external external_mount/&lt;br /&gt;
 mount --make-shared external_mount/&lt;br /&gt;
 cat /proc/$$/mountinfo | grep external&lt;br /&gt;
 # 811 755 0:60 / /external_mount_sharing_test rw,relatime - tmpfs tmpfs rw&lt;br /&gt;
 # 812 811 0:62 / /external_mount_sharing_test/external_mount rw,relatime shared:290 - tmpfs tmpfs-external rw&lt;br /&gt;
 &lt;br /&gt;
 # Switch to CT mntns&lt;br /&gt;
 unshare -m --propagation unchanged sh&lt;br /&gt;
 mkdir root&lt;br /&gt;
 mount -t tmpfs tmpfs-root root/&lt;br /&gt;
 mkdir root/external_sharing root/internal_sharing root/proc&lt;br /&gt;
 &lt;br /&gt;
 # Create external mount&lt;br /&gt;
 mount --bind external_mount/ root/external_sharing&lt;br /&gt;
 mount --bind external_mount/ root/internal_sharing&lt;br /&gt;
 mount --make-private root/internal_sharing&lt;br /&gt;
 mount --make-shared root/internal_sharing&lt;br /&gt;
 &lt;br /&gt;
 # More preparations&lt;br /&gt;
 mount --bind /proc root/proc&lt;br /&gt;
 cd root&lt;br /&gt;
 mkdir bin lib64&lt;br /&gt;
 SH=$(which sh)&lt;br /&gt;
 cp $SH bin&lt;br /&gt;
 cp $(ldd $SH | grep &amp;quot;/lib64&amp;quot; | sed 's/^.*\(\/lib64\S*\)\s.*$/\1/') lib64&lt;br /&gt;
 CAT=$(which cat)&lt;br /&gt;
 cp $CAT bin&lt;br /&gt;
 cp $(ldd $CAT | grep &amp;quot;/lib64&amp;quot; | sed 's/^.*\(\/lib64\S*\)\s.*$/\1/') lib64&lt;br /&gt;
 PATH=$PATH:/bin&lt;br /&gt;
 chroot . sh&lt;br /&gt;
 cat /proc/$$/mountinfo&lt;br /&gt;
 # 843 841 0:63 / / rw,relatime - tmpfs tmpfs-root rw&lt;br /&gt;
 # 861 843 0:62 / /external_sharing rw,relatime shared:290 - tmpfs tmpfs-external rw&lt;br /&gt;
 # 898 843 0:62 / /internal_sharing rw,relatime shared:349 - tmpfs tmpfs-external rw&lt;br /&gt;
 # 899 843 0:5 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw&lt;br /&gt;
&lt;br /&gt;
Mounts 812 (on the host) and 861 (in a container) have the same sharing (shared group) - external sharing and mount 898 has it's own local shared group - internal sharing. Same is applicable for master_ids, if we convert them into slaves external/internal shared_id would convert to external/internal master_id.&lt;br /&gt;
&lt;br /&gt;
[https://criu.org/Mount-v2 Mount-v2] is introducing a better support of external sharing:&lt;br /&gt;
&lt;br /&gt;
- External sharing is not supported (converted to internal sharing after c/r) as reasonable container environments should not allow it due to security reasons, and implementing it's lookup would lead to bad performance (host mountinfo reading).&lt;br /&gt;
&lt;br /&gt;
- External slavery is supported for mountpoint external mounts and the root mount. It is detected when criu can't lookup master_id of the mount across shared_ids in container mount namespaces. CRIU relies that mountpoint external source provides right shared/slave mount to copy sharing from. Everything else is considered as internal sharing/slavery.&lt;br /&gt;
&lt;br /&gt;
== Old days ==&lt;br /&gt;
&lt;br /&gt;
For now the same behavior is configured with the &amp;lt;code&amp;gt;--ext-mount-map KEY:VAL&amp;lt;/code&amp;gt; option. Soon this option will be [[deprecation|deprecated]].&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:External]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=External_bind_mounts&amp;diff=5274</id>
		<title>External bind mounts</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=External_bind_mounts&amp;diff=5274"/>
		<updated>2022-04-28T11:16:38Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Sharing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
One of typical external resources when dumping a container (especially LXC/Docker) is a mount point whose root sits outside of the container's root. This situation was intended to be resolved using [[plugins]] but turned out to be common enough to introduce a built-in way of handling it.&lt;br /&gt;
&lt;br /&gt;
== What is external bind mount ==&lt;br /&gt;
&lt;br /&gt;
The way to create such is simple as&lt;br /&gt;
&lt;br /&gt;
 mkdir /root&lt;br /&gt;
 mount --bind /foo /root/bar&lt;br /&gt;
 chroot /root&lt;br /&gt;
&lt;br /&gt;
This is it. From now on, the /bar file is a mountpoint whose root (the source) is not accessible directly.&lt;br /&gt;
&lt;br /&gt;
If you look at the /proc/$pid/mountinfo file of a task seeing such you would see smth like&lt;br /&gt;
&lt;br /&gt;
 11 23 8:3 /root / ... - ext4 /dev/sda1 ...&lt;br /&gt;
 23 34 8:3 /foo /bar ... - ext4 /dev/sda1 ...&lt;br /&gt;
&lt;br /&gt;
The columns 4 and 5 are root and mountpoint respectively. You can see, that the / is /root file from /dev/sda1 device and /bar file is a mountpoint with the root being /foo file from the same device.&lt;br /&gt;
&lt;br /&gt;
== How to teach CRIU to dump them ==&lt;br /&gt;
&lt;br /&gt;
By default CRIU doesn't dump such mountpoints, because there's no way CRIU will be able to restore it -- the root of these mounts is out of scope of what CRIU dumped. In the logs you would see a message like&lt;br /&gt;
&lt;br /&gt;
 34:/bar doesn't have a proper root mount&lt;br /&gt;
&lt;br /&gt;
which means the mountpoint /bar has inaccessible root.&lt;br /&gt;
&lt;br /&gt;
To dump and restore them there's the &amp;lt;code&amp;gt;--external mnt[KEY]:VAL&amp;lt;/code&amp;gt; option that sets up external mounts root mapping.&lt;br /&gt;
&lt;br /&gt;
On dump, KEY is a mountpoint inside container, and corresponding VAL is a string that will be written into the image as mountpoint's root value.&lt;br /&gt;
&lt;br /&gt;
On restore, KEY is the value from the image (VAL from dump), and the VAL is the path on host that will be bind-mounted into container (to the mountpoint path from image).&lt;br /&gt;
&lt;br /&gt;
For example, if we want to dump the task above we should call&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external mnt[/bar]:barmount&lt;br /&gt;
&lt;br /&gt;
The word &amp;lt;code&amp;gt;barmount&amp;lt;/code&amp;gt; is an arbitrary identifier, that will be put in the image file instead of the original root path&lt;br /&gt;
&lt;br /&gt;
 criu show -f mountpoints.img -F mnt_id,root,mountpoint&lt;br /&gt;
 mnt_id: 0x22 root: barmount mountpoint: /bar&lt;br /&gt;
&lt;br /&gt;
On restore we should tell CRIU where to bind mount the &amp;lt;code&amp;gt;barmount&amp;lt;/code&amp;gt; from like this&lt;br /&gt;
&lt;br /&gt;
 criu restore ... --external mnt[barmount]:/foo&lt;br /&gt;
&lt;br /&gt;
With this CRIU will bind mount the /foo into proper mountpoint.&lt;br /&gt;
&lt;br /&gt;
== Auto detection ==&lt;br /&gt;
&lt;br /&gt;
In case one wants CRIU to autodetect and dump all the external bind mounts, and there is no need to change host mount points on restore, one can use a special syntax:&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external mnt[]:''flags''&lt;br /&gt;
&lt;br /&gt;
Note here is nothing inside square brackets, and the optional &amp;lt;code&amp;gt;:''flags''&amp;lt;/code&amp;gt; argument can contain the following characters:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;&lt;br /&gt;
: Also enable dumping of external master mounts (as in &amp;lt;code&amp;gt;mount --make-slave&amp;lt;/code&amp;gt;)&lt;br /&gt;
; &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;&lt;br /&gt;
: Also enable dumping of external shared mounts (as in &amp;lt;code&amp;gt;mount --make-shared&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
By default, neither master nor shared external mounts are dumped (if found, dump is aborted). Note if &amp;lt;code&amp;gt;''flags''&amp;lt;/code&amp;gt; are not given, semicolon is optional.&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]'&lt;br /&gt;
&lt;br /&gt;
Auto-detect and dump all external bind mounts.&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]:s'&lt;br /&gt;
&lt;br /&gt;
Auto-detect and dump all external bind mounts, including the shared ones.&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]:sm'&lt;br /&gt;
&lt;br /&gt;
Auto-detect and dump all external bind mounts, including the shared and the master ones.&lt;br /&gt;
&lt;br /&gt;
== Sharing ==&lt;br /&gt;
&lt;br /&gt;
External bindmounts can both have internal/external sharing. Please see the example:&lt;br /&gt;
&lt;br /&gt;
 # Preparation&lt;br /&gt;
 unshare -m --propagation private&lt;br /&gt;
 mkdir /external_mount_sharing_test&lt;br /&gt;
 mount -t tmpfs tmpfs /external_mount_sharing_test/&lt;br /&gt;
 mount --make-private /external_mount_sharing_test/&lt;br /&gt;
 cd /external_mount_sharing_test&lt;br /&gt;
 # Source of external mount&lt;br /&gt;
 mkdir external_mount&lt;br /&gt;
 mount -t tmpfs tmpfs-external external_mount/&lt;br /&gt;
 mount --make-shared external_mount/&lt;br /&gt;
 cat /proc/$$/mountinfo | grep external&lt;br /&gt;
 # 811 755 0:60 / /external_mount_sharing_test rw,relatime - tmpfs tmpfs rw&lt;br /&gt;
 # 812 811 0:62 / /external_mount_sharing_test/external_mount rw,relatime shared:290 - tmpfs tmpfs-external rw&lt;br /&gt;
 &lt;br /&gt;
 # Switch to CT mntns&lt;br /&gt;
 unshare -m --propagation unchanged sh&lt;br /&gt;
 mkdir root&lt;br /&gt;
 mount -t tmpfs tmpfs-root root/&lt;br /&gt;
 mkdir root/external_sharing root/internal_sharing root/proc&lt;br /&gt;
 &lt;br /&gt;
 # Create external mount&lt;br /&gt;
 mount --bind external_mount/ root/external_sharing&lt;br /&gt;
 mount --bind external_mount/ root/internal_sharing&lt;br /&gt;
 mount --make-private root/internal_sharing&lt;br /&gt;
 mount --make-shared root/internal_sharing&lt;br /&gt;
 &lt;br /&gt;
 # More preparations&lt;br /&gt;
 mount --bind /proc root/proc&lt;br /&gt;
 cd root&lt;br /&gt;
 mkdir bin lib64&lt;br /&gt;
 SH=$(which sh)&lt;br /&gt;
 cp $SH bin&lt;br /&gt;
 cp $(ldd $SH | grep &amp;quot;/lib64&amp;quot; | sed 's/^.*\(\/lib64\S*\)\s.*$/\1/') lib64&lt;br /&gt;
 CAT=$(which cat)&lt;br /&gt;
 cp $CAT bin&lt;br /&gt;
 cp $(ldd $CAT | grep &amp;quot;/lib64&amp;quot; | sed 's/^.*\(\/lib64\S*\)\s.*$/\1/') lib64&lt;br /&gt;
 PATH=$PATH:/bin&lt;br /&gt;
 chroot . sh&lt;br /&gt;
 cat /proc/$$/mountinfo&lt;br /&gt;
 # 843 841 0:63 / / rw,relatime - tmpfs tmpfs-root rw&lt;br /&gt;
 # 861 843 0:62 / /external_sharing rw,relatime shared:290 - tmpfs tmpfs-external rw&lt;br /&gt;
 # 898 843 0:62 / /internal_sharing rw,relatime shared:349 - tmpfs tmpfs-external rw&lt;br /&gt;
 # 899 843 0:5 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw&lt;br /&gt;
&lt;br /&gt;
Mounts 812 (on the host) and 861 (in a container) have the same sharing (shared group) - external sharing and mount 898 has it's own local shared group - internal sharing. Same is applicable for master_ids, if we convert them into slaves external/internal shared_id would convert to external/internal master_id.&lt;br /&gt;
&lt;br /&gt;
[https://criu.org/Mount-v2 Mount-v2] is introducing a better support of external sharing:&lt;br /&gt;
&lt;br /&gt;
- External sharing is not supported (converted to internal sharing after c/r) as reasonable container environments should not allow it due to security reasons, and implementing it's lookup would lead to bad performance (host mountinfo reading).&lt;br /&gt;
- External slavery is supported for mountpoint external mounts and the root mount. It is detected when criu can't lookup master_id of the mount across shared_ids in container mount namespaces. CRIU relies that mountpoint external source provides right shared/slave mount to copy sharing from. Everything else is considered as internal sharing/slavery.&lt;br /&gt;
&lt;br /&gt;
== Old days ==&lt;br /&gt;
&lt;br /&gt;
For now the same behavior is configured with the &amp;lt;code&amp;gt;--ext-mount-map KEY:VAL&amp;lt;/code&amp;gt; option. Soon this option will be [[deprecation|deprecated]].&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:External]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5260</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5260"/>
		<updated>2022-04-11T12:00:36Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: Add detached mounts idea&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@openvz.org mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Support sparse ghosts ===&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
When criu dumps processes it also dumps files that are opened by them. It does this by saving file names by which the files are accessible. But sometimes files can have no names. It may happen if a task opened a file and then removed it. To dump this file criu cannot save its name (because the name doesn't exist). Instead criu saves the whole file. This is called &amp;quot;ghost file&amp;quot;. Since saving the whole file is very expensive (copying lots of data on disk) criu limits the maximum size of a ghost file. The latter is also not good, because there are &amp;quot;sparse&amp;quot; files, that are large in size, but may be small from the real disk usage perspective. The goal of the task is to support sparse ghost files, i.e. limit the size of the ghost not by its length but by disk usage and when copying the data detect the used blocks and save only those.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
 &lt;br /&gt;
*[https://en.wikipedia.org/wiki/Sparse_file Sparse files]&lt;br /&gt;
*[[Dumping files]]&lt;br /&gt;
*[[Invisible files]]&lt;br /&gt;
*[https://www.kernel.org/doc/html/latest/filesystems/fiemap.html Fiemap ioctl]&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Emelianov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelianov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for pidfd file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of pidfd descriptors&lt;br /&gt;
&lt;br /&gt;
There is pidfd_open syscall which allows opening&lt;br /&gt;
a special PID file descriptor. A user can send a signal to&lt;br /&gt;
the process (pidfd_send_signal syscall), wait for the process&lt;br /&gt;
(poll() on pidfd).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have pidfd's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/801319/&lt;br /&gt;
* https://lwn.net/Articles/794707/&lt;br /&gt;
* https://github.com/torvalds/linux/blob/v5.16/kernel/fork.c#L1877&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Christian Brauner &amp;lt;christian@brauner.io&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for memfd_secret file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of memfd_secret descriptors&lt;br /&gt;
&lt;br /&gt;
There is memfd_secret syscall which allows user to open&lt;br /&gt;
special memfd which is backed by special memory range which&lt;br /&gt;
is inaccessible by another processes (and the kernel too!).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have memfd_secret's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/865256/&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Mike Rapoport &amp;lt;mike.rapoport@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CGroup-v2 support ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' cgroup is a mechanism to organize processes hierarchically and distribute system resources along the hierarchy in a controlled and configurable manner. cgroup v2 is a new version of the cgroup file system. Unlike v1, cgroup v2 has only single hierarchy. CRIU has to dump/restore a container cgroup hierarchy along with all per-cgroup options. The cgroupv2 support in CRIU has to be compatible with Docker, containerd and cri-o.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[CGroups]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/252&lt;br /&gt;
* https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dump shmem in user-mode (unprivileged-mode) ===&lt;br /&gt;
&lt;br /&gt;
CRIU uses /proc/pid/map_files to dump and restore anonymous shared memory regions, but map_files is restricted to the global CAP_SYS_ADMIN capability. In most cases, it is possible to dump/restore shared memory region without map_files and we need to implement this in CRIU.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[User-mode]]&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Porting crit functionalities in GO ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Implement image view and manipulation in Go&lt;br /&gt;
 &lt;br /&gt;
CRIU's checkpoint images are stored on disk using protobuf. For easier analysis of checkpoint files CRIU has a tool called [[CRIT|CRiu Image Tool (CRIT)]]. It can display/decode CRIU image files from binary protobuf to JSON as well as encode JSON files back to the binary format. With closer integration of CRIU in container runtimes it becomes important to be able to view the CRIU output files. Either for manipulation before restoring or for reading checkpoint statistics (memory pages written to disk, memory pages skipped, process downtime).&lt;br /&gt;
&lt;br /&gt;
Currently CRIT is implemented in Python, for easier integration in other Go projects it is important to have image manipulation and analysis available from GO. This means we need a Go based library to read/modify/write/encode/decode CRIU's image files. Based on this library a Go based implementation of CRIT would be useful.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[CRIT]]&lt;br /&gt;
* Possible use case see LXD: https://github.com/lxc/lxd/blob/cb55b1c5a484a43e0c21c6ae8c4a2e30b4d45be3/lxd/migrate_container.go#L179&lt;br /&gt;
* https://github.com/lxc/lxd/pull/4072&lt;br /&gt;
* https://github.com/checkpoint-restore/go-criu/tree/master/stats&lt;br /&gt;
* https://github.com/checkpoint-restore/go-criu/pull/28&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Go&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander.mikhalitsyn@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Files on detached mounts ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Initial support of open files on &amp;quot;detached&amp;quot; mounts&lt;br /&gt;
&lt;br /&gt;
When criu dumps a process with an open fd on a file, it gets the mount identifier (mnt_id) via /proc/&amp;lt;pid&amp;gt;/fdinfo/&amp;lt;fd&amp;gt;, so that criu knows from which exact mount the file was initially opened. This way criu can restore this fd by opening the same exact file from topologically the same mount in restored mount tree.&lt;br /&gt;
&lt;br /&gt;
Restoring fd from the right mount can be important in different cases, for instance if the process would later want to resolve paths relative to the fd, and obviously resolving from the same file on different mount can lead to different resolved paths, or if the process wants to check path to the file via /proc/&amp;lt;pid&amp;gt;/fd/&amp;lt;fd&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
But we have a problem finding on which mount we need to reopen the file at restore if we only know mnt_id but can't find this mnt_id in /proc/&amp;lt;pid&amp;gt;/mountinfo.&lt;br /&gt;
&lt;br /&gt;
Mountinfo file shows the mount tree topology of current mntns: parent - child relations, sharing group information, mountpoint and fs root information. And if we don't see mnt_id in it we don't know anything about this mount.&lt;br /&gt;
&lt;br /&gt;
This can happen in two cases&lt;br /&gt;
&lt;br /&gt;
* 1) external mount or file - if file was opened from e.g. host it's mount would not be visible in container mountinfo&lt;br /&gt;
* 2) mount was lazily unmounted&lt;br /&gt;
&lt;br /&gt;
In case of 1) we have criu options to help criu handle external dependencies.&lt;br /&gt;
&lt;br /&gt;
In case of 2) or no options provided criu can't resolve mnt_id in mountinfo and criu fails.&lt;br /&gt;
&lt;br /&gt;
'''Solution:'''&lt;br /&gt;
We can handle 2) with: resolving major/minor via fstat, using name_to_handle_at and open_by_handle_at to open same file on any other available mount from same superblock (same major/minor) in container. Now we have fd2 of the same file as fd, but on existing mount we can dump it as usual instead, and mark it as &amp;quot;detached&amp;quot; in image, now criu on restore knows where to find this file, but instead of just opening fd2 from actually restored mount, we create a temporary bindmount which is lazy unmounted just after open making the file appear as a file on detached mount.&lt;br /&gt;
&lt;br /&gt;
Known problems with this approach:&lt;br /&gt;
&lt;br /&gt;
* Stat on btrfs gives wrong major/minor&lt;br /&gt;
* file handles does not work everywhere&lt;br /&gt;
* file handles can return fd2 on deleted file or on other hardlink, this needs special handling.&lt;br /&gt;
&lt;br /&gt;
Additionally (optional part):&lt;br /&gt;
We can export real major/minor in fdinfo (kernel).&lt;br /&gt;
We can think of new kernel interface to get mount's major/minor and root (shift from fsroot) for detached mounts, if we have it we don't need file handle hack to find file on other mount (see fsinfo or getvalues kernel patches in LKML, can we add this info there?).&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt; / &amp;lt;alexander.mikhalitsyn@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander.mikhalitsyn@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
* Mentor: Pavel Emelianov &amp;lt;xemul@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelianov &amp;lt;xemul@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5259</id>
		<title>Google Summer of Code Ideas</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Google_Summer_of_Code_Ideas&amp;diff=5259"/>
		<updated>2022-04-11T09:34:51Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Support sparse ghosts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Google Summer of Code (GSoC) is a global program that offers post-secondary students an opportunity to be paid for contributing to an open source project over a three month period. &lt;br /&gt;
&lt;br /&gt;
This page contains project ideas for upcoming Google Summer of Code.&lt;br /&gt;
&lt;br /&gt;
== Contacts ==&lt;br /&gt;
&lt;br /&gt;
Please contact the respective mentor for the idea you are interested in. For general questions feel free to send an email to the [mailto:criu@openvz.org mailing list] or write in [https://gitter.im/save-restore/criu gitter].&lt;br /&gt;
&lt;br /&gt;
== Project ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Support sparse ghosts ===&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
When criu dumps processes it also dumps files that are opened by them. It does this by saving file names by which the files are accessible. But sometimes files can have no names. It may happen if a task opened a file and then removed it. To dump this file criu cannot save its name (because the name doesn't exist). Instead criu saves the whole file. This is called &amp;quot;ghost file&amp;quot;. Since saving the whole file is very expensive (copying lots of data on disk) criu limits the maximum size of a ghost file. The latter is also not good, because there are &amp;quot;sparse&amp;quot; files, that are large in size, but may be small from the real disk usage perspective. The goal of the task is to support sparse ghost files, i.e. limit the size of the ghost not by its length but by disk usage and when copying the data detect the used blocks and save only those.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
 &lt;br /&gt;
*[https://en.wikipedia.org/wiki/Sparse_file Sparse files]&lt;br /&gt;
*[[Dumping files]]&lt;br /&gt;
*[[Invisible files]]&lt;br /&gt;
*[https://www.kernel.org/doc/html/latest/filesystems/fiemap.html Fiemap ioctl]&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Mentor: Pavel Tikhomirov &amp;lt;ptikhomirov@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optimize logging engine ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' CRIU puts a lots of logs when doing its job. Logging is done with simple fprintf function. They are typically useless, but ''if'' some operation fails -- the logs are the only way to find what was the reason for failure.&lt;br /&gt;
&lt;br /&gt;
At the same time the printf family of functions is known to take some time to work -- they need to scan the format string for %-s and then convert the arguments into strings. If comparing criu dump with and without logs the time difference is notable (15%-20%), so speeding the logs up will help improve criu performance.&lt;br /&gt;
&lt;br /&gt;
One of the solutions to the problem might be binary logging. The problem with binary logs is the amount of efforts to convert existing logs to binary form. Preferably, the switch to binary logging either keeps existing log() calls intact, either has some automatics to convert them.&lt;br /&gt;
&lt;br /&gt;
The option to keep log() calls intact might be in pre-compilation pass of the sources. In this pass each &amp;lt;code&amp;gt;log(fmt, ...)&amp;lt;/code&amp;gt; call gets translated into a call to a binary log function that saves &amp;lt;code&amp;gt;fmt&amp;lt;/code&amp;gt; identifier copies all the args ''as is'' into the log file. The binary log decode utility, required in this case, should then find the fmt string by its ID in the log file and print the resulting message.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Better logging]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C, though decoder/preprocessor can be in any language&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for checkpoint/restore of CORK-ed UDP socket ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Support C/R of corked UDP socket&lt;br /&gt;
 &lt;br /&gt;
There's UDP_CORK option for sockets. As man page says:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    If this option is enabled, then all data output on this socket&lt;br /&gt;
    is accumulated into a single datagram that is transmitted when&lt;br /&gt;
    the option is disabled.  This option should not be used in&lt;br /&gt;
    code intended to be portable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently criu refuses to dump this case, so it's effectively a bug. Supporting&lt;br /&gt;
this will need extending the kernel API to allow criu read back the write queue&lt;br /&gt;
of the socket (see [[TCP connection|how it's done]] for TCP sockets, for example). Then&lt;br /&gt;
the queue is written into the image and is restored into the socket (with the CORK&lt;br /&gt;
bit set too).&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/409&lt;br /&gt;
* [[Sockets]], [[TCP connection]]&lt;br /&gt;
* [[https://groups.google.com/forum/#!topic/comp.os.linux.networking/Uz8PYiTCZSg UDP cork explained]]&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate (+linux kernel)&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Pavel Emelianov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelianov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for pidfd file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of pidfd descriptors&lt;br /&gt;
&lt;br /&gt;
There is pidfd_open syscall which allows opening&lt;br /&gt;
a special PID file descriptor. A user can send a signal to&lt;br /&gt;
the process (pidfd_send_signal syscall), wait for the process&lt;br /&gt;
(poll() on pidfd).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have pidfd's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/801319/&lt;br /&gt;
* https://lwn.net/Articles/794707/&lt;br /&gt;
* https://github.com/torvalds/linux/blob/v5.16/kernel/fork.c#L1877&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Christian Brauner &amp;lt;christian@brauner.io&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for memfd_secret file descriptors ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' Support C/R of memfd_secret descriptors&lt;br /&gt;
&lt;br /&gt;
There is memfd_secret syscall which allows user to open&lt;br /&gt;
special memfd which is backed by special memory range which&lt;br /&gt;
is inaccessible by another processes (and the kernel too!).&lt;br /&gt;
&lt;br /&gt;
At the moment CRIU can't dump processes that have memfd_secret's opened.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://lwn.net/Articles/865256/&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentors: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;, Mike Rapoport &amp;lt;mike.rapoport@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use eBPF to lock and unlock the network ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Use eBPF instead of external iptables-restore tool for network lock and unlock.&lt;br /&gt;
&lt;br /&gt;
During checkpointing and restoring CRIU locks the network to make sure no network packets are accepted by the network stack during the time the process is checkpointed. Currently CRIU calls out to iptables-restore to create and delete the corresponding iptables rules. Another approach which avoids calling out to the external binary iptables-restore would be to directly inject eBPF rules. There have been reports from users that iptables-restore fails in some way and eBPF could avoid this external dependency.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://www.criu.org/TCP_connection#Checkpoint_and_restore_TCP_connection&lt;br /&gt;
* https://github.com/systemd/systemd/blob/master/src/core/bpf-firewall.c&lt;br /&gt;
* https://blog.zeyady.com/2021-08-16/gsoc-criu&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CGroup-v2 support ===&lt;br /&gt;
&lt;br /&gt;
'''Summary:''' cgroup is a mechanism to organize processes hierarchically and distribute system resources along the hierarchy in a controlled and configurable manner. cgroup v2 is a new version of the cgroup file system. Unlike v1, cgroup v2 has only single hierarchy. CRIU has to dump/restore a container cgroup hierarchy along with all per-cgroup options. The cgroupv2 support in CRIU has to be compatible with Docker, containerd and cri-o.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[CGroups]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/252&lt;br /&gt;
* https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dump shmem in user-mode (unprivileged-mode) ===&lt;br /&gt;
&lt;br /&gt;
CRIU uses /proc/pid/map_files to dump and restore anonymous shared memory regions, but map_files is restricted to the global CAP_SYS_ADMIN capability. In most cases, it is possible to dump/restore shared memory region without map_files and we need to implement this in CRIU.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[User-mode]]&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: intermediate&lt;br /&gt;
* Language: C&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Andrei Vagin &amp;lt;avagin@gmail.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Porting crit functionalities in GO ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Implement image view and manipulation in Go&lt;br /&gt;
 &lt;br /&gt;
CRIU's checkpoint images are stored on disk using protobuf. For easier analysis of checkpoint files CRIU has a tool called [[CRIT|CRiu Image Tool (CRIT)]]. It can display/decode CRIU image files from binary protobuf to JSON as well as encode JSON files back to the binary format. With closer integration of CRIU in container runtimes it becomes important to be able to view the CRIU output files. Either for manipulation before restoring or for reading checkpoint statistics (memory pages written to disk, memory pages skipped, process downtime).&lt;br /&gt;
&lt;br /&gt;
Currently CRIT is implemented in Python, for easier integration in other Go projects it is important to have image manipulation and analysis available from GO. This means we need a Go based library to read/modify/write/encode/decode CRIU's image files. Based on this library a Go based implementation of CRIT would be useful.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[CRIT]]&lt;br /&gt;
* Possible use case see LXD: https://github.com/lxc/lxd/blob/cb55b1c5a484a43e0c21c6ae8c4a2e30b4d45be3/lxd/migrate_container.go#L179&lt;br /&gt;
* https://github.com/lxc/lxd/pull/4072&lt;br /&gt;
* https://github.com/checkpoint-restore/go-criu/tree/master/stats&lt;br /&gt;
* https://github.com/checkpoint-restore/go-criu/pull/28&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Go&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Mentor: Radostin Stoyanov &amp;lt;rstoyanov@fedoraproject.org&amp;gt;, Alexander Mikhalitsyn &amp;lt;alexander.mikhalitsyn@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Adrian Reber &amp;lt;areber@redhat.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Suspended project ideas ==&lt;br /&gt;
&lt;br /&gt;
Listed here are tasks that seem suitable for GSoC, but currently do not have anybody to mentor it.&lt;br /&gt;
&lt;br /&gt;
=== IOUring support ===&lt;br /&gt;
The io_uring Asynchronous I/O (AIO) framework is a new Linux I/O interface, first introduced in upstream Linux kernel version 5.1 (March 2019). It provides a low-latency and feature-rich interface for applications that require AIO functionality.&lt;br /&gt;
&lt;br /&gt;
'''Links:'''&lt;br /&gt;
* https://blogs.oracle.com/linux/an-introduction-to-the-io_uring-asynchronous-io-framework&lt;br /&gt;
* https://github.com/axboe/liburing&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert (+linux kernel)&lt;br /&gt;
* Expected size: 350 hours&lt;br /&gt;
* Suggested by: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
* Mentor: Pavel Emelyanov &amp;lt;ovzxemul@gmail.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add support for SPFS ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' The SPFS is a special filesystem that allows checkpoint and restore of such things as NFS and FUSE&lt;br /&gt;
&lt;br /&gt;
NFS support is already implemented in Virtuozzo CRIU, but it's very beneficial to port it to mainline CRIU. The importaint part of it is the need to implement the integration of Stub-Proxy File System (SPFS) with LXC/yet_another_containers_environment.&lt;br /&gt;
&lt;br /&gt;
'''Links'''&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/60&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/53&lt;br /&gt;
* https://github.com/skinsbursky/spfs&lt;br /&gt;
* https://patchwork.criu.org/series/137/&lt;br /&gt;
&lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: expert&lt;br /&gt;
* Language: C&lt;br /&gt;
* Mentor: Alexander Mikhalitsyn &amp;lt;alexander@mihalicyn.com&amp;gt; / &amp;lt;alexander.mikhalitsyn@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Alexander Mikhalitsyn &amp;lt;alexander.mikhalitsyn@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anonymise image files ===&lt;br /&gt;
 &lt;br /&gt;
'''Summary:''' Teach [[CRIT]] to remove sensitive information from images&lt;br /&gt;
 &lt;br /&gt;
When reporting a BUG it may be not acceptable for the reporter to send us raw images, as they may contain sensitive data. Need to teach CRIT to &amp;quot;anonymise&amp;quot; images for publication.&lt;br /&gt;
&lt;br /&gt;
List of data to shred:&lt;br /&gt;
&lt;br /&gt;
* Memory contents. For the sake of investigation, all the memory contents can be just removed. Only the sizes of pages*.img files are enough.&lt;br /&gt;
* Paths to files. Here we should keep the paths relations to each other. The simplest way seem to be replacing file names with &amp;quot;random&amp;quot; (or sequential) strings, BUT (!) keeping an eye on making this mapping be 1:1. Note, that file paths may also sit in sk-unix.img.&lt;br /&gt;
* Registers.&lt;br /&gt;
* Process names. (But relations should be kept).&lt;br /&gt;
* Contents of streams, i.e. pipe/fifo data, sk-queue, tcp-stream, tty data.&lt;br /&gt;
* Ghost files.&lt;br /&gt;
* Tarballs with tmpfs-s.&lt;br /&gt;
* IP addresses in sk-inet-s, ip tool dumps and net*.img.&lt;br /&gt;
 &lt;br /&gt;
'''Links:'''&lt;br /&gt;
* [[Anonymize image files]]&lt;br /&gt;
* https://github.com/checkpoint-restore/criu/issues/360&lt;br /&gt;
* [[CRIT]], [[Images]]&lt;br /&gt;
* External links to mailing lists or web sites&lt;br /&gt;
 &lt;br /&gt;
'''Details:'''&lt;br /&gt;
* Skill level: beginner&lt;br /&gt;
* Language: Python&lt;br /&gt;
* Mentor: Pavel Emelianov &amp;lt;xemul@virtuozzo.com&amp;gt;&lt;br /&gt;
* Suggested by: Pavel Emelianov &amp;lt;xemul@virtuozzo.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount-v2&amp;diff=5233</id>
		<title>Mount-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount-v2&amp;diff=5233"/>
		<updated>2022-01-31T09:57:49Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mount-v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
After we've merged MOVE_MOUNT_SET_GROUP feature to mainstream linux v5.15 [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e] now we can use it to restore sharing groups of mounts without the need to care about inheriting those groups when create mounts, we can just set sharing groups at later stage and before that construct mount trees with private mounts.&lt;br /&gt;
&lt;br /&gt;
Restoring propagation right with conservative approach of both creating mounts and inheriting propagation groups looks like mission impossible task for us due to many problems:&lt;br /&gt;
&lt;br /&gt;
* Criu knows nothing about the initial history or order of mount tree creation;&lt;br /&gt;
* Propagation can create tons of mounts;&lt;br /&gt;
* Propagation may change parent mounts for existing mount tree;&lt;br /&gt;
* &amp;quot;Mount trap&amp;quot; - propagation may cover initial mount;&lt;br /&gt;
* &amp;quot;Non-uniform&amp;quot; propagation - there are different tricks with mount order and temporary children-&amp;quot;lock&amp;quot; mounts, which create mount trees which can't be restored without those tricks;&lt;br /&gt;
* &amp;quot;Cross-namespace&amp;quot; sharing groups creation need to be ordered with mount namespace creation right;&lt;br /&gt;
* Sharing groups vs mount tree order inversion can be very complex to restore and require multiple auxiliary. (see example below)&lt;br /&gt;
&lt;br /&gt;
See my talks about it on Linux Plumbers Conference:&lt;br /&gt;
* [https://www.linuxplumbersconf.org/event/7/contributions/640/ CRIU mounts migration: problems and solutions]&lt;br /&gt;
* [https://linuxplumbersconf.org/event/11/contributions/923/ Mount-v2 CRIU migration engine: status update]&lt;br /&gt;
&lt;br /&gt;
And here is the example of order inversion where multiple temporary mounts needed to achieve the result:&lt;br /&gt;
[[File:Mounts-inverse-order-example.gif|none|link=|Mounts-inverse-order-example.gif]]&lt;br /&gt;
&lt;br /&gt;
== Mount-v2 description ==&lt;br /&gt;
&lt;br /&gt;
New mount-v2 algorithm is integrated deeply in the original one, so that dumping of mounts is done exactly the same for original mount engine and new one. So mount-v2 series has preparatory steps related to bindmount detection, external mounts detection and helper mounts handling to make the original mount code more robust, to make it easier to reuse it in mount-v2.&lt;br /&gt;
&lt;br /&gt;
==== Plain mountpoints ====&lt;br /&gt;
&lt;br /&gt;
One of main differences of mount-v2 comparing to original is that mounts are initially created &amp;quot;plain&amp;quot;, for instance if we had '''MOUNT''' with '''mnt_id=1000''' and '''ns_mountpoint=&amp;quot;/mount/point/path&amp;quot;''', original mount engine would originally mount this '''MOUNT''' in the mount tree to '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point/path''' so that if this mount had '''PARENT''' mount with '''mnt_id=999''' and '''ns_mountpoint=&amp;quot;/mount/point&amp;quot;''' corresponding mount for '''PARENT''' would be created in '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point''' thus restoring parent-child relationship between them initially. For mount-v2 '''MOUNT''' would be first mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-1000''' and '''PARENT''' would be mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-999''' so that on the first stage we only create mounts and then on separate second stage handle the tree assembling separately. This way we can have useful heuristics like on the second stage we can create overmounts after mounts they overmount, and on the  first stage we can create external mounts before their bindmounts and these two do not clinch with each other.&lt;br /&gt;
&lt;br /&gt;
But it is not so simple actually because we do not want to rewrite all the code for instance for restoring mount content or restoring ghost and remap files, which used mountpoint paths in &amp;quot;tree&amp;quot; format. So in all places where it does not matter (where we do not access &amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/... paths) we switched from using mount_info-&amp;gt;mountpoint to mount_info-&amp;gt;ns_mountpoint and in all places where we actually needed &amp;quot;tree&amp;quot; format paths we replace them with service_mountpoint() helper which would return &amp;quot;tree&amp;quot; paths for original mount engine and &amp;quot;plain&amp;quot; paths for mount-v2. This way we can safely switch from one to another.&lt;br /&gt;
&lt;br /&gt;
==== Resolving sharing groups ====&lt;br /&gt;
&lt;br /&gt;
Just after reading mounts from images in read_mnt_ns_img() when mount-v2 is enabled we have an additional step to collect sharing group information from mounts and turn it to sharing groups forest graph (resolve_shared_mounts_v2). First, we just walk over all mounts and create sharing group for each mount with unique shared_id + master_id pair, also we sew all mounts to corresponding sharing group with same id pair. Second, we walk over all sharing groups which has non-zero master_id and lookup the corresponding parent sharing groups and connect them with a tree.&lt;br /&gt;
&lt;br /&gt;
There is also a case when master_id is non-zero but there is no corresponding parent sharing group, this means that outside of dumped container there is mount with matching shared_id - external slavery detected. For this case we just collect sibling sharing groups in list with empty parent link. Also we detect source path from which the master_id would be inherited either from some mountpoint-external mount or from root container mount.&lt;br /&gt;
&lt;br /&gt;
==== Actual restore of mounts ====&lt;br /&gt;
&lt;br /&gt;
Actual restore of mounts in original mount engine starts with prepare_mnt_ns() function, when mount-v2 is enabled we pass controll from it to prepare_mnt_ns_v2() instead. It consists of several stages:&lt;br /&gt;
&lt;br /&gt;
1) We pre-create mount namespaces for each restored mount namespace in pre_create_mount_namespaces(). These namespaces appear almost empty: they contain tmpfs as their root, they have root yard path created in it with another tmpfs mounted in it, and&amp;quot;namespace&amp;quot; path for assembling tree of mounts in it created in corresponding subdirectory of root yard mount. Surely we also save nsfs fds to each mount namespace to be able to reenter them later.&lt;br /&gt;
&lt;br /&gt;
2) In populate_mnt_ns_v2() we reuse mnt_tree_for_each() walk over mount tree from original mount engine and so we walk mounts in tree order with addition of temporary skipping mounts and their descendants with can_mount_now_v2() in case they depend from other mounts, restarting the walk for them later. The can_mount_now_v2() is basically skipping mounts which should be restored as bindmounts but their source is not ready yet, this is true for bindmounts of root, external or plugin mounts or non-fsroot mounts.&lt;br /&gt;
&lt;br /&gt;
3) In the mentioned walk over mounts forest in do_mount_one_v2() we determine if the newly created mount is directory one or a file one in detect_is_dir(), we just open its mountpoint path relative to parent &amp;quot;plain&amp;quot; mountpoint and do stat. That's why it is important to use mnt_tree_for_each() as it insures that parent is already &amp;quot;plain&amp;quot; mounted.&lt;br /&gt;
&lt;br /&gt;
4) In the mentioned walk over mounts forest in do_mount_one_v2() we create &amp;quot;plain&amp;quot; mountpoint for a new mount, empty file or directory based on the previous step.&lt;br /&gt;
&lt;br /&gt;
5) In the mentioned walk over mounts forest in do_mount_one_v2() we actually create new mount, either we create completely new mount or device-external in do_new_mount_v2() if it's supported, or bind container root mount in do_mount_root_v2() from the still visible host mount tree, or bind mountpoint-external mount in do_bind_mount_v2() and similarly bind any mount for which superblock is already created by other mount beforehand and we can just bind it in do_bind_mount_v2(). These functions act similar to ones in original mount engine but simplified as they don't need to care about inheriting sharing groups.&lt;br /&gt;
&lt;br /&gt;
6) The do_bind_mount_v2() is improved to do bindmount via open_tree() + move_mount() with flags allowing not to traverse symlinks or autofs mounts.&lt;br /&gt;
&lt;br /&gt;
7) Also we cross-namespace bindmount the newly created mount to restored mount namespace to the same &amp;quot;plain&amp;quot; mountpoint in do_mount_in_right_mntns(). So that we initially have a mount which would be visible after restore, this would be required in future to be able to restore bindmounted unix sockets on the right mount.&lt;br /&gt;
&lt;br /&gt;
8) Now after the walk we don't plan to do bindmounts anymore so we set unbindable flags on mounts.&lt;br /&gt;
&lt;br /&gt;
9) Next we assemble mount trees in each restored mount namespace in assemble_mount_namespaces() by again reusing move_mount_to_tree() to have tree order of moving mounts into proper places in mount tree. Also we open fds on the mountpoint: one mp_fd_id before moving and another mnt_fd_id after, so that we can access files on each mount later from final mntns via those fds.&lt;br /&gt;
&lt;br /&gt;
10) Finally we do restore sharing groups on the assembled mount forest in restore_mount_sharing_options(). It walks each root sharing group and their descendants with dfs tree walk. It creates sharing for the first mount in the sharing group and then sets the same sharing on all other mounts in this group.&lt;br /&gt;
&lt;br /&gt;
Sharing creation for first mount is two step:&lt;br /&gt;
&lt;br /&gt;
a) If mount has master_id we either copy shared_id from parent sharing group or from external source and then make mount slave thus converting it to right master_id.&lt;br /&gt;
b) Next if mount has shared_id we just make us shared, creating right shared_id.&lt;br /&gt;
&lt;br /&gt;
We need to use userns_call() for MOVE_MOUNT_SET_GROUP to have all right permissions for copying sharing (move_mount_set_group()). Also we need to resolve external paths given by user to their actual mountpoint, we do so with openat2(RESOLVE_NO_XDEV) in resolve_mountpoint, this also only works from userns_call().&lt;br /&gt;
&lt;br /&gt;
11) We remove sources of deleted mounts making them actually deleted (from &amp;quot;service&amp;quot; mount namespace), as moving deleted mounts is not allowed and just to simplify things we do it at the last step.&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Virtuozzo&amp;quot; (original) version (using non-mainstream kernel interface): [[Mounts-v2-Virtuozzo|Mounts-v2-Virtuozzo]] It actually has cool features we don't have in mainstream yet, for instance - nested pidns proc handling, this feature requires nested pidns support beforehand.&lt;br /&gt;
&lt;br /&gt;
MOVE_MOUNT_SET_GROUP kernel feature: [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e]&lt;br /&gt;
&lt;br /&gt;
Mount-v2 PR to criu: [https://github.com/checkpoint-restore/criu/pull/1721 #1721]&lt;br /&gt;
&lt;br /&gt;
[[Category: Under the hood]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount-v2&amp;diff=5232</id>
		<title>Mount-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount-v2&amp;diff=5232"/>
		<updated>2022-01-31T09:56:34Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mount-v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
After we've merged MOVE_MOUNT_SET_GROUP feature to mainstream linux v5.15 [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e] now we can use it to restore sharing groups of mounts without the need to care about inheriting those groups when create mounts, we can just set sharing groups at later stage and before that construct mount trees with private mounts.&lt;br /&gt;
&lt;br /&gt;
Restoring propagation right with conservative approach of both creating mounts and inheriting propagation groups looks like mission impossible task for us due to many problems:&lt;br /&gt;
&lt;br /&gt;
* Criu knows nothing about the initial history or order of mount tree creation;&lt;br /&gt;
* Propagation can create tons of mounts;&lt;br /&gt;
* Propagation may change parent mounts for existing mount tree;&lt;br /&gt;
* &amp;quot;Mount trap&amp;quot; - propagation may cover initial mount;&lt;br /&gt;
* &amp;quot;Non-uniform&amp;quot; propagation - there are different tricks with mount order and temporary children-&amp;quot;lock&amp;quot; mounts, which create mount trees which can't be restored without those tricks;&lt;br /&gt;
* &amp;quot;Cross-namespace&amp;quot; sharing groups creation need to be ordered with mount namespace creation right;&lt;br /&gt;
* Sharing groups vs mount tree order inversion can be very complex to restore and require multiple auxiliary. (see example below)&lt;br /&gt;
&lt;br /&gt;
See my talks about it on Linux Plumbers Conference:&lt;br /&gt;
* [https://www.linuxplumbersconf.org/event/7/contributions/640/ CRIU mounts migration: problems and solutions]&lt;br /&gt;
* [https://linuxplumbersconf.org/event/11/contributions/923/ Mount-v2 CRIU migration engine: status update]&lt;br /&gt;
&lt;br /&gt;
And here is the example of order inversion where multiple temporary mounts needed to achieve the result:&lt;br /&gt;
[[File:Mounts-inverse-order-example.gif|none|link=|Mounts-inverse-order-example.gif]]&lt;br /&gt;
&lt;br /&gt;
== Mount-v2 description ==&lt;br /&gt;
&lt;br /&gt;
New mount-v2 algorithm is integrated deeply in the original one, so that dumping of mounts is done exactly the same for original mount engine and new one. So mount-v2 series has preparatory steps related to bindmount detection, external mounts detection and helper mounts handling to make the original mount code more robust, to make it easier to reuse it in mount-v2.&lt;br /&gt;
&lt;br /&gt;
==== Plain mountpoints ====&lt;br /&gt;
&lt;br /&gt;
One of main differences of mount-v2 comparing to original is that mounts are initially created &amp;quot;plain&amp;quot;, for instance if we had '''MOUNT''' with '''mnt_id=1000''' and '''ns_mountpoint=&amp;quot;/mount/point/path&amp;quot;''', original mount engine would originally mount this '''MOUNT''' in the mount tree to '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point/path''' so that if this mount had '''PARENT''' mount with '''mnt_id=999''' and '''ns_mountpoint=&amp;quot;/mount/point&amp;quot;''' corresponding mount for '''PARENT''' would be created in '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point''' thus restoring parent-child relationship between them initially. For mount-v2 '''MOUNT''' would be first mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-1000''' and '''PARENT''' would be mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-999''' so that on the first stage we only create mounts and then on separate second stage handle the tree assembling separately. This way we can have useful heuristics like on the second stage we can create overmounts after mounts they overmount, and on the  first stage we can create external mounts before their bindmounts and these two do not clinch with each other.&lt;br /&gt;
&lt;br /&gt;
But it is not so simple actually because we do not want to rewrite all the code for instance for restoring mount content or restoring ghost and remap files, which used mountpoint paths in &amp;quot;tree&amp;quot; format. So in all places where it does not matter (where we do not access &amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/... paths) we switched from using mount_info-&amp;gt;mountpoint to mount_info-&amp;gt;ns_mountpoint and in all places where we actually needed &amp;quot;tree&amp;quot; format paths we replace them with service_mountpoint() helper which would return &amp;quot;tree&amp;quot; paths for original mount engine and &amp;quot;plain&amp;quot; paths for mount-v2. This way we can safely switch from one to another.&lt;br /&gt;
&lt;br /&gt;
==== Resolving sharing groups ====&lt;br /&gt;
&lt;br /&gt;
Just after reading mounts from images in read_mnt_ns_img() when mount-v2 is enabled we have an additional step to collect sharing group information from mounts and turn it to sharing groups forest graph (resolve_shared_mounts_v2). First, we just walk over all mounts and create sharing group for each mount with unique shared_id + master_id pair, also we sew all mounts to corresponding sharing group with same id pair. Second, we walk over all sharing groups which has non-zero master_id and lookup the corresponding parent sharing groups and connect them with a tree.&lt;br /&gt;
&lt;br /&gt;
There is also a case when master_id is non-zero but there is no corresponding parent sharing group, this means that outside of dumped container there is mount with matching shared_id - external slavery detected. For this case we just collect sibling sharing groups in list with empty parent link. Also we detect source path from which the master_id would be inherited either from some mountpoint-external mount or from root container mount.&lt;br /&gt;
&lt;br /&gt;
==== Actual restore of mounts ====&lt;br /&gt;
&lt;br /&gt;
Actual restore of mounts in original mount engine starts with prepare_mnt_ns() function, when mount-v2 is enabled we pass controll from it to prepare_mnt_ns_v2() instead. It consists of several stages:&lt;br /&gt;
&lt;br /&gt;
1) We pre-create mount namespaces for each restored mount namespace in pre_create_mount_namespaces(). These namespaces appear almost empty: they contain tmpfs as their root, they have root yard path created in it with another tmpfs mounted in it, and&amp;quot;namespace&amp;quot; path for assembling tree of mounts in it created in corresponding subdirectory of root yard mount. Surely we also save nsfs fds to each mount namespace to be able to reenter them later.&lt;br /&gt;
&lt;br /&gt;
2) In populate_mnt_ns_v2() we reuse mnt_tree_for_each() walk over mount tree from original mount engine and so we walk mounts in tree order with addition of temporary skipping mounts and their descendants with can_mount_now_v2() in case they depend from other mounts, restarting the walk for them later. The can_mount_now_v2() is basically skipping mounts which should be restored as bindmounts but their source is not ready yet, this is true for bindmounts of root, external or plugin mounts or non-fsroot mounts.&lt;br /&gt;
&lt;br /&gt;
3) In the mentioned walk over mounts forest in do_mount_one_v2() we determine if the newly created mount is directory one or a file one in detect_is_dir(), we just open its mountpoint path relative to parent &amp;quot;plain&amp;quot; mountpoint and do stat. That's why it is important to use mnt_tree_for_each() as it insures that parent is already &amp;quot;plain&amp;quot; mounted.&lt;br /&gt;
&lt;br /&gt;
4) In the mentioned walk over mounts forest in do_mount_one_v2() we create &amp;quot;plain&amp;quot; mountpoint for a new mount, empty file or directory based on the previous step.&lt;br /&gt;
&lt;br /&gt;
5) In the mentioned walk over mounts forest in do_mount_one_v2() we actually create new mount, either we create completely new mount or device-external in do_new_mount_v2() if it's supported, or bind container root mount in do_mount_root_v2() from the still visible host mount tree, or bind mountpoint-external mount in do_bind_mount_v2() and similarly bind any mount for which superblock is already created by other mount beforehand and we can just bind it in do_bind_mount_v2(). These functions act similar to ones in original mount engine but simplified as they don't need to care about inheriting sharing groups.&lt;br /&gt;
&lt;br /&gt;
6) The do_bind_mount_v2() is improved to do bindmount via open_tree() + move_mount() with flags allowing not to traverse symlinks or autofs mounts.&lt;br /&gt;
&lt;br /&gt;
7) Also we cross-namespace bindmount the newly created mount to restored mount namespace to the same &amp;quot;plain&amp;quot; mountpoint in do_mount_in_right_mntns(). So that we initially have a mount which would be visible after restore, this would be required in future to be able to restore bindmounted unix sockets on the right mount.&lt;br /&gt;
&lt;br /&gt;
8) Now after the walk we don't plan to do bindmounts anymore so we set unbindable flags on mounts.&lt;br /&gt;
&lt;br /&gt;
9) Next we assemble mount trees in each restored mount namespace in assemble_mount_namespaces() by again reusing move_mount_to_tree() to have tree order of moving mounts into proper places in mount tree. Also we open fds on the mountpoint: one mp_fd_id before moving and another mnt_fd_id after, so that we can access files on each mount later from final mntns via those fds.&lt;br /&gt;
&lt;br /&gt;
10) Finally we do restore sharing groups on the assembled mount forest in restore_mount_sharing_options(). It walks each root sharing group and their descendants with dfs tree walk. It creates sharing for the first mount in the sharing group and then sets the same sharing on all other mounts in this group.&lt;br /&gt;
&lt;br /&gt;
Sharing creation for first mount is two step:&lt;br /&gt;
&lt;br /&gt;
a) If mount has master_id we either copy shared_id from parent sharing group or from external source and then make mount slave thus converting it to right master_id.&lt;br /&gt;
b) Next if mount has shared_id we just make us shared, creating right shared_id.&lt;br /&gt;
&lt;br /&gt;
We need to use userns_call() for MOVE_MOUNT_SET_GROUP to have all right permissions for copying sharing (move_mount_set_group()). Also we need to resolve external paths given by user to their actual mountpoint, we do so with openat2(RESOLVE_NO_XDEV) in resolve_mountpoint, this also only works from userns_call().&lt;br /&gt;
&lt;br /&gt;
11) We remove sources of deleted mounts making them actually deleted (from &amp;quot;service&amp;quot; mount namespace), as moving deleted mounts is not allowed and just to simplify things we do it at the last step.&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Virtuozzo&amp;quot; (original) version (using non-mainstream kernel interface): [[Mounts-v2-Virtuozzo|Mounts-v2-Virtuozzo]] It actually has cool features we don't have in mainstream yet, for instance - nested pidns proc handling, this feature requires nested pidns support beforehand.&lt;br /&gt;
&lt;br /&gt;
MOVE_MOUNT_SET_GROUP kernel feature: [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e]&lt;br /&gt;
&lt;br /&gt;
PR with this feature to criu: [https://github.com/checkpoint-restore/criu/pull/1721 #1721]&lt;br /&gt;
&lt;br /&gt;
[[Category: Under the hood]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount-v2&amp;diff=5231</id>
		<title>Mount-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount-v2&amp;diff=5231"/>
		<updated>2022-01-27T15:03:27Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mount-v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
After we've merged MOVE_MOUNT_SET_GROUP feature to mainstream linux v5.15 [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e] now we can use it to restore sharing groups of mounts without the need to care about inheriting those groups when create mounts, we can just set sharing groups at later stage and before that construct mount trees with private mounts.&lt;br /&gt;
&lt;br /&gt;
Restoring propagation right with conservative approach of both creating mounts and inheriting propagation groups looks like mission impossible task for us due to many problems:&lt;br /&gt;
&lt;br /&gt;
* Criu knows nothing about the initial history or order of mount tree creation;&lt;br /&gt;
* Propagation can create tons of mounts;&lt;br /&gt;
* Propagation may change parent mounts for existing mount tree;&lt;br /&gt;
* &amp;quot;Mount trap&amp;quot; - propagation may cover initial mount;&lt;br /&gt;
* &amp;quot;Non-uniform&amp;quot; propagation - there are different tricks with mount order and temporary children-&amp;quot;lock&amp;quot; mounts, which create mount trees which can't be restored without those tricks;&lt;br /&gt;
* &amp;quot;Cross-namespace&amp;quot; sharing groups creation need to be ordered with mount namespace creation right;&lt;br /&gt;
* Sharing groups vs mount tree order inversion can be very complex to restore and require multiple auxiliary. (see example below)&lt;br /&gt;
&lt;br /&gt;
See my talks about it on Linux Plumbers Conference:&lt;br /&gt;
* [https://www.linuxplumbersconf.org/event/7/contributions/640/ CRIU mounts migration: problems and solutions]&lt;br /&gt;
* [https://linuxplumbersconf.org/event/11/contributions/923/ Mount-v2 CRIU migration engine: status update]&lt;br /&gt;
&lt;br /&gt;
And here is the example of order inversion where multiple temporary mounts needed to achieve the result:&lt;br /&gt;
[[File:Mounts-inverse-order-example.gif|none|link=|Mounts-inverse-order-example.gif]]&lt;br /&gt;
&lt;br /&gt;
== Mount-v2 description ==&lt;br /&gt;
&lt;br /&gt;
New mount-v2 algorithm is integrated deeply in the original one, so that dumping of mounts is done exactly the same for original mount engine and new one. So mount-v2 series has preparatory steps related to bindmount detection, external mounts detection and helper mounts handling to make the original mount code more robust, to make it easier to reuse it in mount-v2.&lt;br /&gt;
&lt;br /&gt;
==== Plain mountpoints ====&lt;br /&gt;
&lt;br /&gt;
One of main differences of mount-v2 comparing to original is that mounts are initially created &amp;quot;plain&amp;quot;, for instance if we had '''MOUNT''' with '''mnt_id=1000''' and '''ns_mountpoint=&amp;quot;/mount/point/path&amp;quot;''', original mount engine would originally mount this '''MOUNT''' in the mount tree to '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point/path''' so that if this mount had '''PARENT''' mount with '''mnt_id=999''' and '''ns_mountpoint=&amp;quot;/mount/point&amp;quot;''' corresponding mount for '''PARENT''' would be created in '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point''' thus restoring parent-child relationship between them initially. For mount-v2 '''MOUNT''' would be first mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-1000''' and '''PARENT''' would be mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-999''' so that on the first stage we only create mounts and then on separate second stage handle the tree assembling separately. This way we can have useful heuristics like on the second stage we can create overmounts after mounts they overmount, and on the  first stage we can create external mounts before their bindmounts and these two do not clinch with each other.&lt;br /&gt;
&lt;br /&gt;
But it is not so simple actually because we do not want to rewrite all the code for instance for restoring mount content or restoring ghost and remap files, which used mountpoint paths in &amp;quot;tree&amp;quot; format. So in all places where it does not matter (where we do not access &amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/... paths) we switched from using mount_info-&amp;gt;mountpoint to mount_info-&amp;gt;ns_mountpoint and in all places where we actually needed &amp;quot;tree&amp;quot; format paths we replace them with service_mountpoint() helper which would return &amp;quot;tree&amp;quot; paths for original mount engine and &amp;quot;plain&amp;quot; paths for mount-v2. This way we can safely switch from one to another.&lt;br /&gt;
&lt;br /&gt;
==== Resolving sharing groups ====&lt;br /&gt;
&lt;br /&gt;
Just after reading mounts from images in read_mnt_ns_img() when mount-v2 is enabled we have an additional step to collect sharing group information from mounts and turn it to sharing groups forest graph (resolve_shared_mounts_v2). First, we just walk over all mounts and create sharing group for each mount with unique shared_id + master_id pair, also we sew all mounts to corresponding sharing group with same id pair. Second, we walk over all sharing groups which has non-zero master_id and lookup the corresponding parent sharing groups and connect them with a tree.&lt;br /&gt;
&lt;br /&gt;
There is also a case when master_id is non-zero but there is no corresponding parent sharing group, this means that outside of dumped container there is mount with matching shared_id - external slavery detected. For this case we just collect sibling sharing groups in list with empty parent link. Also we detect source path from which the master_id would be inherited either from some mountpoint-external mount or from root container mount.&lt;br /&gt;
&lt;br /&gt;
==== Actual restore of mounts ====&lt;br /&gt;
&lt;br /&gt;
Actual restore of mounts in original mount engine starts with prepare_mnt_ns() function, when mount-v2 is enabled we pass controll from it to prepare_mnt_ns_v2() instead. It consists of several stages:&lt;br /&gt;
&lt;br /&gt;
1) We pre-create mount namespaces for each restored mount namespace in pre_create_mount_namespaces(). These namespaces appear almost empty: they contain tmpfs as their root, they have root yard path created in it with another tmpfs mounted in it, and&amp;quot;namespace&amp;quot; path for assembling tree of mounts in it created in corresponding subdirectory of root yard mount. Surely we also save nsfs fds to each mount namespace to be able to reenter them later.&lt;br /&gt;
&lt;br /&gt;
2) In populate_mnt_ns_v2() we reuse mnt_tree_for_each() walk over mount tree from original mount engine and so we walk mounts in tree order with addition of temporary skipping mounts and their descendants with can_mount_now_v2() in case they depend from other mounts, restarting the walk for them later. The can_mount_now_v2() is basically skipping mounts which should be restored as bindmounts but their source is not ready yet, this is true for bindmounts of root, external or plugin mounts or non-fsroot mounts.&lt;br /&gt;
&lt;br /&gt;
3) In the mentioned walk over mounts forest in do_mount_one_v2() we determine if the newly created mount is directory one or a file one in detect_is_dir(), we just open its mountpoint path relative to parent &amp;quot;plain&amp;quot; mountpoint and do stat. That's why it is important to use mnt_tree_for_each() as it insures that parent is already &amp;quot;plain&amp;quot; mounted.&lt;br /&gt;
&lt;br /&gt;
4) In the mentioned walk over mounts forest in do_mount_one_v2() we create &amp;quot;plain&amp;quot; mountpoint for a new mount, empty file or directory based on the previous step.&lt;br /&gt;
&lt;br /&gt;
5) In the mentioned walk over mounts forest in do_mount_one_v2() we actually create new mount, either we create completely new mount or device-external in do_new_mount_v2() if it's supported, or bind container root mount in do_mount_root_v2() from the still visible host mount tree, or bind mountpoint-external mount in do_bind_mount_v2() and similarly bind any mount for which superblock is already created by other mount beforehand and we can just bind it in do_bind_mount_v2(). These functions act similar to ones in original mount engine but simplified as they don't need to care about inheriting sharing groups.&lt;br /&gt;
&lt;br /&gt;
6) The do_bind_mount_v2() is improved to do bindmount via open_tree() + move_mount() with flags allowing not to traverse symlinks or autofs mounts.&lt;br /&gt;
&lt;br /&gt;
7) Also we cross-namespace bindmount the newly created mount to restored mount namespace to the same &amp;quot;plain&amp;quot; mountpoint in do_mount_in_right_mntns(). So that we initially have a mount which would be visible after restore, this would be required in future to be able to restore bindmounted unix sockets on the right mount.&lt;br /&gt;
&lt;br /&gt;
8) Now after the walk we don't plan to do bindmounts anymore so we set unbindable flags on mounts.&lt;br /&gt;
&lt;br /&gt;
9) Next we assemble mount trees in each restored mount namespace in assemble_mount_namespaces() by again reusing move_mount_to_tree() to have tree order of moving mounts into proper places in mount tree. Also we open fds on the mountpoint: one mp_fd_id before moving and another mnt_fd_id after, so that we can access files on each mount later from final mntns via those fds.&lt;br /&gt;
&lt;br /&gt;
10) Finally we do restore sharing groups on the assembled mount forest in restore_mount_sharing_options(). It walks each root sharing group and their descendants with dfs tree walk. It creates sharing for the first mount in the sharing group and then sets the same sharing on all other mounts in this group.&lt;br /&gt;
&lt;br /&gt;
Sharing creation for first mount is two step:&lt;br /&gt;
&lt;br /&gt;
a) If mount has master_id we either copy shared_id from parent sharing group or from external source and then make mount slave thus converting it to right master_id.&lt;br /&gt;
b) Next if mount has shared_id we just make us shared, creating right shared_id.&lt;br /&gt;
&lt;br /&gt;
We need to use userns_call() for MOVE_MOUNT_SET_GROUP to have all right permissions for copying sharing (move_mount_set_group()). Also we need to resolve external paths given by user to their actual mountpoint, we do so with openat2(RESOLVE_NO_XDEV) in resolve_mountpoint, this also only works from userns_call().&lt;br /&gt;
&lt;br /&gt;
11) We remove sources of deleted mounts making them actually deleted (from &amp;quot;service&amp;quot; mount namespace), as moving deleted mounts is not allowed and just to simplify things we do it at the last step.&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount-v2&amp;diff=5230</id>
		<title>Mount-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount-v2&amp;diff=5230"/>
		<updated>2022-01-27T11:34:57Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mount-v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
After we've merged MOVE_MOUNT_SET_GROUP feature to mainstream linux v5.15 [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e] now we can use it to restore sharing groups of mounts without the need to care about inheriting those groups when create mounts, we can just set sharing groups at later stage and before that construct mount trees with private mounts.&lt;br /&gt;
&lt;br /&gt;
Restoring propagation right with conservative approach of both creating mounts and inheriting propagation groups looks like mission impossible task for us due to many problems:&lt;br /&gt;
&lt;br /&gt;
* Criu knows nothing about the initial history or order of mount tree creation;&lt;br /&gt;
* Propagation can create tons of mounts;&lt;br /&gt;
* Propagation may change parent mounts for existing mount tree;&lt;br /&gt;
* &amp;quot;Mount trap&amp;quot; - propagation may cover initial mount;&lt;br /&gt;
* &amp;quot;Non-uniform&amp;quot; propagation - there are different tricks with mount order and temporary children-&amp;quot;lock&amp;quot; mounts, which create mount trees which can't be restored without those tricks;&lt;br /&gt;
* &amp;quot;Cross-namespace&amp;quot; sharing groups creation need to be ordered with mount namespace creation right;&lt;br /&gt;
* Sharing groups vs mount tree order inversion can be very complex to restore and require multiple auxiliary. (see example below)&lt;br /&gt;
&lt;br /&gt;
See my talks about it on Linux Plumbers Conference:&lt;br /&gt;
* [https://www.linuxplumbersconf.org/event/7/contributions/640/ CRIU mounts migration: problems and solutions]&lt;br /&gt;
* [https://linuxplumbersconf.org/event/11/contributions/923/ Mount-v2 CRIU migration engine: status update]&lt;br /&gt;
&lt;br /&gt;
And here is the example of order inversion where multiple temporary mounts needed to achieve the result:&lt;br /&gt;
[[File:Mounts-inverse-order-example.gif|none|link=|Mounts-inverse-order-example.gif]]&lt;br /&gt;
&lt;br /&gt;
== Mount-v2 description ==&lt;br /&gt;
&lt;br /&gt;
New mount-v2 algorithm is integrated deeply in the original one, so that dumping of mounts is done exactly the same for original mount engine and new one. So mount-v2 series has preparatory steps related to bindmount detection, external mounts detection and helper mounts handling to make the original mount code more robust, to make it easier to reuse it in mount-v2.&lt;br /&gt;
&lt;br /&gt;
==== Plain mountpoints ====&lt;br /&gt;
&lt;br /&gt;
One of main differences of mount-v2 comparing to original is that mounts are initially created &amp;quot;plain&amp;quot;, for instance if we had '''MOUNT''' with '''mnt_id=1000''' and '''ns_mountpoint=&amp;quot;/mount/point/path&amp;quot;''', original mount engine would originally mount this '''MOUNT''' in the mount tree to '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point/path''' so that if this mount had '''PARENT''' mount with '''mnt_id=999''' and '''ns_mountpoint=&amp;quot;/mount/point&amp;quot;''' corresponding mount for '''PARENT''' would be created in '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point''' thus restoring parent-child relationship between them initially. For mount-v2 '''MOUNT''' would be first mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-1000''' and '''PARENT''' would be mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-999''' so that on the first stage we only create mounts and then on separate second stage handle the tree assembling separately. This way we can have useful heuristics like on the second stage we can create overmounts after mounts they overmount, and on the  first stage we can create external mounts before their bindmounts and these two do not clinch with each other.&lt;br /&gt;
&lt;br /&gt;
But it is not so simple actually because we do not want to rewrite all the code for instance for restoring mount content or restoring ghost and remap files, which used mountpoint paths in &amp;quot;tree&amp;quot; format. So in all places where it does not matter (where we do not access &amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/... paths) we switched from using mount_info-&amp;gt;mountpoint to mount_info-&amp;gt;ns_mountpoint and in all places where we actually needed &amp;quot;tree&amp;quot; format paths we replace them with service_mountpoint() helper which would return &amp;quot;tree&amp;quot; paths for original mount engine and &amp;quot;plain&amp;quot; paths for mount-v2. This way we can safely switch from one to another.&lt;br /&gt;
&lt;br /&gt;
==== Resolving sharing groups ====&lt;br /&gt;
&lt;br /&gt;
Just after reading mounts from images in read_mnt_ns_img() when mount-v2 is enabled we have an additional step to collect sharing group information from mounts and turn it to sharing groups forest graph (resolve_shared_mounts_v2). First, we just walk over all mounts and create sharing group for each mount with unique shared_id + master_id pair, also we sew all mounts to corresponding sharing group with same id pair. Second, we walk over all sharing groups which has non-zero master_id and lookup the corresponding parent sharing groups and connect them with a tree.&lt;br /&gt;
&lt;br /&gt;
There is also a case when master_id is non-zero but there is no corresponding parent sharing group, this means that outside of dumped container there is mount with matching shared_id - external slavery detected. For this case we just collect sibling sharing groups in list with empty parent link. Also we detect source path from which the master_id would be inherited either from some mountpoint-external mount or from root container mount.&lt;br /&gt;
&lt;br /&gt;
to be continued...&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount-v2&amp;diff=5229</id>
		<title>Mount-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount-v2&amp;diff=5229"/>
		<updated>2022-01-27T11:33:19Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mount-v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
After we've merged MOVE_MOUNT_SET_GROUP feature to mainstream linux v5.15 [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e] now we can use it to restore sharing groups of mounts without the need to care about inheriting those groups when create mounts, we can just set sharing groups at later stage and before that construct mount trees with private mounts.&lt;br /&gt;
&lt;br /&gt;
Restoring propagation right with conservative approach of both creating mounts and inheriting propagation groups looks like mission impossible task for us due to many problems:&lt;br /&gt;
&lt;br /&gt;
* Criu knows nothing about the initial history or order of mount tree creation;&lt;br /&gt;
* Propagation can create tons of mounts;&lt;br /&gt;
* Propagation may change parent mounts for existing mount tree;&lt;br /&gt;
* &amp;quot;Mount trap&amp;quot; - propagation may cover initial mount;&lt;br /&gt;
* &amp;quot;Non-uniform&amp;quot; propagation - there are different tricks with mount order and temporary children-&amp;quot;lock&amp;quot; mounts, which create mount trees which can't be restored without those tricks;&lt;br /&gt;
* &amp;quot;Cross-namespace&amp;quot; sharing groups creation need to be ordered with mount namespace creation right;&lt;br /&gt;
* Sharing groups vs mount tree order inversion can be very complex to restore and require multiple auxiliary. (see example below)&lt;br /&gt;
&lt;br /&gt;
See my talks about it on Linux Plumbers Conference:&lt;br /&gt;
* [https://www.linuxplumbersconf.org/event/7/contributions/640/ CRIU mounts migration: problems and solutions]&lt;br /&gt;
* [https://linuxplumbersconf.org/event/11/contributions/923/ Mount-v2 CRIU migration engine: status update]&lt;br /&gt;
&lt;br /&gt;
And here is the example of order inversion where multiple temporary mounts needed to achieve the result:&lt;br /&gt;
[[File:Mounts-inverse-order-example.gif|none|link=|Mounts-inverse-order-example.gif]]&lt;br /&gt;
&lt;br /&gt;
== Mount-v2 description ==&lt;br /&gt;
&lt;br /&gt;
New mount-v2 algorithm is integrated deeply in the original one, so that dumping of mounts is done exactly the same for original mount engine and new one. So mount-v2 series has preparatory steps related to bindmount detection, external mounts detection and helper mounts handling to make the original mount code more robust, to make it easier to reuse it in mount-v2.&lt;br /&gt;
&lt;br /&gt;
==== Plain mountpoints ====&lt;br /&gt;
&lt;br /&gt;
One of main differences of mount-v2 comparing to original is that mounts are initially created &amp;quot;plain&amp;quot;, for instance if we had '''MOUNT''' with '''mnt_id=1000''' and '''ns_mountpoint=&amp;quot;/mount/point/path&amp;quot;''', original mount engine would originally mount this '''MOUNT''' in the mount tree to '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point/path''' so that if this mount had '''PARENT''' mount with '''mnt_id=999''' and '''ns_mountpoint=&amp;quot;/mount/point&amp;quot;''' corresponding mount for '''PARENT''' would be created in '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point''' thus restoring parent-child relationship between them initially. For mount-v2 '''MOUNT''' would be first mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-1000''' and '''PARENT''' would be mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-999''' so that on the first stage we only create mounts and then on separate second stage handle the tree assembling separately. This way we can have useful heuristics like on the second stage we can create overmounts after mounts they overmount, and on the  first stage we can create external mounts before their bindmounts and these two do not clinch with each other.&lt;br /&gt;
&lt;br /&gt;
But it is not so simple actually because we do not want to rewrite all the code for instance for restoring mount content or restoring ghost and remap files, which used mountpoint paths in &amp;quot;tree&amp;quot; format. So in all places where it does not matter (where we do not access &amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/... paths) we switched from using mount_info-&amp;gt;mountpoint to mount_info-&amp;gt;ns_mountpoint and in all places where we actually needed &amp;quot;tree&amp;quot; format paths we replace them with service_mountpoint() helper which would return &amp;quot;tree&amp;quot; paths for original mount engine and &amp;quot;plain&amp;quot; paths for mount-v2. This way we can safely switch from one to another.&lt;br /&gt;
&lt;br /&gt;
==== Resolving sharing groups ====&lt;br /&gt;
&lt;br /&gt;
Just after reading mounts from images in read_mnt_ns_img() when mount-v2 is enabled we have an additional step to collect sharing group information from mounts and turn it to sharing groups forest graph. First, we just walk over all mounts and create sharing group for each mount with unique shared_id + master_id pair, also we sew all mounts to corresponding sharing group with same id pair. Second, we walk over all sharing groups which has non-zero master_id and lookup the corresponding parent sharing groups and connect them with a tree.&lt;br /&gt;
&lt;br /&gt;
There is also a case when master_id is non-zero but there is no corresponding parent sharing group, this means that outside of dumped container there is mount with matching shared_id - external slavery detected. For this case we just collect sibling sharing groups in list with empty parent link. Also we detect source path from which the master_id would be inherited either from some mountpoint-external mount or from root container mount.&lt;br /&gt;
&lt;br /&gt;
to be continued...&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount-v2&amp;diff=5228</id>
		<title>Mount-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount-v2&amp;diff=5228"/>
		<updated>2022-01-26T08:24:32Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mount-v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
After we've merged MOVE_MOUNT_SET_GROUP feature to mainstream linux v5.15 [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e] now we can use it to restore sharing groups of mounts without the need to care about inheriting those groups when create mounts, we can just set sharing groups at later stage and before that construct mount trees with private mounts.&lt;br /&gt;
&lt;br /&gt;
Restoring propagation right with conservative approach of both creating mounts and inheriting propagation groups looks like mission impossible task for us due to many problems:&lt;br /&gt;
&lt;br /&gt;
* Criu knows nothing about the initial history or order of mount tree creation;&lt;br /&gt;
* Propagation can create tons of mounts;&lt;br /&gt;
* Propagation may change parent mounts for existing mount tree;&lt;br /&gt;
* &amp;quot;Mount trap&amp;quot; - propagation may cover initial mount;&lt;br /&gt;
* &amp;quot;Non-uniform&amp;quot; propagation - there are different tricks with mount order and temporary children-&amp;quot;lock&amp;quot; mounts, which create mount trees which can't be restored without those tricks;&lt;br /&gt;
* &amp;quot;Cross-namespace&amp;quot; sharing groups creation need to be ordered with mount namespace creation right;&lt;br /&gt;
* Sharing groups vs mount tree order inversion can be very complex to restore and require multiple auxiliary. (see example below)&lt;br /&gt;
&lt;br /&gt;
See my talks about it on Linux Plumbers Conference:&lt;br /&gt;
* [https://www.linuxplumbersconf.org/event/7/contributions/640/ CRIU mounts migration: problems and solutions]&lt;br /&gt;
* [https://linuxplumbersconf.org/event/11/contributions/923/ Mount-v2 CRIU migration engine: status update]&lt;br /&gt;
&lt;br /&gt;
And here is the example of order inversion where multiple temporary mounts needed to achieve the result:&lt;br /&gt;
[[File:Mounts-inverse-order-example.gif|none|link=|Mounts-inverse-order-example.gif]]&lt;br /&gt;
&lt;br /&gt;
== Mount-v2 description ==&lt;br /&gt;
&lt;br /&gt;
New mount-v2 algorithm is integrated deeply in the original one, so that dumping of mounts is done exactly the same for original mount engine and new one. So mount-v2 series has preparatory steps related to bindmount detection, external mounts detection and helper mounts handling to make the original mount code more robust, to make it easier to reuse it in mount-v2.&lt;br /&gt;
&lt;br /&gt;
One of main differences of mount-v2 comparing to original is that mounts are initially created &amp;quot;plain&amp;quot;, for instance if we had '''MOUNT''' with '''mnt_id=1000''' and '''ns_mountpoint=&amp;quot;/mount/point/path&amp;quot;''', original mount engine would originally mount this '''MOUNT''' in the mount tree to '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point/path''' so that if this mount had '''PARENT''' mount with '''mnt_id=999''' and '''ns_mountpoint=&amp;quot;/mount/point&amp;quot;''' corresponding mount for '''PARENT''' would be created in '''&amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/mount/point''' thus restoring parent-child relationship between them initially. For mount-v2 '''MOUNT''' would be first mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-1000''' and '''PARENT''' would be mounted to '''&amp;lt;criu_root_yard&amp;gt;/mnt-999''' so that on the first stage we only create mounts and then on separate second stage handle the tree assembling separately. This way we can have useful heuristics like on the second stage we can create overmounts after mounts they overmount, and on the  first stage we can create external mounts before their bindmounts and these two do not clinch with each other.&lt;br /&gt;
&lt;br /&gt;
But it is not so simple actually because we do not want to rewrite all the code for instance for restoring mount content or restoring ghost and remap files, which used mountpoint paths in &amp;quot;tree&amp;quot; format. So in all places where it does not matter (where we do not access &amp;lt;criu_root_yard&amp;gt;/&amp;lt;mntns&amp;gt;/... paths) we switched from using mount_info-&amp;gt;mountpoint to mount_info-&amp;gt;ns_mountpoint and in all places where we actually needed &amp;quot;tree&amp;quot; format paths we replace them with service_mountpoint() helper which would return &amp;quot;tree&amp;quot; paths for original mount engine and &amp;quot;plain&amp;quot; paths for mount-v2. This way we can safely switch from one to another.&lt;br /&gt;
&lt;br /&gt;
to be continued...&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount-v2&amp;diff=5227</id>
		<title>Mount-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount-v2&amp;diff=5227"/>
		<updated>2022-01-26T07:17:45Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mount-v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
After we've merged MOVE_MOUNT_SET_GROUP feature to mainstream linux v5.15 [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e] now we can use it to restore sharing groups of mounts without the need to care about inheriting those groups when create mounts, we can just set sharing groups at later stage and before that construct mount trees with private mounts.&lt;br /&gt;
&lt;br /&gt;
Restoring propagation right with conservative approach of both creating mounts and inheriting propagation groups looks like mission impossible task for us due to many problems:&lt;br /&gt;
&lt;br /&gt;
* Criu knows nothing about the initial history or order of mount tree creation;&lt;br /&gt;
* Propagation can create tons of mounts;&lt;br /&gt;
* Propagation may change parent mounts for existing mount tree;&lt;br /&gt;
* &amp;quot;Mount trap&amp;quot; - propagation may cover initial mount;&lt;br /&gt;
* &amp;quot;Non-uniform&amp;quot; propagation - there are different tricks with mount order and temporary children-&amp;quot;lock&amp;quot; mounts, which create mount trees which can't be restored without those tricks;&lt;br /&gt;
* &amp;quot;Cross-namespace&amp;quot; sharing groups creation need to be ordered with mount namespace creation right;&lt;br /&gt;
* Sharing groups vs mount tree order inversion can be very complex to restore and require multiple auxiliary. (see example below)&lt;br /&gt;
&lt;br /&gt;
See my talks about it on Linux Plumbers Conference:&lt;br /&gt;
* [https://www.linuxplumbersconf.org/event/7/contributions/640/ CRIU mounts migration: problems and solutions]&lt;br /&gt;
* [https://linuxplumbersconf.org/event/11/contributions/923/ Mount-v2 CRIU migration engine: status update]&lt;br /&gt;
&lt;br /&gt;
And here is the example of order inversion where multiple temporary mounts needed to achieve the result:&lt;br /&gt;
[[File:Mounts-inverse-order-example.gif|none|link=|Mounts-inverse-order-example.gif]]&lt;br /&gt;
&lt;br /&gt;
to be continued...&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount-v2&amp;diff=5226</id>
		<title>Mount-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount-v2&amp;diff=5226"/>
		<updated>2022-01-26T07:09:33Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mount-v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
After we've merged MOVE_MOUNT_SET_GROUP feature to mainstream linux v5.15 [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e] now we can use it to restore sharing groups of mounts without the need to care about inheriting those groups when create mounts, we can just set sharing groups at later stage and before that construct mount trees with private mounts.&lt;br /&gt;
&lt;br /&gt;
Restoring propagation right with conservative approach of both creating mounts and inheriting propagation groups looks like mission impossible task for us due to many problems:&lt;br /&gt;
&lt;br /&gt;
* Criu knows nothing about the initial history or order of mount tree creation;&lt;br /&gt;
* Propagation can create tons of mounts;&lt;br /&gt;
* Propagation may change parent mounts for existing mount tree;&lt;br /&gt;
* &amp;quot;Mount trap&amp;quot; - propagation may cover initial mount;&lt;br /&gt;
* &amp;quot;Non-uniform&amp;quot; propagation - there are different tricks with mount order and temporary children-&amp;quot;lock&amp;quot; mounts, which create mount trees which can't be restored without those tricks.&lt;br /&gt;
* &amp;quot;Cross-namespace&amp;quot; sharing groups creation need to be ordered with mount namespace creation right.&lt;br /&gt;
* Sharing groups vs mount tree order inversion can be very complex to restore and require multiple auxiliary. (see example below)&lt;br /&gt;
&lt;br /&gt;
See my talks about it on Linux Plumbers Conference:&lt;br /&gt;
* [https://www.linuxplumbersconf.org/event/7/contributions/640/ CRIU mounts migration: problems and solutions]&lt;br /&gt;
* [https://linuxplumbersconf.org/event/11/contributions/923/ Mount-v2 CRIU migration engine: status update]&lt;br /&gt;
&lt;br /&gt;
And here is the example of order inversion where multiple temporary mounts needed to achieve the result:&lt;br /&gt;
[[File:Mounts-inverse-order-example.gif|none|link=|Mounts-inverse-order-example.gif]]&lt;br /&gt;
&lt;br /&gt;
to be continued...&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount-v2&amp;diff=5225</id>
		<title>Mount-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount-v2&amp;diff=5225"/>
		<updated>2022-01-25T16:26:25Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: Mount-v2 CRIU algorithm which uses new MOVE_MOUNT_SET_GROUP kernel feature&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mount-v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
After we've merged MOVE_MOUNT_SET_GROUP feature to mainstream linux v5.15 [https://github.com/torvalds/linux/commit/9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 torvalds/linux@9ffb14e] now we can use it to restore sharing groups of mounts without the need to care about inheriting those groups when create mounts, we can just set sharing groups at later stage and before that construct mount trees with private mounts.&lt;br /&gt;
&lt;br /&gt;
Restoring propagation right with conservative approach of both creating mounts and inheriting propagation groups looks like mission impossible task for us due to many problems:&lt;br /&gt;
&lt;br /&gt;
* Criu knows nothing about the initial history or order of mount tree creation;&lt;br /&gt;
* Propagation can create tons of mounts;&lt;br /&gt;
* Propagation may change parent mounts for existing mount tree;&lt;br /&gt;
* &amp;quot;Mount trap&amp;quot; - propagation may cover initial mount;&lt;br /&gt;
* &amp;quot;Non-uniform&amp;quot; propagation - there are different tricks with mount order and temporary children-&amp;quot;lock&amp;quot; mounts, which create mount trees which can't be restored without those tricks.&lt;br /&gt;
* &amp;quot;Cross-namespace&amp;quot; sharing groups creation need to be ordered with mount namespace creation right.&lt;br /&gt;
* Sharing groups vs mount tree order inversion can be very complex to restore and require multiple auxiliary. (see example below)&lt;br /&gt;
[[File:Mounts-inverse-order-example.gif|none|Mounts-inverse-order-example.gif]]&lt;br /&gt;
&lt;br /&gt;
to be continued...&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=File:Mounts-inverse-order-example.gif&amp;diff=5224</id>
		<title>File:Mounts-inverse-order-example.gif</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=File:Mounts-inverse-order-example.gif&amp;diff=5224"/>
		<updated>2022-01-25T16:16:40Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: Ptikhomirov uploaded a new version of File:Mounts-inverse-order-example.gif&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
This a gif to illustrate how complex inverse mnt_id via sharing_id chains can be created.&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=File:Mounts-inverse-order-example-2.gif&amp;diff=5223</id>
		<title>File:Mounts-inverse-order-example-2.gif</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=File:Mounts-inverse-order-example-2.gif&amp;diff=5223"/>
		<updated>2022-01-25T16:15:22Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: This a gif to illustrate how complex inverse mnt_id via sharing_id chains can be created.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
This a gif to illustrate how complex inverse mnt_id via sharing_id chains can be created.&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=File:Mounts-inverse-order-example.gif&amp;diff=5222</id>
		<title>File:Mounts-inverse-order-example.gif</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=File:Mounts-inverse-order-example.gif&amp;diff=5222"/>
		<updated>2022-01-25T16:05:16Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: Ptikhomirov uploaded a new version of File:Mounts-inverse-order-example.gif&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
This a gif to illustrate how complex inverse mnt_id via sharing_id chains can be created.&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=File:Mounts-inverse-order-example.gif&amp;diff=5221</id>
		<title>File:Mounts-inverse-order-example.gif</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=File:Mounts-inverse-order-example.gif&amp;diff=5221"/>
		<updated>2022-01-25T15:26:26Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: This a gif to illustrate how complex inverse mnt_id via sharing_id chains can be created.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
This a gif to illustrate how complex inverse mnt_id via sharing_id chains can be created.&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mounts-v2&amp;diff=5220</id>
		<title>Mounts-v2</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mounts-v2&amp;diff=5220"/>
		<updated>2022-01-25T15:19:00Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: Ptikhomirov moved page Mounts-v2 to Mounts-v2-Virtuozzo: Need a place for a Mount-v2 description for a changed ported version.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Mounts-v2-Virtuozzo]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mounts-v2-Virtuozzo&amp;diff=5219</id>
		<title>Mounts-v2-Virtuozzo</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mounts-v2-Virtuozzo&amp;diff=5219"/>
		<updated>2022-01-25T15:19:00Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: Ptikhomirov moved page Mounts-v2 to Mounts-v2-Virtuozzo: Need a place for a Mount-v2 description for a changed ported version.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mounts v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
This algorithm is designed to overcome problems with sharing group restore, overmounted files, mounts with namespace tags and some more smaller problems.&lt;br /&gt;
&lt;br /&gt;
(assume single userns for now)&lt;br /&gt;
&lt;br /&gt;
* Mounts image read stage (read_mnt_ns_img + read_mnt_ns_img_v2)&lt;br /&gt;
** Read mount_infos from images for each mount namespace to lists (collect_mnt_from_image)&lt;br /&gt;
** Put mounts to trees for each mount namespace (mnt_build_tree)&lt;br /&gt;
** Group mounts by superblock equality into &amp;quot;bind&amp;quot; lists (search_bindmounts)&lt;br /&gt;
** Prepare sharing groups&lt;br /&gt;
*** Group mounts into shared group by equality of (master_id + shared_id)&lt;br /&gt;
*** Put shared groups in tree where parent-&amp;gt;shared_id == child-&amp;gt;master_id&lt;br /&gt;
*** If two groups has same master_id, make them siblings (even if no parent)&lt;br /&gt;
** Prepare &amp;quot;internal yard&amp;quot; mount_info aside (setup_internal_yards)&lt;br /&gt;
*** ns mountpoint &amp;quot;/internal-yard-XXXXXX&amp;quot;&lt;br /&gt;
*** will require writable namespace root mount&lt;br /&gt;
*** needed for mount stage after forking tasks&lt;br /&gt;
** Prepare nested pidns procfses &lt;br /&gt;
*** Copy namespace tag across &amp;quot;bind&amp;quot; list (search_nested_pidns_proc)&lt;br /&gt;
*** Create helpers for descendants of nested pidns procfses in &amp;quot;internal yard&amp;quot; (handle_nested_pidns_proc)&lt;br /&gt;
**** These helpers get root &amp;quot;/&amp;quot; for simplicity (deleted, file/dir)&lt;br /&gt;
***** no nsfs bind support&lt;br /&gt;
**** ns mountpoint &amp;quot;/internal-yard-XXXXXX/hlp-[mnt_id]&lt;br /&gt;
** Prepare &amp;quot;root yard&amp;quot;&lt;br /&gt;
*** helper mount with mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/&amp;quot;&lt;br /&gt;
*** Merge mount trees of all mount namespaces as subdirectories of &amp;quot;root yard&amp;quot; (merge_mount_trees)&lt;br /&gt;
**** mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/[nns_id]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* Mounting, first stage (before forking processes) from init task in &amp;quot;service&amp;quot; mntns (prepare_mnt_ns_v2)&lt;br /&gt;
** Actually create and mount &amp;quot;root yard&amp;quot; (populate_mnt_ns_v2 -&amp;gt; populate_roots_yard_v2)&lt;br /&gt;
** Replace mounts for after forking tasks stage (insert_internal_yards)&lt;br /&gt;
*** Delete nested pidns procfses from tree&lt;br /&gt;
*** Insert internal yards with helpers to tree&lt;br /&gt;
** Walk the merged mount tree (mnt_tree_for_each) parents before children&lt;br /&gt;
*** Mount all mounts &amp;quot;plain&amp;quot; (do_mount_one_v2)&lt;br /&gt;
**** check mount can be mounted (can_mount_now_v2) e.g. for overlay, root, external, bind or nsfs&lt;br /&gt;
**** create mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/mnt-[mnt_id]&amp;quot; (create_plain_mountpoint)&lt;br /&gt;
***** dir/file detected by stat on mountpoint&lt;br /&gt;
**** Mount all mounts private and &amp;quot;plain&amp;quot;&lt;br /&gt;
***** just mount a new mount (do_new_mount_v2)&lt;br /&gt;
****** setup as bind source for other mounts of this super block (propagate_mount_v2)&lt;br /&gt;
***** bind if superblock is already mounted or external or root (do_bind_mount_v2, do_mount_root_v2)&lt;br /&gt;
****** create sources for &amp;quot;deleted&amp;quot; bind mounts and leave it for now&lt;br /&gt;
***** Handle internal yard (do_internal_yard_mount_v2)&lt;br /&gt;
****** mount tmpfs&lt;br /&gt;
****** create mountpoints for children&lt;br /&gt;
****** mount host's proc helper mount inside&lt;br /&gt;
**** Exept for &amp;quot;plain&amp;quot;, &amp;quot;private&amp;quot; and helpers from &amp;quot;internal yard&amp;quot; we restore each mount as it should be in the final mountns (all flags and options applied)&lt;br /&gt;
*** This mounting all the mounts from all final mount namespaces in a single service mount namespace allows us to do &amp;quot;cross-namespace&amp;quot; bindmounts&lt;br /&gt;
&lt;br /&gt;
* Mounting, second stage (&amp;quot;plain&amp;quot; to &amp;quot;tree&amp;quot; mount) (prepare_mnt_ns_v2)&lt;br /&gt;
** Walk across all mount namespaces&lt;br /&gt;
*** unshare(CLONE_NEWNS)&lt;br /&gt;
*** Walk all mounts belonging to this mntns (tree order) (assemble_tree_from_plain_mounts)&lt;br /&gt;
**** mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/[nns_id]/[ns_mountpoint]&amp;quot;&lt;br /&gt;
**** Open mountpoint fd before moving mount to it and save (mp_fd)&lt;br /&gt;
**** Move (MS_MOVE) mount to the tree&lt;br /&gt;
**** Open mount fd (root dentry on a mount) (mnt_fd)&lt;br /&gt;
*** Pivot root to &amp;quot;&amp;quot;/tmp/.criu.mntns.XXXXXX/[nns_id]&amp;quot;&lt;br /&gt;
**** leaving only mounts which should be in this mntns&lt;br /&gt;
** Extract &amp;quot;internal yard&amp;quot;s from the tree and put back procfses and their ancestors (extract_internal_yards)&lt;br /&gt;
** Remove sources of deleted mounts making them really &amp;quot;deleted&amp;quot; from &amp;quot;service&amp;quot; mntns (remove_sources_of_deleted_mounts)&lt;br /&gt;
&lt;br /&gt;
* Forking stage: fork all processes (tree order)&lt;br /&gt;
** Inits also creat pid namespaces&lt;br /&gt;
** Enter mount namespace&lt;br /&gt;
** Mmap files from mounted filesystem to restore COW mappings&lt;br /&gt;
*** We assume here that we don't have file mappings on delayed mounts else we can't handle it&lt;br /&gt;
*** Ghost/Link remaps may be created here&lt;br /&gt;
** Fork children&lt;br /&gt;
&lt;br /&gt;
* Mounting, third stage (after forking processes) (from main criu task) (__fini_restore_mntns_v2)&lt;br /&gt;
** Enter CT userns (fini_restore_mntns_v2)&lt;br /&gt;
** For each mount namespace&lt;br /&gt;
*** For each procfs of this mntns (fixup_nested_pidns_proc)&lt;br /&gt;
**** Enter tagged pidns&lt;br /&gt;
**** Mount procfs from it in &amp;quot;internal yard&amp;quot;&lt;br /&gt;
*** Walk the mount tree of each mntns and mount all yet not mounted mounts to the tree&lt;br /&gt;
**** Find the mountpoint for the mount via mnt_fd of parent and mp_fds of sibling overmounts&lt;br /&gt;
**** Bind the mount to it from the internal yard helper or procfs helper&lt;br /&gt;
***** via /proc/self/fd/&amp;lt;id&amp;gt; on hosts proc in &amp;quot;internal yard&amp;quot;&lt;br /&gt;
**** Also open mnt_fd and mp_fd for a new mount (before and after bind)&lt;br /&gt;
*** Umount and rmdir &amp;quot;internal yard&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* And finally&lt;br /&gt;
** Restore sharing groups for each mount (use mnt_fd to access mounts) (restore_mount_sharing_options)&lt;br /&gt;
*** Walk sharing group trees (parents before children)&lt;br /&gt;
**** Setup first (any) mount in a group&lt;br /&gt;
***** Is slave&lt;br /&gt;
****** Find any mount from parent sg or find external mount source&lt;br /&gt;
****** Copy sharing from it with MS_SET_GROUP&lt;br /&gt;
****** Make slave&lt;br /&gt;
***** Is shared - make it also shared&lt;br /&gt;
**** Setup other mounts - copy sharing from the first one&lt;br /&gt;
&lt;br /&gt;
* Done&lt;br /&gt;
&lt;br /&gt;
Here are links to mounts-v2 implementation in Virtuozzo criu:&lt;br /&gt;
* Main part: https://src.openvz.org/projects/OVZ/repos/criu/commits?until=v3.12.3.12&lt;br /&gt;
* Delayed proc part: https://src.openvz.org/projects/OVZ/repos/criu/commits?until=v3.12.5.13&lt;br /&gt;
* Kernel patch for MS_SET_GROUP: https://lore.kernel.org/lkml/1485214628-23812-1-git-send-email-avagin@openvz.org/&lt;br /&gt;
&lt;br /&gt;
[[Category: Under the hood]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mounts-v2-Virtuozzo&amp;diff=5082</id>
		<title>Mounts-v2-Virtuozzo</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mounts-v2-Virtuozzo&amp;diff=5082"/>
		<updated>2020-08-21T08:49:39Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: Add category.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mounts v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
This algorithm is designed to overcome problems with sharing group restore, overmounted files, mounts with namespace tags and some more smaller problems.&lt;br /&gt;
&lt;br /&gt;
(assume single userns for now)&lt;br /&gt;
&lt;br /&gt;
* Mounts image read stage (read_mnt_ns_img + read_mnt_ns_img_v2)&lt;br /&gt;
** Read mount_infos from images for each mount namespace to lists (collect_mnt_from_image)&lt;br /&gt;
** Put mounts to trees for each mount namespace (mnt_build_tree)&lt;br /&gt;
** Group mounts by superblock equality into &amp;quot;bind&amp;quot; lists (search_bindmounts)&lt;br /&gt;
** Prepare sharing groups&lt;br /&gt;
*** Group mounts into shared group by equality of (master_id + shared_id)&lt;br /&gt;
*** Put shared groups in tree where parent-&amp;gt;shared_id == child-&amp;gt;master_id&lt;br /&gt;
*** If two groups has same master_id, make them siblings (even if no parent)&lt;br /&gt;
** Prepare &amp;quot;internal yard&amp;quot; mount_info aside (setup_internal_yards)&lt;br /&gt;
*** ns mountpoint &amp;quot;/internal-yard-XXXXXX&amp;quot;&lt;br /&gt;
*** will require writable namespace root mount&lt;br /&gt;
*** needed for mount stage after forking tasks&lt;br /&gt;
** Prepare nested pidns procfses &lt;br /&gt;
*** Copy namespace tag across &amp;quot;bind&amp;quot; list (search_nested_pidns_proc)&lt;br /&gt;
*** Create helpers for descendants of nested pidns procfses in &amp;quot;internal yard&amp;quot; (handle_nested_pidns_proc)&lt;br /&gt;
**** These helpers get root &amp;quot;/&amp;quot; for simplicity (deleted, file/dir)&lt;br /&gt;
***** no nsfs bind support&lt;br /&gt;
**** ns mountpoint &amp;quot;/internal-yard-XXXXXX/hlp-[mnt_id]&lt;br /&gt;
** Prepare &amp;quot;root yard&amp;quot;&lt;br /&gt;
*** helper mount with mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/&amp;quot;&lt;br /&gt;
*** Merge mount trees of all mount namespaces as subdirectories of &amp;quot;root yard&amp;quot; (merge_mount_trees)&lt;br /&gt;
**** mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/[nns_id]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* Mounting, first stage (before forking processes) from init task in &amp;quot;service&amp;quot; mntns (prepare_mnt_ns_v2)&lt;br /&gt;
** Actually create and mount &amp;quot;root yard&amp;quot; (populate_mnt_ns_v2 -&amp;gt; populate_roots_yard_v2)&lt;br /&gt;
** Replace mounts for after forking tasks stage (insert_internal_yards)&lt;br /&gt;
*** Delete nested pidns procfses from tree&lt;br /&gt;
*** Insert internal yards with helpers to tree&lt;br /&gt;
** Walk the merged mount tree (mnt_tree_for_each) parents before children&lt;br /&gt;
*** Mount all mounts &amp;quot;plain&amp;quot; (do_mount_one_v2)&lt;br /&gt;
**** check mount can be mounted (can_mount_now_v2) e.g. for overlay, root, external, bind or nsfs&lt;br /&gt;
**** create mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/mnt-[mnt_id]&amp;quot; (create_plain_mountpoint)&lt;br /&gt;
***** dir/file detected by stat on mountpoint&lt;br /&gt;
**** Mount all mounts private and &amp;quot;plain&amp;quot;&lt;br /&gt;
***** just mount a new mount (do_new_mount_v2)&lt;br /&gt;
****** setup as bind source for other mounts of this super block (propagate_mount_v2)&lt;br /&gt;
***** bind if superblock is already mounted or external or root (do_bind_mount_v2, do_mount_root_v2)&lt;br /&gt;
****** create sources for &amp;quot;deleted&amp;quot; bind mounts and leave it for now&lt;br /&gt;
***** Handle internal yard (do_internal_yard_mount_v2)&lt;br /&gt;
****** mount tmpfs&lt;br /&gt;
****** create mountpoints for children&lt;br /&gt;
****** mount host's proc helper mount inside&lt;br /&gt;
**** Exept for &amp;quot;plain&amp;quot;, &amp;quot;private&amp;quot; and helpers from &amp;quot;internal yard&amp;quot; we restore each mount as it should be in the final mountns (all flags and options applied)&lt;br /&gt;
*** This mounting all the mounts from all final mount namespaces in a single service mount namespace allows us to do &amp;quot;cross-namespace&amp;quot; bindmounts&lt;br /&gt;
&lt;br /&gt;
* Mounting, second stage (&amp;quot;plain&amp;quot; to &amp;quot;tree&amp;quot; mount) (prepare_mnt_ns_v2)&lt;br /&gt;
** Walk across all mount namespaces&lt;br /&gt;
*** unshare(CLONE_NEWNS)&lt;br /&gt;
*** Walk all mounts belonging to this mntns (tree order) (assemble_tree_from_plain_mounts)&lt;br /&gt;
**** mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/[nns_id]/[ns_mountpoint]&amp;quot;&lt;br /&gt;
**** Open mountpoint fd before moving mount to it and save (mp_fd)&lt;br /&gt;
**** Move (MS_MOVE) mount to the tree&lt;br /&gt;
**** Open mount fd (root dentry on a mount) (mnt_fd)&lt;br /&gt;
*** Pivot root to &amp;quot;&amp;quot;/tmp/.criu.mntns.XXXXXX/[nns_id]&amp;quot;&lt;br /&gt;
**** leaving only mounts which should be in this mntns&lt;br /&gt;
** Extract &amp;quot;internal yard&amp;quot;s from the tree and put back procfses and their ancestors (extract_internal_yards)&lt;br /&gt;
** Remove sources of deleted mounts making them really &amp;quot;deleted&amp;quot; from &amp;quot;service&amp;quot; mntns (remove_sources_of_deleted_mounts)&lt;br /&gt;
&lt;br /&gt;
* Forking stage: fork all processes (tree order)&lt;br /&gt;
** Inits also creat pid namespaces&lt;br /&gt;
** Enter mount namespace&lt;br /&gt;
** Mmap files from mounted filesystem to restore COW mappings&lt;br /&gt;
*** We assume here that we don't have file mappings on delayed mounts else we can't handle it&lt;br /&gt;
*** Ghost/Link remaps may be created here&lt;br /&gt;
** Fork children&lt;br /&gt;
&lt;br /&gt;
* Mounting, third stage (after forking processes) (from main criu task) (__fini_restore_mntns_v2)&lt;br /&gt;
** Enter CT userns (fini_restore_mntns_v2)&lt;br /&gt;
** For each mount namespace&lt;br /&gt;
*** For each procfs of this mntns (fixup_nested_pidns_proc)&lt;br /&gt;
**** Enter tagged pidns&lt;br /&gt;
**** Mount procfs from it in &amp;quot;internal yard&amp;quot;&lt;br /&gt;
*** Walk the mount tree of each mntns and mount all yet not mounted mounts to the tree&lt;br /&gt;
**** Find the mountpoint for the mount via mnt_fd of parent and mp_fds of sibling overmounts&lt;br /&gt;
**** Bind the mount to it from the internal yard helper or procfs helper&lt;br /&gt;
***** via /proc/self/fd/&amp;lt;id&amp;gt; on hosts proc in &amp;quot;internal yard&amp;quot;&lt;br /&gt;
**** Also open mnt_fd and mp_fd for a new mount (before and after bind)&lt;br /&gt;
*** Umount and rmdir &amp;quot;internal yard&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* And finally&lt;br /&gt;
** Restore sharing groups for each mount (use mnt_fd to access mounts) (restore_mount_sharing_options)&lt;br /&gt;
*** Walk sharing group trees (parents before children)&lt;br /&gt;
**** Setup first (any) mount in a group&lt;br /&gt;
***** Is slave&lt;br /&gt;
****** Find any mount from parent sg or find external mount source&lt;br /&gt;
****** Copy sharing from it with MS_SET_GROUP&lt;br /&gt;
****** Make slave&lt;br /&gt;
***** Is shared - make it also shared&lt;br /&gt;
**** Setup other mounts - copy sharing from the first one&lt;br /&gt;
&lt;br /&gt;
* Done&lt;br /&gt;
&lt;br /&gt;
Here are links to mounts-v2 implementation in Virtuozzo criu:&lt;br /&gt;
* Main part: https://src.openvz.org/projects/OVZ/repos/criu/commits?until=v3.12.3.12&lt;br /&gt;
* Delayed proc part: https://src.openvz.org/projects/OVZ/repos/criu/commits?until=v3.12.5.13&lt;br /&gt;
* Kernel patch for MS_SET_GROUP: https://lore.kernel.org/lkml/1485214628-23812-1-git-send-email-avagin@openvz.org/&lt;br /&gt;
&lt;br /&gt;
[[Category: Under the hood]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mounts-v2-Virtuozzo&amp;diff=5081</id>
		<title>Mounts-v2-Virtuozzo</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mounts-v2-Virtuozzo&amp;diff=5081"/>
		<updated>2020-08-21T08:28:12Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: Design of mounts-v2 engine&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mounts v2 CRIU algorithm&lt;br /&gt;
&lt;br /&gt;
This algorithm is designed to overcome problems with sharing group restore, overmounted files, mounts with namespace tags and some more smaller problems.&lt;br /&gt;
&lt;br /&gt;
(assume single userns for now)&lt;br /&gt;
&lt;br /&gt;
* Mounts image read stage (read_mnt_ns_img + read_mnt_ns_img_v2)&lt;br /&gt;
** Read mount_infos from images for each mount namespace to lists (collect_mnt_from_image)&lt;br /&gt;
** Put mounts to trees for each mount namespace (mnt_build_tree)&lt;br /&gt;
** Group mounts by superblock equality into &amp;quot;bind&amp;quot; lists (search_bindmounts)&lt;br /&gt;
** Prepare sharing groups&lt;br /&gt;
*** Group mounts into shared group by equality of (master_id + shared_id)&lt;br /&gt;
*** Put shared groups in tree where parent-&amp;gt;shared_id == child-&amp;gt;master_id&lt;br /&gt;
*** If two groups has same master_id, make them siblings (even if no parent)&lt;br /&gt;
** Prepare &amp;quot;internal yard&amp;quot; mount_info aside (setup_internal_yards)&lt;br /&gt;
*** ns mountpoint &amp;quot;/internal-yard-XXXXXX&amp;quot;&lt;br /&gt;
*** will require writable namespace root mount&lt;br /&gt;
*** needed for mount stage after forking tasks&lt;br /&gt;
** Prepare nested pidns procfses &lt;br /&gt;
*** Copy namespace tag across &amp;quot;bind&amp;quot; list (search_nested_pidns_proc)&lt;br /&gt;
*** Create helpers for descendants of nested pidns procfses in &amp;quot;internal yard&amp;quot; (handle_nested_pidns_proc)&lt;br /&gt;
**** These helpers get root &amp;quot;/&amp;quot; for simplicity (deleted, file/dir)&lt;br /&gt;
***** no nsfs bind support&lt;br /&gt;
**** ns mountpoint &amp;quot;/internal-yard-XXXXXX/hlp-[mnt_id]&lt;br /&gt;
** Prepare &amp;quot;root yard&amp;quot;&lt;br /&gt;
*** helper mount with mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/&amp;quot;&lt;br /&gt;
*** Merge mount trees of all mount namespaces as subdirectories of &amp;quot;root yard&amp;quot; (merge_mount_trees)&lt;br /&gt;
**** mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/[nns_id]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* Mounting, first stage (before forking processes) from init task in &amp;quot;service&amp;quot; mntns (prepare_mnt_ns_v2)&lt;br /&gt;
** Actually create and mount &amp;quot;root yard&amp;quot; (populate_mnt_ns_v2 -&amp;gt; populate_roots_yard_v2)&lt;br /&gt;
** Replace mounts for after forking tasks stage (insert_internal_yards)&lt;br /&gt;
*** Delete nested pidns procfses from tree&lt;br /&gt;
*** Insert internal yards with helpers to tree&lt;br /&gt;
** Walk the merged mount tree (mnt_tree_for_each) parents before children&lt;br /&gt;
*** Mount all mounts &amp;quot;plain&amp;quot; (do_mount_one_v2)&lt;br /&gt;
**** check mount can be mounted (can_mount_now_v2) e.g. for overlay, root, external, bind or nsfs&lt;br /&gt;
**** create mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/mnt-[mnt_id]&amp;quot; (create_plain_mountpoint)&lt;br /&gt;
***** dir/file detected by stat on mountpoint&lt;br /&gt;
**** Mount all mounts private and &amp;quot;plain&amp;quot;&lt;br /&gt;
***** just mount a new mount (do_new_mount_v2)&lt;br /&gt;
****** setup as bind source for other mounts of this super block (propagate_mount_v2)&lt;br /&gt;
***** bind if superblock is already mounted or external or root (do_bind_mount_v2, do_mount_root_v2)&lt;br /&gt;
****** create sources for &amp;quot;deleted&amp;quot; bind mounts and leave it for now&lt;br /&gt;
***** Handle internal yard (do_internal_yard_mount_v2)&lt;br /&gt;
****** mount tmpfs&lt;br /&gt;
****** create mountpoints for children&lt;br /&gt;
****** mount host's proc helper mount inside&lt;br /&gt;
**** Exept for &amp;quot;plain&amp;quot;, &amp;quot;private&amp;quot; and helpers from &amp;quot;internal yard&amp;quot; we restore each mount as it should be in the final mountns (all flags and options applied)&lt;br /&gt;
*** This mounting all the mounts from all final mount namespaces in a single service mount namespace allows us to do &amp;quot;cross-namespace&amp;quot; bindmounts&lt;br /&gt;
&lt;br /&gt;
* Mounting, second stage (&amp;quot;plain&amp;quot; to &amp;quot;tree&amp;quot; mount) (prepare_mnt_ns_v2)&lt;br /&gt;
** Walk across all mount namespaces&lt;br /&gt;
*** unshare(CLONE_NEWNS)&lt;br /&gt;
*** Walk all mounts belonging to this mntns (tree order) (assemble_tree_from_plain_mounts)&lt;br /&gt;
**** mountpoint &amp;quot;/tmp/.criu.mntns.XXXXXX/[nns_id]/[ns_mountpoint]&amp;quot;&lt;br /&gt;
**** Open mountpoint fd before moving mount to it and save (mp_fd)&lt;br /&gt;
**** Move (MS_MOVE) mount to the tree&lt;br /&gt;
**** Open mount fd (root dentry on a mount) (mnt_fd)&lt;br /&gt;
*** Pivot root to &amp;quot;&amp;quot;/tmp/.criu.mntns.XXXXXX/[nns_id]&amp;quot;&lt;br /&gt;
**** leaving only mounts which should be in this mntns&lt;br /&gt;
** Extract &amp;quot;internal yard&amp;quot;s from the tree and put back procfses and their ancestors (extract_internal_yards)&lt;br /&gt;
** Remove sources of deleted mounts making them really &amp;quot;deleted&amp;quot; from &amp;quot;service&amp;quot; mntns (remove_sources_of_deleted_mounts)&lt;br /&gt;
&lt;br /&gt;
* Forking stage: fork all processes (tree order)&lt;br /&gt;
** Inits also creat pid namespaces&lt;br /&gt;
** Enter mount namespace&lt;br /&gt;
** Mmap files from mounted filesystem to restore COW mappings&lt;br /&gt;
*** We assume here that we don't have file mappings on delayed mounts else we can't handle it&lt;br /&gt;
*** Ghost/Link remaps may be created here&lt;br /&gt;
** Fork children&lt;br /&gt;
&lt;br /&gt;
* Mounting, third stage (after forking processes) (from main criu task) (__fini_restore_mntns_v2)&lt;br /&gt;
** Enter CT userns (fini_restore_mntns_v2)&lt;br /&gt;
** For each mount namespace&lt;br /&gt;
*** For each procfs of this mntns (fixup_nested_pidns_proc)&lt;br /&gt;
**** Enter tagged pidns&lt;br /&gt;
**** Mount procfs from it in &amp;quot;internal yard&amp;quot;&lt;br /&gt;
*** Walk the mount tree of each mntns and mount all yet not mounted mounts to the tree&lt;br /&gt;
**** Find the mountpoint for the mount via mnt_fd of parent and mp_fds of sibling overmounts&lt;br /&gt;
**** Bind the mount to it from the internal yard helper or procfs helper&lt;br /&gt;
***** via /proc/self/fd/&amp;lt;id&amp;gt; on hosts proc in &amp;quot;internal yard&amp;quot;&lt;br /&gt;
**** Also open mnt_fd and mp_fd for a new mount (before and after bind)&lt;br /&gt;
*** Umount and rmdir &amp;quot;internal yard&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* And finally&lt;br /&gt;
** Restore sharing groups for each mount (use mnt_fd to access mounts) (restore_mount_sharing_options)&lt;br /&gt;
*** Walk sharing group trees (parents before children)&lt;br /&gt;
**** Setup first (any) mount in a group&lt;br /&gt;
***** Is slave&lt;br /&gt;
****** Find any mount from parent sg or find external mount source&lt;br /&gt;
****** Copy sharing from it with MS_SET_GROUP&lt;br /&gt;
****** Make slave&lt;br /&gt;
***** Is shared - make it also shared&lt;br /&gt;
**** Setup other mounts - copy sharing from the first one&lt;br /&gt;
&lt;br /&gt;
* Done&lt;br /&gt;
&lt;br /&gt;
Here are links to mounts-v2 implementation in Virtuozzo criu:&lt;br /&gt;
* Main part: https://src.openvz.org/projects/OVZ/repos/criu/commits?until=v3.12.3.12&lt;br /&gt;
* Delayed proc part: https://src.openvz.org/projects/OVZ/repos/criu/commits?until=v3.12.5.13&lt;br /&gt;
* Kernel patch for MS_SET_GROUP: https://lore.kernel.org/lkml/1485214628-23812-1-git-send-email-avagin@openvz.org/&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=RPC&amp;diff=5043</id>
		<title>RPC</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=RPC&amp;diff=5043"/>
		<updated>2020-03-25T12:28:21Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: remove systemd service part as unsupported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;CRIU-RPC is a remote procedure call (RPC) protocol which uses Google Protocol Buffers to encode its calls. The requests are served by CRIU when either launched in so called &amp;quot;swrk&amp;quot; mode or by a service started with the &amp;lt;code&amp;gt;criu service&amp;lt;/code&amp;gt; command. It uses a &amp;lt;code&amp;gt;SEQPACKET&amp;lt;/code&amp;gt; Unix domain socket for transport. In case of a standalone service it listens at &amp;lt;code&amp;gt;/var/run/criu-service.socket&amp;lt;/code&amp;gt; as a transport.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;criu_req&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;criu_resp&amp;lt;/code&amp;gt; are two main messages for requests/responses. They are to be used for transferring messages and needed to provide compatibility with an older versions of rpc. Field type in them ''must'' be set accordingly to type of request/response that is stored. Types of request/response are defined in &amp;lt;code&amp;gt;enum criu_req_type&amp;lt;/code&amp;gt;. See the [[API compliance]] page for information what each option might mean.&lt;br /&gt;
&lt;br /&gt;
== Protocol ==&lt;br /&gt;
&lt;br /&gt;
The protocol is simple: client sends a &amp;lt;code&amp;gt;criu_req&amp;lt;/code&amp;gt; message to server, server responds back with &amp;lt;code&amp;gt;criu_resp&amp;lt;/code&amp;gt;. In most of the cases the socket gets closed, but there are three exceptions from this rule, see below.&lt;br /&gt;
&lt;br /&gt;
== Request ==&lt;br /&gt;
&lt;br /&gt;
This is the header of the request. It defines the operation requested and options.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message criu_req {&lt;br /&gt;
	required criu_req_type type	= 1;&lt;br /&gt;
	optional criu_opts opts		= 2;&lt;br /&gt;
	optional notify_success         = 3; /* see Notifications below */&lt;br /&gt;
	optional keep_open              = 4; /* for multi-req, below */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently, there are a few request/response types:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
enum criu_req_type {&lt;br /&gt;
	EMPTY		= 0;&lt;br /&gt;
	DUMP		= 1; /* criu dump */&lt;br /&gt;
	RESTORE		= 2; /* criu restore */&lt;br /&gt;
	CHECK		= 3; /* criu check */&lt;br /&gt;
	PRE_DUMP	= 4; /* criu pre-dump */&lt;br /&gt;
	PAGE_SERVER	= 5; /* criu page-server */&lt;br /&gt;
	NOTIFY          = 6; /* see Notifications below */&lt;br /&gt;
	CPUINFO_DUMP	= 7; /* criu cpuinfo dump */&lt;br /&gt;
	CPUINFO_CHECK	= 8; /* criu cpuinfo check */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following options are available:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message criu_opts {&lt;br /&gt;
	required int32			images_dir_fd	= 1;&lt;br /&gt;
	optional int32			pid		= 2; /* if not set on dump, will dump requesting process */&lt;br /&gt;
&lt;br /&gt;
	optional bool			leave_running	= 3;&lt;br /&gt;
	optional bool			ext_unix_sk	= 4;&lt;br /&gt;
	optional bool			tcp_established	= 5;&lt;br /&gt;
	optional bool			evasive_devices	= 6;&lt;br /&gt;
	optional bool			shell_job	= 7;&lt;br /&gt;
	optional bool			file_locks	= 8;&lt;br /&gt;
	optional int32			log_level	= 9 [default = 2];&lt;br /&gt;
	optional string			log_file	= 10; /* No subdirs are allowed. Consider using work-dir */&lt;br /&gt;
&lt;br /&gt;
	optional criu_page_server_info	ps		= 11;&lt;br /&gt;
&lt;br /&gt;
	optional bool			notify_scripts	= 12;&lt;br /&gt;
&lt;br /&gt;
	optional string			root		= 13;&lt;br /&gt;
	optional string			parent_img	= 14;&lt;br /&gt;
	optional bool			track_mem	= 15;&lt;br /&gt;
	optional bool			auto_dedup	= 16;&lt;br /&gt;
&lt;br /&gt;
	optional int32			work_dir_fd	= 17;&lt;br /&gt;
	optional bool			link_remap	= 18;&lt;br /&gt;
	repeated criu_veth_pair		veths		= 19;&lt;br /&gt;
&lt;br /&gt;
	optional uint32			cpu_cap		= 20 [default = 0xffffffff];&lt;br /&gt;
	optional bool			force_irmap	= 21;&lt;br /&gt;
	repeated string			exec_cmd	= 22;&lt;br /&gt;
&lt;br /&gt;
	repeated ext_mount_map		ext_mnt		= 23;&lt;br /&gt;
	optional bool			manage_cgroups	= 24;&lt;br /&gt;
	repeated cgroup_root		cg_root		= 25;&lt;br /&gt;
&lt;br /&gt;
	optional bool			rst_sibling	= 26; /* swrk only */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and examples ===&lt;br /&gt;
&lt;br /&gt;
* If no &amp;lt;code&amp;gt;pid&amp;lt;/code&amp;gt; is set and type is &amp;lt;code&amp;gt;DUMP&amp;lt;/code&amp;gt;, CRIU will dump client process by default.&lt;br /&gt;
* All processes in the subtree starting with &amp;lt;code&amp;gt;''pid''&amp;lt;/code&amp;gt; must have the same uid, as a client, or client's uid must be root (uid == 0), otherwise CRIU will return an error.&lt;br /&gt;
* Only the &amp;lt;code&amp;gt;images_dir_fd&amp;lt;/code&amp;gt; is required, all other fields are optional. Client must open directory for/with images by itself and set &amp;lt;code&amp;gt;images_dir_fd&amp;lt;/code&amp;gt; to the opened &amp;lt;code&amp;gt;fd&amp;lt;/code&amp;gt;. CRIU will open &amp;lt;code&amp;gt;/proc/''client_pid''/fd/''images_dir_fd''&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The logic of setting request is the same as when setting options in console.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
&lt;br /&gt;
 # criu restore -D /path/to/imgs_dir -v4 -o restore.log&lt;br /&gt;
&lt;br /&gt;
This is equal to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
request.type = RESTORE;&lt;br /&gt;
&lt;br /&gt;
request.opts.imgs_dir_fd	= open(&amp;quot;/path/to/imgs_dir&amp;quot;)&lt;br /&gt;
request.opts.log_level		= 4&lt;br /&gt;
request.opts.log_file		= &amp;quot;restore.log&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sub-messages for options ===&lt;br /&gt;
&lt;br /&gt;
==== Info about page-server ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message criu_page_server_info {&lt;br /&gt;
	optional string		address	= 1; /* bind address -- if not set 0.0.0.0 is used */&lt;br /&gt;
	optional int32		port	= 2; /* bind port -- if not set on request, autobind is used and port is returned in response */&lt;br /&gt;
	optional int32		pid	= 3; /* page-server pid -- returned in response */&lt;br /&gt;
	optional int32		fd	= 4; /* could be used to inherit fd by page-server */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message criu_veth_pair {&lt;br /&gt;
	required string		if_in	= 1; /* inside veth device name */&lt;br /&gt;
	required string		if_out	= 2; /* outside veth device name */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Info about veth mappings (&amp;lt;code&amp;gt;--ext-mount-map&amp;lt;/code&amp;gt; analogue) ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message ext_mount_map {&lt;br /&gt;
	required string		key	= 1;&lt;br /&gt;
	required string		val	= 2;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Specifying where cgroup root should be (&amp;lt;code&amp;gt;--cgroup-root&amp;lt;/code&amp;gt; analogue) ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message cgroup_root {&lt;br /&gt;
	optional string		ctrl	= 1;&lt;br /&gt;
	required string		path	= 2;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Response ==&lt;br /&gt;
&lt;br /&gt;
This message is sent after (un)successful execution of the request.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message criu_resp {&lt;br /&gt;
	required criu_req_type		type		= 1;&lt;br /&gt;
	required bool			success		= 2;&lt;br /&gt;
&lt;br /&gt;
	optional criu_dump_resp		dump		= 3;&lt;br /&gt;
	optional criu_restore_resp	restore		= 4;&lt;br /&gt;
	optional criu_notify		notify		= 5;&lt;br /&gt;
	optional criu_page_server_info	ps		= 6;&lt;br /&gt;
&lt;br /&gt;
        optional int32			cr_errno	= 7;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The field &amp;lt;code&amp;gt;success&amp;lt;/code&amp;gt; reports result of processing request, while &amp;lt;code&amp;gt;criu_***_resp&amp;lt;/code&amp;gt; store some request-specific information. The response type is set to the corresponding request type or to &amp;lt;code&amp;gt;EMPTY&amp;lt;/code&amp;gt; to report a &amp;quot;generic&amp;quot; error. If &amp;lt;code&amp;gt;success == false&amp;lt;/code&amp;gt;, one should check &amp;lt;code&amp;gt;cr_errno&amp;lt;/code&amp;gt; field to get a more detailed error code (see [https://github.com/xemul/criu/blob/master/include/cr-errno.h#L8 include/cr-errno.h]).&lt;br /&gt;
&lt;br /&gt;
==== The criu_dump_resp is used to store response from DUMP request ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message criu_dump_resp {&lt;br /&gt;
	optional bool restored		= 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This message can be sent twice — one time for the process that calls DUMP, and  another time for the same process again, in case it requested a self-dump. In the latter case the ''restored'' field would be true.&lt;br /&gt;
&lt;br /&gt;
==== The response on RESTORE request ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message criu_restore_resp {&lt;br /&gt;
	required int32 pid		= 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;pid&amp;lt;/code&amp;gt; field is set to the PID of the newly restored process.&lt;br /&gt;
&lt;br /&gt;
==== Info about page server ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;criu_page_server_info&amp;lt;/code&amp;gt; from requests will be sent back on &amp;lt;code&amp;gt;PAGE_SERVER&amp;lt;/code&amp;gt; request. The &amp;lt;code&amp;gt;port&amp;lt;/code&amp;gt; field will contain the port to which the server is bound.&lt;br /&gt;
&lt;br /&gt;
=== Notifications ===&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;opts.notify_scripts&amp;lt;/code&amp;gt; in the request is set to &amp;lt;code&amp;gt;TRUE&amp;lt;/code&amp;gt;, CRIU would report back resp messages with type set to &amp;lt;code&amp;gt;NOTIFY&amp;lt;/code&amp;gt; and this field present. The notifications are the way [[action scripts]] work for RPC mode.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
message criu_notify {&lt;br /&gt;
	optional string script		= 1;&lt;br /&gt;
	optional int32	pid		= 2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After handling the notification the client must response with the request again with the type set to &amp;lt;code&amp;gt;NOTIFY&amp;lt;/code&amp;gt; and the &amp;lt;code&amp;gt;notify_success&amp;lt;/code&amp;gt; set to the whether the notification was successful. In case of successful notification acknowledge the server doesn't close the socket and continues to work.&lt;br /&gt;
&lt;br /&gt;
== Pre-dumps ==&lt;br /&gt;
&lt;br /&gt;
Before issuing a &amp;lt;code&amp;gt;DUMP&amp;lt;/code&amp;gt; request client may send one or more &amp;lt;code&amp;gt;PRE_DUMP&amp;lt;/code&amp;gt; requests. Once the &amp;lt;code&amp;gt;PRE_DUMP&amp;lt;/code&amp;gt; is sent and response is received, client may send one more &amp;lt;code&amp;gt;PRE_DUMP&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;DUMP&amp;lt;/code&amp;gt; request. The server would only close the socket after the &amp;lt;code&amp;gt;DUMP&amp;lt;/code&amp;gt; one.&lt;br /&gt;
&lt;br /&gt;
== Multi-request mode ==&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;req.keep_open&amp;lt;/code&amp;gt; flag is set to true server will not close the socket after response, but will wait for more requests. This mode is supported only for the following request types:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;PRE_DUMP&amp;lt;/code&amp;gt; (automatically)&lt;br /&gt;
* &amp;lt;code&amp;gt;PAGE_SERVER&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CPUINFO_DUMP&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CPUINFO_CHECK&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Run ==&lt;br /&gt;
&lt;br /&gt;
=== SWRK mode ===&lt;br /&gt;
&lt;br /&gt;
This mode turns on when one &amp;lt;code&amp;gt;fork() + exec()&amp;lt;/code&amp;gt; CRIU with the &amp;lt;code&amp;gt;swrk&amp;lt;/code&amp;gt; action and one more argument specifying the number of descriptor with &amp;lt;code&amp;gt;SOCK_SEQPACKET&amp;lt;/code&amp;gt; Unix socket. With this CRIU works as service worker task accepting standard RPC requests via the mentioned socket and using one to do action scripts notifications and result reporting.&lt;br /&gt;
&lt;br /&gt;
=== Server ===&lt;br /&gt;
&lt;br /&gt;
On a server side, CRIU creates &amp;lt;code&amp;gt;SOCK_SEQPACKET&amp;lt;/code&amp;gt; Unix socket and listens for connections on it. After receiving &amp;lt;code&amp;gt;criu_req&amp;lt;/code&amp;gt;, CRIU processes it, does what was requested and sends &amp;lt;code&amp;gt;criu_resp&amp;lt;/code&amp;gt; with set request-specific &amp;lt;code&amp;gt;criu_***_resp&amp;lt;/code&amp;gt; field back.&lt;br /&gt;
If CRIU gets unknown type of request, it will return &amp;lt;code&amp;gt;criu_resp&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;type == EMPTY&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;success == false&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To launch the service, run:&lt;br /&gt;
&lt;br /&gt;
 # criu service [options]&lt;br /&gt;
&lt;br /&gt;
Options accepted by service are&lt;br /&gt;
&lt;br /&gt;
; --address &amp;lt;path&amp;gt;&lt;br /&gt;
: where to put listening socket&lt;br /&gt;
&lt;br /&gt;
; --pid-file &amp;lt;path&amp;gt;&lt;br /&gt;
: where to write pid of service process&lt;br /&gt;
&lt;br /&gt;
; --daemon&lt;br /&gt;
: tells service to daemonize&lt;br /&gt;
&lt;br /&gt;
; -o &amp;lt;file&amp;gt;&lt;br /&gt;
: says where to write logs&lt;br /&gt;
&lt;br /&gt;
; -v[N]&lt;br /&gt;
: sets the log level&lt;br /&gt;
&lt;br /&gt;
=== Client ===&lt;br /&gt;
&lt;br /&gt;
Client, in its turn, must connect to service socket, send &amp;lt;code&amp;gt;criu_req&amp;lt;/code&amp;gt; with request in it, and wait for a &amp;lt;code&amp;gt;criu_resp&amp;lt;/code&amp;gt; with response.&lt;br /&gt;
You can find examples of client programs in C and Python in test/rpc/.&lt;br /&gt;
&lt;br /&gt;
With RPC facilities one can perform a [[self dump]].&lt;br /&gt;
&lt;br /&gt;
There's a [[C API|library]] that implements simple wrappers on top of RPC.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[CLI]]&lt;br /&gt;
* [[C API]]&lt;br /&gt;
&lt;br /&gt;
[[Category: API]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=External_bind_mounts&amp;diff=5042</id>
		<title>External bind mounts</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=External_bind_mounts&amp;diff=5042"/>
		<updated>2020-03-25T10:07:59Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: External mounts, external/internal sharing/slavery.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
One of typical external resources when dumping a container (especially LXC/Docker) is a mount point whose root sits outside of the container's root. This situation was intended to be resolved using [[plugins]] but turned out to be common enough to introduce a built-in way of handling it.&lt;br /&gt;
&lt;br /&gt;
== What is external bind mount ==&lt;br /&gt;
&lt;br /&gt;
The way to create such is simple as&lt;br /&gt;
&lt;br /&gt;
 mkdir /root&lt;br /&gt;
 mount --bind /foo /root/bar&lt;br /&gt;
 chroot /root&lt;br /&gt;
&lt;br /&gt;
This is it. From now on, the /bar file is a mountpoint whose root (the source) is not accessible directly.&lt;br /&gt;
&lt;br /&gt;
If you look at the /proc/$pid/mountinfo file of a task seeing such you would see smth like&lt;br /&gt;
&lt;br /&gt;
 11 23 8:3 /root / ... - ext4 /dev/sda1 ...&lt;br /&gt;
 23 34 8:3 /foo /bar ... - ext4 /dev/sda1 ...&lt;br /&gt;
&lt;br /&gt;
The columns 4 and 5 are root and mountpoint respectively. You can see, that the / is /root file from /dev/sda1 device and /bar file is a mountpoint with the root being /foo file from the same device.&lt;br /&gt;
&lt;br /&gt;
== How to teach CRIU to dump them ==&lt;br /&gt;
&lt;br /&gt;
By default CRIU doesn't dump such mountpoints, because there's no way CRIU will be able to restore it -- the root of these mounts is out of scope of what CRIU dumped. In the logs you would see a message like&lt;br /&gt;
&lt;br /&gt;
 34:/bar doesn't have a proper root mount&lt;br /&gt;
&lt;br /&gt;
which means the mountpoint /bar has inaccessible root.&lt;br /&gt;
&lt;br /&gt;
To dump and restore them there's the &amp;lt;code&amp;gt;--external mnt[KEY]:VAL&amp;lt;/code&amp;gt; option that sets up external mounts root mapping.&lt;br /&gt;
&lt;br /&gt;
On dump, KEY is a mountpoint inside container, and corresponding VAL is a string that will be written into the image as mountpoint's root value.&lt;br /&gt;
&lt;br /&gt;
On restore, KEY is the value from the image (VAL from dump), and the VAL is the path on host that will be bind-mounted into container (to the mountpoint path from image).&lt;br /&gt;
&lt;br /&gt;
For example, if we want to dump the task above we should call&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external mnt[/bar]:barmount&lt;br /&gt;
&lt;br /&gt;
The word &amp;lt;code&amp;gt;barmount&amp;lt;/code&amp;gt; is an arbitrary identifier, that will be put in the image file instead of the original root path&lt;br /&gt;
&lt;br /&gt;
 criu show -f mountpoints.img -F mnt_id,root,mountpoint&lt;br /&gt;
 mnt_id: 0x22 root: barmount mountpoint: /bar&lt;br /&gt;
&lt;br /&gt;
On restore we should tell CRIU where to bind mount the &amp;lt;code&amp;gt;barmount&amp;lt;/code&amp;gt; from like this&lt;br /&gt;
&lt;br /&gt;
 criu restore ... --external mnt[barmount]:/foo&lt;br /&gt;
&lt;br /&gt;
With this CRIU will bind mount the /foo into proper mountpoint.&lt;br /&gt;
&lt;br /&gt;
== Auto detection ==&lt;br /&gt;
&lt;br /&gt;
In case one wants CRIU to autodetect and dump all the external bind mounts, and there is no need to change host mount points on restore, one can use a special syntax:&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external mnt[]:''flags''&lt;br /&gt;
&lt;br /&gt;
Note here is nothing inside square brackets, and the optional &amp;lt;code&amp;gt;:''flags''&amp;lt;/code&amp;gt; argument can contain the following characters:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;&lt;br /&gt;
: Also enable dumping of external master mounts (as in &amp;lt;code&amp;gt;mount --make-slave&amp;lt;/code&amp;gt;)&lt;br /&gt;
; &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;&lt;br /&gt;
: Also enable dumping of external shared mounts (as in &amp;lt;code&amp;gt;mount --make-shared&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
By default, neither master nor shared external mounts are not dumped (if found, dump is aborted). Note if &amp;lt;code&amp;gt;''flags''&amp;lt;/code&amp;gt; are not given, semicolon is optional.&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]'&lt;br /&gt;
&lt;br /&gt;
Auto detect and dump all external bind mounts.&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]:s'&lt;br /&gt;
&lt;br /&gt;
Auto detect and dump all external bind mounts, including the shared ones.&lt;br /&gt;
&lt;br /&gt;
 criu dump ... --external 'mnt[]:sm'&lt;br /&gt;
&lt;br /&gt;
Auto detect and dump all external bind mounts, including the shared and the master ones.&lt;br /&gt;
&lt;br /&gt;
== Old days ==&lt;br /&gt;
&lt;br /&gt;
For now the same behavior is configured with the &amp;lt;code&amp;gt;--ext-mount-map KEY:VAL&amp;lt;/code&amp;gt; option. Soon this option will be [[deprecation|deprecated]].&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:External]]&lt;br /&gt;
&lt;br /&gt;
=== Sharing for external bindmounts ===&lt;br /&gt;
&lt;br /&gt;
External bindmounts can both have internal/external sharing. Please see the example:&lt;br /&gt;
&lt;br /&gt;
 # Preparation&lt;br /&gt;
 unshare -m --propagation private&lt;br /&gt;
 mkdir /external_mount_sharing_test&lt;br /&gt;
 mount -t tmpfs tmpfs /external_mount_sharing_test/&lt;br /&gt;
 mount --make-private /external_mount_sharing_test/&lt;br /&gt;
 cd /external_mount_sharing_test&lt;br /&gt;
 # Source of external mount&lt;br /&gt;
 mkdir external_mount&lt;br /&gt;
 mount -t tmpfs tmpfs-external external_mount/&lt;br /&gt;
 mount --make-shared external_mount/&lt;br /&gt;
 cat /proc/$$/mountinfo | grep external&lt;br /&gt;
 # 811 755 0:60 / /external_mount_sharing_test rw,relatime - tmpfs tmpfs rw&lt;br /&gt;
 # 812 811 0:62 / /external_mount_sharing_test/external_mount rw,relatime shared:290 - tmpfs tmpfs-external rw&lt;br /&gt;
 &lt;br /&gt;
 # Switch to CT mntns&lt;br /&gt;
 unshare -m --propagation unchanged sh&lt;br /&gt;
 mkdir root&lt;br /&gt;
 mount -t tmpfs tmpfs-root root/&lt;br /&gt;
 mkdir root/external_sharing root/internal_sharing root/proc&lt;br /&gt;
 &lt;br /&gt;
 # Create external mount&lt;br /&gt;
 mount --bind external_mount/ root/external_sharing&lt;br /&gt;
 mount --bind external_mount/ root/internal_sharing&lt;br /&gt;
 mount --make-private root/internal_sharing&lt;br /&gt;
 mount --make-shared root/internal_sharing&lt;br /&gt;
 &lt;br /&gt;
 # More preparations&lt;br /&gt;
 mount --bind /proc root/proc&lt;br /&gt;
 cd root&lt;br /&gt;
 mkdir bin lib64&lt;br /&gt;
 SH=$(which sh)&lt;br /&gt;
 cp $SH bin&lt;br /&gt;
 cp $(ldd $SH | grep &amp;quot;/lib64&amp;quot; | sed 's/^.*\(\/lib64\S*\)\s.*$/\1/') lib64&lt;br /&gt;
 CAT=$(which cat)&lt;br /&gt;
 cp $CAT bin&lt;br /&gt;
 cp $(ldd $CAT | grep &amp;quot;/lib64&amp;quot; | sed 's/^.*\(\/lib64\S*\)\s.*$/\1/') lib64&lt;br /&gt;
 PATH=$PATH:/bin&lt;br /&gt;
 chroot . sh&lt;br /&gt;
 cat /proc/$$/mountinfo&lt;br /&gt;
 # 843 841 0:63 / / rw,relatime - tmpfs tmpfs-root rw&lt;br /&gt;
 # 861 843 0:62 / /external_sharing rw,relatime shared:290 - tmpfs tmpfs-external rw&lt;br /&gt;
 # 898 843 0:62 / /internal_sharing rw,relatime shared:349 - tmpfs tmpfs-external rw&lt;br /&gt;
 # 899 843 0:5 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw&lt;br /&gt;
&lt;br /&gt;
Mounts 812 (on host) and 861 (in container) have the same sharing (shared group) - external sharing and mount 898 has it's own local shared group - internal sharing.&lt;br /&gt;
&lt;br /&gt;
Before [https://github.com/checkpoint-restore/criu/pull/906 #906] we were detecting this external/internal sharing state for auto detected external mounts only, but we need it for manual external mounts too. Moreover this also applies to manual external slave mounts they can be external/internal slaves too.&lt;br /&gt;
&lt;br /&gt;
So we detect that the mount is from external sharing if in mount namespace of CRIU there are mounts of same shared group and also we detect that the mount is from external slavery if there is no master mount for it in CT mount namespaces.&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount_points&amp;diff=5041</id>
		<title>Mount points</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount_points&amp;diff=5041"/>
		<updated>2020-03-25T07:17:28Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* TODO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes what we do with mount points trees.&lt;br /&gt;
== Introduction ==&lt;br /&gt;
When we are thinking about restoring a mount tree, we need to remember a few things:&lt;br /&gt;
* shared and slave groups&lt;br /&gt;
* how mounts are propagated inside one group&lt;br /&gt;
* bind mounts (rw, ro)&lt;br /&gt;
&lt;br /&gt;
The algorithm described here is not able to cover all the cases, so this solution is a temporary one.&lt;br /&gt;
&lt;br /&gt;
== Dump ==&lt;br /&gt;
&lt;br /&gt;
There is nothing interesting here. We just dump information about mounts and validate them to be sure that we are able to restore them.&lt;br /&gt;
&lt;br /&gt;
== Restore ==&lt;br /&gt;
&lt;br /&gt;
Mounts are restored for a few iterations. On each iteration we enumerate all mounts and mount everything we can. On the next iteration we mount a bit more and continue to do so  step by step. The idea is that we will be able to mount something new on each iteration. If we can't mount anything, we stop and report an error telling that we can't restore this configuration.&lt;br /&gt;
For example, a mount can't be mounted if its parent isn't mounted yet. Or a more interesting example, a mount can't be mounted if not all the mounts from its parent shared group are mounted.&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
CRIU doesn't support configurations where two mounts of one shared group have different set of mounts. This is not a feature, this is a bug and you are welcome to fix it.&lt;br /&gt;
&lt;br /&gt;
(done and checked by non_uniform_share_propagation in zdtm)&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
* Read-only bind mounts&lt;br /&gt;
(not sure was meant here but e.g. ghost files on readonly mounts handled and checked by ghost_on_rofs zdtm test)&lt;br /&gt;
* Skipping mountpoints&lt;br /&gt;
* Enabling FS runtime&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[External bind mounts]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Under the hood]]&lt;br /&gt;
[[Category: Fly in the ointment]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=Mount_points&amp;diff=5040</id>
		<title>Mount points</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=Mount_points&amp;diff=5040"/>
		<updated>2020-03-25T07:15:53Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: /* Known issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes what we do with mount points trees.&lt;br /&gt;
== Introduction ==&lt;br /&gt;
When we are thinking about restoring a mount tree, we need to remember a few things:&lt;br /&gt;
* shared and slave groups&lt;br /&gt;
* how mounts are propagated inside one group&lt;br /&gt;
* bind mounts (rw, ro)&lt;br /&gt;
&lt;br /&gt;
The algorithm described here is not able to cover all the cases, so this solution is a temporary one.&lt;br /&gt;
&lt;br /&gt;
== Dump ==&lt;br /&gt;
&lt;br /&gt;
There is nothing interesting here. We just dump information about mounts and validate them to be sure that we are able to restore them.&lt;br /&gt;
&lt;br /&gt;
== Restore ==&lt;br /&gt;
&lt;br /&gt;
Mounts are restored for a few iterations. On each iteration we enumerate all mounts and mount everything we can. On the next iteration we mount a bit more and continue to do so  step by step. The idea is that we will be able to mount something new on each iteration. If we can't mount anything, we stop and report an error telling that we can't restore this configuration.&lt;br /&gt;
For example, a mount can't be mounted if its parent isn't mounted yet. Or a more interesting example, a mount can't be mounted if not all the mounts from its parent shared group are mounted.&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
CRIU doesn't support configurations where two mounts of one shared group have different set of mounts. This is not a feature, this is a bug and you are welcome to fix it.&lt;br /&gt;
&lt;br /&gt;
(done and checked by non_uniform_share_propagation in zdtm)&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
* Read-only bind mounts&lt;br /&gt;
* Skipping mountpoints&lt;br /&gt;
* Enabling FS runtime&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[External bind mounts]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Under the hood]]&lt;br /&gt;
[[Category: Fly in the ointment]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=GSoC20_Students_Requests&amp;diff=5027</id>
		<title>GSoC20 Students Requests</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=GSoC20_Students_Requests&amp;diff=5027"/>
		<updated>2020-03-04T07:45:06Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: fixup&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
# Manas Mangaonkar&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Porting_crit_functionalities_in_GO|Porting crit functionalities in GO]]&lt;br /&gt;
# Anmol&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Anonymise_image_files|Anonymise image files]]&lt;br /&gt;
# Aashim Garg&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Restrict_checks_for_open.2Fmmaped_files|Restrict checks for open/mmaped files]]&lt;br /&gt;
# Zeyad Yasser&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Anonymise_image_files|Anonymise image files]]&lt;br /&gt;
# Kaushlendra Pratap&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Anonymise_image_files|Anonymise image files]]&lt;br /&gt;
# Adhitya Mahajan&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Restrict_checks_for_open.2Fmmaped_files|Restrict checks for open/mmaped files]]&lt;br /&gt;
# Nishchay Agrawal&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Use_eBPF_to_lock_and_unlock_the_network|Use eBPF to lock and unlock the network]]&lt;br /&gt;
# Shivamani Patil&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Porting_crit_functionalities_in_GO|Porting crit functionalities in GO]]&lt;br /&gt;
# Yannis Thomopoulos&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Add_support_for_SPFS|Add support for SPFS]]&lt;br /&gt;
# Sahil Kumar Sahu&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Use_eBPF_to_lock_and_unlock_the_network|Use eBPF to lock and unlock the network]]&lt;br /&gt;
# Puranjay Mohan&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Optimize_logging_engine|Optimize logging engine]]&lt;br /&gt;
# Ajay Bharadwa&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Restrict_checks_for_open.2Fmmaped_files|Restrict checks for open/mmaped files]]&lt;br /&gt;
# Subham Pandey&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Memory_changes_tracking_with_userfaultfd-WP|Memory changes tracker]]&lt;br /&gt;
# Vineet Jain&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Use_eBPF_to_lock_and_unlock_the_network|Use eBPF to lock and unlock the network]] or [[Google_Summer_of_Code_Ideas#Restrict_checks_for_open.2Fmmaped_files|Restrict checks for open/mmaped files]]&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=GSoC20_Students_Requests&amp;diff=5022</id>
		<title>GSoC20 Students Requests</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=GSoC20_Students_Requests&amp;diff=5022"/>
		<updated>2020-03-02T07:54:06Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
# Manas Mangaonkar&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Porting_crit_functionalities_in_GO|Porting crit functionalities in GO]]&lt;br /&gt;
# Anmol&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Anonymise_image_files|Anonymise image files]]&lt;br /&gt;
# Aashim Garg&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Restrict_checks_for_open.2Fmmaped_files|Restrict checks for open/mmaped files]]&lt;br /&gt;
# Zeyad Yasser&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Anonymise_image_files|Anonymise image files]]&lt;br /&gt;
# Kaushlendra Pratap&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Anonymise_image_files|Anonymise image files]]&lt;br /&gt;
# Adhitya Mahajan&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Restrict_checks_for_open.2Fmmaped_files|Restrict checks for open/mmaped files]]&lt;br /&gt;
# Nishchay Agrawal&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Use_eBPF_to_lock_and_unlock_the_network|Use eBPF to lock and unlock the network]]&lt;br /&gt;
# Shivamani Patil&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Porting_crit_functionalities_in_GO|Porting crit functionalities in GO]]&lt;br /&gt;
# Yannis Thomopoulos&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Add_support_for_SPFS|Add support for SPFS]]&lt;br /&gt;
# Sahil Kumar Sahu&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Use_eBPF_to_lock_and_unlock_the_network|Use eBPF to lock and unlock the network]]&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
	<entry>
		<id>https://criu.org/index.php?title=GSoC20_Students_Requests&amp;diff=5016</id>
		<title>GSoC20 Students Requests</title>
		<link rel="alternate" type="text/html" href="https://criu.org/index.php?title=GSoC20_Students_Requests&amp;diff=5016"/>
		<updated>2020-02-28T20:52:52Z</updated>

		<summary type="html">&lt;p&gt;Ptikhomirov: Created page with &amp;quot; # Manas Mangaonkar #* Subproject: Porting crit functionalities in GO # Anmol #* Subproject: Google_Summer...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
# Manas Mangaonkar&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Porting_crit_functionalities_in_GO|Porting crit functionalities in GO]]&lt;br /&gt;
# Anmol&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Anonymise_image_files|Anonymise image files]]&lt;br /&gt;
# Aashim Garg&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Restrict_checks_for_open.2Fmmaped_files|Restrict checks for open/mmaped files]]&lt;br /&gt;
# Zeyad Yasser&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Anonymise_image_files|Anonymise image files]]&lt;br /&gt;
# Kaushlendra Pratap&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Anonymise_image_files|Anonymise image files]]&lt;br /&gt;
# Adhitya Mahajan&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Restrict_checks_for_open.2Fmmaped_filesRestrict checks for open/mmaped files]]&lt;br /&gt;
# Nishchay Agrawal&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Use_eBPF_to_lock_and_unlock_the_network|Use eBPF to lock and unlock the network]]&lt;br /&gt;
# Shivamani Patil&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Porting_crit_functionalities_in_GO|Porting crit functionalities in GO]]&lt;br /&gt;
# Yannis Thomopoulos&lt;br /&gt;
#* Subproject: [[Google_Summer_of_Code_Ideas#Add_support_for_SPFS|Add support for SPFS]]&lt;br /&gt;
&lt;br /&gt;
[[Category:GSoC]]&lt;/div&gt;</summary>
		<author><name>Ptikhomirov</name></author>
	</entry>
</feed>