rrd_graph fucntion with the arguments you usually give rrd on the command line. So, I need to create a temporary file for this. Luckily enough, nginx seems to have a nice function handy for that:ngx_int_t
ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access)
- The
accessargument is simple: it's what you would use as argument tochmodthe temporary file. - The
cleanargument tells nginx whether it should clean the file when it does not need it anymore (which is usually at the end of the request). Interestingly enough the cleanup mechanism relies on the pool-cleanup feature and thepoolargument. So, the cleanup could happen pretty much at any time you see fit provided you hand over the rightpool persistentseems to be atrick by which a file becomes effectively invisible to everybody else but its creator if this creator callsunlinkjust after callingopenwithO_CREATngx_path_tis probably some kind of path but I actually got a headache trying to figure out how to create angx_path_t. So, instead of trying to figure it out, I decided to use thengx_conf_set_path_slotfunction that lets you configure a path in a directive (the brand newrrd_image_temp_pathdirective in my case). I love it when everything falls in place...
While I was at it, I decided to review my good old
rrd configuration directive. So far, it had been relying on ngx_conf_set_str to handle the string that indicates where the rrd db is. As a result the object stored in the ngx_http_rrd_conf_loc_t is a ngx_str_t. Unfortunately, most of the time, I need this object as a C-style (null terminated) string to call the rrd functions. Therefore, I decided to drop using ngx_conf_str_t and to perform the "conversion" to c-style once and for all at configuration time.After that I tried to put together the new directive. And, once again, I tried to be smarter than I should have. Once again, it backfired... :( Here is the story...
The new directive had no reason to be limited to the location scope. It could as well be in the server or even the main scope. So, I decided to configure the corresponding
ngx_command_t accordingly:{ ngx_string("rrd_image_temp_path"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
ngx_conf_set_path_slot,
Note, that pretty much summarizes all I said so far: directive is rrd_image_temp_path; it is allowed at main, server and location scopes; it takes 1 to 4 arguments which are handled by ngx_conf_set_path_slot (what I call the "ngx_path black magic").And then, I had to figure out what should be the other fields of the structure:
ngx_uint_t conf;
ngx_uint_t offset;
void *post;
postwas easy: no post-processing, so useNULL.offsetwas the offset where the variable would be in my configuration object. So something like:offsetof(ngx_http_rrd_loc_conf_t, rrd_image_temp_path).confwas a bit trickier and got me wondering. As the directive could be up to the main scope, I set it toNGX_HTTP_MAIN_CONF_OFFSET. And as Yoda would put it "That is why you fail"...
But before realising I had failed, I wrote my nice little configuration merging function:
static char *
ngx_http_rrd_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) {
ngx_http_rrd_loc_conf_t* plcf = parent;
ngx_http_rrd_loc_conf_t* clcf = child;
if (ngx_conf_merge_path_value(cf, &clcf->rrd_image_temp_path,
plcf->rrd_image_temp_path,
&ngx_http_rrd_temp_path)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
Pretty easy as long as you use the "out-of-the-box" tools of nginx like ngx_conf_merge_path_value.Except that after getting the thing to compile, nothing was working. My nginx server would not even start. And after quite a bit of research I figured the culprit was the
conf. What nginx expects here has absolutely nothing to do with where the directive is allowed (this is handled in one place only: the type field of ngx_command_t) it has to do with where the data is stored: the location configuration structure, the server configuration structure or the main configuration structure. In our example, as we want to be able to set this to the location in certain situations, the data must be in the location configuration structure. So, the right value is NGX_HTTP_LOC_CONF_OFFSET. So, with conf and offset, nginx is able to figure out where exactly it should put the data it read from the configuration file.That's all folks.
No comments:
Post a Comment