Smartmontools to zestaw narzędzi do odpytywania dysków twardych używających
SMART. Można dobrać się do danych statystycznych jakie dyski gromadzą
podczas całej swojej pracy - ile razy talerze były zatrzymywane/rozkręcane,
ile godzin dysk pracuje, czy zarejestrował jakieś błędy podczas swojej pracy
(a jeśli tak, to kiedy), temperatura dysku, liczba realokowanych wewnętrznie
(przez elektronikę dysku) uszkodzonych sektorów itp. Smartmontools jest
bezpośrednim następcą pakietu smartsuite.
1. Źródła można znaleźć np. poprzez Freshmeat
2. Próbna instalacja
Po rozpakowaniu źródeł okaże się, że pakiet nie ma skryptu ./configure, że
w ogóle nie bazuje na standardowych narzędziach autoconf/automake GNU. Używa
zwykłego pliku Makefile. Respektuje $DESTDIR, a flagi kompilatora wyrażone
są wewnętrzą zmienną CFLAGS, którą można przedefiniować przy wywoływaniu
,,make''. Problem dotyczy późniejszej instalacji: co prawda pliki instalują
się przez $DESTDIR, ale trzeba im chyba najpierw pozakładać katalogi (to
akurat niewielki problem), gorzej że przy instalacji skrypt próbuje zmieniać
atrybuty plików. A konkretniej, to próbuje zmieniać im grupę/właściciela na
,,root''. Do czego ma prawo tylko root. Nie da się tego zmienić bez
ingerencji w Makefile (potwornie długie linie, ale wolałem ich nie łamać,
dla czytelności):
To sekcja instalacyjna wycięta z Makefile. Teraz jakie poprawki należy
wprowadzić? Po pierwsze można wyciąć te linie które kompresują strony
manuala, bo to i tak zrobi rpm. Można też wyciąć te fragmenty usuwające
stare manuale. Z tych wszystkich linijek ,,install...'' trzeba usunąć
fragmenty '-o root -g root'. Można też uprościć ten kawałek instalujący
konfigurację. Po przeróbkach będzie to wyglądało tak:
Przy okazji wywaliłem też linijkę instalującą plik /etc/rc.d/init.d/smartd,
bo mój system nie używa skryptów startowych SysV, i to już powinno działać.
Ale ze względów dydaktycznych chcę jeszcze pokazać, jak można sobie
,,udanymicznić'' ścieżki dostępu: tutaj są one zakodowane na sztywno, np.
/usr/sbin. Aby było bardziej rpm-owo, to powinno
być możliwe do późniejszego zmieniania bez edycji plików. Ale jak to zrobić?
Rozwiązanie jest w sumie proste - zamiast katalogów trzeba użyć zmiennych.
Zmienne te się potem zainicjuje przy wywołaniu ,,make'' odpowiednimi
makrami. Sekcja po przeróbkach mogłaby wyglądać tak:
make install H_SBINDIR=%{_sbindir} H_MANDIR=%{_mandir} \
H_DOCDIR=%{_docdir} H_SYSCONFDIR=%{_sysconfdir} DESTDIR=%{buildroot} \
CFLAGS="$CFLAGS"
Ale tutaj nasuwają mi się dwie refleksje: jedna to to, że będziemy mieć
zmienne położenie pliku konfiguracyjnego. Ale jego lokacja jest zaszyta
gdzieś na stałe w kodzie programu... i ją też trzeba by zmieniać. Po krótkim
grepowaniu przez źródła znalazłem odpowiedzialny fragment, w pliku smartd.h
znajduje się wpis
#define CONFIGFILE "/etc/smartd.conf"
Ale to zwykła dyrektywa #define, więc można ją przykryć z linii poleceń,
dodając do flag kompilatora w trakcie kompilacji:
make CFLAGS="$CFLAGS -DCONFIGFILE=\"%{_sysconfdir}/smartd.conf\""
I to powinno załatwić sprawę. Ale ta druga rzecz która przyszła mi do głowy,
ona jest dużo większego kalibru: nie da się wygenerować patcha z tych zmian!
To znaczy OK, dobra, patcha zrobić to się da, ale on nie da się potem
zaaplikować gdy wyjdzie nowa wersja smartmontools. A dlaczego? Bo
w patchowanych linijkach jest numer wersji (w nazwie katalogu docelowego dla
dokumentacji). A to oznacza, że przy upgradzie ten numer się zmieni. A to
z kolei oznacza, że patch nie rozpozna tych linijek. Rezultat: patch się nie
zaaplikuje. Czyli można sobie zabawę z patchem podarować.
Alternatywnie można napisać regułkę sed-a która by powprowadzała te zmiany,
a na dodatek była na tyle sprytna, by ignorować numerki wersji. To da się
zrobić, ale nie chcę. Pójdę w inną stronę: instalowanych plików jest
niewiele i mam podaną na tacy ich listę, łącznie z przeznaczeniem...
przecież ja zamiast robić ,,make install'' mogę po prostu przekleić te
linijki które instalują pliki prosto do sekcji %install! Trochę drobnych
poprawek i powinno być po krzyku. To nie jest idealne wyjście, ale na pewno
o niebo lepsze niż robienie łatek jednorazowego użytku.
Plik nie jest bardzo skomplikowany. W preambule jedyne ciekawostki to użycie
Obsoletes: i zdefiniowanie pomocniczego makra %{sub_release} które ułatwia
mi poradzenie sobie z dziwną nazwą pakietu źródłowego (*-5.1-1.tar.bz2). Bo
nie mogę użyć w pliku .spec jako wersji po prostu tego 5.1-1, znak minusa
jest niedozwolony przy określaniu wersji.
Sekcja %prep też normalna, tylko ostrzegam RPM że rozpakowany katalog ma
niestandardową nazwę. W sekcji %build definiuję zmienne dla ,,make''
- ustawiam LDFLAGS i CFLAGS. Przy ustawianiu CFLAGS od razu dodaję
definiowanie stałej CONFIGFILE na potrzeby kompilatora. To spowoduje, że
zmieniając makro %{_sysconfdir} zmiana ta znajdzie odzwierciedlenie
w skompilowanym kodzie binarnym, i programy będą szukać swojego pliku
konfiguracyjnego we właściwym miejscu.
Następnie sekcja instalacyjna: przeklejone z Makefile linijki, tyle że nieco
zmienione - pozamieniałem odwołania do katalogów docelowych makrami RPM-a,
przy okazji usunąłem też niechciane pliki dokumentacji.
Na tym etapie artykułu opisywanie tak wtórnej sekcji %files byłoby chyba już
przesadą, prawda? Więc jej nie opiszę, chyba jest już jasna i zrozumiała.
4. Budowanie pakietu się udaje, w końcu to już któryś z rzędu pakiet :)