This is an old revision of the document!


Curs 02 - Sistemul de fișiere

  • Suport curs
    • Operating System Concepts Essentials
      • Capitolul 9 - File-System Interface
      • Capitolul 10, Secțiunea 10.1 - File-System Structure
    • Modern Operating Systems
      • Capitolul 6 - File System Implementation (secțiunile 1 și 2)
    • Linux System Programming
      • Capitolul 2 (programatic)
    • Windows System Programming
      • Capitolul 2 (programatic)

Demo-uri

Pentru parcurgerea demo-urilor, folosim arhiva aferentă. Demo-urile rulează pe Linux. Descărcăm arhiva folosind comanda

user@host:~$ wget http://elf.cs.pub.ro/so/res/cursuri/curs-02-demo.zip

și apoi decomprimăm arhiva

user@host:~$ unzip curs-02-demo.zip

și accesăm directorul rezultat în urma decomprimării

user@host:~$ cd curs-02-demo/

Acum putem parcurge secțiunile cu demo-uri de mai jos.

Tabela de descriptori de fișier a unui proces

Pentru a afișa tabela de descriptor de fișier a procesului shell current (PID-ul său este reținut în construcția $$), folosim comanda

user@host:~$ lsof -a -d 0-1023 -p $$

Ce referă descriptorii 0, 1, 2?

Răspuns

Răspuns

Descriptorii 0, 1 și 2 reprezintă, respectiv, intrarea standard (standard input, stdin), ieșirea standard (standard output, stdout) și ieșirea de eroare standard (standard error, stderr). Toți cei trei descriptori referă, de obicei, un dispozitiv de tip terminal (de forma /dev/pts/0); adică atunci când se citesc sau se scriu informații de la/către descriptori, acestea sunt preluate de la terminal

De ce (pe unele sisteme) descriptorul 0 este marcat 0r (adică read-only)?

Răspuns

Răspuns

Descriptorul 0 referă intrarea standard (standard input). Întrucât de la intrarea standard doar se citesc informații, are sens să fie deschis doar pentru citire (adică read-only).

Descriptori de fișier pentru procesele daemon

Vrem să investigăm descriptorii de fișiere pentru procesele daemon din sistem. Pentru început vrem să aflăm procesele daemon din sistem; procesele daemon au ca proces părinte procesul init (procesul cu PID-ul 1) și vom folosi comanda de mai jos pentru a le afla:

user@host:~$ ps --ppid 1

Pentru unul dintre procesele daemon descoperite prin rularea comenzii anterioare , afișam tabela de descriptori (e nevoie de drept de root) folosind comanda lsof:

root@host:~# sudo lsof -a -d 0-1023 -p $PID

Mai sus, construcția $PID referă PID-ul procesului daemon inspectat.

Ce referă descriptorii 0, 1, 2? De ce?

Răspuns

Răspuns

Descriptorii 0, 1, 2, aferenți intrării, ieșirii și ieșirii de eroare standar, referă /dev/null.

Un proces daemon nu este atașat nici unui terminal. Nu există mod prin care utilizatorul poate comunica direct cu acesta prin intermediul intrării sau ieșirii standard, motiv pentru care acestea referă /dev/null, “gaura neagră” a sistemului.

Ce alți descriptori sunt folosiți? Ce referă acești descriptori?

Raspuns

Raspuns

Sunt folosiți în continuare alți descriptori: 4, 5, 6 etc. Descriptorii proceselor daemon vor referi fișiere de jurnalizare (log files), sockeți Unix sau sockeți de rețea sau fișiere deschise pentru a fi prelucrate. Utilizatorul va comunica cu daemonii prin semnale, fișiere de configurare, sockeți și fișiere de jurnalizare.

Descriptorii de fișier după redirectare

Vrem să vedem cum se modifică descriptorii de fișier în cazul redicterării. Pentru a putea vedea acest lucru vom rula o comandă de durată (sleep) și vom redirecta intrarea și ieșirea standard:

user@host:~$ sleep 100 < /etc/passwd > f.txt

Pentru a investiga procesul sleep proaspăt porni, trebuie să știm PID-ul său. Deschidem o altă consolă și aflăm PID-ul procesului sleep creat folosind comanda:

user@host:~$ pidof sleep

Vom folosi onstrucția $PID referă PID-ul procesului sleep pe care-l investigăm. Ca și până acum, afișam tabela de descriptori de fișier a procesului folosind comanda:

user@host:~$ lsof -a -o -d 0-1023 -p $PID

Ce referă acum descriptorul 0, respectiv 1?

Răspuns

Răspuns

În urma redirectării intrării standard cu operatorul <, descriptorul 0 referă acum fișierul /etc/passwd. La fel, în urma redirectării ieșirii standard cu operatorul >, descriptorul 1 referă acum fișierul f.txt.

Modificarea cursorului de fișier

Vrem să urmărim modificarea cursorului de fișier (numit și file pointer sau file offset). Pentru aceasta vom folosi un program C în care, la cererea utilizatorului folosim apeluri care alterează cursorul de fișier: write și lseek,

Pentru început intrăm în directorul c-file-ops/ din directorul cu demo-uri și urmărim fișierul c-file-ops.c. Observăm că în program se deschide fișierul f.txt și apoi se scrie (folosind write) și se parcurge fișierul (folosind lseek). Fiecare operație este precedată de apăsarea tastei ENTER din parte utilizatorului. Compilăm programul folosind comanda

user@host:~$ make

și obținem executabilul c-file-ops. Rulăm executabilul c-file-ops:

user@host:~$ ./c-file-ops

Pentru a urmări evoluția tabelei de descriptori și a cursorului de fișier, vom folosi comanda lsof. Într-o altă consolă rulăm comanda

user@host:~$ lsof -a -o -d 0-1023 -p $(pidof c-file-ops)

Pentru început sunt afișați doar descriptorii standard.

Pentru a urmări evoluția tabelei de descriptori de fișier și a cursorului de fișier, vom folosi ENTER în consola în care am rulat executabilul c-file-ops. Vom urmări evoluția programului în consola în care am rulat lsof.

Coloana OFFSET indică poziția cursorului de fișier.

Inițial cursorul de fișier are valoarea 0 întrucât a fost proaspăt deschis și trunchiat. La apăsarea tastei ENTER în prima consolă, care indică programul să facă o nouă acțiune, observăm modificarea cursorului de fișier în a doua consolă.

Parcurgem întreg programul pentru a urmări evoluția completă a cursorului de fișier.

La finalul rulării programului urmărim dimensiunea fișierului f.txt:

user@host:~$ stat -c "%s" f.txt
256

Observăm că fișierul are dimensiunea de 256 octeți, atât cât a primit ca argument apelul ftruncate.

Ce efect are apelul ftruncate asupra cursorului de fișier?

Răspuns

Răspuns

Apelul ftruncate modifică modifică dimensiunea fișierului. Un fișier are un câmp de dimensiune alterat de comanda ftruncate. Acest câmp este diferit de cursorul de fișier. Teoretic cursorul de fișier poate fi plasat dincolo de sfârșitul fișierului. Din acest motiv, apelul ftruncate nu are nici un efect asupra cursorului de fișier.

Acest lucru este precizat și în secțiunea DESCRIPTION a paginii de manual a apelului ftrunctate.

Modificarea cursorului de fișier (Python)

  1. Intrați în directorul py-file-ops/ din arhiva cu demo-uri a cursului.
    • Parcurgeți fișierul py-file-ops.py.
    • Rulați programul folosind comanda:
      python py-file-ops.py
    • Într-o altă consolă, pentru a urmări evoluția tabelei de descriptori și a cursorului de fișier, rulați comenzile:
      ps -ef | grep py-file-ops
      lsof -a -o -d 0-1023 -p $PID
      • $PID este process ID-ul obținut la prima comandă.
    • Folosiți ENTER în consola în care ați rulat programul py-file-ops și urmăriți evoluția programului în consola în care ați rulat lsof.
      • Coloana OFFSET indică file pointer-ul (cursorul de fișier, file offset).
    • De ce nu există tot timpul o corespondență între operațiile Python și modificarea file pointer-ului?
    • Ce se întâmplă dacă nu se apelează f.flush() (după ciclul de scriere cu f.write())?

Buffered I/O vs. System-Level I/O

  1. Intrați în directorul buffered-system-io/ din arhiva cu demo-uri a cursului.
    • Parcurgeți fișierele buffered.c și system.c.
    • Compilați cele două programe folosind comanda:
      make
    • Într-o consolă rulați programul buffered:
      ./buffered
      • Rapid, într-o altă consolă, urmăriți apelurile de bibliotecă realizate de program, folosind comanda:
        ltrace -e putchar,fputc -p $(pidof buffered)
      • După încheiere, rulați din nou programul și, într-o altă consolă, urmăriți apelurile de sistem realizate de program, folosind comanda:
        strace -e write -p $(pidof buffered)
      • Ce observați? Care este numărul de apeluri de bibliotecă și de apeluri de sistem realizate?
    • Într-o consolă rulați programul system:
      ./system
      • Rapid, într-o altă consolă, urmăriți apelurile de bibliotecă realizate de program, folosind comanda:
        ltrace -e write -p $(pidof system)
      • După încheiere, rulați din nou programul și, într-o altă consolă, urmăriți apelurile de sistem realizate de program, folosind comanda:
        strace -e write -p $(pidof system)
      • Ce observați? Care este numărul de apeluri de bibliotecă și de apeluri de sistem realizate?

Apelul dup și cursorul de fișier

  1. Intrați în directorul open-dup/ din arhiva cu demo-uri a cursului.
    • Parcurgeți fișierele open.c și dup.c.
    • Compilați programele folosind comanda
      make
      • Veți obține executabilele open și dup.
    • Rulați executabilul open:
      ./open
    • Într-o altă consolă, pentru a urmări evoluția tabelei de descriptori și a cursorului de fișier, rulați comanda:
      watch -d lsof -a -o -d 0-1023 -p $(pidof open)
    • Folosiți ENTER în consola în care ați rulat executabilul open și urmăriți evoluția programului în consola în care ați rulat lsof.
      • Coloana OFFSET indică file pointer-ul (cursorul de fișier, file offset).
    • Urmați aceeași pași pentru executabilul dup.
    • Ce diferențe apar?
so/cursuri/curs-02.1392978597.txt.gz · Last modified: 2014/02/21 12:29 by razvan.deaconescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0