Niniej­szy post jest oparty o histo­rię z pola bitwy. Bar­dzo tech­niczny i nie­szcze­gól­nie cie­kawy, jeśli ktoś nie używa wymie­nio­nych tech­no­lo­gii. Być może komuś się przyda.

Awaria

Poszu­ki­wa­nie przy­czyn pozwo­liło nam usta­lić nastę­pu­jące fakty:

  • W jed­nej z maszyn wir­tu­al­nych ktoś zain­sta­lo­wał pakiety rpm i poldek, a następ­nie użył ich do insta­la­cji oprogramowania;
  • Maszyna miała cały czas zamon­to­waną zewnętrzną bazę rpm (praw­do­po­dob­nie utils-vserver zde­chło i pozo­sta­wiło po sobie bała­gan, ale o tym później);
  • Wewnętrzny rpm miał inną wer­sję i w jakiś spo­sób uszko­dził bazę zain­sta­lo­wa­nych pakietów;
  • Nastę­pu­jący po nim rpm --rebuilddb bez­pow­rot­nie wyczy­ścił bazę pakie­tów maszyny;
  • W mię­dzy­cza­sie miał miej­sce upgrade pakie­tów rpm i poldek w zewnętrz­nym systemie;

Posta­no­wi­li­śmy zatem prze­in­sta­lo­wać maszynę od nowa, rekon­stru­ując na pod­sta­wie dzia­ła­ją­cych usług listę nie­zbęd­nych pakietów.

Nosem w dół

Dość szybko oka­zało się, że nie będzie tak łatwo:

ncontext: vc_net_create(): Invalid argument

Tak wła­śnie koń­czyło się każde wywo­ła­nie narzę­dzi vrpm i vpoldek. Win­nym oka­zało się wywo­ła­nie chbind, a poprawka wygląda tak:

--- /usr/lib/util-vserver/functions~    2007-09-05 16:09:16.967334575 +0200
+++ /usr/lib/util-vserver/functions     2007-09-05 16:10:29.456275993 +0200
@@ -1171,5 +1171,5 @@
     export RPM_FAKE_CHROOT RPM_FAKE_CTX RPM_FAKE_CAP RPM_FAKE_FLAGS

     LD_PRELOAD=$_RPM_FAKE_SO${LD_PRELOAD:+:$LD_PRELOAD} \
-       exec $_CHBIND "${CHBIND_OPTS[@]}" "$@"
+       exec $_CHBIND --nid $RPM_FAKE_CTX "${CHBIND_OPTS[@]}" "$@"
 }

Dość szybko oka­zało się, że radość jest przed­wcze­sna. O ile vrpm i vpoldek zaczęły dzia­łać, to żadne z nich nie potra­fiło nic zmie­nić. Odpy­ty­wa­nie bazy nie przy­spa­rzało żadnych trud­no­ści, próba insta­la­cji lub usu­nię­cia pakietu koń­czyły się kolej­nym rado­snym komunikatem:

error: cannot open Basenames index using db3 - No such file or directory (2)

Winny

Oka­zało się, że winny jest rpm-4.4.9 w połą­cze­niu z db4.6. Nie mia­łem oka­zji spraw­dzić, co dokład­nie powo­duje nie­pra­wi­dłowe dzia­ła­nie, dość było upew­nić się, że działa wer­sja rpm-4.4.9-1, zbu­do­wana z pakie­tem db4.5-devel.

Pro­ble­mem jest fakt, że db4.6 auto­ma­tycz­nie kon­wer­tuje każdą otwartą bazę do swo­jego for­matu, co ozna­cza, że po wyko­na­niu down­grade pakietu rpm zosta­niemy z bez­u­ży­tecz­nym narzędziem.

Rozwiązanie

Jeff, autor rpm pomógł mi cof­nąć upgrade:

  1. Insta­lu­jemy pakiet db4.6-utils, kopiu­jemy z niego pro­gram db_dump;
  2. Odin­sta­lo­wu­jemy db4.6-utils, zacho­wu­jąc sam db4.6;
  3. Insta­lu­jemy pakiet db4.5-utils;
  4. Cofamy wer­sję rpm i insta­lu­jemy pakiet poldek zbu­do­wany dla tej wer­sji rpm;
  5. Wyko­nu­jemy:
    cd /var/lib/rpm
    rm __db*
    mv Packages{,.old}
    db_dump_4.6 Packages.old > Packages.dump
    db_load Packages < Packages.dump
    rpm --rebuilddb
  6. Powyż­szą czyn­ność powta­rzamy dla wszyst­kich kata­lo­gów /vservers/.pkg/*/rpm/state, które zdą­żyły się zak­tu­ali­zo­wać do nowej wer­sji, odpo­wied­nio mody­fi­ku­jąc pierw­szą linię i do ostat­niej dopi­su­jąc --dbpath <sciezka_do_katalogu_state>

Kolejny problem

Ostat­nim kro­kiem było prze­ko­na­nie narzę­dzia vpoldek, że insta­lo­wane pakiety są dla wła­ści­wej archi­tek­tury. Tutaj roz­wią­za­niem było dopi­sa­nie do każ­dego pliku /vservers/.pkg/*/rpm/etc/macros linijki:

%_host_os %_os

Voila, wszystko działa, maszyna została prze­bu­do­wana. Następ­nym razem posta­ram się pozbyć iry­tu­ją­cych komu­ni­ka­tów LD_PRELOAD.