Allow multiple atomic transactions to be used with one root object.
authorJ. Ali Harlow <ali@juiblex.co.uk>
Thu Feb 16 17:33:47 2012 +0000 (2012-02-16)
changeset 4248cbc438cc298
parent 423 6112bcc5d1cf
child 425 0c8bdd8dc942
Allow multiple atomic transactions to be used with one root object.
This allows transactions that include barriers to be performed
while holding an exclusive system lock.
configure.ac
librazor/Makefile.am
librazor/atomic-ktm.c
librazor/error.c
librazor/razor-internal.h
librazor/razor.c
librazor/razor.h
librazor/root.c
librazor/rpm.c
librazor/test-lua.c
librazor/util.c
src/main.c
src/rpm.c
     1.1 --- a/configure.ac	Sat Feb 11 23:50:26 2012 +0000
     1.2 +++ b/configure.ac	Thu Feb 16 17:33:47 2012 +0000
     1.3 @@ -12,7 +12,7 @@
     1.4  #
     1.5  LT_CURRENT=4
     1.6  LT_REVISION=0
     1.7 -LT_AGE=2
     1.8 +LT_AGE=0
     1.9  AC_SUBST(LT_CURRENT)
    1.10  AC_SUBST(LT_REVISION)
    1.11  AC_SUBST(LT_AGE)
     2.1 --- a/librazor/Makefile.am	Sat Feb 11 23:50:26 2012 +0000
     2.2 +++ b/librazor/Makefile.am	Thu Feb 16 17:33:47 2012 +0000
     2.3 @@ -52,7 +52,7 @@
     2.4  
     2.5  if HAVE_LUA
     2.6    test_lua_SOURCES = test-lua.c
     2.7 -  test_lua_LDADD = lua.lo util.lo types/libtypes.la $(LUA_LIBS) \
     2.8 +  test_lua_LDADD = lua.lo util.lo error.lo types/libtypes.la $(LUA_LIBS) \
     2.9  	../gl/libgnu.la $(INTLLIBS) $(EXTRA_LIBS)
    2.10  
    2.11    TESTS = test-lua
     3.1 --- a/librazor/atomic-ktm.c	Sat Feb 11 23:50:26 2012 +0000
     3.2 +++ b/librazor/atomic-ktm.c	Thu Feb 16 17:33:47 2012 +0000
     3.3 @@ -142,7 +142,7 @@
     3.4  	retval = !CommitTransaction(atomic->transaction);
     3.5  
     3.6  	if (retval) {
     3.7 -		atomic->error = razor_error_new_mswin(NULL, GetLastError());
     3.8 +		razor_set_error_mswin(&atomic->error, NULL, GetLastError());
     3.9  		RollbackTransaction(atomic->transaction);
    3.10  	}
    3.11  
    3.12 @@ -210,15 +210,15 @@
    3.13  				if (err == ERROR_FILE_NOT_FOUND) {
    3.14  					creating = 1;
    3.15  				} else {
    3.16 -					atomic->error = razor_error_new_mswin(buffer->str,
    3.17 -									      err);
    3.18 +					razor_set_error_mswin(&atomic->error,
    3.19 +							      buffer->str, err);
    3.20  					razor_wstr_destroy(buffer);
    3.21  					return -1;
    3.22  				}
    3.23  			} else if (!(fa.dwFileAttributes&
    3.24  				     FILE_ATTRIBUTE_DIRECTORY)) {
    3.25 -				atomic->error = razor_error_new_str(buffer->str,
    3.26 -								    "Not a directory");
    3.27 +				razor_set_error2(&atomic->error, buffer->str,
    3.28 +						 "Not a directory");
    3.29  				razor_wstr_destroy(buffer);
    3.30  				return -1;
    3.31  			}
    3.32 @@ -226,8 +226,9 @@
    3.33  		if (creating) {
    3.34  			if (!CreateDirectoryTransactedW(NULL, buffer->str, NULL,
    3.35  							atomic->transaction)) {
    3.36 -				atomic->error = razor_error_new_mswin(buffer->str,
    3.37 -								      GetLastError());
    3.38 +				razor_set_error_mswin(&atomic->error,
    3.39 +						      buffer->str,
    3.40 +						      GetLastError());
    3.41  				razor_wstr_destroy(buffer);
    3.42  				return -1;
    3.43  			}
    3.44 @@ -287,7 +288,7 @@
    3.45  	 * same path, this is likely to cause more problems than it solves.
    3.46  	 */
    3.47  
    3.48 -	atomic->error = razor_error_new_mswin(buf, err);
    3.49 +	razor_set_error_mswin(&atomic->error, buf, err);
    3.50  	free(buf);
    3.51  	return -1;
    3.52  }
    3.53 @@ -315,7 +316,7 @@
    3.54  
    3.55  	if (!MoveFileTransactedW(oldbuf, newbuf, NULL, NULL, flags,
    3.56  			         atomic->transaction))
    3.57 -		atomic->error = razor_error_new_mswin(newbuf, GetLastError());
    3.58 +		razor_set_error_mswin(&atomic->error, newbuf, GetLastError());
    3.59  
    3.60  	free(newbuf);
    3.61  	free(oldbuf);
    3.62 @@ -340,7 +341,7 @@
    3.63  		err = GetLastError();
    3.64  		if (err != ERROR_FILE_EXISTS && err != ERROR_ALREADY_EXISTS) {
    3.65  abort:
    3.66 -			atomic->error = razor_error_new_mswin(buf, err);
    3.67 +			razor_set_error_mswin(&atomic->error, buf, err);
    3.68  			free(buf);
    3.69  			return -1;
    3.70  		}
    3.71 @@ -380,9 +381,8 @@
    3.72  	 * and we don't always know that at the time when the
    3.73  	 * link is created, so it's a convienent lie for now.
    3.74  	 */
    3.75 -	atomic->error = razor_error_new_str(NULL,
    3.76 -					    "Symbolic links not supported "
    3.77 -					    "on this platform");
    3.78 +	razor_set_error(&atomic->error, NULL,
    3.79 +			"Symbolic links not supported on this platform");
    3.80  
    3.81  	return -1;
    3.82  }
    3.83 @@ -401,7 +401,7 @@
    3.84  	files = realloc(atomic->files,
    3.85  			(atomic->n_files+1) * sizeof(struct razor_atomic_file));
    3.86  	if (!files) {
    3.87 -		atomic->error = razor_error_new_str(NULL, "Not enough memory");
    3.88 +		razor_set_error(&atomic->error, NULL, "Not enough memory");
    3.89  		return -1;
    3.90  	}
    3.91  	atomic->n_files++;
    3.92 @@ -428,8 +428,8 @@
    3.93  					   NULL);
    3.94  
    3.95  	if (files[i].h == INVALID_HANDLE_VALUE) {
    3.96 -		atomic->error = razor_error_new_mswin(files[i].path,
    3.97 -						      GetLastError());
    3.98 +		razor_set_error_mswin(&atomic->error, files[i].path,
    3.99 +				      GetLastError());
   3.100  		free(files[i].path);
   3.101  		atomic->n_files--;
   3.102  		return -1;
   3.103 @@ -453,8 +453,9 @@
   3.104  	while(size) {
   3.105  		if (!WriteFile(atomic->files[handle].h, data, size, &written,
   3.106  			       NULL)) {
   3.107 -			atomic->error = razor_error_new_mswin(atomic->files[handle].path,
   3.108 -							      GetLastError());
   3.109 +			razor_set_error_mswin(&atomic->error,
   3.110 +					      atomic->files[handle].path,
   3.111 +					      GetLastError());
   3.112  
   3.113  			(void)CloseHandle(atomic->files[handle].h);
   3.114  			free(atomic->files[handle].path);
   3.115 @@ -483,8 +484,9 @@
   3.116  	assert(atomic->files[handle].h != INVALID_HANDLE_VALUE);
   3.117  
   3.118  	if (!CloseHandle(atomic->files[handle].h)) {
   3.119 -		atomic->error = razor_error_new_mswin(atomic->files[handle].path,
   3.120 -						      GetLastError());
   3.121 +		razor_set_error_mswin(&atomic->error,
   3.122 +				      atomic->files[handle].path,
   3.123 +				      GetLastError());
   3.124  		free(atomic->files[handle].path);
   3.125  		atomic->files[handle].path = NULL;
   3.126  		atomic->files[handle].h = INVALID_HANDLE_VALUE;
   3.127 @@ -497,8 +499,9 @@
   3.128  	atomic->files[handle].h = h;
   3.129  
   3.130  	if (atomic->files[handle].h == INVALID_HANDLE_VALUE) {
   3.131 -		atomic->error = razor_error_new_mswin(atomic->files[handle].path,
   3.132 -						      GetLastError());
   3.133 +		razor_set_error_mswin(&atomic->error,
   3.134 +				      atomic->files[handle].path,
   3.135 +				      GetLastError());
   3.136  		free(atomic->files[handle].path);
   3.137  		atomic->files[handle].path = NULL;
   3.138  		return -1;
   3.139 @@ -517,8 +520,9 @@
   3.140  	assert(atomic->files[handle].h != INVALID_HANDLE_VALUE);
   3.141  
   3.142  	if (!CloseHandle(atomic->files[handle].h))
   3.143 -		atomic->error = razor_error_new_mswin(atomic->files[handle].path,
   3.144 -						      GetLastError());
   3.145 +		razor_set_error_mswin(&atomic->error,
   3.146 +				      atomic->files[handle].path,
   3.147 +				      GetLastError());
   3.148  
   3.149  	free(atomic->files[handle].path);
   3.150  	atomic->files[handle].path = NULL;
     4.1 --- a/librazor/error.c	Sat Feb 11 23:50:26 2012 +0000
     4.2 +++ b/librazor/error.c	Thu Feb 16 17:33:47 2012 +0000
     4.3 @@ -62,37 +62,43 @@
     4.4  
     4.5  	return error;
     4.6  }
     4.7 -#endif
     4.8  
     4.9 -#if HAVE_WINDOWS_KTM
    4.10  struct razor_error *
    4.11 -razor_error_new_str(const wchar_t *path, const char *str)
    4.12 -#else
    4.13 -struct razor_error *
    4.14 -razor_error_new_str(const char *path, const char *str)
    4.15 -#endif
    4.16 +razor_error_new_str2(const wchar_t *path, const char *str)
    4.17  {
    4.18  	struct razor_error *error;
    4.19  
    4.20  	error = zalloc(sizeof *error);
    4.21  
    4.22 -#if HAVE_WINDOWS_KTM
    4.23  	if (path)
    4.24  		error->path = razor_utf16_to_utf8(path, -1);
    4.25 -#else
    4.26 +
    4.27 +	error->str = strdup(str);
    4.28 +
    4.29 +	return error;
    4.30 +}
    4.31 +#endif	/* MSWIN_API */
    4.32 +
    4.33 +RAZOR_EXPORT struct razor_error *
    4.34 +razor_error_new_str(const char *path, const char *str)
    4.35 +{
    4.36 +	struct razor_error *error;
    4.37 +
    4.38 +	error = zalloc(sizeof *error);
    4.39 +
    4.40  	if (path)
    4.41  		error->path = strdup(path);
    4.42 -#endif
    4.43  
    4.44  	error->str = strdup(str);
    4.45  
    4.46  	return error;
    4.47  }
    4.48  
    4.49 -void razor_error_free(struct razor_error *error)
    4.50 +RAZOR_EXPORT void
    4.51 +razor_error_free(struct razor_error *error)
    4.52  {
    4.53 -    free(error->path);
    4.54 -    free(error->str);
    4.55 -    free(error->msg);
    4.56 -    free(error);
    4.57 +	free(error->path);
    4.58 +	free(error->str);
    4.59 +	free(error->msg);
    4.60 +	free(error);
    4.61  }
     5.1 --- a/librazor/razor-internal.h	Sat Feb 11 23:50:26 2012 +0000
     5.2 +++ b/librazor/razor-internal.h	Thu Feb 16 17:33:47 2012 +0000
     5.3 @@ -123,6 +123,7 @@
     5.4  	struct array details_string_pool;
     5.5  	struct razor_mapped_file *mapped_files;
     5.6  	int lock_fd, ref_count;
     5.7 +	enum razor_set_flags flags;
     5.8  };
     5.9  
    5.10  struct import_entry {
    5.11 @@ -214,7 +215,9 @@
    5.12  int razor_remove(const char *path);
    5.13  int razor_write(int fd, const void *data, size_t size);
    5.14  
    5.15 -void *razor_file_get_contents(const char *filename, size_t *length);
    5.16 +void *
    5.17 +razor_file_get_contents(const char *filename, size_t *length, int private,
    5.18 +			struct razor_error **error);
    5.19  int razor_file_free_contents(void *addr, size_t length);
    5.20  
    5.21  
    5.22 @@ -251,13 +254,17 @@
    5.23  
    5.24  #ifdef MSWIN_API
    5.25  struct razor_error *razor_error_new_mswin(const wchar_t *path, DWORD error);
    5.26 -#endif
    5.27 +struct razor_error *razor_error_new_str2(const wchar_t *path, const char *str);
    5.28  
    5.29 -#if HAVE_WINDOWS_KTM
    5.30 -struct razor_error *razor_error_new_str(const wchar_t *path, const char *str);
    5.31 -#else
    5.32 -struct razor_error *razor_error_new_str(const char *path, const char *str);
    5.33 -#endif
    5.34 +#define razor_set_error_mswin(error, path, err) \
    5.35 +	if (error) \
    5.36 +		*(error) = razor_error_new_mswin(path, err); \
    5.37 +	else
    5.38 +#define razor_set_error2(error, path, str) \
    5.39 +	if (error) \
    5.40 +		*(error) = razor_error_new_str2(path, str); \
    5.41 +	else
    5.42 +#endif	/* MSWIN_API */
    5.43  
    5.44  /* Atomic functions */
    5.45  
     6.1 --- a/librazor/razor.c	Sat Feb 11 23:50:26 2012 +0000
     6.2 +++ b/librazor/razor.c	Thu Feb 16 17:33:47 2012 +0000
     6.3 @@ -48,17 +48,6 @@
     6.4  #define O_BINARY	0
     6.5  #endif
     6.6  
     6.7 -void *
     6.8 -zalloc(size_t size)
     6.9 -{
    6.10 -	void *p;
    6.11 -
    6.12 -	p = malloc(size);
    6.13 -	memset(p, 0, size);
    6.14 -
    6.15 -	return p;
    6.16 -}
    6.17 -
    6.18  struct razor_set_section_index {
    6.19  	const char *name;
    6.20  	uint32_t offset;
    6.21 @@ -102,6 +91,8 @@
    6.22  		set->ref_count = 1;
    6.23  
    6.24  		set->header_version = RAZOR_HEADER_VERSION;
    6.25 +
    6.26 +		set->flags = RAZOR_SET_PRIVATE;
    6.27  	}
    6.28  
    6.29  	return set;
    6.30 @@ -149,27 +140,25 @@
    6.31  };
    6.32  
    6.33  RAZOR_EXPORT int
    6.34 -razor_set_bind_sections(struct razor_set *set, struct razor_atomic *atomic,
    6.35 -			const char *filename)
    6.36 +razor_set_bind_sections(struct razor_set *set, const char *filename,
    6.37 +			enum razor_set_flags flags, struct razor_error **error)
    6.38  {
    6.39  	struct razor_set_section *s, *sections;
    6.40  	struct razor_mapped_file *file;
    6.41  	const char *pool, *reason;
    6.42 -	char *msg;
    6.43  	struct array *array;
    6.44  	int i, j;
    6.45  
    6.46  	file = zalloc(sizeof *file);
    6.47  	if (file == NULL) {
    6.48 -		razor_atomic_abort(atomic, "Not enough memory");
    6.49 +		razor_set_error(error, NULL, "Not enough memory");
    6.50  		return -1;
    6.51  	}
    6.52  
    6.53 -	file->header = razor_file_get_contents(filename, &file->size);
    6.54 +	file->header = razor_file_get_contents(filename, &file->size,
    6.55 +					       flags & RAZOR_SET_PRIVATE,
    6.56 +					       error);
    6.57  	if (!file->header) {
    6.58 -		msg = razor_concat(filename, ": ", strerror(errno), NULL);
    6.59 -		razor_atomic_abort(atomic, msg);
    6.60 -		free(msg);
    6.61  		free(file);
    6.62  		return -1;
    6.63  	}
    6.64 @@ -185,14 +174,14 @@
    6.65  		reason = NULL;
    6.66  
    6.67  	if (reason) {
    6.68 -		msg = razor_concat(filename, ": ", reason, NULL);
    6.69 -		razor_atomic_abort(atomic, msg);
    6.70 -		free(msg);
    6.71 +		razor_set_error(error, filename, reason);
    6.72  		razor_file_free_contents(file->header, file->size);
    6.73  		free(file);
    6.74  		return -1;
    6.75  	}
    6.76  
    6.77 +	set->flags = flags & RAZOR_SET_PRIVATE;
    6.78 +
    6.79  	set->header_version = file->header->version;
    6.80  
    6.81  	if (set->mapped_files == NULL) {
    6.82 @@ -226,19 +215,20 @@
    6.83  }
    6.84  
    6.85  RAZOR_EXPORT struct razor_set *
    6.86 -razor_set_open(const char *filename, struct razor_atomic *atomic)
    6.87 +razor_set_open(const char *filename, enum razor_set_flags flags,
    6.88 +	       struct razor_error **error)
    6.89  {
    6.90  	struct razor_set *set;
    6.91  
    6.92  	set = zalloc(sizeof *set);
    6.93  	if (!set) {
    6.94 -		razor_atomic_abort(atomic, "Not enough memory");
    6.95 +		razor_set_error(error, NULL, "Not enough memory");
    6.96  		return NULL;
    6.97  	}
    6.98  
    6.99  	set->lock_fd = -1;
   6.100  	set->ref_count = 1;
   6.101 -	if (razor_set_bind_sections(set, atomic, filename)) {
   6.102 +	if (razor_set_bind_sections(set, filename, flags, error)) {
   6.103  		free(set);
   6.104  		return NULL;
   6.105  	}
     7.1 --- a/librazor/razor.h	Sat Feb 11 23:50:26 2012 +0000
     7.2 +++ b/librazor/razor.h	Thu Feb 16 17:33:47 2012 +0000
     7.3 @@ -95,6 +95,16 @@
     7.4  		RAZOR_PROPERTY_POSTUN
     7.5  };
     7.6  
     7.7 +enum razor_set_flags {
     7.8 +	/*
     7.9 +	 * Create a private copy of the razor set such that changes made
    7.10 +	 * to the underlying file are not visible in the razor set.
    7.11 +	 * If this flag is not set then the caller must ensure that the
    7.12 +	 * underlying file (if any) is not changed.
    7.13 +	 */
    7.14 +	RAZOR_SET_PRIVATE		= 1 << 0,
    7.15 +};
    7.16 +
    7.17  /**
    7.18   * SECTION:error
    7.19   * @title: Error reporting
    7.20 @@ -104,6 +114,13 @@
    7.21   */
    7.22  struct razor_error;
    7.23  
    7.24 +struct razor_error *razor_error_new_str(const char *path, const char *str);
    7.25 +
    7.26 +#define razor_set_error(error, path, str) \
    7.27 +	if (error) \
    7.28 +		*(error) = razor_error_new_str(path, str); \
    7.29 +	else
    7.30 +
    7.31  const char *razor_error_get_msg(struct razor_error *error);
    7.32  void razor_error_free(struct razor_error *error);
    7.33  
    7.34 @@ -216,8 +233,9 @@
    7.35   **/
    7.36  struct razor_set *razor_set_create_without_root(void);
    7.37  struct razor_set *razor_set_create(void);
    7.38 -struct razor_set *razor_set_open(const char *filename,
    7.39 -				 struct razor_atomic *atomic);
    7.40 +struct razor_set *
    7.41 +razor_set_open(const char *filename, enum razor_set_flags flags,
    7.42 +	       struct razor_error **error);
    7.43  uint32_t razor_set_get_header_version(struct razor_set *set);
    7.44  int razor_set_set_header_version(struct razor_set *set,
    7.45  				 uint32_t header_version);
    7.46 @@ -228,8 +246,9 @@
    7.47  			       uint32_t section_mask);
    7.48  int razor_set_write(struct razor_set *set, struct razor_atomic *atomic,
    7.49  		    const char *filename, uint32_t setions);
    7.50 -int razor_set_bind_sections(struct razor_set *set, struct razor_atomic *atomic,
    7.51 -			    const char *filename);
    7.52 +int
    7.53 +razor_set_bind_sections(struct razor_set *set, const char *filename,
    7.54 +			enum razor_set_flags flags, struct razor_error **error);
    7.55  
    7.56  struct razor_package *
    7.57  razor_set_get_package(struct razor_set *set, const char *package);
    7.58 @@ -528,13 +547,14 @@
    7.59  
    7.60  int razor_root_create(const char *root);
    7.61  struct razor_root *
    7.62 -razor_root_open(const char *root, struct razor_atomic *atomic);
    7.63 -struct razor_set *razor_root_open_read_only(const char *root,
    7.64 -					    struct razor_atomic *atomic);
    7.65 +razor_root_open(const char *root, struct razor_error **error);
    7.66 +struct razor_set *
    7.67 +razor_root_open_read_only(const char *root, struct razor_error **error);
    7.68  struct razor_set *razor_root_get_system_set(struct razor_root *root);
    7.69  int razor_root_close(struct razor_root *root);
    7.70 -void razor_root_update(struct razor_root *root, struct razor_set *next);
    7.71 -int razor_root_commit(struct razor_root *root);
    7.72 +int
    7.73 +razor_root_update(struct razor_root *root, struct razor_set *next,
    7.74 +		  struct razor_atomic *atomic);
    7.75  
    7.76  /**
    7.77   * SECTION:misc
     8.1 --- a/librazor/root.c	Sat Feb 11 23:50:26 2012 +0000
     8.2 +++ b/librazor/root.c	Thu Feb 16 17:33:47 2012 +0000
     8.3 @@ -1,7 +1,7 @@
     8.4  /*
     8.5   * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     8.6   * Copyright (C) 2008  Red Hat, Inc
     8.7 - * Copyright (C) 2009, 2011  J. Ali Harlow <ali@juiblex.co.uk>
     8.8 + * Copyright (C) 2009, 2011, 2012  J. Ali Harlow <ali@juiblex.co.uk>
     8.9   *
    8.10   * This program is free software; you can redistribute it and/or modify
    8.11   * it under the terms of the GNU General Public License as published by
    8.12 @@ -49,7 +49,6 @@
    8.13   * will see the system as permenantly locked.
    8.14   */
    8.15  static const char system_lock_filename[] = "system-next.rzdb";
    8.16 -static const char system_tmp_filename[] = "system.tmp";
    8.17  #ifdef MSWIN_API
    8.18  #define RAZOR_ROOT_PATH	NULL
    8.19  #else
    8.20 @@ -59,10 +58,7 @@
    8.21  
    8.22  struct razor_root {
    8.23  	struct razor_set *system;
    8.24 -	struct razor_set *next;
    8.25 -	struct razor_atomic *atomic;
    8.26 -	int handle;
    8.27 -	char *path, *new_path;
    8.28 +	char *path;
    8.29  };
    8.30  
    8.31  static void
    8.32 @@ -136,7 +132,7 @@
    8.33  }
    8.34  
    8.35  RAZOR_EXPORT struct razor_root *
    8.36 -razor_root_open(const char *root, struct razor_atomic *atomic)
    8.37 +razor_root_open(const char *root, struct razor_error **error)
    8.38  {
    8.39  	struct razor_root *image;
    8.40  	char *lock_path;
    8.41 @@ -147,16 +143,14 @@
    8.42  	razor_root_init();
    8.43  	image = malloc(sizeof *image);
    8.44  	if (image == NULL) {
    8.45 -		razor_atomic_abort(atomic, "Not enough memory");
    8.46 +		razor_set_error(error, NULL, "Not enough memory");
    8.47  		return NULL;
    8.48  	}
    8.49  
    8.50 -	image->atomic = atomic;
    8.51 -
    8.52  	image->system = razor_set_create_without_root();
    8.53  	if (image->system == NULL) {
    8.54  		free(image);
    8.55 -		razor_atomic_abort(atomic, "Not enough memory");
    8.56 +		razor_set_error(error, NULL, "Not enough memory");
    8.57  		return NULL;
    8.58  	}
    8.59  
    8.60 @@ -168,19 +162,8 @@
    8.61  	free(lock_path);
    8.62  
    8.63  	if (r < 0) {
    8.64 -		razor_atomic_abort(atomic,
    8.65 -				   "Failed to aquire exclusive system lock");
    8.66 -		razor_set_unref(image->system);
    8.67 -		free(image);
    8.68 -		return NULL;
    8.69 -	}
    8.70 -
    8.71 -	image->new_path = razor_concat(root, razor_root_path, "/",
    8.72 -				       system_tmp_filename, NULL);
    8.73 -	image->handle = razor_atomic_create_file(atomic, image->new_path,
    8.74 -						 S_IRWXU | S_IRWXG | S_IRWXO);
    8.75 -	if (image->handle < 0) {
    8.76 -		free(image->new_path);
    8.77 +		razor_set_error(error, NULL,
    8.78 +				"Failed to aquire exclusive system lock");
    8.79  		razor_set_unref(image->system);
    8.80  		free(image);
    8.81  		return NULL;
    8.82 @@ -189,9 +172,8 @@
    8.83  	image->path = razor_concat(root, razor_root_path, "/",
    8.84  				   system_repo_filename, NULL);
    8.85  
    8.86 -	if (razor_set_bind_sections(image->system, atomic, image->path)) {
    8.87 -		unlink(image->new_path);
    8.88 -		free(image->new_path);
    8.89 +	if (razor_set_bind_sections(image->system, image->path,
    8.90 +				    RAZOR_SET_PRIVATE, error)) {
    8.91  		free(image->path);
    8.92  		razor_set_unref(image->system);
    8.93  		free(image);
    8.94 @@ -202,7 +184,7 @@
    8.95  }
    8.96  
    8.97  RAZOR_EXPORT struct razor_set *
    8.98 -razor_root_open_read_only(const char *root, struct razor_atomic *atomic)
    8.99 +razor_root_open_read_only(const char *root, struct razor_error **error)
   8.100  {
   8.101  	char *path;
   8.102  	struct razor_set *set;
   8.103 @@ -212,15 +194,15 @@
   8.104  	razor_root_init();
   8.105  	set = razor_set_create_without_root();
   8.106  	if (set == NULL) {
   8.107 -		razor_atomic_abort(atomic, "Not enough memory");
   8.108 +		razor_set_error(error, NULL, "Not enough memory");
   8.109  		return NULL;
   8.110  	}
   8.111  
   8.112  	path = razor_concat(root, razor_root_path, "/", system_lock_filename,
   8.113  			    NULL);
   8.114  	if (razor_set_aquire_lock(set, path, 0) < 0) {
   8.115 -		razor_atomic_abort(atomic, "Failed to aquire non-exclusive "
   8.116 -					   "system lock");
   8.117 +		razor_set_error(error, NULL,
   8.118 +				"Failed to aquire non-exclusive system lock");
   8.119  		free(path);
   8.120  		razor_set_unref(set);
   8.121  		return NULL;
   8.122 @@ -230,7 +212,7 @@
   8.123  	path = razor_concat(root, razor_root_path, "/", system_repo_filename,
   8.124  			    NULL);
   8.125  
   8.126 -	if (razor_set_bind_sections(set, atomic, path)) {
   8.127 +	if (razor_set_bind_sections(set, path, 0, error)) {
   8.128  		razor_set_unref(set);
   8.129  		set = NULL;
   8.130  	}
   8.131 @@ -254,44 +236,34 @@
   8.132  	assert (root != NULL);
   8.133  
   8.134  	razor_set_unref(root->system);
   8.135 -	razor_atomic_close(root->atomic, root->handle);
   8.136 -	razor_atomic_remove(root->atomic, root->new_path);
   8.137  	free(root->path);
   8.138 -	free(root->new_path);
   8.139  	free(root);
   8.140  
   8.141  	return 0;
   8.142  }
   8.143  
   8.144 -RAZOR_EXPORT void
   8.145 -razor_root_update(struct razor_root *root, struct razor_set *next)
   8.146 +RAZOR_EXPORT int
   8.147 +razor_root_update(struct razor_root *root, struct razor_set *next,
   8.148 +		  struct razor_atomic *atomic)
   8.149  {
   8.150 +	int handle, retval;
   8.151 +
   8.152  	assert (root != NULL);
   8.153  	assert (next != NULL);
   8.154  
   8.155 -	razor_root_init();
   8.156 -	razor_set_write_to_handle(next, root->atomic, root->handle,
   8.157 -				  RAZOR_SECTION_ALL);
   8.158 -	root->next = next;
   8.159 +	handle = razor_atomic_create_file(atomic, root->path,
   8.160 +					  S_IRWXU | S_IRWXG | S_IRWXO);
   8.161 +	if (handle < 0)
   8.162 +		return handle;
   8.163  
   8.164 -	/* Sync the new repo file so the new package set is on disk
   8.165 -	 * before we start upgrading. */
   8.166 -	razor_atomic_sync(root->atomic, root->handle);
   8.167 -}
   8.168 +	razor_set_write_to_handle(next, atomic, handle, RAZOR_SECTION_ALL);
   8.169  
   8.170 -RAZOR_EXPORT int
   8.171 -razor_root_commit(struct razor_root *root)
   8.172 -{
   8.173 -	int retval;
   8.174 -	assert (root != NULL);
   8.175 +	retval = razor_atomic_close(atomic, handle);
   8.176  
   8.177 -	razor_atomic_close(root->atomic, root->handle);
   8.178 -	retval = razor_atomic_rename_file(root->atomic, root->new_path,
   8.179 -					  root->path);
   8.180 -	razor_set_unref(root->system);
   8.181 -	free(root->path);
   8.182 -	free(root->new_path);
   8.183 -	free(root);
   8.184 +	if (!retval) {
   8.185 +		razor_set_unref(root->system);
   8.186 +		root->system = razor_set_ref(next);
   8.187 +	}
   8.188  
   8.189  	return retval;
   8.190  }
     9.1 --- a/librazor/rpm.c	Sat Feb 11 23:50:26 2012 +0000
     9.2 +++ b/librazor/rpm.c	Thu Feb 16 17:33:47 2012 +0000
     9.3 @@ -606,6 +606,7 @@
     9.4  {
     9.5  	struct razor_rpm *rpm;
     9.6  	struct rpm_header_index *base, *index;
     9.7 +	struct razor_error *error = NULL;
     9.8  	unsigned int count, i, nindex, hsize;
     9.9  	const char *name, *prefix;
    9.10  	char *s;
    9.11 @@ -619,11 +620,10 @@
    9.12  	}
    9.13  	memset(rpm, 0, sizeof *rpm);
    9.14  
    9.15 -	rpm->map = razor_file_get_contents(filename, &rpm->size);
    9.16 +	rpm->map = razor_file_get_contents(filename, &rpm->size, 0, &error);
    9.17  	if (!rpm->map) {
    9.18 -		s = razor_concat(filename, ": ", strerror(errno), NULL);
    9.19 -		razor_atomic_abort(atomic, s);
    9.20 -		free(s);
    9.21 +		razor_atomic_abort(atomic, razor_error_get_msg(error));
    9.22 +		razor_error_free(error);
    9.23  		free(rpm);
    9.24  		return NULL;
    9.25  	}
    9.26 @@ -1138,7 +1138,7 @@
    9.27  	struct cpio_file_header *header;
    9.28  	struct stat buf;
    9.29  	unsigned int mode;
    9.30 -	const char *path, *name;
    9.31 +	const char *path;
    9.32  	size_t filesize;
    9.33  	char *s;
    9.34  	int retval = 0;
    9.35 @@ -1153,7 +1153,7 @@
    9.36  	/* FIXME: Only do this before a transaction, not per rpm. */
    9.37  	if (*root && (stat(root, &buf) < 0 || !S_ISDIR(buf.st_mode))) {
    9.38  		s = razor_concat(root, ": Directory does not exist", NULL);
    9.39 -		razor_atomic_abort(stderr, s);
    9.40 +		razor_atomic_abort(atomic, s);
    9.41  		free(s);
    9.42  		return -1;
    9.43  	}
    10.1 --- a/librazor/test-lua.c	Sat Feb 11 23:50:26 2012 +0000
    10.2 +++ b/librazor/test-lua.c	Thu Feb 16 17:33:47 2012 +0000
    10.3 @@ -65,6 +65,7 @@
    10.4  	size_t len;
    10.5  	char *s, *test_file, *srcdir;
    10.6  	FILE *fp;
    10.7 +	struct razor_error *error = NULL;
    10.8  
    10.9  	if (argc > 2) {
   10.10  		fprintf(stderr, "usage: %s [TESTS-FILE]\n", argv[0]);
   10.11 @@ -94,22 +95,26 @@
   10.12  	fclose(fp);
   10.13  	free(s);
   10.14  
   10.15 -	script = razor_file_get_contents(test_file, &len);
   10.16 +	script = razor_file_get_contents(test_file, &len, 0, &error);
   10.17  	if (!script) {
   10.18  		srcdir = getenv("srcdir");
   10.19  		if (srcdir && errno == ENOENT && *test_file != '/') {
   10.20 +			razor_error_free(error);
   10.21  			s = malloc(strlen(srcdir) + strlen(test_file) + 2);
   10.22  			strcpy(s, srcdir);
   10.23  			strcat(s, "/");
   10.24  			strcat(s, test_file);
   10.25 -			script = razor_file_get_contents(s, &len);
   10.26 +			script = razor_file_get_contents(s, &len, 0, &error);
   10.27  			if (!script) {
   10.28 -				perror(s);
   10.29 +				fprintf(stderr, "%s\n",
   10.30 +					razor_error_get_msg(error));
   10.31 +				razor_error_free(error);
   10.32  				exit(1);
   10.33  			}
   10.34  			free(s);
   10.35  		} else {
   10.36 -			perror(test_file);
   10.37 +			fprintf(stderr, "%s\n", razor_error_get_msg(error));
   10.38 +			razor_error_free(error);
   10.39  			exit(1);
   10.40  		}
   10.41  	}
    11.1 --- a/librazor/util.c	Sat Feb 11 23:50:26 2012 +0000
    11.2 +++ b/librazor/util.c	Thu Feb 16 17:33:47 2012 +0000
    11.3 @@ -1,7 +1,7 @@
    11.4  /*
    11.5   * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
    11.6   * Copyright (C) 2008  Red Hat, Inc
    11.7 - * Copyright (C) 2009, 2011  J. Ali Harlow <ali@juiblex.co.uk>
    11.8 + * Copyright (C) 2009, 2011, 2012  J. Ali Harlow <ali@juiblex.co.uk>
    11.9   *
   11.10   * This program is free software; you can redistribute it and/or modify
   11.11   * it under the terms of the GNU General Public License as published by
   11.12 @@ -52,54 +52,70 @@
   11.13  char *program_name = "librazor";
   11.14  
   11.15  void *
   11.16 -razor_file_get_contents(const char *filename, size_t *length)
   11.17 +zalloc(size_t size)
   11.18 +{
   11.19 +	void *p;
   11.20 +
   11.21 +	p = malloc(size);
   11.22 +	memset(p, 0, size);
   11.23 +
   11.24 +	return p;
   11.25 +}
   11.26 +
   11.27 +void *
   11.28 +razor_file_get_contents(const char *filename, size_t *length, int private,
   11.29 +			struct razor_error **error)
   11.30  {
   11.31  	int fd;
   11.32  	struct stat st;
   11.33 -	void *addr;
   11.34 -#if !HAVE_SYS_MMAN_H
   11.35 +	void *addr = NULL;
   11.36  	size_t nb;
   11.37  	ssize_t res;
   11.38 -#endif
   11.39  
   11.40  	fd = open(filename, O_RDONLY | O_BINARY);
   11.41 -	if (fd < 0)
   11.42 +	if (fd < 0) {
   11.43 +		razor_set_error(error, filename, strerror(errno));
   11.44  		return NULL;
   11.45 +	}
   11.46  
   11.47  	if (fstat(fd, &st) < 0) {
   11.48 +		razor_set_error(error, filename, strerror(errno));
   11.49  		close(fd);
   11.50  		return NULL;
   11.51  	}
   11.52  
   11.53  	*length = st.st_size;
   11.54  #if HAVE_SYS_MMAN_H
   11.55 -	addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   11.56 -#else
   11.57 -	addr = malloc(st.st_size);
   11.58 -	if (addr) {
   11.59 -		nb = 0;
   11.60 -		while(nb < st.st_size) {
   11.61 -			res = read(fd, addr + nb, st.st_size - nb);
   11.62 -			if (res <= 0) {
   11.63 -				free(addr);
   11.64 -				addr = NULL;
   11.65 -				break;
   11.66 -			}
   11.67 -			nb += res;
   11.68 -		}
   11.69 +	if (!private) {
   11.70 +		addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   11.71 +		if (addr == MAP_FAILED)
   11.72 +			addr = NULL;
   11.73  	}
   11.74  #endif
   11.75 +	if (!addr) {
   11.76 +		addr = malloc(st.st_size);
   11.77 +		if (addr) {
   11.78 +			nb = 0;
   11.79 +			while(nb < st.st_size) {
   11.80 +				res = read(fd, addr + nb, st.st_size - nb);
   11.81 +				if (res <= 0) {
   11.82 +					razor_set_error(error, filename,
   11.83 +							strerror(errno));
   11.84 +					free(addr);
   11.85 +					addr = NULL;
   11.86 +					break;
   11.87 +				}
   11.88 +				nb += res;
   11.89 +			}
   11.90 +		} else
   11.91 +			razor_set_error(error, NULL, "Not enough memory");
   11.92 +	}
   11.93  	close(fd);
   11.94  
   11.95 -#if HAVE_SYS_MMAN_H
   11.96 -	if (addr == MAP_FAILED)
   11.97 -		addr = NULL;
   11.98 -#endif
   11.99 -
  11.100  	return addr;
  11.101  }
  11.102  
  11.103 -razor_file_free_contents(void *addr, size_t length)
  11.104 +int razor_file_free_contents(void *addr, size_t length)
  11.105  {
  11.106  #if HAVE_SYS_MMAN_H
  11.107  	return munmap(addr, length);
    12.1 --- a/src/main.c	Sat Feb 11 23:50:26 2012 +0000
    12.2 +++ b/src/main.c	Thu Feb 16 17:33:47 2012 +0000
    12.3 @@ -55,9 +55,9 @@
    12.4  		struct razor_relocations *relocations,
    12.5  		enum razor_stage_type stage);
    12.6  static int
    12.7 -update_system(const char *install_root, struct razor_relocations *relocations,
    12.8 -	      struct razor_transaction *trans, struct razor_set *system,
    12.9 -	      struct razor_set *next, const char *verb);
   12.10 +update_system(struct razor_root *root, struct razor_relocations *relocations,
   12.11 +	      struct razor_transaction *trans, struct razor_set *next,
   12.12 +	      const char *verb);
   12.13  
   12.14  static struct razor_package_iterator *
   12.15  create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[])
   12.16 @@ -120,7 +120,7 @@
   12.17  command_list(int argc, const char *argv[])
   12.18  {
   12.19  	struct razor_package_iterator *pi;
   12.20 -	struct razor_atomic *atomic;
   12.21 +	struct razor_error *error = NULL;
   12.22  	struct razor_set *set;
   12.23  	uint32_t flags = 0;
   12.24  	int i = 0;
   12.25 @@ -130,11 +130,10 @@
   12.26  		i++;
   12.27  	}
   12.28  
   12.29 -	atomic = razor_atomic_open("List installed packages");
   12.30 -	set = razor_root_open_read_only(install_root, atomic);
   12.31 +	set = razor_root_open_read_only(install_root, &error);
   12.32  	if (set == NULL) {
   12.33 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
   12.34 -		razor_atomic_destroy(atomic);
   12.35 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   12.36 +		razor_error_free(error);
   12.37  		return 1;
   12.38  	}
   12.39  
   12.40 @@ -142,7 +141,6 @@
   12.41  	list_packages(pi, flags);
   12.42  	razor_package_iterator_destroy(pi);
   12.43  	razor_set_unref(set);
   12.44 -	razor_atomic_destroy(atomic);
   12.45  
   12.46  	return 0;
   12.47  }
   12.48 @@ -188,16 +186,15 @@
   12.49  list_properties(int argc, const char *argv[], uint32_t type)
   12.50  {
   12.51  	struct razor_set *set;
   12.52 -	struct razor_atomic *atomic;
   12.53 +	struct razor_error *error = NULL;
   12.54  	struct razor_package *package;
   12.55  	struct razor_package_iterator *pi;
   12.56  	const char *name, *version, *arch;
   12.57  
   12.58 -	atomic = razor_atomic_open("List package properties");
   12.59 -	set = razor_root_open_read_only(install_root, atomic);
   12.60 +	set = razor_root_open_read_only(install_root, &error);
   12.61  	if (set == NULL) {
   12.62 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
   12.63 -		razor_atomic_destroy(atomic);
   12.64 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   12.65 +		razor_error_free(error);
   12.66  		return 1;
   12.67  	}
   12.68  
   12.69 @@ -210,7 +207,6 @@
   12.70  		list_package_properties(set, package, type);
   12.71  	razor_package_iterator_destroy(pi);
   12.72  	razor_set_unref(set);
   12.73 -	razor_atomic_destroy(atomic);
   12.74  
   12.75  	return 0;
   12.76  }
   12.77 @@ -243,16 +239,15 @@
   12.78  command_list_scripts(int argc, const char *argv[])
   12.79  {
   12.80  	struct razor_set *set;
   12.81 -	struct razor_atomic *atomic;
   12.82 +	struct razor_error *error = NULL;
   12.83  	struct razor_package *package;
   12.84  	struct razor_package_iterator *pi;
   12.85  	const char *preunprog, *preun, *postunprog, *postun;
   12.86  
   12.87 -	atomic = razor_atomic_open("List package scripts");
   12.88 -	set = razor_root_open_read_only(install_root, atomic);
   12.89 +	set = razor_root_open_read_only(install_root, &error);
   12.90  	if (set == NULL) {
   12.91 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
   12.92 -		razor_atomic_destroy(atomic);
   12.93 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   12.94 +		razor_error_free(error);
   12.95  		return 1;
   12.96  	}
   12.97  
   12.98 @@ -278,7 +273,6 @@
   12.99  	}
  12.100  	razor_package_iterator_destroy(pi);
  12.101  	razor_set_unref(set);
  12.102 -	razor_atomic_destroy(atomic);
  12.103  
  12.104  	return 0;
  12.105  }
  12.106 @@ -286,20 +280,18 @@
  12.107  static int
  12.108  command_list_files(int argc, const char *argv[])
  12.109  {
  12.110 -	struct razor_atomic *atomic;
  12.111 +	struct razor_error *error = NULL;
  12.112  	struct razor_set *set;
  12.113  
  12.114 -	atomic = razor_atomic_open("List package files");
  12.115 -	set = razor_root_open_read_only(install_root, atomic);
  12.116 +	set = razor_root_open_read_only(install_root, &error);
  12.117  	if (set == NULL) {
  12.118 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.119 -		razor_atomic_destroy(atomic);
  12.120 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.121 +		razor_error_free(error);
  12.122  		return 1;
  12.123  	}
  12.124  
  12.125  	razor_set_list_files(set, argv[0]);
  12.126  	razor_set_unref(set);
  12.127 -	razor_atomic_destroy(atomic);
  12.128  
  12.129  	return 0;
  12.130  }
  12.131 @@ -307,15 +299,14 @@
  12.132  static int
  12.133  command_list_file_packages(int argc, const char *argv[])
  12.134  {
  12.135 -	struct razor_atomic *atomic;
  12.136 +	struct razor_error *error = NULL;
  12.137  	struct razor_set *set;
  12.138  	struct razor_package_iterator *pi;
  12.139  
  12.140 -	atomic = razor_atomic_open("List file packages");
  12.141 -	set = razor_root_open_read_only(install_root, atomic);
  12.142 +	set = razor_root_open_read_only(install_root, &error);
  12.143  	if (set == NULL) {
  12.144 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.145 -		razor_atomic_destroy(atomic);
  12.146 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.147 +		razor_error_free(error);
  12.148  		return 1;
  12.149  	}
  12.150  
  12.151 @@ -324,7 +315,6 @@
  12.152  	razor_package_iterator_destroy(pi);
  12.153  
  12.154  	razor_set_unref(set);
  12.155 -	razor_atomic_destroy(atomic);
  12.156  
  12.157  	return 0;
  12.158  }
  12.159 @@ -332,17 +322,16 @@
  12.160  static int
  12.161  command_list_package_files(int argc, const char *argv[])
  12.162  {
  12.163 -	struct razor_atomic *atomic;
  12.164 +	struct razor_error *error = NULL;
  12.165  	struct razor_set *set;
  12.166  	struct razor_package_iterator *pi;
  12.167  	struct razor_package *package;
  12.168  	const char *name, *version, *arch;
  12.169  
  12.170 -	atomic = razor_atomic_open("List package files");
  12.171 -	set = razor_root_open_read_only(install_root, atomic);
  12.172 +	set = razor_root_open_read_only(install_root, &error);
  12.173  	if (set == NULL) {
  12.174 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.175 -		razor_atomic_destroy(atomic);
  12.176 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.177 +		razor_error_free(error);
  12.178  		return 1;
  12.179  	}
  12.180  
  12.181 @@ -356,7 +345,6 @@
  12.182  	razor_package_iterator_destroy(pi);
  12.183  
  12.184  	razor_set_unref(set);
  12.185 -	razor_atomic_destroy(atomic);
  12.186  
  12.187  	return 0;
  12.188  }
  12.189 @@ -366,7 +354,7 @@
  12.190  		       const char *ref_version,
  12.191  		       uint32_t type)
  12.192  {
  12.193 -	struct razor_atomic *atomic;
  12.194 +	struct razor_error *error = NULL;
  12.195  	struct razor_set *set;
  12.196  	struct razor_property *property;
  12.197  	struct razor_property_iterator *prop_iter;
  12.198 @@ -377,11 +365,10 @@
  12.199  	if (ref_name == NULL)
  12.200  		return 0;
  12.201  
  12.202 -	atomic = razor_atomic_open("List package properties");
  12.203 -	set = razor_root_open_read_only(install_root, atomic);
  12.204 +	set = razor_root_open_read_only(install_root, &error);
  12.205  	if (set == NULL) {
  12.206 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.207 -		razor_atomic_destroy(atomic);
  12.208 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.209 +		razor_error_free(error);
  12.210  		return 1;
  12.211  	}
  12.212  
  12.213 @@ -406,7 +393,6 @@
  12.214  	razor_property_iterator_destroy(prop_iter);
  12.215  
  12.216  	razor_set_unref(set);
  12.217 -	razor_atomic_destroy(atomic);
  12.218  
  12.219  	return 0;
  12.220  }
  12.221 @@ -540,15 +526,14 @@
  12.222  {
  12.223  	struct razor_set *set;
  12.224  	struct razor_root *root;
  12.225 +	struct razor_error *error = NULL;
  12.226  	struct razor_atomic *atomic;
  12.227  	int retval;
  12.228  
  12.229 -	atomic = razor_atomic_open("Import RPM database");
  12.230 -
  12.231 -	root = razor_root_open(install_root, atomic);
  12.232 +	root = razor_root_open(install_root, &error);
  12.233  	if (root == NULL) {
  12.234 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.235 -		razor_atomic_destroy(atomic);
  12.236 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.237 +		razor_error_free(error);
  12.238  		return 1;
  12.239  	}
  12.240  
  12.241 @@ -556,14 +541,17 @@
  12.242  	if (set == NULL)
  12.243  		return 1;
  12.244  
  12.245 -	razor_root_update(root, set);
  12.246 +	atomic = razor_atomic_open("Import RPM database");
  12.247  
  12.248 -	retval = razor_root_commit(root);
  12.249 +	retval = razor_root_update(root, set, atomic);
  12.250 +
  12.251  	if (retval)
  12.252  		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.253  
  12.254  	razor_atomic_destroy(atomic);
  12.255  
  12.256 +	razor_root_close(root);
  12.257 +
  12.258  	return retval;
  12.259  }
  12.260  #endif
  12.261 @@ -619,20 +607,18 @@
  12.262  {
  12.263  	struct razor_set *system, *upstream, *next;
  12.264  	struct razor_transaction *trans;
  12.265 -	struct razor_atomic *atomic;
  12.266 +	struct razor_error *error = NULL;
  12.267 +	struct razor_root *root;
  12.268  	int i, retval;
  12.269  
  12.270 -	atomic = razor_atomic_open("Remove packages");
  12.271 -
  12.272 -	system = razor_root_open_read_only(install_root, atomic);
  12.273 -	if (system == NULL) {
  12.274 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.275 -		razor_atomic_destroy(atomic);
  12.276 +	root = razor_root_open(install_root, &error);
  12.277 +	if (root == NULL) {
  12.278 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.279 +		razor_error_free(error);
  12.280  		return 1;
  12.281  	}
  12.282  
  12.283 -	razor_atomic_destroy(atomic);
  12.284 -
  12.285 +	system = razor_root_get_system_set(root);
  12.286  	upstream = razor_set_create_without_root();
  12.287  	trans = razor_transaction_create(system, upstream);
  12.288  	razor_set_unref(upstream);
  12.289 @@ -640,7 +626,7 @@
  12.290  		if (mark_packages_for_removal(trans, system, argv[i]) == 0) {
  12.291  			fprintf(stderr, "no match for %s\n", argv[i]);
  12.292  			razor_transaction_destroy(trans);
  12.293 -			razor_set_unref(system);
  12.294 +			razor_root_close(root);
  12.295  			return 1;
  12.296  		}
  12.297  	}
  12.298 @@ -649,17 +635,16 @@
  12.299  	retval = razor_transaction_describe(trans);
  12.300  	if (retval) {
  12.301  		razor_transaction_destroy(trans);
  12.302 -		razor_set_unref(system);
  12.303 +		razor_root_close(root);
  12.304  		return 1;
  12.305  	}
  12.306  
  12.307  	next = razor_transaction_commit(trans);
  12.308  
  12.309 -	retval = update_system(install_root, NULL, trans, system, next,
  12.310 -			       "Remove");
  12.311 +	retval = update_system(root, NULL, trans, next, "Remove");
  12.312  
  12.313  	razor_transaction_destroy(trans);
  12.314 -	razor_set_unref(system);
  12.315 +	razor_root_close(root);
  12.316  	razor_set_unref(next);
  12.317  
  12.318  	return retval;
  12.319 @@ -682,15 +667,19 @@
  12.320  static int
  12.321  command_diff(int argc, const char *argv[])
  12.322  {
  12.323 -	struct razor_atomic *atomic;
  12.324 +	struct razor_error *error = NULL;
  12.325  	struct razor_set *set, *updated;
  12.326  
  12.327 -	atomic = razor_atomic_open("Show package differences");
  12.328 -	set = razor_root_open_read_only(install_root, atomic);
  12.329 -	updated = razor_set_open(rawhide_repo_filename, atomic);
  12.330 -	if (set == NULL || updated == NULL) {
  12.331 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.332 -		razor_atomic_destroy(atomic);
  12.333 +	set = razor_root_open_read_only(install_root, &error);
  12.334 +	if (set)
  12.335 +		updated = razor_set_open(rawhide_repo_filename, 0, &error);
  12.336 +	else
  12.337 +		updated = NULL;
  12.338 +	if (updated == NULL) {
  12.339 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.340 +		razor_error_free(error);
  12.341 +		if (set)
  12.342 +			razor_set_unref(set);
  12.343  		return 1;
  12.344  	}
  12.345  
  12.346 @@ -698,7 +687,6 @@
  12.347  
  12.348  	razor_set_unref(set);
  12.349  	razor_set_unref(updated);
  12.350 -	razor_atomic_destroy(atomic);
  12.351  
  12.352  	return 0;
  12.353  }
  12.354 @@ -997,12 +985,11 @@
  12.355  }
  12.356  
  12.357  static int
  12.358 -update_system(const char *install_root, struct razor_relocations *relocations,
  12.359 -	      struct razor_transaction *trans, struct razor_set *system,
  12.360 -	      struct razor_set *next, const char *verb)
  12.361 +update_system(struct razor_root *root, struct razor_relocations *relocations,
  12.362 +	      struct razor_transaction *trans, struct razor_set *next,
  12.363 +	      const char *verb)
  12.364  {
  12.365 -	struct razor_root *root;
  12.366 -	struct razor_set *set;
  12.367 +	struct razor_set *system, *set;
  12.368  	struct razor_atomic *atomic;
  12.369  	struct razor_install_iterator *ii;
  12.370  	int r, retval = 0;
  12.371 @@ -1011,6 +998,8 @@
  12.372  
  12.373  	description = razor_concat(verb, " packages", NULL);
  12.374  
  12.375 +	system = razor_set_ref(razor_root_get_system_set(root));
  12.376 +
  12.377  	ii = razor_set_create_install_iterator(system, next);
  12.378  
  12.379  	do {
  12.380 @@ -1018,20 +1007,10 @@
  12.381  
  12.382  		atomic = razor_atomic_open(description);
  12.383  
  12.384 -		root = razor_root_open(install_root, atomic);
  12.385 -		if (root == NULL) {
  12.386 -			fprintf(stderr, "%s\n",
  12.387 -				razor_atomic_get_error_msg(atomic));
  12.388 -			razor_atomic_destroy(atomic);
  12.389 -			retval = 1;
  12.390 -			break;
  12.391 -		}
  12.392 -
  12.393  		r = update_packages(trans, ii, system, next, atomic,
  12.394  				    relocations, RAZOR_STAGE_SCRIPTS_PRE);
  12.395  		if (r < 0) {
  12.396  			fprintf(stderr, "%s aborted\n", verb);
  12.397 -			razor_root_close(root);
  12.398  			retval = r;
  12.399  		} else {
  12.400  			razor_install_iterator_seek(ii, pos);
  12.401 @@ -1040,12 +1019,11 @@
  12.402  
  12.403  			if (r == 1) {
  12.404  				set = razor_install_iterator_commit_set(ii);
  12.405 -				razor_root_update(root, set);
  12.406 +				razor_root_update(root, set, atomic);
  12.407  				razor_set_unref(set);
  12.408  			} else if (r == 0)
  12.409 -				razor_root_update(root, next);
  12.410 +				razor_root_update(root, next, atomic);
  12.411  
  12.412 -			(void)razor_root_commit(root);
  12.413  			retval = razor_atomic_commit(atomic);
  12.414  			if (retval)
  12.415  				fprintf(stderr, "%s\n",
  12.416 @@ -1061,6 +1039,8 @@
  12.417  		razor_atomic_destroy(atomic);
  12.418  	} while(!retval && r == 1);
  12.419  
  12.420 +	razor_set_unref(system);
  12.421 +
  12.422  	free(description);
  12.423  
  12.424  	return retval;
  12.425 @@ -1069,10 +1049,12 @@
  12.426  static int
  12.427  command_install_or_update(int argc, const char *argv[], int do_update)
  12.428  {
  12.429 -	struct razor_relocations *relocations=NULL;
  12.430 +	struct razor_relocations *relocations = NULL;
  12.431  	struct razor_set *system, *upstream, *next, *set;
  12.432  	struct razor_transaction *trans;
  12.433 +	struct razor_error *error = NULL;
  12.434  	struct razor_atomic *atomic;
  12.435 +	struct razor_root *root;
  12.436  	int i, retval, len, dependencies = 1;
  12.437  	char *oldpath;
  12.438  
  12.439 @@ -1104,18 +1086,18 @@
  12.440  			break;
  12.441  	}
  12.442  
  12.443 +	upstream = razor_set_open(rawhide_repo_filename, 0, &error);
  12.444 +	if (upstream == NULL) {
  12.445 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.446 +		razor_error_free(error);
  12.447 +		return 1;
  12.448 +	}
  12.449 +
  12.450  	if (do_update)
  12.451  		atomic = razor_atomic_open("Update packages");
  12.452  	else
  12.453  		atomic = razor_atomic_open("Install packages");
  12.454  
  12.455 -	upstream = razor_set_open(rawhide_repo_filename, atomic);
  12.456 -	if (upstream == NULL) {
  12.457 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.458 -		razor_atomic_destroy(atomic);
  12.459 -		return 1;
  12.460 -	}
  12.461 -
  12.462  	if (relocations) {
  12.463  		set = relocate_packages(upstream, atomic, relocations);
  12.464  		if (set == NULL) {
  12.465 @@ -1129,8 +1111,18 @@
  12.466  		upstream = set;
  12.467  	}
  12.468  
  12.469 -	system = razor_root_open_read_only(install_root, atomic);
  12.470 +	root = razor_root_open(install_root, &error);
  12.471 +	if (root == NULL) {
  12.472 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.473 +		razor_error_free(error);
  12.474 +		razor_atomic_destroy(atomic);
  12.475 +		razor_set_unref(upstream);
  12.476 +		if (relocations)
  12.477 +			razor_relocations_destroy(relocations);
  12.478 +		return 1;
  12.479 +	}
  12.480  
  12.481 +	system = razor_root_get_system_set(root);
  12.482  	trans = razor_transaction_create(system, upstream);
  12.483  
  12.484  	if (i == argc && do_update)
  12.485 @@ -1142,9 +1134,11 @@
  12.486  		if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
  12.487  			fprintf(stderr, "no package matched %s\n", argv[i]);
  12.488  			razor_transaction_destroy(trans);
  12.489 +			razor_root_close(root);
  12.490  			razor_set_unref(upstream);
  12.491 -			razor_set_unref(system);
  12.492  			razor_atomic_destroy(atomic);
  12.493 +			if (relocations)
  12.494 +				razor_relocations_destroy(relocations);
  12.495  			return 1;
  12.496  		}
  12.497  	}
  12.498 @@ -1154,8 +1148,10 @@
  12.499  		if (razor_transaction_describe(trans) > 0) {
  12.500  			razor_transaction_destroy(trans);
  12.501  			razor_set_unref(upstream);
  12.502 -			razor_set_unref(system);
  12.503 +			razor_root_close(root);
  12.504  			razor_atomic_destroy(atomic);
  12.505 +			if (relocations)
  12.506 +				razor_relocations_destroy(relocations);
  12.507  			return 1;
  12.508  		}
  12.509  	}
  12.510 @@ -1166,8 +1162,10 @@
  12.511  		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.512  		razor_transaction_destroy(trans);
  12.513  		razor_set_unref(upstream);
  12.514 -		razor_set_unref(system);
  12.515 +		razor_root_close(root);
  12.516  		razor_atomic_destroy(atomic);
  12.517 +		if (relocations)
  12.518 +			razor_relocations_destroy(relocations);
  12.519  		return 1;
  12.520  	}
  12.521  
  12.522 @@ -1179,22 +1177,24 @@
  12.523  		razor_set_unref(next);
  12.524  		razor_transaction_destroy(trans);
  12.525  		razor_set_unref(upstream);
  12.526 -		razor_set_unref(system);
  12.527 +		razor_root_close(root);
  12.528  		razor_atomic_destroy(atomic);
  12.529 +		if (relocations)
  12.530 +			razor_relocations_destroy(relocations);
  12.531                  return 1;
  12.532          }
  12.533  
  12.534 -	retval = update_system(install_root, relocations, trans, system, next,
  12.535 +	retval = update_system(root, relocations, trans, next,
  12.536  			       do_update ? "Update" : "Install");
  12.537  
  12.538  	razor_set_unref(upstream);
  12.539 +	razor_root_close(root);
  12.540  
  12.541  	razor_transaction_destroy(trans);
  12.542  	if (relocations)
  12.543  		razor_relocations_destroy(relocations);
  12.544  
  12.545  	razor_set_unref(next);
  12.546 -	razor_set_unref(system);
  12.547  
  12.548  	return retval;
  12.549  }
  12.550 @@ -1220,6 +1220,7 @@
  12.551  static int
  12.552  command_download(int argc, const char *argv[])
  12.553  {
  12.554 +	struct razor_error *error = NULL;
  12.555  	struct razor_atomic *atomic;
  12.556  	struct razor_set *set;
  12.557  	struct razor_package_iterator *pi;
  12.558 @@ -1228,6 +1229,13 @@
  12.559  	char url[256], file[256];
  12.560  	int matches = 0;
  12.561  
  12.562 +	set = razor_set_open(rawhide_repo_filename, 0, &error);
  12.563 +	if (set == NULL) {
  12.564 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.565 +		razor_error_free(error);
  12.566 +		return 1;
  12.567 +	}
  12.568 +
  12.569  	atomic = razor_atomic_open("Download packages");
  12.570  
  12.571  	if (razor_atomic_create_dir(atomic, "rpms", 
  12.572 @@ -1237,8 +1245,6 @@
  12.573  		return 1;
  12.574  	}
  12.575  
  12.576 -	set = razor_set_open(rawhide_repo_filename, atomic);
  12.577 -
  12.578  	if (razor_atomic_commit(atomic)) {
  12.579  		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.580  		razor_atomic_destroy(atomic);
  12.581 @@ -1279,18 +1285,17 @@
  12.582  static int
  12.583  command_info(int argc, const char *argv[])
  12.584  {
  12.585 -	struct razor_atomic *atomic;
  12.586 +	struct razor_error *error = NULL;
  12.587  	struct razor_set *set;
  12.588  	struct razor_package_iterator *pi;
  12.589  	struct razor_package *package;
  12.590  	const char *pattern = argv[0], *name, *version, *arch;
  12.591  	const char *summary, *description, *url, *license;
  12.592  
  12.593 -	atomic = razor_atomic_open("Package info");
  12.594 -	set = razor_root_open_read_only(install_root, atomic);
  12.595 +	set = razor_root_open_read_only(install_root, &error);
  12.596  	if (set == NULL) {
  12.597 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.598 -		razor_atomic_destroy(atomic);
  12.599 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.600 +		razor_error_free(error);
  12.601  		return 1;
  12.602  	}
  12.603  
  12.604 @@ -1322,7 +1327,6 @@
  12.605  	}
  12.606  	razor_package_iterator_destroy(pi);
  12.607  	razor_set_unref(set);
  12.608 -	razor_atomic_destroy(atomic);
  12.609  
  12.610  	return 0;
  12.611  }
  12.612 @@ -1332,7 +1336,7 @@
  12.613  static int
  12.614  command_search(int argc, const char *argv[])
  12.615  {
  12.616 -	struct razor_atomic *atomic;
  12.617 +	struct razor_error *error = NULL;
  12.618  	struct razor_set *set;
  12.619  	struct razor_package_iterator *pi;
  12.620  	struct razor_package *package;
  12.621 @@ -1347,14 +1351,12 @@
  12.622  
  12.623  	snprintf(pattern, sizeof pattern, "*%s*", argv[0]);
  12.624  
  12.625 -	atomic = razor_atomic_open("Search packages");
  12.626 -	set = razor_set_open(rawhide_repo_filename, atomic);
  12.627 -	if (set == NULL || razor_atomic_commit(atomic)) {
  12.628 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  12.629 -		razor_atomic_destroy(atomic);
  12.630 +	set = razor_set_open(rawhide_repo_filename, 0, &error);
  12.631 +	if (set == NULL) {
  12.632 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  12.633 +		razor_error_free(error);
  12.634  		return 1;
  12.635  	}
  12.636 -	razor_atomic_destroy(atomic);
  12.637  
  12.638  	pi = razor_package_iterator_create(set);
  12.639  	while (razor_package_iterator_next(pi, &package,
    13.1 --- a/src/rpm.c	Sat Feb 11 23:50:26 2012 +0000
    13.2 +++ b/src/rpm.c	Thu Feb 16 17:33:47 2012 +0000
    13.3 @@ -465,23 +465,21 @@
    13.4  static void
    13.5  command_query(int argc, const char *argv[])
    13.6  {
    13.7 -	struct razor_atomic *atomic;
    13.8 +	struct razor_error *error = NULL;
    13.9  	struct razor_set *set;
   13.10  	struct razor_package_iterator *pi;
   13.11  	struct razor_package *package;
   13.12  	const char *name, *version, *arch;
   13.13  
   13.14 -	atomic = razor_atomic_open("Query packages");
   13.15  	if (option_package) {
   13.16  		set = create_set_from_command_line(argc, argv);
   13.17  		argc = 0;
   13.18  		option_all = 1;
   13.19  	} else {
   13.20 -		set = razor_root_open_read_only(option_root, atomic);
   13.21 +		set = razor_root_open_read_only(option_root, &error);
   13.22  		if (!set) {
   13.23 -			fprintf(stderr, "%s\n",
   13.24 -				razor_atomic_get_error_msg(atomic));
   13.25 -			razor_atomic_destroy(atomic);
   13.26 +			fprintf(stderr, "%s\n", razor_error_get_msg(error));
   13.27 +			razor_error_free(error);
   13.28  			return;
   13.29  		}
   13.30  	}
   13.31 @@ -521,29 +519,26 @@
   13.32  	razor_package_iterator_destroy(pi);
   13.33  
   13.34  	razor_set_unref(set);
   13.35 -	razor_atomic_destroy(atomic);
   13.36  }
   13.37  
   13.38  static void
   13.39  command_verify(int argc, const char *argv[])
   13.40  {
   13.41 -	struct razor_atomic *atomic;
   13.42 +	struct razor_error *error = NULL;
   13.43  	struct razor_set *set;
   13.44  	struct razor_package_iterator *pi;
   13.45  	struct razor_package *package;
   13.46  	const char *name, *version, *arch;
   13.47  
   13.48 -	atomic = razor_atomic_open("Verify packages");
   13.49  	if (option_package) {
   13.50  		set = create_set_from_command_line(argc, argv);
   13.51  		argc = 0;
   13.52  		option_all = 1;
   13.53  	} else {
   13.54 -		set = razor_root_open_read_only(option_root, atomic);
   13.55 +		set = razor_root_open_read_only(option_root, &error);
   13.56  		if (!set) {
   13.57 -			fprintf(stderr, "%s\n",
   13.58 -				razor_atomic_get_error_msg(atomic));
   13.59 -			razor_atomic_destroy(atomic);
   13.60 +			fprintf(stderr, "%s\n", razor_error_get_msg(error));
   13.61 +			razor_error_free(error);
   13.62  			return;
   13.63  		}
   13.64  	}
   13.65 @@ -560,7 +555,6 @@
   13.66  	}
   13.67  
   13.68  	razor_package_iterator_destroy(pi);
   13.69 -	razor_atomic_destroy(atomic);
   13.70  }
   13.71  
   13.72  static void
   13.73 @@ -580,7 +574,7 @@
   13.74  static void
   13.75  command_erase(int argc, const char *argv[])
   13.76  {
   13.77 -	struct razor_atomic *atomic;
   13.78 +	struct razor_error *error = NULL;
   13.79  	struct razor_set *set, *upstream, *next;
   13.80  	struct razor_transaction *trans;
   13.81  	struct razor_package_query *query;
   13.82 @@ -592,15 +586,12 @@
   13.83  		exit(1);
   13.84  	}
   13.85  
   13.86 -	atomic = razor_atomic_open("Erase packages");
   13.87 -
   13.88 -	set = razor_set_open(repo_filename, atomic);
   13.89 -	if (!set || razor_atomic_commit(atomic)) {
   13.90 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
   13.91 -		razor_atomic_destroy(atomic);
   13.92 +	set = razor_set_open(repo_filename, RAZOR_SET_PRIVATE, &error);
   13.93 +	if (!set) {
   13.94 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   13.95 +		razor_error_free(error);
   13.96  		exit(1);
   13.97  	}
   13.98 -	razor_atomic_destroy(atomic);
   13.99  	upstream = razor_set_create();
  13.100  
  13.101  	trans = razor_transaction_create(set, upstream);
  13.102 @@ -639,7 +630,7 @@
  13.103  static void
  13.104  command_install(int argc, const char *argv[])
  13.105  {
  13.106 -	struct razor_atomic *atomic;
  13.107 +	struct razor_error *error = NULL;
  13.108  	struct razor_set *set, *upstream, *next;
  13.109  	struct razor_transaction *trans;
  13.110  	struct razor_package_iterator *pi;
  13.111 @@ -650,14 +641,11 @@
  13.112  		exit(1);
  13.113  	}
  13.114  
  13.115 -	atomic = razor_atomic_open("Install packages");
  13.116 -
  13.117 -	set = razor_set_open(repo_filename, atomic);
  13.118 -	if (!set || razor_atomic_commit(atomic)) {
  13.119 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  13.120 -		razor_atomic_destroy(atomic);
  13.121 +	set = razor_set_open(repo_filename, RAZOR_SET_PRIVATE, &error);
  13.122 +	if (!set) {
  13.123 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  13.124 +		razor_error_free(error);
  13.125  	}
  13.126 -	razor_atomic_destroy(atomic);
  13.127  	upstream = create_set_from_command_line(argc, argv);
  13.128  
  13.129  	trans = razor_transaction_create(set, upstream);
  13.130 @@ -693,7 +681,7 @@
  13.131  static void
  13.132  command_update(int argc, const char *argv[])
  13.133  {
  13.134 -	struct razor_atomic *atomic;
  13.135 +	struct razor_error *error = NULL;
  13.136  	struct razor_set *set, *upstream, *next;
  13.137  	struct razor_transaction *trans;
  13.138  	struct razor_package_iterator *pi;
  13.139 @@ -704,14 +692,11 @@
  13.140  		exit(1);
  13.141  	}
  13.142  
  13.143 -	atomic = razor_atomic_open("Update packages");
  13.144 -
  13.145 -	set = razor_set_open(repo_filename, atomic);
  13.146 -	if (!set || razor_atomic_commit(atomic)) {
  13.147 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
  13.148 -		razor_atomic_destroy(atomic);
  13.149 +	set = razor_set_open(repo_filename, RAZOR_SET_PRIVATE, &error);
  13.150 +	if (!set) {
  13.151 +		fprintf(stderr, "%s\n", razor_error_get_msg(error));
  13.152 +		razor_error_free(error);
  13.153  	}
  13.154 -	razor_atomic_destroy(atomic);
  13.155  	upstream = create_set_from_command_line(argc, argv);
  13.156  
  13.157  	trans = razor_transaction_create(set, upstream);