1.1 --- a/librazor/root.c Thu Oct 01 20:02:12 2009 +0100
1.2 +++ b/librazor/root.c Thu Nov 10 10:35:21 2011 +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;