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



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

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

Εργαστήριο Λειτουργικών Συστημάτων 8ο εξάμηνο, Ακαδημαϊκή περίοδος

Ανάπτυξη και Σχεδίαση Λογισμικού

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

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

Δομημένος Προγραμματισμός

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

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

Μεταγλώττιση και σύνδεση πολλαπλών αρχείων κώδικα. Προγραμματισμός II 1

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

Δείκτες σε συναρτήσεις. Προγραμματισμός II 1

Χρονοδρομολογητής Κυκλικής Επαναφοράς

Δομές δεδομένων (2) Αλγόριθμοι

Ανάπτυξη και Σχεδίαση Λογισμικού

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

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

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

Εικονική Μνήμη (1/2)

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

Εργαστήριο 5. Εαρινό Εξάμηνο

Εργαστήριο Λειτουργικών Συστημάτων 8ο εξάμηνο, Ακαδημαϊκή περίοδος

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

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

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

Προγραμματισμός Υπολογιστών με C++

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

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

Ο πίνακας συμβόλων (symbol table) είναι μία δομή, όπου αποθηκεύεται πληροφορία σχετικά με τα σύμβολα του προγράμματος

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

Στοίβες με Δυναμική Δέσμευση Μνήμης

Εργαστήριο Λειτουργικών Συστημάτων 8ο εξάμηνο, Ακαδημαϊκή περίοδος

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Πληροφορική & Τηλεπικοινωνίες K18 - Υλοποίηση Συστημάτων Βάσεων Δεδομένων Χειμερινό Εξάμηνο M. Χατζόπουλος. Προθεσμία: 19/01/2015

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

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

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

Τύποι Δεδομένων και Απλές Δομές Δεδομένων. Παύλος Εφραιμίδης V1.0 ( )

2.1. Εντολές Σχόλια Τύποι Δεδομένων

Προγραμματισμός Ι (ΗΥ120)

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΚΑΙ ΠΙΝΑΚΕΣ

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκή περίοδος

ΗΥ240: Δοµές Δεδοµένων Εαρινό Εξάµηνο Ακαδηµαϊκό Έτος 2017 Διδάσκουσα: Παναγιώτα Φατούρου Προγραµµατιστική Εργασία - 1 ο Μέρος

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

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

Εισαγωγή στο Bison. Μεταγλωττιστές, Χειμερινό εξάμηνο

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

Κεφάλαιο Αλφαριθμητικές Σειρές Χαρακτήρων (Strings) (Διάλεξη 20) 1) Strings στη C

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

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

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

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

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

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

Εισαγωγή στην Επιστήμη Υπολογιστών. Εισαγωγή στην Python

Εισαγωγή στον Προγραμματισμό (με. τη C)

Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

6. ΠΙΝΑΚΕΣ & ΑΛΦΑΡΙΘΜΗΤΙΚΑ

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

Επανάληψη για τις Τελικές εξετάσεις. (Διάλεξη 24) ΕΠΛ 032: ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΕΘΟΔΩΝ ΕΠΙΛΥΣΗΣ ΠΡΟΒΛΗΜΑΤΩΝ

Slide 6 / 43. Slide 5 / 43. Α. Σαββίδης. Α. Σαββίδης. Slide 8 / 43. Slide 7 / 43. Α. Σαββίδης. Α. Σαββίδης HY340, 2009 HY340, 2009 HY340, 2009

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

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

'Ασκηση 1: Στατικός Κατακερματισμός. Εισαγωγή. Ρουτίνες υλοποίησης κατακερματισμού. (Ημερομηνία Παράδοσης: Παρασκευή, 16/5/2008, 5μμ) HT_Init()

Τεχνολογία και Προγραμματισμός Υπολογιστών. Η γλώσσα προγραμματισμού C

Περιεχόμενα. Πρόλογος... 17

3ο σετ σημειώσεων - Πίνακες, συμβολοσειρές, συναρτήσεις

Προηγμένοι Μικροεπεξεργαστές. Εργαστήριο 6 C & Assembly

Εργαστήριο 4. Εαρινό Εξάμηνο ΠΡΟΣΟΧΗ: Αρχίστε νωρίς το Εργαστήριο 4. Οι ασκήσεις είναι πιο απαιτητικές από τα προηγούμενα εργαστήρια.

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 3 Επανάληψη Γ μέρος

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

Διάλεξη 2: Επανάληψη Προγραμματισμού Συμβολοσειρές (strings) Διδάσκων: Παναγιώτης Ανδρέου

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

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

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

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

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

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

ΑΣΚΗΣΗ 2: ΔΟΜΗ ΠΡΟΓΡΑΜΜΑΤΟΣ C, ΧΕΙΡΙΣΜΟΣ ΜΕΤΑΒΛΗΤΩΝ ΚΑΙ ΣΥΝΑΡΤΗΣΕΙΣ ΕΙΣΟΔΟΥ ΚΑΙ ΕΞΟΔΟΥ

Προγραμματισμός ΙΙ Εαρινό εξάμηνο Εργασία 3 Βιβλιοθήκη για λειτουργίες σε γράφους

ΟΝΤΟΚΕΝΤΡΙΚΟΣ ΠΡΟΓΡ/ΣΜΟΣ C++

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

Α Β Γ static; printf("%c\n", putchar( A +1)+2); B DB BD. int i = 0; while (++i); printf("*");

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκή περίοδος

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

Οντοκεντρικός Προγραμματισμός

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

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

Εισαγωγή στη γλώσσα προγραμματισμού C++

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

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

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

Δομημένος Προγραμματισμός

ΗΥ240: Δομές Δεδομένων Εαρινό Εξάμηνο Ακαδημαϊκό Έτος 2017 Διδάσκουσα: Παναγιώτα Φατούρου Προγραμματιστική Εργασία - 2o Μέρος

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

1 η ΑΣΚΗΣΗ ΣΤΗΝ ΑΡΧΙΤΕΚΤΟΝΙΚΗ ΥΠΟΛΟΓΙΣΤΩΝ. Ακ. έτος , 5ο Εξάμηνο, Σχολή ΗΜ&ΜΥ

Παράλληλη Επεξεργασία

Transcript:

ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ Σχολή Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών Εργαστήριο Λειτουργικών Συστημάτων 8o εξάμηνο, Ροή Υ, ΗΜΜΥ Σχεδιασμός και υλοποίηση υποδομής σημείωσης διεργασιών στον πυρήνα του Linux Τελική αναφορά Σταυρακάκης Χρήστος, 03106165 Τσιούρης Ιωάννης, 03106193 Η/Μ Παράδοσης: 10 Ιουνίου 2010 Αθήνα, 2010

1 ΕΙΣΑΓΩΓΗ 1 1 Εισαγωγή Σκοπός αυτής της αναφοράς είναι η παρουσίαση της τελικής σχεδίασης της υποδομής σημείωσης διεργασιών με κατάρες στον πυρήνα του linux καθώς και της κατάρας no-fs-ca e. Στην αναφορά αυτή δεν θα δοθεί έμφαση στην ανάλυση του προβλήματος ή στις σχεδιαστικές επιλογές, καθώς αυτό έγινε αναλυτικά στην ενδιάμεση αναφορά. Ωστόσο, θα εστιάσουμε στα σημεία στα οποία η υλοποίηση μας δεν ακολούθησε την ενδιάμεση σχεδίαση. Τέλος θα παρουσιαστεί η τεκμηρίωση για τους χρήστες. 2 Τελική σχεδίαση 2.1 Υποδομή σημείωσης διεργασιών Η σημείωση διεργασιών στον πυρήνα του linux γίνεται μέσω ενός system call, του sys_curse το οποίο υλοποιείται και δηλώνεται στον πυρήνα του linux. Τα ονόματα των κατάρων υπάρχουν αποκλειστικά στον πυρήνα. Η δομή struct curses_names περιέχει μια μεταβλητή που δείχνει τον αριθμό των υλοποιημένων κατάρων και έναν πίνακα(names) από pointer σε string με τα ονόματα τους. t y p e d e f s t r u c t { i n t nr_names ; c o n s t char * names [MAX_NAME_LIST_NAME_LEN ] ; n a m e _ l i s t _ t ; s t a t i c n a m e _ l i s t _ t c u r s e s _ n a m e s = {. nr_names = 2,. names = { [ CURSE_STINK ] = s t i n k, [CURSE_NOCACHE] = nocache ; Τα ονόματα αυτά πρέπει να μπορούν να ανακτηθούν από το χρήστη. Καθώς όμως ο πίνακας βρίσκεται σε χώρο πυρήνα ο χρήστης δε μπορεί να τον προσπελάσει. Απαιτείται λοιπόν να αντιγραφεί στο χώρο χρήστη. Αυτό επιτυγχάνεται με τη συνάρτηση copy_to_user η οποία πραγματοποιεί την αντιγραφή έπειτα από κάποιος απαραίτητους ελέγχους. Όμως η αντιγραφή ενός πίνακα από pointer σε string απαιτεί την αντιγραφή του κάθε στοιχείου ξεχωριστά. Για να αποφευχθεί αυτό επιλέχθηκε η συνένωση των ονομάτων των κατάρων σε ένα string, διαχωρισμένα με κάποιο ειδικό στοιχείο (separator= ). To string αυτό γίνεται εύκολα copy to user, και έπειτα ο χρήστης το χειρίζεται κατάλληλα. Στον πυρήνα μας ορίζουμε τη μεταβλητή curses_status η οποία θα χρησιμοποιηθεί για την αποθήκευση της κατάστασης (ενεργοποιημένη ή όχι) των κατάρων. Η μεταβλητή αυτή θα χρησιμοποιηθεί σαν Bitmap. Δηλαδή κάθε κατάρα θα γίνεται map σε κάποιο από τα bit της μεταβλητής curses_status.το ποιο bit αντιστοιχεί σε ποια κατάρα γίνεται define. Αν το bit είναι 1 η κατάρα είναι ενεργοποιημένη, ενώ αν είναι 0 η κατάρα είναι απενεργοποιημένη. s t a t i c unsigned long c u r s e s _ s t a t u s = 0 x0 ; Καθώς όμως ο χρήστης δίνει όνομα κατάρας, χρειάζεται κάποιος τρόπος αντιστοίχισης του ο- νόματος σε bit. Αυτό επιτυγχάνεται με τη βοήθεια του πίνακα curses_names.names. Στον πίνακα αυτό, τα ονόματα δηλώνονται με τέτοιο τρόπο ώστε το όνομα της κατάρας που αντιστοιχεί στο x bit να βρίσκεται στην x θέση του πίνακα(zero indexed). Για να βρούμε λοιπόν το ποιο bit αντιστοιχεί σε ποια κατάρα, αρκεί μια γραμμική αναζήτηση στον πίνακα. Η γραμμική αναζήτηση γενικά

2 ΤΕΛΙΚΗ ΣΧΕΔΙΑΣΗ 2 αυξάνει την πολυπλοκότητα. Όμως καθώς ο αριθμός των κατάρων είναι μικρός δεν δημιουργείται πρόβλημα. Όσον λοιπόν αφορά της λειτουργίες ελέγχου κατάστασης κατάρας, ενεργοποίησης και απενεργοποιήσης αρκεί ο έλεγχος ή η μεταβολή του bit της μεταβλητής curses_status που αντιστοιχεί στην κατάρα. Τα race conditions που προκύπτουν για τον έλεγχο και μεταβολή αυτής της μεταβλητής λύνονται με χρήση bitwise atomic operations. Συγκεκριμένα χρησιμοποιούνται οι test_bit, set_bit και clear_bit. Αντίστοιχη σχεδίαση χρησιμοποιείται και για τον αν μια διεργασία είναι καταραμένη ή όχι. Σε αντιστοιχία με την μεταβλητή curses_status χρησιμοποιείται μια μεταβλητή ανά διεργασία η οποία αποθηκεύεται μέσα στη δομή struct task_struct, που αποτελεί τον proccess descriptor της διεργασίας. Η μεταβλητή αυτή είναι η curses. s t u c t t a s k _ s t r u c t { v o l a t i l e long s t a t e ;... unsigned long c u r s e s ;.... Όταν λοιπόν θέλουμε να ελέγξουμε αν μια διεργασία είναι καταραμένη, να την καταραστούμε ή να τις αφαιρέσουμε την κατάρα, αρκεί να ελέγξουμε η να μεταβάλουμε το αντίστοιχο bit. Ο χρήστης λοιπόν δίνει το pid της διεργασίες που τον ενδιαφέρει και εμείς πρέπει να βρούμε το task_struct της και να χρησιμοποιήσουμε την μεταβλητή curses. Για να βρούμε το task_struct της διεργασίας με βάση το pid χρησιμοποιούμε τη συνάρτηση find_task_by_vpid(pid). Ο έλεγχος και η μεταβολή της μεταβλητής curses γίνεται με atomic operations κατά αντιστοιχία με τη global μεταβλητή curses_status. Για την εύρεση του task_struct καθώς και τον έλεγχο της μεταβλητής προκύπτουν ζητήματα ταυτόχρονης πρόσβασης και συγχρονισμού. Τα ζητήματα αυτά λύνονται με το lo του πυρήνα του linux tasklist_lock. Αυτό το lo αφορά την λίστα με όλα τα task_struct. Έτσι διασφαλίζουμε και το ψάξιμο μας ενάντια σε άλλα λειτουργίες του πυρήνα. Για τον έλεγχο της μεταβλητής θα χρησιμοποιήσουμε τη read_lo _irq(&tasklist_lo ) (Acquire reader lo and disable local interrupts) ενώ για την τροποποίηση της write_lo _irq(&tasklist_lo )(Acquire writer lo and disable local interrupt). Ακόμα, για τις ανά διεργασία λειτουργίες προκύπτουν ορισμένα ζητήματα ασφάλειας. Ο χρήστης πρέπει να μπορεί να καταραστεί μόνο τις δικές του διεργασίες. Ο μόνος που μπορεί να καταραστεί άλλες διεργασίες είναι ο administrator. Ο έλεγχος λοιπόν αυτός γίνεται με βάση τα credentials που υπάρχουν στο stuct cred που υπάρχει μέσα στο task_struct. Γίνεται λοιπόν ο έλεγχος των credentials του χρήστη με αυτών τις διεργασίες που θέλει να καταραστεί ή ελέγχεται αν ο χρήστης είναι administrator. Αυτό επιτυγχάνεται με τον εξής κώδικα : i f ( ( own_creds >e u i d ^ t a r g e t _ c r e d s > s u i d ) && ( own_creds >e u i d ^ t a r g e t _ c r e d s >u i d ) && ( own_creds >u i d ^ t a r g e t _ c r e d s > s u i d ) && ( own_creds >u i d ^ t a r g e t _ c r e d s >u i d ) &&! c a p a b l e ( CAP_SYS_ADMIN ) ) { e r r = EACCES ; 2.1.1 Στατική Βιβλιοθήκη Χρήστη Ο ρόλος αυτής της βιβλιοθήκης είναι να υλοποιεί μια διεπαφή για τα προγράμματα χρήστη. Έτσι η πρόσβαση στις λειτουργίες της υποδομής να είναι πιο φιλική στο χρήστη και λιγότερο επιρρεπής σε λάθη. Αυτό το επιτυγχάνουμε δημιουργώντας wrapper συναρτήσεις για το system call, με αντίστοιχη

2 ΤΕΛΙΚΗ ΣΧΕΔΙΑΣΗ 3 λογική της glibc. Δημιουργείται λοιπόν μια συνάρτηση curse η οποία έχει ως μοναδικό σκοπό να καλεί το system call. long c u r s e ( long c a l l, const char * curse_name, p i d _ t pid, char * c u r s e s _ l i s t ) { r e t u r n s y s c a l l ( NR_curse, c a l l, curse_name, pid, c u r s e s _ l i s t ) ; Ακόμα δημιουργείται μια συνάρτηση για κάθε μία από τις λειτουργίες του system call. Αυτές οι συναρτήσεις δέχονται μόνο τα απαραίτητα ορίσματα από το χρήστη, και καλούν την curse διαμορφώνοντας τα υπόλοιπα ορίσματα (όπως τα flags που γίνονται include από την βιβλιοθήκη πυρήνα). Για παράδειγμα η συνάρτηση που δημιουργείται για την επιβολή κατάρας σε μια διεργασία είναι η : long c u r s e _ c a s t ( const char * curse_name, p i d _ t p i d ) { r e t u r n c u r s e ( CURSE_CMD_CURSE_CAST, curse_name, pid, NULL ) ; Επίσης η βιβλιοθήκη χρήστη έχει μια συνάρτηση για την εκτύπωση της λίστας ονομάτων των κατάρων που επιστρέφει το system call. Αυτή η συνάρτηση ουσιαστικά χωρίζει την λίστα με βάση τον separator όπως ορίστηκε στο system call. Η συνάρτηση αυτή είναι η εξής: i n t c u r s e _ p r i n t _ l i s t ( char * c u r s e _ l i s t ) { char * name ; char * l i s t ; i n t i = 1 ; l i s t = s t r d u p ( c u r s e _ l i s t ) ; name = s t r t o k ( l i s t, CURSE_LIST_SEPERATOR ) ; p r i n t f ( A v a i l a b l e C u r s e s : \ n Number \ tname \ n ) ; while ( name! = NULL ) { p r i n t f ( %d \ t %s \ n, i, name ) ; name = s t r t o k ( NULL, CURSE_LIST_SEPERATOR ) ; i + + ; r e t u r n 0 ; 2.1.2 Εργαλείο Χρήστη Το εργαλείο χρήστη έχει σκοπό την εύκολη αλληλεπίδραση του χρήστη με τις λειτουργίες της υποδομής. Το εργαλείο αυτό υλοποιήθηκε σαν ένας ψευδο-φλοιός ο οποίος δέχεται εντολές από το χρήστη σε εύκολη και φιλική σύνταξη και καλεί κατάλληλα τις συναρτήσεις της βιβλιοθήκης χρήστη. Το εργαλείο χρήστη θα μπορούσε να υλοποιηθεί και ως εργαλείο γραμμής εντολών, όμως υλοποιήθηκε σαν ψευδο-φλοιός καθώς θεωρούμε ότι αποτελεί έναν πιο διαδραστικό τρόπο επικοινωνίας. Ένα παράδειγμα λειτουργίες για το εργαλείο είναι η λειτουργία εκτύπωσης των διαθέσιμων κατάρων. Ο χρήστης απλά πληκτρολογεί list. Έπειτα το εργαλείο κάνει μια κλήση στο system call με έναν NULL pointer. Στην συνέχεια δέχεται από το system call το πόσο χώρο χρειάζεται να δεσμεύσει και με βάση αυτό, δεσμεύει τον κατάλληλο χώρο και πραγματοποιεί την δεύτερη κλήση στο system call. i f ( s t r c m p ( cmdline, l i s t ) == 0 ) { r e s = c u r s e _ l i s t ( NULL ) ; m y l i s t = ( char * ) m a l l o c ( r e s * s i z e o f ( char ) ) ; r e s = c u r s e _ l i s t ( m y l i s t ) ;

3 ΣΥΓΚΡΙΣΗ ΜΕ ΑΡΧΙΚΗ ΣΧΕΔΙΑΣΗ 4 i f (! r e s ) c u r s e _ p r i n t _ l i s t ( m y l i s t ) ; e l s e p r i n t f ( E r r o r \ n ) ; f r e e ( m y l i s t ) ; r e t u r n ; Επίσης το εργαλείο είναι υπεύθυνο για να ενημερώνει το χρήστη για την κατάλληλη κλήση του system call καθώς και για τα διάφορα σφάλματα που προκύπτουν. 2.2 Κατάρα no-fs-ca e Η κατάρα no-fs-ca e αποτελεί την λύση για το πρόβλημα του λόξυγγα ανετοιμότητας όπως αυτός ορίστηκε στην ενδιάμεση αναφορά. Σκοπός της no-fs-ca e είναι οι καταραμένες διεργασίες να μην γεμίζουν την μνήμη με τα αρχεία τα οποία διαχειρίζονται. Για να το επιτύχουμε αυτό χρησιμοποιούμε την κλήση συστήματος fadvise64 που ορίζεται στο πρότυπο POSIX. SYSCALL_DEFINE ( f a d v i s e 6 4 _ 6 4 ) ( i n t fd, l o f f _ t o f f s e t, l o f f _ t len, i n t a d v i c e ) Η κλήση σε αυτή θα πραγματοποιηθεί με την επιλογή POSIX_FADV_DONTNEED. Με αυτήν την ε- πιλογή η fadvise απομακρύνει το μέρος του αρχείου που ορίζεται από τη μνήμη. Η κατάρα αυτή λοιπόν υλοποιείται με την προσθήκη στις κλήσεις συστήματος read και write της συνάρτησης curse_no_cache_checkpoint η οποία ελέγχει αν είναι ενεργοποιημένη η κατάρα καθώς και αν είναι καταραμένη η διεργασία που έκανε το read/write. Αν ισχύουν και τα δύο πραγματοποιεί την κλήση στην fadvise με τα κατάλληλα ορίσματα. Τα ορίσματα είναι τέτοια ώστε να απομακρύνεται από τη μνήμη η περιοχή που μόλις διάβασε/έγγραψε η read/write. Οι read/write παίρνουν σαν όρισμα τον file descriptor(fd) και το πόσα bytes(count) θα διαβάσουν/γράψουν. Βρίσκουν την τρέχουσα θέση στο αρχείο (loff_t pos),πραγματοποιούν την λειτουργία και ανανεώνουν την θέση(pos). Η κλήση της e point θα γίνεται αφού πραγματοποιηθούν οι λειτουργίες read/write. Αρά αφού η θέση στο αρχείου θα έχει μετακινηθεί κατά count, η κλήση στην fadvise αν καλούταν απευθείας από τις read/write θα πρέπει να είχε τα εξής ορίσματα: s y s _ f a d v i s e 6 4 ( fd, pos count, count, POSIX_FADV_DONTNEED ) Η συνάρτηση λοιπόν curse_no_cache_checkpoint είναι η εξής: void c u r s e _ n o c a c h e _ c h e c k p o i n t ( unsigned i n t fd, s i z e _ t o f f s e t, s i z e _ t c o u n t ) { i f ( NOCACHE_ENABLED && t e s t _ b i t ( CURSE_NOCACHE, &( c u r r e n t > c u r s e s ) ) ) { s y s _ f a d v i s e 6 4 ( fd, o f f s e t count, count, POSIX_FADV_DONTNEED ) ; ; 3 Σύγκριση με αρχική σχεδίαση Η υλοποίηση της υποδομής και της κατάρας ακολούθησε την σχεδίαση που είχε γίνει στην ενδιάμεση αναφορά Ωστόσο η υλοποίηση διαφοροποιήθηκε σε ελάχιστα σημεία, τα οποία είναι τα εξής : 1. Στην αρχική μας σχεδίαση το system call δεχόταν ως όρισμα τον αριθμό της κατάρας όπως αυτή επιστρεφόταν από τη λίστα με τις διαθέσιμες κατάρες και με βάση αυτό τον αριθμό βρισκόταν σε ποιο bit της μεταβλητής curses_status γινόταν map αυτή η κατάρα. Στην τελική μας υλοποίηση ωστόσο το system call δέχεται σαν όρισμα το όνομα της κατάρας και η αναζήτηση για το ποιο bit αντιστοιχεί στην κατάρα γίνεται εσωτερικά με βάση τον πίνακα κατάρων. Η επιλογή αυτή βασίστηκε στο γεγονός ότι το πέρασμα του ονόματος είναι

4 ΠΕΡΙΓΡΑΦΗ ΥΛΟΠΟΙΗΣΗΣ ΚΑΙ ΤΕΚΜΗΡΙΩΣΗ 5 πολύ πιο φιλικό προς το χρήστη και πιο δύσκολο να δημιουργήσει errors. Άντι να απαιτούμε από το χρήστη να κάνει την αντιστοίχιση στο όνομα μιας κατάρας που έχει στο μυαλό του με κάποιο αριθμό, επιτελούμε εμείς αυτή τη λειτουργία στον πυρήνα. 2. Επίσης υλοποιήθηκε διαφορετικά ο τρόπος επιστροφής των διαθέσιμων κατάρων καθώς στην αρχική μας σχεδίαση δεν είχαμε σκεφτεί την δυσκολία του να κάνεις copy σε user space έναν πίνακα από pointer σε string. 3. Η global μεταβλητή για την αποθήκευση των ενεργοποιημένων κατάρων curses_status καθώς και η μεταβλητή ανά διεργασία curses δεν υλοποιήθηκαν ως μεταβλητές short int όπως είχε αναφερθεί στην αρχική αναφορά. Αντίθετα μοντελοποιήθηκαν ως unsigned long. Αυτό οφείλεται στο γεγονός ότι τα atomic operations στην αρχιτεκτονική x86, έχουν υλοποιηθεί ώστε να δέχονται pointer σε unsigned long Καθώς θεωρούμε ότι τα cast δεν είναι ιδιαίτερα ασφαλή μετατρέψαμε τις μεταβλητές σε unsigned long. Αυτό αυξάνει τον χώρο που απαιτείται αλλά είναι προτιμότερο από ενδεχόμενο σφάλματα που θα μπορούσαν να προκύψουν. 4. Στην αρχική σχεδίαση μας σχεδίαση είχαμε προβλέψει ότι όταν θα θέλαμε να βρούμε το task_struct που αντιστοιχεί στο pid που γνωρίζουμε θα χρησιμοποιούσαμε τον μηχανισμό rcu (Read-Copy-Update). Ωστόσο τελικά χρησιμοποιήσαμε το lo του πυρήνα tasklist_lo. 4 Περιγραφή υλοποίησης και Τεκμηρίωση