summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/graph.y
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/graph.y')
-rw-r--r--libglusterfs/src/graph.y273
1 files changed, 140 insertions, 133 deletions
diff --git a/libglusterfs/src/graph.y b/libglusterfs/src/graph.y
index 62c57dd6c5f..e63febdc08b 100644
--- a/libglusterfs/src/graph.y
+++ b/libglusterfs/src/graph.y
@@ -1,23 +1,13 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
-
%token VOLUME_BEGIN VOLUME_END OPTION NEWLINE SUBVOLUME ID WHITESPACE COMMENT TYPE STRING_TOK
%{
@@ -28,12 +18,15 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <pthread.h>
#define RELAX_POISONING
-#include "xlator.h"
-#include "graph-utils.h"
-#include "logging.h"
+#include "glusterfs/xlator.h"
+#include "glusterfs/graph-utils.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/libglusterfs-messages.h"
static int new_volume (char *name);
static int volume_type (char *type);
@@ -47,8 +40,8 @@ static void option_error (void);
#define YYSTYPE char *
#define GF_CMD_BUFFER_LEN (8 * GF_UNIT_KB)
-int yyerror (const char *);
-int yylex ();
+int graphyyerror (const char *);
+int graphyylex ();
%}
@@ -88,11 +81,11 @@ glusterfs_graph_t *construct;
static void
type_error (void)
{
- extern int yylineno;
+ extern int graphyylineno;
- gf_log ("parser", GF_LOG_ERROR,
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_VOLFILE_PARSE_ERROR,
"Volume %s, before line %d: Please specify volume type",
- curr->name, yylineno);
+ curr->name, graphyylineno);
return;
}
@@ -100,11 +93,11 @@ type_error (void)
static void
sub_error (void)
{
- extern int yylineno;
+ extern int graphyylineno;
- gf_log ("parser", GF_LOG_ERROR,
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_VOLFILE_PARSE_ERROR,
"Volume %s, before line %d: Please specify subvolumes",
- curr->name, yylineno);
+ curr->name, graphyylineno);
return;
}
@@ -112,12 +105,12 @@ sub_error (void)
static void
option_error (void)
{
- extern int yylineno;
+ extern int graphyylineno;
- gf_log ("parser", GF_LOG_ERROR,
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_VOLFILE_PARSE_ERROR,
"Volume %s, before line %d: Please specify "
"option <key> <value>",
- curr->name, yylineno);
+ curr->name, graphyylineno);
return;
}
@@ -125,21 +118,20 @@ option_error (void)
static int
new_volume (char *name)
{
- extern int yylineno;
+ extern int graphyylineno;
xlator_t *trav = NULL;
int ret = 0;
if (!name) {
- gf_log ("parser", GF_LOG_DEBUG,
- "Invalid argument name: '%s'", name);
+ gf_msg_debug ("parser", 0,"Invalid argument name");
ret = -1;
goto out;
}
if (curr) {
- gf_log ("parser", GF_LOG_ERROR,
- "new volume (%s) defintion in line %d unexpected",
- name, yylineno);
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
+ "new volume (%s) definition in line %d unexpected",
+ name, graphyylineno);
ret = -1;
goto out;
}
@@ -148,7 +140,6 @@ new_volume (char *name)
gf_common_mt_xlator_t);
if (!curr) {
- gf_log ("parser", GF_LOG_ERROR, "Out of memory");
ret = -1;
goto out;
}
@@ -157,9 +148,9 @@ new_volume (char *name)
while (trav) {
if (!strcmp (name, trav->name)) {
- gf_log ("parser", GF_LOG_ERROR,
- "Line %d: volume '%s' defined again",
- yylineno, name);
+ gf_msg ("parser", GF_LOG_ERROR, 0,
+ LG_MSG_VOLFILE_PARSE_ERROR, "Line %d: volume "
+ "'%s' defined again", graphyylineno, name);
ret = -1;
goto out;
}
@@ -173,7 +164,8 @@ new_volume (char *name)
goto out;
}
- curr->options = get_new_dict ();
+ INIT_LIST_HEAD(&curr->volume_options);
+ curr->options = dict_new ();
if (!curr->options) {
GF_FREE (curr->name);
@@ -191,8 +183,9 @@ new_volume (char *name)
construct->first = curr;
construct->xl_count++;
+ curr->xl_id = construct->xl_count;
- gf_log ("parser", GF_LOG_TRACE, "New node for '%s'", name);
+ gf_msg_trace ("parser", 0, "New node for '%s'", name);
out:
GF_FREE (name);
@@ -204,26 +197,26 @@ out:
static int
volume_type (char *type)
{
- extern int yylineno;
+ extern int graphyylineno;
int32_t ret = 0;
if (!type) {
- gf_log ("parser", GF_LOG_DEBUG, "Invalid argument type");
+ gf_msg_debug ("parser", 0, "Invalid argument type");
ret = -1;
goto out;
}
ret = xlator_set_type (curr, type);
if (ret) {
- gf_log ("parser", GF_LOG_ERROR,
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
"Volume '%s', line %d: type '%s' is not valid or "
"not found on this machine",
- curr->name, yylineno, type);
+ curr->name, graphyylineno, type);
ret = -1;
goto out;
}
- gf_log ("parser", GF_LOG_TRACE, "Type:%s:%s", curr->name, type);
+ gf_msg_trace ("parser", 0, "Type:%s:%s", curr->name, type);
out:
GF_FREE (type);
@@ -235,30 +228,30 @@ out:
static int
volume_option (char *key, char *value)
{
- extern int yylineno;
+ extern int graphyylineno;
int ret = 0;
char *set_value = NULL;
if (!key || !value){
- gf_log ("parser", GF_LOG_ERROR, "Invalid argument");
+ gf_msg ("parser", GF_LOG_ERROR, 0,
+ LG_MSG_INVALID_VOLFILE_ENTRY, "Invalid argument");
ret = -1;
goto out;
}
set_value = gf_strdup (value);
- ret = dict_set_dynstr (curr->options, key, set_value);
+ ret = dict_set_option (curr->options, key, set_value);
if (ret == 1) {
- gf_log ("parser", GF_LOG_ERROR,
- "Volume '%s', line %d: duplicate entry "
- "('option %s') present",
- curr->name, yylineno, key);
+ gf_msg ("parser", GF_LOG_ERROR, 0,
+ LG_MSG_INVALID_VOLFILE_ENTRY, "Volume '%s', line %d: "
+ "duplicate entry ('option %s') present",
+ curr->name, graphyylineno, key);
ret = -1;
goto out;
}
- gf_log ("parser", GF_LOG_TRACE, "Option:%s:%s:%s",
- curr->name, key, value);
+ gf_msg_trace ("parser", 0, "Option:%s:%s:%s", curr->name, key, value);
out:
GF_FREE (key);
@@ -271,12 +264,13 @@ out:
static int
volume_sub (char *sub)
{
- extern int yylineno;
+ extern int graphyylineno;
xlator_t *trav = NULL;
int ret = 0;
if (!sub) {
- gf_log ("parser", GF_LOG_ERROR, "Invalid subvolumes argument");
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
+ "Invalid subvolumes argument");
ret = -1;
goto out;
}
@@ -290,30 +284,28 @@ volume_sub (char *sub)
}
if (!trav) {
- gf_log ("parser", GF_LOG_ERROR,
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_SUB_VOLUME_ERROR,
"Volume '%s', line %d: subvolume '%s' is not defined "
- "prior to usage",
- curr->name, yylineno, sub);
+ "prior to usage",curr->name, graphyylineno, sub);
ret = -1;
goto out;
}
if (trav == curr) {
- gf_log ("parser", GF_LOG_ERROR,
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
"Volume '%s', line %d: has '%s' itself as subvolume",
- curr->name, yylineno, sub);
+ curr->name, graphyylineno, sub);
ret = -1;
goto out;
}
ret = glusterfs_xlator_link (curr, trav);
if (ret) {
- gf_log ("parser", GF_LOG_ERROR, "Out of memory");
ret = -1;
goto out;
}
- gf_log ("parser", GF_LOG_TRACE, "child:%s->%s", curr->name, sub);
+ gf_msg_trace ("parser", 0, "child:%s->%s", curr->name, sub);
out:
GF_FREE (sub);
@@ -326,11 +318,11 @@ static int
volume_end (void)
{
if (!curr->fops) {
- gf_log ("parser", GF_LOG_ERROR,
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR,
"\"type\" not specified for volume %s", curr->name);
return -1;
}
- gf_log ("parser", GF_LOG_TRACE, "end:%s", curr->name);
+ gf_msg_trace ("parser", 0, "end:%s", curr->name);
curr = NULL;
return 0;
@@ -338,55 +330,52 @@ volume_end (void)
int
-yywrap ()
+graphyywrap ()
{
return 1;
}
int
-yyerror (const char *str)
+graphyyerror (const char *str)
{
- extern char *yytext;
- extern int yylineno;
-
- if (curr && curr->name && yytext) {
- if (!strcmp (yytext, "volume")) {
- gf_log ("parser", GF_LOG_ERROR,
- "'end-volume' not defined for volume '%s'",
- curr->name);
- } else if (!strcmp (yytext, "type")) {
- gf_log ("parser", GF_LOG_ERROR,
+ extern char *graphyytext;
+ extern int graphyylineno;
+
+ if (curr && curr->name && graphyytext) {
+ if (!strcmp (graphyytext, "volume")) {
+ gf_msg ("parser", GF_LOG_ERROR, 0,
+ LG_MSG_VOLUME_ERROR, "'end-volume' not"
+ " defined for volume '%s'", curr->name);
+ } else if (!strcmp (graphyytext, "type")) {
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR,
"line %d: duplicate 'type' defined for "
- "volume '%s'",
- yylineno, curr->name);
- } else if (!strcmp (yytext, "subvolumes")) {
- gf_log ("parser", GF_LOG_ERROR,
- "line %d: duplicate 'subvolumes' defined for "
- "volume '%s'",
- yylineno, curr->name);
+ "volume '%s'", graphyylineno, curr->name);
+ } else if (!strcmp (graphyytext, "subvolumes")) {
+ gf_msg ("parser", GF_LOG_ERROR, 0,
+ LG_MSG_SUB_VOLUME_ERROR, "line %d: duplicate "
+ "'subvolumes' defined for volume '%s'",
+ graphyylineno, curr->name);
} else if (curr) {
- gf_log ("parser", GF_LOG_ERROR,
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_SYNTAX_ERROR,
"syntax error: line %d (volume '%s'): \"%s\""
"\nallowed tokens are 'volume', 'type', "
"'subvolumes', 'option', 'end-volume'()",
- yylineno, curr->name,
- yytext);
+ graphyylineno, curr->name, graphyytext);
} else {
- gf_log ("parser", GF_LOG_ERROR,
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_SYNTAX_ERROR,
"syntax error: line %d (just after volume "
"'%s'): \"%s\"\n(%s)",
- yylineno, curr->name,
- yytext,
+ graphyylineno, curr->name, graphyytext,
"allowed tokens are 'volume', 'type', "
"'subvolumes', 'option', 'end-volume'");
}
} else {
- gf_log ("parser", GF_LOG_ERROR,
- "syntax error in line %d: \"%s\" \n"
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_SYNTAX_ERROR,
+ "syntax error in line %d: \"%s\"\n"
"(allowed tokens are 'volume', 'type', "
"'subvolumes', 'option', 'end-volume')\n",
- yylineno, yytext);
+ graphyylineno, graphyytext);
}
return -1;
@@ -404,7 +393,8 @@ execute_cmd (char *cmd, char **result, size_t size)
fpp = popen (cmd, "r");
if (!fpp) {
- gf_log ("parser", GF_LOG_ERROR, "%s: failed to popen", cmd);
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_FILE_OP_FAILED,
+ "%s: failed to popen", cmd);
return -1;
}
@@ -454,7 +444,6 @@ preprocess (FILE *srcfp, FILE *dstfp)
cmd = GF_CALLOC (cmd_buf_size, 1,
gf_common_mt_char);
if (cmd == NULL) {
- gf_log ("parser", GF_LOG_ERROR, "Out of memory");
return -1;
}
@@ -462,7 +451,6 @@ preprocess (FILE *srcfp, FILE *dstfp)
gf_common_mt_char);
if (result == NULL) {
GF_FREE (cmd);
- gf_log ("parser", GF_LOG_ERROR, "Out of memory");
return -1;
}
@@ -491,6 +479,7 @@ preprocess (FILE *srcfp, FILE *dstfp)
cmd_buf_size *= 2;
cmd = GF_REALLOC (cmd, cmd_buf_size);
if (cmd == NULL) {
+ GF_FREE (result);
return -1;
}
@@ -523,15 +512,16 @@ preprocess (FILE *srcfp, FILE *dstfp)
}
if (in_backtick) {
- gf_log ("parser", GF_LOG_ERROR,
- "Unterminated backtick in volume specfication file at line (%d), column (%d).",
- line, column);
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR,
+ "Unterminated backtick in volume specification file at "
+ "line (%d), column (%d).", line, column);
ret = -1;
}
out:
fseek (srcfp, 0L, SEEK_SET);
fseek (dstfp, 0L, SEEK_SET);
+
GF_FREE (cmd);
GF_FREE (result);
@@ -539,7 +529,7 @@ out:
}
-extern FILE *yyin;
+extern FILE *graphyyin;
glusterfs_graph_t *
glusterfs_graph_new ()
@@ -553,6 +543,9 @@ glusterfs_graph_new ()
INIT_LIST_HEAD (&graph->list);
+ pthread_mutex_init(&graph->mutex, NULL);
+ pthread_cond_init(&graph->child_down_cond, NULL);
+
gettimeofday (&graph->dob, NULL);
return graph;
@@ -563,52 +556,66 @@ glusterfs_graph_t *
glusterfs_graph_construct (FILE *fp)
{
int ret = 0;
+ int tmp_fd = -1;
glusterfs_graph_t *graph = NULL;
- FILE *tmp_file = NULL;
+ FILE *tmp_file = NULL;
+ char template[] = "/tmp/tmp.XXXXXX";
+ static pthread_mutex_t graph_mutex = PTHREAD_MUTEX_INITIALIZER;
graph = glusterfs_graph_new ();
if (!graph)
- return NULL;
+ goto err;
- tmp_file = tmpfile ();
+ /* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
+ tmp_fd = mkstemp (template);
+ if (-1 == tmp_fd)
+ goto err;
- if (tmp_file == NULL) {
- gf_log ("parser", GF_LOG_ERROR,
- "cannot create temparory file");
+ ret = sys_unlink (template);
+ if (ret < 0) {
+ gf_msg ("parser", GF_LOG_WARNING, 0, LG_MSG_FILE_OP_FAILED,
+ "Unable to delete file: %s", template);
+ }
- glusterfs_graph_destroy (graph);
- return NULL;
- }
+ tmp_file = fdopen (tmp_fd, "w+b");
+ if (!tmp_file)
+ goto err;
- ret = preprocess (fp, tmp_file);
- if (ret < 0) {
- gf_log ("parser", GF_LOG_ERROR,
- "parsing of backticks failed");
+ ret = preprocess (fp, tmp_file);
+ if (ret < 0) {
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_BACKTICK_PARSE_FAILED,
+ "parsing of backticks failed");
+ goto err;
+ }
- glusterfs_graph_destroy (graph);
- fclose (tmp_file);
- return NULL;
+ pthread_mutex_lock (&graph_mutex);
+ {
+ graphyyin = tmp_file;
+ construct = graph;
+ ret = yyparse ();
+ construct = NULL;
}
-
- yyin = tmp_file;
-
- construct = graph;
-
- ret = yyparse ();
-
- construct = NULL;
-
- fclose (tmp_file);
+ pthread_mutex_unlock (&graph_mutex);
if (ret == 1) {
- gf_log ("parser", GF_LOG_DEBUG,
- "parsing of volfile failed, please review it "
- "once more");
-
- glusterfs_graph_destroy (graph);
- return NULL;
+ gf_msg_debug ("parser", 0, "parsing of volfile failed, please "
+ "review it once more");
+ goto err;
}
+ fclose (tmp_file);
return graph;
+err:
+ if (tmp_file) {
+ fclose (tmp_file);
+ } else {
+ gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_FILE_OP_FAILED,
+ "cannot create temporary file");
+ if (-1 != tmp_fd)
+ sys_close (tmp_fd);
+ }
+
+ glusterfs_graph_destroy (graph);
+ return NULL;
}