diff -r 6a6462ce8a08 -r f960eb19dca2 librazor/root.c --- a/librazor/root.c Thu Oct 01 20:02:12 2009 +0100 +++ b/librazor/root.c Fri Jan 27 07:55:30 2012 +0000 @@ -1,7 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc - * Copyright (C) 2009 J. Ali Harlow + * Copyright (C) 2009, 2011 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,9 +60,9 @@ struct razor_root { struct razor_set *system; struct razor_set *next; - int fd; - char path[PATH_MAX]; - char new_path[PATH_MAX]; + struct razor_atomic *atomic; + int handle; + char *path, *new_path; }; static void @@ -83,9 +83,11 @@ RAZOR_EXPORT int razor_root_create(const char *root) { + int retval; struct stat buf; struct razor_set *set; - char path[PATH_MAX]; + struct razor_atomic *atomic; + char *path; assert (root != NULL); @@ -107,77 +109,90 @@ return -1; } - snprintf(path, sizeof path, "%s/%s", - razor_root_path, system_repo_filename); - if (razor_create_dir(root, path) < 0) { - fprintf(stderr, "could not create %s%s\n", - root, razor_root_path); - return -1; + path = razor_concat(root, razor_root_path, "/", system_repo_filename, + NULL); + retval = !stat(path, &buf); + free(path); + if (retval) { + fprintf(stderr, + "a razor install root is already initialized\n"); + return retval; } + atomic = razor_atomic_open("Create initial package set"); + path = razor_concat(razor_root_path, "/", system_repo_filename, NULL); + razor_atomic_make_dirs(atomic, root, path); set = razor_set_create(); - snprintf(path, sizeof path, "%s%s/%s", - root, razor_root_path, system_repo_filename); - if (stat(path, &buf) == 0) { - fprintf(stderr, - "a razor install root is already initialized\n"); - return -1; - } - if (razor_set_write(set, path, RAZOR_SECTION_ALL) < 0) { + razor_set_write(set, atomic, path, RAZOR_SECTION_ALL); + free(path); + retval = razor_atomic_commit(atomic); + if (retval) fprintf(stderr, "could not write initial package set\n"); - return -1; - } - razor_set_destroy(set); + razor_set_unref(set); + razor_atomic_destroy(atomic); - return 0; + return retval; } RAZOR_EXPORT struct razor_root * -razor_root_open(const char *root) +razor_root_open(const char *root, struct razor_atomic *atomic) { struct razor_root *image; - char lock_path[PATH_MAX]; + char *lock_path; + int r; assert (root != NULL); razor_root_init(); image = malloc(sizeof *image); - if (image == NULL) + if (image == NULL) { + razor_atomic_abort(atomic, "Not enough memory"); return NULL; + } + + image->atomic = atomic; image->system = razor_set_create_without_root(); if (image->system == NULL) { free(image); + razor_atomic_abort(atomic, "Not enough memory"); return NULL; } - snprintf(lock_path, sizeof lock_path, - "%s%s/%s", root, razor_root_path, system_lock_filename); + lock_path = razor_concat(root, razor_root_path, "/", + system_lock_filename, NULL); - if (razor_set_aquire_lock(image->system, lock_path, 1) < 0) { - razor_set_destroy(image->system); + r = razor_set_aquire_lock(image->system, lock_path, 1); + + free(lock_path); + + if (r < 0) { + razor_atomic_abort(atomic, + "Failed to aquire exclusive system lock"); + razor_set_unref(image->system); free(image); return NULL; } - snprintf(image->new_path, sizeof image->new_path, - "%s%s/%s", root, razor_root_path, system_tmp_filename); - image->fd = open(image->new_path, - O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, - 0666); - if (image->fd < 0) { - razor_set_destroy(image->system); + image->new_path = razor_concat(root, razor_root_path, "/", + system_tmp_filename, NULL); + image->handle = razor_atomic_create_file(atomic, image->new_path, + S_IRWXU | S_IRWXG | S_IRWXO); + if (image->handle < 0) { + free(image->new_path); + razor_set_unref(image->system); free(image); return NULL; } - snprintf(image->path, sizeof image->path, - "%s%s/%s", root, razor_root_path, system_repo_filename); + image->path = razor_concat(root, razor_root_path, "/", + system_repo_filename, NULL); - if (razor_set_bind_sections(image->system, image->path)) { - close(image->fd); + if (razor_set_bind_sections(image->system, atomic, image->path)) { unlink(image->new_path); - razor_set_destroy(image->system); + free(image->new_path); + free(image->path); + razor_set_unref(image->system); free(image); return NULL; } @@ -186,33 +201,41 @@ } RAZOR_EXPORT struct razor_set * -razor_root_open_read_only(const char *root) +razor_root_open_read_only(const char *root, struct razor_atomic *atomic) { - char path[PATH_MAX]; + char *path; struct razor_set *set; assert (root != NULL); razor_root_init(); set = razor_set_create_without_root(); - if (set == NULL) - return NULL; - - snprintf(path, sizeof path, - "%s%s/%s", root, razor_root_path, system_lock_filename); - if (razor_set_aquire_lock(set, path, 0) < 0) { - razor_set_destroy(set); + if (set == NULL) { + razor_atomic_abort(atomic, "Not enough memory"); return NULL; } - snprintf(path, sizeof path, "%s%s/%s", - root, razor_root_path, system_repo_filename); - - if (razor_set_bind_sections(set, path)) { - razor_set_destroy(set); + path = razor_concat(root, razor_root_path, "/", system_lock_filename, + NULL); + if (razor_set_aquire_lock(set, path, 0) < 0) { + razor_atomic_abort(atomic, "Failed to aquire non-exclusive " + "system lock"); + free(path); + razor_set_unref(set); return NULL; } + free(path); + path = razor_concat(root, razor_root_path, "/", system_repo_filename, + NULL); + + if (razor_set_bind_sections(set, atomic, path)) { + razor_set_unref(set); + set = NULL; + } + + free(path); + return set; } @@ -229,9 +252,11 @@ { assert (root != NULL); - razor_set_destroy(root->system); - close(root->fd); - unlink(root->new_path); + razor_set_unref(root->system); + razor_atomic_close(root->atomic, root->handle); + razor_atomic_remove(root->atomic, root->new_path); + free(root->path); + free(root->new_path); free(root); return 0; @@ -244,13 +269,13 @@ assert (next != NULL); razor_root_init(); - razor_set_write_to_fd(next, root->fd, RAZOR_SECTION_ALL); + razor_set_write_to_handle(next, root->atomic, root->handle, + RAZOR_SECTION_ALL); root->next = next; /* Sync the new repo file so the new package set is on disk * before we start upgrading. */ - fsync(root->fd); - printf("wrote %s\n", root->new_path); + razor_atomic_sync(root->atomic, root->handle); } RAZOR_EXPORT int @@ -259,18 +284,12 @@ int retval; assert (root != NULL); - /* Make it so. */ - close(root->fd); -#ifdef MSWIN_API - /* Rename is not atomic under MS-Windows */ - remove(root->path); -#endif - retval = rename(root->new_path, root->path); - if (retval) - perror(root->path); - else - printf("renamed %s to %s\n", root->new_path, root->path); - razor_set_destroy(root->system); + razor_atomic_close(root->atomic, root->handle); + retval = razor_atomic_rename_file(root->atomic, root->new_path, + root->path); + razor_set_unref(root->system); + free(root->path); + free(root->new_path); free(root); return retval;