File Management και I/O στο UNIX

Σχετικά έγγραφα
Προγραμματισμός Ι. Είσοδος/Έξοδος. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Διάλεξη 18η: Διαχείρηση Αρχείων

Βιβλιοθήκη stdio. Προγραμματισμός II 1

Προγραμματισμός συστημάτων UNIX/POSIX. Ανακατευθύνσεις (redirections)

Μετατροπή χαρακτήρων ASCII σε αριθμό (atoi) & διάβασμα, και αποθήκευση του περιεχομένου του στη μνήμη. (Διάλεξη. Πανεπιστήμιο Κύπρου

Λειτουργικά Συστήματα (Λ/Σ)

Κεφάλαιο VΙ: Προσπέλαση Αρχείων. 5.1 Αρχεία δεδομένων.

Βιβλιοθήκη stdio. Προγραμματισμός II 1

Εισαγωγή στην Πληροφορική

Λύβας Χρήστος Αρχική επιµέλεια Πιτροπάκης Νικόλαος και Υφαντόπουλος Νικόλαος

Διαδιεργασιακή επικοινωνία (inter-process communication IPC) Προγραμματισμός II 1

Εικονική Μνήμη (Virtual Μemory)

Αγωγοί/Σωλήνες (Pipes) Προγραμματισμός II 1

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. (Διάλεξη 15)

Εργαστήριο Λειτουργικών Συστημάτων. File Systems

Προγραμματισμός Η/Υ (ΤΛ2007 )

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

Προγραμματισμός συστημάτων UNIX/POSIX. Διαδιεργασιακή επικοινωνία: αγωγοί (IPC inter-process communication: pipes)

ΗΜΥ 213 Εργαστήριο Οργάνωσης Ηλεκτρονικών Υπολογιστών και Μικροεπεξεργαστών

ΗΜΥ 213 Εργαστήριο Οργάνωσης Ηλεκτρονικών Υπολογιστών και Μικροεπεξεργαστών

Αρχιτεκτονική Υπολογιστών

Μετατροπή χαρακτήρων ASCII σε ακέραιο αριθµό (atoi) & Άνοιγµα αρχείου µέσα από τo QtSPIM, διάβασµα, και αποθήκευση του περιεχοµένου του στη µνήµη

Streams Input / Output in C++ George Kastrinis

Λειτουργικά Συστήματα (ΗΥ-345) Χειμερινό Εξάμηνο

Εισαγωγή στον Προγραμματισμό Εργαστήριο 3: Βοηθητικά προγράμματα του Linux CLI. Οκτώβριος 2014 Χ. Αλεξανδράκη Γ. Δημητρακάκης

S, (5, -3, 34, -23, 7) ( *, _

ΗΜΥ 213 Εργαστήριο Οργάνωσης Ηλεκτρονικών Υπολογιστών και Μικροεπεξεργαστών

Εργαστήριο Λειτουργικών Συστημάτων 8o εξάμηνο, Ροή Υ, ΗΜΜΥ

Εισαγωγή στον Προγραμματισμό Εργαστήριο 3: Βοηθητικά προγράμματα του Linux CLI. Οκτώβριος 2014 Χ. Αλεξανδράκη Γ. Δημητρακάκης

Μεθόδων Επίλυσης Προβλημάτων

Οργάνωση Υπολογιστών ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ. Ασκήσεις 7: Πρόγραμμα Συνδεδεμένης Λίστας και Διαδικασιών. Μανόλης Γ.Η.

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ Ι

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ I

Δομημένος Προγραμματισμός (ΤΛ1006)

Εργαστήριο 9: Αρχεία

Στο εργαστήριο θα μελετηθούν: Διδάσκων: Γιώργος Χατζηπολλάς. Εργαστήριο 2: Εργαλεία Συστήματος UNIX. Ομάδες για παρουσίαση

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ ΙΙ - UNIX. Συστήματα Αρχείων. Διδάσκoντες: Καθ. Κ. Λαμπρινουδάκης Δρ. Α. Γαλάνη

Προηγμένοι Μικροεπεξεργαστές. Εργαστήριο 4 - Editor

Λειτουργικά Συστήματα

Αρχεία Ένα αρχείο αποτελείται από μία σειρά ομοειδών δεδομένων που ονομάζονται λογικές εγγραφές (logical record)

Σημειωματάριο Τετάρτης 25 Οκτ. 2017

Προγραμματισμός Η/Υ (ΤΛ2007 )

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. ( ιάλεξη 13) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Εργαστήριο Λειτουργικών Συστημάτων. Minix Overview

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ ΙΙ - UNIX. Συστήματα Αρχείων. Διδάσκoντες: Καθ. Κ. Λαμπρινουδάκης Δρ. Α. Γαλάνη

Λειτουργικά. Συστήματα Ι. Φ ρ ο ν τ ι σ τ ή ρ ι ο. Αριστείδης Ηλίας. Εργαστήριο Ηλεκτρονικών Υπολογιστών

SMPcache. Ένα εργαλείο για προσομοίωση-οπτικοποίηση κρυφής μνήμης (Cache)

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Βασικές λειτουργίες συστήματος πάνω σε αρχεία δεδομένων. Προγραμματισμός II 1

Διαχείριση Περιεχομένου Παγκόσμιου Ιστού και Γλωσσικά Εργαλεία ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ FILE & PROCESS HANDLING

Το λειτουργικό σύστημα. Προγραμματισμός II 1

Διάλεξη 2. Μεταβλητές - Δομές Δεδομένων - Eίσοδος δεδομένων - Έξοδος: Μορφοποίηση - Συναρτήσεις. Διοργάνωση : ΚΕΛ ΣΑΤΜ

Λειτουργικά Συστήματα (ΙΙ) (διαχείριση αρχείων)

Εισαγωγή στο περιβάλλον προγραμματισμού του εργαστηρίου

File Handling & I/O ΓΛΩΣΣΙΚΉ ΤΕΧΝΟΛΟΓΊΑ

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Αναφορές

HY150a Φροντιστήριο 3 24/11/2017

Modbus basic setup notes for IO-Link AL1xxx Master Block

Επεξεργασία Αρχείων Κειµένου

Hancock. Ζωγραφάκης Ιωάννης Εξαρχάκος Νικόλαος. ΕΠΛ 428 Προγραμματισμός Συστημάτων

Λιβανός Γιώργος Εξάμηνο 2017Β

Προγραµµατισµός 2 The shell

Δομημένος Προγραμματισμός (ΤΛ1006)

Κλείδωμα αρχείων (file locking) Προγραμματισμός II 1

Λειτουργικό Σύστημα: διαχείριση πόρων. Διαχείριση αρχείων. Τι είναι ένα αρχείο ; Λειτουργικά Συστήματα (ΙΙ) (διαχείριση αρχείων)

Δίκτυα Επικοινωνιών ΙΙ: Network Programming UDP Sockets, Signals

Πως θα αποθηκεύσει τη λίστα με τα ψώνια του και θα την ανακτήσει στο Σ/Μ; και πως θα προσθέσει στη λίστα του επιπλέον προϊόντα;

Διαδικασιακός Προγραμματισμός

Εισαγωγή στον Προγραμματισμό

Privilege Separation. Dimitris Mitropoulos

Εικονική Μνήμη (Virtual Memory) Προγραμματισμός II 1

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Πίνακες Κλάσεις και Αντικείμενα

Επιτεύγµατα των Λ.Σ.

Εικονική Μνήμη (Virtual Memory) Προγραμματισμός II 1

$./jms console -w <jms in> -r <jms out> -o <operations file> namedpipe. (standard input).

Εικονική Μνήμη (Virtual Μemory)

Λειτουργικό Σύστημα: διαχείριση πόρων. Τι είναι ένα αρχείο ; Διαχείριση αρχείων. Λειτουργικά Συστήματα (ΙΙ) (διαχείριση αρχείων)

Τμήμα Μηχανολόγων Μηχανικών Πανεπιστήμιο Θεσσαλίας ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ. Αρχεία Δεδομένων. Ιωάννης Λυχναρόπουλος Μαθηματικός, MSc, PhD

Αρχεία. Προγραμματισμός II 1

Διάλεξη 20: Χαμηλού Επιπέδου Προγραμματισμός II

Εργαστήριο ΔΙΑΧΕΙΡΙΣΗ ΑΡΧΕΙΩΝ & ΚΑΤΑΛΟΓΩΝ ΣΤΟ UNIX. Εισαγωγή

Εισαγωγή στην Αριθμητική Ανάλυση

Αρχεία. Προγραμματισμός II 1

Αρχιτεκτονική υπολογιστών

3. Γράψτε μία εντολή που να εμφανίζει π.χ. «Πόσα είναι τα κορίτσια του;» και μία που να εμφανίζει: «Τα κορίτσια του Τζειμς Μποντ είναι 4»

C: Από τη Θεωρία στην Εφαρμογή

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Εισαγωγή εκτελέσιμου κώδικα σε διεργασίες

Εισαγωγή στον Προγραμματισμό

Ενδεικτική περιγραφή μαθήματος

ΔΙΑΧΥΤΑ ΚΑΙ ΕΝΣΩΜΑΤΩΜΕΝΑ ΣΥΣΤΗΜΑΤΑ

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα ως ορίσματα Εισαγωγή στις αναφορές

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Δομημένος Προγραμματισμός (ΤΛ1006)

Δίκτυα Η/Υ στην Επιχείρηση

Πληροφορική & Τηλεπικοινωνίες. K18 - Υλοποίηση Συστημάτων Βάσεων Δεδομένων Χειμερινό Εξάμηνο

Transcript:

File Management και I/O στο UNIX Λειτουργικά Συστήματα Ντίρλης Νικόλαος- ΕΤΥ Τμήμα Μηχανικών Η/Υ και Πληροφορικής Πάτρας Συστήματα 2013-2014 1

Εισαγωγή Ένα από τα βασικά στοιχεία της επιστήμης της Πληροφορικής (όπως άλλωστε φαίνεται και από το όνομά της) είναι η έρευνα της φύσης της πληροφορίας καθώς και η διαχείρισή της με αποδοτικό τρόπο. Πληροφορία (info) εξάγεται μετά από επεξεργασία δεδομένων (data) και η οργάνωση της πληροφορίας σε ένα υπολογιστικό σύστημα ήταν από τα πρώτα προβλήματα που έπρεπε να λύσουν οι επιστήμονες της Πληροφορικής. Η ιδέα της «αρχειοποίησης» της πληροφορίας σε αντιστοιχία με τον τρόπο που λειτουργεί η αρχειοποίηση φυσικών εγγράφων σε ένα γραφείο ήταν μια προφανής και φυσική ιδέα που είναι απλή στην κατανόηση και υλοποίηση. Η δομή και το σύνολο των κανόνων που χρησιμοποιούμε για να διαχειριστούμε ομάδες αρχείων μπορούμε να πούμε πως είναι αυτό που ονομάζουμε file system. Συστήματα 2013-2014 2

Σκοπός της παρουσίασης Σκοπός μας σε αυτή την παρουσίαση είναι η κατανόηση της διαχείρισης αρχείων και μεθόδων Ι/Ο στο λειτουργικό σύστημα του UNIX με τελικό στόχο τη δημιουργία ενός flat file system χωρίς ασφάλεια πρόσβασης χρησιμοποιώντας τα εργαλεία που προσφέρει το UNIX. Μέσα από αυτή τη διαδικασία θα κατανοήσουμε καλύτερα τους μηχανισμούς διαχείρισης αρχείων και κάποιες βασικές προγραμματιστικές μεθόδους για την υλοποίηση αυτών σε UNIX-like συστήματα. Συστήματα 2013-2014 3

Flat File System Ένα file system (FS) είναι flat όταν αποτελείται από ένα root folder και έπειτα μόνο από αρχεία, χωρίς δηλ sub-folders. Tέτοια FS (που αλλιώς λέγονται «ενός επιπέδου») έχουν χρησιμοποιηθεί στην πράξη και είναι εύκολο να παρουσιαστούν στον χρήστη ως πολύ-επίπεδα, τεχνική που εφαρμόστηκε στα πρώτα ΛΣ της η Apple. Ένα FS αποτελείται από τρία μέρη, το Directory Service, το Folder Service και το Block Service. Εμείς, στα πλαίσια του στόχου μας για την δημιουργία ενός flat file system, καλούμαστε να υλοποιήσουμε αυτά τα τρία μέρη για ένα FS ενός εικονικού δίσκου. Συστήματα 2013-2014 4

Κέλυφος Στο υψηλότερο επίπεδο, ο χρήστης θα δίνει εντολές σε ένα κέλυφος που θα δημιουργήσουμε το οποίο θα μετατρέπει τις εντολές του υψηλότερου επιπέδου σε κλίσεις συναρτήσεων των Directory και File Services, οι οποίες με τη σειρά τους θα καλούν τις χαμηλότερου επιπέδου συναρτήσεις του Block Service που αναλαμβάνουν τη μετακίνηση block από και προς τον εικονικό δίσκο. Συστήματα 2013-2014 5

Ενδεικτικός κώδικας για το κέλυφος printf("user@shell:~/"); int command = scanf("%c",&argument); if (command<=0) { printf("error :in scanf\n"); continue; } while(chara!='\n') { if(argument==' ') { argum[g][i]='\0'; g++; i=0;} else{ argum[g][i++]=command;} int command = scanf("%c",&argument); if (command<0) { printf("error :in scanf\n"); continue; } } /* add terminal symbol to the last operand */ argum[g][i]='\0'; Συστήματα 2013-2014 6

Σχόλια Έχουμε ορίσει έναν πίνακα τριών ορισμάτων ((ή δύο, ανάλογα με το μέγιστο αριθμό ορισμάτων κάθε εντολής) που ονομάσαμε argum και περιμένουμε από τον χρήστη να εισάγει κάποια εντολή (για παράδειγμα μέσα σε ένα while(true)). Όταν πάρουμε κάποια εντολή μετά μπορούμε να ξεκινήσουμε τη διαδικασία αναγνώρισής της και να καλούμε αντίστοιχα το utility που θα παρέχει το file system μας στον χρήστη (το οποίο θα έχουμε υλοποιήσει εμείς σε κάποιο.h αρχείο), πχ /* check for each command */ if (strcmp(argum[0],"mkfs")==0) { mkfs(); } Συστήματα 2013-2014 7

Μετα-δεδομένα Γνωρίζουμε πως ένα FS διατηρεί κάποιες δομές που περιέχουν μετα-δεδομένα, δηλ βοηθητικά δεδομένα για τα πραγματικά δεδομένα που υπάρχουν στο μέσον (στην περίπτωσή μας στο «δίσκο») που διαχειρίζεται το FS. Οι δομές αυτές θα διατηρούνται στα πρώτα blocks του δίσκου και θα είναι οι εξής: Superblock i-nodes bit map Block bit map Directory Table i-node Συστήματα 2013-2014 8

Μέγεθος των βοηθητικών δομών Λαμβάνοντας κάποιες σχεδιαστικές αποφάσεις, μπορούμε να γνωρίζουμε ακριβώς το μέγεθος σε blocks των παραπάνω δομών. Λαμβάνοντας αυτό υπόψη είναι εύκολο να δημιουργήσουμε το block service χρησιμοποιώντας τις συναρτήσεις lseek(), read() και write() του UNIX (εκτός και αν θέλουμε να δημιουργήσουμε τον δικό μας device manager). Στη συνέχεια της παρουσίασης θα δούμε αναλυτικότερα αυτά τα calls του UNIX. Συστήματα 2013-2014 9

Τα File I/O calls του UNIX Στο UNIX, τα calls που παρέχονται για file I/O είναι τα παρακάτω: open close create read write lseek dup Συστήματα 2013-2014 10

To open call (ορίσματα) int open (char*pathname, int oflag, int mode); Το πρώτο όρισμα είναι το όνομα του αρχείου που θα γίνει open. Το δεύτερο όρισμα καθορίζει τον τρόπο που θα γίνει το open, δηλ μόνο για ανάγνωση, μόνο για εγγραφή, για ανάγνωση και εγγραφή, δημιουργία του αρχείου αν δεν υπάρχει κ.α. Το τρίτο όρισμα χρησιμοποιείται μόνο το αρχείο δημιουργείται και θέτει τα permission bits για αυτό. Συστήματα 2013-2014 11

Το open call (συνέχεια) Αν το αρχείο γίνει open επιτυχώς, το call επιστρέφει έναν file descriptor για αυτό, ή -1 σε περίπτωση λάθους. Όλα τα υπόλοιπα calls χρησιμοποιούν αυτόν τον descriptor για το αρχείο και όχι το όνομα του αρχείου. Όπως θα δούμε λίγο πιο μετά, ο fd αποθηκεύεται στον kernel μαζί με ένα file pointer (offset) που δείχνει το επόμενο byte από το αρχείο που θα γίνει read ή write από τα αντίστοιχα calls. Δείτε επίσης στα man pages για τις fopen και fwrite. Η create είναι ισοδύναμη της open. Συστήματα 2013-2014 12

Κάποια βασικά πράγματα για τα errors Πριν προχωρήσουμε παρακάτω είναι χρήσιμο να αποσαφηνίσουμε κάποια βασικά πράγματα για την διαχείριση των errors στο UNIX. Να τονίσω εδώ πως για το error stream θα μιλήσουμε παρακάτω μαζί με τα άλλα streams. Γενικά στο UNIX οι επιστρεφόμενες τιμές των calls του είναι θετικοί ακέραιοι. Μία αρνητική επιστρεφόμενη τιμή συμβαίνει σαν εξαίρεση. Το global integer variable errno περιέχει πληροφορίες για τα errors και μπορούμε να χρησιμοποιήσουμε τη συνάρτηση perror για να πάρουμε μια περιγραφή του error από το σύστημα. Συστήματα 2013-2014 13

Παράδειγμα με perror int fd =open( foo,o_rdwr); if (fd<0) { perror( Can t open foo );exit(-1); } Αυτό που κάνουμε παραπάνω είναι να προσπαθήσουμε να ανοίξουμε το αρχείο foo για ανάγνωση και εγγραφή. Αν η open αποτύχει για κάποιο λόγο στην errno θα περιέχεται ο αντίστοιχος error code. Τότε αυτό που η perror θα επιστρέψει θα είναι: Can t open foo: [description of error code in errno] Συστήματα 2013-2014 14

To read call (ορίσματα) int read(int fd, void*buffer, int nbytes); H read χρησιμοποιείται για να διαβάσει σε ένα buffer (δεύτερο όρισμα) τόσα bytes όσα ορίζονται στο τρίτο όρισμα από το offset και μετά. Ας δούμε ένα παράδειγμα: char buf[10]; int num_read=read(fd,buf,10); Συστήματα 2013-2014 15

Το read call (συνέχεια) Στο παράδειγμά μας γίνεται σαφής η λειτουργία της read αλλά αυτό που δεν είναι σαφές είναι αν όντως η read θα διαβάσει τα 10 αυτά bytes. Αν η read δεν το κάνει θα επιστρέψει μια αρνητική τιμή και στη μεταβλητή errno θα υπάρχει περισσότερη πληροφορία για αυτό. Αν η επιστρεφόμενη τιμή είναι μηδέν, τότε το offset δείχνει στο τέλος του αρχείου. Αν επιστραφεί μια θετική τιμή μικρότερη του 10 τότε αυτό εκφράζει τα bytes που πραγματικά διαβάστηκαν και το offset θα έχει μετακινηθεί όσο είναι αυτή η τιμή. Είναι ευθύνη του προγραμματιστή να καλέσει την read πάλι για να διαβάσει τα bytes που απομένουν. Συστήματα 2013-2014 16

Το write call Το write λειτουργεί σε αντιστοιχία με το read. Οι read και write είναι και οι δυο τους «blocking» που σημαίνει πως δεν θα επιστρέψουν μέχρι να συμβεί κάποιο error ή μέχρι να φτάσει το offset στο τέλος του αρχείου ή να διαβαστούν ή γραφούν επιτυχώς κάποια bytes. Είναι δυνατόν να τεθεί ένας file descriptor ως non-blocking και σε αυτή την περίπτωση όταν μια διεργασία είναι να γίνει block επιστρέφει αμέσως μια αρνητική τιμή και το errno γίνεται EWOULDBLOCK. Φυσικά, ένα call μπορεί να διακοπεί από ένα signal και σε αυτή την περίπτωση η errno παίρνει την τιμή EINTR. Ο προγραμματιστής έχει τη δυνατότητα να χρησιμοποιήσει τις τιμές της errno για να διαχειριστεί καταστάσεις σφαλμάτων, interrupts κτλ. Συστήματα 2013-2014 17

Το lseek call (ορίσματα) int lseek(int fd, int offset, int whence); Είδαμε πως οι read και write χρησιμοποιούν το offset και του αλλάζουν τιμή. Η αλλαγή του offset μπορεί να γίνει κατά βούληση του προγραμματιστή μέσω της lseek. Τα πρώτα δύο ορίσματα είναι το αρχείο που θα «πειράξουμε» το offset του και πόσο αυτό θα μετακινηθεί. Το τρίτο όρισμα καθορίζει τον τρόπο της μετακίνησης. SEEK_SET offset is from the beginning of the file SEEK_CUR offset is from the current position SEEK_END offset if from the end of the file Συστήματα 2013-2014 18

Το lseek call (συνέχεια) An example from http://codewiki.wikidot.com/c:system-calls:lseek int file=0; if((file=open("testfile.txt",o_rdonly)) < -1) return 1; char buffer[19]; if(read(file,buffer,19)!= 19) return 1; printf("%s\n",buffer); if(lseek(file,10,seek_set) < 0) return 1; if(read(file,buffer,19)!= 19) return 1; printf("%s\n",buffer); return 0; The output of the preceding code is: $ cat testfile.txt This is a test file that will be used to demonstrate the use of lseek. $./testing This is a test file test file that will Συστήματα 2013-2014 19

Block Service- Υλοποίηση (1/2) Κάνοντας χρήση των πραγμάτων που έχουμε δει μέχρι τώρα μπορούμε εύκολα να δημιουργήσουμε το block service του file system μας με τη βοήθεια των read, write και lseek. To Block Service παρέχει υπηρεσίες ανάγνωσης και εγγραφής ανά block στα επόμενα επίπεδα και αυτό μπορεί να συντελεστεί ως εξής: Βήμα 1 ο : Πήγαινε στην αρχή του αρχείου που θα εξομοιώνει τον εικονικό μας δίσκο (έτσι κι αλλιώς όλα είναι ένα αρχείο στο UNIX) Βήμα 2 ο : Προσπέρασε τα structs με τα meta-data (όπως είπαμε αυτά έχουν σταθερό μέγεθος στο project μας) Βήμα 3 ο : Βρες το block στο οποίο θα γίνει εγγραφή ή ανάγνωση και κάνε το αντίστοιχο write() ή read() Συστήματα 2013-2014 20

Block Service- Υλοποίηση (2/2) Με την βοήθεια της lseek τα παραπάνω βήματα γίνονται εύκολα. Για να υλοποιηθεί λοιπόν ένα read και write ενός block πριν από τη χρησιμοποίηση αυτών των συναρτήσεων του UNIX αρκεί να εισάγουμε μια lseek() της μορφής: lseek(file,sizeof(superblock)+ sizeof(inodesbitmap)+ sizeof(blockbitmap)+ sizeof(inode)+ sizeof(directory_table)+ block_number,seek_set); Συστήματα 2013-2014 21

Το close call close(fd); Όταν «τελειώσουμε» με τον fd πρέπει να τον κλείσουμε. Το UNIX (όπως θα δούμε παρακάτω, αλλά όπως ισχύει και στο δικό μας file system) κρατάει σε ένα πίνακα τα ανοικτά αρχεία και αυτός ο πίνακας έχει πεπερασμένο μέγεθος. Άρα υπάρχει περιορισμένος αριθμός αρχείων που ανά πάσα στιγμή είναι ανοιχτά, που σημαίνει πως για να μην επιβαρύνεται το σύστημα, πρέπει τα αρχεία που δεν χρησιμοποιούνται πια να γίνονται απαραιτήτως close. Συστήματα 2013-2014 22

Το dup call (εισαγωγή) int dup(int fd); int dup2(int fd, int fd2); Το dup δημιουργεί ένα διπλότυπο του fd. Χρησιμοποιεί την πρώτη κενή θέση στο process file table (θα μιλήσουμε γι αυτό στην επόμενη διαφάνεια) για να αποθηκεύσει αυτό το διπλότυπο. Η dup2 θα τοποθετήσει το διπλότυπο στη θέση fd2. Το γεγονός ότι η dup κάνει δυνατό να έχουμε δύο θέσεις στο process's open file table να δείχνουν στην ίδια θέση του kernel fle table μας παρέχει την δυνατότητα να κάνουμε I/O redirection ή να δημιουργήσουμε pipelines. Για να κατανοήσουμε καλύτερα τα παραπάνω, πρέπει να πούμε δύο λόγια για κάποια data structures για file management του UNIX καθώς επίσης και για τα I/O streams του. Συστήματα 2013-2014 23

Data Structures για file management στο UNIX Το UNIX χρησιμοποιεί τις παρακάτω τρεις δομές για να διαχειριστεί τα αρχεία: 1. Έναν ανα-διαδικασία πίνακα όπου αποθηκεύονται τα fd. Κάθε entry του πίνακα περιέχει και έναν pointer στο kernel file table. 2. Ο kernel file table που περιέχει κάθε αρχείο που είναι ανοικτό από όλες τις processes. Περιέχει flags που υποδηλώνουν read/write access, blocking/nonblocking κτλ καθώς επίσης το offset και έναν pointer για το v-node table. 3. O v-node table είναι μια in-memory copy του i- node για κάθε ανοικτό αρχείο. Συστήματα 2013-2014 24

Τα Ι/Ο streams του UNIX Κάθε πρόγραμμα ξεκινά με τρεις ανοικτούς file descriptors: stdin, stdout και stderr Στην αρχή κάθε προγράμματος, οι τιμές των descriptors αυτών είναι 0,1 και 2 αντίστοιχα. Με την freopen μπορεί να γίνει αλλαγή στον αριθμό του descriptor που αντιστοιχεί σε κάθε stream. To stderr είναι unbuffered. To stdout είναι line-buffered όταν δείχνει σε ένα τερματικό. Αυτό σημαίνει πως αν δεν εμφανιστεί το fflush() ή το exit() ή κάποια αλλαγή γραμμής, η έξοδος δεν θα εμφανιστεί αν δεν γεμίσει πρώτα ο buffer. To buffering mode κάθε stream μπορεί να αλλάξει με τις setbuf() και setvbuf() calls. Συστήματα 2013-2014 25

Ι/Ο redirection με την dup Στο παράδειγμα που ακολουθεί τα write που γίνονται στο stdout εμφανίζονται στο stdout.log. int fd = open( stdout.log,o_wronly); dup2(fd,fileno(stdout)); Σε ένα άλλο παράδειγμα δείχνουμε πως μπορεί να υλοποιηθεί το σχήμα command < somefile Κάνε fork μια child process; Η child process (cp)cκάνει open το somefile; Η cp κάνει close το standard input (descriptor 0); Ηcp κάνει dup τον fd του somefile (δημιουργία ενός fd στο slot 0); H cp κάνει close τιν αρχικό fd του somefile; Η cp εκτελεί το command; Τώρα, όταν το command κάνει read από το stdin (descriptor 0), θα διαβάζει από το somefile! Συστήματα 2013-2014 26

Δημιουργία pipelines Παρόμοια τεχνική χρησιμοποιείται και για την δημιουργία pipelines. Για να υλοποιηθεί το σχήμα command1 command2 πρέπει Το κέλυφος δημιουργεί ένα pipe και έπειτα κάνει fork δύο child processes. Μία από αυτές κάνει redirection της εξόδου στο writing end του pipe και εκτελεί την command1. Η άλλη process κάνει redirection την είσοδό της στο reading end του pipe και εκτελεί την command2. Συστήματα 2013-2014 27

Δημιουργία utilities Σε αυτή την ενότητα θα δούμε πως μπορούμε να δημιουργήσουμε κάποια utilities του file system μας προς τον χρήστη όπως για παράδειγμα η δημιουργία και η διαγραφή αρχείων. Στο σύστημά μας (αλλά και στο fs του UNIX) υπάρχει η δομή του superblock (για λεπτομέρειες κάντε man mkfs) όπου λεπτομέρειες για το file size, name κα συγκεκριμενοποιούνται. Εμείς έχουμε λάβει τη σχεδιαστική απόφαση να έχουμε σταθερό superblock και άρα δεν χρειάζεται πραγματικά να υπάρχει. Στο UNIX μετά το superblock υπάρχει ένας πίνακας δομών που ονομάζονται inodes. Υπάρχει ένα inode για κάθε αρχείο και για κάθε directory όπου υπάρχει και ένα bit που καθορίζει ότι το συγκεκριμένο αρχείο είναι directory. Μία αναφορά σε ένα inode μέσα σε ένα dir file ονομάζεται link Συστήματα 2013-2014 28

Το remove Όταν ένα αρχείο διαγράφεται από το σύστημά μας, η διαδικασία διαφέρει από αυτή όπου «διαγράφουμε» (σβήνουμε) κάτι στην πραγματική ζωή. Στο UNIX απλά γίνεται unlink το αρχείο από το parent directory και στα meta-data structures (όπως για παράδειγμα στο block bit map) γίνονται οι απαραίτητες ενέργειες έτσι ώστε να γίνει κατανοητό ότι τα συγκεκριμένα blocks μπορούν να επαναχρησιμοποιηθούν. Συστήματα 2013-2014 29

Ενδεικτικός κώδικας για το rm /*********RM********************* /*var1 contains the name of the file to delete*/ void rm(char *var1){ int i=0; int found=0; for(;i<100;i++){ /* try to find the file in the Directory Table */ if((strcmp( Directory_Table[i].Filename,var1)==0)&& (Directory_Table[i].InodeIndex!=-2)){ found=1; break;}} if(found){ /* use create to clear the blocks it uses */ create(var1); /* set its entry in directory table to not existing */ Directory_Table[i].InodeIndex=-2; for(i=0;i<100;i++){ if(strcmp( FILES[i].filename,var1)==0){ /* set its entry in FILES to not existing */ FILES[i].ufid=-1; break; }} printf("file deleted\n");} //end if else{ printf("file not found\n"); }//end else }//end of RM Συστήματα 2013-2014 30