LINUX.ORG.RU

Lunatik v3.6 — релиз среды исполнения Lua в пространстве ядра Linux

 , , , ,

Lunatik v3.6 — релиз среды исполнения Lua в пространстве ядра Linux

0

4

Lunatik — это фреймворк для написания сценариев для ядра Linux на Lua. Разрабатывается LabLua в рамках Lua in kernel с явными ссылками на опыт использования Lua в ядре NetBSD.

Основные компоненты

  • интерпретатор Lua, модифицированный для работы в ядре;
  • драйвера устройства (написаны на Lua);
  • средства командной строки для запуска сценариев и управления средами выполнения из пользовательского пространства;
  • C API для загрузки и запуска сценариев и управления средами выполнения из ядра;
  • Lua API для привязки средств ядра к Lua-скриптам.

Новые возможности


Группа разработчиков Lunatik выражает благодарность контрибуторам, благодаря которым стал возможен этот релиз: sav и marcelstanley из Ring-0 Networks, sheharyaar, jperon, vincentmli, rustedusted, glk0, ну и конечно же всем другим участникам, работающими над Lunatik.

Пример драйвера устройства для генерации простых «паролей»

-- /lib/modules/lua/passwd.lua
--
-- implements /dev/passwd for generate passwords
-- usage: $ sudo lunatik run passwd
--        $ head -c <width> /dev/passwd

local device = require("device")
local linux  = require("linux")

local function nop() end -- do nothing

local s = linux.stat
local driver = {name = "passwd", open = nop, release = nop, mode = s.IRUGO}

function driver:read() -- read(2) callback
	-- generate random ASCII printable characters
	return string.char(linux.random(32, 126))
end

-- creates a new character device
device.new(driver)

>>> Исходный код релиза

>>> Документация, исходный код и примеры проекта

>>> Сопутствующие проекты

>>> Анонс в официальной группе Lua

★★★★★

Проверено: CrX ()
Последнее исправление: hobbit (всего исправлений: 9)
Ответ на: комментарий от mord0d

Пока, вроде, не нужен, но упаси ТНБ понадобится. Найдется ведь какая файловая система, которая будет хранить пути с BOM'ом :)

gns ★★★★★
()
Ответ на: комментарий от Anoxemian
function utf8myLen2(s)
    local count = 0
    local len = #s
    for i = 1, len do
        local char = s:sub(i, i)  -- Получаем символ (подстроку длиной 1)
        if char < "\128" or char >= "\192" then
            count = count + 1
        end
    end
    return count
end
[49:25]Прошло: 0.00099999969825149
[49:26]Прошло: 1.1019999999553
[49:29]Прошло: 3.6349999997765

Гораздо хуже. К слову, реализация ютф8саб у меня тоже есть. Где то в пять раз быстрее библиотечной, но всеравно на порядки медленене базовой:

local strbyte, strlen, strsub = string.byte, string.len, string.sub

-- Определяет количество байт, занимаемых UTF-8 символом (без изменения логики)
local function utf8charbytes(s, i)
    local c = strbyte(s, i)
    if c > 0 and c <= 127 then
        return 1
    elseif c >= 194 and c <= 223 then
        return 2
    elseif c >= 224 and c <= 239 then
        return 3
    elseif c >= 240 and c <= 244 then
        return 4
    else
        error("Invalid UTF-8 character at position " .. i)
    end
end

-- Извлекает подстроку из UTF-8 строки с оптимизациями
function utf8mySub(s, i, j)
    if type(s) ~= "string" then
        error("bad argument #1 to 'utf8sub' (string expected)")
    end
    if type(i) ~= "number" or type(j) ~= "number" then
        error("bad arguments #2 and/or #3 to 'utf8sub' (numbers expected)")
    end

    local bytes = strlen(s)
    local startChar, endChar = i, j
    local charPositions -- Таблица для кэширования позиций символов при необходимости

    -- Обработка отрицательных индексов и вычисление длины
    if i < 0 or j < 0 then
        charPositions = {}
        local len = 0
        local pos = 1
        while pos <= bytes do
            local charBytes = utf8charbytes(s, pos)
            len = len + 1
            charPositions[len] = pos -- Сохраняем позицию символа
            pos = pos + charBytes
        end
        -- Корректируем индексы
        startChar = (i < 0) and (len + i + 1) or i
        endChar = (j < 0) and (len + j + 1) or j
        -- Ограничиваем endChar до максимума и корректируем startChar
        endChar = math.min(endChar, len)
        startChar = math.max(startChar, 1)
    end

    -- Проверка невалидных границ
    if startChar > endChar then
        return ""
    end

    -- Поиск байтовых позиций
    local startByte, endByte
    if charPositions then
        -- Используем кэшированные позиции
        startByte = charPositions[startChar]
        local endPos = charPositions[endChar]
        endByte = endPos + utf8charbytes(s, endPos) - 1
    else
        -- Стандартный поиск
        local currentChar = 0
        local pos = 1
        while pos <= bytes do
            local charBytes = utf8charbytes(s, pos)
            currentChar = currentChar + 1
            if currentChar == startChar then
                startByte = pos
            end
            if currentChar == endChar then
                endByte = pos + charBytes - 1
                break
            end
            pos = pos + charBytes
        end
    end

    return strsub(s, startByte, endByte)
end

Тут тоже бы что то ускорить, но как? А никак скорее всего. Это предел.

LightDiver ★★★★★
()
Ответ на: комментарий от mord0d

Да скорее осознание того, что синусы в ядре никто считать не будет в здравом уме. :)

gns ★★★★★
()
Ответ на: комментарий от Android

А что, Rust не пошёл?

А что, Rust - это скрипт, который можно крутить без перекомпиляции?

her_s_gory
()
Ответ на: комментарий от LightDiver

Вот, кстати, сопоставления пути с регуляркой в ядре как раз и нет. Ну, то есть, есть, но только в синтаксисе shell-глобов, а этого мало. Машинка для регулярок была бы полезна.

gns ★★★★★
()
Ответ на: комментарий от gagarin0

Да работать то оно работает. Я вот столкнулся с неприятной вещью: тут ограничение на количество элементво в общей таблице. Где то 263 тысячи элементов. Превышаем ограничение - таблица обнуляется, все слетает. Кирдык.

Я начал «оптимизировать». Пришел сейчас вот к такому формату:

https://ctxt.io/2/AAB45a07FQ

Я тут записываю логи в строки длиной 32000 символов. Во второй таблице ниже храню адреса строк. Так я никогда не переполню таблицу, но скорость очень уж медленная. Чтение 10000 строк логов занимает от 35 до 45 секунд вместо 0.01с в случае с хэш-таблицами.

Вот я и взялся оптимизировать работу с ютф. Но всеравно очень тяжко.

То есть вопрос не в том - работает или нет. Вопрос в скорости, нагрузке на цпу, нагрузке на память.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от Anoxemian
[59:51]Прошло: 0
[59:52]Прошло: 0
[59:53]Прошло: 0
[59:54]Прошло: 0
[59:56]Прошло: 0.0010000001639128
[59:57]Прошло: 0

В основном нисколько. Это 10000 проходов пустого цикла несколько раз запустил.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Ну какуюнить ++ оставь, очевидно пустой просто выкинул интерпретатор.

upd у тебя lua какая, чтоб знать на будущее, когда решусь поковырять.

Anoxemian ★★★★★
()
Последнее исправление: Anoxemian (всего исправлений: 1)
Ответ на: комментарий от Anoxemian
[04:48]Прошло: 0.0019999998621643
[04:50]Прошло: 0.0019999998621643
[04:51]Прошло: 0.00099999969825149
[04:52]Прошло: 0.00099999969825149
[04:53]Прошло: 0.003000000026077
[04:56]Прошло: 0.0020000003278255
function test222(n1, n2)
    local temp
    local time1 = GetTime()
    for i = 1, n1 do
        local temp = ns_chat_log_line_q_p["лог_чат"][10]
    end
    print("Прошло: " .. GetTime()-time1)
end

10000 проходов несколько раз.

lua5.1 wow 3.3.5. Тут своя модификация.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 2)
Ответ на: комментарий от gagarin0

Суть, как я и сказал: луа проще, на ней можно быстренько что то накалякать, а на си придется это делать дольше. Вроде так.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Да мне то в ядре юникод не надо. Я просто последние 2 года работаю с луа, в том числе с юникодом.

В Lua ≥5.4 завезли utf8. И он даже есть в flua (огрызок Lua во FreeBSD).

Я просто привел пример, что чуть отхождение от стандартных функций, который написаны на си и падение производительности на несколько прядков.

Пусть не всё, но многое на Lua можно сделать быстро. Естественно такие операции как работа с регулярками, перебор огромных размеров массивов и чтение/запись файлов будут медленными, но использовать для этого Lua немного странно. (=

А не проще тогда сразу на си?

Lua это встраиваемый язык. Если нужна производительность и/или многопоточность, основное реализуется на C и вываливается интерфейсами в вызываемый Lua, где исполняется логика, которую можно вынести из C.

А писать прям всё на Lua никто в здравом уме не станет. (=

Да, я немного фанбой Lua, у меня на нём много кода, я даже умею его немного оптимизировать, но я не стану утверждать что он замена C. Он лишь его расширение.

mord0d ★★★★★
()
Ответ на: комментарий от gns

Эх, да если бы у меня был доступ к серверу, я бы туда давно уже запилил модули на си для работы со всем этим и не только. К сожалению, мне приходится работать на пользовательском уровен через аддоны.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Нет. И не думал даже. :) Ни на Lua, ни на чем еще. Туда вообще лезть не надо, разве что с целью гранату кинуть :)

gns ★★★★★
()
Ответ на: комментарий от mord0d

Там много чего запилили уже даже в луа5.2. Но мне надо работать с очень урезанной версией 5.1, например.

И какая разница, что там запилили, если у тебя задача - написать свою функцию для использования? Вот представь, ты написал свое, используешь, а оно уже на 5 порядков медленнее. Это получается что чисто игрушка для тестов, не более. Нормально всеравно придется писать на си в итоге.

Просто как я мыслю: если я работаю все время с си и нормально на автоматизме его знаю, мне ведь не сложно сделать то же самое на нем без всяких луа. С той же скоростью. Разве нет?

Тогда нахрена? Для нубов? Так нуб туда не полезет. А профессионалу оно зачем? Непонятно.

LightDiver ★★★★★
()
Ответ на: комментарий от gns

Представь. Есть игровой сервер world of warcraft. Есть игровой клиент. В клиент встроена возможность работать с луа 5.1. С их реализацией.

Хм.. До меня дошло, доступ к серверу наверное мне ничего бы не дал. Не выполнять же это все на сервере. Да, печаль. Тут только менять клиент, если в будущих встроили более удачную версию си.

LightDiver ★★★★★
()
Ответ на: комментарий от gagarin0

Тут 1 встроенная функция превращает код в тыкву, а ты библиотеку советуешь))

Anoxemian ★★★★★
()
Ответ на: комментарий от Anoxemian

Это сразу мимо - это такая нагрузка на память, что оно даже не работает:

Message: Interface\AddOns\NSQS\server_functions.lua:259: stack overflow (string slice too long)
Time: 02/17/25 17:18:54
Count: 1
Stack: [C]: in function `byte'
Interface\AddOns\NSQS\server_functions.lua:259: in function `utf8myLen2'
Interface\AddOns\NSQS\server_functions.lua:294: in function `test222'
[string "test222(10000)"]:1: in main chunk
[C]: in function `RunScript'
Interface\FrameXML\ChatFrame.lua:1996: in function `value'
Interface\FrameXML\ChatFrame.lua:4070: in function `ChatEdit_ParseText'
Interface\FrameXML\ChatFrame.lua:3660: in function `ChatEdit_SendText'
Interface\FrameXML\ChatFrame.lua:3698: in function `ChatEdit_OnEnterPressed'
[string "*:OnEnterPressed"]:1: in function <[string "*:OnEnterPressed"]:1>

Locals: (*temporary) = "  ;  ` 1f 2a 3> 3e 4* 57 5R 5p 64 74 7H 7y 8Z 98 9W 9x Ad BC BR C4 Cu D$ De E# Ed FD Fc GC #I #h $_ %/ %` %[ (@ (c )- )d *W *| +P +u -e /9 /^ /' ;T <5 =W >% @C @d HG Hb I7 J2 J/ JU J} K= L5 Lq MM Mv NZ Nr OF Ob O] Pe Q5 Qj RC RZ S) Sg T@ Te UA Uq V% Vk W6 WK XE Xa Y) YY Yy ZK Zf ^) ^y _/ _l `@ a^ a] bh c3 dG e9 ev f% fX fm g% gy h@ iG j7 jI k1 kY lX mh n) n` oX o[ pM pm q3 r1 rs sE tF t[ vC ve w# w^ x9 xV xy yW zL zz {+ {U {]  }G }U [E [e ]6 ]{ 'N 'l10J10x11U12813Z13n14=15615=15`16K16{17a18N18e19619W19w1A%1Ae1B%1BL1Be1B|1Cw1D71Dq1E]1FH1Gd1#01#%1#b1$`1%01%g1(/1(s1)U1*I1*v1+|1-<1-U1;01;`1<$1<R1=@1=d1=x1>81>/1>'1@G1@X1@r1HF1Hg1I31IP1Ip1J01J*1Jc1Jy1K#1KK1M)1NF1NJ1N'1O=1OW1Ok1P01QD1Qb1Q|1R^1Rw1S@1Sd1Sy1UJ1U_1Up1VA1Vt1WR1X71X/1Xz1YN1Yc1Zq1^h1_$1_s1`91`P1a41ao1b81bS1b}1d+1dW1d'1eP1eo1fR1g#1g_1g]1hc1i81iP1id1iy1jg1jx1k91kS1kp1l^1m61mN1n)1n|1od1ox1pi1q%1qi1r*1r}1s@1t81tp1uf1v%1w51wO1xF1xJ1xp1y}1z'1{R1|21}$1}s1[31[d1[t1]C1]U1]{1'B1'^20R20n20]21K21i21y23J23n24524L24_25F25W25{26$26K26u27)27c27s28(28b29(*temporary) = 1
(*temporary) = -1

Для длинных строк это создает переполнение.

LightDiver ★★★★★
()
Ответ на: комментарий от gns

А вот пример использования можно?

Не очень удобно сейчас.

Что там у вас на Lua пишут?

Тестировщик базовой системы kyua написан на Lua, например. Из загрузчика много логики вынесено в Lua (раньше был Forth). В ядро я не лез, там слишмом страшно. (=

Ещё проскакивала идея переписать /etc/rc на flua (огрызок Lua 5.4 в поставке FreeBSD), но дальше идеи оно пока не продвинулось. Я бы и сам proof-of-concept запилил, но зная насколько консервативно всё в базовой системе, скорее всего оно так и останется валяться в рассылке.

mord0d ★★★★★
()
Ответ на: комментарий от Anoxemian

Указателей в луа нету, он более высокоуровневый, но тут есть ссылки на таблицы, есть замыкания, есть метатаблицы, как имитация указателей. Короче, симуляция на симуляции.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Вот для этого и используют Lua — чтобы не давать прямого доступа к core на C, дополнительно изолируя всякое (потенциально) опасное. (=

Это в контексте модов для игр, например.
А если речь идёт о каком-нибудь AwesomeWM, так он зародился благодаря идее что dwm (из которого он однажды форкнулся) не компилять при каждом изменении.

mord0d ★★★★★
()
Ответ на: комментарий от gagarin0

Уже в 5.3 бэкпортировали? Когда я последний раз тыкал, его там не было… вроде бы.

mord0d ★★★★★
()
Ответ на: комментарий от gagarin0

А как я этим воспользуюсь? Не модифицирую же я клиент вовки?

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Не, ну писать ботов на Lua — это святое дело :) В сервере WoW Lua нужен, может быть, что бы поведение игрового мира для игрока иногда менялось непредсказуемым образом. Типа волшебник придумал новое заклинание с продолженным действием. Уж не знаю, есть там у вас волшебники? :)

gns ★★★★★
()
Ответ на: комментарий от gns

Кстати, написание ботов на луа для фрилансеров - одно из самых популярных направлений. И ботоводство процветает, как никогда.

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

Мне надо делать свои скрипты и хранить о действих игроков информацию. И вот с хранением начинают возникать проблемы.

Представь, есть игровое поле вроде шахматного 10 х 10 клеток. Каждая клетка - объект. У каждой клетки может быть несколько состояний в зависимости от ситуации. И вот если хранить эти состояния хотя бы в массивах, уже к 5-10 тысячах игроков все превратится в тыкву, произойдет переполнение таблиц и база рухнет.

Если не учитывать скорость работы, твой «сервер», через который работают игроки, тупо зависнет от нагрузки. Нужно учитывать количество запросов - ибо все передаетс строками через чат. Нужноу читывать размер запросов - не более 254 байт. Одни ограничения и никакой благодарности.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Ну, основной сервер справляется с большим количеством игроков и состояний и «в этой колоссальной пещере лампа не гаснет». Если можно модифицировать клиента, то можно поставить рядом с основным сервером свой гильдейский, и пусть клиенты твоей гильдии будут как-то еще и с твоим сервером взаимодействовать. Хотя, со мной про игры беседовать бессмысленно. Я только в тетрис играть умею. И если в преферанс, и то с живыми людьми и на деньги.

gns ★★★★★
()
Ответ на: комментарий от gns

А у основного сервера все работает на си и таких ограничений нету. Им просто работать. Я ж писал - если б только у меня была возможность работать на си, я бы ВСЕ делал на нем. Вообще все.

Потому эта новость для меня как издевательство какое то.

LightDiver ★★★★★
()
Ответ на: комментарий от bender

драйвера на луа хотя бы будут читаемы и поддерживаемы

bernd ★★★★★
()
Ответ на: комментарий от LightDiver

Ну берешь клиента, если он опенсорсный, говоришь, что у клиента появился еще один канал обменя с еще одним с сервером, ставишь рядом с основным свой для групповой статистики и склада уж не знаю чего. И пишешь этот сервер хоть на Си, хоть на Ассемблере :) И пусть твоя группа игроков использует модифицированный клиент. Или модифицировать код клиента нельзя по условиям использования игрового сервера?

gns ★★★★★
()
Ответ на: комментарий от gns

Не. Это жесткая проприетарщина. Даже использование кастомных серверов это пиратство и нарушение лицензии.

А писать свою игру это как бы немного другой уровень.

LightDiver ★★★★★
()
Ответ на: комментарий от gns

А хочешь главный прикол? В игре нет сообщения с реальным адрессным пространством компа. Все в рамках игровой сессии хранится в ОЗУ, а сохраняется на диск только в заранее указанных переменных в заранее указанный файл при выходе из игры. Подгружается при входе.

Ты не можешь никак работать с информацией в игре. А скрипты в игре не имеют прямого доступа к диску.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 2)
Ответ на: комментарий от LightDiver

Я просто привел пример, что чуть отхождение от стандартных функций, который написаны на си и падение производительности на несколько прядков. В любой нестандартной ситуации. А тогда в чем смысол? Свои функции писать и использовать нельзя. А не проще тогда сразу на си?

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

sena ★★
()
Последнее исправление: sena (всего исправлений: 1)
Ответ на: комментарий от LightDiver

И что, си настолько в этом хуже? Для профессионала, который привык работать каждый день на си.

Да, конечно, значительно хуже. Даже профессионалу придётся компилировать сишный код перед использованием.

sena ★★
()
Последнее исправление: sena (всего исправлений: 1)
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.