lunes, 28 de noviembre de 2011

Cron/Crontab

CRON
Es un administrador regular de procesos en segundo plano (lo que le llaman demonio). Ejecuta procesos a intervalos regulares (horas, minutos, días). Todo esto se especifica en el fichero crontab.


COMO USARLO
El demonio cron inicia de /etc/rc.d/ o /etc/init.d dependiendo de la distribucion. Cron se ejecuta en el background, revisa cada minuto la tabla de tareas crontab /etc/crontab o en /var/spool/cron en búsqueda de tareas que se deban cumplir. Esto es util por ejemplo para automatizar la actualizacion de un sistema o un buen sistema de respaldos.


CRONTAB
Es un archivo de texto que guarda los comandos a ejecutar en un tiempo especificado. Crontab verificará la fecha y hora en que se debe ejecutar el script o el comando, los permisos de ejecución y lo realizará en el background. Cada usuario puede tener su propio archivo crontab, de hecho el /etc/crontab se asume que es el archivo crontab del usuario root, cuando los usuarios normales (e incluso root) desean generar su propio archivo de crontab, entonces utilizaremos el comando crontab.

 EJEMPLOS Y MANUALES
http://usemoslinux.blogspot.com/2010/11/cron-crontab-explicados.html
http://www.linuxtotal.com.mx/index.php?cont=info_admon_006

Nachos-dfs

I found this:

http://www.cs.sunysb.edu/~stoller/nachos-dfs.html

It is Nachos-dfs (Distributed File System).
It says it have a plus on File System and Network. Maybe it could help somebody :)

N3P

domingo, 27 de noviembre de 2011

Nachos Network



Each running Nachos is a node in the network, this node is emulated as a UNIX process; a network provides the communication between those nodes, these networks are emulated by UNIX sockets.

We can try this by running 'nachos -m 0 -o 1' and 'nachos -m 1 -o 0'simultaneously, in two different terminals. For this, you need implamantation of locks and condition variables.

For now, I'm just explaining nachos' network code.

nettest.cc


MailTest : Function for test out message delivery.
farAddr : machine's ID, to wich we are sending the message.
outPktHdr, OutMailHdr : Outcoming message properties.
inPktHdr, inMailHdr : Incoming message properties.
const char *data = "Hello there" : Message that we are sendig to the other machin, at mailbox #0.
const char *ack = "Got it" : This is gonna be the acknowledgment of receiving the message.
MaxMailSize: Maximum real data that a message can include. (defined in post.cc)


outPktHdr.to = radAddr / outMailHdr.to = 0: Destination machin. Its mailbox it's mailbox #0
outMailHdr.from: Machine that is sending the message. Reply to mailbox #1
outMailHdr.length = strlen(data) + 1: measuring message size ("Hello there!")


postOffice->Send: Sending first message.


postOffice->Receive : Waiting message from the other machine.
0, &inPktHdr, &inMailHdr, buffer: incoming mesagge properties.
fflush(stdout): cleaning output buffer.


Machine is going to know were te incoming message is coming from (inPktHdr.from, inMailHdr.from)
Then it is sending the acknowledgment to the other machine (outPktHdr.to , outMail.Hdr.to)
The size of the outgoing message is measured by outMailHdr.lenght = strleng(ack) +1
Sending the ack: postOffice->Send


Waiting the ack of the second machin from the first sended message.



Done!

----------------------------------------------------------------------
post.cc


This is where we are going to storage our messages.


to: destination mailbox.
from: Where we are going to reply the message.
length: size of the message. Size cannot be negative.


Maximum data that a message can include.


The format of a message we send/recieve is by layers:
- Network Header (PacketHeader)
- Post Office Header (MailHeader)
- data
This class define this format.

Mail ( PacketHeader pktH , MailHeader mailH , const char *msgData ) : concatenate headers to data.
char data[MaxMailSize]: message data. Array of MAXMAILSIZE size.


This class defines the place where we are going to storage the messages.

Mailbox() : Allocate and initialize mail box
~Mailbox() : De-allocate mail box.


SynchList<Mail*> *messages : A mailbox is a list of messages.


Post Office is a collection of mailboxes. This class defines a Post Office.

PostOffice : allocate and initalizate.


De-allocate.


Send a message to the other machine mailbox.


Retrieve the ack.


Wait incoming message. Put them in the correct mailbox.

Interrupt Handler: Next packet can now be sent.


Interrupt Handler: incoming message has arrived.


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


These are the files that nettest.cc includes.





Sockets implementation: Client

#include 
#include
#include

#define SERVER_PORT 9999


these are the libraries which define socket and the internet socket also a server port.

if( ( hp = gethostbyname( argv[1] ) ) == NULL )
{
printf( "%s: %s unknown host\n", argv[0], argv[1] );
exit( 1 );
}
bcopy( hp->h_addr_list[0], (char*)&server_addr.sin_addr, hp->h_length );


this part of code gets the host and if it doesn't get it print a error message


if( ( sd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
{
perror( "client: socket failed" );
exit( 1 );
}
if( connect( sd, (struct sockaddr*)&server_addr,
sizeof(server_addr) ) == -1 )
{
perror( "client: connect FAILED:" );
exit( 1 );
}

printf("connect() successful! will send a message to server\n");
printf("Input a string:\n" );

while( scanf( "%s", buf) != EOF)
{
write(sd, buf, sizeof(buf));
read(sd, buf, sizeof(buf));
printf("SERVER ECHOED: %s\n", buf);
}



hier the socket is created and conected with the client and server



Sockets implementation: Server

if( listen( sd, 1 ) == -1 )
{
perror( "server: listen failed" );
exit( 1 );
}

printf("SERVER is listening for clients to establish a connection\n");

if( ( ns = accept( sd, (struct sockaddr*)&client_addr,
&client_len ) ) == -1 )
{
perror( "server: accept failed" );
exit( 1 );
}

printf("accept() successful.. a client has connected! waiting for a message\n");



the server is listenig for clients and if is conected successfuly then you can write the message....


OUTPUT





Sources:
http://www.dreamincode.net/forums/topic/62891-what-is-fflush/
http://athena.nitc.ac.in/labs/os/html/nettest_8cc.html

lunes, 21 de noviembre de 2011

Sockets en C

Breve explicación de sockets en C:

Modelo cliente-servidor:
Ya todos sabemos que es el modelo mas usado. El cliente hace a petición de algún servicio al servidor.

Una analogía es una persona haciendo una llamada telefónica. Solo una de las partes en la comunicación debe saber el número al cual llamar (cliente), el otro no (servidor). Pero una vez que la conexión se ha hecho, ambos pueden mandar y recibir información.

LOS SOCKETS


Son la forma en que dos programas se transmitan datos, basados en el protocolo TCP/IP. Socket es un "canal de comunicación" entre dos programas.


EL SERVIDOR
Pasos que debe seguir un programa servidor:

  • socket(): crear el socket con esta llamada al sistema.
Esto nos devolverá un descriptor de fichero (file descriptor), tal como lo devolvería open(). Esta función no hace nada, solo devuelve y prepara el file descriptor que el sistema asociará a una conexión de red.
  • bind(): avisar al S.O. que se ha abierto un socket
Asociando nuestro programa con dicho socket. Aquí se indica el "número de servicio" al que se quiere atender. Aun no se atenderán las conexiones de clientes. 

  • listen(): Avisar al sistema de que comience a atender la conexión.
El S.O. anotará la conexión de cualquier cliente para pasárnosla cuando se lo pidamos. El S.O. hace una cola con los clientes y nos los pasa según los pidamos.

  • accept(): Pedir y aceptar las conexiones.
Esta función le indica al S.O. que nos dé al siguiente cliente de la cola. Si no hay, se bloquea hasta que algún cliente se conecte.

  • write() y read(): escribir y recibir datos del cliente.
  • close(): cierre de la comunicación y del socket.
EL CLIENTE
Pasos a seguir :

  • socket(): crear el socket.
  • connect(): solicitar conexión con el servidor.
  • write() y read(): escribir y recibir datos del servidor.
  • close(): cerrar la comnunicación
FICHROS UNIX/LINUX IMPLICADOS

/etc/hosts : Aquí hay una lista de nombres de ordenadores conectados en red y dirección IP de cada uno. Normalmente en esta carpeta, del lado del cliente, se suele colocar el nombre del servidor y su dirección IP. Luego desde el programa, se hace una llamada a la función gethostbyname(), que devuelve una estructura de datos entre los que está la dirección IP.

/etc/services : Este fichero es análogo a una agenda donde tenemos apuntados distintos números telefonicos de personas y demás datos. Desde el programa, cliente y servidor deben hacer una llamada a la función getservbyname(), que devuelve una estructura de datos entre los que está el número de servicio y tipo.


EJEMPLO EN CODIGO

Los siguientes códigos se pueden descargar desde http://www.linuxhowtos.org/C_C++/socket.htm de donde resumiré el funcionamento de los mismos. 

A) SERVIDOR
B)CLIENTE



Para correr estos programas, después de haberlos compilado con el gcc, haremos esto:
./server 31000

./cliente localhost 31000

31000 = número de puerto
localhost = el nombre del host donde se está ejecutando el SERVER, en este caso, se hará en una misma computadora.

El cliente te pedirá escribir un mensaje. Si funciona, el servidor desplegará tu mensaje, y le enviará un mensaje de respuesta al cliente y terminar el programa.


Una explicación detallada del código línea por línea se da en la siguiente página:
http://www.linuxhowtos.org/C_C++/socket.htm

También se explica como lograr, técnicamente, un chat. Puesto que en estos programas el servidor recibe el mensaje del cliente, y el programa termina. Pero con una modificación en la función main() se lograría que se puedan seguir mandando mensajes uno al otro, y resolver lo que en la misma página llaman "el problema del zombie".
En el main se debe agregar :  signal (SIGCHLD, SIG_IGN);
Lo cual le dice al cliente que ignore la señal SIGCHLD para que así el programa no se cierre.



PROGRAMA FUNCIONANDO

Compilación:
- Servidor

- Cliente


Ejecución:
- Servidor 
Aún no hace nada, espera a que el cliente envíe un mensaje


- Cliente 
Ingresa el mismo puerto y el nombre del host donde se encuentra el servidor.
Pide un mensaje.
La respuesta I GOT YOUR MESSAGE, es el mensaje del servidor.


Fuentes:
http://www.linuxhowtos.org/C_C++/socket.htm
http://www.chuidiang.com/clinux/sockets/sockets_simp.php


domingo, 6 de noviembre de 2011

Assignment 2 -> Practical practice



Well we found this kind of tutorial but it doesn´t work because we don't have the system calls implemented

First step is to define a counter varialble in system.h/system.cc to keep track of the current spot to check/update the TLB (also get rid of restoreState bit in Addrspace.cc)

in system.h
int tlbCounter;

in system.cc
tlbCounter = 0;

Next step is alter exception.cc so as to be able to catch PageFaultExpceptions

//in exception.cc
// add a section for
else if (which == PageFaultException)
{
PageFaultHandler(machine->ReadRegister(39));
}
void PageFaultHandler(unsigned int virtualAddr) will serve as the function in which the TLB miss is handled and the TLB is eventually updated
{
unsigned int vpn = virtualAddr/PageSize; //now we have the virtual page number
unsigned int physicalPageNum = -2;
if( virtualAddr is valid) //check the bounds
{
physicalPageNum = currentThread->space->ConvertVPN(vpn); //new method for addrspace class that simply returns the physical page number associated with the
//vpn
//At this simplified level we can now move to update the TLB since we're still preloading memory
tlb[tlbCounter]=currentThread->space->GetEntry(vpn); //new addrspace method to return entry of pagetable
tlbCounter++;
if (tlbCounter==4)
tlbCounter = 0; //tlbcounter ranges from [0,3]
//Now we need to run the machine at this instruction
machine->WriteRegister(PCReg, virtualAddr); //actually leave this off for now
machine->Run(); //actually leave this off for now

}
else //invalid virtual address, print error

Then how to integrate the Swap File

in system.h
#define MAX_SWAP_PAGES big number
#define MAX_SWAP_SIze (PageSize*MAX_SWAP_PAGES)

extern OpenFile* swapFile;

in system.cc

if(fileSystem->Create("swap", MAX_SWAP_SIZE)) //invoke filesystem method to create the file in cur directory with name "swap"
OpenFile* swapFile = fileSystem->Open("swap"); //open it to make it ready for i/o
else
OpenFile* swapFile = NULL; //bad; not enough space or otherwise an error in creating the fil

in system.h
extern Bitmap* swapFileCheck;


in system.cc

Bitmap* swapfileCheck = new Bitmap (MAX_SWAP_PAGES);


In AddrSpace.h
unsigned int* swapFileLoc;
int* location;


In AddrSpace.cc
swapFileLoc = new int[numPages+(MAX_NUMBER_OF_THREADS-1)*numStackPages]; //number of possible entries for this address space
location = new int[numPages+(MAX_NUMBER_OF_THREADS-1)*numStackPages]; (0=main memory; 1=executable; 2=swap file; 3=?)
for(int i = 0; i< (numPages+(MAX_NUMBER_OF_THREADS-1)*numStackPages); i++) inSwap[i]=false;


and thats it... you can see the whole text here


Page Replacement Algorithm FIFO

#include
#include

int fr[3];
int main(void)
{
void display();
int i,j,page[12]={2,3,2,1,5,2,4,5,3,2,5,2};
int flag1=0,flag2=0,pf=0,frsize=3,top=0;
system("cls");
for(i=0;i<3;i++) { fr[i]=-1; } for(j=0;j<12;j++) { flag1=0; flag2=0; for(i=0;i<3;i++) { if(fr[i]==page[j]) { flag1=1; flag2=1; break; } } if(flag1==0) { for(i=0;i=frsize)
top=0;
}
display();
}
printf("Number of page faults : %d ",pf);
getchar();
}
void display()
{
int i;
printf("\n");
for(i=0;i<3;i++) printf("%d\t",fr[i]);
}


OUTPUT



Also we found this code with all of te page replacements algorthms implemented but this appears
Violacion de segmento (´core' generado) I tried to fixed with Cecy's answer but it didn't work anyways
so here is the code...





#include
#include

#define MAX_Program_Size 20
#define MAX_Reference_Sequence_Size 50
#define MAX_WorkingSet_Size 10

int Program_Size = 10;
int Reference_Sequence_Size = 0;
int WorkingSet_Size = 5;

int ReferenceSequence[MAX_Reference_Sequence_Size];

int MemoryAllocation_History[MAX_WorkingSet_Size][MAX_Reference_Sequence_Size];
int Current_MemoryAllocation[MAX_WorkingSet_Size];

int PageFaultCount;
int FIFO_PageFaultCount;
int OPTIMAL_PageFaultCount;
int LRU_PageFaultCount;
int LFU_PageFaultCount;
int MFU_PageFaultCount;
int SequenceFileFlag = 1;


typedef struct {
int PageNumber;
int Count;
} PageEntry;

PageEntry PageTable[MAX_WorkingSet_Size];

int PageFault(int);
int Empty_Store(int);
void exit(int);
int Verbose = 0;

main(int argc, char *argv[])
{
int proc;

if (argc == 2 && strcmp(argv[1],"v") == 0) Verbose = 1;
Init_PageRefSeq();
OPTIMAL();
FIFO();
LRU();
LFU();
MFU();
SUMMERY();
getchar();
}


OPTIMAL()
{

int i;
int j;
PageFaultCount = 0;

Init_Memory();

for (i = 0; i < Reference_Sequence_Size; i++) { if ((j = PageFault(i)) >= 0) {
PageTable[j].Count = UsedNext(i);
UpdateStateHistory(i);
} else {
OPTIMAL_StorePage(i);
UpdateStateHistory(i);
}
}
OPTIMAL_PageFaultCount = PageFaultCount;
if (Verbose) {
printf("OPTIMAL:");
DisplayStateHistory();
}getchar();
}


FIFO()
{
int i;
int j;
PageFaultCount = 0;

Init_Memory();
for (i = 0; i < Reference_Sequence_Size; i++) { if (PageFault(i) >= 0) {
UpdateStateHistory(i);
} else {
FIFO_StorePage(i);
UpdateStateHistory(i);
}
}
FIFO_PageFaultCount = PageFaultCount;
if (Verbose) {
printf("FIFO:");
DisplayStateHistory();
}getchar();
}

LRU()
{

int i;
int j;
PageFaultCount = 0;

Init_Memory();

for (i = 0; i < Reference_Sequence_Size; i++) { if ((j = PageFault(i)) >= 0) {
PageTable[j].Count = i;
UpdateStateHistory(i);
} else {
LRU_StorePage(i);
UpdateStateHistory(i);
}
}
LRU_PageFaultCount = PageFaultCount;
if (Verbose) {
printf("LRU:");
DisplayStateHistory();
}getchar();
}

LFU()
{

int i;
int j;
PageFaultCount = 0;

Init_Memory();

for (i = 0; i < Reference_Sequence_Size; i++) { if ((j = PageFault(i)) >= 0) {
PageTable[j].Count++;
UpdateStateHistory(i);
} else {
LFU_StorePage(i);
UpdateStateHistory(i);
}
}
LFU_PageFaultCount = PageFaultCount;
if (Verbose) {
printf("LFU:");
DisplayStateHistory();
}getchar();
}

MFU()
{

int i;
int j;
PageFaultCount = 0;

Init_Memory();

for (i = 0; i < Reference_Sequence_Size; i++) { if ((j = PageFault(i)) >= 0) {
PageTable[j].Count++;
UpdateStateHistory(i);
} else {
MFU_StorePage(i);
UpdateStateHistory(i);
}
}
MFU_PageFaultCount = PageFaultCount;
if (Verbose) {
printf("MFU:");
DisplayStateHistory();
}getchar();
}

OPTIMAL_StorePage(int i)
{

int j;
int k;
PageFaultCount++;
for (j = 0; j < WorkingSet_Size; j++) { if (Current_MemoryAllocation[j] == -1) { Current_MemoryAllocation[j] = ReferenceSequence[i]; PageTable[j].PageNumber = ReferenceSequence[i]; PageTable[j].Count = UsedNext(i); return; } } j = Get_Most(); Current_MemoryAllocation[j] = ReferenceSequence[i]; PageTable[j].PageNumber = ReferenceSequence[i]; PageTable[j].Count = UsedNext(i); getchar(); } FIFO_StorePage(int i) { int j; int k; PageFaultCount++; for (j = 0; j < WorkingSet_Size; j++) { if (PageTable[j].Count == 0) { Current_MemoryAllocation[j] = ReferenceSequence[i]; PageTable[j].PageNumber = ReferenceSequence[i]; PageTable[j].Count = WorkingSet_Size - 1; for (k = 0; k < WorkingSet_Size; k++) { if ((k != j) && (PageTable[k].PageNumber != -1)) PageTable[k].Count--; } return; } }getchar(); } LRU_StorePage(int i) { int j; int k; PageFaultCount++; for (j = 0; j < WorkingSet_Size; j++) { if (Current_MemoryAllocation[j] == -1) { Current_MemoryAllocation[j] = ReferenceSequence[i]; PageTable[j].PageNumber = ReferenceSequence[i]; PageTable[j].Count = i; return; } } j = Get_Least(); Current_MemoryAllocation[j] = ReferenceSequence[i]; PageTable[j].PageNumber = ReferenceSequence[i]; PageTable[j].Count = i; getchar(); } LFU_StorePage(int i) { int j; int k; PageFaultCount++; for (j = 0; j < WorkingSet_Size; j++) { if (Current_MemoryAllocation[j] == -1) { Current_MemoryAllocation[j] = ReferenceSequence[i]; PageTable[j].PageNumber = ReferenceSequence[i]; PageTable[j].Count = 0; return; } } j = Get_Least(); Current_MemoryAllocation[j] = ReferenceSequence[i]; PageTable[j].PageNumber = ReferenceSequence[i]; PageTable[j].Count = 0; getchar(); } MFU_StorePage(int i) { int j; int k; PageFaultCount++; for (j = 0; j < WorkingSet_Size; j++) { if (Current_MemoryAllocation[j] == -1) { Current_MemoryAllocation[j] = ReferenceSequence[i]; PageTable[j].PageNumber = ReferenceSequence[i]; PageTable[j].Count = 0; return; } } j = Get_Most(); Current_MemoryAllocation[j] = ReferenceSequence[i]; PageTable[j].PageNumber = ReferenceSequence[i]; PageTable[j].Count = 0; getchar(); } int UsedNext(int index) { int i; for (i = index + 1; i < Reference_Sequence_Size; i++) { if (ReferenceSequence[i] == ReferenceSequence[index]) return (i); } return (Reference_Sequence_Size); getchar(); } int PageFault(int i) { int j; for (j = 0; j < WorkingSet_Size; j++) { if (PageTable[j].PageNumber == ReferenceSequence[i]) return (j); } return (-1); getchar(); } int Get_Least() { int j; int index = 0; int min = PageTable[index].Count; for (j = 0; j < WorkingSet_Size; j++) { if (PageTable[j].Count < min) { min = PageTable[j].Count; index = j; } } for (j = 0; j < WorkingSet_Size; j++) { if (Current_MemoryAllocation[j] == PageTable[index].PageNumber) return (j); }getchar(); } int Get_Most() { int j; int index = 0; int max = PageTable[index].Count; for (j = 0; j < WorkingSet_Size; j++) { if (PageTable[j].Count > max) {
max = PageTable[j].Count;
index = j;
}
}
for (j = 0; j < WorkingSet_Size; j++) { if (Current_MemoryAllocation[j] == PageTable[index].PageNumber) return (j); } } UpdateStateHistory(int i) { int j; for (j = 0; j < WorkingSet_Size; j++) { MemoryAllocation_History[j][i] = Current_MemoryAllocation[j]; } } DisplayStateHistory() { int i, j; printf("\n"); for (j = 0; j < WorkingSet_Size; j++) { printf("|"); for (i = 0; i < Reference_Sequence_Size; i++) { if ( MemoryAllocation_History[j][i] == -1) printf(" |"); else printf("%d|", MemoryAllocation_History[j][i]); } printf("\n"); } getchar(); } Init_PageRefSeq() { FILE *fp; int i; int n; if (SequenceFileFlag == 1) { if ((fp = fopen("SequenceFile.txt", "r")) == NULL) { perror("SequenceFile"); exit(1); } while ((n = fscanf(fp, "%d", &ReferenceSequence[i++])) == 1) { printf("%d %d\n", n, ReferenceSequence[i - 1]); } Reference_Sequence_Size=i-1; } else { srand((unsigned) time(0)); for (i = 0; i < Reference_Sequence_Size; i++) ReferenceSequence[i] = (rand() % (Program_Size)); } if (Verbose) { printf("\nSequenceFile:\n"); Display_PageRefSeq(); }getchar(); } Display_PageRefSeq() { int i; printf("[ "); for (i = 0; i < Reference_Sequence_Size; i++) { printf("%d ", ReferenceSequence[i]); } printf("]\n"); getchar(); } Init_Memory() { int j; int i; for (j = 0; j < WorkingSet_Size; j++) { Current_MemoryAllocation[j] = -1; PageTable[j].PageNumber = -1; PageTable[j].Count = 0; for (i = 0; i < Reference_Sequence_Size; i++) MemoryAllocation_History[j][i] = -1; } getchar(); }
SUMMERY()
{
if (Verbose) printf("\n\nSUMMERY:\n");
printf("\nProgram Page Size = %d\nWorking Set Size = %d\nSequenceFile Size = %d",
Program_Size, WorkingSet_Size, Reference_Sequence_Size);
if (!Verbose) {
printf("\n\nSequenceFile Content:\n");
Display_PageRefSeq();
}

printf("\nPage Fault Counts:");
printf("\n\n\tOPTIMAL = %d\n", OPTIMAL_PageFaultCount);
printf("\tFIFO \t= %d\n", FIFO_PageFaultCount);
printf("\tLRU \t= %d\n", LRU_PageFaultCount);
printf("\tLFU \t= %d\n", LFU_PageFaultCount);
printf("\tMFU \t= %d\n\n", MFU_PageFaultCount);
getchar();
}

if you want to try it you have to create a .txt named SequenceFile and put some numbers(it depends on your MAX_Reference_Sequence_Size 50, 50 numbers) in there