Scribe Notes

1/23/08

 

by:

Jeff Lee

Hagop Hagopian

Alan Zhao

 

Orthogonality

  y   z

  |  /

  | /

  |/___ x    (3-D axis grid)

 

any combination of (x,y,z) works

                             features

 

OS

 

we can explore the space by combining features (like using x,y,z to define a position in a space), use this to design systems

 

examples of non-orthogonality

Java: every value is an object

        put them into hash tables

        subclass them

        except for; int, double

                                Double <--- object

 

Orthogonal axes for accessing files:

open

close

read

write

 

is this enough?

 

create a temp file

                                             read_write                        truncate any existing file to 0 length

                                                    \                                      \

    int fol = open ("/tmp/CS111",O_RDWR | O_CREAT | O_TRUNC, 0666)

                                   /                                 \                                            \

                         don't really care              create file if it doesnt exist          mode argument - specifies permission of

                                                   Why all these options?                                                      any newly created file

                                                                                                                    used only in some cases, awkward

 

Alternative primitives

(steal this from UNIX v7   1979)

 

int fd = creat("temp/cs111", 0666)   ==   open("temp/cs111",O_CREAT, 0666)

             ( no O_CREAT )

 

pros/cons

+ push complexity of the file creation into a different axis

- complicates code that may want open or create, depending on options

- implemention/documentation overlap quite a lot

 

 

SIDE NOTE 1:

open options

O_RDONLY - read

O_WRONLY - write

O_RDWR   - read/write

O_CREAT - boolean value, create if needed

O_TRUNC - truncate if it exists

 

 

circa 1985

CREAT defined to mean open(...,O_WRONLY|O_CREAT|O_TRUNC,...)

new axis: what flags can you give open?

 

combinations that are questionable

(...,O_RDONLY|O_CREAT|O_TRUNC,...) (..., O_RDONLY|O_TRUNC,...)

 

Permissions are determined by two things

1) Application - specifies most generous permission

2) umask - restricts permissions according to user preferences

   $umask 022 <- bits to turn off when files are created

$umask 077 = trust only myself

0666-022 = 0644

 

 

SIDE NOTE 2:

unix permissions

ls -l

-rwxr-xr-x

111,101,101

  7    5     5

owner group other

read write execute

 

-rw-rw-rw

110 110 110

  6     6    6

 

SIDE NOTE 3:

Unix: orthogonality vs compactness

 

1.  Compactness is the property that a design can fit inside the OS without intervening other parts.

 

2.  When the OS has too many components, (in other words: extremely orthogonal), each component

      will interrupt other components or they will compete to get enough memory to run their processes.

 

3.  If 2 happens, a racing condition was raised. 

 

 

open("f",O_WRONLY|O_CREAT, 0)

 

2 processes executing program at same time

1) fd = open ("tmp/cs111a",O_RDWR|O_CREAT|O_TRUNC,0666)

2) fd = open ("tmp/cs111b",O_RDWR|O_CREAT|O_TRUNC,0666)

we dont want this! we want each process to have its own file (assume we are writng the code)

 

Race Condition - bug engendered by two processes "racing" to access the same resource

 

Possible solutions

A) File locking: 1st opener wins

B) open with permission 0, remove when done

       -pain to have unreadable files

C) use differnet file names: derived from time of day, process id, host name, random number, etc.

       -crash means everyone is locked out

D) look at all files in /tmp choose a name not in that list

       -slow

       -doesn't work due to race condition

E) check where file exists

       if so, sleep 1 sec, try again

       if not, open

       use file

       remove it

 

introduce 4th flag: O_EXCL, don't open file if it already exists, no race conditions

                           always used with O_CREAT

 

char file[100]

do

  generate_randomname(file)

while (fd = open(file,O_RDWR|O_CREAT|O_EXCL,0666) < 0 && errno == Eexist)

 

 

SIDE NOTE 4:

create a temp file

int mkstemp(char* template) <- some OS's don't pass in a value

/                                   \

fd of a new file          "tmp/abcdxxxxxx"   6 x's

 

this is a library function, not a system call

 

 

 

This is a primitive in some OS's

pro/cons

+ let OS choose file location

+ let OS free file

+ OS need not worry about persistence

 

 

SIDE NOTE 5:

locking files                              struct flock*

                         F_SETLK        /

   int s = fcntl(fd,F_SETLKW, P)

                         F_GETLK       \

                                                pointer

                                                     \

l_type

l_whence

l_start

l_len

l_pid

<- read/write/unlock

<- SEEK_SET, SEEK_CUR, SEEK_END

<- starting offset

<- size of region locked

<- which pid is being looked at

 


--------------------------------------------------------------------

    |  lock  |                                    |   lock   |

--------------------------------------------------------------------

        /                                                 \

i want a "write lock"             i want a read lock

            exclusive                             shared

 

honor system, with respect to read+write

advisory locks (not mandatory)

pros

+ I/O is a bit faster

+ minimizes hassle

 

cons

- "dishonorable" processes

- program crashes with a lock => locks evaporate

- overlapping locks collide within a process, freeing up one lock frees up part of another lock

- fork : child lacks locks

 

 

primitives for process creation/destruction

                               parent stuff/child process id

pid_t fork (void);                              or 0

                                                        or -1

 

int execvp(char const* file, char* const *argv);

always returns -1;    errno says failure reason

 

                                                               WNOHANO = don't wait

                                                                /

pid_t waitpid(pid_t pid, int* status, int options)

                            /                    \

              process waiting for        child's exit status

                     or any

 

 

child stuff       8 bit

                    /

void_exit(status)

void exit(status)

int main (...) {return 27;}

 

void print_date(void){

    pid_t p = fork();

    if (p<0)

         error();         //error calls exit

    if (p == 0){

         char* const args[2] = {"/bin/date",NULL};

         execvp(args[0],args);

         error();

    }

    int status;

    if (waitpid(p,&status,0)< 0) error();

    if (!WIFEXITED(status) || WEXITSTATUS(status)!=0) error();

}

 

int posix_spawnp(pid_t* restrict_pid, const char* restrict_file,

                                     const posispawnfileactions_t* file_acts,       describes all

                                     const posix_spawn_attract* restrict_attrp,     "interesting things"

                                     char* const* restrict_argv,

                                     char* const* restrict_envp);