razor-root.c
author Kristian H?gsberg <krh@redhat.com>
Mon Jun 09 16:14:05 2008 -0400 (2008-06-09)
changeset 234 7f5d32472bef
child 235 060d83d8eca9
permissions -rw-r--r--
Move razor root code to its own file.
     1 #include <stdlib.h>
     2 #include <stdint.h>
     3 #include <stdio.h>
     4 #include <sys/stat.h>
     5 #include <dirent.h>
     6 #include <unistd.h>
     7 #include <fcntl.h>
     8 #include "razor.h"
     9 #include "razor-internal.h"
    10 
    11 static const char system_repo_filename[] = "system.repo";
    12 static const char next_repo_filename[] = "system-next.repo";
    13 static const char razor_root_path[] = "/var/lib/razor";
    14 
    15 struct razor_root {
    16 	struct razor_set *system;
    17 	struct razor_set *next;
    18 	int fd;
    19 	char path[PATH_MAX];
    20 	char new_path[PATH_MAX];
    21 };
    22 
    23 int
    24 razor_root_create(const char *root)
    25 {	
    26 	struct stat buf;
    27 	struct razor_set *set;
    28 	char path[PATH_MAX];
    29 
    30 	if (stat(root, &buf) < 0) {
    31 		if (mkdir(root, 0777) < 0) {
    32 			fprintf(stderr,
    33 				"could not create install root \"%s\"\n",
    34 				root);
    35 			return -1;
    36 		}
    37 		fprintf(stderr, "created install root \"%s\"\n", root);
    38 	} else if (!S_ISDIR(buf.st_mode)) {
    39 		fprintf(stderr,
    40 			"install root \"%s\" exists, but is not a directory\n",
    41 			root);
    42 		return -1;
    43 	}
    44 
    45 	snprintf(path, sizeof path, "%s/%s",
    46 		 razor_root_path, system_repo_filename);
    47 	if (razor_create_dir(root, path) < 0) {
    48 		fprintf(stderr, "could not create %s%s\n",
    49 			root, razor_root_path);
    50 		return -1;
    51 	}
    52 
    53 	set = razor_set_create();
    54 	snprintf(path, sizeof path, "%s%s/%s",
    55 		 root, razor_root_path, system_repo_filename);
    56 	if (stat(root, &buf) == 0) {
    57 		fprintf(stderr,
    58 			"a razor install root is already initialized\n");
    59 		return -1;
    60 	}
    61 	if (razor_set_write(set, path) < 0) {
    62 		fprintf(stderr, "could not write initial package set\n");
    63 		return -1;
    64 	}
    65 	razor_set_destroy(set);
    66 
    67 	return 0;
    68 }
    69 
    70 struct razor_root *
    71 razor_root_open(const char *root, int flags)
    72 {
    73 	struct razor_root *image;
    74 
    75 	image = malloc(sizeof *image);
    76 	if (image == NULL)
    77 		return NULL;
    78 
    79 	/* Create the new next repo file up front to ensure exclusive
    80 	 * access. */
    81 	snprintf(image->new_path, sizeof image->new_path,
    82 		 "%s%s/%s", root, root, next_repo_filename);
    83 	image->fd = open(image->new_path,
    84 			 O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666);
    85 	if (image->fd < 0) {
    86 		fprintf(stderr, "failed to get lock file, "
    87 			"maybe previous operation crashed?\n");
    88 
    89 		/* FIXME: Use fcntl advisory locking on the system
    90 		 * package set file to figure out whether previous
    91 		 * operation crashed or is still in progress. */
    92 
    93 		free(image);
    94 		return NULL;
    95 	}
    96 
    97 	snprintf(image->path, sizeof image->path,
    98 		 "%s%s/%s", root, razor_root_path, system_repo_filename);
    99 	image->system = razor_set_open(image->path);
   100 	if (image->system == NULL) {
   101 		unlink(image->new_path);
   102 		close(image->fd);
   103 		free(image);
   104 		return NULL;
   105 	}
   106 
   107 	return image;
   108 }
   109 
   110 struct razor_transaction *
   111 razor_root_create_transaction(struct razor_root *image,
   112 			      struct razor_set *upstream)
   113 {
   114 	/* FIXME: This should take a number of upstream repos. */
   115 	return razor_transaction_create(image->system, upstream);
   116 }
   117 
   118 int
   119 razor_root_close(struct razor_root *image)
   120 {
   121 	unlink(image->new_path);
   122 	close(image->fd);
   123 	free(image);
   124 
   125 	return 0;
   126 }
   127 
   128 void
   129 razor_root_update(struct razor_root *root, struct razor_set *next)
   130 {
   131 	razor_set_write_to_fd(next, root->fd);
   132 	root->next = next;
   133 
   134 	/* Sync the new repo file so the new package set is on disk
   135 	 * before we start upgrading. */
   136 	fsync(root->fd);
   137 	printf("wrote %s\n", root->new_path);
   138 }
   139 
   140 int
   141 razor_root_commit(struct razor_root *image)
   142 {
   143 	/* Make it so. */
   144 	rename(image->new_path, image->path);
   145 	printf("renamed %s to %s\n", image->new_path, image->path);
   146 	close(image->fd);
   147 	free(image);
   148 
   149 	return 0;
   150 }
   151 
   152 void
   153 razor_root_diff(struct razor_root *root,
   154 		razor_package_callback_t callback, void *data)
   155 {
   156 	return razor_set_diff(root->system, root->next, callback, data);
   157 }