|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Konstantin Tokar 2:5020/400 15 Jul 2003 23:18:28 To : Andrey Sapozhnikov Subject : Re: Как писать в raw device ? --------------------------------------------------------------------------------
Понятно, спасибо. Тогда вопрос следующий - как побороть кэширование при
записи и будет ли оно? Проблема в том, что возможны частые перезагрузки
и выключения компьютера непредсказуемы, а запись идёт постоянно
(телеметрия).
Andrey Sapozhnikov wrote:
> Konstantin Tokar wrote:
>
>> Привет всем неотдыхающим!
>>
>> Как писать/читать в raw device, например /dev/sda1 , из программы на
>> перле? Желательно с указанием номера сектора.
>
>
> Да точно так же как и на C. Аллокируем буфер равный (N+1)*Nsize-1,
> где N - максимальное количество секторов которое хотим записывать
> или считывать за одну операцию, а Nsize - длина сектора в байтах.
>
> C:
>
> #define MAX_SECTORS 8
> #define SECTORSIZE 512
> unsigned char *buffer = malloc((MAX_SECTORS + 1) * SECTORSIZE - 1);
>
> Perl:
>
> use constant MAX_SECTORS => 8;
> use constant SECTORSIZE => 512;
> my $buffer = '\0' x ((MAX_SECTORS + 1) * SECTORSIZE - 1);
>
> Далее надо найти ближайшую к началу позицию в буфере
> адрес которой кратен длине сектора.
>
> C:
>
> int offset = ((unsigned long)buffer % SECTORSIZE) ?
> SECTORSIZE - ((unsigned long)buffer % SECTORSIZE) : 0;
>
> Perl:
>
> use Devel::Peek;
> my $out;
> open(SAVEERR, '>&2') or die "Cannot save stderr: $!";
> close STDERR;
> open(STDERR, '>', \$out);
> Dump($buffer);
> my $pv_address = hex($1) if $out =~ / PV = 0x([\da-f]+) /;
> close STDERR;
> open(STDERR, '>&SAVEERR') or die "Cannot restore stderr: $!";
> close(SAVEERR);
> my $offset = ($pv_address % SECTORSIZE) ?
> SECTORSIZE - ($pv_address % SECTORSIZE) : 0;
>
>
> после чего читаем или пишем используя выровненую часть буффера:
>
> C:
>
> lseek(rawfd, SECTORSIZE * startsector, SEEK_SET);
> read(rawfd, buffer + offset, SECTORSIZE * nsectors);
>
> Perl:
>
> sysseek(RAWFD, SECTORSIZE * $startsector, SEEK_SET);
> sysread(RAWFD, $buffer, SECTORSIZE * $nsectors, $offset);
>
>
--- ifmail v.2.15dev5
* Origin: MTU-Intel ISP (2:5020/400)
Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/280512b3d911.html, оценка из 5, голосов 10
|