From c8cc16c73d01846e7056488ee5c186f5921aaf8f Mon Sep 17 00:00:00 2001 From: chennaidong <415079670@qq.com> Date: Sat, 24 Dec 2022 07:58:06 +0000 Subject: [PATCH] =?UTF-8?q?CMA=E6=8F=90=E4=BE=9B=E5=B7=A1=E6=A3=80?= =?UTF-8?q?=E5=85=B1=E4=BA=AB=E7=9B=98=E8=BD=AF=E9=93=BE=E6=8E=A5=E8=83=BD?= =?UTF-8?q?=E5=8A=9B=EF=BC=8C=E9=81=BF=E5=85=8D=E6=96=AD=E7=BD=91=E5=8D=A1?= =?UTF-8?q?=EF=BC=8C=E7=BD=91=E5=8D=A1=E6=81=A2=E5=A4=8D=E5=90=8E=E8=BD=AF?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chennaidong <415079670@qq.com> --- src/cm_agent/cma_main.cpp | 2 + src/cm_agent/cma_scan_disk.cpp | 191 ++++++++++++++++++++++++ src/cm_persist/share_disk_lock_api.cpp | 3 +- src/include/cm/cm_agent/cma_scan_disk.h | 30 ++++ 4 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 src/cm_agent/cma_scan_disk.cpp create mode 100644 src/include/cm/cm_agent/cma_scan_disk.h diff --git a/src/cm_agent/cma_main.cpp b/src/cm_agent/cma_main.cpp index 9662a92..48d4103 100644 --- a/src/cm_agent/cma_main.cpp +++ b/src/cm_agent/cma_main.cpp @@ -44,6 +44,7 @@ #include "cma_connect.h" #include "cma_status_check.h" #include "cma_mes.h" +#include "cma_scan_disk.h" #ifdef ENABLE_MULTIPLE_NODES #include "cma_gtm.h" #include "cma_coordinator.h" @@ -1677,6 +1678,7 @@ int main(int argc, char** argv) exit(-1); } + CreateScanDiskThread(); CmServerCmdProcessorInit(); status = CreateCheckNetworkThread(); if (status != 0) { diff --git a/src/cm_agent/cma_scan_disk.cpp b/src/cm_agent/cma_scan_disk.cpp new file mode 100644 index 0000000..e4cab1c --- /dev/null +++ b/src/cm_agent/cma_scan_disk.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2022 Huawei Technologies Co.,Ltd. + * + * CM is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * ------------------------------------------------------------------------- + * + * cma_scan_disk.cpp + * + * + * IDENTIFICATION + * src/cm_agent/cma_scan_disk.cpp + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include "cma_global_params.h" +#include "cm/cm_misc.h" +#include "cma_scan_disk.h" + +static void GetShareDiskPathFromCmsConfig(char *shareDiskPath, size_t shareDiskPathLen) +{ + if (g_currentNode->cmServerLevel != 1) { + return; + } + char cmServerConfigFile[MAX_PATH_LEN] = {0}; + int rc = snprintf_s( + cmServerConfigFile, MAX_PATH_LEN, MAX_PATH_LEN - 1, "%s/cm_server/cm_server.conf", g_currentNode->cmDataPath); + securec_check_intval(rc, (void)rc); + + if (access(cmServerConfigFile, R_OK) != 0) { + write_runlog(WARNING, "The cm_server.conf is unreadable when read share_disk_path!\n"); + return; + } + GetStringFromConf(cmServerConfigFile, shareDiskPath, shareDiskPathLen, "share_disk_path"); +} + +bool IsShareDiskPathEnv(const char *shareDiskPath) +{ + if (shareDiskPath[0] == '\0' || (strcmp(shareDiskPath, "\'\'") == 0)) { + return false; + } + return true; +} + +static void GetParentDiskPath(const char *shareDiskPath, char *parentDir, size_t parentDirLen) +{ + char tempDiskPath[MAX_PATH_LEN] = {0}; + int rc = strcpy_s(tempDiskPath, MAX_PATH_LEN, shareDiskPath); + securec_check_errno(rc, (void)rc); + + rc = strcpy_s(parentDir, parentDirLen, dirname(tempDiskPath)); + securec_check_errno(rc, (void)rc); +} + +static void GetGroupName(char *groupName, size_t groupNameLen) +{ + struct group *gp = getgrgid(pw->pw_gid); + if (gp != NULL && gp->gr_name != NULL) { + int rc = strcpy_s(groupName, groupNameLen, gp->gr_name); + securec_check_errno(rc, (void)rc); + } +} + +static status_t CheckDiskPathExist(const char *diskPath) +{ + if (access(diskPath, F_OK) != 0) { + write_runlog(WARNING, "share disk path %s is not exists.\n", diskPath); + return CM_ERROR; + } + return CM_SUCCESS; +} + +static void ScanDisk(const char *parentDiskPath, const char *groupName) +{ + char cmd[MAX_PATH_LEN] = {0}; + int rc = snprintf_s(cmd, + MAX_PATH_LEN, + MAX_PATH_LEN - 1, + "ls -l %s/* |grep ' %s \\+%s '|grep '^b'| awk -F\" %s\" '{print \"%s\" $2}' | awk '{print $1}'", + parentDiskPath, + pw->pw_name, + groupName, + parentDiskPath, + parentDiskPath); + securec_check_intval(rc, (void)rc); + + char result[MAX_PATH_LEN] = {0}; + FILE *fp = popen(cmd, "r"); + if (fp == NULL) { + write_runlog(WARNING, "Failed to scan disk when execute cmd %s.\n", cmd); + return; + } + int32 handle = -1; + while (fgets(result, MAX_PATH_LEN, fp) != NULL) { + write_runlog(DEBUG1, "Execute cmd %s result is %s.\n", cmd, result); + result[strlen(result) - 1] = '\0'; + handle = open(result, O_RDWR); + if (handle == -1) { + write_runlog(WARNING, "Failed to scan disk when open %s.\n", result); + continue; + } + write_runlog(DEBUG1, "Success to open disk %s.\n", result); + rc = close(handle); + if (rc != 0) { + write_runlog(WARNING, "Failed to scan disk when close handle of %s.\n", result); + continue; + } + } + rc = pclose(fp); + if (rc != 0) { + write_runlog(DEBUG1, "Failed to scan disk when pclose, error %d.\n", errno); + return; + } + write_runlog(DEBUG1, "Succeed to scan disk.\n"); +} + +static void ScanAllDisk(const char *shareDiskPath, const char *groupName) +{ + char votingParentDiskPath[MAX_PATH_LEN] = {0}; + GetParentDiskPath(g_votingDiskPath, votingParentDiskPath, MAX_PATH_LEN); + char shareParentDiskPath[MAX_PATH_LEN] = {0}; + GetParentDiskPath(shareDiskPath, shareParentDiskPath, MAX_PATH_LEN); + if (IsShareDiskPathEnv(g_votingDiskPath) && CheckDiskPathExist(g_votingDiskPath) != CM_SUCCESS) { + ScanDisk(votingParentDiskPath, groupName); + if (g_currentNode->cmServerLevel == 1 && IsShareDiskPathEnv(shareDiskPath) && + strcmp(votingParentDiskPath, shareParentDiskPath) == 0) { + return; + } + } + + if (g_currentNode->cmServerLevel == 1 && IsShareDiskPathEnv(shareDiskPath) && + CheckDiskPathExist(shareDiskPath) != CM_SUCCESS) { + ScanDisk(shareParentDiskPath, groupName); + } +} + +static void *CmaScanDiskMain(void *arg) +{ + thread_name = "CmaScanDiskMain"; + pthread_t threadId = pthread_self(); + char shareDiskPath[MAX_PATH_LEN] = {0}; + GetShareDiskPathFromCmsConfig(shareDiskPath, MAX_PATH_LEN); + char groupName[MAX_PATH_LEN] = {0}; + GetGroupName(groupName, MAX_PATH_LEN); + write_runlog(LOG, "CmaScanDiskMain will start, and threadId is %lu.\n", threadId); + for (;;) { + if (g_exitFlag || g_shutdownRequest) { + cm_sleep(5); + continue; + } + + ScanAllDisk(shareDiskPath, groupName); + cm_sleep(1); + } + return NULL; +} + +void CreateScanDiskThread() +{ + int err; + pthread_t thrId; + + char shareDiskPath[MAX_PATH_LEN] = {0}; + GetShareDiskPathFromCmsConfig(shareDiskPath, MAX_PATH_LEN); + if (!IsShareDiskPathEnv(g_votingDiskPath) && !IsShareDiskPathEnv(shareDiskPath)) { + write_runlog(LOG, "Voting and share disk path is empty, disable scan disk path\n"); + return; + } + + char groupName[MAX_PATH_LEN] = {0}; + GetGroupName(groupName, MAX_PATH_LEN); + + ScanAllDisk(shareDiskPath, groupName); + + if ((err = pthread_create(&thrId, NULL, CmaScanDiskMain, NULL)) != 0) { + write_runlog(FATAL, "Failed to create new thread: error %d\n", err); + exit(err); + } +} \ No newline at end of file diff --git a/src/cm_persist/share_disk_lock_api.cpp b/src/cm_persist/share_disk_lock_api.cpp index 3a04158..23fc3bb 100644 --- a/src/cm_persist/share_disk_lock_api.cpp +++ b/src/cm_persist/share_disk_lock_api.cpp @@ -41,7 +41,8 @@ status_t ShareDiskHandlerInit(diskLrwHandler *handler) status_t InitDiskLockHandle(diskLrwHandler *sdLrwHandler, const char *scsi_dev, uint32 offset, int64 instId) { - if (realpath(scsi_dev, sdLrwHandler->scsiDev) == NULL) { + int32 ret = strcpy_s(sdLrwHandler->scsiDev, MAX_PATH_LENGTH, scsi_dev); + if (ret != 0) { (void)printf(_("InitDiskLockHandle: copy string %s failed\n"), scsi_dev); return CM_ERROR; } diff --git a/src/include/cm/cm_agent/cma_scan_disk.h b/src/include/cm/cm_agent/cma_scan_disk.h new file mode 100644 index 0000000..1fe768b --- /dev/null +++ b/src/include/cm/cm_agent/cma_scan_disk.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Huawei Technologies Co.,Ltd. + * + * CM is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * ------------------------------------------------------------------------- + * + * cma_scan_disk.h + * + * + * IDENTIFICATION + * include/cm/cm_agent/cma_scan_disk.h + * + * ------------------------------------------------------------------------- + */ + +#ifndef CMA_SCAN_DISK_H +#define CMA_SCAN_DISK_H + +void CreateScanDiskThread(); + +#endif \ No newline at end of file -- Gitee