blob: 2760071969b23fd39ccca759aeac4536c5be5b55 [file] [log] [blame]
/*-------------------------------------------------------------------------
*
* perfmon.c
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* $Id: //cdb2/private/cpedrotti/main/cdb-pg/src/backend/postmaster/perfmon.c#1 $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <unistd.h>
#include "miscadmin.h"
#include "postmaster/postmaster.h"
#include "postmaster/fork_process.h"
#include "postmaster/perfmon.h"
#include "storage/ipc.h"
#include "utils/ps_status.h"
#include "cdb/cdbvars.h"
#include "gpmon/gpmon.h"
/*
* FUNCTION PROTOTYPES
*/
#ifdef EXEC_BACKEND
static pid_t perfmon_forkexec(void);
#endif /* EXEC_BACKEND */
NON_EXEC_STATIC void PerfmonMain(int argc, char *argv[]);
/*
* Main entry point for perfmon process.
*/
int
perfmon_start(void)
{
pid_t PerfmonPID;
#ifdef EXEC_BACKEND
switch ((PerfmonPID = perfmon_forkexec()))
#else
switch ((PerfmonPID = fork_process()))
#endif
{
case -1:
ereport(LOG,
(errmsg("could not fork perfmon process: %m")));
return 0;
#ifndef EXEC_BACKEND
case 0:
/* in postmaster child ... */
/* Close the postmaster's sockets */
ClosePostmasterPorts(false);
PerfmonMain(0, NULL);
break;
#endif
default:
return (int)PerfmonPID;
}
/* shouldn't get here */
Assert(false);
return 0;
}
#ifdef EXEC_BACKEND
/*
* perfmon_forkexec()
*
* Format up the arglist for the perfmon process, then fork and exec.
*/
static pid_t
perfmon_forkexec(void)
{
char *av[10];
int ac = 0;
av[ac++] = "postgres";
av[ac++] = "--forkperfmon";
av[ac++] = NULL; /* filled in by postmaster_forkexec */
av[ac] = NULL;
Assert(ac < lengthof(av));
return postmaster_forkexec(ac, av);
}
#endif /* EXEC_BACKEND */
NON_EXEC_STATIC void
PerfmonMain(int argc, char *argv[])
{
char gpmmon_bin[MAXPGPATH] = {'\0'};
char gpmmon_cfg_file[MAXPGPATH] = {'\0'};
char *av[10] = {NULL};
char port[6] = {'\0'};
int ac = 0;
int ret = 0;
/* reset MyProcPid */
MyProcPid = getpid();
/* Lose the postmaster's on-exit routines */
on_exit_reset();
/* Find gpmmon executable */
if ((ret = find_other_exec(my_exec_path, "gpmmon",
GPMMON_PACKET_VERSION_STRING, gpmmon_bin)) < 0)
{
elog(FATAL,"Failed to find gpmmon executable: %s (%s)", gpmmon_bin,
GPMMON_PACKET_VERSION_STRING);
proc_exit(0);
}
snprintf(gpmmon_cfg_file, MAXPGPATH, "%s/gpperfmon/conf/gpperfmon.conf",
data_directory);
snprintf(port, 6, "%d", PostPortNumber);
av[ac++] = gpmmon_bin;
av[ac++] = "-D";
av[ac++] = gpmmon_cfg_file;
av[ac++] = "-p";
av[ac++] = port;
av[ac] = NULL;
Assert(ac < lengthof(av));
/* exec gpmmon now */
if (execv(gpmmon_bin, av) < 0)
{
elog(FATAL, "could not execute server process \"%s\"", gpmmon_bin);
proc_exit(0);
}
}