Re: [systemd-devel] Using *.path units without races?

2020-03-18 Thread Uwe Geuder
Hi!

On Tue, 17 Mar 2020 at 23:52, Michael Chapman wrote:
>
> On Wed, 18 Mar 2020, Uwe Geuder wrote:
> > Hi!
> >
> > I have wondered for a while how I can use *.path units without (too bad)
> > races.
> >
> > Since
> > https://github.com/systemd/systemd/pull/13509/commits/06582e42de65a61d0238a18720a12b6353edb7cd
> > the behaviour has been become much clearer, but I must admit I still
> > don't get it.
>
> That commit does look incomplete to me.
>
> As a quick test, are you able to try out the patch below? This makes
> systemd always check the filesystem when the service stops, rather than
> just relying on the (as of that commit nonexistent) inotify event.
...
> diff --git a/src/core/path.c b/src/core/path.c
> index cb75d778af..a513df97b2 100644
> --- a/src/core/path.c
> +++ b/src/core/path.c
> @@ -759,11 +759,7 @@ static void path_trigger_notify(Unit *u, Unit *other) 
> {
>  if (p->state == PATH_RUNNING &&
>  UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
>  log_unit_debug(UNIT(p), "Got notified about unit 
> deactivation.");
> -
> -/* Hmm, so inotify was triggered since the
> - * last activation, so I guess we need to
> - * recheck what is going on. */
> -path_enter_waiting(p, false, p->inotify_triggered);
> +path_enter_waiting(p, false, true);
>  }
>  }
> 

Thanks a lot Michael for this quick patch. The patch seems to have
suffered a formatting accident in the mail. However, your intent to
change the 3rd agument of that function call is pretty clear.

I built that change and quickly tested it. It seems to work fine!

Please note that I have not yet done any wider (regression) testing and
my understanding of the code base is not good.

I can share my test code

- test.path -
[Unit]
Description=%n testing racyness of path

[Path]
DirectoryNotEmpty=/tmp/systemd-path-test/
MakeDirectory=true


- test.service -
[Unit]
Description=%n testing racyness of path

[Service]
ExecStart=%h/try/systemd/test.sh


- test.sh -
#!/bin/sh -eu
# Usage: Expects to find .sleep files in ${testdir}

echo "${0} starting"
testdir=/tmp/systemd-path-test/

exit_handler() {
  echo "${0} exiting"
}
trap exit_handler EXIT

# assume good faith, don't worry about dotfiles or
# pathologic filenames...
files=$(ls "${testdir}/")
if [ -z "${files}" ] ; then
  echo "No files found"
  exit
else
  echo "Found ${files}"
fi

for f in ${files} ; do
  if [ -e "${testdir}/${f}" ] ; then
  rm -f "${testdir}/${f}"
  else
echo "Race: ${f} has disappeared"
  fi
  case "${f}" in
*.sleep) # don't worry about non-numeric...
  s=$(basename "${f}" .sleep)
  echo "sleeping ${s}"
  sleep "${s}"
  ;;
  esac
done

--

Test case:

touch /tmp/systemd-path-test/5.sleep ; sleep 2 ; \
  touch /tmp/systemd-path-test/6.sleep ; sleep 5 ; \
  touch /tmp/systemd-path-test/0.5.sleep

(all 5 commands in one go)

As expected the service gets now invoked 3 times. Without your patch the
second touch command/file is missed and only "handled" together with the
third touch command/file.


Regards,

Uwe

Uwe Geuder
Neuro Event Labs Oy
Tampere, Finland
uwe.gxu...@neuroeventlabs.com (bot check: fix 1 obvious typo)
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] Reasoning behind sd_bus_error argument to sd_bus_call?

2020-03-18 Thread Daan De Meyer
I completely agree that for errors returned by the service, a D-Bus error
is a lot better. However, from what I understand of sd-bus, any errors
returned by the service are encoded in the reply returned by sd_bus_call
and you use sd_bus_message_is_method_error and sd_bus_message_get_error on
the reply to get the actual service error. Where does that leave the
sd_bus_error argument of sd_bus_call? Is it simply another way to get the
error? It seems to be always be set when a local or remote error occurs,
but it can only contain information that I can get by checking the return
value of the function or by checking whether the reply object passed to
sd_bus_call contains an error.

How I would imagine using sd_bus_call:

r = sd_bus_call(..., reply, ...);
if (r < 0) {
  // Local error
}

if (sd_bus_message_is_method_error(reply)) {
  const sd_bus_error *error = sd_bus_message_get_error(reply);
  // Service error
}

But if this is the intended usage, what's the use of the sd_bus_error
argument of sd_bus_call since the above code already handles both the local
error and the remote service error failure paths?

Daan

On Wed, 18 Mar 2020 at 11:57, Simon McVittie  wrote:

> On Tue, 17 Mar 2020 at 20:17:05 +0100, Daan De Meyer wrote:
> > I'm documenting sd_bus_call and its async variant and I was wondering
> about the
> > sd_bus_error output parameter that's passed to it. [...] I don't
> > see immediately see the benefit of the sd_bus_error parameter in a D-Bus
> client
> > since I can simply check the return value instead which seems to contain
> the
> > same information looking at the implementation.
>
> The return value is a single int, which according to systemd conventions
> is probably a negative errno value. That's a lot less information than
> a D-Bus error (systemd sd_bus_error, libdbus DBusError or equivalent):
> D-Bus errors consist of a machine-readable name (namespaced by a reversed
> domain name) and a human-readable message.
>
> For the information about *whether* an error occurred, sure, you get the
> same information, but for information about *which* error occurred and why,
> a sd_bus_error is a lot better.
>
> Let's pretend your D-Bus client is interacting with a D-Bus service that
> resembles systemd-timedated. An errno value can give you, at best,
> something like this (where *** marks the part that came from the service's
> reply):
>
> my-client: Error: Unable to set time zone to America/Gotham:
> ***No such file or directory (errno 2)***
>
> whereas a D-Bus error (sd_bus_error) from a well-implemented service can
> give you something a lot more detailed. For example, after you ispect
> the sd_bus_error, you might find that the error above was either of these:
>
> my-client: Error: Unable to set time zone to America/Gotham:
> ***No time zone file for "America/Gotham" found (tried
> "/usr/share/zoneinfo/America/Gotham",
> "/usr/local/share/zoneinfo/America/Gotham")
> (error code com.example.NotTimedated.Error.NoSuchTimezone)***
>
> my-client: Error: Unable to set time zone to America/Gotham:
> ***No time zone data installed (tried "/usr/share/zoneinfo",
> "/usr/local/share/zoneinfo")
> (error code com.example.NotTimedated.Error.TzdataNotInstalled)***
>
> In this example a programmatic client would also be able
> to respond differently to the distinct machine-readable
> errors com.example.NotTimedated.Error.NoSuchTimezone and
> com.example.NotTimedated.Error.TzdataNotInstalled if it wanted to;
> for example it could respond to the second error by trying to use
> PackageKit to install tzdata, which obviously wouldn't be appropriate
> for the first error.
>
> D-Bus errors were inspired by GLib's GError, which is basically a triple
> { domain: interned string, code: int, message: string }, where the domain
> provides extensible uniqueness, and the code is a member of an enum
> determined by the domain.
>
> smcv
> ___
> systemd-devel mailing list
> systemd-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/systemd-devel
>
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] Reasoning behind sd_bus_error argument to sd_bus_call?

2020-03-18 Thread Simon McVittie
On Tue, 17 Mar 2020 at 20:17:05 +0100, Daan De Meyer wrote:
> I'm documenting sd_bus_call and its async variant and I was wondering about 
> the
> sd_bus_error output parameter that's passed to it. [...] I don't
> see immediately see the benefit of the sd_bus_error parameter in a D-Bus 
> client
> since I can simply check the return value instead which seems to contain the
> same information looking at the implementation.

The return value is a single int, which according to systemd conventions
is probably a negative errno value. That's a lot less information than
a D-Bus error (systemd sd_bus_error, libdbus DBusError or equivalent):
D-Bus errors consist of a machine-readable name (namespaced by a reversed
domain name) and a human-readable message.

For the information about *whether* an error occurred, sure, you get the
same information, but for information about *which* error occurred and why,
a sd_bus_error is a lot better.

Let's pretend your D-Bus client is interacting with a D-Bus service that
resembles systemd-timedated. An errno value can give you, at best,
something like this (where *** marks the part that came from the service's
reply):

my-client: Error: Unable to set time zone to America/Gotham:
***No such file or directory (errno 2)***

whereas a D-Bus error (sd_bus_error) from a well-implemented service can
give you something a lot more detailed. For example, after you ispect
the sd_bus_error, you might find that the error above was either of these:

my-client: Error: Unable to set time zone to America/Gotham:
***No time zone file for "America/Gotham" found (tried
"/usr/share/zoneinfo/America/Gotham",
"/usr/local/share/zoneinfo/America/Gotham")
(error code com.example.NotTimedated.Error.NoSuchTimezone)***

my-client: Error: Unable to set time zone to America/Gotham:
***No time zone data installed (tried "/usr/share/zoneinfo",
"/usr/local/share/zoneinfo")
(error code com.example.NotTimedated.Error.TzdataNotInstalled)***

In this example a programmatic client would also be able
to respond differently to the distinct machine-readable
errors com.example.NotTimedated.Error.NoSuchTimezone and
com.example.NotTimedated.Error.TzdataNotInstalled if it wanted to;
for example it could respond to the second error by trying to use
PackageKit to install tzdata, which obviously wouldn't be appropriate
for the first error.

D-Bus errors were inspired by GLib's GError, which is basically a triple
{ domain: interned string, code: int, message: string }, where the domain
provides extensible uniqueness, and the code is a member of an enum
determined by the domain.

smcv
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel