FreeBSD 7.0: быстрее, современней, надёжней Сергей Супрунов # ipfw add 3000 nat 5 ip from any to any # ipfw nat 5 config if nfe0 same_ports CFLAGS+= -DIPFIREWALL_NAT # cd /usr/src/sys/modules/ipfw # make && make install # mount -t tmpfs tmpfs /tmp # mount -t msdosfs /dev/ad0s2 /mnt # gjournal label /dev/ad1 # gjournal load # ls /dev/ad1* # newfs -O 2 -J /dev/ad1.journal # mount /dev/ad1.journal /mnt # sysctl compat.linux.osrelease=2.6.16 # freebsd-update -r 7.0-RELEASE upgrade # freebsd-update install # ... перезагрузка ... # freebsd-update install # ...перекомпиляция стороннего ПО... # freebsd-update install ----------------------------------------------------------------------------------------------------------------- Dao DTrace Часть III Евгений Ильин, Филипп Торчинский profile-1000 { @ = count(); } tick-1s { printa(@); clear(@); } # dtrace -n profile-997'{ @[execname] = count(); }' #if defined(__APPLE__) /* * If the thread on which this probe has fired * belongs to a process marked P_LNOATTACH then * this enabling is not permitted to observe it. * Move along, nothing to see here. */ if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) { continue; } #endif /* __APPLE__ */ # ls /media/SOL_11_X86/* & (sleep 1 && eject -f cdrom) #!/usr/bin/dtrace -s #pragma D option flowindent syscall::open:entry / execname == "ls" / { self->follow = 1; printf( "open (%s)\n ", copyinstr(arg0) ); } fbt::: /self->follow/ { } syscall::open:return /self->follow && errno == 0/ { self->follow = 0; } syscall::open:return /self->follow && errno != 0/ { self->follow = 0; printf( "ERROR" ) exit(0); } #pragma D option nspec=3 ostap#dtrace -x cleanrate=303 -s speculation.d #!/usr/bin/dtrace -s #pragma D option flowindent syscall::open:entry / execname == "ls" / { self->spec = speculation(); printf( "open (%s)\n ", copyinstr(arg0) ); } fbt::: /self->spec/ { speculate(self->spec); } syscall::open:return /self->spec/ { speculate( self->spec ); trace( errno ); } syscall::open:return /self->spec && errno == 0/ { discard( self->spec ); self->spec= 0; } syscall::open:return /self->spec && errno != 0/ { commit( self->spec ); self->spec = 0; } hotspot$target:::gc-begin { printf("GC called at %Y\n", walltimestamp); } # java -jar /usr/jdk/instances/jdk1.6.0/demo/jfc/Java2D/Java2Demo.jar & # dtrace -qn 'hotspot$target:::gc-begin { printf("GC called at %Y\n", walltimestamp); }' -p 1147 # cat Greeting.java public class Greeting { public void greet() { System.out.println("Hello DTrace!"); } } # cat TestGreeting.java public class TestGreeting { public static void main(String[] args) { Greeting hello = new Greeting(); while (true) { hello.greet(); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { } } } } javac TestGreeting.java # java -XX:+ExtendedDTraceProbes TestGreeting & # cat hs.d hotspot$target:::method-entry { printf("%s.\%s %s\n",copyinstr(arg1,arg2), copyinstr(arg3,arg4), copyinstr(arg5,arg6)); } tick-5ms { exit(0); } # dtrace -qs hs.d -p 1448 extension=dtrace.so # /usr/php5/5.2.4/bin/php -i | grep -i dtrace CREATE TABLE notebook ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50), lastname VARCHAR(50), phone VARCHAR(15) ); #!/usr/sbin/dtrace -Zqs php*:::function-entry { printf("called %s() in %s at line %d\n",copyinstr(arg0),copyinstr(arg1),arg2) } php simpledb.php ./php-trace.d mysql_parse(THD *thd, char *inBuf, uint length) cat mysql-catch.d pid$target::*mysql_parse*:entry { printf("%Y %s\n", walltimestamp, copyinstr(arg1)); } # dtrace -qs mysql-catch.d -p 1019 # php simpledb.php pid$target::*mysql_execute_command*:return pid$target::*mysql_execute_command*:return { printf("%Y %d \n", walltimestamp, arg1); } #!/usr/sbin/dtrace -Zqs postgresql*:::transaction-start { self->ts=timestamp; @cnt[pid]=count(); } postgresql*:::transaction-commit { @avg[pid]=avg(timestamp - self->ts); } tick-5sec { normalize(@avg, 1000000); printf("%15s %30s %30s\n","PID","Total queries","Avegrage time (ms)"); printf("\t====================================================\n\n"); printa("%15d %@30d %@30d\n",@cnt,@avg); printf("\t====================================================\n\n"); clear(@cnt); clear(@avg); } # ./postgres_avg_query_time.d #!/usr/sbin/dtrace -Zwqs BEGIN { freopen(“sql.trace”); } pid$1::pg_parse_query:entry { printf("%s\n",copyinstr(arg0)); } ----------------------------------------------------------------------------------------------------------------- Определение первичного ключа вставленной записи Сергей Супрунов CREATE TABLE users (id serial, fio varchar); INSERT INTO users (fio) VALUES ('Иванов И.И.'); CREATE SEQUENCE seq; CREATE TABLE users (id integer default nextval('seq'), fio varchar); CREATE SEQUENCE users_id_seq; INSERT INTO users (id, fio) VALUES (NEXT VALUE FOR users_id_seq, 'Иванов И.И.'); CREATE TABLE users (id int not null auto_increment primary key, fio varchar(50)); INSERT INTO users (fio) VALUES ('Иванов И.И.'); INSERT INTO users (fio) VALUES ('Иванов И.И.'); SELECT MAX(id) FROM users; INSERT INTO users (fio) VALUES ('Иванов И.И.'); SELECT id FROM users WHERE fio = 'Иванов И.И.'; INSERT INTO users (fio) VALUES ('Иванов И.И.'); SELECT LAST_INSERT_ID(); INSERT INTO users (fio) VALUES ('Иванов И.И.'); SELECT currval('users_id_seq'); import pgdb db = pgdb.connect(user='user', database='database') cr = db.cursor() cr.execute('''INSERT INTO users (fio) VALIES ('Иванов И.И.')''') # Здесь получаем OID вставленной записи lastoid = cr.lastrowid cr.execute('''SELECT id FROM users WHERE oid = %d''' % lastoid) id = cr.fetchone()[0] # А это — искомое значение ключа cr.execute('''INSERT INTO logins (id, login) VALUE (%d, 'ivanov')''' % id) cr.close() db.commit() db.close() INSERT INTO users (fio) VALUES ('Иванов И.И.'); SELECT GEN_ID(users_id_seq, 0); INSERT INTO users (fio) VALUES ('Иванов И.И.') RETURNING id; SELECT MAX(id) FROM users INSERT INTO users ... SELECT nextval() FROM users_id_seq INSERT INTO users... CREATE TABLE users_id_seq (id int not null); INSERT INTO users_id_seq VALUES (0); UPDATE users_id_seq SET id = last_insert_id(id + 1); SELECT last_insert_id(); ----------------------------------------------------------------------------------------------------------------- Организуем сетевой календарь в корпоративной среде Иван Максимов aptitude install apache2 libapache-mod-dav davfs2 aptitude install openssl libssl-dev openssl req -x509 -nodes -newkey rsa:1024 -keyout /etc/apache2/server.key -out /etc/apache2/server.crt openssl req -new -nodes -keyout /etc/ssl/private/myserver.key -out /etc/ssl/private/respotse.csr # cat /etc/ssl/private/respotse.csr # mkdir /mnt/disk/calendar/data/ # cat "" > /mnt/disk/calendar/DavLock # wget http://www.mozilla-russia.org/projects/calendar/data/RussianHolidays.ics # htpasswd -c /mnt/disk/calendar/data/.htpasswd admin # chown -R www-data:www-data /mnt/disk/calendar/ # Модуль, отвечающий за работу протокола WebDAV и взаимодействие с хранилищем LoadModule dav_module /usr/lib/apache2/modules/mod_dav.so # Модуль, реализующий функциональность хранилища ресурсов WebDAV на файловой системе LoadModule dav_fs_module /usr/lib/apache2/modules/mod_dav_fs.so # Модуль обеспечивающий шифрование SSL LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so # Слушать 443 порт, стандартный для https-соединений Listen 443 # Принимаем запросы на виртуальные серверы со всех адресов, порт 443 NameVirtualHost *:443 # Разрешаем SSL-кэширование. Используем SHM - shared memory. # Если не выставлять данную опцию, производительность веб-сервера значительно снижается SSLSessionCache shm:/usr/local/apache2/logs/ssl_cache_shm # Указываем время в секундах для кэшируемых сессий SSLSessionCacheTimeout 600 # Открываем контейнер виртуального хоста # Указываем расположение файла базы данных блокировок WebDAV DavLockDB "/mnt/disk/calendar/DavLock" # Ассоциировать для клиентов путь https://HOST/uploads с физически расположенной # на жестком диске папкой /mnt/disk/calendar/data/ Alias /uploads "/mnt/disk/calendar/data" # Включаем поддержку SSL/TLS на виртуальном хоcту SSLEngine on # Указываем расположение файла сертификата SSLCertificateFile /etc/ssl/private/192_168_0_1.crt # Место расположение закрытого ключа сервера SSLCertificateKeyFile /etc/ssl/private/myserver.key # Директива ограничивает диапазон команд в пределах веб-адресов # Включаем поддержку WebDAV DAV On # Аутентификация базовая AuthType Basic # Описание аутентификации AuthName "Введите пароль для доступа к календарю" # Расположение файла с базой пользователей AuthUserFile /mnt/disk/calendar/data/.htpasswd # Разрешаем доступ только авторизированным пользователям Require valid-user # Закрываем директивы, описывающие секцию # Фиксируем все ошибки виртуального хоста в отдельный лог-файл ErrorLog /var/log/apache2/calendar_error.log # фиксируем все действия, связанные с доступом к WebDAV-каталогу, # в отдельный файл, формат файла «combined» описан выше # (это один из шаблонов в стандартном файле конфигурации apache2) CustomLog /var/log/apache2/calendar-access.log combined # Закрываем контейнер, описывающий виртуальный хост # apache2ctl -t CustomLog /var/log/apache2/calendar-access.log # apache2ctl -t /etc/init.d/apache2 start apache2 -k start ----------------------------------------------------------------------------------------------------------------- Microsoft Exchange Server 2007 Первые шаги по развёртыванию и настройке Сергей Лопутнев, Дмитрий Ильин C:\DISTR\E2007RTM\Setup.com /PrepareSchema C:\DISTR\E2007RTM\Setup.com /PrepareAD /OrganizationName: <имя организации> C:\DISTR\E2007RTM\Setup.com /PrepareDomain [PS] C:\>new-SendConnector -Name 'OUT' -Usage 'Internet' -AddressSpaces 'smtp:*;1' \ -DNSRoutingEnabled $false -SmartHosts '[192.168.0.254]' -SmartHostAuthMechanism 'None' \ -UseExternalDNSServersEnabled $true -SourceTransportServers 'BETA' [PS] C:\>Dismount-Database -Identity "BETA\First Storage Group\Mailbox Database" [PS] C:\>Dismount-Database -Identity "BETA\Second Storage Group\Public Folders Database" [PS] C:\>Move-StorageGroupPath -Identity "BETA\First Storage Group" -LogFolderPath \ "D:\Mail\FSG\Logs\" -SystemFolderPath "D:\Mail\FSG\System\" [PS] C:\>Move-StorageGroupPath -Identity "BETA\Second Storage Group" -LogFolderPath \ "D:\Mail\PFD\Logs\" -SystemFolderPath "D:\Mail\PFD\System\" [PS] C:\>Move-DatabasePath -Identity "BETA\First Storage Group\Mailbox Database" -EdbFilePath "D:\Mail\FSG\FSG.edb" [PS] C:\>Move-DatabasePath -Identity "BETA\Second Storage Group\Public Folder Database" -EdbFilePath "D:\Mail\PFD\PFD.edb" [PS] C:\>Mount-Database -Identity "BETA\First Storage Group\Mailbox Database" [PS] C:\>Mount-Database -Identity "BETA\Second Storage Group\Public Folders Database" # Проверяем наличие пользователей в Exchange deny domains = +relay_to_domains message = "Unknown user for this domain" condition = ${if !match{${lookup ldap {LDAP_AD_MAIL_RCPT}}}\ {@MS_EXCHANGE_DOMAIN}{yes}{no}} OurDomain_Howto_RU_delivery: driver = manualroute transport = beta_howto_ru route_list = "howto.ru beta.howto.ru byname" beta_howto_ru: driver = smtp hosts = 192.10.0.3 envelope_to_add = true ----------------------------------------------------------------------------------------------------------------- Простейшая установка и настройка PPPoE-сервера под Linux Исправление ошибки LCP Config Request Сергей Гулинов --- ppp-2.4.4/pppd/main.c.orig 2006-06-04 07:52:50.000000000 +0400 +++ ppp-2.4.4/pppd/main.c 2007-11-09 14:47:20.000000000 +0300 @@ -1567,6 +1567,8 @@ if (errfd == 0 || errfd == 1) errfd = dup(errfd); + closelog(); + /* dup the in, out, err fds to 0, 1, 2 */ if (infd != 0) dup2(infd, 0); @@ -1575,7 +1577,6 @@ if (errfd != 2) dup2(errfd, 2); - closelog(); if (log_to_fd > 2) close(log_to_fd); if (the_channel->close) which pppd ./configure --prefix=/usr make make install ./go name pppoe logfile /var/log/log.pppoe require-pap require-chap require-mschap require-mschap-v2 lcp-echo-interval 20 lcp-echo-failure 3 netmask 255.255.255.0 nobsdcomp lock # Secrets for authentication using CHAP # client server secret IP addresses "testlogin" * "testpass" * pppoe-server -I eth0 -L 192.168.0.1 -R 192.168.0.2 ifconfig ----------------------------------------------------------------------------------------------------------------- Простой скрипт для резервного копирования Рашид Ачилов daily_backup_fileplace="/path/to/backup" daily_backup_dirs_cfg="/path/to/backup/dirs/config" daily_backup_owner="owner" daily_backup_group="group" daily_backup_mode="octal_mode_like_0644" daily_backup_dirmode="octal_mode_like_0755" daily_backup_startup="/path/to/startup/scripts" daily_backup_connect="username" daily_backup_dbconnect_conf="/path/to/dbconnect.conf" [daily] /tmp/smbfs/office/1cbase|/Manfc/Mnfctr:smbfs test:mysql [weekly] /etc:ufs /usr/local/etc:ufs /usr/src/sys/i386/conf:ufs [monthly] /var/log/squid:ufs:squid.sh <путь[|отделяемая часть]>:<тип файловой системы>:<скрипт перезапуска> [testmysql] dbtype=mysql user=testuser password=testpwd host=localhost port=3306 location=/var/db/mysql 0 1 * * * /usr/sbin/periodic /usr/local/etc/periodic/daily parse_sectioned_config() { # Удалить из файла комментарии bla=`awk '{if ($1 == "#") next; else print $0}' < $filename` # Разбить по первой квадратной скобке [, так что части будут выглядеть типа: # "section] /path/to /path/to" "section] /path/another /path/more" saveifs=$IFS IFS=[ set $bla # Взять одну часть "section] /path/to /path/more" for blabla in $bla do IFS=] set $blabla # Разбить по второй скобке, так что части будут выглядеть: # "section" "/path/to /path/more". # Это нужно для проверки имени секции if [ $1 = $section ]; then line=$2 IFS=$saveifs return fi done } if [ ! ${#bstopper} -eq 0 ]; then dostop="yes" $daily_backup_startup/$bstopper stop fi # Точка монтирования не найдена в файле .mssmbrc if [ -z "$smbmp" ]; then echo "$bmount missed in $homedir/.mssmbrc, mount aborted" rc=3 else # Разобрать запись из файла .mssmbrc set $smbmp # Перевести имя сервера в верхний регистр userver=`echo $1 | tr "[:lower:]" "[:upper:]"` gserver=`grep $userver /etc/nsmb.conf` if [ -z $gserver ]; then echo "$1 did not described in /etc/nsmb.conf, mount aborted" rc=3 fi # Если точка резервирования не смонтирована if [ -z "$mounts" ]; then # Это все переменные из записи файла .mssmbrc mount_smbfs -f $5 -d $4 //$daily_backup_connect@$1/$2 $bmount if [ $? -ne 0 ]; then status=$? echo "$bmount cannot be mounted, error code is $status" rc=3 else domount="yes" fi fi section=$bpath filename=$daily_backup_dbconnect_conf parse_sectioned_config tokens=$line # Выполнить распознавание всех переменных for onetoken in $tokens do eval $onetoken done # Получаем список таблиц в базе данных, пропускаем первую строчку ответа tables=`$wmysql -B -u $user -h $hostname -P $port -p$password -e "use $bpath; show tables;" | tail -n +2` # Если попытка неудачна, возможно, неверно указан пользователь или пароль status=$? if [ $status -ne 0 ]; then echo "Cannot read tables list from database $bpath, " "probably invalid authentication credenitals" rc=3 continue fi comma=0 locks="" for onetable in $tables do # Если это не первый элемент в строке, приписать запятую и пробел if [ ! $comma -eq 0 ]; then locks="$locks, " fi locks="$locks $onetable read" comma=1 done printf "use $bpath;\nlock tables $locks;\n \\\! cp -Rp $location/$bpath \ $filepath;\nunlock tables;" | mysql -B -n -u $user -P $port -h $hostname -p$password status=$? if [ $status -ne 0 ]; then echo "Cannot copy tables for base $bpath, " "copying routine returned $status" rc=3 continue fi tradir=`echo $bmount$bsepart | sed 's@/@_@g'` tar -cyf "$filepath/$tradir.tar.bz2" $bmount$bsepart > /dev/null 2> /dev/null \ && chown $daily_backup_owner:$daily_backup_group $filepath/$tradir.tar.bz2 \ && chmod $daily_backup_mode $filepath/$tradir.tar.bz2 && rc=0 || rc=3 ----------------------------------------------------------------------------------------------------------------- Потоковое аудио/видеовещание с VideoLAN Крис Касперски # cd /usr/ports/multimedia/vlc && make install clean Листинг 1. Каркас веб-страницы для приема потокового видео по протоколу UDP Demo of VLC mozilla plugin

Demo of VLC mozilla plugin - Example 2


Play video2 Stop video2 Fullscreen Листинг 2. Каркас веб-страницы для приема потокового видео по протоколу HTTP Demo of VLC mozilla plugin

Demo of VLC mozilla plugin - Example 1


Play video1 Pause video1 Stop video1 Fullscreen ----------------------------------------------------------------------------------------------------------------- Создаем распределенную сеть доставки контента Виталий Банковский gzip -d GeoIP.dat.gz mkdir /var/geodns mv GeoIP.dat /var/geodns/ tar -xzvf GeoIP.tar.gz ./configure –with-dbdir=/var/geodns make make install ldconfig tar -xzvf bind-9.4.1-geodns-patch.tar.gz cp bind-9.4.1-geodns-patch/patch.diff bind-9.4.2 cd bind-9.4.1 patch -p 1 < patch.diff CFLAGS="-I/usr/local/geoip/include" LDFLAGS="-L/usr/local/geoip/lib -lGeoIP" ./configure --prefix=/usr/local/geobind make make install ; стандартные опции конфигурации options { directory "/usr/local/geobind/etc"; notify yes; pid-file "/var/run/geo-named.pid"; statistics-file "/var/log/geo-named.stats"; }; ; представление для региона USA и Canada view "us" { match-clients { country_US; country_CA; }; recursion no; zone "example.com" { type master; file "us.db"; }; }; ; представление для региона JP view "jp" { match-clients { country_jp; }; recursion no; zone "example.com" { type master; file "jp.db"; }; }; ; представление для региона RU view "ru" { match-clients { country_ru; }; recursion no; zone "example.com" { type master; file "ru.db"; }; }; ; представление для всех остальных регионов view "central" { match-clients { any; }; recursion no; zone "example.com" { type master; file "central.db"; }; }; @ IN SOA inet.example.com. root.example.com. ( 2007110206 ; Serial yyyymmddnn 1800 ; Refresh 30 min 1200 ; Retry 20 min 2592000 ; Expire 30 days 300 ) ; Default TTL ; IN NS ns1 IN NS ns2 ; серверы имен в центральном датацентре ns1 IN A 40.40.40.41 ns2 IN A 40.40.40.42 ; 66.66.66.66 – адрес кэширующего сервера в USA @ IN A 66.66.66.66 www IN A 66.66.66.66 jp IN A 22.22.22.22 us IN A 66.66.66.66 ru IN A 77.77.77.77 @ IN SOA inet.example.com. root.example.com. ( 2007110206 ; Serial yyyymmddnn 1800 ; Refresh 30 min 1200 ; Retry 20 min 2592000 ; Expire 30 days 300 ) ; Default TTL ; IN NS ns1 IN NS ns2 ; серверы имен в центральном датацентре ns1 IN A 40.40.40.41 ns2 IN A 40.40.40.42 ; 77.77.77.77 – адрес кэширующего сервера в Russia @ IN A 77.77.77.77 www IN A 77.77.77.77 jp IN A 22.22.22.22 us IN A 66.66.66.66 ru IN A 77.77.77.77 > dig example.com ns1.example.com A +nostats > dig example.com ns1.example.com A +nostats tar -xzvf lighttpd-1.5.0-r1605.tar.gz cd lighttpd-1.5.0 patch -p 0 < ../lighttpd-1.5.0.r1605.modcache.v.1.3.2.patch ./configure –with-pcre make make install cp doc/lighttpd.conf /usr/local/etc/ # Подключаем необходимые модули server.modules = ( "mod_cache", "mod_proxy_core", "mod_proxy_backend_http", "mod_proxy_backend_fastcgi", "mod_accesslog" ) # Каталог, в котором будут храниться закэшированные данные server.document-root = "/home/lighttpd/cache" # Имя файла, в котором будут сохраняться ошибки server.errorlog = "/www/logs/lighttpd.error.log" # Имя файла, в котором будет храниться история обращений accesslog.filename = "/var/log/lighttpd-access.log" # Каталог, в котором должны сохраняться закэшированные # ответы с центрального DC. Значение этого параметра # должно совпадать с значением переменной server.document-root cache.bases=(""/home/lighttpd/cache"") # Включаем кэширование cache.enable = "enable" # Задаем параметры кэширования. Включаем кэширование всего # содержимого центрального сайта с временем обновления # каждые 30 минут cache.refresh-pattern = ( "." => "20 ignore-reload override-expire" ) # # Далее прописаны параметры, описывающие наш центральный DC # # Адрес центрального DC proxy-core.backends = ( "40.40.40.42:80" ) # Протокол, по которому нужно обращаться к центральному DC proxy-core.protocol = "http" # Включение режима «сотрудничества» кэширующей # и проксирующей подсистем proxy-core.worked-with-modcache = "enable" #!/bin/sh # chkconfig: 2345 55 25 case "$1" in start) echo -n "Starting: lighttpd" /usr/local/sbin/lighttpd -f /usr/local/etc/lighttpd.conf echo "." ;; stop) echo -n "Stopping service: lighttpd" killall lighttpd echo "." ;; restart) $0 stop sleep 2 $0 start ;; *) echo "Usage: /etc/init.d/lighttpd {start|stop|restart}" >&2 exit 1 ;; esac exit 0 chkconfig lighttpd –add chkconfig lighttpd on /etc/init.d/lighttpd start wget http://example.com tar -xzvf nagios-plugins-1.4.11.tar.gz cd nagios-plugins-1.4.11 ./configure –prefix=/usr/local/nagios-plugins make make install #!/usr/bin/perl # Путь к файлам зон сервера имен my $bind_cfg='/usr/local/geobind/etc'; # Команда для перечитывания файлов зон сервером BIND9 my $bind_restart = '/usr/local/geobind/sbin/rndc reload'; # Описание наших кэширующих датацентров: my $datacenters = [ {id=>'us', name=>'us.example.com'}, {id=>'ru', name=>'ru.example.com'}, {id=>'jp', name=>'jp.example.com'}, ]; # Примечание: имена типа jp.example.com были раньше # прописаны в DNS и служат для обнаружения факта # восстановления отказавших региональных датацентров foreach my $dc (@$datacenters) { # Вычисление контрольных сумм зон для дальнейшего # сравнения my $md1= (split(/\s+/, `md5sum $bind_cfg/$dc->{id}.db`))[0]; my $md2= (split(/\s+/, `md5sum $bind_cfg/central.db`))[0]; # Если контрольные суммы совпадают, то это означает, # что уже было переключение с отказавшего датацентра # на центральный if($md1 eq $md2) { # Проверяем состояние датацентра и, если был факт # восстановления, то переключаем пользователей # обратно на региональный датацентр if(!system("/usr/local/nagios-plugins/libexec/check_http -H $dc->{name}")) { print "$dc->{id} has been recovered\n"; system("cp $bind_cfg/$dc->{id}-original.db $bind_cfg/$dc->{id}.db"); restart_dns("$bind_cfg/$dc->{id}.db",2); } } # Если переключения не было (разные контрольные суммы), # то тестируем доступность датацентра и переключаем # пользователей на центральный в случае проблем else { if(system("/usr/local/nagios-plugins/libexec/check_http -H $dc->{name}")) { print "$dc->{id} has failed\n"; system("cp $bind_cfg/$dc->{id}.db $bind_cfg/$dc->{id}-original.db"); system("cp $bind_cfg/central.db $bind_cfg/$dc->{id}.db"); restart_dns("$bind_cfg/$bind_cfg/ $dc->{id}.db",1); } } } # Продедура увеличения серийного номера зоны # и перезапуск сервера имен sub restart_dns { my ($file,$step)=@_; open(F,"<$file"); my @lines=; close(F); open(F, ">$file"); foreach my $i(@lines) { if($i=~/Serial/ && $i=~/(\d+)/igs) { my $serial=$1; $serial+=$step; $i=~s/$1/$serial/igs; } print F $i; } close(F); system($bind_restart); } ----------------------------------------------------------------------------------------------------------------- Контуры HTML 5: Больше тегов, хороших и разных Обзор предварительной спецификации нового стандарта языка гипертекстовой разметки Кирилл Сухов
….
….
….

Первый уровень

Второй уровень

Третий уровень

The highlighted part below is where the error lies:

var i: Integer;
begin
   i := 1.1;
end.

I also have some kittens who are visiting me these days. They're really cute. I think they like my garden!

Pyatachok
Вини, а куда это мы идём?
Vinny Puh
За мёдом!
Pyatachok
А где мы его возьмём?
Vinny Puh
У пчел.