LINUX.ORG.RU

Сообщения id_thx1138

 

В Debian 12 перестал работать ctrl+ins / shift+ins

Форум — General

После обновления до Debian 12 сочетание ctrl+ins/shift+ins стало работать очень странно - срабатывает только если нажать на ins дважды. Проверил в MATE и в xfce - поведение одинаковое.

 

id_thx1138
()

Запустить initramfs с systemd c /etc на отдельном разделе

Форум — Admin

У меня есть сборка buildroot с systemd и initramfs, понадобилось чтобы была возможность конфигурирования systemd и проч., перенести раздел /etc из инитрамфс на отдельный раздел.

Но возник вопрос, как смонтировать раздел, который нужен для запуска systemd? uBoot запускает initramfs а там уже systemd

Может кто сталкивался уже с таким?

Спасибо!

 ,

id_thx1138
()

Не удается изменить размер виртуального экрана для фреймбуфера в linux 5.10

Форум — Development

У меня есть работающее приложение, которое работало напрямую с /dev/fb0 и использовало двойную буферизацию. Приложение прекрасно работало на linux 4.4, но запустив ПО на linux 5.10 я получил сообщение об ошибке:

fbset: ioctl FBIOPUT_VSCREENINFO: Invalid argument

Конкретное место в коде, которое приводит к ошибке:

	/* Set virtual display size double the width for double buffering */
	device->fb_vinfo.yres_virtual = device->fb_vinfo.yres * 2;
	if (ioctl(device->fb_fd, FBIOPUT_VSCREENINFO, &device->fb_vinfo)) {
		perror("Error setting variable screen info from fb");
		goto handle_ioctl_error;
	}

Я так понимаю, что проблема связана с тем, что в linux 5.10 fb эмулируется через DRM и драйвер DRM не поддерживает изменение размера виртуального экрана больше физического. Возможно дело в конкретной реализации drm - sun4i-drmdrmfb.

Вот лог загрузки ядра (linux 5.10 на Allwinner A20):

[    8.593273] sun4i-drm display-engine: bound 1e00000.display-frontend (ops 0xc0aa5648)
[    8.601279] sun4i-drm display-engine: bound 1e20000.display-frontend (ops 0xc0aa5648)
[    8.609606] sun4i-drm display-engine: bound 1e60000.display-backend (ops 0xc0aa4de8)
[    8.617394] sun4i-drm display-engine: attempt to add DMA range to existing map
[    8.624981] sun4i-drm display-engine: bound 1e40000.display-backend (ops 0xc0aa4de8)
[    8.633498] sun4i-drm display-engine: bound 1c0c000.lcd-controller (ops 0xc0aa363c)
[    8.641837] sun4i-drm display-engine: No panel or bridge found... RGB output disabled
[    8.649733] sun4i-drm display-engine: bound 1c0d000.lcd-controller (ops 0xc0aa363c)
[    8.658485] [drm] Initialized sun4i-drm 1.0.0 20150629 for display-engine on minor 0
[    8.709176] Console: switching to colour frame buffer device 60x50
[    8.731589] sun4i-drm display-engine: [drm] fb0: sun4i-drmdrmfb frame buffer device

Можно прям в консоли проверить:

# fbset -i

mode "800x480"
    geometry 800 480 800 400 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0
endmode

Frame buffer device information:
    Name        : sun4i-drmdrmfb
    Address     : (nil)
    Size        : 1536000
    Type        : PACKED PIXELS
    Visual      : TRUECOLOR
    XPanStep    : 1
    YPanStep    : 1
    YWrapStep   : 0
    LineLength  : 3200
    Accelerator : No

попробуем установить виртуальную область меньше физической:

# fbset -v -xres 800 -yres 480 -vxres 800 -vyres 400
Linux Frame Buffer Device Configuration Version 2.1 (23/06/1999)
(C) Copyright 1995-1999 by Geert Uytterhoeven

Opening frame buffer device `/dev/fb0'
Using current video mode from `/dev/fb0'
Setting video mode to `/dev/fb0'

# fbset

mode "800x480"
    geometry 800 480 800 400 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0
endmode

вернем все как было:

# fbset -v -xres 800 -yres 480 -vxres 800 -vyres 480
Linux Frame Buffer Device Configuration Version 2.1 (23/06/1999)
(C) Copyright 1995-1999 by Geert Uytterhoeven

Opening frame buffer device `/dev/fb0'
Using current video mode from `/dev/fb0'
Setting video mode to `/dev/fb0'

# fbset 

mode "800x480"
    geometry 800 480 800 480 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0
endmode

пробуем установить виртуальный экран как 800x960 для double buffering:

# fbset -v -xres 800 -yres 480 -vxres 800 -vyres 960
Linux Frame Buffer Device Configuration Version 2.1 (23/06/1999)
(C) Copyright 1995-1999 by Geert Uytterhoeven

Opening frame buffer device `/dev/fb0'
Using current video mode from `/dev/fb0'
Setting video mode to `/dev/fb0'
ioctl FBIOPUT_VSCREENINFO: Invalid argument

Кто ни будь сталкивался с такой проблемой? Что можно сделать в данном случае - отказаться от double buffering? переписать бекенд на libdrm?

Хотелось бы еще понять почему драйвер drm не поддерживает изменение размера виртуального дисплея…

Спасибо.

 ,

id_thx1138
()

Особенности работы с poll

Форум — Development

Добрый день!

Столкнулся с такой вот проблемой при работе с poll на некоторых устройствах, какой бы таймаут не задавал - первый poll может не дать никакого результата - возвращает 0, а во второй попытке уже есть нужное событие POLLIN. Это случается не всегда, но довольно часто. Это точно не таймаут, тк я пробовал задавать таймаут 30-60 сек., и ситуация так же воспроизводилась, как и на таймауте в 500мс.

Кто ни будь сталкивался с таким поведением?

ps Да, порт конечно же открыт как O_NONBLOCK

...
struct pollfd pfd = { .fd = fd, .events = POLLIN };
...
int retries = 0;
while (retries < 3) {
    res = poll (&pfd, 1, ms_to);

    if (res <= 0 || pfd.revents != POLLIN) {
        retries++;
        continue;
    }
    ssize_t chunksize = read (fd, buf + bytesread, size);
...

Обновление: Теперь работа с tcp запросами на сервер, посылку организовал +/- так же, система debian 10 (если это важно); Стоит таймаут 1000мс ожидания ответа от сервера, примерно на 15 запросов 3-4 остаются без ответа, первое что сделал - увеличил таймаут до 2000мс, да, стало меньше запросов без ответа, но все равно случаются… поставил 5 секунд - ответ от сервера стал приходить стабильно но блин - 5 секунд камон! И тут я вспомнил эту тему.

Как выглядело получение пакета изначально:

ssize_t
recv_to (int fd, void *buf, size_t size, int flags, int ms_to) {
	struct pollfd pfd = { .fd = fd, .events = POLLIN };
	size_t bytesread = 0;
	int res;

	while ((res = poll (&pfd, 1, ms_to)) > 0) {
		if (pfd.revents != POLLIN) break;
		ssize_t chunksize = recv (fd, buf + bytesread, size, flags);
		if (chunksize < 0) return chunksize;
		if (chunksize == 0) break;

		bytesread += chunksize;
		size -= chunksize;

		if (size == 0) break;
		pfd.revents = 0;
	}

	if (res < 0) return res;
	return bytesread;
}

Поделим таймаут на некоторое значение (на 3 например) и будем 3 раза пытаться вызывать poll с укороченным таймаутом. Таймаут ожидания ответа от сервера вернул в 1000мс, вот что получилось:

ssize_t
recv_to (int fd, void *buf, size_t size, int flags, int ms_to) {
	struct pollfd pfd = { .fd = fd, .events = POLLIN };
	size_t bytesread = 0;
	int res;

	const int trypoll = 3;
	ms_to = ms_to / trypoll;
	for (int i = 0; i < trypoll; i++) {
		while ((res = poll (&pfd, 1, ms_to)) > 0) {
			if (pfd.revents != POLLIN) break;
			ssize_t chunksize = recv (fd, buf + bytesread, size, flags);
			if (chunksize < 0) return chunksize;
			if (chunksize == 0) break;

			bytesread += chunksize;
			size -= chunksize;

			if (size == 0) break;
			pfd.revents = 0;
		}

		if (size == 0) break;
		dbgmsg_func ("try tcp poll #%d\n", i + 1);
	}

	if (res < 0) return res;
	return bytesread;
}

На trypoll==2 еще были недополученные пакеты, на trypoll==3 уже нет… WTF? Мне кажется, что я что-то делаю не так, как-то не правильно работаю с poll, но у меня нет никаких идей, почему 3 poll c таймаутом 333мс работают а один с таймаутом 1000мс - нет.

Что думаете?

 , , ,

id_thx1138
()

Как правильно разделить 2 типа сборки в Makefile

Форум — Development

Сразу скажу, что да, знаю, что есть autotools, но хочу попробовать все же обойтись одним мейкфайлом.

Есть библиотека, которая собирается под arm и x86, выглядит это все примерно так:

INCLUDEPATH=-I./include -I$(SRCINCL) -I$(USRLIBS)

LIBS= -lpthread

MAIN_SRC= \
	./src/mylib.c \
	./src/impl_1.c

all: arm

arm: TARGET=arm
arm: CC=$(CC_ARM)
arm: buildinfo clean depends ${TARGET_LIB} test

x86-64: TARGET=linux
x86-64: CC=$(CC_LINUX)
x86-64: buildinfo clean depends ${TARGET_LIB} test

$(TARGET_LIB): $(MAIN_SRC:.c=.o)
	@echo linking: $@
	@ $(CC) ${LDFLAGS} ${LIBS} -Wl,-soname,$(LIB_NAME).so.$(MAJOR).$(MINOR) -o $@ $^ ./libs/other/libother.a
	@rm -f ./$(LIB_NAME).so
	@ln -s -f $@ ./$(LIB_NAME).so

$(MAIN_SRC:.c=.o): %.o:%.c
	@echo compile: "\t" $<" >>> "$@
	@ $(CC) $(INCLUDEPATH) $(CFLAGS_LIB) $(DEFINES)  $< -o $@

depends:
	@echo depends!
	@echo $(MAKE) $(TARGET)
	@cd libs/other && $(MAKE) $(TARGET)

Теперь мне нужно добавить новую цель target2, которая бы собирала так же как arm цель, но вместо ./src/impl_1.c использовала бы файл ./src/impl_2.c

Я тут наговнокодил так, но это все выглядит максимально плохо конечно…

INCLUDEPATH=-I./include -I$(SRCINCL) -I$(USRLIBS)

LIBS= -lpthread

MAIN_SRC= \
	./src/mylib.c

SRC_1= \
	./src/impl_1.c

SRC_2= \
	./src/impl_2.c

all: arm

arm: TARGET=arm
arm: CC=$(CC_ARM)
arm: buildinfo clean depends ${TARGET_LIB} test

target2: TARGET=arm
target2: CC=$(CC_ARM)
target2: buildinfo clean depends ${TARGET_LIB_2} test

x86-64: TARGET=linux
x86-64: CC=$(CC_LINUX)
x86-64: buildinfo clean depends ${TARGET_LIB} test

$(TARGET_LIB): $(MAIN_SRC:.c=.o) $(SRC_1:.c=.o)
	@echo linking: $@
	@ $(CC) ${LDFLAGS} ${LIBS} -Wl,-soname,$(LIB_NAME).so.$(MAJOR).$(MINOR) -o $@ $^ ./libs/other/libother.a
	@rm -f ./$(LIB_NAME).so
	@ln -s -f $@ ./$(LIB_NAME).so

$(TARGET_LIB_2): $(MAIN_SRC:.c=.o) $(SRC_2:.c=.o)
	@echo linking: $@
	@ $(CC) ${LDFLAGS} ${LIBS} -Wl,-soname,$(LIB_NAME).so.$(MAJOR).$(MINOR) -o $@ $^ ./libs/other/libother.a
	@rm -f ./$(LIB_NAME).so
	@ln -s -f $@ ./$(LIB_NAME).so

$(MAIN_SRC:.c=.o): %.o:%.c
	@echo compile: "\t" $<" >>> "$@
	@ $(CC) $(INCLUDEPATH) $(CFLAGS_LIB) $(DEFINES)  $< -o $@

$(SRC_1:.c=.o): %.o:%.c
	@echo compile: "\t" $<" >>> "$@
	@ $(CC) $(INCLUDEPATH) $(CFLAGS_LIB) $(DEFINES)  $< -o $@

$(SRC_2:.c=.o): %.o:%.c
	@echo compile: "\t" $<" >>> "$@
	@ $(CC) $(INCLUDEPATH) $(CFLAGS_LIB) $(DEFINES)  $< -o $@


depends:
	@echo depends!
	@echo $(MAKE) $(TARGET)
	@cd libs/other && $(MAKE) $(TARGET)

P.S. Я намерено многое выкинул из примера, не относящееся к сути.

 

id_thx1138
()

Особенности реализации программы, для работы в качестве сервиса systemd

Форум — Development

Всем привет, такой вопрос, есть ли какой-то перечень того, что должно быть реализовано в программе, чтобы она правильно работала как сервис systemd? Может быть какой-то how to есть? Я реализовал в программе перехват SIGINT и SIGTERM - достаточно ли этого?

 

id_thx1138
()

Проблема с функциями в динамической библиотеке .so

Форум — Development

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

uint16_t crc16_ccitt (const void *p, size_t size);

она используется исключительно внутри библиотеки в не объявлена в экспортируемых заголовочных файлах.

Если вдруг в приложении, где будет использоваться эта библиотека, есть функция с таким же именем, то из библиотеки вызывается именно эта пользовательская реализация… конкретно это я заметил исключительно потому, что у пользователя эта функция была объявлена как

uint16_t crc16_ccitt (size_t size, const void *p);

то есть параметры были поменяны местами и когда библиотека пыталась ее вызвать, приложение падало в segmentation fault.

Есть ли какой-то способ избежать таких эффектов и изолировать функции библиотеки от пользовательских функций с таким же именем, возможно, некоторая опция gcc?

Если нет, то как такую проблему решают в крупных проектах?

Библиотека собирается с такими опциями:

-fPIC -c -std=c11 -fplan9-extensions -Wall -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-format-zero-length

 , ,

id_thx1138
()

Named pipes в виде последовательного порта

Форум — Development

Думал это будет довольно просто сделать, но оказалось, что нет (( Есть 2 пайпа (tx и rx), нужно чтобы они выглядели в системе как последовательный порт. Со всеми подобающими атрибутами последовательного порта, вроде настройки baud итд, но совсем не обязательно, чтобы эти настройки работали, достаточно того, чтобы со стороны клиента не было ошибок. Как это можно сделать? В какую сторону копать? Писать минимальный драйвер последовательного порта конечно бы не хотелось… Желательно ещё, чтобы это можно было создавать динамически, типа вот тебе ~/my_tty - подключайся, пользуйся.

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

 ,

id_thx1138
()

Какой самый быстрый способ прочитать значение из файла

Форум — Development

Всем привет!

Допустим у меня есть файлы содержащие одно единственное значение, например md5 другого файла, или файл '/sys/class/power_supply/battery/online', который содержит только 0 или 1 в зависимости от состояния устройства...

Какой самый простой и правильный способ получить эти значения в программе?

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

static int
battery_online () {
    FILE *f = fopen ("/sys/class/power_supply/battery/online", "r");
    if (!f) {
        perrmsg ("fopen: '/sys/class/power_supply/battery/online'");
        return 0;
    }

    char str[32];
    int status = 0;
    if (fgets (str, sizeof (str), f))
        status = atoi (str);
    else
        perrmsg ("fail on read '/sys/class/power_supply/battery/online'");
    fclose (f);
    return status;
}

Покритикуйте? Как правильней сделать? Спасибо)

 ,

id_thx1138
()

Не работает dns при запуске dhcpcd

Форум — Development

При запуске dhcpcd не работает dns, при этом пинг по ip адресу работает.

dhcpcd.conf:

( читать дальше... )

Интерфейс запускается следующим образом:

# modprobe rt2800usb
...
# wpa_supplicant -B -Dwext -iwlan0 -c /usr/local/etc/wpa_supplicant.conf
...

# dhcpcd wlan0
all: IPv6 kernel autoconf disabled
wlan0: adding address fe80::d5ec:46d2:4d48:9e42
if_addaddress6: Operation not supported
script_runreason: /lib/dhcpcd/dhcpcd-run-hooks: WEXITSTATUS 127
script_runreason: /lib/dhcpcd/dhcpcd-run-hooks: WEXITSTATUS 127
wlan0: waiting for carrier
[ 2663.433046] wlan0: authenticate with 40:4a:03:42:17:0f
[ 2663.573679] wlan0: send auth to 40:4a:03:42:17:0f (try 1/3)
[ 2663.581269] wlan0: authenticated
[ 2663.584864] rt2800usb 2-1.3:1.0 wlan0: disabling HT as WMM/QoS is not supported by the AP
[ 2663.594791] rt2800usb 2-1.3:1.0 wlan0: disabling VHT as WMM/QoS is not supported by the AP
[ 2663.609222] wlan0: associate with 40:4a:03:42:17:0f (try 1/3)
[ 2663.627678] wlan0: RX AssocResp from 40:4a:03:42:17:0f (capab=0x31 status=0 aid=6)
[ 2663.642889] wlan0: associated
wlan0: carrier acquired
all: IPv6 kernel autoconf disabled
script_runreason: /lib/dhcpcd/dhcpcd-run-hooks: WEXITSTATUS 127
DUID 00:01:00:01:c9:73:fa:7a:7c:dd:90:bf:ad:54
wlan0: IAID 90:bf:ad:54
wlan0: soliciting a DHCP lease
wlan0: offered 192.168.30.32 from 192.168.30.1
wlan0: probing address 192.168.30.32/24
wlan0: leased 192.168.30.32 for 1200 seconds
wlan0: adding route to 192.168.30.0/24
wlan0: adding default route via 192.168.30.1
script_runreason: /lib/dhcpcd/dhcpcd-run-hooks: WEXITSTATUS 127
forked to background, child pid 1878
# 
# ping ya.ru
ping: bad address 'ya.ru'

При этом, если использовать ifup - то все работает, но ifup использует udhcpc, хотелось бы отказаться от него в пользу dhcpcd из-за некоторых глюков в процессе работы.

# ifup wlan0
udhcpc (v1.24.1) started
Sending discover...
Sending select for 192.168.30.32...
Lease of 192.168.30.32 obtained, lease time 1200
deleting routers
adding dns 192.168.30.1
# 
# ping ya.ru
PING ya.ru (87.250.250.242): 56 data bytes
64 bytes from 87.250.250.242: seq=0 ttl=48 time=10.295 ms
64 bytes from 87.250.250.242: seq=1 ttl=48 time=8.960 ms
64 bytes from 87.250.250.242: seq=2 ttl=48 time=8.520 ms

--- ya.ru ping statistics ---

И файл resolv.conf пуст.

 ,

id_thx1138
()

Как система определяет, какой сетевой интерфейс будет использовать?

Форум — Development

Сразу оговорюсь, у меня embedded, со своим урезанным линуксом. Допустим в системе есть интерфейсы eth0 и wlan0, они то становятся доступными, то нет. Если в основной программе мы открываем сокет (AF_INET), то на каком из интерфейсов он будет назначен?

Понятно, что можно явно указать IP, но что будет в случае, если мы не указываем IP?

    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE
    int res = getaddrinfo (NULL, port_num, &hints, &servinfo);

И второй вопрос: как определить программно, что: 1) какой либо из интерфейсов стал доступен 2) там доступен интернет (можно конечно пингануть, но может есть менее костыльный способ?)

Спасибо.

 , ,

id_thx1138
()

Зачем avahi требуется одноименный пользователь?

Форум — Development

Пытаюсь запустить avahi на embeded linux с одним пользователем root

# ./avahi-daemon 
Failed to find user 'avahi'.

Юзера добавить в систему проблематично, зачем вообще avahi нужен отдельный пользователь?

По сути задача такая: в локальной сети находить определенное устройство, получать его IP и начинать с ним TCP обмен сообщениями. Конечно можно самому написать обмен широковещательными udp пакетами, но мне кажется это все таки велосипед... хотя avahi и прочие Bonjour с zeroconf тянут столько зависимостей, что кажется это не самая плохая идея.

Правильно ли я вообще пытаюсь решить задачу?

 ,

id_thx1138
()

Что означают круглые скобки в shell

Форум — Development

Столкнулся со странным поведением скрипта в тех случаях, когда я пишу примерно так:

[ $? = 0 ] && (echo -e "OK!"; chmod +x "$target_file") || echo "FAILED"

Можно ли так использовать круглые скобки и если нет то почему?

 , ,

id_thx1138
()

RSS подписка на новые темы