aff95158创建于 2025年12月23日历史提交
/**

 * Copyright (c) 2025 Huawei Technologies Co., Ltd.

 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of

 * CANN Open Software License Agreement Version 2.0 (the "License").

 * Please refer to the License for details. You may not use this file except in compliance with the License.

 * 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 FITNESS FOR A PARTICULAR PURPOSE.

 * See LICENSE in the root of the software repository for the full text of the License.

 */

#include <sys/ioctl.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include "dms/dms_misc_interface.h"

#include "dms_cmd_def.h"

#include "ascend_kernel_hal.h"

#include "dms_user_common.h"

#include "devdrv_ioctl.h"

#include "devmng_user_common.h"

#include "securec.h"

#include "ascend_dev_num.h"



#define DMS_LOG_BUF_SIZE     0x1400000

#define DMS_DIR_MAXLEN       256U

#define DMS_LOG_FILE_NAME    "host_kernel.log"

struct LogInfo {

    void *buffer;

    u32 length;

    u32 buf_len;

};



static int drvKlogSaveFs(const void *buffer, u32 len, const char *logPath)

{

#ifndef DMS_UT

    char fullPath[DMS_DIR_MAXLEN] = { 0 };

    ssize_t cnt = 0;

    int fd = -1;

    int ret;



    if (len == 0) {

        DMS_ERR("Invalid len to save file. (len=%u, path=%s)\n", len, logPath);

        return DRV_ERROR_PARA_ERROR;

    }



    ret = sprintf_s(fullPath, DMS_DIR_MAXLEN, "%s/%s", logPath, DMS_LOG_FILE_NAME);

    if (ret == -1) {

        DMS_ERR("Format full path failed. (dir=%s, fileName=%s)\n", logPath, DMS_LOG_FILE_NAME);

        return DRV_ERROR_INVALID_VALUE;

    }



    fd = open(fullPath, (O_CREAT | O_RDWR | O_TRUNC), S_IRUSR | S_IWUSR);

    if (fd < 0) {

        DMS_ERR("Open failed. (errno=%s, path=%s)\n", strerror(errno), fullPath);

        return DRV_ERROR_INVALID_VALUE;

    }



    cnt = write(fd, buffer, len);

    if (cnt < 0) {

        DMS_ERR("Write failed. (errno=%s, path=%s)\n", strerror(errno), fullPath);

        ret = DRV_ERROR_INVALID_VALUE;

        goto cleanup;

    }



    if (cnt != len) {

        DMS_WARN("Write file return bad write length. (path=%s, ret=%d, len=%u)", fullPath, ret, len);

    }



    if (fsync(fd) != 0) {

        DMS_ERR("Sync failed. (errno=%s, path=%s)\n", strerror(errno), fullPath);

        ret = DRV_ERROR_INVALID_VALUE;

        goto cleanup;

    }



    ret = DRV_ERROR_NONE;

cleanup:

    close(fd);

    fd = -1;

    return ret;

#else

    return DRV_ERROR_NONE;

#endif

}



static bool drvIsVritEnv(void)

{

#ifdef CFG_FEATURE_VDEVMNG_IN_VIRTUAL

    return DmsGetVirtFlag() != 0 ? true : false;

#else

    return false;

#endif

}



int drvGetKlogBuf(uint32_t devId, const char *path, unsigned int *pSize)

{

    unsigned int maxLen = DMS_DIR_MAXLEN - strlen(DMS_LOG_FILE_NAME);

    struct dms_ioctl_arg ioarg = { 0 };

    struct LogInfo log_info = { 0 };

    int ret;



    if ((devId >= ASCEND_PDEV_MAX_NUM) || (path == NULL) || (pSize == NULL)) {

        DMS_ERR("Invalid parameters. (devId=%u, buf%s, p_size%s)\n",

            devId, path == NULL ? "=NULL" : "!=NULL", pSize == NULL ? "=NULL" : "!=NULL");

        return DRV_ERROR_INVALID_VALUE;

    }



    if ((*pSize >= maxLen) || (strnlen(path, (size_t)maxLen) != *pSize)) {

        DMS_ERR("Invalid path or size. (devId=%u, *pSize=%u, pathLen=%d, maxLen=%d)\n", devId, *pSize,

            strnlen(path, (size_t)maxLen), maxLen);

        return DRV_ERROR_INVALID_VALUE;

    }



    log_info.buffer = (char *)malloc(DMS_LOG_BUF_SIZE);

    if (log_info.buffer == NULL) {

#ifndef DMS_UT

        DMS_ERR("Malloc failed. (devId=%u, size=%u)\n", devId, DMS_LOG_BUF_SIZE);

        return DRV_ERROR_OUT_OF_MEMORY;

#endif

    }

    log_info.length = DMS_LOG_BUF_SIZE;



#ifndef DMS_UT

    if (drvIsVritEnv()) {

        ret = dmanage_common_ioctl(DEVDRV_MANAGER_GET_HOST_KERN_LOG, &log_info);

        if (ret != 0) {

            DMS_EX_NOTSUPPORT_ERR(ret, "Ioctl failed. (dev_id=%u; ret=%d; errno=%d)\n", devId, ret, errno);

            free(log_info.buffer);

            return ret;

        }

    } else {

        ioarg.main_cmd = DMS_MAIN_CMD_LOG;

        ioarg.sub_cmd = DMS_SUBCMD_GET_LOG_INFO;

        ioarg.filter_len = 0;

        ioarg.input = &log_info;

        ioarg.input_len = sizeof(struct LogInfo);

        ioarg.output = &log_info.buf_len;

        ioarg.output_len = sizeof(u32);

        ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));

        if (ret != 0) {

            DMS_EX_NOTSUPPORT_ERR(ret, "drvGetKlogBuf failed. (devId=%u, ret=%d)", devId, ret);

            free(log_info.buffer);

            return ret;

        }

    }

#endif



    ret = drvKlogSaveFs((const char *)log_info.buffer, log_info.buf_len, path);

    if (ret != 0) {

#ifndef DMS_UT

        DMS_ERR("Save klog failed. (ret=%d)\n", ret);

        free(log_info.buffer);

        return ret;

#endif

    }



    free(log_info.buffer);

    return DRV_ERROR_NONE;

}