diff options
Diffstat (limited to 'drivers/xen/xenbus/xenbus_xs.c')
-rw-r--r-- | drivers/xen/xenbus/xenbus_xs.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index b6d5fff43d16..ba804f3d8278 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <xen/xenbus.h> | 50 | #include <xen/xenbus.h> |
51 | #include <xen/xen.h> | 51 | #include <xen/xen.h> |
52 | #include "xenbus_comms.h" | 52 | #include "xenbus_comms.h" |
53 | #include "xenbus_probe.h" | ||
53 | 54 | ||
54 | struct xs_stored_msg { | 55 | struct xs_stored_msg { |
55 | struct list_head list; | 56 | struct list_head list; |
@@ -139,6 +140,29 @@ static int get_error(const char *errorstring) | |||
139 | return xsd_errors[i].errnum; | 140 | return xsd_errors[i].errnum; |
140 | } | 141 | } |
141 | 142 | ||
143 | static bool xenbus_ok(void) | ||
144 | { | ||
145 | switch (xen_store_domain_type) { | ||
146 | case XS_LOCAL: | ||
147 | switch (system_state) { | ||
148 | case SYSTEM_POWER_OFF: | ||
149 | case SYSTEM_RESTART: | ||
150 | case SYSTEM_HALT: | ||
151 | return false; | ||
152 | default: | ||
153 | break; | ||
154 | } | ||
155 | return true; | ||
156 | case XS_PV: | ||
157 | case XS_HVM: | ||
158 | /* FIXME: Could check that the remote domain is alive, | ||
159 | * but it is normally initial domain. */ | ||
160 | return true; | ||
161 | default: | ||
162 | break; | ||
163 | } | ||
164 | return false; | ||
165 | } | ||
142 | static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len) | 166 | static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len) |
143 | { | 167 | { |
144 | struct xs_stored_msg *msg; | 168 | struct xs_stored_msg *msg; |
@@ -148,9 +172,20 @@ static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len) | |||
148 | 172 | ||
149 | while (list_empty(&xs_state.reply_list)) { | 173 | while (list_empty(&xs_state.reply_list)) { |
150 | spin_unlock(&xs_state.reply_lock); | 174 | spin_unlock(&xs_state.reply_lock); |
151 | /* XXX FIXME: Avoid synchronous wait for response here. */ | 175 | if (xenbus_ok()) |
152 | wait_event(xs_state.reply_waitq, | 176 | /* XXX FIXME: Avoid synchronous wait for response here. */ |
153 | !list_empty(&xs_state.reply_list)); | 177 | wait_event_timeout(xs_state.reply_waitq, |
178 | !list_empty(&xs_state.reply_list), | ||
179 | msecs_to_jiffies(500)); | ||
180 | else { | ||
181 | /* | ||
182 | * If we are in the process of being shut-down there is | ||
183 | * no point of trying to contact XenBus - it is either | ||
184 | * killed (xenstored application) or the other domain | ||
185 | * has been killed or is unreachable. | ||
186 | */ | ||
187 | return ERR_PTR(-EIO); | ||
188 | } | ||
154 | spin_lock(&xs_state.reply_lock); | 189 | spin_lock(&xs_state.reply_lock); |
155 | } | 190 | } |
156 | 191 | ||
@@ -215,6 +250,9 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg) | |||
215 | 250 | ||
216 | mutex_unlock(&xs_state.request_mutex); | 251 | mutex_unlock(&xs_state.request_mutex); |
217 | 252 | ||
253 | if (IS_ERR(ret)) | ||
254 | return ret; | ||
255 | |||
218 | if ((msg->type == XS_TRANSACTION_END) || | 256 | if ((msg->type == XS_TRANSACTION_END) || |
219 | ((req_msg.type == XS_TRANSACTION_START) && | 257 | ((req_msg.type == XS_TRANSACTION_START) && |
220 | (msg->type == XS_ERROR))) | 258 | (msg->type == XS_ERROR))) |