ia64/xen-unstable
changeset 5871:997b2b07b96d
Change from bool indicating blocked to an enum: when watches go
synchronous this makes it easier (because then we have two reasons
to block)
Instead of using return value, use explicit state member inside
struct connection.
Signed-off-by: Rusty Russel <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
synchronous this makes it easier (because then we have two reasons
to block)
Instead of using return value, use explicit state member inside
struct connection.
Signed-off-by: Rusty Russel <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Tue Jul 26 15:13:56 2005 +0000 (2005-07-26) |
parents | 99366b44c421 |
children | 4e833037159d |
files | tools/xenstore/xenstored_core.c tools/xenstore/xenstored_core.h tools/xenstore/xenstored_domain.c tools/xenstore/xenstored_domain.h tools/xenstore/xenstored_transaction.c tools/xenstore/xenstored_transaction.h tools/xenstore/xenstored_watch.c tools/xenstore/xenstored_watch.h |
line diff
1.1 --- a/tools/xenstore/xenstored_core.c Tue Jul 26 15:09:43 2005 +0000 1.2 +++ b/tools/xenstore/xenstored_core.c Tue Jul 26 15:13:56 2005 +0000 1.3 @@ -318,7 +318,7 @@ static int initialize_set(fd_set *inset, 1.4 list_for_each_entry(i, &connections, list) { 1.5 if (i->domain) 1.6 continue; 1.7 - if (!i->blocked) 1.8 + if (i->state == OK) 1.9 FD_SET(i->fd, inset); 1.10 if (i->out) 1.11 FD_SET(i->fd, outset); 1.12 @@ -454,8 +454,7 @@ unsigned int get_strings(struct buffered 1.13 return i; 1.14 } 1.15 1.16 -/* Returns "false", meaning "connection is not blocked". */ 1.17 -bool send_reply(struct connection *conn, enum xsd_sockmsg_type type, 1.18 +void send_reply(struct connection *conn, enum xsd_sockmsg_type type, 1.19 const void *data, unsigned int len) 1.20 { 1.21 struct buffered_data *bdata; 1.22 @@ -476,16 +475,15 @@ bool send_reply(struct connection *conn, 1.23 conn->waiting_reply = bdata; 1.24 } else 1.25 conn->out = bdata; 1.26 - return false; 1.27 } 1.28 1.29 /* Some routines (write, mkdir, etc) just need a non-error return */ 1.30 -bool send_ack(struct connection *conn, enum xsd_sockmsg_type type) 1.31 +void send_ack(struct connection *conn, enum xsd_sockmsg_type type) 1.32 { 1.33 - return send_reply(conn, type, "OK", sizeof("OK")); 1.34 + send_reply(conn, type, "OK", sizeof("OK")); 1.35 } 1.36 1.37 -bool send_error(struct connection *conn, int error) 1.38 +void send_error(struct connection *conn, int error) 1.39 { 1.40 unsigned int i; 1.41 1.42 @@ -494,7 +492,7 @@ bool send_error(struct connection *conn, 1.43 corrupt(conn, "Unknown error %i (%s)", error, 1.44 strerror(error)); 1.45 1.46 - return send_reply(conn, XS_ERROR, xsd_errors[i].errstring, 1.47 + send_reply(conn, XS_ERROR, xsd_errors[i].errstring, 1.48 strlen(xsd_errors[i].errstring) + 1); 1.49 } 1.50 1.51 @@ -780,7 +778,7 @@ bool check_node_perms(struct connection 1.52 return false; 1.53 } 1.54 1.55 -static bool send_directory(struct connection *conn, const char *node) 1.56 +static void send_directory(struct connection *conn, const char *node) 1.57 { 1.58 char *path, *reply = talloc_strdup(node, ""); 1.59 unsigned int reply_len = 0; 1.60 @@ -788,13 +786,17 @@ static bool send_directory(struct connec 1.61 struct dirent *dirent; 1.62 1.63 node = canonicalize(conn, node); 1.64 - if (!check_node_perms(conn, node, XS_PERM_READ)) 1.65 - return send_error(conn, errno); 1.66 + if (!check_node_perms(conn, node, XS_PERM_READ)) { 1.67 + send_error(conn, errno); 1.68 + return; 1.69 + } 1.70 1.71 path = node_dir(conn->transaction, node); 1.72 dir = talloc_opendir(path); 1.73 - if (!dir) 1.74 - return send_error(conn, errno); 1.75 + if (!dir) { 1.76 + send_error(conn, errno); 1.77 + return; 1.78 + } 1.79 1.80 while ((dirent = readdir(*dir)) != NULL) { 1.81 int len = strlen(dirent->d_name) + 1; 1.82 @@ -807,32 +809,35 @@ static bool send_directory(struct connec 1.83 reply_len += len; 1.84 } 1.85 1.86 - return send_reply(conn, XS_DIRECTORY, reply, reply_len); 1.87 + send_reply(conn, XS_DIRECTORY, reply, reply_len); 1.88 } 1.89 1.90 -static bool do_read(struct connection *conn, const char *node) 1.91 +static void do_read(struct connection *conn, const char *node) 1.92 { 1.93 char *value; 1.94 unsigned int size; 1.95 int *fd; 1.96 1.97 node = canonicalize(conn, node); 1.98 - if (!check_node_perms(conn, node, XS_PERM_READ)) 1.99 - return send_error(conn, errno); 1.100 + if (!check_node_perms(conn, node, XS_PERM_READ)) { 1.101 + send_error(conn, errno); 1.102 + return; 1.103 + } 1.104 1.105 fd = talloc_open(node_datafile(conn->transaction, node), O_RDONLY, 0); 1.106 if (!fd) { 1.107 /* Data file doesn't exist? We call that a directory */ 1.108 if (errno == ENOENT) 1.109 errno = EISDIR; 1.110 - return send_error(conn, errno); 1.111 + send_error(conn, errno); 1.112 + return; 1.113 } 1.114 1.115 value = read_all(fd, &size); 1.116 if (!value) 1.117 - return send_error(conn, errno); 1.118 - 1.119 - return send_reply(conn, XS_READ, value, size); 1.120 + send_error(conn, errno); 1.121 + else 1.122 + send_reply(conn, XS_READ, value, size); 1.123 } 1.124 1.125 /* Create a new directory. Optionally put data in it (if data != NULL) */ 1.126 @@ -876,7 +881,7 @@ static bool new_directory(struct connect 1.127 } 1.128 1.129 /* path, flags, data... */ 1.130 -static bool do_write(struct connection *conn, struct buffered_data *in) 1.131 +static void do_write(struct connection *conn, struct buffered_data *in) 1.132 { 1.133 unsigned int offset, datalen; 1.134 char *vec[2]; 1.135 @@ -885,16 +890,20 @@ static bool do_write(struct connection * 1.136 struct stat st; 1.137 1.138 /* Extra "strings" can be created by binary data. */ 1.139 - if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) 1.140 - return send_error(conn, EINVAL); 1.141 + if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) { 1.142 + send_error(conn, EINVAL); 1.143 + return; 1.144 + } 1.145 1.146 node = canonicalize(conn, vec[0]); 1.147 if (/*suppress error on write outside transaction*/ 0 && 1.148 - !within_transaction(conn->transaction, node)) 1.149 - return send_error(conn, EROFS); 1.150 + !within_transaction(conn->transaction, node)) { 1.151 + send_error(conn, EROFS); 1.152 + return; 1.153 + } 1.154 1.155 if (transaction_block(conn, node)) 1.156 - return true; 1.157 + return; 1.158 1.159 offset = strlen(vec[0]) + strlen(vec[1]) + 2; 1.160 datalen = in->used - offset; 1.161 @@ -905,32 +914,46 @@ static bool do_write(struct connection * 1.162 mode = XS_PERM_WRITE|XS_PERM_CREATE; 1.163 else if (streq(vec[1], XS_WRITE_CREATE_EXCL)) 1.164 mode = XS_PERM_WRITE|XS_PERM_CREATE; 1.165 - else 1.166 - return send_error(conn, EINVAL); 1.167 + else { 1.168 + send_error(conn, EINVAL); 1.169 + return; 1.170 + } 1.171 1.172 - if (!check_node_perms(conn, node, mode)) 1.173 - return send_error(conn, errno); 1.174 + if (!check_node_perms(conn, node, mode)) { 1.175 + send_error(conn, errno); 1.176 + return; 1.177 + } 1.178 1.179 if (lstat(node_dir(conn->transaction, node), &st) != 0) { 1.180 /* Does not exist... */ 1.181 - if (errno != ENOENT) 1.182 - return send_error(conn, errno); 1.183 + if (errno != ENOENT) { 1.184 + send_error(conn, errno); 1.185 + return; 1.186 + } 1.187 1.188 /* Not going to create it? */ 1.189 - if (!(mode & XS_PERM_CREATE)) 1.190 - return send_error(conn, ENOENT); 1.191 + if (!(mode & XS_PERM_CREATE)) { 1.192 + send_error(conn, ENOENT); 1.193 + return; 1.194 + } 1.195 1.196 - if (!new_directory(conn, node, in->buffer + offset, datalen)) 1.197 - return send_error(conn, errno); 1.198 + if (!new_directory(conn, node, in->buffer + offset, datalen)) { 1.199 + send_error(conn, errno); 1.200 + return; 1.201 + } 1.202 } else { 1.203 /* Exists... */ 1.204 - if (streq(vec[1], XS_WRITE_CREATE_EXCL)) 1.205 - return send_error(conn, EEXIST); 1.206 + if (streq(vec[1], XS_WRITE_CREATE_EXCL)) { 1.207 + send_error(conn, EEXIST); 1.208 + return; 1.209 + } 1.210 1.211 tmppath = tempfile(node_datafile(conn->transaction, node), 1.212 in->buffer + offset, datalen); 1.213 - if (!tmppath) 1.214 - return send_error(conn, errno); 1.215 + if (!tmppath) { 1.216 + send_error(conn, errno); 1.217 + return; 1.218 + } 1.219 1.220 commit_tempfile(tmppath); 1.221 } 1.222 @@ -938,163 +961,196 @@ static bool do_write(struct connection * 1.223 add_change_node(conn->transaction, node, false); 1.224 send_ack(conn, XS_WRITE); 1.225 fire_watches(conn->transaction, node, false); 1.226 - return false; 1.227 } 1.228 1.229 -static bool do_mkdir(struct connection *conn, const char *node) 1.230 +static void do_mkdir(struct connection *conn, const char *node) 1.231 { 1.232 node = canonicalize(conn, node); 1.233 - if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_CREATE)) 1.234 - return send_error(conn, errno); 1.235 + if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_CREATE)) { 1.236 + send_error(conn, errno); 1.237 + return; 1.238 + } 1.239 1.240 - if (!within_transaction(conn->transaction, node)) 1.241 - return send_error(conn, EROFS); 1.242 + if (!within_transaction(conn->transaction, node)) { 1.243 + send_error(conn, EROFS); 1.244 + return; 1.245 + } 1.246 1.247 if (transaction_block(conn, node)) 1.248 - return true; 1.249 + return; 1.250 1.251 - if (!new_directory(conn, node, NULL, 0)) 1.252 - return send_error(conn, errno); 1.253 + if (!new_directory(conn, node, NULL, 0)) { 1.254 + send_error(conn, errno); 1.255 + return; 1.256 + } 1.257 1.258 add_change_node(conn->transaction, node, false); 1.259 send_ack(conn, XS_MKDIR); 1.260 fire_watches(conn->transaction, node, false); 1.261 - return false; 1.262 } 1.263 1.264 -static bool do_rm(struct connection *conn, const char *node) 1.265 +static void do_rm(struct connection *conn, const char *node) 1.266 { 1.267 char *tmppath, *path; 1.268 1.269 node = canonicalize(conn, node); 1.270 - if (!check_node_perms(conn, node, XS_PERM_WRITE)) 1.271 - return send_error(conn, errno); 1.272 + if (!check_node_perms(conn, node, XS_PERM_WRITE)) { 1.273 + send_error(conn, errno); 1.274 + return; 1.275 + } 1.276 1.277 - if (!within_transaction(conn->transaction, node)) 1.278 - return send_error(conn, EROFS); 1.279 + if (!within_transaction(conn->transaction, node)) { 1.280 + send_error(conn, EROFS); 1.281 + return; 1.282 + } 1.283 1.284 if (transaction_block(conn, node)) 1.285 - return true; 1.286 + return; 1.287 1.288 - if (streq(node, "/")) 1.289 - return send_error(conn, EINVAL); 1.290 + if (streq(node, "/")) { 1.291 + send_error(conn, EINVAL); 1.292 + return; 1.293 + } 1.294 1.295 /* We move the directory to temporary name, destructor cleans up. */ 1.296 path = node_dir(conn->transaction, node); 1.297 tmppath = talloc_asprintf(node, "%s.tmp", path); 1.298 talloc_set_destructor(tmppath, destroy_path); 1.299 1.300 - if (rename(path, tmppath) != 0) 1.301 - return send_error(conn, errno); 1.302 + if (rename(path, tmppath) != 0) { 1.303 + send_error(conn, errno); 1.304 + return; 1.305 + } 1.306 1.307 add_change_node(conn->transaction, node, true); 1.308 send_ack(conn, XS_RM); 1.309 fire_watches(conn->transaction, node, true); 1.310 - return false; 1.311 } 1.312 1.313 -static bool do_get_perms(struct connection *conn, const char *node) 1.314 +static void do_get_perms(struct connection *conn, const char *node) 1.315 { 1.316 struct xs_permissions *perms; 1.317 char *strings; 1.318 unsigned int len, num; 1.319 1.320 node = canonicalize(conn, node); 1.321 - if (!check_node_perms(conn, node, XS_PERM_READ)) 1.322 - return send_error(conn, errno); 1.323 + if (!check_node_perms(conn, node, XS_PERM_READ)) { 1.324 + send_error(conn, errno); 1.325 + return; 1.326 + } 1.327 1.328 perms = get_perms(conn->transaction, node, &num); 1.329 - if (!perms) 1.330 - return send_error(conn, errno); 1.331 + if (!perms) { 1.332 + send_error(conn, errno); 1.333 + return; 1.334 + } 1.335 1.336 strings = perms_to_strings(node, perms, num, &len); 1.337 if (!strings) 1.338 - return send_error(conn, errno); 1.339 - 1.340 - return send_reply(conn, XS_GET_PERMS, strings, len); 1.341 + send_error(conn, errno); 1.342 + else 1.343 + send_reply(conn, XS_GET_PERMS, strings, len); 1.344 } 1.345 1.346 -static bool do_set_perms(struct connection *conn, struct buffered_data *in) 1.347 +static void do_set_perms(struct connection *conn, struct buffered_data *in) 1.348 { 1.349 unsigned int num; 1.350 char *node; 1.351 struct xs_permissions *perms; 1.352 1.353 num = xs_count_strings(in->buffer, in->used); 1.354 - if (num < 2) 1.355 - return send_error(conn, EINVAL); 1.356 + if (num < 2) { 1.357 + send_error(conn, EINVAL); 1.358 + return; 1.359 + } 1.360 1.361 /* First arg is node name. */ 1.362 node = canonicalize(conn, in->buffer); 1.363 in->buffer += strlen(in->buffer) + 1; 1.364 num--; 1.365 1.366 - if (!within_transaction(conn->transaction, node)) 1.367 - return send_error(conn, EROFS); 1.368 + if (!within_transaction(conn->transaction, node)) { 1.369 + send_error(conn, EROFS); 1.370 + return; 1.371 + } 1.372 1.373 if (transaction_block(conn, node)) 1.374 - return true; 1.375 + return; 1.376 1.377 /* We must own node to do this (tools can do this too). */ 1.378 - if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_OWNER)) 1.379 - return send_error(conn, errno); 1.380 + if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_OWNER)) { 1.381 + send_error(conn, errno); 1.382 + return; 1.383 + } 1.384 1.385 perms = talloc_array(node, struct xs_permissions, num); 1.386 - if (!xs_strings_to_perms(perms, num, in->buffer)) 1.387 - return send_error(conn, errno); 1.388 + if (!xs_strings_to_perms(perms, num, in->buffer)) { 1.389 + send_error(conn, errno); 1.390 + return; 1.391 + } 1.392 1.393 - if (!set_perms(conn->transaction, node, perms, num)) 1.394 - return send_error(conn, errno); 1.395 + if (!set_perms(conn->transaction, node, perms, num)) { 1.396 + send_error(conn, errno); 1.397 + return; 1.398 + } 1.399 + 1.400 add_change_node(conn->transaction, node, false); 1.401 send_ack(conn, XS_SET_PERMS); 1.402 fire_watches(conn->transaction, node, false); 1.403 - return false; 1.404 } 1.405 1.406 /* Process "in" for conn: "in" will vanish after this conversation, so 1.407 * we can talloc off it for temporary variables. May free "conn". 1.408 - * Returns true if can't complete due to block. 1.409 */ 1.410 -static bool process_message(struct connection *conn, struct buffered_data *in) 1.411 +static void process_message(struct connection *conn, struct buffered_data *in) 1.412 { 1.413 switch (in->hdr.msg.type) { 1.414 case XS_DIRECTORY: 1.415 - return send_directory(conn, onearg(in)); 1.416 + send_directory(conn, onearg(in)); 1.417 + break; 1.418 1.419 case XS_READ: 1.420 - return do_read(conn, onearg(in)); 1.421 + do_read(conn, onearg(in)); 1.422 + break; 1.423 1.424 case XS_WRITE: 1.425 - return do_write(conn, in); 1.426 + do_write(conn, in); 1.427 + break; 1.428 1.429 case XS_MKDIR: 1.430 - return do_mkdir(conn, onearg(in)); 1.431 + do_mkdir(conn, onearg(in)); 1.432 + break; 1.433 1.434 case XS_RM: 1.435 - return do_rm(conn, onearg(in)); 1.436 + do_rm(conn, onearg(in)); 1.437 + break; 1.438 1.439 case XS_GET_PERMS: 1.440 - return do_get_perms(conn, onearg(in)); 1.441 + do_get_perms(conn, onearg(in)); 1.442 + break; 1.443 1.444 case XS_SET_PERMS: 1.445 - return do_set_perms(conn, in); 1.446 + do_set_perms(conn, in); 1.447 + break; 1.448 1.449 case XS_SHUTDOWN: 1.450 /* FIXME: Implement gentle shutdown too. */ 1.451 /* Only tools can do this. */ 1.452 - if (conn->id != 0) 1.453 - return send_error(conn, EACCES); 1.454 - if (!conn->can_write) 1.455 - return send_error(conn, EROFS); 1.456 + if (conn->id != 0) { 1.457 + send_error(conn, EACCES); 1.458 + break; 1.459 + } 1.460 + if (!conn->can_write) { 1.461 + send_error(conn, EROFS); 1.462 + break; 1.463 + } 1.464 send_ack(conn, XS_SHUTDOWN); 1.465 /* Everything hangs off auto-free context, freed at exit. */ 1.466 exit(0); 1.467 1.468 case XS_DEBUG: 1.469 - if (streq(in->buffer, "print")) { 1.470 + if (streq(in->buffer, "print")) 1.471 xprintf("debug: %s", in->buffer + get_string(in, 0)); 1.472 - return false; 1.473 - } 1.474 #ifdef TESTING 1.475 /* For testing, we allow them to set id. */ 1.476 if (streq(in->buffer, "setid")) { 1.477 @@ -1107,37 +1163,44 @@ static bool process_message(struct conne 1.478 failtest = true; 1.479 } 1.480 #endif /* TESTING */ 1.481 - return false; 1.482 + break; 1.483 1.484 case XS_WATCH: 1.485 - return do_watch(conn, in); 1.486 + do_watch(conn, in); 1.487 + break; 1.488 1.489 case XS_WATCH_ACK: 1.490 - return do_watch_ack(conn, onearg(in)); 1.491 + do_watch_ack(conn, onearg(in)); 1.492 + break; 1.493 1.494 case XS_UNWATCH: 1.495 - return do_unwatch(conn, in); 1.496 + do_unwatch(conn, in); 1.497 + break; 1.498 1.499 case XS_TRANSACTION_START: 1.500 - return do_transaction_start(conn, onearg(in)); 1.501 + do_transaction_start(conn, onearg(in)); 1.502 + break; 1.503 1.504 case XS_TRANSACTION_END: 1.505 - return do_transaction_end(conn, onearg(in)); 1.506 + do_transaction_end(conn, onearg(in)); 1.507 + break; 1.508 1.509 case XS_INTRODUCE: 1.510 - return do_introduce(conn, in); 1.511 + do_introduce(conn, in); 1.512 + break; 1.513 1.514 case XS_RELEASE: 1.515 - return do_release(conn, onearg(in)); 1.516 + do_release(conn, onearg(in)); 1.517 + break; 1.518 1.519 case XS_GETDOMAINPATH: 1.520 - return do_get_domain_path(conn, onearg(in)); 1.521 + do_get_domain_path(conn, onearg(in)); 1.522 + break; 1.523 1.524 case XS_WATCH_EVENT: 1.525 default: 1.526 eprintf("Client unknown operation %i", in->hdr.msg.type); 1.527 send_error(conn, ENOSYS); 1.528 - return false; 1.529 } 1.530 } 1.531 1.532 @@ -1152,6 +1215,8 @@ static void consider_message(struct conn 1.533 enum xsd_sockmsg_type type = conn->in->hdr.msg.type; 1.534 jmp_buf talloc_fail; 1.535 1.536 + assert(conn->state == OK); 1.537 + 1.538 /* For simplicity, we kill the connection on OOM. */ 1.539 talloc_set_fail_handler(out_of_mem, &talloc_fail); 1.540 if (setjmp(talloc_fail)) { 1.541 @@ -1174,7 +1239,9 @@ static void consider_message(struct conn 1.542 */ 1.543 in = talloc_steal(talloc_autofree_context(), conn->in); 1.544 conn->in = new_buffer(conn); 1.545 - if (process_message(conn, in)) { 1.546 + process_message(conn, in); 1.547 + 1.548 + if (conn->state == BLOCKED) { 1.549 /* Blocked by transaction: queue for re-xmit. */ 1.550 talloc_free(conn->in); 1.551 conn->in = in; 1.552 @@ -1197,7 +1264,7 @@ void handle_input(struct connection *con 1.553 int bytes; 1.554 struct buffered_data *in; 1.555 1.556 - assert(!conn->blocked); 1.557 + assert(conn->state == OK); 1.558 in = conn->in; 1.559 1.560 /* Not finished header yet? */ 1.561 @@ -1254,12 +1321,13 @@ static void unblock_connections(void) 1.562 struct connection *i, *tmp; 1.563 1.564 list_for_each_entry_safe(i, tmp, &connections, list) { 1.565 - if (!i->blocked) 1.566 + if (i->state == OK) 1.567 continue; 1.568 1.569 - if (!transaction_covering_node(i->blocked)) { 1.570 - talloc_free(i->blocked); 1.571 - i->blocked = NULL; 1.572 + if (!transaction_covering_node(i->blocked_by)) { 1.573 + talloc_free(i->blocked_by); 1.574 + i->blocked_by = NULL; 1.575 + i->state = OK; 1.576 consider_message(i); 1.577 } 1.578 } 1.579 @@ -1281,7 +1349,8 @@ struct connection *new_connection(connwr 1.580 if (!new) 1.581 return NULL; 1.582 1.583 - new->blocked = false; 1.584 + new->state = OK; 1.585 + new->blocked_by = NULL; 1.586 new->out = new->waiting_reply = NULL; 1.587 new->fd = -1; 1.588 new->id = 0; 1.589 @@ -1358,10 +1427,14 @@ void dump_connection(void) 1.590 1.591 list_for_each_entry(i, &connections, list) { 1.592 printf("Connection %p:\n", i); 1.593 + printf(" state = %s\n", 1.594 + i->state == OK ? "OK" 1.595 + : i->state == BLOCKED ? "BLOCKED" 1.596 + : "INVALID"); 1.597 if (i->id) 1.598 printf(" id = %i\n", i->id); 1.599 - if (i->blocked) 1.600 - printf(" blocked on = %s\n", i->blocked); 1.601 + if (i->blocked_by) 1.602 + printf(" blocked on = %s\n", i->blocked_by); 1.603 if (i->waiting_for_ack) 1.604 printf(" waiting_for_ack TRUE\n"); 1.605 if (!i->in->inhdr || i->in->used) 1.606 @@ -1418,7 +1491,6 @@ static void setup_structure(void) 1.607 permfile = talloc_strdup(root, "/tool/xenstored"); 1.608 if (!set_perms(NULL, permfile, &perms, 1)) 1.609 barf_perror("Could not create permissions on %s", permfile); 1.610 - 1.611 talloc_free(root); 1.612 if (mkdir(xs_daemon_transactions(), 0750) != 0) 1.613 barf_perror("Could not create transaction dir %s",
2.1 --- a/tools/xenstore/xenstored_core.h Tue Jul 26 15:09:43 2005 +0000 2.2 +++ b/tools/xenstore/xenstored_core.h Tue Jul 26 15:13:56 2005 +0000 2.3 @@ -47,6 +47,14 @@ struct connection; 2.4 typedef int connwritefn_t(struct connection *, const void *, unsigned int); 2.5 typedef int connreadfn_t(struct connection *, void *, unsigned int); 2.6 2.7 +enum state 2.8 +{ 2.9 + /* Blocked by transaction. */ 2.10 + BLOCKED, 2.11 + /* Completed */ 2.12 + OK, 2.13 +}; 2.14 + 2.15 struct connection 2.16 { 2.17 struct list_head list; 2.18 @@ -57,8 +65,11 @@ struct connection 2.19 /* Who am I? 0 for socket connections. */ 2.20 domid_t id; 2.21 2.22 - /* Are we blocked waiting for a transaction to end? Contains node. */ 2.23 - char *blocked; 2.24 + /* Blocked on transaction? */ 2.25 + enum state state; 2.26 + 2.27 + /* Node we are waiting for (if state == BLOCKED) */ 2.28 + char *blocked_by; 2.29 2.30 /* Is this a read-only connection? */ 2.31 bool can_write; 2.32 @@ -100,14 +111,14 @@ bool is_child(const char *child, const c 2.33 /* Create a new buffer with lifetime of context. */ 2.34 struct buffered_data *new_buffer(void *ctx); 2.35 2.36 -bool send_reply(struct connection *conn, enum xsd_sockmsg_type type, 2.37 - const void *data, unsigned int len); 2.38 +void send_reply(struct connection *conn, enum xsd_sockmsg_type type, 2.39 + const void *data, unsigned int len); 2.40 2.41 /* Some routines (write, mkdir, etc) just need a non-error return */ 2.42 -bool send_ack(struct connection *conn, enum xsd_sockmsg_type type); 2.43 +void send_ack(struct connection *conn, enum xsd_sockmsg_type type); 2.44 2.45 /* Send an error: error is usually "errno". */ 2.46 -bool send_error(struct connection *conn, int error); 2.47 +void send_error(struct connection *conn, int error); 2.48 2.49 /* Canonicalize this path if possible. */ 2.50 char *canonicalize(struct connection *conn, const char *node);
3.1 --- a/tools/xenstore/xenstored_domain.c Tue Jul 26 15:09:43 2005 +0000 3.2 +++ b/tools/xenstore/xenstored_domain.c Tue Jul 26 15:13:56 2005 +0000 3.3 @@ -239,7 +239,8 @@ void handle_event(int event_fd) 3.4 * careful that handle_input/handle_output can destroy conn. 3.5 */ 3.6 while ((domain = find_domain(port)) != NULL) { 3.7 - if (!domain->conn->blocked && buffer_has_input(domain->input)) 3.8 + if (domain->conn->state == OK 3.9 + && buffer_has_input(domain->input)) 3.10 handle_input(domain->conn); 3.11 else if (domain->conn->out 3.12 && buffer_has_output_room(domain->output)) 3.13 @@ -287,33 +288,42 @@ static struct domain *new_domain(void *c 3.14 } 3.15 3.16 /* domid, mfn, evtchn, path */ 3.17 -bool do_introduce(struct connection *conn, struct buffered_data *in) 3.18 +void do_introduce(struct connection *conn, struct buffered_data *in) 3.19 { 3.20 struct domain *domain; 3.21 char *vec[4]; 3.22 3.23 - if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) 3.24 - return send_error(conn, EINVAL); 3.25 + if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) { 3.26 + send_error(conn, EINVAL); 3.27 + return; 3.28 + } 3.29 3.30 - if (conn->id != 0) 3.31 - return send_error(conn, EACCES); 3.32 + if (conn->id != 0) { 3.33 + send_error(conn, EACCES); 3.34 + return; 3.35 + } 3.36 3.37 - if (!conn->can_write) 3.38 - return send_error(conn, EROFS); 3.39 + if (!conn->can_write) { 3.40 + send_error(conn, EROFS); 3.41 + return; 3.42 + } 3.43 3.44 /* Sanity check args. */ 3.45 - if ((atoi(vec[2]) <= 0) || !is_valid_nodename(vec[3])) 3.46 - return send_error(conn, EINVAL); 3.47 + if ((atoi(vec[2]) <= 0) || !is_valid_nodename(vec[3])) { 3.48 + send_error(conn, EINVAL); 3.49 + return; 3.50 + } 3.51 /* Hang domain off "in" until we're finished. */ 3.52 domain = new_domain(in, atoi(vec[0]), atol(vec[1]), atol(vec[2]), 3.53 vec[3]); 3.54 - if (!domain) 3.55 - return send_error(conn, errno); 3.56 + if (!domain) { 3.57 + send_error(conn, errno); 3.58 + return; 3.59 + } 3.60 3.61 /* Now domain belongs to its connection. */ 3.62 talloc_steal(domain->conn, domain); 3.63 - 3.64 - return send_ack(conn, XS_INTRODUCE); 3.65 + send_ack(conn, XS_INTRODUCE); 3.66 } 3.67 3.68 static struct domain *find_domain_by_domid(domid_t domid) 3.69 @@ -328,39 +338,51 @@ static struct domain *find_domain_by_dom 3.70 } 3.71 3.72 /* domid */ 3.73 -bool do_release(struct connection *conn, const char *domid_str) 3.74 +void do_release(struct connection *conn, const char *domid_str) 3.75 { 3.76 struct domain *domain; 3.77 domid_t domid; 3.78 3.79 - if (!domid_str) 3.80 - return send_error(conn, EINVAL); 3.81 + if (!domid_str) { 3.82 + send_error(conn, EINVAL); 3.83 + return; 3.84 + } 3.85 3.86 domid = atoi(domid_str); 3.87 - if (!domid) 3.88 - return send_error(conn, EINVAL); 3.89 + if (!domid) { 3.90 + send_error(conn, EINVAL); 3.91 + return; 3.92 + } 3.93 3.94 - if (conn->id != 0) 3.95 - return send_error(conn, EACCES); 3.96 + if (conn->id != 0) { 3.97 + send_error(conn, EACCES); 3.98 + return; 3.99 + } 3.100 3.101 domain = find_domain_by_domid(domid); 3.102 - if (!domain) 3.103 - return send_error(conn, ENOENT); 3.104 + if (!domain) { 3.105 + send_error(conn, ENOENT); 3.106 + return; 3.107 + } 3.108 3.109 - if (!domain->conn) 3.110 - return send_error(conn, EINVAL); 3.111 + if (!domain->conn) { 3.112 + send_error(conn, EINVAL); 3.113 + return; 3.114 + } 3.115 3.116 talloc_free(domain->conn); 3.117 - return send_ack(conn, XS_RELEASE); 3.118 + send_ack(conn, XS_RELEASE); 3.119 } 3.120 3.121 -bool do_get_domain_path(struct connection *conn, const char *domid_str) 3.122 +void do_get_domain_path(struct connection *conn, const char *domid_str) 3.123 { 3.124 struct domain *domain; 3.125 domid_t domid; 3.126 3.127 - if (!domid_str) 3.128 - return send_error(conn, EINVAL); 3.129 + if (!domid_str) { 3.130 + send_error(conn, EINVAL); 3.131 + return; 3.132 + } 3.133 3.134 domid = atoi(domid_str); 3.135 if (domid == DOMID_SELF) 3.136 @@ -368,11 +390,11 @@ bool do_get_domain_path(struct connectio 3.137 else 3.138 domain = find_domain_by_domid(domid); 3.139 3.140 - if (!domain) 3.141 - return send_error(conn, ENOENT); 3.142 - 3.143 - return send_reply(conn, XS_GETDOMAINPATH, domain->path, 3.144 - strlen(domain->path) + 1); 3.145 + if (!domain) 3.146 + send_error(conn, ENOENT); 3.147 + else 3.148 + send_reply(conn, XS_GETDOMAINPATH, domain->path, 3.149 + strlen(domain->path) + 1); 3.150 } 3.151 3.152 static int close_xc_handle(void *_handle)
4.1 --- a/tools/xenstore/xenstored_domain.h Tue Jul 26 15:09:43 2005 +0000 4.2 +++ b/tools/xenstore/xenstored_domain.h Tue Jul 26 15:13:56 2005 +0000 4.3 @@ -23,13 +23,13 @@ 4.4 void handle_event(int event_fd); 4.5 4.6 /* domid, mfn, eventchn, path */ 4.7 -bool do_introduce(struct connection *conn, struct buffered_data *in); 4.8 +void do_introduce(struct connection *conn, struct buffered_data *in); 4.9 4.10 /* domid */ 4.11 -bool do_release(struct connection *conn, const char *domid_str); 4.12 +void do_release(struct connection *conn, const char *domid_str); 4.13 4.14 /* domid */ 4.15 -bool do_get_domain_path(struct connection *conn, const char *domid_str); 4.16 +void do_get_domain_path(struct connection *conn, const char *domid_str); 4.17 4.18 /* Returns the event channel handle */ 4.19 int domain_init(void);
5.1 --- a/tools/xenstore/xenstored_transaction.c Tue Jul 26 15:09:43 2005 +0000 5.2 +++ b/tools/xenstore/xenstored_transaction.c Tue Jul 26 15:13:56 2005 +0000 5.3 @@ -114,7 +114,8 @@ bool transaction_block(struct connection 5.4 trans = transaction_covering_node(node); 5.5 if (trans) { 5.6 start_transaction_timeout(trans); 5.7 - conn->blocked = talloc_strdup(conn, node); 5.8 + conn->state = BLOCKED; 5.9 + conn->blocked_by = talloc_strdup(conn, node); 5.10 return true; 5.11 } 5.12 return false; 5.13 @@ -239,20 +240,24 @@ static bool copy_dir(const char *src, co 5.14 return true; 5.15 } 5.16 5.17 -bool do_transaction_start(struct connection *conn, const char *node) 5.18 +void do_transaction_start(struct connection *conn, const char *node) 5.19 { 5.20 struct transaction *transaction; 5.21 char *dir; 5.22 5.23 - if (conn->transaction) 5.24 - return send_error(conn, EBUSY); 5.25 + if (conn->transaction) { 5.26 + send_error(conn, EBUSY); 5.27 + return; 5.28 + } 5.29 5.30 node = canonicalize(conn, node); 5.31 - if (!check_node_perms(conn, node, XS_PERM_READ)) 5.32 - return send_error(conn, errno); 5.33 + if (!check_node_perms(conn, node, XS_PERM_READ)) { 5.34 + send_error(conn, errno); 5.35 + return; 5.36 + } 5.37 5.38 if (transaction_block(conn, node)) 5.39 - return true; 5.40 + return; 5.41 5.42 dir = node_dir_outside_transaction(node); 5.43 5.44 @@ -270,12 +275,14 @@ bool do_transaction_start(struct connect 5.45 talloc_set_destructor(transaction, destroy_transaction); 5.46 trace_create(transaction, "transaction"); 5.47 5.48 - if (!copy_dir(dir, transaction->divert)) 5.49 - return send_error(conn, errno); 5.50 + if (!copy_dir(dir, transaction->divert)) { 5.51 + send_error(conn, errno); 5.52 + return; 5.53 + } 5.54 5.55 talloc_steal(conn, transaction); 5.56 conn->transaction = transaction; 5.57 - return send_ack(transaction->conn, XS_TRANSACTION_START); 5.58 + send_ack(transaction->conn, XS_TRANSACTION_START); 5.59 } 5.60 5.61 static bool commit_transaction(struct transaction *trans) 5.62 @@ -301,13 +308,17 @@ static bool commit_transaction(struct tr 5.63 return true; 5.64 } 5.65 5.66 -bool do_transaction_end(struct connection *conn, const char *arg) 5.67 +void do_transaction_end(struct connection *conn, const char *arg) 5.68 { 5.69 - if (!arg || (!streq(arg, "T") && !streq(arg, "F"))) 5.70 - return send_error(conn, EINVAL); 5.71 + if (!arg || (!streq(arg, "T") && !streq(arg, "F"))) { 5.72 + send_error(conn, EINVAL); 5.73 + return; 5.74 + } 5.75 5.76 - if (!conn->transaction) 5.77 - return send_error(conn, ENOENT); 5.78 + if (!conn->transaction) { 5.79 + send_error(conn, ENOENT); 5.80 + return; 5.81 + } 5.82 5.83 if (streq(arg, "T")) { 5.84 if (conn->transaction->destined_to_fail) { 5.85 @@ -322,11 +333,11 @@ bool do_transaction_end(struct connectio 5.86 5.87 talloc_free(conn->transaction); 5.88 conn->transaction = NULL; 5.89 - return send_ack(conn, XS_TRANSACTION_END); 5.90 + send_ack(conn, XS_TRANSACTION_END); 5.91 + return; 5.92 5.93 failed: 5.94 talloc_free(conn->transaction); 5.95 conn->transaction = NULL; 5.96 - return false; 5.97 } 5.98
6.1 --- a/tools/xenstore/xenstored_transaction.h Tue Jul 26 15:09:43 2005 +0000 6.2 +++ b/tools/xenstore/xenstored_transaction.h Tue Jul 26 15:13:56 2005 +0000 6.3 @@ -22,8 +22,8 @@ 6.4 6.5 struct transaction; 6.6 6.7 -bool do_transaction_start(struct connection *conn, const char *node); 6.8 -bool do_transaction_end(struct connection *conn, const char *arg); 6.9 +void do_transaction_start(struct connection *conn, const char *node); 6.10 +void do_transaction_end(struct connection *conn, const char *arg); 6.11 6.12 /* Is node covered by this transaction? */ 6.13 bool within_transaction(struct transaction *trans, const char *node);
7.1 --- a/tools/xenstore/xenstored_watch.c Tue Jul 26 15:09:43 2005 +0000 7.2 +++ b/tools/xenstore/xenstored_watch.c Tue Jul 26 15:13:56 2005 +0000 7.3 @@ -310,19 +310,23 @@ void check_watch_ack_timeout(void) 7.4 } 7.5 } 7.6 7.7 -bool do_watch(struct connection *conn, struct buffered_data *in) 7.8 +void do_watch(struct connection *conn, struct buffered_data *in) 7.9 { 7.10 struct watch *watch; 7.11 char *vec[3]; 7.12 bool relative; 7.13 7.14 - if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) 7.15 - return send_error(conn, EINVAL); 7.16 + if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) { 7.17 + send_error(conn, EINVAL); 7.18 + return; 7.19 + } 7.20 7.21 relative = !strstarts(vec[0], "/"); 7.22 vec[0] = canonicalize(conn, vec[0]); 7.23 - if (!check_node_perms(conn, vec[0], XS_PERM_READ)) 7.24 - return send_error(conn, errno); 7.25 + if (!check_node_perms(conn, vec[0], XS_PERM_READ)) { 7.26 + send_error(conn, errno); 7.27 + return; 7.28 + } 7.29 7.30 watch = talloc(conn, struct watch); 7.31 watch->node = talloc_strdup(watch, vec[0]); 7.32 @@ -335,18 +339,22 @@ bool do_watch(struct connection *conn, s 7.33 insert_watch(watch); 7.34 talloc_set_destructor(watch, destroy_watch); 7.35 trace_create(watch, "watch"); 7.36 - return send_ack(conn, XS_WATCH); 7.37 + send_ack(conn, XS_WATCH); 7.38 } 7.39 7.40 -bool do_watch_ack(struct connection *conn, const char *token) 7.41 +void do_watch_ack(struct connection *conn, const char *token) 7.42 { 7.43 struct watch_event *event; 7.44 7.45 - if (!token) 7.46 - return send_error(conn, EINVAL); 7.47 + if (!token) { 7.48 + send_error(conn, EINVAL); 7.49 + return; 7.50 + } 7.51 7.52 - if (!conn->waiting_for_ack) 7.53 - return send_error(conn, ENOENT); 7.54 + if (!conn->waiting_for_ack) { 7.55 + send_error(conn, ENOENT); 7.56 + return; 7.57 + } 7.58 7.59 event = list_top(&conn->waiting_for_ack->events, 7.60 struct watch_event, list); 7.61 @@ -354,21 +362,24 @@ bool do_watch_ack(struct connection *con 7.62 if (!streq(conn->waiting_for_ack->token, token)) { 7.63 /* They're confused: this will cause us to send event again */ 7.64 conn->waiting_for_ack = NULL; 7.65 - return send_error(conn, EINVAL); 7.66 + send_error(conn, EINVAL); 7.67 + return; 7.68 } 7.69 7.70 move_event_onwards(event); 7.71 conn->waiting_for_ack = NULL; 7.72 - return send_ack(conn, XS_WATCH_ACK); 7.73 + send_ack(conn, XS_WATCH_ACK); 7.74 } 7.75 7.76 -bool do_unwatch(struct connection *conn, struct buffered_data *in) 7.77 +void do_unwatch(struct connection *conn, struct buffered_data *in) 7.78 { 7.79 struct watch *watch; 7.80 char *node, *vec[2]; 7.81 7.82 - if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) 7.83 - return send_error(conn, EINVAL); 7.84 + if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) { 7.85 + send_error(conn, EINVAL); 7.86 + return; 7.87 + } 7.88 7.89 /* We don't need to worry if we're waiting for an ack for the 7.90 * watch we're deleting: conn->waiting_for_ack was reset by 7.91 @@ -380,10 +391,11 @@ bool do_unwatch(struct connection *conn, 7.92 7.93 if (streq(watch->node, node) && streq(watch->token, vec[1])) { 7.94 talloc_free(watch); 7.95 - return send_ack(conn, XS_UNWATCH); 7.96 + send_ack(conn, XS_UNWATCH); 7.97 + return; 7.98 } 7.99 } 7.100 - return send_error(conn, ENOENT); 7.101 + send_error(conn, ENOENT); 7.102 } 7.103 7.104 #ifdef TESTING
8.1 --- a/tools/xenstore/xenstored_watch.h Tue Jul 26 15:09:43 2005 +0000 8.2 +++ b/tools/xenstore/xenstored_watch.h Tue Jul 26 15:13:56 2005 +0000 8.3 @@ -22,9 +22,9 @@ 8.4 8.5 #include "xenstored_core.h" 8.6 8.7 -bool do_watch(struct connection *conn, struct buffered_data *in); 8.8 -bool do_watch_ack(struct connection *conn, const char *token); 8.9 -bool do_unwatch(struct connection *conn, struct buffered_data *in); 8.10 +void do_watch(struct connection *conn, struct buffered_data *in); 8.11 +void do_watch_ack(struct connection *conn, const char *token); 8.12 +void do_unwatch(struct connection *conn, struct buffered_data *in); 8.13 8.14 /* Is this a watch event message for this connection? */ 8.15 bool is_watch_event(struct connection *conn, struct buffered_data *out);