Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Allow upgrade process to be splitted.
Vsevolod Stakhov committed 12 years ago
commit 55ade1d4b463d1886cadad8e484b590ab6aaf289
parent 634ec4d
5 files changed +80 -58
modified libpkg/pkg.h.in
@@ -513,6 +513,7 @@ typedef enum {
	PKG_SOLVED_INSTALL,
	PKG_SOLVED_DELETE,
	PKG_SOLVED_UPGRADE,
+
	PKG_SOLVED_UPGRADE_REMOVE,
	PKG_SOLVED_FETCH
} pkg_solved_t;

modified libpkg/pkg_jobs.c
@@ -293,7 +293,7 @@ pkg_jobs_update_universe_priority(struct pkg_jobs *j,
 */
static int
pkg_jobs_handle_pkg_universe(struct pkg_jobs *j, struct pkg *pkg,
-
		int priority, struct pkg_job_universe_item **found)
+
		int *priority, struct pkg_job_universe_item **found)
{
	struct pkg_job_universe_item *item, *cur, *tmp = NULL;
	const char *origin, *digest, *version, *name;
@@ -324,16 +324,18 @@ pkg_jobs_handle_pkg_universe(struct pkg_jobs *j, struct pkg *pkg,
	HASH_FIND_STR(j->seen, digest, seen);
	if (seen != NULL) {
		cur = seen->un;
-
		if (priority > cur->priority)
-
			pkg_jobs_update_universe_priority(j, cur, priority, "found in seen",
+
		if (*priority > cur->priority)
+
			pkg_jobs_update_universe_priority(j, cur, *priority, "found in seen",
					false);
+
		else if (*priority < cur->priority)
+
			*priority = cur->priority;
		*found = seen->un;
		return (EPKG_END);
	}

	pkg_debug(2, "universe: add new %s pkg: %s(%d), (%s-%s)",
				(pkg->type == PKG_INSTALLED ? "local" : "remote"), origin,
-
				priority, name, version);
+
				*priority, name, version);

	item = calloc(1, sizeof (struct pkg_job_universe_item));
	if (item == NULL) {
@@ -342,12 +344,19 @@ pkg_jobs_handle_pkg_universe(struct pkg_jobs *j, struct pkg *pkg,
	}

	item->pkg = pkg;
-
	item->priority = priority;
+
	item->priority = *priority;

	HASH_FIND_STR(j->universe, origin, tmp);
	if (tmp == NULL) {
		HASH_ADD_KEYPTR(hh, j->universe, origin, strlen(origin), item);
	}
+
	else {
+
		if (tmp->priority > *priority)
+
			*priority = tmp->priority;
+
		else if (tmp->priority < *priority)
+
			pkg_jobs_update_universe_priority(j, tmp, *priority, "same origin",
+
					false);
+
	}

	DL_APPEND(tmp, item);

@@ -375,7 +384,7 @@ pkg_jobs_add_universe(struct pkg_jobs *j, struct pkg *pkg, int priority, bool re
	int maxpri;

	/* Add the requested package itself */
-
	ret = pkg_jobs_handle_pkg_universe(j, pkg, priority, &local);
+
	ret = pkg_jobs_handle_pkg_universe(j, pkg, &priority, &local);

	if (ret == EPKG_END)
		return (EPKG_OK);
@@ -633,29 +642,28 @@ find_remote_pkg(struct pkg_jobs *j, const char *pattern,
		pkg_get(p, PKG_ORIGIN, &origin);
		HASH_FIND_STR(j->universe, origin, jit);
		if (jit != NULL) {
-
			p1 = jit->pkg;
-
			seen = true;
-
		}
-

-
		if (p1 != NULL) {
-
			pkg_get(p1, PKG_VERSION, &buf1);
-
			pkg_get(p, PKG_VERSION, &buf2);
			p->direct = root;
			/* We have a more recent package */
-
			if (!pkg_need_upgrade(p, p1, false)) {
+
			if (!pkg_need_upgrade(p, jit->pkg, false)) {
				if (root)
					pkg_emit_already_installed(p);
				rc = EPKG_INSTALLED;
				continue;
			}
+
			if (jit->priority > priority)
+
				priority = jit->priority;
+
			else
+
				pkg_jobs_update_universe_priority(j, jit, priority,
+
						"remote found", false);
		}
-

-
		if (j->type != PKG_JOBS_FETCH) {
-
			if (!newer_than_local_pkg(j, p, force)) {
-
				if (root)
-
					pkg_emit_already_installed(p);
-
				rc = EPKG_INSTALLED;
-
				continue;
+
		else {
+
			if (j->type != PKG_JOBS_FETCH) {
+
				if (!newer_than_local_pkg(j, p, force)) {
+
					if (root)
+
						pkg_emit_already_installed(p);
+
					rc = EPKG_INSTALLED;
+
					continue;
+
				}
			}
		}

@@ -1299,18 +1307,6 @@ jobs_solve_fetch(struct pkg_jobs *j)
static int
pkg_jobs_sort_priority(struct pkg_solved *r1, struct pkg_solved *r2)
{
-
	/* Always execute delete requests before install or upgrade */
-
	if (r1->type == PKG_SOLVED_DELETE && r2->type != PKG_SOLVED_DELETE) {
-
		return -1;
-
	}
-
	else if (r1->type != PKG_SOLVED_DELETE && r2->type == PKG_SOLVED_DELETE) {
-
		return 1;
-
	}
-
	else if (r1->type == PKG_SOLVED_DELETE && r2->type == PKG_SOLVED_DELETE) {
-
		/* Inverse deletion priority */
-
		return (r1->priority - r2->priority);
-
	}
-

	return (r2->priority - r1->priority);
}

@@ -1429,10 +1425,10 @@ pkg_jobs_type(struct pkg_jobs *j)
}

static int
-
pkg_jobs_handle_install(struct pkg *new, struct pkg *old, struct pkg_jobs *j, bool handle_rc,
+
pkg_jobs_handle_install(struct pkg_solved *ps, struct pkg_jobs *j, bool handle_rc,
		const char *cachedir, struct pkg_manifest_key *keys)
{
-
	struct pkg *newpkg = NULL;
+
	struct pkg *newpkg = NULL, *new, *old;
	const char *pkgorigin, *oldversion = NULL;
	struct pkg_note *an;
	char path[MAXPATHLEN];
@@ -1440,6 +1436,9 @@ pkg_jobs_handle_install(struct pkg *new, struct pkg *old, struct pkg_jobs *j, bo
	int flags = 0;
	int retcode = EPKG_FATAL;

+
	old = ps->pkg[1];
+
	new = ps->pkg[0];
+

	pkg_get(new, PKG_ORIGIN, &pkgorigin,
				PKG_AUTOMATIC, &automatic);
	if (old != NULL)
@@ -1471,7 +1470,7 @@ pkg_jobs_handle_install(struct pkg *new, struct pkg *old, struct pkg_jobs *j, bo
	if (automatic)
		flags |= PKG_ADD_AUTOMATIC;

-
	if (old != NULL) {
+
	if (old != NULL && !ps->already_deleted) {
		if ((retcode = pkg_delete(old, j->db, PKG_DELETE_UPGRADE)) != EPKG_OK) {
			pkgdb_transaction_rollback(j->db->sqlite, "upgrade");
			goto cleanup;
@@ -1534,6 +1533,7 @@ pkg_jobs_execute(struct pkg_jobs *j)
	DL_FOREACH(j->jobs, ps) {
		switch (ps->type) {
		case PKG_SOLVED_DELETE:
+
		case PKG_SOLVED_UPGRADE_REMOVE:
			p = ps->pkg[0];
			pkg_get(p, PKG_NAME, &name);
			if ((strcmp(name, "pkg") == 0 ||
@@ -1553,13 +1553,13 @@ pkg_jobs_execute(struct pkg_jobs *j)
				goto cleanup;
			break;
		case PKG_SOLVED_INSTALL:
-
			retcode = pkg_jobs_handle_install(ps->pkg[0], NULL,
+
			retcode = pkg_jobs_handle_install(ps,
					j, handle_rc, cachedir, keys);
			if (retcode != EPKG_OK)
				goto cleanup;
			break;
		case PKG_SOLVED_UPGRADE:
-
			retcode = pkg_jobs_handle_install(ps->pkg[0], ps->pkg[1],
+
			retcode = pkg_jobs_handle_install(ps,
					j, handle_rc, cachedir, keys);
			if (retcode != EPKG_OK)
				goto cleanup;
@@ -1669,7 +1669,7 @@ pkg_jobs_apply(struct pkg_jobs *j)

#define PKG_JOBS_FETCH_CALCULATE(list) do {										\
	DL_FOREACH((list), ps) {														\
-
		if (ps->type != PKG_SOLVED_DELETE) {										\
+
		if (ps->type != PKG_SOLVED_DELETE && ps->type != PKG_SOLVED_UPGRADE_REMOVE) {\
			p = ps->pkg[0];															\
			int64_t pkgsize;														\
			pkg_get(p, PKG_PKGSIZE, &pkgsize, PKG_REPOPATH, &repopath);				\
@@ -1684,7 +1684,7 @@ pkg_jobs_apply(struct pkg_jobs *j)

#define PKG_JOBS_DO_FETCH(list) do {												\
	DL_FOREACH((list), ps) {														\
-
		if (ps->type != PKG_SOLVED_DELETE) {										\
+
		if (ps->type != PKG_SOLVED_DELETE && ps->type != PKG_SOLVED_UPGRADE_REMOVE) {\
			p = ps->pkg[0];															\
			if (pkg_repo_fetch(p) != EPKG_OK)										\
				return (EPKG_FATAL);												\
@@ -1764,7 +1764,7 @@ pkg_jobs_check_conflicts(struct pkg_jobs *j)

	pkg_manifest_keys_new(&keys);
	DL_FOREACH(j->jobs, ps) {
-
		if (ps->type == PKG_SOLVED_DELETE) {
+
		if (ps->type == PKG_SOLVED_DELETE || ps->type == PKG_SOLVED_UPGRADE_REMOVE) {
			continue;
		}
		else {
modified libpkg/pkg_solve.c
@@ -234,7 +234,7 @@ pkg_solve_test_guess(struct pkg_solve_problem *problem)
	HASH_ITER(hd, problem->variables_by_digest, var, tvar) {
		LL_FOREACH(var->rules, rul) {
			it = rul->rule;
-
			if (true) {
+
			if (it->nitems != it->nresolved) {
				/* Check guess */
				test = false;
				LL_FOREACH(it, cur) {
@@ -288,7 +288,7 @@ pkg_solve_sat_problem(struct pkg_solve_problem *problem)
				break;
			}
			else {
-
				tvar->guess = !tvar->guess;
+
				var->guess = !var->guess;
				if (pkg_solve_test_guess(problem)) {
					guessed = true;
					break;
@@ -449,14 +449,15 @@ pkg_solve_add_universe_variable(struct pkg_jobs *j,

static int
pkg_solve_add_var_rules (struct pkg_solve_variable *var,
-
		struct pkg_solve_item *rule, int nrules, bool iterate_vars)
+
		struct pkg_solve_item *rule, int nrules, bool iterate_vars,
+
		const char *desc)
{
	struct _pkg_solve_var_rule *head = NULL;
	struct pkg_solve_variable *tvar;

	LL_FOREACH(var, tvar) {
-
		pkg_debug(4, "solver: add %d-ary clause to variable %s-%s: %d",
-
				nrules, tvar->origin, tvar->digest, rule->inverse);
+
		pkg_debug(4, "solver: add %d-ary %s clause to variable %s-%s: %d",
+
				nrules, desc, tvar->origin, tvar->digest, rule->inverse);
		tvar->nrules += nrules;
		head = calloc(1, sizeof (struct _pkg_solve_var_rule));
		if (head == NULL) {
@@ -527,8 +528,8 @@ pkg_solve_add_pkg_rule(struct pkg_jobs *j, struct pkg_solve_problem *problem,
				RULE_ITEM_PREPEND(rule, it);
				cnt ++;
			}
-
			pkg_solve_add_var_rules (var, rule->items, cnt, true);
-
			pkg_solve_add_var_rules (cur_var, rule->items, cnt, false);
+
			pkg_solve_add_var_rules (var, rule->items, cnt, true, "dependency");
+
			pkg_solve_add_var_rules (cur_var, rule->items, cnt, false, "dependency");

			LL_PREPEND(problem->rules, rule);
			problem->rules_count ++;
@@ -551,7 +552,7 @@ pkg_solve_add_pkg_rule(struct pkg_jobs *j, struct pkg_solve_problem *problem,
				HASH_FIND_STR(tvar->pkg->conflicts, origin, cfound);
				if (cfound == NULL) {
					/* Skip non-mutual conflicts */
-
					//continue;
+
					continue;
				}
				/* Conflict rule: (!A | !Bx) */
				rule = pkg_solve_rule_new();
@@ -574,8 +575,8 @@ pkg_solve_add_pkg_rule(struct pkg_jobs *j, struct pkg_solve_problem *problem,

				LL_PREPEND(problem->rules, rule);
				problem->rules_count ++;
-
				pkg_solve_add_var_rules (tvar, rule->items, 2, false);
-
				pkg_solve_add_var_rules (cur_var, rule->items, 2, false);
+
				pkg_solve_add_var_rules (tvar, rule->items, 2, false, "conflict");
+
				pkg_solve_add_var_rules (cur_var, rule->items, 2, false, "conflict");
			}
		}

@@ -610,8 +611,8 @@ pkg_solve_add_pkg_rule(struct pkg_jobs *j, struct pkg_solve_problem *problem,
					LL_PREPEND(problem->rules, rule);
					problem->rules_count ++;

-
					pkg_solve_add_var_rules (tvar, rule->items, 2, true);
-
					pkg_solve_add_var_rules (cur_var, rule->items, 2, false);
+
					pkg_solve_add_var_rules (tvar, rule->items, 2, false, "chain conflict");
+
					pkg_solve_add_var_rules (cur_var, rule->items, 2, false, "chain conflict");
				}
			}
		}
@@ -679,7 +680,7 @@ pkg_solve_jobs_to_sat(struct pkg_jobs *j)

		/* Requests are unary rules */
		RULE_ITEM_PREPEND(rule, it);
-
		pkg_solve_add_var_rules (var, it, 1, false);
+
		pkg_solve_add_var_rules (var, it, 1, false, "unary add");
		LL_PREPEND(problem->rules, rule);
		problem->rules_count ++;
	}
@@ -717,7 +718,7 @@ pkg_solve_jobs_to_sat(struct pkg_jobs *j)
		/* Requests are unary rules */
		RULE_ITEM_PREPEND(rule, it);
		LL_PREPEND(problem->rules, rule);
-
		pkg_solve_add_var_rules (var, it, 1, false);
+
		pkg_solve_add_var_rules (var, it, 1, false, "unary del");
		problem->rules_count ++;
	}

@@ -814,7 +815,7 @@ static void
pkg_solve_insert_res_job (struct pkg_solve_variable *var,
		struct pkg_solve_problem *problem, struct pkg_jobs *j)
{
-
	struct pkg_solved *res;
+
	struct pkg_solved *res, *dres;
	struct pkg_solve_variable *cur_var, *del_var = NULL, *add_var = NULL;
	int seen_add = 0, seen_del = 0;

@@ -856,12 +857,27 @@ pkg_solve_insert_res_job (struct pkg_solve_variable *var,
					add_var->origin, res->priority, add_var->digest);
		}
		else {
-
			res->priority = MAX(del_var->priority, add_var->priority);
+
			assert(del_var->priority >= add_var->priority);
+
			if (del_var->priority > add_var->priority) {
+
				dres = calloc(1, sizeof(struct pkg_solved));
+
				if (dres == NULL) {
+
					pkg_emit_errno("calloc", "pkg_solved");
+
					return;
+
				}
+
				dres->priority = del_var->priority;
+
				dres->pkg[0] = del_var->pkg;
+
				dres->pkg[1] = add_var->pkg;
+
				dres->type = PKG_SOLVED_UPGRADE_REMOVE;
+
				DL_APPEND(j->jobs, dres);
+
				res->already_deleted = true;
+
			}
+
			res->priority = add_var->priority;
			res->pkg[0] = add_var->pkg;
			res->pkg[1] = del_var->pkg;
			res->type = PKG_SOLVED_UPGRADE;
			DL_APPEND(j->jobs, res);
-
			pkg_debug(3, "pkg_solve: schedule upgrade of %s(%d->%d) from %s to %s",
+
			pkg_debug(3, "pkg_solve: schedule upgrade(%s) of %s(%d->%d) from %s to %s",
+
					res->already_deleted ? "delayed" : "immediate",
					del_var->origin, del_var->priority,
					add_var->priority, del_var->digest, add_var->digest);
		}
modified libpkg/private/pkg.h
@@ -207,6 +207,7 @@ struct pkg_solved {
	struct pkg *pkg[2];
	int priority;
	pkg_solved_t type;
+
	bool already_deleted;
	struct pkg_solved *prev, *next;
};

modified src/utils.c
@@ -569,6 +569,7 @@ print_jobs_summary_pkg(struct pkg *new_pkg, struct pkg *old_pkg,
			}
			break;
		case PKG_SOLVED_DELETE:
+
		case PKG_SOLVED_UPGRADE_REMOVE:
			printf("and may not be deinstalled\n");
			return;
			break;
@@ -630,6 +631,9 @@ print_jobs_summary_pkg(struct pkg *new_pkg, struct pkg *old_pkg,

		pkg_printf("\tRemoving %n-%v\n", new_pkg, new_pkg);
		break;
+
	case PKG_SOLVED_UPGRADE_REMOVE:
+
		pkg_printf("\tRemoving old version of %n-%v\n", new_pkg, new_pkg);
+
		break;
	case PKG_SOLVED_FETCH:
		*dlsize += pkgsize;
		pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, new_pkg);