-
Notifications
You must be signed in to change notification settings - Fork 225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tee-supplicant: send READY=1 notification to systemd #383
base: master
Are you sure you want to change the base?
Conversation
c7649f8
to
0b76849
Compare
0b76849
to
3b5d908
Compare
tee-supplicant/src/tee_supplicant.c
Outdated
@@ -835,6 +839,7 @@ int main(int argc, char *argv[]) | |||
/* long name | has argument | flag | short value */ | |||
{ "help", no_argument, 0, 'h' }, | |||
{ "daemonize", no_argument, 0, 'd' }, | |||
{ "sdnotify", no_argument, 0, 'n' }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-n
usually means dry-run in other utilities. How about -s
instead?
tee-supplicant/src/tee_supplicant.c
Outdated
@@ -923,6 +931,28 @@ int main(int argc, char *argv[]) | |||
} | |||
} | |||
|
|||
if ((sdnotify) && (!daemonize)) { | |||
/* we are set here notify systemd */ | |||
int(*__sd_notify__)(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The __
are ugly, I suppose you've added them to avoid conflicts with sd_notify()
in <systemd/sd-daemon.h>
. How about int (*my_sd_notify)(int unset_environment, const char *state)
?
Please initialize all local variables.
tee-supplicant/src/tee_supplicant.c
Outdated
int(*__sd_notify__)(); | ||
void *systemd = dlopen("libsystemd.so", RTLD_LAZY); | ||
if (systemd) { | ||
*(int**)(&__sd_notify__) = dlsym(systemd, "sd_notify"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need all this casting?
tee-supplicant/src/tee_supplicant.c
Outdated
@@ -923,6 +931,28 @@ int main(int argc, char *argv[]) | |||
} | |||
} | |||
|
|||
if ((sdnotify) && (!daemonize)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The extra ()
are not needed.
tee-supplicant/src/tee_supplicant.c
Outdated
*(int**)(&__sd_notify__) = dlsym(systemd, "sd_notify"); | ||
if (__sd_notify__) { | ||
int ret = __sd_notify__(0, "READY=1"); | ||
if (ret <= 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The extra {}
are not needed.
0c60cfb
to
920d783
Compare
@jforissier : I just figured out on the target testing that yocto doesn't ship libsystemd.so but only versioned so.
the dlopen won't work unless the symlink /lib/libsystemd.so is present |
@embetrix |
920d783
to
41ef939
Compare
done |
tee-supplicant/src/tee_supplicant.c
Outdated
if (ret <= 0) | ||
fprintf(stderr, "sd_notify failed: %d\n", ret); | ||
} | ||
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fold up else
to make it } else
tee-supplicant/src/tee_supplicant.c
Outdated
if (sdnotify && !daemonize) { | ||
int ret = 0; | ||
void *sd_handle = NULL; | ||
int (*sd_notify)(int unset_environment, const char *state) = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is bound to cause a compile error if <systemd/sd-daemon.h>
is ever included, that's why I suggested my_sd_notify
or such.
65d76d3
to
d130624
Compare
tee-supplicant/src/tee_supplicant.c
Outdated
if (sd_handle) { | ||
tee_sd_notify = dlsym(sd_handle, "sd_notify"); | ||
if (tee_sd_notify) { | ||
e = tee_sd_notify(0, "READY=1"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While at it, could you add a "tee_sd_notify(0, "WATCHDOG=1"); into the main loops which call process_one_request()?
What could be the maximum time that a process_one_request() call takes? We could then double this and add to systemd service file to detect if tee-supplicant hangs. I've seen hangs related ftpm kernel module unloading which could affect tee-supplicant too, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How long does it take to copy a file (of unknown size) from the file system into memory, worst case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, the watchdog target is application dependent but the sd_notify() call to kick the watchdog could be generic in the loop.
Users could set the application specific watchdog timeout in the systemd service file for tee-supplicant. Default could be that it's not set at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ioctl()
call is blocking until a request comes, with no timeout. So we would at least need to add a timeout before adding support for such a watchdog. An alternative would be to ping from a separate thread but that's obviously a weaker health guarantee.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The watchdog call from tee-supplicant to systemd is just a health signal. It can block for ever. The timeout value is set in systemd service file, which can be unset by default, or a really large value. Dending on use cases and TAs, then this value can be reduced.
But it's ok to skip this for now too.
tee-supplicant/src/tee_supplicant.c
Outdated
fprintf(stderr, "sd_notify failed: %d\n", e); | ||
} else | ||
fprintf(stderr, "Couldn't find sd_notify symbol: %s\n", dlerror()); | ||
dlclose(sd_handle); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If watchdog calls are done, I'd leave this open until exiting mainloops
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also note that libsystemd.so is nowadays built with -z nodelete
, i.e. we do not support being unloaded, and the dlclose() is hence without effect
Tested on Linaro Trusted Substrate firmware https://gitlab.com/Linaro/trustedsubstrate/meta-ts/ and TRS https://trs.readthedocs.io/en/latest/ yocto based distro with systemd initramfs using service file, running on ARM64 Rockpi4b:
udev rule:
boot log in initramfs which uses optee early fTPM TA to create an encrypted rootfs:
So this sd_notify() patch works nicely. Thanks! |
tee-supplicant/src/tee_supplicant.c
Outdated
@@ -923,6 +926,20 @@ int main(int argc, char *argv[]) | |||
} | |||
} | |||
|
|||
/* we are set here notify systemd */ | |||
sd_handle = dlopen("libsystemd.so.0", RTLD_LAZY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry for parachuting in here, I was pointed to this PR from here:
https://lists.freedesktop.org/archives/systemd-devel/2024-June/050385.html
I just wanted to mention that for a trivial call like sd_notify() you might just opt directly implementing this, rather than doing dlopen()/dlsym(). i.e. something like this:
https://www.freedesktop.org/software/systemd/man/devel/sd_notify.html#Standalone%20Implementations
tee-supplicant/src/tee_supplicant.c
Outdated
if (tee_sd_notify) { | ||
e = tee_sd_notify(0, "READY=1"); | ||
if (e <= 0) | ||
fprintf(stderr, "sd_notify failed: %d\n", e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please do not consider e == 0
an error, it's really not. It just means no message sent because $NOTIFY_SOCKET wasn't set, i.e. because it was invoked in a non-systemd context, which is entirely fine however.
7044c13
to
50010dd
Compare
2cddc19
to
37a6124
Compare
Tested latest version of patch with TS and TRS in https://ledge.validation.linaro.org/scheduler/job/88692 and it works. tee-supplicant startup state is correctly reported to systemd. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- See comments below.
- Please use prefix in commit subject: "tee-supplicant: send READY=1 notification to systemd"
- Please add your
Signed-off-by:
0cece47
to
fc9f273
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please wrap the commit description at 72 characters and add:
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
@poettering thanks for your recommendations
This option is very useful when tee-supplicant is started from systemd and can used with Type=notify to signal readiness Signed-off-by: Ayoub Zaki <ayoub.zaki@embetrix.com> Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
fc9f273
to
e3ebccc
Compare
done |
Any more feedback? @mikkorapeli-linaro would you mind giving an Ack and/or Tested-by perhaps? |
Yes, latest patch version also Tested-by: Mikko Rapeli mikko.rapeli@linaro.org TS firmware with optee 4.1 and RPMB kernel patches from Jens, and TRS uki kernel and initramfs with systemd which starts tee-supplicant using this patch to create fTPM encrypted rootfs, on rockpi4b. The few remaining failures in TS/TRS test suite are not related to this patch. Test run: |
This is very useful when tee-supplicant is started from systemd and can used with Type=notify to signal readiness
#382