core: rework how we track cgroup realized state
Prompted by https://github.com/systemd/systemd/pull/37646#discussion_r2126882561
Follow-up for
879952a85311ca375c673480d9718a9e0cd93c1d
Currently, almost all cgroup attr getters check cgroup_path for whether
cgroup is around. This is actually great, because we never want to expose
a non-existent cgroup path via IPC and such. However, it is spuriously
initialized at places where it shouldn't be, e.g. in unit_warn_leftover_processes().
This matters especially to units that *may* carry processes to run, but
not *always*, notably socket units. unit_warn_leftover_processes() is supposed
to be informative only and not try to set cgroup tracking to realized in
a half-assed way.
Hence, let's kill cgroup_realized field, and make sure cgroup_path is set
only if cgroup has been created. Be extra careful with deserialization
though, since the previous versions don't follow this rule and we need
to patch cgroup_path manually based on cgroup_realized we got from deserialization.
Calls to unit_watch_cgroup*() are dropped in cgroup_runtime_deserialize_one(),
because unit_deserialize_state() will invalidate cgroup realized state and
reapply later.