ia64/xen-unstable
changeset 5570:d7daa40eb8b0
bitkeeper revision 1.1748 (42bbc14djIjScNrLp20eDhlxUjQl4g)
xenstored_transaction.c, xenstored_core.h, xenstored_core.c, TODO:
Update TODO list
Wrap opendir in talloc so it gets cleaned up on OOM.
Remove last call to system by open-coding "cp -al" to create
transaction.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
xenstored_transaction.c, xenstored_core.h, xenstored_core.c, TODO:
Update TODO list
Wrap opendir in talloc so it gets cleaned up on OOM.
Remove last call to system by open-coding "cp -al" to create
transaction.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Fri Jun 24 08:16:13 2005 +0000 (2005-06-24) |
parents | 6cfdf7b8a9dc |
children | ef4c824e3720 b0b95421d32e |
files | tools/xenstore/TODO tools/xenstore/xenstored_core.c tools/xenstore/xenstored_core.h tools/xenstore/xenstored_transaction.c |
line diff
1.1 --- a/tools/xenstore/TODO Fri Jun 24 08:11:11 2005 +0000 1.2 +++ b/tools/xenstore/TODO Fri Jun 24 08:16:13 2005 +0000 1.3 @@ -4,4 +4,6 @@ reader to fill in the blanks. 1.4 1.5 - Remove calls to system() from daemon 1.6 - Timeout failed watch responses 1.7 -- Timeout blocking transactions 1.8 +- Dynamic nodes 1.9 +- Persistant storage of introductions, watches and transactions, so daemon can restart 1.10 +- Remove assumption that rename doesn't fail
2.1 --- a/tools/xenstore/xenstored_core.c Fri Jun 24 08:11:11 2005 +0000 2.2 +++ b/tools/xenstore/xenstored_core.c Fri Jun 24 08:16:13 2005 +0000 2.3 @@ -246,7 +246,7 @@ static int initialize_set(fd_set *inset, 2.4 } 2.5 2.6 /* Read everything from a talloc_open'ed fd. */ 2.7 -static void *read_all(int *fd, unsigned int *size) 2.8 +void *read_all(int *fd, unsigned int *size) 2.9 { 2.10 unsigned int max = 4; 2.11 int ret; 2.12 @@ -271,7 +271,7 @@ static int destroy_fd(void *_fd) 2.13 } 2.14 2.15 /* Return a pointer to an fd, self-closing and attached to this pathname. */ 2.16 -static int *talloc_open(const char *pathname, int flags, int mode) 2.17 +int *talloc_open(const char *pathname, int flags, int mode) 2.18 { 2.19 int *fd; 2.20 2.21 @@ -534,6 +534,30 @@ static char *tempfile(const char *path, 2.22 return tmppath; 2.23 } 2.24 2.25 +static int destroy_opendir(void *_dir) 2.26 +{ 2.27 + DIR **dir = _dir; 2.28 + closedir(*dir); 2.29 + return 0; 2.30 +} 2.31 + 2.32 +/* Return a pointer to a DIR*, self-closing and attached to this pathname. */ 2.33 +DIR **talloc_opendir(const char *pathname) 2.34 +{ 2.35 + DIR **dir; 2.36 + 2.37 + dir = talloc(pathname, DIR *); 2.38 + *dir = opendir(pathname); 2.39 + if (!*dir) { 2.40 + int saved_errno = errno; 2.41 + talloc_free(dir); 2.42 + errno = saved_errno; 2.43 + return NULL; 2.44 + } 2.45 + talloc_set_destructor(dir, destroy_opendir); 2.46 + return dir; 2.47 +} 2.48 + 2.49 /* We assume rename() doesn't fail on moves in same dir. */ 2.50 static void commit_tempfile(const char *path) 2.51 { 2.52 @@ -677,7 +701,7 @@ static bool send_directory(struct connec 2.53 { 2.54 char *path, *reply = talloc_strdup(node, ""); 2.55 unsigned int reply_len = 0; 2.56 - DIR *dir; 2.57 + DIR **dir; 2.58 struct dirent *dirent; 2.59 2.60 node = canonicalize(conn, node); 2.61 @@ -685,11 +709,11 @@ static bool send_directory(struct connec 2.62 return send_error(conn, errno); 2.63 2.64 path = node_dir(conn->transaction, node); 2.65 - dir = opendir(path); 2.66 + dir = talloc_opendir(path); 2.67 if (!dir) 2.68 return send_error(conn, errno); 2.69 2.70 - while ((dirent = readdir(dir)) != NULL) { 2.71 + while ((dirent = readdir(*dir)) != NULL) { 2.72 int len = strlen(dirent->d_name) + 1; 2.73 2.74 if (!valid_chars(dirent->d_name)) 2.75 @@ -699,7 +723,6 @@ static bool send_directory(struct connec 2.76 strcpy(reply + reply_len, dirent->d_name); 2.77 reply_len += len; 2.78 } 2.79 - closedir(dir); 2.80 2.81 return send_reply(conn, XS_DIRECTORY, reply, reply_len); 2.82 }
3.1 --- a/tools/xenstore/xenstored_core.h Fri Jun 24 08:11:11 2005 +0000 3.2 +++ b/tools/xenstore/xenstored_core.h Fri Jun 24 08:16:13 2005 +0000 3.3 @@ -20,6 +20,8 @@ 3.4 #ifndef _XENSTORED_CORE_H 3.5 #define _XENSTORED_CORE_H 3.6 3.7 +#include <sys/types.h> 3.8 +#include <dirent.h> 3.9 #include <stdbool.h> 3.10 #include <stdint.h> 3.11 #include <errno.h> 3.12 @@ -129,7 +131,16 @@ void handle_output(struct connection *co 3.13 /* Is this a valid node name? */ 3.14 bool is_valid_nodename(const char *node); 3.15 3.16 +/* Return a pointer to an open dir, self-closig and attached to pathname. */ 3.17 +DIR **talloc_opendir(const char *pathname); 3.18 + 3.19 +/* Return a pointer to an fd, self-closing and attached to this pathname. */ 3.20 +int *talloc_open(const char *pathname, int flags, int mode); 3.21 + 3.22 /* Convenient talloc-style destructor for paths. */ 3.23 int destroy_path(void *path); 3.24 3.25 +/* Read entire contents of a talloced fd. */ 3.26 +void *read_all(int *fd, unsigned int *size); 3.27 + 3.28 #endif /* _XENSTORED_CORE_H */
4.1 --- a/tools/xenstore/xenstored_transaction.c Fri Jun 24 08:11:11 2005 +0000 4.2 +++ b/tools/xenstore/xenstored_transaction.c Fri Jun 24 08:16:13 2005 +0000 4.3 @@ -25,6 +25,7 @@ 4.4 #include <time.h> 4.5 #include <stdarg.h> 4.6 #include <stdlib.h> 4.7 +#include <fcntl.h> 4.8 #include "talloc.h" 4.9 #include "list.h" 4.10 #include "xenstored_transaction.h" 4.11 @@ -137,7 +138,7 @@ void add_change_node(struct transaction 4.12 4.13 char *node_dir_inside_transaction(struct transaction *trans, const char *node) 4.14 { 4.15 - return talloc_asprintf(node, "%s%s", trans->divert, 4.16 + return talloc_asprintf(node, "%s/%s", trans->divert, 4.17 node + strlen(trans->node)); 4.18 } 4.19 4.20 @@ -170,21 +171,6 @@ void check_transaction_timeout(void) 4.21 } 4.22 } 4.23 4.24 -/* FIXME: Eliminate all uses of this */ 4.25 -static bool do_command(const char *cmd) 4.26 -{ 4.27 - int ret; 4.28 - 4.29 - ret = system(cmd); 4.30 - if (ret == -1) 4.31 - return false; 4.32 - if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { 4.33 - errno = EIO; 4.34 - return false; 4.35 - } 4.36 - return true; 4.37 -} 4.38 - 4.39 static int destroy_transaction(void *_transaction) 4.40 { 4.41 struct transaction *trans = _transaction; 4.42 @@ -193,10 +179,66 @@ static int destroy_transaction(void *_tr 4.43 return destroy_path(trans->divert); 4.44 } 4.45 4.46 +static bool copy_file(const char *src, const char *dst) 4.47 +{ 4.48 + int *infd, *outfd; 4.49 + void *data; 4.50 + unsigned int size; 4.51 + 4.52 + infd = talloc_open(src, O_RDONLY, 0); 4.53 + if (!infd) 4.54 + return false; 4.55 + outfd = talloc_open(dst, O_WRONLY|O_CREAT|O_EXCL, 0640); 4.56 + if (!outfd) 4.57 + return false; 4.58 + data = read_all(infd, &size); 4.59 + if (!data) 4.60 + return false; 4.61 + return xs_write_all(*outfd, data, size); 4.62 +} 4.63 + 4.64 +static bool copy_dir(const char *src, const char *dst) 4.65 +{ 4.66 + DIR **dir; 4.67 + struct dirent *dirent; 4.68 + 4.69 + if (mkdir(dst, 0750) != 0) 4.70 + return false; 4.71 + 4.72 + dir = talloc_opendir(src); 4.73 + if (!dir) 4.74 + return false; 4.75 + 4.76 + while ((dirent = readdir(*dir)) != NULL) { 4.77 + struct stat st; 4.78 + char *newsrc, *newdst; 4.79 + 4.80 + if (streq(dirent->d_name, ".") || streq(dirent->d_name, "..")) 4.81 + continue; 4.82 + 4.83 + newsrc = talloc_asprintf(src, "%s/%s", src, dirent->d_name); 4.84 + newdst = talloc_asprintf(src, "%s/%s", dst, dirent->d_name); 4.85 + if (stat(newsrc, &st) != 0) 4.86 + return false; 4.87 + 4.88 + if (S_ISDIR(st.st_mode)) { 4.89 + if (!copy_dir(newsrc, newdst)) 4.90 + return false; 4.91 + } else { 4.92 + if (!copy_file(newsrc, newdst)) 4.93 + return false; 4.94 + } 4.95 + /* Free now so we don't run out of file descriptors */ 4.96 + talloc_free(newsrc); 4.97 + talloc_free(newdst); 4.98 + } 4.99 + return true; 4.100 +} 4.101 + 4.102 bool do_transaction_start(struct connection *conn, const char *node) 4.103 { 4.104 struct transaction *transaction; 4.105 - char *dir, *cmd; 4.106 + char *dir; 4.107 4.108 if (conn->transaction) 4.109 return send_error(conn, EBUSY); 4.110 @@ -213,14 +255,9 @@ bool do_transaction_start(struct connect 4.111 /* Attach transaction to node for autofree until it's complete */ 4.112 transaction = talloc(node, struct transaction); 4.113 transaction->node = talloc_strdup(transaction, node); 4.114 - transaction->divert = talloc_asprintf(transaction, "%s/%p/", 4.115 + transaction->divert = talloc_asprintf(transaction, "%s/%p", 4.116 xs_daemon_transactions(), 4.117 transaction); 4.118 - cmd = talloc_asprintf(node, "cp -a %s %s", dir, transaction->divert); 4.119 - if (!do_command(cmd)) 4.120 - corrupt(conn, "Creating transaction %s", transaction->divert); 4.121 - 4.122 - talloc_steal(conn, transaction); 4.123 INIT_LIST_HEAD(&transaction->changes); 4.124 transaction->conn = conn; 4.125 timerclear(&transaction->timeout); 4.126 @@ -228,6 +265,11 @@ bool do_transaction_start(struct connect 4.127 list_add_tail(&transaction->list, &transactions); 4.128 conn->transaction = transaction; 4.129 talloc_set_destructor(transaction, destroy_transaction); 4.130 + 4.131 + if (!copy_dir(dir, transaction->divert)) 4.132 + return send_error(conn, errno); 4.133 + 4.134 + talloc_steal(conn, transaction); 4.135 return send_ack(transaction->conn, XS_TRANSACTION_START); 4.136 } 4.137