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