Поиск по этому блогу

понедельник, 21 февраля 2011 г.

Восстановление ReiserFS после форматирования в NTFS

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

Итак, имее
м:
1. Прерванное ПОЛНОЕ форматирование в
NTFS
2. Быстрое форматирование в
NTFS
3. Неудачную попытку восстановления раздела из-за которй он стал неразмеченной областью

После всего перечисленного попытка восстановить инфу носила лишь познавательный характер.
Начались скитания по Гуглу в поисках софта по восстановлению. Многое смотрел, пытался даже ставить - Линуксовые коммерческие даж не ставились на Kubuntu 10.10, виндовые пока не рассматривал, т.к. мастдай отсутсвует(не фанат какой-либо ОС, использую ту, которая лучше подходит по требованиям, сейчас это Линукс).
Экспериментировать на разделе в единственном экземпляре не очень хотелось.

Делаем полную копию раздела, чтоб вернуть если что:

dd if=/dev/устройство_раздела bs=4M of=/путь_к_файлу_резервной_копии

Таким образом была сделана полная копия раздела в файл.
bs=4M - это размер, в байтах(4М - 4 мегабайта), копируемых за такт, рекомендуют ставить равным размеру кеша винчестера.

Ну резервная копия через часик нарисовалась теперь можно и экспериментировать. Проводить опыты на живом диске рука не поднялась. Да и ведь в Unix мы!
Была-небыла, наугад - скажем что файл это устройство и запустим на нем обычную порверялку файловой системы. А вдруг?

sudo reiserfsck --check /путь_к_файлу_резервной_копии

И тут челюсть отвисает первый раз - проверка идет! reiserfsck ругнулась на пару ошибок и сказала что обязательно надо запуститься с параметром --rebuild-tree

sudo reiserfsck --rebuild-tree /путь_к_файлу_резервной_копии

попыхтев пару часов указала на несколько ошибок, что не всё удалось восстановить сказала: "Хозяин, готово, забирай!" :)

Пробуем примонтировать:

sudo mount -t reiserfs -o loop /путь_к_файлу_резервной_копии /куда_монтировать

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

З.Ы.
Есть тут конечно элемент везения - спохватились рано, на раздел записи практически небыло да и полное форматирование тормознули вовремя, недобралось оно к нужным файлам.
Вполне возможно что метод поможет не только при форматировании в NTFS, а при форматировании в другие ФС.


воскресенье, 13 февраля 2011 г.

Учёт трафика для Linux десктопа (KDE)

Да, не весь интеренет еще безлимитный :(
Не мало ещё провайдеров, ограничивающих обьём трафика и считающих весь трафик выше нормы по бешеным ценам.
После продолжительного гугления и испытаний разных софтин для учёта трафика под Linux, остановился на KNemo. Для десктопа самое оно - просто настраивается, стабильно работает, автоматически запускается.

Скриншоты(зеленый цвет из-за темы KDE):


суббота, 12 февраля 2011 г.

Использование iconv на C++

Долгое время использовал преобразование кодировок при помощи Glib, функцией g_convert

Например преобразование из UTF-8 в Win-1251
g_convert(s.c_str(), -1, "cp1251", "utf-8", NULL, NULL, &error);

Но по непонятным причинам случайным образом эта функция под FreeBSD отказывалась преобразовывать в одном случае из тысяч из UCS2 в Win-1251 абсолютно нормальный текст, при этом отлично работая под Linux. Возможно причина кроется в том что приложение многопоточное и реализация многопоточности в Фре и Линухе различна. Но факт остается фактом - случайным образом во время преобразоания кодировки из библиотеки Glib на консоль вываливался варнинг, что неполучается использовать закрытый конвертер или чтот еще подобное, сейчас уже не помню и приложение благополчно падало в кор.
Поизучав исходники Glib решил написать свою функцию перекодирования, используя iconv.
Вот только вела она себя както странно.
После продолжительного гугления был найден действительно рабочий вариант http://www.opennet.ru/openforum/vsluhforumID9/4656.html#1 , отличавшийся от моего совсем не многим.
После небольшого тюнинга и проверки работоспособности получился такой вариант:

#include <iconv.h> //как минимум нужно подключить этот хеадер
...
string iconv_recode(string from, string to, string text)
{
iconv_t cnv = iconv_open(to.c_str(), from.c_str());
if (cnv == (iconv_t) - 1)
{
iconv_close(cnv);
return "";
}
char *outbuf;
if ((outbuf = (char *) malloc(text.length()*2 + 1)) == NULL)
{
iconv_close(cnv);
return "";
}
char *ip = (char *) text.c_str(), *op = outbuf;
size_t icount = text.length(), ocount = text.length()*2;

if (iconv(cnv, &ip, &icount, &op, &ocount) != (size_t) - 1)
{
outbuf[text.length()*2 - ocount] = '\0';
text = outbuf;
}
else
{
text = "";
}

free(outbuf);
iconv_close(cnv);
return text;
}

И тут есть момент, упущенный мною в своей неработающей функции. Смотрим строки
...
char *outbuf;
...
char *ip = (char *) text.c_str(), *op = outbuf;
...
if (iconv(cnv, &ip, &icount, &op, &ocount) != (size_t) - 1)

...

А именно в iconv, как параметр, для преобразованной строки передаётся &op, а не &outbuf, как у меня. Попытка в параметрах передать &outbuf вместо &op приводит к неожиданным результатам. Также в дебагере стало видно, что op и outbuf до вызова iconv(cnv, &ip, &icount, &op, &ocount) имеют одинаковый адрес, но после вызова iconv адреса разные. Результат работы iconv находится в outbuf, а op указывает на другой не коректный адрес