И это всё МОЁ

Всю жизнь создаю раздел подкачки. А тут ставлю свежую систему на SSD и думаю - нафига?

Ведь основной смысл отдельного раздела на HDD был в том, что он не фрагментируется. Но зачем теперь это на SSD?








 , ,








И это всё МОЁ

Задача


Получать поток данных с микрофона, конвертировать на лету в mp3 формат и передавать на сервер. Цифровой аналог рации.


Используется



  • ElectronJS (ver. 6.0.10);

  • fluent-ffmpeg (ver. 2.1.2)

  • ffmpeg (ver. 4.2-static)


Комментарий


Сейчас используется следующий алгоритм:
В renderer процессе через navigator.getUserMedia инициализируется микрофон и получаем поток.
Поток скармливается MediaRecorder.
Когда приходит команда начать запись, данные собираются в blob, blob скармливается FileReader, чтобы получить base64 строку.
Полученный результат передаётся через IPC из renderer процесса в main.
В main процессе данные сохраняются во временный файл.
Временный файл скармливается ffmpeg, который в виде выходного файла некий url адрес конечного файла, куда производится запись/передача.
Это одинаково работает, и в Windows системе, и в Linux системах.


Сейчас требуется real-time реализация, чтобы данные конвертировались в mp3 и передавались в процессе записи.


Что пробовал:




  • Скармливать данные из MediaRecorder в ffmpeg через Stream API.
    Мысль такова: Пока «активен» поток, ffmpeg конвертирует и передаёт данные в real-time режиме. Поток закрываем, конвертирование останавливается, в файл записывается окончание.
    Через remote.require подключил ffmpeg в renderer процессе.
    Создал сквозной Transform поток, который входящие данные трансформировал в Blob’ы.
    Поток скармливался ffmpeg.
    Аналогично действующему решению, только данные передаются сразу в ffmpeg.
    ffmpeg ругается на входные данные, это странно, потому что такие же данные записываются во временный файл.
    Ещё не разобрался в причинах такого поведения.




  • Передавать в ffmpeg адрес микрофона.
    Мысль такова: ffmpeg всеяден и может самостоятельно брать поток данных с микрофона.
    ElectronJS будет только управлять командами «старт», «стоп» и предоставлять конечный url.
    Здесь всплывает пласт проблем, связанных с поиском и объявлением аудио устройств.




Вопросы


Какие ещё можно рассмотреть доступные варианты, что мог упустить из виду или сделать неправильно?









 , , ,








И это всё МОЁ
cat /etc/debian_version

out:

9.11

wget dl.suckless.org/dwm/dwm-6.2.tar.gz
tar xzpf dwm-6.2.tar.gz
cd dwm-6.2/dwm
make

out:

dwm build options:
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os -I/usr/X11R6/include -I/usr/include/freetype2 -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION="6.2" -DXINERAMA
LDFLAGS = -L/usr/X11R6/lib -lX11 -lXinerama -lfontconfig -lXft
CC = cc
cc -c -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os -I/usr/X11R6/include -I/usr/include/freetype2 -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"6.2\" -DXINERAMA drw.c
drw.c: In function ‘xfont_create’:
drw.c:143:38: error: ‘FC_COLOR’ undeclared (first use in this function)
if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
^~~~~~~~
drw.c:143:38: note: each undeclared identifier is reported only once for each function it appears in
drw.c: In function ‘drw_text’:
drw.c:353:32: error: ‘FC_COLOR’ undeclared (first use in this function)
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
^~~~~~~~
Makefile:18: recipe for target 'drw.o' failed
make: *** [drw.o] Error 1








 ,








И это всё МОЁ

https://easyeda.com/puzrin/dispenser


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


Тогда если воткнуть USB с нажатой кнопкой, то запустится загрузчик. А если просто подать питание, то запустится прошивка и дальше состояние boot0 не должно иметь значения. Но это в теории. А на практике как? Какие-то подобные эффекты? Спрашиваю, потому что ни разу не имел дел с этими чипами.


Ну и минутка рекламы https://github.com/puzrin/dispenser :). Наконец-то покончил с библиотекостроительством, и начал лепить пошивку. С гуями получается довольно бодро. Скриншот в ридми. Фонты генерятся из TTF. Ради этого долго страдал, изобретал новый формат и писал конвертор. Там нормальный кернинг и хинтинг. Если разработчики LVGL осилят, будет еще и субпиксельный рендеринг.


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









 








И это всё МОЁ

Начиная с версии 3.34 Gnome полностью перешёл на инструментарий пользовательских сессий systemd. Данное изменение полностью прозрачно как для пользователей, так и для разработчиков (XDG autostart поддерживается) - видимо по этому оно и прошло незамеченным на ЛОР.


Ранее только DBUS-activated запускались с помощью пользовательских сессий, а остальное делал gnome-session. Теперь от этой лишней прослойки наконец-то избавились.


Что любопытно, в процессе миграции systemd добавил новое API для удобства разработчиков гнома - https://github.com/systemd/systemd/pull/12424


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


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


Для модераторов: на мини-новость, по-моему, тянет.









 , ,








И это всё МОЁ

Други подскажите.

У меня установлен на машине Debian 10, KDE Plasma, проприетарные драйвера Nvidia. В системе 2 видеокарты, GTX 1060 и GTX 690.

К 1060 подключено 2 монитора 4k и 1 телек 4к.
Телек должен дублировать 1 из 2х моников.

Теперь вопросы.

1) Я не знаю что произошло, но с недавнего времени у меня в случае если подключены все 3 монитора (2 моника + 1 телек) то при логине и старте загрузке KDE моники отключаются и пишет что нет сигнала по Display Port на обоих мониках. На телеке тоже тишина.
Приходится выходить в текстовый режим и перегружать машину. И только если я отключаю телек (выдергиваю hdmi кабель которым от подключен), то после логина грузится KDE и на обоих мониках есть картинка. Как вылечить эту проблему?

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

Подскажите, что не так. Но самое главное это вопрос трех моников.








 , ,








И это всё МОЁ

«Микроэлектроника» в Алуште компания «Байкал Электроникс» представила свой новый процессор «Байкал-М».

Разработка этого процессора началась несколько лет назад, но затем, в силу ряда объективных обстоятельств компания была вынуждена переключить основную часть ресурсов на разработку процессора «Байкал-Т». После выхода последнего разработка «Байкал-М» вновь вступила в активную фазу и сегодня процессор был представлен широкой публике:

Подробнее

https://sdelanounas.ru/blogs/125046/








 , ,








И это всё МОЁ

Hacktoberfest 2019


Отпразднуйте Hacktoberfest, приняв участие в сообществе открытого кода. Мы хотели бы попросить вас помочь нам перевести openITCOCKPIT на максимально возможное количество языков. Абсолютно каждый может присоединиться к проекту, для участия нужен только аккаунт на GitHub.


О проекте:


openITCOCKPIT - это современный веб-интерфейс для управления средой мониторинга на основе Nagios или Naemon.


Описание участия можно найти здесь.









 , , , ,








И это всё МОЁ

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








 








И это всё МОЁ

Всем доброго времени суток. Неделю назад была проблема со спамом и пониженной репутацией на почтовом сервере. Проблему решил, однако заметил что ip-адрес сервера числиться в листе BACKSCATTERER.ORG,а эти ребята ушлые, просят деньги или 4 недели жди. Вообще читал про них что это как неплохой бизнес, берешь рандомный адрес хоста и пихаешь его в свой список, обновляешь раз в пару дней и ждешь бабок.
Так вот к сути, попробовал сменить ip-адрес, вроде все норм и горя не знаю, однако заметил что новый адрес появился в этом же списке, будто домен взяли на крючок. На самом этом листе указано, когда якобы замечены подозрительные действия, изучив логи видел лишь то, что на нашу почту с несуществующего хостнейма пытались прислать спам и почтовик его отфутболил и все.
Как бороться с этим?








 , ,








И это всё МОЁ

Купил Самсунг, продавец создал новый гугл аккаунт, я убрал его с телефона и вошел под старым.Может новый аккаунт повлиять на безопасность старого аккаунта?








 , ,








И это всё МОЁ

Сабж. Правда, не для линуксов, а для винды. Но развивают.


Becky! Internet Mail - это почтовая программа японского производства с адаптацией под российские «дороги» в
виде поддержки русских кодировок koi8-r и windows-1251, с умением не только показывать, но и создавать
HTML-письма, с возможностью приема почты по POP3 и IMAP4 протоколам.


Обновлено 30.09.2019


http://m.softportal.com/software-875-becky-internet-mail.html

Сам сайт на который выложена софтина не в юникоде, а в cp1251.








 ,








И это всё МОЁ

Всем привет!

На компе стоит Manjaro KDE x64, за компом работают несколько пользователей. Также к компу подключена web'ка, которая мониторит комнату. Видео захватывается при помощи ffmpeg примерно так:

ffmpeg -thread_queue_size 256 -f v4l2 -i /dev/video0 -f pulse -i alsa_input.usb-046d_0805_4201AA60-02.analog-mono ...

Проблема в том, что из-за PulseAudio ffmpeg нужно запускать от имени активного юзера, а при переключении, перезапускать от имени нового активного юзера, ибо крашится. Всё это вызывает жуткие головные боли. Вопросы:

1. Можно ли в пульсе привязать конкретное устройство строго к конкретному юзеру вне зависимости от активности?

2. Можно ли отвязать одно устройство от пульсы и вернуть его на ALSA?

3. Можно ли автоматизировать перезапуск ffmpeg при переключении юзеров (самый плохой вариант)?








 , , ,








И это всё МОЁ

Есть приложение, которое авторизует пользователей при помощи Active Directory, но через Nginx Ingress до него не доходят нужные заголовки. Возня с custom headers и аннотациями ни к чему не привела: браузеры продолжают запрашивать логин-пароль.

Есть аналогичный стэк в Docker Swarm с Nginx-сервером в качестве балансировщика - там прекрасно работает.

У кого реализован SSO в приложениях в Kubernetes и каким образом?








 








И это всё МОЁ

Есть проект: https://github.com/OrenKishon/stackbd
- это блочное устройство, которое перенаправляет все запросы на некоторое другое устройство, попутно добавляя информацию об этих запросах в syslog. В качестве подхода к реализации обмена данными выбрано прямое выполнение запроса без использование очереди. Если же переделать код таким образом, что бы очередь использовалась, модуль повисает в том случае, если в устройство записать больше 8 секторов за раз (с помощью dd например, при count=9). С чтением при этом проблем нет.

Есть идеи, почему так, как лечить?

#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>

#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/vmalloc.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/kthread.h>

#include <trace/events/block.h>

#include "../common/stackbd.h"

#define USE_BLKMQ 1

#if USE_BLKMQ
#include <linux/blk-mq.h>
#endif

#define LOGOUT(lvl, fmt, args...) printk(lvl "%s [task=%p] %s: " fmt, THIS_MODULE->name, current, __func__, ## args)
#define PINFO(fmt, args...) LOGOUT(KERN_INFO, fmt, ## args)
#define PWARN(fmt, args...) LOGOUT(KERN_WARNING, fmt, ## args)
#define PERROR(fmt, args...) LOGOUT(KERN_ERR, fmt, ## args)

#define STACKBD_BDEV_MODE (FMODE_READ | FMODE_WRITE | FMODE_EXCL)
#define DEBUGGG printk("stackbd: %d\n", __LINE__);
/*
* We can tweak our hardware sector size, but the kernel talks to us
* in terms of small sectors, always.
*/
#define KERNEL_SECTOR_SHIFT 9
#define KERNEL_SECTOR_SIZE (1 << KERNEL_SECTOR_SHIFT)
#define KERNEL_PAGE_SHIFT 12
#define KERNEL_PAGE_SIZE (1 << KERNEL_PAGE_SHIFT)

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
# define DECLARE_BIO_VEC struct bio_vec
# define ACCESS_BIO_VEC(x) (x)
#else
# define DECLARE_BIO_VEC struct bio_vec *
# define ACCESS_BIO_VEC(x) (*(x))
#endif

MODULE_LICENSE("Dual BSD/GPL";);

static int major_num = 0;
module_param(major_num, int, 0);
static int LOGICAL_BLOCK_SIZE = 4096;
module_param(LOGICAL_BLOCK_SIZE, int, 0);

/*
* The internal representation of our device.
*/
static struct stackbd_t {
sector_t capacity; /* Sectors */
struct gendisk *gd;
spinlock_t lock;
struct bio_list bio_list;
struct task_struct *thread;
int is_active;
struct block_device *bdev_raw;
/* Our request queue */
struct request_queue *queue;
#if USE_BLKMQ
struct blk_mq_tag_set tag_set;
#endif
} stackbd;

struct bio_private
{
void *bi_private_old;
void *data;
bool is_ready;
};

typedef struct hidden_cmd_s
{
long ret;
} hidden_cmd_t;


static DECLARE_WAIT_QUEUE_HEAD(req_event);

int ald_buffer_read(
unsigned long sector,
unsigned long nsect,
char *buffer
)
{
int result = 0;
unsigned nsize = nsect << KERNEL_SECTOR_SHIFT;
int npages = ((nsize - 1) >> KERNEL_PAGE_SHIFT) + 1;
struct bio *bio = bio_alloc(GFP_ATOMIC, npages);
struct block_device *bdev = stackbd.bdev_raw;

PINFO("begin; sector=%ld; nsect=%ld; buffer=%p\n", sector, nsect, buffer);

if(unlikely(!bio))
{
PINFO("bio_alloc failed!\n";);
result = -ENOMEM;
return result;
}
bio_set_dev(bio, bdev);
bio->bi_iter.bi_sector = sector;
bio_set_op_attrs(bio, REQ_OP_READ, 0);
{
char *ptr = buffer;
do
{
struct page *page;
page = virt_to_page(ptr);
if(unlikely(!page))
{
PINFO("virt_to_page failed!\n";);
result = -ENOMEM;
break;
}

{
unsigned this_step = min((unsigned)(PAGE_SIZE - offset_in_page(ptr)), nsize);
bio_add_page(bio, page, this_step, offset_in_page(ptr));
nsize -= this_step;
ptr += this_step;
}
} while(nsize > 0);

if(likely(!result))
{
result = submit_bio_wait(bio);
}
bio_put(bio);
}
PINFO("end (%d)\n", result);
return result;
}

int ald_buffer_write(
unsigned long sector,
unsigned long nsect,
char *buffer
)
{
int result = 0;
unsigned nsize = nsect << KERNEL_SECTOR_SHIFT;
int npages = ((nsize - 1) >> KERNEL_PAGE_SHIFT) + 1;
struct bio *bio = bio_alloc(GFP_ATOMIC, npages);
struct block_device *bdev = stackbd.bdev_raw;

PINFO("begin; sector=%ld; nsect=%ld; buffer=%p\n", sector, nsect, buffer);

if(unlikely(!bio))
{
PINFO("bio_alloc failed!\n";);
result = -ENOMEM;
return result;
}
bio_set_dev(bio, bdev);
bio->bi_iter.bi_sector = sector;
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
{
char *ptr = buffer;
do
{
struct page *page = virt_to_page(ptr);

if(unlikely(!page))
{
PINFO("alloc page failed!\n";);
result = -ENOMEM;
break;
}

{
unsigned op = offset_in_page(ptr);
unsigned this_step = min((unsigned)(KERNEL_PAGE_SIZE - op), nsize);
bio_add_page(bio, page, this_step, op);
nsize -= this_step;
ptr += this_step;
}
} while(nsize > 0);

if(likely(!result))
{
result = submit_bio_wait(bio);
}
bio_put(bio);
}
PINFO("end (%d)\n", result);
return result;
}

#if USE_BLKMQ
static void pb_alloc(struct bio *bio, void *data)
{
struct bio_private *pb = kmalloc(sizeof(struct bio_private), GFP_ATOMIC);

pb->bi_private_old = bio->bi_private;
pb->data = data;
pb->is_ready = false;
bio->bi_private = pb;
}

static void pb_free(struct bio *bio)
{
struct bio_private *pb = bio->bi_private;
void *t = bio->bi_private;
bio->bi_private = pb->bi_private_old;
kfree(t);
}
#endif

static void my_bio_complete(struct bio *bio, int ret)
{
#if USE_BLKMQ
struct bio_private *pb = bio->bi_private;
struct request *rq = pb->data;

pb_free(bio);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
blk_mq_end_request(rq, ret ? BLK_STS_IOERR : BLK_STS_OK);
#else
blk_mq_end_io(rq, ret ? BLK_STS_IOERR : BLK_STS_OK);
#endif

#else // #if USE_BLKMQ
bio_endio(bio);
#endif // #if USE_BLKMQ
}


static void stackbd_io_fn(struct bio *bio)
{
sector_t sector = bio->bi_iter.bi_sector;
int size = bio->bi_iter.bi_size;
int nsect = size >> KERNEL_SECTOR_SHIFT;
DECLARE_BIO_VEC bvec;
struct bvec_iter iter;
u8 *buffer = kmalloc(size, GFP_ATOMIC);
u8 *ptr = buffer;

if (bio_data_dir(bio) == READ)
{
ald_buffer_read(sector, nsect, ptr);

bio_for_each_segment(bvec, bio, iter)
{
u8 *dst = page_address(ACCESS_BIO_VEC(bvec).bv_page) + ACCESS_BIO_VEC(bvec).bv_offset;
int len = ACCESS_BIO_VEC(bvec).bv_len;
memcpy(dst, ptr, len);
ptr += len;
}
}
else
{
bio_for_each_segment(bvec, bio, iter)
{
u8 *src = page_address(ACCESS_BIO_VEC(bvec).bv_page) + ACCESS_BIO_VEC(bvec).bv_offset;
int len = ACCESS_BIO_VEC(bvec).bv_len;
memcpy(ptr, src, len);
ptr += len;
}
ald_buffer_write(sector, nsect, buffer);
}
kfree(buffer);
my_bio_complete(bio, 0);
}

static int stackbd_threadfn(void *data)
{
struct bio *bio;

set_user_nice(current, -20);

while (!kthread_should_stop())
{
/* wake_up() is after adding bio to list. No need for condition */
wait_event_interruptible(req_event, kthread_should_stop() ||
!bio_list_empty(&stackbd.bio_list));

spin_lock_irq(&stackbd.lock);
if (bio_list_empty(&stackbd.bio_list))
{
spin_unlock_irq(&stackbd.lock);
continue;
}

bio = bio_list_pop(&stackbd.bio_list);
spin_unlock_irq(&stackbd.lock);

stackbd_io_fn(bio);
}

return 0;
}

#if USE_BLKMQ
//#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 3)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
static blk_status_t hidden_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data* bd)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
static blk_status_t hidden_queue_rq(struct blk_mq_hw_ctx *hctx, struct request* rq, bool last)
#else
static blk_status_t hidden_queue_rq(struct blk_mq_hw_ctx *hctx, struct request* rq)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
struct request *rq = bd->rq;
#endif
struct bio *bio = rq->bio;
pb_alloc(bio, rq);
spin_lock_irq(&stackbd.lock);
if (!stackbd.bdev_raw)
{
printk("stackbd: Request before bdev_raw is ready, aborting\n";);
goto abort;
}
if (!stackbd.is_active)
{
printk("stackbd: Device not active yet, aborting\n";);
goto abort;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
blk_mq_start_request(rq);
#endif

bio_list_add(&stackbd.bio_list, bio);
wake_up(&req_event);
spin_unlock_irq(&stackbd.lock);

exit:
return BLK_STS_OK; //always return ok
abort:
my_bio_complete(bio, -EIO);
goto exit;
}

static struct blk_mq_ops _mq_ops =
{
.queue_rq = hidden_queue_rq,
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 2, 0)
.map_queue = blk_mq_map_queue
#endif
};
#else // #if USE_BLKMQ
/*
* Handle an I/O request.
*/
static blk_qc_t stackbd_make_request(struct request_queue *q, struct bio *bio)
{
printk("stackbd: make request %-5s block %-12lu #pages %-4hu total-size "
"%-10u\n", bio_data_dir(bio) == WRITE ? "write" : "read",
bio->bi_iter.bi_sector, bio->bi_vcnt, bio->bi_iter.bi_size);

// printk("<%p> Make request %s %s %s\n", bio,
// bio->bi_rw & REQ_SYNC ? "SYNC" : "",
// bio->bi_rw & REQ_FLUSH ? "FLUSH" : "",
// bio->bi_rw & REQ_NOIDLE ? "NOIDLE" : "";);
//
spin_lock_irq(&stackbd.lock);
if (!stackbd.bdev_raw)
{
printk("stackbd: Request before bdev_raw is ready, aborting\n";);
goto abort;
}
if (!stackbd.is_active)
{
printk("stackbd: Device not active yet, aborting\n";);
goto abort;
}
bio_list_add(&stackbd.bio_list, bio);
wake_up(&req_event);
spin_unlock_irq(&stackbd.lock);

goto exit;

abort:
spin_unlock_irq(&stackbd.lock);
printk("<%p> Abort request\n\n", bio);
bio_io_error(bio);
exit:
return BLK_QC_T_NONE;
}
#endif // #if USE_BLKMQ

static struct block_device *stackbd_bdev_open(char dev_path[])
{
/* Open underlying device */
struct block_device *bdev_raw = lookup_bdev(dev_path);
printk("Opened %s\n", dev_path);

if (IS_ERR(bdev_raw))
{
printk("stackbd: error opening raw device <%lu>\n", PTR_ERR(bdev_raw));
return NULL;
}

if (!bdget(bdev_raw->bd_dev))
{
printk("stackbd: error bdget()\n";);
return NULL;
}

if (blkdev_get(bdev_raw, STACKBD_BDEV_MODE, &stackbd))
{
printk("stackbd: error blkdev_get()\n";);
bdput(bdev_raw);
return NULL;
}

return bdev_raw;
}

static int stackbd_start(char dev_path[])
{
unsigned max_sectors;

if (!(stackbd.bdev_raw = stackbd_bdev_open(dev_path)))
return -EFAULT;

/* Set up our internal device */
stackbd.capacity = get_capacity(stackbd.bdev_raw->bd_disk);
printk("stackbd: Device real capacity: %lu\n", stackbd.capacity);

set_capacity(stackbd.gd, stackbd.capacity);

max_sectors = queue_max_hw_sectors(bdev_get_queue(stackbd.bdev_raw));
blk_queue_max_hw_sectors(stackbd.queue, max_sectors);
printk("stackbd: Max sectors: %u\n", max_sectors);

stackbd.thread = kthread_create(stackbd_threadfn, NULL,
stackbd.gd->disk_name);
if (IS_ERR(stackbd.thread))
{
printk("stackbd: error kthread_create <%lu>\n",
PTR_ERR(stackbd.thread));
goto error_after_bdev;
}

printk("stackbd: done initializing successfully\n";);
stackbd.is_active = 1;
wake_up_process(stackbd.thread);

return 0;

error_after_bdev:
blkdev_put(stackbd.bdev_raw, STACKBD_BDEV_MODE);
bdput(stackbd.bdev_raw);

return -EFAULT;
}

static int stackbd_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
char dev_path[80];
void __user *argp = (void __user *)arg;

switch (cmd)
{
case STACKBD_DO_IT:
printk("\n*** DO IT!!!!!!! ***\n\n";);

if (copy_from_user(dev_path, argp, sizeof(dev_path)))
return -EFAULT;

return stackbd_start(dev_path);
default:
return -ENOTTY;
}
}

/*
* The HDIO_GETGEO ioctl is handled in blkdev_ioctl(), which
* calls this. We need to implement getgeo, since we can't
* use tools such as fdisk to partition the drive otherwise.
*/
int stackbd_getgeo(struct block_device * block_device, struct hd_geometry * geo)
{
long size;

/* We have no real geometry, of course, so make something up. */
size = stackbd.capacity * (LOGICAL_BLOCK_SIZE / KERNEL_SECTOR_SIZE);
geo->cylinders = (size & ~0x3f) >> 6;
geo->heads = 4;
geo->sectors = 16;
geo->start = 0;
return 0;
}

/*
* The device operations structure.
*/
static struct block_device_operations stackbd_ops = {
.owner = THIS_MODULE,
.getgeo = stackbd_getgeo,
.ioctl = stackbd_ioctl,
};

static int __init stackbd_init(void)
{
/* Set up our internal device */
spin_lock_init(&stackbd.lock);

/* blk_alloc_queue() instead of blk_init_queue() so it won't set up the
* queue for requests.
*/
#if USE_BLKMQ
stackbd.tag_set.ops = &_mq_ops;
stackbd.tag_set.nr_hw_queues = 1;
stackbd.tag_set.queue_depth = 128;
stackbd.tag_set.numa_node = NUMA_NO_NODE;
stackbd.tag_set.cmd_size = sizeof(hidden_cmd_t);
stackbd.tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE | BLK_MQ_F_BLOCKING;
stackbd.tag_set.driver_data = &stackbd;

{
int res = blk_mq_alloc_tag_set(&stackbd.tag_set);
if (res)
{
PWARN("unable to allocate tag set (%d)\n", res);
return -EFAULT;
}
}
stackbd.queue = blk_mq_init_queue(&stackbd.tag_set);
if (IS_ERR(stackbd.queue))
{
int res = PTR_ERR(stackbd.queue);
PWARN("Failed to allocate queue (%d)", res);
return -EFAULT;
}
#else
if (!(stackbd.queue = blk_alloc_queue(GFP_KERNEL)))
{
printk("stackbd: alloc_queue failed\n";);
return -EFAULT;
}

blk_queue_make_request(stackbd.queue, stackbd_make_request);
#endif
blk_queue_logical_block_size(stackbd.queue, LOGICAL_BLOCK_SIZE);

/* Get registered */
if ((major_num = register_blkdev(major_num, STACKBD_NAME)) < 0)
{
printk("stackbd: unable to get major number\n";);
goto error_after_alloc_queue;
}

/* Gendisk structure */
if (!(stackbd.gd = alloc_disk(16)))
goto error_after_redister_blkdev;
stackbd.gd->major = major_num;
stackbd.gd->first_minor = 0;
stackbd.gd->fops = &stackbd_ops;
stackbd.gd->private_data = &stackbd;
strcpy(stackbd.gd->disk_name, STACKBD_NAME_0);
stackbd.gd->queue = stackbd.queue;
add_disk(stackbd.gd);

printk("stackbd: init done\n";);

return 0;

error_after_redister_blkdev:
unregister_blkdev(major_num, STACKBD_NAME);
error_after_alloc_queue:
blk_cleanup_queue(stackbd.queue);

return -EFAULT;
}

static void __exit stackbd_exit(void)
{
printk("stackbd: exit\n";);

if (stackbd.is_active)
{
kthread_stop(stackbd.thread);
blkdev_put(stackbd.bdev_raw, STACKBD_BDEV_MODE);
bdput(stackbd. bdev_raw);
}

del_gendisk(stackbd.gd);
put_disk(stackbd.gd);
unregister_blkdev(major_num, STACKBD_NAME);
blk_cleanup_queue(stackbd.queue);
#if USE_BLKMQ
if (stackbd.tag_set.tags)
blk_mq_free_tag_set(&stackbd.tag_set);
#endif
}

module_init(stackbd_init);
module_exit(stackbd_exit);








 , , , ,








И это всё МОЁ

Привет.

CentOS 6.

После обновления gs (ghostscript) в системе оказались две версии этого тула:

[maxegorov@aibk ~]$ gs
GPL Ghostscript 9.27 (2019-04-04)

[maxegorov@aibk ~]$ sudo gs
GPL Ghostscript 8.70 (2009-07-31)

Мне более всего важно, чтобы apache запускал версию 9.27. Что за хрень? Как это исправить?

Спасибо.








 , ,








И это всё МОЁ

На выходных выпил пивка и занялся некрофилией: откопал lcc и собрал его современным gcc, восьмым правда, девяткой пока не осилил.

Вы спросите, зачем? Да он мне нужен как retargetable сишный компилятор для пары задач, где llvm - оверкилл.

Вот потихоньку ковыряю кишки. Лицензия, конечно, говно, но что поделать...

saahriktu, не только ты можешь в некрофилию!








 , , ,








И это всё МОЁ

Здравствуйте, коллеги! Ситуация простая и в тоже время сложная. HP Proliant dl360e Gen8. ESXI 5.5 был установлен на SD карту и работал несколько лет. После некорректного выключения, при следующей загрузке начал ругаться на /sb.v00 и перестал загружаться. Местные ребята взяли новую флешку и установили ESXI заново через Intelligent Provisioning в режиме «Рекомендуется». Итог: ESXI установился на RAID, который являлся хранилищем ВМ в рабочей системе.
Вопрос: возможно ли восстановление хранилища/раздела/файлов после такого пируэта или это конец.
Разумеется, на любые вопросы/комментарии готов ответить, т.к. приехал из другого города и нахожусь в одной комнате с сервером.
Спасибо.








 








И это всё МОЁ

Суть происходящего https://imgur.com/a/wZNEccd
Пожалуйста, помогите, что делать? Стоит арч








 








И это всё МОЁ

Всем привет!

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

  1. 4 ядерного ЦП.
  2. Желательно не меньше 8гб ОЗУ.
  3. Хотелось бы 1тб NVMe SSD.
  4. Видеокарта особо не нужна, но если будет затычка то тоже не плохо.
  5. 15" FullHD матовый.
  6. Клава с подсветкой желательно, но не обязательно.


Бюджет около 50 000 руб, НО!

Как я это себе представляю. Купить за бюджет ноут с 4 ядрами, hdd, 2-4Gb, FullHD и т.д. И купить отдельно (в указанный бюджет не входит) оперативы, SSD и заменить дефолтные. Понятное дело, что параметры можно вбить в какой-нибудь Яндекс.Маркет и подобрать машинку, но хотелось бы корпус по крепче, экран по лучше и совместимость с Linux. Уот такие пироги.








 ,