ALT Linux Team development discussions
 help / color / mirror / Atom feed
From: Alexey Tourbin <at@altlinux.ru>
To: ALT Devel discussion list <devel@lists.altlinux.org>
Subject: Re: [devel] symlinks.req: semi-unmets
Date: Sat, 11 Aug 2007 20:26:47 +0400
Message-ID: <20070811162647.GE7530@solemn.turbinal> (raw)
In-Reply-To: <20070806222048.GH7530@solemn.turbinal>


[-- Attachment #1.1: Type: text/plain, Size: 2515 bytes --]

On Tue, Aug 07, 2007 at 02:20:48AM +0400, Alexey Tourbin wrote:
> On Mon, Aug 06, 2007 at 03:08:04PM +0400, Alexey Tourbin wrote:
> ЗАОСТРЯЮ ПРОБЛЕМУ "ПОЛУ-АНМЕТОВ".
> 
> 
> Это проблема проявляется тогда, когда зависимость имеет вид /ПУТЬ,
> но у соответствующего пакета не стоит Provides: /ПУТЬ.  На уровне
> rpm это не является unmet'ом: если при установке пакета с такой
> зависимостью имеется какой-либо другой пакет с файлом /ПУТЬ,
> то для rpm это "канает".
> 
> С другой стороны, apt видит такую зависимость именно как unmet.
> Вообще-то у апта к каждому пакету есть файловые листы, и он использует
> их для разрешения такого рода зависимостей.  Но при изготовлении
> репозитария аптовые листы у нас насильно "оптимизируются".
> 
> Два простых варианта решения это проблемы:
> 
> 1) Генерировать более полный content_index для hasher, чтобы любой путь
> более гарантированно трансформировался в название пакета (насколько
> более полный/гарантированно?).
> 
> 2) Восстановить файловые листы для апт.  Насколько потяжелеет
> pkglist.classic.bz2?

Я немного захачил апт, но это всё равно как следует не работает, см. ниже.

commit 30e27b0f1c74b4f67354a6035fae3e210131bca1
Author: Alexey Tourbin <at@altlinux>
Date:   Sat Aug 11 20:01:05 2007 +0400

    apt-0.5.15lorg2-alt-genpkglist-reqfiles.patch
    
    genpkglist strips file lists by default (without --bloat option).
    It keeps only some "useful files" by using a few ad hoc patterns.
    
    This can break file-level dependencies.  Consider pkgA requires
    /usr/lib/foo1/bar, and pkgB owns this file without explicitly
    providing it.  Now if genpkglist strips /usr/lib/foo1/bar
    from pkgB file list, this is going to be an unmet dependency.
    
    This patch changes genpkglist behaviour, so that, when genpkglist
    is invoked without --bloat option, it first finds all file-level
    dependencies (something like "rpm -qaR |grep ^/").  This requires
    a separate pass.  The list of file-level dependencies is saved into
    "reqfiles" global variable.  And on the second (normal) pass, the
    function usefulFile() is modified to check the "reqfiles" variable;
    that is, it should keep a file in the file list if it's been required
    by some package in the repo.
    
    (Unfortunately, this patch does not solve all of the problems
    I want it to solve; we have separate repos for i586 and noarch --
    inter-repo file-level dependencies cannot be resolved this way.)

[-- Attachment #1.2: apt-0.5.15lorg2-alt-genpkglist-reqfiles.patch --]
[-- Type: text/plain, Size: 3224 bytes --]

--- apt-0.5.15lorg2/tools/genpkglist.cc-	2007-08-11 15:10:54 +0400
+++ apt-0.5.15lorg2/tools/genpkglist.cc	2007-08-11 19:36:03 +0400
@@ -18,6 +18,8 @@
 #include <map>
 #include <iostream>
 
+#include <tr1/unordered_set>
+
 #include <apt-pkg/error.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/configuration.h>
@@ -77,20 +79,30 @@ typedef struct {
    string url;
 } UpdateInfo;
 
+static std::tr1::unordered_set<std::string> reqfiles;
 
-static inline int usefullFile(char *a)
+static int usefulFile(const char *dir, const char *basename)
 {
-   int l = strlen(a);
-   
-   if (strstr(a, "bin") || strstr(a, "/etc") || strncmp(a, "/lib", 4) == 0)
-       return 1;
-   
-   if (l < 3)
-       return 0;
+   if (strstr(dir, "bin/"))
+      return 1;
+   if (strstr(dir, "/etc/"))
+      return 1;
    
-   if (strcmp(a + l - 3, ".so") == 0
-       || strstr(a, ".so."))
-       return 1;
+   const char *pos = strstr(basename, ".so");
+   if (pos > basename) {
+      int c = pos[3];
+      if (c == '.' || c == '\0')
+         return 1;
+   }
+
+   if (reqfiles.size() > 0) {
+      char fullname[strlen(dir) + strlen(basename) + 1];
+      strcpy(fullname, dir);
+      strcat(fullname, basename);
+      if (reqfiles.find(fullname) != reqfiles.end())
+         return 2;
+   }
+
    return 0;
 }
 
@@ -133,9 +145,8 @@ static void copyStrippedFileList(Header 
    {
       int ok = 0;
       
-      ok = usefullFile(basenames[i]);
-      if (!ok) 
-	  ok = usefullFile(dirnames[dirindexes[i]]);
+      ok = usefulFile(dirnames[dirindexes[i]], basenames[i]);
+      // if (ok > 1) cerr << "useful file: " << dirnames[dirindexes[i]] << basenames[i] <<endl;
       
       if (!ok) {
 	 int k = i;
@@ -599,6 +610,40 @@ int main(int argc, char ** argv) 
    int isSource;
 #endif   
 
+   if (!fullFileList) {
+      // first pass: initialize reqfiles
+      for (entry_cur = 0; entry_cur < entry_no; entry_cur++) {
+         fd = fdOpen(dirEntries[entry_cur]->d_name, O_RDONLY, 0666);
+         if (!fd)
+            continue;
+         int rc;
+         Header h;
+#if RPM_VERSION >= 0x040100
+         rc = rpmReadPackageFile(ts, fd, dirEntries[entry_cur]->d_name, &h);
+         if (rc == RPMRC_OK || rc == RPMRC_NOTTRUSTED || rc == RPMRC_NOKEY) {
+#else
+         rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
+         if (rc == 0) {
+#endif
+            int reqtype;
+            const char **requires;
+            int nreq;
+            rc = headerGetEntry(h, RPMTAG_REQUIRENAME, &reqtype, (void**)&requires, &nreq);
+            if (rc == 1 && reqtype == RPM_STRING_ARRAY_TYPE) {
+               int i;
+               for (i = 0; i < nreq; i++) {
+                  const char *req = requires[i];
+                  if (*req == '/') {
+                     // cerr << dirEntries[entry_cur]->d_name << " requires " << req << endl;
+                     reqfiles.insert(req);
+                  }
+               }
+            }
+            headerFree(h);
+         }
+         Fclose(fd);
+      }
+   }
    for (entry_cur = 0; entry_cur < entry_no; entry_cur++) {
       struct stat sb;
 

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

  parent reply	other threads:[~2007-08-11 16:26 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-06 22:20 Alexey Tourbin
2007-08-06 23:34 ` Alexey Tourbin
2007-08-10  8:21   ` Alexey Tourbin
2007-08-11 16:26 ` Alexey Tourbin [this message]
2007-08-11 19:07 ` Alexey Tourbin
2007-08-13 10:12   ` Alexey Tourbin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070811162647.GE7530@solemn.turbinal \
    --to=at@altlinux.ru \
    --cc=devel@lists.altlinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

ALT Linux Team development discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
		devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
	public-inbox-index devel

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git