Create the new repo file O_EXCL to prevent racing with another razor process.
authorKristian H?gsberg <krh@redhat.com>
Mon Apr 07 00:35:27 2008 -0400 (2008-04-07)
changeset 197d29026900856
parent 196 b38fc517ea04
child 198 d26bdf77569d
Create the new repo file O_EXCL to prevent racing with another razor process.

And remember to clean it up on exit paths.
main.c
razor.c
razor.h
     1.1 --- a/main.c	Mon Apr 07 00:06:22 2008 -0400
     1.2 +++ b/main.c	Mon Apr 07 00:35:27 2008 -0400
     1.3 @@ -5,6 +5,7 @@
     1.4  #include <string.h>
     1.5  #include <sys/stat.h>
     1.6  #include <unistd.h>
     1.7 +#include <fcntl.h>
     1.8  #include <dirent.h>
     1.9  #include <curl/curl.h>
    1.10  #include <fnmatch.h>
    1.11 @@ -530,33 +531,50 @@
    1.12  	struct razor_transaction *trans;
    1.13  	char path[PATH_MAX], new_path[PATH_MAX];
    1.14  	CURL *curl;
    1.15 -	int errors;
    1.16 +	int errors, fd;
    1.17 +
    1.18 +	/* Create the new next repo file up front to ensure exclusive
    1.19 +	 * access. */
    1.20 +	snprintf(new_path, sizeof new_path,
    1.21 +		 "%s%s/%s", root, razor_root_path, next_repo_filename);
    1.22 +	fd = open(new_path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666);
    1.23 +	if (fd < 0) {
    1.24 +		fprintf(stderr, "failed to get lock file, "
    1.25 +			"maybe previous operation crashed?\n");
    1.26 +
    1.27 +		/* FIXME: Use fcntl advisory locking to figure out
    1.28 +		 * whether previous operation crashed or is still in
    1.29 +		 * progress. */
    1.30 +
    1.31 +		return -1;
    1.32 +	}
    1.33  
    1.34  	upstream = razor_set_open(rawhide_repo_filename);
    1.35  	snprintf(path, sizeof path,
    1.36  		 "%s%s/%s", root, razor_root_path, system_repo_filename);
    1.37  	system = razor_set_open(path);
    1.38 -	if (system == NULL || upstream == NULL)
    1.39 +	if (system == NULL || upstream == NULL) {
    1.40 +		unlink(new_path);
    1.41  		return 1;
    1.42 +	}
    1.43  	trans = razor_transaction_create(system, upstream,
    1.44  					 argc, argv, 0, NULL);
    1.45  	errors = razor_transaction_describe(trans);
    1.46 -	if (errors)
    1.47 +	if (errors) {
    1.48 +		unlink(new_path);
    1.49  		return 1;
    1.50 +	}
    1.51  
    1.52  	next = razor_transaction_finish(trans);
    1.53  
    1.54 -	/* FIXME: Need razor_set_write_to_fd() so we can open it excl
    1.55 -	 * up front here or fail if it already exists. */
    1.56 -	snprintf(new_path, sizeof new_path,
    1.57 -		 "%s%s/%s", root, razor_root_path, next_repo_filename);
    1.58 -
    1.59 -	razor_set_write(next, new_path);
    1.60 +	razor_set_write_to_fd(next, fd);
    1.61  	printf("wrote %s\n", new_path);
    1.62  
    1.63  	curl = curl_easy_init();
    1.64 -	if (curl == NULL)
    1.65 +	if (curl == NULL) {
    1.66 +		unlink(new_path);
    1.67  		return 1;
    1.68 +	}
    1.69  	razor_set_diff(system, next, download_package, curl);	
    1.70  	curl_easy_cleanup(curl);
    1.71  
     2.1 --- a/razor.c	Mon Apr 07 00:06:22 2008 -0400
     2.2 +++ b/razor.c	Mon Apr 07 00:35:27 2008 -0400
     2.3 @@ -198,13 +198,13 @@
     2.4  }
     2.5  
     2.6  int
     2.7 -razor_set_write(struct razor_set *set, const char *filename)
     2.8 +razor_set_write_to_fd(struct razor_set *set, int fd)
     2.9  {
    2.10  	char data[4096];
    2.11  	struct razor_set_header *header = (struct razor_set_header *) data;
    2.12  	struct array *a;
    2.13  	uint32_t offset;
    2.14 -	int i, fd;
    2.15 +	int i;
    2.16  
    2.17  	memset(data, 0, sizeof data);
    2.18  	header->magic = RAZOR_MAGIC;
    2.19 @@ -225,10 +225,6 @@
    2.20  	header->sections[i].offset = 0;
    2.21  	header->sections[i].size = 0;
    2.22  
    2.23 -	fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
    2.24 -	if (fd < 0)
    2.25 -		return -1;
    2.26 -
    2.27  	razor_write(fd, data, sizeof data);
    2.28  	memset(data, 0, sizeof data);
    2.29  	for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
    2.30 @@ -239,11 +235,27 @@
    2.31  		razor_write(fd, data, ALIGN(a->size, 4096) - a->size);
    2.32  	}
    2.33  
    2.34 -	close(fd);
    2.35 -
    2.36  	return 0;
    2.37  }
    2.38  
    2.39 +int
    2.40 +razor_set_write(struct razor_set *set, const char *filename)
    2.41 +{
    2.42 +	int fd, status;
    2.43 +
    2.44 +	fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
    2.45 +	if (fd < 0)
    2.46 +		return -1;
    2.47 +
    2.48 +	status = razor_set_write_to_fd(set, fd);
    2.49 +	if (status) {
    2.50 +	    close(fd);
    2.51 +	    return status;
    2.52 +	}
    2.53 +
    2.54 +	return close(fd);
    2.55 +}
    2.56 +
    2.57  void
    2.58  razor_build_evr(char *evr_buf, int size, const char *epoch,
    2.59  		const char *version, const char *release)
     3.1 --- a/razor.h	Mon Apr 07 00:06:22 2008 -0400
     3.2 +++ b/razor.h	Mon Apr 07 00:35:27 2008 -0400
     3.3 @@ -26,6 +26,7 @@
     3.4  struct razor_set *razor_set_create(void);
     3.5  struct razor_set *razor_set_open(const char *filename);
     3.6  void razor_set_destroy(struct razor_set *set);
     3.7 +int razor_set_write_to_fd(struct razor_set *set, int fd);
     3.8  int razor_set_write(struct razor_set *set, const char *filename);
     3.9  
    3.10  struct razor_package *