Сообщения vbr
Эксперименты с Rust в ядре закончились
На ежегодной встрече «Linux Kernel Maintainer Summit» разработчики обсудили тему экспериментов с Rust в ядре. Участники пришли к единому мнению, что Rust в ядре больше не является экспериментальным — теперь он является неотъемлемой частью. Таким образом, метка «экспериментальный» будет снята. Поздравляем всю команду Rust for Linux.
Как использовать run0 вместо sudo?
Предположим у меня есть sudoers файл вида
myuser myhost=(root) NOPASSWD: /usr/bin/pacman --sync --downloadonly --sysupgrade --refresh
myuser myhost=(root) NOPASSWD: /usr/bin/pacman --sync --refresh linux
myuser myhost=(root) NOPASSWD: /usr/bin/pacman --sync --refresh linux-lts
myuser myhost=(root) NOPASSWD: /usr/local/bin/offline-sysupgrade
который позволяет пользователю myuser выполнять на хосте myhost указанные команды с указанными аргументами, от имени суперпользователя, не вводя пароль.
Как настроить run0 похожим образом? В интернете почему-то не нашёл никаких инструкций.
Работает ли тренировка аккумулятора?
Есть у меня старый ноутбук, у которого, кажется, убили аккумулятор его неправильным использованием (использование на 5-10%, потом зарядка до 20% и тд).
Он лежал несколько месяцев на полке, я его попытался включить кнопкой и никакой реакции не последовало. Я вставил зарядное устройство и он сразу включился и показал 60% батареи.
Я его зарядил до 100%, оставив на ночь. С утра включил ютуб, отключил зарядное устройство и наблюдаю за процентами аккумулятора. До 50% он разряжался часа 3. После 50% процесс заметно ускорился. Сейчас показывает 13% и одного процента хватает на минуту. Я планирую его разряжать, пока процессор не отключится.
Собственно вопрос - поможет ли это откалибровать аккумулятор чему-либо внутри? Понятно, что у аккумулятора ёмкость такая, какая есть, но хотя бы отображать проценты хочется правильно. А также есть опасение, что если я дам высокую нагрузку, то аккумулятор не выдаст нужные токи и процессор просто может отключиться, даже показывая 50% батареи, например (у меня такое было на старом макбуке).
Chromium использует Wayland по умолчанию
Очередной гвоздь в гроб иксам. До недавнего времени Chromium при запуске использовал X11 (т.е. работал под Xwayland), и требовал передачи флага --ozone-platform-hint=auto для полноценной работы под Wayland. А сегодня проверил - всё, теперь по умолчанию под Wayland. Chromium готов к светлому будущему.
PS я правда никаких отличий не увидел, ну да ладно, наверное они есть.
PPS теперь осталось дождаться аппаратной поддержки кодирования и декодирования видео-потоков, включенной по умолчанию, которые в Windows работают уже лет 20, ну да ладно, дождёмся и этого. А пока --enable-features=AcceleratedVideoDecodeLinuxGL,AcceleratedVideoDecodeLinuxZeroCopyGL,AcceleratedVideoEncoder наше всё.
Альфа версия дистрибутива KDE Linux
KDE Linux — это новая операционная система, предназначенная для повседневного использования, которая демонстрирует Plasma и программное обеспечение KDE в лучшем свете и использует современные технологии.
Кто уже пробовал?
Буфер обмена не всегда работает
Запускаю Android Studio с флагом -Dawt.toolkit.name=WLToolkit. Вроде это запускает её, как нативное wayland приложение.
Копирую что-нибудь из неё. Открываю GNOME Text Editor. Пытаюсь вставить, не срабатывает. И даже пункт Paste не активен совсем.
Открываю терминал, пишу wl-paste - он выводит то, что я скопировал.
Пишу wl-paste | wl-copy, переключаюсь на GNOME Text Editor, всё внезапно начинает работать.
Я сейчас на 100% не уверен, но кажется оно иногда таки работает как надо, а вот сейчас не работает.
Почему такое происходит? Кто виноват, и что делать?
Перемещено hobbit из general
Почему pipewire такой сложный?
Захотел написать простейшую программу, которая будет считывать звук с микрофона. Как-то очень сложно получилось, это тупо абсолютный минимум, чтобы просто печатать сэмплы в stdout:
#include <pipewire/pipewire.h>
#include <spa/param/audio/format-utils.h>
#include <stdio.h>
struct stream_data {
struct pw_stream *stream;
enum spa_audio_format audio_format;
};
static void main_loop_signal(void *data, int signal_number);
static void stream_param_changed(void *data, uint32_t id, const struct spa_pod *param);
static void stream_param_format_changed(void *data, const struct spa_pod *param);
static void stream_process(void *data);
int main(int argc, char *argv[]) {
pw_init(&argc, &argv);
struct pw_main_loop *main_loop = pw_main_loop_new(NULL);
struct pw_loop *loop = pw_main_loop_get_loop(main_loop);
pw_loop_add_signal(loop, SIGINT, main_loop_signal, main_loop);
pw_loop_add_signal(loop, SIGTERM, main_loop_signal, main_loop);
struct pw_properties *stream_properties = pw_properties_new(PW_KEY_MEDIA_TYPE, "Audio", PW_KEY_MEDIA_CATEGORY,
"Capture", PW_KEY_MEDIA_ROLE, "Accessibility", NULL);
struct pw_stream_events stream_events = {
.version = PW_VERSION_STREAM_EVENTS,
.param_changed = stream_param_changed,
.process = stream_process,
};
struct stream_data stream_data;
struct pw_stream *stream = pw_stream_new_simple(loop, "tuktuk", stream_properties, &stream_events, &stream_data);
stream_data.stream = stream;
const struct spa_pod *stream_connect_params[1];
uint8_t spa_pod_builder_buffer[1024];
struct spa_pod_builder spa_pod_builder = SPA_POD_BUILDER_INIT(spa_pod_builder_buffer, sizeof(spa_pod_builder_buffer));
struct spa_audio_info_raw spa_audio_info_raw = SPA_AUDIO_INFO_RAW_INIT(.format = SPA_AUDIO_FORMAT_UNKNOWN);
stream_connect_params[0] = spa_format_audio_raw_build(&spa_pod_builder, SPA_PARAM_EnumFormat, &spa_audio_info_raw);
pw_stream_connect(stream, PW_DIRECTION_INPUT, PW_ID_ANY, PW_STREAM_FLAG_AUTOCONNECT, stream_connect_params,
sizeof(stream_connect_params) / sizeof(stream_connect_params[0]));
pw_main_loop_run(main_loop);
pw_main_loop_destroy(main_loop);
pw_deinit();
}
static void main_loop_signal(void *data, int signal_number) {
struct pw_main_loop *main_loop = data;
pw_main_loop_quit(main_loop);
}
static void stream_param_changed(void *data, uint32_t id, const struct spa_pod *param) {
switch (id) {
case SPA_PARAM_Format:
stream_param_format_changed(data, param);
break;
}
}
static void stream_param_format_changed(void *data, const struct spa_pod *param) {
uint32_t media_type;
uint32_t media_subtype;
if (spa_format_parse(param, &media_type, &media_subtype) < 0) {
fprintf(stderr, "Failed to parse format");
return;
}
if (media_type != SPA_MEDIA_TYPE_audio || media_subtype != SPA_MEDIA_SUBTYPE_raw) {
fprintf(stderr, "stream_param_format_changed media_type=%u media_subtype=%u\n", media_type, media_subtype);
return;
}
struct spa_audio_info_raw audio_info_raw;
spa_format_audio_raw_parse(param, &audio_info_raw);
enum spa_audio_format audio_format = audio_info_raw.format;
if (audio_format != SPA_AUDIO_FORMAT_DSP_F32) {
fprintf(stderr, "stream_param_format_changed audio_format=%d\n", audio_format);
}
}
static void stream_process(void *data) {
struct stream_data *stream_data = data;
struct pw_stream *stream = stream_data->stream;
struct pw_buffer *pw_buffer = pw_stream_dequeue_buffer(stream);
if (pw_buffer == NULL) {
pw_log_warn("out of buffers: %m");
return;
}
struct spa_buffer *spa_buffer = pw_buffer->buffer;
struct spa_data *spa_data = &spa_buffer->datas[0];
struct spa_chunk *spa_chunk = spa_data->chunk;
float *samples = spa_data->data;
uint32_t sample_count = spa_chunk->size / sizeof(float);
for (uint32_t i = 0; i < sample_count; i++) {
printf("%f\n", samples[i]);
}
pw_stream_queue_buffer(stream, pw_buffer);
}
Почему всё так сложно? Должно же быть проще. Зачем аудио-библиотеке выдумывать какие-то main loop-ы, это же не её дело. Почему такие хитрые API. Почему конфигурация через строки. Сложно, очень сложно, надо проще. И все хвалят этот pipewire. А я вот не хвалю, мне не понравилось.
Ещё добавлю, что документации там вообще около нуля. Вот наглядный пример: pw_main_loop_new
Что делает функция pw_main_loop_new? «Create a new main loop.». Да что вы говорите. Что она возвращает? «a newly allocated Main Loop». Да что вы говорите. А бывают ли ошибки? Ой, не написано. А что передаётся в параметре props? Ой, не написано. И это ещё хорошо документированная функция, в куче других и того нет.
Линукс скоро перестанет загружаться
LWN: Linux and Secure Boot certificate expiration
Старые дистрибутивы, у которых shim подписан старым микрософтовским ключом, перестанут загружаться этой осенью, т.к. сертификаты протухнут.
Я, кстати, не понимаю, почему, ну да ладно, не суть.
В общем после 11 сентября ждите небольшого наплыва товарищей с проблемами и готовьтесь советовать отключить secure boot.
Найм в IT всё-таки мёртв
Намедни на хабрахабре появилась любопытная статья Найм в IT всё-таки мёртв, вызвавшая большое число комментариев. Если вкратце - то она констатирует сложность поиска новой работы в IT сегодня. В комментариях многие люди, как в России так и за рубежом подтверждают это явление.
Как я понимаю, если говорить про заграницу, то там фактически идёт экономический кризис. Во время ковида в экономику вбросили много печатных денег, что разогнало инфляцию. А также наняли много работников в IT. Далее для сдерживания инфляции поднимали ставку, что увеличило проценты по кредитам для юрлиц. Компании теперь вынуждены сокращать расходы, чтобы платить по кредитам, в том числе увольняя людей.
В России, конечно, своя специфика: часть IT-шников уехала из-за войны, процессы импортозамещения вроде как должны увеличивать спрос на IT, но тем не менее графики в статье выше никуда не деваются, то бишь в целом явление похожее.
Ещё один интересный фактор это замена IT-шников на ИИ. На мой взгляд пока это скорей теоретические опасения. ИИ совсем недавно начал показывать серьёзные результаты, я не думаю, что он влияет на число вакансий, это история для грядущих годов. Но тоже фактор…
Что вы про всё это думаете и когда наступит оттепель на рынке IT-вакансий?
Asterinas: Linux-совместимое ядро
Из самого сердца Китая, Южного Университета Наук и Технологий (SUSTech) города Шэньчжэня, родился проект Asterinas. Совместимый с ядром Linux на уровне ABI, написанный на Rust, основанный на архитектуре, которую авторы называют «framekernel», сочетающей в себе плюсы монолитного и микроядерного дизайна.
Ядро ядра, простите за каламбур, написано на unsafe Rust и представляет из себя небольшую, но достаточно функциональную библиотеку, которая реализует все нужные абстракции. Это аналог микроядра. Остальная часть ядра написана на safe Rust и использует эту библиотеку. Это аналог сервисов для микроядра. Но в данном случае всё ядро выполняется в одном адресном пространстве на одном уровне привилегий. Таким образом вызовы между этими частями не вызывают накладных расходов, которые типичны для микроядер, связанных с переключением контекста процессора. Но в то же время гарантии, которые даёт компилятор safe Rust, дают стабильность, которая, традиционно, достигалась разграничением кода на аппаратном уровне и была лишь прерогативой микроядер.
Ну а совместимость с ядром Linux на уровне ABI позволяет использовать любой софт, скомпилированный для Linux.
Asterinas был анонсирован в начале 2024 года под свободной лицензией Mozilla Public License. В настоящий момент проект активно разрабатывается студентами ряда китайских университетов и поддерживает 206 из 368 системных вызовов Linux.
Подробней на английском языке почитать можно тут: LWN: Asterinas: a new Linux-compatible kernel project
Конечно пока проект находится на ранней стадии разработки, и в целом является скорей академическим проектом, но мне показалась очень интересной описанная архитектура. Поистине, Rust открывает новые страницы в казалось бы несвязанных с ним областях.
Свободный Android - всё
Reddit: AOSP project is coming to an end
Информация от разработчиков GrapheneOS: Android 16 закрыл репозитории Pixel. AOSP будет закрыт. Официальный Android закрывает исходники.
Зачем запускать приложение под wayland?
Есть некоторые приложения, к примеру chromium, vscode, которые можно запускать как под X, так и под wayland. Например по умолчанию chromium запускается под X, но если запускать его с параметром --ozone-platform-hint=auto, то запустится под wayland.
У меня последний GNOME, сам GNOME запущен под wayland, использую масштабирование 2x. Понятно, что через Xwayland оно всё работает в любом случае.
Собственно вопрос - а зачем это делать? Каких-то визуальных отличий в случае с chrome я не увидел. В случае с vscode не рисуется рамка окна под wayland (известный баг). Есть ли какие-то наблюдаемые отличия, которые я не замечаю? Может FPS в режиме wayland больше, или шрифты по-другому рисуются?
Создание passkey в Chrome
У меня на компьютере Arch Linux, Google Chrome, залогинен в Google аккаунт, пароли синхронизированы.
У меня также имеется Android устройство. Я смог создать на нём passkey и синхронизировать его с компьютером. На компьютере смог использовать этот passkey для входа на сайт passkeys-demo.appspot.com
Однако при попытке создать passkey на компьютере выдаёт ошибку: Your device can’t be used with this site. Т.е. функционал работает лишь наполовину.
На сайте Google имеется такая статья от 19 сентября прошлого года: Sync passkeys securely across your devices
В этой статье написано:
Today, we’re rolling out updates that make it even easier to use passkeys across your devices. You can now save passkeys to Google Password Manager from Windows, macOS, Linux and Android, with ChromeOS currently available for testing in Beta. 1
Once they’re saved, they’ll automatically sync across your devices, making signing in as easy as scanning your fingerprint.
Т.е. они прямым текстом утверждают, что создание passkey на десктопном браузера под Linux должно работать.
Что я делаю не так?
Андроид без лишнего
У меня Pixel 9. ОС не нравится, хочу максимально простую ОС без всего лишнего.
Из опций нашёл:
LineageOS - честно говоря так и не понял, что это такое, на сайте документации не нашёл. Но вроде все про неё пишут.
GrapheneOS. Упоротые на безопасности, мне вообще такое не нужно, мне нужно максимально просто, безопасность мне ни к чему.
Какой-то GSI. Вроде пишут, что это для тестов. Кто-то пробовал его ставить на пиксель?
Есть ещё какие-то альтернативы? Компилировать AOSP не очень хочется, у меня слабый компьютер. Но в идеале мне хочется именно AOSP для пикселя, без чего-либо ещё.
Да, ещё мне надо, чтобы работал Play Store и банковские приложения. Я так понял, с этим в неофициальных андроидах бывают нюансы.
GNOME 48 приехал в арч
И реально не тормозит. Ура.
Можно ли в идее совместить меню и тулбар?
Что-то обновился и как будто они что-то испортили. По дефолту меню вообще скрыто за гамбургером. Это полный бред, конечно. Есть галочка - показывать меню в отдельном тулбаре. С такой настройкой появляется лишняя полоса и жрёт вертикальное место. При этом само меню у меня занимает процентов 30 ширины экрана и справа от него вроде вполне вмещаются все кнопки. В общем какая-то шляпа неудобная в очередной раз, не могут они оставить идею в покое, всё портят и портят.
Как-то это можно исправить может быть? Даунгрейдить не хочу, я новую жаву хочу использовать.
Тут добавил скриншоты, как у меня. https://imgur.com/a/OsBOg8Y
Как должно быть - это, собственно, развёрнутый гамбургер. Но он, конечно, не разворачивается просто так, только пока мышка там. Просто в строку с меню засунуть все кнопки справа и всё, без лишних строк и не сворачивая меню.
Как делать инкрементальный бэкап без WAL-файлов?
Есть только удалённый доступ как юзера, без доступа на сервер. Сейчас делаю через pgdump, но как-то неудобно это, куча места впустую тратится. В голову приходит только хранить предыдущий бэкап и делать тупо текстовый diff с текущим, который и сохранять… Но как-то это странно и не уверен, что diff будет нормально работать для огромных файлов. В теории вроде никто не мешает написать инструмент, который будет это делать более интеллектуально, т.е. работать аналогично pgdump-у, но сохранять только изменённые строки, может такой инструмент уже существует?
Xorg всё
xorg-x11-server is removed from RHEL 10
So Long, and Thanks for All the Fish
Как быстро сконвертировать uint32_t в uint8_t
У меня есть указатель на uint8_t. Я знаю, что он выровнен по адресу 4. Я хочу быстро читать и писать туда uint32_t значение.
Правильный по стандарту вариант использовать memcpy, но он очень медленный.
Быстрый вариант - кастовать uint8_t * в uint32_t * и полагаться на то, что он выровнен. Это генерирует одну инструкцию, но это UB по стандарту, хотя по факту работать будет…
Как тут можно поступить? Меня интересует конкретный компилятор gcc 9.2. Может быть gcc даёт какие-то дополнительные гарантии сверх стандарта для данного случая?
Код:
#include <stdint.h>
#include <string.h>
void save1(uint8_t *p, uint32_t v) {
memcpy(p, &v, 4);
}
void save2(uint8_t *p, uint32_t v) {
uint32_t *p32 = (uint32_t *)p;
*p = v;
}
uint32_t load1(uint8_t *p) {
uint32_t v;
memcpy(&v, p, 4);
return v;
}
uint32_t load2(uint8_t *p) {
uint32_t *p32 = (uint32_t *)p;
return *p32;
}
Во что он компилируется с -Os:
save1:
push {r0, r1, r2, lr}
mov r2, #4
str r1, [sp, #4]
add r1, sp, r2
bl memcpy
add sp, sp, #12
ldr lr, [sp], #4
bx lr
save2:
strb r1, [r0]
bx lr
load1:
push {r0, r1, r2, lr}
mov r2, #4
mov r1, r0
add r0, sp, r2
bl memcpy
ldr r0, [sp, #4]
add sp, sp, #12
ldr lr, [sp], #4
bx lr
load2:
ldr r0, [r0]
bx lr
| следующие → |