From: Michael Schroeder Date: Wed, 7 May 2008 15:18:01 +0000 (+0000) Subject: - add rpmdbcookie support X-Git-Tag: BASE-SuSE-Code-12_1-Branch~308^2~369 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ccae3859358e9518cb67b101d0b62138f7554eb;p=thirdparty%2Flibsolv.git - add rpmdbcookie support --- diff --git a/src/knownid.h b/src/knownid.h index ce0876ff..866d262e 100644 --- a/src/knownid.h +++ b/src/knownid.h @@ -53,6 +53,7 @@ KNOWNID(REPODATA_EXTERNAL, "repodata:external"), KNOWNID(REPODATA_KEYS, "repodata:keys"), KNOWNID(REPODATA_LOCATION, "repodata:location"), KNOWNID(REPODATA_ADDEDFILEPROVIDES, "repodata:addedfileprovides"), +KNOWNID(REPODATA_RPMDBCOOKIE, "repodata:rpmdbcookie"), /* The void type is usable to encode one-valued attributes, they have no associated data. This is useful to encode values which many solvables diff --git a/src/repo.h b/src/repo.h index f56d7add..ab0e7611 100644 --- a/src/repo.h +++ b/src/repo.h @@ -48,6 +48,7 @@ typedef struct _Repo { Offset lastoff; Id *rpmdbid; /* hmm, go to repodata? */ + unsigned char rpmdbcookie[32]; Repodata *repodata; /* our stores for non-solvable related data */ unsigned nrepodata; /* number of our stores.. */ diff --git a/src/repo_solv.c b/src/repo_solv.c index 8822dcc4..85e71e68 100644 --- a/src/repo_solv.c +++ b/src/repo_solv.c @@ -585,6 +585,13 @@ parse_info_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsi } continue; } + if (id == REPODATA_RPMDBCOOKIE && keys[key].type == REPOKEY_TYPE_SHA256) + { + int i; + for (i = 0; i < 32; i++) + maindata->repo->rpmdbcookie[i] = read_u8(maindata); + continue; + } skip_item(maindata, keys[key].type, numid, numrel); } } diff --git a/tools/common_write.c b/tools/common_write.c index 7be42d2b..884b4179 100644 --- a/tools/common_write.c +++ b/tools/common_write.c @@ -169,7 +169,9 @@ tool_write(Repo *repo, const char *basename, const char *attrname) fileinfos = sat_zextend(fileinfos, nfileinfos, 1, sizeof(Repodatafile), REPODATAFILE_BLOCK); pool_addfileprovides_ids(repo->pool, 0, &fileinfos[nfileinfos].addedfileprovides); - if (fileinfos[nfileinfos].addedfileprovides) + if (repo->rpmdbcookie) + fileinfos[nfileinfos].rpmdbcookie = repo->rpmdbcookie; + if (fileinfos[nfileinfos].addedfileprovides || fileinfos[nfileinfos].rpmdbcookie) nfileinfos++; if (basename) diff --git a/tools/dumpsolv.c b/tools/dumpsolv.c index aaa85912..ffc624c0 100644 --- a/tools/dumpsolv.c +++ b/tools/dumpsolv.c @@ -22,6 +22,16 @@ dump_repodata (Repo *repo) Repodata *data; if (repo->nrepodata == 0) return; + for (i = 0; i < 32; i++) + if (repo->rpmdbcookie[i]) + break; + if (i < 32) + { + printf("rpmdb cookie: "); + for (i = 0; i < 32; i++) + printf("%02x", repo->rpmdbcookie[i]); + printf("\n"); + } printf("repo refers to %d subfiles:\n", repo->nrepodata); for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) { diff --git a/tools/repo_rpmdb.c b/tools/repo_rpmdb.c index 48a02d55..db37da52 100644 --- a/tools/repo_rpmdb.c +++ b/tools/repo_rpmdb.c @@ -30,6 +30,7 @@ #include "util.h" #include "repo_rpmdb.h" +#define RPMDB_COOKIE_VERSION 1 #define TAG_NAME 1000 #define TAG_VERSION 1001 @@ -1128,6 +1129,15 @@ swap_solvables(Repo *repo, Repodata *data, Id pa, Id pb) } } +static void +mkrpmdbcookie(struct stat *st, unsigned char *cookie) +{ + memset(cookie, 0, 32); + cookie[3] = RPMDB_COOKIE_VERSION; + memcpy(cookie + 16, &st->st_ino, sizeof(st->st_ino)); + memcpy(cookie + 24, &st->st_dev, sizeof(st->st_dev)); +} + /* * read rpm db as repo * @@ -1157,6 +1167,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir) DB_ENV *dbenv = 0; DBT dbkey; DBT dbdata; + struct stat packagesstat; memset(&dbkey, 0, sizeof(dbkey)); memset(&dbdata, 0, sizeof(dbdata)); @@ -1189,10 +1200,18 @@ repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir) exit(1); } - if (!ref) + /* XXX: should get ro lock of Packages database! */ + snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm/Packages", rootdir); + if (stat(dbpath, &packagesstat)) + { + perror(dbpath); + exit(1); + } + mkrpmdbcookie(&packagesstat, repo->rpmdbcookie); + + if (!ref || memcmp(repo->rpmdbcookie, ref->rpmdbcookie, 32) != 0) { Id *pkgids; - snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm/Packages", rootdir); if (db->open(db, 0, dbpath, 0, DB_HASH, DB_RDONLY, 0664)) { perror("db->open var/lib/rpm/Packages"); diff --git a/tools/repo_write.c b/tools/repo_write.c index 5d659c4b..06bd6ca8 100644 --- a/tools/repo_write.c +++ b/tools/repo_write.c @@ -890,6 +890,17 @@ write_compressed_page(FILE *fp, unsigned char *page, int len) } } + +static Id subfilekeys[] = { + REPODATA_INFO, REPOKEY_TYPE_VOID, + REPODATA_EXTERNAL, REPOKEY_TYPE_VOID, + REPODATA_KEYS, REPOKEY_TYPE_IDARRAY, + REPODATA_LOCATION, REPOKEY_TYPE_STR, + REPODATA_ADDEDFILEPROVIDES, REPOKEY_TYPE_REL_IDARRAY, + REPODATA_RPMDBCOOKIE, REPOKEY_TYPE_SHA256, + 0, +}; + /* * Repo */ @@ -992,40 +1003,15 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void /* If we store subfile info, generate the necessary keys. */ if (nsubfiles) { - key = cbdata.mykeys + cbdata.nmykeys; - key->name = REPODATA_INFO; - key->type = REPOKEY_TYPE_VOID; - key->size = 0; - key->storage = KEY_STORAGE_SOLVABLE; - cbdata.keymap[key->name] = cbdata.nmykeys++; - - key = cbdata.mykeys + cbdata.nmykeys; - key->name = REPODATA_EXTERNAL; - key->type = REPOKEY_TYPE_VOID; - key->size = 0; - key->storage = KEY_STORAGE_SOLVABLE; - cbdata.keymap[key->name] = cbdata.nmykeys++; - - key = cbdata.mykeys + cbdata.nmykeys; - key->name = REPODATA_KEYS; - key->type = REPOKEY_TYPE_IDARRAY; - key->size = 0; - key->storage = KEY_STORAGE_SOLVABLE; - cbdata.keymap[key->name] = cbdata.nmykeys++; - - key = cbdata.mykeys + cbdata.nmykeys; - key->name = REPODATA_LOCATION; - key->type = REPOKEY_TYPE_STR; - key->size = 0; - key->storage = KEY_STORAGE_SOLVABLE; - cbdata.keymap[key->name] = cbdata.nmykeys++; - - key = cbdata.mykeys + cbdata.nmykeys; - key->name = REPODATA_ADDEDFILEPROVIDES; - key->type = REPOKEY_TYPE_REL_IDARRAY; - key->size = 0; - key->storage = KEY_STORAGE_SOLVABLE; - cbdata.keymap[key->name] = cbdata.nmykeys++; + for (i = 0; subfilekeys[i]; i += 2) + { + key = cbdata.mykeys + cbdata.nmykeys; + key->name = subfilekeys[i]; + key->type = subfilekeys[i + 1]; + key->size = 0; + key->storage = KEY_STORAGE_SOLVABLE; + cbdata.keymap[key->name] = cbdata.nmykeys++; + } } dirpoolusage = 0; @@ -1326,14 +1312,19 @@ for (i = 1; i < cbdata.nmykeys; i++) Id schema[4], *sp; sp = schema; - if (fileinfo[i].addedfileprovides) + if (fileinfo[i].addedfileprovides || fileinfo[i].rpmdbcookie) { /* extra info about this file */ *sp++ = cbdata.keymap[REPODATA_INFO]; - *sp++ = cbdata.keymap[REPODATA_ADDEDFILEPROVIDES]; - for (j = 0; fileinfo[i].addedfileprovides[j]; j++) - ; - cbdata.mykeys[cbdata.keymap[REPODATA_ADDEDFILEPROVIDES]].size += j + 1; + if (fileinfo[i].addedfileprovides) + { + *sp++ = cbdata.keymap[REPODATA_ADDEDFILEPROVIDES]; + for (j = 0; fileinfo[i].addedfileprovides[j]; j++) + ; + cbdata.mykeys[cbdata.keymap[REPODATA_ADDEDFILEPROVIDES]].size += j + 1; + } + if (fileinfo[i].rpmdbcookie) + *sp++ = cbdata.keymap[REPODATA_RPMDBCOOKIE]; } else { @@ -1717,9 +1708,12 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1); cur = xd.len; data_addid(&xd, repodataschemata[i]); - if (fileinfo[i].addedfileprovides) + if (fileinfo[i].addedfileprovides || fileinfo[i].rpmdbcookie) { - data_addidarray_sort(&xd, pool, needid, fileinfo[i].addedfileprovides, 0); + if (fileinfo[i].addedfileprovides) + data_addidarray_sort(&xd, pool, needid, fileinfo[i].addedfileprovides, 0); + if (fileinfo[i].rpmdbcookie) + data_addblob(&xd, fileinfo[i].rpmdbcookie, 32); } else { diff --git a/tools/repo_write.h b/tools/repo_write.h index 0d9d51df..544ff728 100644 --- a/tools/repo_write.h +++ b/tools/repo_write.h @@ -25,11 +25,12 @@ typedef struct _Repodatafile Repodata. */ char *location; char *checksum; - unsigned nchecksum; - unsigned checksumtype; + unsigned int nchecksum; + unsigned int checksumtype; struct _Repokey *keys; unsigned int nkeys; Id *addedfileprovides; + unsigned char *rpmdbcookie; } Repodatafile; void repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodatafile *fileinfo, int nsubfiles);