2012-02-05 11:35:58 -05:00
|
|
|
/****************************************************************
|
|
|
|
* *
|
|
|
|
* Copyright 2001, 2011 Fidelity Information Services, Inc *
|
|
|
|
* *
|
|
|
|
* This source code contains the intellectual property *
|
|
|
|
* of its copyright holder(s), and is made available *
|
|
|
|
* under a license. If you do not know the terms of *
|
|
|
|
* the license, please stop and do not read further. *
|
|
|
|
* *
|
|
|
|
****************************************************************/
|
|
|
|
|
|
|
|
#include "mdef.h"
|
|
|
|
|
|
|
|
#include "gtm_string.h"
|
|
|
|
#include "gtm_stdio.h"
|
|
|
|
#include "gtm_stdlib.h" /* for exit() */
|
|
|
|
#include "gtm_unistd.h" /* for getopt() and read() */
|
|
|
|
#include "gtm_fcntl.h"
|
|
|
|
#include "gtm_ipc.h"
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/shm.h>
|
|
|
|
#include <sys/msg.h> /* for msgget() and msgctl() prototype */
|
|
|
|
#include <sys/sem.h> /* for semget() and semctl() prototype */
|
|
|
|
|
|
|
|
#include "iosp.h"
|
|
|
|
#include "rc_cpt.h"
|
|
|
|
#include "gdsroot.h"
|
|
|
|
#include "gdsblk.h"
|
|
|
|
#include "gtm_facility.h"
|
|
|
|
#include "fileinfo.h"
|
|
|
|
#include "gdsbt.h"
|
|
|
|
#include "gdsfhead.h"
|
|
|
|
#include "trans_log_name.h"
|
|
|
|
#include "cli.h"
|
|
|
|
#include "gtm_threadgbl_init.h"
|
|
|
|
|
|
|
|
/* This executable does not have any command tables so initialize command array to NULL. The reason why cmd_ary is needed is
|
|
|
|
* because trans_log_name (invoked by this module) in turn pulls in gtm_malloc/gtm_free and in turn a lot of the database
|
|
|
|
* runtime logic which in turn (due to triggers) pulls in the compiler as well (op_zcompile etc. require cmd_ary).
|
|
|
|
*/
|
|
|
|
GBLDEF CLI_ENTRY *cmd_ary = NULL;
|
|
|
|
|
|
|
|
int quiet = 0;
|
|
|
|
|
|
|
|
void clean_mem(char *name);
|
|
|
|
void database_clean(char *path);
|
|
|
|
|
|
|
|
void clean_mem(char *name)
|
|
|
|
{
|
|
|
|
mstr path1, path2;
|
|
|
|
int semid;
|
|
|
|
key_t msg_key;
|
|
|
|
char buff[512];
|
|
|
|
int q_id, s_id, m_id;
|
|
|
|
|
|
|
|
path1.len = STRLEN(name);
|
|
|
|
path1.addr = name;
|
|
|
|
if (SS_NORMAL != TRANS_LOG_NAME(&path1, &path2, buff, SIZEOF(buff), do_sendmsg_on_log2long))
|
|
|
|
FPRINTF(stderr, "Error translating path: %s\n", name);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
path2.addr[path2.len] = '\0';
|
2012-03-24 14:06:46 -04:00
|
|
|
if ((msg_key = FTOK(path2.addr, GTM_ID)) == -1)
|
2012-02-05 11:35:58 -05:00
|
|
|
perror("shmclean: Error with ftok");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((q_id = msgget(msg_key, 0)) != -1)
|
|
|
|
{
|
|
|
|
if (!quiet)
|
|
|
|
PRINTF("shmclean: removing msg queue %d\n", q_id);
|
|
|
|
if (msgctl(q_id, IPC_RMID, 0) == -1)
|
|
|
|
{
|
|
|
|
FPRINTF(stderr,"shmclean: error removing msg queue %d\n", q_id);
|
|
|
|
perror("shmclean");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((semid = semget(msg_key, 2, RWDALL)) != -1)
|
|
|
|
{
|
|
|
|
if (!quiet)
|
|
|
|
PRINTF("shmclean: removing semid %d\n", semid);
|
|
|
|
if (semctl(semid, 0, IPC_RMID, 0) == -1)
|
|
|
|
{
|
|
|
|
FPRINTF(stderr,"shmclean: error removing semid %d\n", semid);
|
|
|
|
perror("shmclean");
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
semid = INVALID_SEMID;
|
|
|
|
if ((m_id = shmget(msg_key, 10, RWDALL)) != -1)
|
|
|
|
{
|
|
|
|
if (!quiet)
|
|
|
|
PRINTF("shmclean: removing shmid %d\n", m_id);
|
|
|
|
if (shmctl(m_id, IPC_RMID, 0) == -1)
|
|
|
|
{
|
|
|
|
FPRINTF(stderr,"shmclean: error removing shmid %d\n", m_id);
|
|
|
|
perror("shmclean");
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
m_id = INVALID_SEMID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void database_clean(char *path)
|
|
|
|
{
|
|
|
|
key_t d_key;
|
|
|
|
int shmid;
|
|
|
|
int semid;
|
|
|
|
|
2012-03-24 14:06:46 -04:00
|
|
|
if ((d_key = FTOK(path, GTM_ID)) == -1)
|
2012-02-05 11:35:58 -05:00
|
|
|
{
|
|
|
|
perror("Error with database ftok");
|
|
|
|
PRINTF("File: %s\n", path);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ((shmid = shmget(d_key, 10, RWALL)) != -1)
|
|
|
|
{
|
|
|
|
if (!quiet)
|
|
|
|
PRINTF("shmclean: removing shmid %d\n", shmid);
|
|
|
|
if (shmctl(shmid, IPC_RMID, 0) == -1)
|
|
|
|
{
|
|
|
|
FPRINTF(stderr,"shmclean: error removing shmid %d\n", shmid);
|
|
|
|
perror("shmclean");
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
shmid = INVALID_SHMID;
|
|
|
|
if ((semid = semget(d_key, 2, 0600)) != -1)
|
|
|
|
{
|
|
|
|
if (!quiet)
|
|
|
|
PRINTF("shmclean: removing semid %d\n", semid);
|
|
|
|
if (semctl(semid, 0, IPC_RMID, 0) == -1)
|
|
|
|
{
|
|
|
|
FPRINTF(stderr,"shmclean: error removing semid %d\n", semid);
|
|
|
|
perror("shmclean");
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
semid = INVALID_SEMID;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* On OSF/1 (Digital Unix), pointers are 64 bits wide; the only exception to this is C programs for which one may
|
|
|
|
* specify compiler and link editor options in order to use (and allocate) 32-bit pointers. However, since C is
|
|
|
|
* the only exception and, in particular because the operating system does not support such an exception, the argv
|
|
|
|
* array passed to the main program is an array of 64-bit pointers. Thus the C program needs to declare argv[]
|
|
|
|
* as an array of 64-bit pointers and needs to do the same for any pointer it sets to an element of argv[].
|
|
|
|
*/
|
|
|
|
int main(int argc, char_ptr_t argv[])
|
|
|
|
{
|
|
|
|
key_t d_msg_key, key, s_msg_key;
|
|
|
|
int q_id, s_id, m_id;
|
|
|
|
mstr dpath1, dpath2, fpath1, fpath2;
|
|
|
|
int server_sem, daemon_sem;
|
|
|
|
char buff[512];
|
|
|
|
int server = 0;
|
|
|
|
int daemon = 0;
|
|
|
|
char resp;
|
|
|
|
int opt, err;
|
|
|
|
DCL_THREADGBL_ACCESS;
|
|
|
|
|
|
|
|
GTM_THREADGBL_INIT;
|
|
|
|
err = 0;
|
|
|
|
while ((opt = getopt(argc, argv, "qds")) != -1)
|
|
|
|
{
|
|
|
|
switch (opt)
|
|
|
|
{
|
|
|
|
case 'q':
|
|
|
|
quiet = 1;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
daemon = 1;
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
server = 1;
|
|
|
|
break;
|
|
|
|
/* mupip rundown should be used for databases. */
|
|
|
|
/*
|
|
|
|
* case 'D':
|
|
|
|
* database_clean(optarg);
|
|
|
|
* break;
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (quiet != 1)
|
|
|
|
{
|
|
|
|
FPRINTF(stderr,"If this program is used to remove shared memory from running\n");
|
|
|
|
FPRINTF(stderr,"processes, it will cause the program to fail. Please make\n");
|
|
|
|
FPRINTF(stderr,"sure all GTM processes have been shut down cleanly before running\n");
|
|
|
|
FPRINTF(stderr,"this program.\n\n");
|
|
|
|
FPRINTF(stderr,"Do you want to contine? (y or n) ");
|
|
|
|
|
|
|
|
if (1 != read(0, &resp, 1)) /*unable to read response*/
|
|
|
|
{
|
|
|
|
FPRINTF(stderr,"Error while reading response from user. Exiting\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
if ((resp != 'y') && (resp != 'Y'))
|
|
|
|
{
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (server == 1 && daemon == 0)
|
|
|
|
clean_mem(RC_CPT_PATH);
|
|
|
|
}
|