LINUX.ORG.RU

Сообщения bugs-bunny

 

Вставка bash-команд в Makefile. Передача переменных.

Есть сборка RPM-пакетов софтины через rpmbuild. Задача стоит опакетить это под DEB. Для сборки запускается shell-скрипт, который тянет исходники из git, патчит их, парсит конфигурацию сборки и выставляет -D и -I для сборки в переменных для Makefile-ов через export, и запускает rpmbuild.

rpmbuild делает в итоге

make -C каталог all
и собирает RPM-ы из бинарников. На замену rpmbuild решено было использовать свой Makefile. Shell-скрипт поправлен так, чтобы вызывал этот скрипт
make -f make_deb.mak
. Из shell в Makefile переменные передаются через export, все нормально, переменные видны. Но в Makefile при сборке target-ов происходит что-то мне непонятное. Для теста сделал отдельный пример.

var = ""
val = "value"
num = 1

.PHONY: all

all: test6

test:
	echo "1#### "$$var ; \
	if [ -z $$var ] ; then \
	    var="$(val)";  \
	    echo "2#### var="$$var; \
	else \
	    echo "3#### FAIL"; \
	fi; \
	echo "4#### "$$var

test4:
	echo "##### test4"$(optflags)
	if [ -z "${CFLAGS}" ]; \
	then \
	    CFLAGS=${optflags}; \
	    echo $$CFLAGS ; \
	fi ; \
	echo $$CFLAGS

test6:
	@PYTHON=/usr/bin/python3 ; \
	TESTVAR=test ; \
	env ; \
	echo $(PYTHON) ; \
	./a.sh

Заданные в Makefile переменные, в нем же видны (test). Заданные в bash-консоли переменные видны (test4).

optflags=anyflags; make -f b.sh test4
Заданные во фрагменте shell-кода (test6) переменные не видны ни в следующих командах вставки, ни в вызываемом ./a.sh (там тоже просто echo $(PYTHON)). Какую магию нужно использовать в этом случае?

 , ,

bugs-bunny
()

Отслеживание подключения флешки

Нужно отследить момент подключения флешки. Предполагаю, что это делается через D-Bus, и надо ловить сигнал на шине org.freedesktop.UDisks2 (dbus-monitor --system показывает сигналы на этой шине, d-feet-ом можно посмотреть структуру). Желательно на чистом C без крестов (да, читал на freedesktop.org, что это «pain»), без GTK, QT.

Есть утилита USBGuard, включена в Ubuntu, из исходников не собирается (в 2-х разных форумах пишут про эти грабли), писана на С++17 со всеми его прибабахами, про freedesktop.org там вообще не нашел в коде, но бинарный пакет ставил и он вообщем работает (автор проект забросил, в каждом дистре собирают его форки).

Тут примерно описано, что надо делать, но ссылка на пример сдохла http://wiki.linuxformat.ru/wiki/LXF99:D-Bus. Пример отсюда запускал, как-то работает, что-то гоняет https://stackoverflow.com/questions/9378593/dbuswatch-and-dbustimeout-examples . Прошу выдать волшебного пенделя. В какую сторону копать, что почитать? Ведь работают же например всякие нотификации в трее, может кто знает в каком пакете KDE/Gnome это находится.

Вот этот код ничего не ловит, кроме первого сообщения от org.freedesktop.DBus, NameAcquired.

/**

 */

#define _GNU_SOURCE   /* for pipe2 in unistd.h */

#include "dbus/dbus.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>   /* for pipe2 */
#include <errno.h>
#include <fcntl.h>    /* for O_NONBLOCK */
#include <sys/time.h> /* for gettimeofday */
#include <limits.h>   /* for INT_MAX */


static DBusHandlerResult handle_messages(DBusConnection *connection, DBusMessage *message, void *user_data);

#if 0
#define INTERFACE   "org.freedesktop.HAL"
#define OBJPATH     "/org/freedesktop/HAL"
#endif

#if 1
#define INTERFACE   "org.freedesktop.UDisks2"
#define OBJPATH     "/org/freedesktop/UDisks2"
#endif

DBusObjectPathVTable	vtable;

typedef struct _DBusContext
{
    DBusConnection      *conn;
}
DBusContext;

DBusContext     ctx;

//---------------------------------------------------------------------------//
/**
 * @brief flt_handle_messages
 * @param connection
 * @param message
 * @param user_data
 * @return
 */
static DBusHandlerResult flt_handle_messages(DBusConnection *connection, DBusMessage *message, void *user_data)
{
    const char *interface_name = dbus_message_get_interface(message);
    const char *member_name = dbus_message_get_member(message);

    printf("##### Got Message \n%s\n%s\n", interface_name, member_name);

    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

//---------------------------------------------------------------------------//
// watch
static DBusWatch * watched_watch = NULL;
static int watched_rd_fd = 0;
static int watched_wr_fd = 0;


static dbus_bool_t add_watch(DBusWatch *w, void *data)
{
    if (!dbus_watch_get_enabled(w))
        return TRUE;

    int fd = dbus_watch_get_unix_fd(w);
    unsigned int flags = dbus_watch_get_flags(w);
    int old_rd_fd = watched_rd_fd;
    int old_wr_fd = watched_wr_fd;

    if (flags & DBUS_WATCH_READABLE)
        watched_rd_fd = fd;
    if (flags & DBUS_WATCH_WRITABLE)
        watched_wr_fd = fd;
    watched_watch = w;

    printf(" WATCH:    add dbus watch fd=%d watch=%p rd_fd=%d/%d wr_fd=%d/%d\n",
           fd, w, watched_rd_fd, old_rd_fd, watched_wr_fd, old_wr_fd);
    //watched_chgevt_send( CHGEVT_ADD_WATCH );

    return TRUE;
}

static void remove_watch(DBusWatch *w, void *data)
{
    watched_watch = NULL;
    watched_rd_fd = 0;
    watched_wr_fd = 0;
    printf(" WATCH:    remove dbus watch watch=%p\n", w);
}

static void toggle_watch(DBusWatch *w, void *data)
{
    printf(" WATCH:    toggle dbus watch watch=%p\n", w);
    if (dbus_watch_get_enabled(w))
        add_watch(w, data);
    else
        remove_watch(w, data);
}
//---------------------------------------------------------------------------//
/**
 * @brief dbus_loop
 * @return
 */
int flt_loop()
{
    DBusError 		error;
    DBusConnection 	*conn;
    DBusMessage 	*msg;
    DBusMessageIter iter;
    dbus_bool_t		res;
    int             ret = 1; // default fail

    dbus_error_init (&error);
    conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
    if (!conn)
    {
        fprintf (stderr, "%s: %s\n", error.name, error.message);
        return 1;
    }
    ctx.conn = conn;

    dbus_connection_add_filter(conn, flt_handle_messages, NULL, NULL);

    dbus_bus_add_match(conn, "type='signal',interface='"INTERFACE"'", NULL);
    dbus_connection_flush(conn);

#if 0
    DBusObjectPathVTable vtable;
    vtable.message_function = handle_messages;
    vtable.unregister_function = NULL;

    res = dbus_connection_try_register_object_path(conn, OBJPATH,&vtable,NULL,&error);
#endif

#if 1
    // setup watch and timeout
    if (!dbus_connection_set_watch_functions(conn, add_watch, remove_watch,
                                             toggle_watch, NULL, NULL)) {
        printf(" ERROR dbus_connection_set_watch_functions() failed\n");
        return ret; /* ret=1 fail */
    }
    /*if (!dbus_connection_set_timeout_functions(conn, add_timeout,
                                               remove_timeout, toggle_timeout,
                                               NULL, NULL)) {
        printf(" ERROR dbus_connection_set_timeout_functions() failed\n");
        return ret; // ret=1 fail
    }*/
#endif

#if 1
    while (1)
    {
        dbus_connection_read_write_dispatch(ctx.conn, 1000);
    }
#endif
#if 0
    // ToDo.
#endif
}

//---------------------------------------------------------------------------//
/**
 * @brief main
 * @param argc
 * @param argv
 * @return
 */
int main(int argc, char **argv)
{
    // ToDo. Parse command line (e.g. start, stop commands)

    flt_loop();

	return 0;
}

Makefile

#PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

#OBJS = portsflt.o
OBJS = test001.o

INC = -I/usr/include/dbus-1.0/ -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include/
#INC = `pkg-config --cflags dbus-1`
LIBS = -L/usr/lib/x86_64-linux-gnu/ -ldbus-1
#LIBS = `pkg-config --cflags --libs dbus-1`

ifeq ($(BUILD_MODE),debug)
	CXXFLAGS = $(CFLAGS) -O0 -g3 -Wall -fmessage-length=0
else ifeq ($(BUILD_MODE),run)
	CXXFLAGS = $(CFLAGS) -O0 -g3 -Wall -fmessage-length=0
else
#	$(error Build mode $(BUILD_MODE) not supported by this Makefile)
	CXXFLAGS = $(CFLAGS) -O0 -g3 -Wall -fmessage-length=0
endif

.PHONY:all

all:	portsflt

portsflt:	$(OBJS)
	$(CXX) -o $@ $^ $(LIBS)

.SUFFIXES: .c .cpp .o

%.o : %.cpp
	$(CXX) -c $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(INC) -o $@ $<

%.o : %.c
	$(CC) -c $(CFLAGS) $(CXXFLAGS) $(INC) -o $@ $<

clean:
	rm -fr portsflt $(OBJS)
	
test:
	echo $(LIBS)
	echo $(BUILD_MODE)

 ,

bugs-bunny
()

GDB в Eclipse не делает StepOver через dlopen

Есть функция, которая подгружает «/usr/lib/x86_64-linux-gnu/libpcsclite.so.1»

#include <dlfcn.h>
void *sc_dlopen(const char *filename)
{
	void* ret;
	char* err;

	//ret = dlopen(filename, RTLD_LAZY);
	ret = dlopen(filename, RTLD_NOW);
	if(!ret)
	{
		err = dlerror();
		printf("dlopen error %s\r\n",err?err:"unknown");
	}
	return ret;
}

Ставлю breakpoint на dlopen. При попытке сделать Step Over через dlopen дебагер зависает и дальше не идет. Если запускать программу просто из консоли, то этот код отрабатывает без ошибок (по крайней мере сообщений и с нормальным кодом завершения) и зависаний. С флагами RTLD_LAZY и RTLD_NOW результат одинаковый.

В чем тут может быть дело?

 , ,

bugs-bunny
()

Датчики, Твердотельные реле для системы управления. Посоветуйте.

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

Завел Raspbian на RPi 3B. Все замечательно, даже Eclipse оказывается собран для arm (не без косяков).

1) Для замера температуры взял датчики LM75AD с I2C, еще не паял. Вроде бы есть готовые датчики (температуры и давления) BMP180 (http://roboshop.spb.ru/barometr-bmp180). Буду смотреть в сторону libsoc2 для работы с I2C. Или что лучше использовать для GPIO и I2C в RPi?

2) Для включения обогрева и насоса думаю выбрать твердотельные реле. Тут есть сомнения. Вот эти https://smartmodules.ru/fotek-ssr-25da ,говорят на easyelectronics, за час работы на 1/3 заявленного рабочего тока перегреваются, залипают и сгорают до углей. Про эти https://www.chipdip.ru/product/hhg1-1-032f-38-80a ничего не знаю. Кто что использовал и посоветует?

3) А собственно что нужно реализовать? Демона, который будет заниматься управлением железом; и наверное CGI-программу для веб-морды, которая будет снимать данные, давать установки демону, и гнать html в stdout. Так?

 ,

bugs-bunny
()

libblkid выдает неверные данные для GPT диска

Есть 3 диска в виртуалке. sda1 и sda2 имеют MBR, sda3 - GPT. Вот что показывает blkid.

root@LIN:/home/user# blkid
/dev/sdb2: UUID="36c5be34-179b-4af9-a677-9cd8239c9127" TYPE="swap" 
/dev/sdb1: UUID="cbfb2cad-8cc6-4497-a109-fd91e4b185d2" TYPE="ext4" 
/dev/sda1: UUID="eb047a72-374a-47ab-ab4a-2287f5f5001a" TYPE="ext3" 
/dev/sdc1: UUID="9269-9FCA" TYPE="vfat" 
/dev/sdc2: UUID="9275-D8F7" TYPE="vfat" 
/dev/sdc3: UUID="67CDA00432B128C5" TYPE="ntfs" 
/dev/sdc4: UUID="15FAB91367B9E2F7" TYPE="ntfs" 
Т.е. кривой UUID (и метка тома тоже).

Кроме того, я использую функцию blkid_partition_get_type() из libblkid в своей софтине, чтобы найти раздел EFI по типу 0xEF00, а получаю 0x0000 на всех разделах диска с GPT. Для MBR разбивки возвращаются нормальные значения, например 0x0083 для ext2.

С чем это может быть связано? Что использовать взамен libblkid?

 ,

bugs-bunny
()

Отладка FUSE драйвера с помощью GDB из Eclipse

Сделал FUSE-драйвер. В прошлый раз отлаживался по отладочным сообщениям (ключ "-d" при запуске драйвера), отлаживал куски кода по отдельности и потом включал в драйвер.

Можно ли как-то отловить вызовы функций драйвера после того как вызван fuse_main?

Рецепты для отладки fork-ающихся программ здесь кажется не работают. Делал .gdbinit c «follow-fork-mode child». Ставил в настройках Eclipse «Non-stop mode» и «Automatic debug forked process». Ключ "-s" (single thread) в параметрах драйвера. GDB не ловит брекпоинты.

 , ,

bugs-bunny
()

Разделить массив в JSON

Есть задача разделить строку «{1},{2},{3}» на несколько строк «1\n2\n3». 123 это подстроки вида «param1»:«value1», не суть. Пробую

echo "{1},{2},{3}" |  sed 's/{\(.*\)},/\1\n/'
Хотелось бы
1
2
3
Получаю
1},{2
{3}
Заменяю { и } на ( и ) - результат аналогичный, т.е. дело не в {} и не в экранировании в bash или в sed (пишут https://www.opennet.ru/docs/RUS/bash_scripting_guide/c11895.html, что {} воспринимаются как обычные символы). ЧЯДНТ?

 , , ,

bugs-bunny
()

Hybrid ISO. grub-mkimage. Grub: out of range pointer

Пилю свою ОС с нескучными обоями спасательный Live-CD на основе Ubuntu c дополнительным специфическим софтом. Ранее сделал Live-CD на основе live-build, который сам кривой как сабля, поддержка его заброшена (но вроде бы кто-то взялся за него снова) и не собирает hybrid образы для загрузки и Legacy, и EFI.

Решил сделать свой bash-скрипт для сборки hybrid iso. Образ собирается, в VMWare в Legacy-режиме вроде бы грузится. В EFI-режиме возникла проблема с запуском Grub2 загрузчика.

Функция сборки fat-раздела с загрузчиком

CHROOT="chroot64"
ARCH="amd64"
ARCHG="x86_64-efi"
BINARY="binary64"

...............................
makegrub()
{
mkdir -p $BINARY/EFI/BOOT
#mkdir -p $BINARY/boot/grub

cat > $BINARY/EFI/BOOT/grub.cfg << EOF
set timeout=5
set color_highlight=black/light-magenta
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray

menuentry 'Boot rescue system' {
    set gfxpayload=keep
    linux /live/vmlinuz boot=casper
    initrd /live/initrd
}
EOF
#    root (hd0)/live/filesystem.squashfs

# https://askubuntu.com/questions/91484/how-to-boot-ubuntu-from-efi-uefi

GRUB_MODULES="fat iso9660 part_gpt part_msdos ntfs ext2 exfat btrfs hfsplus udf
 font gettext gzio
 normal boot linux linux16 configfile loopback chain
 efifwsetup efi_gop efi_uga
 ls help echo elf search search_label search_fs_uuid search_fs_file
 test all_video loadenv
 gfxterm gfxterm_background gfxterm_menu"

#GRUB_MODULES="linux part_gpt ext2 normal gfxterm gfxterm_background gfxterm_menu test all_video loadenv fat"

grub-mkimage -o $BINARY/EFI/BOOT/bootx64.efi -p /EFI/BOOT -O $ARCHG  --verbose -c $BINARY/EFI/BOOT/grub.cfg  $GRUB_MODULES
#grub-mkstandalone -o $BINARY/EFI/BOOT/bootx64.efi -O $ARCHG --verbose.

#cp -r /usr/lib/grub/$ARCHG  $BINARY/EFI/BOOT

#rm -f $BINARY/EFI/BOOT/bootx64.efi; cp ./2/bootx64.efi $BINARY/EFI/BOOT
#rm -f $BINARY/EFI/BOOT/bootx64.efi; cp ./2/grubx64.efi $BINARY/EFI/BOOT/bootx64.efi

mkdir -p ./tmp
dd if=/dev/zero of=./efi.img bs=512 count=16384
mkfs.fat ./efi.img
mount ./efi.img ./tmp
cp -r $BINARY/EFI ./tmp
sync
umount ./tmp
rm -rf ./tmp
mv -f efi.img $BINARY

}

В итоге, при загрузке этого grub-а выводится

out of range pointer 0x48fb894800000000
Aborted. Press any key to exit.

... и вываливается в EFI shell.

Если подсунуть в качестве /EFI/BOOT/bootx64.efi загрузчик из ubuntu-mate-16.10-desktop-amd64.iso, переименовав из grubx64.efi, то появляется меню и ядро грузится (выпадая в итоге в panic, но это отдельная история).

Если подсунуть результат grub-mkstandalone (использует grub-mkimage и те же модули и ядро grub), то он тоже запускается.

Явно, что проблема в сборке grub-mkimage, образ получается немного меньше ubunt-овского. По всем описаниям, модулей для сборки указывается не так уж много, и то, что я видел и по логике должно быть я добавил - fat, part_msdos и т.д.

Кто-нибудь сталкивался с такой проблемой? Какие-то более информативные отладочные сообщения в grub можно включить?

 ,

bugs-bunny
()

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