среда, 30 июня 2010 г.

Антимульт студио, рекомендовано к просмотру :)

http://www.youtube.com/user/antimultstudio

О настоящей любви

http://www.youtube.com/watch?v=z8f3rMhxW0o&feature=related

На все воля случая :)

Холодное лето 2003го

Всем смотреть, заставляет о многом задуматься. http://www.youtube.com/watch?v=rSC0pMvILmk&playnext_from=TL&videos=45zo_PdWkQc&feature=grec_browse

четверг, 24 июня 2010 г.

Компания Nokia выпустила пакет Qt SDK 1.0 и среду разработки Qt Creator 2.0

Сабж :)

Активация Hyper-Threading на серверах NHS-1, NHS-2, NHS-3, NHS-24 fastvps.ru

Заказываем KVM, заходим в биос клавишей DEL, "Advanced BIOS features", "CPU feature", Hyper-Threading function - enabled после этого нажимаем F10 и подтверждаем сохранение настроек.

Все, теперь будет логических процессоров не 4, а 8 :) Ну а если все описанное для Вас сложно, то напишите в нашу замечательную поддержку и мы все сделаем сами :)

Как ограничить число php5-cgi процессов при использовании mod_fcgid?

Есть такая директива:

DefaultMaxClassProcessCount 2

Она ограничит число процессов для одного сайта двумя штуками? Или для пользователя? А хрен вот знает на самом деле.

Тут пишут, что поведение директивы было изменено в версии 2.3.5.
Somehow there was a decision made that changed max PHP processes from
per-user to per-vhost between the old mod-fcgid and the newer 2.3.5 version.

Так что попробуем разобраться с тем, что же значит эта директива для версии mod_fcgid 2.2-1 (Debian 5 Lenny) на основе исходных кодов.

cd /usr/src/
apt-get source libapache2-mod-fcgid
apt-get build-dep -y libapache2-mod-fcgid
cd libapache2-mod-fcgid-2.2

Первое упоминание этой опции идет в файле mod_fcgid.c:
571 AP_INIT_TAKE1("DefaultMaxClassProcessCount",
572 set_max_class_process,
573 NULL, RSRC_CONF,
574 "Max process count of one class of fastcgi application"),

Далее эта функция упоминается в файле fcgid_conf.c:
465 const char *set_max_class_process(cmd_parms * cmd, void *dummy,
466 const char *arg)
467 {
468 server_rec *s = cmd->server;
469 fcgid_server_conf *config =
470 ap_get_module_config(s->module_config, &fcgid_module);
471 config->max_class_process_count = atol(arg);
472 return NULL;
473 }

Чуть нижее нее есть функция получения значения этого лимита:
475 int get_max_class_process(server_rec * s)
476 {
477 fcgid_server_conf *config =
478 ap_get_module_config(s->module_config, &fcgid_module);
479 return config ? config->
480 max_class_process_count : DEFAULT_MAX_CLASS_PROCESS_COUNT;
481 }

Далее вторая функция вызывается в файле fcgid_spawn_ctl.c (предпоследняя строка) для инициализации переменной g_max_class_process :
99 void spawn_control_init(server_rec * main_server, apr_pool_t * configpool)
100 {
101 apr_status_t rv;
102
103 if ((rv = apr_pool_create(&g_stat_pool, configpool)) != APR_SUCCESS) {
104 /* Fatal error */
105 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
106 "mod_fcgid: can't create stat pool");
107 exit(1);
108 }
109
110 /* Initialize the variables from configuration */
111 g_time_score = get_time_score(main_server);
112 g_termination_score = get_termination_score(main_server);
113 g_spawn_score = get_spawn_score(main_server);
114 g_score_uplimit = get_spawnscore_uplimit(main_server);
115 g_max_process = get_max_process(main_server); // этот лимит установлен стандартно в DEFAULT_MAX_PROCESS_COUNT, а он равен 1000
116 g_max_class_process = get_max_class_process(main_server); // этот лимит стандартно установлен в DEFAULT_MAX_CLASS_PROCESS_COUNT, а он равен 100
117 g_min_class_process = get_min_class_process(main_server); // этот лимит стандартно установлен в DEFAULT_MIN_CLASS_PROCESS_COUNT, а он равен 3
118 }


Далее идет использование переменных g_max_class_process и g_max_process (глобальный лимит FastCGI процессов) в коде функции is_spawn_allowed:
182
183 /* Total process count higher than up limit? */
184 if (g_total_process >= g_max_process) {
185 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
186 "mod_fcgid: %s total process count %d >= %d, skip the spawn requ
est",
187 command->cgipath, g_total_process, g_max_process);
188 return 0;
189 }
190
191 /*
192 Process count of this class higher than up limit?
193 */
194 /* I need max class proccess count */
195 if (current_node->process_counter >= g_max_class_process) {
196 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
197 "mod_fcgid: too much %s process(current:%d, max:%d), skip the sp awn request",
198 command->cgipath, current_node->process_counter,
199 g_max_class_process);
200 return 0;
201 }


Где g_max_process (глобальный лимит процессов) сравниваем с g_total_process, тут все очевидно, это глобальное число процессов, которые были форкнуты. А вот g_max_class_process сравнивается с неким current_node->process_counter. Что есть этот current_node ?

Идем далее, функция is_spawn_allowed имеет прототип int is_spawn_allowed(server_rec * main_server, fcgid_command * command), по логике, второй параметр, command - это запускаемый в данный момент бинарик (блок информации о нем), как раз там мы и можем понять, каким образом они разделяются.

Вот описание структуры fcgid_command (см. fcgid_pm.h):
8 typedef struct {
9 char cgipath[_POSIX_PATH_MAX];
10 char wrapperpath[_POSIX_PATH_MAX];
11 apr_ino_t inode; // он-то нам и нужен!
12 dev_t deviceid;
13 apr_size_t share_grp_id;
14 uid_t uid; /* For suEXEC */
15 gid_t gid; /* For suEXEC */
16 int userdir; /* For suEXEC */
17 char initenv_key[INITENV_CNT][INITENV_KEY_LEN];
18 char initenv_val[INITENV_CNT][INITENV_VAL_LEN];
19 } fcgid_command;

Вызов функции is_spawn_allowed идет из функции pm_main (файл fcgid_pm_main.c) в виде:
466 apr_status_t pm_main(server_rec * main_server, apr_pool_t * configpool)
467 {
468 fcgid_command command;
469
470 /* Initialize the variables from configuration */
471 g_idle_timeout = get_idle_timeout(main_server);
472 g_idle_scan_interval = get_idle_scan_interval(main_server);
473 g_busy_scan_interval = get_busy_scan_interval(main_server);
474 g_proc_lifetime = get_proc_lifetime(main_server);
475 g_error_scan_interval = get_error_scan_interval(main_server);
476 g_zombie_scan_interval = get_zombie_scan_interval(main_server);
477 g_busy_timeout = get_busy_timeout(main_server);
478 g_busy_timeout += 10;
479 g_shutdown_timeout = get_shutdown_timeout(main_server);
480
481 while (1) {
482 if (procmgr_must_exit())
483 break;
484
485 /* Wait for command */
486 if (procmgr_peek_cmd(&command, main_server) == APR_SUCCESS) {
487 if (is_spawn_allowed(main_server, &command))
488 fastcgi_spawn(&command, main_server, configpool);
489
490 procmgr_finish_notify(main_server);
491 }
492


То есть, содержимое command мы получаем откуда-то извне посредством вызова команды procmgr_peek_cmd, которая читает этот самый command из некоего pipe (способ межпроцессного обмена данными) посредством функции (вот ее описание) apr_file_read_full(g_pm_read_pipe, command, sizeof(*command), NULL), файл arch/unix/fcgid_pm_unix.c:

464 apr_status_t procmgr_peek_cmd(fcgid_command * command,
465 server_rec * main_server)
466 {
467 apr_status_t rv;
468
469 /* Sanity check */
470 if (!g_pm_read_pipe)
471 return APR_EPIPE;
472
473 /* Wait for next command */
474 rv = apr_wait_for_io_or_timeout(g_pm_read_pipe, NULL, FOR_READ);
475
476 /* Log any unexpect result */
477 if (rv != APR_SUCCESS && !APR_STATUS_IS_TIMEUP(rv)) {
478 ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
479 "mod_fcgid: wait io error while getting message from pipe");
480 return rv;
481 }
482
483 /* Timeout */
484 if (rv != APR_SUCCESS)
485 return rv;
486
487 return apr_file_read_full(g_pm_read_pipe, command, sizeof(*command),
488 NULL);
489 }

Этот pipe создается следующей функцией (см. arch/unix/fcgid_pm_unix.c):
308 if ((rv = apr_file_pipe_create(&g_pm_read_pipe, &g_ap_write_pipe,

pipe этот предназначен для обмена данными между Апачем и процесс-менеджером (так понимаю, он является отдельным процессом), который отфоркивает нам процессы.

Процесс-менеджер создается функцией apr_proc_fork, это обычный fork процесса (см. arch/unix/fcgid_pm_unix.c):
198 static apr_status_t
199 create_process_manager(server_rec * main_server, apr_pool_t * configpool)
200 {
201 apr_status_t rv;
202
203 g_process_manager =
204 (apr_proc_t *) apr_pcalloc(configpool, sizeof(*g_process_manager));
205 rv = apr_proc_fork(g_process_manager, configpool);


Осталось понять, откуда эти блоки данных типа fcgid_command отправляются.

А делает это функция procmgr_post_spawn_cmd (arch/unix/fcgid_pm_unix.c):
401 apr_status_t procmgr_post_spawn_cmd(fcgid_command * command,
402 request_rec * r)
403 {
404 apr_status_t rv;
405 char notifybyte;
406 apr_size_t nbytes = sizeof(*command);
407 server_rec *main_server = r->server;
408
409 /* Sanity check first */
410 if (g_caughtSigTerm || !g_ap_write_pipe)
411 return APR_SUCCESS;
412
413 /* Get the global mutex before posting the request */
414 if ((rv = apr_global_mutex_lock(g_pipelock)) != APR_SUCCESS) {
415 ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
416 "mod_fcgid: can't get pipe mutex");
417 exit(0);
418 }
419
420 if ((rv =
421 apr_file_write_full(g_ap_write_pipe, command, nbytes,
422 NULL)) != APR_SUCCESS) {


А вызывается она из функции handle_request (fcgid_bridge.c):
270 static int
271 handle_request(request_rec * r, int role, const char *argv0,
272 fcgid_wrapper_conf * wrapper_conf,
273 apr_bucket_brigade * output_brigade)
274 {
...
342
343 /* Send a spawn request if I can't get a process slot */
344 procmgr_post_spawn_cmd(&fcgi_request, r);


В частности посылается структура fcgi_request, которая чуть выше инициализируется вот так:
320 /* Init spawn request */
321 procmgr_init_spawn_cmd(&fcgi_request, r, argv0, deviceid,
322 inode, shareid);
323

Сама функция инициализации command имеет вид:
337 void procmgr_init_spawn_cmd(fcgid_command * command, request_rec * r,
338 const char *argv0, dev_t deviceid,
339 apr_ino_t inode, apr_size_t share_grp_id)
340 {
...
384 strncpy(command->cgipath, argv0, _POSIX_PATH_MAX);
385 command->cgipath[_POSIX_PATH_MAX - 1] = '\0';
386 command->deviceid = deviceid;
387 command->inode = inode; // внимание!
388 command->share_grp_id = share_grp_id;
389
390 /* Update fcgid_command with wrapper info */
391 command->wrapperpath[0] = '\0';
392 if ((wrapperconf = get_wrapper_info(argv0, r))) {
393 strncpy(command->wrapperpath, wrapperconf->args, _POSIX_PATH_MAX);
394 command->wrapperpath[_POSIX_PATH_MAX - 1] = '\0';
395 command->deviceid = wrapperconf->deviceid;
396 command->inode = wrapperconf->inode; // внимание!
397 command->share_grp_id = wrapperconf->share_group_id;
398 }


Итого, у нас два варианта заполнения поля inode - обычный и из wrapper. И использование / не использование inode от wrapper управляется функцией get_wrapper_info (fcgid_conf.c), которая имеет вид:
846 fcgid_wrapper_conf *get_wrapper_info(const char *cgipath, request_rec * r)
847 {
848 char *extension;
849 fcgid_wrapper_conf *wrapper;
850 fcgid_dir_conf *config =
851 ap_get_module_config(r->per_dir_config, &fcgid_module);
852
853 /* Get file name extension */
854 extension = ap_strrchr_c(cgipath, '.');
855 if (extension == NULL)
856 return NULL;
857
858 /* Search file name extension in per_dir_config */
859 if (config
860 && (wrapper =
861 apr_hash_get(config->wrapper_info_hash, extension,
862 strlen(extension))))
863 return wrapper;
864
865 return NULL;
866 }

В моем случае wrapper используется и задается директивой FCGIWrapper в конфиге Апача, далее (fcgid_conf.c) для инициализации таблицы этих самых wrapper`ов используется функция set_wrapper_config (fcgid_conf.c):
773 const char *set_wrapper_config(cmd_parms * cmd, void *dirconfig,
774 const char *wrapperpath,
775 const char *extension)
776 {
777 const char *path, *tmp;
778 apr_status_t rv;
779 apr_finfo_t finfo;
780 const char *userdata_key = "fcgid_wrapper_id";
781 wrapper_id_info *id_info;
782 apr_size_t *wrapper_id;
783 fcgid_wrapper_conf *wrapper = NULL;
784 fcgid_dir_conf *config = (fcgid_dir_conf *) dirconfig;

Там же получаем stat файла враппера:
824 /* Is the wrapper exist? */
825 if ((rv = apr_stat(&finfo, path, APR_FINFO_NORM,
826 cmd->temp_pool)) != APR_SUCCESS) {
827 return apr_psprintf(cmd->pool,
828 "can't get fastcgi file info: %s(%s), errno: %d",
829 wrapperpath, path, apr_get_os_error());
830 }
831

И чуть ниже inode от него помещаем в требуемую нам структуру:
832 strncpy(wrapper->args, wrapperpath, _POSIX_PATH_MAX - 1);
833 wrapper->args[_POSIX_PATH_MAX - 1] = '\0';
834 wrapper->inode = finfo.inode;
835 wrapper->deviceid = finfo.device;
836 wrapper->share_group_id = *wrapper_id;
837 *wrapper_id++;
838
839 /* Add the node now */
840 apr_hash_set(config->wrapper_info_hash, extension, strlen(extension),
841 wrapper);
842
843 return NULL;
844 }

Итого, выходит, что идентификация идет по inode враппера, то есть, "число соединений до 1 сайта" это и ничто иное.


Возможно, где-то в рассуждениях я ошибся, для проверки результатов проведем тесты.

Открываем файл:
vi fcgid_spawn_ctl.c

Ищем блок:
194 /* I need max class proccess count */
195 if (current_node->process_counter >= g_max_class_process) {
196 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
197 "mod_fcgid: too much %s process(current:%d, max:%d), skip the sp awn request",
198 command->cgipath, current_node->process_counter,
199 g_max_class_process);
200 return 0;
201 }

И корректируем ее до вида (добавляем дамп inode при ошибке spawn нового процесса):
194 /* I need max class proccess count */
195 if (current_node->process_counter >= g_max_class_process) {
196 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
197 "mod_fcgid: too much %s process(current:%d, max:%d, inode:%d), skip the sp awn request",
198 command->cgipath, current_node->process_counter,
199 g_max_class_process, command->inode);
200 return 0;
201 }


И пересобираем mod_fcgid ( debuild -us -uc ) и пробуем вызвать ошибку.

Получаем ошибку в логе:
[Sat Oct 30 04:07:40 2010] [notice] mod_fcgid: too much /var/www/yyyy/data/www/forum.xxxx.ru/xxxxx.php process(current:2, max:2, inode:85541102), skip the spawn request

Теперь смотрим inode враппера:
ls -i /var/www/yyyy/data/php-bin/php
85541102 /var/www/yyyy/data/php-bin/php

Таким образом, исследование кода было проведено верно (но, к слову, не в полной мере, вариант отсутствия wrapper, если он, конечно, возможен, не рассмотрен) :)

Заключение

Параметр конфига, указанный в самом начале поста, регулирует число рабочих процессов для всех сайтов, которые используют один wrapper.


Вот пример такой конфигурации:
[Sat Oct 30 04:07:51 2010] [notice] mod_fcgid: too much /var/www/v001001/data/www/xxxxx.ru/index.php process(current:2, max:2, inode:85541102), skip the spawn request
[Sat Oct 30 04:07:51 2010] [notice] mod_fcgid: too much /var/www/v001001/data/www/yyyyyy.com/index.php process(current:2, max:2, inode:85541102), skip the spawn request

Активация модуля geo в Nginx 0.7.65

Будем подключать вот это:
http://wiki.nginx.org/NginxHttpGeoModule

Почему именно geo, а не geoip? Вот результаты тестов, проведенных нашими сотрудниками:

С геоип:
средняя для -n1 (10 измерений, каждый запрос с нового адреса): 5.20
средняя для -n10000 -c1: 6.63
Средняя для -n10000 -c10: 55.06
потребление памяти: каждый воркер имеет свою базу geoip (страны - 500 Кб, города - 20 Мб)

C гео:
средняя для -n1 (10 измерений, каждый запрос с нового адреса): 6.61
средняя для -n10000 -c1: 6.73
Средняя для -n10000 -c10: 58.01
потребление памяти: каждый воркер имеет свою базу geoip (только страны - 4 Мб)

Без геоип:
средняя для -n1 (10 измерений, каждый запрос с нового адреса): 6.70
Средняя для -n10000 -c1: 6.76
Средняя для -n10000 -c10: 57.91


Скачиваем файлы с IP адресами:

cd /usr/src
wget http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
unzip GeoIPCountryCSV.zip


Теперь, даже если у Вас nginx стоит из пакетов стягиваем дистрибутив nginx треубуемой версии:

cd /usr/src
wget http://sysoev.ru/nginx/nginx-0.7.65.tar.gz
tar -xf nginx-0.7.65.tar.gz


Конвертируем geoip файл в формат nginx и переносим в папку nginx:

perl nginx-0.7.65/contrib/geo2nginx.pl < GeoIPCountryWhois.csv > geo.conf
mv geo.conf /etc/nginx/



Подключаем к nginx:
vi /etc/nginx/nginx.conf


Также вниз блока http добавляем следующее:

geo $country {
default no;
include /etc/nginx/geo.conf;
}


Далее изменяем формат логов, чтобы туда также попадала страна клиента:

log_format vhost_ip_full_format '$remote_addr - $remote_user [$time_local] $host $server_addr $request '
'$status $body_bytes_sent "$http_referer"'
'"$http_user_agent" "$http_x_forwarded_for" $request_time-$upstream_response_time "$country"';
access_log /var/log/nginx/access.log vhost_ip_full_format;


Перезапускаем Nginx:
/etc/init.d/nginx reload

e1000: eth0: e1000_clean_tx_irq: Detected Tx Unit Hang

Вот вылезла такая радость на машинке сильно нагруженной по сети:


[399393.714927] e1000: eth0: e1000_clean_tx_irq: Detected Tx Unit Hang
[399393.714929] Tx Queue <0>
[399393.714930] TDH
[399393.714931] TDT <91>
[399393.714932] next_to_use <91>
[399393.714933] next_to_clean
[399393.714934] buffer_info[next_to_clean]
[399393.714935] time_stamp <105f49deb>
[399393.714936] next_to_watch
[399393.714937] jiffies <105f49f85>
[399393.714938] next_to_watch.status <0>
[399395.715956] e1000: eth0: e1000_clean_tx_irq: Detected Tx Unit Hang
[399395.715957] Tx Queue <0>
[399395.715958] TDH
[399395.715958] TDT <91>
[399395.715959] next_to_use <91>
[399395.715959] next_to_clean
[399395.715960] buffer_info[next_to_clean]
[399395.715960] time_stamp <105f49deb>
[399395.715961] next_to_watch
[399395.715961] jiffies <105f4a179>
[399395.715962] next_to_watch.status <0>
[399397.709166] e1000: eth0: e1000_clean_tx_irq: Detected Tx Unit Hang
[399397.709167] Tx Queue <0>
[399397.709168] TDH
[399397.709168] TDT <91>
[399397.709169] next_to_use <91>
[399397.709169] next_to_clean
[399397.709170] buffer_info[next_to_clean]
[399397.709170] time_stamp <105f49deb>
[399397.709171] next_to_watch
[399397.709171] jiffies <105f4a36d>
[399397.709172] next_to_watch.status <0>
[399399.706064] e1000: eth0: e1000_clean_tx_irq: Detected Tx Unit Hang
[399399.706065] Tx Queue <0>
[399399.706066] TDH
[399399.706066] TDT <91>
[399399.706066] next_to_use <91>
[399399.706067] next_to_clean
[399399.706067] buffer_info[next_to_clean]
[399399.706068] time_stamp <105f49deb>
[399399.706068] next_to_watch
[399399.706069] jiffies <105f4a561>
[399399.706069] next_to_watch.status <0>
[399400.704517] ------------[ cut here ]------------
[399400.704547] WARNING: at net/sched/sch_generic.c:255 dev_watchdog+0xd2/0x16c()
[399400.704587] Hardware name: MS-7522
[399400.704608] NETDEV WATCHDOG: eth0 (e1000): transmit queue 0 timed out
[399400.704634] Modules linked in: xt_multiport acpi_cpufreq cpufreq_stats cpufreq_powersave cpufreq_userspace cpufreq_conservative ip6table_filter ip6_tables xt_recent xt_tcpudp nf_conntrack_ipv4 nf_defrag_ipv4 xt_state xt_owner iptable_filter ip_tables x_tables quota_v2 quota_tree fuse nf_conntrack_ftp nf_conntrack loop snd_pcm snd_timer snd soundcore wmi i2c_i801 snd_page_alloc tpm_tis tpm tpm_bios i2c_core usbhid evdev hid pcspkr button ext3 jbd mbcache dm_mirror dm_region_hash dm_log dm_snapshot dm_mod sd_mod crc_t10dif e1000 uhci_hcd ehci_hcd thermal fan processor thermal_sys raid10 raid456 async_raid6_recov async_pq raid6_pq async_xor xor async_memcpy async_tx raid1 raid0 md_mod atiixp ahci sata_nv sata_sil sata_via libata via82cxxx ide_core 3w_9xxx 3w_xxxx scsi_mod [last unloaded: scsi_wait_scan]
[399400.705068] Pid: 0, comm: swapper Not tainted 2.6.33.4-fastvps-2-4 #1
[399400.705095] Call Trace:
[399400.705114] [] ? dev_watchdog+0xd2/0x16c
[399400.705146] [] ? dev_watchdog+0xd2/0x16c
[399400.705173] [] ? warn_slowpath_common+0x77/0xa3
[399400.705201] [] ? dev_watchdog+0x0/0x16c
[399400.705227] [] ? warn_slowpath_fmt+0x51/0x59
[399400.705254] [] ? try_to_wake_up+0x248/0x256
[399400.705282] [] ? autoremove_wake_function+0x9/0x2e
[399400.705310] [] ? netif_tx_lock+0x3d/0x69
[399400.705337] [] ? netdev_drivername+0x3b/0x40
[399400.705364] [] ? dev_watchdog+0xd2/0x16c
[399400.705392] [] ? blk_rq_timed_out_timer+0x2a/0x103
[399400.705421] [] ? run_timer_softirq+0x1c4/0x263
[399400.705450] [] ? __do_softirq+0xdd/0x1a2
[399400.705476] [] ? lapic_next_event+0x18/0x1d
[399400.705503] [] ? call_softirq+0x1c/0x30
[399400.705529] [] ? do_softirq+0x3f/0x79
[399400.705555] [] ? irq_exit+0x36/0x76
[399400.705580] [] ? smp_apic_timer_interrupt+0x87/0x95
[399400.705608] [] ? apic_timer_interrupt+0x13/0x20
[399400.705633] [] ? acpi_idle_enter_bm+0x273/0x2a5 [processor]
[399400.705685] [] ? acpi_idle_enter_bm+0x26c/0x2a5 [processor]
[399400.705729] [] ? cpuidle_idle_call+0x94/0xee
[399400.705757] [] ? cpu_idle+0x59/0x91
[399400.705782] ---[ end trace e53d97746b1a3cdf ]---
[399402.758125] e1000: eth0 NIC Link is Up 100 Mbps Full Duplex, Flow Control: RX



Юзаем фикс аналогичный http://phpsuxx.blogspot.com/2009/11/e1000-centos-netdev-watchdog-eth0.html

Источник: https://bugzilla.redhat.com/show_bug.cgi?id=398921

вторник, 22 июня 2010 г.

На сайтах посольств Германии и Финляндии все документы в .pdf

А у Российского УФМС - все в .doc. Делаем выводы сами? :)

Получение визы Германии, условия

http://www.moskau.diplo.de/Vertretung/moskau/ru/01/Visabestimmungen/__Merkblaetter.html

Обратите внимание на то, чтобы среди бумаг не оказались деньги, это расценивается как попытка подкупа и влечет за собой отказ в выдаче визы

• Предоставьте на собеседовании все документы, которые Вы прилагаете к
заявлению. Обратите внимание на то, чтобы среди бумаг не оказались деньги,
это расценивается как попытка подкупа и влечет за собой отказ в выдаче визы.


(c) Памятка о порядке получения виз Германии

Официальный сайт посольства Финляндии в Москве

Ибо хрен найдешь его даже гуглом. http://www.finland.org.ru

четверг, 17 июня 2010 г.

Проверяйте файловую систему, если на сервере отказала память

После замены, размуеется. Почти всегда будет уйма ошибок, которые если не исправить сразу, можно лишиться данных.

Увеличение диска для Xen VPS с диском в файле

Допустим, у нас есть VPS с малым диском и мы хотим его увеличить. Самый безопасный путь следующий.

Создаем новый файл-фс большего размера:
dd if=/dev/zero of=/home/vps/domain-new-disk bs=1000000 count=20000
mkfs.ext3 domain-new-disk


Останавливаем VPS:
xm shutdown domain


Убежадемся, что VPS точно остановился:
xm list


Монтируем оба образа:

mkdir /mnt/domain
mkdir /mnt/domain-new
mount -o loop /home/vps/domain-disk /mnt/domain
mount -o loop /home/vps/domain-new-disk /mnt/domain-new


Переносим все файлы:
cp -a /mnt/domain/* /mnt/domain-new/


Убеждаемся в идентичности содержимого (визуально, по размеру):
du -sh /mnt/domain
du -sh /mnt/domain-new


Отмонтируем оба диска:
umount mnt/domain-new
umount mnt/domain


Теперь редактируем файл конфигурации домена, указываем там новый диск:
vi /etc/xen/domain.conf


Запускаем VPS:
xm create -c domain

Защита от запуска нескольких инстансов (экземпляров) Perl / Python скриптов

Решение для Perl

Стоит задача - есть некий скрипт, который производит определенные действия с определенной периодичностью. Вызов скрипта в определенном случае может заблокироваться (допустим, ожиданием ввода-вывода). При этом следом может запуститься вторая копия скрипта (интервал не велик), третья и далее. Что в итоге приведет к тому, что система после разблокировки рухнет. Допустим, наш скрипт зовут: /usr/bin/ispmanager_fix_fastcgi и написан он на Перле.

Для начала алгоритм - узнаем имя текущего скрипта (ну не захардкоживать же его в самом деле), грепаем выдачу ps aux (текущие запущенные в системе процессы) на предмет наличия указанного. Если находим, то просто завершаемся - значит предыдущий запуск скрипта еще продолжает работать.

Во-первых, тут нам понадобится спец-переменная $0, которая содержит имя исполняемой программы. В моем случае это будет "/usr/bin/ispmanager_fix_fastcgi". То есть, код будет такой:
ps aux | grep "/usr/bin/ispmanager_fix_fastcgi"
Далее нам надо будет исключить из выдачи ps aux скрипт, из которго сделан запрос проверки. Тут нам поможет встроенная переменная $$, содержащая pid текущего процесса, который в пределах системы, разумеется, уникален. То есть, у нас получается нечто вида:

ps aux | grep "/usr/bin/ispmanager_fix_fastcgi" | grep -v "pid"


Также в выдачу ps aux обязательно попадет сам grep, поэтому его также нужно исключить:

ps aux | grep "/usr/bin/ispmanager_fix_fastcgi" | grep -v "pid" | grep -v grep


Итого получается следующий Perl код:

#!/usr/bin/perl

use strict;
use warnings;

unless ( system("ps aux | grep $0 | grep -v grep | grep -v $$ | grep -v '/bin/sh -c' > /dev/null") ) {
print "Duplicate!\n";
exit 0; # another copy already running
}

# тут код параллельного запуска которого мы и собираемся избегать

Исключение /bin/sh -c добавлено для Debian cron, где каждая cron задача запускается как два процесса.


Конечно, решение не подойдет для форкащихся процессов, которые имеют одинаковые имена, не подойдет оно и для скриптов запускающихся друг за другом, но если интервал между запусками велик и от него не зависят жизни людей (тут уже ключевые слова звучат, например, как "flock"), то юзать вполне можно :)

Как вариант "красивого решения", могу предложить модуль: Proc::ProcessTable, который на Debian ставится вот так:
apt-get install -y libproc-processtable-perl

Решение для Python

Логику рассуждений повторять не буду, приведу лишь код.

import os

pid = os.getpid()
Nil, scriptname = os.path.split(sys.argv[0])

result = os.system("ps aux | grep '" + scriptname + "' | grep -v grep | grep -v '" + str(pid) + "' > /dev/null" )

if result == 0:
    print "Another copy of script already running"
    sys.exit(0)

Запуск теста железа на FastVPS.ru

Перезагружаемся в Rescue, даем команду "hwcheck", в меню выбора нажимаем A. После этого тесты будут запущены. Потом отключаемся от консоли командами CTRL+a d, в ответ нам будет выдано "[detached]", что ознаачет о том, что мы отключились от экрана, где идут тесты, но при этом тесты не прерваны. После этого можно отключаться от ssh.

Есть также способ запуска теста без скрина:
/root/.oldroot/nfs/check/menu.sh

Через часов 12 снова подключаемся к машине по ssh, вводим команду screen -r и перед нами разверытвается окно с данными законченых тестов, но его не видно целиком - только нижнюю часть. Теперь нажимаем клавиши CTRL+a [, после чего screen переходит в copy-mode и стрелочками можно подняться на экран выше и просмотреть результаты всех тестов.

Проект Kinect (ex. "Natal") от Microsoft, презентация на E3

Всем смотреть: http://www.youtube.com/watch?v=PY68bAeDtF0

С 11й минуты начинается самая зрелищная часть :)

воскресенье, 6 июня 2010 г.

О кариесе


Отличается от большинства остальных бактерий, находящихся в нашем рту, способностью жить и процветать при высокой кислотности. Кроме того, умеет производить специальный полимер, с помощью которого может прилипать даже к гладкой поверхности зубов (а не только болтаться в трещинках и пазухах). Для производства этого полимера ей абсолютно необходима сахароза (именно она, а не какой-нибудь иной сахар), отсюда и связь между большим потреблением сахара и развитием кариеса.

Бороться с этой тварью (и последствиями ее разножения) можно фторосодержащими зубными пастами (сам процесс чистки зубов пользы не имеет), а в особо-запущенных случаях можно и антибиотиками. Помогают ли от нее полоскалки для рта (содержащие хлоргексидин) - консенсуса на этот вопрос еще не сложилось, кратковременный эффект вроде есть, а долговременный - не очень. Жевачки с ксилитолом, насколько я понял, тоже особой пользы не несут - разве что собственно процесс жевания усиливает отделение слюны, которая обладает буферными свойствами и приводит в норму кислотный баланс после еды.


http://shvarz.livejournal.com/238226.html

суббота, 5 июня 2010 г.

Как правильно разбирать soft-raid на fastvps.ru?

Итак, допустим, мы имеем следующую картину raid массивов:

cat /proc/mdstat
Personalities : [raid1] [raid10] [raid0] [raid6] [raid5] [raid4]
md0 : active raid1 sdb1[1] sda1[0]
4200896 blocks [2/2] [UU]

md1 : active raid1 sdb2[1] sda2[0]
2104448 blocks [2/2] [UU]

md2 : active raid1 sdb3[1] sda3[0]
306263040 blocks [2/2] [UU]
[==========>..........] resync = 51.7% (158425088/306263040) finish=51.3min speed=47962K/sec

unused devices:



Очевидно, у нас три массива - /dev/md0, /dev/md1, /dev/md2. Каждый из которых, соответственно, состоит из двух физических дисков - md0 из /dev/sda1, /dev/sdb1, md1 из /dev/sda2, /dev/sdb2, md2 из /dev/sda3, /dev/sdb3.

Допустим, у нас физически отказал диск /dev/sda и в результате этого сервер начинает работать крайне нестабильно (да, несмотря на raid), поэтому сбойный жесткий диск необходимо выбросить из массива и дождаться плановой его замены. Но как это сделать?

Разбор массива осуществляется двумя шагами - метим диск как faulty (отказ) ключом -f, а потом выбрасываем ключом -r. Например, для массива /dev/md0 это выглядит так:

mdadm /dev/md0 -f /dev/sda1
mdadm /dev/md0 -r /dev/sda1


После этого массив /dev/md0 перейдет в однодисковый (DEGRADED) режим:

cat /proc/mdstat
Personalities : [raid1] [raid10] [raid0] [raid6] [raid5] [raid4]
md0 : active raid1 sdb1[1]
4200896 blocks [2/1] [_U]


Повторяем аналогичную операцию для других массивов (/dev/md1 и /dev/md2) и все, сбойный диск исключен из массива.

Удаление папок с сессиями PHP в ISPManager

mv mod-tmp mod-tmp2
mkdir mod-tmp
chmod 2700 mod-tmp
chown 33:33 mod-tmp
rm -rf mod-tmp2

четверг, 3 июня 2010 г.

Самое популярное в стране ИТ - подкастинг радио

Всем слушать: http://radio-t.rpod.ru/ !

Выдача различных IP адресов DNS записей в зависимости от расположения клиента

http://www.caraytech.com/geodns/

BGP Blackhole как защита от DDoS

Что это такое: http://m.habrahabr.ru/post/91574/

Проблема с открытием формул Equation в Office 2008 Mac? Обновитесь!

Description of the Office 2008 for Mac 12.0.1 Update

Documents that contain Word 2007 for Windows equations open correctly.
This update fixes an issue that prevents Word 2008 from opening some documents. The issue affects only documents that contain equations that were created in Word 2007 for Windows.


http://support.microsoft.com/kb/948057

Но мне не помогло, все равно кракозяблы в части формул :(

среда, 2 июня 2010 г.

вторник, 1 июня 2010 г.

Юзаете венду?

Компания Google начала воплощение в жизнь плана по полному избавлению от использования платформы Windows на рабочих станциях персонала компании, мотивировав такое решение работой в области повышения информационной безопасности. Указание о повсеместном переходе на другие операционные системы было дано в начале января, после истории со взломом нескольких машин сотрудников Google, через уязвимость в Internet Explorer.


http://rss.feedsportal.com/c/32457/f/477056/s/ad9d475/l/0L0Sopennet0Bru0Copennews0Cart0Bshtml0Dnum0F26797/story01.htm