diff options
Diffstat (limited to 'src/backend/port/beos/support.c')
-rw-r--r-- | src/backend/port/beos/support.c | 344 |
1 files changed, 0 insertions, 344 deletions
diff --git a/src/backend/port/beos/support.c b/src/backend/port/beos/support.c deleted file mode 100644 index 820cb80f3a3..00000000000 --- a/src/backend/port/beos/support.c +++ /dev/null @@ -1,344 +0,0 @@ -/*------------------------------------------------------------------------- - * - * support.c - * BeOS Support functions - * - * Copyright (c) 1999-2001, Cyril VELTER - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -/* Support Globals */ -port_id beos_dl_port_in = 0; -port_id beos_dl_port_out = 0; -sem_id beos_shm_sem; - -/* Global var containing the postgres path */ -extern char my_exec_path[]; - - -/* Shared library loading doesn't work after fork in beos. The solution is to use an exact -copy of the process and use it to perform the loading, then just map the Text and Data segment -of the add-on in our address space. Both process must have the exact same memory mapping, so -we use the postgres executable. When it's lauched with the -beossupportserver parameter, the -postgres executable just run a loop to wait command on a port. Its only action is to load the addon, -the beos_dl_open will then remap the good areas in the backend address space. */ - - -image_id -beos_dl_open(char *filename) -{ - image_id im; - - /* If a port doesn't exist, lauch support server */ - if ((beos_dl_port_in <= 0) || (beos_dl_port_out <= 0)) - { - /* Create communication port */ - beos_dl_port_in = create_port(50, "beos_support_in"); - beos_dl_port_out = create_port(50, "beos_support_in"); - - - if ((beos_dl_port_in <= 0) || (beos_dl_port_out <= 0)) - { - elog(WARNING, "error loading BeOS support server: could not create communication ports"); - return B_ERROR; - } - else - { - char Cmd[4000]; - - /* Build arg list */ - sprintf(Cmd, "%s -beossupportserver %d %d &", my_exec_path, (int) beos_dl_port_in, (int) beos_dl_port_out); - - /* Lauch process */ - system(Cmd); - } - } - - /* Add-on loading */ - - /* Send command '1' (load) to the support server */ - write_port(beos_dl_port_in, 1, filename, strlen(filename) + 1); - - /* Read Object Id */ - read_port(beos_dl_port_out, &im, NULL, 0); - - /* Checking integrity */ - if (im < 0) - { - elog(WARNING, "could not load this add-on"); - return B_ERROR; - } - else - { - /* Map text and data segment in our address space */ - char datas[4000]; - int32 area; - int32 resu; - void *add; - - /* read text segment id and address */ - read_port(beos_dl_port_out, &area, datas, 4000); - read_port(beos_dl_port_out, (void *) &add, datas, 4000); - /* map text segment in our address space */ - resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area); - if (resu < 0) - { - /* If we can't map, we are in reload case */ - /* delete the mapping */ - resu = delete_area(area_for(add)); - /* Remap */ - resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area); - if (resu < 0) - elog(WARNING, "could not load this add-on: map text error"); - } - - /* read text segment id and address */ - read_port(beos_dl_port_out, &area, datas, 4000); - read_port(beos_dl_port_out, (void *) &add, datas, 4000); - /* map text segment in our address space */ - resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area); - if (resu < 0) - { - /* If we can't map, we are in reload case */ - /* delete the mapping */ - resu = delete_area(area_for(add)); - /* Remap */ - resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area); - if (resu < 0) - elog(WARNING, "could not load this add-on: map data error"); - } - - return im; - } -} - -void -beos_dl_sym(image_id im, char *symname, void **fptr) -{ - /* Send command '3' (get symbol) to the support server */ - write_port(beos_dl_port_in, 3, symname, strlen(symname) + 1); - write_port(beos_dl_port_in, im, NULL, 0); - - /* Read sym address */ - read_port(beos_dl_port_out, (int32 *) (fptr), NULL, 0); - - if (fptr == NULL) - elog(WARNING, "loading symbol \"%s\" failed", symname); -} - -status_t -beos_dl_close(image_id im) -{ - /* unload add-on */ - int32 resu; - - write_port(beos_dl_port_in, 2, &im, 4); - read_port(beos_dl_port_out, &resu, NULL, 0); - return resu; -} - -/* Main support server loop */ - -void -beos_startup(int argc, char **argv) -{ - if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - 10, "postmaster")) - { - /* - * We are in the postmaster, create the protection semaphore for - * shared mem remapping - */ - beos_shm_sem = create_sem(1, "beos_shm_sem"); - } - - if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0) - { - /* We are in the support server, run it ... */ - - port_id port_in; - port_id port_out; - - /* Get back port ids from arglist */ - sscanf(argv[2], "%d", (int *) (&port_in)); - sscanf(argv[3], "%d", (int *) (&port_out)); - - /* Main server loop */ - for (;;) - { - int32 opcode = 0; - char datas[4000]; - - /* - * Wait for a message from the backend : 1 : load a shared object - * 2 : unload a shared object any other : exit support server - */ - read_port(port_in, &opcode, datas, 4000); - - switch (opcode) - { - image_id addon; - image_info info_im; - area_info info_ar; - void *fpt; - - /* Load Add-On */ - case 1: - - /* Load shared object */ - addon = load_add_on(datas); - - /* send back the shared object Id */ - write_port(port_out, addon, NULL, 0); - - /* Get Shared Object infos */ - get_image_info(addon, &info_im); - - /* get text segment info */ - get_area_info(area_for(info_im.text), &info_ar); - /* Send back area_id of text segment */ - write_port(port_out, info_ar.area, info_ar.name, strlen(info_ar.name) + 1); - /* Send back real address of text segment */ - write_port(port_out, (int) info_ar.address, info_ar.name, strlen(info_ar.name) + 1); - - - /* get data segment info */ - get_area_info(area_for(info_im.data), &info_ar); - /* Send back area_id of data segment */ - write_port(port_out, info_ar.area, info_ar.name, strlen(info_ar.name) + 1); - /* Send back real address of data segment */ - write_port(port_out, (int) info_ar.address, info_ar.name, strlen(info_ar.name) + 1); - break; - /* UnLoad Add-On */ - case 2: - - /* - * Unload shared object and send back the result of the - * operation - */ - write_port(port_out, unload_add_on(*((int *) (datas))), NULL, 0); - break; - /* Cleanup and exit */ - case 3: - - /* read image Id on the input port */ - read_port(port_in, &addon, NULL, 0); - - /* Loading symbol */ - fpt = NULL; - - - if (get_image_symbol(addon, datas, B_SYMBOL_TYPE_TEXT, &fpt) == B_OK); - { - /* - * Sometime the loader return B_OK for an inexistant - * function with an invalid address !!! Check that the - * return address is in the image range - */ - - get_image_info(addon, &info_im); - if ((fpt < info_im.text) ||(fpt >= (info_im.text +info_im.text_size))) - fpt = NULL; - } - - /* Send back fptr of data segment */ - write_port(port_out, (int32) (fpt), NULL, 0); - break; - - default: - /* Free system resources */ - delete_port(port_in); - delete_port(port_out); - /* Exit */ - exit(0); - break; - } - } - /* Never be there */ - exit(1); - } -} - - - -/* The behavior of fork is broken on beos regarding shared memory. In fact -all shared memory areas are clones in copy on write mode in the new process. - -We need to do a remapping of these areas. Just afer the fork we performe the -following actions : - - * Find all areas with a name begining by SYS_V_IPC_ in our process - (areas created by the SYSV IPC emulation functions). The name is - followed by the IPC KEY in decimal format - - * For each area we do : - - * 1 : Get its name - * 2 : destroy it - * 3 : find another area with the exact same name - * 4 : clone it in our address space with a different name - - There is a race condition in 3-4 : if there two fork in a very short - time, in step 3 we might end up with two areas with the same name, and no - possibility to find the postmaster one. So the whole process is protected - by a semaphore which is acquires just before the fork and released in case - of fork failure or just after the end of the remapping.*/ - -void -beos_before_backend_startup(void) -{ - /* Just before forking, acquire the semaphore */ - if (acquire_sem(beos_shm_sem) != B_OK) - exit(1); /* Fatal error, exiting with error */ -} - -void -beos_backend_startup_failed(void) -{ - /* The fork failed, just release the semaphore */ - release_sem(beos_shm_sem); -} - - -void -beos_backend_startup(void) -{ - char nom[50]; - char nvnom[50]; - area_info inf; - int32 cook = 0; - - /* Perform the remapping process */ - - /* Loop in all our team areas */ - while (get_next_area_info(0, &cook, &inf) == B_OK) - { - strcpy(nom, inf.name); - strcpy(nvnom, inf.name); - nom[9] = 0; - nvnom[5] = 'i'; - /* Is it a SYS V area ? */ - if (!strcmp(nom, "SYSV_IPC_")) - { - void *area_address; - area_id area_postmaster; - - /* Get the area address */ - area_address = inf.address; - /* Destroy the bad area */ - delete_area(inf.area); - /* Find the postmaster area */ - area_postmaster = find_area(inf.name); - /* Compute new area name */ - sprintf(nvnom, "SYSV_IPC %d", area_postmaster); - /* Clone it at the exact same address */ - clone_area(nvnom, &area_address, B_CLONE_ADDRESS, B_READ_AREA | B_WRITE_AREA, area_postmaster); - } - } - - /* remapping done release semaphore to allow other backend to startup */ - - release_sem(beos_shm_sem); -} |