LINUX.ORG.RU

Сообщения vbr

 

Как разобраться с китайским SoB?

Форум — Linux-hardware

Имеется такая плата: OKMX6ULL-C

К ней по шлейфу подключил маленький дисплей. При подаче питания грузится какой-то китайский линукс с демо-программами.

Теперь мне надо из этого сделать что-то своё. Я на raspberry собирал свой линукс, но как тут подступиться, пока не понимаю.

Во-первых я не могу подключиться к нему по UART-у, чтобы работать полноценно, а не на крохотном дисплейчике. На выходных пинах есть UART2, …, UART4. Я подключил USB UART к UART2, но дальше соединиться не смог. К распберри я так подключался.

Судя по схеме UART1 разведён на USB-C выход на этой плате через USB-UART микросхему. Не очень понимаю, для чего это сделано. Можно ли подключить этот выход к компьютеру напрямую? Я боюсь спалить что-нибудь.

Во-вторых я не понимаю, как там вообще устроена загрузка. В распберри просто сд-карта, с неё и грузишься. Тут внутри есть emmc память на 8 гигабайтов. Встроенный линукс грузится именно с неё. Там два раздела, один на 500 MB, там ядро и ещё какой-то файл dtb. На втором разделе корень. В принципе слот для сд-карты есть. Пока грузиться с него не пробовал, т.к. вообще не очень понимаю, что туда сувать.

Ещё есть два раздела mmcblk1boot1 4MiB, mmcblk1boot0 4MiB. Они не монтируются, не знаю, что там на них.

В /etc/issue написано Freescale i.MX Release Distro 4.1.15-2.0.1 \n \l

Моя цель: для начала подключить это всё дело через серийный порт, чтобы можно было с компьютера с ним работать по-человечески. Потом скомпилировать минимальный линукс и загрузиться с него. А потом я уже сам разберусь.

Насколько я понимаю, производитель процессора это NXP, компания нормальная, но саму плату сделали китайцы.

У меня есть два гигабайта какой-то мусорной документации, которую они выслали, но я там ничего не понял. Собственно там толком ничего и нет, самое полезное это распиновка самой платы, остальное - тупо несколько десятков даташитов по всем микросхемам, использованным на плате и какой-то «мануал» с putty.exe и ссылками на китайские форумы, откуда предлагается скачать виртуалбокс. В общем такие мануалы мне не нужны.

Я на распи собирал свой линукс через buildroot. Но там был готовый конфиг и человеческие гайды. Как действовать тут - я пока в затруднении.

 , ,

vbr
()

Будут ли языки программирования супер высокого уровня?

Форум — Talks

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

На мой взгляд за последние лет 30 языки программирования не стали выше уровнем. Если взять тот же Haskell, который в каком-то виде в первый раз появился в 1990 году, то я бы не сказал, что Rust последней версии чем-то категорично его превосходит. В целом примерно одни и те же идеи тусуют в разных пропорциях. Я тут говорю исключительно про то, насколько язык помогает программисту писать код.

Мне интересно, как вообще можно совершить качественный скачок в языках программирования, оставаясь в той же парадигме, т.е. мы не будем рассматривать фантастику вроде того, что ты пытаешься там в чате чего-то объяснять роботу. А мы так же пишем формальный строгий текст латинницей, который преобразуется в машинный код. Но при этом то, что сейчас требует месяца работы, будет требовать трёх дней. Там, где сейчас 10 багов, будет 1 баг.

Предполагать, что что-то придёт взамен тексту, я тоже не буду. Текст доказал свою пользу на протяжении тысячелетий. Думаю, что ничего лучше текста не придумать.

Или же программирование в текущем виде достигло своего апогея и никаких принципиально новых идей уже не стоит ожидать?

 ,

vbr
()

Не могу поморгать диодом из C

Форум — Development

Хочу поморгать диодом без библиотек. В целом сетап описан тут. Процессор STM32F030F4P6. Диод подключен, насколько я могу судить, к ноге PA4.

На текущий момент конфигурация такая:

Makefile:

CC = arm-none-eabi-gcc
AS = arm-none-eabi-as
LD = arm-none-eabi-ld
CFLAGS = -mthumb -mcpu=cortex-m0 -O0

.PHONY: all flash

all: app.bin

crt.o: crt.s

app.elf: linker.ld crt.o blink.o
	$(LD) -T linker.ld -o app.elf crt.o blink.o

app.bin: app.elf
	arm-none-eabi-objcopy -O binary $< $@

flash: app.bin
	st-flash --reset write $< 0x8000000

crt.s:

.cpu cortex-m3
.thumb

.word 0x20005000
.word _reset
.thumb_func
_reset:
  bl blink
  b .

linker.ld:

MEMORY {
  FLASH(rx): ORIGIN = 0x08000000, LENGTH = 16K
  RAM (xrw): ORIGIN = 0x20000000, LENGTH = 4K
}

blink.c:

#include <stdint.h>

const uint32_t RCC_BASE = 0x40021000;
const uint32_t GPIOA_BASE = 0x48000000;
const uint32_t RCC_AHBENR_OFFSET = 0x14;
const uint8_t RCC_AHBENR_IOPAEN_BIT = 17;
const uint32_t GPIOx_MODER_OFFSET = 0x00;
const uint8_t GPIOx_MODER_MODE4_BIT_OFFSET = 8;
const uint32_t GPIOx_ODR_OFFSET = 0x14;
const uint8_t GPIOx_ODR_OD4_BIT = 4;

void bit_clear(uint32_t address, uint8_t bit);
void bit_set(uint32_t address, uint8_t bit);
void bit_toggle(uint32_t address, uint8_t bit);

void blink(void) {
  bit_set(RCC_BASE + RCC_AHBENR_OFFSET, RCC_AHBENR_IOPAEN_BIT);
  bit_set(GPIOA_BASE + GPIOx_MODER_OFFSET, GPIOx_MODER_MODE4_BIT_OFFSET);
  bit_set(GPIOA_BASE + GPIOx_ODR_OFFSET, GPIOx_ODR_OD4_BIT);
  volatile uint32_t counter = 0;
  while (1) {
    if (counter % 0x10000 == 0) {
      bit_toggle(GPIOA_BASE + GPIOx_ODR_OFFSET, GPIOx_ODR_OD4_BIT);
    }
    counter++;
  }
}

void bit_clear(uint32_t address, uint8_t bit) {
  uint32_t mask = 1 << bit;
  volatile uint32_t *ptr = (uint32_t *) address;
  *ptr &= ~mask;
}

void bit_set(uint32_t address, uint8_t bit) {
  uint32_t mask = 1 << bit;
  volatile uint32_t *ptr = (uint32_t *) address;
  *ptr |= mask;
}

void bit_toggle(uint32_t address, uint8_t bit) {
  uint32_t mask = 1 << bit;
  volatile uint32_t *ptr = (uint32_t *) address;
  *ptr ^= mask;
}

Адреса брал из RM0360:

2.2.2 Memory map and register boundary addresses

AHB2 0x4800 0000 - 0x4800 03FF GPIOA
AHB1 0x4002 1000 - 0x4002 13FF RCC

7.4.6
Reset and clock control (RCC)
AHB peripheral clock enable register (RCC_AHBENR)
Address offset: 0x14
Bit 17: IOPAEN: I/O port A clock enable

8.4.1
GPIO port mode register (GPIOx_MODER)
Address offset:0x00
Bits 9:8 Port configuration bits
01: General purpose output mode

8.4.6
GPIO port output data register (GPIOx_ODR)
Address offset: 0x14
Bit 4: Port output databit

Насколько я понял из чтения документации:

  1. Нужно настроить регистр RCC_AHBENR и включить I/O port A.
  2. Нужно настроить регистр GPIOx_MODER и включить output mode для PA4.
  3. Для включения/выключения диода нужно менять бит GPIOx_ODR.

Возможно код на C неправильный, я его знаю плохо, пытался писать максимально просто.

На CubeMX пример с HAL копипастил, он работает, диод моргает. Ниже приведу на всякий случай:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
	HAL_Delay(100);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA4 */
  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

Но я в нём ничего не понимаю, хотелось бы попроще.

 , ,

vbr
()

Правильно ли я подключил МК?

Форум — Development

Хочу поэкспериментировать с МК. Для этого собрал следующую конструкцию:

Плата Baite STM32F030F4

Модуль зарядки TP4056

Далее у меня есть плата Nucleo L073RZ мануал (стр. 16). Я от этой платы отрезал верхний кусок по линии разреза, как я понимаю, там находится программатор. У этого программатора я вытащил два джампера CN2 чтобы переключить его на работу с внешним МК.

Подключил я это всё следующим образом:

1 провод от модуля зарядки TP4056 с пометкой «OUT +» к плате Baite, пину «header 1 pin 5 VIN»

1 провод от модуля зарядки TP4056 с пометкой «OUT -» к плате Baite, пину «header 1 pin 6 GND»

4 провода от Nucleo L073RZ коннектор CN4 пины VDD_TARGET, SWCLK, GND, SWDIO к Baite пинам SWD header pins 3V3, SWCLK, GND, SWDIO

2 провода от Nucleo L073RZ пины TX RX к Baite пинам Serial header pins RX TX

Вообще вчера я подключал всё почти так же, только питание у модуля зарядки брал похоже не с тех разъёмов. В итоге на Baite шло нефильтрованное питание из USB (примерно 4.5В показывал мультиметр). В целом всё заработало, программу я смог залить, но периодически программатор показывал, что соединения с контролером нет.

Сегодня я питание подключил как выше написал, теперь там 4.2В, как я понимаю, более стабильное. Также запитал USB-порт отдельным блоком питания. Пока вроде не отваливается. Вообще допускаю, что я плохо что-то припаял, т.к. паять я не умею, модуль питания и контролер шли без гребёнок, я эту гребёнку к ним припаял и соединил всё на проводках с квадратными разъёмами.

Вопрос 1 - вообще всё правильно?

Вопрос 2 - для чего нужен пин VDD_TARGET? Я сначала подумал, что от него можно запитать контролер, но потом почитав понял, что он питание не даёт а наоборот проверяет.

Вопрос 3 - для чего я подключил TX/RX? Я сам не знаю. Как-то через ST Link можно получить к нему доступ?

Вопрос 4. Можно ли куда-то подключить пин с программатора NRST? Я так понимаю, это удобная штука для перезагрузки контролера, но куда его подключить я не нашёл. Или он не нужен?

 

vbr
()

Контроль своего домена

Форум — Talks

Предположим, мне не нравится, что гугл в любой момент может забанить мой username@gmail.com, на который завязана вся моя цифровая жизнь.

Ну как линуксоид я иду и покупаю домен. Настраиваю на этот домен почтовый ящик и вот уже я me@username.com, счастье.

Но есть одно «но». Чтобы купить домен, мне надо зарегистрироваться на каком-нибудь namecheap-е. И для регистрации мне нужна… Правильно, почта.

Если я потеряю доступ к своей исходной почте, любая проблема с аккаунтом и доступ к домену я теряю.

Что же делать?

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

Альтернативно: можно после покупки домена и настройки почтового сервера у регистратора сменить почту. Рекурсивненько получается. Но опять же это рецепт для проблем. Забыл домен оплатить вовремя, побежал его продлевать - а зайти не можешь и почта не ходит уже.

Я даже думал завести отдельную почту как раз для такой цели - регистрировать на неё самое важное. И желательно не в гугле. Но я не нашёл ни одного крупного почтового сервера, который бы обещал, что он никогда не удалит аккаунт. У всех есть оговорки, что если вы не заходите полгода, мы имеем право удалить аккаунт. Ну я каждого не изучал, только самых крупных, а мелкие и сами закрыться могут.

 

vbr
()

Постгрес в контейнере и ограничение по памяти?

Форум — General

Имеется постгрес в контейнере в кубе. За несколько дней у него растёт потребление по памяти постепенно. Пока не дорастает до лимита, процесс-коннект не прибивает ООМ-ом и всё заново не происходит. Кажется, что это не совсем хорошо. Хочется навести порядок. Начинал с 60M, уже 300M ему выделил, он сегодня до 200 дорос, как чайный гриб, растёт и всё, при том, что он и на 60M работал - ему 200M явно не надо.

Причём судя по тому, что, скажем, он 3 дня работает нормально, это явно не какие-то там пики и тд, просто память утекает в какие-то кеши или хз куда.

В идеале хочется задать постгресу Xmx60m как жаве и он за пределы этих 60m не вылазил и сам рассчитал там размеры для своих кешей и прочего. А не ронял процессы по ООМ.

Как тут правильно поступить?

 , ,

vbr
()

Как грамотно запустить контейнер, чтобы работал Ctrl+C

Форум — General

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

Первое, что пробовал это ENTRYPOINT ["sleep", "infinity"]. Не сработало. sleep игнорирует сигналы. Всякие вариации вроде bash -c "sleep infinity" или bash -c "exec sleep infinity" тоже не работают.

Лучшее, что придумал - ENTRYPOINT ["sh", "-c", "while sleep 1; do true; done"]. Но немного некрасиво - секунду всё равно ждать и крутится там туда-сюда, запускает sleep всё время. И кажись для SIGSTOP не работает, только для SIGINT.

Какой самый классный и короткой способ сделать так, чтобы и по сигналу (SIGINT и SIGSTOP) завершало выполнение, и чтобы в рамках sh работало, и выглядело не монструозно. Через всякие trap-ы и kill-ы и я смогу, но там строк на 10 будет в лучшем случае.

 , , ,

vbr
()

А вы пытаетесь соблюдать FHS в контейнерах?

Форум — Talks

Почему-то коробит, когда делают контейнеры с /data, /app и прочим бредом. Всегда делаю контейнеры с /home/build, /opt/app, /srv/data, /mnt/host и тд, пытаясь хоть как-то в FHS. Для меня создавать рандомный каталог в корне это какое-то кощунство. Вполне могу себе представить, что с таким подходом кто-нибудь смонтирует что-нибудь в /dev, типа среда разработки.

А вы как думаете? Есть в этом смысл?

 

vbr
()

Помогите улучшить хук usePromise

Форум — Web-development

Пытаюсь подружить реакт с промисами. React Query и прочую муть не предлагать.

Пока родился такой вариант. Думаю, из сигнатур очевидно, как оно должно работать. Не нравится то, что reducer получился «не чистый». Вызывает abortController.abort(). Хотя и идемпотентный но кажется это всё равно не по феншую.

Как сделать нормально - я не придумал. Хотя думал много и это далеко не первая итерация. Буду благодарен помощи от гуру, если у кого будет хорошая идея.

import { DependencyList, useEffect, useReducer } from "react";

type PromiseFunction<T> = (signal: AbortSignal) => Promise<T>;

type Result<T> =
  | { status: "pending" }
  | { status: "fulfilled"; value: T }
  | { status: "rejected"; reason: unknown };

type State<T> =
  | { status: "uninitialized" }
  | { status: "pending"; id: number; abortController: AbortController }
  | { status: "fulfilled"; value: T }
  | { status: "rejected"; reason: unknown };

type Action<T> =
  | { type: "init"; id: number; abortController: AbortController }
  | { type: "resolve"; id: number; value: T }
  | { type: "reject"; id: number; reason: unknown }
  | { type: "clean" };

function reducer<T>(state: State<T>, action: Action<T>): State<T> {
  switch (action.type) {
    case "init":
      switch (state.status) {
        case "uninitialized":
          return {
            status: "pending",
            id: action.id,
            abortController: action.abortController,
          };
      }
      break;

    case "resolve":
      switch (state.status) {
        case "uninitialized":
          return state;
        case "pending":
          if (action.id < state.id) {
            return state;
          }
          if (action.id == state.id) {
            return { status: "fulfilled", value: action.value };
          }
          break;
      }
      break;

    case "reject":
      switch (state.status) {
        case "uninitialized":
          return state;
        case "pending":
          if (action.id < state.id) {
            return state;
          }
          if (action.id == state.id) {
            return { status: "rejected", reason: action.reason };
          }
          break;
      }
      break;

    case "clean":
      switch (state.status) {
        case "pending":
          state.abortController.abort();
          return { status: "uninitialized" };
        case "fulfilled":
        case "rejected":
          return { status: "uninitialized" };
      }
      break;
  }

  console.error("Unexpected state", state, action);
  return state;
}

function loggingReducer<S, A>(
  reducer: (state: S, action: A) => S,
): (state: S, action: A) => S {
  return (state, action) => {
    try {
      const nextState = reducer(state, action);
      console.log(state, action, nextState);
      return nextState;
    } catch (e) {
      console.log(state, action, e);
      throw e;
    }
  };
}

let nextId = 1;

export default function usePromise<T>(
  promiseFunction: PromiseFunction<T>,
  deps: DependencyList,
): Result<T> {
  const [state, dispatch] = useReducer(loggingReducer(reducer<T>), {
    status: "uninitialized",
  });

  useEffect(() => {
    const id = nextId++;
    const abortController = new AbortController();

    dispatch({ type: "init", id, abortController });

    promiseFunction(abortController.signal).then(
      (value) => dispatch({ type: "resolve", id, value }),
      (reason) => dispatch({ type: "reject", id, reason }),
    );

    return () => dispatch({ type: "clean" });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, deps);

  switch (state.status) {
    case "uninitialized":
    case "pending":
      return { status: "pending" };

    case "fulfilled":
      return { status: "fulfilled", value: state.value };

    case "rejected":
      return { status: "rejected", reason: state.reason };
  }
}

 

vbr
()

prometheus, whitelisting всего

Форум — General

Хочу начать освоение прометеуса с малого.

К примеру есть адрес someserver.com/metrics

Он выплёвывает кучу всего. Мне из всего этого нужно только одна метрика:

base_gc_time_total_seconds{name="G1 Old Generation"} 0.0
base_gc_time_total_seconds{name="G1 Young Generation"} 0.303

Причём вот этот label мне не нужен, я хочу его убрать. Чтобы в базе лежало только одно значение - сумма этих двух значений.

Как убирать лишние метрики я вроде понял:

    metric_relabel_configs:
      - source_labels: [ __name__ ]
        regex: base_gc_time_total_seconds
        action: keep

А вот как убрать лишние label-ы - я не понял. Можно использовать labeldrop, но кажется это не то, он не будет комбинировать получившиеся метрики, а получится какая-то смесь.

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

Также важно, чтобы эта конфигурация применялась локально к конкретной метрике.

В общем по сути хочу включать метрики потихоньку добавляя нужные мне метрики и label-ы, а не всё скопом. Типа добавил base_gc_time_total_seconds, а все label-ы у него убрал. Потом разобрался - что мне нужна более тонкая статистика и добавил этот name конкретно к этой метрике.

 

vbr
()

Как проверить oom killer?

Форум — General

Завис сервер. Я рассчитывал, что он отвиснет, когда oom killer что-нибудь прибьёт, а он не отвисает до сих пор. Подожду до завтра, но явно ситуация не нормальная. Поэтому на соседнем сервере пытаюсь разобраться.

Сам я ничего не настраивал специально, свопа у системы нет. Система установлена из облачного образа debian.

Почему создал тему - в интернете на каждом сайте пишут, что оно контролируется через sysctl vm.oom-kill. Но у меня такого нет:

debian@worker-d-3:~$ /usr/sbin/sysctl vm.oom-kill
sysctl: cannot stat /proc/sys/vm/oom-kill: No such file or directory
debian@worker-d-3:~$ ls /proc/sys/vm
admin_reserve_kbytes         dirty_ratio                max_map_count              nr_hugepages              overcommit_ratio          user_reserve_kbytes
block_dump                   dirty_writeback_centisecs  memory_failure_early_kill  nr_hugepages_mempolicy    page-cluster              vfs_cache_pressure
compact_memory               dirtytime_expire_seconds   memory_failure_recovery    nr_overcommit_hugepages   page_lock_unfairness      watermark_boost_factor
compact_unevictable_allowed  drop_caches                min_free_kbytes            numa_stat                 panic_on_oom              watermark_scale_factor
compaction_proactiveness     extfrag_threshold          min_slab_ratio             numa_zonelist_order       percpu_pagelist_fraction  zone_reclaim_mode
dirty_background_bytes       hugetlb_shm_group          min_unmapped_ratio         oom_dump_tasks            stat_interval
dirty_background_ratio       laptop_mode                mmap_min_addr              oom_kill_allocating_task  stat_refresh
dirty_bytes                  legacy_va_layout           mmap_rnd_bits              overcommit_kbytes         swappiness
dirty_expire_centisecs       lowmem_reserve_ratio       mmap_rnd_compat_bits       overcommit_memory         unprivileged_userfaultfd

Видимо гайды устарели. Как правильно проверить? Ядро 5.10.0-20-amd64

В /usr/lib/systemd/ бинарника systemd-oomd тоже нет и сервиса соответствующего тоже нет, если что.

 ,

vbr
()

Файловая система для SD-карт

Форум — General

Есть смысл смотреть на что-то вроде F2FS или сейчас нормальные карты от SSD не отличаются и сами балансируют записи по блокам, то бишь стандартный Ext4 будет предпочтительней?

Помимо прочего крайне необходимо, чтобы не было порчи ФС при выключении питания. Данные хранятся в sqlite, поэтому важно, чтобы sqlite оставалась в работоспособном состоянии.

 , , , ,

vbr
()

raspberry, buildroot, wayland

Форум — General

Хочу сделать на raspberry киоск с веб-интерфейсом (чтобы после загрузки открывался браузер на весь экран с HTML с диска).

Как я понял, свой линукс надо собирать через buildroot, вместо electron надо использовать wpewebkit и сейчас графика работает через wayland.

Но ничего у меня в итоге не получилось и не работает.

Минимальный образ buildroot-ом с помощью make raspberrypi4_defconfig я собрал, он грузится, консоль есть, залогиниться можно. buildroot 2022.02.8

Далее долго пытался найти минимальный подбор опций, чтобы получилось выбрать wpewebkit. Вышло примерно следующее:

Toolchain
 Enable WCHAR support
Target packages
 Graphic libraries and applications (graphic/text)
  mesa3d
   Gallium vc4 driver
   OpenGL ES
 Libraries
  Graphics
   wpewebkit
 Graphic libraries and applications (graphic/text)
  cog
   Wayland backend
Filesystem images
 ext2/3/4 root filesystem
  exact size: 180M

cog это, как я понимаю, браузер на этом wpewebkit, т.е. видимо то, что и должно показать мою HTML-ку и то, что я должен буду настроить на автозапуск.

В итоге cog этот не запускается. Пишу cog (от рута), он начинает в цикле писать (сокращаю, т.к. перепечатываю)

error: XDG_RUNTIME_DIR not set in the environment.
WARNING Your application does not implement g_application_activate() and has no handlers connected to the activate signal. It should do one of these.
libEGL warning: MESA-LOADER: failed to open swrast: File not found (search paths /usr/lib/dri, suffix _dri)

EGLDisplay initialization failed: EGL_NOT_INITIALIZED

Cog Core WARNING THe rendered process crashed.

XDG_RUNTIME_DIR ставил, эта ошибка ушла, толку не было.

Что за libEGL warning я не понял. В /usr/lib/dri файла swrast_dri.so нет. Есть файл vc4_dri.so. Как я предполагаю, swrast это софтовый растеризатор, а vc4 это хардварный. Как этому libEGL сказать, чтобы он использовал vc4, я пока не понял, гугл не очень помогает.

Пробовал добавить weston, пришлось для этого udev ставить, но ничего не изменилось, weston тоже не запускается.

Пробовал запускать cog --platform=wl, пишет preferred modulewlnot supported, cannot create platformm: could not find an usable platform module. could not load the impl library. Is there any backend installed? File not foudn.

Может я вообще не в том направлении двигаюсь? raspi в целом это больше прототип, потом надо будет это на i.mx8 делать, поэтому хочу через buildroot сделать.

Также пробовал включать v3d драйвер, не помогло.

 , ,

vbr
()

Почему не работает suid бит

Форум — General

Хочу взломать свой компьютер через докер.

Запустил в конейнере линукс, подмонтировал туда локальную папку. В неё предварительно скопировал sh. Сделал chmod u+s sh из докера. Вышел из докера - suid бит остался. Запускаю этот sh ожидая, что suid бит его запустит под рутом - но не получается.

vbr@13049:~/test$ ls -la
total 132
drwxr-xr-x 2 vbr vbr   4096 Dec  4 05:51 .
drwxr-xr-x 8 vbr vbr   4096 Dec  4 05:47 ..
-rwsr-xr-x 1 root      root      125560 Dec  4 05:47 sh
vbr@13049:~/test$ stat sh
  File: sh
  Size: 125560    	Blocks: 248        IO Block: 4096   regular file
Device: 801h/2049d	Inode: 3951222     Links: 1
Access: (4755/-rwsr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2022-12-04 05:52:33.620839091 +0600
Modify: 2022-12-04 05:47:48.758333113 +0600
Change: 2022-12-04 05:52:24.856885055 +0600
 Birth: 2022-12-04 05:47:48.758333113 +0600
vbr@13049:~/test$ ./sh 
$ id
uid=1001(vbr) gid=1001(vbr) groups=1001(vbr),997(docker)
$ ls /root
ls: cannot open directory '/root': Permission denied

Никаких маунтов с nosuid нет.

 

vbr
()

self hosted github runner в публичном репозитории

Форум — Security

Имеется организация в github на бесплатном тарифе.

Имеется несколько закрытых репозиториев.

Хочется иметь reusable workflow, который можно вызывать из этих закрытых репозиториев. Хранить его нужно в публичном репозитории, т.к. на бесплатном тарифе нельзя вызывать reusable workflow из закрытых репозиториев.

К этой организации прикреплены self hosted runners. Они должны использоваться для этого workflow.

В документации написано:

We recommend that you only use self-hosted runners with private repositories. This is because forks of your public repository can potentially run dangerous code on your self-hosted runner machine by creating a pull request that executes the code in a workflow.

В самом публичном репозитории с reusable workflows ничего кроме них самих и какой-нибудь документации ничего не будет.

Хочется понять, как правильно и безопасно это всё организовать.

 ,

vbr
()

.gitignore: всё в secrets/ кроме *.example.*

Форум — Development

Есть каталог some/path/secrets/ в нём есть два файла: name.env и name.example.env. Нужно заигнорить первый и разигнорить второй. Таких каталогов и файлов много, нужно универсальное правило.

Логичный вариант (в корне) не сработал

secrets/
!secrets/*.example.*

он всё игнорит в итоге. Пробовал некоторые вариации, не получилось.

Как правильно?

 

vbr
()

Как вычитать http запрос?

Форум — Web-development

Хочу вычитать входящий запрос по протоколу HTTP 1.0 или 1.1 и послать ответ, в котором будет текст запроса.

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

Выходит, придётся парсить запрос.

Я так понимаю, есть три алгоритма:

transfer-encoding не указан и content-length не указан. Тогда читаем до закрытия соединения.

content-length указан. Тогда читаем указанное число байтов (ну или до закрытия соединения, что будет странно).

указан transfer-encoding и в нём присутствует chunked. Тогда читаем чанки, пока не придёт чанк нулевой длины, что сигнализирует конец запроса.

Пока не понял, что делать, если указан и chunked и content-length, но я прочитаю.

Можно ли считать, что этого хватит для любых разумных и неразумных (но в рамках протокола) запросов?

 

vbr
()

Альтернативы keycloak

Форум — General

Ищу легковесную альтернативу Keycloak.

Хотелки:

  • Всякие oauth штуки. Тут нужна достаточно продвинутая поддержка - маппинг групп, audience.
  • Своя база юзеров с паролями.
  • Страница логина. Регистрация не нужна.
  • Функционал сброса пароля путём отправки ссылки на почту через SMTP-сервер с авторизацией.
  • Sqlite база или что-то подобное.
  • Админка для просмотра, добавления и редактирования пользователей.
  • Настройки realm-а и прочих oauth штук через конфиги, а не как в keycloak в базе/UI. Чтобы можно было конфиг поменять и запустить с изменённым конфигом, а не тыкаться там по менюшкам.

Нужно что-то легковесное, чтобы стартовало шустро и память не жрало.

В кейклоке не устраивает:

  • Долгий старт, несколько минут. Они предлагают собирать свой образ. Это неудобно.
  • Жрёт под половину гигабайта на пустой базе.
  • Конфиг в базе хранится. Нет удобного способа делать что-то, похожее на gitops. На terraform можно сделать, но это бред какой-то.
  • Работает на взрослой базе вроде постгреса. У меня нагрузка смешная, мне это не надо, гемор по поддержке полноценной базы не хочу.

 

vbr
()

Решето

Форум — Talks

Sudo 1.8.0 through 1.9.12, with the crypt() password backend, contains a plugins/sudoers/auth/passwd.c array-out-of-bounds error that can result in a heap-based buffer over-read. This can be triggered by arbitrary local users with access to Sudo by entering a password of seven characters or fewer. The impact could vary depending on the compiler and processor architecture.

 ,

vbr
()

Без чего вы не обходитесь на андроиде?

Форум — Talks

По случаю санкций решил пересесть с айфона на андроид. Зонд это хорошо, но когда у тебя отбирают двагис, это плохо. Купил пиксель 7, вроде говорят, что у гугла самые приятные ощущения.

Про андроид знаю больше как программист, но в повседневной жизни его почти не использовал.

Пока на аосп/ф-дроид переезжать не планирую, но держу этот вариант в уме на всякий случай.

Собственно что вы бы поставили себе на телефон из неочевидных приложений? Может лаунчер какой маст хэв или файловый менеджер. И почему. Что не хватает в стандартном?

 

vbr
()

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