Compare commits

..

No commits in common. "criu-dev" and "v1.5" have entirely different histories.

2804 changed files with 82277 additions and 245731 deletions

View file

@ -1,44 +0,0 @@
version: 2.1
jobs:
test-local:
machine:
image: default
working_directory: ~/criu
parameters:
compiler:
type: string
shard_index:
type: integer
shard_count:
type: integer
default: 4
steps:
- checkout
- run:
name: "Test local << parameters.compiler >> shard << parameters.shard_index >>"
command: >
sudo -E make -C scripts/ci local << parameters.compiler >>=1
ZDTM_SHARD_INDEX=<< parameters.shard_index >>
ZDTM_SHARD_COUNT=<< parameters.shard_count >>
- run:
name: Print dmesg
when: always
command: sudo dmesg
workflows:
version: 2
builds:
jobs:
- test-local:
matrix:
parameters:
compiler: ["GCC", "CLANG"]
shard_index: [0, 1, 2, 3]
- test-local:
name: "GCC non-zdtm"
compiler: "GCC"
shard_index: 4
- test-local:
name: "CLANG non-zdtm"
compiler: "CLANG"
shard_index: 4

View file

@ -1,565 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
#
# clang-format configuration file. Intended for clang-format >= 11.
#
# For more information, see:
#
# Documentation/process/clang-format.rst
# https://clang.llvm.org/docs/ClangFormat.html
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
#
---
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left # Unknown to clang-format-4.0
AlignOperands: true
AlignTrailingComments: true
AlignConsecutiveMacros: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false # Unknown to clang-format-5.0
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true # Unknown to clang-format-4.0
SplitEmptyRecord: true # Unknown to clang-format-4.0
SplitEmptyNamespace: true # Unknown to clang-format-4.0
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false # Unknown to clang-format-4.0
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false # Unknown to clang-format-4.0
# Taken from:
# git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ \
# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \
# | sort | uniq
ForEachMacros:
- 'for_each_pstree_item'
- 'for_each_bit'
- 'apei_estatus_for_each_section'
- 'ata_for_each_dev'
- 'ata_for_each_link'
- '__ata_qc_for_each'
- 'ata_qc_for_each'
- 'ata_qc_for_each_raw'
- 'ata_qc_for_each_with_internal'
- 'ax25_for_each'
- 'ax25_uid_for_each'
- '__bio_for_each_bvec'
- 'bio_for_each_bvec'
- 'bio_for_each_bvec_all'
- 'bio_for_each_integrity_vec'
- '__bio_for_each_segment'
- 'bio_for_each_segment'
- 'bio_for_each_segment_all'
- 'bio_list_for_each'
- 'bip_for_each_vec'
- 'bitmap_for_each_clear_region'
- 'bitmap_for_each_set_region'
- 'blkg_for_each_descendant_post'
- 'blkg_for_each_descendant_pre'
- 'blk_queue_for_each_rl'
- 'bond_for_each_slave'
- 'bond_for_each_slave_rcu'
- 'bpf_for_each_spilled_reg'
- 'btree_for_each_safe128'
- 'btree_for_each_safe32'
- 'btree_for_each_safe64'
- 'btree_for_each_safel'
- 'card_for_each_dev'
- 'cgroup_taskset_for_each'
- 'cgroup_taskset_for_each_leader'
- 'cpufreq_for_each_entry'
- 'cpufreq_for_each_entry_idx'
- 'cpufreq_for_each_valid_entry'
- 'cpufreq_for_each_valid_entry_idx'
- 'css_for_each_child'
- 'css_for_each_descendant_post'
- 'css_for_each_descendant_pre'
- 'device_for_each_child_node'
- 'displayid_iter_for_each'
- 'dma_fence_chain_for_each'
- 'do_for_each_ftrace_op'
- 'drm_atomic_crtc_for_each_plane'
- 'drm_atomic_crtc_state_for_each_plane'
- 'drm_atomic_crtc_state_for_each_plane_state'
- 'drm_atomic_for_each_plane_damage'
- 'drm_client_for_each_connector_iter'
- 'drm_client_for_each_modeset'
- 'drm_connector_for_each_possible_encoder'
- 'drm_for_each_bridge_in_chain'
- 'drm_for_each_connector_iter'
- 'drm_for_each_crtc'
- 'drm_for_each_crtc_reverse'
- 'drm_for_each_encoder'
- 'drm_for_each_encoder_mask'
- 'drm_for_each_fb'
- 'drm_for_each_legacy_plane'
- 'drm_for_each_plane'
- 'drm_for_each_plane_mask'
- 'drm_for_each_privobj'
- 'drm_mm_for_each_hole'
- 'drm_mm_for_each_node'
- 'drm_mm_for_each_node_in_range'
- 'drm_mm_for_each_node_safe'
- 'flow_action_for_each'
- 'for_each_acpi_dev_match'
- 'for_each_active_dev_scope'
- 'for_each_active_drhd_unit'
- 'for_each_active_iommu'
- 'for_each_aggr_pgid'
- 'for_each_available_child_of_node'
- 'for_each_bio'
- 'for_each_board_func_rsrc'
- 'for_each_bvec'
- 'for_each_card_auxs'
- 'for_each_card_auxs_safe'
- 'for_each_card_components'
- 'for_each_card_dapms'
- 'for_each_card_pre_auxs'
- 'for_each_card_prelinks'
- 'for_each_card_rtds'
- 'for_each_card_rtds_safe'
- 'for_each_card_widgets'
- 'for_each_card_widgets_safe'
- 'for_each_cgroup_storage_type'
- 'for_each_child_of_node'
- 'for_each_clear_bit'
- 'for_each_clear_bit_from'
- 'for_each_cmsghdr'
- 'for_each_compatible_node'
- 'for_each_component_dais'
- 'for_each_component_dais_safe'
- 'for_each_comp_order'
- 'for_each_console'
- 'for_each_cpu'
- 'for_each_cpu_and'
- 'for_each_cpu_not'
- 'for_each_cpu_wrap'
- 'for_each_dapm_widgets'
- 'for_each_dev_addr'
- 'for_each_dev_scope'
- 'for_each_dma_cap_mask'
- 'for_each_dpcm_be'
- 'for_each_dpcm_be_rollback'
- 'for_each_dpcm_be_safe'
- 'for_each_dpcm_fe'
- 'for_each_drhd_unit'
- 'for_each_dss_dev'
- 'for_each_dtpm_table'
- 'for_each_efi_memory_desc'
- 'for_each_efi_memory_desc_in_map'
- 'for_each_element'
- 'for_each_element_extid'
- 'for_each_element_id'
- 'for_each_endpoint_of_node'
- 'for_each_evictable_lru'
- 'for_each_fib6_node_rt_rcu'
- 'for_each_fib6_walker_rt'
- 'for_each_free_mem_pfn_range_in_zone'
- 'for_each_free_mem_pfn_range_in_zone_from'
- 'for_each_free_mem_range'
- 'for_each_free_mem_range_reverse'
- 'for_each_func_rsrc'
- 'for_each_hstate'
- 'for_each_if'
- 'for_each_iommu'
- 'for_each_ip_tunnel_rcu'
- 'for_each_irq_nr'
- 'for_each_link_codecs'
- 'for_each_link_cpus'
- 'for_each_link_platforms'
- 'for_each_lru'
- 'for_each_matching_node'
- 'for_each_matching_node_and_match'
- 'for_each_member'
- 'for_each_memcg_cache_index'
- 'for_each_mem_pfn_range'
- '__for_each_mem_range'
- 'for_each_mem_range'
- '__for_each_mem_range_rev'
- 'for_each_mem_range_rev'
- 'for_each_mem_region'
- 'for_each_migratetype_order'
- 'for_each_msi_entry'
- 'for_each_msi_entry_safe'
- 'for_each_msi_vector'
- 'for_each_net'
- 'for_each_net_continue_reverse'
- 'for_each_netdev'
- 'for_each_netdev_continue'
- 'for_each_netdev_continue_rcu'
- 'for_each_netdev_continue_reverse'
- 'for_each_netdev_feature'
- 'for_each_netdev_in_bond_rcu'
- 'for_each_netdev_rcu'
- 'for_each_netdev_reverse'
- 'for_each_netdev_safe'
- 'for_each_net_rcu'
- 'for_each_new_connector_in_state'
- 'for_each_new_crtc_in_state'
- 'for_each_new_mst_mgr_in_state'
- 'for_each_new_plane_in_state'
- 'for_each_new_private_obj_in_state'
- 'for_each_node'
- 'for_each_node_by_name'
- 'for_each_node_by_type'
- 'for_each_node_mask'
- 'for_each_node_state'
- 'for_each_node_with_cpus'
- 'for_each_node_with_property'
- 'for_each_nonreserved_multicast_dest_pgid'
- 'for_each_of_allnodes'
- 'for_each_of_allnodes_from'
- 'for_each_of_cpu_node'
- 'for_each_of_pci_range'
- 'for_each_old_connector_in_state'
- 'for_each_old_crtc_in_state'
- 'for_each_old_mst_mgr_in_state'
- 'for_each_oldnew_connector_in_state'
- 'for_each_oldnew_crtc_in_state'
- 'for_each_oldnew_mst_mgr_in_state'
- 'for_each_oldnew_plane_in_state'
- 'for_each_oldnew_plane_in_state_reverse'
- 'for_each_oldnew_private_obj_in_state'
- 'for_each_old_plane_in_state'
- 'for_each_old_private_obj_in_state'
- 'for_each_online_cpu'
- 'for_each_online_node'
- 'for_each_online_pgdat'
- 'for_each_pci_bridge'
- 'for_each_pci_dev'
- 'for_each_pci_msi_entry'
- 'for_each_pcm_streams'
- 'for_each_physmem_range'
- 'for_each_populated_zone'
- 'for_each_possible_cpu'
- 'for_each_present_cpu'
- 'for_each_prime_number'
- 'for_each_prime_number_from'
- 'for_each_process'
- 'for_each_process_thread'
- 'for_each_prop_codec_conf'
- 'for_each_prop_dai_codec'
- 'for_each_prop_dai_cpu'
- 'for_each_prop_dlc_codecs'
- 'for_each_prop_dlc_cpus'
- 'for_each_prop_dlc_platforms'
- 'for_each_property_of_node'
- 'for_each_registered_fb'
- 'for_each_requested_gpio'
- 'for_each_requested_gpio_in_range'
- 'for_each_reserved_mem_range'
- 'for_each_reserved_mem_region'
- 'for_each_rtd_codec_dais'
- 'for_each_rtd_components'
- 'for_each_rtd_cpu_dais'
- 'for_each_rtd_dais'
- 'for_each_set_bit'
- 'for_each_set_bit_from'
- 'for_each_set_clump8'
- 'for_each_sg'
- 'for_each_sg_dma_page'
- 'for_each_sg_page'
- 'for_each_sgtable_dma_page'
- 'for_each_sgtable_dma_sg'
- 'for_each_sgtable_page'
- 'for_each_sgtable_sg'
- 'for_each_sibling_event'
- 'for_each_subelement'
- 'for_each_subelement_extid'
- 'for_each_subelement_id'
- '__for_each_thread'
- 'for_each_thread'
- 'for_each_unicast_dest_pgid'
- 'for_each_vsi'
- 'for_each_wakeup_source'
- 'for_each_zone'
- 'for_each_zone_zonelist'
- 'for_each_zone_zonelist_nodemask'
- 'fwnode_for_each_available_child_node'
- 'fwnode_for_each_child_node'
- 'fwnode_graph_for_each_endpoint'
- 'gadget_for_each_ep'
- 'genradix_for_each'
- 'genradix_for_each_from'
- 'hash_for_each'
- 'hash_for_each_possible'
- 'hash_for_each_possible_rcu'
- 'hash_for_each_possible_rcu_notrace'
- 'hash_for_each_possible_safe'
- 'hash_for_each_rcu'
- 'hash_for_each_safe'
- 'hctx_for_each_ctx'
- 'hlist_bl_for_each_entry'
- 'hlist_bl_for_each_entry_rcu'
- 'hlist_bl_for_each_entry_safe'
- 'hlist_for_each'
- 'hlist_for_each_entry'
- 'hlist_for_each_entry_continue'
- 'hlist_for_each_entry_continue_rcu'
- 'hlist_for_each_entry_continue_rcu_bh'
- 'hlist_for_each_entry_from'
- 'hlist_for_each_entry_from_rcu'
- 'hlist_for_each_entry_rcu'
- 'hlist_for_each_entry_rcu_bh'
- 'hlist_for_each_entry_rcu_notrace'
- 'hlist_for_each_entry_safe'
- 'hlist_for_each_entry_srcu'
- '__hlist_for_each_rcu'
- 'hlist_for_each_safe'
- 'hlist_nulls_for_each_entry'
- 'hlist_nulls_for_each_entry_from'
- 'hlist_nulls_for_each_entry_rcu'
- 'hlist_nulls_for_each_entry_safe'
- 'i3c_bus_for_each_i2cdev'
- 'i3c_bus_for_each_i3cdev'
- 'ide_host_for_each_port'
- 'ide_port_for_each_dev'
- 'ide_port_for_each_present_dev'
- 'idr_for_each_entry'
- 'idr_for_each_entry_continue'
- 'idr_for_each_entry_continue_ul'
- 'idr_for_each_entry_ul'
- 'in_dev_for_each_ifa_rcu'
- 'in_dev_for_each_ifa_rtnl'
- 'inet_bind_bucket_for_each'
- 'inet_lhash2_for_each_icsk_rcu'
- 'key_for_each'
- 'key_for_each_safe'
- 'klp_for_each_func'
- 'klp_for_each_func_safe'
- 'klp_for_each_func_static'
- 'klp_for_each_object'
- 'klp_for_each_object_safe'
- 'klp_for_each_object_static'
- 'kunit_suite_for_each_test_case'
- 'kvm_for_each_memslot'
- 'kvm_for_each_vcpu'
- 'list_for_each'
- 'list_for_each_codec'
- 'list_for_each_codec_safe'
- 'list_for_each_continue'
- 'list_for_each_entry'
- 'list_for_each_entry_continue'
- 'list_for_each_entry_continue_rcu'
- 'list_for_each_entry_continue_reverse'
- 'list_for_each_entry_from'
- 'list_for_each_entry_from_rcu'
- 'list_for_each_entry_from_reverse'
- 'list_for_each_entry_lockless'
- 'list_for_each_entry_rcu'
- 'list_for_each_entry_reverse'
- 'list_for_each_entry_safe'
- 'list_for_each_entry_safe_continue'
- 'list_for_each_entry_safe_from'
- 'list_for_each_entry_safe_reverse'
- 'list_for_each_entry_srcu'
- 'list_for_each_prev'
- 'list_for_each_prev_safe'
- 'list_for_each_safe'
- 'llist_for_each'
- 'llist_for_each_entry'
- 'llist_for_each_entry_safe'
- 'llist_for_each_safe'
- 'mci_for_each_dimm'
- 'media_device_for_each_entity'
- 'media_device_for_each_intf'
- 'media_device_for_each_link'
- 'media_device_for_each_pad'
- 'nanddev_io_for_each_page'
- 'netdev_for_each_lower_dev'
- 'netdev_for_each_lower_private'
- 'netdev_for_each_lower_private_rcu'
- 'netdev_for_each_mc_addr'
- 'netdev_for_each_uc_addr'
- 'netdev_for_each_upper_dev_rcu'
- 'netdev_hw_addr_list_for_each'
- 'nft_rule_for_each_expr'
- 'nla_for_each_attr'
- 'nla_for_each_nested'
- 'nlmsg_for_each_attr'
- 'nlmsg_for_each_msg'
- 'nr_neigh_for_each'
- 'nr_neigh_for_each_safe'
- 'nr_node_for_each'
- 'nr_node_for_each_safe'
- 'of_for_each_phandle'
- 'of_property_for_each_string'
- 'of_property_for_each_u32'
- 'pci_bus_for_each_resource'
- 'pcl_for_each_chunk'
- 'pcl_for_each_segment'
- 'pcm_for_each_format'
- 'ping_portaddr_for_each_entry'
- 'plist_for_each'
- 'plist_for_each_continue'
- 'plist_for_each_entry'
- 'plist_for_each_entry_continue'
- 'plist_for_each_entry_safe'
- 'plist_for_each_safe'
- 'pnp_for_each_card'
- 'pnp_for_each_dev'
- 'protocol_for_each_card'
- 'protocol_for_each_dev'
- 'queue_for_each_hw_ctx'
- 'radix_tree_for_each_slot'
- 'radix_tree_for_each_tagged'
- 'rb_for_each'
- 'rbtree_postorder_for_each_entry_safe'
- 'rdma_for_each_block'
- 'rdma_for_each_port'
- 'rdma_umem_for_each_dma_block'
- 'resource_list_for_each_entry'
- 'resource_list_for_each_entry_safe'
- 'rhl_for_each_entry_rcu'
- 'rhl_for_each_rcu'
- 'rht_for_each'
- 'rht_for_each_entry'
- 'rht_for_each_entry_from'
- 'rht_for_each_entry_rcu'
- 'rht_for_each_entry_rcu_from'
- 'rht_for_each_entry_safe'
- 'rht_for_each_from'
- 'rht_for_each_rcu'
- 'rht_for_each_rcu_from'
- '__rq_for_each_bio'
- 'rq_for_each_bvec'
- 'rq_for_each_segment'
- 'scsi_for_each_prot_sg'
- 'scsi_for_each_sg'
- 'sctp_for_each_hentry'
- 'sctp_skb_for_each'
- 'shdma_for_each_chan'
- '__shost_for_each_device'
- 'shost_for_each_device'
- 'sk_for_each'
- 'sk_for_each_bound'
- 'sk_for_each_entry_offset_rcu'
- 'sk_for_each_from'
- 'sk_for_each_rcu'
- 'sk_for_each_safe'
- 'sk_nulls_for_each'
- 'sk_nulls_for_each_from'
- 'sk_nulls_for_each_rcu'
- 'snd_array_for_each'
- 'snd_pcm_group_for_each_entry'
- 'snd_soc_dapm_widget_for_each_path'
- 'snd_soc_dapm_widget_for_each_path_safe'
- 'snd_soc_dapm_widget_for_each_sink_path'
- 'snd_soc_dapm_widget_for_each_source_path'
- 'tb_property_for_each'
- 'tcf_exts_for_each_action'
- 'udp_portaddr_for_each_entry'
- 'udp_portaddr_for_each_entry_rcu'
- 'usb_hub_for_each_child'
- 'v4l2_device_for_each_subdev'
- 'v4l2_m2m_for_each_dst_buf'
- 'v4l2_m2m_for_each_dst_buf_safe'
- 'v4l2_m2m_for_each_src_buf'
- 'v4l2_m2m_for_each_src_buf_safe'
- 'virtio_device_for_each_vq'
- 'while_for_each_ftrace_op'
- 'xa_for_each'
- 'xa_for_each_marked'
- 'xa_for_each_range'
- 'xa_for_each_start'
- 'xas_for_each'
- 'xas_for_each_conflict'
- 'xas_for_each_marked'
- 'xbc_array_for_each_value'
- 'xbc_for_each_key_value'
- 'xbc_node_for_each_array_value'
- 'xbc_node_for_each_child'
- 'xbc_node_for_each_key_value'
- 'zorro_for_each_dev'
IncludeBlocks: Preserve # Unknown to clang-format-5.0
IncludeCategories:
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentGotoLabels: false
IndentPPDirectives: None # Unknown to clang-format-5.0
IndentWidth: 8
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0
ObjCBlockIndentWidth: 8
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
# Taken from git's rules
PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0
PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 0
PenaltyBreakString: 10
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: false # Unknown to clang-format-4.0
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0
SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0
SpaceBeforeParens: ControlStatementsExceptForEachMacros
SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp03
TabWidth: 8
UseTab: Always
...

View file

@ -1,3 +0,0 @@
[codespell]
skip = ./.git,./test/pki,./tags,./plugins/amdgpu/amdgpu_drm.h,./plugins/amdgpu/drm.h,./plugins/amdgpu/drm_mode.h
ignore-words-list = creat,fpr,fle,ue,bord,parms,nd,te,testng,inh,wronly,renderd,bui,clen,sems

View file

@ -1,63 +0,0 @@
<!--
Before reporting a new issue, please make sure that it's not a duplicate.
If you suspect your issue is a bug, please provide information as shown below. If your issue is a feature request, this information is not always necessary.
-->
**Description**
<!--
Briefly describe the problem you are having in a few paragraphs.
-->
**Steps to reproduce the issue:**
1.
2.
3.
**Describe the results you received:**
**Describe the results you expected:**
**Additional information you deem important (e.g. issue happens only occasionally):**
**CRIU logs and information:**
<!--
You can either attach logs as files to the issue or put them under details
-->
<details><summary>CRIU full dump/restore logs:</summary>
<p>
```
(paste your output here)
```
</p>
</details>
<details><summary>Output of `criu --version`:</summary>
<p>
```
(paste your output here)
```
</p>
</details>
<details><summary>Output of `criu check --all`:</summary>
<p>
```
(paste your output here)
```
</p>
</details>
**Additional environment details:**

View file

@ -1,18 +0,0 @@
<!--
Please make sure you've read and understood our contributing guidelines:
https://github.com/checkpoint-restore/criu/blob/criu-dev/CONTRIBUTING.md
In short you need to:
- Describe What you do and How you do it;
- Separate each logical change into a separate commit;
- Add a "Signed-off-by:" line identifying that you certify your work with DCO;
- If you fix some specific bug or commit, please add "Fixes: ..." line;
- Review fixes should be made by amending the original commits. For example:
a) fix the code (e.g. this fixes commit with hash aaa1111)
b) git commit -a --fixup aaa1111
c) git rebase --interactive --autosquash aaa1111^
- Pull request integration tests should generally be passing;
- If you change something non-obvious, please consider adding a ZDTM test for it;
-->

View file

@ -1,35 +0,0 @@
name: 'Lima VM Setup'
description: 'Install Lima, enable KVM, start a VM and copy the CRIU source into it'
inputs:
template:
description: 'Lima VM template name (e.g. fedora, centos-stream-9)'
required: true
cache-key-prefix:
description: 'Prefix for the Lima image cache key'
required: true
runs:
using: composite
steps:
- name: Install Lima
uses: lima-vm/lima-actions/setup@55627e31b78637bf254a8b2a14da8ea7d12564e5 # v1
- name: Cache Lima images
uses: actions/cache@v6
with:
path: ~/.cache/lima
key: ${{ inputs.cache-key-prefix }}-${{ github.sha }}
restore-keys: ${{ inputs.cache-key-prefix }}-
- name: Start VM
shell: bash
# Enable VNC display so QEMU attaches a VGA device instead of
# passing -vga none. Without it the kernel only registers a CGA
# text console and VT ioctls (TIOCSLCKTRMIOS, TIOCSWINSZ) fail,
# which breaks the zdtm/static/vt test on restore.
run: limactl start --plain --name=default --cpus=4 --memory=12 --set '.video.display = "vnc"' template://${{ inputs.template }}
- name: Copy source into VM
shell: bash
run: |
lima sudo mkdir -p /home/criu
lima sudo chown "$(lima whoami)" /home/criu
limactl copy -r . default:/home/criu

View file

@ -1,95 +0,0 @@
# GitHub Copilot Instructions for CRIU
CRIU (Checkpoint/Restore In User-space) is a specialized tool for checkpointing
and restoring running processes on Linux.
## Coding Style & Conventions
All C code MUST follow the [Linux Kernel Coding Style](https://www.kernel.org/doc/html/latest/process/coding-style.html).
- **Indentation**: Use hard tabs. Set tab width to 8 characters.
- **Line Length**: Preferred limit is 80 characters. Max 120 if it
significantly improves readability.
- **Braces**:
- Functions: Opening brace on a new line.
- Blocks (`if`, `for`, `while`, `switch`): Opening brace on the same line as
the statement.
- **Spaces**: Use spaces around operators (`+`, `-`, `*`, `/`, `%`, `<`, `>`,
`=`, etc.).
- **Naming**: Use descriptive, snake_case names for functions and variables.
- **Comments**: Use C-style comments (`/* ... */`).
- Multi-line format:
```c
/*
* This is a multi-line
* comment.
*/
```
## Architecture Overview
- **criu/**: Contains the main logic for checkpoint and restore.
- **compel/**: Sub-project for "parasite" code injection and PIE blob
generation.
- **images/**: Protobuf descriptions for image files. Use these to understand
the state being saved.
- **restorer**: PIE code that handles the final stages of process restoration.
See `criu/include/restorer.h` for `CR_STATE_*` definitions.
- **crit**: Tooling for inspecting CRIU image files.
- **soccr**: Library for TCP socket checkpoint/restore.
- **pie/ directories**: Code in these directories (e.g., `criu/pie/`) should be
self-contained Position-Independent Executable (PIE) code. It MUST NOT
depend on any external libraries and can only depend on things implemented by
Compel.
### CRIU Commands
- **dump**: Saves a process tree and all its related resources into a
collection of image files.
- **restore**: Restores processes from image files to the same state they were
in before the dump.
- **check**: Checks whether the kernel supports the features needed by CRIU to
dump and restore a process tree.
- **pre-dump**: Performs the pre-dump procedure, creating a snapshot of memory
changes since the previous dump/pre-dump (incremental checkpointing).
- **service**: Launches CRIU in RPC daemon mode, listening for commands over a
socket.
- **dedup**: Starts pagemap data deduplication, minimizing image size by
obtaining references from parent images.
- **page-server**: Launches CRIU in page server mode to send memory pages over
the network during migration.
## Development & Testing
- **ZDTM (Zero-Downtime Migration)**: The primary test suite located in
`test/zdtm`.
- **Test Scope**: Each test case targets a specific kernel primitive type
(e.g., file descriptors, sockets, timers).
- **Test Purpose**: Verifies that the targeted kernel primitive is
Checkpointed/Restored (C/R-ed) correctly.
- **Test Executor**: `test/zdtm.py`.
- **Running a test**: `sudo ./test/zdtm.py run -t zdtm/static/env00`.
- **Test Structure**: Tests typically use `test_daemon()` to signal readiness
and `test_waitsig()` to wait for the C/R cycle to complete. After being
restored, the test checks that all its resources are still in a valid state.
## Commit Message Guidelines
Follow these principles when forming commits:
- **Separate each logical change into a separate patch**: Each commit must
represent a single logical change. Separate bug fixes from performance
improvements or API updates.
- **The commit subject has to start with the sub-system prefix**: Prefix the
subject with the affected component (e.g., `criu:`, `compel:`, `images:`,
`test:`, or specific file names like `criu-ns:`).
- **Imperative Mood**: Use the imperative mood in the subject (e.g., "make
xyzzy do frotz" instead of "changed xyzzy").
- **Detailed Body**: Explain the problem being solved (the "why") and the
technical details of the implementation (the "how").
- **Hard Wrap**: The commit message has to be hard wrapped at 72 characters.
- **Signed-off-by**: Every commit MUST be signed off (`git commit -s`). This
certifies the Developer's Certificate of Origin (DCO).
- **Fixes Tag**:
- For bugs: `Fixes: <12-char-commit-id> ("summary")`. The `<commit-id>` has
to be the first 12 characters of the commit SHA-1 ID.
- For GitHub issues: `Fixes: #<issue-number>`
- **Atomicity**: Ensure CRIU builds and tests pass after *every* commit in a
series to maintain bisectability.
- **No Fixups**: Squash "fixup!" or "work in progress" commits before final
submission.

View file

@ -1,35 +0,0 @@
name: Verify self-contained commits
on: pull_request
# Cancel any preceding run on the pull request
concurrency:
group: commit-test-${{ github.event.pull_request.number }}
jobs:
build:
runs-on: ubuntu-latest
# Check if pull request does not have label "not-selfcontained-ok"
if: "!contains(github.event.pull_request.labels.*.name, 'not-selfcontained-ok')"
steps:
- uses: actions/checkout@v7
with:
# Needed to rebase against the base branch
fetch-depth: 0
# Checkout pull request HEAD commit instead of merge commit
ref: ${{ github.event.pull_request.head.sha }}
- name: Install dependencies
run: sudo contrib/apt-install libprotobuf-dev libprotobuf-c-dev protobuf-c-compiler protobuf-compiler python3-protobuf libnl-3-dev libnet-dev libcap-dev uuid-dev liblz4-dev
- name: Configure git user details
run: |
git config --global user.email "checkpoint-restore@users.noreply.github.com"
git config --global user.name "checkpoint-restore"
- name: Configure base branch without switching current branch
run: git fetch origin ${{ github.base_ref }}:${{ github.base_ref }}
- name: Build each commit
run: git rebase ${{ github.base_ref }} -x "make -C scripts/ci check-commit"
- name: Build without LZ4
run: |
make mrproper
make -j "$(nproc)" NO_LZ4=1
make unittest NO_LZ4=1

View file

@ -1,367 +0,0 @@
name: CI
on: [push, pull_request]
# Cancel any preceding run on the pull request.
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/criu-dev' }}
jobs:
alpine-test:
name: Alpine Test (${{ matrix.target }}, ${{ matrix.shard_name }})
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04]
target: [GCC=1, CLANG=1]
shard: [0, 1, 2, 3, 4]
include:
- shard: 0
shard_name: zdtm 1/4
- shard: 1
shard_name: zdtm 2/4
- shard: 2
shard_name: zdtm 3/4
- shard: 3
shard_name: zdtm 4/4
- shard: 4
shard_name: non-zdtm
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- name: Run Alpine ${{ matrix.target }} ${{ matrix.shard_name }} Test
run: >
sudo -E make -C scripts/ci alpine ${{ matrix.target }}
ZDTM_SHARD_INDEX=${{ matrix.shard }}
ZDTM_SHARD_COUNT=4
- name: Print dmesg
if: always()
run: sudo dmesg
alpine-test-arm64:
name: Alpine Test ARM64
needs: [alpine-test]
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04-arm]
target: [GCC=1, CLANG=1]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- name: Run Alpine ${{ matrix.target }} Test
run: sudo -E make -C scripts/ci alpine ${{ matrix.target }}
- name: Print dmesg
if: always()
run: sudo dmesg
aarch64-test:
needs: [alpine-test]
strategy:
fail-fast: false
matrix:
os: [ubuntu-26.04-arm, ubuntu-22.04-arm]
target: [GCC=1, CLANG=1]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- name: Run Tests ${{ matrix.target }} on ${{ matrix.os }}
run: |
# The 'sched_policy00' needs the following:
sudo sysctl -w kernel.sched_rt_runtime_us=-1
# etc/hosts entry is needed for netns_lock_iptables
echo "127.0.0.1 localhost" | sudo tee -a /etc/hosts
sudo -E make -C scripts/ci local ${{ matrix.target }} RUN_TESTS=1 \
ZDTM_OPTS="-x zdtm/static/change_mnt_context -x zdtm/static/maps05"
- name: Print dmesg
if: always()
run: sudo dmesg
archlinux-test:
name: Arch Linux Test (${{ matrix.shard_name }})
needs: [alpine-test]
# archlinux:latest + pacman -Syu is a rolling-release build; failures
# caused by upstream package churn are outside CRIU's control.
continue-on-error: true
strategy:
fail-fast: false
matrix:
shard: [0, 1, 2, 3, 4]
include:
- shard: 0
shard_name: zdtm 1/4
- shard: 1
shard_name: zdtm 2/4
- shard: 2
shard_name: zdtm 3/4
- shard: 3
shard_name: zdtm 4/4
- shard: 4
shard_name: non-zdtm
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Run Arch Linux ${{ matrix.shard_name }} Test
run: >
sudo -E make -C scripts/ci archlinux
ZDTM_SHARD_INDEX=${{ matrix.shard }}
ZDTM_SHARD_COUNT=4
- name: Print dmesg
if: always()
run: sudo dmesg
centos-stream-test:
name: CentOS Stream ${{ matrix.version }}
# aarch64 is not supported by lima-vm/lima-actions
# https://github.com/lima-vm/lima-actions/pull/1
needs: [alpine-test]
runs-on: ubuntu-24.04
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
version: [9, 10]
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/lima-vm-setup
with:
template: centos-stream-${{ matrix.version }}
cache-key-prefix: lima-centos-stream-${{ matrix.version }}
- name: Setup VM
run: lima sudo /home/criu/scripts/ci/lima.sh centos-stream-setup
- name: Show VM info
run: |
lima uname -a
lima cat /proc/cmdline
- name: Run tests
run: ssh -tt lima-default sudo -i /home/criu/scripts/ci/lima.sh centos-stream-test
- name: Print dmesg
if: always()
run: lima sudo dmesg
compat-test:
needs: [alpine-test]
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
target: [GCC, CLANG]
steps:
- uses: actions/checkout@v7
- name: Run Compat Tests (${{ matrix.target }})
run: sudo -E make -C scripts/ci local COMPAT_TEST=y ${{ matrix.target }}=1
- name: Print dmesg
if: always()
run: sudo dmesg
cross-compile:
needs: [alpine-test]
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
experimental: [false]
target: [
armv7-stable-cross,
aarch64-stable-cross,
ppc64-stable-cross,
riscv64-stable-cross,
]
include:
- experimental: true
target: armv7-unstable-cross
- experimental: true
target: aarch64-unstable-cross
- experimental: true
target: ppc64-unstable-cross
steps:
- uses: actions/checkout@v7
- name: Run Cross Compilation Targets
run: >
sudo make -C scripts/ci ${{ matrix.target }}
BUILD_OPTIONS="--build-arg CI_CROSS_COMPILE=1"
docker-test:
needs: [alpine-test]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04]
steps:
- uses: actions/checkout@v7
- name: Run Docker Test (${{ matrix.os }})
run: sudo make -C scripts/ci docker-test
fedora-asan-test:
needs: [alpine-test]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Run Fedora ASAN Test
run: sudo -E make -C scripts/ci fedora-asan
- name: Print dmesg
if: always()
run: sudo dmesg
fedora-rawhide-test:
name: ${{ matrix.name }}
needs: [alpine-test]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
name: x86_64 Fedora Rawhide
- os: ubuntu-24.04-arm
name: aarch64 Fedora Rawhide
steps:
- uses: actions/checkout@v7
- name: Run Fedora Rawhide Test
# We need to pass environment variables from the CI environment to
# distinguish between CI environments. However, we need to make sure that
# XDG_RUNTIME_DIR environment variable is not set due to a bug in Podman.
# FIXME: https://github.com/containers/podman/issues/14920
run: sudo -E XDG_RUNTIME_DIR= make -C scripts/ci fedora-rawhide CONTAINER_RUNTIME=podman BUILD_OPTIONS="--security-opt seccomp=unconfined"
- name: Print dmesg
if: always()
run: sudo dmesg
vm-fedora-rawhide-test:
name: VM Fedora ${{ matrix.name }} based test
needs: [alpine-test]
runs-on: ubuntu-24.04
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- variant: fedora-stable
name: Stable
reboot: true
- variant: fedora-next
name: Next
reboot: true
- variant: fedora-no-vdso
name: No VDSO
reboot: true
- variant: fedora-non-root
name: Non-Root
reboot: false
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/lima-vm-setup
with:
template: fedora
cache-key-prefix: lima-fedora
- name: Setup VM
run: lima sudo /home/criu/scripts/ci/lima.sh ${{ matrix.variant }}-setup
- name: Reboot VM to activate new kernel
if: matrix.reboot
run: |
limactl stop default
limactl start default
- name: Show VM info
run: |
lima uname -a
lima cat /proc/cmdline
- name: Run tests
run: ssh -tt lima-default sudo -i /home/criu/scripts/ci/lima.sh ${{ matrix.variant }}-test
- name: Print dmesg
if: always()
run: lima sudo dmesg
gcov-test:
needs: [alpine-test]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Run Coverage Tests
run: sudo -E make -C scripts/ci local GCOV=1
- name: Run gcov
run: sudo -E find . -name '*gcda' -type f -print0 | sudo -E xargs --null --max-args 128 gcov
- name: Upload coverage to Codecov
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Print dmesg
if: always()
run: sudo dmesg
java-test:
needs: [alpine-test]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Run Java Test
run: sudo make -C scripts/ci java-test
loongarch64-qemu-test:
needs: [alpine-test]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- run: sudo make -C scripts/ci loongarch64-qemu-test
nftables-test:
needs: [alpine-test]
runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@v7
- name: Remove iptables
run: sudo apt remove -y iptables
- name: Install libnftables-dev
run: sudo contrib/apt-install libnftables-dev
- name: chmod 755 /home/runner
# CRIU's tests are sometimes running as some random user and need
# to be able to access the test files.
run: sudo chmod 755 /home/runner
- name: Build with nftables network locking backend
run: sudo make -C scripts/ci local COMPILE_FLAGS="NETWORK_LOCK_DEFAULT=NETWORK_LOCK_NFTABLES"
- name: Print dmesg
if: always()
run: sudo dmesg
podman-test:
needs: [alpine-test]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Run Podman Test
run: sudo make -C scripts/ci podman-test
stream-test:
needs: [alpine-test]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Run CRIU Image Streamer Test
run: sudo -E make -C scripts/ci local STREAM_TEST=1
- name: Print dmesg
if: always()
run: sudo dmesg
x86-64-clang-test:
needs: [alpine-test]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Run X86_64 CLANG Test
run: sudo make -C scripts/ci x86_64 CLANG=1
- name: Print dmesg
if: always()
run: sudo dmesg
x86-64-gcc-test:
needs: [alpine-test]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Run X86_64 GCC Test
run: sudo make -C scripts/ci x86_64
- name: Print dmesg
if: always()
run: sudo dmesg

View file

@ -1,50 +0,0 @@
name: "CodeQL"
on:
push:
branches: [ "criu-dev", "master" ]
pull_request:
branches: [ "criu-dev" ]
schedule:
- cron: "11 6 * * 3"
# Cancel any preceding run on the pull request.
concurrency:
group: codeql-test-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/criu-dev' }}
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ python, cpp ]
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install Packages (cpp)
if: ${{ matrix.language == 'cpp' }}
run: |
sudo contrib/apt-install protobuf-c-compiler libprotobuf-c-dev libprotobuf-dev build-essential libprotobuf-dev libprotobuf-c-dev protobuf-c-compiler protobuf-compiler python3-protobuf libnet-dev pkg-config libnl-3-dev libbsd0 libbsd-dev iproute2 libcap-dev libaio-dev libbsd-dev python3-yaml libnl-route-3-dev gnutls-dev
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ matrix.language }}"

View file

@ -1,22 +0,0 @@
name: Daily Cross Compile Tests
on:
schedule:
- cron: '30 12 * * *'
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
target: [armv7-stable-cross, aarch64-stable-cross, ppc64-stable-cross, mips64el-stable-cross, riscv64-stable-cross]
branches: [criu-dev, master]
steps:
- uses: actions/checkout@v7
with:
ref: ${{ matrix.branches }}
- name: Run Cross Compilation Targets
run: >
sudo make -C scripts/ci ${{ matrix.target }}

View file

@ -1,40 +0,0 @@
name: Run code linter
on: [push, pull_request]
# Cancel any preceding run on the pull request.
concurrency:
group: lint-test-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/criu-dev' }}
jobs:
build:
runs-on: ubuntu-latest
container:
image: registry.fedoraproject.org/fedora:latest
steps:
- name: Install tools
run: sudo dnf -y install git make ruff xz clang-tools-extra codespell git-clang-format ShellCheck
- uses: actions/checkout@v7
- name: Set git safe directory
# https://github.com/actions/checkout/issues/760
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Run make lint
run: make lint
- name: Run make indent
continue-on-error: true
run: |
if [ -z "${{github.base_ref}}" ]; then
git fetch --deepen=1
make indent
else
git fetch origin ${{github.base_ref}}
make indent BASE=origin/${{github.base_ref}}
fi
- name: Raise in-line make indent warnings
run: |
git diff | ./scripts/github-indent-warnings.py

View file

@ -1,402 +0,0 @@
name: linux-next-tests
on:
schedule:
- cron: "20 8 * * 0"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
#
# This workflow is to test CRIU on linux-next tree.
# It involves external GitHub Actions runners (EC2 instances on AWS).
# To run it requires necessary setup on AWS side (auth via GitHub OIDC to
# manage EC2 instances and S3 bucket), and GH_RUNNERS_PAT_TOKEN
# (GitHub Personal Access Token to manage GitHub Actions Runners for a repo).
#
# Logic is simple:
# 1. Build linux kernel on GitHub-hosted runner and upload .deb-packages
# to S3 bucket
# 2. Create EC2 instance and register it as GH self-hosted runner
# (we use machulav/ec2-github-runner for this)
# 3. Schedule a job on newly created runner, install a new kernel
# 4. Reboot EC2 instance
# 5. Schedule CRIU test job on EC2 runner
# 6. Destroy EC2 instance and unregister it from GitHub.
#
# I use explicit commit hashes for actions steps which are not GitHub-provided
# (for example machulav/ec2-github-runner@343a1b2ae682e681c3cec9a235d882da17ff04ef).
# This is to be on a safe side and ensure that any update is done manually.
#
permissions:
id-token: write
jobs:
kernel-build:
env:
BUILDDIR: "/home/runner/kernel-build/tmp"
name: Kernel build
runs-on: ubuntu-24.04
outputs:
date: ${{ steps.get-date.outputs.date }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Prepare directory for build
run: |
set -eux
echo $BUILDDIR
mkdir -p $BUILDDIR
# Not enough RAM for kernel builds anymore
# sudo mount -t tmpfs tmpfs $BUILDDIR
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
- name: Restore linux-next build artifacts from cache
id: build-artifacts-restore
uses: actions/cache@v5
with:
path: ${{ env.BUILDDIR }}/artifacts
key: linux-next-build-${{ steps.get-date.outputs.date }}
- name: Install dependencies
if: steps.build-artifacts-restore.outputs.cache-hit != 'true'
run: |
set -eux
sudo apt-get update
sudo apt-get install --no-install-recommends -y \
curl \
git \
build-essential \
libssl-dev \
libelf-dev \
libdw-dev \
bc \
bison \
cpio \
flex \
debhelper-compat
# We don't want to put too much stress to git.kernel.org so we
# use a cache (valid for 1 day) for git clone copy of the repo.
- name: Restore linux-next git cache
if: steps.build-artifacts-restore.outputs.cache-hit != 'true'
id: linux-next-git-restore
uses: actions/cache@v5
with:
path: ${{ env.BUILDDIR }}/linux
key: linux-next-git-cache-${{ steps.get-date.outputs.date }}
- name: Checkout Linux kernel
if: ${{ steps.build-artifacts-restore.outputs.cache-hit != 'true' &&
steps.linux-next-git-restore.outputs.cache-hit != 'true' }}
run: |
set -eux
cd "$BUILDDIR"
git clone --depth=1 --branch master --single-branch \
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git linux
# Record exactly which linux-next state we built, so a CI failure
# can be correlated with a specific tree (and its daily next-* tag).
git -C linux --no-pager log -1 --format='linux-next HEAD: %H %cs %s'
- name: Save linux-next git cache
if: ${{ steps.build-artifacts-restore.outputs.cache-hit != 'true' &&
steps.linux-next-git-restore.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v5
with:
path: |
${{ env.BUILDDIR }}/linux
key: linux-next-git-cache-${{ steps.get-date.outputs.date }}
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@254c19bd240aabef8777f48595e9d2d7b972184b # 6.2.1
with:
role-to-assume: ${{ vars.AWS_IAM_ROLE }}
aws-region: ${{ vars.AWS_REGION }}
- name: Build Linux kernel
if: steps.build-artifacts-restore.outputs.cache-hit != 'true'
run: |
set -eux
cd "$BUILDDIR/linux"
# kernel config was generated with make localmodconfig on EC2 instance
# after full CRIU tests run (to trigger all modules load)
aws s3 cp \
s3://criu-linux-next-ci-634567146514-eu-central-1-an/t3.xlarge-kernel-config \
.config
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS
make olddefconfig
time make -j$(nproc) bindeb-pkg LOCALVERSION="-criu-ci"
ls -la .
ls -la ..
cd "$BUILDDIR"
mkdir artifacts/
mv linux-*.deb artifacts/
echo "artifactPath=${BUILDDIR}/artifacts" >> $GITHUB_ENV
- name: Save linux-next build results cache
if: steps.build-artifacts-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v5
with:
path: ${{ env.artifactPath }}
key: linux-next-build-${{ steps.get-date.outputs.date }}
- name: Upload kernel packages to S3
run: |
set -eux
cd "$BUILDDIR"
BUILD_DATE="${{ steps.get-date.outputs.date }}"
aws s3 cp \
artifacts \
s3://criu-linux-next-ci-634567146514-eu-central-1-an/artifacts/$BUILD_DATE/ \
--recursive
- uses: actions/upload-artifact@v7
with:
name: linux-kernel-build
path: ${{ env.BUILDDIR }}/artifacts/linux-*.deb
if-no-files-found: error
retention-days: 14
start-runner:
name: Start self-hosted EC2 runner
needs:
- kernel-build
runs-on: ubuntu-latest
outputs:
label: ${{ steps.start-ec2-runner.outputs.label }}
ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }}
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@254c19bd240aabef8777f48595e9d2d7b972184b # 6.2.1
with:
role-to-assume: ${{ vars.AWS_IAM_ROLE }}
aws-region: ${{ vars.AWS_REGION }}
- name: Start EC2 runner
id: start-ec2-runner
uses: machulav/ec2-github-runner@343a1b2ae682e681c3cec9a235d882da17ff04ef # 2.6.1
with:
mode: start
startup-timeout-minutes: 10
github-token: ${{ secrets.GH_RUNNERS_PAT_TOKEN }}
ec2-image-id: ami-0596cf3199908321b # Ubuntu 24.04 LTS image id on AWS
ec2-instance-type: t3.xlarge
subnet-id: subnet-0ddb356c3fc41e51a
security-group-id: sg-054aa948984162822
packages: '["git", "docker.io"]'
runner-debug: true
# we need this so GitHub runner software survives EC2 reboot
run-runner-as-service: true
# we need this to make EC2 runner capable of accessing S3 bucket with kernel builds
iam-role-name: ec2-linux-next-vm
aws-resource-tags: > # attach tags to distinguish GH Actions instances on AWS
[
{"Key": "Name", "Value": "ec2-github-runner"},
{"Key": "GitHubRepository", "Value": "${{ github.repository }}"},
{"Key": "GitHubRunId", "Value": "${{ github.run_id }}"}
]
install-kernel:
name: Install kernel on the EC2 runner
needs:
- kernel-build
- start-runner # required to start the main job when the runner is ready
runs-on: ${{ needs.start-runner.outputs.label }} # run the job on the newly created runner
timeout-minutes: 15
steps:
- name: Install unzip
run: |
set -eux
sudo apt-get update
sudo apt-get install --no-install-recommends -y \
unzip
- name: Install AWS CLI
run: |
set -eux
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install --update
- name: Install linux-next kernel
run: |
set -eux
BUILD_DATE="${{ needs.kernel-build.outputs.date }}"
aws s3 cp \
s3://criu-linux-next-ci-634567146514-eu-central-1-an/artifacts/$BUILD_DATE/ \
artifacts \
--recursive
ls -la artifacts
sudo dpkg -i artifacts/linux-image-*-criu-ci_*_amd64.deb
reboot-runner:
name: Reboot EC2 runner instance
needs:
- start-runner
- install-kernel # required to start the main job when the runner is ready
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@254c19bd240aabef8777f48595e9d2d7b972184b # 6.2.1
with:
role-to-assume: ${{ vars.AWS_IAM_ROLE }}
aws-region: ${{ vars.AWS_REGION }}
- name: Reboot runner
run: |
set -eux
INSTANCE_ID="${{ needs.start-runner.outputs.ec2-instance-id }}"
aws ec2 reboot-instances --instance-ids "$INSTANCE_ID"
aws ec2 wait instance-status-ok --instance-ids "$INSTANCE_ID"
do-the-job:
name: Do the job on the runner
needs:
- start-runner
- reboot-runner # required to start the main job when the runner is ready
runs-on: ${{ needs.start-runner.outputs.label }} # run the job on the newly created runner
timeout-minutes: 60
steps:
- name: Validate kernel
run: |
set -eux
# ensure that we are running linux-next kernel
uname -a | grep next | grep "criu-ci"
- name: Install make
run: |
set -eux
sudo apt-get install --no-install-recommends -y \
make
- name: Checkout
uses: actions/checkout@v6
- name: Run CRIU tests
run: |
set -eux
#
# We have to set oom_score_adj to the minimal possible value,
# otherwise zdtm/static/oom_score_adj test will fail with EACCES
# check (see __set_oom_adj() [1] in the kernel).
#
# This is not a problem on a normal GitHub runners, but is a problem
# on a self-hosted ones cause we run GitHub stuff via systemd service
# and systemd sets oom_score_adj on a parent process to 500, while
# in the test we want to set 400.
#
# [1] https://github.com/torvalds/linux/blob/27fa82620cbaa89a7fc11ac3057701d598813e87/fs/proc/base.c#L1151
echo "-1000" > /proc/self/oom_score_adj
echo 131072 > /sys/kernel/debug/tracing/buffer_size_kb
echo 1 > /sys/kernel/tracing/events/x86_fpu/x86_fpu_xstate_check_failed/enable
echo 1 > /sys/kernel/tracing/tracing_on
sudo make -C scripts/ci local
- name: Print trace buffer
run: |
set -eux
cat /sys/kernel/tracing/trace
! grep x86_fpu_xstate_check_failed /sys/kernel/tracing/trace
- name: Get tainted state
run: |
set -eux
cat /proc/sys/kernel/tainted
- name: Print dmesg
if: always()
run: |
set -eux
dmesg
get-serial-console:
name: Get EC2 serial console output
needs:
- start-runner
- do-the-job # required to wait when the main job is done
if: ${{ always() }} # required to get logs even if the error happened in the previous jobs
runs-on: ubuntu-latest
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@254c19bd240aabef8777f48595e9d2d7b972184b # 6.2.1
with:
role-to-assume: ${{ vars.AWS_IAM_ROLE }}
aws-region: ${{ vars.AWS_REGION }}
- name: Get serial console output
run: |
set -eux
INSTANCE_ID="${{ needs.start-runner.outputs.ec2-instance-id }}"
aws ec2 get-console-output \
--instance-id "$INSTANCE_ID" \
--latest \
--output text
stop-runner:
name: Stop self-hosted EC2 runner
needs:
- start-runner # required to get output from the start-runner job
- get-serial-console
if: ${{ always() }} # required to stop the runner even if the error happened in the previous jobs
runs-on: ubuntu-latest
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@254c19bd240aabef8777f48595e9d2d7b972184b # 6.2.1
with:
role-to-assume: ${{ vars.AWS_IAM_ROLE }}
aws-region: ${{ vars.AWS_REGION }}
- name: Stop EC2 runner
uses: machulav/ec2-github-runner@343a1b2ae682e681c3cec9a235d882da17ff04ef # 2.6.1
with:
mode: stop
github-token: ${{ secrets.GH_RUNNERS_PAT_TOKEN }}
label: ${{ needs.start-runner.outputs.label }}
ec2-instance-id: ${{ needs.start-runner.outputs.ec2-instance-id }}

View file

@ -1,14 +0,0 @@
name: Remove labels
on: [issue_comment, pull_request_review_comment]
jobs:
remove-labels-on-comments:
name: Remove labels on comments
if: github.event_name == 'issue_comment'
runs-on: ubuntu-latest
steps:
- uses: mondeja/remove-labels-gh-action@b7118e4ba5dca74acf1059b3cb7660378ff9ab1a # v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
labels: |
changes requested
awaiting reply

View file

@ -1,27 +0,0 @@
name: Mark stale issues and pull requests
# Please refer to https://github.com/actions/stale/blob/master/action.yml
# to see all config knobs of the stale action.
on:
schedule:
- cron: "0 0 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'A friendly reminder that this issue had no activity for 30 days.'
stale-pr-message: 'A friendly reminder that this PR had no activity for 30 days.'
stale-issue-label: 'stale-issue'
stale-pr-label: 'stale-pr'
days-before-stale: 30
days-before-close: 365
remove-stale-when-updated: true
exempt-pr-labels: 'no-auto-close'
exempt-issue-labels: 'no-auto-close,new feature,enhancement'

37
.gitignore vendored
View file

@ -1,35 +1,32 @@
.config
*.o
*.d
*.a
*.img
*.bin
*.elf
*.out
*.swp
*.swo
*-blob.h
*.so
.git-ignore
*.patch
*.pyc
criu
cscope*
tags
TAGS
Makefile.local
compel/compel
compel/compel-host-bin
images/*.c
images/*.h
.gitid
criu/criu
criu/unittest/unittest
criu/include/version.h
criu/pie/restorer-blob.h
criu/pie/parasite-blob.h
criu/protobuf-desc-gen.h
lib/build/
lib/c/criu.pc
compel/include/asm
include/common/asm
include/common/config.h
build/**
syscall-x86-64.S
include/syscall.h
include/syscall-codes.h
protobuf/*.c
protobuf/*.h
protobuf/google/protobuf/*.c
protobuf/google/protobuf/*.h
include/version.h
arch/x86/sys-exec-tbl.c
arch/x86/syscalls.S
pie/pie.lds.S
include/config.h
protobuf-desc-gen.h
criu.pc
build

View file

@ -1,25 +0,0 @@
extraction:
cpp:
prepare:
packages:
- "protobuf-c-compiler"
- "libprotobuf-c-dev"
- "libprotobuf-dev"
- "build-essential"
- "libprotobuf-dev"
- "libprotobuf-c-dev"
- "protobuf-c-compiler"
- "protobuf-compiler"
- "python3-protobuf"
- "libnet-dev"
- "pkg-config"
- "libnl-3-dev"
- "libbsd0"
- "libbsd-dev"
- "iproute2"
- "libcap-dev"
- "libaio-dev"
- "libbsd-dev"
- "python3-yaml"
- "libnl-route-3-dev"
- "gnutls-dev"

View file

@ -1,10 +1,6 @@
Stanislav Kinsbursky <skinsbursky@parallels.com> <skinsbursky@openvz.org>
Pavel Emelyanov <xemul@parallels.com> <xemul@openvz.org>
Andrei Vagin <avagin@gmail.com> <avagin@openvz.org>
Andrei Vagin <avagin@gmail.com> <avagin@parallels.com>
Andrei Vagin <avagin@gmail.com> <avagin@virtuozzo.com>
Andrei Vagin <avagin@gmail.com> <avagin@odin.com>
Andrei Vagin <avagin@gmail.com> <avagin@google.com>
Andrey Vagin <avagin@parallels.com> <avagin@openvz.org>
Andrey Vagin <avagin@parallels.com> <avagin@gmail.com>
Andrey Vagin <avagin@parallels.com> Andrew Vagin <avagin@parallels.com>
Cyrill Gorcunov <gorcunov@openvz.org> <gorcunov@gmail.com>
Alexander Mikhalitsyn <alexander@mihalicyn.com> <alexander.mikhalitsyn@virtuozzo.com>
Alexander Mikhalitsyn <alexander@mihalicyn.com> <aleksandr.mikhalitsyn@canonical.com>

11
.travis.yml Normal file
View file

@ -0,0 +1,11 @@
language: c
env:
- ARCH=arm
- ARCH=x86_64
compiler:
- gcc
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq protobuf-c-compiler libprotobuf-c0-dev libaio-dev libprotobuf-dev protobuf-compiler python-ipaddr
script:
- "bash -ex scripts/travis-ci.sh"

View file

@ -1 +0,0 @@
GEMINI.md

View file

@ -1,449 +0,0 @@
## How to contribute to CRIU
CRIU project is (almost) the never-ending story, because we have to always keep up with the
Linux kernel supporting checkpoint and restore for all the features it provides. Thus we're
looking for contributors of all kinds -- feedback, bug reports, testing, coding, writing, etc.
Here are some useful hints to get involved.
* We have both -- [very simple](https://github.com/checkpoint-restore/criu/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement) and [more sophisticated](https://github.com/checkpoint-restore/criu/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+feature%22) coding tasks;
* CRIU does need [extensive testing](https://github.com/checkpoint-restore/criu/issues?q=is%3Aissue+is%3Aopen+label%3Atesting);
* Documentation is always hard, we have [some information](https://criu.org/Category:Empty_articles) that is to be extracted from people's heads into wiki pages as well as [some texts](https://criu.org/Category:Editor_help_needed) that all need to be converted into useful articles;
* Feedback is expected on the GitHub issues page and on the [mailing list](https://lore.kernel.org/criu);
* We accept GitHub pull requests and this is the preferred way to contribute to CRIU. If you prefer to send patches by email, you are welcome to send them to [CRIU development mailing list](https://lore.kernel.org/criu).
Below we describe in more detail recommend practices for CRIU development.
* Spread the word about CRIU in [social networks](http://criu.org/Contacts);
* If you're giving a talk about CRIU -- let us know, we'll mention it on the [wiki main page](https://criu.org/News/events);
### Setting up the development environment
Although `criu` could be run as non-root (see [Security](https://criu.org/Security)), development is better to be done as root. For example, some tests require root. So, it would be a good idea to set up some recent Linux distro on a virtual machine.
### Get the source code
The CRIU sources are tracked by Git. Official CRIU repo is at https://github.com/checkpoint-restore/criu.
The repository may contain multiple branches. Development happens in the **criu-dev** branch.
To clone CRIU repo and switch to the proper branch, run:
```
git clone https://github.com/checkpoint-restore/criu criu
cd criu
git checkout criu-dev
```
### Building from source
Follow these steps to compile CRIU from source code.
#### Installing build dependencies
First, you need to install the required build dependencies. We provide scripts to simplify this process for several Linux distributions in [contrib/dependencies](contrib/dependencies). For a complete list of dependencies, please refer to the [installation guide](https://criu.org/Installation).
##### On Ubuntu/Debian-based systems:
```
./contrib/dependencies/apt-packages.sh
```
##### On Fedora/CentOS-based systems:
```
./contrib/dependencies/dnf-packages.sh
```
##### Using Nix:
```
nix develop
```
#### Compiling CRIU
Once the dependencies are installed, you can compile CRIU by running the `make` command from the root of the source directory:
```
make
```
This should create the `./criu/criu` executable.
## Edit the source code
When you change the source code, please keep in mind the following code conventions:
* code is written to be read, so the code readability is the most important thing you need to have in mind when preparing patches
* we prefer tabs and indentations to be 8 characters width
* we prefer line length of 80 characters or less, more is allowed if it helps with code readability
* CRIU mostly follows [Linux kernel coding style](https://www.kernel.org/doc/Documentation/process/coding-style.rst), but we are less strict than the kernel community
Other conventions can be learned from the source code itself. In short, make sure your new code looks similar to what is already there.
## Automatic tools to fix coding-style
Important: These tools are there to advise you, but should not be considered as a "source of truth", as tools also make nasty mistakes from time to time which can completely break code readability.
The following command can be used to automatically run a code linter for Python files (ruff), Shell scripts (shellcheck),
text spelling (codespell), and a number of CRIU-specific checks (usage of print macros and EOL whitespace for C files).
```
make lint
```
In addition, we have adopted a [clang-format configuration file](https://www.kernel.org/doc/Documentation/process/clang-format.rst)
based on the kernel source tree. However, compliance with the clang-format autoformat rules is optional. If the automatic code formatting
results in decreased readability, we may choose to ignore these errors.
Run the following command to check if your changes are compliant with the clang-format rules:
```
make indent
```
This command is built upon the `git-clang-format` tool and supports two options `BASE` and `OPTS`. The `BASE` option allows you to
specify a range of commits to check for coding style issues. By default, it is set to `HEAD~1`, so that only the last commit is checked.
If you are developing on top of the criu-dev branch and want to check all your commits for compliance with the clang-format rules, you
can use `BASE=origin/criu-dev`. The `OPTS` option can be used to pass additional options to `git-clang-format`. For example, if you want
to check the last *N* commits for formatting errors, without applying the changes to the codebase you can use the following command.
```
make indent OPTS=--diff BASE=HEAD~N
```
Note that for pull requests, the "Run code linter" workflow runs these checks for all commits. If a clang-format error is detected
we need to review the suggested changes and decide if they should be fixed before merging.
Here are some bad examples of clang-format-ing:
* if clang-format tries to force 120 characters and breaks readability - it is wrong:
```
@@ -58,8 +59,7 @@ static int register_membarriers(void)
}
if (!all_ok) {
- fail("can't register membarrier()s - tried %#x, kernel %#x",
- barriers_registered, barriers_supported);
+ fail("can't register membarrier()s - tried %#x, kernel %#x", barriers_registered, barriers_supported);
return -1;
}
```
* if clang-format breaks your beautiful readability friendly alignment in structures, comments or defines - it is wrong:
```
--- a/test/zdtm/static/membarrier.c
+++ b/test/zdtm/static/membarrier.c
@@ -27,9 +27,10 @@ static const struct {
int register_cmd;
int execute_cmd;
} membarrier_cmds[] = {
- { "", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, MEMBARRIER_CMD_PRIVATE_EXPEDITED },
- { "_SYNC_CORE", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE },
- { "_RSEQ", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ, MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ },
+ { "", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, MEMBARRIER_CMD_PRIVATE_EXPEDITED },
+ { "_SYNC_CORE", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE },
+ { "_RSEQ", MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ, MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ },
};
```
## Test your changes
CRIU comes with an extensive test suite. To check whether your changes introduce any regressions, run
```
make test
```
The command runs [ZDTM Test Suite](https://criu.org/ZDTM_Test_Suite). Check for any error messages produced by it.
## Describe your changes
Describe your problem. Whether your change is a one-line bug fix or
5000 lines of a new feature, there must be an underlying problem that
motivated you to do this work. Convince the reviewer that there is a
problem worth fixing and that it makes sense for them to read past the
first paragraph.
Once the problem is established, describe what you are actually doing
about it in technical detail. It's important to describe the change
in plain English for the reviewer to verify that the code is behaving
as you intend it to.
Solve only one problem per commit. If your description starts to get
long, that's a sign that you probably need to split up your commit.
See [Separate your changes](#separate-your-changes).
Describe your changes in imperative mood, e.g. "make xyzzy do frotz"
instead of "[This commit] makes xyzzy do frotz" or "[I] changed xyzzy
to do frotz", as if you are giving orders to the codebase to change
its behaviour.
If your change fixes a bug in a specific commit, e.g. you found an issue using
`git bisect`, please use the `Fixes:` tag with the abbreviation of
the SHA-1 ID, and the one line summary. For example:
```
Fixes: 9433b7b9db3e ("make: use cflags/ldflags for config.h detection mechanism")
```
The following `git config` settings can be used to add a pretty format for
outputting the above style in the `git log` or `git show` commands:
```
[pretty]
fixes = Fixes: %h (\"%s\")
```
If your change address an issue listed in GitHub, please use `Fixes:` tag with the number of the issue. For instance:
```
Fixes: #339
```
The `Fixes:` tags should be put at the end of the detailed description.
Please add a prefix to your commit subject line describing the part of the
project your change is related to. This can be either the name of the file or
directory you changed, or just a general word. If your patch is touching
multiple components you may separate prefixes with "/"-es. Here are some good
examples of subject lines from git log:
```
criu-ns: Convert to python3 style print() syntax
compel: Calculate sh_addr if not provided by linker
style: Enforce kernel style -Wstrict-prototypes
rpc/libcriu: Add lsm-profile option
```
You may refer to [How to Write a Git Commit
Message](https://chris.beams.io/posts/git-commit/) article for
recommendations for good commit message.
## Separate your changes
Separate each **logical change** into a separate commit.
For example, if your changes include both bug fixes and performance
enhancements for a single driver, separate those changes into two
or more commits. If your changes include an API update, and a new
driver which uses that new API, separate those into two commits.
On the other hand, if you make a single change to numerous files,
group those changes into a single commit. Thus a single logical change
is contained within a single commit.
The point to remember is that each commit should make an easily understood
change that can be verified by reviewers. Each commit should be justifiable
on its own merits.
When dividing your change into a series of commits, take special care to
ensure that CRIU builds and runs properly after each commit in the
series. Developers using `git bisect` to track down a problem can end up
splitting your patch series at any point; they will not thank you if you
introduce bugs in the middle.
## Sign your work
To improve tracking of who did what, we ask you to sign off the commits in
your fork of CRIU or the patches that are to be emailed.
The sign-off is a simple line at the end of the explanation for the
patch, which certifies that you wrote it or otherwise have the right to
pass it on as an open-source patch. The rules are pretty simple: if you
can certify the below:
### Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
then you just add a line saying
```
Signed-off-by: Random J Developer <random at developer.example.org>
```
using your real name (please, no pseudonyms or anonymous contributions if
it possible).
Hint: you can use `git commit -s` to add Signed-off-by line to your
commit message. To append such line to a commit you already made, use
`git commit --amend -s`.
```
From: Random J Developer <random at developer.example.org>
Subject: [PATCH] component: Short patch description
Long patch description (could be skipped if patch
is trivial enough)
Signed-off-by: Random J Developer <random at developer.example.org>
---
Patch body here
```
## AI-assisted contributions
Use this tag when AI tools meaningfully contribute to the code,
design, or commit message. Trivial use (e.g. basic autocomplete)
does not require attribution. Following the
[Linux kernel guidance on coding assistants](https://docs.kernel.org/process/coding-assistants.html),
the tag format is:
```
Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]
```
Where `AGENT_NAME` identifies the AI tool or framework, `MODEL_VERSION`
specifies which model was used, and the optional `[TOOL1] [TOOL2]`
fields list any specialized analysis tools (e.g. coccinelle, sparse,
smatch, clang-tidy) that were used alongside the AI assistant. Basic
development tools (git, gcc, make, editors) should not be listed.
For example:
```
Assisted-by: Claude:claude-3-opus coccinelle sparse
```
The `Assisted-by` tag should be placed after the commit message body
and before the `Signed-off-by` line.
Note that AI agents should not add `Signed-off-by` tags. Only human
developers can certify the Developer's Certificate of Origin. The
submitter is responsible for reviewing all AI-generated code and
ensuring its correctness and license compliance.
## Submit your work upstream
We accept GitHub pull requests and this is the preferred way to contribute to CRIU.
For that you should push your work to your fork of CRIU at [GitHub](https://github.com) and create a [pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests)
### Pull request guidelines
Pull request comment should contain description of the problem your changes
solve and a brief outline of the changes included in the pull request.
Please avoid pushing fixup commits to an existent pull request. Each commit
should be self contained and there should not be fixup commits in a patch
series. Pull requests that contain one commit which breaks something
and another commit which fixes it, will be rejected.
Please merge the fixup commits into the commits that has introduced the
problem before creating a pull request.
It may happen that the reviewers were not completely happy with your
changes and requested changes to your patches. After you updated your
changes please close the old pull request and create a new one that
contains the following:
* Description of the problem your changes solve and a brief outline of the
changes
* Link to the previous version of the pull request
* Brief description of the changes between old and new versions of the pull
request. If there were more than one previous pull request, all the
revisions should be listed. For example:
```
v3: rebase on the current criu-dev
v2: add commit to foo() and update bar() coding style
```
If there are only minor updates to the commits in a pull request, it is
possible to force-push them into an existing pull request. This only applies
to small changes and should be used with care. If you update an existing
pull request, remember to add the description of the changes from the
previous version.
### Mailing list submission
Historically, CRIU worked with mailing lists and patches so if you still prefer this way continue reading till the end of this section.
### Make a patch
To create a patch, run
```
git format-patch --signoff origin/criu-dev
```
You might need to read GIT documentation on how to prepare patches
for mail submission. Take a look at http://book.git-scm.com/ and/or
http://git-scm.com/documentation for details. It should not be hard
at all.
We recommend to post patches using `git send-email`
```
git send-email --cover-letter --no-chain-reply-to --annotate \
--confirm=always --to=criu@lists.linux.dev criu-dev
```
Note that the `git send-email` subcommand may not be in
the main git package and using it may require installation of a
separate package, for example the "git-email" package in Fedora and
Debian.
If this is your first time using git send-email, you might need to
configure it to point it to your SMTP server with something like:
```
git config --global sendemail.smtpServer stmp.example.net
```
If you get tired of typing `--to=criu@lists.linux.dev` all the time,
you can configure that to be automatically handled as well:
```
git config sendemail.to criu@lists.linux.dev
```
If a developer is sending another version of the patch (e.g. to address
review comments), they are advised to note differences to previous versions
after the `---` line in the patch so that it helps reviewers but
doesn't become part of git history. Moreover, such patch needs to be prefixed
correctly with `--subject-prefix=PATCHv2` appended to
`git send-email` (substitute `v2` with the correct
version if needed though).
### Mail patches
The patches should be sent to CRIU development mailing list, `criu AT lists.linux.dev`. Note that you need to be subscribed first in order to post. The list web interface is available at https://lore.kernel.org/criu; you can also use standard mailman aliases to work with it.
Please make sure the email client you're using doesn't screw your patch (line wrapping and so on).
> **Note:** When sending a patch set that consists of more than one patch, please, push your changes in your local repo and provide the URL of the branch in the cover-letter
### Wait for response
Be patient. Most CRIU developers are pretty busy people so if
there is no immediate response on your patch — don't be surprised,
sometimes a patch may fly around a week before it gets reviewed.
## Continuous integration
Wiki article: [Continuous integration](https://criu.org/Continuous_integration)
CRIU tests are run for each series sent to the mailing list. If you get a message from our patchwork that patches failed to pass the tests, you have to investigate what is wrong.

View file

@ -1,4 +1,4 @@
This software is licensed under the GNU GENERAL PUBLIC LICENCE Version
This software is licenced under the GNU GENERAL PUBLIC LICENCE Version
2. Except that any software in the lib/ directory is for the creation of a
linkable library to the tools and is licensed under the GNU LESSER GENERAL
PUBLIC LICENCE Version 2.1. Contributing Authors agree that their code is

View file

@ -3,4 +3,3 @@
*.[1-8]
*.pdf
*.ps
footer.txt

View file

@ -1,10 +1,4 @@
How to cross-compile CRIU on x86:
Use the Dockerfile provided:
scripts/build/Dockerfile.armv7-cross
Historical guide how-to do it without docker container:
[Unsupported, may not work anymore!]
This HOWTO explains how to cross-compile CRIU on x86
1. Download the protobuf sources.
2. Apply the patch http://16918.selcdn.ru/crtools/aarch64/0001-protobuf-added-the-support-for-the-acrchitecture-AAr.patch
@ -35,11 +29,3 @@ Historical guide how-to do it without docker container:
13. Compile CRIU:
ARCH=<target arch> CROSS_COMPILE=$TARGET- CFLAGS=`pkg-config --cflags libprotobuf-c` LDFLAGS="`pkg-config --libs libprotobuf-c`" make
Special notes for Android NDK cross compile:
1, Android NDK doesn't have some headers required by CRIU build, they are <aio.h>, <sys/fanotify.h>
2, Android NDK doesn't have some function required by CRIU build, they are aio*, fanotify_init, fanotify_mark, povit_root, index.
3, in order to pass build with Android NDK, you implement them yourself, and link them to CRIU.

View file

@ -1,34 +1,20 @@
__nmk_dir ?= ../scripts/nmk/scripts/
include $(__nmk_dir)include.mk
include $(__nmk_dir)macro.mk
-include ../Makefile.inc
ifneq ($(USE_ASCIIDOCTOR),)
ASCIIDOC := asciidoctor
XMLTO :=
else
ASCIIDOC := asciidoc
A2X := a2x
XMLTO := xmlto
endif
FOOTER := footer.txt
SRC1 += crit.txt
SRC1 += criu-ns.txt
SRC1 += compel.txt
SRC1 += criu-amdgpu-plugin.txt
SRC8 += criu.txt
SRC := $(SRC1) $(SRC8)
SRC += criu.txt
XMLS := $(patsubst %.txt,%.xml,$(SRC))
MAN1S := $(patsubst %.txt,%.1,$(SRC1))
MAN8S := $(patsubst %.txt,%.8,$(SRC8))
MANS := $(MAN1S) $(MAN8S)
MAN1DIR := $(MANDIR)/man1
MANS := $(patsubst %.txt,%.8,$(SRC))
MAN8DIR := $(MANDIR)/man8
GROFF :=groff
PAPER :=$(shell paperconf 2>/dev/null || echo letter)
GROFF_OPTS := -Tps -t -dpaper=$(PAPER) -P-p$(PAPER) -man -msafer -rC1 -rD1 -rS11
PSS := $(patsubst %,%.ps,$(basename $(MANS)))
PDFS := $(patsubst %,%.pdf,$(basename $(MANS)))
GROFF=groff
PAPER=$(shell paperconf 2>/dev/null || echo letter)
GROFF_OPTS := -Tps -t -dpaper=$(PAPER) -P-p$(PAPER) \
-man -msafer -rC1 -rD1 -rS11
PSS := $(MANS:%.8=%.ps)
PDFS := $(MANS:%.8=%.pdf)
all: check $(MANS)
ps: $(PSS)
@ -36,66 +22,30 @@ pdf: $(PDFS)
.PHONY: all ps pdf check
check:
$(Q) for B in $(ASCIIDOC) $(XMLTO); do \
$(Q) for B in $(ASCIIDOC) $(A2X) $(XMLTO); do \
$$B --version > /dev/null || exit 1; \
done
ifeq ($(CRIU_VERSION),)
include ../Makefile.versions
endif
$(FOOTER): ../Makefile.versions
$(call msg-gen, $@)
$(Q) echo ":doctype: manpage" > $@
$(Q) echo ":man source: criu" >> $@
$(Q) echo ":man version: $(CRIU_VERSION)" >> $@
$(Q) echo ":man manual: CRIU Manual" >> $@
%.1: %.txt $(FOOTER) custom.xsl
$(call msg-gen, $@)
ifneq ($(USE_ASCIIDOCTOR),)
$(Q) $(ASCIIDOC) -b manpage -d manpage -o $@ $<
else
$(Q) $(ASCIIDOC) -b docbook -d manpage -o $(patsubst %.1,%.xml,$@) $<
$(Q) $(XMLTO) man -m custom.xsl $(patsubst %.1,%.xml,$@)
endif
%.8: %.txt $(FOOTER) custom.xsl
$(call msg-gen, $@)
ifneq ($(USE_ASCIIDOCTOR),)
$(Q) $(ASCIIDOC) -b manpage -d manpage -o $@ $<
else
%.8: %.txt
$(E) " GEN " $@
$(Q) $(ASCIIDOC) -b docbook -d manpage -o $(patsubst %.8,%.xml,$@) $<
$(Q) $(XMLTO) man -m custom.xsl $(patsubst %.8,%.xml,$@)
endif
%.ps: %.1
$(call msg-gen, $@)
$(Q) $(GROFF) $(GROFF_OPTS) $^ > $@
$(Q) $(XMLTO) man --skip-validation $(patsubst %.8,%.xml,$@) 2>/dev/null
%.ps: %.8
$(call msg-gen, $@)
$(E) " GEN " $@
$(Q) $(GROFF) $(GROFF_OPTS) $^ > $@
%.pdf: %.ps
$(call msg-gen, $@)
$(E) " GEN " $@
$(Q) ps2pdf $< $@
clean:
$(call msg-clean, "Documentation")
$(Q) rm -f $(XMLS) $(MANS) $(PSS) $(PDFS) $(FOOTER)
$(E) " CLEAN "
$(Q) rm -f $(XMLS) $(MANS) $(PSS) $(PDFS)
install: check $(MANS)
$(E) " INSTALL " $(MAN8S)
install: $(MANS)
$(E) " INSTALL " $(MANS)
$(Q) mkdir -p $(DESTDIR)$(MAN8DIR)
$(Q) install -m 644 $(MAN8S) $(DESTDIR)$(MAN8DIR)
$(E) " INSTALL " $(MAN1S)
$(Q) mkdir -p $(DESTDIR)$(MAN1DIR)
$(Q) install -m 644 $(MAN1S) $(DESTDIR)$(MAN1DIR)
$(Q) install -m 644 $(MANS) $(DESTDIR)$(MAN8DIR)
uninstall:
$(E) " UNINSTALL" $(MAN1S)
$(Q) $(RM) $(addprefix $(DESTDIR)$(MAN1DIR)/,$(MAN1S))
$(E) " UNINSTALL" $(MAN8S)
$(Q) $(RM) $(addprefix $(DESTDIR)$(MAN8DIR)/,$(MAN8S))
.PHONY: clean install uninstall
.PHONY: clean install

View file

@ -0,0 +1,194 @@
Makefile.build(1)
=================
:doctype: manpage
:man source: CRtools
:man version: 0.0.2
:man manual: CRtools Manual
NAME
----
Makefile.build - a bunch of helpers for simplified Makefiles
SYNOPSIS
--------
'make' -f scripts/Makefile.build obj=<dir>
DESCRIPTION
-----------
This is main build helpers script we use. Basically the idea is to minimize hand
work and describe Makefiles with somewhat simplified grammar.
The script may work in two modes
- *Default mode*
- *Target mode*
Following keywords are reserved and must not be used for anything else --
'targets', 'deps', 'all-obj', 'incdeps', 'obj-y', 'obj-e', 'asm-y', 'asm-e',
'file', 'libs-e', '<x>-obj-y', '<x>-obj-e', '<x>-asm-y', '<x>-asm-e',
'<x>-obj-y-cflags', '<x>-obj-e-cflags', '<x>-asm-y-asmflags', '<x>-asm-e-asmflags',
'<x>-libs-e'. Where '<x>' is a prefix of the target, will be explained below.
That said, do not use such names for other purposes as stated here.
OBJ=
----
Parameter *obj=* states for passing directory where simplified Makefile lays in.
Note the directory name must not end up with a slash, it is mandatory.
In your simplifiled Makefile you still can refer to it as '$(obj)' variable. If
you need an ending slash, just type it explicitly as '$(obj)/'.
DEFAULT MODE
------------
In *default* mode the script builds '$(obj)/built-in.o' relocatable file. To use
*default* mode do not ever mention '<x>-' and 'targets' variables in a Makefile.
This done for simplicity, otherwise more complex logic will be needed in the
script which slows down built procedure.
Thus in *default* mode the following variables may and should be referred
obj-y::
Source code C file. Typically refered as *obj-y += 'some-file.o'*.
This implies you have real 'some-file.c' in '$(obj)' directory.
obj-e::
Same as 'obj-y' but implies that source code file lays in directory
other than '$(obj)'. The postfix '-e' came from word 'external'.
obj-ext-src-y::
Same as 'obj-y' but implies that source code file lays in directory
other than '$(obj)', while compiled object file pushed into '$(obj)' directory.
Consider using this variable if you need to compile same source file with
different flags.
asm-y::
Source code S file. Same as 'obj-y' but for assembly language.
asm-e::
Same as 'obj-e' but for assembly language.
lib-e::
Some extarnal library the 'built-in.o' should link with.
lib-so::
Tells the make engine to build a shared library.
incdeps::
A flag which tells the script to generate dependency (that named '*.d'
files) for source code C files. To turn this functionality on just
type 'incdeps := y' somewhere in your Makefile.
cleanup-y::
List of files to be cleaned up when 'clean' target is called.
For example a simplified Makefile may look like
obj-y += file1.o
obj-y += file2.o
obj-y += file3.o
ifneq ($(MAKECMDGOALS),clean)
incdeps := y
endif
TARGET MODE
-----------
In *target* mode the script builds all targets declared in a Makefile. Thus the
final built relocatable files will have a name as '<x>.built-in.o', where '<x>'
is a name of a target (I will continue using '<x>' to refer the target name).
The following variables may be used for *target* mode.
targets::
This one defines a target name to built.
<x>-obj-y::
Same as 'obj-y' but per target.
<x>-obj-y-cflags::
Additional compiler flags for this target and object files
in '<x>-obj-y'.
<x>-obj-e::
Same as 'obj-e' but per target.
<x>-obj-e-cflags::
Additional compiler flags for this target and object files
in '<x>-obj-e'.
<x>-asm-y::
Same as 'asm-y' but per target.
<x>-asm-y-asmflags::
Additional compiler flags for this target and object files
in '<x>-asm-y'.
<x>-asm-e::
Same as 'asm-e' but per target.
<x>-asm-e-asmflags::
Additional compiler flags for this target and object files
in '<x>-asm-e'.
<x>-libs-e::
Same as 'libs-e' but per-target.
There might be a situation where we have several targets and each of them need
some object file to be linked in. In this case we need to use variables from
*default* mode. Better to explain with example.
Lets say we need to built two targets 'one' and 'two' (thus 'one.built-in.o' and
'two.built-in.o' relocatable files will be generated). For 'one' we need to use
files 'a.o', 'b.o', and for 'two' we need to use 'c.o' and 'd.o'. But both
targets need functionality from file 'e.o'. To force the script share the 'e.o'
we describe it as plain 'obj-y'.
targets += one
targets += two
one-obj-y += a.o
one-obj-y += b.o
two-obj-y += c.o
two-obj-y += d.o
obj-y += e.o
The script will compile all files and link 'one.built-in.o' from files 'one-obj-y'
plus 'obj-y'. The same applies to the target 'two' ('obj-y' file will be linked
in as well).
Thus if you refer variables from *default* mode but have 'targets' defined, the
script will treat such variables as a sign to share the productions at moment
when targets get linked.
INVISIBLE RULES
---------------
If the script is used for build procedure then a couple of additional rules are
generated on the fly. Better to explain with example again.
Lets say we have a Makefile with the following contents
obj-y += file.o
where $(obj) is a directory named 'dir'. So once we use the script we can
generate the following files.
make dir/file.o::
To compile the file.
make dir/file.s::
To generate assembly file from C file.
make dir/file.d::
To generate dependency file.
make dir/file.i::
To generate C file with preprocessor only.

View file

@ -1,122 +0,0 @@
COMPEL(1)
==========
include::footer.txt[]
NAME
----
compel - Execute parasitic code within another process.
SYNOPSIS
--------
*compel* 'hgen' ['option' ...]
*compel* 'plugins' ['PLUGIN_NAME' ...]
*compel* ['--compat'] 'includes' | 'cflags' | 'ldflags'
*compel* ['--compat'] ['--static'] 'libs'
DESCRIPTION
------------
*compel* is a utility to execute arbitrary code, also called parasite code,
in the context of a foreign process. The parasitic code, once compiled with
compel flags and packed, can be executed in the context of other tasks. Currently
there is only one way to load the parasitic blob into victim task using libcompel.a,
called c-header.
ARGUMENTS
----------
Positional Arguments
~~~~~~~~~~~~~~~~~~~~
*hgen*::
create a header from the .po file, which is the parasite binary.
*plugins*::
prints the plugins available.
*ldflags*::
prints the ldflags available to compel during linking of parasite code.
*cflags*::
prints the compel cflags to be used during compilation of parasitic code.
*includes*::
prints list of standard include directories.
*libs*::
prints list of static or dynamic libraries that compel can link with.
OPTIONS
--------
*-f*, *--file* 'FILE'::
Path to the binary file, 'FILE', which *compel* must turn into a header
*-o*, *--output* 'FILE'::
Path to the header file, 'FILE', where compel must write the resulting header.
*-p*, *--prefix* 'NAME'::
Specify prefix for var names
*-l*, *--log-level* 'NUM'::
Default log level of compel.
*-h*, *--help*::
Prints usage and exits.
*-V*, *--version*::
Prints version number of compel.
SOURCE EXAMPLES
----------------
Parasitic Code
~~~~~~~~~~~~~~
*#include <compel/plugins/std.h>*
*int parasite_trap_cmd(int cmd, void *args);* //gets called by compel_run_in_thread()
*int parasite_daemon_cmd(int cmd, void *arg);* // gets called by compel_rpc_call() and compel_rpc_call_sync()
*void parasite_cleanup(void);* //gets called on parasite unload by compel_cure()
Infecting code
~~~~~~~~~~~~~~
The parasitic code is compiled and converted to a header using *compel*, and included here.
*#include <compel/infect.h>*
*#include "parasite.h"*
Following steps are performed to infect the victim process:
- stop the task: *int compel_stop_task(int pid);*
- prepare infection handler: *struct parasite_ctl *compel_prepare(int pid);*
- execute system call: *int compel_syscall(ctl, int syscall_nr, long *ret, int arg ...);*
- infect victim: *int compel_infect(ctl, nr_thread, size_of_args_area);*
- cure the victim: *int compel_cure(ctl);* //ctl pointer is freed by this call
- Resume victim: *int compel_resume_task(pid, orig_state, state)* or
*int compel_resume_task_sig(pid, orig_state, state, stop_signo).*
//compel_resume_task_sig() could be used in case when victim is in stopped state.
stop_signo could be read by calling compel_parse_stop_signo().
*ctl* must be configured with blob information by calling *PREFIX_setup_c_header()*, with ctl as its argument.
*PREFIX* is the argument given to *-p* when calling hgen, else it is deduced from file name.
EXAMPLES
---------
To generate a header file(.h) from a parasite binary file(.po) use:
----------
compel hgen -f parasite.po -o parasite.h
----------
'parasite.po' file is obtained by compiling the parasite source with compel flags and
linking it with the compel plugins.
AUTHOR
------
The CRIU team.

View file

@ -1,96 +0,0 @@
CRIT(1)
=======
include::footer.txt[]
NAME
----
crit - CRiu Image Tool
SYNOPSIS
--------
*crit* 'decode' [-h] [-i IN] [-o OUT] [--pretty]
*crit* 'encode' [-h] [-i IN] [-o OUT]
*crit* 'info' [-h] in
*crit* 'x' [-h] dir {ps,fds,mems}
*crit* 'show' [-h] in
*crit* 'compress' [-h] [--in-place] [--acceleration N] dir
*crit* 'decompress' [-h] [--in-place] dir
DESCRIPTION
-----------
*crit* is a feature-rich replacement for existing *criu* show.
ARGUMENTS
---------
Positional Arguments
~~~~~~~~~~~~~~~~~~~~
*decode*::
convert *criu* image from binary type JSON
*encode*::
convert *criu* image from JSON type to binary
*info*::
show info about image
*x*::
explore image directory
*show*::
convert *criu* image from binary to human-readable JSON
*compress*::
compress memory page images in a checkpoint directory using CRIU's
per-page LZ4 format. The command rewrites *pages-*.img*,
*pagemap-*.img*, and *inventory.img*. Pages that are zero-filled or
do not meet CRIU's compression threshold are stored without an LZ4
payload. By default, the original files are preserved with a *.bak*
suffix; use *--in-place* to skip these backup files. The inventory
is updated to record compression metadata and the compressed-image
version. Existing *.bak* files are never overwritten.
*decompress*::
decompress memory page images in a checkpoint directory back to
uncompressed page payloads. The command removes compression metadata
from the pagemap and inventory images. When the directory has no parent
reference, the command also restores the normal image version. It retains
the compressed-image version for incremental checkpoints because a parent
may still contain compressed payloads. By default, rewritten files are
preserved with a *.bak* suffix; use *--in-place* to skip these backup
files. Existing *.bak* files are never overwritten.
Both transformations preserve the ownership, permissions, ACLs, security
labels, and other extended attributes of rewritten images. All output is
staged and synchronized before it is installed. If a write, rename, *SIGHUP*,
*SIGINT*, or *SIGTERM* interrupts the commit, CRIT restores the complete
original image set instead of leaving a partially transformed set.
Optional Arguments
~~~~~~~~~~~~~~~~~~
*-h*, *--help*::
Print some help and exit
*--in-place*::
Rewrite files without creating *.bak* backup files. This option is
accepted by *compress* and *decompress*.
*--acceleration* 'N'::
Set the LZ4 acceleration level used by *compress*. Higher values
trade compression ratio for speed.
SEE ALSO
--------
criu(8)
AUTHOR
------
The CRIU team

View file

@ -1,114 +0,0 @@
ROCM Support(1)
===============
NAME
----
criu-amdgpu-plugin - A plugin extension to CRIU to support checkpoint/restore in
userspace for AMD GPUs.
CURRENT SUPPORT
---------------
Single and Multi GPU systems (Gfx9)
Checkpoint / Restore on different system
Checkpoint / Restore inside a docker container
Pytorch
Tensorflow
Using CRIU Image Streamer
Parallel Restore
DESCRIPTION
-----------
Though *criu* is a great tool for checkpointing and restoring running
applications, it has certain limitations such as it cannot handle
applications that have device files open. In order to support *ROCm* based
workloads with *criu* we need to augment criu's core functionality with a
plugin based extension mechanism. *criu-amdgpu-plugin* provides the necessary support
to criu to allow Checkpoint / Restore with ROCm.
Dependencies
------------
*amdkfd support*::
In order to snapshot the *VRAM* and other *GPU* device states, we require
an updated version of amdkfd(amdgpu) driver.
OPTIONS
-------
Optional parameters can be passed in as environment variables before
executing criu command.
*KFD_FW_VER_CHECK*::
Enable or disable firmware version check.
If enabled, firmware version on restored gpu needs to be greater than or
equal firmware version on checkpointed GPU. Default:Enabled
E.g:
KFD_FW_VER_CHECK=0
*KFD_SDMA_FW_VER_CHECK*::
Enable or disable SDMA firmware version check.
If enabled, SDMA firmware version on restored gpu needs to be greater than or
equal firmware version on checkpointed GPU. Default:Enabled
E.g:
KFD_SDMA_FW_VER_CHECK=0
*KFD_CACHES_COUNT_CHECK*::
Enable or disable caches count check. If enabled, the caches count on
restored GPU needs to be greater than or equal caches count on checkpointed
GPU. Default:Enabled
E.g:
KFD_CACHES_COUNT_CHECK=0
*KFD_NUM_GWS_CHECK*::
Enable or disable num_gws check. If enabled, the num_gws on
restored GPU needs to be greater than or equal num_gws on checkpointed
GPU. Default:Enabled
E.g:
KFD_NUM_GWS_CHECK=0
*KFD_VRAM_SIZE_CHECK*::
Enable or disable VRAM size check. If enabled, the VRAM size on
restored GPU needs to be greater than or equal VRAM size on checkpointed
GPU. Default:Enabled
E.g:
KFD_VRAM_SIZE_CHECK=0
*KFD_NUMA_CHECK*::
Enable or disable NUMA CPU region check. If enabled, the plugin will restore
GPUs that belong to one CPU NUMA region to the same CPU NUMA region.
Default:Enabled
E.g:
KFD_NUMA_CHECK=1
*KFD_CAPABILITY_CHECK*::
Enable or disable capability check. If enabled, the capability on
restored GPU needs to be equal to the capability on the checkpointed GPU.
Default:Enabled
E.g:
KFD_CAPABILITY_CHECK=1
*KFD_MAX_BUFFER_SIZE*::
On some systems, VRAM sizes may exceed RAM sizes, and so buffers for dumping
and restoring VRAM may be unable to fit. Set to a nonzero value (in bytes)
to set a limit on the plugin's memory usage.
Default:0 (Disabled)
E.g:
KFD_MAX_BUFFER_SIZE="2G"
AUTHOR
------
The AMDKFD team.
COPYRIGHT
---------
Copyright \(C) 2020-2021, Advanced Micro Devices, Inc. (AMD)

View file

@ -1,32 +0,0 @@
CRIU-NS(1)
==========
include::footer.txt[]
NAME
----
criu-ns - run criu in different namespaces
SYNOPSIS
--------
*criu-ns* 'dump' -t PID [<options>]
*criu-ns* 'pre-dump' -t PID [<options>]
*criu-ns* 'restore' [<options>]
*criu-ns* 'check' [<options>]
DESCRIPTION
-----------
The *criu-ns* command executes 'criu' in a new PID and mount namespace.
The purpose of this wrapper script is to enable restoring a process tree
that might require a specific PID that is already used on the system;
so called "PID mismatch" problem.
SEE ALSO
--------
nsenter(1) namespaces(7) criu(8)
AUTHOR
------
The CRIU team

File diff suppressed because it is too large Load diff

View file

@ -1,8 +0,0 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="man.hyphenate">1</xsl:param>
<xsl:param name="man.justify">1</xsl:param>
<xsl:param name="man.output.better.ps.enabled">1</xsl:param>
</xsl:stylesheet>

View file

@ -1,136 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="560px" height="560px" viewBox="0 0 560 560" enable-background="new 0 0 560 560" xml:space="preserve">
<path opacity="0.3" fill="#990000" d="M315.137,360.271c-18.771-7.159-41.548-8.85-68.479-8.85c-16.661,0-46.255,2.939-74.654,3.38
c11.209-4.884,20.734-10.265,24.842-16.87c14.531-23.346,17.645-65.893,17.645-65.893l-20.758,3.114c0,0-2.591,35.8-16.085,47.733
c-5.35,4.736-15.96,7.834-27.916,10.856c2.447-26.071,29.477-57.552,29.477-57.552l-14.874-3.966l-5.88-7.448
c0,0-3.011,1.761-7.588,5.315c-18.298,4.208-75.946,20.443-75.946,57.983c0,15.292,5.77,26.308,14.768,34.244
c-22.858,26.966-20.755,61.618-20.755,61.618s-8.945,16.61-8.021,31.254c2.083,32.973,34.931,25.097,44.313,26.374
c9.644,1.313,34.313-4.18,34.313-4.18s-16.276-2.639-15.329-18.562c0.5-8.369-0.947-27.628-21.404-37.307
c-1.13-10.066,2.111-18.309,6.379-28.015c18.452,45.263,92.601,53.97,92.601,53.97c0.393-0.097-10.269,20.047,0.221,35.632
c4.652,6.915,18.284,10.019,22.436,19.356c4.151,9.341,2.199,30.354,2.199,30.354s21.267-16.864,27.239-30.18
c3.334-7.432,25.989,0.926,25.989-34.047c0-14.077-12.26-26.841-13.675-29.815c-20.858-20.334-5.427-4.743,2.677-8.236
c12.758-5.499,35.412,11.657,35.412,11.657s-10.402-20.119-11.437-31.013c-0.795-8.335-4.537-16.816-16.624-30.042
c7.166-0.752,20.362,2.327,20.362,2.327s-5.202,11.251-0.879,25.515c3.588,11.84,7.193,7.193,14.736,14.737
c6.599,6.598,3.146,26.284,3.146,26.284s4.674-4.513,18.081-18.235c9.072-9.29,23.645-16.717,23.645-47.86
C355.312,365.969,334.97,360.979,315.137,360.271z M134.108,285.901c-11.5,13.048-23.667,32.329-28.23,58.293
c-4.821-3.519-7.613-8.1-7.613-14.043C98.265,309.699,117.078,295.016,134.108,285.901z"/>
<path fill="#990000" d="M382.184,115.435c3.654,1.208,7.327,2.37,10.968,3.444c14.16,4.183,26.745-9.798,26.745-9.798
s-8.785-2.243-17.857-3.497c12.173-2.653,21.085-18.66,21.085-18.66s-17.366,4.819-27.224,5.087
c-2.042,0.057-4.107,0.118-6.189,0.186c2.464-0.37,4.925-0.847,7.361-1.485c14.201-3.714,21.505-23.382,21.505-23.382
s-15.411,6.743-24.951,9.239c-2.694,0.703-5.438,1.437-8.197,2.185c3.038-1.071,6.008-2.306,8.815-3.82
c12.922-6.965,12.241-29.347,12.241-29.347s-10.162,11.926-18.844,16.605c-3.557,1.916-7.199,3.904-10.846,5.911
c3.798-2.277,7.45-4.743,10.596-7.569c10.918-9.814,7.722-29.605,7.722-29.605s-9.801,12.54-17.135,19.131
c-8.939,8.037-18.775,14.104-27.014,21.81c-6.427,6.011-25.14,35.236-36.812,46.283c-11.671,11.047-18.301,12.476-19.159,14.388
c-0.863,1.913,1.006,30.46-14.078,39.145c-16.476-21.583-50.565-44.007-53.101-72.033c-2.079-22.959,5.209-34.055,19.149-35.316
c14.994-1.359,15.998,24.507,15.998,24.507s-1.379,1.064-1.708,6.391c-0.097,0.629-0.145,1.272-0.083,1.934
c0.004,0.031,0.008,0.06,0.011,0.091c-0.014,1.674,0.065,3.664,0.278,6.039c1.131,12.474,4.53,14.574,4.53,14.574l2.075-0.722
c0,0-2.24-4.079-2.554-7.529c-0.172-1.917-0.187-3.556-0.079-4.977c0.45,0.067,0.949,0.081,1.506,0.031
c4.398-0.399,6.049-4.141,5.65-8.539c-0.042-0.45-0.069-0.885-0.094-1.316c2.485-26.032-1.756-29.637,4.788-41.391
c9.032-16.218,17.279-16.015,17.279-16.015l1.402-8.155c0,0-6.817,2.462-14.819,13.652c-8.833,12.354-8.983,26.229-9.066,47.958
c-0.188-0.761-0.502-1.37-1.017-1.784c-2.457-11.192-9.087-32.13-24.112-30.77c-16.72,1.514-29.419,14.974-26.773,44.171
c3.609,39.832,26.186,52.701,29.829,80.84c-13.47-2.349-23.883-10.656-30.866-20.282c-7.803-10.749-7.297-22.949-8.324-24.779
c-1.027-1.829-7.761-2.662-20.367-12.627c-12.605-9.965-33.845-37.41-40.78-42.824c-8.895-6.942-19.229-12.111-28.848-19.32
c-7.892-5.915-18.769-17.531-18.769-17.531s-1.419,19.995,10.323,28.8c3.386,2.536,7.246,4.665,11.229,6.597
c-3.808-1.674-7.616-3.33-11.327-4.925c-9.062-3.887-20.246-14.861-20.246-14.861s1.31,22.353,14.803,28.143
c2.931,1.257,6,2.223,9.12,3.019c-2.818-0.5-5.615-0.985-8.357-1.447c-9.728-1.636-25.677-6.981-25.677-6.981
s9.025,18.94,23.5,21.376c2.485,0.417,4.975,0.674,7.466,0.822c-2.08,0.118-4.148,0.242-6.183,0.368
c-9.843,0.61-27.566-2.645-27.566-2.645S85.667,120.333,110,120c-8.922,2.057-25.678,6.008-25.678,6.008s13.778,12.806,27.508,7.38
c3.533-1.394,7.087-2.876,10.62-4.404c-3.726,1.804-7.424,3.581-11.005,5.273c-8.963,4.243-19.428,10.176-19.428,10.176
s15.069,9.759,27.305,1.497c0.558-0.378,3.121-1.76,3.678-2.143c-7.904,5.808-19.754,14.937-19.754,14.937
s15.802,6.027,27.092-3.354c4.663-3.875,8.104-7.185,12.238-11.618c-3.773,4.55-6.699,8.018-10.634,12.106
c-6.839,7.104-13.06,19.791-13.06,19.791s15.597,0.39,24.359-11.388c4.488-6.035,7.482-11.633,10.974-18.191
c-3.113,6.479-5.468,11.95-8.911,17.788c-5.018,8.49-7.574,22.624-7.574,22.624s15.342-3.655,21.07-17.17
c2.231-5.266,2.107-9.783,3.694-15.291c-1.257,5.272-0.666,9.475-2.24,14.319c-3.045,9.379,0.011,25.554,0.011,25.554
s9.713-5.855,10.359-20.52c0.006-0.153,0.5-8.47,0.5-8.625L171,171.496c0,9.917,6.295,23.276,6.295,23.276
s11.459-10.649,9.369-25.266c-0.188-1.31-0.1-2.627-0.305-3.947c0.408,1.507,0.998,3.016,1.493,4.524
c3.075,9.429,3.5,15.957,3.5,15.957s6.483,1.251,8.73-1.594c0.764,5.625-0.843,10.2-0.843,10.2s5.471-1.1,8.893-3.756
c0.705,5.331,0.155,8.789,0.155,8.789s5.106-1.603,8.419-4.323c0.611,4.642,1.764,7.542,1.764,7.542s6.398-0.88,9.021-5.393
c0.199,0.038,0.395,0.079,0.59,0.117c2.269,4.875,1.438,8.517,1.438,8.517s7.492-2.14,9.492-6.14c0.003,0,0.007,0,0.01,0
c1.798,4,2.727,6.102,2.727,6.102s4.853-2.349,7.093-6.064c0.189,0.009,0.364-0.093,0.547-0.086
c-4.702,19.629-23.62,29.658-42.207,42.764c-1.392,0.981-2.712,1.925-3.97,2.884c-2.891,1.512-6.788,3.495-11.311,5.724
c-9.829,3.363-23.7,6.057-41.038,4.084c-9.798-1.115-21.037,10.02-21.037,10.02s6.87,4.843,16.565,5.028
c-8.819,3.621-17.438,12.632-17.438,12.632s0.045,0.019,0.069,0.029c-27.096,11.688-51.621,29.917-47.651,57.105
c2.375,16.27,14.692,25.475,31.704,30.254c-17.81,14.742-32.921,36.129-30.707,60.59c0.134,1.487,0.309,2.916,0.508,4.311
c-2.209,5.6-3.288,17.842-2.674,24.886c0.949,10.838,13.686,8.662,18.219,6.729c14.139,12.202,32.258,10.252,32.258,10.252
s-17.301,1.211-30.306-11.156c5.551-2.659,6.424-3.925,6.788-11.579c0.36-7.61-9.104-20.759-20.57-21.966
c-1.25-20.07,9.861-43.32,30.603-60.203c0.02,0.249,0.023,0.491,0.048,0.742c4.248,46.957,30.584,54.634,81.148,63.26
c12.603,2.15,22.04,5.821,29.042,10.457c-3.844,5.388-5.706,21.559-2.895,32.325c3.045,11.655,12.647,14.53,19.429,14.955
c-3.304,16.035-11.235,29.024-11.235,29.024s10.015-11.628,15.04-29.016c0.48-0.031,0.928-0.069,1.319-0.114
c10.922-1.262,16.17-11.338,14.743-23.071c-1.195-9.826-13.974-24.54-28.598-25.992c-33.117-21.52-109.104-9.05-113.877-61.769
c-0.341-3.746-0.517-7.367-0.571-10.888c5.709,1.111,11.782,1.844,18.104,2.244c14.111,28.517,62.158,22.269,95.818,20.694
c1.764,3.09,7.043,7.064,13.929,9.779c11.751,4.633,14.889,3.742,18.869,1.502c1.484-0.835,2.828-1.92,3.979-3.155
c10.822,10.456,25.37,30.251,25.37,30.251s-12.29-22.284-22.733-33.97c2.601-4.923,2.433-10.619-2.559-13.297
c-6.956-3.732-31.321,1.581-36.316,4.981c-30.811,1.668-71.853,6.551-89.576-16.474c41.005,1.192,88.786-9.133,102.385-10.365
c21.726-1.966,47.319,1.367,64.887,8.228c-0.783,5.681,1.867,18.47,4.641,25.318c3.316,8.197,11.561,5.887,16.562,3.028
c-0.588,13.3-4.495,22.638-4.495,22.638s7.86-14.125,9.117-26.183c4.354-4.041,4.774-5.562,2.904-12.887
c-1.849-7.24-14.317-16.821-25.47-15.096c-21.855-8.906-54.594-11.087-75.74-9.175c-18.253,1.653-61.404,10.802-97.611,10.237
c-1.895-3.338-3.402-7.122-4.412-11.479c5.113-2.364,10.551-4.388,16.307-5.975c30.999-8.551,40.97-29.258,42.943-48.579
c1.127,1.303,1.938,2.069,1.938,2.069s7.087-12.679,5.522-27.275c-0.264-2.469-0.429-4.737-0.553-6.911
c2.499,6.741,7.778,13.001,7.778,13.001s16.438-20.208,5.846-27.268c-11.583-7.714-6.836-13.283-4.31-15.299
c3.354-1.984,6.973-3.94,10.859-5.817c26.561-12.817,59.903-20.002,64.443-40.039c0.265-1.172,0.388-2.34,0.443-3.507
c3.701,2.396,9.165,2.053,9.165,2.053s-0.367-2.88-0.601-7.556c3.747,2.081,8.874,1.758,8.874,1.758s-0.986-2.319-1.255-7.689
c3.846,1.998,8.434,2.278,8.434,2.278s-0.725-2.246-1.24-5.573c3.788,0.719,8.84,0.419,8.84,0.419s-3.543-7.302-1.316-16.965
c0.357-1.547,0.666-3.09,0.938-4.626c-0.087,1.332-0.169,2.662-0.238,3.985c-0.783,14.742,10.85,24.47,10.85,24.47
S337,172.178,337,162.303c0-0.021,0-0.042,0-0.061c0,0.153-0.804,0.309-0.782,0.46c1.951,14.548,13.499,20.839,13.499,20.839
s2.388-16.471-1.478-25.542c-1.998-4.686-3.966-9.742-5.688-14.881c2.068,5.344,4.374,10.673,7.067,15.72
c6.909,12.952,20.498,15.406,20.498,15.406s-1.832-14.029-7.581-22.041c-3.952-5.505-7.874-11.654-11.551-17.83
c4.059,6.22,8.622,12.438,13.631,18.048c9.774,10.953,25.27,9.178,25.27,9.178s-7.323-12.085-14.767-18.552
c-4.283-3.722-8.589-7.824-12.754-12.019c4.513,4.047,9.319,7.944,14.31,11.39c12.077,8.341,27.281,0.931,27.281,0.931
s-10.533-7.219-18.926-12.302c0.595,0.332,1.186,0.662,1.777,0.988c12.922,7.14,28.146-3.013,28.146-3.013
s-12.036-5.887-21.343-9.313C389.896,118.341,386.055,116.903,382.184,115.435z M116.917,367.418
c-0.172,0.131-0.344,0.268-0.516,0.398c-17.301-3.899-29.646-12.415-31.124-28.752c-2.244-24.777,21.669-42.631,47.562-54.59
c3.553,1,9.203,1.919,15.541,0.503c-4.694,4.817-7.998,9.859-7.998,9.859s2.076,0.564,5.3,0.733
C133.582,308.673,115.917,333.715,116.917,367.418z M146.295,295.598c1.834,0.062,3.979-0.014,6.326-0.386
c-0.141,0.365-0.274,0.72-0.401,1.069c-10.511,14.57-18.745,34.363-17.404,59.912c-4.522,2.267-9.248,5.074-13.939,8.343
C122.237,330.3,136.218,307.613,146.295,295.598z M121.776,368.86c4.131-2.979,8.589-5.697,13.361-8.115
c0.358,3.527,1.032,6.741,2.025,9.634C131.805,370.131,126.629,369.657,121.776,368.86z M150.478,350.278
c-3.791,0.864-8.16,2.403-12.812,4.546c-0.062-0.425-0.168-0.803-0.224-1.236c-2.557-19.875,3.873-37.276,13.005-51.347
c0,0.005-0.007,0.032-0.007,0.032s13.533-3.395,23.088-14.017c-1.715,7.205,0.158,14.79,0.158,14.79s9.774-5.185,16.654-15.216
c-0.131,5.548,2.84,10.803,5.451,14.331C193.303,321.731,182.711,342.934,150.478,350.278z M259.516,275.357
c0.846-4.127,1.649-8.135,2.42-12.012c2.199-4.002,5.203-6.524,9.011-7.55c3.808-1.04,7.78-1.559,11.919-1.559l1.739-17.042
c-5.942,0.378-11.657,1.419-17.144,3.105c-5.492,1.672-10.946,3.611-16.369,5.8c-4.526,4.131-7.915,8.875-10.169,14.237
c-2.262,5.359-3.755,11.051-4.655,17.055c-0.906,6.007-1.268,12.17-1.268,18.489v18.209c0,3.23,0.201,6.368,0.779,9.393
c0.584,3.045,1.728,5.66,3.543,7.85c3.614,2.588,7.203,3.85,10.822,3.771c3.619-0.066,7.224-0.712,10.842-1.925
c3.611-1.23,7.162-2.757,10.647-4.558c3.484-1.811,6.904-3.293,10.266-4.457l7.159-14.521c-2.066,0.505-4.2,1.23-6.394,2.127
c-2.199,0.9-4.453,1.643-6.777,2.224c-2.322,0.585-4.649,0.773-6.977,0.585c-2.322-0.189-4.649-1.2-6.976-2.994
c-2.063-3.626-3.355-7.475-3.87-11.541c-0.519-4.065-0.612-8.165-0.289-12.296C258.1,283.619,258.674,279.488,259.516,275.357z
M367.6,320.582c-0.196-3.025-1.001-5.908-2.42-8.623c-1.031-3.608-2.649-6.588-4.846-8.905c-2.193-2.333-4.682-4.162-7.458-5.516
c-2.773-1.358-5.712-2.364-8.812-3.014c-3.098-0.643-6.004-1.056-8.717-1.259c-2.711-0.188-5.101-0.285-7.166-0.285
s-3.419-0.062-4.064-0.189c0.25-1.037,0.449-2.302,0.574-3.783c0.133-1.481,0.322-2.866,0.584-4.162
c0.258-1.419,0.512-2.977,0.773-4.65c6.326,0,12.073-0.581,17.242-1.749c5.165-1.148,9.688-3.059,13.558-5.705
c3.876-2.646,7.135-6.131,9.781-10.469c2.649-4.318,4.558-9.583,5.715-15.776c-5.684,0-11.596,0.029-17.727,0.093
s-12.328,0.158-18.593,0.284c-6.266,0.143-12.431,0.332-18.5,0.583c-6.066,0.27-11.812,0.584-17.236,0.979
c0.128,0,0.221,1.387,0.293,4.161c0.062,2.775,0.062,6.465,0,11.035c-0.072,4.588-0.2,9.788-0.386,15.589
c-0.199,5.819-0.49,11.73-0.875,17.734c-0.386,6.007-0.878,11.901-1.451,17.72c-0.584,5.815-1.262,10.908-2.035,15.304
c5.552-0.268,11.432-0.488,17.624-0.677c2.162-0.065,4.33-0.127,6.503-0.176l1.247-5.547c0.385-2.192,0.708-4.776,0.969-7.739
c0.259-2.979,0.513-5.754,0.773-8.338c0.259-3.093,0.386-6.196,0.386-9.286c0.646-0.127,1.677-0.206,3.103-0.206
c1.547,0,3.225,0.269,5.039,0.773c1.804,0.519,3.68,1.292,5.612,2.334c1.938,1.041,3.615,2.522,5.034,4.46
c1.42,1.925,2.45,4.352,3.104,7.252c0.638,2.914,0.638,6.495,0,10.75l0.631,5.39c1.609,0.033,3.207,0.079,4.796,0.144
c6.068,0.189,11.812,0.471,17.234,0.866C367.891,326.747,367.795,323.609,367.6,320.582z M327.506,263.345
c0.707-4.397,1.323-8.133,1.835-11.238c1.168-0.521,2.522-0.835,4.069-0.962c1.549-0.125,3.103-0.205,4.65-0.205
c1.677,0,3.291,0.031,4.845,0.112c1.547,0.062,2.901,0.093,4.069,0.093c0,1.151-0.041,2.586-0.103,4.256
c-0.066,1.688-0.189,3.42-0.389,5.232c-0.189,1.815-0.512,3.578-0.97,5.331c-0.446,1.732-1.127,3.182-2.034,4.347
c-0.896,0.918-2.128,1.657-3.681,2.224c-1.543,0.584-3.159,1.042-4.84,1.357c-1.677,0.33-3.291,0.55-4.838,0.677
c-1.555,0.141-2.78,0.207-3.682,0.207C326.439,271.542,326.798,267.727,327.506,263.345z M393.035,246.385
c-2.517,0.33-4.84,0.584-6.97,0.773c-2.135,0.205-3.781,0.172-4.939-0.096l3.678,2.711c0.899,5.423,1.356,11.051,1.356,16.851
c0,5.818-0.195,11.695-0.584,17.642c-0.385,5.941-0.872,11.805-1.45,17.624c-0.581,5.801-1,11.427-1.261,16.85
c-0.907,4.522-1.519,9.238-1.835,14.139c-0.331,4.901-0.843,9.713-1.554,14.425c-0.708,4.712-1.812,9.3-3.297,13.761
c-1.48,4.443-3.773,8.481-6.869,12.107l-2.908,1.543c0.513,0.52,1.323,0.993,2.42,1.45c1.093,0.457,1.842,0.678,2.23,0.678
c2.708-3.23,4.712-6.558,6.004-9.978c1.286-3.419,2.64-6.746,4.069-9.963c1.544-2.711,2.969-5.626,4.261-8.716
c1.286-3.107,2.774-6.008,4.455-8.719c1.671-2.708,3.681-5.045,6.008-6.984c2.322-1.938,5.285-3.15,8.903-3.67
c0.386-6.319,0.836-13.114,1.354-20.335c0.517-7.235,1.001-14.534,1.451-21.896c0.457-7.361,0.846-14.596,1.168-21.689
c0.323-7.111,0.482-13.684,0.482-19.769c-2.713,0-5.458,0.143-8.229,0.394C398.196,245.785,395.553,246.07,393.035,246.385z
M483.002,245c0,4-0.061,5.618-0.188,7.038c-0.135,1.419-0.323,3.525-0.581,5.259c-0.261,1.751-0.584,4.166-0.972,6.752
c-0.386,2.584-0.843,6.388-1.354,11.165c-0.519,4.791-1.135,11.551-1.839,19.167c-0.715,7.612-1.519,18.619-2.427,29.619h-32.15
c0-15,1.065-26.686,3.192-39.535c2.138-12.847,4.101-25.911,5.911-38.695c-5.034,0.52-9.85,1.042-14.427,1.812
c-4.589,0.773-9.136,0.898-13.662,0.52c-0.513,13.682-1.543,27.507-3.097,41.521c-1.553,13.998-3.23,27.586-5.038,40.749
c4.52,0,9.396-0.166,14.631-0.496c5.224-0.316,10.292-0.479,15.2-0.479c0.649,1.152,1.285,2.776,1.942,4.838
c0.638,2.065,1.22,4.318,1.738,6.779c0.517,2.457,0.997,5.027,1.454,7.753c0.447,2.715,0.873,5.424,1.258,8.135
c0.9,6.32,1.681,13.102,2.327,20.336c2.192-6.196,4.454-12.28,6.777-18.209c1.938-5.045,4.004-10.262,6.196-15.699
c2.199-5.423,4.327-10.073,6.393-13.936c2.323,0.254,4.649,0.316,6.974,0.188c2.326-0.124,4.681-0.25,7.071-0.392
c2.386-0.127,4.775-0.127,7.163,0c2.389,0.142,4.681,0.52,6.88,1.165c-0.257-6.716-0.164-13.619,0.293-20.728
c0.449-7.093,1.096-14.204,1.932-21.297c0.841-7.111,1.707-15.14,2.615-22.062c0.907-6.901,1.742-13.27,2.522-21.27H483.002z"/>
</svg>

Before

Width:  |  Height:  |  Size: 15 KiB

View file

@ -1,105 +0,0 @@
# 32-bit tasks C/R
## Compatible applications
On x86_64, there are two types of compatibility mode applications:
- ia32: Compiled to run on an i686 target, these can be executed on x86_64 if the `IA32_EMULATION` configuration option is enabled.
- x32: Specially compiled binaries designed to run on x86_64 with the `CONFIG_X86_X32` configuration option enabled.
Both use 4-byte pointers and thus can address no more than 4 GB of virtual memory.
However, x32 uses the full 64-bit register set and therefore cannot be launched natively on an i686 host.
Both require an additional environment on x86_64, such as Glibc, libraries, and compiler support.
x32 is rarely distributed; currently, only the [Debian x32 port](https://wiki.debian.org/X32Port) is easily found.
Currently, CRIU supports ia32 C/R. Support for x32 can be added relatively easily, as the necessary kernel patches for ia32 C/R are already in place.
In this document, the terms *compatible* and *32-bit* refer to ia32 applications unless otherwise specified.
## Difference between native and compatibility mode applications
From the CPU's point of view, 32-bit compatibility mode applications differ from 64-bit applications by the current Code Segment (CS) selector. If the L-bit (Long mode) in the segment descriptor is set, the CPU operates in 64-bit mode when that descriptor is used. There are other differences between 32-bit and 64-bit selectors; for more details, see [the article "The 0x33 Segment Selector (Heavens Gate)"](https://www.malwaretech.com/2014/02/the-0x33-segment-selector-heavens-gate.html). Code selectors for both modes are defined in kernel headers as `__USER32_CS` and `__USER_CS`, corresponding to descriptors in the Global Descriptor Table (GDT). The mode can be switched from 64-bit to compatibility mode by changing the CS value (e.g., using a long jump).
From the Linux kernel's point of view, applications differ based on values set during `exec`, such as `mmap_base` or thread info flags like `TIF_ADDR32`, `TIF_IA32`, or `TIF_X32`.
Both native and compatibility mode applications can perform either 32-bit or 64-bit syscalls.
## Mixed-bitness applications
The current kernel ABI allows for the creation of mixed-bitness applications, which can become quite complex.
For instance, an application could set both 32-bit and 64-bit robust futex list pointers.
Alternatively, a multi-threaded application could have some threads executing 32-bit code while others execute 64-bit code.
If support for such mixed-bitness applications is ever needed, it could be added to CRIU relatively easily. However, this should likely be a compile-time configuration option to avoid adding unnecessary syscalls to standard C/R operations.
Currently, there are no plans to add this support, as such applications are unlikely to be encountered outside of synthetic tests.
## Approaches to C/R for compatibility mode applications
32-bit C/R can be implemented in several ways. This section describes the pros and cons of various approaches and explains why the current implementation was chosen.
### Restore via exec() of a 32-bit dummy binary vs. from 64-bit CRIU
Restoring a 32-bit application could be done using a 32-bit daemon that communicates with the 64-bit CRIU binary or a 32-bit CRIU subprocess.
**Pros**:
- No kernel patches expected (though `vDSO mremap()` would still require support).
**Cons**:
- The CRIU codebase lacks a dedicated restore daemon, requiring significant rework.
- A 64-bit application can have a 32-bit child, which in turn could parent a 64-bit process. This would require re-executing the native 64-bit CRIU from the 32-bit dummy or subprocess.
- It would be necessary to send process properties, open image file descriptors, and shared memory containing the parsed `ps_tree` to the daemon. The volume of IPC calls would slow down the restoration process.
- Restoration becomes more complex, especially when considering user and PID namespaces.
- Task properties that are erased during `exec()` cannot benefit from optimized inheritance.
- A separate daemon would also be needed for x32.
### Restore with a flag to sigreturn() or arch_prctl()
The initial attempt to implement 32-bit C/R was rejected by the LKML community for several reasons. It involved swapping thread info flags (e.g., `TIF_ADDR32`, `TIF_IA32`, `TIF_X32`), unmapping the native 64-bit vDSO, and mapping the 32-bit vDSO based on a bit in the `rt_sigreturn()` sigframe or a dedicated `arch_prctl()` call.
**Pros**:
- Simple for CRIU: just perform a `sigreturn` with the new bit set or call `arch_prctl` before `sigreturn`.
**Cons**:
- If the 32-bit vDSO on the restoration host differs from the dumped image, the task must be intercepted after `sigreturn` to create jump trampolines (this is simpler with `arch_prctl`).
- Too many potential failure points for a single syscall; overly complex.
- Allowing userspace to swap thread info flags could introduce new race conditions and bugs (e.g., since the `TASK_SIZE` macro depends on `TIF_ADDR32`, memory mapping behavior might become unpredictable).
Following LKML discussions, it was decided to separate personality changes from the vDSO mapping API, remove the `TIF_IA32` flag that distinguished 32-bit from 64-bit tasks, and instead rely on the nature of the syscall (compat, x32, or native).
### Seizing with separate 32-bit and 64-bit parasites
**Pros**:
- No 32-bit calls in the 64-bit parasite and vice-versa.
- Since `ptrace` does not allow setting a 32-bit register set on a 64-bit task (and vice versa), using a parasite of the same nature as the task avoids these limitations.
**Cons**:
- Requires maintaining two or three (for x32) separate parasite blobs.
- Requires complex Makefile macros to build multiple parasites.
- Serializing parasite responses is difficult because argument sizes differ between modes, leading to complex and less readable C macros.
### Current approach
CRIU (a 64-bit process) handles 32-bit (ia32) tasks through a series of architecture-specific transitions:
1. **Architecture Detection**: CRIU uses `ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov)` to detect the task's architecture. The kernel returns different register set sizes depending on the mode: `sizeof(user_regs_struct64)` for native 64-bit tasks and `sizeof(user_regs_struct32)` for 32-bit compatibility mode tasks.
2. **Dumping**: When dumping a 32-bit task, CRIU uses the 64-bit `ptrace` interface. The kernel handles the internal mapping of 32-bit registers into the structure expected by CRIU.
3. **vDSO Handling**: To ensure the restored task uses a vDSO compatible with the current kernel, CRIU uses the `arch_prctl(ARCH_MAP_VDSO_32, addr)` system call (available since kernel v4.8) to map the 32-bit vDSO into the restored process's address space.
4. **Restoration via Sigreturn**: The final restoration of 32-bit registers is performed using a 32-bit `rt_sigreturn` call:
* CRIU prepares a 32-bit signal frame (`rt_sigframe_ia32`) on the target task's stack.
* The CRIU restorer code, running in 64-bit mode, executes a far return (`lretq`) to switch the CPU to 32-bit mode with the `USER32_CS` (0x23) segment selector.
* Once in 32-bit mode, it executes `int $0x80` with the `__NR32_rt_sigreturn` syscall number. The kernel then restores all registers from the 32-bit sigframe and resumes the task in 32-bit mode.
## To-Do
### vsyscall page handling
The `vsyscall` page is an emulated, fixed-address page (`0xffffffffff600000`) used for legacy support. It is not a standard VMA and is marked as `VMA_AREA_VSYSCALL` by CRIU, which avoids dumping or restoring its contents. Since its presence in `/proc/<pid>/maps` depends on kernel configuration (`vsyscall=emulate` or `vsyscall=xonly`), it can introduce noise during ZDTM tests that compare memory layouts. Consequently, tests are often run with `vsyscall=none`.
### Error reporting on x32 binary dumping
Currently, CRIU does not support x32 binaries (64-bit registers with 32-bit pointers). While the infrastructure for 32-bit pointers exists, the specific register handling and vDSO mapping for x32 are not implemented. Attempting to dump an x32 binary should result in an explicit error.
### Removal of TIF_IA32 from the kernel
The `TIF_IA32` thread info flag was historically used to distinguish 32-bit tasks. Kernel efforts (merged in v5.11) have moved towards relying on the nature of the syscall (compat vs. native) rather than a persistent thread flag. This unification simplifies how the kernel and CRIU interact, particularly for tracing tools like uprobes.
## External links
- [GitHub issue](https://github.com/checkpoint-restore/criu/issues/43)

View file

@ -1 +0,0 @@
index.md

View file

@ -1,32 +0,0 @@
# Asynchronous I/O (AIO)
CRIU supports checkpointing and restoring kernel-level Asynchronous I/O (AIO) contexts, which are managed via the `io_setup`, `io_submit`, `io_getevents`, and `io_destroy` system calls.
## How CRIU Handles AIO
To successfully checkpoint and restore an AIO context, CRIU manages three primary components:
1. **The AIO Ring Buffer**: This is a memory-mapped area where the kernel and userspace communicate. CRIU identifies these areas by their `[aio]` label in `/proc/pid/maps` or by detecting the specific VMA attributes.
2. **Completed Events**: Events that have finished and are already residing in the ring buffer are dumped as part of the process's memory.
3. **AIO Context State**: This includes the kernel's internal tracking of the ring's head and tail.
### The Restoration Process
The restoration of an AIO ring is complex because the kernel's AIO context ID (the `aio_context_t` value) is an internal pointer that cannot be arbitrarily assigned by userspace. CRIU uses the following strategy to restore it:
1. **New Ring Creation**: The restorer calls `io_setup` to create a fresh AIO ring with the original number of requested events.
2. **Tail Synchronization**: To move the kernel's internal `tail` pointer to the original position, CRIU submits dummy I/O requests (typically writes to `/dev/null`). Since these operations are synchronous for the device, the kernel advances the tail as each request completes.
3. **Head Synchronization**: CRIU manually adjusts the `head` pointer in the ring header to match the state at the time of the dump.
4. **Event Data Restoration**: The original `io_events` data (the completed but unread events) is copied from the dump image into the new ring buffer.
5. **Memory Remapping**: Finally, CRIU uses `mremap` to move the new ring buffer to its original virtual address, ensuring the application can continue using its existing AIO context ID.
## Limitations: In-Flight Events
Currently, **in-flight events** (I/O requests that have been submitted but not yet completed at the time of the dump) are **not supported**.
* **Dumping**: CRIU's parasite code checks for AIO rings but does not currently wait for pending requests to complete. If a request completes during or after the dump, it may lead to data inconsistency or a failed restore.
* **Restoring**: There is no mechanism to re-submit pending I/O requests upon restoration. Applications using AIO should ideally be in a quiescent state (all submitted I/O completed) before being checkpointed.
## See also
* [Memory dumping and restoring](memory-dumping-and-restoring.md)

View file

@ -1,35 +0,0 @@
# AppArmor Support
CRIU provides support for checkpointing and restoring **AppArmor** security profiles and namespaces. This is a critical feature for containerized environments (like Docker, LXC, or Podman) where each container frequently operates under its own set of specialized security policies.
## How CRIU Handles AppArmor
AppArmor integration in CRIU ensures that restored processes continue to operate under the same security constraints as the original processes, while also managing the temporary permissions needed for the checkpointing process itself.
### 1. Checkpointing (Dumping)
During the dump phase, CRIU detects the AppArmor state of each task:
* **Profile Identification**: CRIU captures the active profile name for every thread (e.g., `unconfined`, `docker-default`, or a custom user-defined profile).
* **Namespace and Policy Dumping**: In modern containerized setups, containers often have their own AppArmor namespaces. CRIU walks the `/sys/kernel/security/apparmor/policy/` directory to capture the full hierarchy of namespaces and the raw binary blobs of all loaded policies.
* **Parasite Profile**: To allow the [Parasite Code](parasite-code.md) to perform its necessary inspections (like opening network sockets or reading memory) without being blocked by the application's strict security policy, CRIU temporarily transitions the task into a special, permissive "parasite profile" while it is infected.
### 2. Restoration
Restoring AppArmor state involves re-establishing the security context before the process resumes:
* **Policy Loading**: CRIU uses the `apparmor_parser` utility on the destination host to re-load the policy blobs captured in the image files.
* **Namespace Reconstruction**: It recreates any nested AppArmor namespaces to match the original environment.
* **Profile Re-attachment**: As each process is restored, CRIU ensures it is transitioned back into its original profile (or stack of profiles) using the `aa_change_profile()` interface before the application code begins executing.
## Support for Stacking
Modern AppArmor implementations support **Profile Stacking**, where multiple security profiles are applied to a single process simultaneously (e.g., a container-wide profile plus a per-application profile). CRIU correctly identifies, dumps, and restores these complex stacked configurations.
## Kernel Requirements
Reliable AppArmor C/R requires:
* A kernel with `CONFIG_SECURITY_APPARMOR` enabled and active.
* The `securityfs` filesystem mounted (typically at `/sys/kernel/security`).
* Support for AppArmor policy introspection and namespaces, which is standard in modern distributions like Ubuntu and Debian.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Parasite Code](parasite-code.md)
* [Kerndat Feature Detection](kerndat.md)

View file

@ -1,32 +0,0 @@
# ARM64 Guarded Control Stack (GCS)
CRIU supports checkpointing and restoring the **Guarded Control Stack (GCS)** feature on ARM64 (AArch64) architectures. GCS is a hardware-assisted shadow stack mechanism designed to prevent return-oriented programming (ROP) attacks by maintaining a protected stack of return addresses.
## How CRIU Handles GCS
GCS support is integrated into CRIU's architecture-specific code for AArch64 (`arch/aarch64/gcs.c`).
### 1. Checkpointing (Dumping)
During the dump phase, CRIU detects if a task has GCS enabled by checking its CPU features and hardware capabilities (`HWCAP_GCS`).
* **State Capture**: CRIU uses `ptrace(PTRACE_GETREGSET, ..., NT_ARM_GCS, ...)` to retrieve the current GCS state.
* **Key Parameters**:
* `gcspr_el0`: The current Guarded Control Stack Pointer.
* `features_enabled`: The GCS configuration flags (e.g., `PR_SHADOW_STACK_ENABLE`).
* **VMA Identification**: CRIU identifies the memory region (VMA) used for the shadow stack, which is marked with special kernel attributes.
### 2. Restoration
Restoring GCS requires carefully re-establishing the shadow stack before the process resumes normal execution.
* **Shadow Stack Mapping**: CRIU uses the `map_shadow_stack` system call to recreate the shadow stack at its original virtual address.
* **Context Setup**: The captured GCS state (`gcspr_el0` and flags) is integrated into the task's **restorer context**.
* **Sigframe Integration**: To ensure a seamless transition, CRIU places a `gcs_context` entry into the signal frame used for the final `sigreturn`. This informs the kernel to switch to the restored shadow stack as the process resumes.
## Kernel Requirements
GCS support in CRIU requires an ARM64 host and a kernel that supports the Guarded Control Stack ABI, typically including:
* `PR_SHADOW_STACK_ENABLE` prctl support.
* The `map_shadow_stack` system call.
* `NT_ARM_GCS` ptrace regset.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Restorer Context](restorer-context.md)

View file

@ -1,36 +0,0 @@
# BPF Maps
BPF maps are kernel objects that store data used by BPF programs, typically in the form of key-value pairs. Applications access these maps via file descriptors. Checkpointing and restoring BPF maps involves serializing both their **metadata** and their **data contents**.
## How CRIU Handles BPF Maps
### Metadata Serialization
CRIU collects essential map attributes from several sources:
- **/proc filesystem**: Essential fields such as `map_type`, `key_size`, `value_size`, `max_entries`, and the `frozen` status are parsed from the task's `fdinfo`.
- **BPF System Call**: CRIU uses the `bpf` system call with the `BPF_OBJ_GET_INFO_BY_FD` command to retrieve additional information, including the map name and interface index (`ifindex`).
### Data Serialization
To preserve the map's contents, CRIU relies on batch operations:
- **Dumping**: During the checkpoint stage, CRIU uses `BPF_MAP_LOOKUP_BATCH` to efficiently read all key-value pairs from the map.
- **Restoring**: During the restore phase, CRIU recreates the map and uses `BPF_MAP_UPDATE_BATCH` to repopulate it with the saved key-value pairs.
### Supported Map Types
CRIU currently supports data serialization for the following BPF map types:
- `BPF_MAP_TYPE_HASH`
- `BPF_MAP_TYPE_ARRAY`
For other map types, CRIU may be able to restore the map itself (metadata) but not its contents, depending on kernel support for batch operations on those types.
### Frozen Maps
If a BPF map was marked as read-only (frozen) using `bpf_map_freeze()`, CRIU detects this state from `fdinfo` and reapplies the freeze during restoration after the data has been repopulated.
## To-Do
- **BTF Support**: Serialization and restoration of BPF Type Format (BTF) information associated with maps.
- **Extended Map Types**: Implementation of data serialization for more BPF map types (e.g., `BPF_MAP_TYPE_PERF_EVENT_ARRAY`, `BPF_MAP_TYPE_LPM_TRIE`).
- **Map Extra Data**: Full support for `map_extra` fields introduced in recent kernels (currently only partially parsed with limited restoration).
## External Links
- [BPF Documentation](https://www.kernel.org/doc/html/latest/bpf/index.html)
- [Notes on BPF](https://blogs.oracle.com/linux/notes-on-bpf-1)
- [An eBPF Overview](https://www.collabora.com/news-and-blog/blog/2019/04/05/an-ebpf-overview-part-1-introduction/)

View file

@ -1,56 +0,0 @@
# CGroups
CRIU provides comprehensive support for checkpointing and restoring Control Groups (CGroups) for both cgroup v1 and cgroup v2.
## Overview
When managing CGroups, CRIU handles three main aspects:
1. **Process Placement**: The specific cgroup sets (a list of controller/path pairs) that each task in the process tree belongs to.
2. **Hierarchy and Properties**: The existing cgroup directory tree, its permissions, and various control properties (e.g., CPU shares, memory limits).
3. **Namespace Boundaries**: Support for CGroup namespaces (`CLONE_NEWCGROUP`), ensuring that the restored tasks have the same view of the cgroup hierarchy.
## Default Behavior
By default, CRIU manages cgroups in **soft mode** (`--manage-cgroups=soft`). In this mode:
* CRIU automatically dumps process cgroup memberships.
* Upon restoration, it attempts to recreate the cgroup hierarchy and restore properties for cgroups that it created.
* If a cgroup already exists, CRIU avoids overwriting its properties to prevent interference with other tasks on the system.
## CGroup V2 Support
CRIU fully supports the unified cgroup v2 hierarchy. Key features include:
* **Global Properties**: Restoration of global v2 attributes such as `cgroup.subtree_control`, `cgroup.max.descendants`, and `cgroup.max.depth`.
* **Process Migration**: Moving tasks between v2 cgroups using `cgroup.procs` (or `cgroup.threads` for threaded controllers).
* **Freezer**: Integrated support for the cgroup v2 freezer mechanism (`cgroup.freeze`).
## CGroup Namespaces
CRIU leverages cgroup namespaces to accurately restore a container's view of the cgroup tree. During restoration:
1. It identifies the cgroup namespace boundary (the path prefix) for each controller.
2. It moves the root task into the appropriate cgroup relative to the host.
3. It calls `unshare(CLONE_NEWCGROUP)` to pin the root of the cgroup namespace to that location, matching the original environment.
## Mountpoints of the "cgroup" Filesystem
CRIU supports dumping and restoring cgroup filesystem mountpoints. However, a significant limitation exists regarding bind-mounted subgroups:
**Root Mount Requirement**: By default, CRIU expects to find the "root" mount of a cgroup controller (where the mount root is `/`) within the dumped mount namespace.
* If a container has only bind-mounted **subgroups** (e.g., `/sys/fs/cgroup/memory/my-container` is bind-mounted to `/sys/fs/cgroup/memory`) without a corresponding root mount of that controller being visible, CRIU may fail the dump.
* This is because CRIU needs to identify the full path of the cgroup relative to the hierarchy root to accurately reconstruct it.
To overcome this, such mounts must often be treated as **external mounts** (`--external mnt[...]`) or the full hierarchy must be made visible to CRIU during the dump.
## CGroups Restoration Strategy
The `--manage-cgroups=MODE` option allows for fine-grained control:
* `none`: Requires cgroups to pre-exist; does not restore properties.
* `props`: Requires cgroups to pre-exist; restores properties from the image.
* `soft` (Default): Restores properties only for cgroups created by CRIU.
* `full`: Always recreates all cgroups and restores all properties.
* `strict`: Recreates all cgroups from scratch; fails if any already exist.
* `ignore`: Completely ignores cgroup information.
## External CGroup Yard
The `--cgroup-yard PATH` option allows CRIU to use a pre-mounted cgroup hierarchy located at `PATH`. This is particularly useful in unprivileged environments where CRIU may not have the `CAP_SYS_ADMIN` capability required to mount cgroup filesystems itself. For every cgroup mount, there should be exactly one directory named after the controller(s) co-mounted there (or "unified" for cgroup v2).

View file

@ -1,46 +0,0 @@
# Changing IP Addresses During Migration
When performing a [live migration](live-migration.md) of a process between hosts, a common challenge is handling IP address changes. While the ideal solution often involves using containers with their own network namespaces and virtual IPs, migrating a service to a different physical IP address is sometimes necessary.
## The Core Problem
TCP connections are identified by a 4-tuple: (Source IP, Source Port, Destination IP, Destination Port). If either IP address changes during migration, the TCP stack on the peer will not recognize the migrated connection and will typically respond with a Reset (RST) or simply ignore the packets.
Consequently, there are three scenarios to consider when changing IPs:
### 1. Listening Sockets
If a server is bound to `0.0.0.0` (INADDR_ANY), it will "just work" after migration, as it will listen on all available interfaces on the new host. However, if the server is bound to a specific IP address that does not exist on the destination host, restoration will fail unless the binding is updated.
**Solutions:**
- **CRIT**: Use the [CRIT](../crit.md) tool to manually edit the `inetsk.img` or `files.img` images to update the binding address.
- **Plugins**: Use the `UPDATE_INETSK` plugin hook (see below) to programmatically change the IP address during restoration.
### 2. In-Flight Connections
These are connections that have been initiated but not yet accepted by the application. CRIU provides the `--skip-in-flight` option to ignore these connections during the dump.
### 3. Established Sockets
These are active connections. Changing the IP address of an established socket is technically possible but will usually break the connection unless specialized network-level translation (like NAT) is used.
**CRIU Solutions:**
- **--tcp-close**: This option tells CRIU to dump established connections but restore them in a closed state. This prevents application-level errors caused by "holes" in the file descriptor table while acknowledging that the specific network connection is terminated.
- **--tcp-established**: Used in combination with IP translation mechanisms (like NAT or proxies), this allows the connection to be restored.
## Programmatic IP Remapping (Plugins)
CRIU provides a plugin hook, `UPDATE_INETSK`, specifically for modifying socket attributes during restoration. A plugin can implement this hook to intercept the restoration of an INET socket and change its source or destination IP addresses.
```c
/* Plugin hook signature in criu-plugin.h */
int cr_plugin_update_inetsk(uint32_t family, uint32_t state, uint32_t *src_ip, uint32_t *dst_ip);
```
By modifying `src_ip` and `dst_ip` within the plugin, you can redirect sockets to new addresses as they are being recreated.
## Summary of Options
| Scenario | Recommendation | CRIU Flag / Tool |
| :--- | :--- | :--- |
| **Old IP not on new host** | Remap local binding | `CRIT` or `UPDATE_INETSK` plugin |
| **In-Flight Connection** | Ignore | `--skip-in-flight` |
| **Established Connection** | Terminate gracefully | `--tcp-close` |
| **Established Connection** | Maintain (requires NAT) | `--tcp-established` + remapping |

View file

@ -1,57 +0,0 @@
# Checkpoint and Restore Architecture
This page describes the high-level design and internal mechanics of the Checkpoint and Restore processes in CRIU.
## Checkpoint
The checkpoint procedure captures the full state of a process tree. It combines information from the Linux kernel's `/proc` filesystem with data extracted directly from the processes' address space.
### 1. Freezing the Process Tree
CRIU begins by identifying the process group leader (via the `--tree` option) and recursively collecting all threads and children. To ensure a consistent snapshot, the entire tree must be "frozen."
* **ptrace**: CRIU uses `PTRACE_SEIZE` followed by `PTRACE_INTERRUPT` to stop tasks without delivering signals that could be visible to the application.
* **Freezer CGroup**: Alternatively, the [Freezer CGroup](freezing-the-tree.md) can be used to freeze all tasks in a single operation.
### 2. Resource Collection (External State)
CRIU gathers state that the kernel exposes via `/proc`:
* **File Descriptors**: Parsed from `/proc/$pid/fdinfo` (which includes positions and flags).
* **Memory Maps**: Captured from `/proc/$pid/smaps` and `/proc/$pid/map_files`.
* **Core State**: Task statistics and basic identifiers from `/proc/$pid/stat`.
### 3. Parasite Injection (Internal State)
Some state (like memory contents and specific credentials) can only be captured from within the process. CRIU uses a technique called **parasite injection**:
1. **Infection**: CRIU uses `ptrace` to inject a small bit of code into the task's instruction stream (at the current `CS:IP`).
2. **Bootstrap**: This code executes an `mmap` syscall to allocate space for the full **parasite blob**.
3. **Execution**: The parasite code runs as a daemon inside the task, communicating with the CRIU coordinator via a Unix socket to dump memory pages and other internal metadata.
### 4. Cleanup
Once the state is captured, CRIU uses `ptrace` to remove the parasite code and restore the original instructions. The processes are then either resumed or killed, depending on the command-line options.
---
## Restore
The restore procedure is essentially the reverse of a checkpoint. CRIU "morphs" itself into the process tree it is restoring through a multi-stage process.
### 1. Resolve Shared Resources
CRIU analyzes the image files to identify resources shared between processes (e.g., shared memory segments, pipes, or inherited file descriptors). It determines which process will "create" the resource and how others will "inherit" it.
### 2. Fork the Process Tree
CRIU calls `fork()` repeatedly to recreate the original process hierarchy. To restore specific PIDs, it uses the `ns_last_pid` interface or the `clone3` system call. At this stage, only process leaders are created; threads are restored later.
### 3. Restore Basic Resources
Each process in the new tree begins restoring its environment:
* **Namespaces**: Joins or creates Network, Mount, UTS, and IPC namespaces.
* **Files and Sockets**: Reopens file descriptors and recreates network sockets.
* **Memory Prep**: Maps anonymous memory regions and fills them with data from the images.
### 4. The Restorer Context
To restore the final memory layout, CRIU must unmap its own code and data. This requires a **restorer blob**:
* **Self-Contained**: The blob is a Position-Independent Executable (PIE) that contains all necessary logic to perform the final `mmap` and `munmap` calls.
* **Non-Conflicting**: It is mapped into a "hole" in the task's address space that does not conflict with either CRIU's current mappings or the task's original mappings.
* **Final Transition**: The process jumps into the restorer blob, which unmaps CRIU, maps the final memory regions, restores timers and credentials, and recreates any additional threads.
### 5. Sigreturn
The very last step of the restorer is to call `sigreturn`. CRIU prepares a special signal frame on the stack that contains the original register state (including the instruction pointer) of the process at the time of the checkpoint. The `sigreturn` syscall tells the kernel to load this state and resume execution of the application code.
*See also: [Restorer Context](restorer-context.md), [Tree After Restore](tree-after-restore.md)*

View file

@ -1,68 +0,0 @@
# Code Blobs and PIE Generation
CRIU and its sub-project **Compel** use specialized binary blobs to execute code in environments where standard libraries and runtime environments are unavailable. These blobs are Position-Independent Executables (PIE) that are converted into C headers for easy integration into the main CRIU binary.
## Why Code Blobs are Necessary
CRIU operates in two primary scenarios that require these specialized environments:
1. **Parasite Code Execution**: During a checkpoint, CRIU injects code into the target process's address space to extract internal state (like memory contents and credentials). This code must be self-contained and PIE-compiled to run at any address.
2. **Restorer Context**: During restoration, the process must unmap its current memory (including CRIU's own code) and map the original memory of the checkpointed application. The code performing these operations must exist in a memory region that does not conflict with the target application's layout.
## Building PIE Code Blobs
The generation of these blobs is handled by the **Compel** utility. The process involves compiling C and assembly source files into a single ELF object and then using the `compel hgen` tool to transform that object into a C header.
### The `compel hgen` Tool
The `hgen` (header generator) tool performs the following tasks:
1. **Relocation Extraction**: It identifies all symbols that require relocation and creates a structured `compel_reloc` array.
2. **Binary Data Conversion**: It converts the allocated ELF sections (code and data) into a static C byte array.
3. **Bootstrap Initialization**: It generates a setup function (e.g., `parasite_setup_c_header`) that populates a `parasite_blob_desc` structure, which CRIU uses to manage the blob's lifecycle.
### Example Header Format
The generated header file typically contains:
```c
/* Relocation information */
static const struct compel_reloc parasite_relocs[] = {
{ .offset = 0x0000002c, .type = COMPEL_TYPE_INT, .addend = 0, .value = 0x12345678 },
...
};
/* The binary blob itself */
static const char parasite_blob[] = {
0x48, 0x8d, 0x25, 0x2d, 0x60, 0x00, 0x00, 0x48,
...
};
/* Setup function for CRIU integration */
static void parasite_setup_c_header_desc(struct parasite_blob_desc *pbd, bool native)
{
pbd->parasite_type = COMPEL_BLOB_CHEADER;
pbd->hdr.mem = parasite_blob;
pbd->hdr.bsize = sizeof(parasite_blob);
...
}
```
## Build Procedure
The build system follows these steps to generate the headers:
1. **Compilation**: Source files (like `parasite.c` or `restorer.c`) are compiled with PIE flags (`-fpie`, `-ffreestanding`, `-nostdlib`).
2. **Linking**: Object files are linked into a single `.built-in.o` file using a specialized linker script (`compel-pack.lds.S`) that organizes sections into a layout suitable for a standalone blob.
3. **Header Generation**: The `compel hgen` command is executed on the linked object to produce the final `-blob.h` header.
```bash
# Example Makefile recipe
$(obj)/parasite-blob.h: $(obj)/parasite.built-in.o
compel hgen -f $< -o $@
```
## See also
* [Parasite Code](parasite-code.md)
* [Restorer Context](restorer-context.md)
* [Compel Sub-project](../compel.md)

View file

@ -1,63 +0,0 @@
# Comparison to Other Checkpoint/Restore Projects
This page explains the primary differences between CRIU and other checkpoint/restore (C/R) solutions available for Linux.
## DMTCP (Distributed MultiThreaded Checkpointing)
DMTCP implements checkpoint/restore at the library level. To use it, an application must be launched with the DMTCP library dynamically linked from the start. This library intercepts library calls, builds an internal shadow database of the process state, and forwards requests to `glibc` or the kernel.
**Key Characteristics of DMTCP:**
* **No Kernel Patches**: Works on standard kernels without requiring specific features.
* **Library Level**: Intercepts calls at the userspace level, which can introduce performance overhead.
* **PID Virtualization**: Since the kernel does not traditionally allow setting a specific PID during fork, DMTCP "fools" the application by intercepting `getpid()` and returning a fake value. This can be problematic if the application accesses `/proc` using its real PID.
* **Limited API Coverage**: May not support all kernel APIs (e.g., `inotify` support is limited).
In contrast, **CRIU** does not require pre-loading libraries. It uses standard kernel interfaces (extended where necessary for C/R) to transparently capture and restore arbitrary applications.
## BLCR (Berkeley Lab Checkpoint/Restart)
BLCR is a system-level checkpointer designed primarily for High Performance Computing (HPC) and MPI jobs. It is implemented as a loadable kernel module.
**Key Characteristics of BLCR:**
* **Kernel Module**: Requires a specific GPL-licensed kernel module.
* **HPC Focused**: Optimized for CPU and memory-intensive batch jobs.
* **Limited Scope**: Traditionally lacks support for complex modern features like namespaces, containers, or diverse socket types.
## PinPlay
PinPlay is a checkpointing tool built on top of Intel's PIN binary instrumentation tool. It is primarily used for deterministic replay and architectural simulation. It records architectural register state and memory pages, often focusing on reducing runtime for simulators.
## OpenVZ (In-Kernel)
Legacy OpenVZ (RHEL6 and earlier) featured an in-kernel C/R implementation. While highly efficient and robust for its time, it required a heavily patched kernel. CRIU was developed as the "user-space" successor to this technology, moving the logic out of the kernel to improve maintainability and facilitate upstream adoption.
---
## Comparison Table
| Feature | CRIU | DMTCP | BLCR | OpenVZ (Legacy) |
| :--- | :--- | :--- | :--- | :--- |
| **Architectures** | x86_64, ARM, AArch64, PPC64, s390, MIPS, RISC-V, LoongArch | x86, x86_64, ARM | x86, x86_64, PPC, ARM | x86, x86_64 |
| **OS** | Linux | Linux | Linux | Linux |
| **Standard Kernel?** | Yes (v3.11+) | Yes | Yes (needs module) | No (Custom kernel) |
| **No Preloading?** | Yes | No | No | Yes |
| **Non-Root Support?** | Yes (limited) | Yes | Yes | No |
| **Unmodified Apps?** | Yes | Yes | No (Static/Threaded issues) | Yes |
| **Unprepared Tasks?** | Yes | No | No | Yes |
| **Retains Behavior?** | Yes | No (Wrappers used) | No (Wrappers used) | Yes |
| **Live Migration** | Yes (Optimized) | Yes | Yes (Identical env only) | Yes |
| **Containers** | Yes (LXC, Docker, Podman) | No | No | Yes |
| **GDB Support** | No (same interface) | Yes | No | Yes |
| **Unix Sockets** | Yes | Yes | No | Yes |
| **TCP Sockets** | Yes | Yes | No | Yes |
| **Established TCP** | Yes | No (needs plugin) | No | Yes |
| **Namespaces** | Yes | No | No | Yes |
| **System V IPC** | Yes | Yes | No | Yes |
| **Non-POSIX Files** | Yes (Inotify, Epoll) | Yes | No | Yes |
| **Timers** | Yes | No | Yes | Yes |
## Sources and External Links
* **DMTCP**: [dmtcp.sourceforge.net](http://dmtcp.sourceforge.net/)
* **BLCR**: [ftg.lbl.gov/projects/CheckpointRestart](https://ftg.lbl.gov/projects/CheckpointRestart/)
* **CRIU FAQ**: [How does DMTCP differ?](http://dmtcp.sourceforge.net/FAQ.html#Internals)

View file

@ -1,42 +0,0 @@
# Copy-on-Write (COW) Memory Restoration
CRIU employs a specialized multi-stage process to preserve Copy-on-Write (COW) sharing of private anonymous memory mappings during restoration. This prevents the memory duplication that would occur if each process's memory were restored independently, thereby significantly reducing the memory footprint of the restored process tree.
## The Problem
When a process calls `fork()`, the Linux kernel optimizes memory usage by sharing private anonymous mappings between the parent and child. Physical pages are only duplicated (COW) when one of the processes modifies them.
Traditional checkpointing captures each process's memory separately. If restored naively (by mapping and filling each VMA individually), the kernel would allocate separate physical pages for the parent and child, even for pages that were originally shared. This leads to a massive increase in physical memory usage upon restoration.
## CRIU's COW Restoration Strategy
To keep COW mappings intact, CRIU performs restoration in a way that mimics the original `fork()` behavior.
### 1. Identifying COW Candidates
Before forking the process tree, CRIU analyzes the memory maps of all tasks:
* It compares each task's VMAs with those of its parent.
* Two VMAs are identified as COW candidates if they have identical start/end addresses, the same protection flags (e.g., `PROT_READ`, `PROT_WRITE`), and belong to the same executable.
* This mapping is stored internally, marking which VMAs are "inherited" from a parent.
### 2. Pre-mapping and Filling
During restoration, processes are created in a specific order:
1. **Root VMA Population**: If a VMA is the "root" of a COW set (it is not inherited), the restoring task maps it and fills it with data from the image files.
2. **Inheritance via Fork**: When a task forks a child, the child automatically inherits the parent's memory mappings via the standard kernel COW mechanism.
3. **Content Verification**: The child then iterates through its own memory images:
* It compares the page contents in the image with the data already present in its inherited memory (which it got from the parent).
* If the contents match exactly, the physical page remains shared with the parent.
* If they differ (meaning the page was modified in either process after the original fork), the child overwrites the page with the data from its image, triggering a kernel COW event for that specific page.
### 3. Cleaning Up (madvise)
A parent may contain pages that were unmapped or modified in the child process. To ensure the child's memory layout is perfectly accurate:
* CRIU maintains a bitmap of pages touched during the content verification stage.
* After all pages are processed, CRIU uses `madvise(MADV_DONTNEED)` on any pages that exist in the inherited VMA but were not present in the child's dump images. This effectively "punches holes" in the child's VMA to match its original state while preserving the sharing of other pages.
## Current Limitations
* **Reparenting to Init**: If a process was reparented to the system `init` (PID 1) and that `init` process is not part of the checkpointed process tree, CRIU cannot identify the parent's VMAs, and COW sharing will not be restored for that process.
* **VMA Movement**: If a VMA was moved (e.g., via `mremap`) after the original `fork()`, CRIU's current address-based matching algorithm will fail to identify it as a COW candidate.
## See Also
* [Memory Dumping and Restoring](memory-dumping-and-restoring.md)
* [Restorer Context](restorer-context.md)

View file

@ -1,26 +0,0 @@
# DMTCP vs. CRIU
This article explains the fundamental differences between CRIU and DMTCP (Distributed MultiThreaded Checkpointing), focusing on their architectural approaches to process capture and restoration.
## Architectural Approach
### DMTCP: Library-Level Interception
DMTCP implements checkpoint/restore at the **userspace library level**. To use it, an application must be launched with the DMTCP library dynamically linked (`LD_PRELOAD`).
* **Mechanism**: The library intercepts library calls (e.g., `glibc` wrappers for syscalls), builds an internal shadow database of the process state, and then forwards requests to the kernel.
* **Implications**: This approach can introduce performance overhead due to proxying. Only applications compatible with the DMTCP library can be reliably dumped. Furthermore, DMTCP may not support all kernel APIs; for instance, complex features like `inotify` or specific socket types may lack sufficient proxies.
### CRIU: Kernel-Level Integration
CRIU, by contrast, operates primarily from **outside the process** using standard kernel interfaces (extended where necessary for C/R).
* **Mechanism**: CRIU uses tools like `ptrace`, `/proc`, and specialized system calls (e.g., `kcmp`, `map_files`) to transparently capture the process state without requiring pre-loaded libraries.
* **Implications**: It can checkpoint and restore virtually any application, provided the kernel supports the required features. It requires a relatively modern kernel version but offers much deeper integration with system resources like namespaces and cgroups.
## PID Handling and Virtualization
Restoring a process tree often requires restoring specific Process IDs (PIDs).
* **DMTCP "Fake" PIDs**: Because the kernel does not traditionally allow userspace to request a specific PID during `fork()`, DMTCP "fools" the application. It intercepts the `getpid()` call and returns a fake value that matches the original PID. This is highly dangerous, as the application may see inconsistent information in the `/proc` filesystem (where directories are named by the *real* PID).
* **CRIU Real PIDs**: CRIU restores the **actual PID** of the process. It achieves this by using the `ns_last_pid` interface or the modern `clone3` system call with a specified PID. This ensures that the restored process has the exact same identity as the original, with no inconsistencies in `/proc` or other kernel interfaces.
## Summary
DMTCP is often easier to deploy on older kernels since it doesn't require specific kernel support, but it suffers from the inherent limitations and risks of userspace interception. CRIU is the more robust and transparent solution for modern Linux systems, offering faithful restoration of the entire process environment.

View file

@ -1,54 +0,0 @@
# Dumping File Descriptors
This document explains the internal mechanisms CRIU uses to capture the state of opened file descriptors (FDs).
## Linux File Objects: Inodes, Dentries, and Files
In the Linux kernel, an opened file is represented by a chain of three distinct objects:
1. **Inode**: Contains metadata (owner, type, size) and pointers to the actual data on disk.
2. **Dentry (Directory Entry)**: A helper object used to resolve file paths. An inode can have multiple dentries if hard links exist.
3. **File (or "File Description")**: Represents an active handle to a dentry/inode pair. It maintains state such as the current file position (`pos`) and access flags.
Crucially, **file descriptors** are per-task integers that point to these shared "File" objects. When a task calls `fork()`, the child's FDs point to the same "File" objects as the parent's.
## How CRIU Collects FD Information
Dumping FDs requires CRIU to collect state from both the kernel's `/proc` filesystem and the file objects themselves.
### 1. Identifying Open FDs
CRIU reads `/proc/$pid/fd/` and `/proc/$pid/fdinfo/` to determine which FD numbers are currently open and to retrieve their basic properties (position and flags).
### 2. Retrieving File Objects (SCM_RIGHTS)
To perform deeper inspection (like `fstat` or `ioctl`), CRIU needs a local copy of the file descriptor. It achieves this by:
* Injecting **parasite code** into the target task.
* Commanding the parasite to send the FDs to the CRIU coordinator via a Unix domain socket using the `SCM_RIGHTS` mechanism.
### 3. Detecting Shared Files (gen_id and kcmp)
To minimize image size and avoid redundant dumps, CRIU must identify if FDs in different tasks (or even the same task) point to the same underlying "File" object. It uses a two-stage optimization:
1. **gen_id**: CRIU calculates a "generation ID" based on the file's device ID, inode number, and current position. If two FDs have different `gen_id`s, they are guaranteed to be different.
2. **kcmp**: If `gen_id`s match, CRIU uses the `kcmp()` system call (with the `KCMP_FILE` flag) to definitively determine if the two descriptors refer to the same kernel "File" object.
## Image Storage
CRIU stores FD information in a two-tier structure:
### The `fdinfo-$id.img` Image
This per-task image maps task-specific FD numbers to global **File IDs**. Each entry contains:
* `fd`: The numeric descriptor in the task.
* `id`: A unique identifier for the underlying file object.
### Specialized File Images
The actual state of the file objects is stored in specialized images based on their type:
* `reg-files.img`: Regular files (includes the path).
* `pipes.img`: Pipes and FIFOs.
* `unixsk.img` / `inetsk.img`: Sockets.
* `signalfd.img`, `eventfd.img`, `epoll.img`, etc.
This separation allows CRIU to efficiently handle shared files: multiple `fdinfo` entries can point to a single entry in a specialized file image.
## See also
* [Kcmp Trees](kcmp-trees.md)
* [Parasite Code](parasite-code.md)
* [Invisible Files](invisible-files.md)

View file

@ -1,45 +0,0 @@
# Frequently Asked Questions (FAQ)
This page provides answers to common questions and technical insights into CRIU's behavior and limitations.
## General Questions
### Q: Why does CRIU dump parts of read-only code mappings?
**A**: Even if a mapping (like the code section of `/usr/bin/something`) is marked as read-only, it may still contain "dirty" pages that CRIU must dump. This typically happens due to **Copy-on-Write (COW)** events during dynamic linking, relocation patching, or if the process modified its own code via `mprotect` and `ptrace`.
### Q: How can I verify that my system is ready for CRIU?
**A**: Use the built-in check tool:
```bash
criu check --extra
```
This will verify that your kernel has all the necessary features (like `kcmp`, `ns_last_pid`, etc.) enabled. Additionally, running the [ZDTM Test Suite](zdtm-test-suite.md) is the best way to confirm functional correctness on your specific hardware and software stack.
### Q: Is it possible to change the IP address during live migration?
**A**: Yes, but with caveats. Since TCP connections are identified by their IP/Port 4-tuple, changing the IP will normally break established connections.
- If you can tolerate connection resets, use the `--tcp-close` flag.
- For listening sockets, you can use the `UPDATE_INETSK` plugin hook or the `CRIT` tool to remap addresses.
- For seamless migration, virtual IPs or network-level NAT are required. See [Changing IP Addresses](change-ip-address.md) for more details.
### Q: Why does restore fail with a "PID mismatch" error?
**A**: This occurs because the PID CRIU is trying to restore is already in use by another process on the system.
- **Solution**: The most common way to avoid this is to run the restored process inside a fresh **PID namespace**. This ensures that the PID range is entirely available to CRIU.
- **Internal Note**: CRIU uses the `ns_last_pid` kernel interface or the modern `clone3` system call to request specific PIDs during restoration.
### Q: Why does dump fail with "Cannot dump half of a stream unix connection"?
**A**: This usually happens when one end of a Unix domain socket is held by a process *outside* the process tree being checkpointed. CRIU cannot capture the state of the "external" peer, so it cannot safely restore the connection unless the socket is explicitly marked as external via the `--external unix[ino]` option.
---
## Testing (ZDTM)
### Q: Why do my ZDTM tests fail with "Permission Denied" even when run as root?
**A**: The `zdtm.py` test runner executes many sub-tests as a non-privileged user to verify CRIU's behavior in unprivileged environments. If your specific test requires root privileges, you must add `'flags': 'suid'` to the test's `.desc` file.
---
## Containers and Docker
### Q: Why can't I restore a Docker container onto a different image?
**A**: CRIU checkpoints the state of the processes, but it does **not** checkpoint the underlying filesystem. The process images contain paths to files that must exist exactly as they did during the dump.
- **Solution**: To restore a container, you must ensure the filesystem state is identical. In Docker, this often involves using `docker commit` to create an image of the container's filesystem at the moment of the checkpoint.
- **Modern Tools**: Container engines like Podman or newer versions of Docker/RunC handle this integration more seamlessly by managing the filesystem snapshots alongside the CRIU state.

View file

@ -1,44 +0,0 @@
# File Restoration Engine (fdinfo)
CRIU uses a sophisticated state machine to restore file descriptors (FDs) across a process tree, handling shared files, complex dependencies, and inter-process synchronization.
## Master and Slave Descriptors
In the Linux kernel, multiple FDs can refer to the same underlying "File Description." CRIU mirrors this by categorizing FDs into **Masters** and **Slaves**:
1. **Master**: For each unique file object, one FD is designated as the master. This process is responsible for the actual `open()`, `socket()`, or `pipe()` system call that recreates the object.
2. **Slaves**: All other FDs referring to the same object are slaves. They do not perform the creation call themselves; instead, they receive the file descriptor from the master.
3. **Transport (SCM_RIGHTS)**: CRIU uses Unix domain sockets and the `SCM_RIGHTS` mechanism to "send" file descriptors from the master process to slave processes.
## Per-Process Restore Loop
Each task in the process tree executes a loop (`open_fdinfos`) to restore its descriptors. The core of this loop is the `file_desc_ops->open()` method.
### The `open()` State Machine
The `open()` method for a master file can return one of three values:
* **0 (Success)**: The file is fully restored.
* **1 (In Progress)**: The file has been opened (or the process has started opening it), but it cannot be completed yet due to a dependency on another file. The loop will call this method again in the next iteration.
* **-1 (Failure)**: An error occurred, and restoration must abort.
### Early FD Distribution
To maximize parallelism, a master can return a valid FD in the `new_fd` argument even if it returns `1` (In Progress). This allows CRIU to immediately distribute the FD to all slave processes via `SCM_RIGHTS`, even before the master has finished its own restoration steps (e.g., a connected Unix socket waiting for its peer).
## Inter-Process Synchronization
CRIU uses **futexes** and a specialized event mechanism to coordinate between processes:
* **set_fds_event(pid)**: Signals a task that a file it was waiting for (as a slave) is now available or that a dependency has changed.
* **wait_fds_event()**: Causes a task to sleep until it receives a notification.
* **FLE Stages**: Each descriptor entry (`struct fdinfo_list_entry` or `fle`) transitions through stages: `INITIALIZED` -> `OPEN` -> `RESTORED`.
## Key Dependencies
The engine must resolve complex dependencies between different file types:
1. **TTYs**: A slave TTY can only be fully restored after its master peer is active.
2. **Unix Sockets**: A connected socket must wait for its peer to `bind()` to its address before it can `connect()`.
3. **Epoll**: An epoll FD can be created immediately, but adding FDs to its interest list must wait until those FDs are themselves restored.
4. **Pipes and Socketpairs**: These calls create two FDs at once. One is treated as the primary master, and the second is distributed to the appropriate task (which might be the same task or a different one).
## Technical Notes
* **Service FDs**: CRIU maintains its own internal FDs (for images, logs, etc.) in a "protected" range to avoid conflicts with the application's FDs during restoration.
* **Ordering**: Descriptors are generally restored in ascending order of their FD number to improve efficiency, though dependencies can override this order.

View file

@ -1,40 +0,0 @@
# Filesystem Peculiarities in CRIU
While Linux aims for a uniform filesystem interface, several filesystems have unique behaviors ("peculiarities") that require specialized handling in CRIU to ensure accurate checkpointing and restoration.
## BTRFS: Virtual Device Numbers
When you `stat()` a file on BTRFS, the kernel often reports a **virtual device ID** (`st_dev`) that is unique to that specific subvolume or snapshot. However, other kernel interfaces, such as `/proc/$pid/mountinfo` or the `sock_diag` subsystem, may report the **physical device ID**.
**Problem**: CRIU cannot rely on simple `st_dev` comparisons to identify which mount a file belongs to, as the virtual and physical IDs will mismatch.
**Solution**: CRIU performs userspace path-to-device resolution. It analyzes `/proc/$pid/mountinfo` to build a mapping between virtual and physical IDs, allowing it to correctly resolve file locations. See `mount.c:phys_stat_resolve_dev()`.
**Workaround**: In some environments (like Podman), disabling Copy-on-Write for the container storage (`chattr +C`) can mitigate some BTRFS-related complexities.
## NFS: "Silly Rename" and Unlinked Files
NFS handles unlinked but open files differently than local filesystems. When a file is unlinked while still open, the NFS client performs a **"Silly Rename"**, renaming the file to something like `.nfsXXX` instead of truly removing it.
**Problem**: CRIU's standard logic for detecting unlinked files (checking if `st_nlink == 0`) fails on NFS because the "silly renamed" file still has a link count of 1.
**Solution**: CRIU explicitly checks if a file resides on an NFS mount. If it does, it examines the filename for the `.nfs` prefix. If both conditions match, CRIU treats the file as "opened and unlinked," capturing its contents into the image as a **ghost file**. See `files-reg.c:nfs_silly_rename()`.
## OverlayFS: Path Inconsistencies and Link-Remap
OverlayFS, the standard for modern container engines, has several known issues:
1. **Path Mismatches (Pre-v4.2)**: On older kernels, `/proc/$pid/fd/` and `/proc/$pid/fdinfo/` could report paths that did not include the OverlayFS mountpoint. CRIU detects OverlayFS mounts and manually corrects these paths using information from the mount table.
2. **linkat() Failures**: In OverlayFS, the `linkat()` system call fails with `ENOENT` if the file being linked resides on a **lower layer** (read-only layer) and has been unlinked from the upper layer.
* **CRIU Response**: When a "link-remap" (linking a deleted file back to the filesystem) fails on OverlayFS, CRIU automatically falls back to dumping the file as a **ghost file** (copying its contents into the image).
## AUFS: Branch Path Leakage (Legacy)
AUFS (mostly superseded by OverlayFS) has a bug where `/proc/$pid/maps` reveals the path of a file within its internal **branch** directory instead of its visible path within the AUFS mount.
**Solution**: CRIU identifies AUFS mounts, reads the branch configuration from `sysfs`, and "fixes" the paths in the memory map to ensure the file can be correctly located during restoration. See `sysfs_parse.c:fixup_aufs_vma_fd`.
## See also
* [How Hard is it to Open a File?](how-hard-is-it-to-open-a-file.md)
* [Invisible Files](invisible-files.md)
* [Mount Points](mount-points.md)

View file

@ -1,44 +0,0 @@
# Process Tree Final States
This document describes the possible states a process tree can end up in after a successful CRIU **dump** or **restore** operation.
## Supported Final States
CRIU supports three primary final states for the process tree:
1. **Running (`TASK_ALIVE`)**: The processes continue execution as normal.
2. **Stopped (`TASK_STOPPED`)**: The processes are left in a stopped state (equivalent to receiving `SIGSTOP`).
3. **Dead (`TASK_DEAD`)**: The processes are terminated (equivalent to receiving `SIGKILL`).
## Controlling the Final State
You can specify the desired final state using the following command-line options:
* `--leave-running`: Forces the process tree to continue running after the operation.
* `--leave-stopped`: Forces the process tree to remain stopped after the operation.
### Default Behavior for `criu dump`
By default, `criu dump` terminates the process tree (**Dead**).
**Rationale**: Leaving a process tree running after a full dump is risky. If the processes continue to run, they will likely modify the filesystem, network state, or shared memory. These changes can make the captured image inconsistent or impossible to restore later, as the system state will no longer match the process's internal state at the moment of the dump.
* **Exceptions**: The `pre-dump` command always enforces the **Running** state, as its purpose is to capture memory changes while the application continues to operate.
### Default Behavior for `criu restore`
By default, `criu restore` resumes the process tree (**Running**).
**Rationale**: The primary goal of restoration is typically to resume the application's work immediately.
* **Debugging**: Using `--leave-stopped` during restoration can be extremely useful for debugging. It allows you to inspect the restored process tree (e.g., via `/proc` or a debugger) before it begins executing any code.
## Resuming a Stopped Tree
If a process tree was left in the **Stopped** state (either by dump or restore), you can resume its execution by sending a `SIGCONT` signal to all processes in the tree.
For complex process trees, the [pstree_cont.py](https://github.com/checkpoint-restore/criu-scripts/blob/master/pstree_cont.py) script (available in the `criu-scripts` repository) can be used to safely resume the entire hierarchy by targeting the root PID.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Freezing the Tree](freezing-the-tree.md)

View file

@ -1,37 +0,0 @@
# Freezing the Process Tree
Before CRIU can begin checkpointing, it must ensure that the entire process tree is completely "immobilized." This prevents tasks from changing their state (e.g., opening files, creating children, or receiving network packets) while the snapshot is being taken. This freezing process must be transparent to the application, meaning it should not observe any disruption or unexpected signals.
CRIU employs two primary methods to achieve this:
## Capturing with ptrace
The most common method for freezing a tree is using the Linux `ptrace` interface. Unlike traditional debuggers that might send disruptive signals like `SIGSTOP`, CRIU uses a more modern, non-invasive approach:
1. **SEIZE**: CRIU calls `ptrace(PTRACE_SEIZE, pid, ...)` for every task in the tree. This "attaches" to the process without stopping it or delivering any signals.
2. **INTERRUPT**: Once seized, CRIU sends a `ptrace(PTRACE_INTERRUPT, pid, ...)` command. This causes the kernel to stop the task at the next possible opportunity (typically upon entering or exiting a syscall or being preempted).
3. **WAIT**: CRIU then waits for the task to enter the `TRAP_STOP` state. This state is invisible to the task's own signal handling logic, ensuring transparency.
By seizing every task in the tree, CRIU ensures that no task can resume execution or fork new children during the dump.
## Using Freezer CGroups
For large process trees or environments where `ptrace` might be restricted or inefficient, CRIU can use the Linux **Freezer CGroup**. This allows the kernel to freeze an entire group of processes in a single, atomic operation.
CRIU supports both versions of the freezer:
### CGroup v1 Freezer
* **Mechanism**: CRIU identifies the freezer cgroup containing the process tree and writes `FROZEN` to the `freezer.state` file.
* **Handling Inconsistency**: Historically, the v1 freezer could be unreliable, sometimes getting stuck in a `FREEZING` state. CRIU includes "kludges" to handle this, such as periodically retrying the freeze command or briefly thawing and re-freezing the group to kick the kernel's internal state machine.
### CGroup v2 Freezer
* **Mechanism**: In the unified cgroup v2 hierarchy, CRIU writes `1` to the `cgroup.freeze` file.
* **Verification**: It then monitors the `cgroup.events` file, waiting for the `frozen 1` event to signal that all processes in the sub-hierarchy have successfully stopped.
**Note**: Even when using a freezer cgroup, CRIU still attaches to the tasks via `ptrace` after they are frozen. This is necessary to perform internal inspections, such as extracting register states and injecting parasite code.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Process Tree Final States](final-states.md)
* [Parasite Code](parasite-code.md)

View file

@ -1,38 +0,0 @@
# FSNotify (Inotify and Fanotify)
CRIU supports checkpointing and restoring `inotify` and `fanotify` instances. These mechanisms allow applications to monitor filesystem events (like file creation, modification, or deletion).
## The Challenges of FSNotify C/R
Restoring an fsnotify instance is inherently difficult because the kernel does not provide a direct way to retrieve the original path of a watched object (the "watchee"). Furthermore, the event queues themselves pose consistency risks.
### 1. Identifying the Watchee
When an application adds a watch (via `inotify_add_watch`), the kernel associates the watch with an **inode**, but it does not store the **path** used to create it. To restore the watch, CRIU must find a valid path to that specific inode.
* **Open by Handle**: CRIU first attempts to use `open_by_handle_at()`. If the filesystem supports file handles, CRIU captures the handle during the dump and uses it to re-open the inode during restoration without needing the original path.
* **Irmap (Inode Reverse Mapping)**: If file handles are unavailable, CRIU uses the [Irmap](irmap.md) engine to scan the filesystem and find a path that leads to the target inode.
### 2. Event Queue Consistency
If there are pending events in the fsnotify queue at the time of the dump, CRIU cannot currently "peek" at them or safely migrate them.
* **Dropped Events**: During a dump, CRIU checks if the fsnotify file descriptor has data. If it does, CRIU emits a warning: `The ... inotify events will be dropped`. These events are lost, and the application must be prepared to handle this gap in its event stream.
* **Spurious Events**: The process of checkpointing and restoring itself can trigger new filesystem events. For example, creating or deleting **ghost files** (temporary files used to restore unlinked but open files) can generate `IN_CREATE` or `IN_DELETE` events that the application will see upon resumption.
### 3. Ghost Files and Circular Dependencies
A "ghost file" is a file that was deleted by the application but is still held open. During restoration, CRIU must recreate these files. This action itself generates notify events, potentially confusing applications that monitor the directories where these ghost files are temporarily placed.
## Support for Fanotify
CRIU also supports `fanotify`, including:
* **Inode Marks**: Similar to inotify, these target specific files or directories.
* **Mount Marks**: Fanotify can monitor entire mount points. CRIU identifies the mount ID and restores the mark on the corresponding mount in the restored namespace.
## Current Strategy: "Chopping the Knot"
Due to the complexity of perfectly migrating event queues, CRIU's current strategy is:
1. **Warn and Drop**: Acknowledge that pending events are lost.
2. **Restore the Watches**: Ensure the application continues to receive *new* events after restoration.
3. **Namespace Integration**: Correctly map mount-level fanotify marks within their respective mount namespaces.
## See also
* [Irmap](irmap.md)
* [Invisible Files](invisible-files.md)
* [Mount Points](mount-points.md)

View file

@ -1,43 +0,0 @@
# The Complexity of Re-opening Files during Restore
Re-creating an open file descriptor during restoration is far more complex than simply calling `open(path, flags)`. This article explores the numerous edge cases CRIU must handle to faithfully reconstruct the file state.
## 1. Basic Opening
At its simplest, a file is defined by its path and access mode:
```c
int fd = open(f->path, f->mode);
```
However, this is only the beginning of the process.
## 2. FIFOs and Blocking
A standard `open()` call on a FIFO (named pipe) can hang indefinitely if there is no corresponding reader or writer on the other end. CRIU avoids this by first opening the FIFO with `O_RDWR` (to ensure at least one of each is present) and then using `dup2` to establish the final descriptor with the correct original flags.
## 3. Unlinked but Open Files (Ghost Files)
Linux allows files to be deleted while they are still open. These "invisible" files no longer have a path in the filesystem.
* **link-remap**: If the file still has other hard links elsewhere, CRIU may create a temporary link to it to allow it to be re-opened via a path.
* **Ghost Files**: If the link count is zero, CRIU captures the entire content of the file during the dump. During restore, it recreates this file in a temporary location, opens it, and then unlinks it to match the original state.
## 4. Directories and Hard Links
Directories cannot be hard-linked. If a directory was unlinked, CRIU must recreate it, open it, and then remove it. For files with multiple hard links that were all deleted, CRIU must ensure they all point back to the same physical inode upon restoration, requiring careful tracking of "temporary" paths and user-space reference counts.
## 5. Mount Namespaces and Chroot
The same path (e.g., `/etc/passwd`) might refer to entirely different files depending on the mount namespace or `chroot` environment of the process.
* **mnt_id**: CRIU records the mount ID for every file during the dump.
* **open_ns_root**: During restoration, CRIU uses file descriptors referring to the root of the specific mount namespace to ensure that `openat()` targets the correct physical file, regardless of the restorer's current root.
## 6. File Ownership and Signals (fown)
Files can have an associated "owner" (a PID or PGID) that receives signals (like `SIGIO` or `SIGPOLL`) when I/O events occur.
* **F_SETOWN_EX**: CRIU restores this ownership using the extended owner structure.
* **UID Switching**: Setting the owner of a file may require specific privileges. CRIU may temporarily switch its effective UIDs during the `fcntl` call to satisfy kernel permission checks if the file owner differs from the restorer.
* **F_SETSIG**: The specific signal number to be delivered is also faithfully restored.
## 7. Position and Flags
* **Lseek**: The current byte offset (`pos`) is restored using `lseek`.
* **Flag Sanitization**: Certain flags (like `O_CREAT`, `O_EXCL`, `O_TRUNC`) only make sense during the initial creation of a file. CRIU strips these before the restore-time `open()` to avoid accidentally creating or truncating existing files.
* **O_PATH**: Files opened with `O_PATH` are handled as pure path references; they do not have positions, ownership, or data access.
## 8. The Final Step: Descriptor Planting
Once a file is successfully opened (at a temporary descriptor number assigned by the kernel), it must be moved to the exact numeric descriptor the application expects (e.g., FD 42). This is achieved via `dup2()`, but requires coordination when descriptors are shared across a process tree.
*See also: [How to assign needed file descriptor to a file](how-to-assign-needed-file-descriptor-to-a-file.md)*

View file

@ -1,55 +0,0 @@
# Assigning Descriptors and Sharing Files
Once a file is [opened during restoration](how-hard-is-it-to-open-a-file.md), it often needs to be moved to a specific numeric file descriptor (FD) and potentially shared with other tasks in the process tree. This document explains how CRIU coordinates this process.
## The Basic Mechanism: `dup2`
In Linux, the `dup2(oldfd, newfd)` system call is the standard way to assign a file to a specific descriptor number. CRIU uses this to move a newly opened file from its temporary descriptor (assigned by the kernel) to the target descriptor expected by the application.
```c
int fd = open_a_file(f->file);
dup2(fd, f->target_fd);
close(fd);
```
## Handling Multiple Descriptors for One File
A single task may have multiple FDs referring to the same kernel "File Description" (e.g., a shell where FD 0, 1, and 2 all point to the same TTY). CRIU handles this by identifying the unique file object, opening it once, and then calling `dup2()` for every target FD slot the application expects.
## Sharing Files Across the Process Tree
Files are frequently shared between processes. While these files were originally inherited via `fork()`, CRIU must often distribute them between processes that do not have a direct parent-child relationship during the restore phase.
### Master and Slave Descriptors
For every unique file object in a checkpoint:
1. **The Master**: One task is designated as the "master" for that file. It is responsible for the actual system call that recreates the object (e.g., `open()`, `socket()`, or `pipe()`).
2. **The Slaves**: All other tasks that share the same file are "slaves." They do not create the file themselves.
### Transport via SCM_RIGHTS
CRIU uses Unix domain sockets to "send" descriptors from the master process to slave processes using the `SCM_RIGHTS` mechanism.
**The Workflow:**
1. **Master Opens**: The master task creates the file object.
2. **Master Sends**: The master sends the resulting file descriptor to each slave task over a dedicated transport socket.
3. **Slave Receives**: The slave task waits on its transport socket, receives the FD, and uses `dup2()` to plant it into the correct numeric slot.
## Solving the Coordination Problem
Distributing thousands of descriptors across a complex process tree requires careful management to avoid deadlocks and descriptor collisions.
### 1. Transport Sockets
CRIU creates abstract Unix sockets for each process to receive descriptors. The names are uniquely generated using the PID and a `criu_run_id` (e.g., `\0x/crtools-fd-123-abcdef`) to ensure that multiple simultaneous CRIU runs on the same host do not interfere with each other.
### 2. Deterministic "Master" Selection
To prevent circular dependencies (e.g., Task A waiting for Task B while B waits for A), CRIU uses a deterministic priority system to select the master. Typically, the task with the highest priority—usually the one closest to the root of the tree or with the lowest PID—is chosen to open and distribute the file.
### 3. Descriptor Collisions
A task's target FDs may conflict with the internal "service" FDs CRIU uses for images, logs, or transport sockets. CRIU resolves this by:
* **Service FD Range**: Restricting CRIU's own FDs to a specific range.
* **Dynamic Relocation**: If a target FD slot is occupied by an active service FD, CRIU moves the service FD to a new, free slot using `dup()` before planting the application's FD.
## Complex Dependencies
Some file types have inherent dependencies. For instance, an `epoll` descriptor cannot be fully restored until the files it monitors are already opened and their numeric descriptors are known. CRIU's file restoration engine handles this via a multi-pass state machine, where some files are opened but their full restoration is deferred until their dependencies are satisfied.
*See also: [File Restoration Engine (fdinfo)](fdinfo-engine.md)*

View file

@ -1,41 +0,0 @@
# Re-opening Files without Paths (open_by_handle_at)
Occasionally, CRIU encounters an open file descriptor for which the kernel no longer maintains a path. This document explains how CRIU uses file handles and Inode Reverse Mapping (Irmap) to reconstruct these "nameless" files.
## When Paths Are Lost
The most common scenario for path loss occurs with **fsnotify** (inotify and fanotify) instances.
When an application calls `inotify_add_watch(path)`, the kernel:
1. Resolves the path to an **inode**.
2. Attaches a watch generator to that inode.
3. Immediately forgets the path used to create the watch.
The resulting file descriptor points to the fsnotify instance, which knows *which* inode it is watching but not *where* that inode lives in the filesystem hierarchy. Because the dentry (directory entry) cache can be shrunk by the kernel at any time, the path information is often permanently lost to userspace.
## Strategy 1: open_by_handle_at
Linux provides a specialized system call, `open_by_handle_at()`, designed for userspace NFS servers. It allows opening a file using a **File Handle**—a filesystem-specific blob of bytes that uniquely identifies an inode.
### The Handle mechanism
1. **Dumping**: CRIU reads the file handle for a watch from `/proc/$pid/fdinfo/$fd`. (CRIU developers upstreamed patches to the Linux kernel to ensure this information is exposed).
2. **Restoring**: During restoration, CRIU takes this handle and calls `open_by_handle_at()`. This returns an `O_PATH` file descriptor pointing to the original inode, even if its original path is unknown.
3. **Re-attaching**: CRIU then uses this `O_PATH` descriptor to re-establish the inotify or fanotify watch, effectively "tricking" the kernel into watching the correct inode.
## Strategy 2: Irmap (Inode Reverse Mapping)
Not all filesystems support file handles (e.g., some older or specialized filesystems). In these cases, CRIU must resort to a brute-force approach called **Irmap**.
The Irmap engine maintains a cache that maps `(device, inode)` pairs back to their filesystem paths.
1. **Scanning**: Irmap recursively scans "known" directories (like configuration paths or application homes) and records every name-to-inode mapping it finds.
2. **Lookup**: When CRIU needs a path for a specific inode, it queries the Irmap cache.
3. **Pre-dump Integration**: To minimize the performance impact of filesystem scanning, CRIU can perform this scan during a **pre-dump** while the application is still running. The results are saved to an `irmap-cache.img` file and reused during the final dump.
## Filesystem Specifics
* **Tmpfs**: This filesystem pins its dentries in memory. For tmpfs, paths are almost always available via `/proc` and do not require handles or Irmap.
* **OverlayFS**: Due to its layered nature, OverlayFS can have complex handle behaviors. CRIU includes specific logic to navigate these layers during handle resolution.
## See also
* [Dumping File Descriptors](dumping-files.md)
* [FSNotify (Inotify and Fanotify)](fsnotify.md)
* [Irmap](irmap.md)

View file

@ -1,82 +0,0 @@
# CRIU: Under the Hood
This directory contains technical documentation detailing the internal implementation of CRIU, the kernel APIs it leverages, and the complex algorithms used to achieve checkpoint and restore of various Linux resources.
## Core Architecture & Lifecycle
* [Checkpoint and Restore Overview](checkpointrestore.md): High-level view of the C/R process.
* [Freezing the Process Tree](freezing-the-tree.md): How CRIU stops the application using the freezer cgroup or signals.
* [Parasite Code](parasite-code.md): Injection and execution of code within the victim's address space.
* [Restorer Context](restorer-context.md): The environment in which the restorer blob executes.
* [Stages of Restore](stages-of-restoring.md): Detailed breakdown of the multi-stage restoration process.
* [Final States](final-states.md): The state of processes after restore.
* [Technologies Used](technologies.md): Overview of kernel technologies CRIU depends on.
* [Kerndat](kerndat.md): How CRIU probes and caches kernel feature support.
## Memory Management
* [Memory Dumping and Restoring](memory-dumping-and-restoring.md): The primary algorithms for memory C/R.
* [Memory Changes Tracking](memory-changes-tracking.md): Using dirty bits (soft-dirty) for iterative migration.
* [Pagemap Cache](pagemap-cache.md): Optimizing access to `/proc/pid/pagemap`.
* [Copy-on-Write Memory](copy-on-write-memory.md): Handling shared and private COW mappings.
* [Shared Memory](shared-memory.md): Restoration of SysV IPC and POSIX shared memory.
* [Memory Images Deduplication](memory-images-deduplication.md): Saving space in image files.
* [Optimizing Pre-dump Algorithm](optimizing-pre-dump-algorithm.md): Strategies for minimizing downtime.
* [Userfaultfd](userfaultfd.md): Lazy migration and post-copy restoration.
## Files, Mounts & I/O
* [Dumping Files](dumping-files.md): General overview of file descriptor C/R.
* [How hard is it to open a file?](how-hard-is-it-to-open-a-file.md): The complexities of reconstructing file states.
* [How to open a file without open() syscall](how-to-open-a-file-without-open-system-call.md): Using `linkat` and other tricks for inaccessible files.
* [How to assign needed FD to a file](how-to-assign-needed-file-descriptor-to-a-file.md): Re-mapping FDs to match original values.
* [Invisible Files](invisible-files.md): Handling unlinked but open files.
* [FD Info Engine](fdinfo-engine.md): Parsing `/proc/pid/fdinfo`.
* [Service Descriptors](service-descriptors.md): Managing CRIU's internal FDs to avoid collisions.
* [Mount Points](mount-points.md): Basic mount restoration.
* [Mount V2](mount-v2.md): Modern mount restoration using `open_tree` and `move_mount`.
* [Mounts V2 Virtuozzo](mounts-v2-virtuozzo.md): Extensions for Virtuozzo-specific mount features.
* [Filesystem Peculiarities](filesystems-pecularities.md): Handling `/dev`, `/proc`, `sysfs`, etc.
* [IRM](irmap.md): Inode-to-path mapping (irmap).
* [KCMP Trees](kcmp-trees.md): Using `kcmp` to deduplicate shared resources.
* [Validate Files on Restore](validate-files-on-restore.md): Ensuring file consistency.
* [FSNotify](fsnotify.md): Checkpointing inotify and fanotify marks.
* [AIO](aio.md): Checkpointing asynchronous I/O contexts.
## Networking
* [TCP Connections](tcp-connection.md): Using TCP Repair mode for zero-loss socket migration.
* [Unix Sockets](unix-sockets.md): Reconnecting stream and dgram unix sockets.
* [Sockets](sockets.md): General socket restoration (Netlink, Raw, etc.).
* [Change IP Address](change-ip-address.md): Handling network configuration changes during migration.
* [MAC-VLAN](mac-vlan.md): Support for MAC-VLAN interfaces.
* [TUN/TAP](tun-tap.md): Virtual network device restoration.
## Process & Resource Management
* [PID Restore](pid-restore.md): Algorithms for restoring tasks with specific PIDs.
* [PIDFD](pidfd.md): Checkpointing and restoring pidfds.
* [PIDFD Store](pidfd-store.md): Internal management of pidfds.
* [Zombies](zombies.md): Handling processes in the `EXIT_ZOMBIE` state.
* [32-bit Tasks C/R](32bit-tasks-cr.md): Specifics for IA32/compat mode tasks.
* [Pending Signals](pending-signals.md): Capturing and re-queuing signals.
* [Restartable Sequences (rseq)](restartable-sequences.md): Handling the `rseq` kernel feature.
* [vDSO](vdso.md): Handling the virtual dynamic shared object across kernel versions.
* [TTYs](ttys.md): The complex state of terminal devices and PTY pairs.
* [CGroups](cgroups.md): Restoring cgroup hierarchy and membership.
## Security & Kernel Features
* [AppArmor](apparmor.md): Handling AppArmor profiles during dump and restore.
* [ARM64 GCS](arm64-gcs.md): Guarded Control Stack support on AArch64.
* [BPF Maps](bpf-maps.md): Experimental support for checkpointing BPF map data.
* [Code Blobs](code-blobs.md): Management of PIE blobs (parasite, restorer).
## Comparison & External Tools
* [Comparison to other C/R projects](comparison-to-other-cr-projects.md): How CRIU differs from DMTCP, BLCR, etc.
* [DMTCP](dmtcp.md): Specific notes on DMTCP integration or comparison.
* [FAQ](faq.md): Frequently Asked Questions about CRIU internals.
---
*Generated by Gemini CLI as part of the Documentation Audit (March 2026).*

View file

@ -1,57 +0,0 @@
# Invisible and Nameless Files
In Linux, a file can remain accessible to a process even if it no longer has a visible path in the filesystem. This occurs when a file is unlinked (deleted) while still open or when its path becomes inaccessible due to mount shadowing. This document explains how CRIU detects and reconstructs these "invisible" files.
## How Files Lose Their Paths
### 1. Unlinked while Open
The most common case is when an application opens a file and then immediately deletes it:
```c
int fd = open("/tmp/secret", O_RDWR);
unlink("/tmp/secret");
```
The file data persists in the kernel as long as the file descriptor remains open, but it no longer exists in the filesystem directory structure.
### 2. Virtual Filesystem Deletion
On virtual filesystems like `/proc`, if a process dies, its entries (e.g., `/proc/$PID/cmdline`) disappear. However, if another process still has an open file descriptor to one of these entries, the file remains alive but "nameless."
### 3. Mount Shadowing (Overmounts)
If a process opens a file in `/mnt/data` and then a new filesystem is mounted over `/mnt`, the original file becomes inaccessible via its path.
## CRIU's Detection and Reconstruction Strategies
CRIU uses the `/proc/$pid/fd/` and `/proc/$pid/fdinfo/` interfaces to identify open files and their expected paths.
### Ghost Files (Link Count = 0)
If a file has a link count of zero (`st_nlink == 0`), it is truly deleted.
* **Dumping**: CRIU reads the entire content of the file and stores it within the image directory as a "ghost file."
* **Restoring**: During restoration, CRIU recreates the file in a temporary location, opens it, and then immediately unlinks it to restore the original unlinked state.
* **Optimization**: For large sparse files, CRIU can use the `--ghost-fiemap` option to only capture the data blocks, significantly reducing image size.
### Link-Remap (Link Count > 0)
If a file has a positive link count but its expected path is missing or points to a different file, it means the specific name used to open the file was deleted, but other hard links still exist.
* **Strategy**: CRIU uses `linkat()` with the `AT_EMPTY_PATH` flag to create a temporary name for the file on the same filesystem. This allows it to be re-opened via a path during restoration.
* **Option**: This behavior is enabled via the `--link-remap` flag.
### Virtual File Remap (The PID Helper)
For deleted `/proc` entries, CRIU cannot use ghost files or `linkat()`. Instead:
1. It records the PID of the original process that the `/proc` entry referred to.
2. During restoration, it creates a temporary **TASK_HELPER** process with that specific PID.
3. The restored application opens the `/proc/$PID/...` entry of this helper.
4. The helper is terminated once all restoration tasks are complete.
### Filesystem-Specific Handling
* **NFS**: CRIU detects "Silly Rename" files (`.nfsXXX`) and handles them via the link-remap mechanism.
* **OverlayFS**: Since `linkat()` may fail on OverlayFS if the file resides on a read-only lower layer, CRIU automatically falls back to the ghost file strategy in these cases.
* **Devpts**: Files on `devpts` (like PTYs) are managed by the kernel and are restored using specific PTY master/slave allocation logic rather than file-based reconstruction.
## Technical Details
* **--ghost-limit**: By default, CRIU limits ghost files to **1 MB** to prevent excessive disk usage. This can be increased via the `--ghost-limit` option.
* **--evasive-devices**: Allows CRIU to proceed even if a character or block device path has changed, provided the device numbers (`st_rdev`) match.
## See also
* [Dumping File Descriptors](dumping-files.md)
* [Filesystem Peculiarities](filesystems-pecularities.md)
* [Mount Points](mount-points.md)

View file

@ -1,43 +0,0 @@
# Irmap (Inode Reverse Mapping)
Irmap is CRIU's engine for resolving an `(inode, device)` pair back into a filesystem path. This is primarily required for restoring **fsnotify** (inotify and fanotify) instances, which internally reference inodes but do not preserve the paths used to create them.
## The Problem
When an application creates an inotify watch, the kernel resolves the path to an inode and attaches the watch to it. The original path string is then discarded by the kernel. During a checkpoint, CRIU can see which inode is being watched but needs a valid path to recreate that watch during restoration.
## How Irmap Works
Irmap uses a combination of predefined hints and brute-force scanning to build a reverse mapping cache.
### 1. Heuristic Hints
CRIU starts by scanning "known" locations where applications typically place watches, such as:
- `/etc` (configuration files)
- `/var/log` (log monitoring)
- `/var/spool`
- D-Bus and Polkit service paths (`/usr/share/dbus-1/services`, etc.)
- `/lib/udev`
- The root directory (`/`)
### 2. User-Defined Scan Paths
Users can provide additional directories to scan via the command line to help CRIU find application-specific files more quickly:
```bash
criu dump --irmap-scan-path /path/to/my/app ...
```
These paths are prioritized and scanned before the default hints.
### 3. Caching and Pre-dump
Scanning large filesystems can be slow and resource-intensive. To mitigate this:
- **irmap-cache.img**: Scan results are stored in this image file within the images directory.
- **Pre-dump Optimization**: CRIU can perform the irmap scan during a `pre-dump` while the application is still running. This populates the cache early, significantly reducing the time the application must remain frozen during the final dump.
- **Validation**: On subsequent runs, CRIU loads the cache and re-validates entries individually (checking if the inode/device still matches the path) rather than performing a full re-scan.
## Support for Filesystems
* **Standard Filesystems**: Works well on most local filesystems (ext4, xfs, etc.).
* **Tmpfs**: Paths are generally available via `/proc` and don't strictly require Irmap, though it can still be used.
* **OverlayFS**: Irmap has historically had difficulties with OverlayFS due to how inodes are reported across different layers. In modern kernels, **open_by_handle_at** (leveraging file handles exposed in `/proc/$pid/fdinfo`) is the preferred and more reliable alternative to Irmap.
## See also
* [FSNotify](fsnotify.md)
* [Re-opening nameless files](how-to-open-a-file-without-open-system-call.md)

View file

@ -1,48 +0,0 @@
# Shared Object Detection (Kcmp Trees)
CRIU must frequently determine if system resources (such as file descriptions, memory mappings, or namespaces) are shared between different processes. While some objects have unique kernel-provided IDs (like inode numbers for files on disk), many do not. This document explains how CRIU uses the `kcmp()` system call and red-black trees to efficiently detect these shared objects.
## The Challenge
Comparing every resource in every process against every other process would result in $O(N^2)$ complexity, where $N$ is the total number of resources (e.g., 100 tasks with 100 files each = 10,000 files, or 50 million pairs). This is prohibitively slow.
## The Solution: `kcmp()` and Pointer Comparison
The `kcmp()` system call identifies whether two kernel objects are the same. Crucially, its return value is not a simple boolean; it returns the result of an internal kernel pointer comparison:
* **0**: The objects are identical.
* **1**: The first object's pointer is "less than" the second.
* **2**: The first object's pointer is "greater than" the second.
* **-1**: Error.
This ordering information allows CRIU to use **red-black trees** to sort and search for objects with $O(N \log N)$ complexity.
## Two-Level Red-Black Trees
To further optimize performance and minimize the number of expensive `kcmp()` system calls, CRIU uses a two-level tree structure:
### Level 1: Fast ID (genid)
CRIU first calculates a "generation ID" (`genid`) using cheap, locally available metadata. For regular files, this is derived from the device ID, inode number, and current file position.
* Objects are inserted into a primary red-black tree ordered by `genid`.
* If two objects have different `genid`s, they are guaranteed to be different, and no system call is needed.
### Level 2: Sub-tree (kcmp)
If two objects have identical `genid`s, they *might* be the same.
* CRIU then descends into a sub-tree associated with that `genid`.
* In this sub-tree, objects are ordered using the `kcmp()` system call.
* If `kcmp()` returns 0, the objects are confirmed as shared.
## Supported Object Types
CRIU uses `kcmp()` for various object types, including:
* **KCMP_FILE**: Individual file descriptions.
* **KCMP_VM**: Virtual memory address spaces.
* **KCMP_FILES**: The entire file descriptor table.
* **KCMP_FS**: Filesystem information (umask, root, cwd).
* **KCMP_SIGHAND**: Signal handler tables.
* **KCMP_IO**: I/O context.
* **KCMP_SYSV_SEM**: System V semaphore undo lists.
* **KCMP_EPOLL_TFD**: Specific descriptors within an epoll interest list.
## See also
* [Dumping File Descriptors](dumping-files.md)
* [Copy-on-write memory](copy-on-write-memory.md)

View file

@ -1,36 +0,0 @@
# Kerndat (Kernel Data)
**Kerndat** is a CRIU module responsible for detecting the capabilities and features of the currently running Linux kernel. Since CRIU's functionality depends heavily on specific kernel system calls and behaviors, runtime detection is essential for ensuring compatibility and selecting the most efficient algorithms.
## Feature Detection
CRIU performs a wide array of checks during initialization. These include:
* **System Call Availability**: Checking for `kcmp()`, `userfaultfd()`, `memfd_create()`, `clone3()`, `openat2()`, `membarrier()`, and more.
* **Filesystem Features**: Verifying `pagemap` functionality, `PAGEMAP_SCAN` support, and anonymous shared mapping behaviors.
* **Namespace Support**: Detecting Time namespaces, CGroup namespaces, and namespace-specific identifiers.
* **Architecture-Specific Quirks**: Identifying known CPU bugs or features, such as the x86 FPU/XSAVE ptrace bug.
The results of these checks are stored in a global `kdat` structure, which other CRIU modules query to determine how to proceed during dump and restore operations.
## Persistent Caching
Executing hundreds of kernel feature checks can be time-consuming. To speed up subsequent CRIU invocations, the results are cached on disk.
* **Cache Location**:
* **Root**: `/run/criu.kdat` (typically stored on `tmpfs` to ensure it is cleared on reboot).
* **Non-root**: `$XDG_RUNTIME_DIR/criu.kdat`.
* **Lifecycle**: CRIU attempts to load this cache during `kerndat_init()`. If the cache is missing or stale (e.g., if the CRIU binary has been updated with new checks), CRIU performs a full detection and saves the new results back to the cache file.
## Kerndat vs. Inventory
It is important to distinguish between **kerndat** and the **inventory image** (`inventory.img`):
* **Kerndat**: Captures the capabilities of the **host kernel**. It is system-wide and typically survives across different CRIU operations on the same host.
* **Inventory**: Captures critical metadata about a **specific checkpoint**. It is stored within the images directory and includes the CRIU version used for the dump, the host's LSM type (SELinux/AppArmor), and the root task's original IDs.
## Inspection
To see the features detected by CRIU on your current system, use the check command:
```bash
criu check --extra
```
This command triggers a kerndat initialization and prints the status of various required and optional kernel features, allowing you to verify that your environment is ready for CRIU.

View file

@ -1,35 +0,0 @@
# Mac-VLAN
Mac-VLAN is a Linux network driver that allows creating multiple virtual interfaces with unique MAC addresses on top of a single physical interface. These virtual interfaces act as standalone devices on the network, each with its own IP and MAC address.
## Checkpoint and Restore of Mac-VLAN
CRIU identifies Mac-VLAN interfaces by monitoring netlink messages (specifically `RTM_NEWLINK`) and inspecting their attributes.
### 1. Checkpointing
During a dump, CRIU extracts the following attributes for each Mac-VLAN device:
- **Parent Interface**: The physical device (or "upper" link) that the Mac-VLAN is built upon (identified via `IFLA_LINK`).
- **Mode**: The specific Mac-VLAN operational mode (e.g., `bridge`, `private`, `vepa`, `passthru`), extracted from `IFLA_MACVLAN_MODE`.
- **Flags**: Any additional configuration flags associated with the interface (`IFLA_MACVLAN_FLAGS`).
- **MAC Address**: The unique hardware address of the virtual interface.
### 2. Restoration
To recreate a Mac-VLAN interface exactly as it was, CRIU performs the following:
- **Link Creation**: It sends an `RTM_NEWLINK` netlink message with the kind set to `"macvlan"`, specifying the original mode and the link to the parent device.
- **Index Preservation**: To ensure that any application sockets bound to the interface index remain valid, CRIU uses the `IFLA_NEW_IFINDEX` attribute. This allows CRIU to request the exact same interface index that the device possessed before the checkpoint. (This kernel feature was originally developed specifically to support CRIU).
- **Namespace Migration**: Once created, the interface is moved into the target network namespace for the restored process.
## External Interface Mapping
Since the parent physical interface may have a different name or index on the destination host during migration, CRIU provides the `--external` option to map these dependencies:
```bash
# Example mapping of an internal macvlan interface to a host physical interface
criu restore --external macvlan[eth0]:phys0 ...
```
This tells CRIU that the Mac-VLAN interface which was originally attached to `eth0` should now be attached to the physical interface `phys0` on the current host.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Networking](networking.md)

View file

@ -1,45 +0,0 @@
# Memory Changes Tracking
Memory changes tracking (also known as "dirty memory tracking") is a critical feature in CRIU that enables efficient **live migration** with minimal downtime. By identifying and capturing only the memory pages that have been modified since a previous snapshot, CRIU can perform iterative dumps while the application continues to run.
## The Problem: Memory Dump Latency
During a standard checkpoint, CRIU freezes the process tree and dumps its entire memory state to disk. For memory-intensive applications (like large databases), this process can take several seconds, during which the application is completely unresponsive. This "freeze time" is directly proportional to the amount of memory used by the application.
## The Solution: Iterative Dumps
To minimize freeze time, CRIU supports an iterative migration scheme:
1. **Initial Pre-dump**: Capture a full snapshot of the application's memory while it is still running.
2. **Subsequent Pre-dumps**: Periodically capture only those pages that have been modified (made "dirty") since the last pre-dump.
3. **Final Dump**: Freeze the processes and capture the final set of dirty pages. Since most memory was already transferred in previous steps, the final freeze time is significantly reduced.
## Kernel Mechanisms for Tracking
CRIU relies on two primary kernel mechanisms to track dirty pages:
### 1. The Soft-Dirty Bit
Linux maintains a "soft-dirty" bit for each Page Table Entry (PTE).
* **Resetting**: CRIU enables tracking by writing "4" to `/proc/$pid/clear_refs`, which clears the soft-dirty bit for all pages in the task's address space.
* **Tracking**: Any subsequent write to a page causes the kernel to set its soft-dirty bit.
* **Reading**: CRIU identifies dirty pages by reading the bit from the process's `/proc/$pid/pagemap` interface.
### 2. ioctl(PAGEMAP_SCAN)
Reading the entire `/proc/$pid/pagemap` file can be slow for very large address spaces. Modern kernels (v6.7+) support the `PAGEMAP_SCAN` ioctl, which allows CRIU to:
* **Efficient Scanning**: Identify dirty pages across a large address space in a single kernel call.
* **Filtering**: Directly filter for specific page categories (e.g., only dirty and present pages).
* **Atomic Reset**: Optionally clear the soft-dirty bit while scanning, ensuring no writes are missed between scanning and resetting.
CRIU automatically detects and uses `PAGEMAP_SCAN` if available, falling back to manual `/proc` parsing on older kernels.
## Implementation in CRIU
Iterative migration is managed through the `pre-dump` command:
1. **Chained Images**: Each pre-dump creates a set of image files in a new directory. These directories are linked together using the `--prev-images-dir` option.
2. **Consolidated Restore**: During restoration, CRIU traverses the chain of images from newest to oldest. For any given memory address, it restores the most recent version of the page found in the image stack.
3. **Page Server**: To avoid writing iterative dumps to disk, they can be sent over the network to a **page server** on the destination host.
## See also
* [Iterative Migration](iterative-migration.md)
* [Memory Images Deduplication](memory-images-deduplication.md)
* [Page Server](page-server.md)

View file

@ -1,55 +0,0 @@
# Memory Dumping and Restoring
Dumping and restoring the memory of a process tree is one of the most critical and complex tasks performed by CRIU. This document details the mechanisms, optimizations, and kernel interfaces involved in this process.
## The Virtual Memory Layout (VMAs)
A process's address space is composed of several Virtual Memory Areas (VMAs). CRIU identifies these areas by parsing `/proc/$pid/smaps` and `/proc/$pid/map_files/`.
* **Metadata**: Each VMA's start address, end address, protection flags (read, write, execute), and sharing status (private or shared) are recorded in the `mm-$id.img` file.
* **Backing Store**: CRIU also records whether a VMA is anonymous (backed by RAM/swap) or file-backed.
## The Dumping Process
Capturing memory contents while maintaining consistency and performance requires a multi-stage approach.
### 1. Parasite Injection
CRIU cannot efficiently read a process's private memory from the outside. Instead, it injects **parasite code** into the target task. This code runs within the task's own address space and context, allowing it direct access to all memory regions.
### 2. Zero-Copy Dumping (vmsplice)
To transfer memory from the parasite to the CRIU dumper with minimal overhead, CRIU uses a zero-copy mechanism:
1. **Pipe Setup**: CRIU creates a pipe and sends one end to the parasite via a Unix domain socket.
2. **vmsplice**: The parasite uses the `vmsplice()` system call with the `SPLICE_F_GIFT` flag. This effectively "gifts" the memory pages to the kernel's pipe buffer without copying the data in userspace.
3. **Splice to Image**: The CRIU dumper then uses `splice()` to move the data from the pipe directly into the image file (`pages-$id.img`) or to a network socket (for the page server).
### 3. Page Deduplication and Skipping
CRIU avoids dumping unnecessary data to save time and space:
* **Unchanged File Pages**: Read-only, file-backed pages (like library code) that have not been modified are not dumped. CRIU simply records the file and offset to re-map them during restoration.
* **Dirty Tracking**: Using the **soft-dirty bit** (or `PAGEMAP_SCAN`), CRIU can identify and dump only those pages that have changed since a previous pre-dump.
---
## The Restoration Process
Restoring memory involves reconstructing the exact address space layout the application had at the moment of the checkpoint.
### 1. Re-mapping VMAs
During the early stages of restoration, each process calls `mmap()` to recreate its VMAs based on the data in `mm-$id.img`.
* **Anonymous Memory**: Mapped as private and anonymous.
* **File Mappings**: Re-mapped from their original files on disk.
### 2. Filling Memory Contents
CRIU then repopulates the mappings with the data stored in the `pages-$id.img` files. For efficiency, CRIU uses its own optimized I/O routines to read the images and fill the memory regions.
### 3. COW Preservation
CRIU uses a specialized strategy to ensure that memory shared via `fork()` (Copy-on-Write) remains shared after restoration. This minimizes the total physical memory footprint of the restored process tree. See [COW Memory](copy-on-write-memory.md) for details.
## Advanced Migration Techniques
* **Page Server**: During live migration, memory pages are sent over the network to a page server on the destination host, avoiding expensive disk I/O.
* **Lazy Migration (Userfaultfd)**: CRIU can restore a process immediately without its memory and then load pages on demand as the application accesses them. This is powered by the `userfaultfd` kernel feature and is essential for reducing initial downtime.
## See also
* [Memory Changes Tracking](memory-changes-tracking.md)
* [Copy-on-write Memory](copy-on-write-memory.md)
* [Userfaultfd](userfaultfd.md)
* [Page Server](page-server.md)

View file

@ -1,40 +0,0 @@
# Memory Images Deduplication
During iterative migration, CRIU produces multiple snapshots of a process's memory. Since most memory pages remain unchanged between iterations, saving every page in every snapshot would result in significant disk space waste and increased migration time. CRIU uses several deduplication techniques to address this.
## How Deduplication Works
Deduplication relies on identifying pages that are identical to those in a previous snapshot (the "parent" image).
### 1. The `in_parent` Flag
The `pagemap-$id.img` file describes the virtual memory layout. Each entry (`pagemap_entry`) can include an `in_parent` flag:
* **If `false`**: The page's contents are stored in the current `pages-$id.img` file.
* **If `true`**: The page's contents are identical to the one in the parent image. CRIU does not write the data to the current `pages-$id.img`, saving both disk space and I/O time.
### 2. Detection via Soft-Dirty
During a `pre-dump`, CRIU uses the kernel's **soft-dirty bit** to identify which pages have been modified.
* If a page was present in the previous iteration and its soft-dirty bit is **not set**, CRIU knows the content remains unchanged.
* It marks the page as `in_parent` in the current pagemap image and skips dumping its data.
## Auto-Deduplication (`--auto-dedup`)
CRIU provides an advanced `--auto-dedup` mode that optimizes both the dumping and restoration processes.
### During Dump
When `--auto-dedup` is enabled during a dump, CRIU actively manages the relationship between the current and parent image sets to ensure maximum deduplication efficiency. It traverses the previous images to verify which regions can be safely referenced rather than re-dumped.
### During Restore (Disk Space Optimization)
A unique and powerful feature of `--auto-dedup` during restoration is **online disk space reclamation**:
* As CRIU reads pages from the `pages-$id.img` files to restore the process's memory, it uses the `fallocate(FALLOC_FL_PUNCH_HOLE)` system call on the image files.
* This "punches holes" in the images, effectively freeing the underlying physical disk blocks as soon as the data has been loaded into RAM.
* This is critical for systems with limited disk space when restoring from a large number of iterative pre-dumps, as it prevents the total image size from exceeding the available storage.
## Implementation Details
* **Image Chaining**: Deduplication requires a chain of images established via the `--prev-images-dir` option, allowing CRIU to look back through multiple layers of snapshots.
* **Sparse File Support**: The hole-punching mechanism leverages the host filesystem's support for sparse files, ensuring that the restored environment remains efficient.
## See also
* [Memory Changes Tracking](memory-changes-tracking.md)
* [Iterative Migration](iterative-migration.md)
* [Memory Dumping and Restoring](memory-dumping-and-restoring.md)

View file

@ -1,49 +0,0 @@
# Checkpoint and Restore of Mount Points
CRIU provides deep support for capturing and reconstructing Linux mount namespaces and the complex hierarchies of mount points within them. This includes support for bind mounts, shared propagation, and external dependencies.
## Key Information Captured
For every mount namespace, CRIU parses `/proc/$pid/mountinfo` to extract:
1. **Mount Hierarchy**: The parent-child relationships between mount points.
2. **Filesystem Details**: Device IDs, filesystem types, and the mount source.
3. **Root and Target**: The specific directory within the filesystem being mounted and its destination in the process's view.
4. **Propagation State**: Whether a mount is `shared`, `slave`, `private`, or `unbindable`.
5. **Mount Options**: Flags such as `ro`, `nodev`, `noexec`, and `nosuid`.
## The Restoration Challenge
Restoring mounts is one of CRIU's most difficult tasks because it must recreate the exact same state that the kernel built up over time. This requires:
* **Dependency Sorting**: Mounts must be recreated in the correct order (e.g., a parent must exist before its child can be mounted).
* **Source Resolution**: CRIU must be able to access the original filesystem source.
* **Propagation Reconstruction**: Shared and slave relationships must be established in the correct sequence to ensure future mount events propagate as expected.
## Mount V2: The Modern Engine
CRIU includes an advanced restoration engine called **Mount V2** (`--mount-v2`). This engine uses a more robust algorithm to handle:
* **Complex Overmounts**: Scenarios where multiple mounts are stacked on the same directory.
* **Circular Dependencies**: Resolving cases where mounts depend on each other in non-trivial ways.
* **Namespace Sharing**: Efficiently handling processes that share the same mount namespace.
## External and Auto-detected Mounts
Sometimes, the source of a mount point is located outside the container or process tree being checkpointed (e.g., a host directory bind-mounted into a container).
### 1. External Mounts (`--external`)
Users can manually specify how to handle these external dependencies by mapping the mount's identifier to a path on the destination host:
```bash
criu restore --external mnt[ID]:/new/host/path ...
```
### 2. Auto-detection
CRIU can often automatically identify external bind mounts by comparing the mount points in the target process with those in its own mount namespace. This simplifies migration by reducing the need for manual mapping.
## Common Issues
* **Unsupported Filesystems**: Some specialized or virtual filesystems may not support standard checkpointing. These often require plugins or must be marked as external.
* **Hidden Sources**: If a bind mount's source is overmounted and no longer visible, CRIU may fail to identify how to recreate it without the Mount V2 engine or manual hints.
## See also
* [Mount V2 Details](mount-v2.md)
* [Filesystem Peculiarities](filesystems-pecularities.md)
* [Invisible Files (Overmounts)](invisible-files.md)

View file

@ -1,8 +0,0 @@
# Mount Points 2.0 (Legacy)
> **Note**: This document describes an early design iteration for mount restoration. The current and much more advanced implementation is documented in [Mount V2](mount-v2.md).
For detailed information on the modern mount restoration algorithm, including the use of detached mounts and `move_mount`, please refer to:
* [Mount V2 Overview](mount-v2.md)
* [Mount V2 Detailed Algorithm](mounts-v2-virtuozzo.md)
* [Mount Points (General)](mount-points.md)

View file

@ -1,42 +0,0 @@
# Mount V2: Advanced Mount Restoration
Introduced in CRIU v3.16, **Mount V2** is a sophisticated restoration engine that leverages modern Linux kernel APIs to handle complex mount hierarchies, propagation groups, and overmounts with high reliability.
## Why Mount V2 was Necessary
The original mount restoration mechanism (Mount V1) relied on sequential, path-based `mount()` calls. This approach had several critical flaws:
1. **Overmount Sensitivity**: If a directory was already covered by another mount, performing a path-based mount on it could fail or target the wrong filesystem.
2. **Circular Dependencies**: Resolving mounts that depend on each other in non-linear ways was difficult and often resulted in ordering failures.
3. **Propagation Complexity**: Establishing `shared` and `slave` relationships required creating dummy mount points and performing specific sequences of `mount --make-shared/slave` calls, which was fragile in complex scenarios.
## How Mount V2 Works
Mount V2 moves away from path-based mounting, instead using **File Descriptor-based** mounting provided by newer kernel system calls.
### 1. Detached Mounts
CRIU creates each required mount as a **detached mount**. These mounts exist in the kernel but are not yet attached to any visible path in the filesystem.
* **New Filesystems**: Created using `fsopen()` and `fsmount()`.
* **Bind Mounts**: Created using `open_tree()` with the `OPEN_TREE_CLONE` flag to create an unattached clone of an existing path.
### 2. Precise Propagation Grouping
Using the `move_mount()` syscall with the `MOVE_MOUNT_SET_GROUP` flag (introduced in kernel v5.15), CRIU can explicitly assign a detached mount to a specific **shared or slave propagation group**. This eliminates the need for dummy mounts and ensures that the propagation state is perfectly restored as recorded in the images.
### 3. Tree Construction via File Descriptors
CRIU constructs the entire mount hierarchy by attaching child mounts to their parents using their respective file descriptors. Since this happens "off-line" (outside of any mount namespace), it is immune to path shadowing, path resolution errors, or overmounting issues.
### 4. Atomic Final Attachment
Once the complete hierarchy is assembled as a tree of detached mounts, CRIU performs a final `move_mount()` to attach the root of this reconstructed tree into the target mount namespace at the desired destination path.
## Kernel Requirements
Mount V2 requires a modern kernel that supports:
* `fsopen()`, `fsmount()`, `move_mount()` (Kernel v5.2+)
* `open_tree()` (Kernel v5.3+)
* `MOVE_MOUNT_SET_GROUP` (Kernel v5.15+)
CRIU automatically detects these features during the [Kerndat](kerndat.md) phase. It will fall back to the older Mount V1 engine if these calls are unavailable, though many modern container layouts now effectively require Mount V2 for a successful restore.
## See also
* [Mount Points](mount-points.md)
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Kerndat](kerndat.md)

View file

@ -1,42 +0,0 @@
# Mount V2: Detailed Algorithm
The Mount V2 engine (originally developed by Virtuozzo and later merged into upstream CRIU) is designed to resolve complex issues with restoring sharing groups, over-mounted files, and cross-namespace bind mounts. This document provides a technical breakdown of its operation.
## 1. Mount Image Processing Stage
During initialization, CRIU processes the mount images for all namespaces to build an internal model of the filesystem state:
- **Hierarchy Construction**: Build a per-namespace mount tree based on parent IDs.
- **Bind Grouping**: Group mounts by superblock equality into "bind" lists to identify shared underlying filesystems.
- **Sharing Groups**: Organize shared and slave groups into a tree structure (e.g., where a parent's `shared_id` matches a child's `master_id`).
- **The Root Yard**: Create a helper mount (`root_yard_mp`) at a temporary location (e.g., `/tmp/.criu.mntns.XXXXXX/`). All mount trees from all namespaces are initially merged as subdirectories of this "root yard."
## 2. Pre-Fork Mounting Stage
This stage is executed from the init task in a dedicated "service" mount namespace before the target process tree is forked:
1. **Plain Mounting**: CRIU walks the merged mount tree and creates all mounts in a "plain" (unattached) and "private" state.
2. **Source Resolution**: For each mount, CRIU identifies its source (a real filesystem, a bind mount from another already-mounted superblock, or an external source).
3. **Cross-Namespace Handling**: By maintaining all mounts within a single service namespace during this stage, CRIU can easily handle bind mounts that cross namespace boundaries.
## 3. Propagation and Shared Group Restoration
CRIU restores complex propagation relationships using modern kernel APIs:
- **Slavery and Sharing**: For each sharing group, CRIU identifies the "master" mount. It uses the `move_mount()` system call with the `MOVE_MOUNT_SET_GROUP` flag (or the legacy `MS_SET_GROUP` mechanism) to establish slave/shared relationships precisely as they existed during the dump.
- **Settings Replication**: Once the sharing state is established for the primary mount in a group, all other members of the group inherit these settings.
## 4. Namespace Transition and Final Positioning
For each target mount namespace being restored:
1. **Unshare**: CRIU calls `unshare(CLONE_NEWNS)` to create a fresh, empty mount namespace.
2. **Tree Positioning**: Move the "plain" mounts from the root yard into their final hierarchical positions within the new namespace using `move_mount()`.
3. **Pivot Root**: Execute `pivot_root()` to switch to the new namespace root, effectively hiding the temporary "yard" and finalizing the mount hierarchy.
## 5. Post-Fork Fixups
Certain mounts cannot be fully restored until the process tree is established:
- **Delayed Procfs**: `proc` mounts for nested PID namespaces must wait until the target PID namespace is created. CRIU enters these namespaces after forking to perform the final mounts.
- **Internal Yards**: In some cases, temporary `tmpfs` mounts ("internal yards") are used within a namespace to hold mounts that must be moved or adjusted after the process tree is fully alive.
## See also
* [Mount V2 Overview](mount-v2.md)
* [Mount Points](mount-points.md)
* [Checkpoint/Restore Architecture](checkpointrestore.md)

View file

@ -1,5 +0,0 @@
# NFS mount points
When C/R-ing NFS mount points there a chicken-and-egg problem.

View file

@ -1,44 +0,0 @@
# Optimized Pre-dump Algorithm
Pre-dumping is the process of capturing dirty memory pages while an application continues to run, aiming to minimize the final "freeze time" during live migration. CRIU provides two primary modes for pre-dumping: `read` and `splice`.
## Traditional vs. Optimized Pre-dump
### The `read` Mode (Traditional)
In this mode, CRIU uses the `process_vm_readv` system call to read memory from the target process.
* **Workflow**: Tasks are briefly frozen to identify dirty pages and reset the soft-dirty bit, then resumed. CRIU then reads the pages from the running process's address space.
* **Challenge**: Reading memory while a process is running can lead to minor inconsistencies if the process modifies a page *while* it is being read (see [Memory Consistency](#memory-consistency) below). Furthermore, `process_vm_readv` requires the target process to be alive and its memory mappings to remain stable during the read.
### The `splice` Mode (Optimized & Default)
The `splice` mode (enabled via `--pre-dump-mode=splice`) uses a zero-copy "gift" mechanism to further reduce freeze time and improve reliability.
#### How `splice` Mode Works:
1. **Brief Freeze**: CRIU seizes the tasks and injects the parasite code.
2. **vmsplice "Gifting"**: The parasite identifies dirty pages and calls `vmsplice()` with the `SPLICE_F_GIFT` flag. This flag tells the kernel that the process is "giving" these pages to a pipe.
3. **Immediate Resume**: Once the `vmsplice()` calls are complete (which is extremely fast as no data is actually copied), the parasite is removed, and the tasks are resumed immediately.
4. **Parallel Draining**: While the tasks are running, the main CRIU process "drains" the data from the pipes and writes it to the image files or sends it to the page server.
#### Why `splice` is Better:
* **Minimized Downtime**: The "freeze" duration is reduced to just the time needed for the parasite to execute the `vmsplice()` system calls, rather than the time needed to transfer memory data over the network or to disk. This scheme relies entirely on `vmsplice()` being extremely fast. Because the target process is frozen during these calls, minimizing this duration is critical to the primary goal of pre-dumping: reducing process downtime during live migration and making the migration process almost invisible to the application.
* **Zero-Copy Transfer**: By gifting pages directly from the target process to the pipe, `splice` mode avoids copying memory to CRIU user-space buffers (unlike `read` mode which uses `process_vm_readv` to copy data). While this zero-copy mechanism does not use COW (meaning intermediate dumps can be inconsistent if pages are modified after resume), CRIU's iterative design handles this inconsistency (see below) while maximizing transfer performance.
## Memory Consistency
Because the target process is resumed while CRIU is still writing the memory data (in both `read` and `splice` modes), intermediate pre-dump images may contain inconsistent memory states.
This inconsistency is expected and handled by CRIU's iterative design:
1. **Tracking Changes**: CRIU uses the kernel's soft-dirty tracker to monitor memory writes after the process is resumed.
2. **Subsequent Dumps**: Any page modified after it has been pre-dumped is marked dirty again and will be captured in the next pre-dump iteration or during the final dump.
3. **Restoring Consistency**: During restore, CRIU applies the dump images in sequence (from oldest pre-dump to the final dump). The final dump is taken while the process is fully frozen, ensuring that the final state of all memory pages is consistent.
## Usage
The optimized `splice` mode is the default in modern CRIU. It can be explicitly requested using the `--pre-dump-mode` option:
```bash
criu pre-dump --pre-dump-mode splice ...
```
## See also
* [Memory Changes Tracking](memory-changes-tracking.md)
* [Memory Dumping and Restoring](memory-dumping-and-restoring.md)
* [Iterative Migration](iterative-migration.md)

View file

@ -1,35 +0,0 @@
# Pagemap Cache
When dumping the memory of a process, CRIU must frequently query the kernel to determine which virtual memory pages are currently present in RAM, swapped out, or modified (dirty). This information is typically retrieved from the `/proc/$pid/pagemap` file. However, reading and parsing this file repeatedly for every Virtual Memory Area (VMA) is inefficient. To solve this, CRIU implements a high-performance **Pagemap Cache**.
## The Performance Problem
The `/proc/$pid/pagemap` file is a 64-bit-per-page binary stream. For a process with a large address space, this file can be several megabytes in size. While a single sequential read is fast, CRIU needs this data across multiple stages of the dump (e.g., initial size estimation, private memory dumping, shared memory dumping, and iterative pre-dumps). Performing multiple full reads and frequent `lseek()` calls into this file introduces significant overhead, especially for applications with thousands of small VMAs.
## Implementation Details
The pagemap cache (`struct pmc`) optimizes access through several advanced techniques:
### 1. Sliding Window Caching
Instead of reading the entire pagemap at once, CRIU uses a sliding window (typically **2MB** in size, defined as `PMC_SIZE`).
* When a VMA is accessed that is not currently in the cache (a cache miss), the cache "refills" itself by reading the pagemap for the required range.
* **Greedy Prefetching**: If the current VMA is small, the cache tries to fill the remainder of the 2MB window by pre-reading information for subsequent, adjacent VMAs. This significantly reduces the total number of `read()` system calls and minimizes the overhead of kernel-side page table walks.
### 2. ioctl(PAGEMAP_SCAN) Integration
On modern kernels (v6.7+), the pagemap cache leverages the `PAGEMAP_SCAN` ioctl. This interface is far more efficient than the legacy `/proc` file:
* **Bulk Retrieval**: It allows CRIU to fetch information for multiple, non-contiguous page ranges in a single kernel call.
* **Kernel-Side Filtering**: CRIU can instruct the kernel to only return information for specific categories of pages (e.g., pages that are both present in RAM and marked as "soft-dirty"), further reducing the amount of data transferred and processed in userspace.
### 3. Cache Invalidation
To ensure consistency, the pagemap cache is per-process and is strictly managed:
* The cache is typically populated while the target process is **frozen** to ensure a stable view of memory.
* The cache is invalidated whenever the process state might have changed or when the dumper transitions between different memory processing phases.
## Debugging and Control
The pagemap cache can be disabled for troubleshooting or performance comparison by setting the `CRIU_PMC_OFF` environment variable.
## See also
* [Memory Dumping and Restoring](memory-dumping-and-restoring.md)
* [Memory Changes Tracking](memory-changes-tracking.md)
* [Optimizing Pre-dump Algorithm](optimizing-pre-dump-algorithm.md)

View file

@ -1,54 +0,0 @@
# Parasite Code Injection and Execution
The **parasite code** is a specialized binary blob that CRIU injects into the address space of a target process during a checkpoint. Its primary purpose is to extract internal task state—such as private memory contents, credentials, and signal handlers—that is not available via standard kernel interfaces like `/proc`.
## The Infection Process
Infection is a multi-stage operation managed by the **Compel** sub-project, leveraging the `ptrace` system call to take control of the target process.
### 1. Seizing the Task
CRIU stops the target task using `PTRACE_SEIZE` followed by `PTRACE_INTERRUPT`. This ensures a non-disruptive stop without delivering signals to the application, maintaining transparency.
### 2. Bootstrap Payload
CRIU identifies the task's current instruction pointer (`RIP`/`PC`) and uses `PTRACE_POKEDATA` to temporarily inject a small bootstrap payload. This payload is typically designed to execute a system call (such as `mmap` or `memfd_create`) to allocate a dedicated memory region for the full parasite blob.
### 3. Memory Exchange Optimization
To maximize efficiency and avoid thousands of slow `ptrace` calls, CRIU uses a **memory exchange** technique:
* The parasite's memory region is often backed by a file descriptor (e.g., `memfd`).
* CRIU maps this same file descriptor into its own address space.
* This allows the CRIU coordinator to write the parasite code, Global Offset Table (GOT), and arguments directly into the target's memory at local memory speeds.
### 4. Relocation and GOT Patching
Since the parasite is a Position-Independent Executable (PIE), CRIU must patch its GOT table with the actual addresses where the blob was mapped in the target process's address space.
### 5. Starting the Daemon
CRIU sets the task's instruction pointer to the entry point of the parasite and resumes execution using `PTRACE_CONT`. The parasite initializes its own stack, sets up signal handling for its own internal use, and enters **daemon mode**.
## Execution and Communication
The parasite runs as a daemon within the target task's context, communicating with the main CRIU process via a Unix domain socket.
### Control Loop
The parasite enters a loop where it waits for commands from the CRIU coordinator. Each command follows a **Request-Response** pattern:
1. **Request**: CRIU sends a command ID (e.g., `PARASITE_CMD_DUMP_PAGES`) and any necessary arguments through the socket.
2. **Execution**: The parasite executes the requested action within the task's context (e.g., calling `vmsplice` on its own memory).
3. **Response**: The parasite sends an acknowledgment (ACK) and optional data back to CRIU.
### Supported Actions
* **Memory Dumping**: Efficiently transfers memory pages to CRIU using the `vmsplice()` system call.
* **Credential Extraction**: Captures UIDs, GIDs, and capability sets.
* **Timer and Signal State**: Reads interval timers and signal action tables that are not visible through `/proc`.
* **Thread Coordination**: In multi-threaded processes, the parasite coordinates state collection across all threads.
## Cleanup and Cure
Once the state capture is complete, CRIU performs a "cure" operation to return the process to its original state:
1. CRIU sends the `PARASITE_CMD_FINI` command to the daemon.
2. The parasite unmaps its allocated memory and prepares to exit.
3. CRIU restores the original register state (including the instruction pointer) and the original code bytes that were overwritten during the bootstrap phase.
4. CRIU detaches from the task, allowing it to resume normal operation or terminating it as requested.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Code Blobs](code-blobs.md)
* [Memory Dumping and Restoring](memory-dumping-and-restoring.md)

View file

@ -1,34 +0,0 @@
# Pending Signals
In Linux, a signal is marked as **pending** if it has been delivered to a task but has not yet been handled (e.g., because the signal is blocked or the task is currently stopped). CRIU provides full support for capturing and restoring these pending signal queues, ensuring that the application's signal state remains perfectly consistent across a checkpoint.
## Checkpoint and Restore of Pending Signals
CRIU manages pending signals using specialized `ptrace` interfaces and signal injection system calls.
### 1. Checkpointing (Dumping)
During a dump, CRIU must extract both the list of pending signals and the detailed metadata associated with each one (the `siginfo_t` structure).
* **PTRACE_PEEKSIGINFO**: CRIU uses this system call (introduced in Linux kernel v3.10 specifically to support CRIU) to read the signal queues of the target task without actually delivering them.
* **Private Signals**: Signals delivered to a specific thread are read using standard peeking.
* **Shared Signals**: Signals delivered to the entire process (which can be handled by any thread) are read by adding the `PTRACE_PEEKSIGINFO_SHARED` flag.
* **Batch Processing**: CRIU reads signals in batches (typically 32 at a time) to efficiently capture entire queues, which is common in high-throughput applications.
* **Signal Mask**: In addition to the pending signals, CRIU uses `PTRACE_GETSIGMASK` to capture the set of signals currently blocked by each thread. This mask is essential because it determines why the signals were pending in the first place.
### 2. Restoration
To recreate the pending state, CRIU re-injects the captured signals into the newly created process tree before it begins normal execution.
* **rt_sigqueueinfo()**: For process-wide (shared) signals, CRIU uses this system call to send a signal to a process with the original `siginfo_t` data.
* **rt_tgsigqueueinfo()**: For thread-specific (private) signals, CRIU uses this variant to target a specific thread ID (TID) within a process.
* **Preserving siginfo**: These system calls allow CRIU to pass the exact original `siginfo_t` structure (including the sender's PID, UID, and any signal-specific data), ensuring the restored task sees the identical signal context.
## Shared vs. Private Pending Signals
* **Multi-threaded Handling**: In multi-threaded applications, signals are carefully tracked:
* **Shared signals** are stored in the process leader's `core.img`.
* **Private signals** are stored in the `core.img` corresponding to each individual thread.
* **Restore Order**: Signals are restored while the task is still under CRIU's control, ensuring that they remain pending until the task is finally resumed and its original signal mask is applied.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Parasite Code](parasite-code.md)

View file

@ -1,38 +0,0 @@
# PID Restoration
A critical requirement for successful checkpoint/restore is ensuring that each process and thread is restored with its original **Process ID (PID)** and **Thread ID (TID)**. Applications frequently rely on these IDs for inter-process communication, signal delivery, and as keys for shared resources (such as System V IPC).
## Restoration Mechanisms
CRIU employs two primary methods to request specific PIDs from the Linux kernel during restoration.
### 1. The Legacy Interface: `ns_last_pid`
On older kernels, Linux does not provide a direct way to request a specific PID during a `fork()` or `clone()` call. Instead, CRIU uses the `/proc/sys/kernel/ns_last_pid` interface:
1. CRIU acquires a global lock (`lock_last_pid`) to minimize the chance of other processes interfering.
2. It writes `N-1` to `/proc/sys/kernel/ns_last_pid`.
3. It calls `fork()`.
4. The kernel assigns the next available PID, which should be `N`.
**Limitations**:
* **Race Conditions**: Other processes on the system (outside of CRIU's control) might fork and "steal" the intended PID between the write and the fork.
* **Performance**: Repeatedly writing to the `/proc` filesystem and calling `fork()` is slow, especially for large process trees.
* **Nesting Complexity**: Handling nested PID namespaces with this interface requires recursively entering namespaces and managing the legacy interface at each level.
### 2. The Modern Interface: `clone3()` with `set_tid`
Introduced in Linux kernel v5.5, the `clone3()` system call provides a much more robust and efficient mechanism via the `set_tid` array in the `clone_args` structure.
* **Atomic Assignment**: CRIU explicitly specifies the desired PID directly during the creation call.
* **No Races**: The PID assignment is atomic with process creation, eliminating the risk of PID theft.
* **Efficiency**: Offers significant performance improvements, particularly during the restoration of large, multi-threaded applications.
* **Full Hierarchy Support**: CRIU can pass an array of PIDs to `set_tid`, allowing it to simultaneously set the process's identity in all nested PID namespaces.
## Implementation in CRIU
CRIU includes architecture-specific assembly wrappers (`RUN_CLONE3_RESTORE_FN`) to safely execute these calls during the critical restoration phase.
* **Automatic Selection**: CRIU automatically detects the presence of `clone3()` and `set_tid` support during the [Kerndat](kerndat.md) phase. If the modern interface is available, it is prioritized.
* **Thread Restoration**: Individual threads are restored using the same mechanisms, ensuring that their TIDs match the original state.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Kerndat](kerndat.md)
* [Restorer Context](restorer-context.md)

View file

@ -1,41 +0,0 @@
# Pidfd Store: Reliable Process Identification
The **Pidfd Store** is an internal CRIU mechanism used during iterative migration to reliably identify processes across multiple pre-dump iterations. It leverages the Linux kernel's `pidfd` interface to eliminate the risks associated with PID reuse.
## The Problem: PID Reuse
In an iterative migration workflow, CRIU performs multiple `pre-dump` operations. Each iteration captures memory pages that have changed since the previous snapshot. To do this safely, CRIU must ensure that it is still talking to the *exact same process* it was in the previous iteration.
If a process dies between iterations and the kernel assigns its old PID to a new, unrelated process, a naive check based only on the PID would fail to detect this change. Performing an incremental dump on a new process using the state of an old one would lead to corrupted images and a failed restoration.
## How the Pidfd Store Works
The Pidfd Store allows CRIU to maintain a persistent, race-free handle for every process in the tree.
### 1. Capturing Pidfds
During the first pre-dump, CRIU calls `pidfd_open()` for every task it captures. Unlike a numeric PID, a **pidfd** is a file descriptor that refers to a specific process *instance*. If that process terminates, its pidfd becomes invalid and will never refer to a subsequent process, even if the numeric PID is reused.
### 2. Persistent Storage via "The Socket Trick"
CRIU often operates as a service, receiving commands via RPC. To keep pidfds alive between independent RPC calls, CRIU uses a clever "socket trick":
* CRIU creates a Unix domain socket and connects it to itself.
* It "sends" the captured pidfds into this socket using the `SCM_RIGHTS` mechanism.
* The Linux kernel stores these file descriptors in the socket's internal buffer. Because the socket is connected to itself, the descriptors remain queued in the kernel until CRIU explicitly reads them back.
### 3. Identity Verification
In each subsequent `pre-dump` or the final `dump` command:
1. CRIU "drains" the pidfds from its internal storage socket.
2. It builds a hash table mapping PIDs to these stable pidfd handles.
3. Before capturing state for a PID, CRIU verifies the task against the stored pidfd.
4. If the pidfd is still valid, CRIU knows it is the same process and can safely perform an incremental memory dump.
5. If the pidfd is invalid or missing, CRIU detects a **PID reuse** event and treats the process as entirely new, performing a full dump to maintain consistency.
## Kernel Requirements
The Pidfd Store requires modern kernel features (automatically detected via [Kerndat](kerndat.md)):
* `pidfd_open()` (Kernel v5.3+)
* `pidfd_getfd()` (Kernel v5.6+, used to transfer the storage socket between service components).
## See also
* [Memory Changes Tracking](memory-changes-tracking.md)
* [Iterative Migration](iterative-migration.md)
* [Kerndat](kerndat.md)

View file

@ -1,39 +0,0 @@
# Pidfd Support
A **pidfd** is a file descriptor that refers to a specific process. Unlike traditional numeric PIDs, which can be reused by the kernel once a process terminates, a pidfd is a stable and race-free handle. It remains valid as long as the descriptor is open, even after the process it refers to has died. CRIU provides full support for checkpointing and restoring pidfds owned by applications.
## How CRIU Handles Pidfds
CRIU treats pidfds as a specialized type of file descriptor. During a dump, it captures both the target of the pidfd and its configuration.
### 1. Checkpointing (Dumping)
When CRIU encounters a pidfd in a process's file descriptor table:
* **Target Identification**: It parses `/proc/$pid/fdinfo/$fd` to determine the numeric PID that the pidfd currently refers to.
* **Tree Validation**: CRIU verifies that this target PID is part of the process tree being checkpointed. This ensures that the process will be available for re-binding during restoration.
* **Metadata Capture**: CRIU records the target process's namespace-local PID and any flags associated with the pidfd (such as `O_NONBLOCK` or `O_CLOEXEC`).
### 2. Restoration
Restoring a pidfd involves recreating a handle that points to the equivalent process in the newly restored tree.
* **Alive Processes**: If the target process is alive, CRIU simply calls the `pidfd_open()` system call on the restored PID of that task.
* **Dead Processes**: A unique feature of pidfds is that they can be held open even after the target process has exited. To restore this state, CRIU:
1. Creates a temporary "helper" process.
2. Opens a pidfd to this helper.
3. Terminates the helper process.
This leaves the restored application with a valid pidfd that refers to a dead process, perfectly mimicking the original state.
## Kernel Evolution: From Anonymous Inodes to `pidfs`
The underlying implementation of pidfds in the Linux kernel has changed over time:
* **Pre-v6.9**: Pidfds were implemented using anonymous inodes. In `/proc/$pid/fd`, they appeared as `anon_inode:[pidfd]`.
* **v6.9 and later**: Pidfds are now part of a dedicated **pidfs** filesystem. They appear in `/proc` as `pidfd:[N]`.
CRIU automatically detects these kernel differences and handles both formats transparently, ensuring that pidfds are correctly identified and restored regardless of the host kernel version.
## Current Limitations
* **PIDFD_THREAD**: Support for pidfds that target specific threads (created with the `PIDFD_THREAD` flag) is currently not implemented.
## See also
* [Pidfd Store (Iterative Migration)](pidfd-store.md)
* [PID Restoration](pid-restore.md)
* [Kerndat Feature Detection](kerndat.md)

View file

@ -1,38 +0,0 @@
# Restartable Sequences (rseq)
Restartable Sequences (rseq) is a Linux kernel feature (introduced in v4.18) that enables high-performance userspace operations on per-CPU data without requiring atomic instructions or traditional locking. Each thread registers a `struct rseq`, and the kernel ensures that if a thread is preempted or interrupted while inside a critical section, it is "restarted" by jumping to a predefined abort handler.
## The Challenge of C/R with rseq
Checkpointing and restoring rseq is exceptionally delicate because the kernel's rseq state is tightly coupled with process execution.
1. **Dumping Sensitivity**: If an infected thread is allowed to run even briefly (e.g., to execute parasite code), the kernel's `rseq_handle_notify_resume` hook may be triggered. This would cause the kernel to "fix up" the rseq state, clearing critical section pointers in userspace memory and losing the very state CRIU needs to capture.
2. **Restoration Morphing**: During restoration, CRIU "morphs" into the target process. If the CRIU binary itself was compiled with rseq support (common in modern distributions), it may have an active rseq registration that must be carefully managed before the memory layout is swapped.
## How CRIU Handles rseq
CRIU provides robust support for rseq, ensuring that threads interrupted within a critical section correctly restart after restoration.
### 1. Checkpointing (Dumping)
CRIU captures the rseq configuration without disturbing the thread's execution state:
* **PTRACE_GET_RSEQ_CONF**: CRIU uses this ptrace command (Kernel v5.13+) to retrieve the address, size, and signature of the `struct rseq` registered for each thread.
* **External Peeking**: To avoid triggering kernel fixups, CRIU **does not** use its standard parasite code to read rseq-related memory. Instead, it uses `PTRACE_PEEKDATA` to read the `struct rseq` and `struct rseq_cs` (critical section descriptor) directly from the outside while the task is frozen.
* **Critical Section Detection**: By reading the `rseq_cs` pointer within the `struct rseq`, CRIU identifies if a thread was in the middle of a sequence at the time of the snapshot.
### 2. Restoration
The restoration process involves two critical rseq-related steps:
* **Unregistering Restorer rseq**: Before CRIU performs the final "morphing" (unmapping its own memory and mapping the application's memory), it must explicitly **unregister** any rseq area used by the CRIU process itself. Failing to do so would cause the kernel to attempt to update a `cpu_id` field in memory that has been unmapped, resulting in an immediate segmentation fault.
* **Re-establishing Application rseq**: Once the application's memory layout and thread registers are restored, CRIU calls the `rseq()` system call for each thread. It re-registers the original `struct rseq` at its original address.
* **Automatic Restart**: Because the `rseq_cs` pointer is restored as part of the thread's memory, the kernel will detect the active critical section upon the first resumption and automatically trigger the application's restart/abort logic, ensuring data integrity.
## Kernel Requirements
* **rseq support**: Linux Kernel v4.18+
* **PTRACE_GET_RSEQ_CONF**: Linux Kernel v5.13+ (Required for reliable automated detection).
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Parasite Code](parasite-code.md)
* [Restorer Context](restorer-context.md)

View file

@ -1,34 +0,0 @@
# Restorer Context
The **Restorer Context** refers to the final stage of the restoration process, where a CRIU process "morphs" itself into the target application. This critical transition is performed by a specialized [PIE](code-blobs.md) blob known as the **Restorer PIE**.
## Why a Dedicated Context is Necessary
During the final stage of restoration, CRIU must accomplish two conflicting goals:
1. **Memory Swapping**: It must unmap all of CRIU's own code, stack, and data to completely clear the address space for the application.
2. **Memory Re-mapping**: It must map the application's original memory regions (VMAs) back into their exact original addresses.
While these operations are occurring, some code must remain in the address space to execute the necessary `munmap()` and `mmap()` system calls. The Restorer PIE is designed to reside in a temporary "safe hole" in the address space—a range that does not conflict with either CRIU's temporary mappings or the application's final layout.
## The Restoration Workflow
1. **Preparation**: The root CRIU process identifies the restorer code and prepares it for distribution.
2. **Forking**: The process tree is recreated. Since the restorer code is mapped in the root task before forking, all child processes share the same physical memory for the restorer via standard Copy-on-Write (COW).
3. **Safe Hole Detection**: Each restored process scans its target memory layout (from the `mm.img` file) to find a contiguous area large enough to hold the restorer code and its stack.
4. **Remapping**: Each process uses `mremap()` to move the shared restorer blob to its specific safe hole.
5. **Execution Jump**: The process jumps from the main CRIU code into the restorer PIE.
6. **Cleanup and Reconstruction**: The restorer PIE unmaps CRIU, recreates the application's original mappings, and populates them with data from the image files.
7. **Final Transition (Sigreturn)**: The very last step is calling `sigreturn()`. The restorer prepares a special signal frame on the stack containing the application's original register state (including the instruction pointer). The kernel then loads this state, effectively resuming the application from the exact point of the checkpoint.
## Technical Characteristics
### Freestanding PIE
Because the restorer runs in an environment where standard libraries have been unmapped, it is a **freestanding** Position-Independent Executable. It contains its own minimal assembly-level system call wrappers and does not depend on `glibc` or any external runtime.
### Conflict Avoidance
The algorithm for finding the "safe hole" is architecture-specific. It must account for various kernel-mapped regions like the vDSO, the stack, and potential guard pages to ensure that the restorer code never overlaps with memory that the application needs.
## See also
* [Code Blobs](code-blobs.md)
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Memory Dumping and Restoring](memory-dumping-and-restoring.md)

View file

@ -1,37 +0,0 @@
# Service Descriptors (Service FDs)
During dump and restore operations, CRIU requires numerous internal file descriptors (FDs) to manage logs, images, RPC communication, and transport sockets. Because the application being checkpointed or restored may use any arbitrary FD number, CRIU must ensure its internal descriptors never conflict with those of the application. To achieve this, CRIU uses the **Service FD Engine**.
## The Protected Range
CRIU avoids FD collisions by placing its internal descriptors in a "protected" range at the very top of the process's file descriptor table.
* **Lifting Limits**: Upon startup, CRIU attempts to lift its `RLIMIT_NOFILE` resource limit (using `rlimit_unlimit_nofile()`) to a very high value (typically 1,048,576 or higher).
* **Top-Down Allocation**: Service FDs are allocated starting from the maximum allowed FD number and working downwards. This strategy places them as far as possible from the range typically used by applications (which usually start from 0 and work upwards).
## Service FD Engine Mechanisms
The engine (`criu/servicefd.c`) provides a robust abstraction for managing these descriptors through several key techniques:
### 1. Per-Process Isolation in Shared Tables
In scenarios where multiple processes share the same file descriptor table (e.g., threads or processes created with `CLONE_FILES`), CRIU assigns a unique `service_fd_id` to each task. The engine uses this ID to offset the service FD range, ensuring that even tasks sharing an FD table have distinct, non-overlapping slots for their internal CRIU descriptors.
### 2. Descriptor Relocation
When CRIU opens a file for its own use (such as an image file or the log), the kernel initially assigns it the lowest available FD number (e.g., FD 3). CRIU then uses `fcntl(F_DUPFD_CLOEXEC)` or `dup3()` to "move" that descriptor to its designated high-range slot and immediately closes the original low-numbered descriptor.
### 3. Protection Flags and Safety
During critical phases of restoration—specifically when the application's FDs are being "planted" into their final numeric slots—CRIU sets a global `sfds_protected` flag. While this flag is set, the service FD engine is "locked." Any attempt by the code to modify or close a service descriptor will trigger an immediate safety crash (BUG), preventing accidental corruption of the restoration state.
## Common Service FD Types
The engine manages various types of descriptors, each with a specific role:
* **LOG_FD**: The descriptor for the main CRIU log file.
* **IMG_FD**: The descriptor used for accessing image files.
* **RPC_SK**: The socket used for RPC communication with external management tools.
* **TRANSPORT_FD**: Sockets used to "send" and "receive" FDs between processes via `SCM_RIGHTS`.
* **PROC_FD**: A stable handle to the `/proc` filesystem.
* **CGROUP_YARD**: A descriptor for the temporary directory used during cgroup restoration.
## See also
* [Dumping File Descriptors](dumping-files.md)
* [Descriptor Assignment](how-to-assign-needed-file-descriptor-to-a-file.md)

View file

@ -1,38 +0,0 @@
# Shared Memory
CRIU provides comprehensive support for capturing and reconstructing the various ways processes share memory in Linux. This includes anonymous shared regions, file-backed shared mappings, and System V IPC segments.
## Types of Shared Memory
CRIU categorizes shared memory into three primary types, each with a dedicated restoration strategy:
### 1. Shared Anonymous Mappings
Created via `mmap(..., MAP_SHARED | MAP_ANONYMOUS, ...)`, these regions have no persistent backing file on disk but are shared between a parent and its children after a `fork()`, or between unrelated processes that inherit the mapping.
* **Identification**: CRIU identifies these regions by parsing `/proc/$pid/maps`. For shared anonymous regions, the kernel assigns a unique **internal inode number** (often appearing in the `inode` column of maps). CRIU uses this inode number as a `shmid` to group and identify identical mappings across the entire process tree.
* **Restoration via memfd**: During restoration, CRIU uses the `memfd_create()` system call to create an anonymous, RAM-backed file.
* One process (the designated "master" for that specific `shmid`) creates the `memfd`, populates it with the memory contents captured in `pages-shmem.img`, and maps it.
* All other processes that shared the original region map the same `memfd` file descriptor, ensuring that any subsequent writes are visible to all participants, just as they were before the checkpoint.
### 2. Shared File Mappings
Created via `mmap(..., MAP_SHARED, fd, ...)`, these regions are backed by a regular file on the filesystem.
* **Mechanism**: CRIU records the file's unique identity (device and inode), the offset within the file, and the mapping length.
* **Restoration**: Each process re-opens the original file (or a restored version of it) and calls `mmap()` with the `MAP_SHARED` flag. The Linux kernel's standard page cache mechanism automatically handles the sharing and synchronization between processes.
### 3. System V IPC Shared Memory
Managed via the legacy `shmget()` and `shmat()` APIs, these segments are part of the kernel's IPC subsystem.
* **Mechanism**: CRIU captures the segment's metadata (key, ID, permissions, size) and its full data contents during the dump.
* **Restoration**: CRIU recreates the IPC segments using `shmget()` with the original parameters and repopulates the data. The restored processes then attach to these segments using `shmat()`, ensuring that IPC-based communication continues seamlessly.
## Advanced Coordination Features
CRIU leverages modern kernel features to handle complex sharing accurately:
* **kcmp**: Used to definitively verify if two memory mappings in different processes refer to the same underlying kernel object (via `KCMP_VM`), ensuring that shared resources are only dumped once.
* **Futex Synchronization**: During restoration, CRIU uses futexes to coordinate between the "master" process (which populates shared memory) and "slave" processes, ensuring that no process starts execution until the shared memory state is fully consistent.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Memory Dumping and Restoring](memory-dumping-and-restoring.md)
* [Kcmp Trees](kcmp-trees.md)

View file

@ -1,50 +0,0 @@
# Network Sockets
CRIU provides extensive support for checkpointing and restoring a wide variety of Linux network sockets, including Unix domain sockets, IPv4/IPv6 (TCP, UDP, RAW), Netlink, and Packet sockets.
## Key Information Captured
To faithfully restore a socket, CRIU must capture its full kernel state:
1. **Identity**: Family (AF_INET, AF_UNIX, etc.), type (SOCK_STREAM, SOCK_DGRAM), and protocol (TCP, UDP, etc.).
2. **Addresses**: Local binding addresses and, for connected sockets, the remote peer address and port.
3. **Socket Options**: A wide range of options (e.g., `SO_KEEPALIVE`, `SO_REUSEADDR`, `TCP_NODELAY`, buffer sizes) are captured and reapplied.
4. **Queues**: Data currently residing in the send and receive buffers is extracted and re-injected upon restoration.
5. **State**: Whether the socket is listening, connected, or in a transitional state (like `FIN_WAIT` or `CLOSE_WAIT` for TCP).
## The Dumping Process
CRIU combines information from multiple sources to build a complete picture of each socket.
### 1. sock_diag
The primary source of truth is the **sock_diag** kernel module. CRIU sends Netlink requests to `sock_diag` to retrieve detailed internal state for most socket families. This provides protocol-level information that is not available via standard userspace APIs.
### 2. SCM_RIGHTS and Parasite
For deeper inspection—such as peeking at socket queues or enabling TCP repair mode—CRIU uses its **parasite code** to send the actual socket file descriptor to the CRIU process via a Unix domain socket using the `SCM_RIGHTS` mechanism. This allows the CRIU coordinator to perform `ioctl`, `getsockopt`, and `recv(MSG_PEEK)` calls directly on a local copy of the socket.
## Restoration Strategies
### TCP Repair Mode
Restoring a TCP connection without disrupting the peer (and without sending any packets) is a major challenge. CRIU uses a specialized kernel feature called **TCP Repair Mode**:
1. CRIU creates a new socket and immediately puts it into repair mode.
2. While in this mode, CRIU can manually set the sequence numbers, window sizes, and other protocol-level state to match the captured dump.
3. It populates the send and receive queues with the dumped data.
4. Finally, it takes the socket out of repair mode, allowing the connection to resume as if it were never interrupted.
### Unix Sockets and SCM_RIGHTS
Unix sockets are unique because they can be used to transfer other file descriptors. CRIU captures these "in-flight" descriptors (files that have been sent but not yet received) and ensures they are correctly re-queued for the restored process.
## Supported Socket Families
* **AF_UNIX**: Full support for Stream, Datagram, and Sequential Packet types, including abstract and file-backed names.
* **AF_INET / AF_INET6**:
* **TCP**: Full connection state restoration via Repair Mode.
* **UDP / UDPLITE**: Captures addresses, options, and queues.
* **RAW**: Captures protocol settings and binding state.
* **AF_NETLINK**: Captures the state of Netlink sockets used for kernel communication (e.g., for routing or audit).
* **AF_PACKET**: Supports capturing packet filters (BPF) and specific interface bindings.
## See also
* [TCP Connection Details](tcp-connection.md)
* [Unix Sockets and SCM_RIGHTS](unix-sockets.md)
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Kerndat Feature Detection](kerndat.md)

View file

@ -1,44 +0,0 @@
# Stages of Restoration
Restoring a complex process tree is a multi-step operation coordinated by a central CRIU process and executed across the newly created process tree. Each stage is synchronized to ensure that dependencies (such as shared files and parent-child relationships) are met and security invariants are maintained.
## The Synchronization Mechanism
CRIU uses a global state machine (defined as `CR_STATE_*` constants) to coordinate between the main CRIU process and the tasks being restored. Tasks use **futexes** in shared memory to signal the completion of their work in each stage and wait for the coordinator to signal the transition to the next stage.
## Stage 1: Root Task Initiation (`CR_STATE_ROOT_TASK`)
The main CRIU process performs initial image analysis, resolves shared resources, and prepares the restorer code blobs. It then forks the **root task** of the tree being restored. The root task performs initial pre-checks and begins its environmental setup.
## Stage 2: Namespace Preparation (`CR_STATE_PREPARE_NAMESPACES`)
The root task (and specialized helpers) initializes the required namespaces (Mount, Network, IPC, UTS, Time). This ensures that all subsequent processes in the tree are created within the correct containerized environment from the moment of their birth.
## Stage 3: Process Tree Forking (`CR_STATE_FORKING`)
The process tree is recursively forked until all processes are recreated.
* **PID Restoration**: Processes are created with their original PIDs using the `clone3()` system call or the `ns_last_pid` interface.
* **Transport Setup**: Each task creates an abstract Unix domain socket to "receive" shared file descriptors from its designated "master" peers.
## Stage 4: Main Resource Restoration (`CR_STATE_RESTORE`)
This is the primary stage where the bulk of the application state is reconstructed:
* **Files and Sockets**: File descriptors are opened locally or received via `SCM_RIGHTS`.
* **Memory Mapping**: VMAs are recreated via `mmap()`.
* **Restorer Jump**: Each task "morphs" by jumping from the main CRIU code into the freestanding **Restorer PIE** blob.
* **Threads**: Individual application threads are recreated within each process.
## Stage 5: Signal Synchronization (`CR_STATE_RESTORE_SIGCHLD`)
Tasks restore their original `SIGCHLD` handlers. This stage serves as a critical synchronization point to transition from CRIU's internal error-tracking (which relies on `SIGCHLD` to detect failed restoration steps in children) to the application's original signal handling logic.
## Stage 6: Security and Credentials (`CR_STATE_RESTORE_CREDS`)
For security reasons, this is the final stage before the application resumes execution. CRIU ensures that sensitive attributes are restored in a specific order:
1. **Credentials**: UIDs, GIDs, and Capability sets are applied.
2. **Seccomp**: Security filters are enabled only after the final credentials are in place.
3. **Process Attributes**: The "dumpable" status and parent-death signals (`pdeath_sig`) are re-established.
By delaying these steps until the very end, CRIU prevents potential security vulnerabilities where a partially-restored process could be intercepted or manipulated while in a transitional state.
## Stage 7: Resumption (`CR_STATE_COMPLETE`)
The tasks execute their final `sigreturn()` call from within the Restorer PIE. This restores the original register state (including the instruction pointer) and jumps the CPU back into the application's code. The process tree is now fully restored and running.
## See also
* [Restorer Context](restorer-context.md)
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [PID Restoration](pid-restore.md)

View file

@ -1,46 +0,0 @@
# TCP Connection Checkpoint and Restore
Checkpointing and restoring established TCP connections is one of CRIU's most advanced features. It allows migrating live applications without dropping active network sessions, provided that the network infrastructure (such as IP routing, virtual IPs, or NAT) supports the transition.
## The Challenge
Standard TCP is managed entirely by the kernel's network stack. Under normal circumstances, userspace cannot:
1. Read or set internal sequence numbers.
2. Directly populate the kernel's send and receive buffers.
3. Transition a socket between states (e.g., from `SYN_SENT` to `ESTABLISHED`) without performing an actual network handshake.
Attempting to restore a connection without specific kernel support would lead to immediate sequence number mismatches and connection resets (RST) from the remote peer.
## The Solution: TCP Repair Mode
To address these limitations, CRIU developers implemented **TCP Repair Mode** in the Linux kernel. When a socket is placed into repair mode, the TCP state machine is suspended, and the kernel allows userspace to manipulate its internal parameters directly.
### Checkpointing (Dumping)
1. **Network Locking**: Before capturing the socket state, CRIU "locks" the connection using **iptables** or **nftables**. This ensures the kernel drops any incoming packets from the peer, preventing the connection state from changing while CRIU is performing the dump.
2. **Enable Repair**: CRIU puts the socket into repair mode (`TCP_REPAIR`).
3. **State Capture**: Using the `libsoccr` library, CRIU extracts:
* **Sequence Numbers**: The current positions in the data stream (`TCP_QUEUE_SEQ`).
* **TCP Options**: Window scaling factors, timestamps, and SACK settings (`TCP_REPAIR_OPTIONS`).
* **Window Parameters**: Send and receive window sizes and offsets (`TCP_REPAIR_WINDOW`).
* **Queue Data**: The actual bytes currently residing in the kernel's send and receive buffers.
4. **Silent Close**: Once the state is captured, the socket is closed while still in repair mode. This is crucial as it prevents the kernel from sending `FIN` or `RST` packets to the peer, keeping the connection "alive" from the peer's perspective.
### Restoration
1. **Socket Creation**: CRIU creates a new socket and immediately enables repair mode.
2. **Binding**: The socket is bound to the original local IP address and port.
3. **State Injection**: captured parameters (sequences, windows, options) are applied to the new socket using `setsockopt`.
4. **Queue Re-population**: The send and receive buffers are re-filled with the original data.
5. **Activation**: CRIU takes the socket out of repair mode. The kernel now considers the connection to be in the exact state it was at the moment of the checkpoint.
6. **Network Unlocking**: Finally, the network locks are removed. The application resumes, and the next packet sent or received will have perfectly consistent sequence numbers.
## Network Locking Methods
CRIU supports multiple strategies to manage the network during migration:
* **nftables** (Preferred): Uses the modern `nft` API to create efficient, temporary rules.
* **iptables**: Uses traditional `iptables` commands to drop packets for the specific 4-tuple.
* **Skip**: Allows external orchestration (e.g., by an SDN controller) to handle packet buffering and redirection.
## See also
* [Network Sockets](sockets.md)
* [Changing IP Addresses](change-ip-address.md)
* [Kerndat Feature Detection](kerndat.md)

View file

@ -1,48 +0,0 @@
# Foundational Technologies
CRIU relies on a wide array of advanced Linux kernel features and userspace libraries to perform transparent checkpoint and restore.
## Kernel Technologies
### Core C/R Capabilities
* **kcmp()**: A system call used to identify shared resources (files, memory mappings, namespaces) between processes by performing internal kernel pointer comparisons.
* **clone3()**: A modern process creation interface that allows CRIU to atomically request specific PIDs and TIDs, even across nested PID namespaces.
* **prctl() Extensions**:
* `PR_SET_MM`: Allows the restorer to reconstruct a process's original memory layout (code, data, heap, etc.).
* `PR_GET_TID_ADDRESS`: Captures the address used for `set_tid_address`.
* `PR_SET_THP_DISABLE`: Preserves the status of Transparent Huge Pages.
* **ptrace() Extensions**:
* `PTRACE_SEIZE` & `PTRACE_INTERRUPT`: Enables non-disruptive task stopping.
* `PTRACE_GETSIGMASK` & `PTRACE_SETSIGMASK`: Captures and restores thread signal masks.
* `PTRACE_PEEKSIGINFO`: Reads pending signal queues without delivering them.
* `PTRACE_GET_RSEQ_CONF`: Retrieves Restartable Sequences (rseq) registration details.
### Resource Introspection
* **/proc Filesystem**:
* `/proc/$pid/map_files`: Provides stable handles to files mapped into a process's memory.
* `/proc/$pid/fdinfo`: Exposes internal state for file descriptors, including positions, flags, and socket handles.
* `ioctl(PAGEMAP_SCAN)`: Efficiently identifies dirty and present pages in large address spaces.
* **sock_diag**: A netlink-based interface used to retrieve detailed protocol-level state for sockets (TCP, UDP, Unix, etc.).
### Advanced Subsystems
* **TCP Repair Mode**: A specialized socket state that allows CRIU to capture and restore the full internal state of TCP connections without sending network packets.
* **Userfaultfd**: Enables **Lazy Migration** by allowing CRIU to handle page faults in userspace and load memory pages on-demand.
* **Mount V2 APIs**: Uses `fsopen()`, `fsmount()`, `open_tree()`, and `move_mount()` to robustly reconstruct complex filesystem hierarchies and propagation groups.
* **Netfilter (nftables/iptables)**: Used to "lock" network connections during migration to prevent state changes.
## Userspace Technologies
### Compel
[Compel](../compel.md) is a dedicated sub-project that provides the infrastructure for **Parasite Injection**. It allows CRIU to execute self-contained code (PIE) within the context of a target process to capture internal state.
### Google Protocol Buffers (protobuf)
CRIU uses [Protocol Buffers](https://developers.google.com/protocol-buffers/) as the standard serialization format for all image files. This ensures a structured, extensible, and cross-version compatible way to store process state.
### ZDTM (Zero-Downtime Migration)
[ZDTM](zdtm-test-suite.md) is CRIU's comprehensive test suite. It includes hundreds of tests that verify the functional correctness of C/R across various architectures and kernel versions.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Memory Changes Tracking](memory-changes-tracking.md)
* [Mount V2](mount-v2.md)
* [PID Restoration](pid-restore.md)

View file

@ -1,41 +0,0 @@
# TTY (Teletype) Support
CRIU provides support for checkpointing and restoring various types of Linux terminals (TTYs), with a primary focus on **Unix98 Pseudoterminals (PTYs)**.
## Key Information Captured
For each TTY instance, CRIU captures a comprehensive set of kernel metadata:
1. **Identity**: The TTY type (PTY, Console, Serial, or Virtual Terminal), subtype (Master or Slave), and its unique kernel index.
2. **Configuration**: Detailed `termios` settings (baud rate, parity, control characters) and window size parameters (`winsize`).
3. **Ownership and Permissions**: The original UID/GID and mode of the TTY device node.
4. **Process Context**: Controlling terminal status, Session ID (SID), and Foreground Process Group (PGRP).
5. **Extended State**: Lock status (`TIOCGLCKTRMIOS`), exclusive mode settings, and packet mode (`TIOCPKT`) flags.
## The PTY Index Challenge
A major challenge in restoring PTYs is that the Linux kernel assigns indices (e.g., the `N` in `/dev/pts/N`) sequentially when `/dev/ptmx` is opened. Standard userspace APIs do not allow requesting a specific index.
### The "Sequential Opening" Strategy
To ensure each PTY is restored with its original index, CRIU employs a specialized "brute-force" technique:
1. **Looping Open**: CRIU enters a loop, repeatedly calling `open("/dev/ptmx")`.
2. **Index Verification**: After each open, it queries the assigned index using the `TIOCGPTN` ioctl.
3. **Consuming Indices**: If the assigned index is lower than the target index, CRIU **keeps the file descriptor open**. This prevents the kernel from reassigning that index.
4. **Target Match**: Once the kernel assigns the correct original index, CRIU uses that descriptor as the restored master PTY.
5. **Cleanup**: All "placeholder" descriptors opened during the loop are then closed, freeing those indices for the rest of the system.
## Restoration Workflow
1. **Master Peer Reconstruction**: A designated process recreates the master PTY using the sequential opening strategy.
2. **Slave Peer Attachment**: Slave processes open the corresponding `/dev/pts/N` devices. Because the master was created with the correct index, these slaves automatically link to the correct peer.
3. **State Application**: Termios, window sizes, and device ownership are applied to the newly opened descriptors.
4. **Controlling Terminal Re-binding**: CRIU re-establishes the relationship between each process and its controlling terminal using the `TIOCSCTTY` ioctl.
## Current Limitations
* **Buffered Data**: Captured TTY input and output queues (data that was sent but not yet read) are currently not fully restored. CRIU ensures the *interface* is restored, but the application may see a reset of buffered streams.
* **Legacy BSD PTYs**: Support for older BSD-style PTYs is not implemented, as the modern Linux kernel does not provide the necessary introspection to reliably pair these devices.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Descriptor Assignment](how-to-assign-needed-file-descriptor-to-a-file.md)
* [Kerndat Feature Detection](kerndat.md)

View file

@ -1,32 +0,0 @@
# TUN/TAP Interface Support
CRIU supports checkpointing and restoring Linux TUN/TAP virtual network interfaces. These devices are frequently used in VPN clients, virtualization platforms (like QEMU), and container networking.
## How CRIU Handles TUN/TAP
CRIU manages TUN/TAP as a combination of a **Network Interface** (the link visible to the kernel) and a **File Descriptor** (the handle used by the application to send and receive packets).
### 1. Checkpointing (Dumping)
During a dump, CRIU identifies TUN/TAP descriptors and collects their full kernel state:
* **Device Attributes**: The interface name, type (TUN for L3 or TAP for L2), and operational flags (e.g., `IFF_NO_PI`, `IFF_VNET_HDR`).
* **Persistency**: Whether the device is persistent (`IFF_PERSIST`), meaning it survives even when no process has it open.
* **Buffer Sizes**: Captures the send buffer size (`TUNGETSNDBUF`) and the virtual network header size (`TUNGETVNETHDRSZ`).
* **Multi-Queue State**: CRIU identifies if multiple file descriptors are attached to different queues of the same TUN/TAP device, allowing for parallel I/O.
* **Ownership**: Captures the UID and GID associated with the TUN/TAP device.
### 2. Restoration
To recreate the TUN/TAP environment exactly as it was, CRIU performs the following:
* **Interface Creation**: Recreates the virtual link or attaches to an existing persistent one using `TUNSETIFF`.
* **Index Preservation**: Uses the `TUNSETIFINDEX` ioctl to ensure the restored interface has the exact same numeric index as the original. This is critical for applications that have cached the interface index.
* **Queue Re-attachment**: For multi-queue devices, CRIU uses `TUNSETIFF` in combination with `TUNSETQUEUE` to correctly re-link each restored file descriptor to its original queue.
* **State Application**: Restores the original buffer sizes, ownership, and persistent status. If a device was not originally persistent, CRIU explicitly drops the persistency after the application has attached to it.
## Current Limitations
* **Packet Filters (BPF)**: Capturing a TAP interface with a complex BPF filter attached is currently **not supported**. The kernel does not provide a robust way to extract the filter program and re-attach it during restoration without the original application context.
* **In-flight Packets**: Data currently residing in the kernel's internal TUN/TAP queues (packets sent by the application but not yet processed by the virtual device, or vice versa) is not preserved across a checkpoint.
## See also
* [Network Sockets](sockets.md)
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Kerndat Feature Detection](kerndat.md)

View file

@ -1,44 +0,0 @@
# Unix Domain Sockets
CRIU supports checkpointing and restoring Unix domain sockets (AF_UNIX), including Stream, Datagram, and Sequential Packet types. Unix sockets are unique because they can be bound to paths in the filesystem and are frequently used to transfer file descriptors between processes.
## Key Challenges
1. **Path and Inode Decoupling**: A Unix socket's address (its bind path) and the actual socket file on disk are not intrinsically linked in the kernel. If a socket file is moved or unlinked after `bind()`, the socket still reports its original address.
2. **In-flight Descriptors**: Unix sockets can contain "in-flight" file descriptors sent via `SCM_RIGHTS` that have been sent by one process but not yet received by the peer.
3. **Cross-Namespace Bindings**: Sockets in one mount namespace may be bound to paths that are only visible or reachable from another mount namespace.
## CRIU's Solution: `SIOCUNIXFILE`
To reliably restore Unix sockets, CRIU developers upstreamed the `SIOCUNIXFILE` ioctl to the Linux kernel. This ioctl allows CRIU to:
* Retrieve an `O_PATH` file descriptor to the actual socket file on disk, regardless of its current name or overmounting status in the filesystem.
* By obtaining this `O_PATH` descriptor, CRIU can definitively identify the exact mount point and inode of the socket file, ensuring it can be recreated in the correct location during restoration.
## Dumping Workflow
1. **Identity and State**: CRIU uses the `sock_diag` netlink interface to retrieve the socket's type, state, and peer ID.
2. **Peer Linking**: For connected or related sockets (like those created via `socketpair()`), CRIU uses the peer information to link them together in the process tree model.
3. **File Handle Retrieval**: For sockets bound to the filesystem, CRIU uses `SIOCUNIXFILE` to get a handle to the socket file and records its location.
4. **Queue and FD Capture**: Send and receive queues are peeked to capture pending data. Crucially, any file descriptors currently residing in the socket's queues are also captured and dumped.
## Restoration Workflow
1. **Socket Creation**: CRIU recreate the socket using the original family, type, and protocol.
2. **Address Binding**:
* CRIU creates a temporary "yard" (a `tmpfs` mount) to safely recreate socket files without interfering with the host filesystem.
* It creates the required directory structure and uses symlinks to ensure the `bind()` call targets the correct path.
3. **Peer Connection**: For connected stream sockets, one peer performs a `bind()` and `listen()`, while the other calls `connect()`. CRIU's file restoration engine coordinates this to ensure the server end is ready before the client attempts to connect.
4. **State and Data Injection**: Socket options and pending data are restored.
5. **Descriptor Redelivery**: In-flight file descriptors are re-injected into the socket's queue using the `SCM_RIGHTS` mechanism, ensuring the application receives them upon resumption.
## External Unix Sockets
If a socket is connected to a process *outside* the tree being checkpointed, CRIU cannot capture the peer's state. These are **External Sockets**.
* Restoration will fail by default for these sockets to prevent inconsistent states.
* Users can explicitly allow these connections using the `--external unix[ID]` option, which tells CRIU to treat the socket as a persistent external dependency.
## See also
* [Network Sockets](sockets.md)
* [External UNIX socket](external-unix-socket.md)
* [Descriptor Assignment](how-to-assign-needed-file-descriptor-to-a-file.md)
* [Kerndat Feature Detection](kerndat.md)

View file

@ -1,48 +0,0 @@
# Userfaultfd and Lazy Migration
**Userfaultfd** is a powerful Linux kernel feature that allows a userspace process (a "monitor") to handle page faults for other processes. CRIU leverages this feature to implement **Lazy Migration**, which significantly reduces the initial downtime when migrating memory-intensive applications.
## Lazy Migration Overview
In a traditional migration, the destination host must receive the entire memory dump (potentially many gigabytes) before the application can resume. This "freeze time" can be several seconds or even minutes for large applications.
With **Lazy Migration**:
1. CRIU captures only the minimal process state (registers, file descriptors, etc.) and essential memory pages.
2. The process tree is resumed immediately on the destination host with most of its memory regions mapped but empty.
3. Memory pages are transferred from the source host only when the application actually tries to access them ("on-demand").
## How it Works: The Lazy Pages Daemon
CRIU implements lazy migration through a dedicated background process called the **Lazy Pages Daemon**.
### 1. The Handover
During the restoration process, each process in the tree:
* Opens a `userfaultfd` file descriptor.
* Registers its memory regions with the kernel for tracking.
* Sends the descriptor to the Lazy Pages Daemon via a Unix domain socket using the `SCM_RIGHTS` mechanism.
* Resumes execution of the application code via `sigreturn`.
### 2. Handling Page Faults
When the application accesses a page that hasn't been loaded yet, the kernel pauses the faulting thread and sends a message to the Lazy Pages Daemon.
1. **Notification**: The daemon receives a `UFFD_EVENT_PAGEFAULT` message containing the faulting address.
2. **Retrieval**: The daemon fetches the required page contents, either from the local `pages.img` images or from a remote **Page Server** on the source host.
3. **Injection**: The daemon uses the `UFFDIO_COPY` (to fill data) or `UFFDIO_ZEROPAGE` (to fill zeros) ioctl to inject the page into the application's address space.
4. **Resumption**: Once the kernel confirms the page is filled, it automatically resumes the paused thread.
## Advanced Features: Non-Cooperative UFFD
CRIU utilizes "non-cooperative" kernel features to maintain consistency if the application modifies its memory layout while being lazily restored:
* **UFFD_FEATURE_EVENT_FORK**: If the process calls `fork()`, the kernel notifies the daemon, which then begins monitoring the new child process.
* **UFFD_FEATURE_EVENT_REMAP**: If the process moves memory using `mremap()`, the daemon updates its internal mapping table to ensure it continues to fetch the correct data for the new addresses.
* **UFFD_FEATURE_EVENT_UNMAP / REMOVE**: Handles scenarios where the application releases memory.
## Benefits and Trade-offs
* **Reduced Downtime**: Applications resume in milliseconds, regardless of their total memory size.
* **Network Jitter**: The application may experience minor stalls (latency spikes) during the initial phase as pages are fetched over the network.
* **Source Dependency**: The source host and the Page Server must remain alive and connected until the entire memory state has been successfully transferred to the destination.
## See also
* [Memory Dumping and Restoring](memory-dumping-and-restoring.md)
* [Page Server](page-server.md)
* [Kerndat Feature Detection](kerndat.md)

View file

@ -1,43 +0,0 @@
# File Validation on Restore
CRIU can verify that regular files and shared libraries being restored on the destination host are identical to the ones captured during the checkpoint. This is a critical security and stability feature, as mismatching libraries (e.g., a different version of `libc.so`) can lead to immediate application crashes or subtle data corruption due to changed offsets and symbols.
## How File Validation Works
File validation is managed via the `--file-validation` option. CRIU automatically captures metadata for all regular, file-backed mappings during the dump and stores it in the image files.
### Supported Validation Methods
CRIU supports two primary methods for validating files:
#### 1. Build-ID (Default)
Most modern Linux executables and shared libraries include a **GNU Build-ID**—a unique, compiler-generated hash stored in a dedicated ELF note section (`NT_GNU_BUILD_ID`).
* **Dumping**: CRIU identifies ELF files by checking their magic numbers. For each ELF file, it maps at most the first **1 MB** of the file (defined as `BUILD_ID_MAP_SIZE`) and extracts the Build-ID hash.
* **Restoring**: During restoration, CRIU performs the same extraction on the file residing on the target host. If the resulting hash does not match the one stored in the image, CRIU aborts the restoration to prevent corruption.
* **Fallback**: If a file is not an ELF or lacks a Build-ID, CRIU automatically falls back to validating the file by its size.
#### 2. File Size (`filesize`)
A simpler and faster validation method that only compares the total size of the file in bytes.
* **Advantage**: Minimal overhead as it only requires a `stat()` call.
* **Disadvantage**: Less reliable than Build-ID, as different versions of a file can occasionally have identical sizes.
## Usage and Configuration
File validation is enabled by default using the `buildid` method. You can explicitly configure the behavior using the `--file-validation` flag:
```bash
# Explicitly use Build-ID validation
criu restore --file-validation buildid ...
# Use only file size validation
criu restore --file-validation filesize ...
```
## Security and Integrity
File validation ensures that the restored process tree runs against the same binary environment it was captured in. This prevents "library injection" scenarios where an attacker might try to force a restored process to run against malicious versions of its original dependencies. It also ensures that internal pointers (such as function addresses) remain valid, as they are often tied to specific library versions.
## See also
* [Dumping File Descriptors](dumping-files.md)
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Filesystem Peculiarities](filesystems-pecularities.md)

View file

@ -1,40 +0,0 @@
# vDSO and VVAR Handling
The **vDSO** (virtual Dynamic Shared Object) and **VVAR** (virtual VARiable) areas are specialized memory regions mapped by the Linux kernel into every process. They enable high-performance userspace execution of specific system calls (such as `gettimeofday()` or `clock_gettime()`) by providing direct access to kernel-maintained code and data without the overhead of a full context switch.
## The Challenge of C/R
The vDSO is uniquely challenging for checkpoint/restore because its contents and memory layout are determined by the **host kernel**.
1. **Address Dependencies**: Applications frequently cache the addresses of vDSO functions. These must remain identical after restoration.
2. **ABI and Kernel Compatibility**: If a process is migrated to a different kernel version, the vDSO code from the original host might be incompatible with the new host's internal kernel-to-userspace data interfaces.
## CRIU's Restoration Strategy
CRIU uses two primary strategies to handle vDSO migration, automatically selecting the best one based on kernel capabilities detected during the [Kerndat](kerndat.md) phase.
### 1. The Proxy (Patching) Method
This is the fallback approach used when the kernel does not support mapping the vDSO at an arbitrary address:
* **Checkpoint**: CRIU captures the original vDSO contents and parses its ELF symbol table to identify the offsets of essential functions (e.g., `__vdso_gettimeofday`, `__vdso_time`).
* **Restoration**:
1. CRIU maps the original vDSO binary at its original virtual address.
2. It identifies the **new vDSO** provided by the current host kernel.
3. For each essential symbol, CRIU locates the corresponding function in the new vDSO.
4. CRIU **patches** the code in the original vDSO with a "trampoline" (a small jump instruction) that redirects execution to the equivalent function in the new host's vDSO.
* **Result**: The application continues to call the memory addresses it originally linked against, but it transparently executes the code optimized for the current host kernel.
### 2. The `arch_prctl` Method (Modern)
On modern kernels (v4.18+ for x86_64), CRIU uses a significantly more efficient mechanism:
* CRIU uses the `arch_prctl()` system call with the `ARCH_MAP_VDSO_64` (or `ARCH_MAP_VDSO_32`) flag to instruct the kernel to map its **current, native** vDSO directly at the application's original virtual address.
* **Advantage**: This eliminates the complexity of ELF patching and ensures the application always uses the most optimal, native code path for the host kernel.
## VVAR Handling
The **VVAR** area contains the raw data (such as the current clock value) that the vDSO code reads.
* VVAR is a data-only region and is not executable.
* CRIU identifies the VVAR mapping during the dump and ensures it is correctly re-established on the destination host, usually adjacent to the restored vDSO.
* When using the `arch_prctl` method, the kernel automatically manages the associated VVAR mapping when the vDSO is moved.
## See also
* [Checkpoint/Restore Architecture](checkpointrestore.md)
* [Kerndat Feature Detection](kerndat.md)
* [Restorer Context](restorer-context.md)

View file

@ -1,25 +0,0 @@
# Zombie Processes
CRIU supports checkpointing and restoring **zombie processes** (tasks that have terminated but have not yet been reaped by their parent). These processes are a vital part of a process tree's state, as they maintain exit codes that the parent may eventually need to read.
## How CRIU Handles Zombies
Zombie processes are unique because they have no active memory, no file descriptors, and no CPU state. However, they still occupy an entry in the kernel's process table and maintain an identity via their PID.
### 1. Checkpointing (Dumping)
During the dump phase, CRIU identifies zombie tasks by checking their state in `/proc/$pid/stat`.
* **State Capture**: CRIU records the zombie's PID and its original **exit code**.
* **Minimal Footprint**: Because zombies have no address space, CRIU does not attempt to inject parasite code or dump memory for them.
### 2. Restoration
Restoring a zombie process involves recreating a task and immediately forcing it into a terminated state without allowing its parent to reap it.
* **The Helper Technique**: CRIU forks a new process using the original PID (via `clone3` or `ns_last_pid`).
* **Immediate Termination**: This process immediately calls the `exit()` system call with the captured exit code.
* **Parent Coordination**: The parent process of the zombie (which is also being restored) is managed to ensure it does not accidentally reap the new zombie before the restoration is complete.
* **Result**: This leaves the new process in the zombie state, perfectly matching the original environment's PID table.
## See also
* [Process Tree Final States](final-states.md)
* [PID Restoration](pid-restore.md)
* [Checkpoint/Restore Architecture](checkpointrestore.md)

147
GEMINI.md
View file

@ -1,147 +0,0 @@
# CRIU (Checkpoint/Restore In User-space)
CRIU is a tool for saving the state of a running application to a set of files
(checkpointing) and restoring it back to a live state. It is primarily used for
live migration of containers, in-place updates, and fast application startup.
It is implemented as a command-line tool called `criu`. The two primary commands
are `dump` and `restore`.
- `dump`: Saves a process tree and all its related resources (file
descriptors, IPC, sockets, namespaces, etc.) into a collection of image
files.
- `restore`: Restores processes from image files to the same state they were
in before the dump.
## Quick Start
To get a feel for `criu`, you can try checkpointing and restoring a simple
process.
1. **Run a simple process:**
Open a terminal and run a command that will run for a while. Find its PID.
```bash
sleep 1000 &
[1] 12345
```
2. **Dump the process:**
As root, use `criu dump` with the process ID (`-t`) and a directory for the
image files (`-D`).
```bash
sudo criu dump -t 12345 -D /tmp/sleep_images -v4 --shell-job
```
The `sleep` process will no longer be running.
3. **Restore the process:**
Use `criu restore` to bring the process back to life from the images.
```bash
sudo criu restore -D /tmp/sleep_images -v4 --shell-job
```
The `sleep` process will be running again as if nothing happened.
# For Developers and Contributors
This section contains more technical details about CRIU's internals and
development process.
## Dump Process
On dump, CRIU uses available kernel interfaces to collect information about
processes. For properties that can only be retrieved from within the process
itself, CRIU injects a binary blob (called a "parasite") into the process's
address space and executes it in the context of one of the process's threads.
This injection is handled by a subproject called **Compel**.
## Restore Process
On restore, CRIU reads the image files to reconstruct the processes. The goal is
to restore them to the exact state they were in before the dump. The restore
process is divided into several stages (defined as `CR_STATE_*` in
`./criu/include/restorer.h`).
The main `criu` process acts as a coordinator. It first restores resources with
inter-process dependencies (file descriptors, sockets, shared memory,
namespaces, etc.). It then forks the process tree and sets up namespaces.
Finally, it restores process-specific resources like file descriptors and memory
mappings.
A key step involves a small, self-contained binary called the "restorer". All
restored processes switch to executing this code, which unmaps the CRIU-specific
memory and restores the application's original memory mappings. On the final
step, the restorer calls `sigreturn` on a prepared signal frame to resume the
process with the state it had at the moment of the dump.
## Compel
Compel is a subproject responsible for generating the binary blobs used for the
parasite code (for dumping) and the restorer code (for restoring). It provides a
library for injecting and executing this code within the target process's
address space. It is a separate project because the logic for generating and
injecting Position-Independent Executable (PIE) code is complex and
self-contained.
## Coding Style
The C code in the CRIU project follows the
[Linux Kernel Coding Style](https://www.kernel.org/doc/html/latest/process/coding-style.html).
Here are some of the main points:
- **Indentation**: Use tabs, which are set to 8 characters.
- **Line Length**: The preferred line limit is 80 characters, but it can be
extended to 120 if it improves code readability.
- **Braces**:
- The opening brace for a function goes on a new line.
- The opening brace for a block (like `if`, `for`, `while`, `switch`) goes
on the same line.
- **Spaces**: Use spaces around operators (`+`, `-`, `*`, `/`, `%`, `<`, `>`,
`=`, etc.).
- **Naming**: Use descriptive names for functions and variables.
- **Comments**: Use C-style comments (`/* ... */`). For multi-line comments,
the preferred format is:
```c
/*
* This is a multi-line
* comment.
*/
```
## Code Layout
The code is organized into the following directories:
- `./compel`: The Compel sub-project.
- `./criu`: The main `criu` tool source code.
- `./images`: Protobuf descriptions for the image files.
- `./test`: All tests.
- `./test/zdtm`: The Zero-Downtime Migration (ZDTM) test suite.
- `./test/zdtm.py`: The executor script for ZDTM tests.
- `./scripts`: Helper scripts.
- `./scripts/build`: Docker image files used for CI and cross-compilation
checks.
- `./crit`: A tool to inspect and manipulate CRIU image files.
- `./soccr`: A library for TCP socket checkpoint/restore.
## Tests
The main test suite is ZDTM. Here is an example of how to run a single test:
```bash
sudo ./test/zdtm.py run -t zdtm/static/env00
```
Each ZDTM test has three stages: preparation, C/R, and results checks. During
the test, a process calls `test_daemon()` to signal it is ready for C/R, then
calls `test_waitsig()` to wait for the C/R stage to complete. After being
restored, the test checks that all its resources are still in a valid state.
## AI-assisted contributions
Add an `Assisted-by` tag to each commit message, placed after the
commit message body and before the `Signed-off-by` line:
```
Assisted-by: AGENT_NAME:MODEL_VERSION
```
Do not add `Signed-off-by` tags on behalf of the user.

View file

@ -1,52 +0,0 @@
## Building CRIU from source code
First, you need to install compile-time dependencies. Check [Installation dependencies](https://criu.org/Installation#Dependencies) for more info.
To compile CRIU, run:
```
make
```
This should create the `./criu/criu` executable.
To change the default behaviour of CRIU, the following variables can be passed
to the make command:
* **NETWORK_LOCK_DEFAULT**, can be set to one of the following
values: `NETWORK_LOCK_IPTABLES`, `NETWORK_LOCK_NFTABLES`,
`NETWORK_LOCK_SKIP`. CRIU defaults to `NETWORK_LOCK_IPTABLES`
if nothing is specified. If another network locking backend is
needed, `make` can be called like this:
`make NETWORK_LOCK_DEFAULT=NETWORK_LOCK_NFTABLES`
## Installing CRIU from source code
Once CRIU is built one can easily setup the complete CRIU package
(which includes executable itself, CRIT tool, libraries, manual
and etc) simply typing
```
make install
```
this command accepts the following variables:
* **DESTDIR**, to specify global root where all components will be placed under (empty by default);
* **PREFIX**, to specify additional prefix for path of every component installed (`/usr/local` by default);
* **BINDIR**, to specify where to put CRIT tool (`$(PREFIX)/bin` by default);
* **SBINDIR**, to specify where to put CRIU executable (`$(PREFIX)/sbin` by default);
* **MANDIR**, to specify directory for manual pages (`$(PREFIX)/share/man` by default);
* **LIBDIR**, to specify directory where to put libraries (guess the correct path by default).
Thus one can type
```
make DESTDIR=/some/new/place install
```
and get everything installed under `/some/new/place`.
## Uninstalling CRIU
To clean up previously installed CRIU instance one can type
```
make uninstall
```
and everything should be removed. Note though that if some variable (**DESTDIR**, **BINDIR**
and such) has been used during installation procedure, the same *must* be passed with
uninstall action.

View file

@ -1,9 +0,0 @@
Andrey Vagin <avagin@gmail.com> (chief)
Mike Rapoport <rppt@kernel.org>
Dmitry Safonov <0x7f454c46@gmail.com>
Adrian Reber <areber@redhat.com>
Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Radostin Stoyanov <rstoyanov@fedoraproject.org>
Alexander Mikhalitsyn <alexander@mihalicyn.com>
Pavel Emelyanov <ovzxemul@gmail.com> (retired)

View file

@ -1,136 +0,0 @@
## Introduction
Dear maintainer. Thank you for investing the time and energy to help
make CRIU as useful as possible. Maintaining a project is difficult,
sometimes unrewarding work. Sure, you will contribute cool features
to the project, but most of your time will be spent reviewing patches,
cleaning things up, documenting, answering questions, justifying design
decisions - while everyone else will just have fun! But remember -- the
quality of the maintainers work is what distinguishes the good projects
from the great. So please be proud of your work, even the unglamorous
parts, and encourage a culture of appreciation and respect for *every*
aspect of improving the project -- not just the hot new features.
Being a maintainer is a time consuming commitment and should not be
taken lightly. This document is a manual for maintainers old and new.
It explains what is expected of maintainers, how they should work, and
what tools are available to them.
This is a living document - if you see something out of date or missing,
speak up!
## What are a maintainer's responsibility?
Part of a healthy project is to have active maintainers to support the
community in contributions and perform tasks to keep the project running.
It is every maintainer's responsibility to:
* Keep the community a friendly place
* Deliver prompt feedback and decisions on pull requests and mailing
list threads
* Encourage other members to help each other, especially in cases the
maintainer is overloaded or feels the lack of needed expertise
* Make sure the changes made respects the philosophy, design and
roadmap of the project
## How are decisions made?
CRIU is an open-source project with an open design philosophy. This
means that the repository is the source of truth for EVERY aspect of the
project. *If it's part of the project, it's in the repo. It's in the
repo, it's part of the project.*
All decisions affecting CRIU, big and small, follow the same 3 steps:
* Submit a change. Anyone can do this
* Discuss it. Anyone can and is encouraged to do this
* Accept or decline it. Only maintainers do this
*I'm a maintainer, should I make pull requests / send patches too?*
Yes. Nobody should ever push to the repository directly. All changes
should be made through submitting (and accepting) the change.
### Two-steps decision making ###
Since CRIU is extremely complex piece of software we try double hard
not to make mistakes, that would be hard to fix in the future. In order
to facilitate this, the "final" decision is made in two stages:
* We definitely want to try something out
* We think that the attempt was successful
Respectively, new features get accepted first into the *criu-dev* branch and
after they have been validated they are merged into the *master* branch. Yet,
urgent bug fixes may land directly in the master branch. If a change in
the criu-dev branch is considered to be bad (whatever it means), then it
can be reverted without propagation to the master branch. Reverting from
the master branch is expected not to happen at all, but if such an
extraordinary case occurs, the impact of this step, especially the question
of backward compatibility, should be considered in the most careful manner.
## Who decides what?
All decisions can be expressed as changes to the repository (either in the
form of pull requests, or patches sent to the mailing list), and maintainers
make decisions by merging or rejecting them. Review and approval or
disagreement can be done by anyone and is denoted by adding a respective
comment in the pull request. However, merging the change into either branch
only happens after approvals from maintainers.
In order for a patch to be merged into the criu-dev branch at least two
maintainers should accept it. In order for a patch to be merged into the
master branch the majority of maintainers should decide that (then prepare
a pull request, submit it, etc.).
Overall the maintainer system works because of mutual respect across the
maintainers of the project. The maintainers trust one another to make
decisions in the best interests of the project. Sometimes maintainers
can disagree and this is part of a healthy project to represent the point
of views of various people. In the case where maintainers cannot find
agreement on a specific change the role of a Chief Maintainer comes into
play.
### Chief maintainer
The chief maintainer for the project is responsible for overall architecture
of the project to maintain conceptual integrity. Large decisions and
architecture changes should be reviewed by the chief maintainer.
Also the chief maintainer has the veto power on any change submitted
to any branch. Naturally, a change in the criu-dev branch can be reverted
after a chief maintainer veto, a change in the master branch must be
carefully reviewed by the chief maintainer and vetoed in advance.
### How are maintainers added (and removed)?
The best maintainers have a vested interest in the project. Maintainers
are first and foremost contributors that have shown they are committed to
the long term success of the project. Contributors wanting to become
maintainers are expected to be deeply involved in contributing code,
patches review, and paying needed attention to the issues in the project.
Just contributing does not make you a maintainer, it is about building trust
with the current maintainers of the project and being a person that they can
rely on and trust to make decisions in the best interest of the project.
When a contributor wants to become a maintainer or nominate someone as a
maintainer, one can submit a "nomination", which technically is the
respective modification to the `MAINTAINERS` file. When a maintainer feels
they is unable to perform the required duties, or someone else wants to draw
the community attention to this fact, one can submit a "(self-)removing"
change.
The final vote to add or to remove a maintainer is to be approved by the
majority of current maintainers (with the chief maintainer having veto power
on that too).
One might have noticed, that the chief maintainer (re-)assignment is not
regulated by this document. That's true :) However, this can be done. If
the community decides that the chief maintainer needs to be changed the
respective "decision making rules" are to be prepared, submitted and
accepted into this file first.
Good luck!

694
Makefile
View file

@ -1,532 +1,322 @@
__nmk_dir=$(CURDIR)/scripts/nmk/scripts/
export __nmk_dir
VERSION_MAJOR := 1
VERSION_MINOR := 5
VERSION_SUBLEVEL :=
VERSION_EXTRA :=
VERSION_NAME :=
VERSION_SO_MAJOR := 1
VERSION_SO_MINOR := 0
export VERSION_MAJOR VERSION_MINOR VERSION_SUBLEVEL VERSION_EXTRA VERSION_NAME
export VERSION_SO_MAJOR VERSION_SO_MINOR
#
# No need to try to remake our Makefiles
Makefile: ;
Makefile.%: ;
scripts/%.mak: ;
$(__nmk_dir)%.mk: ;
# FIXME zdtm building procedure requires implicit rules
# so I can't use strict make file mode and drop completely
# all of implicit rules, so I tuned only .SUFFIXES:
#
# In future zdtm makefiles need to be fixed and the line below
# may be uncommented.
#
#MAKEFLAGS := -r -R
#
# Import the build engine
include $(__nmk_dir)include.mk
include $(__nmk_dir)macro.mk
# Common definitions
#
ifeq ($(origin HOSTCFLAGS), undefined)
HOSTCFLAGS := $(CFLAGS) $(USERCFLAGS)
endif
FIND := find
CSCOPE := cscope
RM := rm -f
LD := $(CROSS_COMPILE)ld
CC := $(CROSS_COMPILE)gcc
NM := $(CROSS_COMPILE)nm
SH := bash
MAKE := make
OBJCOPY := $(CROSS_COMPILE)objcopy
CFLAGS += $(USERCFLAGS)
#
# Supported Architectures
ifneq ($(filter-out x86 arm aarch64 ppc64 s390 mips loongarch64 riscv64,$(ARCH)),)
$(error "The architecture $(ARCH) isn't supported")
endif
# The PowerPC 64 bits architecture could be big or little endian.
# They are handled in the same way.
ifeq ($(SUBARCH),ppc64)
error := $(error ppc64 big endian is not yet supported)
endif
# Fetch ARCH from the uname if not yet set
#
# Architecture specific options.
ifeq ($(ARCH),arm)
ARMV := $(shell echo $(SUBARCH) | sed -nr 's/armv([[:digit:]]).*/\1/p; t; i7')
ARCH ?= $(shell uname -m | sed \
-e s/i.86/i386/ \
-e s/sun4u/sparc64/ \
-e s/s390x/s390/ \
-e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ \
-e s/mips.*/mips/ \
-e s/sh[234].*/sh/)
ifeq ($(ARMV),6)
ARCHCFLAGS += -march=armv6
endif
ifeq ($(ARMV),7)
ARCHCFLAGS += -march=armv7-a+fp
endif
ifeq ($(ARMV),8)
# Running 'setarch linux32 uname -m' returns armv8l on aarch64.
# This tells CRIU to handle armv8l just as armv7hf. Right now this is
# only used for compile testing. No further verification of armv8l exists.
ARCHCFLAGS += -march=armv7-a
ARMV := 7
endif
DEFINES := -DCONFIG_ARMV$(ARMV) -DCONFIG_VDSO_32
PROTOUFIX := y
# For simplicity - compile code in Arm mode without interwork.
# We could choose Thumb mode as default instead - but a dirty
# experiment shows that with 90Kb PIEs Thumb code doesn't save
# even one page. So, let's stick so far to Arm mode as it's more
# universal around all different Arm variations, until someone
# will find any use for Thumb mode. -dima
CFLAGS_PIE := -marm
ifeq ($(ARCH),i386)
SRCARCH := x86-32
DEFINES := -DCONFIG_X86_32
VDSO := y
endif
ifeq ($(ARCH),x86_64)
SRCARCH := x86
DEFINES := -DCONFIG_X86_64
LDARCH := i386:x86-64
VDSO := y
endif
ifeq ($(shell echo $(ARCH) | sed -e 's/arm.*/arm/'),arm)
ARMV := $(shell echo $(ARCH) | sed -nr 's/armv([[:digit:]]).*/\1/p; t; i7')
SRCARCH := arm
DEFINES := -DCONFIG_ARMV$(ARMV)
USERCFLAGS += -Wa,-mimplicit-it=always
ifeq ($(ARMV),6)
USERCFLAGS += -march=armv6
endif
ifeq ($(ARMV),7)
USERCFLAGS += -march=armv7-a
endif
endif
ifeq ($(ARCH),aarch64)
DEFINES := -DCONFIG_AARCH64
CC_MBRANCH_PROT := $(shell $(CC) -c -x c /dev/null -mbranch-protection=none -o /dev/null >/dev/null 2>&1 && echo "-mbranch-protection=none")
CFLAGS_PIE := $(CC_MBRANCH_PROT)
VDSO := y
endif
ifeq ($(ARCH),ppc64)
LDARCH := powerpc:common64
DEFINES := -DCONFIG_PPC64 -D__SANE_USERSPACE_TYPES__
endif
SRCARCH ?= $(ARCH)
LDARCH ?= $(SRCARCH)
ifeq ($(ARCH),x86)
LDARCH := i386:x86-64
DEFINES := -DCONFIG_X86_64
endif
SRC_DIR ?= $(CURDIR)
ARCH_DIR := arch/$(SRCARCH)
ifeq ($(ARCH),mips)
DEFINES := -DCONFIG_MIPS
endif
$(if $(wildcard $(ARCH_DIR)),,$(error "The architecture $(ARCH) isn't supported"))
ifeq ($(ARCH),loongarch64)
DEFINES := -DCONFIG_LOONGARCH64
endif
cflags-y += -iquote include -iquote pie -iquote .
cflags-y += -iquote $(ARCH_DIR) -iquote $(ARCH_DIR)/include
cflags-y += -fno-strict-aliasing
export cflags-y
ifeq ($(ARCH),riscv64)
DEFINES := -DCONFIG_RISCV64
endif
LIBS := -lrt -lpthread -lprotobuf-c -ldl
#
# CFLAGS_PIE:
#
# Ensure with -fno-optimize-sibling-calls that we don't create GOT
# (Global Offset Table) relocations with gcc compilers that don't have
# commit "S/390: Fix 64 bit sibcall".
ifeq ($(ARCH),s390)
ARCH := s390
DEFINES := -DCONFIG_S390
CFLAGS_PIE := -fno-optimize-sibling-calls
endif
DEFINES += -D_FILE_OFFSET_BITS=64
DEFINES += -D_GNU_SOURCE
CFLAGS_PIE += -DCR_NOGLIBC
export CFLAGS_PIE
LDARCH ?= $(ARCH)
export LDARCH
export PROTOUFIX DEFINES
#
# Independent options for all tools.
DEFINES += -D_FILE_OFFSET_BITS=64
DEFINES += -D_LARGEFILE64_SOURCE
DEFINES += -D_GNU_SOURCE
WARNINGS := -Wall -Wformat-security -Wdeclaration-after-statement -Wstrict-prototypes
# -Wdangling-pointer results in false warning when we add a list element to
# local list head variable. It is false positive because before leaving the
# function we always check that local list head variable is empty, thus
# insuring that pointer to it is not dangling anywhere, but gcc can't
# understand it.
# Note: There is similar problem with kernel list, where this warning is also
# disabled: https://github.com/torvalds/linux/commit/49beadbd47c2
WARNINGS += -Wno-dangling-pointer -Wno-unknown-warning-option
CFLAGS-GCOV := --coverage -fno-exceptions -fno-inline -fprofile-update=atomic
export CFLAGS-GCOV
ifeq ($(ARCH),mips)
WARNINGS := -rdynamic
endif
ifeq ($(ARCH),loongarch64)
WARNINGS += -Wno-implicit-function-declaration
endif
ifneq ($(GCOV),)
LDFLAGS += -lgcov
CFLAGS += $(CFLAGS-GCOV)
endif
ifneq ($(NETWORK_LOCK_DEFAULT),)
CFLAGS += -DNETWORK_LOCK_DEFAULT=$(NETWORK_LOCK_DEFAULT)
endif
ifeq ($(ASAN),1)
CFLAGS-ASAN := -fsanitize=address
export CFLAGS-ASAN
CFLAGS += $(CFLAGS-ASAN)
endif
WARNINGS := -Wall
ifneq ($(WERROR),0)
WARNINGS += -Werror
WARNINGS += -Werror
endif
ifeq ($(DEBUG),1)
DEFINES += -DCR_DEBUG
CFLAGS += -O0 -ggdb3
DEFINES += -DCR_DEBUG
CFLAGS += -O0 -ggdb3
else
CFLAGS += -O2 -g
CFLAGS += -O2
endif
ifeq ($(GMON),1)
CFLAGS += -pg
GMONLDOPT += -pg
export GMON GMONLDOPT
CFLAGS += -pg
GMONLDOPT = -pg
endif
AFLAGS += -D__ASSEMBLY__
CFLAGS += $(USERCFLAGS) $(ARCHCFLAGS) $(WARNINGS) $(DEFINES) -iquote include/
HOSTCFLAGS += $(WARNINGS) $(DEFINES) -iquote include/
export AFLAGS CFLAGS USERCLFAGS HOSTCFLAGS
CFLAGS += $(WARNINGS) $(DEFINES)
SYSCALL-LIB := $(ARCH_DIR)/syscalls.built-in.o
ARCH-LIB := $(ARCH_DIR)/crtools.built-in.o
CRIU-SO := libcriu
CRIU-LIB := lib/$(CRIU-SO).so
CRIU-INC := lib/criu.h include/criu-plugin.h include/criu-log.h protobuf/rpc.proto
# Default target
all: criu lib crit cuda_plugin
.PHONY: all
export CC MAKE CFLAGS LIBS SRCARCH DEFINES MAKEFLAGS CRIU-SO
export SRC_DIR SYSCALL-LIB SH RM ARCH_DIR OBJCOPY LDARCH LD
export USERCFLAGS
export cflags-y
export VDSO
#
# Version headers.
include Makefile.versions
VERSION_HEADER := criu/include/version.h
GITID_FILE := .gitid
GITID := $(shell if [ -d ".git" ]; then git describe --always; fi)
# Git repository wasn't inited in CRIU folder
ifeq ($(GITID),)
GITID := 0
else
GITID_FILE_VALUE := $(shell if [ -f '$(GITID_FILE)' ]; then if [ `cat '$(GITID_FILE)'` = $(GITID) ]; then echo y; fi; fi)
ifneq ($(GITID_FILE_VALUE),y)
.PHONY: $(GITID_FILE)
endif
endif
$(GITID_FILE):
$(call msg-gen, $@)
$(Q) echo "$(GITID)" > $(GITID_FILE)
$(VERSION_HEADER): Makefile.versions $(GITID_FILE)
$(call msg-gen, $@)
$(Q) echo "/* Autogenerated, do not edit */" > $@
$(Q) echo "#ifndef __CR_VERSION_H__" >> $@
$(Q) echo "#define __CR_VERSION_H__" >> $@
$(Q) echo "#define CRIU_VERSION \"$(CRIU_VERSION)\"" >> $@
$(Q) echo "#define CRIU_VERSION_MAJOR " $(CRIU_VERSION_MAJOR) >> $@
$(Q) echo "#define CRIU_VERSION_MINOR " $(CRIU_VERSION_MINOR) >> $@
ifneq ($(CRIU_VERSION_SUBLEVEL),)
$(Q) echo "#define CRIU_VERSION_SUBLEVEL " $(CRIU_VERSION_SUBLEVEL) >> $@
endif
ifneq ($(CRIU_VERSION_EXTRA),)
$(Q) echo "#define CRIU_VERSION_EXTRA " $(CRIU_VERSION_EXTRA) >> $@
endif
$(Q) echo "#define CRIU_GITID \"$(GITID)\"" >> $@
$(Q) echo "#endif /* __CR_VERSION_H__ */" >> $@
criu-deps += $(VERSION_HEADER)
#
# Setup proper link for asm headers in common code.
include/common/asm: include/common/arch/$(ARCH)/asm
$(call msg-gen, $@)
$(Q) ln -s ./arch/$(ARCH)/asm $@
criu-deps += include/common/asm
#
# Configure variables.
export CONFIG_HEADER := include/common/config.h
ifeq ($(filter tags etags cscope clean lint indent fetch-clang-format help mrproper,$(MAKECMDGOALS)),)
include Makefile.inc
include Makefile.config
else
# To clean all files, enable make/build options here
export CONFIG_COMPAT := y
export CONFIG_GNUTLS := y
export CONFIG_HAS_LIBBPF := y
export CONFIG_LZ4 := y
include scripts/Makefile.version
include scripts/Makefile.rules
.SUFFIXES:
#
# shorthand
build := -r -R -f scripts/Makefile.build makefile=Makefile obj
build-crtools := -r -R -f scripts/Makefile.build makefile=Makefile.crtools obj
PROGRAM := criu
.PHONY: all zdtm test rebuild clean distclean tags cscope \
docs help pie protobuf $(ARCH_DIR) clean-built lib crit
ifeq ($(GCOV),1)
%.o $(PROGRAM): override CFLAGS += --coverage
endif
#
# Protobuf images first, they are not depending
# on anything else.
$(eval $(call gen-built-in,images))
criu-deps += images/built-in.o
all: config pie $(VERSION_HEADER) $(CRIU-LIB)
$(Q) $(MAKE) $(PROGRAM)
$(Q) $(MAKE) crit
#
# Compel get used by CRIU, build it earlier
include Makefile.compel
protobuf/%::
$(Q) $(MAKE) $(build)=protobuf $@
protobuf:
$(Q) $(MAKE) $(build)=protobuf all
#
# Next the socket CR library
#
SOCCR_A := soccr/libsoccr.a
soccr/Makefile: ;
soccr/%: $(CONFIG_HEADER) .FORCE
$(Q) $(MAKE) $(build)=soccr $@
soccr/built-in.o: $(CONFIG_HEADER) .FORCE
$(Q) $(MAKE) $(build)=soccr all
$(SOCCR_A): |soccr/built-in.o
criu-deps += $(SOCCR_A)
$(ARCH_DIR)/%:: protobuf config
$(Q) $(MAKE) $(build)=$(ARCH_DIR) $@
$(ARCH_DIR): protobuf config
$(Q) $(MAKE) $(build)=$(ARCH_DIR) all
#
# CRIU building done in own directory
# with slightly different rules so we
# can't use nmk engine directly (we
# build syscalls library and such).
#
# But note that we're already included
# the nmk so we can reuse it there.
criu/Makefile: ;
criu/Makefile.packages: ;
criu/Makefile.crtools: ;
criu/%: $(criu-deps) .FORCE
$(Q) $(MAKE) $(build)=criu $@
criu: $(criu-deps)
$(Q) $(MAKE) $(build)=criu all
.PHONY: criu
pie/%:: $(ARCH_DIR)
$(Q) $(MAKE) $(build)=pie $@
pie: $(ARCH_DIR)
$(Q) $(MAKE) $(build)=pie all
unittest: $(criu-deps)
$(Q) $(MAKE) $(build)=criu unittest
.PHONY: unittest
%.o %.i %.s %.d: $(VERSION_HEADER) pie
$(Q) $(MAKE) $(build-crtools)=. $@
built-in.o: $(VERSION_HEADER) pie
$(Q) $(MAKE) $(build-crtools)=. $@
#
# Libraries next once criu is ready
# (we might generate headers and such
# when building criu itself).
lib/Makefile: ;
lib/%: criu .FORCE
lib/%:: $(VERSION_HEADER) config built-in.o
$(Q) $(MAKE) $(build)=lib $@
lib: criu
lib: $(VERSION_HEADER) config built-in.o
$(Q) $(MAKE) $(build)=lib all
.PHONY: lib
clean mrproper:
$(Q) $(MAKE) $(build)=images $@
$(Q) $(MAKE) $(build)=criu $@
$(Q) $(MAKE) $(build)=soccr $@
$(Q) $(MAKE) $(build)=lib $@
$(Q) $(MAKE) $(build)=crit $@
$(Q) $(MAKE) $(build)=compel $@
$(Q) $(MAKE) $(build)=compel/plugins $@
.PHONY: clean mrproper
ifeq ($(VDSO),y)
$(ARCH_DIR)/vdso-pie.o: pie
$(Q) $(MAKE) $(build)=pie $(ARCH_DIR)/vdso-pie.o
PROGRAM-BUILTINS += $(ARCH_DIR)/vdso-pie.o
ifeq ($(SRCARCH),aarch64)
PROGRAM-BUILTINS += $(ARCH_DIR)/intraprocedure.o
endif
endif
clean-amdgpu_plugin:
$(Q) $(MAKE) -C plugins/amdgpu clean
.PHONY: clean-amdgpu_plugin
PROGRAM-BUILTINS += pie/util-fd.o
PROGRAM-BUILTINS += pie/util.o
PROGRAM-BUILTINS += protobuf/built-in.o
PROGRAM-BUILTINS += built-in.o
clean-cuda_plugin:
$(Q) $(MAKE) -C plugins/cuda clean
.PHONY: clean-cuda_plugin
$(SYSCALL-LIB) $(ARCH-LIB) $(PROGRAM-BUILTINS): config
clean-top:
$(Q) $(MAKE) -C Documentation clean
$(Q) $(MAKE) -C soccr/test clean
$(Q) $(MAKE) $(build)=test/compel clean
$(Q) $(RM) .gitid
.PHONY: clean-top
$(PROGRAM): $(SYSCALL-LIB) $(ARCH-LIB) $(PROGRAM-BUILTINS)
$(E) " LINK " $@
$(Q) $(CC) $(CFLAGS) $^ $(LIBS) $(LDFLAGS) $(GMONLDOPT) -rdynamic -o $@
clean: clean-top clean-amdgpu_plugin clean-cuda_plugin
mrproper-top: clean-top clean-amdgpu_plugin clean-cuda_plugin
$(Q) $(RM) $(CONFIG_HEADER)
$(Q) $(RM) $(VERSION_HEADER)
$(Q) $(RM) $(COMPEL_VERSION_HEADER)
$(Q) $(RM) include/common/asm
$(Q) $(RM) compel/include/asm
$(Q) $(RM) cscope.*
$(Q) $(RM) tags TAGS
.PHONY: mrproper-top
mrproper: mrproper-top
#
# Non-CRIU stuff.
#
docs:
$(Q) $(MAKE) -s -C Documentation all
.PHONY: docs
crit:
$(Q) $(MAKE) -C pycriu all
zdtm: all
$(Q) $(MAKE) -C test/zdtm all
.PHONY: zdtm
test: zdtm
$(Q) $(MAKE) -C test
.PHONY: test
amdgpu_plugin: criu
$(Q) $(MAKE) -C plugins/amdgpu all
.PHONY: amdgpu_plugin
clean-built:
$(Q) $(RM) $(VERSION_HEADER)
$(Q) $(MAKE) $(build)=$(ARCH_DIR) clean
$(Q) $(MAKE) $(build)=protobuf clean
$(Q) $(MAKE) $(build)=pie clean
$(Q) $(MAKE) $(build)=lib clean
$(Q) $(MAKE) $(build-crtools)=. clean
$(Q) $(MAKE) -C Documentation clean
$(Q) $(RM) ./include/config.h
$(Q) $(RM) ./$(PROGRAM)
cuda_plugin: criu
$(Q) $(MAKE) -C plugins/cuda all
.PHONY: cuda_plugin
rebuild: clean-built
$(E) " FORCE-REBUILD"
$(Q) $(MAKE)
crit: lib
$(Q) $(MAKE) -C crit
.PHONY: crit
clean: clean-built
$(E) " CLEAN"
$(Q) $(RM) ./*.img
$(Q) $(RM) ./*.out
$(Q) $(RM) ./*.bin
$(Q) $(RM) ./*.gcov ./*.gcda ./*.gcno
$(Q) $(RM) -r ./gcov
$(Q) $(RM) protobuf-desc-gen.h
$(Q) $(MAKE) -C test $@
$(Q) $(MAKE) -C pycriu $@
$(Q) $(RM) ./*.pyc
$(Q) $(RM) -r build
#
# Generating tar requires tag matched CRIU_VERSION.
# If not found then simply use GIT's describe with
# "v" prefix stripped.
head-name := $(shell git tag -l v$(CRIU_VERSION))
ifeq ($(head-name),)
head-name := $(shell git describe 2>/dev/null)
endif
# If no git tag could describe current commit,
# use pre-defined CRIU_VERSION with GITID (if any).
ifeq ($(head-name),)
ifneq ($(GITID),)
head-name := $(CRIU_VERSION)-$(GITID)
else
head-name := $(CRIU_VERSION)
endif
endif
tar-name := $(shell echo $(head-name) | sed -e 's/^v//g')
criu-$(tar-name).tar.bz2:
git archive --format tar --prefix 'criu-$(tar-name)/' $(head-name) | bzip2 > $@
dist tar: criu-$(tar-name).tar.bz2 ;
.PHONY: dist tar
distclean: clean
$(E) " DISTCLEAN"
$(Q) $(RM) ./tags
$(Q) $(RM) ./cscope*
TAGS_FILES_REGEXP := . -name '*.[hcS]' ! -path './.*' \( ! -path './test/*' -o -path './test/zdtm/lib/*' \)
tags:
$(call msg-gen, $@)
$(E) " GEN " $@
$(Q) $(RM) tags
$(Q) $(FIND) $(TAGS_FILES_REGEXP) -print | xargs $(CTAGS) -a
.PHONY: tags
etags:
$(call msg-gen, $@)
$(Q) $(RM) TAGS
$(Q) $(FIND) $(TAGS_FILES_REGEXP) -print | xargs $(ETAGS) -a
.PHONY: etags
$(Q) $(FIND) . -name '*.[hcS]' ! -path './.*' -print | xargs ctags -a
cscope:
$(call msg-gen, $@)
$(Q) $(FIND) $(TAGS_FILES_REGEXP) ! -type l -print > cscope.files
$(E) " GEN " $@
$(Q) $(FIND) . -name '*.[hcS]' ! -path './.*' -print > cscope.files
$(Q) $(CSCOPE) -bkqu
.PHONY: cscope
gcov:
$(E) " GCOV"
$(Q) test -d gcov || mkdir gcov && \
geninfo --output-filename gcov/criu.info --no-recursion criu/ && \
cd gcov && \
genhtml --rc lcov_branch_coverage=1 --output-directory html criu.info
@echo "Code coverage report is in `pwd`/gcov/html/ directory."
.PHONY: gcov
docs:
$(Q) $(MAKE) -s -C Documentation all
docker-build:
$(MAKE) -C scripts/build/ x86_64
.PHONY: docker-build
dist: tar
tar: criu-$(CRTOOLSVERSION).tar.bz2
criu-$(CRTOOLSVERSION).tar.bz2:
git archive --format tar --prefix 'criu-$(CRTOOLSVERSION)/' \
v$(CRTOOLSVERSION) | bzip2 > $@
.PHONY: dist tar
docker-test:
docker run --rm --privileged -v /lib/modules:/lib/modules --network=host --cgroupns=host criu-x86_64 \
./test/zdtm.py run -a --keep-going --ignore-taint
.PHONY: docker-test
install: $(PROGRAM) $(CRIU-LIB) install-man install-crit
$(E) " INSTALL " $(PROGRAM)
$(Q) mkdir -p $(DESTDIR)$(SBINDIR)
$(Q) install -m 755 $(PROGRAM) $(DESTDIR)$(SBINDIR)
$(Q) mkdir -p $(DESTDIR)$(LIBDIR)
$(Q) install -m 755 $(CRIU-LIB) \
$(DESTDIR)$(LIBDIR)/$(CRIU-SO).so.$(VERSION_SO_MAJOR).$(VERSION_SO_MINOR)
$(Q) ln -fns $(CRIU-SO).so.$(VERSION_SO_MAJOR).$(VERSION_SO_MINOR) \
$(DESTDIR)$(LIBDIR)/$(CRIU-SO).so.$(VERSION_SO_MAJOR)
$(Q) ln -fns $(CRIU-SO).so.$(VERSION_SO_MAJOR).$(VERSION_SO_MINOR) \
$(DESTDIR)$(LIBDIR)/$(CRIU-SO).so
$(Q) mkdir -p $(DESTDIR)$(INCLUDEDIR)
$(Q) install -m 644 $(CRIU-INC) $(DESTDIR)$(INCLUDEDIR)
$(Q) mkdir -p $(DESTDIR)$(SYSTEMDUNITDIR)
$(Q) install -m 644 scripts/sd/criu.socket $(DESTDIR)$(SYSTEMDUNITDIR)
$(Q) install -m 644 scripts/sd/criu.service $(DESTDIR)$(SYSTEMDUNITDIR)
$(Q) mkdir -p $(DESTDIR)$(LOGROTATEDIR)
$(Q) install -m 644 scripts/logrotate.d/criu-service $(DESTDIR)$(LOGROTATEDIR)
$(Q) sed -e 's,@version@,$(GITID),' \
-e 's,@libdir@,$(LIBDIR),' \
-e 's,@includedir@,$(dir $(INCLUDEDIR)),' \
lib/criu.pc.in > criu.pc
$(Q) mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig
$(Q) install -m 644 criu.pc $(DESTDIR)$(LIBDIR)/pkgconfig
install-man:
$(Q) $(MAKE) -C Documentation install
install-crit: crit
$(E) " INSTALL crit"
$(Q) python scripts/crit-setup.py install --prefix=$(DESTDIR)
.PHONY: install install-man install-crit
help:
@echo ' Targets:'
@echo ' all - Build all [*] targets'
@echo ' * criu - Build criu'
@echo ' * crit - Build crit'
@echo ' zdtm - Build zdtm test-suite'
@echo ' docs - Build documentation'
@echo ' install - Install CRIU (see INSTALL.md)'
@echo ' uninstall - Uninstall CRIU'
@echo ' install - Install binary and man page'
@echo ' dist - Create a source tarball'
@echo ' clean - Clean most, but leave enough to navigate'
@echo ' mrproper - Delete all compiled/generated files'
@echo ' clean - Clean everything'
@echo ' tags - Generate tags file (ctags)'
@echo ' etags - Generate TAGS file (etags)'
@echo ' cscope - Generate cscope database'
@echo ' rebuild - Force-rebuild of [*] targets'
@echo ' test - Run zdtm test-suite'
@echo ' gcov - Make code coverage report'
@echo ' unittest - Run unit tests'
@echo ' lint - Run code linters'
@echo ' indent - Indent C code'
@echo ' amdgpu_plugin - Make AMD GPU plugin'
@echo ' cuda_plugin - Make NVIDIA CUDA plugin'
.PHONY: help
ruff:
@ruff --version
ruff check ${RUFF_FLAGS} --config=scripts/ruff.toml \
test/zdtm.py \
test/inhfd/*.py \
test/others/rpc/config_file.py \
test/others/action-script/check_actions.py \
test/others/pycriu/*.py \
lib/pycriu/criu.py \
lib/pycriu/__init__.py \
lib/pycriu/images/pb2dict.py \
lib/pycriu/images/images.py \
scripts/criu-ns \
scripts/magic-gen.py \
test/others/criu-ns/run.py \
crit/*.py \
crit/crit/*.py \
test/others/crit/*.py \
scripts/uninstall_module.py \
coredump/ coredump/coredump \
scripts/github-indent-warnings.py \
contrib/criu-service-client/test/*.py \
contrib/compression-benchmark/ \
test/others/compression/ \
soccr/test/run.py \
soccr/test/tcp-test.py
gcov:
$(E) " GCOV"
$(Q) mkdir gcov && \
cd gcov && \
cp ../*.gcno ../*.c ../test/root/crtools/ && \
geninfo --no-checksum --output-filename crtools.l.info --no-recursion .. && \
geninfo --no-checksum --output-filename crtools.ns.info --no-recursion ../test/root/crtools && \
sed -i 's#/test/root/crtools##' crtools.ns.info && \
lcov -a crtools.l.info -a crtools.ns.info -o crtools.info && \
genhtml -o html crtools.info
.PHONY: gcov
shellcheck:
shellcheck --version
shellcheck scripts/*.sh
shellcheck scripts/ci/*.sh
shellcheck contrib/apt-install contrib/dependencies/*.sh
shellcheck -x test/others/crit/*.sh
shellcheck -x test/others/libcriu/*.sh
shellcheck -x test/others/crit/*.sh test/others/criu-coredump/*.sh
shellcheck -x test/others/config-file/*.sh
shellcheck -x test/others/action-script/*.sh
shellcheck -x contrib/criu-service-client/test/*.sh
shellcheck -x test/others/compression/*/*.sh
codespell:
codespell
lint: ruff shellcheck codespell
# Do not append \n to pr_perror, pr_pwarn or fail
! git --no-pager grep -E '^\s*\<(pr_perror|pr_pwarn|fail)\>.*\\n"'
# Do not use %m with pr_* or fail
! git --no-pager grep -E '^\s*\<(pr_(err|perror|warn|pwarn|debug|info|msg)|fail)\>.*%m'
# Do not use errno with pr_perror, pr_pwarn or fail
! git --no-pager grep -E '^\s*\<(pr_perror|pr_pwarn|fail)\>\(".*".*errno'
# End pr_(err|warn|msg|info|debug) with \n
! git --no-pager grep -En '^\s*\<pr_(err|warn|msg|info|debug)\>.*);$$' | grep -v '\\n'
# No EOL whitespace for C files
! git --no-pager grep -E '\s+$$' \*.c \*.h
.PHONY: lint ruff shellcheck codespell
codecov: SHELL := $(shell command -v bash)
codecov:
curl -Os https://uploader.codecov.io/latest/linux/codecov
chmod +x codecov
./codecov
.PHONY: codecov
fetch-clang-format: .FORCE
$(E) ".clang-format"
$(Q) scripts/fetch-clang-format.sh
BASE ?= "HEAD~1"
OPTS ?= "--quiet"
indent:
git clang-format --style file --extensions c,h $(OPTS) $(BASE)
.PHONY: indent
include Makefile.install
.DEFAULT_GOAL := all
# Disable implicit rules in _this_ Makefile.
.SUFFIXES:
#
# Optional local include.
-include Makefile.local
.DEFAULT_GOAL := all

View file

@ -1,77 +0,0 @@
COMPEL_BIN := ./compel/compel-host
export COMPEL_BIN
COMPEL_VERSION_HEADER := compel/include/version.h
$(COMPEL_VERSION_HEADER): Makefile.versions
$(call msg-gen, $(COMPEL_VERSION_HEADER))
$(Q) echo "/* Autogenerated, do not edit */" > $(COMPEL_VERSION_HEADER)
$(Q) echo "#ifndef COMPEL_SO_VERSION_H__" >> $(COMPEL_VERSION_HEADER)
$(Q) echo "#define COMPEL_SO_VERSION_H__" >> $(COMPEL_VERSION_HEADER)
$(Q) echo "#define COMPEL_SO_VERSION \"$(COMPEL_SO_VERSION)\"" >> $(COMPEL_VERSION_HEADER)
$(Q) echo "#define COMPEL_SO_VERSION_MAJOR " $(COMPEL_SO_VERSION_MAJOR) >> $(COMPEL_VERSION_HEADER)
$(Q) echo "#define COMPEL_SO_VERSION_MINOR " $(COMPEL_SO_VERSION_MINOR) >> $(COMPEL_VERSION_HEADER)
$(Q) echo "#define COMPEL_SO_VERSION_SUBLEVEL " $(COMPEL_SO_VERSION_SUBLEVEL) >> $(COMPEL_VERSION_HEADER)
$(Q) echo "#endif /* COMPEL_SO_VERSION_H__ */" >> $(COMPEL_VERSION_HEADER)
compel/include/asm:
$(call msg-gen, $@)
$(Q) ln -s ../arch/$(ARCH)/src/lib/include $@
compel-deps += compel/include/asm
compel-deps += $(COMPEL_VERSION_HEADER)
compel-deps += $(CONFIG_HEADER)
compel-deps += include/common/asm
compel-plugins += compel/plugins/std.lib.a compel/plugins/fds.lib.a
LIBCOMPEL_SO := libcompel.so
LIBCOMPEL_A := libcompel.a
export LIBCOMPEL_SO LIBCOMPEL_A
#
# Compel itself.
compel/Makefile: ;
compel/%: $(compel-deps) $(compel-plugins) .FORCE
$(Q) $(MAKE) $(build)=compel $@
criu-deps += compel/compel-host-bin
#
# Make sure the host program is ready after the
# library and plugins are built.
compel/compel-host-bin: | compel/$(LIBCOMPEL_A) $(compel-plugins)
$(COMPEL_BIN): compel/compel-host-bin
#
# Plugins
compel/plugins/Makefile: ;
compel/plugins/%: $(compel-deps) .FORCE
$(Q) $(MAKE) $(build)=compel/plugins $@
#
# GNU make 4.x supports targets matching via wide
# match targeting, where GNU make 3.x series is not,
# so we have to write them here explicitly.
compel/plugins/std.lib.a: $(compel-deps) .FORCE
$(Q) $(MAKE) $(build)=compel/plugins $@
compel/plugins/shmem.lib.a: $(compel-deps) compel/plugins/std.lib.a .FORCE
$(Q) $(MAKE) $(build)=compel/plugins $@
compel/plugins/fds.lib.a: $(compel-deps) compel/plugins/std.lib.a .FORCE
$(Q) $(MAKE) $(build)=compel/plugins $@
compel/compel: compel/built-in.o compel/$(LIBCOMPEL_A) | $(compel-deps)
$(call msg-link, $@)
$(Q) $(CC) $(CFLAGS) $^ $(WRAPFLAGS) $(LDFLAGS) -rdynamic -o $@
#
# And compel library.
LIBCOMPEL_SO_CFLAGS += $(CFLAGS) -rdynamic -Wl,-soname,$(LIBCOMPEL_SO).$(COMPEL_SO_VERSION_MAJOR)
compel/$(LIBCOMPEL_SO): compel/$(LIBCOMPEL_A)
$(call msg-link, $@)
$(Q) $(CC) -shared $(LIBCOMPEL_SO_CFLAGS) -o $@ -Wl,--whole-archive $^ -Wl,--no-whole-archive $(LDFLAGS)
compel-install-targets += compel/$(LIBCOMPEL_SO)
compel-install-targets += compel/compel
compel-install-targets += $(compel-plugins)

View file

@ -1,124 +1,43 @@
include $(__nmk_dir)utils.mk
include $(__nmk_dir)msg.mk
include scripts/utilities.mak
include scripts/feature-tests.mak
# This is a kludge for $(info ...) to not eat spaces.
S :=
CONFIG := include/config.h
ifeq ($(call try-cc,$(FEATURE_TEST_LIBBSD_DEV),-lbsd),true)
LIBS_FEATURES += -lbsd
FEATURE_DEFINES += -DCONFIG_HAS_LIBBSD
else
$(info Note: Building without setproctitle() support.)
$(info $S Install libbsd-devel (RPM) / libbsd-dev (DEB) to fix.)
ifeq ($(call try-cc,$(LIBBSD_DEV_TEST),-lbsd),y)
LIBS += -lbsd
DEFINES += -DCONFIG_HAS_LIBBSD
endif
ifeq ($(call pkg-config-check,libselinux),y)
LIBS_FEATURES += -lselinux
FEATURE_DEFINES += -DCONFIG_HAS_SELINUX
$(CONFIG): scripts/utilities.mak scripts/feature-tests.mak include/config-base.h
$(E) " GEN " $@
$(Q) @echo '#ifndef __CR_CONFIG_H__' > $@
$(Q) @echo '#define __CR_CONFIG_H__' >> $@
$(Q) @echo '' >> $@
$(Q) @echo '#include "config-base.h"' >> $@
$(Q) @echo '' >> $@
ifeq ($(call try-cc,$(TCP_REPAIR_TEST),),y)
$(Q) @echo '#define CONFIG_HAS_TCP_REPAIR' >> $@
endif
ifeq ($(call pkg-config-check,libbpf),y)
LIBS_FEATURES += -lbpf
FEATURE_DEFINES += -DCONFIG_HAS_LIBBPF
export CONFIG_HAS_LIBBPF := y
ifeq ($(call try-cc,$(PRLIMIT_TEST),),y)
$(Q) @echo '#define CONFIG_HAS_PRLIMIT' >> $@
endif
ifeq ($(call pkg-config-check,libdrm),y)
export CONFIG_AMDGPU := y
LIBDRM_CFLAGS := $(shell $(PKG_CONFIG) --cflags libdrm)
ifeq ($(call try-cc,$(FEATURE_TEST_DRM_COLOR_CTM_3X4),,$(LIBDRM_CFLAGS)),true)
export CONFIG_HAS_DRM_COLOR_CTM_3X4 := y
FEATURE_DEFINES += -DHAVE_DRM_COLOR_CTM_3X4
endif
$(info Note: Building with amdgpu_plugin.)
else
$(info Note: Building without amdgpu_plugin.)
$(info $S Install libdrm-devel (RPM) or libdrm-dev (DEB) to fix.)
ifeq ($(call try-cc,$(STRLCPY_TEST),$(LIBS)),y)
$(Q) @echo '#define CONFIG_HAS_STRLCPY' >> $@
endif
ifeq ($(NO_GNUTLS)x$(call pkg-config-check,gnutls),xy)
LIBS_FEATURES += -lgnutls
export CONFIG_GNUTLS := y
FEATURE_DEFINES += -DCONFIG_GNUTLS
else
$(info Note: Building without GnuTLS support.)
$(info $S Install gnutls-devel (RPM) or gnutls-dev (DEB) to fix.)
ifeq ($(call try-cc,$(STRLCAT_TEST),$(LIBS)),y)
$(Q) @echo '#define CONFIG_HAS_STRLCAT' >> $@
endif
ifeq ($(NO_LZ4)x$(call pkg-config-check,liblz4),xy)
LIBS_FEATURES += -llz4
export CONFIG_LZ4 := y
FEATURE_DEFINES += -DCONFIG_LZ4
else
$(info Note: Building without LZ4 compression support.)
ifeq ($(call try-cc,$(PTRACE_PEEKSIGINFO_TEST),),y)
$(Q) @echo '#define CONFIG_HAS_PEEKSIGINFO_ARGS' >> $@
endif
ifeq ($(call pkg-config-check,libnftables),y)
LIB_NFTABLES := $(shell $(PKG_CONFIG) --libs libnftables)
ifeq ($(call try-cc,$(FEATURE_TEST_NFTABLES_LIB_API_0),$(LIB_NFTABLES)),true)
LIBS_FEATURES += $(LIB_NFTABLES)
FEATURE_DEFINES += -DCONFIG_HAS_NFTABLES_LIB_API_0
else ifeq ($(call try-cc,$(FEATURE_TEST_NFTABLES_LIB_API_1),$(LIB_NFTABLES)),true)
LIBS_FEATURES += $(LIB_NFTABLES)
FEATURE_DEFINES += -DCONFIG_HAS_NFTABLES_LIB_API_1
else
$(info Warn: Building without nftables support (incompatible API version).)
endif
else
$(info Warn: Building without nftables support.)
$(info $S Install nftables-devel (RPM) or libnftables-dev (DEB) to fix.)
ifeq ($(VDSO),y)
$(Q) @echo '#define CONFIG_VDSO' >> $@
endif
export LIBS += $(LIBS_FEATURES)
ifneq ($(PLUGINDIR),)
FEATURE_DEFINES += -DCR_PLUGIN_DEFAULT="\"$(PLUGINDIR)\""
ifeq ($(call try-cc,$(SETPROCTITLE_INIT_TEST),-lbsd),y)
$(Q) @echo '#define CONFIG_HAS_SETPROCTITLE_INIT' >> $@
endif
$(Q) @echo '#endif /* __CR_CONFIG_H__ */' >> $@
CONFIG_FILE = .config
config: $(CONFIG)
$(CONFIG_FILE):
touch $(CONFIG_FILE)
ifeq ($(ARCH),x86)
# CONFIG_COMPAT is only for x86 now, no need for compile-test other archs
ifeq ($(call try-asm,$(FEATURE_TEST_X86_COMPAT)),true)
export CONFIG_COMPAT := y
FEATURE_DEFINES += -DCONFIG_COMPAT
else
$(info Note: Building without ia32 C/R, missing ia32 support in gcc.)
$(info $S It may be related to missing gcc-multilib in your)
$(info $S distribution, or you may have Debian with buggy toolchain.)
$(info $S See https://github.com/checkpoint-restore/criu/issues/315.)
endif
endif
export DEFINES += $(FEATURE_DEFINES)
export CFLAGS += $(FEATURE_DEFINES)
FEATURES_LIST := TCP_REPAIR PTRACE_PEEKSIGINFO \
SETPROCTITLE_INIT TCP_REPAIR_WINDOW MEMFD_CREATE \
OPENAT2 NO_LIBC_RSEQ_DEFS
# $1 - config name
define gen-feature-test
ifeq ($$(call try-cc,$$(FEATURE_TEST_$(1)),$$(LIBS_FEATURES),$$(DEFINES)),true)
$(Q) echo '#define CONFIG_HAS_$(1)' >> $$@
else
$(Q) echo '// CONFIG_HAS_$(1) is not set' >> $$@
endif
endef
define config-header-rule
$(CONFIG_HEADER): scripts/feature-tests.mak $(CONFIG_FILE)
$(call msg-gen, $$@)
$(Q) echo '#ifndef __CR_CONFIG_H__' > $$@
$(Q) echo '#define __CR_CONFIG_H__' >> $$@
$(Q) echo '' >> $$@
$(call map,gen-feature-test,$(FEATURES_LIST))
$(Q) cat $(CONFIG_FILE) | sed -n -e '/^[^#]/s/^/#define CONFIG_/p' >> $$@
$(Q) echo '#endif /* __CR_CONFIG_H__ */' >> $$@
endef
$(eval $(config-header-rule))
.PHONY: config

87
Makefile.crtools Normal file
View file

@ -0,0 +1,87 @@
obj-y += parasite-syscall.o
obj-y += mem.o
obj-y += rst-malloc.o
obj-y += cr-restore.o
obj-y += crtools.o
obj-y += security.o
obj-y += image.o
obj-y += image-desc.o
obj-y += net.o
obj-y += tun.o
obj-y += proc_parse.o
obj-y += sysfs_parse.o
obj-y += cr-dump.o
obj-y += cr-show.o
obj-y += cr-check.o
obj-y += cr-dedup.o
obj-y += util.o
obj-y += bfd.o
obj-y += action-scripts.o
obj-y += sysctl.o
obj-y += ptrace.o
obj-y += kcmp-ids.o
obj-y += rbtree.o
obj-y += log.o
obj-y += libnetlink.o
obj-y += sockets.o
obj-y += sk-inet.o
obj-y += sk-tcp.o
obj-y += sk-unix.o
obj-y += sk-packet.o
obj-y += sk-netlink.o
obj-y += sk-queue.o
obj-y += files.o
obj-y += files-reg.o
obj-y += files-ext.o
obj-y += pipes.o
obj-y += fifo.o
obj-y += file-ids.o
obj-y += namespaces.o
obj-y += uts_ns.o
obj-y += ipc_ns.o
obj-y += netfilter.o
obj-y += shmem.o
obj-y += eventfd.o
obj-y += eventpoll.o
obj-y += mount.o
obj-y += fsnotify.o
obj-y += irmap.o
obj-y += signalfd.o
obj-y += pstree.o
obj-y += protobuf.o
obj-y += protobuf-desc.o
obj-y += tty.o
obj-y += cr-exec.o
obj-y += file-lock.o
obj-y += page-pipe.o
obj-y += page-xfer.o
obj-y += page-read.o
obj-y += pagemap-cache.o
obj-y += kerndat.o
obj-y += stats.o
obj-y += cgroup.o
obj-y += timerfd.o
obj-y += aio.o
obj-y += string.o
obj-y += sigframe.o
ifeq ($(VDSO),y)
obj-y += $(ARCH_DIR)/vdso.o
endif
obj-y += cr-service.o
obj-y += sd-daemon.o
obj-y += plugin.o
obj-y += cr-errno.o
ifneq ($(MAKECMDGOALS),clean)
incdeps := y
endif
PROTOBUF_GEN := scripts/protobuf-gen.sh
protobuf-desc.c: protobuf-desc-gen.h
protobuf-desc-gen.h: $(PROTOBUF_GEN) include/protobuf-desc.h
$(E) " GEN " $@
$(Q) $(SH) $(obj)/$(PROTOBUF_GEN) > $@
cleanup-y += protobuf-desc-gen.h

Some files were not shown because too many files have changed in this diff Show more