<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arkadiusz Kuryłowicz, blog prywatny &#187; Linux</title>
	<atom:link href="http://www.kurylowicz.info/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kurylowicz.info</link>
	<description>Blog prywatny, projekty, PHP, Linux, MySQL</description>
	<lastBuildDate>Sun, 11 Apr 2010 12:11:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Apache + PHP+ FastCGI + Spawn FastCGI? Wydajność, migracja.</title>
		<link>http://www.kurylowicz.info/2009/09/20/apache-php-fastcgi-spawn-fastcgi-wydajnosc-migracja/</link>
		<comments>http://www.kurylowicz.info/2009/09/20/apache-php-fastcgi-spawn-fastcgi-wydajnosc-migracja/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 21:32:54 +0000</pubDate>
		<dc:creator>Arek Kuryłowicz</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Php]]></category>

		<guid isPermaLink="false">http://www.pink.art.pl/?p=119</guid>
		<description><![CDATA[
Mijający już weekend upłynął mi pod znakiem migracji serwera www.poema.art.pl na FastCgi. Sporo alternatyw, sporo, ale niepełnych informacji - trudno się w tym połapać komuś, kto nie jest zaznajomiony z tą technologią.  Ale od początku. Dlaczego warto się przerzucić  na FastCgi? Otóż powody są co najmniej dwa:

wydajność
bezpieczeństwo

Rozwinięcie wątku wydajności należałoby zacząć od wyjaśnienia w [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">
<p>Mijający już weekend upłynął mi pod znakiem migracji serwera www.poema.art.pl na FastCgi. Sporo alternatyw, sporo, ale niepełnych informacji - trudno się w tym połapać komuś, kto nie jest zaznajomiony z tą technologią.  Ale od początku. Dlaczego warto się przerzucić  na FastCgi? Otóż powody są co najmniej dwa:</p>
<ol>
<li>wydajność</li>
<li>bezpieczeństwo</li>
</ol>
<p style="text-align: justify">Rozwinięcie wątku wydajności należałoby zacząć od wyjaśnienia w jaki sposób FastCgi działa. Otóż dzięki FastCgi separujemy wykonanie kodu PHP od wątków Apacza. Apacz w modelu FastCgi służy wyłącznie do komunikacji z przeglądarką klienta. W momencie kiedy klient zażąda uruchomienia skryptu PHP - żądanie to przekazywane jest do 'serwera FastCGI' który używając interpretera PHP uruchamia skrypt i odsyła wynik do Apacza. Wygląda to mniej więcej tak:</p>
<pre>+----------+  TCP 80  +----------+ Unix socket
|  Klient  | &lt;-----&gt;  |  Apache  | &lt;-----+
+----------+          +----------+       |
                       user: http        |
+----------+          +----------+       |      +-------------+        +--------------+
|  Klient  | &lt;-----&gt;  |  Apache  | &lt;-----+----&gt; | PHP FastCgi | &lt;----&gt; | Server MySQL |
+----------+          +----------+       |      +-------------+        +--------------+
                       user: http        |        user: john
+----------+          +----------+       |
|  Klient  | &lt;-----&gt;  |  Apache  | &lt;-----+
+----------+          +----------+
                       user: http</pre>
<p style="text-align: justify">Przy użyciu spawn-fastcgi uruchamiamy dla każdego z użytkowników własny serwer PHP FastCgi który nasłuchuje na Unixowym sockecie. Apache komunikuje się po sockecie z wybranym zgodnie z ustawieniami (per vhost) serwerem żądając wykonania skryptu. Dzięki temu otrzymujemy izolację wątków PHP od wątków Apache. Dodatkowo PHP FastCgi działając z uprawnieniami użytkownika, nie zaś serwera Apache ma możliwość zapisu do katalogów użytkownika, a także ograniczenia odczytu plików do których posiada uprawnienia.</p>
<h2>Ok, ale co z wydajnością?</h2>
<p style="text-align: justify">Po pierwsze Apache, dzięki temu że nie parsuje w każdym swoim wątku PHP zabiera o wiele mniej pamięci. Przy dużej ilości żądań jest  to sprawa kluczowa. Dzięki modelowi FastCgi można w prawidłowy sposób wykorzystać mechanizm database persistent connections (eg. w MySQL). W przypadku wielu wątków Apacza parsujących PHP nawiązywanych jest tyle połączeń ile wątków. Nowe wątki nie potrafią użyć ponownie połączeń utworzonych przez zabite wątki. Dzięki temu w parę minut osiągamy maksymalny limit połączeń z bazą.  W przypadku FastCgi nawiązanych zostaje tyle połączeń ile wątków i połączenia te są cały czas utrzymywane. To jest także sprawa kluczowa dla serwisów o wysokim obciążeniu.</p>
<h2>Bezpieczeństwo?</h2>
<p style="text-align: justify">Wspomniałem wcześniej - wykonanie kodu PHP z uprawnieniami użytkownika. Ale nie tylko - separacja cache APC to kolejny element bezpieczeństwa. Dalej: możliwość pozbycia się safe mode w PHP - aktualnie to mechanizm z którego PHP się wycofuje. W wersji 5 ma już go nie być.</p>
<h2>fCgi, FastCgi, fCgid?</h2>
<p style="text-align: justify;">Jest sporo zamieszania jeśli chodzi o mechanizm FastCgi. Istnieje mnóstwo alternatyw. Osoba zaznajamiająca się z tematem za pomocą poldek search *cgi*   może czyć się nieco zagubiona. Dlatego opiszę co potrzebujemy aby to wszystko właściwie uruchomić.</p>
<p style="text-align: justify;">Zacznijmy od końca, czyli od PHP. Potrzebna będzie paczka zawierająca interpreter fcgi dla PHP - jest to dodatkowy moduł SAPI (oprócz eg. zwyczajnego cli, lub modułu do Apacha) które można skompilować, tudzież zainstalować. Pod PLD jest to pakiet "php-fcgi". Dalej, przyda się coś co będzie potrafiło utworzyć nam serwery FastCgi dla użytkowników. Pakiet "spawn-fcgi" jest całkiem dobry do tego. I wreszcie musimy nauczyć Apache komunikować się z naszymi serwerami. Doinstalujmy moduł "apache-mod_fastcgi".</p>
<p style="text-align: justify;">Wszystkie moduły można bez obaw zainstalować na serwerze który używa modułu "apache-mod_php"  do parsowania kodu PHP. Generalnie można używać obu modeli parsowania jednocześnie - część vhostów i aplikacji parsować modułem Apacza, najbardziej obciążone vhosty puścić przez FastCgi.</p>
<p><span id="more-119"></span></p>
<h2>Konfiguracja PHP</h2>
<p style="text-align: justify;">Nieco problematyczną sprawą w modelu FastCgi jest  konfiguracja PHP per vhost. Nie możemy do tego użyć ani plików .htacess ani dyrektyw php_flag w konfiguracji vhosta. Należy dla każdego z vhostów wymagającego niestandardowego konfigu utworzyć osobny php.ini. Ma to jedną zasadniczą wadę. /etc/php/php.ini który zawiera nasze istawienia PHP nie będzie czytany. Zatem dla każdego z vhostów należy mieć kopię php.ini zawierającą <strong>wsztstkie opcje konfiguracyjne które chcemy zmienić</strong>. Jeśli którejś z opcji nie ujmiemy w indywidualnym .ini będzie ona miała wartość domyślną, taką, jaka jest wkompilowana w php. Czytany jest za to katalog /etc/php/conf.d, przy czym każda zdefiniowana tam opcja konfiguracyjna <strong>nadpisuje</strong> tę zdefiniowaną w indywidualnym .ini.</p>
<p style="text-align: justify;">W PHP 5 ma być możliwość używania w globalnym php.ini wpisów [myhost.com], dzięki czemu będzie można nadpisać globalne ustawienia per vhost. Niestety póki co, trzeba robić kopie globalnego php.ini i zmieniać w niej wybrane opcje. Minimalna postać indywidualnego php.ini, tak, aby zachować najważniejsze spersonalizowane dla dystrybucji ustawienia to:</p>
<pre class="ini"><span style="color: #666666; font-style: italic;">; Safe mode w binarce PHP domyślnie jest on, więc jeśli serwis</span>
<span style="color: #666666; font-style: italic;">; pod nim nie działa trzeba wyłączyć</span>
<span style="color: #000099;">safe_mode </span>=<span style="color: #660066;"> Off</span>
<span style="color: #666666; font-style: italic;">; To warto podać, ograniczymy możliwość otwierania cudzych katalogów</span>
<span style="color: #000099;">open_basedir </span>= <span style="color: #933;">&quot;/home/webhosts/www.mychost.pl:/home/services/httpd:/tmp&quot;</span>
<span style="color: #000099;">include_path </span>=<span style="color: #660066;"> $<span style="">&#123;</span>open_basedir<span style="">&#125;</span></span>
<span style="color: #000099;">error_reporting  </span>=<span style="color: #660066;">  E_ALL &amp; ~E_NOTICE &amp; ~E_STRICT</span>
<span style="color: #000099;">display_errors </span>=<span style="color: #660066;"> Off</span>
<span style="color: #000099;">log_errors </span>=<span style="color: #660066;"> On</span>
<span style="color: #666666; font-style: italic;">; Błedy do sysloga, to php będzie działało z prawami usera, więc nie</span>
<span style="color: #666666; font-style: italic;">; można zapisywać błędów do wspólnego pliku</span>
<span style="color: #000099;">error_log </span>=<span style="color: #660066;"> syslog</span>
<span style="color: #000099;">ignore_repeated_errors </span>=<span style="color: #660066;"> On</span>
<span style="color: #000099;">html_errors </span>=<span style="color: #660066;"> Off</span>
<span style="color: #000099;">upload_tmp_dir </span>= <span style="color: #933;">&quot;/tmp&quot;</span>
<span style="color: #000099;">expose_php </span>=<span style="color: #660066;"> Off</span>
<span style="color: #000099;">memory_limit </span>=<span style="color: #660066;"> 32M</span>
date.<span style="color: #000099;">timezone </span>= <span style="color: #933;">&quot;Europe/Warsaw&quot;</span>
<span style="color: #000099;">browscap </span>=<span style="color: #660066;"> /etc/php/browscap.ini</span></pre>
<h2>Konfiguracja spawn-fastcgi</h2>
<p style="text-align: justify;">Tu sprawa jest dość prosta, otóż spawn-fastcgi nie ma żadych konfigów, a wszystkie parametry przekazujemy w linii poleceń.</p>
<pre class="bash">spawn-fcgi -s /var/run/fastcgi/fcgi.myhost.sock -M <span style="color: #000000;">0660</span> \
  -P /var/run/fastcgi/fcgi.myhost.pid -U http -G http \
  -u <span style="color: #000000;">10012</span> -g <span style="color: #000000;">10012</span> -C <span style="color: #000000;">2</span> -- /usr/sbin/php.fcgi -c /etc/php/webapps.d/myhost.ini</pre>
<p style="text-align: justify;">Po kolei: -s  /var/run/fastcgi/fcgi.myhost.sock mówi w którym miejscu tworzyć sockety serwerów FastCgi. Ja wybrałem sobie katalog /var/run/fastcgi. Należy go utworzyć nadając prawo do zapisu użytkownikowi, z którego prawami będzie działał serwer oraz prawa do odczytu dla serwera Apache (user http). -M 0660 każe zmienić uprawnienia do utworzonego socketa na 660, -P /var/run/fastcgi/fcgi.myhost.pid mówi gdzie zapisujemy plik z PIDem serwera. Parametry -U http -G http są ważne, i mówią że prawa dostępu do socketa mają być nadane dla użytkownika http. Jako że z socketa będzie korzystał serwer Apache zmiana uprawnień jest konieczna. Dalej -u 10012 -g 10012 - tutaj definiujemy id (bądź nazwę) użytkownika i grupy z uprawnieniami którego ma działać FastCgi. Z uprawnieniami tego użytkownika będzie wykonany kod PHP.  Można tu użyć ID'ów użytkowników wirtualnych. Nie muszą być dodani do /etc/passwd. Idealnie to się wpisuje w model hostingu gdzie użytkowników trzymamy w bazie danych bazie danych. Ważną sprawą jest jedynie, aby wirtualny użytkownik miał prawa do zapisu do katalogu na który wskazuje parametr -s. Można mu nadać prawa 777 lub trzymać sockety w katalogach domowych użytkowników.  -C 2 określa ile instancji FastCgi ma zostać uruchomionych. Wartość trzeba dobrać doświadczalnie. W przypadku zbyt małej ilości Apache będzie podawał klientom bład 500. I wreszcie pora na interpreter: -- /usr/sbin/php.fcgi -c /etc/php/webapps.d/myhost.ini - używamy zainstalowanego wcześniej php-fgi - podając mu parametr -c z indywidualnym plikiem konfiguracyjnym. Jeśli nie podamy parametru -c zostanie użyty domyślny /etc/php/php.ini.</p>
<p style="text-align: justify;">Jeden serwer FastCgi może obsługiwać wiele hostów wirtualnych. W najprostszym przypadku  można uruchomić jedną instancję serwera na prawach użytkownika mającego prawa do odczyty dla plików PHP (może to być http) i uruchomić na nim wszystkie nasze vhosty. Przy czym w oczywisty sposób pozbywamy się w takim przypadku korzyści płynących z separacji uprawnień. Przy hostingu wirtualnym lepiej przyjąć strategię: jedna instancja per 1 użytkownik na której odpalamy wszystkie jego vhosty.</p>
<p style="text-align: justify;">W ogóle fajnie jest napisać sobie jakiś rc.skrypt, który będzie uruchamiał wszystkie zdefiniowane instancje podczas startu, pozwoli nam je zresetować, zatrzymać, etc.</p>
<h2>Konfiguracja Apache</h2>
<p style="text-align: justify;">Ok, i teraz Apacz. Wszystko co zostało zrobione do tej pory można bez obaw robić na serwerze który obsługuje PHP via moduł Apacza. Operacje poniżej wymagają już zmiany w konfiguracji serwera WWW, a co za tym idzie są ryzykowne. Główne ryzyko, przy pomyłce w konfiguracji to możliwość zaserwowania niesparsowanych skryptów PHP, tak więc na działających serwerach polecam blokadę dostępu dla virtualki via Order deny, allow Allow from my.ad.re.ss Deny from all. Dodatkowo jak wspomniałem wcześnej model parsowania PHP via moduł jak i FastCgi może współistnieć jednocześnie, tak więc możemy przerzucać na FastCgi pojedyncze virtualki.</p>
<p style="text-align: justify;">Ok, zaczynamy od pliku "/etc/httpd/conf.d/90_mod_fastcgi.conf" . Domyślnie jest tam jedynie linijka ładująca moduł fastcgi. Dopiszmy do pliku:</p>
<pre class="apache">&lt;IfModule mod_fastcgi.c&gt;
  <span style="color: #adadad; font-style: italic;"># Domyślne ustawienia serwera FastCgi, -pass-header Authorization jest bardzo ważne</span>
  FastCgiConfig -idle-<span style="color: #00007f;">timeout</span> <span style="color: #ff0000;">20</span> -maxClassProcesses <span style="color: #ff0000;">1</span> -pass-<span style="color: #00007f;">header</span> Authorization
  <span style="color: #adadad; font-style: italic;"># Zarejestrujmy dwie akcje</span>
  <span style="color: #00007f;">Action</span> php5-fcgi /php-cgi
  <span style="color: #00007f;">Action</span> application/x-fcgi-php /php-cgi
  <span style="color: #adadad; font-style: italic;"># Załóżmy że nasz serwer FastCgi będzie znajdował pod wirtualnym adresem /php-cgi</span>
  &lt;Location <span style="color: #7f007f;">&quot;/php-cgi&quot;</span>&gt;
    php_flag engine <span style="color: #0000ff;">off</span>
    <span style="color: #00007f;">Order</span> <span style="color: #00007f;">Deny</span>,<span style="color: #00007f;">Allow</span>
    <span style="color: #00007f;">Deny</span> <span style="color: #00007f;">from</span> <span style="color: #00007f;">All</span>
    <span style="color: #00007f;">Allow</span> <span style="color: #00007f;">from</span> env=REDIRECT_STATUS
    <span style="color: #00007f;">Options</span> ExecCGI <span style="color: #0000ff;">FollowSymLinks</span>
    <span style="color: #00007f;">SetHandler</span> fastcgi-<span style="color: #00007f;">script</span>
  &lt;/Location&gt;
&lt;/IfModule&gt;</pre>
<p style="text-align: justify;">Ok, to wystarczy, żeby móc przystąpić do konfigurowania vhostów. Do vhosta, dla którego uruchomiona została już instancja spawn-fcgi i mamy utworzony socket w katalogu /var/run/fastcgi/fcgi.myhost.sock dopiszmy:</pre>
<pre class="apache">&lt;VirtualHost www.myhost.pl:<span style="color: #ff0000;">80</span>&gt;
<span style="color: #66cc66;">&#91;</span>...<span style="color: #66cc66;">&#93;</span>
&lt;IfModule mod_fastcgi.c&gt;
<span style="color: #adadad; font-style: italic;"># Tak! wyłączamy engine PHP, dzięki temu moduł PHP, który</span>
<span style="color: #adadad; font-style: italic;"># cały czas działa zostawi pliki PHP tej wirtualki w spokoju</span>
php_flag engine <span style="color: #0000ff;">off</span>
<span style="color: #adadad; font-style: italic;"># Magic! Nadpisujemy handler application/x-httpd-php każąc wszystkim</span>
<span style="color: #adadad; font-style: italic;"># plikom php zdefiniowany wcześniej dla modułu zostać sparsowanym via FastCgi</span>
<span style="color: #00007f;">Action</span> application/x-httpd-php /php-cgi
<span style="color: #adadad; font-style: italic;"># Definicja serwera, ścieżka musi być taka sama jak doc_root vhosta + /php-cgi</span>
<span style="color: #adadad; font-style: italic;"># Nie należy się przejmować faktem, iż /php-cgi nie istnieje w tej ścieżce, tak ma być!</span>
FastCgiExternalServer /home/webhosts/myhost/php-cgi -socket /var/run/fastcgi/fcgi.myhost.sock
&lt;/IfModule&gt;
&lt;/VirtualHost&gt;</pre>
<p>Jeśli mamy jakiekolwiek opcje konfiguracyjne dla php (php_flag, php_admin_value) to należy je usunąć.</p>
<h2>Uruchamiamy!</h2>
<p>Checklist:</p>
<ul>
<li>Sprawdzamy czy  instancja serwera FastCgi uruchomiona przez spawn-cgi działa: ps aux | grep cgi:
<pre>10008   7832  0.0  1.6  71324 34212 ? SN   14:19   0:18 /usr/bin/php.fcgi -c /etc/php/webapps.d/myhost.ini
10008   7833  0.0  1.4  67408 29276 ? SN   14:19   0:19 /usr/bin/php.fcgi -c /etc/php/webapps.d/myhost.ini
http   15808  0.0  0.5  72288 11548 ? SN   20:11   0:00 /usr/sbin/fcgi-pm</pre>
</li>
<li>Sprawdzamy czy jest socket i czy http ma możliwośc odczytu: ls -la /var/run/fastcgi:
<pre>-rw-r--r--  1 root root    4 09-20 14:19 fcgi.myhost.pid
srw-rw----  1 http http    0 09-20 14:19 fcgi.myhost.sock</pre>
</li>
<li>Sprawdzamy, czy w naszym konfigu apacza nie ma błedów: service httpd configtest</li>
</ul>
<p style="text-align: justify;">Pora na restart Apache. Po tym kod PHP dla konfigurowanego vhosta powinien być parsowany via FastCgi, co będzie sygnalozowane w wyniku funkcji phpini() wpisem Server API CGI/FastCGI.</p>
<p style="text-align: justify;">Dla kodu parsowanego via moduł Apache Server API  to Apache Handler.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kurylowicz.info/2009/09/20/apache-php-fastcgi-spawn-fastcgi-wydajnosc-migracja/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cpuset dla Linux 2.6</title>
		<link>http://www.kurylowicz.info/2009/04/09/cpuset-dla-linux-26/</link>
		<comments>http://www.kurylowicz.info/2009/04/09/cpuset-dla-linux-26/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 06:29:31 +0000</pubDate>
		<dc:creator>Arek Kuryłowicz</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.pink.art.pl/?p=100</guid>
		<description><![CDATA[Ostatnio, z ciekawości chciałem przetestować sobie Cupset w Linux kernel 2.6. Standardowo pod PLD jest to wkompilowane w Kernel oraz wspierane (mniej więcej) w RC-scripts. Generalnie Cpusets  przydatne jest dla maszyn wieloprocesorowych. Służy do tworzenia wirtualnych procesorów, w których skład może wchodzić dowolna ilość procesorów fizycznych. Następnie, można przypisać wybrany proces do takiego wirtualnego procesora, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Ostatnio, z ciekawości chciałem przetestować sobie Cupset w Linux kernel 2.6. Standardowo pod PLD jest to wkompilowane w Kernel oraz wspierane (mniej więcej) w RC-scripts. Generalnie Cpusets  przydatne jest dla maszyn wieloprocesorowych. Służy do tworzenia wirtualnych procesorów, w których skład może wchodzić dowolna ilość procesorów fizycznych. Następnie, można przypisać wybrany proces do takiego wirtualnego procesora, tak, aby wykonywał się wyłącznie na nim. Potencjalne korzyści wydają się oczywiste:</p>
<ul style="text-align: justify;">
<li>przypisanie zasobów konkretnych procesorów dla wybranych usług, tak aby nie zajmowały sobie wzajemnie czasu procesora, eg. apache + mysql</li>
<li>przypisanie procesów wybranego użytkownika do konkretnego procesora</li>
<li>etc</li>
</ul>
<p style="text-align: justify;">Dla mnie ciekawym wydało się zastosowanie numer 1, z uwagi na fakt, iż mam Apache i MySql na tej samej maszynie. Postanowiłem zatem przypisać obie usługi do osobnych grup procesorów. Jako, iż dysponuje maszyną 2 x Intel(R) XEON(TM) CPU 2.20GHz każdej usłudze przypadło po 1 procesorze.</p>
<p style="text-align: justify;">Ogólne wnioski są takie, ze przy 2 procesorach nie warto. Apache zżera o wiele więcej czasu procesora niż MySQL, co skutkuje ciągłym przeciążeniem jednego procesora, i co za tym idzie obniżeniem wydajności. Procesor przypisany dla MySQL jest obciążany w tym czasie na poziomie 20-40%.</p>
<p style="text-align: justify;">Jedyną korzyścią, jaką widzę w tej konfiguracji, jest to, że przy dużym ruchu, Apache nie zablokuje całkowicie maszyny, ponieważ pozostałe usługi będą mogły wykonać się na mniej obciążonym procesorze.</p>
<p style="text-align: justify;">Przy większej ilości procesorów miało by to być może sensowne zastosowanie. Linki:</p>
<ul style="text-align: justify;">
<li> <a href="http://www.bullopensource.org/cpuset/" target="_blank">http://www.bullopensource.org/cpuset/</a></li>
</ul>
<h2 style="text-align: center;"><span id="more-100"></span><strong>Konfiguracja</strong>:</h2>
<p>/etc/sysconfig/system</p>
<pre class="bash"><span style="color: #808080; font-style: italic;"># Enable cpusets support?</span>
<span style="color: #007800;">CPUSETS=</span>yes</pre>
<p>/etc/sysconfig/cpusets/cpuset-0-httpd</p>
<pre class="bash"><span style="color: #808080; font-style: italic;"># Name of the cpuset</span>
<span style="color: #007800;">NAME=</span>cpuset<span style="color: #000000;">-0</span>-httpd
&nbsp;
<span style="color: #808080; font-style: italic;"># list of CPUs <span style="color: #000000; font-weight: bold;">in</span> that cpuset</span>
<span style="color: #007800;">CPUS=</span><span style="color: #000000;">0</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># list of Memory Nodes <span style="color: #000000; font-weight: bold;">in</span> that cpuset</span>
<span style="color: #007800;">MEMS=</span><span style="color: #000000;">0</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># If a cpuset is cpu or mem exclusive, no other cpuset, other than a direct</span>
<span style="color: #808080; font-style: italic;"># ancestor or descendent, may share any of the same CPUs or Memory Nodes.</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># is cpu placement exclusive?</span>
<span style="color: #007800;">CPU_EXCLUSIVE=</span><span style="color: #000000;">1</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># is memory placement exclusive?</span>
<span style="color: #808080; font-style: italic;">#<span style="color: #007800;">MEM_EXCLUSIVE=</span><span style="color: #000000;">1</span></span>
&nbsp;
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#<span style="color: #007800;">NOTIFY_ON_RELEASE=</span><span style="color: #000000;">0</span></span>
&nbsp;
<span style="color: #808080; font-style: italic;"># PIDs of tasks <span style="color: #000000; font-weight: bold;">in</span> this cpuset</span>
<span style="color: #808080; font-style: italic;">#<span style="color: #007800;">TASKS=</span></span>
&nbsp;
<span style="color: #007800;">ONBOOT=</span>yes</pre>
<p>/etc/sysconfig/cpusets/cpuset-1-mysql</p>
<pre class="bash"><span style="color: #808080; font-style: italic;"># Name of the cpuset</span>
<span style="color: #007800;">NAME=</span>cpuset<span style="color: #000000;">-1</span>-mysql
&nbsp;
<span style="color: #808080; font-style: italic;"># list of CPUs <span style="color: #000000; font-weight: bold;">in</span> that cpuset</span>
<span style="color: #007800;">CPUS=</span><span style="color: #000000;">1</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># list of Memory Nodes <span style="color: #000000; font-weight: bold;">in</span> that cpuset</span>
<span style="color: #007800;">MEMS=</span><span style="color: #000000;">0</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># If a cpuset is cpu or mem exclusive, no other cpuset, other than a direct</span>
<span style="color: #808080; font-style: italic;"># ancestor or descendent, may share any of the same CPUs or Memory Nodes.</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># is cpu placement exclusive?</span>
<span style="color: #007800;">CPU_EXCLUSIVE=</span><span style="color: #000000;">1</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># is memory placement exclusive?</span>
<span style="color: #808080; font-style: italic;">#<span style="color: #007800;">MEM_EXCLUSIVE=</span><span style="color: #000000;">1</span></span>
&nbsp;
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#<span style="color: #007800;">NOTIFY_ON_RELEASE=</span><span style="color: #000000;">0</span></span>
&nbsp;
<span style="color: #808080; font-style: italic;"># PIDs of tasks <span style="color: #000000; font-weight: bold;">in</span> this cpuset</span>
<span style="color: #808080; font-style: italic;">#<span style="color: #007800;">TASKS=</span></span>
&nbsp;
<span style="color: #007800;">ONBOOT=</span>yes</pre>
<p>Później robimy:</p>
<pre class="bash">service cpusets start</pre>
<p>W katalogu /dev/cpusets powinny pojawić sie dwa katalogi, o nazwach takich jakie podano w opcjach NAME. W następnej kolejności przypisujemy usługi do konkretnych Cpusets, defaultowo robi się to w plikach eg. /etc/sysyconfig/httpd dodając rozumianą przez RC-scripts opcję:</p>
<pre class="bash"><span style="color: #007800;">SERVICE_CPUSET=</span><span style="color: #ff0000;">&quot;cpuset-0-httpd&quot;</span></pre>
<p>RC-scripts, przypiszą wtedy podczas startu usługi jej proces do wybranego bpuset. W przypadku MySQL to nie działa, skrypt startowy jest napisany w innej konwencji. W tym przypadku standardowo trzeba dodać do /etc/sysconfig/mysql opcję:</p>
<pre class="bash"><span style="color: #007800;">SERVICE_CPUSET=</span><span style="color: #ff0000;">&quot;cpuset-1-mysql&quot;</span></pre>
<p>i dalej edytować /etc/init.d/mysql, poszukaj poniższy kawałek kodu, i dodaj brakującą linię:</p>
<pre class="bash">        <span style="color: #007800;">pid=</span>$!
&nbsp;
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;$pid&quot;</span> &amp;gt; <span style="color: #ff0000;">&quot;/dev/cpuset/${SERVICE_CPUSET}/tasks&quot;</span>
&nbsp;
        <span style="color: #c20cb9; font-weight: bold;">sleep</span> <span style="color: #000000;">0.1</span>
        mysqlstatus <span style="color: #ff0000;">&quot;$clusterdir&quot;</span> start
        <span style="color: #808080; font-style: italic;"># it takes longer <span style="color: #000000; font-weight: bold;">for</span> mysqld to start and create pidfile <span style="color: #000000; font-weight: bold;">if</span> it has to recover innodb transactions</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;$MYSQL_STATUS&quot;</span> = <span style="color: #ff0000;">&quot;starting&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; the</pre>
<p>Dalej, restart obu usług, cat /dev/cpusets/cpuset-0-httpd/tasks i cat /dev/cpusets/cpuset-1-mysql/tasks - w obu powinny być odpowiednie PIDy procesów, dalej htop i warto sprawdzić, czy faktycznie dany proces trzyma się swojego procesora.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kurylowicz.info/2009/04/09/cpuset-dla-linux-26/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Małe a cieszy: Postfix + SASL + Dovecot</title>
		<link>http://www.kurylowicz.info/2008/12/19/male-a-cieszy-postfix-sasl-dovecot/</link>
		<comments>http://www.kurylowicz.info/2008/12/19/male-a-cieszy-postfix-sasl-dovecot/#comments</comments>
		<pubDate>Fri, 19 Dec 2008 18:57:59 +0000</pubDate>
		<dc:creator>Arek Kuryłowicz</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.pink.art.pl/2008/12/19/male-a-cieszy-postfix-sasl-dovecot/</guid>
		<description><![CDATA[
Podręcznikowa konfiguracja Postfixa z uwierzytelnianiem SASL opiera się na Cyrus SASL. Nie znalazłem nigdzie innego przykładu. A tymczasem można inaczej!  Cyrus ma to do siebie, że jeśli chce się go zmusić do używania bazy SQL i do tego jeszcze szyfrowanych haseł, posługiwać się trzeba w celu rozwiązania tego problemu mechanizmem PAM, a dokładnie pam_mysql. [...]]]></description>
			<content:encoded><![CDATA[<p align="justify">
Podręcznikowa konfiguracja Postfixa z uwierzytelnianiem SASL opiera się na Cyrus SASL. Nie znalazłem nigdzie innego przykładu. A tymczasem można inaczej!  Cyrus ma to do siebie, że jeśli chce się go zmusić do używania bazy SQL i do tego jeszcze szyfrowanych haseł, posługiwać się trzeba w celu rozwiązania tego problemu mechanizmem PAM, a dokładnie pam_mysql. Rozwiązanie podręcznikowe, ale jak dla mnie niezbyt dobre. Sam  Cyrus co prawda potrafi przy pomocy pluginów autoryzować się w bazie SQL, ale jeśli hasło użytkownika jest szyfrowane, jest problem. Tutaj z pomocą przychodzi Dovecot, najczęściej stosowany serwer POP3/IMAP. Otóż zmuszenie go do współpracy z MySQL jest banalnie proste, a dodatkowo, o czym dowiedziałem się dziś zupełnie przypadkowo udostępnia własny mechanizm autoryzacji SASL. Konfiguracja to parę linijek w dovecot.conf i konfigach Postfixa. Małe a cieszy <img src='http://www.kurylowicz.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Linki:</strong></p>
<ul>
<li><a target="_blank" href=" http://wiki.dovecot.org/HowTo/PostfixAndDovecotSASL"> http://wiki.dovecot.org/HowTo/PostfixAndDovecotSASL</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.kurylowicz.info/2008/12/19/male-a-cieszy-postfix-sasl-dovecot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Konfiguracja łącza światłowodowego ATM POLPAK pod Linux PLD</title>
		<link>http://www.kurylowicz.info/2008/06/07/konfiguracja-lacza-swiatlowodowego-atm-polpak-pod-linux-pld/</link>
		<comments>http://www.kurylowicz.info/2008/06/07/konfiguracja-lacza-swiatlowodowego-atm-polpak-pod-linux-pld/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 22:08:00 +0000</pubDate>
		<dc:creator>Arek Kuryłowicz</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.pink.art.pl/2008/06/07/konfiguracja-lacza-swiatlowodowego-atm-polpak-pod-linux-pld/</guid>
		<description><![CDATA[Firma ISP dla której od czasu do czasu świadczę usługi postanowiła wykupić nieco szybsze łącze i z uwagi na w sumie niewielki, a właściwie żaden   wybór - padło na Telekomunikację Polską. Interesującą okazała się usługa ATM/Frame relay. Z uwagi na zastosowaną technologie jak i wymagania co do transferu łącze zakończone zostało światłowodem.
Jako zakończenie [...]]]></description>
			<content:encoded><![CDATA[<p>Firma <a href="http://www.e-mactel.com/" target="_blank">ISP</a> dla której od czasu do czasu świadczę usługi postanowiła wykupić nieco szybsze łącze i z uwagi na w sumie niewielki, a właściwie żaden <img src='http://www.kurylowicz.info/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  wybór - padło na Telekomunikację Polską. Interesującą okazała się usługa <a href="http://www.tp.pl/prt/pl/klienci_biz/transmisja_danych/frame_relay/">ATM/Frame relay</a>. Z uwagi na zastosowaną technologie jak i wymagania co do transferu łącze zakończone zostało światłowodem.</p>
<p>Jako zakończenie klienckie użyta została karta <a href="http://www.prosum.net/atmv155_E.html" target="_blank">PROATM-V155FM</a> firmy Prosum. Jest to doskonała <strong>alternatywa</strong> do zastosowań sprzetowych typu <em>Cisco, Nortel</em>, etc, szczególnie jeśli chodzi o cenę. W Polsce koszt zakupu tej karty na chwilę obecną to około 2.500 zł. Tak więc przy koszcie ~3k, bazuąc na Linuxie można uruchomić w pełni funkcjonalny punkt dostępowy obsługujący interfejs ATM, routing, firewall, QOS oraz dodatkowe, przydatne usługi takie jak DHCP, lokalny DNS.</p>
<p>Zasadniczo karta ma wsparcie w postaci natywnie dostarczanych wraz z kernelem sterowników - konfiguracja samego ATM jest wspierana przez kernel i oprogramowanie linux-atm - w <a target="_blank" href="http://www.pld-linux.org/">PLD</a>, którego użyłem jako systemu bazowego - dostępne są nawet rc-scripts które w ładny sposób pozwalają skonfigurować interfejs i resztę rzeczy.</p>
<p>Sama konfiguracja poszła szybko i bezproblemowo - sterownik wykrył kartę bez problemu - skrypty podniosły interfejs - pozostało czekać jedynie na zestawienie łącza.</p>
<p>Niestety po uruchomieniu usługi przez TP sprawa się nieco skomplikowała. Otóż okazało się że całość po prostu nie działa. Po ponad 2 dniowych rozmowach z działem reklamacyjnym POLPAKu skierowano mnie wreszcie do kompetentnej (dziękuję Panie Grzegorzu za okazaną pomoc) osoby, która była mi stanie wyjaśnić mi na czym dokładnie polega problem.</p>
<p>Otóż TP podłącza klientów do dwóch rodzajów przełączników ATM, o ile przełączniki <em>Nortel Passport 4860</em> nie sprawiają większych problemów, o tyle <em>Nortel Passport 15000/20000</em> wymagają komunikacji z użyciem protokołu strict SDH.</p>
<p><span id="more-80"></span>Problem niestety leży w tym, iż sterownik warstwy ATM w linuxie (suni) domyślnie pracuje z użyciem protokołu SONET - starsze przełączniki są to w stanie obsłużyć - nowsze niestety wymagają obsługi SDH.</p>
<p>Po jakimś czasie grzebania w źródłach sterownika karty i sterowniku suni udało mi się zmusić do inicjalizacji domyślnie w trybie SDH co oczywiście poskutkowało natychmiastowym (na wcześniej przygotowanych konfigach) uaktywnieniem łącza.</p>
<p>Ok, jak to zatem wszystko do kupy uruchomić? Otóż na początek należy od TP uzyskać informacje o adresacji, adresie IP przełącznika, oraz VPI/VCI. Warto równe, po to aby uniknąć kłopotów dowiedzieć się do <strong>jakiego przełącznika</strong> jest wpięte zakończenie - szczególnie zaś jakiego protokołu wymaga. Jeśli jest to starszy typ przełącznika Nortel, lub taki który obsłuży protokół SONET całość prawdopodobnie ruszy na domyślnym sterowniku, który jest dostępny w paczce z kernelem PLD. Jeśli przełącznik wymaga SDH lub nie powiedzie sie uruchomienie karty na domyślnym sterowniku niestety czeka cię ręczna kompilacja jądra.</p>
<p>Przed kompilacją jądra pobrać należy <a target="_blank" href="http://www.prosum.net/soft_E.html#proatm">sterowniki dla karty</a>, które znaleźć można na stronie producenta. Po wymianie listów i wskazaniu problemu producent poprawił sterowniki, tak aby inicjowały suni w trybie SDH, tak więc używając obecnie dostępnych sterowników nie musisz grzebać w suni.</p>
<p>W dalszej kolejności pobieramy paczkę ze źródłami kernela oraz wszystko co przyda sie do kompilacji (mam nadzieję że nie pominąłem niczego, część nie podanych tu pakietów doinstaluje sie jako zależności):</p>
<p><code>[root@ozi-x proc]# poldek -i patch gcc make glibc-devel ncurses-devel kernel-sources</code></p>
<p>Lepiej jest użyć gotowej paczki PLD, gdyż te źródła kernela zawierają nałozone już wszystkie przydatne później łaty takie jak IMQ, Layer7, esfq, etc. W dalszej kolejności przekopiować należy pliki z paczki do katalogu drivers/atm, nałożyć patch odpowiedni dla wersji kernela, <strike>wyedytować <em>nicstar.h</em> i uaktywnić opcję NS_SUNI_FULL_SDH </strike> <em>(update: poczytaj dołączony do sterownika plik README, wymuszenie trybu SDH odbywa sie aktualnie poprzez przekazanie parametru  do modułu)</em>, zaznaczyć odpowiednie moduły do kompilacji i skompilować jądro. Zajrzyj do README, który znajdziesz w paczce ze sterownikiem - tam jest opisane które moduły należy zaznaczyć przy kompilacji kernela, którego patcha użyć, etc.</p>
<p>Tutaj jedna uwaga - zmiany w sterowniku, wg. tego co mi napisał producent nie zostały jeszcze przetestowane za switchem SDH tak więc nie ma pewności że działają. Producent prosił mnie o przeprowadzenie testów, niestety w tym momencie nie jestem tego w stanie zrobić. Jeśli z jakiegoś powodu sterownik nadal by nie działał potrzebne jest patchowanie suni.c</p>
<p>Po kompilacji otrzymujemy sterownik <strong>nicstar</strong> - który to najlepiej dopisać do /etc/modules - tak aby się ładował przy starcie.</p>
<p>Sama karta powinna być widoczna via lspci:</p>
<p><code>[root@ozi-x proc]# lspci<br />
[...]<br />
02:08.0 ATM network controller: Integrated Device Technology, Inc. IDT77222/77252 155Mbps ATM MICRO ABR SAR Controller (rev 05)</code></p>
<p>Załadowanie sterownika <strong>nicstar</strong> powinno wrzucić do logu kernela:</p>
<p><code>NET: Registered protocol family 8<br />
NET: Registered protocol family 20<br />
nicstar0: PHY type detection called.<br />
nicstar0: PHY seems to be 155 Mbps.<br />
nicstar0: SRAM size = 512K x 32bit<br />
nicstar0: vpibase=0, vcibase=0, VPM=0x0<br />
nicstar0: MAC address 00:XX:XX:XX:XX:XX</code></p>
<p>Załadowanie sterownika <strong>idt77252</strong> wygląda nieco inaczej:</p>
<p><code>NET: Registered protocol family 8<br />
NET: Registered protocol family 20<br />
idt77252_init: at df80d000<br />
ACPI: PCI Interrupt 0000:02:08.0[A] -&gt; GSI 18 (level, low) -&gt; IRQ 169<br />
idt77252-0: ABR SAR (Rev E): MEM f1000000 SRAM f4000000 [2048 KB]<br />
idt77252-0: Linkrate on ATM line : 149760000 bit/s, 353207 cell/s.</code></p>
<p>W obu przypadkach załadowanie sterownika powinno automatycznie załadować sterowniki atm i suni.</p>
<p>Paczki które należy zainstalować w PLD to:</p>
<p><code>[root@ozi-x proc]# poldek -i linux-atm linux-atm-rc-scripts</code></p>
<p>Następnie wyedytuj plik:</p>
<p><code>[root@ozi-x atm]# cat /etc/sysconfig/atm<br />
ATM=yes<br />
ATM_NICS_NUMBER=1<br />
CLIP=yes<br />
LANE=no<br />
BR2684=no<br />
PPPOA=no<br />
LANE_SERVER_SERVICES=no<br />
ILMI=yes</code></p>
<p>Konfiguracja samego interfejsu powinna wyglądać tak:</p>
<p><code>[root@ozi-x atm]# cat /etc/sysconfig/interfaces/ifcfg-atm0<br />
# ip - adres ip przydzielony przez TP<br />
# gw - adres portu routera brzegowego<br />
DEVICE=atm0<br />
IPADDR=80.50.55.ip<br />
PREFIX=30<br />
ATMARP_REMIP=80.50.55.gw<br />
ATMARP_PVC=0.VPI.VCI<br />
ATMARP_QOS="ubr,aal5:pcr=20000"<br />
DEFAULTHANDLING=yes<br />
ARP=yes<br />
ONBOOT=yes<br />
</code><code>. /etc/sysconfig/network-scripts/ifup-atm.post</code></p>
<p>Uruchom usługę ATM:</p>
<p><code>[root@ozi-x atm]# service atm start</code></p>
<p>I teraz trochę diagnostyki. Użyteczne informacje znajdziesz w /proc/net/atm - w pvc powinieneś zobaczyć wszystkie zestawione kanały PVC - w szczególności ten odpowiadający VPI/VCI twojego łącza:</p>
<p><code>[root@ozi-x atm]# cat /proc/net/atm/pvc<br />
Itf VPI VCI   AAL RX(PCR,Class) TX(PCR,Class)<br />
0   0     5 5         0 UBR         0 UBR<br />
0   0    16 5         0 UBR         0 UBR<br />
0   x   xxx 5         0 UBR         0 UBR   CLIP, Itf:atm0, Encap:LLC/SNAP<br />
</code><br />
0.5 i 0.16 są zestawiane przez atmsigd i ilmi i służą do sterowania sygnalizacją ATM</p>
<p>Dodatkowo używając atmarp możesz sprawdzić czy poprawnie zestawił się CLIP via PVC:</p>
<p><code>[root@ozi-x atm]# atmarp -a<br />
----- Itf 0 (80.50.55.ip, netmask 255.255.255.252) -----<br />
Default QOS: ubr,aal5:max_sdu=9188<br />
IP 80.50.55.gw, state VALID, addr &lt;none&gt;, flags 0x4&lt;PERM&gt;<br />
QOS: ubr,aal5:pcr=20000,max_sdu=9188<br />
0.vpi.vci<br />
Send buffer: 109568<br />
----- Unknown incoming connections -----<br />
----- Incoming unidirectional connections -----<br />
----- End of dump -----<br />
</code><br />
Statystyki ramek ATM pokazuje atmdiag:</p>
<p><code>[root@ozi-x atm]# atmdiag<br />
Itf       TX_okay   TX_err    RX_okay   RX_err    RX_drop<br />
0 AAL0         0         0         0         0         0<br />
AAL5  103087429         0  131246245         0         0</code></p>
<p>W przypadku <strong>pojawienia się problemów</strong> z protokołem SONET/SDH (patrz port switcha ATM i sterownik) interfejs podniesie się bez problemów, otrzymasz również prawidłowe wyniki z atmarp. Zaś admdiag pokaże zmianę liczników TX_okay i <strong>RX_drop</strong>, RX_okay będzie cały czas pokazywało 0. Próbuj w takim przypadku kompilować sterownik ręcznie.</p>
<p>Jeśli wszystko jest prawidłowo, pingując IP portu switcha ATM powinieneś otrzymać odpowiedź. IP switcha oraz twoje IP powinno również odpowiadać na ping z zewnątrz. Tutaj uwaga: jeśli nie podniesiesz interfejsu ATM, lub wystąpią problemy w komunikacji karta-&gt;przełacznik ATM IP portu switcha <strong>nie odpowiada na ping</strong> z zewnątrz.</p>
<p>Po uruchomieniu interfejsu należy ustawić jeszcze domyślną bramę:</p>
<p><code>[root@ozi-x atm]# route del default<br />
[root@ozi-x atm]# route add default gw $ATMARP_REMIP</code></p>
<p>Można do dopisać do <em>/etc/sysconfig/network-scripts/ifup-atm.post</em>, nie ma chyba lepszej metody bo skrypty nie ustawiają domyślnej bramy same.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kurylowicz.info/2008/06/07/konfiguracja-lacza-swiatlowodowego-atm-polpak-pod-linux-pld/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PLD i kilka łącz (routing wielobramowy)</title>
		<link>http://www.kurylowicz.info/2007/11/06/pld-i-kilka-lacz-routing-wielobramowy/</link>
		<comments>http://www.kurylowicz.info/2007/11/06/pld-i-kilka-lacz-routing-wielobramowy/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 22:06:26 +0000</pubDate>
		<dc:creator>Arek Kuryłowicz</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.pink.art.pl/2007/11/06/pld-i-kilka-lacz-routing-wielobramowy/</guid>
		<description><![CDATA[Jakiś, spory już czas temu stanąłem przed zadaniem konfiguracji load-balance'ingu w oparciu o moje ulubione PLD Linux pomiędzy kilkoma łączami zewnętrznymi. Po przeszukaniu sieci prawdę powiedziawszy, nie znalazłem kompleksowego HOW-TO. Może po prostu przeoczyłem, nie mniej jednak dziś postaram się opisać sposób w który ja rozwiązałem powyższy problem
Trochę teorii.
Największą bolączką powszechnie dostępnych tanich łącz klasy [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś, spory już czas temu stanąłem przed zadaniem konfiguracji load-balance'ingu w oparciu o moje ulubione <a HREF="http://www.pld-linux.org/" TARGET="_blank">PLD Linux</a> pomiędzy kilkoma łączami zewnętrznymi. Po przeszukaniu sieci prawdę powiedziawszy, nie znalazłem kompleksowego HOW-TO. Może po prostu przeoczyłem, nie mniej jednak dziś postaram się opisać sposób w który ja rozwiązałem powyższy problem</p>
<p><strong>Trochę teorii.</strong></p>
<p>Największą bolączką powszechnie dostępnych tanich łącz klasy <em>TPSA Internet DSL</em> jest ich niesymetryczność. Jeśli cały ruch z wewnętrznej sieci puścimy przez niesymetryczne łącze, to nawet pomimo stosowania QOS istnieje duże prawdopodobieństwo, że użytkownicy programów p2p szybko zapchają upload, co skutkuje skutecznymi opóźnieniami na łączu niezależnymi od wysycenia downloadu. Warto zauważyć również, iż zwykły użytkownik relatywną prędkość jego łącza ocenia poprzez jakość działania najpopularniejszych usług takich jak poczta czy WWW.  Interesującym zatem, z punktu widzenia jakości usługi jest priorytetyzacja/izolacja pewnych usług, które mają bezpośredni wpływ na zadowolenie klientów z posiadanego łącza.</p>
<p><span id="more-74"></span></p>
<p><strong>Założenia:</strong></p>
<ul>
<li>trzy lub więcej łącz zewnętrznych (<em>InternetDSL</em>)</li>
<li><em>PLD Linux</em> 2.4 jako NAT+<em>HTB</em>. Kernel 2.4 jest z mojego doświadczenia stabilny dla proponowanego rozwiązania. Z kernelami 2.6 nie udało mi się tego uruchomić (być może to jakiś PLD specyfic) nie mniej jednak powszechnie znane są problemy dla tego kernela z HTB.</li>
<li>dwie wewnętrzne klasy adresowe</li>
</ul>
<p><strong>Rozważmy taki układ:</strong></p>
<ul>
<li>eth0, ip: 80.0.0.2, gw: 80.0.0.1: ruch domyślny dla klasy 192.168.1.0/24</li>
<li>eth1, ip: 80.0.1.2, gw: 80.0.1.1: ruch domyślny dla klasy 192.168.2.0/24</li>
<li>eth2, ip: 80.0.2.2, gw: 80.0.2.1: łącze na wyizolowane usługi dla obu klas</li>
<li>eth3, ip: 192.168.1.254: klasa adresowa wewnętrzna</li>
<li>eth4, ip: 192.168.2.254:  klasa adresowa wewnętrzna</li>
</ul>
<p>Poprzez ruch domyślny rozumiem wszystkie, nie oznaczone specjalnie pakiety, ruch izolowany to WWW, POP3, SMTP</p>
<p><strong>Implementacja:</strong><br />
Poniższa implementacja jest słuszna właściwie dla każdego systemu wspierającego <em>iproute2</em> i <em>iptables</em>. Konfigurujemy standardowo 5 interfejsów sieciowych przypisując im właściwe adresy. Nie definiujemy w pliku <em>/etc/sysconfig/network</em> bramy ustawiając parametry na:</p>
<pre>
GATEWAY=""
GATEWAYDEV=""</pre>
<p>Zestaw magicznych komend do skonfigurowania ręcznego routingu.</p>
<p>Przypisujemy kazde łacze do osobnej tablicy routingu:</p>
<pre>
ip route add default via 80.0.0.1 table 10
ip route add 192.168.1.0/24 via 192.168.1.254 table 10
ip route add 192.168.2.0/24 via 192.168.2.254 table 10           

ip route add default via 80.0.1.1 table 20
ip route add 192.168.1.0/24 via 192.168.1.254 table 20
ip route add 192.168.2.0/24 via 192.168.2.254 table 20           

ip route add default via 80.0.3.1 table 30
ip route add 192.168.1.0/24 via 192.168.1.254 table 30
ip route add 192.168.2.0/24 via 192.168.2.254 table 30</pre>
<p>Następnie definiujemy która klasa powinna być routowana przez którą tablicę, przez 10 i 20 puszczamy ruch w całości per klasa adresowa, przez 30 tylko ruch znaczony:</p>
<pre>
ip rule add from 192.168.1.0/24 table 10
ip rule add from 192.168.2.0/24 table 20
ip rule add from 192.168.1.0/24 fwmark 0x41 table 30
ip rule add from 192.168.2.0/24 fwmark 0x42 table 30           

ip rule add from 80.0.0.2 table 10
ip rule add from 80.0.2.2 table 20
ip rule add from 80.0.3.2 table 30</pre>
<p>Definiujemy routing prywatny: domyślna brama, używając wszystkich łącz. Używane będzie dowolne dostępne (wszystko jako jedna komenda):</p>
<pre>
ip route add default scope global
  nexthop via 80.0.0.1 dev eth0 weight 1
  nexthop via 80.0.1.1 dev eth1 weight 1
  nexthop via 80.0.2.1 dev eth2 weight 1</pre>
<p>Tyle z routingiem, komendy można wpisać do własnego skryptu uruchamianego zaraz po podniesieniu interfejsów sieciowych lub po prostu do <em>rc.local</em></p>
<p>Dalej konfiguracja <em>/proc</em> Opcję <em>rp_filter</em> trzeba ustawić na 0 i uaktywnić <em>ip_forward</em>:</p>
<pre>
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo "0" &gt; $f; done
sysctl -n -e -w net.ipv4.conf.all.rp_filter="0"
sysctl -n -e -w net.ipv4.ip_forward="1"</pre>
<p>Jak wyżej, warto to wpisać razem z komendami konfigurującymi routing.</p>
<p>Teraz <em>iptables</em>:</p>
<p>Standardowo NAT:</p>
<pre>
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 80.0.0.2
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j SNAT --to 80.0.0.2
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to 80.0.1.2
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth1 -j SNAT --to 80.0.1.2
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth2 -j SNAT --to 80.0.2.2
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth2 -j SNAT --to 80.0.2.2</pre>
<p>I znaczymy pakiety które mają iść izolowanym łączem (wcięcie linii to kontunuacja poprzedniej):</p>
<pre>
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -i eth3 -p tcp -m mport --dports 25,80,110,443 
   -j MARK --set-mark 0x41
iptables -t mangle -A PREROUTING -i eth4 -p tcp -m mport --dports 25,80,110,443 
   -j MARK --set-mark 0x42
iptables -t mangle -A PREROUTING -m mark ! --mark 0x0 -j RETURN</pre>
<p>I tyle.</p>
<p>Jak łatwo zauważyć konfiguracja jest nadmiarowa (np nie trzeba NATować wszystkich klas) ale w przypadku awarii np łącza 80.0.1.2 możemy szybko przełączyć cały ruch na łącze 80.0.0.2 puszczając go przez tablicę 10:</p>
<pre>
ip rule add from 192.168.2.0/24 table 20 -&gt; ip rule add from 192.168.2.0/24 table 10</pre>
<p>Pakiety można znaczyć (<em>mark</em>) wg dowolnych reguł, np. adresu docelowego, dla serwerów gier czy np. <em>GG</em>, adresu źródłowego: można wyizolować ruch dla poszczególnych klientów. Pewnym rozwiązaniem może być także przypisanie do każdej z tablic znacznika (tak jak dla tablicy 30) i znaczenie via iptables całego ruchu. Z doświadczenia: problematycznym jest znaczenie pakietów p2p przez moduł <em>ipp2p</em> ponieważ nie klasyfikuje on wszystkich pakietów poprawnie i występują problemy. Ruch p2p lepiej zostawić nieoznaczony i puścić domyślnym łączem. Nie pokusiłem się również o priorytetyzację VoIP czy eg. <em>Skype</em>. Można do tego użyć modułu <em>Layer7</em> (??) niedostępnego standardowo w PLD.</p>
<p>Przypuszczalnie całość można, a nawet trzebaby zrobić "koszerniej", routing do <em>/etc/sysconfig/static-routes</em>  <em>/etc/sysconfig/static-rules</em>, konfig <em>/proc </em>do <em>/etc/sysctrl</em>, iptables via jakaś nakładka. Wszystkie udoskonalenia mile widziane w komentarzach.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kurylowicz.info/2007/11/06/pld-i-kilka-lacz-routing-wielobramowy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Przygoda z Perlem</title>
		<link>http://www.kurylowicz.info/2007/08/17/przygoda-z-perlem/</link>
		<comments>http://www.kurylowicz.info/2007/08/17/przygoda-z-perlem/#comments</comments>
		<pubDate>Thu, 16 Aug 2007 23:01:32 +0000</pubDate>
		<dc:creator>Arek Kuryłowicz</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.pink.art.pl/2007/08/17/przygoda-z-perlem/</guid>
		<description><![CDATA[Dla frajdy cały weekend poświęciłem na rozwijanie swoich umiejętności programowania w Perlu. Perl! Totalny oldshool - kto dziś tego używa? pewno ktoś zapyta. Nie wiem, ale Perl wydaje się na tyle ciekawym językiem programowania, aby zapoznać się z nim trochę.
Na pierwszy ogień poszedł bot GG. Założenia:

boot powinien pracować jako pooler wiadomości dokładanych do bazy danych [...]]]></description>
			<content:encoded><![CDATA[<p>Dla frajdy cały weekend poświęciłem na rozwijanie swoich umiejętności programowania w Perlu. Perl! Totalny oldshool - kto dziś tego używa? pewno ktoś zapyta. Nie wiem, ale Perl wydaje się na tyle ciekawym językiem programowania, aby zapoznać się z nim trochę.</p>
<p>Na pierwszy ogień poszedł bot GG. Założenia:</p>
<ol>
<li>boot powinien pracować jako pooler wiadomości dokładanych do bazy danych przez zewnętrzne aplikacje.</li>
<li>boot powinien obsługiwać komunikaty wysłane do niego od innych użytkowników.</li>
<li>bot powinien mieć możliwośc dołożenia dodatkowych protokołów (Jabber)</li>
</ol>
<p>Implementacja  obsługi GG poszła szybko za sprawą linuxowej biblioteki <a TARGET="_blank" HREF="http://toxygen.net/libgadu/">LibGadu</a>  oraz perlowej nakładki na nią czyli <a TARGET="_blank" HREF="http://search.cpan.org/~krzak/Net-Gadu/Gadu.pm">Net::Gadu</a>. Problemy pojawiły się później. Po zaimplementowaniu obsługi GG postanowiłem zabrać się za wątki, gdyż jest  to jedyny sensowny sposób oprogramowania moich założeń. Niestety okazało  się,  iż  nie  sposób wymieniać dane między wątkiem głównym a wątkami potomnymi. Przypuszczam, że spowodowane jest to właściwościami samego  obiektu  klasy Net::Gadu. Postanowiłem zatem wspomóc się mechanizmami pamięci  współdzielonej.  Implementacja poszła bezproblemowo, niestety okazało  się,  iż  iterujące  w  pętli  nieskończonej  oczekiwanie  na komunikat przez obiekt GG niemiłosiernie obciąża system kiedy odwołuje się do obiektu w pamięci współdzielonej.</p>
<p>Przyznam,  że  nie  wiem  jak  rozwiązać ten problem. W chwili wolnego czasu spróbuję nad tym popracować.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kurylowicz.info/2007/08/17/przygoda-z-perlem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Efektywne zarządzanie bazą danych serwera wirtualnego z backendem MySQL (część 1)</title>
		<link>http://www.kurylowicz.info/2007/07/24/efektywne-zarzadzanie-baza-danych-serwera-wirtualnego-z-backendem-mysql/</link>
		<comments>http://www.kurylowicz.info/2007/07/24/efektywne-zarzadzanie-baza-danych-serwera-wirtualnego-z-backendem-mysql/#comments</comments>
		<pubDate>Tue, 24 Jul 2007 00:03:02 +0000</pubDate>
		<dc:creator>Arek Kuryłowicz</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.pink.art.pl/2007/07/24/efektywne-zarzadzanie-baza-danych-serwera-wirtualnego-z-backendem-mysql/</guid>
		<description><![CDATA[Wielu   osobom  nieobce  jest  zagadnienie  instalacji  usług  serwera wirtualnego (pDNS, Postfix, SASL, Dovecot, Pureftpd, Amavis, GPS, Apache)  w  oparciu  backend na  bazie  danych MySQL. Rozwiązanie takie jest bardzo elastyczne i bezpieczne stanowiąc jednocześnie punkt wyjścia do efektywnego  zarządzania  usługą.
Do w/w integracji [...]]]></description>
			<content:encoded><![CDATA[<p>Wielu   osobom  nieobce  jest  zagadnienie  instalacji  usług  serwera wirtualnego (pDNS, Postfix, SASL, Dovecot, Pureftpd, Amavis, GPS, Apache)  w  oparciu  backend na  bazie  danych MySQL. Rozwiązanie takie jest bardzo elastyczne i bezpieczne stanowiąc jednocześnie punkt wyjścia do efektywnego  zarządzania  usługą.</p>
<p>Do w/w integracji często stosuje się następujące oprogramowanie:</p>
<ul>
<li>pDNS jako serwer DNS (1)</li>
<li>  Postfix wraz z SASL jako MTA</li>
<li>  Dovecot jako serwer usług POP3/IMAP</li>
<li>  Apache</li>
<li>  pureFTPd (2)</li>
</ul>
<p>1) Bind jest najczęściej stosowanym serwerem DNS, jednakże pDNS oferuje natywne wsparcie MySQL oraz bardzo łatwą (gotowe programy) migrację</p>
<p>2) Zazwyczaj stosuje się proFTPd, którego przez długi czas i ja byłem zwolennikiem - jednakże z uwagi na problematyczną konfigurację z MySQL (problemy z quota) zrezygnowałem z niego.</p>
<p>Dodatkowo stosuję oprogramowanie<br />
- GPS - wspierający MySQL grey-list policy server dla Postfixa<br />
- Amavis jako SMTP proxy wspierające skanowanie antyvirusowe (clamav) i antyspamowe (spamassasin)</p>
<p>Integracja całości jest przedmiotem wielu FAQ oraz całej masy dokumentacji którą można znaleźć w googlach, tak więc nie na tym będę się skupiał. Skupie się na samej strukturze bazy danych.</p>
<p>Otóż zauważyć można podczas integracji pewną nadmiarowość i duplikowanie informacji w wielu tabelach podczas konfigurowania różnych usług dla tego samego klienta.</p>
<p><span id="more-70"></span></p>
<p>I tak aby zgodnie z większością znanych opisów integracji metodą dodać klientowi pełną obsługę wszystkich usług musimy:</p>
<ul>
<li>dodać wpisy w 2 tabelach pDNS</li>
<li>  dodać wpisy w 3 tabelach postfixa</li>
<li>  dodać wpisy w tabeli dla Dovecot jeśli nie używamy tabeli Postfixa</li>
<li>  dodać 1 wpis w tabeli pureFTPd</li>
<li>  dodać 2(?) wpisy w tabeli amavis</li>
</ul>
<p>Większość z informacji, które dodajemy do tych tabel jest duplikowana. W przypadku potrzeby zarządzania tą informacją mamy problem. Co zrobić aby nie duplikować niepotrzebnie informacji. Otóż z pomocą przychodzą nam tutaj mechanizmy view (w dalszej części będę używał nazwy widok) dostępne w MySQL od wersji 5.</p>
<p>Przyjrzyjmy się najpierw tabelą pDNS. Tutaj uwaga. Wszystkie tabele mają format zgodny z powszechnie stosowanymi opisami integracji usługi z MySQL. Różnią się tylko nazwą, którą dla własnej wygody prefixowałem nazwą usługi.</p>
<pre>mysql&gt; desc pdns_domains;
+-----------------+------------------+------+-----+---------+----------------+
| Field           | Type             | Null | Key | Default | Extra          |
+-----------------+------------------+------+-----+---------+----------------+
| id              | int(11)          | NO   | PRI | NULL    | auto_increment |
| name            | varchar(255)     | NO   | UNI |         |                |
| master          | varchar(20)      | YES  |     | NULL    |                |
| last_check      | int(11)          | YES  |     | NULL    |                |
| type            | varchar(6)       | NO   |     |         |                |
| notified_serial | int(11) unsigned | YES  |     | NULL    |                |
| account         | varchar(40)      | YES  |     | NULL    |                |
+-----------------+------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)</pre>
<pre>mysql&gt; desc pdns_records;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| domain_id   | int(11)      | YES  | MUL | NULL    |                |
| name        | varchar(255) | YES  | MUL | NULL    |                |
| type        | varchar(6)   | YES  |     | NULL    |                |
| content     | varchar(255) | YES  |     | NULL    |                |
| ttl         | int(11)      | YES  |     | NULL    |                |
| prio        | int(11)      | YES  |     | NULL    |                |
| change_date | int(11)      | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
8 rows in set (0.01 sec)</pre>
<p>Otóż tabel pDNS zmieniać nie możemy z tej oto przyczyny, iż pDNS zapisuje samodzielnie informacje do obu tabel, tak więc nie mogą być one przekonwertowane do widoku. Tabela pdns_domains zawiera jednakże istotne informacje, mianowicie AKTYWNE w naszym systemie domeny podstawowe i zapasowe.</p>
<p>Rzućmy okiem na tabele używane przez Postfixa:</p>
<pre>mysql&gt; show tables like 'postfix%';
+------------------------------+
| Tables_in_vserver (postfix%) |
+------------------------------+
| postfix_alias                |
| postfix_domains              |
| postfix_mailbox              |
+------------------------------+
3 rows in set (0.00 sec)</pre>
<pre>mysql&gt; desc postfix_domains;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| domain   | varchar(255) | NO   |     |         |       |
| backupmx | tinyint(1)   | NO   |     | 0       |       |
+----------+--------------+------+-----+---------+-------+
2 rows in set (0.01 sec)</pre>
<pre>mysql&gt; desc postfix_mailbox;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| username | varchar(255) | NO   | PRI |         |       |
| password | varchar(255) | NO   |     |         |       |
| maildir  | varchar(255) | NO   |     |         |       |
| quota    | int(10)      | NO   |     | 0       |       |
| domain   | varchar(255) | NO   | MUL |         |       |
| active   | tinyint(1)   | NO   | MUL | 1       |       |
+----------+--------------+------+-----+---------+-------+
6 rows in set (0.00 sec)</pre>
<p>Otóż w tabeli postfix_domains znajduje się lista domen obsługiwanych przez nasz system. Dodatkowo znajdują się tam domeny których backup MX utrzymujemy. Z dużym prawdopodobieństwem założyć można, iż będzie to lista domen których DNS utrzymujemy w pDNS. W tabeli postfix_mailbox znajdują się konta użytkowników, tabela ta może być współdzielona przez SASL oraz Dovecot, aczkolwiek jest to nieefektywne z uwagi do różnego sposobu podejścia do tematu blokowania kont.<br />
Zazwyczaj blokada tymczasowa ma na celu zablokowanie możliwości wysyłania i odbierania poczty przy jednoczesnym braku blokady na pocztę przychodzącą.</p>
<p>Tabela serwera FTP, poniższy schemat jest schematem pochodzącym z dokumentacji:</p>
<pre>mysql&gt; desc ftpd_users;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| User     | varchar(16)  | NO   | PRI |         |       |
| Password | varchar(64)  | NO   |     |         |       |
| Uid      | int(11)      | NO   |     | -1      |       |
| Gid      | int(11)      | NO   |     | -1      |       |
| Dir      | varchar(128) | NO   |     |         |       |
+----------+--------------+------+-----+---------+-------+
5 rows in set (0.01 sec)</pre>
<p>Do rzeczy: założenia:</p>
<ul>
<li>  projektowany schemat danych ma mieć zastosowanie w serwerze wirtualnym, który może obsługiwać sporą ilość domen i być punktem wyjścia do zarządzania przy pomocy interfejsu WWW.</li>
<li>  podstawową jednostką przyporządkowania użytkowników do grup będzie domena</li>
<li>  Chcemy mieć na tyle elastyczny system, aby jednym wpisem w odpowiedniej tabeli dało się uaktywnić użytkownikowi cały zestaw usług.</li>
<li>  Chcemy dodatkowo zapewnić minimalną duplikację danych w całym systemie oraz pewne mechanizmy weryfikacji danych na poziomie bazy.</li>
</ul>
<p>Cdn...</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kurylowicz.info/2007/07/24/efektywne-zarzadzanie-baza-danych-serwera-wirtualnego-z-backendem-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
