目录

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_process_options

ngx_process_options

声明在 src\core\nginx.c

复制代码
static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);

定义在 src\core\nginx.c

复制代码
static ngx_int_t
ngx_process_options(ngx_cycle_t *cycle)
{
    u_char  *p;
    size_t   len;

    if (ngx_prefix) {
        len = ngx_strlen(ngx_prefix);
        p = ngx_prefix;

        if (len && !ngx_path_separator(p[len - 1])) {
            p = ngx_pnalloc(cycle->pool, len + 1);
            if (p == NULL) {
                return NGX_ERROR;
            }

            ngx_memcpy(p, ngx_prefix, len);
            p[len++] = '/';
        }

        cycle->conf_prefix.len = len;
        cycle->conf_prefix.data = p;
        cycle->prefix.len = len;
        cycle->prefix.data = p;

    } else {

#ifndef NGX_PREFIX

        p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH);
        if (p == NULL) {
            return NGX_ERROR;
        }

        if (ngx_getcwd(p, NGX_MAX_PATH) == 0) {
            ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed");
            return NGX_ERROR;
        }

        len = ngx_strlen(p);

        p[len++] = '/';

        cycle->conf_prefix.len = len;
        cycle->conf_prefix.data = p;
        cycle->prefix.len = len;
        cycle->prefix.data = p;

#else

#ifdef NGX_CONF_PREFIX
        ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX);
#else
        ngx_str_set(&cycle->conf_prefix, NGX_PREFIX);
#endif
        ngx_str_set(&cycle->prefix, NGX_PREFIX);

#endif
    }

    if (ngx_conf_file) {
        cycle->conf_file.len = ngx_strlen(ngx_conf_file);
        cycle->conf_file.data = ngx_conf_file;

    } else {
        ngx_str_set(&cycle->conf_file, NGX_CONF_PATH);
    }

    if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {
        return NGX_ERROR;
    }

    for (p = cycle->conf_file.data + cycle->conf_file.len - 1;
         p > cycle->conf_file.data;
         p--)
    {
        if (ngx_path_separator(*p)) {
            cycle->conf_prefix.len = p - cycle->conf_file.data + 1;
            cycle->conf_prefix.data = cycle->conf_file.data;
            break;
        }
    }

    if (ngx_error_log) {
        cycle->error_log.len = ngx_strlen(ngx_error_log);
        cycle->error_log.data = ngx_error_log;

    } else {
        ngx_str_set(&cycle->error_log, NGX_ERROR_LOG_PATH);
    }

    if (ngx_conf_params) {
        cycle->conf_param.len = ngx_strlen(ngx_conf_params);
        cycle->conf_param.data = ngx_conf_params;
    }

    if (ngx_test_config) {
        cycle->log->log_level = NGX_LOG_INFO;
    }

    return NGX_OK;
}

ngx_process_options 是 Nginx 启动过程中用于处理命令行选项的函数
主要逻辑

  1. 处理前缀路径 (ngx_prefix)

    • 如果用户指定了 ngx_prefix,则检查是否需要添加路径分隔符 /
    • 如果未指定 ngx_prefix,则根据编译时的宏定义(如 NGX_PREFIXNGX_CONF_PREFIX)或当前工作目录设置默认路径。
  2. 处理配置文件路径 (ngx_conf_file)

    • 如果用户指定了 ngx_conf_file,则使用该路径。
    • 如果未指定,则使用默认路径 NGX_CONF_PATH
    • 调用 ngx_conf_full_name 将路径转换为完整路径,并提取配置文件所在目录作为 conf_prefix
  3. 处理错误日志路径 (ngx_error_log)

    • 如果用户指定了 ngx_error_log,则使用该路径。
    • 如果未指定,则使用默认路径 NGX_ERROR_LOG_PATH
  4. 处理额外配置参数 (ngx_conf_params)

    • 如果用户提供了额外的配置参数,则将其存储到 cycle->conf_param
  5. 测试模式 (ngx_test_config)

    • 如果启用了测试模式,则调整日志级别为 NGX_LOG_INFO
  6. 返回结果

    • 如果所有步骤成功完成,则返回 NGX_OK;否则返回 NGX_ERROR

详解

函数定义

复制代码
static ngx_int_t
ngx_process_options(ngx_cycle_t *cycle)

参数cycle 是 Nginx 的核心结构体,保存全局配置和运行时状态

返回值ngx_int_t 表示处理状态(NGX_OKNGX_ERROR
变量声明

复制代码
    u_char  *p;
    size_t   len;

定义局部变量 plen

  • p:临时指针,用于操作路径字符串。

  • len:路径字符串的长度。

处理 ngx_prefix(路径前缀)

复制代码
    if (ngx_prefix) {
        len = ngx_strlen(ngx_prefix);
        p = ngx_prefix;

检查是否指定了 ngx_prefix(即用户通过命令行或编译时指定的工作目录)。

  • 如果 ngx_prefix 存在,则计算其长度并将其赋值给 p
    确保路径以路径分隔符 / 结尾

    复制代码
          if (len && !ngx_path_separator(p[len - 1])) {
              p = ngx_pnalloc(cycle->pool, len + 1);
              if (p == NULL) {
                  return NGX_ERROR;
              }
              ngx_memcpy(p, ngx_prefix, len);
              p[len++] = '/';
          }
  • 如果 ngx_prefix 不以 / 结尾:

    1. 分配一块新的内存空间,大小为 len + 1
    2. 将原始路径复制到新分配的内存中
    3. 在末尾追加 / 并更新长度 len

ngx_path_separator

定义在 src/os/unix/ngx_files.h 中

复制代码
#define ngx_path_separator(c)    ((c) == '/')

ngx_pnalloc

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_pnalloc函数-CSDN博客

复制代码
        cycle->conf_prefix.len = len;
        cycle->conf_prefix.data = p;
        cycle->prefix.len = len;
        cycle->prefix.data = p;
    } else {

将处理后的路径赋值给 cycle->conf_prefixcycle->prefix

  • conf_prefixprefix 都表示 Nginx 的工作目录。

  • 如果未指定 ngx_prefix,则进入 else 分支。

    #ifndef NGX_PREFIX
    p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH);
    if (p == NULL) {
    return NGX_ERROR;
    }
    if (ngx_getcwd(p, NGX_MAX_PATH) == 0) {
    ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed");
    return NGX_ERROR;
    }
    len = ngx_strlen(p);
    p[len++] = '/';
    cycle->conf_prefix.len = len;
    cycle->conf_prefix.data = p;
    cycle->prefix.len = len;
    cycle->prefix.data = p;
    #else
    #ifdef NGX_CONF_PREFIX
    ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX);
    #else
    ngx_str_set(&cycle->conf_prefix, NGX_PREFIX);
    #endif
    ngx_str_set(&cycle->prefix, NGX_PREFIX);
    #endif

根据是否定义了 NGX_PREFIX 宏,选择不同的路径初始化方式。

  • 未定义 NGX_PREFIX
    1. 动态获取当前工作目录(ngx_getcwd)。
    2. 确保路径以 / 结尾。
    3. 将结果赋值给 conf_prefixprefix
  • 定义了 NGX_PREFIX
    1. 使用预定义的路径(NGX_PREFIXNGX_CONF_PREFIX)。
    2. 调用 ngx_str_set 将路径赋值给 conf_prefixprefix

ngx_str_set

定义在 src\core\ngx_string.h

复制代码
#define ngx_str_set(str, text)                                               \
    (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text

    if (ngx_conf_file) {
        cycle->conf_file.len = ngx_strlen(ngx_conf_file);
        cycle->conf_file.data = ngx_conf_file;
    } else {
        ngx_str_set(&cycle->conf_file, NGX_CONF_PATH);
    }

设置配置文件路径。

  • 如果用户指定了 ngx_conf_file,则使用用户提供的路径。

  • 否则,使用默认路径 NGX_CONF_PATH

    复制代码
      if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {
          return NGX_ERROR;
      }

将配置文件路径转换为绝对路径。

  • 调用 ngx_conf_full_name 函数完成路径标准化。
  • 如果失败,返回错误。

ngx_conf_full_name

该函数的主要作用是将相对路径转换为绝对路径

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_full_name 函数-CSDN博客

复制代码
    for (p = cycle->conf_file.data + cycle->conf_file.len - 1;
         p > cycle->conf_file.data;
         p--)
    {
        if (ngx_path_separator(*p)) {
            cycle->conf_prefix.len = p - cycle->conf_file.data + 1;
            cycle->conf_prefix.data = cycle->conf_file.data;
            break;
        }
    }

从配置文件路径中提取配置目录。

  • 从路径末尾向前遍历,找到最后一个路径分隔符 /

  • 将分隔符之前的部分作为 conf_prefix

    复制代码
      if (ngx_error_log) {
          cycle->error_log.len = ngx_strlen(ngx_error_log);
          cycle->error_log.data = ngx_error_log;
      } else {
          ngx_str_set(&cycle->error_log, NGX_ERROR_LOG_PATH);
      }

设置错误日志路径。

  • 如果用户指定了 ngx_error_log,则使用用户提供的路径。

  • 否则,使用默认路径 NGX_ERROR_LOG_PATH

    复制代码
      if (ngx_conf_params) {
          cycle->conf_param.len = ngx_strlen(ngx_conf_params);
          cycle->conf_param.data = ngx_conf_params;
      }

设置额外的配置参数。

  • 如果用户指定了 ngx_conf_params,则将其赋值给 cycle->conf_param

    复制代码
      if (ngx_test_config) {
          cycle->log->log_level = NGX_LOG_INFO;
      }

如果启用了测试模式(ngx_test_config),将日志级别设置为 INFO

复制代码
    return NGX_OK;
}

返回成功状态。

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
超爱吃香菜的菜鸟27 分钟前
关于我的服务器
运维·服务器
Cv打怪升级35 分钟前
ubuntu 常用指令
linux·运维·ubuntu
用手码出世界40 分钟前
【Linux】进程池bug、命名管道、systemV共享内存
linux·运维·bug
半吊子的程序狗2 小时前
docker测试镜像源
运维·docker·容器
MobiCetus2 小时前
Linux Kernel 7
linux·运维·服务器·windows·ubuntu·centos·gnu
西洼工作室2 小时前
centos时间不正确解决
linux·运维·centos
码--到成功3 小时前
向量数据库Qdrant 安装 不使用docker
运维·docker·容器
再学一丢丢3 小时前
用户管理和权限管理
linux·运维·服务器
碧寒3 小时前
Ubuntu系统18.04更新驱动解决方法
linux·运维·ubuntu
识途老码3 小时前
Ningx负载均衡
运维·负载均衡