librazor/root.c
author Kristian H?gsberg <krh@redhat.com>
Fri Jun 20 16:48:44 2008 -0400 (2008-06-20)
changeset 249 061a5b815727
child 250 ce5402017488
child 258 29d5002bd17f
permissions -rw-r--r--
Rename razor_importer_new to _create to follow convention.
     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(path, &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, razor_root_path, 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_set *
   111 razor_root_open_read_only(const char *root)
   112 {
   113 	char path[PATH_MAX];
   114 
   115 	snprintf(path, sizeof path, "%s%s/%s",
   116 		 root, razor_root_path, system_repo_filename);
   117 
   118 	return razor_set_open(path);
   119 }
   120 
   121 struct razor_transaction *
   122 razor_root_create_transaction(struct razor_root *image,
   123 			      struct razor_set *upstream)
   124 {
   125 	/* FIXME: This should take a number of upstream repos. */
   126 	return razor_transaction_create(image->system, upstream);
   127 }
   128 
   129 int
   130 razor_root_close(struct razor_root *image)
   131 {
   132 	unlink(image->new_path);
   133 	close(image->fd);
   134 	free(image);
   135 
   136 	return 0;
   137 }
   138 
   139 void
   140 razor_root_update(struct razor_root *root, struct razor_set *next)
   141 {
   142 	razor_set_write_to_fd(next, root->fd);
   143 	root->next = next;
   144 
   145 	/* Sync the new repo file so the new package set is on disk
   146 	 * before we start upgrading. */
   147 	fsync(root->fd);
   148 	printf("wrote %s\n", root->new_path);
   149 }
   150 
   151 int
   152 razor_root_commit(struct razor_root *image)
   153 {
   154 	/* Make it so. */
   155 	rename(image->new_path, image->path);
   156 	printf("renamed %s to %s\n", image->new_path, image->path);
   157 	close(image->fd);
   158 	free(image);
   159 
   160 	return 0;
   161 }
   162 
   163 void
   164 razor_root_diff(struct razor_root *root,
   165 		razor_package_callback_t callback, void *data)
   166 {
   167 	return razor_set_diff(root->system, root->next, callback, data);
   168 }