xen/manage: unwind partial shutdown watcher setup on error
setup_shutdown_watcher() registers shutdown_watch first, then the sysrq watch, and finally publishes the supported feature-* nodes in xenstore. If sysrq watch registration fails, or xenbus_printf() fails after one or more feature nodes were created, the function returns immediately without undoing the earlier setup. This leaves the system in a partially initialized state, with registered watches and/or stale xenstore entries despite the function reporting failure. Unwind the partial setup before returning an error by unregistering any watches that were already registered and removing feature nodes that were already published. Signed-off-by: GuoHan Zhao <zhaoguohan@kylinos.cn> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Signed-off-by: Juergen Gross <jgross@suse.com> Message-ID: <20260407022443.12971-1-zhaoguohan@kylinos.cn>
This commit is contained in:
parent
f45ab27774
commit
7f8862d287
1 changed files with 17 additions and 3 deletions
|
|
@ -343,12 +343,11 @@ static int setup_shutdown_watcher(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
err = register_xenbus_watch(&sysrq_watch);
|
||||
if (err) {
|
||||
pr_err("Failed to set sysrq watcher\n");
|
||||
return err;
|
||||
goto err_unregister_shutdown;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -361,11 +360,26 @@ static int setup_shutdown_watcher(void)
|
|||
if (err) {
|
||||
pr_err("%s: Error %d writing %s\n", __func__,
|
||||
err, node);
|
||||
return err;
|
||||
goto err_remove_features;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_features:
|
||||
while (--idx >= 0) {
|
||||
if (!shutdown_handlers[idx].flag)
|
||||
continue;
|
||||
snprintf(node, FEATURE_PATH_SIZE, "feature-%s",
|
||||
shutdown_handlers[idx].command);
|
||||
xenbus_rm(XBT_NIL, "control", node);
|
||||
}
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
unregister_xenbus_watch(&sysrq_watch);
|
||||
err_unregister_shutdown:
|
||||
#endif
|
||||
unregister_xenbus_watch(&shutdown_watch);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int shutdown_event(struct notifier_block *notifier,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue