PHP: syntax error, unexpected $end

Dla zdezorientowanych, w przypadku pojawienia się błędu o podobnej treści:

Parse error: syntax error, unexpected $end in /usr/home/test/application/views/v_main.php on line 1731

Najlepiej jest nie panikować.
Wiemy, że kod jest poprawny, wiemy, że błąd ten generowany jest gdy mamy niepełny kod i brakuje klamer zamykających.

Rozwiązanie:
edytujemy na serwerze plik php.ini i ustawiamy zmienną:

short_open_tag = On

i już.

kernel: panic: ffs_blkfree: freeing free block

Po zainstalowaniu czyściutkiego nowego systemu FreeBSD 8.0-RELEASE, pracując już po SSH (putty) podczas instalowania odpowiednich portów (polecenie: make install clean), system zaczął się dziwnie i niestabilnie zachowywać. Skutkiem niestabilności były restarty systemu w zasadzie z niewyjaśnionych przyczyn.
Przykład: port się kompiluje i nagle restart, putty traci łączność z serwerem, ponownie zalogowanie do systemu, sprawdzenie uptime, gdzie z reguły było kilka sekund/minut. Na koniec dmesg, który potwierdzał restart serwera.
Po każdym restarcie szukałem informacji w logach (/var/run, /var/log). Jedynie co znajdywałem to informację o restarcie.
Ciekawostką było to, że restarty pojawiały się w dowolnym momencie i tylko podczas pracy dysku (read/write). A czasami w logach nie widać nieprawidłowej pracy dysków.
Nieufność do nowych dysków Caviara (tylko 320GB) pokierowały moją intuicją, aby sprawdzić logi S.M.A.R.T. (portem smartmontools). Ale niestety, niczego złego tam nie znalazłem (No Errors Logged).
Zmieniłem kable. Żadnych zmian. Podłączyłem monitor i… przy restartach miałem coś takiego:

Jan 19 09:13:41 fox syslogd: kernel boot file is /boot/kernel/kernel
Jan 19 09:13:41 fox kernel: dev = ad0s1f, block = 1, fs = /usr
Jan 19 09:13:41 fox kernel: panic: ffs_blkfree: freeing free block
Jan 19 09:13:41 fox kernel: cpuid = 0
Jan 19 09:13:41 fox kernel: Uptime: 44m25s
Jan 19 09:13:41 fox kernel: Cannot dump. No dump device defined.
Jan 19 09:13:41 fox kernel: Automatic reboot in 15 seconds - press a key on the console to abort
Jan 19 09:13:41 fox kernel: Rebooting…

Może powinienem ustawić inny poziom logowania demona syslogd? Może wtedy zobaczyłbym powyższe zapisy w logach?
Jednakże z powodu braku czasu zarzuciłem temat wyszukiwarce google.
Okazało się, że freeing free block podczas pracy systemu i dysku, to bug samego systemu, z którym już od kilku lat borykają się autorzy dystrybucji freeBSD.
Wg ich sugestii należało wyłączyć tzw. softupdates dla danego systemu plików (u mnie native freebsd -> ufs).
Podobno softupdates przyspiesza pracę na dysków zwalniając odpowiednie bloki (freeing free blocks) wg zaawansowanych algorytmów.
Sprawdziłem więc jak było u mnie:

fox# mount
/dev/ad0s1a on / (ufs, local)
devfs on /dev (devfs, local, multilabel)
/dev/ad0s1e on /tmp (ufs, local, soft-updates)
/dev/ad0s1f on /usr (ufs, local, soft-updates)
/dev/ad0s1d on /var (ufs, local, soft-updates)

Postanowiłem wyłączyć softupdates dla /usr, na którym występował problem.
Nie można tego było zrobić on-the-fly (podczas pracy systemu), ponieważ /usr była w użyciu, a fix można wykonać tylko i wyłącznie na odmontowanej partycji. Jedyna droga to boot‚owanie systemu w trybie Single user mode.
Polecenie

#tunefs -n disable /usr

wyłącza softupdates na /usr.
Jeszcze szybko sprawdziłem aktualny stan ustawień systemu plików

fox# mount
/dev/ad0s1a on / (ufs, local)
devfs on /dev (devfs, local, multilabel)
/dev/ad0s1e on /tmp (ufs, local, soft-updates)
/dev/ad0s1f on /usr (ufs, local)
/dev/ad0s1d on /var (ufs, local, soft-updates)

i reboot.
Jakoś do dzisiaj nie widać wyraźnego spadku wydajności pracy dysku po wyłączeniu softupdates.
Ważniejszym jest, że restartów już nie ma. Nic tylko się cieszyć.
Jako ciekawostkę mogę dodać, iż serwerów freeBSD postawiłem już całkiem sporo, a taki przypadek pojawił się po raz pierwszy.
Może to jednak ten Caviar? Może powinienem wybrać Seagate albo Maxtor? 🙂

p.s. polecam też HandBook‚a freeBSD o Tuning Disks: http://www.freebsd.org/doc/handbook/configtuning-disk.html

panic: ufs_dirbad i restarty freeBSD

Dobry administrator zawsze i dokładnie czyta logi, z akcentem na dokładnie :).

Kilka dni temu miałem dość ciekawy przypadek automatycznego restartu serwera na skutek wykonywania prostych poleceń, np. find lub locate.
Co ciekawsze, serwer „wywalał” się zawsze na tym samym katalogu. Z początku myślałem, że to wina usługi samba i udostępnionych plików/katalogów, jednak po wnikliwym wczytaniu się w logi systemowe, przekonałem się, że byłem w błędzie.

Błąd był widoczny już w samym dmesg (logi systemowe)

/dev/ad0s1: bad dir usr 25789343 AT OFFSET 1024: MANGLED ENTRY
panic: ufs_dirbad: bad dir

Z tego wynika, że mamy do czynienia z wadliwym katalogiem usr.

Niby prosta rzecz, wchodzimy do single user mode (wtedy dyski/partycje nie są zamontowane).
Sprawdzamy tzw. mount point poleceniem

cat /etc/fstab

i traktujemy zamontowaną etykietkę (label) jako katalog /usr poleceniem fsck

# fsck -y /dev/ad0s1f

(u mnie /usr jest zamontowany jako ad0s1f).

Na koniec skanowania powinno nam się wyświetlić

***** FILE SYSTEM MARKED CLEAN *****

Po ponownym uruchomieniu serwera sprawdzamy czy wszystko jest OK przykładowymi poleceniami

# find / -type d -exec ls -ld {} ;
# find / -type d -exec stat {} ;
# find / -type d -exec touch {}/mydummyfilenamewhichshouldnotexist ;

Najwyraźniej fsck nie poradziło sobie z tym dziwnym przypadkiem, ponieważ freeBSD nadal się restartuje (panic) podczas wykonywania powyższych testów.

Na szczęście jest sposób aby to naprawić, ale może wystąpić sytuacja, że z uszkodzonego katalogu nie odzyskamy danych, aczkolwiek bądźmy dobrej myśli i miejmy pewność, że mamy zrobioną wcześniej kopię zapasową tych danych. Istotą rozwiązania problemu jest naprawienie systemu plików i wyeliminowanie samoistnych restartów systemu freeBSD.

Będąc ponownie w trybie single user mode uruchamiamy narzędzie fsdb (FileSystem DeBugger)

# fsdb /dev/ad0s1f
** /dev/ad0s1f
Editing file system ‚/dev/ad0s1f’
Last mounted on /mnt/ad0s1f
(…)
fsdb (inum: 2)>

Teraz wpisujemy numer tzw. inode, który bierzemy z loga (u mnie był to numer 25789343)

fsdb (inum: 2)> inode 25789343
current inode: directory
I= 25789343 MODE=40777 SIZE=1024
BTIME=May 9 12:52:12 2008 [0 nsec]
MTIME=May 9 12:52:12 2008 [0 nsec]
CTIME=May 9 12:52:12 2008 [0 nsec]
ATIME=May 9 12:52:12 2008 [0 nsec]
OWNER=root GRP=WHEEL LINKCNT=2 FLAGS=0 BLKCNT=4 GEN=157338b7
fsdb (inum: 25789343)>

Nawet gdy stracimy dane, będziemy mieli pewność, że problem zostanie usunięty.
Poleceniem clri debugując inode’a oznaczamy go jako błędny

fsdb (inum: 25789343)> clri 25789343

Wychodzimy z narzędzia debugowania.

fsdb (inum: 25789343)> quit

**** FILE SYSTEM STILL DIRTY *****
*** FILE SYSTEM MARKED DIRTY
*** BE SURE TO RUN FSDK TO CLEAN UP ANY DAMAGE
*** IF IT WAS MOUNTED, RE-MOUNT WITH -u -o reload

Będąc nadal w single user mode uruchamiamy ponownie fsck

# fsck -y /dev/ad0s1f

** /dev/ad0s1f
** Last Mounted on /usr
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
UNALLOCATED I= 25789343 OWNER=root MODE=0
SIZE=1024 MTIME May 9 12:52:12 2008
NAME=/_new2????

REMOVE=YES

** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counters
(…)

Podczas skanowania pojawiały się jeszcze inne różne błędy, które naprawiały się automatycznie dzięki parametrowi -y, np.

LINK COUNT DIR I=2 OWNER=root MODE=40777
SIZE=1024MTIME=May 9 12:52:12 2008 COUNT 21 SHOULD BE 20
ADJUST? yes
(…)
FREE BLK COUNT(S) WRONG IN SUPERBLK
SALVAGE? yes
(…)
SUMMARY INFORMATION BAD
SAVLAGE? yes
(…)
BLK(S) MISSING IN BIT MAPS
SALVAGE? yes

Na końcu pojawił się komunikat

***** FILE SYSTEM MARKED CLEAN *****

***** FILE SYSTEM WAS MODIFIED *****

Ale czy to wszystko? Zdecydowanie tak.
W moim przypadku było dużo szczęścia i wszystkie dane były na swoim miejscu.
Po prostu fsck jakimś dziwnym trafem nie potrafił poradzić sobie z błędnym inode o numerze 25789343.
Oczywiście ponownie przetestowałem find’em czy przypadkiem coś jeszcze nie zostało do naprawienia. Tym razem wszystko było jak należy.
Jednak gdyby nadal były restarty typu panic: ufs_dirbad: bad dir, proponuję powyższe czynności powtórzyć dla każdego złego inode’a.

Pozdrawiam

amavisd nie startuje - błąd z portem 10024

Jakiś czas temu miałem przyjemność borykać się z dziwnym problemem pakietu AMaViS’a komunikującego się z Postfix’em na portach 10024 (nasłuchiwanie AMaViS’a) i 10025 (wysyłanie odpowiedzi do Postfix’a).

Przy uruchamianiu procesu amavisd pojawia się błąd:

fox# /usr/local/etc/rc.d/amavisd start
ERROR: MISSING REQUIRED BASIC MODULES:
IO::Wrap
IO::Stringy
Unix::Syslog
Compress::Zlib
MIME::Entity
MIME::Parser
Net::Server
Net::Server::PreFork
BEGIN failed-compilation aborted at /usr/local/sbin/amavisd line 232.

Dziwnym trafem (to zapewne sprawka upgrade’owania innych portów) brakuje kilku modułów Perl’a do prawidłowego funkcjonowania pakietu AMaViS.

By rozwiązać ten problem należy wejść do konsoli Perl’a poleceniem:

perl -MCPAN -e shell

i w CPAN’ie (konsola Perl’a) instalujemy brakujące moduły (z listy powyżej) zgodnie z poleceniem

install [nazwa modułu], np. install Net::Server

Po ponownym skompilowaniu brakujących modułów (startując amavisa można zweryfikować jakich jeszcze brakuje) sprawdzamy czy nasz proces działa:

fox# /usr/local/etc/rc.d/amavisd start
Starting amavisd.
Problem in Amavis::DKIM code: Can’t locate Crypt/OpenSSL/RSA.pm in @INC (@INC contains: /usr/local/lib/perl5/5.8.9/BSDPAN /usr/local/lib/perl5/site_perl/5.8.9/mach /usr/local/lib/perl5/site_perl/5.8.9 /usr/local/lib/perl5/5.8.9/mach /usr/local/lib/perl5/5.8.9) at (eval 99) line 25.
BEGIN failed-compilation aborted at (eval 99) line 25.

Wydawać się mogło, że ponowna instalacja brakujących modułów rozwiąże problem, a tu jednak zonk.

Wobec powyższego wynika, że wsiąkł również specjalny moduł odpowiedzialny za realizację tzw. DomainKeys Identified Mail (DKIM).
Doinstalowujemy więc port

cd /usr/ports/
make search name=mail-DKIM
(…)
cd /usr/ports/mail/p5-Mail-DKIM
make install clean

I ponownie sprawdzamy czy amavisd działa

fox# /usr/local/etc/rc.d/amavisd start
Starting amavisd.
Problem in antispam SA code: Can’t locate Mail/SpamAssassin.pm in @INC (@INC contains: /usr/local/lib/perl5/5.8.9/BSDPAN /usr/local/lib/perl5/site_perl/5.8.9/mach /usr/local/lib/perl5/site_perl/5.8.9 /usr/local/lib/perl5/5.8.9/mach /usr/local/lib/perl5/5.8.9) at (eval 118) line 63.
BEGIN failed-compilation aborted at (eval 118) line 63.

Teraz łapiemy się za głowę, bowiem okazuje się, że brakuje SA (SpamAssasin’a).

Wchodzimy ponownie do konsoli Perl’a i instalujemy SA

perl -MCPAN -e shell
install Mail:SpamAssassin

Po instalacji SA uruchamiamy proces amavisd kolejny raz aby przekonać się czy jest już wszystko OK.

fox# /usr/local/etc/rc.d/amavisd start
Starting amavisd.

i sprawdzamy czy widać proces

fox# ps aux | grep amavisd
vscan 83335 3.1 3.5 79112 72304 ?? Ss 10:02AM 0:08.15 amavisd (master) (perl)
vscan 83351 0.7 3.6 82116 75068 ?? I 10:03AM 0:01.22 amavisd (ch1-avail) (perl)
vscan 83352 0.0 3.5 79744 72304 ?? I 10:03AM 0:00.03 amavisd (virgin child) (perl)
root 83359 0.0 0.0 1632 844 p0 RL+ 10:03AM 0:00.00 grep amavisd

fox# /usr/local/etc/rc.d/amavisd status
amavisd is running as pid 83335 83351 83352.

Hurra, jest sukces! Udało się! Ale… czy na pewno?
Proces działa, ale poczta nie zostaje dostarczona.

Patrzymy na logi Postfix’a

tail -f /var/log/maillog

i starając się wysłać dowolnego maila widzimy w logach następujące błędy

Oct 13 05:36:16 fox amavis[25159]: (25159-14) (!!)TROUBLE in check_mail: delivery-notification FAILED: temporarily unable to send DSN to : 450 4.4.1 Can’t connect to INET4 socket 127.0.0.1: Connection refused, MTA([127.0.0.1]:10025), id=25159-14 at /usr/local/sbin/amavisd line 11386.
Oct 13 05:36:16 fox amavis[25159]: (25159-14) (!)PRESERVING EVIDENCE in /var/amavis/tmp/amavis-20091013T030230-25159
Oct 13 05:36:16 fox postfix/smtp[29075]: 5FF9B6D42B: to=, relay=127.0.0.1[127.0.0.1]:10024, delay=1689, delays=1683/0.01/0.01/5.9, dsn=4.5.0, status=deferred (host 127.0.0.1[127.0.0.1] said: 451 4.5.0 Error in processing, id=25159-14, delivery-notification FAILED: temporarily unable to send DSN to : 450 4.4.1 Can’t connect to INET4 socket 127.0.0.1: Connection refused, MTA([127.0.0.1]:10025), id=25159-14 at /usr/local/sbin/amavisd line 11386. (in reply to end of DATA command))

Oct 13 06:05:14 fox amavis[28132]: (28132-10) (!)FWD via SMTP: -> , 450 4.4.1 Can’t connect to INET4 socket 127.0.0.1: Connection refused, MTA([127.0.0.1]:10025), id=28132-10
Oct 13 06:05:14 fox amavis[28132]: (28132-10) Blocked MTA-BLOCKED, -> , Message-ID: <[email protected]>, mail_id: i8vzB+cdas+V, Hits: -2.235, size: 7058466, 127353 ms
Oct 13 06:05:15 fox postfix/smtp[29514]: 2B90C6D425: to=, orig_to=, relay=127.0.0.1[127.0.0.1]:10024, delay=21915, delays=21778/9.7/0.02/127, dsn=4.4.1, status=deferred (host 127.0.0.1[127.0.0.1] said: 450 4.4.1 id=28132-10 - Temporary MTA failure on relaying, Can’t connect to INET4 socket 127.0.0.1: Connection refused, MTA([127.0.0.1]:10025), id=28132-10 (in reply to end of DATA command))

Z powyższych błędów wynika, że jest jakiś problem przy połączeniu na porcie 10024.
Tutaj przyznam się bez bicia, że w configu Postfix’a zmieniłem wcześniej w celach testowych port z 10024 na 10025.

Aby nie mieszać, ustawienia plików konfiguracyjnych powinny być następujące

amavisd.conf

# Port na którym będzie nasłuchiwał AMaViS:
$inet_socket_port = 10024;
# Dopuszczaj połączenia jedynie poprzez lokalny adres IP:
@inet_acl = qw( 127.0.0.1 );

main.cf

# AMaViS
content_filter=smtp-amavis:[127.0.0.1]:10024

master.cf

smtp-amavis unix - - n - 2 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes

127.0.0.1:10025 inet n - n - - smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o strict_rfc821_envelopes=yes
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000

Po doprowadzeniu konfiguracji pakietów Postfix + AMaViS do porządku, wszystko wróciło do normy

Oct 13 06:45:44 fox postfix/cleanup[83006]: 7DDC36D41B: message-id=<000d01ca6824$a61bc6b0$6400a8c0@morozov>
Oct 13 06:45:44 fox postfix/qmgr[38715]: 7DDC36D41B: from=, size=10257, nrcpt=1 (queue active)
Oct 13 06:45:44 fox amavis[80899]: (80899-04) (!!)WARN: all primary virus scanners failed, considering backups
Oct 13 06:45:49 fox postfix/smtpd[83003]: disconnect from unknown[113.169.91.43]
Oct 13 06:45:50 fox amavis[80899]: (80899-04) Blocked SPAM, [113.169.91.43] [113.169.91.43] -> , quarantine: spam-gAJtMJQua0NH.gz, Message-ID: <000d01ca6824$a61bc6b0$6400a8c0@morozov>, mail_id: gAJtMJQua0NH, Hits: 14.836, size: 10257, 11290 ms
Oct 13 06:45:50 fox postfix/smtp[83007]: 7DDC36D41B: to=, relay=127.0.0.1[127.0.0.1]:10024, delay=13, delays=1.6/0/0.01/11, dsn=2.5.0, status=sent (250 2.5.0 Ok, id=80899-04, DISCARD(bounce.suppressed))
Oct 13 06:45:50 fox postfix/qmgr[38715]: 7DDC36D41B: removed
Oct 13 06:45:55 fox postfix/anvil[83004]: statistics: max connection rate 1/60s for (smtp:113.23.24.227) at Oct 13 06:45:44
Oct 13 06:45:55 fox postfix/anvil[83004]: statistics: max connection count 1 for (smtp:113.23.24.227) at Oct 13 06:45:44
Oct 13 06:45:51 fox postfix/anvil[83004]: statistics: max cache size 1 at Oct 13 06:45:44

Po takim długim leczeniu choroby nasuwa się myśl: uwaga na upgrade portów 🙂
3mam kciuki. Pozdrawiam.

Przydatne narzędzia kolejek postfix’a

Czasami bywają krytyczne sytuacje w kolejkami postfix’a. Pomocne są wtedy narzędzia będące elementami pakietu (portu) postfix’a. Nie trzeba więc niczego więcej instalować.

Narzędzia kolejek:

postqueue -p
wyświetla listę wszystkich wiadomości w kolejce

postsuper -d (Queue ID)
pozwala usuwać wiadomość z kolejki o danym ID

postsuper -d ALL
usuwa wszystkie wiadomości z kolejki

postsuper -h (Queue ID)
zatrzymanie wiadomośic w kolejce (kolejka hold)

postsuper -H (Queue ID)
przeniesienie wiadomości z powrotem do menadżera kolejek

postsuper -r ALL
zwraca wiadomości z powrotem do kolejki, wiadomości te otrzymują nowe identyfikatory i dodatkowy nagłówek Received

postcat -q
wyświetlanie zawartości pliku kolejki

postqueue -f
wypychanie wiadomości

postqueue -s domena.com
wypychanie wiadomości domeny domena.com

mailq -q /identyczne do sendmail -bp/
lista wiadomości w kolejce do obsłużenia

Bieżący podgląd zawartości loga postfix’a zapewnia polecenie:

tail -f /var/log/maillog

Ostatnie dwa polecenia są bardzo pomocne, jeśli chcemy ręcznie przyspieszyć obsługę kolejek (mailq -q) i jednocześnie przyjrzeć się czy faktycznie postfix coś z nimi robi (tail -f /var/log/maillog).

W sumie o takie czynności zawsze można poprosić administratora.

Autoloader i freeBSD

Tym razem udostępniam (dla potrzebujących) skrypt (również mojego autorstwa) napisany w php, pomagający w operacjach na autoloaderze zamontowanym w systemie freeBSD.

Jak to działa? Skrypt potrzebuje max 2 parametrów wywołania. 1 - opcja, 2 - numer slotu autoloadera. To dopiero v1.0, więc jeszcze będą zmiany.

Generalnie uruchamiamy skrypt w taki sposób:

./backup_multi.php [option] [slot]

Przy czym opcjami mogą być:

backup - tworzy kopię na kasetce (cartridge) oznaczonej jako dany dzień tygodnia (albo z podaniem numeru kasetki)
list - wyświetla zawartość załadowanej lub wskazanej kasetki z taśmą (cartridge)
status - wyświetla status autoloadera
load - ładuje kasetkę z podanego slotu
unload - odkłada kasetkę do slotu, z którego została wcześniej pobrana
rewind - przewijanie taśmy do początku
erase - całkowite kasowanie taśmy

Skrypt ten ma następującą politykę tworzenia kopii zapasowych na tasiemkach w oparciu na istniejącym urzadzeniu o nazwie autoloader:

slot 1 - poniedziałek
slot 2 - wtorek
slot 3 - środa
slot 4 - czwartek
slot 5 - piątek
slot 6 - ostatni dzień co drugiego tygodnia (jeszcze nie działa)
slot 7 - ostatni dzień miesiąca (jeszcze nie działa)
slot 8 - ostatni dzień co trzeciego miesiąca (jeszcze nie działa)

Oto kod:

#! /usr/local/bin/php -f
# by Adam Kucza (c) 2007
<?
# the backup policy of this script
# slot 1 - monday
# slot 2 - tuesday
# slot 3 - wednesday
# slot 4 - thursday
# slot 5 - friday
# slot 6 - last day of every 2nd week
# slot 7 - last day of the month
# slot 8 - last day of every 3rd month

#settings
define („DATE”, date(„Y-m-d_H.i.s”));
define („DAY_OF_WEEK”, date(„N”));
define („LOGFILE”, „/var/log/backup/backup_”.DATE.”.log”);
define („TAPEDRIVE”, „-f /dev/sa0”);
define („CHANGER”, „/dev/pass1”);
define („TAR”, „/usr/bin/tar”);
define („MT”, „/usr/bin/mt”);
define („MTX”, „/usr/local/sbin/mtx”);
define („MAX_SLOTS”, „8”);
define („BACKUPLIST”, „/fox/ustawienia/backup/backup_multi.lst”);

$x = $_SERVER[„argv”];

//print_r($x);

if (count($x)==2 || count($x)==3)
{
$z = „”;

switch ($x[1])
{
case „status”:
# show changer status
$z = MTX.” -f „.CHANGER.” status”;
system($z);
break;

case „load”:
# load cartridge from slot numbered as current day of the week
# mtx -f /dev/pass1 load 1

// firstly free device -> unload cartridge (for sure & safety)
$z = $x[0].” unload”;
system ($z);

//secondly load cartridge (by default or by specified)
$z = MTX.” -f „.CHANGER.” load „;
if ($x[2] && $x[2]>=1 && $x[2]<=MAX_SLOTS) $z .= $x[2]; else $z .= DAY_OF_WEEK; system($z); break; case "unload": # unload cartridge into slot # mtx -f /dev/pass1 unload $z = MTX." -f ".CHANGER." unload"; system($z); break; case "rewind": # rewind the cartridge $z = MT." ".TAPEDRIVE." rewind"; system($z); break; case "erase": # erase the cartridge $z = MT." ".TAPEDRIVE." erase"; system($z); break; case "list": # list of contents of cartridge # tar -f /dev/sa0 -tv // if there is a slot if ($x[2] && $x[2]>=1 && $x[2]<=MAX_SLOTS) { // replace the cartridge $z = $x[0]." unload"; system ($z); $z = MTX." -f ".CHANGER." load ".$x[2]; system($z); } $z = TAR." -tv ".TAPEDRIVE; system($z); break; case "backup": # make backup on cartridge # tar -f /dev/sa0 -cv /etc // reload the cartridge from correct slot $z = MTX." -f ".CHANGER." load "; if ($x[2] && $x[2]>=1 && $x[2]<=MAX_SLOTS) $z .= $x[2]; else $z .= DAY_OF_WEEK; system($z); # backup data echo "\nstarting backup...\n"; $z = TAR." -cv ".TAPEDRIVE." -T ".BACKUPLIST; system($z); # put list of contents into logfile $z = $x[0]." list >> „.LOGFILE;
system($z);
break;

} //end of switch

echo $z;

}
else
{
echo „\nSimple AutoLoader BackUp Script v.1.0 by Adam Kucza (c) 2007\n\n”;

echo „\nThis script operates on autoloader existing in /dev location due to following backup policy:\n”;
echo ” slot 1 - monday\n”;
echo ” slot 2 - tuesday\n”;
echo ” slot 3 - wednesday\n”;
echo ” slot 4 - thursday\n”;
echo ” slot 5 - friday\n”;
echo ” slot 6 - last day of every 2nd week\n”;
echo ” slot 7 - last day of the month\n”;
echo ” slot 8 - last day of every 3rd month\n”;

echo „\nusage:\n”;
echo ” „.$x[0].” [option] [slot]\n”;
echo „\navailable options:\n”;
echo ” backup - make backup on the cartridge from slot due to day of week (by default)\n”;
echo ” list - display the list of contents on loaded cartridge\n”;
echo ” status - display autoloader status\n”;
echo ” load - load cartridge from slot (1-8) numbered as day of the week (by default)\n”;
echo ” unload - unload the cartridge into last used slot\n”;
echo ” rewind - rewind the cartridge (if any) to begin\n”;
echo ” erase - erase entire cartridge (if any, it takes time)\n”;
echo „\nexamples:\n”;
echo ” „.$x[0].” status\t\t- display status\n”;
echo ” „.$x[0].” backup [slot]\t- make backup (into [slot] if specified)\n”;
echo ” „.$x[0].” load [slot]\t- load cartridge (into [slot] - if specified)\n”;
echo ” „.$x[0].” unload\t\t- unload cartridge\n”;

}
echo „\n”;
?>

rsync Twoim przyjacielem

Oddaję do użytku skrypt mojego autorstwa napisany w php, wykonujący kopię synchronizacyjną plików znajdujących się w katalogu podanym jako pierwszy parametr wywołania.

#! /usr/local/bin/php -f
# by Adam Kucza (c) 2007
<?
$x = $_SERVER[„argv”];

if (count($x)==4)
{
//print_r($x);

$rsync = „/usr/local/bin/rsync”;

$srv = $x[1];
$src = $x[2];
$dst = $x[3];

$t = getdate();
//print_r($t);
if (strlen($t[‚mon’])<10) $t['mon']="0".$t['mon']; if (strlen($t['mday'])<10) $t['mday']="0".$t['mday']; $l = "/var/log/rsync/".$x[1]."_".$t['year']."-".$t['mon']."-".$t['mday']."_".$t['hours'].".".$t['minutes'].".".$t['seconds']; $o = ""; $o .= "-a "; $o .= "-v "; $o .= "-z "; $o .= "--delete "; $o .= "--ignore-errors "; $o .= "--force "; $o .= "--stats "; $o .= "--log-file=".$l." "; //$o .= "--dry-run "; //$o .= "--modify-window=1 "; //$o .= "--iconv=UTF-8,CP1251 "; //$o .= "--blocking-io "; //$o .= "--delete-after "; //$o .= "--delete-before "; //$o .= "--progress "; //$o .= "--delete-excluded "; //$o .= "--exclude-from=$EXCLUDES "; //$o .= "--backup --backup-dir=/$BACKUPDIR -a "; $z = $rsync." ".$o." ".$src." ".$srv."::".$dst; echo $z."\n"; system($z); } else { echo "\nusage: ".$x[0]." server_address source_folder destination_module\n"; echo "\nexample: ".$x[0]." 192.168.1.100 /home/user/ backup_module\n"; } echo "\n"; ?>

Przykład jego wywołania wygląda np. tak:

./rsync.php /home/users/ backup_server

enjoy! 🙂

kopia zapasowa na FreeBSD

Czas na garść informacji o wykonywaniui kopii zapasowych na urządzenach taśmowych w systemie freeBSD.

Proponuję zaprzyjaźnić się z poniższymi poleceniami, które tak naprawdę dotyczą standardowych programów każdego freeBSD.
Przy czym chciałbym dodać, iż parametr -f /dev/sa0 określa urządzenie SCSI Tape Drive.

Kilka poleceń programu mt (magnetic tape manipulating program):

sprawdzenie stanu taśmy (ang. status)

mt -f /dev/sa0 status

kasowanie taśmy (ang. erase)

mt -f /dev/sa0 erase

przewinięcie taśmy (ang. rewind)

mt -f /dev/sa0 rewind

retensja (ang. retension), czyli naciągnięcie taśmy (przewijanie do końca i do początku naciągając taśmę)

mt -f /dev/sa0 retension

wysunięcie taśmy z urządzenia (ang. eject)

mt -f /dev/sa0 offline

Kopię zapasową można wykonać za pomocą znanego już zapewne programu tar (manipulate tape archives):

wykonanie kopii zapasowej (kasuje poprzedni zapis na tasmie):

tar -cv /usr/data/dir
tar -cv /usr/data/dir /usr/data/test

po parametrze -cv, wypisujemy katalogi bądź pliki, które chcemy zarchiwizować

wylistowanie zawartości taśmy

tar -tv

odzyskanie danych z taśmy:

tar -xv
tar -xv usr/data/test/filename.ext

po parametrze -xv, wypisujemy katalogi bądź pliki, które chcemy odzyskać

Dodatkowe informacje

Gdy nię będziemy zalogowani w systemie jako root, wykonując jakiekolwiek operacje na urządzeniu taśmowym dostaniemy komunikat:

mt: /dev/nsa0: Permission denied

Jeśli urządzenie taśmowe będzie puste (bez taśmy wewnątrz), to dostaniemy komunikat:

mt: /dev/nsa0: Device not configured

W przypadku, gdy urządzenie taśmowe będzie wykonywało jakąkolwiek operację na taśmie, a my będziemy chcieli zrobić z nią cokolwiek, dostaniemy następujący komunikat:

mt: /dev/nsa0: Device busy

Natomiast jeśli urządzenie będzie wolne od zadań, po wykonaniu polecenia mt status dostaniemy coś takiego:

Mode Density Blocksize bpi Compression
Current: 0x25:DDS-3 variable 97000 DCLZ
———available modes———
0: 0x25:DDS-3 variable 97000 DCLZ
1: 0x25:DDS-3 variable 97000 DCLZ
2: 0x25:DDS-3 variable 97000 DCLZ
3: 0x25:DDS-3 variable 97000 DCLZ
———————————
Current Driver State: at rest.
———————————
File Number: 0 Record Number: 0 Residual Count 0

Jeśli użyjemy polecenia tar -tv a taśma nie będzie sformatowana, uzyskamy komunikat:

tar: Unrecognized archive format: Inappropriate file type or format

Jeśli skorzystamy z polecenia tar -tv, a taśma będzie czysta zobaczymy coś takiego:

tar: Error opening archive: Error reading „/dev/sa0”: Input/output error

Myślę, że powyższy FAQ przybliży nieco archiwizowanie danych na tasiemkach.

rsync i „Bad file descriptor (9)” na freeBSD

Postanowiłem przybliżyć nieco problem związany z rsync.
Podczas synchronizacji widać oraz w logach widzimy błędy identyczne do następujących

[3193] rsync: readlink „jakis_plik” (in intranet) failed: Bad file descriptor (9)
[3193] rsync: recv_generator: failed to stat „jakis_plik” (in intranet): Bad file descriptor (9)
[3197] rsync: stat „jakis_plik” (in intranet) failed: Bad file descriptor (9)
[3197] rsync error: some files could not be transferred (code 23) at main.c(977) [sender=2.6.9]

Czasami nie zawsze pojawiają się tego typu błędy, aczkolwiek administrator widząc readlink … Bad file descriptor (9) zastanawia się czy przypadkiem nie ma uszkodzonego dysku i czy nie jest to błąd odczytu pliku…

W pewnym sensie jest to prawda, bowiem przy konfigurowaniu rsynca należy pamiętać aby system plików (filesystem type) na obu serwerach, a dokładniej na partycjach (źródłowej i docelowej) był dokładnie taki sam.

Mój problem polegał na tym, że zamontowana partycja na serwerze źródłowym posiadała likuksowy system plików ext2fs (subtype=131), a partycja, a raczej rsyncowy moduł docelowy - system plików freebsd (subtype=165).

Stąd te błędy. Korekte systemu plików mozna zrobić „w locie” bez konieczności restartowania serwera, a co ważniejsze - utraty danych (przynajmniej u mnie wszystko pozostało bez zmian).
Dla pewności proponowałbym zrobić uprzednio kopię zapasową danych znajdujących się na partycji, której chcemy zmienić system plików -> przezorny zawsze ubezpieczony.

Zmianę systemu plików dokonujemy następująco:

sysinstall -> configure -> fdisk

Po zamianie ext2fs -> freebsd, wszystko śmiga jak należy i zapominamy o błędach typu bad file descriptor.

mc i problem z subshell_pty

Od pewnego czasu (w sumie nie wiem jak to się stało), przy uruchamianiu Midnight Commandera dostaję następujący komunikat:

freeBSD# mc
read (subshell_pty…): No such file or directory (2)

Co jest grane?
Otóż dziwnym trafem ustawienia aplikacji mówią nam, że jest problem z tzw. subshell (podpowłoka).
Error i brak możliwości usuchomienia programu występuje nawet po reinstalacji mc.
Najszybszym rozwiązaniem jest uruchamianie Midnight Commandera bez subshella w następujący sposób:

mc -u

Innym rozwiązaniem jest ponowne skompilowanie mc bez shubshella.
Polecam również manuala:

man mc