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

216 lines
5.4 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_fhs_stat.h"
/* for fhs */
static struct shm_mgnt fhs_mgnt = {
NULL, NULL, SHM_FHS, SHM_FHS_LOCK, 0, 0
};
static struct shm_mgnt fhscnt_mgnt = {
NULL, NULL, SHM_FHSCNT, SHM_FHSCNT_LOCK, 0, 0
};
struct fhs_stat *g_fhs = NULL;
int *g_fhscnt = NULL;
static int maxfhs = 0;
int dav_initialize_shared_fhs_stat(dav_repos_server_conf *dsc, server_rec *s, apr_pool_t *p)
{
if (!dsc->max_fhs || (maxfhs = atoi(dsc->max_fhs)) <= 0) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: initialize_shared_memory: "
"MaxFHS <= 0 (%d)", maxfhs);
return !OK;
}
/* fhs management: calculate shared memory size from max_fhs value */
fhs_mgnt.size = (sizeof(struct fhs_stat) * maxfhs);
g_fhs = (struct fhs_stat *)dav_shared_get_new_memory(&fhs_mgnt, s, p, false);
if (!g_fhs) return !OK;
fhscnt_mgnt.size = (sizeof(int));
g_fhscnt = (int *)dav_shared_get_new_memory(&fhscnt_mgnt, s, p, false);
if (!g_fhscnt) return !OK;
return OK;
}
void dav_cleanup_shared_fhs_stat()
{
if (fhs_mgnt.shm) {
apr_shm_detach(fhs_mgnt.shm);
}
if (fhs_mgnt.lock) {
apr_global_mutex_destroy(fhs_mgnt.lock);
}
}
int dav_shared_du_is_alive(const char *my_domain)
{
int i = 0;
if (!g_fhs) return 0;
for (i = 0; i < maxfhs; i++)
{
if (*((g_fhs + i)->szHostname) == '\0')
break;
if (!strcmp((g_fhs + i)->szHostname, my_domain))
{
int r = 0;
switch ((g_fhs+i)->nActionCode)
{
case FHS_OK:
case READ_ONLY:
r = 1;
break;
case DELETED:
case MANUAL_STOP:
case SERVICE_STOP:
r = 0;
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_du_is_alive:: FHS[%s] => Action Code [%d] Service Disabled",
(g_fhs + i)->szHostname, (g_fhs + i)->nActionCode);
break;
default:
r = -1;
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_du_is_alive:: FHS[%s] => Action Code [%d] Unknown",
(g_fhs + i)->szHostname, (g_fhs + i)->nActionCode);
break;
}
return r;
}
}
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_du_is_alive:: Not found alive FHS.[%s]", my_domain);
return 0;
}
char *dav_shared_du_put_target(apr_pool_t *p, const char *my_domain)
{
struct fhs_stat *du = NULL;
char *domain = NULL;
if (!g_fhs)
return NULL;
if (!g_fhscnt)
return NULL;
int fhscnt = *g_fhscnt;
if (fhscnt <= 0)
{
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_du_put_target:: Empty FHS.[%s]", my_domain);
return NULL;
}
// 랜덤 선택
unsigned int selfhs = 0;
int i = 0;
for (i = 0; i < 10; i++)
{
apr_generate_random_bytes((unsigned char *)&selfhs, sizeof(unsigned int));
selfhs = selfhs % fhscnt;
if ((g_fhs + selfhs)->nActionCode != FHS_OK)
continue;
du = (g_fhs + selfhs);
break;
}
if (du == NULL)
{
int j = 0;
// 램덤으로 fhs 선정되지 않았을 경우
// 특정 fhs 부터 전체 스캔, 업로드 가능한 서버로
// 처음 발견된 fhs를 업로드 서버로 선정함
// 2017-03-08 BUG huibong
// #30515 - 업로드 대상 선정시 1차 랜덤 선택에서 선택이 실패한 경우..
// - 2차 순차 검색에서 선정해야 하는데 루프 버그로 선택되지 않는 상황 발생. 이를 수정 처리함.
// 마지막 랜덤 선택한 FHS 가 유효하지 않으므로 다시 random 선택한 후 작업을 진행한다.
apr_generate_random_bytes((unsigned char *)&selfhs, sizeof(unsigned int));
selfhs = selfhs % fhscnt;
for (j = selfhs; j < fhscnt; ++j)
{
if ((g_fhs + j)->nActionCode != FHS_OK)
{
//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_du_put_target:: 2nd check FHS readonly. [%s]", (g_fhs+j)->szHostname );
if( selfhs > 0 && (j+1) >= fhscnt )
{
// 최초 0번 장비부터 시작하지 않고 - 즉 중간 장비부터 시작해서
// 마지막까지 검색했는데도 없는 경우...
// 0번 장비부터 다시 검색하도록 조정 처리.
j = -1; // 0번 장비부터 다시 시작하도록 index 조정.
fhscnt = selfhs; // 루프 초기에 설정한 장비까지 검색 범위 조정.
selfhs = 0; // 본 로직이 다시 수행되지 않도록 flag 설정 처리.
//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_du_put_target:: 2nd select index reset" );
}
continue;
}
du = (g_fhs + j);
//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_du_put_target:: 2nd select FHS. [%s]", du->szHostname );
break;
}
}
if (du != NULL)
{
domain = apr_pstrdup(p, du->szHostname);
//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_du_put_target:: writable FHS. [%s]", domain);
}
else
{
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_shared_du_put_target:: No writable FHS. [%s]", my_domain);
}
return domain;
}