ALT Linux Team development discussions
 help / color / mirror / Atom feed
* [devel] packagereq/buildreq proposal
@ 2003-11-16 14:58 Alexey Tourbin
  2003-11-16 15:06 ` [devel] " Alexey Tourbin
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Alexey Tourbin @ 2003-11-16 14:58 UTC (permalink / raw)
  To: devel


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

Greetings!

Дано: имеется список пакетов, полученный packagereq, БЕЗ учета текущей
оптимизации.  Список пакетов вычисляется на основе вывода strace и
получается очень большим.  Некоторая часть этого списка не содержит
полезной информации.  Задача: оптимизировать список пакетов.

Анализ текущего алгоритма оптимизации: если в списке есть пакеты с
названиями %name и %name-foo, то пакет %name удаляется из списка.
Если в списке есть пакеты с названиями lib%name и %name, то пакет
lib%name удаляется из списка.  Удаляются также все пакеты из списка
essential.

Недостатки текущего алгоритма: алгоритм не учитывает зависимости между
пакетами.  В результате 1) список пакетов остается перегруженным; 2)
алгоритм делает ошибки, если структура зависимостей не соответствует
описанным допущениям.

Примеры, которые демонстрируют недостатоки алгоритма:

$ packagereq -o /dev/stdout -- sh -c 'cat `rpm -ql perl-DBD-mysql libMySQL` &>/dev/null ||:'
packagereq: building requires list: libMySQL perl-DBD-mysql
libMySQL perl-DBD-mysql
$

Сейчас в сизифе есть два пакета с libmysqlclient.so.  perl-DBD-mysql
собран с одной из этих библиотек.  Впоследствии он может быть пересобран
с другой.  Зависимость в третьем пакете на libMySQL не нужна.

$ packagereq -o /dev/stdout -- sh -c 'cat `rpm -ql libpcre-devel libpcre` &>/dev/null ||:'
packagereq: building requires list: libpcre-devel libpcre-devel
$

Пакеты libpcre-devel и libpcre, увы, между собой не связаны.

Пример с пакетам ruby, который приводит к тому, что в минимальной
сборочной среде ruby отсутствует, я уже приводил.


Определения.

Прямая зависимость между пакетами: пакет A напрямую зависит от пакета B,
если на уровне RPM существует зависимость следующего типа:

%package -n A
Requires: B

Пример прямой зависимости:
$ rpm -q --requires libpcre-devel | grep pcre
libpcre3 = 4.4-alt1
$

Пакет pcre-devel напрямую зависит от libpcre3.


Прямая зависимость через виртуальный пакет: пакет A зависит от пакета B
через виртуальный пакет, если на уровне RPM существует зависимость
следующего типа:

%package -n A
Requires: package_B

%package -n B
Provides: package_B

Пример зависимости через виртуальный пакет:

$ rpm -q --requires perl-DBD-mysql | grep mysqlclient
libmysqlclient.so.12
$ rpm -q --whatprovides libmysqlclient.so.12
libMySQL-4.0.15-alt2
$

Пакет perl-DBD-mysql зависит от пакета libMySQL через виртуальный пакет
libmysqlclient.so.12.


Косвенная зависимость: любые зависимости с более сложной структурой не
рассматриваются.


Алгоритм оптимизации: из списка по очереди выбирается пакет-кандидат на
удаление.  Если какой-либо пакет из оставшейся части списка зависит от
кандидата напрямую или через виртуальный пакет, кандидат удаляется.
Выполнение алгоритма продолжается на оставшемся списке.


Преимущества алгоритма: алгоритм лишен недостатков текущего алгоритма.

Недостаток алгоритма: результат зависит от порядка пакетов в списке.
Пример:

BuildRequires: XFree86-libs XFree86-devel XFree86-devel-static
		^-------------'     ^----------------'
Пакеты XFree86-libs и XFree86-devel будут по очереди удалены.

BuildRequires: XFree86-devel XFree86-devel-static XFree86-libs
			`----------------------------^
		^---------------------'
Первым будет удален пакет XFree86-devel; информация о том, что он
непосредственно зависит от XFree86-libs, будет потеряна.

Над решением этой проблемы в общем виде я не думал.  В данном частном
случае, как и в некоторых других, достаточно отсортировать список по
возрастанию длины названия пакета.

Недостаток алгоритма: алгоритм не работает с виртуальными пакетами
(которые packagereq подставляет в соответствии с правилами
/etc/buildreqs/packages/substitute.d).  Обсуждение на канале привело
меня к мысли, что семантика виртуальных пакетов, которые предоставляются
несколькими другими пакетами, определена недостаточно хорошо.  Нужно
сформулировать правила использования виртуальных пакетов.

Прототип реализации прилагается.
Примеры работы прототипа:

$ perl rpm.pl libMySQL perl-DBD-mysql
        perl-DBD-mysql requires libMySQL through libmysqlclient.so.12
                libMySQL optimized out
perl-DBD-mysql

$ perl rpm.pl libpcre3 libpcre libpcre-devel
        libpcre-devel requires libpcre3
                libpcre3 optimized out
libpcre libpcre-devel

$ perl rpm.pl XFree86-libs XFree86-devel XFree86-devel-static
        XFree86-devel requires XFree86-libs through libX11.so.6
                XFree86-libs optimized out
        XFree86-devel-static requires XFree86-devel
                XFree86-devel optimized out
XFree86-devel-static


[-- Attachment #1.2: rpm.pl --]
[-- Type: text/plain, Size: 1364 bytes --]

#!/usr/bin/perl

use RPM::Database;
use strict;

my $db = RPM::Database->new;
my %DB;

# load Requires: and Provides: from RPM database for the given packages
foreach my $pkg (@ARGV) {
	my $hdr = $$db{$pkg};
	unless ($hdr) {
		warn "package $pkg not found\n";
		next;
	}
	my $requires = $$hdr{REQUIRENAME};
	if ($requires) {
		$DB{$pkg}{req} = $requires;
	} else {
		warn "package $pkg requires nothing\n";
		$DB{$pkg}{req} = [];
	}
	my $provides = $$hdr{PROVIDES};
	if ($provides) {
		$DB{$pkg}{prov} = $provides;
	} else {
		warn "package $pkg provides nothing\n";
		$DB{$pkg}{prov} = [];
	}
}

use sort 'stable';
# try to optimize out packages with shortest names first
# alphabetical order is also in effect
my @packages = sort { length($a) <=> length($b) } sort keys %DB;

try: while (1) {
	foreach my $pkg (@packages) {
		my @rest = grep { $_ ne $pkg } @packages;
		if (my ($who, $what) = implies($pkg, @rest)) {
			warn "\t$who requires $pkg" . 
				($what eq $pkg ? "\n" : " through $what\n");
			warn "\t\t$pkg optimized out\n";
			@packages = @rest;
			next try;
		}
	}
	last;
}

@packages = sort @packages;
print "@packages\n";

sub implies {
	my ($pkg, @others) = @_;
	foreach my $prov (@{$DB{$pkg}{prov}}) {
		foreach my $who (@others) {
			foreach my $req (@{$DB{$who}{req}}) {
				return ($who, $req)
					if ($req eq $prov);
			}
		}
	}
	return;
}

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2003-12-16 12:18 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-11-16 14:58 [devel] packagereq/buildreq proposal Alexey Tourbin
2003-11-16 15:06 ` [devel] " Alexey Tourbin
2003-11-16 15:54 ` [devel] " Dmitry V. Levin
2003-11-16 17:10   ` [devel] " Alexey Tourbin
2003-11-17  8:46 ` Michael Shigorin
2003-11-17 11:42   ` Alexey Tourbin
2003-11-17 12:09     ` vserge
2003-11-17 12:12       ` Alexey Tourbin
2003-11-17 12:18         ` Sergey Bolshakov
2003-11-17 12:38         ` Marat Khairullin
2003-12-15 19:37 ` Alexey Tourbin
2003-12-15 21:05   ` Michael Shigorin
2003-12-16 10:09   ` Dmitry V. Levin
2003-12-16 12:18     ` Alexey Tourbin

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