/* * 设置配置中的 off slot */ char * ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; off_t *op; ngx_str_t *value; ngx_conf_post_t *post; op = (off_t *) (p + cmd->offset); if (*op != NGX_CONF_UNSET) { return "is duplicate"; } value = cf->args->elts; *op = ngx_parse_offset(&value[1]); if (*op == (off_t) NGX_ERROR) { return "invalid value"; } if (cmd->post) { post = cmd->post; return post->post_handler(cf, post, op); } return NGX_CONF_OK; }
char * ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { off_t max_size; u_char *last, *p; time_t inactive; ssize_t size; ngx_str_t s, name, *value; ngx_uint_t i, n; ngx_http_file_cache_t *cache; cache = ngx_pcalloc(cf->pool, sizeof(ngx_http_file_cache_t)); if (cache == NULL) { return NGX_CONF_ERROR; } cache->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t)); if (cache->path == NULL) { return NGX_CONF_ERROR; } inactive = 600; name.len = 0; size = 0; max_size = NGX_MAX_OFF_T_VALUE; value = cf->args->elts; cache->path->name = value[1]; if (cache->path->name.data[cache->path->name.len - 1] == '/') { cache->path->name.len--; } if (ngx_conf_full_name(cf->cycle, &cache->path->name, 0) != NGX_OK) { return NGX_CONF_ERROR; } for (i = 2; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "levels=", 7) == 0) { p = value[i].data + 7; last = value[i].data + value[i].len; for (n = 0; n < 3 && p < last; n++) { if (*p > '0' && *p < '3') { cache->path->level[n] = *p++ - '0'; cache->path->len += cache->path->level[n] + 1; if (p == last) { break; } if (*p++ == ':' && n < 2 && p != last) { continue; } goto invalid_levels; } goto invalid_levels; } if (cache->path->len < 10 + 3) { continue; } invalid_levels: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid \"levels\" \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (ngx_strncmp(value[i].data, "keys_zone=", 10) == 0) { name.data = value[i].data + 10; p = (u_char *) ngx_strchr(name.data, ':'); if (p) { *p = '\0'; name.len = p - name.data; p++; s.len = value[i].data + value[i].len - p; s.data = p; size = ngx_parse_size(&s); if (size > 8191) { continue; } } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid keys zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; inactive = ngx_parse_time(&s, 1); if (inactive < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid inactive value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "max_size=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; max_size = ngx_parse_offset(&s); if (max_size < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid max_size value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (name.len == 0 || size == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"keys_zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } cache->path->manager = ngx_http_file_cache_manager; cache->path->loader = ngx_http_file_cache_loader; cache->path->data = cache; if (ngx_add_path(cf, &cache->path) != NGX_OK) { return NGX_CONF_ERROR; } cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post); if (cache->shm_zone == NULL) { return NGX_CONF_ERROR; } if (cache->shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate zone \"%V\"", &name); return NGX_CONF_ERROR; } cache->shm_zone->init = ngx_http_file_cache_init; cache->shm_zone->data = cache; cache->inactive = inactive; cache->max_size = max_size; return NGX_CONF_OK; }
ngx_int_t ngx_pipe_rollback_parse_args(ngx_cycle_t *cycle, ngx_open_pipe_t *op, ngx_pipe_rollback_conf_t *rbcf) { u_char **argv; ngx_uint_t i; ngx_int_t j; size_t len; ngx_str_t filename; ngx_str_t value; uint32_t hash; if (op->argv->nelts < 3) { //no logname return NGX_ERROR; } //parse args argv = op->argv->elts; //set default param filename.data = (u_char *) argv[1]; filename.len = ngx_strlen(filename.data); if (ngx_conf_full_name(cycle, &filename, 0) != NGX_OK) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "get fullname failed"); return NGX_ERROR; } rbcf->logname = (char *) filename.data; rbcf->backup_num = 1; rbcf->log_max_size = -1; rbcf->interval = -1; rbcf->suitpath = NULL; rbcf->adjust_time = 60; rbcf->adjust_time_raw = 60; memset(rbcf->backup, 0, sizeof(rbcf->backup)); for (i = 2; i < op->argv->nelts; i++) { if (argv[i] == NULL) { break; } if (ngx_strncmp((u_char *) "interval=", argv[i], 9) == 0) { value.data = argv[i] + 9; value.len = ngx_strlen((char *) argv[i]) - 9; #ifdef T_PIPE_OLD_CONF //just compatibility rbcf->interval = ngx_atoi(value.data, value.len); if (rbcf->interval > 0) { rbcf->interval = rbcf->interval * 60; //convert minute to second continue; } #endif rbcf->interval = ngx_parse_time(&value, 1); if (rbcf->interval <= 0) { rbcf->interval = -1; } } else if (ngx_strncmp((u_char *) "baknum=", argv[i], 7) == 0) { rbcf->backup_num = ngx_atoi(argv[i] + 7, ngx_strlen((char *) argv[i]) - 7); if (rbcf->backup_num <= 0) { rbcf->backup_num = 1; } else if (MAX_BACKUP_NUM < (size_t)rbcf->backup_num) { rbcf->backup_num = MAX_BACKUP_NUM; } } else if (ngx_strncmp((u_char *) "maxsize=", argv[i], 8) == 0) { value.data = argv[i] + 8; value.len = ngx_strlen((char *) argv[i]) - 8; #ifdef T_PIPE_OLD_CONF //just compatibility rbcf->log_max_size = ngx_atoi(value.data, value.len); if (rbcf->log_max_size > 0) { rbcf->log_max_size = rbcf->log_max_size * 1024 * 1024; //M continue; } #endif rbcf->log_max_size = ngx_parse_offset(&value); if (rbcf->log_max_size <= 0) { rbcf->log_max_size = -1; } } else if (ngx_strncmp((u_char *) "suitpath=", argv[i], 9) == 0) { filename.data = (u_char*)(argv[i] + 9); filename.len = ngx_strlen(filename.data); if (ngx_conf_full_name(cycle, &filename, 0) != NGX_OK) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "get fullname failed"); return NGX_ERROR; } rbcf->suitpath = (char*)filename.data; rbcf->time_now = ngx_pipe_get_now_sec(); ngx_pipe_create_suitpath(cycle, rbcf); } else if (ngx_strncmp((u_char *) "adjust=", argv[i], 7) == 0) { value.data =argv[i] + 7; value.len = ngx_strlen((char *) argv[i]) - 7; rbcf->adjust_time_raw = ngx_parse_time(&value, 1); if (rbcf->adjust_time_raw < 1) { rbcf->adjust_time_raw = 1; } } } len = ngx_strlen(rbcf->logname) + 5; //max is ".128" for (j = 0; j < rbcf->backup_num; j++) { rbcf->backup[j] = ngx_pcalloc(cycle->pool, len); if (rbcf->backup[j] == NULL) { return NGX_ERROR; } ngx_snprintf((u_char *) rbcf->backup[j], len, "%s.%i%Z", rbcf->logname, j + 1); } //use same seed for same log file, when reload may have same adjust time hash = ngx_crc32_short((u_char*)rbcf->logname, ngx_strlen(rbcf->logname)); srand(hash); rbcf->adjust_time = rand() % rbcf->adjust_time_raw; ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "log rollback param: num [%i], interval %i(S), size %i(B), adjust %i/%i(S)", rbcf->backup_num, rbcf->interval, rbcf->log_max_size, rbcf->adjust_time, rbcf->adjust_time_raw); return NGX_OK; }
/* * Q: 怎样找到函数中创建的 ngx_http_file_cache_t? * A: 1. 可以通过path中的data字段找到此cache * 2. 通过共享内存区 shm_zone.data 字段找到 */ char * ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { off_t max_size; // cache磁盘空间大小 u_char *last, *p; time_t inactive; // cache不活跃的时间 ssize_t size; // 共享内存区的大小(必须大于8k) ngx_str_t s, name, *value; // name: 共享内存区的名称 ngx_int_t loader_files; ngx_msec_t loader_sleep, loader_threshold; ngx_uint_t i, n; ngx_http_file_cache_t *cache; cache = ngx_pcalloc(cf->pool, sizeof(ngx_http_file_cache_t)); if (cache == NULL) { return NGX_CONF_ERROR; } cache->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t)); if (cache->path == NULL) { return NGX_CONF_ERROR; } inactive = 600; // 不活跃时间默认是10分钟 loader_files = 100; loader_sleep = 50; loader_threshold = 200; name.len = 0; size = 0; max_size = NGX_MAX_OFF_T_VALUE; value = cf->args->elts; // cache路径, 如果以"/"结尾将被自动去掉 cache->path->name = value[1]; if (cache->path->name.data[cache->path->name.len - 1] == '/') { cache->path->name.len--; } // 获取cache的完整路径 if (ngx_conf_full_name(cf->cycle, &cache->path->name, 0) != NGX_OK) { return NGX_CONF_ERROR; } for (i = 2; i < cf->args->nelts; i++) { // 设置子目录数和子目录的文件名长度 if (ngx_strncmp(value[i].data, "levels=", 7) == 0) { p = value[i].data + 7; last = value[i].data + value[i].len; for (n = 0; n < 3 && p < last; n++) { if (*p > '0' && *p < '3') { cache->path->level[n] = *p++ - '0'; cache->path->len += cache->path->level[n] + 1; if (p == last) { break; } if (*p++ == ':' && n < 2 && p != last) { continue; } goto invalid_levels; } goto invalid_levels; } if (cache->path->len < 10 + 3) { continue; } invalid_levels: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid \"levels\" \"%V\"", &value[i]); return NGX_CONF_ERROR; } // 设置cache的共享存储区 if (ngx_strncmp(value[i].data, "keys_zone=", 10) == 0) { name.data = value[i].data + 10; // 共享内存区的名字 p = (u_char *) ngx_strchr(name.data, ':'); if (p) { *p = '\0'; name.len = p - name.data; // 共享内存区的名字长度 p++; s.len = value[i].data + value[i].len - p; // 共享内存区的大小 s.data = p; size = ngx_parse_size(&s); // 申请的共享内存区大小(必须大于8K) if (size > 8191) { continue; } } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid keys zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } // 设置cache不活跃的时间 if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; inactive = ngx_parse_time(&s, 1); if (inactive == (time_t) NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid inactive value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } // 设置缓存磁盘空间大小 max_size if (ngx_strncmp(value[i].data, "max_size=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; max_size = ngx_parse_offset(&s); if (max_size < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid max_size value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } // loader_files if (ngx_strncmp(value[i].data, "loader_files=", 13) == 0) { loader_files = ngx_atoi(value[i].data + 13, value[i].len - 13); if (loader_files == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_files value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } // loader_sleep if (ngx_strncmp(value[i].data, "loader_sleep=", 13) == 0) { s.len = value[i].len - 13; s.data = value[i].data + 13; loader_sleep = ngx_parse_time(&s, 0); if (loader_sleep == (ngx_msec_t) NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_sleep value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } // loader_threshold if (ngx_strncmp(value[i].data, "loader_threshold=", 17) == 0) { s.len = value[i].len - 17; s.data = value[i].data + 17; loader_threshold = ngx_parse_time(&s, 0); if (loader_threshold == (ngx_msec_t) NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_threshold value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } // for if (name.len == 0 || size == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"keys_zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } cache->path->manager = ngx_http_file_cache_manager; cache->path->loader = ngx_http_file_cache_loader; cache->path->data = cache; // 设置 ngx_http_file_cache_t 结构 cache->path->conf_file = cf->conf_file->file.name.data; cache->path->line = cf->conf_file->line; cache->loader_files = loader_files; cache->loader_sleep = loader_sleep; cache->loader_threshold = loader_threshold; // 添加目录到系统管理目录表中 if (ngx_add_path(cf, &cache->path) != NGX_OK) { return NGX_CONF_ERROR; } // 添加共享内存到系统管理表中 cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post); if (cache->shm_zone == NULL) { return NGX_CONF_ERROR; } /* e.g. "proxy_cache" 与 "proxy_cache_path" 这两个指令的使用是有顺序的, "proxy_cache" 指令仅初始化共享内存信息,cache->shm_zone->data字段设置为NULL, 如果data字段被设置,说明重复定义了共享内存区 */ if (cache->shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate zone \"%V\"", &name); return NGX_CONF_ERROR; } cache->shm_zone->init = ngx_http_file_cache_init; cache->shm_zone->data = cache; cache->inactive = inactive; cache->max_size = max_size; return NGX_CONF_OK; }
char * ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { off_t max_size; u_char *last, *p; time_t inactive; ssize_t size; ngx_str_t s, name, *value; ngx_int_t loader_files, loader_sleep, loader_threshold; ngx_uint_t i, n; ngx_http_file_cache_t *cache; cache = ngx_pcalloc(cf->pool, sizeof(ngx_http_file_cache_t)); if (cache == NULL) { return NGX_CONF_ERROR; } cache->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t)); if (cache->path == NULL) { return NGX_CONF_ERROR; } inactive = 600; loader_files = 100; loader_sleep = 50; loader_threshold = 200; name.len = 0; size = 0; max_size = NGX_MAX_OFF_T_VALUE; value = cf->args->elts; cache->path->name = value[1]; if (cache->path->name.data[cache->path->name.len - 1] == '/') { cache->path->name.len--; } if (ngx_conf_full_name(cf->cycle, &cache->path->name, 0) != NGX_OK) { return NGX_CONF_ERROR; } for (i = 2; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "levels=", 7) == 0) { p = value[i].data + 7; last = value[i].data + value[i].len; for (n = 0; n < 3 && p < last; n++) { if (*p > '0' && *p < '3') { cache->path->level[n] = *p++ - '0'; cache->path->len += cache->path->level[n] + 1; if (p == last) { break; } if (*p++ == ':' && n < 2 && p != last) { continue; } goto invalid_levels; } goto invalid_levels; } if (cache->path->len < 10 + 3) { continue; } invalid_levels: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid \"levels\" \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (ngx_strncmp(value[i].data, "keys_zone=", 10) == 0) { name.data = value[i].data + 10; //proxy_cache_path /data/proxy_cache_dir levels=1:2 keys_zone=STATIC:200m inactive=1d max_size=30g; p = (u_char *) ngx_strchr(name.data, ':');//find the if (p) { *p = '\0'; name.len = p - name.data; //the shared dir name!!! p++; s.len = value[i].data + value[i].len - p; s.data = p; size = ngx_parse_size(&s); //The share memory size!!! if (size > 8191) { continue; } } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid keys zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; inactive = ngx_parse_time(&s, 1); if (inactive < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid inactive value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "max_size=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; max_size = ngx_parse_offset(&s); if (max_size < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid max_size value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "loader_files=", 13) == 0) { loader_files = ngx_atoi(value[i].data + 13, value[i].len - 13); if (loader_files == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_files value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "loader_sleep=", 13) == 0) { s.len = value[i].len - 13; s.data = value[i].data + 13; loader_sleep = ngx_parse_time(&s, 0); if (loader_sleep < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_sleep value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "loader_threshold=", 17) == 0) { s.len = value[i].len - 17; s.data = value[i].data + 17; loader_threshold = ngx_parse_time(&s, 0); if (loader_threshold < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_threshold value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (name.len == 0 || size == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"keys_zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } cache->path->manager = ngx_http_file_cache_manager; cache->path->loader = ngx_http_file_cache_loader; cache->path->data = cache; cache->path->conf_file = cf->conf_file->file.name.data; cache->path->line = cf->conf_file->line; cache->loader_files = loader_files; cache->loader_sleep = (ngx_msec_t) loader_sleep; cache->loader_threshold = (ngx_msec_t) loader_threshold; if (ngx_add_path(cf, &cache->path) != NGX_OK) { return NGX_CONF_ERROR; } //the size is the configed size we set in the proxy_cache_path () !!! //Here,We create a shm_zone(share memory!!) cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post); if (cache->shm_zone == NULL) { return NGX_CONF_ERROR; } if (cache->shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate zone \"%V\"", &name); return NGX_CONF_ERROR; } cache->shm_zone->init = ngx_http_file_cache_init; cache->shm_zone->data = cache; cache->inactive = inactive; cache->max_size = max_size; return NGX_CONF_OK; }