Предыстория.
Понадобилось как-то несжатое (после перегонки с видеокамеры) видео передать человеку на обработку. Для этих целей на доп. жостком диске по соседству с разделом 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, а при форматировании в другие ФС.
Поиск по этому блогу
понедельник, 21 февраля 2011 г.
воскресенье, 13 февраля 2011 г.
Учёт трафика для Linux десктопа (KDE)
Да, не весь интеренет еще безлимитный :(
Не мало ещё провайдеров, ограничивающих обьём трафика и считающих весь трафик выше нормы по бешеным ценам.
После продолжительного гугления и испытаний разных софтин для учёта трафика под Linux, остановился на KNemo. Для десктопа самое оно - просто настраивается, стабильно работает, автоматически запускается.
Скриншоты(зеленый цвет из-за темы 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 указывает на другой не коректный адрес
Например преобразование из 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 указывает на другой не коректный адрес
Подписаться на:
Сообщения (Atom)