/*{ ** Name: CS_destroy_serv_segment() - Destroy the server segment. ** ** Description: ** Destroy the server shared memory segment. This should be called when ** server is shut down (ie. should be put into the last chance exception ** handler of CS). ** ** Eventually the abnormal exit code must take care of cleaning up this ** shared memory segment. ** ** This call is internal to CS is meant only to be called by CS, and may ** only exist on unix systems supporting shared memory. ** ** Inputs: ** id id of server segment. ** ** Outputs: ** address on success, set to point to segment ** err_code system dependent error information. ** ** Returns: ** E_DB_OK ** ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 08-sep-88 (mmm) ** First Version ** 12-jun-89 (rogerk) ** Changed MEsmdestroy to take character memory key, not LOCATION ptr. */ STATUS CS_destroy_serv_segment(u_i4 serv_seg_num, CL_ERR_DESC *err_code) { STATUS status = OK; char segname[48]; STcopy("server.", segname); CVna((i4)serv_seg_num, segname+STlength(segname)); #ifdef xCL_NEED_SEM_CLEANUP CS_cp_sem_cleanup(segname,err_code); #endif status = MEsmdestroy(segname, err_code); if (status) { /* Unable to attach allocated shared memory segment. */ status = FAIL; } Cs_sm_cb->css_servinfo[serv_seg_num].csi_in_use = FALSE; /* FIX ME - probably add code to update system control stuctures to ** keep track of when a shared memory segment is mapped. */ return(status); }
/*{ ** Name: RSstats_terminate - terminate statistics ** ** Description: ** Frees up the shared memory for RepServer statistics. ** ** Inputs: ** none ** ** Outputs: ** none ** ** Returns: ** none */ void RSstats_terminate() { CL_SYS_ERR sys_err; if (!mon_stats) return; if (shared_stats) { MEfree_pages((PTR)mon_stats, num_pages, &sys_err); MEsmdestroy(sm_key, &sys_err); } }
/*{ ** Name: LGK_destroy() - destroy shared memory segment used by lg and lk ** ** Description: ** Destroy the shared memory segment. ** ** Inputs: ** none. ** ** Outputs: ** none. ** ** Returns: ** !OK couldn't destroy it for some reason. ** OK success. ** ** History: ** Summer, 1992 (bryanp) ** Working on the new portable logging and locking system. ** 30-Apr-2003 (jenjo02) ** Destroy the mem_ext_sem. BUG 110121. ** 19-Jun-2003 (jenjo02) ** Prototyped function, which is a static. Before ** destroying the memory, free it as some OS's ** (read "Linux") insist, returning EIDRM if the ** process still has the memory "pinned", destroys it, ** then attempts to MEget_pages it again. This does ** not seem to trouble other OS's (Solaris, etal). */ static STATUS LGK_destroy( SIZE_TYPE pages, CL_ERR_DESC *sys_err) { STATUS ret_val; i4 err_code; LGK_MEM *lgk_mem = (LGK_MEM *)LGK_base.lgk_mem_ptr; /* Destroy the semaphore */ CSr_semaphore(&lgk_mem->mem_ext_sem); CS_cp_sem_cleanup("lglkdata.mem", sys_err); MEfree_pages((PTR)lgk_mem, pages, sys_err); ret_val = MEsmdestroy("lglkdata.mem", sys_err); if (ret_val) { uleFormat(NULL, ret_val, (CL_ERR_DESC *)sys_err, ULE_LOG, NULL, NULL, 0, NULL, &err_code, 0); ret_val = E_DMA803_LGKDEST_ERROR; } LGK_base.lgk_mem_ptr = NULL; return(ret_val); }
/*{ ** Name: CS_des_installation() - destroy shared resources of an installation. ** ** Description: ** Destroy the system shared memory segment, the logging/locking ** shared memory segment, and the system semaphores associated with the ** current installtion. This is called from the logging code as a ** result of "rcpconfig /shutdown". ** ** It assumes that all the shared memory segments have already been ** initialized by the appropriate routines. The order of destruction ** is important as a reverse may cause access violations on some ** implementation of shared memory (where the segment disappears as ** soon as it destroyed). ** ** Any subsequent logging/locking or event routines called after this ** routine will likely fail, so the caller should exit soon after this ** call. ** ** Inputs: ** none. ** ** Outputs: ** none. ** ** ** History: ** 08-sep-88 (anton) ** use LOcations for segments and destroy server segments ** 09-jun-88 (mmm) ** written. ** 12-jun-89 (rogerk) ** Change MEsmdestroy calls to take character string key instead ** of LOCATION pointer. ** 22-dec-92 (mikem) ** Changed a for(;;) to a do..while(FALSE) to shut up stupid acc ** warning. ** 02-feb-92 (sweeney) ** remove orphaned call to MEsmdestroy() on lockseg. ** 26-jul-1993 (bryanp) ** Remove no-longer-needed system semaphores (css_semid sems). ** 03-jun-1996 (canor01) ** Clean up semaphores for operating system threads. ** 16-sep-2002 (somsa01) ** Make sure we run the appropriate "cscleanup" in the case of ** ADD_ON64. ** 22-Jun-2009 (kschendel) SIR 122138 ** VMS doesn't do hybrids, but update the conditional anyway. */ STATUS CS_des_installation(void) { STATUS status; LOCATION loc; char *string; PID pid; char *argv[1]; CL_ERR_DESC err_code; i4 i; char segname[48]; /* stop all servers that are still active, forcing them to exit if ** they have not already exited. */ /* call the cscleanup code to clean up all the server slots still out ** there. */ if ((NMloc(SUBDIR, PATH, "utility", &loc) == OK) && #if defined(conf_BUILD_ARCH_32_64) && defined(BUILD_ARCH64) (LOfaddpath(&loc, "lp64", &loc) == OK) && #endif (LOfstfile("cscleanup", &loc) == OK)) { /* if everything is successful try and run the cleanup program, ** else just do the rest and make user run "cscleanup" by themselves. */ LOtos(&loc, &string); argv[0] = string; PCspawn(1, argv, TRUE, (LOCATION *) NULL, (LOCATION *) NULL, &pid); } do { /* destroy any left over server segements */ for (i = 0; i < MAXSERVERS; i++) { STcopy("server.", segname); CVna(i, segname+STlength(segname)); #ifdef xCL_NEED_SEM_CLEANUP CS_cp_sem_cleanup(segname, &err_code); #endif (VOID) MEsmdestroy(segname, &err_code); } /* FIX ME */ /* kill off slave processes here or in cscleanup code */ /* destroy the system shared memory segment */ #ifdef xCL_NEED_SEM_CLEANUP CS_cp_sem_cleanup("sysseg.mem", &err_code); #endif status = MEsmdestroy("sysseg.mem", &err_code); if (status) break; } while (FALSE); return(status); }
/*{ ** Name: RSstats_init - initialize monitor statistics ** ** Description: ** Initializes the Replicator Server statistics memory segment. ** ** Inputs: ** none ** ** Outputs: ** none ** ** Returns: ** OK Function completed normally. */ STATUS RSstats_init() { STATUS status; char *val; i4 num_targs; SIZE_TYPE pages_alloc; u_i4 stats_size; RS_TARGET_STATS *targ; RS_TARGET_STATS *targ_end; RS_TABLE_STATS *tbl; RS_CONN *conn; RS_TBLDESC *tbl_info; CL_SYS_ERR sys_err; char server_num[4]; PMsetDefault(1, PMhost()); STprintf(server_num, ERx("%d"), (i4)RSserver_no); PMsetDefault(3, server_num); status = PMget(ERx("II.$.REPSERV.$.SHARED_STATISTICS"), &val); if (status == OK && STbcompare(val, 0, ERx("ON"), 0, TRUE) == 0) shared_stats = TRUE; num_targs = RSnum_conns - TARG_BASE; stats_size = sizeof(RS_MONITOR) + sizeof(RS_MONITOR) % sizeof(ALIGN_RESTRICT); targ_size = sizeof(RS_TARGET_STATS) + sizeof(RS_TARGET_STATS) % sizeof(ALIGN_RESTRICT); if (shared_stats) tbl_size = sizeof(RS_TABLE_STATS) + sizeof(RS_TABLE_STATS) % sizeof(ALIGN_RESTRICT); else tbl_size = 0; num_pages = (stats_size + num_targs * (targ_size + RSrdf_svcb.num_tbls * tbl_size)) / ME_MPAGESIZE + 1; if (shared_stats) { STprintf(sm_key, ERx("%s.%03d"), RS_STATS_FILE, RSserver_no); status = MEget_pages(ME_SSHARED_MASK | ME_CREATE_MASK | ME_MZERO_MASK | ME_NOTPERM_MASK, num_pages, sm_key, (PTR *)&mon_stats, &pages_alloc, &sys_err); if (status == ME_ALREADY_EXISTS) { status = MEsmdestroy(sm_key, &sys_err); if (status == OK) status = MEget_pages(ME_SSHARED_MASK | ME_CREATE_MASK | ME_MZERO_MASK | ME_NOTPERM_MASK, num_pages, sm_key, (PTR *)&mon_stats, &pages_alloc, &sys_err); } } else { mon_stats = (RS_MONITOR *)MEreqmem(0, num_pages * ME_MPAGESIZE, TRUE, &status); } if (status != OK) return (status); mon_stats->server_no = RSserver_no; mon_stats->local_db_no = RSlocal_conn.db_no; PCpid(&mon_stats->pid); mon_stats->startup_time = TMsecs(); mon_stats->num_targets = num_targs; mon_stats->num_tables = RSrdf_svcb.num_tbls; STcopy(RSlocal_conn.vnode_name, mon_stats->vnode_name); STcopy(RSlocal_conn.db_name, mon_stats->db_name); mon_stats->target_stats = (RS_TARGET_STATS *)((PTR)mon_stats + stats_size); targ_end = (RS_TARGET_STATS *)((PTR)mon_stats->target_stats + mon_stats->num_targets * (targ_size + tbl_size * mon_stats->num_tables)); for (conn = &RSconns[TARG_BASE], targ = mon_stats->target_stats; targ < targ_end; ++conn, targ = (RS_TARGET_STATS *)((PTR)targ + targ_size + tbl_size * mon_stats->num_tables)) { targ->db_no = conn->db_no; STcopy(conn->vnode_name, targ->vnode_name); STcopy(conn->db_name, targ->db_name); if (shared_stats) { targ->table_stats = (RS_TABLE_STATS *)((PTR)targ + targ_size); for (tbl_info = RSrdf_svcb.tbl_info, tbl = targ->table_stats; tbl < targ->table_stats + mon_stats->num_tables; ++tbl, ++tbl_info) { tbl->table_no = tbl_info->table_no; STcopy(tbl_info->table_owner, tbl->table_owner); STcopy(tbl_info->table_name, tbl->table_name); } } } return (OK); }