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



Loadable Modules - Library Interposition

Στην αυτή την άσκηση, στο πρώτο μέρος, θα εξοικειωθείτε με την χρήση προγραμμάτων που υποστηρίζουν Loadable Modules. Τα Loadable Modules είναι κοινόχρηστες βιβλιοθήκες (shared libraries) τα οποία προσθέτουν στο πρόγραμμα λειτουργικότητα τύπου plugin. Το κύριο πρόγραμμα μπορεί κατά την διάρκεια λειτουργίας, ανάλογα τις ανάγκες του, να φορτώσει μια βιβλιοθήκη η οποία θα περιέχει τις κατάλληλες συναρτήσεις για να διεκπεραιώσει την ζητούμενη λειτουργικότητα.

Στο δεύτερο μέρος θα χρησιμοποιήσετε την τεχνική Library Interposition για να αλλάξετε την λειτουργικότητα του προγράμματος του πρώτου μέρους, χωρίς να χρειαστεί να αλλάξετε τον κώδικά του ή των κοινόχρηστων βιβλιοθηκών (modules). Η συγκεκριμένη τεχνική είναι δυνατή με την χρήστη της μεταβλητής περιβάλλοντος LD_PRELOAD, η οποία επιτρέπει την φόρτωση κοινόχρηστης βιβλιοθήκης πριν την εκτέλεση του προγράμματος.

Loadable Modules

Για το πρώτο μέρος της άσκησης θα χρειαστεί να δημιουργήσετε ένα πρόγραμμα το οποίο θα υποστηρίζει Loadable Modules. Το πρόγραμμα σας θα δέχεται ως είσοδο ένα αρχείο και ανάλογα με το είδος αρχείου, θα φορτώνει δυναμικά το αντίστοιχο mοdule το οποίο θα εκτελεί την επεξεργασία του αρχείου εισόδου.

Συγκεκριμένα, το κυρίως πρόγραμμα αρχικά θα διαβάζει ένα αρχείο ρυθμίσεων το οποίο θα περιέχει την πληροφορία για κάθε είδος αρχείου, ποιο module θα πρέπει να κληθεί απο το κυρίως πρόγραμμα. Για τους σκοπούς της άσκησης θα υλοποιήσετε 2 modules για είδη αρχείων .txt και .csv (Comma Seperated Values).

Παράδειγμα αρχείου ρυθμίσεων με ενδεικτική ονομασία assign4.conf

txt:libassign4txt.so
csv:libassign4csv.so


Τα αρχεία εισόδου με κατάληξη txt θα έχουν το παρακάτω format:

Name: Bob
Salary: 12345

Name: Alice
Salary: 54321


Τα αρχεία εισόδου με κατάληξη csv θα έχουν το παρακάτω format:

Name,Salary
Bob,12345
Alice,54321


Το πρόγραμμα σας θα ελέγχει την κατάληξη του αρχείου εισόδου και εφόσον υπάρχει στην πρώτη στήλη του αρχείου ρυθμίσεων, θα φορτώνει το αντίστοιχο module της δεύτερης στήλης. Αν δεν υπάρχει η κατάληξη στο αρχείο ρυθμίσεων ή το module, το κύριο πρόγραμμα θα τερματίζει.

Τα modules θα περιέχουν μία συνάρτηση η οποία θα δέχεται ως όρισμα το file descriptor του αρχείου εισόδου. Στη συνέχεια θα διαβάζουν το αρχείο και θα το μετατρέπουν. Για παράδειγμα, αν το πρόγραμμα έχει είσοδο txt αρχείο, το υπεύθυνο module libassign4txt.so θα παράγει το αντίστοιχο csv αρχείο. Αν το πρόγραμμα έχει είσοδο csv αρχείο, το υπεύθυνο module libassign4csv.so θα παράγει το αντίστοιχο txt αρχείο.

Παράδειγμα εκτέλεσης:

>./assign4 filename.txt

Output:

>cat filename.csv
Name,Salary
Bob,12345
Alice,54321


Library Interposition

Για το δεύτερο μέρος της άσκησης, θα χρησιμοποιήσετε την μεταβλητή περιβάλλοντος LD_PRELOAD, η οποία επιτρέπει να φορτωθούν κοινόχρηστες βιβλιοθήκες (shared libraries) πρίν την εκτέλεση του προγράμματος. Θα δημιουργήσετε μια βιβλιοθήκη η οποία θα αντικαθιστά την συνάρτηση που χρησιμοποιείτε στα modules του πρώτου μέρους για την αποθήκευση των δεδομένων στο δίσκο (για παράδειγμα την fwrite). Η βιβλιοθήκη θα εφαρμόζει τον αλγόριθμο του Καίσαρα ROT13 στα δεδομένα εισόδου της συνάρτησης fwrite (ή της αντίστοιχης του προγράμματος σας). O ROT13 αντικαθιστά κάθε χαρακτήρα με τον χαρακτήρα που βρίσκεται 13 θέσεις παρακάτω στο αλφάβητο. Έπειτα, η βιβλιοθήκη θα καλεί την πραγματική fwrite (ή την αντίστοιχη του προγράμματος σας) με τα δεδομένα που έχουν γίνει ROT13. Εκτελέστε το πρόγραμμα του πρώτου μέρους με την χρήση του LD_PRELOAD και της βιβλιοθήκης αντικατάστασης της fwrite (ή της αντίστοιχης του προγράμματος σας). Θα πρέπει το αρχείο που δημιουργείται κατά την εκτέλεση, να είναι "κρυπτογραφημένο" με τον αλγόριθμο ROT13.

Παράδειγμα εκτέλεσης (bash shell):

>LD_PRELOAD=./encrypt.so ./assign4 filename.txt

Output:

>cat filename.csv
Anzr,Fnynel
Obo,12345
Nyvpr,54321


Reference - man pages

Ένα man page περιγράφει τον τρόπο λειτουργίας ενός προγράμματος, ενός system call ή μιας library function. Η εμφάνιση ενός man page γίνεται με τη χρήση της εντολής:

man(1)

Για να δείτε το man page (σε Linux) που αναφέρεται στη foo(N), κάνετε:

% man -S N foo

Ο συμβολισμός foo(N) αναφέρεται στο man page που περιγράφει τη foo στη κατηγορία (section) 'Ν'.

Λίστα με χρήσιμα man pages για την Aσκηση 4

Σας παραθέτουμε man pages που μπορεί να χρειαστείτε για την υλοποίηση της άσκησης. Η παρακάτω λίστα δεν είναι δεσμευτική. Μπορείτε να χρησιμοποιήσετε και εναλλακτικούς τρόπους.

dlopen(3), dlsym(3), dlclose(3), dlerror(3), ldd(1)
 
Κάποιες από τις βιβλιοθήκες που θα πρέπει να χρησιμοποιήσετε είναι οι παρακάτω:
#include <unistd.h>
#include <dlfcn.h>

Κατά το link θα χρειαστεί να προσθέσετε την παράμετρο -ldl.

Πληροφορίες για τον ROT13

Παρατηρήσεις

  1. Η άσκηση είναι ατομική. Τυχόν αντιγραφές μπορούν να ανιχνευθούν εύκολα από κατάλληλο πρόγραμμα και θα μηδενιστούν. Συμπεριλάβετε το όνομα σας και το λογαριασμό σας (account) σε όλα τα αρχεία.
  2. Κατασκευάστε ένα αρχείο Makefile, έτσι ώστε πληκτρολογώντας make all να γίνεται η μεταγλώττιση (compilation) του προγράμματος και να παράγεται το εκτελέσιμο αρχείο και οι απαραίτητες βιβλιοθήκες. Επίσης πληκτρολογώντας make clean να καθαρίζονται όλα τα περιττά αρχεία, και να μένουν μόνο τα αρχεία που χρειάζονται για τη μεταγλώττιση.
  3. Επιπλέον, γράψτε και ένα αρχείο readme.txt το πολύ 30 γραμμών που να περιέχει επεξηγήσεις για τον τρόπο υλοποίησης.
  4. Τοποθετήστε σε ένα κατάλογο όλα τα αρχεία που χρειάζονται για την άσκηση 4. Παραδώστε τα παραπάνω αρχεία χρησιμοποιώντας το πρόγραμμα submit (πληκτρολογήστε submit assignment_4@hy345 directory_name από τον κατάλογο που περιέχει τον κατάλογο directory_name με τα αρχέια της άσκησης).
  5. Σε πολλές περιπτώσεις τα ονόματα των συναρτήσεων βιβλιοθήκης είναι ενδεικτικά. Μπορείτε να χρησιμοποιήσετε όποια σας βολεύουν.