package chamelon

  1. Overview
  2. Docs
Subset of littlefs filesystem fulfilling MirageOS KV


Dune Dependency






Chamelon implements a subset of the littlefs filesystem, which was originally designed for microcontroller use. It exposes an interface matching the Mirage_kv.RW module type and operates on top of a block device matching Mirage_block.S .

It is extremely not POSIX.

Published: 04 Aug 2022


what is this?

An implementation of the mirage-kv module type offering persistence via mirage-block, suitable for use in MirageOS unikernels. It is inspired by littlefs.

what isn't this?

Performant. Wear-alert. Making big promises. Backed by Big Camel or suitable for Big Data.

under what circumstances should I definitely not use it?

See "how does it differ from littlefs?" for specific caveats of this implementation compared to other users of littlefs.

This implementation is not suitable for use as a large filesystem. Addressing is limited to 32-bit block indices, and currently the solo5 implementation supports blocks of a maximum size of 512 bytes, for a maximum addressible filesystem of 65535 MiB. Block devices of larger size can be supplied, but only 64 GiB will be usable by chamelon.

littlefs is most efficient in its space usage with many small ( < 1/4 block size) files in a broad hierarchy (i.e. most directories have many files or other directories in them).

It is least space-efficient with many files of size > 1/4 block size and < 1 block size, and with deeply-nested directory structures.

The above limitations become more alarming with the knowledge that items within a directory are an unordered linked list, so many operations on directories are O(n) in the number of items within the directory. If performance begins to be of concern, some thought on the filesystem layout is advised.

why did you build this?

Sometimes you just gotta store some stuff. You don't have to store much stuff and you don't have to do it very often but people are gonna get real mad if you don't do it at least a little.

A bit more background is available in a personal blog post announcing chamelon.

can I use it?

Sure, if you want. chamelon is released under the ISC license (like many MirageOS libraries and its core tooling). Prospective users are encouraged to remember that THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.

why would I use it over other MirageOS filesystem implementations?

Good question. I'm using it because I didn't want to end up using an unmaintained filesystem implementation or maintaining someone else's filesystem implementation. Obviously that's not going to apply to you (or if it does, you're unlikely to decide this software is the right choice).

how can I get started understanding it?

I would recommend reading the littlefs document first. After that, if you prefer to drill down from high-level abstractions, start at mirage/kv.mli. If you'd rather start from the details and build abstractions from there, check out the contents of lib/, specifically,, and (You'll probably also be interested in littlefs's

There are several sets of tests for chamelon:

  • src/dune describes some tests using the chamelon-unix command-line tools.

  • mirage_test/ contains tests of the higher-level functions provided by the Kv module, as I expect them to be used in unikernels.

  • lib_test/ contains lower-level unit tests, largely of serializers and deserializers and their accompanying error handling.

  • fuzz/ contains a few property-based tests exercised via crowbar and afl-fuzz.

  • bench/ contains some microbenchmarking tests built with bechamel.

how does it differ from littlefs?

littlefs threads a linked list through its directory tree so the tree can be traversed in constant RAM. This necessitates some extra complexity to ensure that the tree and linked list agree. This implementation does not guarantee constant RAM operations, therefore does not use the threaded linked list (softlinks in the parlance of the littlefs spec), therefore also does not implement global move state.

littlefs implements wear leveling strategies aimed at increasing the life of flash-based storage. This implementation does not, because we assume the execution environment does not provide direct access to real storage; we trust the hypervisor's disk driver to handle this if it's appropriate and required.

This implementation also does not detect or track bad blocks, for similar reasons. (This decision would be fairly easy to reverse.)

The fuse driver for littlefs is interoperable with this implementation, to the best of my knowledge.

how do I thank you for writing and maintaining this software?

Directly with money, by donating to a 501c3 that does important work in my community, or by writing a nice e-mail to the address in the commit messages.

Dependencies (15)

  1. optint >= "0.0.4"
  2. ppx_cstruct
  3. mirage-logs >= "1.2.0"
  4. mirage-kv >= "4.0.1" & < "5.0.0"
  5. mirage-clock >= "2.0.0"
  6. mirage-block >= "3.0.0"
  7. ptime >= "0.8.6"
  8. lwt >= "5.3.0"
  9. logs >= "0.6.0"
  10. fmt >= "0.8.7"
  11. digestif >= "1.0.0"
  12. cstruct >= "6.0.0"
  13. checkseum >= "0.3.2"
  14. dune >= "2.9.0" & < "3.7.0"
  15. ocaml >= "4.10.0"

Dev Dependencies (10)

  1. bechamel-js >= "0.2.0" & with-test
  2. bechamel >= "0.2.0" & with-test
  3. mirage-crypto-rng >= "0.10.6" & < "0.11.0" & with-test
  4. mirage-clock-unix >= "4.0.0" & with-test
  5. mirage-block-unix >= "2.13.0" & with-test
  6. mirage-block-combinators >= "3.0.0" & with-test
  7. alcotest-lwt >= "1.5.0" & with-test
  8. alcotest >= "1.5.0" & with-test
  9. fpath >= "0.7.3" & with-test
  10. crowbar >= "0.2.1" & with-test

Used by (1)

  1. chamelon-unix >= "0.1.2"