Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so:laboratoare:laborator-12 [2019/05/28 15:17]
razvan.nitu1305 [Exercițiul 7]
so:laboratoare:laborator-12 [2020/05/18 13:46] (current)
ioana_elena.ciornei [Exercițiul 4]
Line 30: Line 30:
   * [[#​dirname_si_basename|dirname și basename]]   * [[#​dirname_si_basename|dirname și basename]]
  
 +===== Înainte de laborator: Feedback =====
 +
 +Pentru a îmbunătăți cursul de SO, componentele sale și modul de desfășurare,​ ne sunt foarte utile opiniile voastre. Pentru aceasta, vă rugăm să accesați și completați formularul de feedback de pe site-ul acs.curs.pub.ro. Trebuie să fiți autentificați și înrolați în cadrul cursului.
 +
 +Formularul este anonim și este activ în perioada 11 mai 2020 - 22 mai 2020. Rezultatele vor fi vizibile în cadrul echipei cursului doar după încheierea sesiunii. Este accesibil la link-ul “Formular feedback” a paginii principale a cursului de SO al seriei voastre pe acs.curs.pub.ro. Nu este în meta-cursul disponibil tuturor seriilor.
 +
 +Vă invităm să evaluați activitatea echipei de SO și să precizați punctele tari și punctele slabe și sugestiile voastre de îmbunătățire a disciplinei. Feedback-ul vostru ne ajută să creștem calitatea materiei în anii următori și să îmbunătățim disciplinele pe care le veți face în continuare.
 +
 +Vom publica la începutul semestrului viitor analiza feedback-ului vostru.
 +
 +Ne interesează în special:
 +
 +  * Ce nu v-a plăcut și ce credeți că nu a mers bine?
 +  * De ce nu v-a plăcut și de ce credeți că nu a mers bine?
 +  * Ce ar trebuie să facem ca lucrurile să fie plăcute și să meargă bine?
  
 ===== Device Nodes ===== ===== Device Nodes =====
  
-Nucleul gestionează fiecare device hardware sau virtual prin intermediul unui device driver. Un //device driver// este o porțiune de cod din nucleu care implementează o serie de operații corespunzătoare acțiunilor de I/E asociate cu un device hardware. Procesele din spațiul utilizator ​(userspace) interacționează cu device driver-ul prin intermediul unor fișiere speciale denumite //device nodes//. API-ul (interfața de programare) oferită de device drivere ​este fixatăși include ​următoarele operații:​ +Nucleul gestionează fiecare device hardware sau virtual prin intermediul unui device driver. Un //device driver// este o porțiune de cod din nucleu care implementează o serie de operații corespunzătoare acțiunilor de I/E (intrare/​ieşire) ​asociate cu un device hardware. Procesele din userspace (spațiul utilizator) interacționează cu device driver-ul prin intermediul unor fișiere speciale denumite //device nodes//. API-ul (interfața de programare) oferit de device drivere ​include, în general, următoarele operații:​ 
-  * ''​open'',​ ''​close''​ +  * ''​open'',​ 
-  * ''​read'',​ ''​write''​ +  * ''​close''​, 
-  * ''​ioctl''​, ''​mmap''​+  * ''​read'',​ 
 +  * ''​write''​, 
 +  * ''​ioctl''​
 + 
 +Operaţiile de mai sus sunt aplicate asupra //device node-ului// sau descriptorului de fişier asociat acelui //device node//.
  
 Unele device-uri sunt reale (mouse, tastatură, disc), altele sunt virtuale în sensul că nu au un device hardware asociat (e.g ''/​dev/​zero'',​ ''/​dev/​null''​). După modul în care se accesează datele, device-urile sunt împărțite în două categorii: Unele device-uri sunt reale (mouse, tastatură, disc), altele sunt virtuale în sensul că nu au un device hardware asociat (e.g ''/​dev/​zero'',​ ''/​dev/​null''​). După modul în care se accesează datele, device-urile sunt împărțite în două categorii:
  
   * ''​device de tip caracter'',​ datele sunt procesate octet cu octet. În această categorie se înscriu: tastatura, linia serială, mouse-ul.   * ''​device de tip caracter'',​ datele sunt procesate octet cu octet. În această categorie se înscriu: tastatura, linia serială, mouse-ul.
-  * ''​device de tip bloc'',​ datele pot fi procesate la nivel de bloc (e.g hard disk).+  * ''​device de tip bloc'',​ datele pot fi procesate la nivel de bloce.ghard disk.
 Fișierele device node se găsesc în ''/​dev''​ și au asociat un identificator format din //major ID// și //minor ID//. Fișierele device node se găsesc în ''/​dev''​ și au asociat un identificator format din //major ID// și //minor ID//.
  
Line 49: Line 68:
  
 Crearea unui device node se face folosind funcția [[http://​man7.org/​linux/​man-pages/​man2/​mknod.2.html | mknod ]] Crearea unui device node se face folosind funcția [[http://​man7.org/​linux/​man-pages/​man2/​mknod.2.html | mknod ]]
-<code c>        int mknod(const char *pathname, mode_t mode, dev_t dev);+ 
 +<code c> 
 +int mknod(const char *pathname, mode_t mode, dev_t dev);
 </​code>​ </​code>​
-În general informații despre fișiereși în particular despre device node-uri se pot afla cu funcțiile din familia [[ http://​man7.org/​linux/​man-pages/​man2/​stat.2.html |stat]].+ 
 +În generalinformații despre fișiere și în particular despre device node-uri se pot afla cu funcțiile din familia [[ http://​man7.org/​linux/​man-pages/​man2/​stat.2.html |stat]].
  
 <code c> <code c>
-       int stat(const char *path, struct stat *buf); +int stat(const char *path, struct stat *buf); 
-       ​int fstat(int fd, struct stat *buf); +int fstat(int fd, struct stat *buf); 
-       ​int lstat(const char *path, struct stat *buf);+int lstat(const char *path, struct stat *buf);
 </​code>​ </​code>​
  
Line 62: Line 84:
  
 <code c> <code c>
- +struct stat { 
-           struct stat { +    dev_t     ​st_dev; ​    /* ID of device containing file */ 
-               ​dev_t     ​st_dev; ​    /* ID of device containing file */ +    ino_t     ​st_ino; ​    /* inode number */ 
-               ​ino_t     ​st_ino; ​    /* inode number */ +    mode_t ​   st_mode; ​   /* protection */ 
-               ​mode_t ​   st_mode; ​   /* protection */ +    nlink_t ​  ​st_nlink; ​  /* number of hard links */ 
-               ​nlink_t ​  ​st_nlink; ​  /* number of hard links */ +    uid_t     ​st_uid; ​    /* user ID of owner */ 
-               ​uid_t     ​st_uid; ​    /* user ID of owner */ +    gid_t     ​st_gid; ​    /* group ID of owner */ 
-               ​gid_t     ​st_gid; ​    /* group ID of owner */ +    dev_t     ​st_rdev; ​   /* device ID (if special file) */ 
-               ​dev_t     ​st_rdev; ​   /* device ID (if special file) */ +    off_t     ​st_size; ​   /* total size, in bytes */ 
-               ​off_t     ​st_size; ​   /* total size, in bytes */ +    blksize_t st_blksize; /* blocksize for file system I/O */ 
-               ​blksize_t st_blksize; /* blocksize for file system I/O */ +    blkcnt_t ​ st_blocks; ​ /* number of 512B blocks allocated */ 
-               ​blkcnt_t ​ st_blocks; ​ /* number of 512B blocks allocated */ +    time_t ​   st_atime; ​  /* time of last access */ 
-               ​time_t ​   st_atime; ​  /* time of last access */ +    time_t ​   st_mtime; ​  /* time of last modification */ 
-               ​time_t ​   st_mtime; ​  /* time of last modification */ +    time_t ​   st_ctime; ​  /* time of last status change */ 
-               ​time_t ​   st_ctime; ​  /* time of last status change */ +};
-           ​};+
 </​code>​ </​code>​
  
Line 83: Line 104:
  
 Un //sistem de fișiere// este o colecție organizată de fișiere și directoare. Un sistem de fișiere este creat folosind comanda [[http://​linux.die.net/​man/​8/​mkfs | mkfs]]. Din punct de vedere funcțional sistemele de fișiere se pot împărți în: Un //sistem de fișiere// este o colecție organizată de fișiere și directoare. Un sistem de fișiere este creat folosind comanda [[http://​linux.die.net/​man/​8/​mkfs | mkfs]]. Din punct de vedere funcțional sistemele de fișiere se pot împărți în:
-  * sisteme de fișiere pentru disc (ext2, ext3, reiserfs, fat, ntfsetc.) +  * sisteme de fișiere pentru disc (ext2, ext3, reiserfs, fat, ntfs etc.) 
-  * sisteme de fișiere pentru rețea (nfs, smbfs, ncpetc.) +  * sisteme de fișiere pentru rețea (nfs, smbfs, ncp etc.) 
-  * sisteme de fișiere virtuale (procfs, sysfs, sockfs, pipefsetc.)+  * sisteme de fișiere virtuale (procfs, sysfs, sockfs, pipefs etc.)
  
 Tipurile de sisteme de fișiere suportate de nucleu pot fi observate în fișierul ''/​proc/​filesystems''​.  ​ Tipurile de sisteme de fișiere suportate de nucleu pot fi observate în fișierul ''/​proc/​filesystems''​.  ​
-<​code>​daniel@debian$ cat /​proc/​filesystems ​+<​code>​ 
 +daniel@debian$ cat /​proc/​filesystems ​
 nodev sysfs nodev sysfs
 nodev proc nodev proc
Line 97: Line 119:
 </​code>​ </​code>​
 Pentru a putea fi folosit un sistem de fișiere trebuie atașat (montat) în ierarhia de directoare din sistem. Acest lucru se realizează cu comanda [[http://​linux.die.net/​man/​8/​mount | mount(8)]]: Pentru a putea fi folosit un sistem de fișiere trebuie atașat (montat) în ierarhia de directoare din sistem. Acest lucru se realizează cu comanda [[http://​linux.die.net/​man/​8/​mount | mount(8)]]:
-<code bash>​mount -t type device dir </​code>​+ 
 +<code bash> 
 +mount -t type device dir 
 +</​code>​
 sau apelul [[http://​man7.org/​linux/​man-pages/​man2/​mount.2.html | mount(2)]]: sau apelul [[http://​man7.org/​linux/​man-pages/​man2/​mount.2.html | mount(2)]]:
  
-<code c>    int mount(const char *source, const char *target, +<code c> 
-                 ​const char *filesystemtype,​ unsigned long mountflags,​ +int mount(const char *source, const char *target, 
-                 ​const void *data);+          const char *filesystemtype,​ unsigned long mountflags,​ 
 +          const void *data);
 </​code>​ </​code>​
  
 Operația inversă, demontarea sistemului de fișiere din ierarhia de directoare se face cu comanda [[http://​man7.org/​linux/​man-pages/​man8/​umount.8.html | umount(8)]]:​ Operația inversă, demontarea sistemului de fișiere din ierarhia de directoare se face cu comanda [[http://​man7.org/​linux/​man-pages/​man8/​umount.8.html | umount(8)]]:​
 <code bash> <code bash>
-       umount {dir|device}...+umount {dir|device}...
 </​code>​ </​code>​
  
Line 113: Line 139:
  
 <code c> <code c>
-       int umount(const char *target);+int umount(const char *target);
 </​code>​ </​code>​
  
Line 119: Line 145:
  
 Fiecare proces are două atribute legate de directoare: Fiecare proces are două atribute legate de directoare:
-   ​* ​''​directorul rădăcina''​, determină punctul de unde căile absolute sunt interpretate. +   ​* ​//directorul rădăcina//, determină punctul de unde căile absolute sunt interpretate. 
-   ​* ​''​directorul curent''​, determină punctul de unde căile relative sunt interpretate.+   ​* ​//directorul curent//, determină punctul de unde căile relative sunt interpretate.
  
 Un director este stocat în sistemul de fișiere într-un mod similar cu un fișier obișnuit. Există două lucruri diferite: Un director este stocat în sistemul de fișiere într-un mod similar cu un fișier obișnuit. Există două lucruri diferite:
-  * tipul din structura inode este diferit. +  * tipul din structura ​//inode// este diferit. 
-  * conținutul este diferit. Un director conține un vector de nume de fișiere și inode-uri.+  * conținutul este diferit: un director conține un vector de nume de fișiere și inode-uri.
  
-===== Link-uri simbolice (soft) =====+===== Link-uri simbolice (soft links) =====
  
 Un //link simbolic// (sau soft link), este un tip special de fișier al cărui conținut reprezintă numele altui fișier. Link-urile simbolice sunt create cu comanda ''​ln -s''​ sau cu apelul [[http://​linux.die.net/​man/​2/​symlink | symlink(2)]] Un //link simbolic// (sau soft link), este un tip special de fișier al cărui conținut reprezintă numele altui fișier. Link-urile simbolice sunt create cu comanda ''​ln -s''​ sau cu apelul [[http://​linux.die.net/​man/​2/​symlink | symlink(2)]]
Line 195: Line 221:
  
 Directorul curent al unui proces poate fi determinat folosind apelul [[ http://​linux.die.net/​man/​3/​getcwd | getcwd(3)]]:​ Directorul curent al unui proces poate fi determinat folosind apelul [[ http://​linux.die.net/​man/​3/​getcwd | getcwd(3)]]:​
-<code c>  char *getcwd(char *cwdbuf, size_t size); </​code>​+<code c> 
 +char *getcwd(char *cwdbuf, size_t size); 
 +</​code>​
   * ''​cwdbuf'',​ trebuie alocat înainte de apel astfel încât să poată stoca cel puțin ''​size''​ octeți.   * ''​cwdbuf'',​ trebuie alocat înainte de apel astfel încât să poată stoca cel puțin ''​size''​ octeți.
   * după apel ''​cwdbuf''​ va conține calea absolută a directorului curent.   * după apel ''​cwdbuf''​ va conține calea absolută a directorului curent.
Line 203: Line 231:
  
 Apelul [[http://​linux.die.net/​man/​2/​chdir | chdir(2)]] schimbă directorul curent al procesului apelant către numele absolut sau relativ primit ca argument. Apelul [[http://​linux.die.net/​man/​2/​chdir | chdir(2)]] schimbă directorul curent al procesului apelant către numele absolut sau relativ primit ca argument.
-<code c> int chdir(const char *path); </​code>​+<code c> 
 +int chdir(const char *path); 
 +</​code>​
    
 ===== Schimbarea directorului rădăcina al unui proces ===== ===== Schimbarea directorului rădăcina al unui proces =====
  
 Fiecare proces are un director rădăcină reprezentând punctul de unde căile absolute sunt interpretate. În mod implicit, acesta este directorul rădăcina real al sistemului de fișiere. Un proces nou moștenește directorul rădăcină de la părintele său. Există situații (e.g pentru a ascunde o parte din sistemul de fișiere) în care este util pentru un proces să-și schimbe directorul rădăcină. Acest lucru se realizează folosind apelul [[http://​linux.die.net/​man/​2/​chroot | chroot(2)]] Fiecare proces are un director rădăcină reprezentând punctul de unde căile absolute sunt interpretate. În mod implicit, acesta este directorul rădăcina real al sistemului de fișiere. Un proces nou moștenește directorul rădăcină de la părintele său. Există situații (e.g pentru a ascunde o parte din sistemul de fișiere) în care este util pentru un proces să-și schimbe directorul rădăcină. Acest lucru se realizează folosind apelul [[http://​linux.die.net/​man/​2/​chroot | chroot(2)]]
-<code c> int chroot(const char *path); </​code>​+<code c> 
 +int chroot(const char *path); 
 +</​code>​
  
  
 ===== Rezolvarea unei căi ===== ===== Rezolvarea unei căi =====
  
-Apelul [[http://​man7.org/​linux/​man-pages/​man3/​realpath.3.html | realpath(3)]] dereferențiază link-ul simbolic primit ca argument și rezolvă toate referințele către ​'/​.'​și '/​..'​ pentru a produce un șir de caractere conținând calea absolută.+Apelul [[http://​man7.org/​linux/​man-pages/​man3/​realpath.3.html | realpath(3)]] dereferențiază link-ul simbolic primit ca argument ​în ''​path''​ **și** elimină subşirurile ''/./'', ​''/​../''​ precum şi apariţii în plus ale caracterului ''/'​' pentru a genera o cale absolută ​plasată în parametrul de ieşire ''​realpath''​.
  
-<code c>  char *realpath(const char *path, char *resolved_path);​ </​code>​+Exemplu: Dacă parametrul de intrare ''​path''​ ar fi ''/​home/​madalina/​%%/​%%/​%%/​%%/​so/​tema4/​../​../​seriale/​thewire/''​ , în urma apelului ''​realpath(path,​ resolved_path)'',​ parametrul de ieşire ''​resolved_path''​ devine ''/​home/​madalina/​seriale/​thewire/''​. Presupunem că ierarhia de directoare prezentată în exemplu există deja. 
 + 
 +<code c>  
 +char *realpath(const char *path, char *resolved_path);​ 
 +</​code>​
  
 ===== dirname și basename ===== ===== dirname și basename =====
Line 223: Line 259:
 <code c> <code c>
 char *dirname(char *path); char *dirname(char *path);
- 
 char *basename(char *path); char *basename(char *path);
 </​code>​ </​code>​
Line 248: Line 283:
 </​note>​ </​note>​
 Vă mulțumim! Vă mulțumim!
-===== Exercițiul 0 - Joc interactiv ===== 
- 
-  * Detalii desfășurare [[http://​ocw.cs.pub.ro/​courses/​so/​meta/​notare#​joc_interactiv|joc]]. 
  
 ===== Linux ===== ===== Linux =====
Line 262: Line 294:
  
 ==== Exercițiul 2 ==== ==== Exercițiul 2 ====
-Implementați comanda ''​list''​ <​device_node>,​ ce va primi ca argument un device node și va afișa pentru acesta tipul (c/b), identificatorii ''​major'',​ respectiv ''​minor''​. Folosiți funcția [[http://​man7.org/​linux/​man-pages/​man2/​stat.2.html | stat(2)]] pentru a obține o structură de tipul ''​struct stat''​ din care veți extrage tipul device-ului (''​st_mode''​) (hint: [[http://​www.gnu.org/​software/​libc/​manual/​html_node/​Testing-File-Type.html#​Testing-File-Type|S_ISCHR,​ S_ISBLK]]) apoi din câmpul ''​st_rdev''​ extrageți [[http://​man7.org/​linux/​man-pages/​man3/​makedev.3.html | major]] și [[http://​man7.org/​linux/​man-pages/​man3/​makedev.3.html |minor]]. Nu uitați să decomentați linia marcată cu // #define TODO2 //+Implementați comanda ''​list''​ <​device_node>,​ ce va primi ca argument un device node și va afișa pentru acesta tipul (c/b), identificatorii ''​major'',​ respectiv ''​minor''​. Folosiți funcția [[http://​man7.org/​linux/​man-pages/​man2/​stat.2.html | stat(2)]] pentru a obține o structură de tipul ''​struct stat''​ din care veți extrage tipul device-ului (''​st_mode''​) (hint: [[http://​www.gnu.org/​software/​libc/​manual/​html_node/​Testing-File-Type.html#​Testing-File-Type|S_ISCHR,​ S_ISBLK]]) apoi din câmpul ''​st_rdev''​ extrageți [[http://​man7.org/​linux/​man-pages/​man3/​makedev.3.html | major]] și [[http://​man7.org/​linux/​man-pages/​man3/​makedev.3.html |minor]]. Nu uitați să decomentați linia marcată cu '' ​#define TODO2 ''​
  
  
 ==== Exercițiul 3 ==== ==== Exercițiul 3 ====
  
-Creați punctul de montare ''/​mnt/​my''​. Ca root, rulați comanda:<​code bash> +Creați punctul de montare ''/​mnt/​my''​. Ca root, în terminalul bash, rulați comanda: 
-mkdir /mnt/my+<code bash> 
 +mkdir /mnt/my
 </​code>​ </​code>​
  
 Parcurgeți paginile de manual ale funcțiilor [[http://​man7.org/​linux/​man-pages/​man2/​mount.2.html|mount]] și [[http://​man7.org/​linux/​man-pages/​man2/​umount.2.html|umount]]. Parcurgeți paginile de manual ale funcțiilor [[http://​man7.org/​linux/​man-pages/​man2/​mount.2.html|mount]] și [[http://​man7.org/​linux/​man-pages/​man2/​umount.2.html|umount]].
  
-Folosiți comenzile ''​mount''​ și ''​umount''​ din executabilul mini pentru a monta discul ​''​/dev/sda1''​ în punctul de montare ''/​mnt/​my''​. Citiți secțiunea marcată cu TODO din fișierul ''​mini.c''​. Pentru argumentul 4 și argumentul 5 al funcției ''​mount''​ folosiți, respectiv, valorile ''​0''​ și ''​NULL''​.+Folosiți comenzile ''​mount''​ și ''​umount''​ din executabilul mini pentru a monta fişierul ​''​my_fs''​ în punctul de montare ''/​mnt/​my''​. Citiți secțiunea marcată cu ''​TODO'' ​din fișierul ''​mini.c''​. Pentru argumentul 4 și argumentul 5 al funcției ''​mount''​ folosiți, respectiv, valorile ''​0''​ și ''​NULL''​.
  
-Testare: Rulați, ca root, comanda:<​code bash>+Testare: Rulați, ​**ca root**, comanda: 
 +<code bash>
 ./mini ./mini
-</​code>​și apoi rulați comanda de montare în cadrul acestui shell:<​code bash> 
-mount /dev/sda1 /mnt/my ext3 
 </​code>​ </​code>​
-Într-o altă consolă, într-un shell obișnuit, verificați rezultatele folosind comanda<​code bash>+ 
 +și apoi rulați comanda de montare în cadrul acestui shell: 
 + 
 +<code bash> 
 +mount /​dev/​mapper/​vagrant--vg-root /mnt/my ext4 
 +</​code>​ 
 + 
 +În cazul în care nu lucraţi în maşina virtuală de SO, folosiţi ''/​dev/​sda1''​ în loc de ''/​dev/​mapper/​vagrant--vg-root''​. 
 + 
 +Într-o altă consolă, într-un shell obișnuit, verificați rezultatele folosind comanda
 +<code bash>
 cat /​proc/​mounts cat /​proc/​mounts
 </​code>​ </​code>​
Line 292: Line 334:
  
 Pentru testare folosiți, în shell-ul aferent comenzii ''​./​mini'',​ comanda:<​code bash> Pentru testare folosiți, în shell-ul aferent comenzii ''​./​mini'',​ comanda:<​code bash>
-symlink /etc/passwd ​local-passwd+symlink /proc/filesystems ​local-filesystems
 </​code>​ </​code>​
 Ca să verificați,​ într-o altă consolă, în același director cu cel în care ați rulat comanda ''​./​mini'',​ folosiți<​code bash> Ca să verificați,​ într-o altă consolă, în același director cu cel în care ați rulat comanda ''​./​mini'',​ folosiți<​code bash>
Line 298: Line 340:
 </​code>​ </​code>​
 Pentru a șterge symlink-ul folosiți comanda<​code bash> Pentru a șterge symlink-ul folosiți comanda<​code bash>
-unlink local-passwd+unlink local-filesystems
 </​code>​ </​code>​
 Pentru validare rulați din nou comanda<​code bash> Pentru validare rulați din nou comanda<​code bash>
so/laboratoare/laborator-12.1559045839.txt.gz · Last modified: 2019/05/28 15:17 by razvan.nitu1305
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