Kouhei Sutou
null+****@clear*****
Tue Sep 4 18:03:26 JST 2012
Kouhei Sutou 2012-09-04 18:03:26 +0900 (Tue, 04 Sep 2012) New Revision: 108181cdbc27676afd79d5ea05e3b8250d4eb637 https://github.com/groonga/groonga/commit/108181cdbc27676afd79d5ea05e3b8250d4eb637 Log: groonga-httpd: add groonga_database_auto_create It creates a groonga database automatically if the groonga database doesn't exist. Note that this option is danger when worker_processes is greater than 1. Because one or more worker processes may create the same groonga database at the same time. If you can create a groonga database before running groonga-httpd, you should do it. Modified files: data/groonga-httpd.conf.in src/nginx-module/ngx_http_groonga_module.c Modified: data/groonga-httpd.conf.in (+9 -0) =================================================================== --- data/groonga-httpd.conf.in 2012-09-05 14:22:43 +0900 (86ec3f8) +++ data/groonga-httpd.conf.in 2012-09-04 18:03:26 +0900 (e360fc2) @@ -17,6 +17,15 @@ http { # The default groonga database path. groonga_database @GROONGA_HTTPD_DEFAULT_DATABASE_PATH@; + # Create a groonga database automatically if the groonga database doesn't + # exist. + # + # Note that this option is danger when worker_processes is greater than 1. + # Because one or more worker processes may create the same groonga database + # at the same time. If you can create a groonga database before running + # groonga-httpd, you should do it. + groonga_database_auto_create on; + server { listen 10041; server_name localhost; Modified: src/nginx-module/ngx_http_groonga_module.c (+80 -1) =================================================================== --- src/nginx-module/ngx_http_groonga_module.c 2012-09-05 14:22:43 +0900 (2a7788e) +++ src/nginx-module/ngx_http_groonga_module.c 2012-09-04 18:03:26 +0900 (1750b21) @@ -16,6 +16,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + #include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h> @@ -28,6 +32,7 @@ typedef struct { ngx_flag_t enabled; ngx_str_t database_path; char *database_path_cstr; + ngx_flag_t database_auto_create; ngx_str_t base_path; char *config_file; int config_line; @@ -410,6 +415,7 @@ ngx_http_groonga_create_loc_conf(ngx_conf_t *cf) conf->database_path.data = NULL; conf->database_path.len = 0; conf->database_path_cstr = NULL; + conf->database_auto_create = NGX_CONF_UNSET; conf->base_path.data = NULL; conf->base_path.len = 0; conf->config_file = NULL; @@ -480,6 +486,66 @@ ngx_http_groonga_each_loc_conf(ngx_http_conf_ctx_t *http_conf, } } +static ngx_int_t +ngx_http_groonga_mkdir_p(ngx_log_t *log, const char *dir_name) +{ + char sub_path[PATH_MAX]; + size_t i, dir_name_length; + + dir_name_length = strlen(dir_name); + sub_path[0] = dir_name[0]; + for (i = 1; i < dir_name_length + 1; i++) { + if (dir_name[i] == '/' || dir_name[i] == '\0') { + struct stat stat_buffer; + sub_path[i] = '\0'; + if (stat(sub_path, &stat_buffer) == -1) { + if (ngx_create_dir(sub_path, 0700) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, 0, + "failed to create directory: %s (%s): %s", + sub_path, dir_name, + strerror(errno)); + return NGX_ERROR; + } + } + } + sub_path[i] = dir_name[i]; + } + + return NGX_OK; +} + +static void +ngx_http_groonga_create_database(ngx_http_groonga_loc_conf_t *location_conf, + ngx_http_groonga_database_callback_data_t *data) +{ + const char *database_base_name; + grn_ctx *context; + + database_base_name = strrchr(location_conf->database_path_cstr, '/'); + if (database_base_name) { + char database_dir[PATH_MAX]; + database_dir[0] = '\0'; + strncat(database_dir, + location_conf->database_path_cstr, + database_base_name - location_conf->database_path_cstr); + data->rc = ngx_http_groonga_mkdir_p(data->log, database_dir); + if (data->rc != NGX_OK) { + return; + } + } + + context = &(location_conf->context); + grn_db_create(context, location_conf->database_path_cstr, NULL); + if (context->rc == GRN_SUCCESS) { + return; + } + + ngx_log_error(NGX_LOG_EMERG, data->log, 0, + "failed to create groonga database: %s", + context->errbuf); + data->rc = NGX_ERROR; +} + static void ngx_http_groonga_open_database_callback(ngx_http_groonga_loc_conf_t *location_conf, void *user_data) @@ -506,7 +572,13 @@ ngx_http_groonga_open_database_callback(ngx_http_groonga_loc_conf_t *location_co } grn_db_open(context, location_conf->database_path_cstr); - if (context->rc != GRN_SUCCESS) { + if (context->rc == GRN_SUCCESS) { + return; + } + + if (location_conf->database_auto_create) { + ngx_http_groonga_create_database(location_conf, data); + } else { ngx_log_error(NGX_LOG_EMERG, data->log, 0, "failed to open groonga database: %s", context->errbuf); @@ -587,6 +659,13 @@ static ngx_command_t ngx_http_groonga_commands[] = { offsetof(ngx_http_groonga_loc_conf_t, database_path), NULL }, + { ngx_string("groonga_database_auto_create"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_groonga_loc_conf_t, database_auto_create), + NULL }, + { ngx_string("groonga_base_path"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, -------------- next part -------------- HTML����������������������������...Download