29.11.2021 03:36, Michał Mirosław пишет: > On Mon, Nov 29, 2021 at 12:53:51AM +0300, Dmitry Osipenko wrote: >> 29.11.2021 00:17, Michał Mirosław пишет: >>>> I'm having trouble with parsing this comment. Could you please try to >>>> rephrase it? I don't see how you could check whether power-off handler >>>> is available if you'll mix all handlers together. >>> If notify_call_chain() would be fixed to return NOTIFY_OK if any call >>> returned NOTIFY_OK, then this would be a clear way to gather the >>> answer if any of the handlers will attempt the final action (reboot or >>> power off). >> Could you please show a code snippet that implements your suggestion? > > A rough idea is this: > > static int notifier_call_chain(struct notifier_block **nl, > unsigned long val, void *v, > int nr_to_call, int *nr_calls) > { > - int ret = NOTIFY_DONE; > + int ret, result = NOTIFY_DONE; > struct notifier_block *nb, *next_nb; > > nb = rcu_dereference_raw(*nl); > > while (nb && nr_to_call) { > ... > ret = nb->notifier_call(nb, val, v); > + > + /* Assuming NOTIFY_STOP-carrying return is always greater than non-stopping one. */ > + if (result < ret) > + result = ret; > ... > } > - return ret; > + return result; > } > > Then: > > bool prepare_reboot() > { > int ret = xx_notifier_call_chain(&shutdown_notifier, PREPARE_REBOOT, ...); > return ret == NOTIFY_OK; > } > > And the return value would signify whether the reboot will be attempted > when calling the chain for the REBOOT action. (Analogously for powering off.) If you started to execute call chain, then you began the power-off / restart sequence, this is a point of no return. Sorry, I still don't understand what you're trying to achieve. The approach of having separate call chains is simple and intuitive, I don't see reasons to change it.