Описание

среда, 24 апреля 2013 г.

Locale hell

Если вы столкнулись с ошибкой:
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
То вам сюда!

Я же столкнулся с этой проблемой, когда хотел сделать mongodump/mongorestore сразу после установки MongoDB на только что развернутом новом сервере. В результате мои попытки заканчивались ошибкой упомянутой выше.

Эта ошибка возникает, когда в системе нет скомпилированно локали, которая указана в системе.

Чтобы узнать какая локаль сейчас указана системе для использования:
$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
Вот вывод для моей системы показывает, что указана локаль en_US.UTF-8. Чтобы посмотреть список уже скомпилированных локалей в системе:
$ locale -a
C
C.UTF-8
POSIX
Для того чтобы решить обозначенную верху ошибку, нужно либо указать системе в качестве локали для использования локаль из списка уже имеющихся на системе, либо сгенерировать недостающую локаль самостоятельно. В моем случае недостающая локаль и есть en_US.UTF-8. Генерируем локаль следующим образом:
$ sudo locale-gen en_US.UTF-8
[sudo] password: 
Generating locales...
  en_US.UTF-8... done
Generation complete.
Вот и все!

среда, 17 апреля 2013 г.

Стековое монтирование в Linux

Думаю, что большинство пользователей Linux знакомы с командой mount. В сборках ядра Linux до версии 2.4 точку монтирования возможно было использовать только один раз. Т.е. если вы сделали mount в определенное место, то повторно туда же ничего примонтировать не получится. Начиная с версии ядра 2.4, Linux позволяет осуществлять стековое монтирование — это означает, что можно выполнить монтирование одно поверх другого в одну точку монтирования. Каждое новое монтирование скрывает поддерево директорий, которое было видимым до этого. Когда выполняется размонтирование, то поддерево директорий скрытое  вершиной стека (последний успешно выполненный mount) становится снова видимым. Продемонстрируем это на примере:
$ su
Password:
Необходимы права суперпользователя для выполнения mount(8)
# mount /dev/sda12 /testfs
Выполняем первый mount в /testfs
# touch /testfs/myfile
Создаем файл в поддереве
# mount /dev/sda13 /testfs
Выполняем монтирование в  /testfs еще раз
# mount | grep testfs
/dev/sda12 on /testfs type ext3 (rw)
/dev/sda13 on /testfs type reiserfs (rw)
Проверяем, что действительно два устройства примонтированы в  /testfs
# touch /testfs/newfile
# ls /testfs
newfile
# umount /testfs
# mount | grep testfs
/dev/sda12 on /testfs type ext3 (rw)
# ls /testfs
myfile
Видим сначала утерянный и теперь снова видный наш myfile

Возникает вопрос "А зачем это нужно?". Использование стекового монтирования может пригодится в случае, когда запущенный процесс chroot-jailed, или когда запущенный процесс держит дескриптор на файл, который находится в старой точке монтирования. В этом случае стековое монтирование позволит работать этому уже запущенному процессу со своими файлами и директориями, а новым процессам позволит получить доступ к файлам на вершине стека монтирования.