Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: sandman_7920 в Jan 22, 2009, 14:40



Титла: C and PROCFS
Публикувано от: sandman_7920 в Jan 22, 2009, 14:40
Здравейте имам следният въпрос.

Искам да направя програма която да ползва procfs като конфигурационен файл.
За пример искам да направя експорт на структура от C-то в /proc/primer/config:

struct sMyStruct{
   int userscount,access;
}myStruct;

myStruct.usercount=0;
myStruct.access=0;

и тук export_to("/proc/primer/config",myStruct);

и след това да имам достъп с 'cat|echo' да кажем:

echo usercount=20>/proc/primer/config

cat /proc/primer/config
usercount=20
access=0


Това как може да стане.


Титла: Re: C and PROCFS
Публикувано от: task_struct в Jan 22, 2009, 15:25
Procfs е псевдо файлова система, която се генерира при стартиране на системата. Тя е част от ядрото и само то има достъп до нея. Мисля, че единственият начин да създаваш файл там е да си направиш модул за ядрото. Всеки модул може да се регистрира в ProcFS и да си създава директории и файлове.


Титла: Re: C and PROCFS
Публикувано от: sandman_7920 в Jan 22, 2009, 15:31
Благодаря и Аз бях стигнал до същото заключение, но бях длъжен да питам :):):).


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 18:17
Все пак можеш да представиш конфигурацията си като файлове, само дето няма да е в procfs. Може да използваш fuse или 9p за да направиш приложението ти да изглежда като файлова система.

Преди време тук бях пускал кратка програмка, на която даваш директория с mp3-та и тя създава нова файлова система, в която mp3-ките са сортирани по артисти и албуми.


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 18:32
Да ме извинявате, ама има мноооого по-прост начин да се постигне същото, без да се използва procfs и без да се създава userspace-базирана fs.

man mkfifo.

Просто си създаваш една директория, вътре си създаваш поддиректории и named pipes. Демонът си ги чете. Който иска, пише в тях. Обратното - демонът може да пише в тях и някой да ги чете.


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 18:33
gateway,

Не е същото. Помисли и ще се сетиш защо.


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 18:38
Може да се докара до същото спокойно според мен.

Може ли да се пише там с echo -> да.
Може ли да се чете оттам с cat -> да.
Може ли да се използват позволенията на файловата система -> да.
Могат ли да се "заключват" файлове -> да


Титла: Re: C and PROCFS
Публикувано от: sandman_7920 в Jan 22, 2009, 18:44
Да но при fifo когато един прави read докато няма събитие write той виси( first in first out)
mkfifo new.fifo
cat new.fifo = виси докато няма echo alabala>new.fifo


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 18:50
Това по какъв начин ти пречи?

В смисъл ако мислиш, че четенето от procfs не е блокираща операция и не се чака от ядрото да се подаде нещо, се лъжеш.


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 19:00
Не знаеш кога файл е отворен.
Не можеш да пишеш на произволно място във файла.
От двете следва, че не можеш да има двама четци, които да прочетат същата информация едновременно.
Ако някой изтрие fifo-то, по никакъв начин програмата не разбира за това.
Съществуването на файловете не означава, че от другата страна има някой да върши работата.

И още много други...


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 19:11
Цитат
Не знаеш кога файл е отворен.

Не те и трябва, трябва ти да знаеш дали се пише или чете. Можеш да си направиш fd set от тези named pipes и да си ги обработваш с цикъл от select()-и. Мааму стара, предполагам даже и epoll механизми могат да се ползват ако желаеш.

Цитат
Не можеш да пишеш на произволно място във файла.

Не знам за начин да можеш да го правиш и с procfs.

Цитат
От двете следва, че не можеш да има двама четци, които да прочетат същата информация едновременно.

Добре де, а трябва ли? Според мен трябва да се гони друго - да се подсигуриш срещу това два процеса да четат едновременно.

Цитат
Съществуването на файловете не означава, че от другата страна има някой да върши работата.

Това е много вярно, за жалост.


Обаче айде да погледнем от друга страна на нещата - по-лесно ли ще е да пишеш модул за ядрото, който ти създава procfs entries и чете/пише от тях? А кой може да ти гарантира, че ще можеш да си ползваш файловата система? В смисъл най-малкото ще трябва да си стартираш програмата с superuser-ски привилегии и ядрото да подържа fuse. Не знам де, на мене този вариант не ми допада много.


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 19:21
> Не те и трябва, трябва ти да знаеш дали се пише или чете. Можеш да си направиш fd set от тези
> named pipes и да си ги обработваш с цикъл от select()-и. Мааму стара, предполагам даже и epoll
> механизми могат да се ползват ако желаеш.

Напротив, трябва ти, или по-точно може да ти трябва. Например за да можеш да представяш консистентно (не се сещам българската дума) състояние на клиентите. Представи си, че състоянието е голямо и трябва да се прочете на два пъти, но през това време някакво вътрешно събитие го променя. Двете четения ще доведат до inconsistency. Не е задължително четенето или писането да стане с една атомарна операция.

> Не знам за начин да можеш да го правиш и с procfs.

Ами write функцията на procfs получава offset. И всички имплементации, които съм гледал го използват.

> Добре де, а трябва ли? Според мен трябва да се гони друго - да се подсигуриш срещу това два
> процеса да четат едновременно.

И защо да не трябва? Защо предполагаш, че ще има само един клиент?

> Обаче айде да погледнем от друга страна на нещата - по-лесно ли ще е да пишеш модул за
> ядрото, който ти създава procfs entries и чете/пише от тях?

Не съм казал, че е по-лесно. Но използването на fuse или 9p е наистина лесно. За fuse само предполагам, не съм го използвал. Но за 9p съм писал десетки файлови системи.



Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 19:31
Да добавя още едно против, за което се сетих: fifo-тата са локални и не могат да се екпортират по мрежата.


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 19:37
Хм, верно че имало offset. Аз това винаги съм го игнорирал, бля.

ОК, съгласен съм :)

Иначе:

Цитат
Напротив, трябва ти, или по-точно може да ти трябва. Например за да можеш да представяш консистентно (не се сещам българската дума) състояние на клиентите. Представи си, че състоянието е голямо и трябва да се прочете на два пъти, но през това време някакво вътрешно събитие го променя. Двете четения ще доведат до inconsistency. Не е задължително четенето или писането да стане с една атомарна операция.

Абе това е някаква конфигурация. Според мен нито ще се пише много и често, нито ще се чете. В случаят с procfs така или иначе става тарапана, когато четеш/пишеш повече от PAGE_SIZE и там това пак ще възникне като проблем. При положение че има много писане/четене (и като обем и като честота), няма да си спестиш вероятни грозни странични случаи.

От друга страна, това ще е още по-опасно в kernelspace.



Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 19:40
Разликата е, че 9p или fuse ти позволяват да оправиш страничните случаи, а при fifo-то нямаш никакъв избор освен да се молиш да не се случи нещо такова. А пък колко е "лесно" се диагностицират подобни проблеми...


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 19:51
С това съм съгласен, но от друга страна не ти е гарантирано, че можеш да ги ползваш. Иначе ако държиш да ползваш *кхъм* странни начини за задаване на конфигурация сега ми хрумна друг вариант - що по дяволите не си отвориш един tcp сокет и не си ги четеш/пишеш с nc :) Ето - проблемите с граничните случаи ти се разрешават, от друга страна си е доста portable решение. Пък и дали е nc host/echo shit|nc host или cat/echo няма толкова значение. Така апропо ще отпадне ограничението за мрежата. Въобще живо чудо :)


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 20:46
socket-а е транспорт, а не интерфейс.


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 21:12
Обаче върши работа :)

Дори автентикация и криптиране може да се направят.


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 21:16
И какво, ще чакаш двадесет сокета? А как ще познаеш до какви сокети имаш достъп (нещо като ls)? И аутентикацията и криптирането са properties (днес нещо не ми идват думите на български, извинявам се) на транспорта.

Днес ми се струва, че пишеш без да мислиш :)


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 21:25
Във вашия plan9 как разбирате кой клиентски сокет има право да се връзва от отдалечена машина?


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 21:27
Ако разбирам въпроса ти правилно, за такива неща няма стандартна конвенция.


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 21:31
Добре де, ако решите все пак по някакъв принцип да приемате заявки само от определен процес на определен хост, как го решавате тоя проблем? Без значение дали има определени стандарти за това. Не се заяждам, просто ми е интересна философията.


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 21:34
Всеки клиент трябва да докаже, че е този за който се представя. Ако може да го докаже, какво значение има от кой хост го прави? Защо трябва сървъра да се тревожи от такива маловажни неща като наличието на мрежа или топологията й?


Титла: Re: C and PROCFS
Публикувано от: gat3way в Jan 22, 2009, 21:40
А как го доказва?

Предполагам има някакъв механизъм за авторизация там...в смисъл дали има някакъв механизъм, по който хостовете си обменят информация за процесите вървящи там по някакъв отделен data channel и някакъв план9-ски протокол, или авторизацията става в рамките на връзката, осъществена между клиента и сървъра.


Титла: Re: C and PROCFS
Публикувано от: sandman_7920 в Jan 22, 2009, 21:49
Сега малко да поясна каква е точно ситуацията.
Структурата на програма изглежда долу-горе така

               |-->connect_to_tcp_server()
               |            |
               |            |-->read_to_local_buffer()
               |                      |
               |                      |-->filter()-->write_circular_buffer
               |                           |
               |                           |<-->Interface_za_config()   
               |
main()--->master_thread
       |
       |
       |--->while(1)-->listen_tcp_sock
                              |
                              |-->child_thread()
                                       |
                                       |-->read_circular_buffer_and_send
                                       
Тук просто ми трябва бърз и удобен интерфейс за конфигурация on-fly на филтрите
Имам няколко идеи за това.
1. Още един tcp_sock_listen на нов порт. Но тук се ограничаваме само до TCP
    и това не е лесно достъпен интерфейс.
2. Даже си мисля за sqlite
3. Прост файл.
4. И тук си помислих и за procfs :):):):)

Май доста се отклоних от темата C and PROCFS :(. Тя май трябваше да е
Бърз и универсален интерфейс за конфиг.

П.П. Става дума за видео обработка. Конф. интефейса ще подържа само един
потребител.
П.П.2 И да добавя някой от филтрите са адаптивни и се самопроменят и това трябва да се вижда и от интерфейса


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 22:00
Повечето неща в Plan9 са файлови системи. Има authentication сървър, който в общи линии може само да потвърди "да, този който говори с теб е същия за който се представя". Файловата система си решава дали след това да допусне клиента да си говори с нея. Никой не вярва на никой друг освен на authentication сървъра. Забавното е, че клиента и сървъра могат да се вържат към различни authentication servers и пак потвърждението да е успешно (стига информацията за потребителя в двата auth servers да е същата).


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 22:25
sandman, направи го с прост файл.


Титла: Re: C and PROCFS
Публикувано от: sandman_7920 в Jan 22, 2009, 22:28
:):):) И аз до това заключение стигнах (просто ми беше мерак за нещо по-екзотично). Благодаря на всички за отговорите.


Титла: Re: C and PROCFS
Публикувано от: tarator в Jan 22, 2009, 22:48
Ето как би изглеждало нещо подобно с npfs за 9p. Трябва да извикаш fsstart с директорията, където искаш да бъде монтирано дървото. Предполагам, че с fuse ще е дори и по-лесно и кратко.

Трябва да промениш confread и confwrite да правят каквото искаш. Ако искаш повече файлове, дефинирай операции за тях и ги добави в fsstart. Ако искаш да поддържаш повече от един потребител ще трябва да дефинираш повече операции.

П.П. Не гарантирам, че кода ще работи, надрасках го набързо и ме мързи да го тествам. :)

Код:
#define _XOPEN_SOURCE 600
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#include <assert.h>
#include "npfs.h"

static Npfile* dirfirst(Npfile *);
static Npfile* dirnext(Npfile *, Npfile *);
static int confread(Npfilefid *, u64, u32, u8*, Npreq *);
static int confwrite(Npfilefid *, u64, u32, u8*, Npreq *);
static int confwstat(Npfile *, Npstat *);
static void connclose(Npconn *);

static Npsrv *srv;
static Npfile *root;
static Npfile *conf;

static Npdirops rootops = {
.first = dirfirst,
.next = dirnext,
};

static Npfileops confops = {
.read = confread,
.write = confwrite,
.wstat = confwstat,
};

static int
fsstart(char *mntpt) {
Npuser *user;
char *opts, *s;

user = np_unix_users->uid2user(np_unix_users, geteuid());
root = npfile_alloc(NULL, strdup(""), 0755|Dmdir, 0, &rootops, NULL);
root->parent = root;
npfile_incref(root);
root->atime = time(NULL);
root->mtime = root->atime;
root->uid = user;
root->gid = user->dfltgroup;
root->muid = user;

conf = npfile_alloc(root, strdup("conf"), 0644, 1, &confops, NULL);
npfile_incref(conf);
root->dirfirst = conf;
root->dirlast = conf;

srv = np_pipesrv_create(1);
if (!srv)
return -1;

npfile_init_srv(srv, root);
np_pipesrv_mount(srv, mntpt, user->uname, 0, NULL);

return 0;
}

static Npfile*
dirfirst(Npfile *dir)
{
if (dir->dirfirst)
npfile_incref(dir->dirfirst);

return dir->dirfirst;
}

static Npfile*
dirnext(Npfile *dir, Npfile *prevchild)
{
if (prevchild->next)
npfile_incref(prevchild->next);

return prevchild->next;
}

static int
confread(Npfilefid* file, u64 offset, u32 count, u8* data, Npreq *req)
{
char buf[128];

/* print your configuration here */
snprintf(buf, sizeof(buf), "tarator");
len = strlen(buf);
if (offset > len)
return 0;

if (offset+count > len)
count = len - offset;

memmove(data, buf+offset, count)
return count;
}

static int
confwrite(Npfilefid* file, u64 offset, u32 count, u8* data, Npreq *req)
{
/* the content is in data */
return 0;
}

static int
confwstat(Npfile* file, Npstat* stat)
{
return 1;
}



Титла: Re: C and PROCFS
Публикувано от: go_fire в Jan 25, 2009, 02:55
Напълно извън темата.
----------------------------------------------------


Най-после доживях и Таратора да помогне на някой. Последните три дни следя темата с голям интерес, въпреки че не вдявам нищо от приказките ви с Гейта. Така много, много повече ми харесваш. А и в темата на Тую за man/info си конструктивен, което направо не е за вярване.

Продължавай в същия дух и ще ти стана голям фен! А като се прибереш ще те чакат бири  [_]3