- fix for sync conflicts (patch from VMiklos <vmiklos@frugalware.org>)
- sync code cleanup - added the deps check for targets to be removed in sync_prepare()
This commit is contained in:
parent
a6923f9aae
commit
7858f4c9b4
|
@ -338,10 +338,10 @@ static int ptr_cmp(const void *s1, const void *s2)
|
||||||
int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **data)
|
int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **data)
|
||||||
{
|
{
|
||||||
PMList *deps = NULL;
|
PMList *deps = NULL;
|
||||||
PMList *list = NULL;
|
PMList *list = NULL; /* list allowing checkdeps usage with data from trans->packages */
|
||||||
PMList *trail = NULL;
|
PMList *trail = NULL; /* breadcrum list to avoid running into circles */
|
||||||
PMList *asked = NULL;
|
PMList *asked = NULL;
|
||||||
PMList *i;
|
PMList *i, *j;
|
||||||
|
|
||||||
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
|
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
|
||||||
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
|
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
|
||||||
|
@ -383,7 +383,6 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
|
||||||
deps = checkdeps(db_local, PM_TRANS_TYPE_UPGRADE, list);
|
deps = checkdeps(db_local, PM_TRANS_TYPE_UPGRADE, list);
|
||||||
if(deps) {
|
if(deps) {
|
||||||
int found = 0;
|
int found = 0;
|
||||||
PMList *j, *k;
|
|
||||||
int errorout = 0;
|
int errorout = 0;
|
||||||
|
|
||||||
_alpm_log(PM_LOG_FLOW1, "looking for unresolvable dependencies");
|
_alpm_log(PM_LOG_FLOW1, "looking for unresolvable dependencies");
|
||||||
|
@ -411,6 +410,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
|
||||||
_alpm_log(PM_LOG_FLOW1, "looking for conflicts");
|
_alpm_log(PM_LOG_FLOW1, "looking for conflicts");
|
||||||
for(i = deps; i && !errorout; i = i->next) {
|
for(i = deps; i && !errorout; i = i->next) {
|
||||||
pmdepmissing_t *miss = i->data;
|
pmdepmissing_t *miss = i->data;
|
||||||
|
PMList *k;
|
||||||
if(miss->type != PM_DEP_TYPE_CONFLICT) {
|
if(miss->type != PM_DEP_TYPE_CONFLICT) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
|
||||||
*/
|
*/
|
||||||
for(j = trans->packages; j && !found; j = j->next) {
|
for(j = trans->packages; j && !found; j = j->next) {
|
||||||
pmsyncpkg_t *sync = j->data;
|
pmsyncpkg_t *sync = j->data;
|
||||||
if(sync->type == PM_SYNC_TYPE_REPLACE || sync->type == PM_SYNC_TYPE_REMOVE) {
|
if(sync->type == PM_SYNC_TYPE_REPLACE) {
|
||||||
for(k = sync->data; k && !found; k = k->next) {
|
for(k = sync->data; k && !found; k = k->next) {
|
||||||
pmpkg_t *p = k->data;
|
pmpkg_t *p = k->data;
|
||||||
if(!strcmp(p->name, miss->depend.name)) {
|
if(!strcmp(p->name, miss->depend.name)) {
|
||||||
|
@ -441,16 +441,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
|
||||||
* fields are inherited properly.
|
* fields are inherited properly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* we save the dependency info so we can move p's requiredby stuff
|
if(db_get_pkgfromcache(db_local, miss->depend.name) == NULL) {
|
||||||
* over to the replacing package
|
|
||||||
*/
|
|
||||||
pmpkg_t *q = db_scan(db_local, miss->depend.name, INFRQ_DESC | INFRQ_DEPENDS);
|
|
||||||
if(q) {
|
|
||||||
/* append to the replaces list */
|
|
||||||
pmsyncpkg_t *spkg = sync_new(PM_SYNC_TYPE_REPLACE, q, NULL);
|
|
||||||
trans->packages = pm_list_add(trans->packages, spkg);
|
|
||||||
solved = 1;
|
|
||||||
} else {
|
|
||||||
char *rmpkg = NULL;
|
char *rmpkg = NULL;
|
||||||
/* hmmm, depend.name isn't installed, so it must be conflicting
|
/* hmmm, depend.name isn't installed, so it must be conflicting
|
||||||
* with another package in our final list. For example:
|
* with another package in our final list. For example:
|
||||||
|
@ -492,16 +483,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
|
||||||
if(!solved) {
|
if(!solved) {
|
||||||
/* It's a conflict -- see if they want to remove it
|
/* It's a conflict -- see if they want to remove it
|
||||||
*/
|
*/
|
||||||
pmpkg_t *p,*q = NULL;
|
if(db_get_pkgfromcache(db_local, miss->depend.name)) {
|
||||||
int pkgfound = 0;
|
|
||||||
for(k = db_get_pkgcache(db_local); k; k = k->next) {
|
|
||||||
p = k->data;
|
|
||||||
if(!strcmp(p->name, miss->depend.name)) {
|
|
||||||
pkgfound = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(pkgfound) {
|
|
||||||
int doremove = 0;
|
int doremove = 0;
|
||||||
if(!pm_list_is_strin(miss->depend.name, asked)) {
|
if(!pm_list_is_strin(miss->depend.name, asked)) {
|
||||||
QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &doremove);
|
QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &doremove);
|
||||||
|
@ -512,8 +494,8 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
|
||||||
for(l = trans->packages; l; l = l->next) {
|
for(l = trans->packages; l; l = l->next) {
|
||||||
pmsyncpkg_t *s = l->data;
|
pmsyncpkg_t *s = l->data;
|
||||||
if(!strcmp(s->pkg->name, miss->target)) {
|
if(!strcmp(s->pkg->name, miss->target)) {
|
||||||
q = pkg_new();
|
pmpkg_t *q = pkg_new();
|
||||||
strcpy(q->name, miss->depend.name);
|
STRNCPY(q->name, miss->depend.name, PKG_NAME_LEN);
|
||||||
if(s->type == PM_SYNC_TYPE_REPLACE) {
|
if(s->type == PM_SYNC_TYPE_REPLACE) {
|
||||||
/* append to the replaces list */
|
/* append to the replaces list */
|
||||||
s->data = pm_list_add(s->data, q);
|
s->data = pm_list_add(s->data, q);
|
||||||
|
@ -550,27 +532,42 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
|
||||||
FREELISTPTR(list);
|
FREELISTPTR(list);
|
||||||
FREELISTPTR(trail);
|
FREELISTPTR(trail);
|
||||||
FREELIST(asked);
|
FREELIST(asked);
|
||||||
|
|
||||||
|
/* XXX: this fails for cases where a requested package wants
|
||||||
|
* a dependency that conflicts with an older version of
|
||||||
|
* the package. It will be removed from final, and the user
|
||||||
|
* has to re-request it to get it installed properly.
|
||||||
|
*
|
||||||
|
* Not gonna happen very often, but should be dealt with...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Check dependencies of packages in rmtargs and make sure
|
||||||
|
* we won't be breaking anything by removing them.
|
||||||
|
* If a broken dep is detected, make sure it's not from a
|
||||||
|
* package that's in our final (upgrade) list.
|
||||||
|
*/
|
||||||
|
/*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
|
||||||
|
for(i = trans->packages; i; i = i->next) {
|
||||||
|
pmsyncpkg_t *sync = i->data;
|
||||||
|
if(sync->type == PM_SYNC_TYPE_REPLACE) {
|
||||||
|
for(j = sync->data; j; j = j->next) {
|
||||||
|
list = pm_list_add(list, j->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "checking dependencies of packages designated for removal");
|
||||||
|
deps = checkdeps(db_local, PM_TRANS_TYPE_REMOVE, list);
|
||||||
|
if(deps) {
|
||||||
|
*data = deps;
|
||||||
|
pm_errno = PM_ERR_UNSATISFIED_DEPS;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
FREELISTPTR(list);
|
||||||
|
/*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* any packages in rmtargs need to be removed from final. */
|
|
||||||
/* rather than ripping out nodes from final, we just copy over */
|
|
||||||
/* our "good" nodes to a new list and reassign. */
|
|
||||||
|
|
||||||
/* XXX: this fails for cases where a requested package wants
|
|
||||||
* a dependency that conflicts with an older version of
|
|
||||||
* the package. It will be removed from final, and the user
|
|
||||||
* has to re-request it to get it installed properly.
|
|
||||||
*
|
|
||||||
* Not gonna happen very often, but should be dealt with...
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ORE
|
|
||||||
Check dependencies of packages in rmtargs and make sure
|
|
||||||
we won't be breaking anything by removing them.
|
|
||||||
If a broken dep is detected, make sure it's not from a
|
|
||||||
package that's in our final (upgrade) list. */
|
|
||||||
/*_alpm_log(PM_LOG_DEBUG, "checking dependencies of packages designated for removal");*/
|
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -596,11 +593,14 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
|
||||||
tr = trans_new();
|
tr = trans_new();
|
||||||
if(tr == NULL) {
|
if(tr == NULL) {
|
||||||
_alpm_log(PM_LOG_ERROR, "could not create removal transaction");
|
_alpm_log(PM_LOG_ERROR, "could not create removal transaction");
|
||||||
pm_errno = PM_ERR_XXX;
|
pm_errno = PM_ERR_MEMORY;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
trans_init(tr, PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS, NULL, NULL);
|
if(trans_init(tr, PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS, NULL, NULL) == -1) {
|
||||||
|
_alpm_log(PM_LOG_ERROR, "could not initialize the removal transaction");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
for(i = trans->packages; i; i = i->next) {
|
for(i = trans->packages; i; i = i->next) {
|
||||||
pmsyncpkg_t *sync = i->data;
|
pmsyncpkg_t *sync = i->data;
|
||||||
|
|
Loading…
Reference in New Issue