Eksamen våren 2012 Operativsystemer

Oppgave 1 - Prosesser (10%)

a) Nei, selvom de underliggende instruksjonene er de samme, vil all kommunikasjon programmet gjør med operativsystemet være forskjellig, inkludert systemkall.

b) Ca 10 minutter. En regneprosess trenger CPU hele tiden og de to prosessene må da bytte på å bruke CPU'en og det tar omtrent dobbelt så lang tid.

c) Fordi OS ikke kjenner den indre logikken i prosessene og må la instruksjonene kjøres sekvensielt. Instruksjonen kan ikke kjøres parallelt, for det kan være at de avhenger av hverandre.

d) Ca 20 minutter. OS vil fordele CPU jevnt mellom de 5, de får da 2/5 eller 40% CPU-tid hver og 40% av 20 minutter er 8 minutter. Alternativt: det er $ 5\cdot8 = 40$ minutter CPU-tid som trengs for å bli ferdig. Hver CPU bidrar like mye og det tar $ 40/2 = 20$ minutter.

e) Ca 20 minutter. Hyperthreading vil ikke han noen effekt på CPU-intensive regnejobber, siden hver core deler ALU. Dermed vil to og to jobber bytte på å bruke ALUen i hver av de to CPU-kjernene og det tar dobbelt så lang tid som en regnejobb.

Oppgave 2 - Kode og maskinkode (15%)

a) 101010 = $ 1\cdot2^5 + 1\cdot2^3 + 1\cdot2^1 = 32 + 8 + 2 = 42$

b) Det største tallet er kun en'ere: 11111111 = $ 2^8 -1 = 255$ (alternativt: $ 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255$).

c)

ADD R0 <- R0 + R1

d)

Etter kjøringen er R0 = 2, R1 = 1 og R2 = 2.

e)

for(i = 0; i < 2; i++) {}
Kaller R0 for i. En tom løkke, siden det ikke blir gjort noe inne i løkken. Alternativt:
int i =0;
while(i<2){i++;}
Eller enda mer presist:
int i =0;
do{
i++;
}while(i != 2);

f)
0 0 1 0 0 0 0 0
0 0 1 0 0 1 0 1
0 0 1 0 1 0 1 0
0 1 0 0 0 0 0 1
1 1 0 0 0 0 1 0
1 1 1 1 0 0 1 1


Oppgave 3 - Tråder, synkronisering og internminne (15%)

a) Det vil lages plass til én enkelt variabel a, den vil være felles for alle tråder og tre variabler b, en for hver tråd.

b) Da vil semaforen fortsatt være låst og andre prosesser(om de oppfører seg korrekt) vil ikke kunne komme inn i kritisk avsnitt.

c) Metoden vil aldri virke. Den fjerner låsen, sjekker at den er borte og går så inn i kritisk avsnitt. Regelrett innbrudd. Etterpå settes "låsen" på igjen. (Kommentar: metoden har et snev av funksjon hvis en annen innbruddstyv blir context switch'et til rett før while og denne setter på låsen. Men den vil da sørge for at to prosesser kommer samtidig inn i kritisk avsnitt (når prosess nr 3 fjerner lockfile) og virker mot sin hensikt.)

d) Det er 512 K / 4K = 128 sider.

e) Nei, instruksjonen er allerede hentet inn og siden det er to registere som legges sammen vil det ikke være behov for å hente noe fra minnet og MMU vil ikke involveres.

f) Ja, siden instruksjonen fører til at en byte blir hentet fra RAM, er MMU involvert da den må oversette addressen fra prosessens virtuelle adresserom til en fysisk adresse. (Kommentar: I noen tilfeller brukes virtuelle adresser i L1-cache og da behøves ikke MMU-oppslag, men i L2 og høyere cache er det vanlig å bruke fysiske adresser. Uansett, da blir ikke byte'en hentet fra RAM).

g) En soft miss fører til at en page-entry må hentes fra RAM og det går relativt fort. En hard miss betyr at en page ikke er i RAM og det tar svært mye lenger tid.

h) Hvis man antar en page-størrelse på 4KByte er det ca 128 tusen entries i Page tabellen. Det er altfor mye til å få plass inne på CPU'en i MMU og TLB, så noe av page tabellen vil også ligge i RAM. Deler av den kan også ligge høyere deler av cahche enn TLB, i L2 og L3.

Oppgave 4 - Disker og RAID (10%)

a) MB = $ 10^6$ bytes og MiB = $ 2^{20}$ bytes = $ 1024 \cdot 1024$ bytes og MiB er derfor størst.

b) På fire av diskene stripes dataene med relativt store striper, på størreles med sektorer eller blocks. På den femte disken lagres den tilhørende pariteten.

c) Fordi det leses samtidig fra fire disker, i parallell. Det går teoretisk sett fire ganger så fort å lese fra dette RAID'et sammenlignet med å lese fra én disk.

d) Siden pariteten er lagret på disk nr 5, kan man gjenskape det som var på disk 3. Hvis pariteten av de gjenværende diskene er forskjellig fra den på paritetsdisken, må det ha vært en en'er på disken, hvis ikke en null.

disk 1 disk 2 disk 3 disk4 paritets-disk
1 0 0 0 1
0 1 1 0 0
1 1 0 1 1
1 0 0 1 0
0 0 0 0 0
1 0 1 1 1



Oppgave 5 - Kommandolinjen (20%)

a) ps aux | sort | grep root

b) ps ux eller ps aux | grep ^root

c) Traverserer gjennom mappen scriptet startes i og alle undermapper. For hver mappe som blir funnet legges den i variablen mappe og mappestien skrives ut på skjermen før teksten 'er en mappe' (Scriptet behandler ikke mappenavn med mellomrom riktig).

d) du -b /var/log/* | sort -r -n | head -5

e) ls C:\Windows | sort Length -des | select -first 5 | Format-table Length, Name

f) Kommandoer i PS kalles Command Lets (CmdLets) og de returnerer objekter siden PS er et objektorientert scripting språk.

Oppgave 6 - Scripting (10%)

a)

Bash:
#! /bin/bash
echo 'Hello World'
Perl:
#! /usr/bin/perl
print 'Hello World';
PS:
'Hello World'

b)

for dir in $(find . -type d)
do
   files=`du -b $dir | sort -r -n | head -5`
   echo -e "De 5 største filene\n $files \n\n"
done

Oppgave 7 - Perl-scripting (20%)

#!/usr/bin/perl
$user = `whoami`;
chomp($user);
if($user ne "root"){ print "Må være root for å kjøre dette skriptet!!!\n"; exit 0;}
$usrpass = "Logg over opprettede brukere\n";
$usrfail = "Logg over brukere som ikke kunne opprettes\n";
my $logfile = "./users.log";
if(!$ARGV[0])
{
    die("Må ha minst ett argument for å kjøre!!");
}
else
{
    $infile=$ARGV[0];
}
-T $infile or die("Filen $infile ser ikke ut til å være en tekst fil\n");
open(INFILE,"<$infile") or die("Kan ikke åpne filen $infile $! \n");
<INFILE>;
while (<INFILE>)
  {
      @userpass=split(',');
      chomp($userpass[0],$userpass[1]);
      if(`grep ^$userpass[0] /etc/passwd`)
      {
	  $countusrfail++;
	  $usrfail.="$userpass[0] kunne ikke opprettes!!\n";
      }
      else
      {
	  `/usr/sbin/useradd -m -g 100 $userpass[0] -p $userpass[1]`;
	  $countusrpass++;
	  $usrpass.="$userpass[0] brukeren opprettet\n";
      }
  }
close(INFILE);

open(OUTFILE,">$logfile") or die("Kan ikke åpne filen $logfile $! \n");
print OUTFILE "$usrpass\n$countusrpass bruker(e) opprettet\n\n";
print OUTFILE "$usrfail\n$countusrfail bruker(e) kunne ikke opprettes\n";
close(OUTFILE);



haugerud 2012-06-29