librazor/root.c
author Kristian H?gsberg <krh@redhat.com>
Fri Jun 20 21:56:43 2008 -0400 (2008-06-20)
changeset 254 ccb1c11968ab
parent 248 057933050c42
child 259 5b0601d184ed
permissions -rw-r--r--
Introduce install/remove iterators.

These iterator constructors lets you pass in two sets and creates
an iterator for the packages to remove or the packages to install.
The iterators will step through the packages in a sequence that respects
the pre, post, preun and postun modifiers.

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