Mr. Weiland, respect for the sleuthing work!
I got an alert today that one of my filesystems was getting full and when I looked at it I found the hassio_audio container generated about 1GB of useless logs each day since PI day (03.14). All of the log entries relate to this issue with "Assertion 'clock_gettime(CLOCK_REALTIME, &ts) == 0' failed"
, it repeats every second. And yes, it also uses about 15-20% CPU time.
I quickly found this page and I am really thankful you already identified the cause, and you also found a workaround.
One question for you please, if you don’t mind: do you know which 32-bit time syscalls alpine needs if the 64-bit ones are not available? I’m asking because I’d like to configure only the hassio_audio container to have access to these (and not to all syscalls), while keeping the other containers, well, “contained”, as they currently are. It can be easily done using the " --security-opt
" parameter, see “Pass a profile for a container” at Seccomp security profiles for Docker | Docker Documentation
While your approach obviously works what you did is you probably allowed all containers access to all syscalls, essentially disabling docker security capabilities for all containers. I suppose you could have instead run only hassio_audio without the default seccomp profile by using --security-opt seccomp=unconfined
But I see no reason not to go just one step further and allow hassio_audio access only to the time functions it needs, and nothing else.
[Later edit]: I managed to identify the 19 64-bit syscalls related to time - they conveniently all have “time64” in the name. So I downloaded the default.json Docker seccomp security profile and I set only those 19 syscalls to SCMP_ACT_TRACE
(I left the defaultAction
for all other syscalls to SCMP_ACT_ERRNO
) and it works - date returns the correct value and ping works, too, and hassio_audio is not in a loop anymore.
Steps to replicate when running on raspbian:
- Download the default.json Docker seccomp security profile as
/etc/docker/default.json
- Delete the following 19 lines in the file (they are not all in a single sequence like here):
"clock_adjtime64",
"clock_getres_time64",
"clock_gettime64",
"clock_nanosleep_time64",
"futex_time64",
"io_pgetevents_time64",
"mq_timedreceive_time64",
"mq_timedsend_time64",
"ppoll_time64",
"pselect6_time64",
"recvmmsg_time64",
"rt_sigtimedwait_time64",
"sched_rr_get_interval_time64",
"semtimedop_time64",
"timer_gettime64",
"timer_settime64",
"timerfd_gettime64",
"timerfd_settime64",
"utimensat_time64",
- Add the following section right below the line
"syscalls": [
(the blank space at the beginning of each line is made of TABs, not spaces):
{
"names": [
"clock_adjtime64",
"clock_getres_time64",
"clock_gettime64",
"clock_nanosleep_time64",
"futex_time64",
"io_pgetevents_time64",
"mq_timedreceive_time64",
"mq_timedsend_time64",
"ppoll_time64",
"pselect6_time64",
"recvmmsg_time64",
"rt_sigtimedwait_time64",
"sched_rr_get_interval_time64",
"semtimedop_time64",
"timer_gettime64",
"timer_settime64",
"timerfd_gettime64",
"timerfd_settime64",
"utimensat_time64"
],
"action": "SCMP_ACT_TRACE",
"args": [],
"comment": "Invoke a ptracer to make a decision or set errno to -ENOSYS",
"includes": {},
"excludes": {}
},
- Edit
/lib/systemd/system/docker.service
and change the line
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
to
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --seccomp-profile /etc/docker/default.json
- Completely restart dockerd (or reboot, it’s simpler) and after that the hassio_audio stops (with a different error ) but it’s not in a loop anymore
I wish there was a portainer option to add --security-opt seccomp=/etc/docker/default.json
for a single container (i.e. hassio_audio) and not as the default for all containers but there isn’t one yet. Hopefully, soon, I saw they reopened the feature request 3 days ago:
Cheers!