librazor/root.c
changeset 405 f960eb19dca2
parent 388 6a6462ce8a08
child 406 5ab137def3d1
     1.1 --- a/librazor/root.c	Thu Oct 01 20:02:12 2009 +0100
     1.2 +++ b/librazor/root.c	Fri Jan 27 07:55:30 2012 +0000
     1.3 @@ -1,7 +1,7 @@
     1.4  /*
     1.5   * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     1.6   * Copyright (C) 2008  Red Hat, Inc
     1.7 - * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
     1.8 + * Copyright (C) 2009, 2011  J. Ali Harlow <ali@juiblex.co.uk>
     1.9   *
    1.10   * This program is free software; you can redistribute it and/or modify
    1.11   * it under the terms of the GNU General Public License as published by
    1.12 @@ -60,9 +60,9 @@
    1.13  struct razor_root {
    1.14  	struct razor_set *system;
    1.15  	struct razor_set *next;
    1.16 -	int fd;
    1.17 -	char path[PATH_MAX];
    1.18 -	char new_path[PATH_MAX];
    1.19 +	struct razor_atomic *atomic;
    1.20 +	int handle;
    1.21 +	char *path, *new_path;
    1.22  };
    1.23  
    1.24  static void
    1.25 @@ -83,9 +83,11 @@
    1.26  RAZOR_EXPORT int
    1.27  razor_root_create(const char *root)
    1.28  {
    1.29 +	int retval;
    1.30  	struct stat buf;
    1.31  	struct razor_set *set;
    1.32 -	char path[PATH_MAX];
    1.33 +	struct razor_atomic *atomic;
    1.34 +	char *path;
    1.35  
    1.36  	assert (root != NULL);
    1.37  
    1.38 @@ -107,77 +109,90 @@
    1.39  		return -1;
    1.40  	}
    1.41  
    1.42 -	snprintf(path, sizeof path, "%s/%s",
    1.43 -		 razor_root_path, system_repo_filename);
    1.44 -	if (razor_create_dir(root, path) < 0) {
    1.45 -		fprintf(stderr, "could not create %s%s\n",
    1.46 -			root, razor_root_path);
    1.47 -		return -1;
    1.48 +	path = razor_concat(root, razor_root_path, "/", system_repo_filename,
    1.49 +			    NULL);
    1.50 +	retval = !stat(path, &buf);
    1.51 +	free(path);
    1.52 +	if (retval) {
    1.53 +		fprintf(stderr,
    1.54 +			"a razor install root is already initialized\n");
    1.55 +		return retval;
    1.56  	}
    1.57  
    1.58 +	atomic = razor_atomic_open("Create initial package set");
    1.59 +	path = razor_concat(razor_root_path, "/", system_repo_filename, NULL);
    1.60 +	razor_atomic_make_dirs(atomic, root, path);
    1.61  	set = razor_set_create();
    1.62 -	snprintf(path, sizeof path, "%s%s/%s",
    1.63 -		 root, razor_root_path, system_repo_filename);
    1.64 -	if (stat(path, &buf) == 0) {
    1.65 -		fprintf(stderr,
    1.66 -			"a razor install root is already initialized\n");
    1.67 -		return -1;
    1.68 -	}
    1.69 -	if (razor_set_write(set, path, RAZOR_SECTION_ALL) < 0) {
    1.70 +	razor_set_write(set, atomic, path, RAZOR_SECTION_ALL);
    1.71 +	free(path);
    1.72 +	retval = razor_atomic_commit(atomic);
    1.73 +	if (retval)
    1.74  		fprintf(stderr, "could not write initial package set\n");
    1.75 -		return -1;
    1.76 -	}
    1.77 -	razor_set_destroy(set);
    1.78 +	razor_set_unref(set);
    1.79 +	razor_atomic_destroy(atomic);
    1.80  
    1.81 -	return 0;
    1.82 +	return retval;
    1.83  }
    1.84  
    1.85  RAZOR_EXPORT struct razor_root *
    1.86 -razor_root_open(const char *root)
    1.87 +razor_root_open(const char *root, struct razor_atomic *atomic)
    1.88  {
    1.89  	struct razor_root *image;
    1.90 -	char lock_path[PATH_MAX];
    1.91 +	char *lock_path;
    1.92 +	int r;
    1.93  
    1.94  	assert (root != NULL);
    1.95  
    1.96  	razor_root_init();
    1.97  	image = malloc(sizeof *image);
    1.98 -	if (image == NULL)
    1.99 +	if (image == NULL) {
   1.100 +		razor_atomic_abort(atomic, "Not enough memory");
   1.101  		return NULL;
   1.102 +	}
   1.103 +
   1.104 +	image->atomic = atomic;
   1.105  
   1.106  	image->system = razor_set_create_without_root();
   1.107  	if (image->system == NULL) {
   1.108  		free(image);
   1.109 +		razor_atomic_abort(atomic, "Not enough memory");
   1.110  		return NULL;
   1.111  	}
   1.112  
   1.113 -	snprintf(lock_path, sizeof lock_path,
   1.114 -		 "%s%s/%s", root, razor_root_path, system_lock_filename);
   1.115 +	lock_path = razor_concat(root, razor_root_path, "/",
   1.116 +				 system_lock_filename, NULL);
   1.117  
   1.118 -	if (razor_set_aquire_lock(image->system, lock_path, 1) < 0) {
   1.119 -		razor_set_destroy(image->system);
   1.120 +	r = razor_set_aquire_lock(image->system, lock_path, 1);
   1.121 +
   1.122 +	free(lock_path);
   1.123 +
   1.124 +	if (r < 0) {
   1.125 +		razor_atomic_abort(atomic,
   1.126 +				   "Failed to aquire exclusive system lock");
   1.127 +		razor_set_unref(image->system);
   1.128  		free(image);
   1.129  		return NULL;
   1.130  	}
   1.131  
   1.132 -	snprintf(image->new_path, sizeof image->new_path,
   1.133 -		 "%s%s/%s", root, razor_root_path, system_tmp_filename);
   1.134 -	image->fd = open(image->new_path,
   1.135 -			 O_CREAT | O_WRONLY | O_TRUNC | O_BINARY,
   1.136 -			 0666);
   1.137 -	if (image->fd < 0) {
   1.138 -		razor_set_destroy(image->system);
   1.139 +	image->new_path = razor_concat(root, razor_root_path, "/",
   1.140 +				       system_tmp_filename, NULL);
   1.141 +	image->handle = razor_atomic_create_file(atomic, image->new_path,
   1.142 +						 S_IRWXU | S_IRWXG | S_IRWXO);
   1.143 +	if (image->handle < 0) {
   1.144 +		free(image->new_path);
   1.145 +		razor_set_unref(image->system);
   1.146  		free(image);
   1.147  		return NULL;
   1.148  	}
   1.149  
   1.150 -	snprintf(image->path, sizeof image->path,
   1.151 -		 "%s%s/%s", root, razor_root_path, system_repo_filename);
   1.152 +	image->path = razor_concat(root, razor_root_path, "/",
   1.153 +				   system_repo_filename, NULL);
   1.154  
   1.155 -	if (razor_set_bind_sections(image->system, image->path)) {
   1.156 -		close(image->fd);
   1.157 +	if (razor_set_bind_sections(image->system, atomic, image->path)) {
   1.158  		unlink(image->new_path);
   1.159 -		razor_set_destroy(image->system);
   1.160 +		free(image->new_path);
   1.161 +		free(image->path);
   1.162 +		razor_set_unref(image->system);
   1.163  		free(image);
   1.164  		return NULL;
   1.165  	}
   1.166 @@ -186,33 +201,41 @@
   1.167  }
   1.168  
   1.169  RAZOR_EXPORT struct razor_set *
   1.170 -razor_root_open_read_only(const char *root)
   1.171 +razor_root_open_read_only(const char *root, struct razor_atomic *atomic)
   1.172  {
   1.173 -	char path[PATH_MAX];
   1.174 +	char *path;
   1.175  	struct razor_set *set;
   1.176  
   1.177  	assert (root != NULL);
   1.178  
   1.179  	razor_root_init();
   1.180  	set = razor_set_create_without_root();
   1.181 -	if (set == NULL)
   1.182 -		return NULL;
   1.183 -
   1.184 -	snprintf(path, sizeof path,
   1.185 -		 "%s%s/%s", root, razor_root_path, system_lock_filename);
   1.186 -	if (razor_set_aquire_lock(set, path, 0) < 0) {
   1.187 -		razor_set_destroy(set);
   1.188 +	if (set == NULL) {
   1.189 +		razor_atomic_abort(atomic, "Not enough memory");
   1.190  		return NULL;
   1.191  	}
   1.192  
   1.193 -	snprintf(path, sizeof path, "%s%s/%s",
   1.194 -		 root, razor_root_path, system_repo_filename);
   1.195 -
   1.196 -	if (razor_set_bind_sections(set, path)) {
   1.197 -		razor_set_destroy(set);
   1.198 +	path = razor_concat(root, razor_root_path, "/", system_lock_filename,
   1.199 +			    NULL);
   1.200 +	if (razor_set_aquire_lock(set, path, 0) < 0) {
   1.201 +		razor_atomic_abort(atomic, "Failed to aquire non-exclusive "
   1.202 +					   "system lock");
   1.203 +		free(path);
   1.204 +		razor_set_unref(set);
   1.205  		return NULL;
   1.206  	}
   1.207  
   1.208 +	free(path);
   1.209 +	path = razor_concat(root, razor_root_path, "/", system_repo_filename,
   1.210 +			    NULL);
   1.211 +
   1.212 +	if (razor_set_bind_sections(set, atomic, path)) {
   1.213 +		razor_set_unref(set);
   1.214 +		set = NULL;
   1.215 +	}
   1.216 +
   1.217 +	free(path);
   1.218 +
   1.219  	return set;
   1.220  }
   1.221  
   1.222 @@ -229,9 +252,11 @@
   1.223  {
   1.224  	assert (root != NULL);
   1.225  
   1.226 -	razor_set_destroy(root->system);
   1.227 -	close(root->fd);
   1.228 -	unlink(root->new_path);
   1.229 +	razor_set_unref(root->system);
   1.230 +	razor_atomic_close(root->atomic, root->handle);
   1.231 +	razor_atomic_remove(root->atomic, root->new_path);
   1.232 +	free(root->path);
   1.233 +	free(root->new_path);
   1.234  	free(root);
   1.235  
   1.236  	return 0;
   1.237 @@ -244,13 +269,13 @@
   1.238  	assert (next != NULL);
   1.239  
   1.240  	razor_root_init();
   1.241 -	razor_set_write_to_fd(next, root->fd, RAZOR_SECTION_ALL);
   1.242 +	razor_set_write_to_handle(next, root->atomic, root->handle,
   1.243 +				  RAZOR_SECTION_ALL);
   1.244  	root->next = next;
   1.245  
   1.246  	/* Sync the new repo file so the new package set is on disk
   1.247  	 * before we start upgrading. */
   1.248 -	fsync(root->fd);
   1.249 -	printf("wrote %s\n", root->new_path);
   1.250 +	razor_atomic_sync(root->atomic, root->handle);
   1.251  }
   1.252  
   1.253  RAZOR_EXPORT int
   1.254 @@ -259,18 +284,12 @@
   1.255  	int retval;
   1.256  	assert (root != NULL);
   1.257  
   1.258 -	/* Make it so. */
   1.259 -	close(root->fd);
   1.260 -#ifdef MSWIN_API
   1.261 -	/* Rename is not atomic under MS-Windows */
   1.262 -	remove(root->path);
   1.263 -#endif
   1.264 -	retval = rename(root->new_path, root->path);
   1.265 -	if (retval)
   1.266 -		perror(root->path);
   1.267 -	else
   1.268 -		printf("renamed %s to %s\n", root->new_path, root->path);
   1.269 -	razor_set_destroy(root->system);
   1.270 +	razor_atomic_close(root->atomic, root->handle);
   1.271 +	retval = razor_atomic_rename_file(root->atomic, root->new_path,
   1.272 +					  root->path);
   1.273 +	razor_set_unref(root->system);
   1.274 +	free(root->path);
   1.275 +	free(root->new_path);
   1.276  	free(root);
   1.277  
   1.278  	return retval;