extern struct mutex xb_write_mutex;
int xs_init(void);
+void xs_deinit(void);
int xb_init_comms(void);
void xb_deinit_comms(void);
int xs_watch_msg(struct xs_watch_event *event);
char *id_node, char *path_node);
void xenbus_ring_ops_init(void);
+void xenbus_ring_ops_deinit(void);
int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void *par);
void xenbus_dev_queue_reply(struct xb_req_data *req);
#endif
ring_ops = &ring_ops_hvm;
}
+
+void xenbus_ring_ops_deinit(void)
+{
+ ring_ops = NULL;
+}
return err;
}
+static void xenstored_local_deinit(void)
+{
+ struct evtchn_close close;
+ void *page = NULL;
+
+ page = gfn_to_virt(xen_store_gfn);
+ free_page((unsigned long)page);
+
+ close.port = xen_store_evtchn;
+
+ HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+
+ xen_store_evtchn = 0;
+}
+
static int xenbus_resume_cb(struct notifier_block *nb,
unsigned long action, void *data)
{
.notifier_call = xenbus_resume_cb,
};
-static int __init xenbus_init(void)
+#ifdef CONFIG_XEN_COMPAT_XENFS
+struct proc_dir_entry *xen_procfs;
+#endif
+
+int xenbus_init(void)
{
int err = 0;
uint64_t v = 0;
* Create xenfs mountpoint in /proc for compatibility with
* utilities that expect to find "xenbus" under "/proc/xen".
*/
- proc_create_mount_point("xen");
+ xen_procfs = proc_create_mount_point("xen");
#endif
out_error:
return err;
}
-
+EXPORT_SYMBOL_GPL(xenbus_init);
postcore_initcall(xenbus_init);
+void xenbus_deinit(void)
+{
+ if (!xen_domain())
+ return;
+
+#ifdef CONFIG_XEN_COMPAT_XENFS
+ proc_remove(xen_procfs);
+ xen_procfs = NULL;
+#endif
+
+ xs_deinit();
+ xenstored_ready = 0;
+
+ switch (xen_store_domain_type) {
+ case XS_LOCAL:
+ xenstored_local_deinit();
+ xen_store_interface = NULL;
+ break;
+ default:
+ pr_warn("Xenstore state unknown\n");
+ break;
+ }
+ xenbus_ring_ops_deinit();
+}
+EXPORT_SYMBOL_GPL(xenbus_deinit);
+
MODULE_LICENSE("GPL");
for (;;) {
wait_event_interruptible(watch_events_waitq,
+ kthread_should_stop() ||
!list_empty(&watch_events));
if (kthread_should_stop())
.notifier_call = xs_reboot_notify,
};
+static struct task_struct *xenwatch_task;
+
int xs_init(void)
{
int err;
task = kthread_run(xenwatch_thread, NULL, "xenwatch");
if (IS_ERR(task))
return PTR_ERR(task);
+ xenwatch_task = task;
/* shutdown watches for kexec boot */
xs_reset_watches();
return 0;
}
+
+void cancel_watches(void)
+{
+ struct xs_watch_event *event, *tmp;
+
+ /* Cancel pending watch events. */
+ spin_lock(&watch_events_lock);
+ list_for_each_entry_safe(event, tmp, &watch_events, list) {
+ list_del(&event->list);
+ kfree(event);
+ }
+ spin_unlock(&watch_events_lock);
+}
+
+void delete_watches(void)
+{
+ struct xenbus_watch *watch, *tmp;
+
+ spin_lock(&watches_lock);
+ list_for_each_entry_safe(watch, tmp, &watches, list) {
+ list_del(&watch->list);
+ }
+ spin_unlock(&watches_lock);
+}
+
+void xs_deinit(void)
+{
+ kthread_stop(xenwatch_task);
+ xenwatch_task = NULL;
+ xb_deinit_comms();
+ unregister_reboot_notifier(&xs_reboot_nb);
+ cancel_watches();
+ delete_watches();
+}