MiniDevicesInfo ИТ блоги 2017-09-19 2017-09-19 Отображаются все разделы
1234

root
0

Linux Ubuntu
Tweaks

Без комментариев
x264_cpu_detect: Assertion `!(cpu&(0x0000040|0x0000080))' failed

Sometimes ffmpeg users could meet following error message when decoding something using ffmpeg with x264 codec...

ffmpeg: common/cpu.c:248: x264_cpu_detect: Assertion `!(cpu&(0x00000400x0000080))' failed.

Or

ffmpeg: common/cpu.c:251: x264_cpu_detect: Assertion `!(cpu&(0x00000400x0000080))' failed.

This means that your CPU doesn't supports real hardware decoding, and could be slow during this process. Unfortunately bad developer guys decided to interrupt entire process if CPU doesn't support this feature. Even if you will re-compile ffmpeg from source - you will get this error message.

I spent few hours before understood how to fight and win this problem.


So, let's compile ffmpeg from scratch using Ubuntu (other distro could be different with package names, but process of compilation is the same):


1. Install required packages. apt-get -y install autoconf automake build-essential libass-dev libfreetype6-dev
  libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev
  libxcb-xfixes0-dev pkg-config texinfo zlib1g-dev yasm

2. mkdir ~/ffmpeg_sources

3. cd ~/ffmpeg_sources

4. Compile x264 codec: wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2

tar xjvf last_x264.tar.bz2
cd x264-snapshot*
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static --disable-opencl


Now, and this is urgent, we must open .c file and make few bad things into code: vi common/cpu.c

We should find part of code similar to this:

if( model == 9 model == 13 model == 14 )
            {
                cpu &= ~(X264_CPU_SSE2X264_CPU_SSE3);
                assert(!(cpu&(X264_CPU_SSSE3X264_CPU_SSE4)));
            }


Usually it's about 251-th line. We should replace our CPU id to something else, or just comment this checking. For example replace line "if( model == 9 model == 13 model == 14 )" to "if( model == 900 model == 1300 model == 1400 )". 


That's all. Then we must save file and continue compilation.

PATH="$HOME/bin:$PATH" make
make install
make distclean
5. Compile ffmpeg: cd ~/ffmpeg_sources
wget http://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
tar xjvf ffmpeg-snapshot.tar.bz2
cd ffmpeg
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure
  --prefix="$HOME/ffmpeg_build"
  --pkg-config-flags="--static"
  --extra-cflags="-I$HOME/ffmpeg_build/include"
  --extra-ldflags="-L$HOME/ffmpeg_build/lib"
  --bindir="$HOME/bin"
  --enable-gpl
  --enable-libx264
PATH="$HOME/bin:$PATH" make
make install

6. Enjoy.

If this manual will not work for you, please google for another, but please understand trick to make x264 working with your PC: edit file "common/cpu.c" and comment/remove from it CPU checking.

Hope I helped you. If so, please say thanks :))







root
0

Tweaks
pfSense
Сетевое железо
Mikrotik
Домашний хостинг

2 комментариев
Подключение к внешнему IP-адресу из внутренней сети для роутера Mikrotik

Пил сегодня кофе у друга на работе в гостях, общались о том о сем, и друг мне поведал об интересной проблеме: у него на работе стоит неплохой сервер, где хостятся их сайты, но эти сайты недоступны изнутри. Пока в чашке был кофе, мы немножко помучали его "роутер", как он называл свою коробку на базе PfSense, но к сожалению кофе закончилось раньше, чем мы успели найти решение. Этот PfSense отлично решал эту проблему ранее, но очередное обновление изменило интерфейс настроек, и мой друг-любитель ГУЁв, теперь сидит с головной болью в поисках большой галочки "Сделать все" :)

Ну да ладно, статья не о друге. Дома у меня творится примерно такая же ситуация, только в других масштабах. Точно такой же сервер, точно такая же организация сети, разве что железо поновее, и во главе стола сидит его величество Mikrotik. Поскольку у меня и у жены (а мы - основные потребители наших сайтов) на устройствах стоят Linux, то проблема была решена относительно бескровно, хотя и костыльно: при помощи записи в /etc/hosts.

А теперь, мудаки с просторов интернета, советующие делать подобные костыли нормальным людям - разбежитесь и ударьтесь об стенку! Это не решение. И сегодня я осознал, почему...

1) Представьте что у вас ноутбук. Как у меня, да, с которого иногда можно поработать, или написать статью на своем сайте, подобно этой. Все хорошо, /etc/hosts, и все работает вроде как. А теперь берем этот самый ноутбук, и идем к другу хвастаться своим сайтиком. Садимся, а сайтик-то не работает! Несколько минут смеха, а потом судорожное открывание консоли, и комментирование записи в /etc/hosts. Была бы на месте моего друга какая-нибудь девушка, она бы наверное не дала такому неудачнику. 

2) А представьте себе что у вас Wordpress, но нету домена, что вполне логично, ибо вы оттачиваете свой сайт, для того чтобы на днях купить под него какое-нибудь интересное доменное имя. И ведь логично, что для открытия этого сайта мы будем использовать прямой IP-адрес сервера, ну например http://192.168.1.2, кой и будет внесен как SITE URL в настройках Вордпресса. И это будет работать. А теперь представляем, что получится если на наш сайт попытаться зайти извне? Мудак, которого я раньше упоминал, может спросить "а зачем это делать?" А затем, мудак, что можно попросить друга открыть твой сайт у него из дому, потому что...у него в отличие от тебя, дома есть экзотический Windows с Internet Explorer, только у него есть монитор с каким-нибудь идиотским разрешением 1280х1024, и только он сможет зайти на твой сайт с планшетика на Android, о котором кстати мы еще поговорим. А еще можно пользоваться всякими интересными утилитами вроде Google Pagespeed Insights. 

Итак, если мы зайдем на наш сайт извне, первый запрос будет успешным, и первый ответ нашего сервера будет тоже успешным. И это будет редирект 301. Куда ? Мудак наверное не догадается, но я подскажу: на http://192.168.1.2, который мы прописали в Вордпрессе.

3) Ну а что будем делать с телефонами, планшетами, на Андроидах и Виндовсах, с которых тоже хочется и сайтики свои потестить, да и просто в них поработать ? Будем рутовать, костылить, ломать ?


В общем задумался я о том, что у меня появилась проблема, такая же как и у друга. Правда ребята из Mikrotik предоставили более адекватное решение, нежели ребята из условно-OpenSource PfSense, по крайней мере на поиск этого решения мне понадобилось полчаса и гронка винограда. Итак, как зайти по внешнему IP-адресу из локальной сети?


1) Заходим на страницу настройки IP->Firewall->NAT

2) Создаем новое правило

3) Chain выбираем dstnat

4) Src address указываем нашу внутреннюю сеть с маской, например 192.168.88.0/24

5) Dst address указываем наш адрес, который виден извне, например 74.90.54.2

6) Dst port конечно же ставим 80. Для каждого порта нужно будет делать свое правило

7) Опускаемся ниже, и в Action выбираем dstnat

8) В поле To Addresses прописываем внутренний IP-адрес нашего сервера, например 192.168.88.2

9) На этом все. Поднимаемся вверх, жмем Apply/Ok, наслаждаемся.


Отдельно хочу отметить, что удивлен сложившейся ситуацией: в самом нищебродском старом TP-link, в самом убогом ddwrt, есть галочка для решения этой проблемы проброса. В монстрах от Mikrotik, pfSense, и прочих Smoothwall - приходится лезть в дебри, и включать разные фичи с переменным успехом. Или заходить из своей сети на свои же сайты - очень не популярно?


Кстати буду благодарен если в комментариях напишут как настроить этот NAT Loopback на PfSense последней версии. Рабочее решение, пожалуйста :)


root
0

Умный дом
Сделай сам
Печатные платы
ESP8266

Без комментариев
ESP8266 прошивка по WiFi

ESP8266 - маленькое устройство для DIY.

В этой статье мы разберем, как можно красиво прошивать устройство на лету, в те моменты когда оно не подключено физически к ПК. Да да, через WiFi. Таким образом мы можем изменять и дополнять функционал тех девайсов, которые уже находятся в работе.


Создавать свой способ перепрошивки мы будем на основе популярной прошивки NodeMCU, поэтому я подразумеваю что у вас есть уже готовый девайс, подключенный к ПК через UART. Разбирать, где скачать NodeMCU и как перепрошивать - я не буду, мануалов в сети масса. Перейдем к самой сути.


Основная идея прошивки на лету - возможность NodeMCU вставлять и исполнять файлы .lua на лету. Это означает что мы можем создать один статический файл (пусть это будет init.lua), в который можем вставлять другой файл (например test.lua), который в свою очередь будет динамическим и содержать нашу "прошивку".


Много ерунды писать не буду, а сразу приведу полный скрипт.


wifi.setmode(wifi.STATION)
wifi.sta.config("wp_h","")
print("IP")

print(wifi.sta.getip())

-- 1

srv=net.createServer(net.TCP)
srv:listen(80,function(conn)

    conn:on("receive", function(client,request)

-- 2

        local buf = "";
        local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
        if(method == nil)then
            _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");

        end

-- 3

   if vars=="fwstart" then
   file.open("test.lua", "w+")
                       end


-- 4

   if vars=="fwend" then
   file.flush()
   file.close()
                    end

    

-- 5                  

   if method=="POST" and vars=="fw" then
   r = request
   _,_,DataToGet, request = string.find(request, "Content%-Length: (%d+)(.+)")
   if DataToGet~=nil then
   l = string.len(r)
   DataToGet = tonumber(DataToGet)
   start = l-DataToGet
   payload = string.sub(r, start , l)
   file.writeline(payload)
                        end
                                    end   

-- 6

client:send(buf);

client:close();
collectgarbage();
    end)
end)
dofile("test.lua")


Теперь вкратце разберем что какой блок делает.

-- 1:

Создаем веб-сервер. Все как обычно.

-- 2:

Все GET запросы передаем в переменную vars

-- 3:

Если в GET запросе получаем строку "fwstart", то открываем файл test.lua на запись. Файл пересоздается.

-- 4:

Если в GET запросе получаем строку "fwend", то сбрасываем буферы, и закрываем файл test.lua

-- 5:

Если получаем POST запрос, и при этом в GET запросе есть строка "fw", то считываем то что пришло в POST-запросе, и пишем в файл test.lua

-- 6:

Конец веб-сервера. И запускаем файл test.lua

Это все.


Теперь как этим пользоваться, в картинках.


Интерфейс ESPlorer. Еще ничего не прошито, ESP8266 - девственно чиста



Теперь прошито. Файл test.lua не найден. Ведь мы еще ничего не создавали.


Теперь открываем линуксовую консоль (проще всего делать там, главное поймите принцип)


Собственно процесс прошивки таков:

curl 'http://192.168.88.223?fwstart'

curl --data 'print("This is a test!!")' http://192.168.88.223?fw
curl --data 'print("Hello, daemons")' http://192.168.88.223?fw
curl --data 'print("End of program")' http://192.168.88.223?fw
curl 'http://192.168.88.223?fwend'


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



Собственно на этом все, далее можно модернизировать программу по своему усмотрению.



root
0

Linux Debian
Tweaks
Фриланс

Без комментариев
Восстановление InnoDB MySQL

Как бы не убеждал нас Oracle и Mariadb о надежности InnoDB - это не так.

Поддержка транзакций и прочее страшные слова хороши до тех пор пока база данных не скрашилась (как вариант, не была дерзко скопирована в другое место). В этом случае наступает кризис, и останавливается работа.
Итак, описанный хак будет работать только в случае, если вы используете хранение каждой таблицы в отдельном файле (параметр innodb_file_per_table=1 в my.cnf). Если у вас такой настройки нет - сделайте ее, иначе будет поздно. Вы можете определить использование отдельного файла для таблицы, по присутствию множества .ibd файлов в каталоге базы данных.
Т.е., примерно в /var/lib/mysql/DATABASE_NAME/ у вас должны быть файлы с расширением FRM и IBD.
FRM - это структура таблицы. IBD - содержимое таблицы. Простое копирование не поможет, поскольку несмотря на то, что MySQL будет видеть названия таблиц, ни SELECT FROM ни DESC не получится.

Итак, допустим у вас есть все условия: бэкап с множеством IBD-файлов:
1) Удаляем файлы ibdata1 и логи в папке /var/lib/mysql (или в вашем каталоге с базами)
2) Перезапускаем MySQL. Он должен перезапуститься
3) Открываем консоль MySQL и заходим в него
4) Выполняем show databases; use <имя_вашей_базы>;show tables - вы должны увидеть таблицы.


Основной принцип восстановления таблиц из файлов следующий:
1) Создаем промежуточную базу данных
2) Восстанавливаем структуру каждой таблицы вашей поврежденной базы, при помощи утилиты
3) Создаем таблицы в промежуточной базе, на основе восстановленных из предыдущего пункта
4) Удаляем текущий контент таблицы, при помощи хитрой команды
5) Копируем физический файл с данными таблицы, из нашей поврежденной базы
6) Заставляем MySQL принять и перечитать новые данные.


Как это будет в командах.
1) cd /var/lib/mysql
2) rm ib_logfile0;rm ib_logfile1; rm ibdata1
3) service mysql restart
4) mysql -u'root' -p'ваш_пароль'
5) CREATE DATABASE swap;
6) quit
7) mysqlfrm --server=root:ваш_пароль@localhost:3306 --diagnostic <имя_файла.frm> > table.sql
8) mysql -u'root' -p'ваш_пароль' swap < table.sql
9) Предыдущие команды возможно вызовут ошибки, они незначительные, к примеру незакомментированное слово WARNING, но их придется устранить вручную
10) mysql -u'root' -p'ваш_пароль' swap
11) ALTER TABLE <имя_таблицы_которую мы создали пару пунктов назад> DISCARD TABLESPACE;
12) quit
13) cp <файл_таблицы.ibd из поврежденной базы> swap/ - попросту говоря, копируем восстанавливаемый файл IBD из папки старой базы, в папку с новой
14) mysql -u'root' -p'ваш_пароль' swap
15) ALTER TABLE <имя_таблицы_которую мы создали пару пунктов назад> IMPORT TABLESPACE;
16) Вуаля. service mysql restart


Для автоматизации рутинной работы, я написал скрипт
Код скрипта:

#!/bin/bash

pass='ваш_рутовый_пароль_на_mysql'

rm swap
db=$1
echo "================Restoring database $db======================="
cd $db
echo "1) Creating temp database _$db"
echo "drop database _$db;" | mysql -u'root' -p"$pass"
echo "create database _$db;" | mysql -u'root' -p"$pass"
echo "2) Re-creating table structure"
f=`ls | grep '.frm'`
cd ..
 for ii in $f;do
 tbl=`echo "$ii" | awk -F '.' {'print $1'}`
 echo " Creating structure for table $tbl"
 mysqlfrm --server=web:$pass@localhost:3306 --diagnostic $db/$ii | grep -v 'WARNING' | sed "s/$db/_$db/" > $db.$tbl.sql
 DONE=false
until $DONE ;do
read x || DONE=true
# Следующие строки нужны,чтобы заменять возможные апострофы в комментариях
xx=`echo $x | grep ' comment '`
if [[ "$xx" != "" ]];then
x=`echo $x | sed 's/"/\^/g' | sed "s/'/\"/" |  sed "s/',/\",/"`
                            fi
echo $x >> swap
done < $db.$tbl.sql
mv swap $db.$tbl.sql
mysql -u'root' -p"$pass" < $db.$tbl.sql
done
echo "Now will restart mysql..."
read a
# killall mysqld
# killall mysqld_safe
service mysql stop
/etc/init.d/mysql stop
service mysql start
echo "3) Discarding current table"
# cd ..
cd _$db
f=`ls | grep '.frm'`
for ii in $f;do
tbl=`echo "$ii" | awk -F '.' {'print $1'}`
printf " DISCARD _$db.$tbl..."
mv $tbl.ibd $tbl.bkp 
echo "USE _$db; ALTER TABLE $tbl DISCARD TABLESPACE;" | mysql -u'root' -p"$pass" 2> log
cp ../$db/$tbl.ibd $tbl.ibd

chmod 777 $tbl.ibd

echo "OK"

done
 f=`ls | grep '.ibd'`
 for ii in $f;do
 tbl=`echo "$ii" | awk -F '.' {'print $1'}`
 printf " IMPORT _$db.$tbl..."
 res=`echo "USE _$db; ALTER TABLE $tbl IMPORT TABLESPACE;" | mysql -u'root' -p"$pass" 2>err`
 err=`cat err | grep 'Data structure corruption'`
 # Если контент в IBD файле поврежден, мы его не восстановим, для этого придется оставить таблицу чистой, и снять с нее DISCARD
 if [[ "$err" != "" ]];then
 printf "Data corrupted, running restoration..."
 rm $tbl.ibd
 echo "USE _$db; ALTER TABLE $tbl DISCARD TABLESPACE;" | mysql -u'root' -p"$pass" 2> log
 mv $tbl.bkp $tbl.ibd
 echo "USE _$db; ALTER TABLE $tbl IMPORT TABLESPACE;" | mysql -u'root' -p"$pass" 2> log
 fi
 echo "OK"
 done
service mysql restart


Скрипт должен быть размещен в каталоге datadir (/var/lib/mysql)

Запускается он, находясь в каталоге, командой ./script.sh <имя_базы_данных>

Естественно, каталог с базой должен находиться здесь же. Скрипт создаст новую базу с таким же названием, но со знаком подчеркивания. Не забудьте так же поставить mysqlfrm (apt-get install mysql-utilities в Debian-based).


Не упрекайте меня пожалуйста за красоту программирования на bash, главная цель вовсе не она.

Надеюсь я вам помог.

Посмотрите так же: Восстановление InnoDB MySQL и Статья-помощник для этого сайта


Вы должны войти в систему, чтобы создавать блоги

1+1 / 1+1