Skip to content


Как прибить процесс средствами одного только bash

Однажды одно криво написанное java-приложение серьёзно поднапрягло сервер - почти на любую команду в консоли вылазила такая вот ошибка:

"bash: fork: Resource temporarily unavailable"

Конечно, первым желанием было запустить top или ps чтобы вычислить и пристрелить зажравшийся процесс, но, вот незадача, консоль всё тупо продолжала гнуть свою линию в виде "bash: fork: Resource temporarily unavailable" на все мои попытки запустить какую-либо внешнюю (не из списка bash builtins) команду... Я сразу заподозрил, что зажравшимся процессом, скорей всего, является java. Но вот как прибить оный, не зная его PID-а? И тут я вспомнил, про файловую систему /proc... Затем после пары минут экспериментов родился такой вот скрипт, который успешно позволил решить мне задачу нахождения PID-а процесса java, используя только встроенные в коммандный интерпретатор (bash) команды:

#!/bin/bash
for p in /proc/[0-9]* ; do
  exec 9< $p/cmdline
  read -u 9 line
  [[ $line =~ java ]] && echo "|$p|: |$line|"
  exec 9<&-
done

В строке 3 мы назначаем файловому дескриптору 9 псевдо-файл /proc/<pid>/cmdline, далее читаем из него в переменную line, потом сравниваем эту переменную со строкой "java" и в случае совпадения выводим имя файла, имя которого соответствует PID-у процесса. В строке 6 освобождаем файловый дескриптор 9. Затем оставалось только набрать команду kill с найденным таким образом вожделенным PID-ом (к счастью, kill является встроенной в bash). И, о чудо, консоль снова стала себя адекватно вести, LA упало, память освободилась. Уже потом, по графикам cacti стало понятно, что причиной такого безобразия стало неимоверно большое количество потоков (около 70000), которое успело наплодить вышеупомянутое криво написанное java-приложение.

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

echo s > /proc/sysrq-trigger
echo u > /proc/sysrq-trigger
echo b > /proc/sysrq-trigger

Что привело бы к сбросу дисковых буферов (строка 1), перемонтированию файловых систем в режим read-only (строка 2) и немедленной перезагрузке (строка 3). Если же к консоли всё таки имеется непосредственный доступ (физически или через IP-KVM), то следует предусмотрительно в /etc/sysctl.conf добавить строчку

kernel.sysrq = 1

Тогда будет работать волшебная комбинация клавиш AltGr+PrtScr+<command>, где <command> - однобуквенная команда, посылаемая ядру. Список всех поддерживаемых команд с их очень кратким описанием можно получить на консоли (и в /var/log/messages) если нажать комбинацию AltGr+PrtScr+h или выполнить команду:

echo h > /proc/sysrq-trigger

Полный список магических буковок можно найти тут.

Posted in *nix, Howto.

Tagged with , , , .


Trustlink дарит серьёзным блогам 3000 руб.

С 13.03.2012 по 15.04.2012 ссылочная биржа Trustlink проводит весьма интересную акцию «Блоги 3000».

Блог, на котором система Trustlink проиндексирует 1000 и более страниц, получит бонус в размере 3000 российских рублей на счет в TrustLink. Деньги можно будет вывести через два месяца после добавления блога в биржу.

Условия акции:

  1. ТИЦ блога от 10 и выше;
  2. ёмкость блога 1000 и более страниц;
  3. при добавлении выбрать в качестве тематики «Блоги».
  4. успешно пройти модерацию.

В акции принимают участие блоги на любом движке, добавленные в систему и прошедшие модерацию. К участию в акции принимаются только блоги, добавленные в систему с параметрами "по умолчанию": "Режим беззаботный", отсутствием ограничений по закупке в зависимости от времени.

Posted in Деньги.


tinyproxy: Could not allocate memory for child counting

tinyproxy - это маленький и не требовательный к ресурсам HTTP/SSL-прокси-сервер. Его целесообразно применять там, где не хочется ставить что-то более навороченное, типа squid-а.

Заметил я однажды на одном из серверов, что tinyproxy не взлетает, ругаясь в свой лог-файл /var/log/tinyproxy/tinyproxy.log таким вот образом:

INFO   Feb 16 10:40:57 [25015]: Now running as group "tinyproxy".
INFO   Feb 16 10:40:57 [25015]: Now running as user "tinyproxy".
ERROR  Feb 16 10:40:57 [25015]: Could not allocate memory for child counting.

Само собой, сразу полез проверять что с памятью, но свободной памяти оказалось предостаточно. На всякий случай остановил даже тяжелые по памяти процессы, съедающие обычно по нескольку гигабайт RSS --- безрезультатно, ошибка никуда не делась.

Запустив tinyproxy через strace, я увидел следующее:

munmap(0x2b2ae6a30000, 4096)            = 0
umask(0177)                             = 0177
gettimeofday({1329484731, 868249}, NULL) = 0
getpid()                                = 13041
open("/tmp/tinyproxy.shared.P0QttN", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
unlink("/tmp/tinyproxy.shared.P0QttN")  = 0
ftruncate(3, 40)                        = 0
mmap(NULL, 40, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0) = 0x2b2ae6a30000
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b2ae6a3ce40) = 13042
--- SIGCHLD (Child exited) @ 0 (0) ---
exit_group(0)                           = ?

Эта попытка создать файл в директории /tmp навела меня на мысль проверить права доступа к ней. Оказалось, что права там нестандартные:

[avz@ds1 /tmp]# ls -ld /tmp
lrwxrwxrwx 1 root root 24 Апр 10  2009 /tmp -> /mnt/disk2/tmp/
[avz@ds1 /tmp]# ls -ld /mnt/disk2/tmp
drwxrwxr-x 4 root www 4096 Фев 17 13:18 /mnt/disk2/tmp/

Как видно, отсутствует права на запись для пользователей, не входящих в группу www. А сам tinyproxy как раз должен работать от имени пользователя tinyproxy, который в группу www не входит. После комнады chmod o+w /mnt/disk2/tmp tinyproxy успешно запустился :)

Posted in *nix.

Tagged with .


Создание шифрованного бекапа с помощью fsbackup

Иногда бывают ситуации, когда требуется создание резервной копии на носителе, к которому есть доступ не только у вас. Если есть желание уберечь свои данные от посторонних глаз, то тут, конечно же, потребуется шифрование. Один из быстрых и простых способов добиться этого – использование связки fsbackup и gnupg. Далее пошаговое руководство.

  1. Устанавливаем fsbackup, правим конфиг.
  2. Создаём ключи:
    $ gpg --gen-key
    gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    Please select what kind of key you want:
       (1) RSA and RSA (default)
       (2) DSA and Elgamal
       (3) DSA (sign only)
       (4) RSA (sign only)
    Your selection? 1
    RSA keys may be between 1024 and 4096 bits long.
    What keysize do you want? (2048)
    Requested keysize is 2048 bits
    Please specify how long the key should be valid.
             0 = key does not expire
          <n>  = key expires in n days
          <n>w = key expires in n weeks
          <n>m = key expires in n months
          <n>y = key expires in n years
    Key is valid for? (0)
    Key does not expire at all
    Is this correct? (y/N) y
    You need a user ID to identify your key; the software constructs the user ID
    from the Real Name, Comment and Email Address in this form:
        "Heinrich Heine (Der Dichter) <[email protected]>"
    Real name: SysAdmin
    Email address: mymbox@avz.org.ua
    Comment: 
    You selected this USER-ID:
        "SysAdmin <[email protected]>"
    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
    You need a Passphrase to protect your secret key.
    Repeat passphrase:
  3. Копируем ключи на сервер бекапов:
    $ scp ~/.gnupg/*.gpg backupuser@backupserver.some.where:~/.gnupg
  4. Проверяем, что в конфиг-файле fsbackup-а правильно установлены следующие переменные:
    $prog_pgp = "/usr/bin/gpg";
    # должно соответствовать имени пользователя при создании ключей
    $cfg_pgp_userid = "mymbox";
  5. Запускаем процесс создания бекапа:
    # /usr/local/fsbackup/create_backup.sh
    OS: linux
    Creating system config archive...
    Creating package list...
    Creating remote_ssh backup: s1
    PGP: enabled
    Current increment number: 1
    Adding /usr/local/fsbackup....
    done
    Adding /usr/src/linux/.config....
    done
    Adding /root....
    done
    Adding /etc....
    done
    Storing remote ssh backup...
    gpg: using PGP trust model
    gpg: using subkey 656FA34 instead of primary key 0F36EF13
    gpg: This key belongs to us
    gpg: reading from `[stdin]'
    gpg: writing to stdout
    gpg: RSA/AES256 encrypted for: "656FA34 SysAdmin <[email protected]>"
    ***** Backup successful complete.
  6. При необходимости извлечь файлы из бекапа на сервере бекапов делаем так:
    $ ls -l
    total 50048
    -rw-rw-r--. 1 avz avz 50814369 Фев 15 16:15 s1-2012.02.15.16.15.17-0.tar
    -rw-rw-r--. 1 avz avz        0 Фев 15 16:15 s1-2012.02.15.16.15.17.del
    -rw-rw-r--. 1 avz avz    91076 Фев 15 16:15 s1-2012.02.15.16.15.17.dir
    -rw-rw-r--. 1 avz avz   335872 Фев 15 16:15 s1-2012.02.15.16.15.17.hash
    -rw-rw-r--. 1 avz avz      373 Фев 15 16:15 s1-2012.02.15.16.15.17.list
    -rw-rw-r--. 1 avz avz        0 Фев 15 16:15 s1-2012.02.15.16.15.17.lsize
     
    $ file s1-2012.02.15.16.15.17-0.tar
    s1-2012.02.15.16.15.17-0.tar: data
     
    $ mv s1-2012.02.15.16.15.17-0.tar s1-2012.02.15.16.15.17-0.tar.gpg
     
    $ gpg -d s1-2012.02.15.16.15.17-0.tar.gpg > s1-2012.02.15.16.15.17-0.tar
    You need a passphrase to unlock the secret key for
    user: "SysAdmin <[email protected]>"
    2048-bit RSA key, ID 656FA34, created 2012-02-15 (main key ID 0F36EF13)
    ┌───────────────────────────────────────────────────────────────────────┐
    │ Please enter the passphrase to unlock the secret key for certificate: │ 
    │ "SysAdmin <[email protected]>"                                        │ 
    │ 2048-bit RSA key, ID 656FA34,                                         │ 
    │ created 2012-02-15 (main key ID 0F36EF13).                            │ 
    │                                                                       │ 
    │                                                                       │ 
    │ Passphrase ********__________________________________________________ │ 
    │                                                                       │ 
    │            <OK>                           <Cancel>                    │ 
    └───────────────────────────────────────────────────────────────────────┘
    gpg: encrypted with 2048-bit RSA key, ID 656FA34, created 2012-02-15
          "SysAdmin <[email protected]>"
     
    $ file s1-2012.02.15.16.15.17-0.tar
    s1-2012.02.15.16.15.17-0.tar: POSIX tar archive (GNU)
     
    $ tar -xf s1-2012.02.15.16.15.17-0.tar

Что касается быстродействия при расшифровке, то могу сообщить следующее:

$ ls -l s1-2012.02.15.23.02.34.tar.gpg
-rw-rw-r--. 1 avz avz 4164349204 Фев 15 23:23 s1-2012.02.15.23.02.34.tar.gpg
 
$ time gpg -d s1-2012.02.15.23.02.34.tar.gpg > s1-2012.02.15.23.02.34.tar
You need a passphrase to unlock the secret key for
user: "SysAdmin <[email protected]>"
2048-bit RSA key, ID 656FA34, created 2012-02-15 (main key ID 0F36EF13)
real    3m19.129s
user    2m4.648s
sys     0m6.255s
 
$ ls -l s1-2012.02.15.23.02.34.tar
-rw-rw-r--. 1 avz avz 5637232640 Фев 16 14:31 s1-2012.02.15.23.02.34.tar
 
$ cat /proc/cpuinfo | grep 'model name' | head -n 1
model name      : Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz
 
$ cat /proc/meminfo | grep MemTotal:
MemTotal:        3835144 kB

Posted in *nix, Howto.

Tagged with .