void* conexionNucleo(int socketEscuchaNucleo){ socketNucleo = socketEscuchaNucleo; int seguir = 1; int tamanioPag = umcConfg.configuracionUMC.MARCO_SIZE; while(seguir){ int* header = recibirStream(socketEscuchaNucleo,sizeof(int)); /*int* id = leerHeader(socketEscuchaNucleo); cambiarProceso(*id);*/ if(header==NULL){ header = malloc(sizeof(int)); *header = -1; } log_trace(logConexiones,"Header recibido en Nucleo: %d\n", *header); switch (*header) { case FINALIZACIONPROGRAMA: finalizar_programa(); break; case NUEVOPROGRAMA: inicializar_programa(); break; case CAMBIOPROCESO: change_Proceso(); break; case SOLICITAR: solicitar_Bytes_NL(); break; case ALMACENAR: almacenar_Byte_NL(); break; case 666: enviarStream(socketEscuchaNucleo,666,sizeof(int),&tamanioPag); break; case -1: printf("Se desconecto Nucleo, terminado thread\n"); log_trace(logConexiones,"Nucleo desconectado."); seguir = 0; break; default: break; } free(header); //free(id); } }
void atender_UMC(t_paquete *paquete, int socket_conexion) { int id_mensaje_recibido = paquete->header->id_mensaje; int id_proceso_emisor = paquete->header->id_proceso_emisor; int retorno_de_funcion; switch (id_mensaje_recibido) { case MENSAJE_HANDSHAKE: //TODO: Tomar valor de pagina log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 0] handshake"); if(id_proceso_emisor == PROCESO_UMC) enviar_header_al_UMC(socket_conexion, RESPUESTA_HANDSHAKE); else handshake_error(socket_conexion); break; case MENSAJE_LEER_PAGINA_PARA_ESCRIBIR: case MENSAJE_LEER_PAGINA: //TODO: Revisar/evaluar si el umc estaba pidiendo desde la pagina 1 porque piensa que es la primera (debería de ser 0? revisar). no debería, porque a priori las lecturas les dieron resultados correctos a los chicos, si no explotaria feo log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 1-6] leer_pagina"); t_pagina *pagina = malloc (sizeof (t_pagina)); deserializar_pagina(paquete->payload, pagina); t_pagina_completa *pagina_completa_lectura= malloc (sizeof (t_pagina_completa)); //Se va a usar para responder ok pagina_completa_lectura->id_programa = pagina->id_programa; pagina_completa_lectura->pagina = pagina->pagina; pagina_completa_lectura->offset = pagina->offset; pagina_completa_lectura->tamanio = pagina->tamanio; pagina_completa_lectura->socket_pedido = pagina->socket_pedido; pagina_completa_lectura->valor = malloc(pagina->tamanio); retorno_de_funcion = leer_bytes_swap(pagina, pagina_completa_lectura->valor); t_buffer *buffer_pagina = serializar_pagina(pagina); t_buffer *buffer_pagina_completa_lectura = serializar_pagina_completa(pagina_completa_lectura); //Diferentes retornos de mensajes dependiendo de la situación. PD: Si quedó horrible pero el tiempo está en nuestra contra :P if (retorno_de_funcion != -1 && id_mensaje_recibido == MENSAJE_LEER_PAGINA) enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_LEER_PAGINA, buffer_pagina_completa_lectura); else if (retorno_de_funcion != -1 && id_mensaje_recibido == MENSAJE_LEER_PAGINA_PARA_ESCRIBIR) enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_LEER_PAGINA_PARA_ESCRIBIR, buffer_pagina_completa_lectura); else if (retorno_de_funcion == -1 && id_mensaje_recibido == MENSAJE_LEER_PAGINA) enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_LEER_PAGINA, buffer_pagina); else if (retorno_de_funcion == -1 && id_mensaje_recibido == MENSAJE_LEER_PAGINA_PARA_ESCRIBIR) enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_LEER_PAGINA_PARA_ESCRIBIR, buffer_pagina); free (pagina); free (pagina_completa_lectura->valor); free (pagina_completa_lectura); free (buffer_pagina->contenido_buffer); free (buffer_pagina); free (buffer_pagina_completa_lectura->contenido_buffer); free (buffer_pagina_completa_lectura); break; case MENSAJE_ESCRIBIR_PAGINA_NUEVA: case MENSAJE_ESCRIBIR_PAGINA: log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 2-7] escribir_pagina"); t_pagina_completa *pagina_completa_escritura = malloc (sizeof (t_pagina_completa)); deserializar_pagina_completa(paquete->payload , pagina_completa_escritura); retorno_de_funcion = escribir_bytes_swap(pagina_completa_escritura); t_buffer *buffer_pagina_completa_escritura = serializar_pagina_completa(pagina_completa_escritura); //Diferentes retornos de mensajes dependiendo de la situación. PD: Si quedó horrible pero el tiempo está en nuestra contra :P if (retorno_de_funcion != -1 && id_mensaje_recibido == MENSAJE_ESCRIBIR_PAGINA) enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_ESCRIBIR_PAGINA, buffer_pagina_completa_escritura); else if (retorno_de_funcion != -1 && id_mensaje_recibido == MENSAJE_ESCRIBIR_PAGINA_NUEVA) enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_ESCRIBIR_PAGINA_NUEVA, buffer_pagina_completa_escritura); else if (retorno_de_funcion == -1 && id_mensaje_recibido == MENSAJE_ESCRIBIR_PAGINA) enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_ESCRIBIR_PAGINA, buffer_pagina_completa_escritura); else if (retorno_de_funcion == -1 && id_mensaje_recibido == MENSAJE_ESCRIBIR_PAGINA_NUEVA) enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_ESCRIBIR_PAGINA_NUEVA, buffer_pagina_completa_escritura); free (pagina_completa_escritura); free (buffer_pagina_completa_escritura->contenido_buffer); free (buffer_pagina_completa_escritura); break; case MENSAJE_INICIAR_PROGRAMA: log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 3] iniciar_programa"); t_programa_nuevo *programa_nuevo = malloc (sizeof (t_programa_nuevo)); deserializar_programa_nuevo(paquete->payload , programa_nuevo); retorno_de_funcion = inicializar_programa (programa_nuevo); t_buffer *buffer_con_programa_nuevo = serializar_programa_nuevo(programa_nuevo); if (retorno_de_funcion != -1) enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_INICIALIZAR_PROGRAMA, buffer_con_programa_nuevo); else enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_INICIALIZAR_PROGRAMA, buffer_con_programa_nuevo); free (programa_nuevo); free (buffer_con_programa_nuevo->contenido_buffer); free (buffer_con_programa_nuevo); break; case MENSAJE_FINALIZAR_PROGRAMA: log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 4] finalizar_programa"); t_programa *programa = malloc (sizeof (t_programa)); deserializar_programa(paquete->payload, programa); retorno_de_funcion = finalizar_programa (programa); t_buffer *buffer_con_programa = serializar_programa(programa); if (retorno_de_funcion != -1) enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_FINALIZAR_PROGRAMA, buffer_con_programa); else enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_FINALIZAR_PROGRAMA, buffer_con_programa); free (programa); free(buffer_con_programa->contenido_buffer); free(buffer_con_programa); break; default: log_error(loggerManager,"[Comunicacion UMC] El código de mensaje: %i, no es un mensaje aceptado por el SWAP", id_mensaje_recibido); break; } }
/* ============================================================================ Funcion principal ============================================================================ */ int main(int argc, char *argv[]) { stHeaderIPC *unHeaderIPC = NULL, *stHeaderSwitch = NULL; stMensajeIPC unMensaje; stPCB *unPCB = NULL; t_UMCConfig UMCConfig; pthread_t p_thread, p_threadCpu; char* temp_file = "nucleo.log"; elEstadoActual.path_conf = argv[1]; uint32_t pid_desconectado = 0; int unCliente = 0, maximoAnterior = 0, unSocket, agregarSock; struct sockaddr addressAceptado; /*Inicializacion de las colas del planificador*/ inicializar_pidCounter(); inicializar_cola_ready(); listaBlock = list_create(); consola_crear_lista(); log_create(temp_file, "NUCLEO", -1, LOG_LEVEL_INFO); log_info("Arrancando el Nucleo"); if (elEstadoActual.path_conf == NULL) { log_error("Falta el parametro de configuracion"); exit(-1); } /*Carga del archivo de configuracion*/ if (loadInfo(&elEstadoActual, 0)) { log_error("Error al cargar la configuracion"); exit(-2); } log_info("Configuracion cargada satisfactoriamente..."); /*Se lanza el thread para identificar cambios en el archivo de configuracion*/ pthread_create(&p_thread, NULL, &monitor_configuracion, (void*) &elEstadoActual); inicializarThreadsDispositivos(&elEstadoActual); /*Inicializacion de listas de socket*/ FD_ZERO(&(fds_master)); FD_ZERO(&(read_fds)); /*Inicializacion de socket de escucha*/ elEstadoActual.salir = 0; elEstadoActual.sockEscuchador = -1; /*Iniciando escucha en el socket escuchador de Consola*/ elEstadoActual.sockEscuchador = escuchar(elEstadoActual.miPuerto); FD_SET(elEstadoActual.sockEscuchador, &(fds_master)); log_debug("Se establecio conexion con el socket de escucha..."); /*Seteamos el maximo socket*/ elEstadoActual.fdMax = elEstadoActual.sockEscuchador; /*Conexion con el proceso UMC*/ log_debug("Estableciendo conexion con la UMC..."); elEstadoActual.sockUmc = conectar(elEstadoActual.ipUmc, elEstadoActual.puertoUmc); if (elEstadoActual.sockUmc != -1) { //FD_SET(elEstadoActual.sockUmc, &(fds_master)); unHeaderIPC = nuevoHeaderIPC(ERROR); if (!recibirHeaderIPC(elEstadoActual.sockUmc, unHeaderIPC)) { log_error("UMC handshake error - No se pudo recibir mensaje de respuesta"); log_error("No se pudo conectar a la UMC"); elEstadoActual.salir = 1; } if (unHeaderIPC->tipo == QUIENSOS) { unHeaderIPC = nuevoHeaderIPC(CONNECTNUCLEO); if (!enviarHeaderIPC(elEstadoActual.sockUmc, unHeaderIPC)) { log_error("UMC handshake error - No se pudo enviar mensaje de conexion"); log_error("No se pudo conectar a la UMC"); elEstadoActual.salir = 1; } } liberarHeaderIPC(unHeaderIPC); unHeaderIPC = nuevoHeaderIPC(OK); if (!recibirHeaderIPC(elEstadoActual.sockUmc, unHeaderIPC)) { log_error("UMC handshake error - No se pudo recibir mensaje de confirmacion"); log_error("No se pudo conectar a la UMC"); elEstadoActual.salir = 1; } else { if (recibirConfigUMC(elEstadoActual.sockUmc, &UMCConfig)) { log_error("UMC error - No se pudo recibir la configuracion"); close(unCliente); exit(-2); } agregar_master(elEstadoActual.sockUmc,maximoAnterior); log_info("Paginas por proceso:[%d]", UMCConfig.paginasXProceso); log_info("Tamanio de pagina:[%d]", UMCConfig.tamanioPagina); elEstadoActual.tamanio_paginas = UMCConfig.tamanioPagina; } liberarHeaderIPC(unHeaderIPC); } else { log_error("No se pudo conectar a la UMC"); elEstadoActual.salir = 1; } /*Ciclo Principal del Nucleo*/ log_info("............................................................................."); log_info("..............................Esperando Conexion.............................\n\n"); fflush(stdout); while (elEstadoActual.salir == 0) { read_fds = fds_master; if (seleccionar(elEstadoActual.fdMax, &read_fds, 0) == -1) { log_error("Error Preparando el Select"); break; } for (unSocket = 0; unSocket <= elEstadoActual.fdMax; unSocket++) { if (FD_ISSET(unSocket, &read_fds)) { /*Nueva conexion*/ if (unSocket == elEstadoActual.sockEscuchador) { unCliente = aceptar(elEstadoActual.sockEscuchador, &addressAceptado); unHeaderIPC = nuevoHeaderIPC(QUIENSOS); if (!enviarHeaderIPC(unCliente, unHeaderIPC)) { log_error("Cliente Handshake error - No se puede enviar el mensaje QUIENSOS"); liberarHeaderIPC(unHeaderIPC); close(unCliente); break;/*Sale del for*/ } liberarHeaderIPC(unHeaderIPC); unHeaderIPC = nuevoHeaderIPC(ERROR); if (!recibirHeaderIPC(unCliente, unHeaderIPC)) { log_error("Cliente Handshake error - No se puede recibir el mensaje"); liberarHeaderIPC(unHeaderIPC); close(unCliente); break;/*Sale del for*/ } /*Identifico quien se conecto y procedo*/ switch (unHeaderIPC->tipo) { case CONNECTCONSOLA: stHeaderSwitch = nuevoHeaderIPC(OK); if (!enviarHeaderIPC(unCliente, stHeaderSwitch)) { log_error("Handshake Consola - No se pudo enviar el OK"); liberarHeaderIPC(stHeaderSwitch); close(unCliente); break;/*Sale del switch*/ } liberarHeaderIPC(stHeaderSwitch); log_info("Nueva consola conectada"); agregarSock = 1; /*Agrego el socket conectado a la lista Master*/ if (agregarSock == 1) { agregar_master(unCliente, maximoAnterior); agregarSock = 0; } /* Recibo Programa */ if (!recibirMensajeIPC(unCliente, &unMensaje)) { log_error("No se puede recibir el programa a procesar"); break;/*Sale del switch*/ } else { if (unMensaje.header.tipo == SENDANSISOP) { /*metadata_desde_literal hace un malloc adentro*/ int cantidadDePaginasCodigo = calcular_cantidad_paginas(unMensaje.header.largo, UMCConfig.tamanioPagina); /***Creacion del PCB***/ unPCB = crear_pcb(unCliente, cantidadDePaginasCodigo, elEstadoActual.stackSize, &unMensaje); if (unPCB == NULL) { log_error("Error al crear el PCB... se cierra la consola\n"); quitar_master(unCliente, maximoAnterior); close(unCliente); break;/*Sale del switch*/ } if (inicializar_programa(unPCB, (char *)unMensaje.contenido, elEstadoActual.sockUmc) == EXIT_FAILURE) { log_error("No se pudo inicializar el programa"); quitar_master(unCliente, maximoAnterior); close(unCliente); break;/*Sale del switch*/ } /* Inicializada la consola la agrego a consolas activas */ agregar_consola(unCliente, unPCB->pid); /*Cuando se usa mensajeIPC liberar el contenido*/ free(unMensaje.contenido); ready_productor(unPCB); log_info("PCB [PID - %d] NEW a READY\n", unPCB->pid); fflush(stdout); } } break; case CONNECTCPU: stHeaderSwitch = nuevoHeaderIPC(OK); if (!enviarHeaderIPC(unCliente, stHeaderSwitch)) { liberarHeaderIPC(stHeaderSwitch); log_error("CPU error - No se pudo enviar OK"); close(unCliente); break;/*Sale del switch*/ } liberarHeaderIPC(stHeaderSwitch); if (pthread_create(&p_threadCpu, NULL, (void*) consumidor_cpu, (void*) &unCliente) != 0) { log_error("No se pudo lanzar el hilo correspondiente al cpu conectado"); close(unCliente); break;/*Sale del switch*/ } log_info("Se lanza hilo de atencion a CPU conectado"); fflush(stdout); break; default: break; } if (unHeaderIPC != NULL) { liberarHeaderIPC(unHeaderIPC); } } else { /*Conexion existente*/ log_debug("Recibi otro evento de un cliente ya conectado"); if (!recibirMensajeIPC(unSocket, &unMensaje)) { log_info("Desconexion detectada"); // Desconexion de una consola pid_desconectado = borrar_consola(unSocket); // Desconexion de la UMC if (unSocket == elEstadoActual.sockUmc) { log_info("Se perdio conexion con la UMC..."); elEstadoActual.salir = 1; cerrarSockets(&elEstadoActual); } if (unSocket == elEstadoActual.sockEscuchador) { log_debug("Se perdio conexion..."); } /*Saco el socket de la lista Master*/ quitar_master(unSocket, maximoAnterior); fflush(stdout); } } } } } destruir_planificador(); destruir_lista_dispositivos(&elEstadoActual); consola_destruir_lista(&elEstadoActual); cerrarSockets(&elEstadoActual); finalizarSistema(&unMensaje, unSocket, &elEstadoActual); log_info("Fin del programa"); return 0; }