Hackathon-ul presupune rezolvarea unui exercițiu propus de către echipa de Sisteme de Operare, din materia parcursă în cadrul cursului si laboratoarelor de SO. Exercițiul este propus spre a fi rezolvat de către o echipă de 2 studenți înscriși la cursul de Sisteme de Operare. Primele 3 cele mai bune implementări vor fi recompensate cu premii. În timpul desfășurării hackathon-ului, echipele vor primi ajutor din partea echipei de SO.
Sâmbătă, 20 mai 2023, în intervalul 9:00 - 17:00.
Hackathonul se desfășoară în format fizic în sala PR706.
Echipele participante se vor putea înscrie la hackathon prin completarea formularului de aici până pe data de 17 mai 2023, ora 20:00. Se vor alege maxim 20 de echipe.
Submisiile vor fi încărcate pe Moodle .
.zip
care conține directorul so/hackathon/lambda-loader
(cu directoarele checker
și skel
).so/hackathon/lambda-loader/skel
trebuie să existe un fișier README.md
care să conțină:Fiecare membru al echipelor câștigătoare va fi premiat, în funcție de locul obținut:
Toate echipele participante sunt eligibile de echivalarea unui punct din notele pentru temă în cadrul materiei Sisteme de Operare (în funcție de complexitatea implementării și stadiului proiectului dezvoltat în timpul hackathonului).
Echipele câștigătoare vor fi anunțate până joi, 25 mai 2023.
Dezvoltarea trebuie făcută exclusiv pe mașinile virtuale SO.
local
(pe calculatoarele voastre sau în mașinile voastre virtuale). Pot să apară diferențe între local și VM-uri, iar, pentru corectare, vom considera doar rezultatele obținute în mașina virtuală de la SO.
Proiectul constă în realizarea unui sistem care permite încărcarea dinamică a unor biblioteci și executarea unor funcții din acestea. Proiectul implementează o arhitectură de tip client - server, unde serverul primește cereri de rulat funcții dintr-o anumită bibliotecă dinamică din sistem.
Funcționalitatea este primul pas spre implementarea unei funcționalități similare AWS Lambda, unde utilizatorul poate să încarce o funcție și să o execute pe diferite servere, la cerere; în cazul proiectului propus, funcțiile sunt deja implementare în biblioteci, iar clientul cere executarea anumitor funcții printr-o comandă trimisă serverului. Mai jos sunt detaliate cerințele principale ale temei, precum și posibile îmbunătățiri.
Pentru implementare se pune la dispoziție funcționalitatea de primire de comenzi (folosind UNIX sockets), care conțin numele unei biblioteci (calea către fișierul cu biblioteca) și opțional numele unei funcții. O comandă trimisă de la client către server are următorul format: <libname> [<funcname> [<filename>]]
unde:
libname
- calea spre biblioteca ce se dorește a fi utilizatăfuncname
- parametru opțional; numele funcției din cadrul bibliotecii; în mod implicit, funcția folosită este numită run
.filename
- parametru opțional; numele unui fișier cu date de intrare dat ca argument funcției funcname
.Datele rezultate în urma execuției vor fi scrise într-un fișier al cărui nume este întors ca răspuns clientului. Fișierul returnat va conține doar mesajele afișate la standard output de către funcția de bibliotecă apelată.
Comunicarea între client și server este următoarea:
Client Server listen() connect() accept() send() -—---libname [funcname [filename]]-----> recv() recv() <--------------outputfile--------------- send()
După primirea și parsarea unui mesaj din partea unui client, serverul apelează secvențial o serie de funcții care au următoarele scopuri:
funcname
lipsește, atunci se apelează funcția run
. Parametrul filename
poate să apară doar atunci când este specificat funcname
.
Funcționalitatea de bază presupune implementarea în C, pentru sistemul de operare Linux, folosind API-ul POSIX:
libipc.so
).checker/client.c
) compilează și se poate conecta la server.checker/client.c
) nu poate fi modificat. Dacă aveți nevoie să modificați clientul de test pentru funcționalități adiționale, creați un client nou de test. Error: <command> could not be executed.
urmat de mesaje de eroare sugestive (Hint: folosiți strerror()).mkstemp()
. Folosiți OUTPUTFILE_TEMPLATE
ca template pentru numele fișierului.OUTPUTFILE_TEMPLATE
.
De ce este nevoie pentru implementarea proiectului propus:
man dlopen
## pornirea serverului so@so:~/skel$ ./server ## client # se execută funcția "run" din libbasic.so so@so:~/checker$ ./client $(realpath libbasic.so) Output file: /home/so/checker/output/out-cfy0fl so@so:~/checker$ cat /home/so/output/out-cfy0fl run # se execută funcția "function" din libbasic.so so@so:~/checker$ ./client $(realpath libbasic.so) function Output file: /home/so/checker/output/out-vc7s03 so@so:~/checker$ cat /home/so/output/out-vc7s03 function # se execută funcția "cat" din libbasic.so cu argumentul "/home/so/checker/Makefile" so@so:~/checker$ ./client $(realpath libbasic.so) cat $(realpath Makefile) Output file: /home/so/checker/output/out-y732bN so@so:~/checker$ cat /home/so/output/out-y732bN CC=gcc [...]
Aveți la dispoziție un checker pentru verificarea parțială a implementării voastre.
so@so~$ cd checker so@so~$ ./checker.sh
Funcționalitatea de bază este obligatorie pentru toate echipele participante. Pe lângă aceasta, pentru departajare, fiecare echipă poate aduce funcționalități adiționale aplicației. Fiecare funcționalitate extra va fi descrisă într-un fișier README (ce presupune și cum ați testat).
Câteva funcționalități extra pe care le puteți avea în vedere (puteți propune voi orice altceva vi se pare necesar):
TIMEOUT
) sau a executat o operație care ar duce la oprirea serverului (ex: acces invalid la memorie, apelează exit/abort/etc). Soluția poate avea diferite niveluri de complexitate, funcție de modul în care este tratată terminarea conexiunii cu clientul (dacă clientul primește, sau nu, un mesaj de eroare) și cum se determină cauza terminării execuției.