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>
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