Need to reset OSTree

I’m trying to do a build, and getting an error message.

Deploying OSTree with checksum 593ee8037f1f23fe711c107679094387ca4969b2739f7c04e98c7c8e1424600d
An unexpected Exception occurred. Please provide the following stack trace to
the Toradex TorizonCore support team:

Traceback (most recent call last):File “/builder/torizoncore-builder”, line 231, in mainargs.func(mainargs)File “/builder/tcbuilder/cli/build.py”, line 668, in do_buildbuild(args.config_fname, args.storage_directory,File “/builder/tcbuilder/cli/build.py”, line 654, in buildraise excFile “/builder/tcbuilder/cli/build.py”, line 639, in buildhandle_output_section(File “/builder/tcbuilder/cli/build.py”, line 309, in handle_output_sectionhandle_easy_installer_output(tezi_props, storage_dir, union_params)File “/builder/tcbuilder/cli/build.py”, line 385, in handle_easy_installer_outputdeploy_cli.deploy_tezi_image(**deploy_tezi_image_params)File “/builder/tcbuilder/cli/deploy.py”, line 62, in deploy_tezi_imagedbe.deploy_tezi_image(tezi_dir, src_sysroot_dir, src_ostree_archive_dir,File “/builder/tcbuilder/backend/deploy.py”, line 289, in deploy_tezi_imagedeploy_ostree_local(src_sysroot_dir, src_ostree_archive_dir, dst_sysroot_dir, ref)File “/builder/tcbuilder/backend/deploy.py”, line 271, in deploy_ostree_localdeploy_rootfs(sysroot, src_sysroot_dir, csumdeploy, “torizon”, srckargs)File “/builder/tcbuilder/backend/deploy.py”, line 105, in deploy_rootfsresult, deployment = sysroot.deploy_tree(gi.repository.GLib.GError: g-io-error-quark: Preparing /etc: Tree contains both /etc and /usr/etc (0)

I was using /usr/etc as the path in the customization:filesystem in my tcbuild.yaml. I switched it to just using /etc

How do I “clear out” anything existing from OSTree and start fresh?

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Clearing OSTree and Starting Fresh with TorizonCore Builder

The error you’re encountering indicates a conflict between /etc and /usr/etc in your OSTree deployment(1). This happens when OSTree finds both directories during the deployment process, which creates an ambiguous situation for the 3-way merge mechanism that OSTree uses for /etc(1).

Understanding the Issue

OSTree handles /etc as a special directory that performs a 3-way merge using the old default configuration, the active system’s /etc, and the new default configuration(1). When both /etc and /usr/etc are present, OSTree cannot determine which one to use for this merge process(1).

How to Clear OSTree and Start Fresh

To clear out existing OSTree data and start fresh with TorizonCore Builder, you have several options:

Option 1: Remove Storage Directory

If you’re using a specific storage directory for TorizonCore Builder, you can simply remove it and let the tool recreate it. The storage directory contains all the intermediate OSTree data(2).

Option 2: Use Fresh Working Directory

Create a new working directory for your TorizonCore Builder project and start the build process from there(3).

Option 3: Clean OSTree References

You can use the OSTree commands within TorizonCore Builder to manage references. The tool provides OSTree operational commands for this purpose(2).

Correcting Your Configuration

You’ve already identified the correct solution by switching from /usr/etc to /etc in your customization:filesystem section(4). This is the proper approach because:

  • OSTree expects configuration files to be in /etc(1)
  • The /etc directory is handled specially during OSTree deployments with 3-way merging(1)
  • Using /usr/etc creates conflicts with OSTree’s expected directory structure(1)

Best Practices for Filesystem Customization

When using the customization:filesystem property in your tcbuild.yaml file(3):

  1. Use /etc for configuration files, not /usr/etc(1)
  2. Ensure your directory structure matches OSTree expectations(1)
  3. Remember that /etc will be merged during updates, while /var and /home remain persistent(1)

Your corrected approach of using /etc instead of /usr/etc should resolve the deployment error and allow your build to complete successfully.

Best regards, Toradex AI Assistant.

Greetings @kdubious,

I’m not sure what you did exactly here, but you should almost never touch /usr/etc in an OSTree.

To restart fresh, just simply use TorizonCore Builder to unpack a fresh unmodified OS image this will reset the state.

Best Regards,
Jeremias

I’m experiencing the same issue. Even if I use a new working directory for torizoncorebuilder and only add files under /etc instead of /usr/etc, I get the same error; however, if I use /usr/etc there are no errors.

1 Like

Correction,

It doesn’t throw errors, but it also doesn’t overwrite the files in /etc except for the very first run when the file doesn’t exit yet.

1 Like

Hi @allen.morrison,

I’m not sure I understand exactly what you are doing. Could you please provide detailed steps of what you are exactly doing from start to finish. Please make sure to include any relevant logs or observations.

Best Regards,
Jeremias

1 Like

Sorry for the delay Jeremias,

I have a myriad of service and configuration files that need to be under the /etc directory. In my working directory, I created a directory tree such as:

  • system_config
    • etc
      • cron.d
        • gbx_rotate

Then I add system_config to the filesystem in the yaml.

However, when I attempt to build the image, I get the error:

gi.repository.GLib.GError: g-io-error-quark: Preparing /etc: Tree contains both /etc and /usr/etc (0)

Build Log.txt (10.0 KB)

tcbuild.yaml (8.0 KB)

1 Like

Hi @allen.morrison,

To be clear, when capturing changes for TorizonCore Builder, this can be done in two main ways. Either use the isolate command with the --changes-directory option to produce a directory containing the changes to be applied. This of course requires a running device with your configuration changes done under the /etc directory on that device.

Then, there’s creating your own directory containing changes, which is what you seem to be doing here. In this case you want your directory to be structured like this:

changes/
└── usr
    └── etc
        ├── cni
        │   └── net.d
        ├── locale.conf
        ├── motd
        ├── mtab -> ../proc/self/mounts
        ├── rpm-postinsts
        ├── shadow
        └── vconsole.conf

Notice here it’s all under /usr/etc and not /etc. I could go into the technical reasons why, but the bottom line here is due to how OSTree works under the hood.

Try adapting your directory tree like this, and it should work.

Best Regards,
Jeremias

I can confirm this solves the issue I had.

I feel like I was misguided somewhere about the usr/etc versus etc folder structure at some point along the way, not sure how or why.

@jeremias.tx In September 2025, you had said that we should not be modifying /usr/etc, so I’m confused about that.
Also, storing my changes in /usr/etc works, except that it doesn’t sync those changes to /etc on the device, which is required for systemd and chron to see the service configuration files and chronJob files. Does that makes sense?

In September 2025, you had said that we should not be modifying /usr/etc, so I’m confused about that.

Don’t directly modify /usr/etc on the device, is what was meant by that statement. Otherwise if you’re constructing your changes directory manually then the structure must be as I showed previously.

This is why in most cases we suggest to generate a changes directory using the isolate command. As it’s quite error-prone to generate this directory manually due to the nuances of how OSTree works.

Also, storing my changes in /usr/etc works, except that it doesn’t sync those changes to /etc on the device, which is required for systemd and chron to see the service configuration files and chronJob files. Does that makes sense?

This statement doesn’t make sense. Does it work, or does it not? You said initially that it works, but if you do not see your changes on the device after flashing your custom image, then it doesn’t work correct?

Also, I did a quick test and it definitely does work as described. Here’s my tcbuild.yaml file:

# Sample configuration file:
input:
  easy-installer:
    local: torizon-docker-verdin-imx8mp-Tezi_7.5.0+build.30.tar
#Sample customization: insert the configuration changes made in the device
customization:
  filesystem:
     - changes/
output:
  easy-installer:
    local: test

Here’s the contents of my changes directory:

changes/
└── usr
    └── etc
        ├── .tcattr
        └── foo

I run torizoncore-builder build using this, and flash the custom OS image produced by this command to my device using Toradex Easy Installer. On my device I can clearly see the custom file that I added, foo under /etc on my device:

torizon@verdin-imx8mp-06849059:~$ cat /etc/foo
bar

I would assume that the structure of your changes directory is not correct and is producing strange results. I would suggest creating the required custom files and directories on a Torizon OS device under /etc. Then use the isolate command to capture these changes and produce a valid changes directory that you can then use going forward with the build command. An example of this is documented here: Capturing Changes in the Configuration of a Board on Torizon OS | Toradex Developer Center

Best Regards,
Jeremias

To be more precise, when I use my changes directory, it does successfully write those file to /usr/etc; however, the programs DON’T use /usr/etc, they are looking at /etc/, which does not change when I flash the SoM.

I cleared out one of my SoMs and manually set up the files exactly as desired in /etc/ on the device and tested cron and the various custom services. Then I used the isolate command to pull down those changes; however, it only pulled a few files and of the ones that it did pull, some were empty.
Having connection issues at the moment, but I can send the specific directory structure when I’m connected again if that will help.

Okay you are going to have to send me an exact copy and description of what you are doing here. What you described shouldn’t even be technically possible. I would need to try to reproduce exactly what you did, before I can make sense of what you are observing.

it does successfully write those file to /usr/etc; however, the programs DON’T use /usr/etc, they are looking at /etc/, which does not change when I flash the SoM.

In OSTree /usr/etc is the read-only default copy of /etc. This means on a completely fresh OS image with no modifications /usr/etc should more or less be equivalent to /etc. The only way these are not equivalent is if modifications are made to /etc after the OS image has been flashed.

Then I used the isolate command to pull down those changes; however, it only pulled a few files and of the ones that it did pull, some were empty.

To get what files were added/modified/deleted in /etc we use the ostree admin config-dif command on the device: ostree-admin-config-diff(1) — ostree — Debian testing — Debian Manpages

This takes the difference between usr/etc (which again is the default) and /etc (the current running configuration). If some files were not picked up by isolate that would mean these files are present in both /usr/etc, and /etc. Which means they are not “new” changes.

The device you are running isolate on. Was it flashed with a fresh Torizon OS image from Toradex, that you then set up the new files on? Or was it flashed with an already customized image? As an example consider the following:

Say the device is running a fresh Torizon OS image from us. You add a file /etc/foo on the device filesystem. This is obviously a new file and would be picked up by isolate.

Instead imagine you flashed the device with a customized OS image where /etc/foo already exists on the filesystem of that image. In this case isolate would not pick up /etc/foo. This is because the file /etc/foo is by default part of this image already, it is not a “new” change. This could explain why only some of your files were detected by isolate.

Best Regards,
Jeremias

Hi @allen.morrison ,
Let us and Jeremias know if you can share more info here so we can help you.

Best,