# HG changeset patch # User Kristian H?gsberg # Date 1207542927 14400 # Node ID d290269008563b1c6b57a1413dbdf47df5af353f # Parent b38fc517ea046a162e21263daa32af1b01be9ab0 Create the new repo file O_EXCL to prevent racing with another razor process. And remember to clean it up on exit paths. diff -r b38fc517ea04 -r d29026900856 main.c --- a/main.c Mon Apr 07 00:06:22 2008 -0400 +++ b/main.c Mon Apr 07 00:35:27 2008 -0400 @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -530,33 +531,50 @@ struct razor_transaction *trans; char path[PATH_MAX], new_path[PATH_MAX]; CURL *curl; - int errors; + int errors, fd; + + /* Create the new next repo file up front to ensure exclusive + * access. */ + snprintf(new_path, sizeof new_path, + "%s%s/%s", root, razor_root_path, next_repo_filename); + fd = open(new_path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666); + if (fd < 0) { + fprintf(stderr, "failed to get lock file, " + "maybe previous operation crashed?\n"); + + /* FIXME: Use fcntl advisory locking to figure out + * whether previous operation crashed or is still in + * progress. */ + + return -1; + } upstream = razor_set_open(rawhide_repo_filename); snprintf(path, sizeof path, "%s%s/%s", root, razor_root_path, system_repo_filename); system = razor_set_open(path); - if (system == NULL || upstream == NULL) + if (system == NULL || upstream == NULL) { + unlink(new_path); return 1; + } trans = razor_transaction_create(system, upstream, argc, argv, 0, NULL); errors = razor_transaction_describe(trans); - if (errors) + if (errors) { + unlink(new_path); return 1; + } next = razor_transaction_finish(trans); - /* FIXME: Need razor_set_write_to_fd() so we can open it excl - * up front here or fail if it already exists. */ - snprintf(new_path, sizeof new_path, - "%s%s/%s", root, razor_root_path, next_repo_filename); - - razor_set_write(next, new_path); + razor_set_write_to_fd(next, fd); printf("wrote %s\n", new_path); curl = curl_easy_init(); - if (curl == NULL) + if (curl == NULL) { + unlink(new_path); return 1; + } razor_set_diff(system, next, download_package, curl); curl_easy_cleanup(curl); diff -r b38fc517ea04 -r d29026900856 razor.c --- a/razor.c Mon Apr 07 00:06:22 2008 -0400 +++ b/razor.c Mon Apr 07 00:35:27 2008 -0400 @@ -198,13 +198,13 @@ } int -razor_set_write(struct razor_set *set, const char *filename) +razor_set_write_to_fd(struct razor_set *set, int fd) { char data[4096]; struct razor_set_header *header = (struct razor_set_header *) data; struct array *a; uint32_t offset; - int i, fd; + int i; memset(data, 0, sizeof data); header->magic = RAZOR_MAGIC; @@ -225,10 +225,6 @@ header->sections[i].offset = 0; header->sections[i].size = 0; - fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); - if (fd < 0) - return -1; - razor_write(fd, data, sizeof data); memset(data, 0, sizeof data); for (i = 0; i < ARRAY_SIZE(razor_sections); i++) { @@ -239,11 +235,27 @@ razor_write(fd, data, ALIGN(a->size, 4096) - a->size); } - close(fd); - return 0; } +int +razor_set_write(struct razor_set *set, const char *filename) +{ + int fd, status; + + fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); + if (fd < 0) + return -1; + + status = razor_set_write_to_fd(set, fd); + if (status) { + close(fd); + return status; + } + + return close(fd); +} + void razor_build_evr(char *evr_buf, int size, const char *epoch, const char *version, const char *release) diff -r b38fc517ea04 -r d29026900856 razor.h --- a/razor.h Mon Apr 07 00:06:22 2008 -0400 +++ b/razor.h Mon Apr 07 00:35:27 2008 -0400 @@ -26,6 +26,7 @@ struct razor_set *razor_set_create(void); struct razor_set *razor_set_open(const char *filename); void razor_set_destroy(struct razor_set *set); +int razor_set_write_to_fd(struct razor_set *set, int fd); int razor_set_write(struct razor_set *set, const char *filename); struct razor_package *