- add rpmdbcookie support
authorMichael Schroeder <mls@suse.de>
Wed, 7 May 2008 15:18:01 +0000 (15:18 +0000)
committerMichael Schroeder <mls@suse.de>
Wed, 7 May 2008 15:18:01 +0000 (15:18 +0000)
src/knownid.h
src/repo.h
src/repo_solv.c
tools/common_write.c
tools/dumpsolv.c
tools/repo_rpmdb.c
tools/repo_write.c
tools/repo_write.h

index ce0876f..866d262 100644 (file)
@@ -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
index f56d7ad..ab0e761 100644 (file)
@@ -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..  */
index 8822dcc..85e71e6 100644 (file)
@@ -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);
     }
 }
index 7be42d2..884b417 100644 (file)
@@ -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)
index aaa8591..ffc624c 100644 (file)
@@ -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++)
     {
index 48a02d5..db37da5 100644 (file)
@@ -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");
index 5d659c4..06bd6ca 100644 (file)
@@ -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
            {
index 0d9d51d..544ff72 100644 (file)
@@ -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);