[Fontconfig] [PATCH] Do not remove UUID file when a scanned directory is empty 1 x

Alexander Larsson alexander.larsson at gmail.com
Thu Nov 8 08:54:18 UTC 2018

On Wed, Nov 7, 2018 at 4:47 AM Akira TAGOH <akira at tagoh.org> wrote:
> On Mon, Nov 5, 2018 at 9:36 PM Alexander Larsson
> <alexander.larsson at gmail.com> wrote:
> > A better solution would be to use a *global* unique id as part of the
> > cache lookup. For example, say we have a file /etc/fonts/cache-id. And
> > to generate a cache ID for a directory, we use
> > md5("/usr/share/fonts/foo" + read("/etc/fonts/cache-id")). Flatpak
> > could then create its own cache-id file for each app. And fedora
> > silverblue could generate a different cache-id for each compose, so
> > that caches were not aliased between versions. In fact, in addition to
> > the cache id we could also add in /etc/machine-id, which would let us
> > fix the shared NFS homedir case. This would fix the aliasing of
> > /usr/share/fonts between different containers, but not the lookup for
> > /run/host/fonts, so it would have to be combined with something like
> > keiths dir key, where you can configure the /run/host/fonts dir to use
> > a custom cache-id file.
> Hmm, I may be missing some point or be wrong but how does this idea be
> able to share caches? having different cache id will makes different
> md5 and then different cache filename from your explanation. apps
> always need to create caches at first time then. this can be done
> without implementing this if flatpaks don't share caches and maintain
> own cache directory.

So, the font dir setup for flatpak right now is:

Fonts from the runtime: /usr/share/fonts + /usr/cache/fontconfig/
Fonts from the app: /app/share/fonts + /app/cache/fontconfig
Fonts from the host: /run/host/fonts +/run/host/fonts-cache
User Fonts from the host: /run/host/user-fonts +  /run/host/user-fonts-cache

Each font dir here is paired with a cache dir, which ideally should be
up-to-date. However, if for any reason there is a cache miss there is
a per-app fallback font cache dir:


There are two issues here:

Issue 1)
The fonts and caches from the runtime and app are shipped as one unit,
so  they should always match. However, if for whatever reason they do
not, we generate a cache in the fallback dir. If after this, any of
these font directory changes (say due to a runtime update) we never
detect this (due the the runtime mtime not changing). This means, that
once we generate such a fallback cache it will be used forever and
never be considered stale. This will also be a problem for the OS
fonts if the host uses Ostree (i.e. silverblue) as the mtime will also
not change after an OS update.

Issue 2)
The caches from the host appear in a different pathname than when the
caches in the cache dir were generated so we can't use them in the
sandbox, leading to slow startup first time.

Traditionally, issue 1 is rarely a problem because of the mtime, and 2
rarely happens so the slowness is fine in the rare case.

The current uuid fix solves both 1 (because we can ensure a different
uuid when the runtime changes), and 2 (because the uuid is the same
even if the path changed). However, the disadvantage is that it has to
be able to write in the font directory.

Keiths solution only targets issue 2, so its not good enough.

The global uuid proposal solves issue 1, but as you said, it does not
solve issue 2, which is why I ended the mail with the fact that it
needs keiths solution also.

However, maybe the global uuid thing might be overly complicated. Why
don't we just *allow* uuid files, but don't auto-create them. Then
anything that doesn't support mtimes (flatpak runtime, silverblue os
image) can manually create uuid files, but we fall back to using the
path+mtime like before if there is not uuid file. This would allow us
to solve issue 1 where needed, leaving us with only issue 2.

So, for issue 2, keiths proposal is to have:

        <dir map="/usr/share/fonts">/run/host/fonts</dir>

This is problematic for two reasons.

First of all, what does it mean? If we're looking for caches for
/run/host/fonts, should we use "/usr/share/fonts" as the lookup key?
But that key is also used for whatever is in the container at
/usr/share/fonts, so the two would use the same cache! (Although, if
the container uses a .uuid file for /usr/share/fonts this is not a

Secondly, we also need a /run/host/user-fonts mapping, and the exact
directory this maps to is dynamically generated (as
$XDG_DATA_HOME/fonts or $HOME/.fonts depending on what is in use).
This means that the config snippet has to be runtime generated, and I
much prefer if I could use a static file (as it would then work with
old versions of flatpak).

I think here we can also use optional uuid files to fix things. If we
require that any setup that bind-mounts host font directories use
.uuid files for its own directories, then the /run/host/fonts <=>
/usr/share/fonts conflict goes away and the map= option above works.
Also, if we auto-generate a uuid file for ~/.fonts (which i imagine is
less problematic than /usr) we will not have any need for dynamic

Do you think that would work? It does set some limitations on how
fontconfig should be used in containers and on mtime-less systems,
which probably should be documented somewhere.

> Also there are the problem on storing those caches into one directory.
> fontconfig will cleans up the unused (invalid) caches at runtime. so
> some of them might be picked up by it accidentally.

Each app has a custom $XDG_CACHE_DIR so the caches of two different
apps will not see each others fallback caches. For the other caches
(host, runtime) these are read-only and will never be cleaned up.

More information about the Fontconfig mailing list