Skip to content

Support sparsefiles Copy in blockfile snapshotter#10197

Closed
zhaojizhuang wants to merge 1 commit into
containerd:mainfrom
zhaojizhuang:dev
Closed

Support sparsefiles Copy in blockfile snapshotter#10197
zhaojizhuang wants to merge 1 commit into
containerd:mainfrom
zhaojizhuang:dev

Conversation

@zhaojizhuang

@zhaojizhuang zhaojizhuang commented May 9, 2024

Copy link
Copy Markdown
Contributor

Adds the ability to copy sparse files and can be configured in the config.

In the Go language, io.Copy is equivalent to cp --sparse=never xxx, so even if the initial scratch file is a sparse file, it is still a non-sparse file after go io.copy. Each snapshot block file will occupy the full block file size by default.

Signed-off-by: Zhao Jizhuang <571130360@qq.com>
@k8s-ci-robot

Copy link
Copy Markdown

Hi @zhaojizhuang. Thanks for your PR.

I'm waiting for a containerd member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@zhaojizhuang

Copy link
Copy Markdown
Contributor Author

cc @dmcgowan @dcantah @fuweid

@dmcgowan

dmcgowan commented May 9, 2024

Copy link
Copy Markdown
Member

Can we stat each file after the copy to see if the block usage differs? The expectation right now is blockfile snapshotter is not very efficient when copy file range is not used. Are the sparse file properties preserved when it doesn't go through a full read/write copy of the file?

@zhaojizhuang

zhaojizhuang commented May 10, 2024

Copy link
Copy Markdown
Contributor Author

@dmcgowan
according to https://wiki.archlinux.org/title/sparse_file

We use the command "fallocate -d copy.img" to make the snapshot blockfile sparse.

here is the test demo,using nginxt,which has 7 layers

root@n37-006-180:~# nerdctl pull nginx --snapshotter blockfile
docker.io/library/nginx:latest:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:32e76d4f34f80e479964a0fbd4c5b4f6967b5322c8d004e9cf0cb81c93510766:    exists         |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:43df308e3a5e165fd5d4e077c991ed936aebca01bf20ab25961d7e542db410a0: exists         |++++++++++++++++++++++++++++++++++++++|
config-sha256:1d668e06f1e534ab338404ba891c37d618dd53c9073dcdd4ebde82aa7643f83f:   exists         |++++++++++++++++++++++++++++++++++++++|
layer-sha256:e58cbd904f7f72cc6e30b30dc19b47fc4c1ee2a0103c69eb5b20f8e950c58e42:    exists         |++++++++++++++++++++++++++++++++++++++|
layer-sha256:b0a0cf830b12453b7e15359a804215a7bcccd3788e2bcecff2a03af64bbd4df7:    exists         |++++++++++++++++++++++++++++++++++++++|
layer-sha256:1e5314d67f1699f049bf4bd694833e1e2b1b35905847570442f75ca71e758a62:    exists         |++++++++++++++++++++++++++++++++++++++|
layer-sha256:4d84de5fb9b2d32bc417c2e043fcc88e3303970c61cd4916956e66431a9ce7d3:    exists         |++++++++++++++++++++++++++++++++++++++|
layer-sha256:05f7109fea9eb1af4aae06cbc0894f5e2c5b07a638ebb509f0d88b6dfc948997:    exists         |++++++++++++++++++++++++++++++++++++++|
layer-sha256:2818b7b6a9db4d0901d74850cf1096f76fa22d8a7fad4d711710fbf6ab1b48d1:    exists         |++++++++++++++++++++++++++++++++++++++|
layer-sha256:8066e07ce4f22945d61fa9682f5ef843bb750a4829d3176009d383933c27eedd:    exists         |++++++++++++++++++++++++++++++++++++++|
elapsed: 3.7 s                                                                    total:   0.0 B (0.0 B/s)

After

After 7 snapshots (18~24) were sparsified, the results are as follows:

du -h

root@n37-006-180:/var/lib/containerd/io.containerd.snapshotter.v1.blockfile/snapshots# du -h 18 19 20 21 22 23 24
86M	18
198M	19
198M	20
198M	21
198M	22
198M	23
198M	24

du -h --apparent-size

root@n37-006-180:/var/lib/containerd/io.containerd.snapshotter.v1.blockfile/snapshots# du -h --apparent-size 18 19 20 21 22 23 24
512M	18
512M	19
512M	20
512M	21
512M	22
512M	23
512M	24

stat

root@n37-006-180:/var/lib/containerd/io.containerd.snapshotter.v1.blockfile/snapshots# stat 18 19 20 21 22 23 24
  File: 18
  Size: 536870912 	Blocks: 175208     IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835365     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-08 16:06:57.442605960 +0800
Modify: 2024-05-08 16:06:57.422605477 +0800
Change: 2024-05-08 16:06:57.422605477 +0800
 Birth: -
  File: 19
  Size: 536870912 	Blocks: 403536     IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835373     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-08 16:07:02.313723617 +0800
Modify: 2024-05-08 16:07:02.289723037 +0800
Change: 2024-05-08 16:07:02.289723037 +0800
 Birth: -
  File: 20
  Size: 536870912 	Blocks: 403496     IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835380     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-08 16:07:06.029813372 +0800
Modify: 2024-05-08 16:07:06.020813155 +0800
Change: 2024-05-08 16:07:06.020813155 +0800
 Birth: -
  File: 21
  Size: 536870912 	Blocks: 403496     IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835420     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-08 16:07:09.975908685 +0800
Modify: 2024-05-08 16:07:09.966908468 +0800
Change: 2024-05-08 16:07:09.966908468 +0800
 Birth: -
  File: 22
  Size: 536870912 	Blocks: 403496     IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835428     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-08 16:07:13.929004166 +0800
Modify: 2024-05-08 16:07:13.921003973 +0800
Change: 2024-05-08 16:07:13.921003973 +0800
 Birth: -
  File: 23
  Size: 536870912 	Blocks: 403496     IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835429     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-08 16:07:17.882099647 +0800
Modify: 2024-05-08 16:07:17.874099454 +0800
Change: 2024-05-08 16:07:17.874099454 +0800
 Birth: -
  File: 24
  Size: 536870912 	Blocks: 403496     IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835436     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-08 16:07:21.825194887 +0800
Modify: 2024-05-08 16:07:21.834195105 +0800
Change: 2024-05-08 16:07:21.834195105 +0800
 Birth: -

before

before 7 snapshots (18~24) were sparsified, the results are as follows:

du -h

root@n37-006-180:/var/lib/containerd/io.containerd.snapshotter.v1.blockfile/snapshots# du -h 25 26 27 28 29 30 31
513M	25
513M	26
513M	27
513M	28
513M	29
513M	30
512M	31

du -h --apparent-size

root@n37-006-180:/var/lib/containerd/io.containerd.snapshotter.v1.blockfile/snapshots# du -h --apparent-size 25 26 27 28 29 30 31
512M	25
512M	26
512M	27
512M	28
512M	29
512M	30
512M	31

stat

root@n37-006-180:/var/lib/containerd/io.containerd.snapshotter.v1.blockfile/snapshots# stat 25 26 27 28 29 30 31
  File: 25
  Size: 536870912 	Blocks: 1048584    IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835047     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-10 11:41:07.107070124 +0800
Modify: 2024-05-10 11:41:07.090069713 +0800
Change: 2024-05-10 11:41:07.090069713 +0800
 Birth: -
  File: 26
  Size: 536870912 	Blocks: 1048584    IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835048     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-10 11:41:11.804183768 +0800
Modify: 2024-05-10 11:41:11.786183332 +0800
Change: 2024-05-10 11:41:11.786183332 +0800
 Birth: -
  File: 27
  Size: 536870912 	Blocks: 1048584    IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835053     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-10 11:41:15.521273699 +0800
Modify: 2024-05-10 11:41:15.513273505 +0800
Change: 2024-05-10 11:41:15.513273505 +0800
 Birth: -
  File: 28
  Size: 536870912 	Blocks: 1048584    IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835056     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-10 11:41:19.467369176 +0800
Modify: 2024-05-10 11:41:19.459368982 +0800
Change: 2024-05-10 11:41:19.459368982 +0800
 Birth: -
  File: 29
  Size: 536870912 	Blocks: 1048584    IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835059     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-10 11:41:23.421464842 +0800
Modify: 2024-05-10 11:41:23.413464649 +0800
Change: 2024-05-10 11:41:23.413464649 +0800
 Birth: -
  File: 30
  Size: 536870912 	Blocks: 1048584    IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835103     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-10 11:41:27.374560482 +0800
Modify: 2024-05-10 11:41:27.367560313 +0800
Change: 2024-05-10 11:41:27.367560313 +0800
 Birth: -
  File: 31
  Size: 536870912 	Blocks: 1048576    IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 1835104     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-10 11:41:31.315655833 +0800
Modify: 2024-05-10 11:41:31.325656075 +0800
Change: 2024-05-10 11:41:31.325656075 +0800
 Birth: -

@zhaojizhuang

Copy link
Copy Markdown
Contributor Author

gently ping ... @dmcgowan


// fallocate can make existing files sparse on supported file systems.
func fallocate(file string) error {
cmd := exec.Command("fallocate", "-d", file)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just seek(); write(); close(); instead of introducing a dependency on an external command?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. it sounds that's the best thing to also from perf perspective if io.Copy first creates a full file which gets holes added afterwards.

@fidencio fidencio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a maintainer here, but it does improve a lot the usability of the blockfile snapshotter.

@AkihiroSuda AkihiroSuda added this to the 2.2 milestone Jun 18, 2025
// mountOptions are the base options added to the mount (defaults to ["loop"])
mountOptions []string

// copySparse determine whether sparse files when copy (defaults to true,equivalent to "cp --sparse=always xxx")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this defaulting to true? We also would not want this to be the default since it is not necessary on all file systems.

// on initialization of the plugin instead of using an existing.
RecreateScratch bool `toml:"recreate_scratch"`

// CopySparse create sparse files when copy when is 'false'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is a bit confusing, when what is false?

@dmcgowan

Copy link
Copy Markdown
Member

carried

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

6 participants