Está en la página 1de 10

Solucin al Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria 2002/03.

Tercero Ingeniera Informtica


[Cuestin 1.] Dada la estructura de directorios representada en la Figura 1, y suponiendo que usted se encuentra en el directorio boletines, escriba en una lnea un comando para realizar las siguientes operaciones:
/ +---home | +---practica | +---boletines | +---05-senales | | +---ej1 | | +---ej2 | | +---ej3 | +---07-mensajes | | +---ej1 | | +---ej2 | | +---ej3 | +---08-sockets +---tmp

Figura 1. Estructura directorios. Apartado a .- Borre el directorio 05-senales

rm r 05-senales
Apartado b .- Copie, sin cambiar de directorio, el directorio 07-mensajes y todo su contenido al directorio /tmp

cp r 07-mensajes /tmp
Apartado c .- Pngale los permisos de acceso ms restrictivos al directorio que acaba de copiar en el apartado b, de forma que solamente puedan hacer una copia del mismo los usuarios que pertenecen al mismo grupo de trabajo que usted

chmod 550 /tmp/07-mensajes chmod 440 /tmp/07-mensajes


Apartado d .- Renombre el directorio 08-sockets, como 08-sockets-inet.

mv 08-sockets 08-sockets-inet
Apartado e .- Cree un archivo conten.ndx que contenga una lista ordenada alfabticamente en orden creciente y con las lneas numeradas de todas las entradas que contiene el directorio actual.

ls | sort | cat b > conten.ndx

Puntuacin: 0,5 ptos.

Tiempo estimado: 10 min.

[Cuestin 2.] En la Figura 2 se muestra un extracto de la salida del comando last. A partir de la informacin que ofrece ste, escriba comandos para realizar las siguientes tareas:
i6437 i6437 i6437 so so i7569 i5531 i5531 i7698 pts/21 pts/19 pts/21 pts/20 pts/20 pts/19 pts/19 pts/19 pts/22 81.red-80-33-17. 81.red-80-33-17. 81.red-80-33-17. 62-36-58-151.dia 62-36-58-151.dia cliente-21721601 cliente-21322702 cliente-21322702 152.red-81-40-19 Sat Sat Sat Sat Sat Sat Sat Sat Sat Jun Jun Jun Jun Jun Jun Jun Jun Jun 7 7 7 7 7 7 7 7 7 16:47 16:45 16:23 16:11 15:59 14:12 13:13 13:11 12:27 - 16:48 (00:00) - 16:47 (00:02) - 16:47 (00:23) still logged in - 16:08 (00:09) - 16:28 (02:15) - 13:37 (00:24) - 13:13 (00:01) still logged in

Figura 2: Extracto de la salida del comando last. Apartado a .- Obtenga los usuarios que se encuentran actualmente conectados, ordenados por nombre de usuario. NOTA: Los usuarios conectados son aquellos en los que aparece la cadena still logged in.

last | grep still logged in | sort


Apartado b .- Obtenga el nmero de veces que se ha conectado el usuario que vaya a ejecutar el comando.

last | grep ^$USER | wc l last $USER |wc l


NOTAS: Le puede ser de utilidad la variable de entorno USER. Adems de los comandos vistos en clase, le puede ser de utilidad el comando wc. ste cuenta el nmero de lneas, palabras o letras de un archivo, y su sintaxis la siguiente: wc [opcin...] [archivo...] Si se omite el argumento archivo, wc tomar los datos (naturalmente) de la entrada estndar. La lista de opciones mas importantes es la siguiente: -c Cuenta el nmero de bytes -l Cuenta el nmero de lneas -w Cuenta el nmero de palabras. Como ejemplo, se pueden contar las lneas del archivo /etc/passwd y de esta manera se sabr rpidamente cuantos usuarios tiene definidos el sistema: murillo:/export/home/prof/lensis/reinaqu> wc -l /etc/passwd 2602 /etc/passwd

Puntuacin: 0,5 ptos.

Tiempo estimado:10 min.

Solucin al Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria 2002/03. Tercero Ingeniera Informtica
[Cuestin 3.] Escriba un programa en C, que cree un proceso hijo. Cada n segundos el padre le manda una seal SIGUSR1 al proceso hijo, el cual, cuando reciba la seal, deber ejecutar el programa que se pasa por la lnea de comandos ejecutar <segundos> <comando> Una invocacin posible sera: murillo:/tmp> ejecutar 5 ls la NOTAS: No se permite la utilizacin de la llamada al sistema system() para resolver el ejercicio. Dispone de una variable global, char *argumentos[] que contendr una copia del argv que se recoge en la funcin main(), y que podr utilizar en la funcin manejador_SIGUSR1

Puntuacin: 3 ptos.
char *argumentos[]; int main (int argc, char *argv[]) { int i; int status; int num_segundos; pid_t childpid;

Tiempo estimado: 45 min.

if (argc < 3) { fprintf(stderr, "Usage: %s <segundos> <programa> ...\n", argv[0]); return 1; } sscanf(argv[1], "%d", &num_segundos); childpid=fork(); if (childpid == 0){ /* Hijo */ if (signal(SIGUSR1, manejador) == SIG_ERR) fprintf(stderr, "Error asignando manejador\n"); while (1) pause(); } else if (childpid > 0){ /* Padre */ while(1){ sleep(num_segundos); fprintf(stderr,"Enviando SIGUSR1...%ld\n", childpid); kill (childpid, SIGUSR1); } } return 0; } void manejador(int senal) { int i; ejecutar(&argumentos[2]); if (signal (SIGUSR1, manejador) == SIG_ERR) fprintf(stderr, "Error asignando manejador\n"); }

void ejecutar(char **programa) { pid_t childpid; int status; int waitreturn; childpid = fork(); if (childpid == -1){ fprintf(stderr, "Error en fork\n"); exit (1); } else if (childpid == 0){ /* Hijo */ printf("Ejecutando...%s\n", *programa); if (execvp (*programa, programa) < 0) { fprintf(stderr, "Error..falla la ejecucin del programa\n"); exit(2); } } else { /* Padre */ waitreturn = wait(&status); while ((waitreturn != -1) && (errno != EINTR)) waitreturn = wait (&status); } }

Solucin al Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria 2002/03. Tercero Ingeniera Informtica
[Cuestin 4.] Realice un programa busqueda que dado un fichero o directorio imprima su ruta absoluta. El programa slo realizar la bsqueda en la estructura arbrea del directorio desde donde se hace la llamada al ejecutable. En caso de no encontrarse el archivo o directorio, se deber dar un mensaje de error. Si hubiera ms de una entrada con el mismo nombre, se devolvera la informacin de la primera que se encontrase. Por ejemplo, si tenemos la estructura de directorios de la Figura 3, una /export/home/alumno invocacin al programa sera: murillo:/export/home/alumno>busqueda practicas y el resultado de la ejecucin del mismo, debera ser: /export/home/alumno/asigna/lso/practicas Por el contrario, si hacemos la siguiente invocacin: murillo:/export/home/alumno>busqueda pp el resultado debera ser: No se ha encontrado ninguna entrada llamada pp
+---asigna | +---ada | | +---apuntes | | +---... | +---eda | | +---pract_ant | | +---pract_nuevas | | +---... | +---lso | | +---practicas | | +---apuntes | | +---... +---personal | +---...

Figura 3. Estructura de directorios

Puntuacin: 2,5 ptos.

Tiempo estimado: 30 min.

#define LON_FICHERO 256 #define PATH 255 int busca (char *directorio, char *fichero); int main(int argc, char* argv[]) { char camino[PATH]; int enc; if (argc!=2) { fprintf(stderr, "Usage: %s <directorio>\n", argv[0]); exit (1); } getcwd(camino,PATH); enc=busca (camino,argv[1]); if (enc==0) printf("No se ha encontrado ninguna entrada llamada %s\n", argv[1]); return 0; }

int busca (char *dir,char *entrada) { DIR *dirp; struct dirent *dp; char fichero[LON_FICHERO]; struct stat statbuf; int enc; if ((dirp = opendir (dir)) == NULL) { fprintf(stderr, "Error abriendo directorio %d\n", dir); exit (1); } /* Leemos una por una las restantes entradas del directorio */ dp = readdir(dirp); while (dp != NULL) { /* Formamos la ruta correspondiente al fichero de la entrada de directorio que estamos procesando */ if (strcmp (dp->d_name, ".") && strcmp(dp->d_name, "..")) { if(!strcmp (dp->d_name, entrada)) { printf("Encontrado en:%s/%s\n",dir,entrada); return 1; } sprintf(fichero, "%s/%s", dir, dp->d_name); rdo = stat (fichero, &statbuf); if (rdo != -1 && (statbuf.st_mode & S_IFMT) == S_IFDIR) { enc = busca (fichero,entrada); if (enc==1) return 1; } } dp = readdir(dirp); } closedir (dirp); }

Solucin al Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria 2002/03. Tercero Ingeniera Informtica
[Cuestin 5.] Escriba el cdigo C de una funcin int Crea_Dos_Semaforos(void) que cree un grupo de dos semforos con permisos S_IRUSR | S_IWUSR. En caso de error esta funcin devolver 1, en caso de xito devuelve un entero que identifica al grupo de semforos. Si lo estima conveniente puede hacer uso de la llamada al sistema mktemp que sirve para generar un nombre de archivo nico a partir de una plantilla. Su prototipo es el siguiente: char * mktemp(char * template) dnde template es una cadena de la forma prefijoXXXXXX. Por ejemplo, el siguiente programa: main(){ char tmpfilename[MAX]; sprintf(tmpfilename,"semaph-XXXXXX"); mktemp(tmpfilename); printf("%s\n", tmpfilename); } escribe en la salida estndar una cadena formada por el prefijo semaph- ms seis caracteres de forma que se asegura que no existe ningn archivo en el directorio /tmp con ese nombre.

Puntuacin: 1 pto. Hay que dar los siguientes pasos: 1.- utilizar mktemp para crear un nombre de archivo nico 2.- Crear el archivo 3.- Crear una llave a partir de ese archivo. 4.- Crear un grupo de dos semforos 5.- En el caso de que 2, 3 o 4 fallen hay que devolver -1
int Crea_Dos_Semforos(void) { int result, fd; char nombre_fich[MAX]; key_t llave;

Tiempo estimado: 15 min.

sprintf(nombre_fich,"semaph-XXXXXX"); mktemp(nombre_fich); // Obtengo un nombre de archivo nico fd = open(nombre_fich,O_CREAT,PERMISOS); // Lo creo if (fd != -1) // Si no hay problemas { close(fd); // Cierro el archivo llave = ftok(nombre_fich, 1); // Creo la llave asociada a este archivo if (llave != -1) // Si no hay problemas result = semget(llave, 1, IPC_CREAT | PERMISOS); // Creo el grupo de semforos y lo devuelvo, // en caso de error semget devuelve -1 else result = -1 // Problemas con la llave, devuelvo -1 } else result = -1; // Problemas con el archivo, devuelvo -1 return result; }

[Cuestin 6.] Considrese un sistema de archivos en el que hay un proceso que se encarga de la planificacin central y procesos representantes o proxies que sirven de intermediarios entre dicho planificador central y las aplicaciones de usuario que quieren hacer uso del sistema de archivos. El nmero mximo de archivos abiertos est limitado a MAX_FILE. En caso de que no exista ninguna solicitud de archivo pendiente el planificador central se echa a dormir. Cuando un proceso de usuario necesita un archivo, el sistema operativo crea un proxy o proceso representante. En caso de que el nmero de archivos que tiene que servir el planificador central no exceda de MAX_FILE, el proxy esperar a que el planificador le atienda y terminar con su ejecucin. De lo contrario, se generar un error indicado que la peticin no puede ser atendida finalizando as la ejecucin del proxy. Se pide: a) Haciendo uso de la biblioteca de mensajes realizada en el laboratorio, escriba el cdigo C de los procesos Planificador y Proxy. Omita la inclusin de ficheros de los cabecera. Considere definidas las siguientes funciones: void ProcesaPeticion(Message Peticion): la ejecutar el planificador cada vez que tenga que procesar una nueva peticin de archivo. void ErrorMaximoPermitido(void): la ejecutar el proxy cuando el planificador central no pueda atender la peticin de archivo. Message Crea_Peticion(char nombre_archivo[]): la ejecutar el proxy para crear un mensaje de peticin a partir de un nombre de archivo. Suponga que el proceso de usuario se comunica con su proxy a travs de una variable compartida nombre_archivo. b) De una breve explicacin de cmo resuelve los problemas de sincronizacin entre los proxies y el planificador central.

PROXY dame_archivo PLANIFICADOR dame_archivo PROXY

dame_archivo

APLICACIN USUARIO

dame_archivo

APLICACIN USUARIO

Figura 4. Estructura de procesos.

Puntuacin: 2,5 ptos. Tiempo estimado: 30 min. Este ejercicio es un caso particular del problema del Peluquero Dormiln visto en teora de SSOO. En cualquiera caso, no es necesario conocer la solucin propuesta en teora para resolver este ejercicio. Para resolverlo podemos hacer uso de dos colas de mensajes y una cola o semforo adicional para obtener exclusin mutua entre proxies y planificador: mb_account: para llevar la cuenta de los archivos mb_request: para la peticiones mb_mutex: para obtener exclusin mutua entre los proxies y el planificador en el acceso al buzn mb_account. Tambin se puede hacer uso de una semforo sem_mutex. En la solucin pondremos comentado el cdigo necesario en caso de utilizarlo.

Solucin al Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria 2002/03. Tercero Ingeniera Informtica
Tal y como hemos visto en el laboratorio, en este modulo escribiremos las funciones que se utilizan para crear las colas de mensajes. En este caso solo definimos dos: Iniciador() que sirve para crear/obtener referencia a las colas de mensajes y Inicia_File_Account() que sirve para enviar el buzn que lleva la cuenta de archivos MAX_FILE mensajes vacos.
Iniciador: MailBox mb_ccount, mb_request, mb_mutex; Message mv; void Iniciador(void) { mb_account = MailBox_Create(file_account); mb_request = MailBox_Create(file_request); mb_mutex = MailBox_Create(mutex); //o sem_mutex = Semaph_Create(mutex,1) } void Inicia_File_Account(void) { int i; for (i=0; i++; i<MAX_FILE) MailBox_Send(mb_account, mv) }

Planificador:

este proceso ejecuta un bucle infinito con la siguiente secuencia de pasos: Espera a recibir una peticin (esta espera no es activa) Procesa la peticin Incrementa la cuenta de archivos que pueden procesos (dentro de una seccin crtica protegida por mb_mutex)

Message mv, request; extern MailBox, mb_account, mb_request, mb_mutex; int main(void) { Iniciador(); // Obtengo referencia a los buzones Inicia_File_Account(); // Inicializo el buzn que lleva la cuenta de arch. MailBox_Send(mb_mutex, mv); // Con sem_mutex no hay que hacer nada porque ya // lo hemos inicializado a cero for(;;) { MailBox_Receive(mb_request, & request); // Espero una solicitud Procesa_Peticin(request); // La proceso MailBox_Receive(mb_mutex, &mv); // Semaph_Down(sem_mutex); MailBox_Send(mb_account, mv); // Incremento la cuenta MailBox_Send(mb_mutex,mv); // Semaph_up(sem_mutex); } }

Proxy:

este proceso NO ejecuta ningn bucle infinito y los pasos son los siguientes: Si la cuenta de archivos ha llegado a cero Entonces o Generar error Sino o Decrementar la cuenta de archivos o Crear la peticin o Realizar la peticin Fjese que el acceso a la cuenta de archivos tiene que estar protegido por una regin crtica (gestionada por mb_mutex o sem_mutex)

Message request; extern MailBox, mb_account, mb_request; int main(void) { Iniciador(); // Obtengo referencia a los buzones // En el caso de que los proxies llamaran a Inicia_File_Account(), cada vez que // se creara uno nuevo se aumentar la cuenta de archivos que se pueden tratar // en MAX_FILE MailBox_Receive(mb_mutex, &mv) // Semaph_Down(sem_mutex); if ( ! MailBox_Has_Message(mb_account)) // Si la cuenta a llegado a cero { // MailBox_Send(mb_mutex,mv); o Semaph_Up(sem_mutex); // Tambin puede terminar aqui la seccin crtica ErrorMaximoExcedido(); // Genero un error } else { MailBox_Receive(mb_account, &mv); // Decremento la cuenta // MailBox_Send(mb_mutex,mv); o Semaph_Up(sem_mutex); // Tambin puede terminar aqui la seccin crtica request = Crea_Peticin(nombre_archivo); // Creo una solicitud MailBox_Send(mb_request, request); // Y la envio (al planificador) } MailBox_Send(mb_mutex,mv); } // Semaph_Up(sem_mutex);

10

También podría gustarte