Make transaction lock path per-transaction
authorPanu Matilainen <pmatilai@redhat.com>
Thu, 22 Apr 2010 09:23:24 +0000 (12:23 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Thu, 22 Apr 2010 09:23:24 +0000 (12:23 +0300)
- Although it doesn't really happen in practise, rpm's API permits several
  transactions with possibly differing roots within process lifetime.
  Previously the lock path was calculated just once globally so we could
  easily be locking in a completely wrong place (eg locking in a previously
  accessed chroot when system rpmdb should be transaction-locked)

lib/rpmts.c
lib/rpmts_internal.h

index f1ecda5..3beb1a4 100644 (file)
@@ -582,6 +582,7 @@ rpmts rpmtsFree(rpmts ts)
     }
     ts->rootDir = _free(ts->rootDir);
     ts->currDir = _free(ts->currDir);
+    ts->lockPath = _free(ts->lockPath);
 
     ts->keyring = rpmKeyringFree(ts->keyring);
     ts->netsharedPaths = argvFree(ts->netsharedPaths);
@@ -976,20 +977,23 @@ rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
 rpmlock rpmtsAcquireLock(rpmts ts)
 {
     static const char * const rpmlock_path_default = "%{?_rpmlock_path}";
-    static const char * rpmlock_path = NULL;
-    const char *rootDir = rpmtsRootDir(ts);
-
-    if (!rootDir || rpmtsChrootDone(ts))
-       rootDir = "/";
-    /* XXX oneshot to determine path for fcntl lock. */
-    if (rpmlock_path == NULL) {
-       char * t = rpmGenPath(rootDir, rpmlock_path_default, NULL);
-       if (t == NULL || *t == '\0' || *t == '%')
+
+    if (ts->lockPath == NULL) {
+       const char *rootDir = rpmtsRootDir(ts);
+       char *t;
+
+       if (!rootDir || rpmtsChrootDone(ts))
+           rootDir = "/";
+
+       t = rpmGenPath(rootDir, rpmlock_path_default, NULL);
+       if (t == NULL || *t == '\0' || *t == '%') {
+           free(t);
            t = xstrdup(RPMLOCK_PATH);
-       rpmlock_path = xstrdup(t);
+       }
+       ts->lockPath = xstrdup(t);
        (void) rpmioMkpath(dirname(t), 0755, getuid(), getgid());
-       t = _free(t);
+       free(t);
     }
-    return rpmlockAcquire(rpmlock_path, _("transaction"));
+    return rpmlockAcquire(ts->lockPath, _("transaction"));
 }
 
index c42e2a1..551cdd7 100644 (file)
@@ -52,6 +52,7 @@ struct rpmts_s {
     int chrootDone;            /*!< Has chroot(2) been been done? */
     char * rootDir;            /*!< Path to top of install tree. */
     char * currDir;            /*!< Current working directory. */
+    char * lockPath;           /*!< Transaction lock path */
     FD_t scriptFd;             /*!< Scriptlet stdout/stderr. */
     rpm_tid_t tid;             /*!< Transaction id. */