Enlightenment CVS committal Author : chaos Project : e17 Module : apps/evfs
Dir : e17/apps/evfs/src/bin Modified Files: Makefile.am evfs_main.c evfs_metadata.c Added Files: evfs_worker.c Log Message: * Total rework of server architecture. Few rough edges still, but it passed the torture test. Server now instantiates a new worker process for each client. Cleaner, more secure, and certain elements that shall remain nameless (*cough* samba) - need it for auth. =================================================================== RCS file: /cvs/e/e17/apps/evfs/src/bin/Makefile.am,v retrieving revision 1.26 retrieving revision 1.27 diff -u -3 -r1.26 -r1.27 --- Makefile.am 16 Jul 2007 13:25:22 -0000 1.26 +++ Makefile.am 11 Aug 2007 10:39:02 -0000 1.27 @@ -1,12 +1,12 @@ AUTOMAKE_OPTIONS = 1.7 foreign -bin_PROGRAMS = evfs evfscat evfscopy +bin_PROGRAMS = evfs evfsworker evfscat evfscopy MAINTAINERCLEANFILES = Makefile.in Makefile DEBUGFLAGS = -DDEBUG -DDEBUG_NEST -W -Wall -INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src/include @EET_CFLAGS@ @EVAS_CFLAGS@ @ECORE_CFLAGS@ @XML2_CFLAGS@ $(DEBUGFLAGS) -I. +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src/include @EET_CFLAGS@ @EVAS_CFLAGS@ @ECORE_CFLAGS@ @XML2_CFLAGS@ $(DEBUGFLAGS) -I. -DBINDIR=\""$(bindir)"\" evfs_SOURCES = \ evfs_main.c \ @@ -24,6 +24,22 @@ $(top_srcdir)/src/common/evfs_vfolder.c \ $(top_srcdir)/src/common/evfs_server.c +evfsworker_SOURCES = \ + evfs_worker.c \ + evfs_cleanup.c \ + $(top_srcdir)/src/common/evfs_new.c \ + $(top_srcdir)/src/common/evfs_io.c \ + $(top_srcdir)/src/common/evfs_event_helper.c \ + $(top_srcdir)/src/common/evfs_common.c \ + evfs_server_handle.c \ + evfs_operation.c \ + evfs_operation_tasks.c \ + evfs_metadata.c \ + evfs_metadata_db.c \ + $(top_srcdir)/src/common/evfs_vfolder.c \ + $(top_srcdir)/src/common/evfs_server.c + + evfscat_SOURCES = \ evfscat.c @@ -36,5 +52,7 @@ evfscat_LDADD = $(top_builddir)/src/lib/libevfs.la @XML2_LIBS@ @ECORE_LIBS@ @EVAS_LIBS@ @EET_LIBS@ evfscopy_LDADD = $(top_builddir)/src/lib/libevfs.la @XML2_LIBS@ @ECORE_LIBS@ @EVAS_LIBS@ @EET_LIBS@ + +evfsworker_LDADD = $(top_builddir)/src/lib/libevfs.la @XML2_LIBS@ @ECORE_LIBS@ @EVAS_LIBS@ @EET_LIBS@ =================================================================== RCS file: /cvs/e/e17/apps/evfs/src/bin/evfs_main.c,v retrieving revision 1.61 retrieving revision 1.62 diff -u -3 -r1.61 -r1.62 --- evfs_main.c 25 Jul 2007 17:00:53 -0000 1.61 +++ evfs_main.c 11 Aug 2007 10:39:02 -0000 1.62 @@ -45,8 +45,29 @@ #include <signal.h> #include <errno.h> #include <dirent.h> +#include <ctype.h> + +#define EVFS_TIMER_INTERVAL 0.01 + +static evfs_client* client_worker_waiter = NULL; + +/*An object used for testing, so we can GDB the worker*/ +static Ecore_Ipc_Client* worker_client_waiter = NULL; static evfs_server* server; +static Ecore_Event_Handler *client_add = NULL; +static Ecore_Event_Handler *client_del = NULL; +static Ecore_Event_Handler *client_data = NULL; + +static Ecore_Event_Handler *worker_add = NULL; +static Ecore_Event_Handler *worker_del = NULL; +static Ecore_Event_Handler *worker_data = NULL; + +int ipc_server_data(void *data __UNUSED__, int type __UNUSED__, void *event); +int ecore_timer_enterer(__UNUSED__ void *data); +void evfs_worker_initialise(); +void evfs_load_plugins(); + evfs_client * evfs_client_get(Ecore_Ipc_Client * client) @@ -62,6 +83,38 @@ return serve->clientCounter - 1; } +int evfs_server_worker_spawn(int id) +{ + const char *server_exe = BINDIR "/evfsworker"; + char strid[20]; + + snprintf(strid, 20, "%d", id); + printf("Creating new worker, client ID: %d\n",id); + + if (!access(server_exe, X_OK | R_OK)) { + setsid(); + if (fork() == 0) { + execl(server_exe, strid, NULL); + } + return 1; + } else { + fprintf(stderr, "You don't have rights to execute the evfs worker\n"); + return 1; + } + + return 0; +} + + +void evfs_worker_initialise() +{ + /*Load the plugins */ + evfs_load_plugins(); + evfs_operation_initialise(); +} + + +/* Server -> Client IPC*/ int ipc_client_add(void *data __UNUSED__, int type __UNUSED__, void *event) { @@ -71,17 +124,43 @@ e = (Ecore_Ipc_Event_Client_Add *) event; /*printf("ERR: EVFS Client Connected!!!\n"); */ + /*Make sure we're not the worker server's event*/ + if (ecore_ipc_client_server_get(e->client) != server->ipc_server) return 1; + client = NEW(evfs_client); client->client = e->client; client->server = server; client->prog_command = NULL; client->id = evfs_server_get_next_id(server); ecore_hash_set(server->client_hash, client->client, client); - server->num_clients++; - evfs_event_client_id_notify(client); + printf("Creating new worker..\n"); + + /*Save a reference to this client, so we can allocate the worker child to + * it when it calls back*/ + + if (worker_client_waiter) { + client->worker_client = worker_client_waiter; + ecore_hash_set(evfs_server_get()->worker_hash, worker_client_waiter, client); + worker_client_waiter = NULL; + + evfs_event_client_id_notify(client); + } else { + if (client_worker_waiter) { + printf("EVFS: Worker failed to connect for previous client - Abort\n"); + } else { + client_worker_waiter = client; + + /*Spawn a worker*/ + evfs_server_worker_spawn(client->id); + } + } + + /*ecore_ipc_server_send(client->master, EVFS_MESSAGE_CLIENTID,0,0,0,0,(void*)client,sizeof(int));*/ + + /*Tell our child that we've connected*/ return (1); } @@ -96,6 +175,10 @@ e = (Ecore_Ipc_Event_Client_Del *) event; + /*Make sure we're not the worker server's event*/ + if (ecore_ipc_client_server_get(e->client) != server->ipc_server) return 1; + + client = ecore_hash_get(server->client_hash, e->client); printf("Client %ld, Client Disconnected!!!\n", client->id); @@ -108,8 +191,14 @@ (*EVFS_PLUGIN_FILE(plugin)->functions->evfs_client_disconnect) (client); } - ecore_list_destroy(keys); + /*Kill the child pid*/ + if (client->pid) { + printf("Sending client %p the kill signal\n", client->worker_client); + ecore_ipc_client_send(client->worker_client, EVFS_MESSAGE_KILL,0,0,0,0,NULL,0); + } + ecore_list_destroy(keys); + ecore_ipc_client_del(client->client); ecore_hash_remove(server->client_hash, client); evfs_cleanup_client(client); @@ -123,34 +212,98 @@ Ecore_Ipc_Event_Client_Data *e = (Ecore_Ipc_Event_Client_Data *) event; evfs_client *client; - ecore_ipc_message *msg = - ecore_ipc_message_new(e->major, e->minor, e->ref, e->ref_to, e->response, - e->data, e->size); + /*Make sure we're not the worker server's event*/ + if (ecore_ipc_client_server_get(e->client) != server->ipc_server) return 1; client = evfs_client_get(e->client); - if (!client->prog_command) - { - client->prog_command = evfs_command_new(); - } + /*Onsend to client's worker, if any*/ + if (client->worker_client) { + /*printf("Onsending data to client..%d %d %d %d %d\n", e->major,e->minor,e->ref,e->ref_to,e->response,e->data, e->size );*/ + + ecore_ipc_client_send(client->worker_client,e->major,e->minor,e->ref,e->ref_to,e->response,e->data, e->size); + } else { + printf("No worker client to send to at ipc_client_data\n"); + } - /*True == command finished */ - if (evfs_process_incoming_command(server, client->prog_command, msg)) - { - evfs_command_client *com_cli = NEW(evfs_command_client); + return 1; +} +/*-----------*/ - com_cli->client = client; - com_cli->command = client->prog_command; - client->prog_command = NULL; - ecore_list_append(server->incoming_command_list, com_cli); - } +/*Server -> Worker IPC*/ +int +ipc_worker_add(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Ipc_Event_Client_Data *e = (Ecore_Ipc_Event_Client_Data *) event; + + /*Make sure we're not the daemon server's event*/ + if (ecore_ipc_client_server_get(e->client) != server->worker_server) return 1; + + printf("New worker client to server..\n"); + + if (client_worker_waiter) { + printf("Client %p waiting for worker..\n", client_worker_waiter); + + client_worker_waiter->worker_client = e->client; + ecore_hash_set(evfs_server_get()->worker_hash, e->client, client_worker_waiter); + + evfs_event_client_id_notify(client_worker_waiter); + client_worker_waiter = NULL; + } else { + printf("Added worker to holding queue..\n"); + worker_client_waiter = e->client; + } + + return 1; +} + +int +ipc_worker_del(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Ipc_Event_Client_Del *e; + Ecore_List *keys; + evfs_client *client; + evfs_plugin *plugin; + char *key; + + e = (Ecore_Ipc_Event_Client_Del *) event; + + /*Make sure we're not the daemon server's event*/ + if (ecore_ipc_client_server_get(e->client) != server->worker_server) return 1; - free(msg); + printf("Worker disconnect..\n"); return 1; } int +ipc_worker_data(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + + Ecore_Ipc_Event_Client_Data *e = (Ecore_Ipc_Event_Client_Data *) event; + evfs_client *client; + int id; + + /*Make sure we're not the daemon server's event*/ + if (ecore_ipc_client_server_get(e->client) != server->worker_server) return 1; + + //printf("WORKER: Unrecognised major: %d\n", e->major); + // + /*printf("Sending data to client.. %d %d %d %d %d\n", e->major, e->minor, e->ref, e->ref_to, e->response);*/ + + client = ecore_hash_get(evfs_server_get()->worker_hash, e->client); + if (client) { + ecore_ipc_client_send(client->client, e->major,e->minor,e->ref,e->ref_to,e->response,e->data,e->size); + } else { + printf("Cannot find client at ipc_worker_data\n"); + } + + return 1; +} +/*------------------*/ + + +int evfs_handle_command(evfs_client * client, evfs_command * command) { int cleanup_command=1; @@ -522,6 +675,12 @@ } int +ecore_timer_enterer_server(__UNUSED__ void *data) +{ + return 1; +} + +int main(int argc, char **argv) { /*Init the ipc server */ @@ -533,12 +692,15 @@ server = evfs_server_new(); server->client_hash = ecore_hash_new(ecore_direct_hash, ecore_direct_compare); + + server->worker_hash = + ecore_hash_new(ecore_direct_hash, ecore_direct_compare); server->plugin_uri_hash = ecore_hash_new(ecore_str_hash, ecore_str_compare); server->plugin_meta_hash = ecore_hash_new(ecore_str_hash, ecore_str_compare); server->plugin_vfolder_hash = ecore_hash_new(ecore_str_hash, ecore_str_compare); - server->clientCounter = 0; + server->clientCounter = 1000; server->incoming_command_list = ecore_list_new(); //ecore_idle_enterer_add(incoming_command_cb, NULL); @@ -547,7 +709,7 @@ evfs_object_server_is_set(); /*Add a timer, to make sure our event loop keeps going. Kinda hacky */ - ecore_timer_add(0.01, ecore_timer_enterer, NULL); + server->tmr = ecore_timer_add(1, ecore_timer_enterer_server, NULL); if ((server->ipc_server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, EVFS_IPC_TITLE, 0, @@ -565,19 +727,28 @@ server->ipc_server = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, EVFS_IPC_TITLE, 0, NULL); - ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, ipc_client_add, + client_add = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, ipc_client_add, + NULL); + client_del = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, ipc_client_del, + NULL); + client_data = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, ipc_client_data, NULL); - ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, ipc_client_del, + + server->worker_server = + ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, EVFS_WOR_TITLE, 0, NULL); + + worker_add = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, ipc_worker_add, NULL); - ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, ipc_client_data, + worker_del = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, ipc_worker_del, NULL); + worker_data = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, ipc_worker_data, + NULL); + + } - /*Load the plugins */ - evfs_load_plugins(); evfs_io_initialise(); evfs_vfolder_initialise(); - evfs_operation_initialise(); evfs_trash_initialise(); if (argc >= 2 && !strcmp(argv[1], "-nometa")) =================================================================== RCS file: /cvs/e/e17/apps/evfs/src/bin/evfs_metadata.c,v retrieving revision 1.33 retrieving revision 1.34 diff -u -3 -r1.33 -r1.34 --- evfs_metadata.c 25 Jul 2007 17:00:53 -0000 1.33 +++ evfs_metadata.c 11 Aug 2007 10:39:02 -0000 1.34 @@ -380,6 +380,11 @@ } +void evfs_metadata_initialise_worker() +{ + evfs_metadata_db_init(&db); +} + Evas_List* evfs_metadata_groups_get() { int ret; Evas_List* ret_list = NULL; ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs