Files
interactive/fhs/sh-opendav/share_statistic.c
T
2026-08-07 17:38:18 +09:00

240 lines
6.2 KiB
C

/****************************************************************************
mod_dav_pgsql (DASL) for apache 2.X
CopyRight(C) 2005 SolutionBox Inc. All Rights reserved.
CopyRight(C) 2006 Netomi Inc. All Rights reserved.
Author : elenoa lazyfake (elenoa@solutionbox.co.kr)
$Id: share.c,v 1.8 2007/02/22 08:22:13 elenoa Exp $
Redistribution and use in source and binary forms, with or with out
modification, are not permitted in outside of SolutionBox Inc.
****************************************************************************/
#include <unistd.h>
#include <ctype.h>
#include <math.h>
#include <httpd.h>
#include <http_config.h>
#include <http_protocol.h>
#include <http_log.h>
#include <http_core.h> /* for ap_construct_url */
#include <http_request.h>
#include <apr_strings.h>
#include <apr_signal.h>
#include "dav_repos.h"
#include "dbms.h"
#include "util.h"
#include "share_common.h"
#include "share_statistic.h"
#ifndef __OPENDISK_SOLUTION_NOT_USE_TS__
/* for statistics */
static struct shm_mgnt stat_mgnt = {
NULL, NULL, SHM_STAT, SHM_STAT_LOCK, 0, 0
};
struct service_network_stat *g_ts;
static int maxvol = 0;
int dav_initialize_shared_statistic(dav_repos_server_conf *dsc, server_rec *s, apr_pool_t *p)
{
if (dsc->user_cache <= 0) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: initialize_shared_memory: "
"MaxUserCache <= 0 (%d)", dsc->user_cache);
return !OK;
}
maxvol = dsc->user_cache;
/* statistics : calculate shared memory size from max_volume value */
stat_mgnt.size = (sizeof(struct service_network_stat) * maxvol * 2);
g_ts = (struct service_network_stat *)dav_shared_get_new_memory(&stat_mgnt, s, p, true);
if (!g_ts) return !OK;
return OK;
}
void dav_cleanup_shared_statistic()
{
if (stat_mgnt.shm) {
apr_shm_detach(stat_mgnt.shm);
}
if (stat_mgnt.lock) {
apr_global_mutex_destroy(stat_mgnt.lock);
}
}
static void dav_shared_ts_init(struct service_network_stat *ts, char *volume, unsigned int stamp)
{
acct_info id_parse;
// CHG 2019-08-28 huibong 불필요 변수 삭제 (#32780)
// - 불필요 함수 호출 결과 저장 변수를 제거한다.
// - at_split() 호출 실패시에도 해당 함수내에서 id_parse 변수를 초기화 하므로....
// 호출 결과에 따른 다른 조치는 불필요.
//int res = at_split(volume, &id_parse);
at_split(volume, &id_parse);
//memset(ts, 0, sizeof(struct service_network_stat));
ts->nServiceSeq = atoi(id_parse.szVolumeID);
ts->nUserSeq = atoi(id_parse.szUserID);
ts->down_content_size = 0;
ts->up_content_size = 0;
ts->down_traffic = 0;
ts->up_traffic = 0;
ts->timestamp = stamp;
}
// CHG 2010-08-30 huibong
// 각 함수에서 통계정보 저장을 위한 본함수 호출시 내부의 apr_pstrcat() 함수 사용으로 인해
// 각 접속 세션마다 메모리 할당 현상이 반복하여 발생.
// 특히 대용량 파일에 대한 업로드/다운로드 세션인 경우
// 불필요한 세션 메모리 pool 을 계속적으로 할당하여 결국 시스템 메모리가 부족,
// swap 메모리 임계치 초과 현상이 발생하는 문제점을 발생.
// 따라서 이 문제를 해결하기 위해 apr_pstrcat() 함수 사용부분을 제거후 지역변수를 사용하도록 변경처리한다.
static struct service_network_stat *dav_shared_ts_find(request_rec *r)
{
#ifndef __OPENDAV_SHARED_NOT_USE
time_t t = time(0);
unsigned int stamp = STAT_STAMP(t);
// 2010-08-30 huibong
//char *service = r->user;
char service[128]; // service 저장 정보 형식은 238.0@168 등의 형식임
acct_info acctinfo;
int i;
if (g_ts == NULL)
{
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: dav_shared_ts_find: global ts is null");
return NULL;
}
if (at_split(r->user, &acctinfo) <= 0)
return NULL;
/* 2010-08-30 huibong
* apr_pstrcat() 함수의 반복 사용으로 인한 메모리 중복 allocation 문제로 인해 코드 수정처리
service = apr_pstrcat(r->pool, acctinfo.szVolumeID,
#ifdef __CLASSIFIED_TRAFFIC_MANAGE__
".", acctinfo.szTCClassID,
#endif
"@", acctinfo.szUserID, NULL);
*/
#ifdef __CLASSIFIED_TRAFFIC_MANAGE__
snprintf(service, sizeof(service), "%s.%s@%s", acctinfo.szVolumeID, acctinfo.szTCClassID, acctinfo.szUserID);
#else // !__CLASSIFIED_TRAFFIC_MANAGE__
snprintf(service, sizeof(service), "%s@%s", acctinfo.szVolumeID, acctinfo.szUserID);
#endif // __CLASSIFIED_TRAFFIC_MANAGE__
int nSvcsqe = atoi(acctinfo.szVolumeID);
if (nSvcsqe <= 0)
{
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: dav_shared_ts_find: not found Service seq : %s", service);
return NULL;
}
#define TS (g_ts + (i << 1) + STAT_LOC(stamp))
for (i = 0; i < maxvol; i++)
{
if (TS->nServiceSeq == 0)
break;
if (TS->nServiceSeq == nSvcsqe)
{
if (TS->timestamp != stamp)
{
dav_shared_ts_init(TS, service, stamp);
}
return TS;
}
}
if (i < maxvol)
{
dav_shared_ts_init((g_ts + (i << 1)), service, stamp);
dav_shared_ts_init((g_ts + (i << 1) + 1), service, stamp);
return TS;
}
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: dav_shared_ts_find: volume limit exceeded: %s %d", service, i);
#endif // !__OPENDAV_SHARED_NOT_USE
return NULL;
}
int dav_shared_ts_access_statistic(request_rec *r)
{
#ifndef __OPENDAV_SHARED_NOT_USE
#endif // !__OPENDAV_SHARED_NOT_USE
return OK;
}
void dav_shared_ts_open_stream(request_rec *r, int bound)
{
DBG0("dav_shared_ts_open_stream debugging #0");
#ifndef __OPENDAV_SHARED_NOT_USE
#endif // !__OPENDISK_SOLUTION_NOT_USE_TS__
}
void dav_shared_ts_close_stream(request_rec *r, int bound)
{
#ifndef __OPENDAV_SHARED_NOT_USE
#endif // !__OPENDISK_SOLUTION_NOT_USE_TS__
}
void dav_shared_ts_transfer_data(request_rec *r, int bound, apr_size_t size, apr_size_t org_sent)
{
#ifndef __OPENDAV_SHARED_NOT_USE
if (r == NULL) return;
if (stat_mgnt.lock == NULL) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: "
"dav_shared_ts_transfer_data: lock null");
return;
}
if (size < 0) return;
apr_global_mutex_lock(stat_mgnt.lock);
struct service_network_stat *ts = dav_shared_ts_find(r);
if (ts == NULL) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "OPENDAV: "
"dav_shared_ts_transfer_data: cannot get transfer structure");
apr_global_mutex_unlock(stat_mgnt.lock);
return;
}
if (bound == INB)
{
ts->up_content_size += size;
ts->up_traffic += CONTENT_TO_TRAFFIC(size);
}
else
{
ts->down_content_size += size;
ts->down_traffic += CONTENT_TO_TRAFFIC(size);
}
apr_global_mutex_unlock(stat_mgnt.lock);
#endif // !__OPENDAV_SHARED_NOT_USE
}
#endif // !__OPENDISK_SOLUTION_NOT_USE_TS__