* [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
@ 2026-01-28 14:35 Daniel Dragomir
2026-01-28 14:35 ` [OE-core][scarthgap][PATCH] oeqa/selftest/wic: test recursive dir copy on ext partitions Daniel Dragomir
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Dragomir @ 2026-01-28 14:35 UTC (permalink / raw)
To: openembedded-core
From: "Dragomir, Daniel" <daniel.dragomir@windriver.com>
wic uses debugfs to write on ext* partitions, but debugfs can only
write to the current working directory and it cannot copy complete
directory trees. Running 'wic ls' on a copied directory show this:
-l: Ext2 inode is not a directory
Fix this by creating a command list for debugfs (-f parameter) when
recursive parsing the host directory in order to create a similar
directory structure (mkdir) and copy files (write) on each level
into the destination directory from the wic's ext* partition.
Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
scripts/lib/wic/engine.py | 63 ++++++++++++++++++++++++++++++---------
1 file changed, 49 insertions(+), 14 deletions(-)
diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
index ce7e6c5d75..565a0db38a 100644
--- a/scripts/lib/wic/engine.py
+++ b/scripts/lib/wic/engine.py
@@ -327,29 +327,64 @@ class Disk:
path))
def copy(self, src, dest):
- """Copy partition image into wic image."""
- pnum = dest.part if isinstance(src, str) else src.part
+ """Copy files or directories to/from the vfat or ext* partition."""
+ pnum = dest.part if isinstance(src, str) else src.part
+ partimg = self._get_part_image(pnum)
if self.partitions[pnum].fstype.startswith('ext'):
- if isinstance(src, str):
- cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
- format(os.path.dirname(dest.path), src, os.path.basename(src),
- self.debugfs, self._get_part_image(pnum))
- else: # copy from wic
- # run both dump and rdump to support both files and directory
+ if isinstance(src, str): # host to image case
+ if os.path.isdir(src):
+ base = os.path.abspath(src)
+ base_parent = os.path.dirname(base)
+ cmds = []
+ made = set()
+
+ for root, dirs, files in os.walk(base):
+ for fname in files:
+ host_file = os.path.join(root, fname)
+ rel = os.path.relpath(host_file, base_parent)
+ dest_file = os.path.join(dest.path, rel)
+ dest_dir = os.path.dirname(dest_file)
+
+ # create dir structure (mkdir -p)
+ parts = dest_dir.strip('/').split('/')
+ cur = ''
+ for p in parts:
+ cur = cur + '/' + p
+ if cur not in made:
+ cmds.append(f'mkdir "{cur}"')
+ made.add(cur)
+
+ cmds.append(f'write "{host_file}" "{dest_file}"')
+
+ # write script to a temp file
+ with tempfile.NamedTemporaryFile(mode='w', delete=False,
+ prefix='wic-debugfs-') as tf:
+ for line in cmds:
+ tf.write(line + '\n')
+ scriptname = tf.name
+
+ cmd = f"{self.debugfs} -w -f {scriptname} {partimg}"
+
+ else: # single file
+ cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
+ format(os.path.dirname(dest.path), src,
+ os.path.basename(src), self.debugfs, partimg)
+
+ else: # image to host case
cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n' | {} {}".\
format(os.path.dirname(src.path), src.path,
- dest, src.path, dest, self.debugfs,
- self._get_part_image(pnum))
+ dest, src.path, dest, self.debugfs, partimg)
+
else: # fat
if isinstance(src, str):
cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
- self._get_part_image(pnum),
- src, dest.path)
+ partimg,
+ src, dest.path)
else:
cmd = "{} -i {} -snop ::{} {}".format(self.mcopy,
- self._get_part_image(pnum),
- src.path, dest)
+ partimg,
+ src.path, dest)
exec_cmd(cmd, as_shell=True)
self._put_part_image(pnum)
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [OE-core][scarthgap][PATCH] oeqa/selftest/wic: test recursive dir copy on ext partitions
2026-01-28 14:35 [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition Daniel Dragomir
@ 2026-01-28 14:35 ` Daniel Dragomir
0 siblings, 0 replies; 10+ messages in thread
From: Daniel Dragomir @ 2026-01-28 14:35 UTC (permalink / raw)
To: openembedded-core
From: "Dragomir, Daniel" <daniel.dragomir@windriver.com>
Extend the wic selftests to cover recursive directory copying
into ext partitions.
Previously, copying a directory into an ext partition could
appear to succeed, but attempting to access the directory
contents would fail with:
-l: Ext2 inode is not a directory
This was fixed in commit 4fc3b42774 ("wic/engine: fix copying
directories into wic image with ext* partition").
This test now verifies that directories copied with "wic cp"
into an ext4 partition:
- are created with correct inode types
- can be listed recursively with "wic ls"
- preserve files and subdirectories
- can be copied back out of the image without data loss
A simple directory structure is used in this test:
wic-test-cp-ext-dir/
├── topfile.txt
└── subdir/
└── subfile.txt
Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
meta/lib/oeqa/selftest/cases/wic.py | 65 +++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py
index b616759209..1ba180ff0e 100644
--- a/meta/lib/oeqa/selftest/cases/wic.py
+++ b/meta/lib/oeqa/selftest/cases/wic.py
@@ -12,6 +12,7 @@ import os
import sys
import unittest
import hashlib
+import filecmp
from glob import glob
from shutil import rmtree, copy
@@ -1662,6 +1663,70 @@ class ModifyTests(WicTestCase):
runCmd("wic cp %s:2/etc/fstab %s -n %s" % (images[0], testfile.name, sysroot))
self.assertTrue(os.stat(testfile.name).st_size > 0, msg="Filesize not as expected %s" % os.stat(testfile.name).st_size)
+ # prepare directory structure
+ testdir = os.path.join(self.resultdir, "wic-test-cp-ext-dir")
+ testsubdir = os.path.join(testdir, "subdir")
+ os.makedirs(testsubdir)
+
+ # add a file in the top-level of the directory
+ src_file = os.path.join(testdir, "topfile.txt")
+ with open(src_file, "w") as f:
+ f.write("top-level\n")
+
+ # add file in the subdir
+ src_subfile = os.path.join(testsubdir, "subfile.txt")
+ with open(src_subfile, "w") as f:
+ f.write("sub-level\n")
+
+ # copy directory to the partition root
+ runCmd("wic cp %s %s:2/ -n %s" % (testdir, images[0], sysroot))
+ basedir = os.path.basename(testdir)
+
+ # check if directory is there at partition root
+ result = runCmd("wic ls %s:2/ -n %s" % (images[0], sysroot))
+ root_entries = set(line.split()[-1] for line in result.output.split('\n') if line)
+ self.assertIn(basedir, root_entries, msg="Expected directory not present at root: %s" % root_entries)
+
+ # list INSIDE the copied directory
+ result = runCmd("wic ls %s:2/%s/ -n %s" % (images[0], basedir, sysroot))
+ self.assertEqual(0, result.status,
+ msg="wic ls inside copied directory failed. Output:\n%s" % result.output)
+ self.assertNotIn("Ext2 inode is not a directory", result.output,
+ msg="Regression detected (inode not a directory). Output:\n%s" % result.output)
+
+ inside_entries = set(line.split()[-1] for line in result.output.split('\n') if line)
+ self.assertTrue(set(["subdir", "topfile.txt"]).issubset(inside_entries),
+ msg="Expected entries missing inside dir: %s" % inside_entries)
+
+ # list inside the subdir
+ result = runCmd("wic ls %s:2/%s/subdir/ -n %s" % (images[0], basedir, sysroot))
+ self.assertEqual(0, result.status,
+ msg="wic ls inside copied subdir failed. Output:\n%s" % result.output)
+ self.assertNotIn("Ext2 inode is not a directory", result.output,
+ msg="Regression detected (inode not a directory). Output:\n%s" % result.output)
+
+ sub_entries = set(line.split()[-1] for line in result.output.split('\n') if line)
+ self.assertIn("subfile.txt", sub_entries, msg="Expected file missing in subdir: %s" % sub_entries)
+
+ # copy directory from the partition and compare with original
+ outparent = os.path.join(self.resultdir, "wic-test-cp-ext-out")
+ os.makedirs(outparent)
+ runCmd("wic cp %s:2/%s %s -n %s" % (images[0], basedir, outparent, sysroot))
+
+ copied_dir = os.path.join(outparent, basedir)
+ self.assertTrue(os.path.isdir(copied_dir), msg="Copied-back directory not created: %s" % copied_dir)
+
+ copied_file = os.path.join(copied_dir, "topfile.txt")
+ copied_subfile = os.path.join(copied_dir, "subdir", "subfile.txt")
+
+ self.assertTrue(os.path.isfile(copied_file), msg="Missing copied-back file: %s" % copied_file)
+ self.assertTrue(os.path.isfile(copied_subfile), msg="Missing copied-back subfile: %s" % copied_subfile)
+
+ self.assertTrue(filecmp.cmp(src_file, copied_file, shallow=False),
+ msg="topfile.txt differs after round-trip copy")
+ self.assertTrue(filecmp.cmp(src_subfile, copied_subfile, shallow=False),
+ msg="subfile.txt differs after round-trip copy")
+
def test_wic_rm_ext(self):
"""Test removing files from the ext partition."""
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
@ 2025-10-01 16:34 Dragomir, Daniel
2025-10-02 14:55 ` Steve Sakoman
0 siblings, 1 reply; 10+ messages in thread
From: Dragomir, Daniel @ 2025-10-01 16:34 UTC (permalink / raw)
To: openembedded-core
wic uses debugfs to write on ext* partitions, but debugfs can only
write to the current working directory and it cannot copy complete
directory trees. Running 'wic ls' on a copied directory show this:
-l: Ext2 inode is not a directory
Fix this by creating a command list for debugfs (-f parameter) when
recursive parsing the host directory in order to create a similar
directory structure (mkdir) and copy files (write) on each level
into the destination directory from the wic's ext* partition.
Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
---
scripts/lib/wic/engine.py | 63 ++++++++++++++++++++++++++++++---------
1 file changed, 49 insertions(+), 14 deletions(-)
diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
index b9e60cbe4e..9d596be3a7 100644
--- a/scripts/lib/wic/engine.py
+++ b/scripts/lib/wic/engine.py
@@ -345,29 +345,64 @@ class Disk:
path))
def copy(self, src, dest):
- """Copy partition image into wic image."""
- pnum = dest.part if isinstance(src, str) else src.part
+ """Copy files or directories to/from the vfat or ext* partition."""
+ pnum = dest.part if isinstance(src, str) else src.part
+ partimg = self._get_part_image(pnum)
if self.partitions[pnum].fstype.startswith('ext'):
- if isinstance(src, str):
- cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
- format(os.path.dirname(dest.path), src, os.path.basename(src),
- self.debugfs, self._get_part_image(pnum))
- else: # copy from wic
- # run both dump and rdump to support both files and directory
+ if isinstance(src, str): # host to image case
+ if os.path.isdir(src):
+ base = os.path.abspath(src)
+ base_parent = os.path.dirname(base)
+ cmds = []
+ made = set()
+
+ for root, dirs, files in os.walk(base):
+ for fname in files:
+ host_file = os.path.join(root, fname)
+ rel = os.path.relpath(host_file, base_parent)
+ dest_file = os.path.join(dest.path, rel)
+ dest_dir = os.path.dirname(dest_file)
+
+ # create dir structure (mkdir -p)
+ parts = dest_dir.strip('/').split('/')
+ cur = ''
+ for p in parts:
+ cur = cur + '/' + p
+ if cur not in made:
+ cmds.append(f'mkdir "{cur}"')
+ made.add(cur)
+
+ cmds.append(f'write "{host_file}" "{dest_file}"')
+
+ # write script to a temp file
+ with tempfile.NamedTemporaryFile(mode='w', delete=False,
+ prefix='wic-debugfs-') as tf:
+ for line in cmds:
+ tf.write(line + '\n')
+ scriptname = tf.name
+
+ cmd = f"{self.debugfs} -w -f {scriptname} {partimg}"
+
+ else: # single file
+ cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
+ format(os.path.dirname(dest.path), src,
+ os.path.basename(src), self.debugfs, partimg)
+
+ else: # image to host case
cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n' | {} {}".\
format(os.path.dirname(src.path), src.path,
- dest, src.path, dest, self.debugfs,
- self._get_part_image(pnum))
+ dest, src.path, dest, self.debugfs, partimg)
+
else: # fat
if isinstance(src, str):
cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
- self._get_part_image(pnum),
- src, dest.path)
+ partimg,
+ src, dest.path)
else:
cmd = "{} -i {} -snop ::{} {}".format(self.mcopy,
- self._get_part_image(pnum),
- src.path, dest)
+ partimg,
+ src.path, dest)
exec_cmd(cmd, as_shell=True)
self._put_part_image(pnum)
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
2025-10-01 16:34 [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition Dragomir, Daniel
@ 2025-10-02 14:55 ` Steve Sakoman
2025-10-03 7:13 ` Dragomir, Daniel
0 siblings, 1 reply; 10+ messages in thread
From: Steve Sakoman @ 2025-10-02 14:55 UTC (permalink / raw)
To: daniel.dragomir; +Cc: openembedded-core
Is this also an issue on master? If so, you will need to submit this
patch for master before I can take it for scarthgap. If not, can you
explain why it isn't needed there?
Thanks,
Steve
On Wed, Oct 1, 2025 at 2:25 PM Dragomir, Daniel via
lists.openembedded.org
<daniel.dragomir=windriver.com@lists.openembedded.org> wrote:
>
> wic uses debugfs to write on ext* partitions, but debugfs can only
> write to the current working directory and it cannot copy complete
> directory trees. Running 'wic ls' on a copied directory show this:
> -l: Ext2 inode is not a directory
>
> Fix this by creating a command list for debugfs (-f parameter) when
> recursive parsing the host directory in order to create a similar
> directory structure (mkdir) and copy files (write) on each level
> into the destination directory from the wic's ext* partition.
>
> Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
> ---
> scripts/lib/wic/engine.py | 63 ++++++++++++++++++++++++++++++---------
> 1 file changed, 49 insertions(+), 14 deletions(-)
>
> diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
> index b9e60cbe4e..9d596be3a7 100644
> --- a/scripts/lib/wic/engine.py
> +++ b/scripts/lib/wic/engine.py
> @@ -345,29 +345,64 @@ class Disk:
> path))
>
> def copy(self, src, dest):
> - """Copy partition image into wic image."""
> - pnum = dest.part if isinstance(src, str) else src.part
> + """Copy files or directories to/from the vfat or ext* partition."""
> + pnum = dest.part if isinstance(src, str) else src.part
> + partimg = self._get_part_image(pnum)
>
> if self.partitions[pnum].fstype.startswith('ext'):
> - if isinstance(src, str):
> - cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
> - format(os.path.dirname(dest.path), src, os.path.basename(src),
> - self.debugfs, self._get_part_image(pnum))
> - else: # copy from wic
> - # run both dump and rdump to support both files and directory
> + if isinstance(src, str): # host to image case
> + if os.path.isdir(src):
> + base = os.path.abspath(src)
> + base_parent = os.path.dirname(base)
> + cmds = []
> + made = set()
> +
> + for root, dirs, files in os.walk(base):
> + for fname in files:
> + host_file = os.path.join(root, fname)
> + rel = os.path.relpath(host_file, base_parent)
> + dest_file = os.path.join(dest.path, rel)
> + dest_dir = os.path.dirname(dest_file)
> +
> + # create dir structure (mkdir -p)
> + parts = dest_dir.strip('/').split('/')
> + cur = ''
> + for p in parts:
> + cur = cur + '/' + p
> + if cur not in made:
> + cmds.append(f'mkdir "{cur}"')
> + made.add(cur)
> +
> + cmds.append(f'write "{host_file}" "{dest_file}"')
> +
> + # write script to a temp file
> + with tempfile.NamedTemporaryFile(mode='w', delete=False,
> + prefix='wic-debugfs-') as tf:
> + for line in cmds:
> + tf.write(line + '\n')
> + scriptname = tf.name
> +
> + cmd = f"{self.debugfs} -w -f {scriptname} {partimg}"
> +
> + else: # single file
> + cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
> + format(os.path.dirname(dest.path), src,
> + os.path.basename(src), self.debugfs, partimg)
> +
> + else: # image to host case
> cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n' | {} {}".\
> format(os.path.dirname(src.path), src.path,
> - dest, src.path, dest, self.debugfs,
> - self._get_part_image(pnum))
> + dest, src.path, dest, self.debugfs, partimg)
> +
> else: # fat
> if isinstance(src, str):
> cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
> - self._get_part_image(pnum),
> - src, dest.path)
> + partimg,
> + src, dest.path)
> else:
> cmd = "{} -i {} -snop ::{} {}".format(self.mcopy,
> - self._get_part_image(pnum),
> - src.path, dest)
> + partimg,
> + src.path, dest)
>
> exec_cmd(cmd, as_shell=True)
> self._put_part_image(pnum)
> --
> 2.39.5
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#224331): https://lists.openembedded.org/g/openembedded-core/message/224331
> Mute This Topic: https://lists.openembedded.org/mt/115542019/3620601
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [steve@sakoman.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
2025-10-02 14:55 ` Steve Sakoman
@ 2025-10-03 7:13 ` Dragomir, Daniel
2025-10-03 16:43 ` Steve Sakoman
0 siblings, 1 reply; 10+ messages in thread
From: Dragomir, Daniel @ 2025-10-03 7:13 UTC (permalink / raw)
To: Steve Sakoman; +Cc: openembedded-core@lists.openembedded.org
[-- Attachment #1: Type: text/plain, Size: 6030 bytes --]
Yes, this is an issue on master/master-next too.
I tested and the same patch can be applied fine on both master and scarthgap branches.
Regards,
Daniel
________________________________
From: Steve Sakoman <steve@sakoman.com>
Sent: Thursday, October 2, 2025 5:55 PM
To: Dragomir, Daniel <Daniel.Dragomir@windriver.com>
Cc: openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org>
Subject: Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
Is this also an issue on master? If so, you will need to submit this
patch for master before I can take it for scarthgap. If not, can you
explain why it isn't needed there?
Thanks,
Steve
On Wed, Oct 1, 2025 at 2:25 PM Dragomir, Daniel via
lists.openembedded.org
<daniel.dragomir=windriver.com@lists.openembedded.org> wrote:
>
> wic uses debugfs to write on ext* partitions, but debugfs can only
> write to the current working directory and it cannot copy complete
> directory trees. Running 'wic ls' on a copied directory show this:
> -l: Ext2 inode is not a directory
>
> Fix this by creating a command list for debugfs (-f parameter) when
> recursive parsing the host directory in order to create a similar
> directory structure (mkdir) and copy files (write) on each level
> into the destination directory from the wic's ext* partition.
>
> Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
> ---
> scripts/lib/wic/engine.py | 63 ++++++++++++++++++++++++++++++---------
> 1 file changed, 49 insertions(+), 14 deletions(-)
>
> diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
> index b9e60cbe4e..9d596be3a7 100644
> --- a/scripts/lib/wic/engine.py
> +++ b/scripts/lib/wic/engine.py
> @@ -345,29 +345,64 @@ class Disk:
> path))
>
> def copy(self, src, dest):
> - """Copy partition image into wic image."""
> - pnum = dest.part if isinstance(src, str) else src.part
> + """Copy files or directories to/from the vfat or ext* partition."""
> + pnum = dest.part if isinstance(src, str) else src.part
> + partimg = self._get_part_image(pnum)
>
> if self.partitions[pnum].fstype.startswith('ext'):
> - if isinstance(src, str):
> - cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
> - format(os.path.dirname(dest.path), src, os.path.basename(src),
> - self.debugfs, self._get_part_image(pnum))
> - else: # copy from wic
> - # run both dump and rdump to support both files and directory
> + if isinstance(src, str): # host to image case
> + if os.path.isdir(src):
> + base = os.path.abspath(src)
> + base_parent = os.path.dirname(base)
> + cmds = []
> + made = set()
> +
> + for root, dirs, files in os.walk(base):
> + for fname in files:
> + host_file = os.path.join(root, fname)
> + rel = os.path.relpath(host_file, base_parent)
> + dest_file = os.path.join(dest.path, rel)
> + dest_dir = os.path.dirname(dest_file)
> +
> + # create dir structure (mkdir -p)
> + parts = dest_dir.strip('/').split('/')
> + cur = ''
> + for p in parts:
> + cur = cur + '/' + p
> + if cur not in made:
> + cmds.append(f'mkdir "{cur}"')
> + made.add(cur)
> +
> + cmds.append(f'write "{host_file}" "{dest_file}"')
> +
> + # write script to a temp file
> + with tempfile.NamedTemporaryFile(mode='w', delete=False,
> + prefix='wic-debugfs-') as tf:
> + for line in cmds:
> + tf.write(line + '\n')
> + scriptname = tf.name
> +
> + cmd = f"{self.debugfs} -w -f {scriptname} {partimg}"
> +
> + else: # single file
> + cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
> + format(os.path.dirname(dest.path), src,
> + os.path.basename(src), self.debugfs, partimg)
> +
> + else: # image to host case
> cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n' | {} {}".\
> format(os.path.dirname(src.path), src.path,
> - dest, src.path, dest, self.debugfs,
> - self._get_part_image(pnum))
> + dest, src.path, dest, self.debugfs, partimg)
> +
> else: # fat
> if isinstance(src, str):
> cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
> - self._get_part_image(pnum),
> - src, dest.path)
> + partimg,
> + src, dest.path)
> else:
> cmd = "{} -i {} -snop ::{} {}".format(self.mcopy,
> - self._get_part_image(pnum),
> - src.path, dest)
> + partimg,
> + src.path, dest)
>
> exec_cmd(cmd, as_shell=True)
> self._put_part_image(pnum)
> --
> 2.39.5
>
>
>
>
[-- Attachment #2: Type: text/html, Size: 16965 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
2025-10-03 7:13 ` Dragomir, Daniel
@ 2025-10-03 16:43 ` Steve Sakoman
2026-01-22 22:48 ` Daniel Dragomir
0 siblings, 1 reply; 10+ messages in thread
From: Steve Sakoman @ 2025-10-03 16:43 UTC (permalink / raw)
To: Dragomir, Daniel; +Cc: openembedded-core@lists.openembedded.org
On Fri, Oct 3, 2025 at 12:13 AM Dragomir, Daniel
<Daniel.Dragomir@windriver.com> wrote:
>
> Yes, this is an issue on master/master-next too.
> I tested and the same patch can be applied fine on both master and scarthgap branches.
Thanks for checking.
Please submit the patch for the master branch. It would be helpful if
you would then ping me when you see that it has been accepted. I'll
try to remember to watch for it, but a ping would ensure I don't miss
it :-)
Steve
>
> Regards,
> Daniel
>
> ________________________________
> From: Steve Sakoman <steve@sakoman.com>
> Sent: Thursday, October 2, 2025 5:55 PM
> To: Dragomir, Daniel <Daniel.Dragomir@windriver.com>
> Cc: openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org>
> Subject: Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
>
> Is this also an issue on master? If so, you will need to submit this
> patch for master before I can take it for scarthgap. If not, can you
> explain why it isn't needed there?
>
> Thanks,
>
> Steve
>
> On Wed, Oct 1, 2025 at 2:25 PM Dragomir, Daniel via
> lists.openembedded.org
> <daniel.dragomir=windriver.com@lists.openembedded.org> wrote:
> >
> > wic uses debugfs to write on ext* partitions, but debugfs can only
> > write to the current working directory and it cannot copy complete
> > directory trees. Running 'wic ls' on a copied directory show this:
> > -l: Ext2 inode is not a directory
> >
> > Fix this by creating a command list for debugfs (-f parameter) when
> > recursive parsing the host directory in order to create a similar
> > directory structure (mkdir) and copy files (write) on each level
> > into the destination directory from the wic's ext* partition.
> >
> > Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
> > ---
> > scripts/lib/wic/engine.py | 63 ++++++++++++++++++++++++++++++---------
> > 1 file changed, 49 insertions(+), 14 deletions(-)
> >
> > diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
> > index b9e60cbe4e..9d596be3a7 100644
> > --- a/scripts/lib/wic/engine.py
> > +++ b/scripts/lib/wic/engine.py
> > @@ -345,29 +345,64 @@ class Disk:
> > path))
> >
> > def copy(self, src, dest):
> > - """Copy partition image into wic image."""
> > - pnum = dest.part if isinstance(src, str) else src.part
> > + """Copy files or directories to/from the vfat or ext* partition."""
> > + pnum = dest.part if isinstance(src, str) else src.part
> > + partimg = self._get_part_image(pnum)
> >
> > if self.partitions[pnum].fstype.startswith('ext'):
> > - if isinstance(src, str):
> > - cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
> > - format(os.path.dirname(dest.path), src, os.path.basename(src),
> > - self.debugfs, self._get_part_image(pnum))
> > - else: # copy from wic
> > - # run both dump and rdump to support both files and directory
> > + if isinstance(src, str): # host to image case
> > + if os.path.isdir(src):
> > + base = os.path.abspath(src)
> > + base_parent = os.path.dirname(base)
> > + cmds = []
> > + made = set()
> > +
> > + for root, dirs, files in os.walk(base):
> > + for fname in files:
> > + host_file = os.path.join(root, fname)
> > + rel = os.path.relpath(host_file, base_parent)
> > + dest_file = os.path.join(dest.path, rel)
> > + dest_dir = os.path.dirname(dest_file)
> > +
> > + # create dir structure (mkdir -p)
> > + parts = dest_dir.strip('/').split('/')
> > + cur = ''
> > + for p in parts:
> > + cur = cur + '/' + p
> > + if cur not in made:
> > + cmds.append(f'mkdir "{cur}"')
> > + made.add(cur)
> > +
> > + cmds.append(f'write "{host_file}" "{dest_file}"')
> > +
> > + # write script to a temp file
> > + with tempfile.NamedTemporaryFile(mode='w', delete=False,
> > + prefix='wic-debugfs-') as tf:
> > + for line in cmds:
> > + tf.write(line + '\n')
> > + scriptname = tf.name
> > +
> > + cmd = f"{self.debugfs} -w -f {scriptname} {partimg}"
> > +
> > + else: # single file
> > + cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
> > + format(os.path.dirname(dest.path), src,
> > + os.path.basename(src), self.debugfs, partimg)
> > +
> > + else: # image to host case
> > cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n' | {} {}".\
> > format(os.path.dirname(src.path), src.path,
> > - dest, src.path, dest, self.debugfs,
> > - self._get_part_image(pnum))
> > + dest, src.path, dest, self.debugfs, partimg)
> > +
> > else: # fat
> > if isinstance(src, str):
> > cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
> > - self._get_part_image(pnum),
> > - src, dest.path)
> > + partimg,
> > + src, dest.path)
> > else:
> > cmd = "{} -i {} -snop ::{} {}".format(self.mcopy,
> > - self._get_part_image(pnum),
> > - src.path, dest)
> > + partimg,
> > + src.path, dest)
> >
> > exec_cmd(cmd, as_shell=True)
> > self._put_part_image(pnum)
> > --
> > 2.39.5
> >
> >
> > -=-=-=-=-=-=-=-=-=-=-=-
> > Links: You receive all messages sent to this group.
> > View/Reply Online (#224331): https://lists.openembedded.org/g/openembedded-core/message/224331
> > Mute This Topic: https://lists.openembedded.org/mt/115542019/3620601
> > Group Owner: openembedded-core+owner@lists.openembedded.org
> > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [steve@sakoman.com]
> > -=-=-=-=-=-=-=-=-=-=-=-
> >
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
2025-10-03 16:43 ` Steve Sakoman
@ 2026-01-22 22:48 ` Daniel Dragomir
2026-02-20 9:19 ` Daniel Dragomir
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Dragomir @ 2026-01-22 22:48 UTC (permalink / raw)
To: Steve Sakoman; +Cc: openembedded-core@lists.openembedded.org
On 10/3/25 19:43, Steve Sakoman wrote:
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> On Fri, Oct 3, 2025 at 12:13 AM Dragomir, Daniel
> <Daniel.Dragomir@windriver.com> wrote:
>>
>> Yes, this is an issue on master/master-next too.
>> I tested and the same patch can be applied fine on both master and scarthgap branches.
>
> Thanks for checking.
>
> Please submit the patch for the master branch. It would be helpful if
> you would then ping me when you see that it has been accepted. I'll
> try to remember to watch for it, but a ping would ensure I don't miss
> it :-)
Hi Steve,
Those changes were accepted in master branch. I created also a selftest
for this scenario.
Could you please back-port the commits to scarthgap branch? I tried
locally and there is a minor merge conflict on one of the commits. If
you want me to send again a scarthgap version of the commits on the
mailing list, let me know.
Commits from master branch are:
6de3d2602f oeqa/selftest/wic: test recursive dir copy on ext partitions
1ed38aff5f wic/engine: fix copying directories into wic image with ext*
partition
Regards,
Daniel
>
> Steve
>
>>
>> Regards,
>> Daniel
>>
>> ________________________________
>> From: Steve Sakoman <steve@sakoman.com>
>> Sent: Thursday, October 2, 2025 5:55 PM
>> To: Dragomir, Daniel <Daniel.Dragomir@windriver.com>
>> Cc: openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org>
>> Subject: Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
>>
>> Is this also an issue on master? If so, you will need to submit this
>> patch for master before I can take it for scarthgap. If not, can you
>> explain why it isn't needed there?
>>
>> Thanks,
>>
>> Steve
>>
>> On Wed, Oct 1, 2025 at 2:25 PM Dragomir, Daniel via
>> lists.openembedded.org
>> <daniel.dragomir=windriver.com@lists.openembedded.org> wrote:
>>>
>>> wic uses debugfs to write on ext* partitions, but debugfs can only
>>> write to the current working directory and it cannot copy complete
>>> directory trees. Running 'wic ls' on a copied directory show this:
>>> -l: Ext2 inode is not a directory
>>>
>>> Fix this by creating a command list for debugfs (-f parameter) when
>>> recursive parsing the host directory in order to create a similar
>>> directory structure (mkdir) and copy files (write) on each level
>>> into the destination directory from the wic's ext* partition.
>>>
>>> Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
>>> ---
>>> scripts/lib/wic/engine.py | 63 ++++++++++++++++++++++++++++++---------
>>> 1 file changed, 49 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
>>> index b9e60cbe4e..9d596be3a7 100644
>>> --- a/scripts/lib/wic/engine.py
>>> +++ b/scripts/lib/wic/engine.py
>>> @@ -345,29 +345,64 @@ class Disk:
>>> path))
>>>
>>> def copy(self, src, dest):
>>> - """Copy partition image into wic image."""
>>> - pnum = dest.part if isinstance(src, str) else src.part
>>> + """Copy files or directories to/from the vfat or ext* partition."""
>>> + pnum = dest.part if isinstance(src, str) else src.part
>>> + partimg = self._get_part_image(pnum)
>>>
>>> if self.partitions[pnum].fstype.startswith('ext'):
>>> - if isinstance(src, str):
>>> - cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
>>> - format(os.path.dirname(dest.path), src, os.path.basename(src),
>>> - self.debugfs, self._get_part_image(pnum))
>>> - else: # copy from wic
>>> - # run both dump and rdump to support both files and directory
>>> + if isinstance(src, str): # host to image case
>>> + if os.path.isdir(src):
>>> + base = os.path.abspath(src)
>>> + base_parent = os.path.dirname(base)
>>> + cmds = []
>>> + made = set()
>>> +
>>> + for root, dirs, files in os.walk(base):
>>> + for fname in files:
>>> + host_file = os.path.join(root, fname)
>>> + rel = os.path.relpath(host_file, base_parent)
>>> + dest_file = os.path.join(dest.path, rel)
>>> + dest_dir = os.path.dirname(dest_file)
>>> +
>>> + # create dir structure (mkdir -p)
>>> + parts = dest_dir.strip('/').split('/')
>>> + cur = ''
>>> + for p in parts:
>>> + cur = cur + '/' + p
>>> + if cur not in made:
>>> + cmds.append(f'mkdir "{cur}"')
>>> + made.add(cur)
>>> +
>>> + cmds.append(f'write "{host_file}" "{dest_file}"')
>>> +
>>> + # write script to a temp file
>>> + with tempfile.NamedTemporaryFile(mode='w', delete=False,
>>> + prefix='wic-debugfs-') as tf:
>>> + for line in cmds:
>>> + tf.write(line + '\n')
>>> + scriptname = tf.name
>>> +
>>> + cmd = f"{self.debugfs} -w -f {scriptname} {partimg}"
>>> +
>>> + else: # single file
>>> + cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
>>> + format(os.path.dirname(dest.path), src,
>>> + os.path.basename(src), self.debugfs, partimg)
>>> +
>>> + else: # image to host case
>>> cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n' | {} {}".\
>>> format(os.path.dirname(src.path), src.path,
>>> - dest, src.path, dest, self.debugfs,
>>> - self._get_part_image(pnum))
>>> + dest, src.path, dest, self.debugfs, partimg)
>>> +
>>> else: # fat
>>> if isinstance(src, str):
>>> cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
>>> - self._get_part_image(pnum),
>>> - src, dest.path)
>>> + partimg,
>>> + src, dest.path)
>>> else:
>>> cmd = "{} -i {} -snop ::{} {}".format(self.mcopy,
>>> - self._get_part_image(pnum),
>>> - src.path, dest)
>>> + partimg,
>>> + src.path, dest)
>>>
>>> exec_cmd(cmd, as_shell=True)
>>> self._put_part_image(pnum)
>>> --
>>> 2.39.5
>>>
>>>
>>> -=-=-=-=-=-=-=-=-=-=-=-
>>> Links: You receive all messages sent to this group.
>>> View/Reply Online (#224331): https://lists.openembedded.org/g/openembedded-core/message/224331
>>> Mute This Topic: https://lists.openembedded.org/mt/115542019/3620601
>>> Group Owner: openembedded-core+owner@lists.openembedded.org
>>> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [steve@sakoman.com]
>>> -=-=-=-=-=-=-=-=-=-=-=-
>>>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
2026-01-22 22:48 ` Daniel Dragomir
@ 2026-02-20 9:19 ` Daniel Dragomir
2026-02-20 9:41 ` Yoann Congal
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Dragomir @ 2026-02-20 9:19 UTC (permalink / raw)
To: Steve Sakoman, yoann.congal; +Cc: openembedded-core@lists.openembedded.org
On 1/23/26 00:48, Daniel Dragomir wrote:
>
>
> On 10/3/25 19:43, Steve Sakoman wrote:
>> CAUTION: This email comes from a non Wind River email account!
>> Do not click links or open attachments unless you recognize the sender
>> and know the content is safe.
>>
>> On Fri, Oct 3, 2025 at 12:13 AM Dragomir, Daniel
>> <Daniel.Dragomir@windriver.com> wrote:
>>>
>>> Yes, this is an issue on master/master-next too.
>>> I tested and the same patch can be applied fine on both master and
>>> scarthgap branches.
>>
>> Thanks for checking.
>>
>> Please submit the patch for the master branch. It would be helpful if
>> you would then ping me when you see that it has been accepted. I'll
>> try to remember to watch for it, but a ping would ensure I don't miss
>> it :-)
>
> Hi Steve,
>
> Those changes were accepted in master branch. I created also a selftest
> for this scenario.
> Could you please back-port the commits to scarthgap branch? I tried
> locally and there is a minor merge conflict on one of the commits. If
> you want me to send again a scarthgap version of the commits on the
> mailing list, let me know.
>
> Commits from master branch are:
> 6de3d2602f oeqa/selftest/wic: test recursive dir copy on ext partitions
> 1ed38aff5f wic/engine: fix copying directories into wic image with ext*
> partition
>
Hi Steve and Yoann,
Can you please help with a back-port on scarthgap for the commits bellow
which were accepted in master?
6de3d2602f oeqa/selftest/wic: test recursive dir copy on ext partitions
1ed38aff5f wic/engine: fix copying directories into wic image with ext*
partition
cb536737be wic/engine: error on old host debugfs for standalone
directory copy
Thank you!
Daniel
> Regards,
> Daniel
>
>>
>> Steve
>>
>>>
>>> Regards,
>>> Daniel
>>>
>>> ________________________________
>>> From: Steve Sakoman <steve@sakoman.com>
>>> Sent: Thursday, October 2, 2025 5:55 PM
>>> To: Dragomir, Daniel <Daniel.Dragomir@windriver.com>
>>> Cc: openembedded-core@lists.openembedded.org
>>> <openembedded-core@lists.openembedded.org>
>>> Subject: Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying
>>> directories into wic image with ext* partition
>>>
>>> Is this also an issue on master? If so, you will need to submit this
>>> patch for master before I can take it for scarthgap. If not, can you
>>> explain why it isn't needed there?
>>>
>>> Thanks,
>>>
>>> Steve
>>>
>>> On Wed, Oct 1, 2025 at 2:25 PM Dragomir, Daniel via
>>> lists.openembedded.org
>>> <daniel.dragomir=windriver.com@lists.openembedded.org> wrote:
>>>>
>>>> wic uses debugfs to write on ext* partitions, but debugfs can only
>>>> write to the current working directory and it cannot copy complete
>>>> directory trees. Running 'wic ls' on a copied directory show this:
>>>> -l: Ext2 inode is not a directory
>>>>
>>>> Fix this by creating a command list for debugfs (-f parameter) when
>>>> recursive parsing the host directory in order to create a similar
>>>> directory structure (mkdir) and copy files (write) on each level
>>>> into the destination directory from the wic's ext* partition.
>>>>
>>>> Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
>>>> ---
>>>> scripts/lib/wic/engine.py | 63
>>>> ++++++++++++++++++++++++++++++---------
>>>> 1 file changed, 49 insertions(+), 14 deletions(-)
>>>>
>>>> diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
>>>> index b9e60cbe4e..9d596be3a7 100644
>>>> --- a/scripts/lib/wic/engine.py
>>>> +++ b/scripts/lib/wic/engine.py
>>>> @@ -345,29 +345,64 @@ class Disk:
>>>> path))
>>>>
>>>> def copy(self, src, dest):
>>>> - """Copy partition image into wic image."""
>>>> - pnum = dest.part if isinstance(src, str) else src.part
>>>> + """Copy files or directories to/from the vfat or ext*
>>>> partition."""
>>>> + pnum = dest.part if isinstance(src, str) else src.part
>>>> + partimg = self._get_part_image(pnum)
>>>>
>>>> if self.partitions[pnum].fstype.startswith('ext'):
>>>> - if isinstance(src, str):
>>>> - cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
>>>> - format(os.path.dirname(dest.path), src,
>>>> os.path.basename(src),
>>>> - self.debugfs, self._get_part_image(pnum))
>>>> - else: # copy from wic
>>>> - # run both dump and rdump to support both files and
>>>> directory
>>>> + if isinstance(src, str): # host to image case
>>>> + if os.path.isdir(src):
>>>> + base = os.path.abspath(src)
>>>> + base_parent = os.path.dirname(base)
>>>> + cmds = []
>>>> + made = set()
>>>> +
>>>> + for root, dirs, files in os.walk(base):
>>>> + for fname in files:
>>>> + host_file = os.path.join(root, fname)
>>>> + rel = os.path.relpath(host_file,
>>>> base_parent)
>>>> + dest_file = os.path.join(dest.path, rel)
>>>> + dest_dir = os.path.dirname(dest_file)
>>>> +
>>>> + # create dir structure (mkdir -p)
>>>> + parts = dest_dir.strip('/').split('/')
>>>> + cur = ''
>>>> + for p in parts:
>>>> + cur = cur + '/' + p
>>>> + if cur not in made:
>>>> + cmds.append(f'mkdir "{cur}"')
>>>> + made.add(cur)
>>>> +
>>>> + cmds.append(f'write "{host_file}"
>>>> "{dest_file}"')
>>>> +
>>>> + # write script to a temp file
>>>> + with tempfile.NamedTemporaryFile(mode='w',
>>>> delete=False,
>>>> +
>>>> prefix='wic-debugfs-') as tf:
>>>> + for line in cmds:
>>>> + tf.write(line + '\n')
>>>> + scriptname = tf.name
>>>> +
>>>> + cmd = f"{self.debugfs} -w -f {scriptname}
>>>> {partimg}"
>>>> +
>>>> + else: # single file
>>>> + cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
>>>> + format(os.path.dirname(dest.path), src,
>>>> + os.path.basename(src),
>>>> self.debugfs, partimg)
>>>> +
>>>> + else: # image to host case
>>>> cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n'
>>>> | {} {}".\
>>>> format(os.path.dirname(src.path), src.path,
>>>> - dest, src.path, dest, self.debugfs,
>>>> - self._get_part_image(pnum))
>>>> + dest, src.path, dest, self.debugfs,
>>>> partimg)
>>>> +
>>>> else: # fat
>>>> if isinstance(src, str):
>>>> cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
>>>> -
>>>> self._get_part_image(pnum),
>>>> - src, dest.path)
>>>> + partimg,
>>>> + src, dest.path)
>>>> else:
>>>> cmd = "{} -i {} -snop ::{} {}".format(self.mcopy,
>>>> -
>>>> self._get_part_image(pnum),
>>>> - src.path, dest)
>>>> + partimg,
>>>> + src.path, dest)
>>>>
>>>> exec_cmd(cmd, as_shell=True)
>>>> self._put_part_image(pnum)
>>>> --
>>>> 2.39.5
>>>>
>>>>
>>>> -=-=-=-=-=-=-=-=-=-=-=-
>>>> Links: You receive all messages sent to this group.
>>>> View/Reply Online (#224331):
>>>> https://lists.openembedded.org/g/openembedded-core/message/224331
>>>> Mute This Topic: https://lists.openembedded.org/mt/115542019/3620601
>>>> Group Owner: openembedded-core+owner@lists.openembedded.org
>>>> Unsubscribe:
>>>> https://lists.openembedded.org/g/openembedded-core/unsub
>>>> [steve@sakoman.com]
>>>> -=-=-=-=-=-=-=-=-=-=-=-
>>>>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
2026-02-20 9:19 ` Daniel Dragomir
@ 2026-02-20 9:41 ` Yoann Congal
2026-02-20 10:02 ` Daniel Dragomir
0 siblings, 1 reply; 10+ messages in thread
From: Yoann Congal @ 2026-02-20 9:41 UTC (permalink / raw)
To: daniel.dragomir, Steve Sakoman; +Cc: openembedded-core@lists.openembedded.org
On Fri Feb 20, 2026 at 10:19 AM CET, Daniel via lists.openembedded.org Dragomir wrote:
>
>
> On 1/23/26 00:48, Daniel Dragomir wrote:
>>
>>
>> On 10/3/25 19:43, Steve Sakoman wrote:
>>> CAUTION: This email comes from a non Wind River email account!
>>> Do not click links or open attachments unless you recognize the sender
>>> and know the content is safe.
>>>
>>> On Fri, Oct 3, 2025 at 12:13 AM Dragomir, Daniel
>>> <Daniel.Dragomir@windriver.com> wrote:
>>>>
>>>> Yes, this is an issue on master/master-next too.
>>>> I tested and the same patch can be applied fine on both master and
>>>> scarthgap branches.
>>>
>>> Thanks for checking.
>>>
>>> Please submit the patch for the master branch. It would be helpful if
>>> you would then ping me when you see that it has been accepted. I'll
>>> try to remember to watch for it, but a ping would ensure I don't miss
>>> it :-)
>>
>> Hi Steve,
>>
>> Those changes were accepted in master branch. I created also a selftest
>> for this scenario.
>> Could you please back-port the commits to scarthgap branch? I tried
>> locally and there is a minor merge conflict on one of the commits. If
>> you want me to send again a scarthgap version of the commits on the
>> mailing list, let me know.
>>
>> Commits from master branch are:
>> 6de3d2602f oeqa/selftest/wic: test recursive dir copy on ext partitions
>> 1ed38aff5f wic/engine: fix copying directories into wic image with ext*
>> partition
>>
>
> Hi Steve and Yoann,
Hello,
> Can you please help with a back-port on scarthgap for the commits bellow
> which were accepted in master?
>
> 6de3d2602f oeqa/selftest/wic: test recursive dir copy on ext partitions
> 1ed38aff5f wic/engine: fix copying directories into wic image with ext*
> partition
I reviewed those 2 and they will be in my next series.
> cb536737be wic/engine: error on old host debugfs for standalone directory copy
For this one, can you send backport patches to scarthgap and whinlatter?
>
> Thank you!
> Daniel
>
>> Regards,
>> Daniel
>>
>>>
>>> Steve
>>>
>>>>
>>>> Regards,
>>>> Daniel
>>>>
>>>> ________________________________
>>>> From: Steve Sakoman <steve@sakoman.com>
>>>> Sent: Thursday, October 2, 2025 5:55 PM
>>>> To: Dragomir, Daniel <Daniel.Dragomir@windriver.com>
>>>> Cc: openembedded-core@lists.openembedded.org
>>>> <openembedded-core@lists.openembedded.org>
>>>> Subject: Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying
>>>> directories into wic image with ext* partition
>>>>
>>>> Is this also an issue on master? If so, you will need to submit this
>>>> patch for master before I can take it for scarthgap. If not, can you
>>>> explain why it isn't needed there?
>>>>
>>>> Thanks,
>>>>
>>>> Steve
>>>>
>>>> On Wed, Oct 1, 2025 at 2:25 PM Dragomir, Daniel via
>>>> lists.openembedded.org
>>>> <daniel.dragomir=windriver.com@lists.openembedded.org> wrote:
>>>>>
>>>>> wic uses debugfs to write on ext* partitions, but debugfs can only
>>>>> write to the current working directory and it cannot copy complete
>>>>> directory trees. Running 'wic ls' on a copied directory show this:
>>>>> -l: Ext2 inode is not a directory
>>>>>
>>>>> Fix this by creating a command list for debugfs (-f parameter) when
>>>>> recursive parsing the host directory in order to create a similar
>>>>> directory structure (mkdir) and copy files (write) on each level
>>>>> into the destination directory from the wic's ext* partition.
>>>>>
>>>>> Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
>>>>> ---
>>>>> scripts/lib/wic/engine.py | 63
>>>>> ++++++++++++++++++++++++++++++---------
>>>>> 1 file changed, 49 insertions(+), 14 deletions(-)
>>>>>
>>>>> diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
>>>>> index b9e60cbe4e..9d596be3a7 100644
>>>>> --- a/scripts/lib/wic/engine.py
>>>>> +++ b/scripts/lib/wic/engine.py
>>>>> @@ -345,29 +345,64 @@ class Disk:
>>>>> path))
>>>>>
>>>>> def copy(self, src, dest):
>>>>> - """Copy partition image into wic image."""
>>>>> - pnum = dest.part if isinstance(src, str) else src.part
>>>>> + """Copy files or directories to/from the vfat or ext*
>>>>> partition."""
>>>>> + pnum = dest.part if isinstance(src, str) else src.part
>>>>> + partimg = self._get_part_image(pnum)
>>>>>
>>>>> if self.partitions[pnum].fstype.startswith('ext'):
>>>>> - if isinstance(src, str):
>>>>> - cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
>>>>> - format(os.path.dirname(dest.path), src,
>>>>> os.path.basename(src),
>>>>> - self.debugfs, self._get_part_image(pnum))
>>>>> - else: # copy from wic
>>>>> - # run both dump and rdump to support both files and
>>>>> directory
>>>>> + if isinstance(src, str): # host to image case
>>>>> + if os.path.isdir(src):
>>>>> + base = os.path.abspath(src)
>>>>> + base_parent = os.path.dirname(base)
>>>>> + cmds = []
>>>>> + made = set()
>>>>> +
>>>>> + for root, dirs, files in os.walk(base):
>>>>> + for fname in files:
>>>>> + host_file = os.path.join(root, fname)
>>>>> + rel = os.path.relpath(host_file,
>>>>> base_parent)
>>>>> + dest_file = os.path.join(dest.path, rel)
>>>>> + dest_dir = os.path.dirname(dest_file)
>>>>> +
>>>>> + # create dir structure (mkdir -p)
>>>>> + parts = dest_dir.strip('/').split('/')
>>>>> + cur = ''
>>>>> + for p in parts:
>>>>> + cur = cur + '/' + p
>>>>> + if cur not in made:
>>>>> + cmds.append(f'mkdir "{cur}"')
>>>>> + made.add(cur)
>>>>> +
>>>>> + cmds.append(f'write "{host_file}"
>>>>> "{dest_file}"')
>>>>> +
>>>>> + # write script to a temp file
>>>>> + with tempfile.NamedTemporaryFile(mode='w',
>>>>> delete=False,
>>>>> +
>>>>> prefix='wic-debugfs-') as tf:
>>>>> + for line in cmds:
>>>>> + tf.write(line + '\n')
>>>>> + scriptname = tf.name
>>>>> +
>>>>> + cmd = f"{self.debugfs} -w -f {scriptname}
>>>>> {partimg}"
>>>>> +
>>>>> + else: # single file
>>>>> + cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
>>>>> + format(os.path.dirname(dest.path), src,
>>>>> + os.path.basename(src),
>>>>> self.debugfs, partimg)
>>>>> +
>>>>> + else: # image to host case
>>>>> cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n'
>>>>> | {} {}".\
>>>>> format(os.path.dirname(src.path), src.path,
>>>>> - dest, src.path, dest, self.debugfs,
>>>>> - self._get_part_image(pnum))
>>>>> + dest, src.path, dest, self.debugfs,
>>>>> partimg)
>>>>> +
>>>>> else: # fat
>>>>> if isinstance(src, str):
>>>>> cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
>>>>> -
>>>>> self._get_part_image(pnum),
>>>>> - src, dest.path)
>>>>> + partimg,
>>>>> + src, dest.path)
>>>>> else:
>>>>> cmd = "{} -i {} -snop ::{} {}".format(self.mcopy,
>>>>> -
>>>>> self._get_part_image(pnum),
>>>>> - src.path, dest)
>>>>> + partimg,
>>>>> + src.path, dest)
>>>>>
>>>>> exec_cmd(cmd, as_shell=True)
>>>>> self._put_part_image(pnum)
>>>>> --
>>>>> 2.39.5
>>>>>
>>>>>
>>>>>
>>>>>
--
Yoann Congal
Smile ECS
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition
2026-02-20 9:41 ` Yoann Congal
@ 2026-02-20 10:02 ` Daniel Dragomir
0 siblings, 0 replies; 10+ messages in thread
From: Daniel Dragomir @ 2026-02-20 10:02 UTC (permalink / raw)
To: Yoann Congal, Steve Sakoman; +Cc: openembedded-core@lists.openembedded.org
On 2/20/26 11:41, Yoann Congal wrote:
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> On Fri Feb 20, 2026 at 10:19 AM CET, Daniel via lists.openembedded.org Dragomir wrote:
>>
>>
>> On 1/23/26 00:48, Daniel Dragomir wrote:
>>>
>>>
>>> On 10/3/25 19:43, Steve Sakoman wrote:
>>>> CAUTION: This email comes from a non Wind River email account!
>>>> Do not click links or open attachments unless you recognize the sender
>>>> and know the content is safe.
>>>>
>>>> On Fri, Oct 3, 2025 at 12:13 AM Dragomir, Daniel
>>>> <Daniel.Dragomir@windriver.com> wrote:
>>>>>
>>>>> Yes, this is an issue on master/master-next too.
>>>>> I tested and the same patch can be applied fine on both master and
>>>>> scarthgap branches.
>>>>
>>>> Thanks for checking.
>>>>
>>>> Please submit the patch for the master branch. It would be helpful if
>>>> you would then ping me when you see that it has been accepted. I'll
>>>> try to remember to watch for it, but a ping would ensure I don't miss
>>>> it :-)
>>>
>>> Hi Steve,
>>>
>>> Those changes were accepted in master branch. I created also a selftest
>>> for this scenario.
>>> Could you please back-port the commits to scarthgap branch? I tried
>>> locally and there is a minor merge conflict on one of the commits. If
>>> you want me to send again a scarthgap version of the commits on the
>>> mailing list, let me know.
>>>
>>> Commits from master branch are:
>>> 6de3d2602f oeqa/selftest/wic: test recursive dir copy on ext partitions
>>> 1ed38aff5f wic/engine: fix copying directories into wic image with ext*
>>> partition
>>>
>>
>> Hi Steve and Yoann,
>
> Hello,
>
>> Can you please help with a back-port on scarthgap for the commits bellow
>> which were accepted in master?
>>
>> 6de3d2602f oeqa/selftest/wic: test recursive dir copy on ext partitions
>> 1ed38aff5f wic/engine: fix copying directories into wic image with ext*
>> partition
> I reviewed those 2 and they will be in my next series.
>
>> cb536737be wic/engine: error on old host debugfs for standalone directory copy
> For this one, can you send backport patches to scarthgap and whinlatter?
>
Sure! Will send for both branches.
Thanks Yoann!
>
>>
>> Thank you!
>> Daniel
>>
>>> Regards,
>>> Daniel
>>>
>>>>
>>>> Steve
>>>>
>>>>>
>>>>> Regards,
>>>>> Daniel
>>>>>
>>>>> ________________________________
>>>>> From: Steve Sakoman <steve@sakoman.com>
>>>>> Sent: Thursday, October 2, 2025 5:55 PM
>>>>> To: Dragomir, Daniel <Daniel.Dragomir@windriver.com>
>>>>> Cc: openembedded-core@lists.openembedded.org
>>>>> <openembedded-core@lists.openembedded.org>
>>>>> Subject: Re: [OE-core][scarthgap][PATCH] wic/engine: fix copying
>>>>> directories into wic image with ext* partition
>>>>>
>>>>> Is this also an issue on master? If so, you will need to submit this
>>>>> patch for master before I can take it for scarthgap. If not, can you
>>>>> explain why it isn't needed there?
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Steve
>>>>>
>>>>> On Wed, Oct 1, 2025 at 2:25 PM Dragomir, Daniel via
>>>>> lists.openembedded.org
>>>>> <daniel.dragomir=windriver.com@lists.openembedded.org> wrote:
>>>>>>
>>>>>> wic uses debugfs to write on ext* partitions, but debugfs can only
>>>>>> write to the current working directory and it cannot copy complete
>>>>>> directory trees. Running 'wic ls' on a copied directory show this:
>>>>>> -l: Ext2 inode is not a directory
>>>>>>
>>>>>> Fix this by creating a command list for debugfs (-f parameter) when
>>>>>> recursive parsing the host directory in order to create a similar
>>>>>> directory structure (mkdir) and copy files (write) on each level
>>>>>> into the destination directory from the wic's ext* partition.
>>>>>>
>>>>>> Signed-off-by: Daniel Dragomir <daniel.dragomir@windriver.com>
>>>>>> ---
>>>>>> scripts/lib/wic/engine.py | 63
>>>>>> ++++++++++++++++++++++++++++++---------
>>>>>> 1 file changed, 49 insertions(+), 14 deletions(-)
>>>>>>
>>>>>> diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
>>>>>> index b9e60cbe4e..9d596be3a7 100644
>>>>>> --- a/scripts/lib/wic/engine.py
>>>>>> +++ b/scripts/lib/wic/engine.py
>>>>>> @@ -345,29 +345,64 @@ class Disk:
>>>>>> path))
>>>>>>
>>>>>> def copy(self, src, dest):
>>>>>> - """Copy partition image into wic image."""
>>>>>> - pnum = dest.part if isinstance(src, str) else src.part
>>>>>> + """Copy files or directories to/from the vfat or ext*
>>>>>> partition."""
>>>>>> + pnum = dest.part if isinstance(src, str) else src.part
>>>>>> + partimg = self._get_part_image(pnum)
>>>>>>
>>>>>> if self.partitions[pnum].fstype.startswith('ext'):
>>>>>> - if isinstance(src, str):
>>>>>> - cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
>>>>>> - format(os.path.dirname(dest.path), src,
>>>>>> os.path.basename(src),
>>>>>> - self.debugfs, self._get_part_image(pnum))
>>>>>> - else: # copy from wic
>>>>>> - # run both dump and rdump to support both files and
>>>>>> directory
>>>>>> + if isinstance(src, str): # host to image case
>>>>>> + if os.path.isdir(src):
>>>>>> + base = os.path.abspath(src)
>>>>>> + base_parent = os.path.dirname(base)
>>>>>> + cmds = []
>>>>>> + made = set()
>>>>>> +
>>>>>> + for root, dirs, files in os.walk(base):
>>>>>> + for fname in files:
>>>>>> + host_file = os.path.join(root, fname)
>>>>>> + rel = os.path.relpath(host_file,
>>>>>> base_parent)
>>>>>> + dest_file = os.path.join(dest.path, rel)
>>>>>> + dest_dir = os.path.dirname(dest_file)
>>>>>> +
>>>>>> + # create dir structure (mkdir -p)
>>>>>> + parts = dest_dir.strip('/').split('/')
>>>>>> + cur = ''
>>>>>> + for p in parts:
>>>>>> + cur = cur + '/' + p
>>>>>> + if cur not in made:
>>>>>> + cmds.append(f'mkdir "{cur}"')
>>>>>> + made.add(cur)
>>>>>> +
>>>>>> + cmds.append(f'write "{host_file}"
>>>>>> "{dest_file}"')
>>>>>> +
>>>>>> + # write script to a temp file
>>>>>> + with tempfile.NamedTemporaryFile(mode='w',
>>>>>> delete=False,
>>>>>> +
>>>>>> prefix='wic-debugfs-') as tf:
>>>>>> + for line in cmds:
>>>>>> + tf.write(line + '\n')
>>>>>> + scriptname = tf.name
>>>>>> +
>>>>>> + cmd = f"{self.debugfs} -w -f {scriptname}
>>>>>> {partimg}"
>>>>>> +
>>>>>> + else: # single file
>>>>>> + cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\
>>>>>> + format(os.path.dirname(dest.path), src,
>>>>>> + os.path.basename(src),
>>>>>> self.debugfs, partimg)
>>>>>> +
>>>>>> + else: # image to host case
>>>>>> cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n'
>>>>>> | {} {}".\
>>>>>> format(os.path.dirname(src.path), src.path,
>>>>>> - dest, src.path, dest, self.debugfs,
>>>>>> - self._get_part_image(pnum))
>>>>>> + dest, src.path, dest, self.debugfs,
>>>>>> partimg)
>>>>>> +
>>>>>> else: # fat
>>>>>> if isinstance(src, str):
>>>>>> cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
>>>>>> -
>>>>>> self._get_part_image(pnum),
>>>>>> - src, dest.path)
>>>>>> + partimg,
>>>>>> + src, dest.path)
>>>>>> else:
>>>>>> cmd = "{} -i {} -snop ::{} {}".format(self.mcopy,
>>>>>> -
>>>>>> self._get_part_image(pnum),
>>>>>> - src.path, dest)
>>>>>> + partimg,
>>>>>> + src.path, dest)
>>>>>>
>>>>>> exec_cmd(cmd, as_shell=True)
>>>>>> self._put_part_image(pnum)
>>>>>> --
>>>>>> 2.39.5
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>
>
> --
> Yoann Congal
> Smile ECS
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-02-20 10:02 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-28 14:35 [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition Daniel Dragomir
2026-01-28 14:35 ` [OE-core][scarthgap][PATCH] oeqa/selftest/wic: test recursive dir copy on ext partitions Daniel Dragomir
-- strict thread matches above, loose matches on Subject: below --
2025-10-01 16:34 [OE-core][scarthgap][PATCH] wic/engine: fix copying directories into wic image with ext* partition Dragomir, Daniel
2025-10-02 14:55 ` Steve Sakoman
2025-10-03 7:13 ` Dragomir, Daniel
2025-10-03 16:43 ` Steve Sakoman
2026-01-22 22:48 ` Daniel Dragomir
2026-02-20 9:19 ` Daniel Dragomir
2026-02-20 9:41 ` Yoann Congal
2026-02-20 10:02 ` Daniel Dragomir
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox