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