Land part 2 of clang-format changes

Change-Id: Ia84cc24c8924e6d22d02ac15f611c10e26db99b4
Signed-off-by: Nigel Babu <nigelb@redhat.com>
This commit is contained in:
Gluster Ant 2018-09-12 17:52:45 +05:30 committed by Nigel Babu
parent 45a71c0548
commit e16868dede
490 changed files with 438042 additions and 451040 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -22,166 +22,153 @@
#include "glfs-mem-types.h"
#include "gfapi-messages.h"
int
graph_setup (struct glfs *fs, glusterfs_graph_t *graph)
graph_setup(struct glfs *fs, glusterfs_graph_t *graph)
{
xlator_t *new_subvol = NULL;
xlator_t *old_subvol = NULL;
inode_table_t *itable = NULL;
int ret = -1;
xlator_t *new_subvol = NULL;
xlator_t *old_subvol = NULL;
inode_table_t *itable = NULL;
int ret = -1;
new_subvol = graph->top;
new_subvol = graph->top;
/* This is called in a bottom-up context, it should specifically
NOT be glfs_lock()
*/
pthread_mutex_lock (&fs->mutex);
{
if (new_subvol->switched ||
new_subvol == fs->active_subvol ||
new_subvol == fs->next_subvol ||
new_subvol == fs->mip_subvol) {
/* Spurious CHILD_UP event on old graph */
ret = 0;
goto unlock;
}
/* This is called in a bottom-up context, it should specifically
NOT be glfs_lock()
*/
pthread_mutex_lock(&fs->mutex);
{
if (new_subvol->switched || new_subvol == fs->active_subvol ||
new_subvol == fs->next_subvol || new_subvol == fs->mip_subvol) {
/* Spurious CHILD_UP event on old graph */
ret = 0;
goto unlock;
}
if (!new_subvol->itable) {
itable = inode_table_new (131072, new_subvol);
if (!itable) {
errno = ENOMEM;
ret = -1;
goto unlock;
}
if (!new_subvol->itable) {
itable = inode_table_new(131072, new_subvol);
if (!itable) {
errno = ENOMEM;
ret = -1;
goto unlock;
}
new_subvol->itable = itable;
}
new_subvol->itable = itable;
}
old_subvol = fs->next_subvol;
fs->next_subvol = new_subvol;
fs->next_subvol->winds++; /* first ref */
ret = 0;
}
old_subvol = fs->next_subvol;
fs->next_subvol = new_subvol;
fs->next_subvol->winds++; /* first ref */
ret = 0;
}
unlock:
pthread_mutex_unlock (&fs->mutex);
pthread_mutex_unlock(&fs->mutex);
if (old_subvol)
/* wasn't picked up so far, skip */
glfs_subvol_done (fs, old_subvol);
if (old_subvol)
/* wasn't picked up so far, skip */
glfs_subvol_done(fs, old_subvol);
return ret;
return ret;
}
int
notify (xlator_t *this, int event, void *data, ...)
notify(xlator_t *this, int event, void *data, ...)
{
glusterfs_graph_t *graph = NULL;
struct glfs *fs = NULL;
glusterfs_graph_t *graph = NULL;
struct glfs *fs = NULL;
graph = data;
fs = this->private;
graph = data;
fs = this->private;
switch (event) {
case GF_EVENT_GRAPH_NEW:
gf_msg (this->name, GF_LOG_INFO, 0, API_MSG_NEW_GRAPH,
"New graph %s (%d) coming up",
uuid_utoa ((unsigned char *)graph->graph_uuid),
graph->id);
break;
case GF_EVENT_CHILD_UP:
pthread_mutex_lock (&fs->mutex);
{
graph->used = 1;
}
pthread_mutex_unlock (&fs->mutex);
graph_setup (fs, graph);
glfs_init_done (fs, 0);
break;
case GF_EVENT_CHILD_DOWN:
pthread_mutex_lock (&fs->mutex);
{
graph->used = 0;
pthread_cond_broadcast (&fs->child_down_cond);
}
pthread_mutex_unlock (&fs->mutex);
glfs_init_done (fs, 1);
break;
case GF_EVENT_CHILD_CONNECTING:
break;
switch (event) {
case GF_EVENT_GRAPH_NEW:
gf_msg(this->name, GF_LOG_INFO, 0, API_MSG_NEW_GRAPH,
"New graph %s (%d) coming up",
uuid_utoa((unsigned char *)graph->graph_uuid), graph->id);
break;
case GF_EVENT_CHILD_UP:
pthread_mutex_lock(&fs->mutex);
{
graph->used = 1;
}
pthread_mutex_unlock(&fs->mutex);
graph_setup(fs, graph);
glfs_init_done(fs, 0);
break;
case GF_EVENT_CHILD_DOWN:
pthread_mutex_lock(&fs->mutex);
{
graph->used = 0;
pthread_cond_broadcast(&fs->child_down_cond);
}
pthread_mutex_unlock(&fs->mutex);
glfs_init_done(fs, 1);
break;
case GF_EVENT_CHILD_CONNECTING:
break;
case GF_EVENT_UPCALL:
glfs_process_upcall_event (fs, data);
break;
default:
gf_msg_debug (this->name, 0, "got notify event %d", event);
break;
}
glfs_process_upcall_event(fs, data);
break;
default:
gf_msg_debug(this->name, 0, "got notify event %d", event);
break;
}
return 0;
return 0;
}
int
mem_acct_init (xlator_t *this)
mem_acct_init(xlator_t *this)
{
int ret = -1;
int ret = -1;
if (!this)
return ret;
if (!this)
return ret;
ret = xlator_mem_acct_init (this, glfs_mt_end + 1);
if (ret) {
gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
API_MSG_MEM_ACCT_INIT_FAILED, "Failed to initialise "
"memory accounting");
return ret;
}
ret = xlator_mem_acct_init(this, glfs_mt_end + 1);
if (ret) {
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, API_MSG_MEM_ACCT_INIT_FAILED,
"Failed to initialise "
"memory accounting");
return ret;
}
return 0;
return 0;
}
int
init (xlator_t *this)
init(xlator_t *this)
{
return 0;
return 0;
}
void
fini (xlator_t *this)
fini(xlator_t *this)
{
}
/* place-holder fops */
int
glfs_forget (xlator_t *this, inode_t *inode)
glfs_forget(xlator_t *this, inode_t *inode)
{
return 0;
return 0;
}
int
glfs_release (xlator_t *this, fd_t *fd)
glfs_release(xlator_t *this, fd_t *fd)
{
return 0;
return 0;
}
int
glfs_releasedir (xlator_t *this, fd_t *fd)
glfs_releasedir(xlator_t *this, fd_t *fd)
{
return 0;
return 0;
}
struct xlator_dumpops dumpops;
struct xlator_fops fops;
struct xlator_cbks cbks = {
.forget = glfs_forget,
.release = glfs_release,
.releasedir = glfs_releasedir
};
struct xlator_cbks cbks = {.forget = glfs_forget,
.release = glfs_release,
.releasedir = glfs_releasedir};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -30,111 +30,109 @@
extern rpc_clnt_prog_t *cli_rpc_prog;
int
cli_cmd_global_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount);
cli_cmd_global_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount);
int
cli_cmd_get_state_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount);
cli_cmd_get_state_cbk(struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount);
struct cli_cmd global_cmds[] = {
{ "global help",
cli_cmd_global_help_cbk,
"list global commands",
},
{ "get-state [<daemon>] [[odir </path/to/output/dir/>] "
"[file <filename>]] [detail|volumeoptions]",
cli_cmd_get_state_cbk,
"Get local state representation of mentioned daemon",
},
{NULL, NULL, NULL}
};
{
"global help",
cli_cmd_global_help_cbk,
"list global commands",
},
{
"get-state [<daemon>] [[odir </path/to/output/dir/>] "
"[file <filename>]] [detail|volumeoptions]",
cli_cmd_get_state_cbk,
"Get local state representation of mentioned daemon",
},
{NULL, NULL, NULL}};
int
cli_cmd_global_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
cli_cmd_global_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount)
{
struct cli_cmd *cmd = NULL;
struct cli_cmd *global_cmd = NULL;
int count = 0;
cmd = GF_MALLOC(sizeof(global_cmds), cli_mt_cli_cmd);
memcpy(cmd, global_cmds, sizeof(global_cmds));
count = (sizeof(global_cmds) / sizeof(struct cli_cmd));
cli_cmd_sort(cmd, count);
cli_out("\ngluster global commands");
cli_out("========================\n");
for (global_cmd = cmd; global_cmd->pattern; global_cmd++)
if (_gf_false == global_cmd->disable)
cli_out("%s - %s", global_cmd->pattern, global_cmd->desc);
cli_out("\n");
GF_FREE(cmd);
return 0;
}
int
cli_cmd_global_register(struct cli_state *state)
{
int ret = 0;
struct cli_cmd *cmd = NULL;
for (cmd = global_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register(&state->tree, cmd);
if (ret)
goto out;
}
out:
return ret;
}
int
cli_cmd_get_state_cbk(struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
struct cli_cmd *cmd = NULL;
struct cli_cmd *global_cmd = NULL;
int count = 0;
int sent = 0;
int parse_error = 0;
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *options = NULL;
cli_local_t *local = NULL;
char *op_errstr = NULL;
cmd = GF_MALLOC (sizeof (global_cmds), cli_mt_cli_cmd);
memcpy (cmd, global_cmds, sizeof (global_cmds));
count = (sizeof (global_cmds) / sizeof (struct cli_cmd));
cli_cmd_sort (cmd, count);
frame = create_frame(THIS, THIS->ctx->pool);
if (!frame)
goto out;
cli_out ("\ngluster global commands");
cli_out ("========================\n");
for (global_cmd = cmd; global_cmd->pattern; global_cmd++)
if (_gf_false == global_cmd->disable)
cli_out ("%s - %s", global_cmd->pattern,
global_cmd->desc);
ret = cli_cmd_get_state_parse(state, words, wordcount, &options,
&op_errstr);
cli_out ("\n");
GF_FREE (cmd);
return 0;
}
if (ret) {
if (op_errstr) {
cli_err("%s", op_errstr);
cli_usage_out(word->pattern);
GF_FREE(op_errstr);
} else
cli_usage_out(word->pattern);
int
cli_cmd_global_register (struct cli_state *state)
{
int ret = 0;
struct cli_cmd *cmd = NULL;
for (cmd = global_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register (&state->tree, cmd);
if (ret)
goto out;
}
parse_error = 1;
goto out;
}
CLI_LOCAL_INIT(local, words, frame, options);
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_STATE];
if (proc->fn)
ret = proc->fn(frame, THIS, options);
out:
return ret;
if (ret) {
cli_cmd_sent_status_get(&sent);
if ((sent == 0) && (parse_error == 0))
cli_out("Getting daemon state failed");
}
CLI_STACK_DESTROY(frame);
return ret;
}
int
cli_cmd_get_state_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int sent = 0;
int parse_error = 0;
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *options = NULL;
cli_local_t *local = NULL;
char *op_errstr = NULL;
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
ret = cli_cmd_get_state_parse (state, words, wordcount, &options,
&op_errstr);
if (ret) {
if (op_errstr) {
cli_err ("%s", op_errstr);
cli_usage_out (word->pattern);
GF_FREE (op_errstr);
} else
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
}
CLI_LOCAL_INIT (local, words, frame, options);
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_STATE];
if (proc->fn)
ret = proc->fn (frame, THIS, options);
out:
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
cli_out ("Getting daemon state failed");
}
CLI_STACK_DESTROY (frame);
return ret;
}

View File

@ -35,107 +35,98 @@ extern struct cli_cmd global_cmds[];
struct cli_cmd cli_misc_cmds[];
int
cli_cmd_quit_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
cli_cmd_quit_cbk(struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
exit (0);
exit(0);
}
static gf_boolean_t
cli_is_help_command (const char *pattern)
cli_is_help_command(const char *pattern)
{
/* FixFixFix
* This is not the best way to determine whether
* this is a help command
*/
if (strstr (pattern, "help"))
return _gf_true;
/* FixFixFix
* This is not the best way to determine whether
* this is a help command
*/
if (strstr(pattern, "help"))
return _gf_true;
return _gf_false;
return _gf_false;
}
int
cli_cmd_display_help (struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount)
cli_cmd_display_help(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount)
{
struct cli_cmd *cmd[] = {cli_misc_cmds, cli_probe_cmds,
volume_cmds, bitrot_cmds, quota_cmds,
struct cli_cmd *cmd[] = {
cli_misc_cmds,
cli_probe_cmds,
volume_cmds,
bitrot_cmds,
quota_cmds,
#if !defined(__NetBSD__)
tier_cmds,
tier_cmds,
#endif
snapshot_cmds, global_cmds, NULL};
struct cli_cmd *cmd_ind = NULL;
int i = 0;
gf_boolean_t list_all = _gf_false;
snapshot_cmds,
global_cmds,
NULL
};
struct cli_cmd *cmd_ind = NULL;
int i = 0;
gf_boolean_t list_all = _gf_false;
/* cli_system_cmds commands for internal usage
they are not exposed
*/
/* cli_system_cmds commands for internal usage
they are not exposed
*/
/* If "help all" */
if (wordcount == 2)
list_all = _gf_true;
/* If "help all" */
if (wordcount == 2)
list_all = _gf_true;
for (i = 0; cmd[i] != NULL; i++) {
for (cmd_ind = cmd[i]; cmd_ind->pattern; cmd_ind++) {
if ((_gf_false == cmd_ind->disable) &&
cli_is_help_command (cmd_ind->pattern)) {
if (list_all && (cmd_ind->cbk)) {
cmd_ind->cbk (state, in_word, words,
wordcount);
} else {
cli_out (" %-25s- %s", cmd_ind->pattern,
cmd_ind->desc);
}
}
for (i = 0; cmd[i] != NULL; i++) {
for (cmd_ind = cmd[i]; cmd_ind->pattern; cmd_ind++) {
if ((_gf_false == cmd_ind->disable) &&
cli_is_help_command(cmd_ind->pattern)) {
if (list_all && (cmd_ind->cbk)) {
cmd_ind->cbk(state, in_word, words, wordcount);
} else {
cli_out(" %-25s- %s", cmd_ind->pattern, cmd_ind->desc);
}
}
}
}
cli_out ("\n");
return 0;
cli_out("\n");
return 0;
}
struct cli_cmd cli_help_cmds[] = {
{ "help [all]",
cli_cmd_display_help,
"display help for command classes"},
{"help [all]", cli_cmd_display_help, "display help for command classes"},
{ NULL, NULL, NULL }
};
{NULL, NULL, NULL}};
struct cli_cmd cli_misc_cmds[] = {{"quit", cli_cmd_quit_cbk, "quit"},
{"exit", cli_cmd_quit_cbk, "exit"},
struct cli_cmd cli_misc_cmds[] = {
{ "quit",
cli_cmd_quit_cbk,
"quit"},
{ "exit",
cli_cmd_quit_cbk,
"exit"},
{ NULL, NULL, NULL }
};
{NULL, NULL, NULL}};
int
cli_cmd_misc_register (struct cli_state *state)
cli_cmd_misc_register(struct cli_state *state)
{
int ret = 0;
struct cli_cmd *cmd = NULL;
int ret = 0;
struct cli_cmd *cmd = NULL;
for (cmd = cli_misc_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register (&state->tree, cmd);
if (ret)
goto out;
}
for (cmd = cli_misc_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register(&state->tree, cmd);
if (ret)
goto out;
}
for (cmd = cli_help_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register (&state->tree, cmd);
if (ret)
goto out;
}
for (cmd = cli_help_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register(&state->tree, cmd);
if (ret)
goto out;
}
out:
return ret;
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -24,292 +24,282 @@ extern struct rpc_clnt *global_rpc;
extern rpc_clnt_prog_t *cli_rpc_prog;
int cli_cmd_peer_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
int
cli_cmd_peer_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount);
int
cli_cmd_peer_probe_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *dict = NULL;
int sent = 0;
int parse_error = 0;
cli_local_t *local = NULL;
if (!(wordcount == 3)) {
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PROBE];
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
dict = dict_new ();
if (!dict)
goto out;
ret = dict_set_str (dict, "hostname", (char *)words[2]);
if (ret)
goto out;
ret = valid_internet_address ((char *) words[2], _gf_false);
if (ret == 1) {
ret = 0;
} else {
cli_out ("%s is an invalid address", words[2]);
cli_usage_out (word->pattern);
parse_error = 1;
ret = -1;
goto out;
}
/* if (words[3]) {
ret = dict_set_str (dict, "port", (char *)words[3]);
if (ret)
goto out;
}
*/
CLI_LOCAL_INIT (local, words, frame, dict);
if (proc->fn) {
ret = proc->fn (frame, THIS, dict);
}
out:
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
cli_out ("Peer probe failed");
}
CLI_STACK_DESTROY (frame);
if (ret == 0) {
gf_event (EVENT_PEER_ATTACH, "host=%s", (char *)words[2]);
}
return ret;
}
int
cli_cmd_peer_deprobe_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *dict = NULL;
int flags = 0;
int sent = 0;
int parse_error = 0;
cli_local_t *local = NULL;
if ((wordcount < 3) || (wordcount > 4)) {
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DEPROBE];
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
dict = dict_new ();
ret = dict_set_str (dict, "hostname", (char *)words[2]);
if (ret)
goto out;
/* if (words[3]) {
ret = dict_set_str (dict, "port", (char *)words[3]);
if (ret)
goto out;
}
*/
if (wordcount == 4) {
if (!strcmp("force", words[3]))
flags |= GF_CLI_FLAG_OP_FORCE;
else {
ret = -1;
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
}
}
ret = dict_set_int32 (dict, "flags", flags);
if (ret)
goto out;
CLI_LOCAL_INIT (local, words, frame, dict);
if (proc->fn) {
ret = proc->fn (frame, THIS, dict);
}
out:
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
cli_out ("Peer detach failed");
}
CLI_STACK_DESTROY (frame);
if (ret == 0) {
gf_event (EVENT_PEER_DETACH, "host=%s", (char *)words[2]);
}
return ret;
}
int
cli_cmd_peer_status_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
int sent = 0;
int parse_error = 0;
if (wordcount != 2) {
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_FRIENDS];
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
if (proc->fn) {
ret = proc->fn (frame, THIS, (void *)GF_CLI_LIST_PEERS);
}
out:
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
cli_out ("Peer status failed");
}
CLI_STACK_DESTROY (frame);
return ret;
}
int
cli_cmd_pool_list_cbk (struct cli_state *state, struct cli_cmd_word *word,
cli_cmd_peer_probe_cbk(struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
int sent = 0;
int parse_error = 0;
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *dict = NULL;
int sent = 0;
int parse_error = 0;
cli_local_t *local = NULL;
if (wordcount != 2) {
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
}
if (!(wordcount == 3)) {
cli_usage_out(word->pattern);
parse_error = 1;
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_FRIENDS];
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PROBE];
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
frame = create_frame(THIS, THIS->ctx->pool);
if (!frame)
goto out;
if (proc->fn) {
ret = proc->fn (frame, THIS,
(void *)GF_CLI_LIST_POOL_NODES);
}
dict = dict_new();
if (!dict)
goto out;
ret = dict_set_str(dict, "hostname", (char *)words[2]);
if (ret)
goto out;
ret = valid_internet_address((char *)words[2], _gf_false);
if (ret == 1) {
ret = 0;
} else {
cli_out("%s is an invalid address", words[2]);
cli_usage_out(word->pattern);
parse_error = 1;
ret = -1;
goto out;
}
/* if (words[3]) {
ret = dict_set_str (dict, "port", (char *)words[3]);
if (ret)
goto out;
}
*/
CLI_LOCAL_INIT(local, words, frame, dict);
if (proc->fn) {
ret = proc->fn(frame, THIS, dict);
}
out:
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
cli_err ("pool list: command execution failed");
if (ret) {
cli_cmd_sent_status_get(&sent);
if ((sent == 0) && (parse_error == 0))
cli_out("Peer probe failed");
}
CLI_STACK_DESTROY(frame);
if (ret == 0) {
gf_event(EVENT_PEER_ATTACH, "host=%s", (char *)words[2]);
}
return ret;
}
int
cli_cmd_peer_deprobe_cbk(struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *dict = NULL;
int flags = 0;
int sent = 0;
int parse_error = 0;
cli_local_t *local = NULL;
if ((wordcount < 3) || (wordcount > 4)) {
cli_usage_out(word->pattern);
parse_error = 1;
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DEPROBE];
frame = create_frame(THIS, THIS->ctx->pool);
if (!frame)
goto out;
dict = dict_new();
ret = dict_set_str(dict, "hostname", (char *)words[2]);
if (ret)
goto out;
/* if (words[3]) {
ret = dict_set_str (dict, "port", (char *)words[3]);
if (ret)
goto out;
}
*/
if (wordcount == 4) {
if (!strcmp("force", words[3]))
flags |= GF_CLI_FLAG_OP_FORCE;
else {
ret = -1;
cli_usage_out(word->pattern);
parse_error = 1;
goto out;
}
}
ret = dict_set_int32(dict, "flags", flags);
if (ret)
goto out;
CLI_STACK_DESTROY (frame);
CLI_LOCAL_INIT(local, words, frame, dict);
return ret;
if (proc->fn) {
ret = proc->fn(frame, THIS, dict);
}
out:
if (ret) {
cli_cmd_sent_status_get(&sent);
if ((sent == 0) && (parse_error == 0))
cli_out("Peer detach failed");
}
CLI_STACK_DESTROY(frame);
if (ret == 0) {
gf_event(EVENT_PEER_DETACH, "host=%s", (char *)words[2]);
}
return ret;
}
int
cli_cmd_peer_status_cbk(struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
int sent = 0;
int parse_error = 0;
if (wordcount != 2) {
cli_usage_out(word->pattern);
parse_error = 1;
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_FRIENDS];
frame = create_frame(THIS, THIS->ctx->pool);
if (!frame)
goto out;
if (proc->fn) {
ret = proc->fn(frame, THIS, (void *)GF_CLI_LIST_PEERS);
}
out:
if (ret) {
cli_cmd_sent_status_get(&sent);
if ((sent == 0) && (parse_error == 0))
cli_out("Peer status failed");
}
CLI_STACK_DESTROY(frame);
return ret;
}
int
cli_cmd_pool_list_cbk(struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
int sent = 0;
int parse_error = 0;
if (wordcount != 2) {
cli_usage_out(word->pattern);
parse_error = 1;
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_FRIENDS];
frame = create_frame(THIS, THIS->ctx->pool);
if (!frame)
goto out;
if (proc->fn) {
ret = proc->fn(frame, THIS, (void *)GF_CLI_LIST_POOL_NODES);
}
out:
if (ret) {
cli_cmd_sent_status_get(&sent);
if ((sent == 0) && (parse_error == 0))
cli_err("pool list: command execution failed");
}
CLI_STACK_DESTROY(frame);
return ret;
}
struct cli_cmd cli_probe_cmds[] = {
{ "peer probe { <HOSTNAME> | <IP-address> }",
cli_cmd_peer_probe_cbk,
"probe peer specified by <HOSTNAME>"},
{"peer probe { <HOSTNAME> | <IP-address> }", cli_cmd_peer_probe_cbk,
"probe peer specified by <HOSTNAME>"},
{ "peer detach { <HOSTNAME> | <IP-address> } [force]",
cli_cmd_peer_deprobe_cbk,
"detach peer specified by <HOSTNAME>"},
{"peer detach { <HOSTNAME> | <IP-address> } [force]",
cli_cmd_peer_deprobe_cbk, "detach peer specified by <HOSTNAME>"},
{ "peer status",
cli_cmd_peer_status_cbk,
"list status of peers"},
{"peer status", cli_cmd_peer_status_cbk, "list status of peers"},
{ "peer help",
cli_cmd_peer_help_cbk,
"display help for peer commands"},
{"peer help", cli_cmd_peer_help_cbk, "display help for peer commands"},
{ "pool list",
cli_cmd_pool_list_cbk,
"list all the nodes in the pool (including localhost)"},
{"pool list", cli_cmd_pool_list_cbk,
"list all the nodes in the pool (including localhost)"},
{ NULL, NULL, NULL }
};
{NULL, NULL, NULL}};
int
cli_cmd_peer_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
cli_cmd_peer_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount)
{
struct cli_cmd *cmd = NULL;
struct cli_cmd *probe_cmd = NULL;
int count = 0;
struct cli_cmd *cmd = NULL;
struct cli_cmd *probe_cmd = NULL;
int count = 0;
cli_out ("\ngluster peer commands");
cli_out ("======================\n");
cli_out("\ngluster peer commands");
cli_out("======================\n");
cmd = GF_MALLOC (sizeof (cli_probe_cmds), cli_mt_cli_cmd);
memcpy (cmd, cli_probe_cmds, sizeof (cli_probe_cmds));
count = (sizeof (cli_probe_cmds) / sizeof (struct cli_cmd));
cli_cmd_sort (cmd, count);
cmd = GF_MALLOC(sizeof(cli_probe_cmds), cli_mt_cli_cmd);
memcpy(cmd, cli_probe_cmds, sizeof(cli_probe_cmds));
count = (sizeof(cli_probe_cmds) / sizeof(struct cli_cmd));
cli_cmd_sort(cmd, count);
for (probe_cmd = cmd; probe_cmd->pattern; probe_cmd++)
cli_out ("%s - %s", probe_cmd->pattern, probe_cmd->desc);
for (probe_cmd = cmd; probe_cmd->pattern; probe_cmd++)
cli_out("%s - %s", probe_cmd->pattern, probe_cmd->desc);
GF_FREE (cmd);
GF_FREE(cmd);
cli_out ("\n");
return 0;
cli_out("\n");
return 0;
}
int
cli_cmd_probe_register (struct cli_state *state)
cli_cmd_probe_register(struct cli_state *state)
{
int ret = 0;
struct cli_cmd *cmd = NULL;
int ret = 0;
struct cli_cmd *cmd = NULL;
for (cmd = cli_probe_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register (&state->tree, cmd);
if (ret)
goto out;
}
for (cmd = cli_probe_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register(&state->tree, cmd);
if (ret)
goto out;
}
out:
return ret;
return ret;
}

View File

@ -20,146 +20,118 @@
extern rpc_clnt_prog_t *cli_rpc_prog;
int
cli_cmd_snapshot_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount);
cli_cmd_snapshot_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount);
int
cli_cmd_snapshot_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
cli_cmd_snapshot_cbk(struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = 0;
int parse_err = 0;
dict_t *options = NULL;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
cli_local_t *local = NULL;
int ret = 0;
int parse_err = 0;
dict_t *options = NULL;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
cli_local_t *local = NULL;
proc = &cli_rpc_prog->proctable [GLUSTER_CLI_SNAP];
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SNAP];
frame = create_frame (THIS, THIS->ctx->pool);
if (frame == NULL) {
ret = -1;
goto out;
frame = create_frame(THIS, THIS->ctx->pool);
if (frame == NULL) {
ret = -1;
goto out;
}
/* Parses the command entered by the user */
ret = cli_cmd_snapshot_parse(words, wordcount, &options, state);
if (ret) {
if (ret < 0) {
cli_usage_out(word->pattern);
parse_err = 1;
} else {
/* User might have cancelled the snapshot operation */
ret = 0;
}
goto out;
}
/* Parses the command entered by the user */
ret = cli_cmd_snapshot_parse (words, wordcount, &options, state);
if (ret) {
if (ret < 0) {
cli_usage_out (word->pattern);
parse_err = 1;
} else {
/* User might have cancelled the snapshot operation */
ret = 0;
}
goto out;
}
CLI_LOCAL_INIT(local, words, frame, options);
CLI_LOCAL_INIT (local, words, frame, options);
if (proc->fn)
ret = proc->fn (frame, THIS, options);
if (proc->fn)
ret = proc->fn(frame, THIS, options);
out:
if (ret && parse_err == 0)
cli_out ("Snapshot command failed");
if (ret && parse_err == 0)
cli_out("Snapshot command failed");
CLI_STACK_DESTROY (frame);
CLI_STACK_DESTROY(frame);
return ret;
return ret;
}
struct cli_cmd snapshot_cmds[] = {
{ "snapshot help",
cli_cmd_snapshot_help_cbk,
"display help for snapshot commands"
},
{ "snapshot create <snapname> <volname> [no-timestamp] "
"[description <description>] [force]",
cli_cmd_snapshot_cbk,
"Snapshot Create."
},
{ "snapshot clone <clonename> <snapname>",
cli_cmd_snapshot_cbk,
"Snapshot Clone."
},
{ "snapshot restore <snapname>",
cli_cmd_snapshot_cbk,
"Snapshot Restore."
},
{ "snapshot status [(snapname | volume <volname>)]",
cli_cmd_snapshot_cbk,
"Snapshot Status."
},
{ "snapshot info [(snapname | volume <volname>)]",
cli_cmd_snapshot_cbk,
"Snapshot Info."
},
{ "snapshot list [volname]",
cli_cmd_snapshot_cbk,
"Snapshot List."
},
{"snapshot config [volname] ([snap-max-hard-limit <count>] "
"[snap-max-soft-limit <percent>]) "
"| ([auto-delete <enable|disable>])"
"| ([activate-on-create <enable|disable>])",
cli_cmd_snapshot_cbk,
"Snapshot Config."
},
{"snapshot delete (all | snapname | volume <volname>)",
cli_cmd_snapshot_cbk,
"Snapshot Delete."
},
{"snapshot activate <snapname> [force]",
cli_cmd_snapshot_cbk,
"Activate snapshot volume."
},
{"snapshot deactivate <snapname>",
cli_cmd_snapshot_cbk,
"Deactivate snapshot volume."
},
{ NULL, NULL, NULL }
};
{"snapshot help", cli_cmd_snapshot_help_cbk,
"display help for snapshot commands"},
{"snapshot create <snapname> <volname> [no-timestamp] "
"[description <description>] [force]",
cli_cmd_snapshot_cbk, "Snapshot Create."},
{"snapshot clone <clonename> <snapname>", cli_cmd_snapshot_cbk,
"Snapshot Clone."},
{"snapshot restore <snapname>", cli_cmd_snapshot_cbk, "Snapshot Restore."},
{"snapshot status [(snapname | volume <volname>)]", cli_cmd_snapshot_cbk,
"Snapshot Status."},
{"snapshot info [(snapname | volume <volname>)]", cli_cmd_snapshot_cbk,
"Snapshot Info."},
{"snapshot list [volname]", cli_cmd_snapshot_cbk, "Snapshot List."},
{"snapshot config [volname] ([snap-max-hard-limit <count>] "
"[snap-max-soft-limit <percent>]) "
"| ([auto-delete <enable|disable>])"
"| ([activate-on-create <enable|disable>])",
cli_cmd_snapshot_cbk, "Snapshot Config."},
{"snapshot delete (all | snapname | volume <volname>)",
cli_cmd_snapshot_cbk, "Snapshot Delete."},
{"snapshot activate <snapname> [force]", cli_cmd_snapshot_cbk,
"Activate snapshot volume."},
{"snapshot deactivate <snapname>", cli_cmd_snapshot_cbk,
"Deactivate snapshot volume."},
{NULL, NULL, NULL}};
int
cli_cmd_snapshot_help_cbk (struct cli_state *state,
struct cli_cmd_word *in_word,
const char **words,
int wordcount)
cli_cmd_snapshot_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount)
{
struct cli_cmd *cmd = NULL;
struct cli_cmd *snap_cmd = NULL;
int count = 0;
struct cli_cmd *cmd = NULL;
struct cli_cmd *snap_cmd = NULL;
int count = 0;
cmd = GF_MALLOC (sizeof (snapshot_cmds), cli_mt_cli_cmd);
memcpy (cmd, snapshot_cmds, sizeof (snapshot_cmds));
count = (sizeof (snapshot_cmds) / sizeof (struct cli_cmd));
cli_cmd_sort (cmd, count);
cmd = GF_MALLOC(sizeof(snapshot_cmds), cli_mt_cli_cmd);
memcpy(cmd, snapshot_cmds, sizeof(snapshot_cmds));
count = (sizeof(snapshot_cmds) / sizeof(struct cli_cmd));
cli_cmd_sort(cmd, count);
cli_out ("\ngluster snapshot commands");
cli_out ("=========================\n");
cli_out("\ngluster snapshot commands");
cli_out("=========================\n");
for (snap_cmd = cmd; snap_cmd->pattern; snap_cmd++)
if (_gf_false == snap_cmd->disable)
cli_out ("%s - %s", snap_cmd->pattern, snap_cmd->desc);
cli_out ("\n");
for (snap_cmd = cmd; snap_cmd->pattern; snap_cmd++)
if (_gf_false == snap_cmd->disable)
cli_out("%s - %s", snap_cmd->pattern, snap_cmd->desc);
cli_out("\n");
GF_FREE (cmd);
return 0;
GF_FREE(cmd);
return 0;
}
int
cli_cmd_snapshot_register (struct cli_state *state)
cli_cmd_snapshot_register(struct cli_state *state)
{
int ret = 0;
struct cli_cmd *cmd = NULL;
int ret = 0;
struct cli_cmd *cmd = NULL;
for (cmd = snapshot_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register (&state->tree, cmd);
if (ret)
goto out;
}
for (cmd = snapshot_cmds; cmd->pattern; cmd++) {
ret = cli_cmd_register(&state->tree, cmd);
if (ret)
goto out;
}
out:
return ret;
return ret;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -22,395 +22,390 @@
static int cmd_done;
static int cmd_sent;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t conn = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t conn = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
int cli_op_ret = 0;
int connected = 0;
int cli_op_ret = 0;
int connected = 0;
int cli_cmd_log_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount);
int
cli_cmd_log_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount);
static unsigned
cli_cmd_needs_connection (struct cli_cmd_word *word)
cli_cmd_needs_connection(struct cli_cmd_word *word)
{
if (!strcasecmp ("quit", word->word))
return 0;
if (!strcasecmp("quit", word->word))
return 0;
if (!strcasecmp ("help", word->word))
return 0;
if (!strcasecmp("help", word->word))
return 0;
if (!strcasecmp ("getwd", word->word))
return 1;
if (!strcasecmp("getwd", word->word))
return 1;
if (!strcasecmp ("exit", word->word))
return 0;
if (!strcasecmp("exit", word->word))
return 0;
return cli_default_conn_timeout;
return cli_default_conn_timeout;
}
int
cli_cmd_status_reset (void)
cli_cmd_status_reset(void)
{
int ret = 0;
int ret = 0;
ret = cli_cmd_lock ();
{
if (ret == 0) {
cmd_sent = 0;
cmd_done = 0;
}
ret = cli_cmd_lock();
{
if (ret == 0) {
cmd_sent = 0;
cmd_done = 0;
}
ret = cli_cmd_unlock ();
return ret;
}
ret = cli_cmd_unlock();
return ret;
}
int
cli_cmd_sent_status_get (int *status)
cli_cmd_sent_status_get(int *status)
{
int ret = 0;
GF_ASSERT (status);
int ret = 0;
GF_ASSERT(status);
ret = cli_cmd_lock ();
{
if (ret == 0)
*status = cmd_sent;
}
ret = cli_cmd_unlock ();
return ret;
ret = cli_cmd_lock();
{
if (ret == 0)
*status = cmd_sent;
}
ret = cli_cmd_unlock();
return ret;
}
int
cli_cmd_process (struct cli_state *state, int argc, char **argv)
cli_cmd_process(struct cli_state *state, int argc, char **argv)
{
int ret = 0;
struct cli_cmd_word *word = NULL;
struct cli_cmd_word *next = NULL;
int i = 0;
int ret = 0;
struct cli_cmd_word *word = NULL;
struct cli_cmd_word *next = NULL;
int i = 0;
word = &state->tree.root;
word = &state->tree.root;
if (!argc)
return 0;
if (!argc)
return 0;
for (i = 0; i < argc; i++) {
next = cli_cmd_nextword (word, argv[i]);
for (i = 0; i < argc; i++) {
next = cli_cmd_nextword(word, argv[i]);
word = next;
if (!word)
break;
word = next;
if (!word)
break;
if (word->cbkfn)
break;
}
if (word->cbkfn)
break;
}
if (!word) {
cli_out ("unrecognized word: %s (position %d)",
argv[i], i);
return -1;
}
if (!word) {
cli_out("unrecognized word: %s (position %d)", argv[i], i);
return -1;
}
if (!word->cbkfn) {
cli_out ("unrecognized command");
return -1;
}
if (!word->cbkfn) {
cli_out("unrecognized command");
return -1;
}
if ( strcmp (word->word,"help")==0 )
goto callback;
if (strcmp(word->word, "help") == 0)
goto callback;
state->await_connected = cli_cmd_needs_connection (word);
state->await_connected = cli_cmd_needs_connection(word);
ret = cli_cmd_await_connected (state->await_connected);
if (ret) {
cli_out ("Connection failed. Please check if gluster "
"daemon is operational.");
gf_log ("", GF_LOG_INFO, "Exiting with: %d", ret);
exit (ret);
}
ret = cli_cmd_await_connected(state->await_connected);
if (ret) {
cli_out(
"Connection failed. Please check if gluster "
"daemon is operational.");
gf_log("", GF_LOG_INFO, "Exiting with: %d", ret);
exit(ret);
}
callback:
ret = word->cbkfn (state, word, (const char **)argv, argc);
(void) cli_cmd_status_reset ();
return ret;
ret = word->cbkfn(state, word, (const char **)argv, argc);
(void)cli_cmd_status_reset();
return ret;
}
int
cli_cmd_input_token_count (const char *text)
cli_cmd_input_token_count(const char *text)
{
int count = 0;
const char *trav = NULL;
int is_spc = 1;
int count = 0;
const char *trav = NULL;
int is_spc = 1;
for (trav = text; *trav; trav++) {
if (*trav == ' ') {
is_spc = 1;
} else {
if (is_spc) {
count++;
is_spc = 0;
}
}
for (trav = text; *trav; trav++) {
if (*trav == ' ') {
is_spc = 1;
} else {
if (is_spc) {
count++;
is_spc = 0;
}
}
}
return count;
return count;
}
int
cli_cmd_process_line (struct cli_state *state, const char *text)
cli_cmd_process_line(struct cli_state *state, const char *text)
{
int count = 0;
char **tokens = NULL;
char **tokenp = NULL;
char *token = NULL;
char *copy = NULL;
char *saveptr = NULL;
int i = 0;
int ret = -1;
int count = 0;
char **tokens = NULL;
char **tokenp = NULL;
char *token = NULL;
char *copy = NULL;
char *saveptr = NULL;
int i = 0;
int ret = -1;
count = cli_cmd_input_token_count (text);
count = cli_cmd_input_token_count(text);
tokens = calloc (count + 1, sizeof (*tokens));
if (!tokens)
return -1;
tokens = calloc(count + 1, sizeof(*tokens));
if (!tokens)
return -1;
copy = strdup (text);
if (!copy)
goto out;
copy = strdup(text);
if (!copy)
goto out;
tokenp = tokens;
tokenp = tokens;
for (token = strtok_r (copy, " \t\r\n", &saveptr); token;
token = strtok_r (NULL, " \t\r\n", &saveptr)) {
*tokenp = strdup (token);
for (token = strtok_r(copy, " \t\r\n", &saveptr); token;
token = strtok_r(NULL, " \t\r\n", &saveptr)) {
*tokenp = strdup(token);
if (!*tokenp)
goto out;
tokenp++;
i++;
if (!*tokenp)
goto out;
tokenp++;
i++;
}
}
ret = cli_cmd_process (state, count, tokens);
ret = cli_cmd_process(state, count, tokens);
out:
free (copy);
free(copy);
if (tokens)
cli_cmd_tokens_destroy (tokens);
if (tokens)
cli_cmd_tokens_destroy(tokens);
return ret;
return ret;
}
int
cli_cmds_register (struct cli_state *state)
cli_cmds_register(struct cli_state *state)
{
int ret = 0;
int ret = 0;
ret = cli_cmd_volume_register (state);
if (ret)
goto out;
ret = cli_cmd_volume_register(state);
if (ret)
goto out;
ret = cli_cmd_probe_register (state);
if (ret)
goto out;
ret = cli_cmd_probe_register(state);
if (ret)
goto out;
ret = cli_cmd_system_register (state);
if (ret)
goto out;
ret = cli_cmd_system_register(state);
if (ret)
goto out;
ret = cli_cmd_misc_register (state);
if (ret)
goto out;
ret = cli_cmd_misc_register(state);
if (ret)
goto out;
ret = cli_cmd_snapshot_register (state);
if (ret)
goto out;
ret = cli_cmd_global_register (state);
if (ret)
goto out;
ret = cli_cmd_snapshot_register(state);
if (ret)
goto out;
ret = cli_cmd_global_register(state);
if (ret)
goto out;
out:
return ret;
return ret;
}
int
cli_cmd_cond_init ()
cli_cmd_cond_init()
{
pthread_mutex_init(&cond_mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_mutex_init (&cond_mutex, NULL);
pthread_cond_init (&cond, NULL);
pthread_mutex_init(&conn_mutex, NULL);
pthread_cond_init(&conn, NULL);
pthread_mutex_init (&conn_mutex, NULL);
pthread_cond_init (&conn, NULL);
return 0;
return 0;
}
int
cli_cmd_lock ()
cli_cmd_lock()
{
pthread_mutex_lock (&cond_mutex);
return 0;
pthread_mutex_lock(&cond_mutex);
return 0;
}
int
cli_cmd_unlock ()
cli_cmd_unlock()
{
pthread_mutex_unlock (&cond_mutex);
return 0;
pthread_mutex_unlock(&cond_mutex);
return 0;
}
static void
seconds_from_now (unsigned secs, struct timespec *ts)
seconds_from_now(unsigned secs, struct timespec *ts)
{
struct timeval tv = {0,};
struct timeval tv = {
0,
};
gettimeofday (&tv, NULL);
gettimeofday(&tv, NULL);
ts->tv_sec = tv.tv_sec + secs;
ts->tv_nsec = tv.tv_usec * 1000;
ts->tv_sec = tv.tv_sec + secs;
ts->tv_nsec = tv.tv_usec * 1000;
}
int
cli_cmd_await_response (unsigned time)
cli_cmd_await_response(unsigned time)
{
struct timespec ts = {0,};
int ret = 0;
struct timespec ts = {
0,
};
int ret = 0;
cli_op_ret = -1;
cli_op_ret = -1;
seconds_from_now (time, &ts);
while (!cmd_done && !ret) {
ret = pthread_cond_timedwait (&cond, &cond_mutex,
&ts);
}
seconds_from_now(time, &ts);
while (!cmd_done && !ret) {
ret = pthread_cond_timedwait(&cond, &cond_mutex, &ts);
}
if (!cmd_done) {
if (ret == ETIMEDOUT)
cli_out ("Error : Request timed out");
else
cli_out ("Error : Command returned with error code:%d",
ret);
}
cmd_done = 0;
if (!cmd_done) {
if (ret == ETIMEDOUT)
cli_out("Error : Request timed out");
else
cli_out("Error : Command returned with error code:%d", ret);
}
cmd_done = 0;
return cli_op_ret;
return cli_op_ret;
}
/* This function must be called _only_ after all actions associated with
* command processing is complete. Otherwise, gluster process may exit before
* reporting results to stdout/stderr. */
int
cli_cmd_broadcast_response (int32_t status)
cli_cmd_broadcast_response(int32_t status)
{
pthread_mutex_lock (&cond_mutex);
{
if (!cmd_sent)
goto out;
cmd_done = 1;
cli_op_ret = status;
pthread_cond_broadcast (&cond);
}
pthread_mutex_lock(&cond_mutex);
{
if (!cmd_sent)
goto out;
cmd_done = 1;
cli_op_ret = status;
pthread_cond_broadcast(&cond);
}
out:
pthread_mutex_unlock (&cond_mutex);
return 0;
pthread_mutex_unlock(&cond_mutex);
return 0;
}
int32_t
cli_cmd_await_connected (unsigned conn_timo)
cli_cmd_await_connected(unsigned conn_timo)
{
int32_t ret = 0;
struct timespec ts = {0,};
int32_t ret = 0;
struct timespec ts = {
0,
};
if (!conn_timo)
return 0;
if (!conn_timo)
return 0;
pthread_mutex_lock (&conn_mutex);
{
seconds_from_now (conn_timo, &ts);
while (!connected && !ret) {
ret = pthread_cond_timedwait (&conn, &conn_mutex,
&ts);
}
pthread_mutex_lock(&conn_mutex);
{
seconds_from_now(conn_timo, &ts);
while (!connected && !ret) {
ret = pthread_cond_timedwait(&conn, &conn_mutex, &ts);
}
pthread_mutex_unlock (&conn_mutex);
}
pthread_mutex_unlock(&conn_mutex);
return ret;
return ret;
}
int32_t
cli_cmd_broadcast_connected ()
cli_cmd_broadcast_connected()
{
pthread_mutex_lock (&conn_mutex);
{
connected = 1;
pthread_cond_broadcast (&conn);
}
pthread_mutex_lock(&conn_mutex);
{
connected = 1;
pthread_cond_broadcast(&conn);
}
pthread_mutex_unlock (&conn_mutex);
pthread_mutex_unlock(&conn_mutex);
return 0;
return 0;
}
int
cli_cmd_submit (struct rpc_clnt* rpc, void *req, call_frame_t *frame,
rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref,
xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
cli_cmd_submit(struct rpc_clnt *rpc, void *req, call_frame_t *frame,
rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref,
xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
{
int ret = -1;
unsigned timeout = 0;
int ret = -1;
unsigned timeout = 0;
if ((GLUSTER_CLI_PROFILE_VOLUME == procnum) ||
(GLUSTER_CLI_HEAL_VOLUME == procnum))
timeout = cli_ten_minutes_timeout;
else
timeout = cli_default_conn_timeout;
if ((GLUSTER_CLI_PROFILE_VOLUME == procnum) ||
(GLUSTER_CLI_HEAL_VOLUME == procnum))
timeout = cli_ten_minutes_timeout;
else
timeout = cli_default_conn_timeout;
cli_cmd_lock ();
cmd_sent = 0;
ret = cli_submit_request (rpc, req, frame, prog,
procnum, NULL, this, cbkfn, xdrproc);
cli_cmd_lock();
cmd_sent = 0;
ret = cli_submit_request(rpc, req, frame, prog, procnum, NULL, this, cbkfn,
xdrproc);
if (!ret) {
cmd_sent = 1;
ret = cli_cmd_await_response (timeout);
}
if (!ret) {
cmd_sent = 1;
ret = cli_cmd_await_response(timeout);
}
cli_cmd_unlock ();
cli_cmd_unlock();
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
int
cli_cmd_pattern_cmp (void *a, void *b)
cli_cmd_pattern_cmp(void *a, void *b)
{
struct cli_cmd *ia = NULL;
struct cli_cmd *ib = NULL;
int ret = 0;
struct cli_cmd *ia = NULL;
struct cli_cmd *ib = NULL;
int ret = 0;
ia = a;
ib = b;
if (strcmp (ia->pattern, ib->pattern) > 0)
ret = 1;
else if (strcmp (ia->pattern, ib->pattern) < 0)
ret = -1;
else
ret = 0;
return ret;
ia = a;
ib = b;
if (strcmp(ia->pattern, ib->pattern) > 0)
ret = 1;
else if (strcmp(ia->pattern, ib->pattern) < 0)
ret = -1;
else
ret = 0;
return ret;
}
void
cli_cmd_sort (struct cli_cmd *cmd, int count)
cli_cmd_sort(struct cli_cmd *cmd, int count)
{
gf_array_insertionsort (cmd, 1, count - 2, sizeof(struct cli_cmd),
cli_cmd_pattern_cmp);
gf_array_insertionsort(cmd, 1, count - 2, sizeof(struct cli_cmd),
cli_cmd_pattern_cmp);
}

View File

@ -14,136 +14,131 @@ extern struct rpc_clnt global_quotad_rpc;
extern struct rpc_clnt_program cli_quotad_clnt;
int
cli_quotad_submit_request (void *req, call_frame_t *frame,
rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref,
xlator_t *this, fop_cbk_fn_t cbkfn,
xdrproc_t xdrproc)
cli_quotad_submit_request(void *req, call_frame_t *frame, rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref, xlator_t *this,
fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
{
int ret = -1;
int count = 0;
struct iovec iov = {0, };
struct iobuf *iobuf = NULL;
char new_iobref = 0;
ssize_t xdr_size = 0;
int ret = -1;
int count = 0;
struct iovec iov = {
0,
};
struct iobuf *iobuf = NULL;
char new_iobref = 0;
ssize_t xdr_size = 0;
GF_ASSERT (this);
GF_ASSERT(this);
if (req) {
xdr_size = xdr_sizeof (xdrproc, req);
iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size);
if (!iobuf) {
goto out;
};
if (req) {
xdr_size = xdr_sizeof(xdrproc, req);
iobuf = iobuf_get2(this->ctx->iobuf_pool, xdr_size);
if (!iobuf) {
goto out;
};
if (!iobref) {
iobref = iobref_new ();
if (!iobref) {
goto out;
}
if (!iobref) {
iobref = iobref_new();
if (!iobref) {
goto out;
}
new_iobref = 1;
}
iobref_add (iobref, iobuf);
iov.iov_base = iobuf->ptr;
iov.iov_len = iobuf_size (iobuf);
/* Create the xdr payload */
ret = xdr_serialize_generic (iov, req, xdrproc);
if (ret == -1) {
goto out;
}
iov.iov_len = ret;
count = 1;
new_iobref = 1;
}
/* Send the msg */
ret = rpc_clnt_submit (&global_quotad_rpc, prog, procnum, cbkfn,
&iov, count,
NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
ret = 0;
iobref_add(iobref, iobuf);
iov.iov_base = iobuf->ptr;
iov.iov_len = iobuf_size(iobuf);
/* Create the xdr payload */
ret = xdr_serialize_generic(iov, req, xdrproc);
if (ret == -1) {
goto out;
}
iov.iov_len = ret;
count = 1;
}
/* Send the msg */
ret = rpc_clnt_submit(&global_quotad_rpc, prog, procnum, cbkfn, &iov, count,
NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
ret = 0;
out:
if (new_iobref)
iobref_unref (iobref);
if (iobuf)
iobuf_unref (iobuf);
if (new_iobref)
iobref_unref(iobref);
if (iobuf)
iobuf_unref(iobuf);
return ret;
return ret;
}
int
cli_quotad_notify (struct rpc_clnt *rpc, void *mydata,
rpc_clnt_event_t event, void *data)
cli_quotad_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
void *data)
{
xlator_t *this = NULL;
int ret = 0;
xlator_t *this = NULL;
int ret = 0;
this = mydata;
this = mydata;
switch (event) {
case RPC_CLNT_CONNECT:
{
gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
break;
switch (event) {
case RPC_CLNT_CONNECT: {
gf_log(this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
break;
}
case RPC_CLNT_DISCONNECT:
{
gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
break;
case RPC_CLNT_DISCONNECT: {
gf_log(this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
break;
}
default:
gf_log (this->name, GF_LOG_TRACE,
"got some other RPC event %d", event);
ret = 0;
break;
}
gf_log(this->name, GF_LOG_TRACE, "got some other RPC event %d",
event);
ret = 0;
break;
}
return ret;
return ret;
}
struct rpc_clnt *
cli_quotad_clnt_init (xlator_t *this, dict_t *options)
cli_quotad_clnt_init(xlator_t *this, dict_t *options)
{
struct rpc_clnt *rpc = NULL;
int ret = -1;
struct rpc_clnt *rpc = NULL;
int ret = -1;
ret = dict_set_str(options, "transport.address-family", "unix");
if (ret)
goto out;
ret = dict_set_str (options, "transport.address-family", "unix");
if (ret)
goto out;
ret = dict_set_str(options, "transport-type", "socket");
if (ret)
goto out;
ret = dict_set_str (options, "transport-type", "socket");
if (ret)
goto out;
ret = dict_set_str(options, "transport.socket.connect-path",
"/var/run/gluster/quotad.socket");
if (ret)
goto out;
ret = dict_set_str (options, "transport.socket.connect-path",
"/var/run/gluster/quotad.socket");
if (ret)
goto out;
rpc = rpc_clnt_new(options, this, this->name, 16);
if (!rpc)
goto out;
rpc = rpc_clnt_new (options, this, this->name, 16);
if (!rpc)
goto out;
ret = rpc_clnt_register_notify(rpc, cli_quotad_notify, this);
if (ret) {
gf_log("cli", GF_LOG_ERROR, "failed to register notify");
goto out;
}
ret = rpc_clnt_register_notify (rpc, cli_quotad_notify, this);
if (ret) {
gf_log ("cli", GF_LOG_ERROR, "failed to register notify");
goto out;
}
rpc_clnt_start (rpc);
rpc_clnt_start(rpc);
out:
if (ret) {
if (rpc)
rpc_clnt_unref (rpc);
rpc = NULL;
}
if (ret) {
if (rpc)
rpc_clnt_unref(rpc);
rpc = NULL;
}
return rpc;
return rpc;
}

View File

@ -27,392 +27,374 @@
#include <readline/readline.h>
#include <readline/history.h>
int
cli_rl_out (struct cli_state *state, const char *fmt, va_list ap)
cli_rl_out(struct cli_state *state, const char *fmt, va_list ap)
{
int tmp_rl_point = rl_point;
int n = rl_end;
int ret = 0;
int tmp_rl_point = rl_point;
int n = rl_end;
int ret = 0;
if (rl_end >= 0 ) {
rl_kill_text (0, rl_end);
rl_redisplay ();
}
if (rl_end >= 0) {
rl_kill_text(0, rl_end);
rl_redisplay();
}
printf ("\r%*s\r", (int)strlen (state->prompt), "");
printf("\r%*s\r", (int)strlen(state->prompt), "");
ret = vprintf (fmt, ap);
ret = vprintf(fmt, ap);
printf ("\n");
fflush(stdout);
printf("\n");
fflush(stdout);
if (n) {
rl_do_undo ();
rl_point = tmp_rl_point;
rl_reset_line_state ();
}
if (n) {
rl_do_undo();
rl_point = tmp_rl_point;
rl_reset_line_state();
}
return ret;
return ret;
}
int
cli_rl_err (struct cli_state *state, const char *fmt, va_list ap)
cli_rl_err(struct cli_state *state, const char *fmt, va_list ap)
{
int tmp_rl_point = rl_point;
int n = rl_end;
int ret = 0;
int tmp_rl_point = rl_point;
int n = rl_end;
int ret = 0;
if (rl_end >= 0 ) {
rl_kill_text (0, rl_end);
rl_redisplay ();
}
if (rl_end >= 0) {
rl_kill_text(0, rl_end);
rl_redisplay();
}
fprintf (stderr, "\r%*s\r", (int)strlen (state->prompt), "");
fprintf(stderr, "\r%*s\r", (int)strlen(state->prompt), "");
ret = vfprintf (stderr, fmt, ap);
ret = vfprintf(stderr, fmt, ap);
fprintf (stderr, "\n");
fflush(stderr);
fprintf(stderr, "\n");
fflush(stderr);
if (n) {
rl_do_undo ();
rl_point = tmp_rl_point;
rl_reset_line_state ();
}
if (n) {
rl_do_undo();
rl_point = tmp_rl_point;
rl_reset_line_state();
}
return ret;
return ret;
}
void
cli_rl_process_line (char *line)
cli_rl_process_line(char *line)
{
struct cli_state *state = NULL;
int ret = 0;
struct cli_state *state = NULL;
int ret = 0;
state = global_state;
state = global_state;
state->rl_processing = 1;
{
ret = cli_cmd_process_line (state, line);
if (ret)
gf_log (THIS->name, GF_LOG_WARNING,
"failed to process line");
add_history (line);
}
state->rl_processing = 0;
state->rl_processing = 1;
{
ret = cli_cmd_process_line(state, line);
if (ret)
gf_log(THIS->name, GF_LOG_WARNING, "failed to process line");
add_history(line);
}
state->rl_processing = 0;
}
int
cli_rl_stdin (int fd, int idx, int gen, void *data,
int poll_out, int poll_in, int poll_err)
cli_rl_stdin(int fd, int idx, int gen, void *data, int poll_out, int poll_in,
int poll_err)
{
struct cli_state *state = NULL;
struct cli_state *state = NULL;
state = data;
state = data;
rl_callback_read_char ();
rl_callback_read_char();
event_handled (state->ctx->event_pool, fd, idx, gen);
event_handled(state->ctx->event_pool, fd, idx, gen);
return 0;
return 0;
}
char *
cli_rl_autocomplete_entry (const char *text, int times)
cli_rl_autocomplete_entry(const char *text, int times)
{
struct cli_state *state = NULL;
char *retp = NULL;
struct cli_state *state = NULL;
char *retp = NULL;
state = global_state;
state = global_state;
if (!state->matchesp)
return NULL;
if (!state->matchesp)
return NULL;
retp = *state->matchesp;
retp = *state->matchesp;
state->matchesp++;
state->matchesp++;
return retp ? strdup (retp) : NULL;
return retp ? strdup(retp) : NULL;
}
int
cli_rl_token_count (const char *text)
cli_rl_token_count(const char *text)
{
int count = 0;
const char *trav = NULL;
int is_spc = 1;
int count = 0;
const char *trav = NULL;
int is_spc = 1;
for (trav = text; *trav; trav++) {
if (*trav == ' ') {
is_spc = 1;
} else {
if (is_spc) {
count++;
is_spc = 0;
}
}
}
if (is_spc)
/* what needs to be autocompleted is a full
new word, and not extend the last word
*/
for (trav = text; *trav; trav++) {
if (*trav == ' ') {
is_spc = 1;
} else {
if (is_spc) {
count++;
is_spc = 0;
}
}
}
return count;
if (is_spc)
/* what needs to be autocompleted is a full
new word, and not extend the last word
*/
count++;
return count;
}
char **
cli_rl_tokenize (const char *text)
cli_rl_tokenize(const char *text)
{
int count = 0;
char **tokens = NULL;
char **tokenp = NULL;
char *token = NULL;
char *copy = NULL;
char *saveptr = NULL;
int i = 0;
int count = 0;
char **tokens = NULL;
char **tokenp = NULL;
char *token = NULL;
char *copy = NULL;
char *saveptr = NULL;
int i = 0;
count = cli_rl_token_count (text);
count = cli_rl_token_count(text);
tokens = calloc (count + 1, sizeof (*tokens));
if (!tokens)
return NULL;
tokens = calloc(count + 1, sizeof(*tokens));
if (!tokens)
return NULL;
copy = strdup (text);
if (!copy)
goto out;
copy = strdup(text);
if (!copy)
goto out;
tokenp = tokens;
tokenp = tokens;
for (token = strtok_r (copy, " \t\r\n", &saveptr); token;
token = strtok_r (NULL, " \t\r\n", &saveptr)) {
*tokenp = strdup (token);
for (token = strtok_r(copy, " \t\r\n", &saveptr); token;
token = strtok_r(NULL, " \t\r\n", &saveptr)) {
*tokenp = strdup(token);
if (!*tokenp)
goto out;
tokenp++;
i++;
if (!*tokenp)
goto out;
tokenp++;
i++;
}
}
if (i < count) {
/* symbolize that what needs to be autocompleted is
the full set of possible nextwords, and not extend
the last word
*/
*tokenp = strdup ("");
if (!*tokenp)
goto out;
tokenp++;
i++;
}
if (i < count) {
/* symbolize that what needs to be autocompleted is
the full set of possible nextwords, and not extend
the last word
*/
*tokenp = strdup("");
if (!*tokenp)
goto out;
tokenp++;
i++;
}
out:
free (copy);
free(copy);
if (i < count) {
cli_cmd_tokens_destroy (tokens);
tokens = NULL;
}
if (i < count) {
cli_cmd_tokens_destroy(tokens);
tokens = NULL;
}
return tokens;
return tokens;
}
char **
cli_rl_get_matches (struct cli_state *state, struct cli_cmd_word *word,
const char *text)
cli_rl_get_matches(struct cli_state *state, struct cli_cmd_word *word,
const char *text)
{
char **matches = NULL;
char **matchesp = NULL;
struct cli_cmd_word **next = NULL;
int count = 0;
int len = 0;
char **matches = NULL;
char **matchesp = NULL;
struct cli_cmd_word **next = NULL;
int count = 0;
int len = 0;
len = strlen (text);
len = strlen(text);
if (!word->nextwords)
return NULL;
if (!word->nextwords)
return NULL;
for (next = word->nextwords; *next; next++)
count++;
for (next = word->nextwords; *next; next++)
count++;
matches = calloc (count + 1, sizeof (*matches));
matchesp = matches;
matches = calloc(count + 1, sizeof(*matches));
matchesp = matches;
for (next = word->nextwords; *next; next++) {
if ((*next)->match) {
continue;
}
if (strncmp ((*next)->word, text, len) == 0) {
*matchesp = strdup ((*next)->word);
matchesp++;
}
for (next = word->nextwords; *next; next++) {
if ((*next)->match) {
continue;
}
return matches;
if (strncmp((*next)->word, text, len) == 0) {
*matchesp = strdup((*next)->word);
matchesp++;
}
}
return matches;
}
int
cli_rl_autocomplete_prepare (struct cli_state *state, const char *text)
cli_rl_autocomplete_prepare(struct cli_state *state, const char *text)
{
struct cli_cmd_word *word = NULL;
struct cli_cmd_word *next = NULL;
char **tokens = NULL;
char **tokenp = NULL;
char *token = NULL;
char **matches = NULL;
struct cli_cmd_word *word = NULL;
struct cli_cmd_word *next = NULL;
char **tokens = NULL;
char **tokenp = NULL;
char *token = NULL;
char **matches = NULL;
tokens = cli_rl_tokenize (text);
if (!tokens)
return 0;
tokens = cli_rl_tokenize(text);
if (!tokens)
return 0;
word = &state->tree.root;
word = &state->tree.root;
for (tokenp = tokens; (token = *tokenp); tokenp++) {
if (!*(tokenp+1)) {
/* last word */
break;
}
next = cli_cmd_nextword (word, token);
word = next;
if (!word)
break;
for (tokenp = tokens; (token = *tokenp); tokenp++) {
if (!*(tokenp + 1)) {
/* last word */
break;
}
next = cli_cmd_nextword(word, token);
word = next;
if (!word)
goto out;
break;
}
if (!token)
return 0;
matches = cli_rl_get_matches (state, word, token);
if (!word)
goto out;
state->matches = matches;
state->matchesp = matches;
if (!token)
return 0;
matches = cli_rl_get_matches(state, word, token);
state->matches = matches;
state->matchesp = matches;
out:
cli_cmd_tokens_destroy (tokens);
return 0;
cli_cmd_tokens_destroy(tokens);
return 0;
}
int
cli_rl_autocomplete_cleanup (struct cli_state *state)
cli_rl_autocomplete_cleanup(struct cli_state *state)
{
if (state->matches)
cli_cmd_tokens_destroy (state->matches);
if (state->matches)
cli_cmd_tokens_destroy(state->matches);
state->matches = NULL;
state->matchesp = NULL;
state->matches = NULL;
state->matchesp = NULL;
return 0;
return 0;
}
char **
cli_rl_autocomplete (const char *text, int start, int end)
cli_rl_autocomplete(const char *text, int start, int end)
{
struct cli_state *state = NULL;
char **matches = NULL;
char save = 0;
struct cli_state *state = NULL;
char **matches = NULL;
char save = 0;
state = global_state;
state = global_state;
/* hack to make the autocompletion code neater */
/* fake it as though the cursor is at the end of line */
/* hack to make the autocompletion code neater */
/* fake it as though the cursor is at the end of line */
save = rl_line_buffer[rl_point];
rl_line_buffer[rl_point] = 0;
save = rl_line_buffer[rl_point];
rl_line_buffer[rl_point] = 0;
cli_rl_autocomplete_prepare (state, rl_line_buffer);
cli_rl_autocomplete_prepare(state, rl_line_buffer);
matches = rl_completion_matches (text, cli_rl_autocomplete_entry);
matches = rl_completion_matches(text, cli_rl_autocomplete_entry);
cli_rl_autocomplete_cleanup (state);
cli_rl_autocomplete_cleanup(state);
rl_line_buffer[rl_point] = save;
rl_line_buffer[rl_point] = save;
return matches;
return matches;
}
static char *
complete_none (const char *txt, int times)
complete_none(const char *txt, int times)
{
return NULL;
return NULL;
}
void *
cli_rl_input (void *_data)
cli_rl_input(void *_data)
{
struct cli_state *state = NULL;
char *line = NULL;
struct cli_state *state = NULL;
char *line = NULL;
state = _data;
state = _data;
for (;;) {
line = readline (state->prompt);
if (!line)
exit(0); //break;
for (;;) {
line = readline(state->prompt);
if (!line)
exit(0); // break;
if (*line)
cli_rl_process_line (line);
if (*line)
cli_rl_process_line(line);
free (line);
}
free(line);
}
return NULL;
return NULL;
}
int
cli_rl_enable (struct cli_state *state)
cli_rl_enable(struct cli_state *state)
{
int ret = 0;
int ret = 0;
rl_pre_input_hook = NULL;
rl_attempted_completion_function = cli_rl_autocomplete;
rl_completion_entry_function = complete_none;
rl_pre_input_hook = NULL;
rl_attempted_completion_function = cli_rl_autocomplete;
rl_completion_entry_function = complete_none;
if (!state->rl_async) {
ret = pthread_create (&state->input, NULL,
cli_rl_input, state);
if (ret == 0)
state->rl_enabled = 1;
goto out;
}
if (!state->rl_async) {
ret = pthread_create(&state->input, NULL, cli_rl_input, state);
if (ret == 0)
state->rl_enabled = 1;
goto out;
}
ret = event_register (state->ctx->event_pool, 0, cli_rl_stdin, state,
1, 0);
if (ret == -1)
goto out;
ret = event_register(state->ctx->event_pool, 0, cli_rl_stdin, state, 1, 0);
if (ret == -1)
goto out;
state->rl_enabled = 1;
rl_callback_handler_install (state->prompt, cli_rl_process_line);
state->rl_enabled = 1;
rl_callback_handler_install(state->prompt, cli_rl_process_line);
out:
return state->rl_enabled;
return state->rl_enabled;
}
#else /* HAVE_READLINE */
int
cli_rl_enable (struct cli_state *state)
cli_rl_enable(struct cli_state *state)
{
return 0;
return 0;
}
#endif /* HAVE_READLINE */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,74 +19,72 @@
#define CMDBUFSIZ 1024
void *
cli_batch (void *d)
cli_batch(void *d)
{
struct cli_state *state = NULL;
int ret = 0;
struct cli_state *state = NULL;
int ret = 0;
state = d;
state = d;
ret = cli_cmd_process (state, state->argc, state->argv);
ret = cli_cmd_process(state, state->argc, state->argv);
gf_log ("", GF_LOG_INFO, "Exiting with: %d", ret);
exit (-ret);
gf_log("", GF_LOG_INFO, "Exiting with: %d", ret);
exit(-ret);
return NULL;
return NULL;
}
void *
cli_input (void *d)
cli_input(void *d)
{
struct cli_state *state = NULL;
int ret = 0;
char cmdbuf[CMDBUFSIZ];
char *cmd = NULL;
size_t len = 0;
struct cli_state *state = NULL;
int ret = 0;
char cmdbuf[CMDBUFSIZ];
char *cmd = NULL;
size_t len = 0;
state = d;
state = d;
for (;;) {
printf ("%s", state->prompt);
for (;;) {
printf("%s", state->prompt);
cmd = fgets (cmdbuf, CMDBUFSIZ, stdin);
if (!cmd)
break;
len = strlen(cmd);
if (len > 0 && cmd[len - 1] == '\n') //strip trailing \n
cmd[len - 1] = '\0';
ret = cli_cmd_process_line (state, cmd);
if (ret != 0 && state->mode & GLUSTER_MODE_ERR_FATAL)
break;
}
cmd = fgets(cmdbuf, CMDBUFSIZ, stdin);
if (!cmd)
break;
len = strlen(cmd);
if (len > 0 && cmd[len - 1] == '\n') // strip trailing \n
cmd[len - 1] = '\0';
ret = cli_cmd_process_line(state, cmd);
if (ret != 0 && state->mode & GLUSTER_MODE_ERR_FATAL)
break;
}
exit (-ret);
exit(-ret);
return NULL;
return NULL;
}
int
cli_input_init (struct cli_state *state)
cli_input_init(struct cli_state *state)
{
int ret = 0;
if (state->argc) {
ret = pthread_create (&state->input, NULL, cli_batch, state);
return ret;
}
if (isatty (STDIN_FILENO)) {
state->prompt = "gluster> ";
cli_rl_enable (state);
} else {
state->prompt = "";
state->mode |= GLUSTER_MODE_SCRIPT | GLUSTER_MODE_ERR_FATAL;
}
if (!state->rl_enabled)
ret = pthread_create (&state->input, NULL, cli_input, state);
int ret = 0;
if (state->argc) {
ret = pthread_create(&state->input, NULL, cli_batch, state);
return ret;
}
if (isatty(STDIN_FILENO)) {
state->prompt = "gluster> ";
cli_rl_enable(state);
} else {
state->prompt = "";
state->mode |= GLUSTER_MODE_SCRIPT | GLUSTER_MODE_ERR_FATAL;
}
if (!state->rl_enabled)
ret = pthread_create(&state->input, NULL, cli_input, state);
return ret;
}

View File

@ -15,20 +15,18 @@
#include "cli.h"
#include "cli-cmd.h"
static int
__is_spc (int ch)
__is_spc(int ch)
{
if (ch == ' ')
return 1;
return 0;
if (ch == ' ')
return 1;
return 0;
}
static int
__is_div (int ch)
__is_div(int ch)
{
switch (ch) {
switch (ch) {
case '(':
case ')':
case '<':
@ -38,369 +36,356 @@ __is_div (int ch)
case '{':
case '}':
case '|':
return 1;
}
return 1;
}
return 0;
return 0;
}
static int
__is_word (const char *word)
__is_word(const char *word)
{
return (!__is_div (*word) && !__is_spc (*word));
return (!__is_div(*word) && !__is_spc(*word));
}
int
counter_char (int ch)
counter_char(int ch)
{
switch (ch) {
switch (ch) {
case '(':
return ')';
return ')';
case '<':
return '>';
return '>';
case '[':
return ']';
return ']';
case '{':
return '}';
}
return '}';
}
return -1;
return -1;
}
const char *
__is_template_balanced (const char *template)
__is_template_balanced(const char *template)
{
const char *trav = NULL;
int ch = 0;
const char *trav = NULL;
int ch = 0;
trav = template;
trav = template;
while (*trav) {
ch = *trav;
while (*trav) {
ch = *trav;
switch (ch) {
case '<':
case '(':
case '[':
trav = __is_template_balanced (trav+1);
if (!trav)
return NULL;
if (*trav != counter_char (ch))
return NULL;
break;
case '>':
case ')':
case ']':
return trav;
}
trav++;
switch (ch) {
case '<':
case '(':
case '[':
trav = __is_template_balanced(trav + 1);
if (!trav)
return NULL;
if (*trav != counter_char(ch))
return NULL;
break;
case '>':
case ')':
case ']':
return trav;
}
return trav;
trav++;
}
return trav;
}
int
is_template_balanced (const char *template)
is_template_balanced(const char *template)
{
const char *trav = NULL;
const char *trav = NULL;
trav = __is_template_balanced (template);
if (!trav || *trav)
return -1;
trav = __is_template_balanced(template);
if (!trav || *trav)
return -1;
return 0;
return 0;
}
int
cli_cmd_token_count (const char *template)
cli_cmd_token_count(const char *template)
{
int count = 0;
const char *trav = NULL;
int is_alnum = 0;
int count = 0;
const char *trav = NULL;
int is_alnum = 0;
for (trav = template; *trav; trav++) {
switch (*trav) {
case '<':
case '>':
case '(':
case ')':
case '[':
case ']':
case '{':
case '}':
case '|':
count++;
/* fall through */
case ' ':
is_alnum = 0;
break;
default:
if (!is_alnum) {
is_alnum = 1;
count++;
}
for (trav = template; *trav; trav++) {
switch (*trav) {
case '<':
case '>':
case '(':
case ')':
case '[':
case ']':
case '{':
case '}':
case '|':
count++;
/* fall through */
case ' ':
is_alnum = 0;
break;
default:
if (!is_alnum) {
is_alnum = 1;
count++;
}
}
}
return count + 1;
return count + 1;
}
void
cli_cmd_tokens_destroy (char **tokens)
cli_cmd_tokens_destroy(char **tokens)
{
char **tokenp = NULL;
char **tokenp = NULL;
if (!tokens)
return;
if (!tokens)
return;
tokenp = tokens;
while (*tokenp) {
free (*tokenp);
tokenp++;
}
tokenp = tokens;
while (*tokenp) {
free(*tokenp);
tokenp++;
}
free (tokens);
free(tokens);
}
int
cli_cmd_tokens_fill (char **tokens, const char *template)
cli_cmd_tokens_fill(char **tokens, const char *template)
{
const char *trav = NULL;
char **tokenp = NULL;
char *token = NULL;
int ret = 0;
int ch = 0;
const char *trav = NULL;
char **tokenp = NULL;
char *token = NULL;
int ret = 0;
int ch = 0;
tokenp = tokens;
tokenp = tokens;
for (trav = template; *trav; trav++) {
ch = *trav;
for (trav = template; *trav; trav++) {
ch = *trav;
if (__is_spc (ch))
continue;
if (__is_spc(ch))
continue;
if (__is_div (ch)) {
token = calloc (2, 1);
if (!token)
return -1;
token[0] = ch;
if (__is_div(ch)) {
token = calloc(2, 1);
if (!token)
return -1;
token[0] = ch;
*tokenp = token;
tokenp++;
*tokenp = token;
tokenp++;
continue;
}
token = strdup (trav);
*tokenp = token;
tokenp++;
for (token++; *token; token++) {
if (__is_spc (*token) || __is_div (*token)) {
*token = 0;
break;
}
trav++;
}
continue;
}
return ret;
token = strdup(trav);
*tokenp = token;
tokenp++;
for (token++; *token; token++) {
if (__is_spc(*token) || __is_div(*token)) {
*token = 0;
break;
}
trav++;
}
}
return ret;
}
char **
cli_cmd_tokenize (const char *template)
cli_cmd_tokenize(const char *template)
{
char **tokens = NULL;
int ret = 0;
int count = 0;
char **tokens = NULL;
int ret = 0;
int count = 0;
ret = is_template_balanced (template);
if (ret)
return NULL;
count = cli_cmd_token_count (template);
if (count <= 0)
return NULL;
tokens = calloc (count + 1, sizeof (char *));
if (!tokens)
return NULL;
ret = cli_cmd_tokens_fill (tokens, template);
if (ret)
goto err;
return tokens;
err:
cli_cmd_tokens_destroy (tokens);
ret = is_template_balanced(template);
if (ret)
return NULL;
count = cli_cmd_token_count(template);
if (count <= 0)
return NULL;
tokens = calloc(count + 1, sizeof(char *));
if (!tokens)
return NULL;
ret = cli_cmd_tokens_fill(tokens, template);
if (ret)
goto err;
return tokens;
err:
cli_cmd_tokens_destroy(tokens);
return NULL;
}
void *
cli_getunamb (const char *tok, void **choices, cli_selector_t sel)
cli_getunamb(const char *tok, void **choices, cli_selector_t sel)
{
void **wcon = NULL;
char *w = NULL;
unsigned mn = 0;
void *ret = NULL;
void **wcon = NULL;
char *w = NULL;
unsigned mn = 0;
void *ret = NULL;
if (!choices || !tok || !*tok)
return NULL;
if (!choices || !tok || !*tok)
return NULL;
for (wcon = choices; *wcon; wcon++) {
w = strtail ((char *)sel (*wcon), tok);
if (!w)
/* no match */
continue;
if (!*w)
/* exact match */
return *wcon;
for (wcon = choices; *wcon; wcon++) {
w = strtail((char *)sel(*wcon), tok);
if (!w)
/* no match */
continue;
if (!*w)
/* exact match */
return *wcon;
ret = *wcon;
mn++;
}
ret = *wcon;
mn++;
}
#ifdef FORCE_MATCH_EXACT
return NULL;
return NULL;
#else
return (mn == 1) ? ret : NULL;
return (mn == 1) ? ret : NULL;
#endif
}
static const char *
sel_cmd_word (void *wcon)
sel_cmd_word(void *wcon)
{
return ((struct cli_cmd_word *)wcon)->word;
return ((struct cli_cmd_word *)wcon)->word;
}
struct cli_cmd_word *
cli_cmd_nextword (struct cli_cmd_word *word, const char *token)
cli_cmd_nextword(struct cli_cmd_word *word, const char *token)
{
return (struct cli_cmd_word *)cli_getunamb (token,
(void **)word->nextwords,
sel_cmd_word);
return (struct cli_cmd_word *)cli_getunamb(token, (void **)word->nextwords,
sel_cmd_word);
}
struct cli_cmd_word *
cli_cmd_newword (struct cli_cmd_word *word, const char *token)
cli_cmd_newword(struct cli_cmd_word *word, const char *token)
{
struct cli_cmd_word **nextwords = NULL;
struct cli_cmd_word *nextword = NULL;
struct cli_cmd_word **nextwords = NULL;
struct cli_cmd_word *nextword = NULL;
nextwords = realloc (word->nextwords,
(word->nextwords_cnt + 2) * sizeof (*nextwords));
if (!nextwords)
return NULL;
nextwords = realloc(word->nextwords,
(word->nextwords_cnt + 2) * sizeof(*nextwords));
if (!nextwords)
return NULL;
word->nextwords = nextwords;
word->nextwords = nextwords;
nextword = calloc (1, sizeof (*nextword));
if (!nextword)
return NULL;
nextword = calloc(1, sizeof(*nextword));
if (!nextword)
return NULL;
nextword->word = strdup (token);
if (!nextword->word) {
free (nextword);
return NULL;
}
nextword->word = strdup(token);
if (!nextword->word) {
free(nextword);
return NULL;
}
nextword->tree = word->tree;
nextwords[word->nextwords_cnt++] = nextword;
nextwords[word->nextwords_cnt] = NULL;
nextword->tree = word->tree;
nextwords[word->nextwords_cnt++] = nextword;
nextwords[word->nextwords_cnt] = NULL;
return nextword;
return nextword;
}
int
cli_cmd_ingest (struct cli_cmd_tree *tree, char **tokens, cli_cmd_cbk_t *cbkfn,
const char *desc, const char *pattern)
cli_cmd_ingest(struct cli_cmd_tree *tree, char **tokens, cli_cmd_cbk_t *cbkfn,
const char *desc, const char *pattern)
{
int ret = 0;
char **tokenp = NULL;
char *token = NULL;
struct cli_cmd_word *word = NULL;
struct cli_cmd_word *next = NULL;
int ret = 0;
char **tokenp = NULL;
char *token = NULL;
struct cli_cmd_word *word = NULL;
struct cli_cmd_word *next = NULL;
word = &tree->root;
word = &tree->root;
for (tokenp = tokens; (token = *tokenp); tokenp++) {
if (!__is_word (token))
break;
for (tokenp = tokens; (token = *tokenp); tokenp++) {
if (!__is_word(token))
break;
next = cli_cmd_nextword (word, token);
if (!next)
next = cli_cmd_newword (word, token);
word = next;
if (!word)
break;
}
next = cli_cmd_nextword(word, token);
if (!next)
next = cli_cmd_newword(word, token);
word = next;
if (!word)
return -1;
break;
}
if (word->cbkfn) {
/* warning - command already registered */
}
if (!word)
return -1;
word->cbkfn = cbkfn;
word->desc = desc;
word->pattern = pattern;
if (word->cbkfn) {
/* warning - command already registered */
}
/* end of static strings in command template */
word->cbkfn = cbkfn;
word->desc = desc;
word->pattern = pattern;
/* TODO: autocompletion beyond this point is just "nice to have" */
/* end of static strings in command template */
return ret;
/* TODO: autocompletion beyond this point is just "nice to have" */
return ret;
}
int
cli_cmd_register (struct cli_cmd_tree *tree, struct cli_cmd *cmd)
cli_cmd_register(struct cli_cmd_tree *tree, struct cli_cmd *cmd)
{
char **tokens = NULL;
int ret = 0;
char **tokens = NULL;
int ret = 0;
GF_ASSERT (cmd);
GF_ASSERT(cmd);
if (cmd->reg_cbk)
cmd->reg_cbk (cmd);
if (cmd->disable) {
ret = 0;
goto out;
}
tokens = cli_cmd_tokenize (cmd->pattern);
if (!tokens) {
ret = -1;
goto out;
}
ret = cli_cmd_ingest (tree, tokens, cmd->cbk, cmd->desc, cmd->pattern);
if (ret) {
ret = -1;
goto out;
}
if (cmd->reg_cbk)
cmd->reg_cbk(cmd);
if (cmd->disable) {
ret = 0;
goto out;
}
tokens = cli_cmd_tokenize(cmd->pattern);
if (!tokens) {
ret = -1;
goto out;
}
ret = cli_cmd_ingest(tree, tokens, cmd->cbk, cmd->desc, cmd->pattern);
if (ret) {
ret = -1;
goto out;
}
ret = 0;
out:
if (tokens)
cli_cmd_tokens_destroy (tokens);
if (tokens)
cli_cmd_tokens_destroy(tokens);
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}

View File

@ -25,365 +25,338 @@
#include <sys/time.h>
struct state {
char need_op_write:1;
char need_op_read:1;
char need_op_write : 1;
char need_op_read : 1;
char need_iface_fileio:1;
char need_iface_xattr:1;
char need_iface_fileio : 1;
char need_iface_xattr : 1;
char need_mode_posix:1;
char need_mode_posix : 1;
char prefix[512];
long int count;
char prefix[512];
long int count;
size_t block_size;
size_t block_size;
char *specfile;
char *specfile;
long int io_size;
long int io_size;
};
#define MEASURE(func, arg) measure (func, #func, arg)
#define MEASURE(func, arg) measure(func, #func, arg)
void
tv_difference (struct timeval *tv_stop,
struct timeval *tv_start,
struct timeval *tv_diff)
tv_difference(struct timeval *tv_stop, struct timeval *tv_start,
struct timeval *tv_diff)
{
if (tv_stop->tv_usec < tv_start->tv_usec) {
tv_diff->tv_usec = (tv_stop->tv_usec + 1000000) - tv_start->tv_usec;
tv_diff->tv_sec = (tv_stop->tv_sec - 1 - tv_start->tv_sec);
} else {
tv_diff->tv_usec = tv_stop->tv_usec - tv_start->tv_usec;
tv_diff->tv_sec = tv_stop->tv_sec - tv_start->tv_sec;
}
if (tv_stop->tv_usec < tv_start->tv_usec) {
tv_diff->tv_usec = (tv_stop->tv_usec + 1000000) - tv_start->tv_usec;
tv_diff->tv_sec = (tv_stop->tv_sec - 1 - tv_start->tv_sec);
} else {
tv_diff->tv_usec = tv_stop->tv_usec - tv_start->tv_usec;
tv_diff->tv_sec = tv_stop->tv_sec - tv_start->tv_sec;
}
}
void
measure (int (*func)(struct state *state),
char *func_name, struct state *state)
measure(int (*func)(struct state *state), char *func_name, struct state *state)
{
struct timeval tv_start, tv_stop, tv_diff;
state->io_size = 0;
long int count;
struct timeval tv_start, tv_stop, tv_diff;
state->io_size = 0;
long int count;
gettimeofday (&tv_start, NULL);
count = func (state);
gettimeofday (&tv_stop, NULL);
gettimeofday(&tv_start, NULL);
count = func(state);
gettimeofday(&tv_stop, NULL);
tv_difference (&tv_stop, &tv_start, &tv_diff);
tv_difference(&tv_stop, &tv_start, &tv_diff);
fprintf (stdout, "%s: count=%ld, size=%ld, time=%ld:%ld\n",
func_name, count, state->io_size,
tv_diff.tv_sec, tv_diff.tv_usec);
fprintf(stdout, "%s: count=%ld, size=%ld, time=%ld:%ld\n", func_name, count,
state->io_size, tv_diff.tv_sec, tv_diff.tv_usec);
}
static error_t
parse_opts (int key, char *arg,
struct argp_state *_state)
parse_opts(int key, char *arg, struct argp_state *_state)
{
struct state *state = _state->input;
struct state *state = _state->input;
switch (key)
{
switch (key) {
case 'o':
if (strcasecmp (arg, "read") == 0) {
state->need_op_write = 0;
state->need_op_read = 1;
} else if (strcasecmp (arg, "write") == 0) {
state->need_op_write = 1;
state->need_op_read = 0;
} else if (strcasecmp (arg, "both") == 0) {
state->need_op_write = 1;
state->need_op_read = 1;
} else {
fprintf (stderr, "unknown op: %s\n", arg);
return -1;
}
break;
if (strcasecmp(arg, "read") == 0) {
state->need_op_write = 0;
state->need_op_read = 1;
} else if (strcasecmp(arg, "write") == 0) {
state->need_op_write = 1;
state->need_op_read = 0;
} else if (strcasecmp(arg, "both") == 0) {
state->need_op_write = 1;
state->need_op_read = 1;
} else {
fprintf(stderr, "unknown op: %s\n", arg);
return -1;
}
break;
case 'i':
if (strcasecmp (arg, "fileio") == 0) {
state->need_iface_fileio = 1;
state->need_iface_xattr = 0;
} else if (strcasecmp (arg, "xattr") == 0) {
state->need_iface_fileio = 0;
state->need_iface_xattr = 1;
} else if (strcasecmp (arg, "both") == 0) {
state->need_iface_fileio = 1;
state->need_iface_xattr = 1;
} else {
fprintf (stderr, "unknown interface: %s\n", arg);
return -1;
}
break;
case 'b':
{
size_t block_size = atoi (arg);
if (!block_size) {
fprintf (stderr, "incorrect size: %s\n", arg);
return -1;
}
state->block_size = block_size;
}
break;
if (strcasecmp(arg, "fileio") == 0) {
state->need_iface_fileio = 1;
state->need_iface_xattr = 0;
} else if (strcasecmp(arg, "xattr") == 0) {
state->need_iface_fileio = 0;
state->need_iface_xattr = 1;
} else if (strcasecmp(arg, "both") == 0) {
state->need_iface_fileio = 1;
state->need_iface_xattr = 1;
} else {
fprintf(stderr, "unknown interface: %s\n", arg);
return -1;
}
break;
case 'b': {
size_t block_size = atoi(arg);
if (!block_size) {
fprintf(stderr, "incorrect size: %s\n", arg);
return -1;
}
state->block_size = block_size;
} break;
case 's':
state->specfile = strdup (arg);
break;
state->specfile = strdup(arg);
break;
case 'p':
fprintf (stderr, "using prefix: %s\n", arg);
strncpy (state->prefix, arg, 512);
break;
case 'c':
{
long count = atol (arg);
if (!count) {
fprintf (stderr, "incorrect count: %s\n", arg);
return -1;
}
state->count = count;
}
break;
fprintf(stderr, "using prefix: %s\n", arg);
strncpy(state->prefix, arg, 512);
break;
case 'c': {
long count = atol(arg);
if (!count) {
fprintf(stderr, "incorrect count: %s\n", arg);
return -1;
}
state->count = count;
} break;
case ARGP_KEY_NO_ARGS:
break;
break;
case ARGP_KEY_ARG:
break;
break;
}
return 0;
}
int
do_mode_posix_iface_fileio_write(struct state *state)
{
long int i;
int ret = -1;
char block[state->block_size];
for (i = 0; i < state->count; i++) {
int fd = -1;
char filename[512];
sprintf(filename, "%s.%06ld", state->prefix, i);
fd = open(filename, O_CREAT | O_WRONLY, 00600);
if (fd == -1) {
fprintf(stderr, "open(%s) => %s\n", filename, strerror(errno));
break;
}
return 0;
}
int
do_mode_posix_iface_fileio_write (struct state *state)
{
long int i;
int ret = -1;
char block[state->block_size];
for (i=0; i<state->count; i++) {
int fd = -1;
char filename[512];
sprintf (filename, "%s.%06ld", state->prefix, i);
fd = open (filename, O_CREAT|O_WRONLY, 00600);
if (fd == -1) {
fprintf (stderr, "open(%s) => %s\n", filename, strerror (errno));
break;
}
ret = write (fd, block, state->block_size);
if (ret != state->block_size) {
fprintf (stderr, "write (%s) => %d/%s\n", filename, ret,
strerror (errno));
close (fd);
break;
}
close (fd);
state->io_size += ret;
ret = write(fd, block, state->block_size);
if (ret != state->block_size) {
fprintf(stderr, "write (%s) => %d/%s\n", filename, ret,
strerror(errno));
close(fd);
break;
}
close(fd);
state->io_size += ret;
}
return i;
return i;
}
int
do_mode_posix_iface_fileio_read (struct state *state)
do_mode_posix_iface_fileio_read(struct state *state)
{
long int i;
int ret = -1;
char block[state->block_size];
long int i;
int ret = -1;
char block[state->block_size];
for (i=0; i<state->count; i++) {
int fd = -1;
char filename[512];
for (i = 0; i < state->count; i++) {
int fd = -1;
char filename[512];
sprintf (filename, "%s.%06ld", state->prefix, i);
sprintf(filename, "%s.%06ld", state->prefix, i);
fd = open (filename, O_RDONLY);
if (fd == -1) {
fprintf (stderr, "open(%s) => %s\n", filename, strerror (errno));
break;
}
ret = read (fd, block, state->block_size);
if (ret == -1) {
fprintf (stderr, "read(%s) => %d/%s\n", filename, ret, strerror (errno));
close (fd);
break;
}
close (fd);
state->io_size += ret;
fd = open(filename, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "open(%s) => %s\n", filename, strerror(errno));
break;
}
return i;
}
int
do_mode_posix_iface_fileio (struct state *state)
{
if (state->need_op_write)
MEASURE (do_mode_posix_iface_fileio_write, state);
if (state->need_op_read)
MEASURE (do_mode_posix_iface_fileio_read, state);
return 0;
}
int
do_mode_posix_iface_xattr_write (struct state *state)
{
long int i;
int ret = -1;
char block[state->block_size];
char *dname = NULL, *dirc = NULL;
char *bname = NULL, *basec = NULL;
dirc = strdup (state->prefix);
basec = strdup (state->prefix);
dname = dirname (dirc);
bname = basename (basec);
for (i=0; i<state->count; i++) {
char key[512];
sprintf (key, "glusterfs.file.%s.%06ld", bname, i);
ret = lsetxattr (dname, key, block, state->block_size, 0);
if (ret != 0) {
fprintf (stderr, "lsetxattr (%s, %s, %p) => %s\n",
dname, key, block, strerror (errno));
break;
}
state->io_size += state->block_size;
ret = read(fd, block, state->block_size);
if (ret == -1) {
fprintf(stderr, "read(%s) => %d/%s\n", filename, ret,
strerror(errno));
close(fd);
break;
}
close(fd);
state->io_size += ret;
}
free (dirc);
free (basec);
return i;
return i;
}
int
do_mode_posix_iface_fileio(struct state *state)
{
if (state->need_op_write)
MEASURE(do_mode_posix_iface_fileio_write, state);
if (state->need_op_read)
MEASURE(do_mode_posix_iface_fileio_read, state);
return 0;
}
int
do_mode_posix_iface_xattr_read (struct state *state)
do_mode_posix_iface_xattr_write(struct state *state)
{
long int i;
int ret = -1;
char block[state->block_size];
char *dname = NULL, *dirc = NULL;
char *bname = NULL, *basec = NULL;
long int i;
int ret = -1;
char block[state->block_size];
char *dname = NULL, *dirc = NULL;
char *bname = NULL, *basec = NULL;
dirc = strdup (state->prefix);
basec = strdup (state->prefix);
dname = dirname (dirc);
bname = basename (basec);
dirc = strdup(state->prefix);
basec = strdup(state->prefix);
dname = dirname(dirc);
bname = basename(basec);
for (i=0; i<state->count; i++) {
char key[512];
for (i = 0; i < state->count; i++) {
char key[512];
sprintf (key, "glusterfs.file.%s.%06ld", bname, i);
sprintf(key, "glusterfs.file.%s.%06ld", bname, i);
ret = lgetxattr (dname, key, block, state->block_size);
ret = lsetxattr(dname, key, block, state->block_size, 0);
if (ret < 0) {
fprintf (stderr, "lgetxattr (%s, %s, %p) => %s\n",
dname, key, block, strerror (errno));
break;
}
state->io_size += ret;
if (ret != 0) {
fprintf(stderr, "lsetxattr (%s, %s, %p) => %s\n", dname, key, block,
strerror(errno));
break;
}
state->io_size += state->block_size;
}
return i;
}
free(dirc);
free(basec);
int
do_mode_posix_iface_xattr (struct state *state)
{
if (state->need_op_write)
MEASURE (do_mode_posix_iface_xattr_write, state);
if (state->need_op_read)
MEASURE (do_mode_posix_iface_xattr_read, state);
return 0;
return i;
}
int
do_mode_posix (struct state *state)
do_mode_posix_iface_xattr_read(struct state *state)
{
if (state->need_iface_fileio)
do_mode_posix_iface_fileio (state);
long int i;
int ret = -1;
char block[state->block_size];
char *dname = NULL, *dirc = NULL;
char *bname = NULL, *basec = NULL;
if (state->need_iface_xattr)
do_mode_posix_iface_xattr (state);
dirc = strdup(state->prefix);
basec = strdup(state->prefix);
dname = dirname(dirc);
bname = basename(basec);
return 0;
for (i = 0; i < state->count; i++) {
char key[512];
sprintf(key, "glusterfs.file.%s.%06ld", bname, i);
ret = lgetxattr(dname, key, block, state->block_size);
if (ret < 0) {
fprintf(stderr, "lgetxattr (%s, %s, %p) => %s\n", dname, key, block,
strerror(errno));
break;
}
state->io_size += ret;
}
return i;
}
int
do_mode_posix_iface_xattr(struct state *state)
{
if (state->need_op_write)
MEASURE(do_mode_posix_iface_xattr_write, state);
if (state->need_op_read)
MEASURE(do_mode_posix_iface_xattr_read, state);
return 0;
}
int
do_actions (struct state *state)
do_mode_posix(struct state *state)
{
if (state->need_mode_posix)
do_mode_posix (state);
if (state->need_iface_fileio)
do_mode_posix_iface_fileio(state);
return 0;
if (state->need_iface_xattr)
do_mode_posix_iface_xattr(state);
return 0;
}
int
do_actions(struct state *state)
{
if (state->need_mode_posix)
do_mode_posix(state);
return 0;
}
static struct argp_option options[] = {
{"op", 'o', "OPERATIONS", 0,
"WRITE|READ|BOTH - defaults to BOTH"},
{"iface", 'i', "INTERFACE", 0,
"FILEIO|XATTR|BOTH - defaults to FILEIO"},
{"block", 'b', "BLOCKSIZE", 0,
"<NUM> - defaults to 4096"},
{"specfile", 's', "SPECFILE", 0,
"absolute path to specfile"},
{"prefix", 'p', "PREFIX", 0,
"filename prefix"},
{"count", 'c', "COUNT", 0,
"number of files"},
{0, 0, 0, 0, 0}
};
{"op", 'o', "OPERATIONS", 0, "WRITE|READ|BOTH - defaults to BOTH"},
{"iface", 'i', "INTERFACE", 0, "FILEIO|XATTR|BOTH - defaults to FILEIO"},
{"block", 'b', "BLOCKSIZE", 0, "<NUM> - defaults to 4096"},
{"specfile", 's', "SPECFILE", 0, "absolute path to specfile"},
{"prefix", 'p', "PREFIX", 0, "filename prefix"},
{"count", 'c', "COUNT", 0, "number of files"},
{0, 0, 0, 0, 0}};
static struct argp argp = {
options,
parse_opts,
"tool",
"tool to benchmark small file performance"
};
static struct argp argp = {options, parse_opts, "tool",
"tool to benchmark small file performance"};
int
main (int argc, char *argv[])
main(int argc, char *argv[])
{
struct state state = {0, };
struct state state = {
0,
};
state.need_op_write = 1;
state.need_op_read = 1;
state.need_op_write = 1;
state.need_op_read = 1;
state.need_iface_fileio = 1;
state.need_iface_xattr = 0;
state.need_iface_fileio = 1;
state.need_iface_xattr = 0;
state.need_mode_posix = 1;
state.need_mode_posix = 1;
state.block_size = 4096;
state.block_size = 4096;
strcpy (state.prefix, "tmpfile");
state.count = 1048576;
strcpy(state.prefix, "tmpfile");
state.count = 1048576;
if (argp_parse (&argp, argc, argv, 0, 0, &state) != 0) {
fprintf (stderr, "argp_parse() failed\n");
return 1;
}
if (argp_parse(&argp, argc, argv, 0, 0, &state) != 0) {
fprintf(stderr, "argp_parse() failed\n");
return 1;
}
do_actions (&state);
do_actions(&state);
return 0;
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,32 @@
#pragma fragment CBK_TEMPLATE
int32_t
@FOP_PREFIX@_@NAME@_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, @UNWIND_PARAMS@)
int32_t @FOP_PREFIX @_ @NAME
@_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
int32_t op_errno, @UNWIND_PARAMS @)
{
STACK_UNWIND_STRICT (@NAME@, frame, op_ret, op_errno,
@UNWIND_ARGS@);
return 0;
STACK_UNWIND_STRICT(@NAME @, frame, op_ret, op_errno, @UNWIND_ARGS @);
return 0;
}
#pragma fragment COMMENT
If you are generating the leaf xlators, remove the STACK_WIND
and replace the @ERROR_ARGS@ to @UNWIND_ARGS@ if necessary
If you are generating the leaf xlators, remove the STACK_WIND and replace the
@ERROR_ARGS @to @UNWIND_ARGS @ if necessary
#pragma fragment FOP_TEMPLATE
int32_t
@FOP_PREFIX@_@NAME@ (call_frame_t *frame, xlator_t *this,
@WIND_PARAMS@)
int32_t @FOP_PREFIX @_ @NAME
@(call_frame_t *frame, xlator_t *this, @WIND_PARAMS @)
{
STACK_WIND (frame, @FOP_PREFIX@_@NAME@_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@,
@WIND_ARGS@);
return 0;
STACK_WIND(frame, @FOP_PREFIX @_ @NAME @_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->@NAME @, @WIND_ARGS @);
return 0;
err:
STACK_UNWIND_STRICT (@NAME@, frame, -1, errno,
@ERROR_ARGS@);
return 0;
STACK_UNWIND_STRICT(@NAME @, frame, -1, errno, @ERROR_ARGS @);
return 0;
}
#pragma fragment FUNC_TEMPLATE
@RET_TYPE@
@FOP_PREFIX@_@NAME@ (@FUNC_PARAMS@)
@RET_TYPE @ @FOP_PREFIX @_ @NAME @(@FUNC_PARAMS @)
{
return @RET_VAR@;
return @RET_VAR @;
}
#pragma fragment CP
@ -50,77 +45,71 @@ err:
#pragma fragment XLATOR_METHODS
static int32_t
@FOP_PREFIX@_init (xlator_t *this)
static int32_t @FOP_PREFIX @_init(xlator_t *this)
{
return 0;
return 0;
}
static void
@FOP_PREFIX@_fini (xlator_t *this)
static void @FOP_PREFIX @_fini(xlator_t *this)
{
return;
return;
}
static int32_t
@FOP_PREFIX@_reconfigure (xlator_t *this, dict_t *dict)
static int32_t @FOP_PREFIX @_reconfigure(xlator_t *this, dict_t *dict)
{
return 0;
return 0;
}
static int
@FOP_PREFIX@_notify (xlator_t *this, int event, void *data, ...)
static int @FOP_PREFIX @_notify(xlator_t *this, int event, void *data, ...)
{
return default_notify (this, event, data);
return default_notify(this, event, data);
}
static int32_t
@FOP_PREFIX@_mem_acct_init (xlator_t *this)
static int32_t @FOP_PREFIX @_mem_acct_init(xlator_t *this)
{
int ret = -1;
int ret = -1;
ret = xlator_mem_acct_init (this, gf_@FOP_PREFIX@_mt_end + 1);
return ret;
ret = xlator_mem_acct_init(this, gf_ @FOP_PREFIX @_mt_end + 1);
return ret;
}
static int32_t
@FOP_PREFIX@_dump_metrics (xlator_t *this, int fd)
static int32_t @FOP_PREFIX @_dump_metrics(xlator_t *this, int fd)
{
return 0;
return 0;
}
struct volume_options @FOP_PREFIX@_options[] = {
/*{ .key = {""},
.type = GF_OPTION_TYPE_BOOL,
.default_value = "",
.op_version = {GD_OP_VERSION_},
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_CLIENT_OPT,
.tags = {""},
.description = "",
.category = GF_EXPERIMENTAL,
},
{ .key = {NULL} },
*/
struct volume_options @FOP_PREFIX @_options[] = {
/*{ .key = {""},
.type = GF_OPTION_TYPE_BOOL,
.default_value = "",
.op_version = {GD_OP_VERSION_},
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_CLIENT_OPT,
.tags = {""},
.description = "",
.category = GF_EXPERIMENTAL,
},
{ .key = {NULL} },
*/
};
xlator_api_t xlator_api = {
.init = @FOP_PREFIX@_init,
.fini = @FOP_PREFIX@_fini,
.notify = @FOP_PREFIX@_notify,
.reconfigure = @FOP_PREFIX@_reconfigure,
.mem_acct_init = @FOP_PREFIX@_mem_acct_init,
.dump_metrics = @FOP_PREFIX@_dump_metrics,
.op_version = {GD_OP_VERSION_},
.dumpops = &@FOP_PREFIX@_dumpops,
.fops = &@FOP_PREFIX@_fops,
.cbks = &@FOP_PREFIX@_cbks,
.options = @FOP_PREFIX@_options,
.identifier = "@XL_NAME@",
.category = GF_EXPERIMENTAL,
.init = @FOP_PREFIX @_init,
.fini = @FOP_PREFIX @_fini,
.notify = @FOP_PREFIX @_notify,
.reconfigure = @FOP_PREFIX @_reconfigure,
.mem_acct_init = @FOP_PREFIX @_mem_acct_init,
.dump_metrics = @FOP_PREFIX @_dump_metrics,
.op_version = {GD_OP_VERSION_},
.dumpops = &@FOP_PREFIX @_dumpops,
.fops = &@FOP_PREFIX @_fops,
.cbks = &@FOP_PREFIX @_cbks,
.options = @FOP_PREFIX @_options,
.identifier = "@XL_NAME@",
.category = GF_EXPERIMENTAL,
};
#pragma fragment HEADER_FMT
#ifndef __@HFL_NAME@_H__
#define __@HFL_NAME@_H__
#ifndef __ @HFL_NAME @_H__
#define __ @HFL_NAME @_H__
#include "@XL_NAME@-mem-types.h"
#include "@XL_NAME@-messages.h"
@ -131,21 +120,21 @@ xlator_api_t xlator_api = {
#endif /* __@HFL_NAME@_H__ */
#pragma fragment MEM_HEADER_FMT
#ifndef __@HFL_NAME@_H__
#define __@HFL_NAME@_H__
#ifndef __ @HFL_NAME @_H__
#define __ @HFL_NAME @_H__
#include "mem-types.h"
enum gf_mdc_mem_types_ {
gf_@FOP_PREFIX@_mt_ = gf_common_mt_end + 1,
gf_@FOP_PREFIX@_mt_end
gf_ @FOP_PREFIX @_mt_ = gf_common_mt_end + 1,
gf_ @FOP_PREFIX @_mt_end
};
#endif /* __@HFL_NAME@_H__ */
#pragma fragment MSG_HEADER_FMT
#ifndef __@HFL_NAME@_H__
#define __@HFL_NAME@_H__
#ifndef __ @HFL_NAME @_H__
#define __ @HFL_NAME @_H__
#include "glfs-message-id.h"
@ -159,8 +148,6 @@ enum gf_mdc_mem_types_ {
* glfs-message-id.h.
*/
GLFS_MSGID(@FOP_PREFIX@,
@FOP_PREFIX@_MSG_NO_MEMORY
);
GLFS_MSGID(@FOP_PREFIX @, @FOP_PREFIX @_MSG_NO_MEMORY);
#endif /* __@HFL_NAME@_H__ */

View File

@ -15,96 +15,95 @@
#endif
#ifndef GF_FUSE_AUX_GFID_HEAL
#define GF_FUSE_AUX_GFID_HEAL "glusterfs.gfid.heal"
#define GF_FUSE_AUX_GFID_HEAL "glusterfs.gfid.heal"
#endif
#define GLFS_LINE_MAX (PATH_MAX + (2 * UUID_CANONICAL_FORM_LEN))
#define GLFS_LINE_MAX (PATH_MAX + (2 * UUID_CANONICAL_FORM_LEN))
int
main (int argc, char *argv[])
main(int argc, char *argv[])
{
char *file = NULL;
char *tmp = NULL;
char *tmp1 = NULL;
char *parent_dir = NULL;
char *gfid = NULL;
char *bname = NULL;
int ret = -1;
int len = 0;
FILE *fp = NULL;
char line[GLFS_LINE_MAX] = {0,};
char *path = NULL;
void *blob = NULL;
void *tmp_blob = NULL;
char *file = NULL;
char *tmp = NULL;
char *tmp1 = NULL;
char *parent_dir = NULL;
char *gfid = NULL;
char *bname = NULL;
int ret = -1;
int len = 0;
FILE *fp = NULL;
char line[GLFS_LINE_MAX] = {
0,
};
char *path = NULL;
void *blob = NULL;
void *tmp_blob = NULL;
if (argc != 2) {
/* each line in the file has the following format
* uuid-in-canonical-form path-relative-to-gluster-mount.
* Both uuid and relative path are from master mount.
*/
fprintf (stderr, "usage: %s <file-of-paths-to-be-synced>\n",
argv[0]);
goto out;
if (argc != 2) {
/* each line in the file has the following format
* uuid-in-canonical-form path-relative-to-gluster-mount.
* Both uuid and relative path are from master mount.
*/
fprintf(stderr, "usage: %s <file-of-paths-to-be-synced>\n", argv[0]);
goto out;
}
file = argv[1];
fp = fopen(file, "r");
if (fp == NULL) {
fprintf(stderr, "cannot open %s for reading (%s)\n", file,
strerror(errno));
goto out;
}
while (fgets(line, GLFS_LINE_MAX, fp) != NULL) {
tmp = line;
path = gfid = line;
path += UUID_CANONICAL_FORM_LEN + 1;
while (isspace(*path))
path++;
len = strlen(line);
if ((len < GLFS_LINE_MAX) && (line[len - 1] == '\n'))
line[len - 1] = '\0';
line[UUID_CANONICAL_FORM_LEN] = '\0';
tmp = strdup(path);
tmp1 = strdup(path);
parent_dir = dirname(tmp);
bname = basename(tmp1);
/* gfid + '\0' + bname + '\0' */
len = UUID_CANONICAL_FORM_LEN + 1 + strlen(bname) + 1;
blob = malloc(len);
memcpy(blob, gfid, UUID_CANONICAL_FORM_LEN);
tmp_blob = blob + UUID_CANONICAL_FORM_LEN + 1;
memcpy(tmp_blob, bname, strlen(bname));
ret = sys_lsetxattr(parent_dir, GF_FUSE_AUX_GFID_HEAL, blob, len, 0);
if (ret < 0) {
fprintf(stderr, "setxattr on %s/%s failed (%s)\n", parent_dir,
bname, strerror(errno));
}
memset(line, 0, GLFS_LINE_MAX);
file = argv[1];
free(blob);
free(tmp);
free(tmp1);
blob = NULL;
}
fp = fopen (file, "r");
if (fp == NULL) {
fprintf (stderr, "cannot open %s for reading (%s)\n",
file, strerror (errno));
goto out;
}
while (fgets (line, GLFS_LINE_MAX, fp) != NULL) {
tmp = line;
path = gfid = line;
path += UUID_CANONICAL_FORM_LEN + 1;
while(isspace (*path))
path++;
len = strlen (line);
if ((len < GLFS_LINE_MAX) &&
(line[len - 1] == '\n'))
line[len - 1] = '\0';
line[UUID_CANONICAL_FORM_LEN] = '\0';
tmp = strdup (path);
tmp1 = strdup (path);
parent_dir = dirname (tmp);
bname = basename (tmp1);
/* gfid + '\0' + bname + '\0' */
len = UUID_CANONICAL_FORM_LEN + 1 + strlen (bname) + 1;
blob = malloc (len);
memcpy (blob, gfid, UUID_CANONICAL_FORM_LEN);
tmp_blob = blob + UUID_CANONICAL_FORM_LEN + 1;
memcpy (tmp_blob, bname, strlen (bname));
ret = sys_lsetxattr (parent_dir, GF_FUSE_AUX_GFID_HEAL,
blob, len, 0);
if (ret < 0) {
fprintf (stderr, "setxattr on %s/%s failed (%s)\n",
parent_dir, bname, strerror (errno));
}
memset (line, 0, GLFS_LINE_MAX);
free (blob);
free (tmp); free (tmp1);
blob = NULL;
}
ret = 0;
ret = 0;
out:
if (fp)
fclose(fp);
return ret;
if (fp)
fclose(fp);
return ret;
}

View File

@ -40,33 +40,33 @@
#define INVALID_MODE UINT32_MAX
struct file_stripe_info {
int stripe_count;
int stripe_size;
int coalesce;
mode_t mode;
int fd[0];
int stripe_count;
int stripe_size;
int coalesce;
mode_t mode;
int fd[0];
};
static int close_files(struct file_stripe_info *);
static int
close_files(struct file_stripe_info *);
static struct
file_stripe_info *alloc_file_stripe_info(int count)
static struct file_stripe_info *
alloc_file_stripe_info(int count)
{
int i;
struct file_stripe_info *finfo;
int i;
struct file_stripe_info *finfo;
finfo = calloc(1, sizeof(struct file_stripe_info) +
(sizeof(int) * count));
if (!finfo)
return NULL;
finfo = calloc(1, sizeof(struct file_stripe_info) + (sizeof(int) * count));
if (!finfo)
return NULL;
for (i = 0; i < count; i++)
finfo->fd[i] = INVALID_FD;
for (i = 0; i < count; i++)
finfo->fd[i] = INVALID_FD;
finfo->mode = INVALID_MODE;
finfo->coalesce = INVALID_FD;
finfo->mode = INVALID_MODE;
finfo->coalesce = INVALID_FD;
return finfo;
return finfo;
}
/*
@ -77,39 +77,39 @@ file_stripe_info *alloc_file_stripe_info(int count)
static int
get_stripe_attr_name(const char *path, const char *pattern, char **attrname)
{
char attrbuf[4096];
char *ptr, *match = NULL;
int len, r, match_count = 0;
char attrbuf[4096];
char *ptr, *match = NULL;
int len, r, match_count = 0;
if (!path || !pattern || !attrname)
return -1;
if (!path || !pattern || !attrname)
return -1;
len = listxattr(path, attrbuf, sizeof(attrbuf));
if (len < 0)
return len;
len = listxattr(path, attrbuf, sizeof(attrbuf));
if (len < 0)
return len;
ptr = attrbuf;
while (ptr) {
r = fnmatch(pattern, ptr, 0);
if (!r) {
if (!match)
match = ptr;
match_count++;
} else if (r != FNM_NOMATCH) {
return -1;
}
ptr = attrbuf;
while (ptr) {
r = fnmatch(pattern, ptr, 0);
if (!r) {
if (!match)
match = ptr;
match_count++;
} else if (r != FNM_NOMATCH) {
return -1;
}
len -= strlen(ptr) + 1;
if (len > 0)
ptr += strlen(ptr) + 1;
else
ptr = NULL;
}
len -= strlen(ptr) + 1;
if (len > 0)
ptr += strlen(ptr) + 1;
else
ptr = NULL;
}
if (match)
*attrname = strdup(match);
if (match)
*attrname = strdup(match);
return match_count;
return match_count;
}
/*
@ -118,19 +118,19 @@ get_stripe_attr_name(const char *path, const char *pattern, char **attrname)
static int
get_stripe_attr_val(const char *path, const char *attr, int *val)
{
char attrbuf[4096];
int len;
char attrbuf[4096];
int len;
if (!path || !attr || !val)
return -1;
if (!path || !attr || !val)
return -1;
len = getxattr(path, attr, attrbuf, sizeof(attrbuf));
if (len < 0)
return len;
len = getxattr(path, attr, attrbuf, sizeof(attrbuf));
if (len < 0)
return len;
*val = atoi(attrbuf);
*val = atoi(attrbuf);
return 0;
return 0;
}
/*
@ -145,29 +145,31 @@ get_stripe_attr_val(const char *path, const char *attr, int *val)
static int
get_attr(const char *path, const char *pattern, char **buf, int *val)
{
int count = 1;
int count = 1;
if (!buf)
return -1;
if (!buf)
return -1;
if (!*buf) {
count = get_stripe_attr_name(path, pattern, buf);
if (count > 1) {
/* pattern isn't good enough */
fprintf(stderr, "ERROR: duplicate attributes found "
"matching pattern: %s\n", pattern);
free(*buf);
*buf = NULL;
return count;
} else if (count < 1) {
return count;
}
}
if (!*buf) {
count = get_stripe_attr_name(path, pattern, buf);
if (count > 1) {
/* pattern isn't good enough */
fprintf(stderr,
"ERROR: duplicate attributes found "
"matching pattern: %s\n",
pattern);
free(*buf);
*buf = NULL;
return count;
} else if (count < 1) {
return count;
}
}
if (get_stripe_attr_val(path, *buf, val) < 0)
return -1;
if (get_stripe_attr_val(path, *buf, val) < 0)
return -1;
return count;
return count;
}
/*
@ -178,164 +180,168 @@ get_attr(const char *path, const char *pattern, char **buf, int *val)
* print a warning if any files are missing. We proceed without error in the
* latter case to support partial recovery.
*/
static struct
file_stripe_info *validate_and_open_files(char *paths[], int count)
static struct file_stripe_info *
validate_and_open_files(char *paths[], int count)
{
int i, val, tmp;
struct stat sbuf;
char *stripe_count_attr = NULL;
char *stripe_size_attr = NULL;
char *stripe_index_attr = NULL;
char *stripe_coalesce_attr = NULL;
struct file_stripe_info *finfo = NULL;
int i, val, tmp;
struct stat sbuf;
char *stripe_count_attr = NULL;
char *stripe_size_attr = NULL;
char *stripe_index_attr = NULL;
char *stripe_coalesce_attr = NULL;
struct file_stripe_info *finfo = NULL;
for (i = 0; i < count; i++) {
if (!paths[i])
goto err;
for (i = 0; i < count; i++) {
if (!paths[i])
goto err;
/*
* Check the stripe count first so we can allocate the info
* struct with the appropriate number of fds.
*/
if (get_attr(paths[i], ATTRNAME_STRIPE_COUNT,
&stripe_count_attr, &val) != 1) {
fprintf(stderr, "ERROR: %s: attribute: '%s'\n",
paths[i], ATTRNAME_STRIPE_COUNT);
goto err;
}
if (!finfo) {
finfo = alloc_file_stripe_info(val);
if (!finfo)
goto err;
/*
* Check the stripe count first so we can allocate the info
* struct with the appropriate number of fds.
*/
if (get_attr(paths[i], ATTRNAME_STRIPE_COUNT, &stripe_count_attr,
&val) != 1) {
fprintf(stderr, "ERROR: %s: attribute: '%s'\n", paths[i],
ATTRNAME_STRIPE_COUNT);
goto err;
}
if (!finfo) {
finfo = alloc_file_stripe_info(val);
if (!finfo)
goto err;
if (val != count)
fprintf(stderr, "WARNING: %s: stripe-count "
"(%d) != file count (%d). Result may "
"be incomplete.\n", paths[i], val,
count);
if (val != count)
fprintf(stderr,
"WARNING: %s: stripe-count "
"(%d) != file count (%d). Result may "
"be incomplete.\n",
paths[i], val, count);
finfo->stripe_count = val;
} else if (val != finfo->stripe_count) {
fprintf(stderr, "ERROR %s: invalid stripe count: %d "
"(expected %d)\n", paths[i], val,
finfo->stripe_count);
goto err;
}
finfo->stripe_count = val;
} else if (val != finfo->stripe_count) {
fprintf(stderr,
"ERROR %s: invalid stripe count: %d "
"(expected %d)\n",
paths[i], val, finfo->stripe_count);
goto err;
}
/*
* Get and validate the chunk size.
*/
if (get_attr(paths[i], ATTRNAME_STRIPE_SIZE, &stripe_size_attr,
&val) != 1) {
fprintf(stderr, "ERROR: %s: attribute: '%s'\n",
paths[i], ATTRNAME_STRIPE_SIZE);
goto err;
}
/*
* Get and validate the chunk size.
*/
if (get_attr(paths[i], ATTRNAME_STRIPE_SIZE, &stripe_size_attr, &val) !=
1) {
fprintf(stderr, "ERROR: %s: attribute: '%s'\n", paths[i],
ATTRNAME_STRIPE_SIZE);
goto err;
}
if (!finfo->stripe_size) {
finfo->stripe_size = val;
} else if (val != finfo->stripe_size) {
fprintf(stderr, "ERROR: %s: invalid stripe size: %d "
"(expected %d)\n", paths[i], val,
finfo->stripe_size);
goto err;
}
if (!finfo->stripe_size) {
finfo->stripe_size = val;
} else if (val != finfo->stripe_size) {
fprintf(stderr,
"ERROR: %s: invalid stripe size: %d "
"(expected %d)\n",
paths[i], val, finfo->stripe_size);
goto err;
}
/*
* stripe-coalesce is a backward compatible attribute. If the
* attribute does not exist, assume a value of zero for the
* traditional stripe format.
*/
tmp = get_attr(paths[i], ATTRNAME_STRIPE_COALESCE,
&stripe_coalesce_attr, &val);
if (!tmp) {
val = 0;
} else if (tmp != 1) {
fprintf(stderr, "ERROR: %s: attribute: '%s'\n",
paths[i], ATTRNAME_STRIPE_COALESCE);
goto err;
}
/*
* stripe-coalesce is a backward compatible attribute. If the
* attribute does not exist, assume a value of zero for the
* traditional stripe format.
*/
tmp = get_attr(paths[i], ATTRNAME_STRIPE_COALESCE,
&stripe_coalesce_attr, &val);
if (!tmp) {
val = 0;
} else if (tmp != 1) {
fprintf(stderr, "ERROR: %s: attribute: '%s'\n", paths[i],
ATTRNAME_STRIPE_COALESCE);
goto err;
}
if (finfo->coalesce == INVALID_FD) {
finfo->coalesce = val;
} else if (val != finfo->coalesce) {
fprintf(stderr, "ERROR: %s: invalid coalesce flag\n",
paths[i]);
goto err;
}
if (finfo->coalesce == INVALID_FD) {
finfo->coalesce = val;
} else if (val != finfo->coalesce) {
fprintf(stderr, "ERROR: %s: invalid coalesce flag\n", paths[i]);
goto err;
}
/*
* Get/validate the stripe index and open the file in the
* appropriate fd slot.
*/
if (get_attr(paths[i], ATTRNAME_STRIPE_INDEX,
&stripe_index_attr, &val) != 1) {
fprintf(stderr, "ERROR: %s: attribute: '%s'\n",
paths[i], ATTRNAME_STRIPE_INDEX);
goto err;
}
if (finfo->fd[val] != INVALID_FD) {
fprintf(stderr, "ERROR: %s: duplicate stripe index: "
"%d\n", paths[i], val);
goto err;
}
/*
* Get/validate the stripe index and open the file in the
* appropriate fd slot.
*/
if (get_attr(paths[i], ATTRNAME_STRIPE_INDEX, &stripe_index_attr,
&val) != 1) {
fprintf(stderr, "ERROR: %s: attribute: '%s'\n", paths[i],
ATTRNAME_STRIPE_INDEX);
goto err;
}
if (finfo->fd[val] != INVALID_FD) {
fprintf(stderr,
"ERROR: %s: duplicate stripe index: "
"%d\n",
paths[i], val);
goto err;
}
finfo->fd[val] = open(paths[i], O_RDONLY);
if (finfo->fd[val] < 0)
goto err;
finfo->fd[val] = open(paths[i], O_RDONLY);
if (finfo->fd[val] < 0)
goto err;
/*
* Get the creation mode for the file.
*/
if (fstat(finfo->fd[val], &sbuf) < 0)
goto err;
if (finfo->mode == INVALID_MODE) {
finfo->mode = sbuf.st_mode;
} else if (sbuf.st_mode != finfo->mode) {
fprintf(stderr, "ERROR: %s: invalid mode\n", paths[i]);
goto err;
}
}
/*
* Get the creation mode for the file.
*/
if (fstat(finfo->fd[val], &sbuf) < 0)
goto err;
if (finfo->mode == INVALID_MODE) {
finfo->mode = sbuf.st_mode;
} else if (sbuf.st_mode != finfo->mode) {
fprintf(stderr, "ERROR: %s: invalid mode\n", paths[i]);
goto err;
}
}
free(stripe_count_attr);
free(stripe_size_attr);
free(stripe_index_attr);
free(stripe_coalesce_attr);
free(stripe_count_attr);
free(stripe_size_attr);
free(stripe_index_attr);
free(stripe_coalesce_attr);
return finfo;
return finfo;
err:
free(stripe_count_attr);
free(stripe_size_attr);
free(stripe_index_attr);
free(stripe_coalesce_attr);
free(stripe_count_attr);
free(stripe_size_attr);
free(stripe_index_attr);
free(stripe_coalesce_attr);
if (finfo) {
close_files(finfo);
free(finfo);
}
if (finfo) {
close_files(finfo);
free(finfo);
}
return NULL;
return NULL;
}
static int
close_files(struct file_stripe_info *finfo)
{
int i, ret;
int i, ret;
if (!finfo)
return -1;
if (!finfo)
return -1;
for (i = 0; i < finfo->stripe_count; i++) {
if (finfo->fd[i] == INVALID_FD)
continue;
for (i = 0; i < finfo->stripe_count; i++) {
if (finfo->fd[i] == INVALID_FD)
continue;
ret = close(finfo->fd[i]);
if (ret < 0)
return ret;
}
ret = close(finfo->fd[i]);
if (ret < 0)
return ret;
}
return ret;
return ret;
}
/*
@ -351,43 +357,43 @@ close_files(struct file_stripe_info *finfo)
static int
generate_file_coalesce(int target, struct file_stripe_info *finfo)
{
char *buf;
int ret = 0;
int r, w, i;
char *buf;
int ret = 0;
int r, w, i;
buf = malloc(finfo->stripe_size);
if (!buf)
return -1;
buf = malloc(finfo->stripe_size);
if (!buf)
return -1;
i = 0;
while (1) {
if (finfo->fd[i] == INVALID_FD) {
if (lseek(target, finfo->stripe_size, SEEK_CUR) < 0)
break;
i = 0;
while (1) {
if (finfo->fd[i] == INVALID_FD) {
if (lseek(target, finfo->stripe_size, SEEK_CUR) < 0)
break;
i = (i + 1) % finfo->stripe_count;
continue;
}
i = (i + 1) % finfo->stripe_count;
continue;
}
r = read(finfo->fd[i], buf, finfo->stripe_size);
if (r < 0) {
ret = r;
break;
}
if (!r)
break;
r = read(finfo->fd[i], buf, finfo->stripe_size);
if (r < 0) {
ret = r;
break;
}
if (!r)
break;
w = write(target, buf, r);
if (w < 0) {
ret = w;
break;
}
w = write(target, buf, r);
if (w < 0) {
ret = w;
break;
}
i = (i + 1) % finfo->stripe_count;
}
i = (i + 1) % finfo->stripe_count;
}
free(buf);
return ret;
free(buf);
return ret;
}
/*
@ -398,97 +404,100 @@ generate_file_coalesce(int target, struct file_stripe_info *finfo)
static int
generate_file_traditional(int target, struct file_stripe_info *finfo)
{
int i, j, max_ret, ret;
char buf[finfo->stripe_count][4096];
int i, j, max_ret, ret;
char buf[finfo->stripe_count][4096];
do {
char newbuf[4096] = {0, };
do {
char newbuf[4096] = {
0,
};
max_ret = 0;
for (i = 0; i < finfo->stripe_count; i++) {
memset(buf[i], 0, 4096);
ret = read(finfo->fd[i], buf[i], 4096);
if (ret > max_ret)
max_ret = ret;
}
for (i = 0; i < max_ret; i++)
for (j = 0; j < finfo->stripe_count; j++)
newbuf[i] |= buf[j][i];
write(target, newbuf, max_ret);
} while (max_ret);
max_ret = 0;
for (i = 0; i < finfo->stripe_count; i++) {
memset(buf[i], 0, 4096);
ret = read(finfo->fd[i], buf[i], 4096);
if (ret > max_ret)
max_ret = ret;
}
for (i = 0; i < max_ret; i++)
for (j = 0; j < finfo->stripe_count; j++)
newbuf[i] |= buf[j][i];
write(target, newbuf, max_ret);
} while (max_ret);
return 0;
return 0;
}
static int
generate_file(int target, struct file_stripe_info *finfo)
{
if (finfo->coalesce)
return generate_file_coalesce(target, finfo);
if (finfo->coalesce)
return generate_file_coalesce(target, finfo);
return generate_file_traditional(target, finfo);
return generate_file_traditional(target, finfo);
}
static void
usage(char *name)
{
fprintf(stderr, "Usage: %s [-o <outputfile>] <inputfile1> "
"<inputfile2> ...\n", name);
fprintf(stderr,
"Usage: %s [-o <outputfile>] <inputfile1> "
"<inputfile2> ...\n",
name);
}
int
main(int argc, char *argv[])
{
int file_count, opt;
char *opath = NULL;
int targetfd;
struct file_stripe_info *finfo;
int file_count, opt;
char *opath = NULL;
int targetfd;
struct file_stripe_info *finfo;
while ((opt = getopt(argc, argv, "o:")) != -1) {
switch (opt) {
case 'o':
opath = optarg;
break;
default:
usage(argv[0]);
return -1;
}
}
while ((opt = getopt(argc, argv, "o:")) != -1) {
switch (opt) {
case 'o':
opath = optarg;
break;
default:
usage(argv[0]);
return -1;
}
}
file_count = argc - optind;
file_count = argc - optind;
if (!opath || !file_count) {
usage(argv[0]);
return -1;
}
if (!opath || !file_count) {
usage(argv[0]);
return -1;
}
finfo = validate_and_open_files(&argv[optind], file_count);
if (!finfo)
goto err;
finfo = validate_and_open_files(&argv[optind], file_count);
if (!finfo)
goto err;
targetfd = open(opath, O_RDWR|O_CREAT, finfo->mode);
if (targetfd < 0)
goto err;
targetfd = open(opath, O_RDWR | O_CREAT, finfo->mode);
if (targetfd < 0)
goto err;
if (generate_file(targetfd, finfo) < 0)
goto err;
if (generate_file(targetfd, finfo) < 0)
goto err;
if (fsync(targetfd) < 0)
fprintf(stderr, "ERROR: %s\n", strerror(errno));
if (close(targetfd) < 0)
fprintf(stderr, "ERROR: %s\n", strerror(errno));
if (fsync(targetfd) < 0)
fprintf(stderr, "ERROR: %s\n", strerror(errno));
if (close(targetfd) < 0)
fprintf(stderr, "ERROR: %s\n", strerror(errno));
close_files(finfo);
free(finfo);
close_files(finfo);
free(finfo);
return 0;
return 0;
err:
if (finfo) {
close_files(finfo);
free(finfo);
}
if (finfo) {
close_files(finfo);
free(finfo);
}
return -1;
return -1;
}

View File

@ -40,596 +40,576 @@
/* Err number that is assigned to errno so that test application can
* verify that the function was intercepted correctly.
*/
#define PRELOAD_ERRNO_VERF 6449
#define set_errno() (errno = PRELOAD_ERRNO_VERF)
#define PRELOAD_ERRNO_VERF 6449
#define set_errno() (errno = PRELOAD_ERRNO_VERF)
void
intercept (char *call, int tabs)
intercept(char *call, int tabs)
{
while (tabs > 0) {
fprintf (stdout, "\t");
--tabs;
}
while (tabs > 0) {
fprintf(stdout, "\t");
--tabs;
}
fprintf (stdout, "Intercepted by %s", call);
fprintf(stdout, "Intercepted by %s", call);
}
int
creat64 (const char *pathname, mode_t mode)
creat64(const char *pathname, mode_t mode)
{
intercept ("creat64", 2);
set_errno ();
return -1;
intercept("creat64", 2);
set_errno();
return -1;
}
int
creat (const char *pathname, mode_t mode)
creat(const char *pathname, mode_t mode)
{
intercept ("creat", 2);
set_errno ();
return -1;
}
int
close (int fd)
{
intercept ("close", 2);
set_errno ();
return -1;
intercept("creat", 2);
set_errno();
return -1;
}
int
open64 (const char *pathname, int flags, ...)
close(int fd)
{
intercept ("open64", 2);
set_errno ();
return -1;
intercept("close", 2);
set_errno();
return -1;
}
int
open (const char *pathname, int flags, ...)
open64(const char *pathname, int flags, ...)
{
intercept ("open", 2);
set_errno ();
return -1;
intercept("open64", 2);
set_errno();
return -1;
}
int
open(const char *pathname, int flags, ...)
{
intercept("open", 2);
set_errno();
return -1;
}
ssize_t
read (int fd, void *buf, size_t count)
read(int fd, void *buf, size_t count)
{
intercept ("read", 2);
set_errno ();
return -1;
intercept("read", 2);
set_errno();
return -1;
}
ssize_t
readv (int fd, const struct iovec *vector, int count)
readv(int fd, const struct iovec *vector, int count)
{
intercept ("readv", 2);
set_errno ();
return -1;
intercept("readv", 2);
set_errno();
return -1;
}
ssize_t
pread (int fd, void *buf, size_t count, unsigned long offset)
pread(int fd, void *buf, size_t count, unsigned long offset)
{
intercept ("pread", 2);
set_errno ();
return -1;
}
ssize_t
pread64 (int fd, void *buf, size_t count, uint64_t offset)
{
intercept ("pread64", 2);
set_errno ();
return -1;
intercept("pread", 2);
set_errno();
return -1;
}
ssize_t
write (int fd, const void *buf, size_t count)
pread64(int fd, void *buf, size_t count, uint64_t offset)
{
intercept ("write", 2);
set_errno ();
return -1;
intercept("pread64", 2);
set_errno();
return -1;
}
ssize_t
writev (int fd, const struct iovec *vector, int count)
write(int fd, const void *buf, size_t count)
{
intercept ("writev", 2);
set_errno ();
return -1;
intercept("write", 2);
set_errno();
return -1;
}
ssize_t
pwrite (int fd, const void *buf, size_t count, unsigned long offset)
writev(int fd, const struct iovec *vector, int count)
{
intercept ("pwrite", 2);
set_errno ();
return -1;
intercept("writev", 2);
set_errno();
return -1;
}
ssize_t
pwrite64 (int fd, const void *buf, size_t count, uint64_t offset)
pwrite(int fd, const void *buf, size_t count, unsigned long offset)
{
intercept ("pwrite64", 2);
set_errno ();
return -1;
intercept("pwrite", 2);
set_errno();
return -1;
}
off_t
lseek (int fildes, unsigned long offset, int whence)
ssize_t
pwrite64(int fd, const void *buf, size_t count, uint64_t offset)
{
intercept ("lseek", 2);
set_errno ();
return -1;
intercept("pwrite64", 2);
set_errno();
return -1;
}
off_t
lseek64 (int fildes, uint64_t offset, int whence)
lseek(int fildes, unsigned long offset, int whence)
{
intercept ("lseek64", 2);
set_errno ();
return -1;
intercept("lseek", 2);
set_errno();
return -1;
}
int
dup (int fd)
off_t
lseek64(int fildes, uint64_t offset, int whence)
{
intercept ("dup", 2);
set_errno ();
return -1;
intercept("lseek64", 2);
set_errno();
return -1;
}
int
dup2 (int oldfd, int newfd)
dup(int fd)
{
intercept ("dup2", 2);
set_errno ();
return -1;
intercept("dup", 2);
set_errno();
return -1;
}
int
mkdir (const char *pathname, mode_t mode)
dup2(int oldfd, int newfd)
{
intercept ("mkdir", 2);
set_errno ();
return -1;
intercept("dup2", 2);
set_errno();
return -1;
}
int
rmdir (const char *pathname)
mkdir(const char *pathname, mode_t mode)
{
intercept ("rmdir", 2);
set_errno ();
return -1;
intercept("mkdir", 2);
set_errno();
return -1;
}
int
chmod (const char *pathname, mode_t mode)
rmdir(const char *pathname)
{
intercept ("chmod", 2);
set_errno ();
return -1;
intercept("rmdir", 2);
set_errno();
return -1;
}
int
chown (const char *pathname, uid_t owner, gid_t group)
chmod(const char *pathname, mode_t mode)
{
intercept ("chown", 2);
set_errno ();
return -1;
intercept("chmod", 2);
set_errno();
return -1;
}
int
fchmod (int fd, mode_t mode)
chown(const char *pathname, uid_t owner, gid_t group)
{
intercept ("fchmod", 2);
set_errno ();
return -1;
intercept("chown", 2);
set_errno();
return -1;
}
int
fchown (int fd, uid_t uid, gid_t gid)
fchmod(int fd, mode_t mode)
{
intercept ("fchown", 2);
set_errno ();
return -1;
}
int fsync (int fd)
{
intercept ("fsync", 2);
set_errno ();
return -1;
}
int
ftruncate (int fd, off_t length)
{
intercept ("ftruncate", 1);
set_errno ();
return -1;
}
int
ftruncate64 (int fd, off_t length)
{
intercept ("ftruncate64", 1);
set_errno ();
return -1;
intercept("fchmod", 2);
set_errno();
return -1;
}
int
link (const char *oldpath, const char *newname)
fchown(int fd, uid_t uid, gid_t gid)
{
intercept ("link", 2);
set_errno ();
return -1;
intercept("fchown", 2);
set_errno();
return -1;
}
int
rename (const char *oldpath, const char *newpath)
fsync(int fd)
{
intercept ("rename", 2);
set_errno ();
return -1;
intercept("fsync", 2);
set_errno();
return -1;
}
int
utimes (const char *path, const struct timeval times[2])
ftruncate(int fd, off_t length)
{
intercept ("utimes", 2);
set_errno ();
return -1;
intercept("ftruncate", 1);
set_errno();
return -1;
}
int
futimes (int fd, const struct timeval times[2])
ftruncate64(int fd, off_t length)
{
intercept ("futimes", 2);
set_errno ();
return -1;
intercept("ftruncate64", 1);
set_errno();
return -1;
}
int
utime (const char *path, const struct utimbuf *buf)
link(const char *oldpath, const char *newname)
{
intercept ("utime", 2);
set_errno ();
return -1;
}
int
mknod (const char *path, mode_t mode, dev_t dev)
{
intercept ("mknod", 2);
set_errno ();
return -1;
intercept("link", 2);
set_errno();
return -1;
}
int
__xmknod (int ver, const char *path, mode_t mode, dev_t *dev)
rename(const char *oldpath, const char *newpath)
{
intercept ("__xmknod", 2);
set_errno ();
return -1;
intercept("rename", 2);
set_errno();
return -1;
}
int
mkfifo (const char *path, mode_t mode)
utimes(const char *path, const struct timeval times[2])
{
intercept ("mkfifo", 2);
set_errno ();
return -1;
intercept("utimes", 2);
set_errno();
return -1;
}
int
unlink (const char *path)
futimes(int fd, const struct timeval times[2])
{
intercept ("unlink", 2);
set_errno ();
return -1;
}
int
symlink (const char *oldpath, const char *newpath)
{
intercept ("symlink", 2);
set_errno ();
return -1;
intercept("futimes", 2);
set_errno();
return -1;
}
int
readlink (const char *path, char *buf, size_t bufsize)
utime(const char *path, const struct utimbuf *buf)
{
intercept ("readlink", 1);
set_errno ();
return -1;
intercept("utime", 2);
set_errno();
return -1;
}
int
mknod(const char *path, mode_t mode, dev_t dev)
{
intercept("mknod", 2);
set_errno();
return -1;
}
int
__xmknod(int ver, const char *path, mode_t mode, dev_t *dev)
{
intercept("__xmknod", 2);
set_errno();
return -1;
}
int
mkfifo(const char *path, mode_t mode)
{
intercept("mkfifo", 2);
set_errno();
return -1;
}
int
unlink(const char *path)
{
intercept("unlink", 2);
set_errno();
return -1;
}
int
symlink(const char *oldpath, const char *newpath)
{
intercept("symlink", 2);
set_errno();
return -1;
}
int
readlink(const char *path, char *buf, size_t bufsize)
{
intercept("readlink", 1);
set_errno();
return -1;
}
char *
realpath (const char *path, char *resolved)
realpath(const char *path, char *resolved)
{
intercept ("realpath", 1);
set_errno ();
return NULL;
intercept("realpath", 1);
set_errno();
return NULL;
}
DIR *
opendir (const char *path)
opendir(const char *path)
{
intercept ("opendir", 2);
set_errno ();
return NULL;
}
struct dirent *
readdir (DIR *dir)
{
intercept ("readdir\t", 2);
set_errno ();
return NULL;
intercept("opendir", 2);
set_errno();
return NULL;
}
struct dirent *
readdir64 (DIR *dir)
readdir(DIR *dir)
{
intercept ("readdir64", 2);
set_errno ();
return NULL;
intercept("readdir\t", 2);
set_errno();
return NULL;
}
int
readdir_r (DIR *dir, struct dirent *entry, struct dirent **result)
struct dirent *
readdir64(DIR *dir)
{
intercept ("readdir_r", 1);
set_errno ();
return -1;
intercept("readdir64", 2);
set_errno();
return NULL;
}
int
readdir64_r (DIR *dir, struct dirent *entry, struct dirent **result)
readdir_r(DIR *dir, struct dirent *entry, struct dirent **result)
{
intercept ("readdir64_r", 1);
set_errno ();
return -1;
}
int
closedir (DIR *dh)
{
intercept ("closedir", 1);
set_errno ();
return -1;
intercept("readdir_r", 1);
set_errno();
return -1;
}
int
__xstat (int ver, const char *path, struct stat *buf)
readdir64_r(DIR *dir, struct dirent *entry, struct dirent **result)
{
intercept ("__xstat\t", 2);
set_errno ();
return -1;
}
int
__xstat64 (int ver, const char *path, struct stat *buf)
{
intercept ("__xstat64", 2);
set_errno ();
return -1;
intercept("readdir64_r", 1);
set_errno();
return -1;
}
int
stat (const char *path, struct stat *buf)
closedir(DIR *dh)
{
intercept ("stat", 2);
set_errno ();
return -1;
intercept("closedir", 1);
set_errno();
return -1;
}
int
stat64 (const char *path, struct stat *buf)
__xstat(int ver, const char *path, struct stat *buf)
{
intercept ("stat64", 2);
set_errno ();
return -1;
intercept("__xstat\t", 2);
set_errno();
return -1;
}
int
__fxstat (int ver, int fd, struct stat *buf)
__xstat64(int ver, const char *path, struct stat *buf)
{
intercept ("__fxstat\t", 2);
set_errno ();
return -1;
}
int
__fxstat64 (int ver, int fd, struct stat *buf)
{
intercept ("__fxstat64", 2);
set_errno ();
return -1;
intercept("__xstat64", 2);
set_errno();
return -1;
}
int
fstat (int fd, struct stat *buf)
stat(const char *path, struct stat *buf)
{
intercept ("fstat", 2);
set_errno ();
return -1;
intercept("stat", 2);
set_errno();
return -1;
}
int
fstat64 (int fd , struct stat *buf)
stat64(const char *path, struct stat *buf)
{
intercept ("fstat64", 2);
set_errno ();
return -1;
intercept("stat64", 2);
set_errno();
return -1;
}
int
__lxstat (int ver, const char *path, struct stat *buf)
__fxstat(int ver, int fd, struct stat *buf)
{
intercept ("__lxstat\t", 2);
set_errno ();
return -1;
intercept("__fxstat\t", 2);
set_errno();
return -1;
}
int
__lxstat64 (int ver, const char *path, struct stat *buf)
__fxstat64(int ver, int fd, struct stat *buf)
{
intercept ("__lxstat64", 2);
set_errno ();
return -1;
intercept("__fxstat64", 2);
set_errno();
return -1;
}
int
lstat (const char *path, struct stat *buf)
fstat(int fd, struct stat *buf)
{
intercept ("lstat", 2);
set_errno ();
return -1;
intercept("fstat", 2);
set_errno();
return -1;
}
int
lstat64 (const char *path, struct stat *buf)
fstat64(int fd, struct stat *buf)
{
intercept ("lstat64", 2);
set_errno ();
return -1;
intercept("fstat64", 2);
set_errno();
return -1;
}
int
statfs (const char *path, struct statfs *buf)
__lxstat(int ver, const char *path, struct stat *buf)
{
intercept ("statfs", 2);
set_errno ();
return -1;
}
int
statfs64 (const char *path, struct statfs *buf)
{
intercept ("statfs64", 2);
set_errno ();
return -1;
intercept("__lxstat\t", 2);
set_errno();
return -1;
}
int
statvfs (const char *path, struct statvfs *buf)
__lxstat64(int ver, const char *path, struct stat *buf)
{
intercept ("statvfs\t", 2);
set_errno ();
return -1;
intercept("__lxstat64", 2);
set_errno();
return -1;
}
int
lstat(const char *path, struct stat *buf)
{
intercept("lstat", 2);
set_errno();
return -1;
}
int
statvfs64 (const char *path, struct statvfs *buf)
lstat64(const char *path, struct stat *buf)
{
intercept ("statvfs64", 2);
set_errno ();
return -1;
intercept("lstat64", 2);
set_errno();
return -1;
}
int
statfs(const char *path, struct statfs *buf)
{
intercept("statfs", 2);
set_errno();
return -1;
}
int
statfs64(const char *path, struct statfs *buf)
{
intercept("statfs64", 2);
set_errno();
return -1;
}
int
statvfs(const char *path, struct statvfs *buf)
{
intercept("statvfs\t", 2);
set_errno();
return -1;
}
int
statvfs64(const char *path, struct statvfs *buf)
{
intercept("statvfs64", 2);
set_errno();
return -1;
}
ssize_t
getxattr (const char *path, const char *name, void *value, size_t size)
getxattr(const char *path, const char *name, void *value, size_t size)
{
intercept ("getxattr", 1);
set_errno ();
return -1;
intercept("getxattr", 1);
set_errno();
return -1;
}
ssize_t
lgetxattr (const char *path, const char *name, void *value, size_t size)
lgetxattr(const char *path, const char *name, void *value, size_t size)
{
intercept ("lgetxattr", 1);
set_errno ();
return -1;
}
int
remove (const char* path)
{
intercept ("remove", 2);
set_errno ();
return -1;
intercept("lgetxattr", 1);
set_errno();
return -1;
}
int
lchown (const char *path, uid_t owner, gid_t group)
remove(const char *path)
{
intercept ("lchown", 2);
set_errno ();
return -1;
intercept("remove", 2);
set_errno();
return -1;
}
int
lchown(const char *path, uid_t owner, gid_t group)
{
intercept("lchown", 2);
set_errno();
return -1;
}
void
rewinddir (DIR *dirp)
rewinddir(DIR *dirp)
{
intercept ("rewinddir", 1);
set_errno ();
return;
intercept("rewinddir", 1);
set_errno();
return;
}
void
seekdir (DIR *dirp, off_t offset)
seekdir(DIR *dirp, off_t offset)
{
intercept ("seekdir", 2);
set_errno ();
return;
intercept("seekdir", 2);
set_errno();
return;
}
off_t
telldir (DIR *dirp)
telldir(DIR *dirp)
{
intercept ("telldir", 2);
set_errno ();
return -1;
intercept("telldir", 2);
set_errno();
return -1;
}
ssize_t
sendfile (int out_fd, int in_fd, off_t *offset, size_t count)
sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
intercept ("sendfile\t", 1);
set_errno ();
return -1;
intercept("sendfile\t", 1);
set_errno();
return -1;
}
ssize_t
sendfile64 (int out_fd, int in_fd, off_t *offset, size_t count)
sendfile64(int out_fd, int in_fd, off_t *offset, size_t count)
{
intercept ("sendfile64", 1);
set_errno ();
return -1;
intercept("sendfile64", 1);
set_errno();
return -1;
}
int
fcntl (int fd, int cmd, ...)
fcntl(int fd, int cmd, ...)
{
intercept ("fcntl", 2);
set_errno ();
return -1;
intercept("fcntl", 2);
set_errno();
return -1;
}

View File

@ -49,319 +49,310 @@
#include <sys/xattr.h>
#include <sys/sendfile.h>
#define PRELOAD_ERRNO_VERF 6449
#define PRELOAD_ERRNO_VERF 6449
void
check_err(int ret, char *call, int tabs)
{
while (tabs > 0) {
fprintf (stdout, "\t");
--tabs;
}
if (ret != -1) {
fprintf (stdout, "Not intercepted: %s\n", call);
return;
}
if (errno != PRELOAD_ERRNO_VERF) {
fprintf (stdout, "Not intercepted: %s: err: %s\n", call,
strerror (errno));
return;
}
fprintf (stdout, "Intercept verified: %s\n", call);
while (tabs > 0) {
fprintf(stdout, "\t");
--tabs;
}
if (ret != -1) {
fprintf(stdout, "Not intercepted: %s\n", call);
return;
}
if (errno != PRELOAD_ERRNO_VERF) {
fprintf(stdout, "Not intercepted: %s: err: %s\n", call,
strerror(errno));
return;
}
fprintf(stdout, "Intercept verified: %s\n", call);
return;
}
void
usage (FILE *fp)
usage(FILE *fp)
{
fprintf (fp, "Usage: ld-preload-test <Options>\n");
fprintf (fp, "Options\n");
fprintf (fp, "\t--path\t\tPathname is used as the file/directory"
" created for the test.\n");
}
int
run_file_tests (char *testfile)
{
int ret = -1;
struct stat buf;
assert (testfile);
fprintf (stdout, "Testing creat");
ret = creat (testfile, S_IRWXU);
check_err (ret, "creat", 2);
fprintf (stdout, "Testing close");
ret = close (ret);
check_err (ret, "close", 2);
fprintf (stdout, "Testing open");
ret = open (testfile, O_RDONLY);
check_err (ret, "open", 2);
fprintf (stdout, "Testing read");
ret = read (0, NULL, 0);
check_err (ret, "read", 2);
fprintf (stdout, "Testing readv");
ret = readv (0, NULL, 0);
check_err (ret, "readv", 2);
fprintf (stdout, "Testing pread");
ret = pread (0, NULL, 0, 0);
check_err (ret, "pread", 2);
fprintf (stdout, "Testing write");
ret = write (0, NULL, 0);
check_err (ret, "write", 2);
fprintf (stdout, "Testing writev");
ret = writev (0, NULL, 0);
check_err (ret, "writev", 2);
fprintf (stdout, "Testing pwrite");
ret = pwrite (0, NULL, 0, 0);
check_err (ret, "pwrite", 2);
fprintf (stdout, "Testing lseek");
ret = lseek (0, 0, 0);
check_err (ret, "lseek", 2);
fprintf (stdout, "Testing dup");
ret = dup (0);
check_err (ret, "dup", 2);
fprintf (stdout, "Testing dup2");
ret = dup2 (0, 0);
check_err (ret, "dup2", 2);
fprintf (stdout, "Testing fchmod");
ret = fchmod (0, 0);
check_err (ret, "fchmod", 2);
fprintf (stdout, "Testing fchown");
ret = fchown (0, 0, 0);
check_err (ret, "fchown", 2);
fprintf (stdout, "Testing fsync");
ret = fsync (0);
check_err (ret, "fsync", 2);
fprintf (stdout, "Testing ftruncate");
ret = ftruncate (0, 0);
check_err (ret, "ftruncate", 1);
fprintf (stdout, "Testing fstat");
ret = fstat (0, &buf);
check_err (ret, "fstat", 1);
fprintf (stdout, "Testing sendfile");
ret = sendfile (0, 0, NULL, 0);
check_err (ret, "sendfile", 1);
fprintf (stdout, "Testing fcntl");
ret = fcntl (0, 0, NULL);
check_err (ret, "fcntl", 2);
fprintf (stdout, "Testing close");
ret = close (ret);
check_err (ret, "close", 2);
fprintf (stdout, "Testing remove");
ret = remove (testfile);
check_err (ret, "remove", 2);
return ret;
}
int
run_attr_tests (char *testfile)
{
int ret = -1;
char *res = NULL;
struct stat buf;
struct statfs sbuf;
struct statvfs svbuf;
assert (testfile);
fprintf (stdout, "Testing chmod");
ret = chmod (testfile, 0);
check_err (ret, "chmod", 2);
fprintf (stdout, "Testing chown");
ret = chown (testfile, 0, 0);
check_err (ret, "chown", 2);
fprintf (stdout, "Testing link");
ret = link (testfile, testfile);
check_err (ret, "link", 2);
fprintf (stdout, "Testing rename");
ret = rename (testfile, testfile);
check_err (ret, "rename", 2);
fprintf (stdout, "Testing utimes");
ret = utimes (testfile, NULL);
check_err (ret, "utimes", 2);
fprintf (stdout, "Testing utime");
ret = utime (testfile, NULL);
check_err (ret, "utime", 2);
fprintf (stdout, "Testing unlink");
ret = unlink (testfile);
check_err (ret, "unlink", 2);
fprintf (stdout, "Testing symlink");
ret = symlink (testfile, testfile);
check_err (ret, "symlink", 2);
fprintf (stdout, "Testing readlink");
ret = readlink (testfile, testfile, 0);
check_err (ret, "readlink", 2);
fprintf (stdout, "Testing realpath");
ret = 0;
res = realpath ((const char *)testfile, testfile);
if (!res)
ret = -1;
check_err (ret, "realpath", 2);
fprintf (stdout, "Testing stat");
ret = stat (testfile, &buf);
check_err (ret, "stat", 1);
fprintf (stdout, "Testing lstat");
ret = lstat (testfile, &buf);
check_err (ret, "lstat", 1);
fprintf (stdout, "Testing statfs");
ret = statfs (testfile, &sbuf);
check_err (ret, "statfs", 2);
fprintf (stdout, "Testing statvfs");
ret = statvfs (testfile, &svbuf);
check_err (ret, "statvfs", 1);
fprintf (stdout, "Testing getxattr");
ret = getxattr (testfile, NULL, NULL, 0);
check_err (ret, "getxattr", 2);
fprintf (stdout, "Testing lgetxattr");
ret = lgetxattr (testfile, NULL, NULL, 0);
check_err (ret, "lgetxattr", 1);
fprintf (stdout, "Testing lchown");
ret = lchown (testfile, 0, 0);
check_err (ret, "lchown", 2);
return 0;
}
int
run_dev_tests (char *testfile)
{
int ret = -1;
assert (testfile);
fprintf (stdout, "Testing mknod");
ret = mknod (testfile, 0, 0);
check_err (ret, "mknod", 2);
fprintf (stdout, "Testing mkfifo");
ret = mkfifo (testfile, 0);
check_err (ret, "mkfifo", 2);
return 0;
fprintf(fp, "Usage: ld-preload-test <Options>\n");
fprintf(fp, "Options\n");
fprintf(fp,
"\t--path\t\tPathname is used as the file/directory"
" created for the test.\n");
}
int
run_dir_tests (char *testpath)
run_file_tests(char *testfile)
{
int ret = -1;
DIR *dh = NULL;
struct dirent *dire = NULL;
int ret = -1;
struct stat buf;
assert (testpath);
assert(testfile);
fprintf(stdout, "Testing creat");
ret = creat(testfile, S_IRWXU);
check_err(ret, "creat", 2);
fprintf (stdout, "Testing mkdir");
ret = mkdir (testpath, 0);
check_err (ret, "mkdir", 2);
fprintf(stdout, "Testing close");
ret = close(ret);
check_err(ret, "close", 2);
fprintf (stdout, "Testing rmdir");
ret = rmdir (testpath);
check_err (ret, "rmdir", 2);
fprintf(stdout, "Testing open");
ret = open(testfile, O_RDONLY);
check_err(ret, "open", 2);
fprintf (stdout, "Testing opendir");
ret = 0;
dh = opendir (testpath);
if (!dh)
ret = -1;
check_err (ret, "opendir", 2);
fprintf(stdout, "Testing read");
ret = read(0, NULL, 0);
check_err(ret, "read", 2);
fprintf (stdout, "Testing readdir");
ret = 0;
dire = readdir (dh);
if (!dire)
ret = -1;
check_err (ret, "readdir", 1);
fprintf(stdout, "Testing readv");
ret = readv(0, NULL, 0);
check_err(ret, "readv", 2);
fprintf (stdout, "Testing readdir_r");
ret = readdir_r (dh, dire, &dire);
check_err (ret, "readdir_r", 1);
fprintf(stdout, "Testing pread");
ret = pread(0, NULL, 0, 0);
check_err(ret, "pread", 2);
fprintf (stdout, "Testing rewinddir");
rewinddir (dh);
check_err (-1, "rewinddir", 1);
fprintf(stdout, "Testing write");
ret = write(0, NULL, 0);
check_err(ret, "write", 2);
fprintf (stdout, "Testing seekdir");
seekdir (dh, 0);
check_err (-1, "seekdir", 2);
fprintf(stdout, "Testing writev");
ret = writev(0, NULL, 0);
check_err(ret, "writev", 2);
fprintf (stdout, "Testing telldir");
ret = telldir (dh);
check_err (ret, "telldir", 2);
fprintf(stdout, "Testing pwrite");
ret = pwrite(0, NULL, 0, 0);
check_err(ret, "pwrite", 2);
fprintf (stdout, "Testing closedir");
ret = closedir (dh);
check_err (ret, "closedir", 2);
return 0;
fprintf(stdout, "Testing lseek");
ret = lseek(0, 0, 0);
check_err(ret, "lseek", 2);
fprintf(stdout, "Testing dup");
ret = dup(0);
check_err(ret, "dup", 2);
fprintf(stdout, "Testing dup2");
ret = dup2(0, 0);
check_err(ret, "dup2", 2);
fprintf(stdout, "Testing fchmod");
ret = fchmod(0, 0);
check_err(ret, "fchmod", 2);
fprintf(stdout, "Testing fchown");
ret = fchown(0, 0, 0);
check_err(ret, "fchown", 2);
fprintf(stdout, "Testing fsync");
ret = fsync(0);
check_err(ret, "fsync", 2);
fprintf(stdout, "Testing ftruncate");
ret = ftruncate(0, 0);
check_err(ret, "ftruncate", 1);
fprintf(stdout, "Testing fstat");
ret = fstat(0, &buf);
check_err(ret, "fstat", 1);
fprintf(stdout, "Testing sendfile");
ret = sendfile(0, 0, NULL, 0);
check_err(ret, "sendfile", 1);
fprintf(stdout, "Testing fcntl");
ret = fcntl(0, 0, NULL);
check_err(ret, "fcntl", 2);
fprintf(stdout, "Testing close");
ret = close(ret);
check_err(ret, "close", 2);
fprintf(stdout, "Testing remove");
ret = remove(testfile);
check_err(ret, "remove", 2);
return ret;
}
int
run_attr_tests(char *testfile)
{
int ret = -1;
char *res = NULL;
struct stat buf;
struct statfs sbuf;
struct statvfs svbuf;
assert(testfile);
fprintf(stdout, "Testing chmod");
ret = chmod(testfile, 0);
check_err(ret, "chmod", 2);
fprintf(stdout, "Testing chown");
ret = chown(testfile, 0, 0);
check_err(ret, "chown", 2);
fprintf(stdout, "Testing link");
ret = link(testfile, testfile);
check_err(ret, "link", 2);
fprintf(stdout, "Testing rename");
ret = rename(testfile, testfile);
check_err(ret, "rename", 2);
fprintf(stdout, "Testing utimes");
ret = utimes(testfile, NULL);
check_err(ret, "utimes", 2);
fprintf(stdout, "Testing utime");
ret = utime(testfile, NULL);
check_err(ret, "utime", 2);
fprintf(stdout, "Testing unlink");
ret = unlink(testfile);
check_err(ret, "unlink", 2);
fprintf(stdout, "Testing symlink");
ret = symlink(testfile, testfile);
check_err(ret, "symlink", 2);
fprintf(stdout, "Testing readlink");
ret = readlink(testfile, testfile, 0);
check_err(ret, "readlink", 2);
fprintf(stdout, "Testing realpath");
ret = 0;
res = realpath((const char *)testfile, testfile);
if (!res)
ret = -1;
check_err(ret, "realpath", 2);
fprintf(stdout, "Testing stat");
ret = stat(testfile, &buf);
check_err(ret, "stat", 1);
fprintf(stdout, "Testing lstat");
ret = lstat(testfile, &buf);
check_err(ret, "lstat", 1);
fprintf(stdout, "Testing statfs");
ret = statfs(testfile, &sbuf);
check_err(ret, "statfs", 2);
fprintf(stdout, "Testing statvfs");
ret = statvfs(testfile, &svbuf);
check_err(ret, "statvfs", 1);
fprintf(stdout, "Testing getxattr");
ret = getxattr(testfile, NULL, NULL, 0);
check_err(ret, "getxattr", 2);
fprintf(stdout, "Testing lgetxattr");
ret = lgetxattr(testfile, NULL, NULL, 0);
check_err(ret, "lgetxattr", 1);
fprintf(stdout, "Testing lchown");
ret = lchown(testfile, 0, 0);
check_err(ret, "lchown", 2);
return 0;
}
int
main (int argc, char *argv[])
run_dev_tests(char *testfile)
{
char *testpath = NULL;
int x = 0;
int ret = -1;
for (;x < argc; ++x) {
if (strcmp (argv[x], "--path") == 0) {
testpath = argv[x+1];
continue;
}
assert(testfile);
fprintf(stdout, "Testing mknod");
ret = mknod(testfile, 0, 0);
check_err(ret, "mknod", 2);
fprintf(stdout, "Testing mkfifo");
ret = mkfifo(testfile, 0);
check_err(ret, "mkfifo", 2);
return 0;
}
int
run_dir_tests(char *testpath)
{
int ret = -1;
DIR *dh = NULL;
struct dirent *dire = NULL;
assert(testpath);
fprintf(stdout, "Testing mkdir");
ret = mkdir(testpath, 0);
check_err(ret, "mkdir", 2);
fprintf(stdout, "Testing rmdir");
ret = rmdir(testpath);
check_err(ret, "rmdir", 2);
fprintf(stdout, "Testing opendir");
ret = 0;
dh = opendir(testpath);
if (!dh)
ret = -1;
check_err(ret, "opendir", 2);
fprintf(stdout, "Testing readdir");
ret = 0;
dire = readdir(dh);
if (!dire)
ret = -1;
check_err(ret, "readdir", 1);
fprintf(stdout, "Testing readdir_r");
ret = readdir_r(dh, dire, &dire);
check_err(ret, "readdir_r", 1);
fprintf(stdout, "Testing rewinddir");
rewinddir(dh);
check_err(-1, "rewinddir", 1);
fprintf(stdout, "Testing seekdir");
seekdir(dh, 0);
check_err(-1, "seekdir", 2);
fprintf(stdout, "Testing telldir");
ret = telldir(dh);
check_err(ret, "telldir", 2);
fprintf(stdout, "Testing closedir");
ret = closedir(dh);
check_err(ret, "closedir", 2);
return 0;
}
int
main(int argc, char *argv[])
{
char *testpath = NULL;
int x = 0;
for (; x < argc; ++x) {
if (strcmp(argv[x], "--path") == 0) {
testpath = argv[x + 1];
continue;
}
}
if (!testpath) {
fprintf (stderr, "--path not specified\n");
usage (stderr);
return -1;
}
if (!testpath) {
fprintf(stderr, "--path not specified\n");
usage(stderr);
return -1;
}
run_file_tests (testpath);
run_dir_tests (testpath);
run_attr_tests (testpath);
run_dev_tests (testpath);
run_file_tests(testpath);
run_dir_tests(testpath);
run_attr_tests(testpath);
run_dev_tests(testpath);
return 0;
return 0;
}

View File

@ -9,56 +9,59 @@
#include <string.h>
int
main (int argc, char *argv[])
main(int argc, char *argv[])
{
int ret = -1;
int fd = 0;
char *filename = NULL;
int loop = 0;
struct stat stbuf = {0,};
char string[1024] = {0,};
int ret = -1;
int fd = 0;
char *filename = NULL;
int loop = 0;
struct stat stbuf = {
0,
};
char string[1024] = {
0,
};
if (argc > 1)
filename = argv[1];
if (argc > 1)
filename = argv[1];
if (!filename)
filename = "temp-fd-test-file";
if (!filename)
filename = "temp-fd-test-file";
fd = open (filename, O_RDWR|O_CREAT|O_TRUNC);
if (fd < 0) {
fd = 0;
fprintf (stderr, "open failed : %s\n", strerror (errno));
goto out;
fd = open(filename, O_RDWR | O_CREAT | O_TRUNC);
if (fd < 0) {
fd = 0;
fprintf(stderr, "open failed : %s\n", strerror(errno));
goto out;
}
while (loop < 1000) {
/* Use it as a mechanism to test time delays */
memset(string, 0, 1024);
scanf("%s", string);
ret = write(fd, string, strlen(string));
if (ret != strlen(string)) {
fprintf(stderr, "write failed : %s (%s %d)\n", strerror(errno),
string, loop);
goto out;
}
while (loop < 1000) {
/* Use it as a mechanism to test time delays */
memset (string, 0, 1024);
scanf ("%s", string);
ret = write (fd, string, strlen (string));
if (ret != strlen (string)) {
fprintf (stderr, "write failed : %s (%s %d)\n",
strerror (errno), string, loop);
goto out;
}
ret = write (fd, "\n", 1);
if (ret != 1) {
fprintf (stderr, "write failed : %s (%d)\n",
strerror (errno), loop);
goto out;
}
loop++;
ret = write(fd, "\n", 1);
if (ret != 1) {
fprintf(stderr, "write failed : %s (%d)\n", strerror(errno), loop);
goto out;
}
fprintf (stdout, "finishing the test after %d loops\n", loop);
loop++;
}
ret = 0;
fprintf(stdout, "finishing the test after %d loops\n", loop);
ret = 0;
out:
if (fd)
close (fd);
if (fd)
close(fd);
return ret;
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -42,359 +42,362 @@
int restricted = 0;
static int
duplexpand (void **buf, size_t tsiz, size_t *len)
duplexpand(void **buf, size_t tsiz, size_t *len)
{
size_t osiz = tsiz * *len;
char *p = realloc (*buf, osiz << 1);
if (!p) {
free(*buf);
return -1;
}
memset (p + osiz, 0, osiz);
*buf = p;
*len <<= 1;
return 0;
}
static int
str2argv (char *str, char ***argv)
{
char *p = NULL;
char *savetok = NULL;
char *temp = NULL;
char *temp1 = NULL;
int argc = 0;
size_t argv_len = 32;
int ret = 0;
int i = 0;
assert (str);
temp = str = strdup (str);
if (!str)
goto error;
*argv = calloc (argv_len, sizeof (**argv));
if (!*argv)
goto error;
while ((p = strtok_r (str, " ", &savetok))) {
str = NULL;
argc++;
if (argc == argv_len) {
ret = duplexpand ((void *)argv,
sizeof (**argv),
&argv_len);
if (ret == -1)
goto error;
}
temp1 = strdup (p);
if (!temp1)
goto error;
(*argv)[argc - 1] = temp1;
}
free(temp);
return argc;
error:
fprintf (stderr, "out of memory\n");
free(temp);
for (i = 0; i < argc - 1; i++)
free((*argv)[i]);
free(*argv);
size_t osiz = tsiz * *len;
char *p = realloc(*buf, osiz << 1);
if (!p) {
free(*buf);
return -1;
}
memset(p + osiz, 0, osiz);
*buf = p;
*len <<= 1;
return 0;
}
static int
invoke_gsyncd (int argc, char **argv)
str2argv(char *str, char ***argv)
{
int i = 0;
int j = 0;
char *nargv[argc + 4];
char *python = NULL;
char *p = NULL;
char *savetok = NULL;
char *temp = NULL;
char *temp1 = NULL;
int argc = 0;
size_t argv_len = 32;
int ret = 0;
int i = 0;
if (chdir ("/") == -1)
assert(str);
temp = str = strdup(str);
if (!str)
goto error;
*argv = calloc(argv_len, sizeof(**argv));
if (!*argv)
goto error;
while ((p = strtok_r(str, " ", &savetok))) {
str = NULL;
argc++;
if (argc == argv_len) {
ret = duplexpand((void *)argv, sizeof(**argv), &argv_len);
if (ret == -1)
goto error;
}
temp1 = strdup(p);
if (!temp1)
goto error;
(*argv)[argc - 1] = temp1;
}
j = 0;
python = getenv("PYTHON");
if(!python)
python = PYTHON;
nargv[j++] = python;
nargv[j++] = GSYNCD_PREFIX"/python/syncdaemon/"GSYNCD_PY;
for (i = 1; i < argc; i++)
nargv[j++] = argv[i];
free(temp);
return argc;
nargv[j++] = NULL;
execvp (python, nargv);
fprintf (stderr, "exec of '%s' failed\n", python);
return 127;
error:
fprintf (stderr, "gsyncd initializaion failed\n");
return 1;
error:
fprintf(stderr, "out of memory\n");
free(temp);
for (i = 0; i < argc - 1; i++)
free((*argv)[i]);
free(*argv);
return -1;
}
static int
invoke_gsyncd(int argc, char **argv)
{
int i = 0;
int j = 0;
char *nargv[argc + 4];
char *python = NULL;
if (chdir("/") == -1)
goto error;
j = 0;
python = getenv("PYTHON");
if (!python)
python = PYTHON;
nargv[j++] = python;
nargv[j++] = GSYNCD_PREFIX "/python/syncdaemon/" GSYNCD_PY;
for (i = 1; i < argc; i++)
nargv[j++] = argv[i];
nargv[j++] = NULL;
execvp(python, nargv);
fprintf(stderr, "exec of '%s' failed\n", python);
return 127;
error:
fprintf(stderr, "gsyncd initializaion failed\n");
return 1;
}
static int
find_gsyncd (pid_t pid, pid_t ppid, char *name, void *data)
find_gsyncd(pid_t pid, pid_t ppid, char *name, void *data)
{
char buf[NAME_MAX * 2] = {0,};
char path[PATH_MAX] = {0,};
char *p = NULL;
int zeros = 0;
int ret = 0;
int fd = -1;
pid_t *pida = (pid_t *)data;
if (ppid != pida[0])
return 0;
snprintf (path, sizeof path, PROC"/%d/cmdline", pid);
fd = open (path, O_RDONLY);
if (fd == -1)
return 0;
ret = sys_read (fd, buf, sizeof (buf));
sys_close (fd);
if (ret == -1)
return 0;
for (zeros = 0, p = buf; zeros < 2 && p < buf + ret; p++)
zeros += !*p;
ret = 0;
switch (zeros) {
case 2:
if ((strcmp (basename (buf), basename (PYTHON)) ||
strcmp (basename (buf + strlen (buf) + 1), GSYNCD_PY)) == 0) {
ret = 1;
break;
}
/* fallthrough */
case 1:
if (strcmp (basename (buf), GSYNCD_PY) == 0)
ret = 1;
}
if (ret == 1) {
if (pida[1] != -1) {
fprintf (stderr, GSYNCD_PY" sibling is not unique");
return -1;
}
pida[1] = pid;
}
char buf[NAME_MAX * 2] = {
0,
};
char path[PATH_MAX] = {
0,
};
char *p = NULL;
int zeros = 0;
int ret = 0;
int fd = -1;
pid_t *pida = (pid_t *)data;
if (ppid != pida[0])
return 0;
snprintf(path, sizeof path, PROC "/%d/cmdline", pid);
fd = open(path, O_RDONLY);
if (fd == -1)
return 0;
ret = sys_read(fd, buf, sizeof(buf));
sys_close(fd);
if (ret == -1)
return 0;
for (zeros = 0, p = buf; zeros < 2 && p < buf + ret; p++)
zeros += !*p;
ret = 0;
switch (zeros) {
case 2:
if ((strcmp(basename(buf), basename(PYTHON)) ||
strcmp(basename(buf + strlen(buf) + 1), GSYNCD_PY)) == 0) {
ret = 1;
break;
}
/* fallthrough */
case 1:
if (strcmp(basename(buf), GSYNCD_PY) == 0)
ret = 1;
}
if (ret == 1) {
if (pida[1] != -1) {
fprintf(stderr, GSYNCD_PY " sibling is not unique");
return -1;
}
pida[1] = pid;
}
return 0;
}
static int
invoke_rsync (int argc, char **argv)
invoke_rsync(int argc, char **argv)
{
int i = 0;
char path[PATH_MAX] = {0,};
pid_t pid = -1;
pid_t ppid = -1;
pid_t pida[] = {-1, -1};
char *name = NULL;
char buf[PATH_MAX + 1] = {0,};
int ret = 0;
int i = 0;
char path[PATH_MAX] = {
0,
};
pid_t pid = -1;
pid_t ppid = -1;
pid_t pida[] = {-1, -1};
char *name = NULL;
char buf[PATH_MAX + 1] = {
0,
};
int ret = 0;
assert (argv[argc] == NULL);
assert(argv[argc] == NULL);
if (argc < 2 || strcmp (argv[1], "--server") != 0)
goto error;
if (argc < 2 || strcmp(argv[1], "--server") != 0)
goto error;
for (i = 2; i < argc && argv[i][0] == '-'; i++);
for (i = 2; i < argc && argv[i][0] == '-'; i++)
;
if (!(i == argc - 2 && strcmp (argv[i], ".") == 0 && argv[i + 1][0] == '/')) {
fprintf (stderr, "need an rsync invocation without protected args\n");
goto error;
if (!(i == argc - 2 && strcmp(argv[i], ".") == 0 &&
argv[i + 1][0] == '/')) {
fprintf(stderr, "need an rsync invocation without protected args\n");
goto error;
}
/* look up sshd we are spawned from */
for (pid = getpid();; pid = ppid) {
ppid = pidinfo(pid, &name);
if (ppid < 0) {
fprintf(stderr, "sshd ancestor not found\n");
goto error;
}
/* look up sshd we are spawned from */
for (pid = getpid () ;; pid = ppid) {
ppid = pidinfo (pid, &name);
if (ppid < 0) {
fprintf (stderr, "sshd ancestor not found\n");
goto error;
}
if (strcmp (name, "sshd") == 0) {
GF_FREE (name);
break;
}
GF_FREE (name);
}
/* look up "ssh-sibling" gsyncd */
pida[0] = pid;
ret = prociter (find_gsyncd, pida);
if (ret == -1 || pida[1] == -1) {
fprintf (stderr, "gsyncd sibling not found\n");
goto error;
}
/* check if rsync target matches gsyncd target */
snprintf (path, sizeof path, PROC"/%d/cwd", pida[1]);
ret = sys_readlink (path, buf, sizeof (buf));
if (ret == -1 || ret == sizeof (buf))
goto error;
if (strcmp (argv[argc - 1], "/") == 0 /* root dir cannot be a target */ ||
(strcmp (argv[argc - 1], path) /* match against gluster target */ &&
strcmp (argv[argc - 1], buf) /* match against file target */) != 0) {
fprintf (stderr, "rsync target does not match "GEOREP" session\n");
goto error;
if (strcmp(name, "sshd") == 0) {
GF_FREE(name);
break;
}
GF_FREE(name);
}
/* look up "ssh-sibling" gsyncd */
pida[0] = pid;
ret = prociter(find_gsyncd, pida);
if (ret == -1 || pida[1] == -1) {
fprintf(stderr, "gsyncd sibling not found\n");
goto error;
}
/* check if rsync target matches gsyncd target */
snprintf(path, sizeof path, PROC "/%d/cwd", pida[1]);
ret = sys_readlink(path, buf, sizeof(buf));
if (ret == -1 || ret == sizeof(buf))
goto error;
if (strcmp(argv[argc - 1], "/") == 0 /* root dir cannot be a target */ ||
(strcmp(argv[argc - 1], path) /* match against gluster target */ &&
strcmp(argv[argc - 1], buf) /* match against file target */) != 0) {
fprintf(stderr, "rsync target does not match " GEOREP " session\n");
goto error;
}
argv[0] = RSYNC;
argv[0] = RSYNC;
execvp (RSYNC, argv);
execvp(RSYNC, argv);
fprintf (stderr, "exec of "RSYNC" failed\n");
return 127;
fprintf(stderr, "exec of " RSYNC " failed\n");
return 127;
error:
fprintf (stderr, "disallowed "RSYNC" invocation\n");
return 1;
error:
fprintf(stderr, "disallowed " RSYNC " invocation\n");
return 1;
}
static int
invoke_gluster (int argc, char **argv)
invoke_gluster(int argc, char **argv)
{
int i = 0;
int j = 0;
int optsover = 0;
char *ov = NULL;
int i = 0;
int j = 0;
int optsover = 0;
char *ov = NULL;
for (i = 1; i < argc; i++) {
ov = strtail (argv[i], "--");
if (ov && !optsover) {
if (*ov == '\0')
optsover = 1;
continue;
}
switch (++j) {
case 1:
if (strcmp (argv[i], "volume") != 0)
goto error;
break;
case 2:
if (strcmp (argv[i], "info") != 0)
goto error;
break;
case 3:
break;
default:
goto error;
}
for (i = 1; i < argc; i++) {
ov = strtail(argv[i], "--");
if (ov && !optsover) {
if (*ov == '\0')
optsover = 1;
continue;
}
switch (++j) {
case 1:
if (strcmp(argv[i], "volume") != 0)
goto error;
break;
case 2:
if (strcmp(argv[i], "info") != 0)
goto error;
break;
case 3:
break;
default:
goto error;
}
}
argv[0] = "gluster";
execvp (SBIN_DIR"/gluster", argv);
fprintf (stderr, "exec of gluster failed\n");
return 127;
argv[0] = "gluster";
execvp(SBIN_DIR "/gluster", argv);
fprintf(stderr, "exec of gluster failed\n");
return 127;
error:
fprintf (stderr, "disallowed gluster invocation\n");
return 1;
error:
fprintf(stderr, "disallowed gluster invocation\n");
return 1;
}
struct invocable {
char *name;
int (*invoker) (int argc, char **argv);
char *name;
int (*invoker)(int argc, char **argv);
};
struct invocable invocables[] = {
{ "rsync", invoke_rsync },
{ "gsyncd", invoke_gsyncd },
{ "gluster", invoke_gluster },
{ NULL, NULL}
};
struct invocable invocables[] = {{"rsync", invoke_rsync},
{"gsyncd", invoke_gsyncd},
{"gluster", invoke_gluster},
{NULL, NULL}};
int
main (int argc, char **argv)
main(int argc, char **argv)
{
int ret = -1;
char *evas = NULL;
struct invocable *i = NULL;
char *b = NULL;
char *sargv = NULL;
int j = 0;
int ret = -1;
char *evas = NULL;
struct invocable *i = NULL;
char *b = NULL;
char *sargv = NULL;
int j = 0;
#ifdef USE_LIBGLUSTERFS
glusterfs_ctx_t *ctx = NULL;
glusterfs_ctx_t *ctx = NULL;
ctx = glusterfs_ctx_new ();
if (!ctx)
return ENOMEM;
ctx = glusterfs_ctx_new();
if (!ctx)
return ENOMEM;
if (glusterfs_globals_init (ctx))
return 1;
if (glusterfs_globals_init(ctx))
return 1;
THIS->ctx = ctx;
ret = default_mem_acct_init (THIS);
if (ret) {
fprintf (stderr, "internal error: mem accounting failed\n");
return 1;
}
THIS->ctx = ctx;
ret = default_mem_acct_init(THIS);
if (ret) {
fprintf(stderr, "internal error: mem accounting failed\n");
return 1;
}
#endif
evas = getenv (_GLUSTERD_CALLED_);
if (evas && strcmp (evas, "1") == 0)
/* OK, we know glusterd called us, no need to look for further config
*...although this conclusion should not inherit to our children
*/
unsetenv (_GLUSTERD_CALLED_);
else {
/* we regard all gsyncd invocations unsafe
* that do not come from glusterd and
* therefore restrict it
*/
restricted = 1;
if (!getenv (_GSYNCD_DISPATCHED_)) {
evas = getenv ("SSH_ORIGINAL_COMMAND");
if (evas)
sargv = evas;
else {
evas = getenv ("SHELL");
if (evas && strcmp (basename (evas), "gsyncd") == 0 &&
argc == 3 && strcmp (argv[1], "-c") == 0)
sargv = argv[2];
}
}
evas = getenv(_GLUSTERD_CALLED_);
if (evas && strcmp(evas, "1") == 0)
/* OK, we know glusterd called us, no need to look for further config
*...although this conclusion should not inherit to our children
*/
unsetenv(_GLUSTERD_CALLED_);
else {
/* we regard all gsyncd invocations unsafe
* that do not come from glusterd and
* therefore restrict it
*/
restricted = 1;
if (!getenv(_GSYNCD_DISPATCHED_)) {
evas = getenv("SSH_ORIGINAL_COMMAND");
if (evas)
sargv = evas;
else {
evas = getenv("SHELL");
if (evas && strcmp(basename(evas), "gsyncd") == 0 &&
argc == 3 && strcmp(argv[1], "-c") == 0)
sargv = argv[2];
}
}
}
if (!(sargv && restricted))
return invoke_gsyncd (argc, argv);
if (!(sargv && restricted))
return invoke_gsyncd(argc, argv);
argc = str2argv (sargv, &argv);
argc = str2argv(sargv, &argv);
if (argc == -1) {
fprintf (stderr, "internal error\n");
return 1;
}
if (argc == -1) {
fprintf(stderr, "internal error\n");
return 1;
}
if (setenv (_GSYNCD_DISPATCHED_, "1", 1) == -1) {
fprintf (stderr, "internal error\n");
goto out;
}
if (setenv(_GSYNCD_DISPATCHED_, "1", 1) == -1) {
fprintf(stderr, "internal error\n");
goto out;
}
b = basename(argv[0]);
for (i = invocables; i->name; i++) {
if (strcmp(b, i->name) == 0)
return i->invoker(argc, argv);
}
b = basename (argv[0]);
for (i = invocables; i->name; i++) {
if (strcmp (b, i->name) == 0)
return i->invoker (argc, argv);
}
fprintf (stderr, "invoking %s in restricted SSH session is not allowed\n",
b);
fprintf(stderr, "invoking %s in restricted SSH session is not allowed\n",
b);
out:
for (j = 1; j < argc; j++)
free(argv[j]);
free(argv);
return 1;
for (j = 1; j < argc; j++)
free(argv[j]);
free(argv);
return 1;
}

View File

@ -20,107 +20,115 @@
#include "procdiggy.h"
pid_t
pidinfo (pid_t pid, char **name)
pidinfo(pid_t pid, char **name)
{
char buf[NAME_MAX * 2] = {0,};
FILE *f = NULL;
char path[PATH_MAX] = {0,};
char *p = NULL;
int ret = 0;
char buf[NAME_MAX * 2] = {
0,
};
FILE *f = NULL;
char path[PATH_MAX] = {
0,
};
char *p = NULL;
int ret = 0;
snprintf (path, sizeof path, PROC"/%d/status", pid);
snprintf(path, sizeof path, PROC "/%d/status", pid);
f = fopen (path, "r");
if (!f)
return -1;
f = fopen(path, "r");
if (!f)
return -1;
if (name)
*name = NULL;
for (;;) {
size_t len;
memset (buf, 0, sizeof (buf));
if (fgets (buf, sizeof (buf), f) == NULL ||
(len = strlen (buf)) == 0 ||
buf[len - 1] != '\n') {
pid = -1;
goto out;
if (name)
*name = NULL;
for (;;) {
size_t len;
memset(buf, 0, sizeof(buf));
if (fgets(buf, sizeof(buf), f) == NULL || (len = strlen(buf)) == 0 ||
buf[len - 1] != '\n') {
pid = -1;
goto out;
}
buf[len - 1] = '\0';
if (name && !*name) {
p = strtail(buf, "Name:");
if (p) {
while (isspace(*++p))
;
*name = gf_strdup(p);
if (!*name) {
pid = -2;
goto out;
}
buf[len - 1] = '\0';
if (name && !*name) {
p = strtail (buf, "Name:");
if (p) {
while (isspace (*++p));
*name = gf_strdup (p);
if (!*name) {
pid = -2;
goto out;
}
continue;
}
}
p = strtail (buf, "PPid:");
if (p)
break;
continue;
}
}
while (isspace (*++p));
ret = gf_string2int (p, &pid);
if (ret == -1)
pid = -1;
p = strtail(buf, "PPid:");
if (p)
break;
}
out:
fclose (f);
if (pid == -1 && name && *name)
GF_FREE (*name);
if (pid == -2)
fprintf (stderr, "out of memory\n");
return pid;
while (isspace(*++p))
;
ret = gf_string2int(p, &pid);
if (ret == -1)
pid = -1;
out:
fclose(f);
if (pid == -1 && name && *name)
GF_FREE(*name);
if (pid == -2)
fprintf(stderr, "out of memory\n");
return pid;
}
int
prociter (int (*proch) (pid_t pid, pid_t ppid, char *tmpname, void *data),
void *data)
prociter(int (*proch)(pid_t pid, pid_t ppid, char *tmpname, void *data),
void *data)
{
char *name = NULL;
DIR *d = NULL;
struct dirent *de = NULL;
struct dirent scratch[2] = {{0,},};
pid_t pid = -1;
pid_t ppid = -1;
int ret = 0;
char *name = NULL;
DIR *d = NULL;
struct dirent *de = NULL;
struct dirent scratch[2] = {
{
0,
},
};
pid_t pid = -1;
pid_t ppid = -1;
int ret = 0;
d = sys_opendir (PROC);
if (!d)
return -1;
d = sys_opendir(PROC);
if (!d)
return -1;
for (;;) {
errno = 0;
de = sys_readdir (d, scratch);
if (!de || errno != 0)
break;
for (;;) {
errno = 0;
de = sys_readdir(d, scratch);
if (!de || errno != 0)
break;
if (gf_string2int (de->d_name, &pid) != -1 && pid >= 0) {
ppid = pidinfo (pid, &name);
switch (ppid) {
case -1:
continue;
case -2:
break;
}
ret = proch (pid, ppid, name, data);
GF_FREE (name);
if (ret)
break;
}
}
sys_closedir (d);
if (!de && errno) {
fprintf (stderr, "failed to traverse "PROC" (%s)\n",
strerror (errno));
ret = -1;
if (gf_string2int(de->d_name, &pid) != -1 && pid >= 0) {
ppid = pidinfo(pid, &name);
switch (ppid) {
case -1:
continue;
case -2:
break;
}
ret = proch(pid, ppid, name, data);
GF_FREE(name);
if (ret)
break;
}
}
sys_closedir(d);
if (!de && errno) {
fprintf(stderr, "failed to traverse " PROC " (%s)\n", strerror(errno));
ret = -1;
}
return ret;
return ret;
}

View File

@ -25,189 +25,186 @@ int done = 0;
int rpc_status;
struct rpc_clnt_procedure gf_attach_actors[GLUSTERD_BRICK_MAXVALUE] = {
[GLUSTERD_BRICK_NULL] = {"NULL", NULL },
[GLUSTERD_BRICK_OP] = {"BRICK_OP", NULL },
[GLUSTERD_BRICK_NULL] = {"NULL", NULL},
[GLUSTERD_BRICK_OP] = {"BRICK_OP", NULL},
};
struct rpc_clnt_program gf_attach_prog = {
.progname = "brick operations",
.prognum = GD_BRICK_PROGRAM,
.progver = GD_BRICK_VERSION,
.proctable = gf_attach_actors,
.numproc = GLUSTERD_BRICK_MAXVALUE,
.progname = "brick operations",
.prognum = GD_BRICK_PROGRAM,
.progver = GD_BRICK_VERSION,
.proctable = gf_attach_actors,
.numproc = GLUSTERD_BRICK_MAXVALUE,
};
int32_t
my_callback (struct rpc_req *req, struct iovec *iov, int count, void *frame)
my_callback(struct rpc_req *req, struct iovec *iov, int count, void *frame)
{
rpc_status = req->rpc_status;
done = 1;
return 0;
rpc_status = req->rpc_status;
done = 1;
return 0;
}
/* copied from gd_syncop_submit_request */
int
send_brick_req (xlator_t *this, struct rpc_clnt *rpc, char *path, int op)
send_brick_req(xlator_t *this, struct rpc_clnt *rpc, char *path, int op)
{
int ret = -1;
struct iobuf *iobuf = NULL;
struct iobref *iobref = NULL;
struct iovec iov = {0, };
ssize_t req_size = 0;
call_frame_t *frame = NULL;
gd1_mgmt_brick_op_req brick_req;
void *req = &brick_req;
int i;
int ret = -1;
struct iobuf *iobuf = NULL;
struct iobref *iobref = NULL;
struct iovec iov = {
0,
};
ssize_t req_size = 0;
call_frame_t *frame = NULL;
gd1_mgmt_brick_op_req brick_req;
void *req = &brick_req;
int i;
brick_req.op = op;
brick_req.name = path;
brick_req.input.input_val = NULL;
brick_req.input.input_len = 0;
brick_req.op = op;
brick_req.name = path;
brick_req.input.input_val = NULL;
brick_req.input.input_len = 0;
req_size = xdr_sizeof ((xdrproc_t)xdr_gd1_mgmt_brick_op_req, req);
iobuf = iobuf_get2 (rpc->ctx->iobuf_pool, req_size);
if (!iobuf)
goto out;
req_size = xdr_sizeof((xdrproc_t)xdr_gd1_mgmt_brick_op_req, req);
iobuf = iobuf_get2(rpc->ctx->iobuf_pool, req_size);
if (!iobuf)
goto out;
iobref = iobref_new ();
if (!iobref)
goto out;
iobref = iobref_new();
if (!iobref)
goto out;
frame = create_frame (this, this->ctx->pool);
if (!frame)
goto out;
frame = create_frame(this, this->ctx->pool);
if (!frame)
goto out;
iobref_add (iobref, iobuf);
iobref_add(iobref, iobuf);
iov.iov_base = iobuf->ptr;
iov.iov_len = iobuf_pagesize (iobuf);
iov.iov_base = iobuf->ptr;
iov.iov_len = iobuf_pagesize(iobuf);
/* Create the xdr payload */
ret = xdr_serialize_generic (iov, req,
(xdrproc_t)xdr_gd1_mgmt_brick_op_req);
if (ret == -1)
goto out;
/* Create the xdr payload */
ret = xdr_serialize_generic(iov, req, (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
if (ret == -1)
goto out;
iov.iov_len = ret;
iov.iov_len = ret;
for (i = 0; i < 60; ++i) {
if (rpc->conn.connected) {
break;
}
sleep (1);
for (i = 0; i < 60; ++i) {
if (rpc->conn.connected) {
break;
}
sleep(1);
}
/* Send the msg */
ret = rpc_clnt_submit (rpc, &gf_attach_prog, op,
my_callback, &iov, 1, NULL, 0, iobref, frame,
NULL, 0, NULL, 0, NULL);
if (!ret) {
for (i = 0; !done && (i < 120); ++i) {
sleep (1);
}
/* Send the msg */
ret = rpc_clnt_submit(rpc, &gf_attach_prog, op, my_callback, &iov, 1, NULL,
0, iobref, frame, NULL, 0, NULL, 0, NULL);
if (!ret) {
for (i = 0; !done && (i < 120); ++i) {
sleep(1);
}
}
out:
iobref_unref (iobref);
iobuf_unref (iobuf);
if (frame)
STACK_DESTROY (frame->root);
if (rpc_status != 0) {
fprintf (stderr, "got error %d on RPC\n", rpc_status);
return EXIT_FAILURE;
}
printf ("OK\n");
return EXIT_SUCCESS;
}
int
usage (char *prog)
{
fprintf (stderr, "Usage: %s uds_path volfile_path (to attach)\n",
prog);
fprintf (stderr, " %s -d uds_path brick_path (to detach)\n",
prog);
iobref_unref(iobref);
iobuf_unref(iobuf);
if (frame)
STACK_DESTROY(frame->root);
if (rpc_status != 0) {
fprintf(stderr, "got error %d on RPC\n", rpc_status);
return EXIT_FAILURE;
}
printf("OK\n");
return EXIT_SUCCESS;
}
int
main (int argc, char *argv[])
usage(char *prog)
{
glfs_t *fs;
struct rpc_clnt *rpc;
dict_t *options;
int ret;
int op = GLUSTERD_BRICK_ATTACH;
fprintf(stderr, "Usage: %s uds_path volfile_path (to attach)\n", prog);
fprintf(stderr, " %s -d uds_path brick_path (to detach)\n", prog);
for (;;) {
switch (getopt (argc, argv, "d")) {
case 'd':
op = GLUSTERD_BRICK_TERMINATE;
break;
case -1:
goto done_parsing;
default:
return usage (argv[0]);
}
}
done_parsing:
if (optind != (argc - 2)) {
return usage (argv[0]);
}
fs = glfs_new ("gf-attach");
if (!fs) {
fprintf (stderr, "glfs_new failed\n");
return EXIT_FAILURE;
}
(void) glfs_set_logging (fs, "/dev/stderr", 7);
/*
* This will actually fail because we haven't defined a volume, but
* it will do enough initialization to get us going.
*/
(void) glfs_init (fs);
options = dict_new();
if (!options) {
return EXIT_FAILURE;
}
ret = dict_set_str (options, "transport-type", "socket");
if (ret != 0) {
fprintf (stderr, "failed to set transport type\n");
return EXIT_FAILURE;
}
ret = dict_set_str (options, "transport.address-family", "unix");
if (ret != 0) {
fprintf (stderr, "failed to set address family\n");
return EXIT_FAILURE;
}
ret = dict_set_str (options, "transport.socket.connect-path",
argv[optind]);
if (ret != 0) {
fprintf (stderr, "failed to set connect path\n");
return EXIT_FAILURE;
}
rpc = rpc_clnt_new (options, fs->ctx->master, "gf-attach-rpc", 0);
if (!rpc) {
fprintf (stderr, "rpc_clnt_new failed\n");
return EXIT_FAILURE;
}
if (rpc_clnt_register_notify (rpc, NULL, NULL) != 0) {
fprintf (stderr, "rpc_clnt_register_notify failed\n");
return EXIT_FAILURE;
}
if (rpc_clnt_start(rpc) != 0) {
fprintf (stderr, "rpc_clnt_start failed\n");
return EXIT_FAILURE;
}
return send_brick_req (fs->ctx->master, rpc, argv[optind+1], op);
return EXIT_FAILURE;
}
int
main(int argc, char *argv[])
{
glfs_t *fs;
struct rpc_clnt *rpc;
dict_t *options;
int ret;
int op = GLUSTERD_BRICK_ATTACH;
for (;;) {
switch (getopt(argc, argv, "d")) {
case 'd':
op = GLUSTERD_BRICK_TERMINATE;
break;
case -1:
goto done_parsing;
default:
return usage(argv[0]);
}
}
done_parsing:
if (optind != (argc - 2)) {
return usage(argv[0]);
}
fs = glfs_new("gf-attach");
if (!fs) {
fprintf(stderr, "glfs_new failed\n");
return EXIT_FAILURE;
}
(void)glfs_set_logging(fs, "/dev/stderr", 7);
/*
* This will actually fail because we haven't defined a volume, but
* it will do enough initialization to get us going.
*/
(void)glfs_init(fs);
options = dict_new();
if (!options) {
return EXIT_FAILURE;
}
ret = dict_set_str(options, "transport-type", "socket");
if (ret != 0) {
fprintf(stderr, "failed to set transport type\n");
return EXIT_FAILURE;
}
ret = dict_set_str(options, "transport.address-family", "unix");
if (ret != 0) {
fprintf(stderr, "failed to set address family\n");
return EXIT_FAILURE;
}
ret = dict_set_str(options, "transport.socket.connect-path", argv[optind]);
if (ret != 0) {
fprintf(stderr, "failed to set connect path\n");
return EXIT_FAILURE;
}
rpc = rpc_clnt_new(options, fs->ctx->master, "gf-attach-rpc", 0);
if (!rpc) {
fprintf(stderr, "rpc_clnt_new failed\n");
return EXIT_FAILURE;
}
if (rpc_clnt_register_notify(rpc, NULL, NULL) != 0) {
fprintf(stderr, "rpc_clnt_register_notify failed\n");
return EXIT_FAILURE;
}
if (rpc_clnt_start(rpc) != 0) {
fprintf(stderr, "rpc_clnt_start failed\n");
return EXIT_FAILURE;
}
return send_brick_req(fs->ctx->master, rpc, argv[optind + 1], op);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -114,10 +114,14 @@ GF_ATOMIC_TYPE(SIZEOF_LONG, uintptr); /* gf_atomic_uintptr_t */
* builtin version depending on the size of the atomic structure. */
#define GF_ATOMIC_CHOOSE(_atomic, _op, _args...) \
((sizeof(_atomic) > sizeof(uint64_t)) \
? ({ GF_ATOMIC_MACRO(GF_ATOMIC_LOCK_, _op) \
(_atomic, ##_args); }) \
: ({ GF_ATOMIC_MACRO(GF_ATOMIC_BASE_, _op) \
(_atomic, ##_args); }))
? ({ \
GF_ATOMIC_MACRO(GF_ATOMIC_LOCK_, _op) \
(_atomic, ##_args); \
}) \
: ({ \
GF_ATOMIC_MACRO(GF_ATOMIC_BASE_, _op) \
(_atomic, ##_args); \
}))
/* Macros to implement the mutex-based atomics. */
#define GF_ATOMIC_OP_PREPARE(_atomic, _name) \

File diff suppressed because it is too large Load Diff

View File

@ -22,24 +22,23 @@
* data. Thus int32_t and uint32_t are sufficient
*/
uint32_t
gf_rsync_weak_checksum (unsigned char *buf, size_t len)
gf_rsync_weak_checksum(unsigned char *buf, size_t len)
{
return adler32 (0, buf, len);
return adler32(0, buf, len);
}
/*
* The "strong" checksum required for the rsync algorithm.
*/
void
gf_rsync_strong_checksum (unsigned char *data, size_t len,
unsigned char *sha256_md)
gf_rsync_strong_checksum(unsigned char *data, size_t len,
unsigned char *sha256_md)
{
SHA256((const unsigned char *)data, len, sha256_md);
SHA256((const unsigned char *)data, len, sha256_md);
}
void
gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5)
gf_rsync_md5_checksum(unsigned char *data, size_t len, unsigned char *md5)
{
MD5 (data, len, md5);
MD5(data, len, md5);
}

View File

@ -12,190 +12,182 @@
#include "libglusterfs-messages.h"
void
cb_destroy_data (circular_buffer_t *cb,
void (*destroy_buffer_data) (void *data))
cb_destroy_data(circular_buffer_t *cb, void (*destroy_buffer_data)(void *data))
{
if (destroy_buffer_data)
destroy_buffer_data (cb->data);
GF_FREE (cb->data);
return;
if (destroy_buffer_data)
destroy_buffer_data(cb->data);
GF_FREE(cb->data);
return;
}
/* hold lock while calling this function */
int
__cb_add_entry_buffer (buffer_t *buffer, void *item)
__cb_add_entry_buffer(buffer_t *buffer, void *item)
{
circular_buffer_t *ptr = NULL;
int ret = -1;
//DO we really need the assert here?
GF_ASSERT (buffer->used_len <= buffer->size_buffer);
circular_buffer_t *ptr = NULL;
int ret = -1;
// DO we really need the assert here?
GF_ASSERT(buffer->used_len <= buffer->size_buffer);
if (buffer->use_once == _gf_true &&
buffer->used_len == buffer->size_buffer) {
gf_msg ("circ-buff", GF_LOG_WARNING, 0, LG_MSG_BUFFER_ERROR,
"buffer %p is use once buffer", buffer);
return -1;
} else {
if (buffer->used_len == buffer->size_buffer) {
if (buffer->cb[buffer->w_index]) {
ptr = buffer->cb[buffer->w_index];
if (ptr->data) {
cb_destroy_data (ptr,
buffer->destroy_buffer_data);
ptr->data = NULL;
GF_FREE (ptr);
}
buffer->cb[buffer->w_index] = NULL;
ptr = NULL;
}
if (buffer->use_once == _gf_true &&
buffer->used_len == buffer->size_buffer) {
gf_msg("circ-buff", GF_LOG_WARNING, 0, LG_MSG_BUFFER_ERROR,
"buffer %p is use once buffer", buffer);
return -1;
} else {
if (buffer->used_len == buffer->size_buffer) {
if (buffer->cb[buffer->w_index]) {
ptr = buffer->cb[buffer->w_index];
if (ptr->data) {
cb_destroy_data(ptr, buffer->destroy_buffer_data);
ptr->data = NULL;
GF_FREE(ptr);
}
buffer->cb[buffer->w_index] =
GF_CALLOC (1, sizeof (circular_buffer_t),
gf_common_mt_circular_buffer_t);
if (!buffer->cb[buffer->w_index])
return -1;
buffer->cb[buffer->w_index]->data = item;
ret = gettimeofday (&buffer->cb[buffer->w_index]->tv, NULL);
if (ret == -1)
gf_msg_callingfn ("circ-buff", GF_LOG_WARNING, 0,
LG_MSG_GETTIMEOFDAY_FAILED,
"getting time of the day failed");
buffer->w_index++;
buffer->w_index %= buffer->size_buffer;
//used_buffer size cannot be greater than the total buffer size
if (buffer->used_len < buffer->size_buffer)
buffer->used_len++;
return buffer->w_index;
buffer->cb[buffer->w_index] = NULL;
ptr = NULL;
}
}
buffer->cb[buffer->w_index] = GF_CALLOC(1, sizeof(circular_buffer_t),
gf_common_mt_circular_buffer_t);
if (!buffer->cb[buffer->w_index])
return -1;
buffer->cb[buffer->w_index]->data = item;
ret = gettimeofday(&buffer->cb[buffer->w_index]->tv, NULL);
if (ret == -1)
gf_msg_callingfn("circ-buff", GF_LOG_WARNING, 0,
LG_MSG_GETTIMEOFDAY_FAILED,
"getting time of the day failed");
buffer->w_index++;
buffer->w_index %= buffer->size_buffer;
// used_buffer size cannot be greater than the total buffer size
if (buffer->used_len < buffer->size_buffer)
buffer->used_len++;
return buffer->w_index;
}
}
int
cb_add_entry_buffer (buffer_t *buffer, void *item)
cb_add_entry_buffer(buffer_t *buffer, void *item)
{
int write_index = -1;
int write_index = -1;
pthread_mutex_lock (&buffer->lock);
{
write_index = __cb_add_entry_buffer (buffer, item);
}
pthread_mutex_unlock (&buffer->lock);
pthread_mutex_lock(&buffer->lock);
{
write_index = __cb_add_entry_buffer(buffer, item);
}
pthread_mutex_unlock(&buffer->lock);
return write_index;
return write_index;
}
void
cb_buffer_show (buffer_t *buffer)
cb_buffer_show(buffer_t *buffer)
{
pthread_mutex_lock (&buffer->lock);
{
gf_msg_debug ("circ-buff", 0, "w_index: %d, size: %"
GF_PRI_SIZET" used_buffer: %d", buffer->w_index,
buffer->size_buffer, buffer->used_len);
}
pthread_mutex_unlock (&buffer->lock);
pthread_mutex_lock(&buffer->lock);
{
gf_msg_debug("circ-buff", 0,
"w_index: %d, size: %" GF_PRI_SIZET " used_buffer: %d",
buffer->w_index, buffer->size_buffer, buffer->used_len);
}
pthread_mutex_unlock(&buffer->lock);
}
void
cb_buffer_dump (buffer_t *buffer, void *data,
int (fn) (circular_buffer_t *buffer, void *data))
cb_buffer_dump(buffer_t *buffer, void *data,
int(fn)(circular_buffer_t *buffer, void *data))
{
int index = 0;
circular_buffer_t *entry = NULL;
int entries = 0;
int ul = 0;
int w_ind = 0;
int size_buff = 0;
int i = 0;
int index = 0;
circular_buffer_t *entry = NULL;
int entries = 0;
int ul = 0;
int w_ind = 0;
int size_buff = 0;
int i = 0;
ul = buffer->used_len;
w_ind = buffer->w_index;
size_buff = buffer->size_buffer;
ul = buffer->used_len;
w_ind = buffer->w_index;
size_buff = buffer->size_buffer;
pthread_mutex_lock (&buffer->lock);
{
if (buffer->use_once == _gf_false) {
index = (size_buff + (w_ind - ul))%size_buff;
for (entries = 0; entries < buffer->used_len;
entries++) {
entry = buffer->cb[index];
if (entry)
fn (entry, data);
else
gf_msg_callingfn ("circ-buff",
GF_LOG_WARNING, 0,
LG_MSG_NULL_PTR,
"Null entry in "
"circular buffer at "
"index %d.", index);
pthread_mutex_lock(&buffer->lock);
{
if (buffer->use_once == _gf_false) {
index = (size_buff + (w_ind - ul)) % size_buff;
for (entries = 0; entries < buffer->used_len; entries++) {
entry = buffer->cb[index];
if (entry)
fn(entry, data);
else
gf_msg_callingfn("circ-buff", GF_LOG_WARNING, 0,
LG_MSG_NULL_PTR,
"Null entry in "
"circular buffer at "
"index %d.",
index);
index++;
index %= buffer->size_buffer;
}
} else {
for (i = 0; i < buffer->used_len ; i++) {
entry = buffer->cb[i];
fn (entry, data);
}
}
index++;
index %= buffer->size_buffer;
}
} else {
for (i = 0; i < buffer->used_len; i++) {
entry = buffer->cb[i];
fn(entry, data);
}
}
pthread_mutex_unlock (&buffer->lock);
}
pthread_mutex_unlock(&buffer->lock);
}
buffer_t *
cb_buffer_new (size_t buffer_size, gf_boolean_t use_once,
void (*destroy_buffer_data) (void *data))
cb_buffer_new(size_t buffer_size, gf_boolean_t use_once,
void (*destroy_buffer_data)(void *data))
{
buffer_t *buffer = NULL;
buffer_t *buffer = NULL;
buffer = GF_CALLOC (1, sizeof (*buffer), gf_common_mt_buffer_t);
if (!buffer) {
goto out;
}
buffer = GF_CALLOC(1, sizeof(*buffer), gf_common_mt_buffer_t);
if (!buffer) {
goto out;
}
buffer->cb = GF_CALLOC (buffer_size,
sizeof (circular_buffer_t *),
gf_common_mt_circular_buffer_t);
if (!buffer->cb) {
GF_FREE (buffer);
buffer = NULL;
goto out;
}
buffer->cb = GF_CALLOC(buffer_size, sizeof(circular_buffer_t *),
gf_common_mt_circular_buffer_t);
if (!buffer->cb) {
GF_FREE(buffer);
buffer = NULL;
goto out;
}
buffer->w_index = 0;
buffer->size_buffer = buffer_size;
buffer->use_once = use_once;
buffer->used_len = 0;
buffer->destroy_buffer_data = destroy_buffer_data;
pthread_mutex_init (&buffer->lock, NULL);
buffer->w_index = 0;
buffer->size_buffer = buffer_size;
buffer->use_once = use_once;
buffer->used_len = 0;
buffer->destroy_buffer_data = destroy_buffer_data;
pthread_mutex_init(&buffer->lock, NULL);
out:
return buffer;
return buffer;
}
void
cb_buffer_destroy (buffer_t *buffer)
cb_buffer_destroy(buffer_t *buffer)
{
int i = 0;
circular_buffer_t *ptr = NULL;
if (buffer) {
if (buffer->cb) {
for (i = 0; i < buffer->used_len ; i++) {
ptr = buffer->cb[i];
if (ptr->data) {
cb_destroy_data (ptr,
buffer->destroy_buffer_data);
ptr->data = NULL;
GF_FREE (ptr);
}
}
GF_FREE (buffer->cb);
int i = 0;
circular_buffer_t *ptr = NULL;
if (buffer) {
if (buffer->cb) {
for (i = 0; i < buffer->used_len; i++) {
ptr = buffer->cb[i];
if (ptr->data) {
cb_destroy_data(ptr, buffer->destroy_buffer_data);
ptr->data = NULL;
GF_FREE(ptr);
}
pthread_mutex_destroy (&buffer->lock);
GF_FREE (buffer);
}
GF_FREE(buffer->cb);
}
pthread_mutex_destroy(&buffer->lock);
GF_FREE(buffer);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,125 +14,125 @@
#include "dict.h"
void
compound_args_cleanup (compound_args_t *args)
compound_args_cleanup(compound_args_t *args)
{
int i;
int i;
if (!args)
return;
if (!args)
return;
if (args->xdata)
dict_unref (args->xdata);
if (args->xdata)
dict_unref(args->xdata);
if (args->req_list) {
for (i = 0; i < args->fop_length; i++) {
args_wipe (&args->req_list[i]);
}
if (args->req_list) {
for (i = 0; i < args->fop_length; i++) {
args_wipe(&args->req_list[i]);
}
}
GF_FREE (args->enum_list);
GF_FREE (args->req_list);
GF_FREE (args);
GF_FREE(args->enum_list);
GF_FREE(args->req_list);
GF_FREE(args);
}
void
compound_args_cbk_cleanup (compound_args_cbk_t *args_cbk)
compound_args_cbk_cleanup(compound_args_cbk_t *args_cbk)
{
int i;
int i;
if (!args_cbk)
return;
if (!args_cbk)
return;
if (args_cbk->xdata)
dict_unref (args_cbk->xdata);
if (args_cbk->xdata)
dict_unref(args_cbk->xdata);
if (args_cbk->rsp_list) {
for (i = 0; i < args_cbk->fop_length; i++) {
args_cbk_wipe (&args_cbk->rsp_list[i]);
}
if (args_cbk->rsp_list) {
for (i = 0; i < args_cbk->fop_length; i++) {
args_cbk_wipe(&args_cbk->rsp_list[i]);
}
}
GF_FREE (args_cbk->rsp_list);
GF_FREE (args_cbk->enum_list);
GF_FREE (args_cbk);
GF_FREE(args_cbk->rsp_list);
GF_FREE(args_cbk->enum_list);
GF_FREE(args_cbk);
}
compound_args_cbk_t*
compound_args_cbk_alloc (int length, dict_t *xdata)
compound_args_cbk_t *
compound_args_cbk_alloc(int length, dict_t *xdata)
{
int i = 0;
compound_args_cbk_t *args_cbk = NULL;
int i = 0;
compound_args_cbk_t *args_cbk = NULL;
args_cbk = GF_CALLOC (1, sizeof (*args_cbk), gf_mt_compound_rsp_t);
if (!args_cbk)
return NULL;
args_cbk->fop_length = length;
args_cbk->rsp_list = GF_CALLOC (length, sizeof (*args_cbk->rsp_list),
gf_mt_default_args_cbk_t);
if (!args_cbk->rsp_list)
goto out;
for (i = 0; i < length; i++) {
args_cbk_init (&args_cbk->rsp_list[i]);
}
args_cbk->enum_list = GF_CALLOC (length, sizeof (*args_cbk->enum_list),
gf_common_mt_int);
if (!args_cbk->enum_list)
goto out;
if (xdata) {
args_cbk->xdata = dict_copy_with_ref (xdata, NULL);
if (!args_cbk->xdata)
goto out;
}
return args_cbk;
out:
compound_args_cbk_cleanup (args_cbk);
args_cbk = GF_CALLOC(1, sizeof(*args_cbk), gf_mt_compound_rsp_t);
if (!args_cbk)
return NULL;
}
compound_args_t*
compound_fop_alloc (int length, glusterfs_compound_fop_t fop, dict_t *xdata)
{
compound_args_t *args = NULL;
args_cbk->fop_length = length;
args = GF_CALLOC (1, sizeof (*args), gf_mt_compound_req_t);
args_cbk->rsp_list = GF_CALLOC(length, sizeof(*args_cbk->rsp_list),
gf_mt_default_args_cbk_t);
if (!args_cbk->rsp_list)
goto out;
if (!args)
return NULL;
for (i = 0; i < length; i++) {
args_cbk_init(&args_cbk->rsp_list[i]);
}
/* fop_enum can be used by xlators to see which fops are
* included as part of compound fop. This will help in checking
* for compatibility or support without going through the entire
* fop list packed.
*/
args->fop_enum = fop;
args->fop_length = length;
args_cbk->enum_list = GF_CALLOC(length, sizeof(*args_cbk->enum_list),
gf_common_mt_int);
if (!args_cbk->enum_list)
goto out;
args->enum_list = GF_CALLOC (length, sizeof (*args->enum_list),
gf_common_mt_int);
if (xdata) {
args_cbk->xdata = dict_copy_with_ref(xdata, NULL);
if (!args_cbk->xdata)
goto out;
}
if (!args->enum_list)
goto out;
args->req_list = GF_CALLOC (length, sizeof (*args->req_list),
gf_mt_default_args_t);
if (!args->req_list)
goto out;
if (xdata) {
args->xdata = dict_copy_with_ref (xdata, args->xdata);
if (!args->xdata)
goto out;
}
return args;
return args_cbk;
out:
compound_args_cleanup (args);
return NULL;
compound_args_cbk_cleanup(args_cbk);
return NULL;
}
compound_args_t *
compound_fop_alloc(int length, glusterfs_compound_fop_t fop, dict_t *xdata)
{
compound_args_t *args = NULL;
args = GF_CALLOC(1, sizeof(*args), gf_mt_compound_req_t);
if (!args)
return NULL;
/* fop_enum can be used by xlators to see which fops are
* included as part of compound fop. This will help in checking
* for compatibility or support without going through the entire
* fop list packed.
*/
args->fop_enum = fop;
args->fop_length = length;
args->enum_list = GF_CALLOC(length, sizeof(*args->enum_list),
gf_common_mt_int);
if (!args->enum_list)
goto out;
args->req_list = GF_CALLOC(length, sizeof(*args->req_list),
gf_mt_default_args_t);
if (!args->req_list)
goto out;
if (xdata) {
args->xdata = dict_copy_with_ref(xdata, args->xdata);
if (!args->xdata)
goto out;
}
return args;
out:
compound_args_cleanup(args);
return NULL;
}

View File

@ -15,82 +15,82 @@
#include "timer-wheel.h"
glusterfs_ctx_t *
glusterfs_ctx_new ()
glusterfs_ctx_new()
{
int ret = 0;
glusterfs_ctx_t *ctx = NULL;
int ret = 0;
glusterfs_ctx_t *ctx = NULL;
/* no GF_CALLOC here, gf_acct_mem_set_enable is not
yet decided at this point */
ctx = calloc (1, sizeof (*ctx));
if (!ctx) {
ret = -1;
goto out;
}
/* no GF_CALLOC here, gf_acct_mem_set_enable is not
yet decided at this point */
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
ret = -1;
goto out;
}
ctx->mem_acct_enable = gf_global_mem_acct_enable_get();
ctx->mem_acct_enable = gf_global_mem_acct_enable_get();
INIT_LIST_HEAD (&ctx->graphs);
INIT_LIST_HEAD (&ctx->mempool_list);
INIT_LIST_HEAD (&ctx->volfile_list);
INIT_LIST_HEAD(&ctx->graphs);
INIT_LIST_HEAD(&ctx->mempool_list);
INIT_LIST_HEAD(&ctx->volfile_list);
ctx->daemon_pipe[0] = -1;
ctx->daemon_pipe[1] = -1;
ctx->daemon_pipe[0] = -1;
ctx->daemon_pipe[1] = -1;
ctx->log.loglevel = DEFAULT_LOG_LEVEL;
ctx->log.loglevel = DEFAULT_LOG_LEVEL;
#ifdef RUN_WITH_VALGRIND
ctx->cmd_args.valgrind = _gf_true;
ctx->cmd_args.valgrind = _gf_true;
#endif
/* lock is never destroyed! */
ret = LOCK_INIT (&ctx->lock);
if (ret) {
free (ctx);
ctx = NULL;
goto out;
}
/* lock is never destroyed! */
ret = LOCK_INIT(&ctx->lock);
if (ret) {
free(ctx);
ctx = NULL;
goto out;
}
GF_ATOMIC_INIT (ctx->stats.max_dict_pairs, 0);
GF_ATOMIC_INIT (ctx->stats.total_pairs_used, 0);
GF_ATOMIC_INIT (ctx->stats.total_dicts_used, 0);
GF_ATOMIC_INIT(ctx->stats.max_dict_pairs, 0);
GF_ATOMIC_INIT(ctx->stats.total_pairs_used, 0);
GF_ATOMIC_INIT(ctx->stats.total_dicts_used, 0);
out:
return ctx;
return ctx;
}
static void
glusterfs_ctx_tw_destroy (struct gf_ctx_tw *ctx_tw)
glusterfs_ctx_tw_destroy(struct gf_ctx_tw *ctx_tw)
{
if (ctx_tw->timer_wheel)
gf_tw_cleanup_timers (ctx_tw->timer_wheel);
if (ctx_tw->timer_wheel)
gf_tw_cleanup_timers(ctx_tw->timer_wheel);
GF_FREE (ctx_tw);
GF_FREE(ctx_tw);
}
struct tvec_base*
glusterfs_ctx_tw_get (glusterfs_ctx_t *ctx)
struct tvec_base *
glusterfs_ctx_tw_get(glusterfs_ctx_t *ctx)
{
struct gf_ctx_tw *ctx_tw = NULL;
struct gf_ctx_tw *ctx_tw = NULL;
LOCK (&ctx->lock);
{
if (ctx->tw) {
ctx_tw = GF_REF_GET (ctx->tw);
} else {
ctx_tw = GF_CALLOC (1, sizeof (struct gf_ctx_tw),
gf_common_mt_tw_ctx);
ctx_tw->timer_wheel = gf_tw_init_timers();
GF_REF_INIT (ctx_tw, glusterfs_ctx_tw_destroy);
ctx->tw = ctx_tw;
}
LOCK(&ctx->lock);
{
if (ctx->tw) {
ctx_tw = GF_REF_GET(ctx->tw);
} else {
ctx_tw = GF_CALLOC(1, sizeof(struct gf_ctx_tw),
gf_common_mt_tw_ctx);
ctx_tw->timer_wheel = gf_tw_init_timers();
GF_REF_INIT(ctx_tw, glusterfs_ctx_tw_destroy);
ctx->tw = ctx_tw;
}
UNLOCK (&ctx->lock);
}
UNLOCK(&ctx->lock);
return ctx_tw->timer_wheel;
return ctx_tw->timer_wheel;
}
void
glusterfs_ctx_tw_put (glusterfs_ctx_t *ctx)
glusterfs_ctx_tw_put(glusterfs_ctx_t *ctx)
{
GF_REF_PUT (ctx->tw);
GF_REF_PUT(ctx->tw);
}

View File

@ -14,53 +14,53 @@
#include "daemon.h"
int
os_daemon_return (int nochdir, int noclose)
os_daemon_return(int nochdir, int noclose)
{
pid_t pid = -1;
int ret = -1;
FILE *ptr = NULL;
pid_t pid = -1;
int ret = -1;
FILE *ptr = NULL;
ret = fork();
if (ret)
return ret;
ret = fork();
if (ret)
return ret;
pid = setsid();
pid = setsid();
if (pid == -1) {
ret = -1;
goto out;
}
if (pid == -1) {
ret = -1;
goto out;
}
if (!nochdir)
ret = chdir("/");
if (!nochdir)
ret = chdir("/");
if (!noclose) {
ptr = freopen (DEVNULLPATH, "r", stdin);
if (!ptr)
goto out;
if (!noclose) {
ptr = freopen(DEVNULLPATH, "r", stdin);
if (!ptr)
goto out;
ptr = freopen (DEVNULLPATH, "w", stdout);
if (!ptr)
goto out;
ptr = freopen(DEVNULLPATH, "w", stdout);
if (!ptr)
goto out;
ptr = freopen (DEVNULLPATH, "w", stderr);
if (!ptr)
goto out;
}
ptr = freopen(DEVNULLPATH, "w", stderr);
if (!ptr)
goto out;
}
ret = 0;
ret = 0;
out:
return ret;
return ret;
}
int
os_daemon (int nochdir, int noclose)
os_daemon(int nochdir, int noclose)
{
int ret = -1;
int ret = -1;
ret = os_daemon_return (nochdir, noclose);
if (ret <= 0)
return ret;
ret = os_daemon_return(nochdir, noclose);
if (ret <= 0)
return ret;
_exit (0);
_exit(0);
}

File diff suppressed because it is too large Load Diff

View File

@ -31,206 +31,191 @@
#pragma generate
struct xlator_fops _default_fops = {
.create = default_create,
.open = default_open,
.stat = default_stat,
.readlink = default_readlink,
.mknod = default_mknod,
.mkdir = default_mkdir,
.unlink = default_unlink,
.rmdir = default_rmdir,
.symlink = default_symlink,
.rename = default_rename,
.link = default_link,
.truncate = default_truncate,
.readv = default_readv,
.writev = default_writev,
.statfs = default_statfs,
.flush = default_flush,
.fsync = default_fsync,
.setxattr = default_setxattr,
.getxattr = default_getxattr,
.fsetxattr = default_fsetxattr,
.fgetxattr = default_fgetxattr,
.removexattr = default_removexattr,
.fremovexattr = default_fremovexattr,
.opendir = default_opendir,
.readdir = default_readdir,
.readdirp = default_readdirp,
.fsyncdir = default_fsyncdir,
.access = default_access,
.ftruncate = default_ftruncate,
.fstat = default_fstat,
.lk = default_lk,
.inodelk = default_inodelk,
.finodelk = default_finodelk,
.entrylk = default_entrylk,
.fentrylk = default_fentrylk,
.lookup = default_lookup,
.rchecksum = default_rchecksum,
.xattrop = default_xattrop,
.fxattrop = default_fxattrop,
.setattr = default_setattr,
.fsetattr = default_fsetattr,
.fallocate = default_fallocate,
.discard = default_discard,
.zerofill = default_zerofill,
.ipc = default_ipc,
.seek = default_seek,
.create = default_create,
.open = default_open,
.stat = default_stat,
.readlink = default_readlink,
.mknod = default_mknod,
.mkdir = default_mkdir,
.unlink = default_unlink,
.rmdir = default_rmdir,
.symlink = default_symlink,
.rename = default_rename,
.link = default_link,
.truncate = default_truncate,
.readv = default_readv,
.writev = default_writev,
.statfs = default_statfs,
.flush = default_flush,
.fsync = default_fsync,
.setxattr = default_setxattr,
.getxattr = default_getxattr,
.fsetxattr = default_fsetxattr,
.fgetxattr = default_fgetxattr,
.removexattr = default_removexattr,
.fremovexattr = default_fremovexattr,
.opendir = default_opendir,
.readdir = default_readdir,
.readdirp = default_readdirp,
.fsyncdir = default_fsyncdir,
.access = default_access,
.ftruncate = default_ftruncate,
.fstat = default_fstat,
.lk = default_lk,
.inodelk = default_inodelk,
.finodelk = default_finodelk,
.entrylk = default_entrylk,
.fentrylk = default_fentrylk,
.lookup = default_lookup,
.rchecksum = default_rchecksum,
.xattrop = default_xattrop,
.fxattrop = default_fxattrop,
.setattr = default_setattr,
.fsetattr = default_fsetattr,
.fallocate = default_fallocate,
.discard = default_discard,
.zerofill = default_zerofill,
.ipc = default_ipc,
.seek = default_seek,
.getspec = default_getspec,
.getactivelk = default_getactivelk,
.setactivelk = default_setactivelk,
.put = default_put,
.icreate = default_icreate,
.namelink = default_namelink,
.getspec = default_getspec,
.getactivelk = default_getactivelk,
.setactivelk = default_setactivelk,
.put = default_put,
.icreate = default_icreate,
.namelink = default_namelink,
};
struct xlator_fops *default_fops = &_default_fops;
/*
* Remaining functions don't follow the fop calling conventions, so they're
* not generated.
*/
int32_t
default_forget (xlator_t *this, inode_t *inode)
default_forget(xlator_t *this, inode_t *inode)
{
gf_log_callingfn (this->name, GF_LOG_DEBUG, "xlator does not "
"implement forget_cbk");
return 0;
}
int32_t
default_releasedir (xlator_t *this, fd_t *fd)
{
gf_log_callingfn (this->name, GF_LOG_DEBUG, "xlator does not "
"implement releasedir_cbk");
return 0;
gf_log_callingfn(this->name, GF_LOG_DEBUG,
"xlator does not "
"implement forget_cbk");
return 0;
}
int32_t
default_release (xlator_t *this, fd_t *fd)
default_releasedir(xlator_t *this, fd_t *fd)
{
gf_log_callingfn (this->name, GF_LOG_DEBUG, "xlator does not "
"implement release_cbk");
return 0;
gf_log_callingfn(this->name, GF_LOG_DEBUG,
"xlator does not "
"implement releasedir_cbk");
return 0;
}
int32_t
default_release(xlator_t *this, fd_t *fd)
{
gf_log_callingfn(this->name, GF_LOG_DEBUG,
"xlator does not "
"implement release_cbk");
return 0;
}
/* notify */
int
default_notify (xlator_t *this, int32_t event, void *data, ...)
default_notify(xlator_t *this, int32_t event, void *data, ...)
{
GF_UNUSED int ret = 0;
switch (event) {
GF_UNUSED int ret = 0;
switch (event) {
case GF_EVENT_PARENT_UP:
case GF_EVENT_PARENT_DOWN:
{
xlator_list_t *list = this->children;
case GF_EVENT_PARENT_DOWN: {
xlator_list_t *list = this->children;
while (list) {
xlator_notify (list->xlator, event, this);
list = list->next;
}
}
break;
while (list) {
xlator_notify(list->xlator, event, this);
list = list->next;
}
} break;
case GF_EVENT_CHILD_CONNECTING:
case GF_EVENT_CHILD_DOWN:
case GF_EVENT_CHILD_UP:
case GF_EVENT_AUTH_FAILED:
{
xlator_list_t *parent = this->parents;
case GF_EVENT_AUTH_FAILED: {
xlator_list_t *parent = this->parents;
/*
* Handle case of CHILD_* & AUTH_FAILED event specially, send
* it to fuse.
*/
if (!parent && this->ctx && this->ctx->master) {
xlator_notify (this->ctx->master, event, this->graph,
NULL);
}
/*
* Handle case of CHILD_* & AUTH_FAILED event specially, send
* it to fuse.
*/
if (!parent && this->ctx && this->ctx->master) {
xlator_notify(this->ctx->master, event, this->graph, NULL);
}
while (parent) {
if (parent->xlator->init_succeeded)
xlator_notify (parent->xlator, event,
this, NULL);
parent = parent->next;
}
while (parent) {
if (parent->xlator->init_succeeded)
xlator_notify(parent->xlator, event, this, NULL);
parent = parent->next;
}
} break;
case GF_EVENT_UPCALL: {
xlator_list_t *parent = this->parents;
if (!parent && this->ctx && this->ctx->master)
xlator_notify(this->ctx->master, event, data, NULL);
while (parent) {
if (parent->xlator->init_succeeded)
xlator_notify(parent->xlator, event, data, NULL);
parent = parent->next;
}
} break;
case GF_EVENT_CHILD_PING: {
xlator_list_t *parent = this->parents;
while (parent) {
if (parent->xlator->init_succeeded)
XLATOR_NOTIFY(ret, parent->xlator, event, this, data);
parent = parent->next;
}
} break;
case GF_EVENT_CLEANUP: {
xlator_list_t *list = this->children;
while (list) {
xlator_notify(list->xlator, event, this);
list = list->next;
}
} break;
default: {
xlator_list_t *parent = this->parents;
while (parent) {
if (parent->xlator->init_succeeded)
xlator_notify(parent->xlator, event, this, NULL);
parent = parent->next;
}
}
break;
case GF_EVENT_UPCALL:
{
xlator_list_t *parent = this->parents;
/*
* Apparently our picky-about-everything else coding standard allows
* adjacent same-indendation-level close braces. Clearly it has
* nothing to do with readability.
*/
}
if (!parent && this->ctx && this->ctx->master)
xlator_notify (this->ctx->master, event, data, NULL);
while (parent) {
if (parent->xlator->init_succeeded)
xlator_notify (parent->xlator, event,
data, NULL);
parent = parent->next;
}
}
break;
case GF_EVENT_CHILD_PING:
{
xlator_list_t *parent = this->parents;
while (parent) {
if (parent->xlator->init_succeeded)
XLATOR_NOTIFY (ret, parent->xlator, event,
this, data);
parent = parent->next;
}
}
break;
case GF_EVENT_CLEANUP:
{
xlator_list_t *list = this->children;
while (list) {
xlator_notify (list->xlator, event, this);
list = list->next;
}
}
break;
default:
{
xlator_list_t *parent = this->parents;
while (parent) {
if (parent->xlator->init_succeeded)
xlator_notify (parent->xlator, event,
this, NULL);
parent = parent->next;
}
}
/*
* Apparently our picky-about-everything else coding standard allows
* adjacent same-indendation-level close braces. Clearly it has
* nothing to do with readability.
*/
}
return 0;
return 0;
}
int32_t
default_mem_acct_init (xlator_t *this)
default_mem_acct_init(xlator_t *this)
{
int ret = -1;
int ret = -1;
ret = xlator_mem_acct_init (this, gf_common_mt_end);
ret = xlator_mem_acct_init(this, gf_common_mt_end);
return ret;
return ret;
}
void
default_fini (xlator_t *this)
default_fini(xlator_t *this)
{
if (this && this->private)
GF_FREE (this->private);
if (this && this->private)
GF_FREE(this->private);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,72 +12,71 @@
#include "libglusterfs-messages.h"
eh_t *
eh_new (size_t buffer_size, gf_boolean_t use_buffer_once,
void (*destroy_buffer_data) (void *data))
eh_new(size_t buffer_size, gf_boolean_t use_buffer_once,
void (*destroy_buffer_data)(void *data))
{
eh_t *history = NULL;
buffer_t *buffer = NULL;
eh_t *history = NULL;
buffer_t *buffer = NULL;
history = GF_CALLOC (1, sizeof (eh_t), gf_common_mt_eh_t);
if (!history) {
goto out;
}
history = GF_CALLOC(1, sizeof(eh_t), gf_common_mt_eh_t);
if (!history) {
goto out;
}
buffer = cb_buffer_new (buffer_size, use_buffer_once,
destroy_buffer_data);
if (!buffer) {
GF_FREE (history);
history = NULL;
goto out;
}
buffer = cb_buffer_new(buffer_size, use_buffer_once, destroy_buffer_data);
if (!buffer) {
GF_FREE(history);
history = NULL;
goto out;
}
history->buffer = buffer;
history->buffer = buffer;
pthread_mutex_init (&history->lock, NULL);
pthread_mutex_init(&history->lock, NULL);
out:
return history;
return history;
}
void
eh_dump (eh_t *history, void *data,
int (dump_fn) (circular_buffer_t *buffer, void *data))
eh_dump(eh_t *history, void *data,
int(dump_fn)(circular_buffer_t *buffer, void *data))
{
if (!history) {
gf_msg_debug ("event-history", 0, "history is NULL");
goto out;
}
if (!history) {
gf_msg_debug("event-history", 0, "history is NULL");
goto out;
}
cb_buffer_dump (history->buffer, data, dump_fn);
cb_buffer_dump(history->buffer, data, dump_fn);
out:
return;
return;
}
int
eh_save_history (eh_t *history, void *data)
eh_save_history(eh_t *history, void *data)
{
int ret = -1;
int ret = -1;
ret = cb_add_entry_buffer (history->buffer, data);
ret = cb_add_entry_buffer(history->buffer, data);
return ret;
return ret;
}
int
eh_destroy (eh_t *history)
eh_destroy(eh_t *history)
{
if (!history) {
gf_msg ("event-history", GF_LOG_INFO, 0, LG_MSG_INVALID_ARG,
"history for the xlator is NULL");
return -1;
}
if (!history) {
gf_msg("event-history", GF_LOG_INFO, 0, LG_MSG_INVALID_ARG,
"history for the xlator is NULL");
return -1;
}
cb_buffer_destroy (history->buffer);
history->buffer = NULL;
cb_buffer_destroy(history->buffer);
history->buffer = NULL;
pthread_mutex_destroy (&history->lock);
pthread_mutex_destroy(&history->lock);
GF_FREE (history);
GF_FREE(history);
return 0;
return 0;
}

View File

@ -23,490 +23,469 @@
#include "syscall.h"
#include "libglusterfs-messages.h"
struct event_slot_poll {
int fd;
int events;
void *data;
event_handler_t handler;
int fd;
int events;
void *data;
event_handler_t handler;
};
static int
event_register_poll(struct event_pool *event_pool, int fd,
event_handler_t handler, void *data, int poll_in,
int poll_out);
static int
event_register_poll (struct event_pool *event_pool, int fd,
event_handler_t handler,
void *data, int poll_in, int poll_out);
static int
__flush_fd (int fd, int idx, int gen, void *data,
int poll_in, int poll_out, int poll_err)
__flush_fd(int fd, int idx, int gen, void *data, int poll_in, int poll_out,
int poll_err)
{
char buf[64];
int ret = -1;
if (!poll_in)
return ret;
do {
ret = sys_read (fd, buf, 64);
if (ret == -1 && errno != EAGAIN) {
gf_msg ("poll", GF_LOG_ERROR, errno,
LG_MSG_FILE_OP_FAILED, "read on %d returned "
"error", fd);
}
} while (ret == 64);
char buf[64];
int ret = -1;
if (!poll_in)
return ret;
do {
ret = sys_read(fd, buf, 64);
if (ret == -1 && errno != EAGAIN) {
gf_msg("poll", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
"read on %d returned "
"error",
fd);
}
} while (ret == 64);
return ret;
}
static int
__event_getindex (struct event_pool *event_pool, int fd, int idx)
__event_getindex(struct event_pool *event_pool, int fd, int idx)
{
int ret = -1;
int i = 0;
int ret = -1;
int i = 0;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
GF_VALIDATE_OR_GOTO("event", event_pool, out);
/* lookup in used space based on index provided */
if (idx > -1 && idx < event_pool->used) {
if (event_pool->reg[idx].fd == fd) {
ret = idx;
goto out;
}
/* lookup in used space based on index provided */
if (idx > -1 && idx < event_pool->used) {
if (event_pool->reg[idx].fd == fd) {
ret = idx;
goto out;
}
}
/* search in used space, if lookup fails */
for (i = 0; i < event_pool->used; i++) {
if (event_pool->reg[i].fd == fd) {
ret = i;
break;
}
/* search in used space, if lookup fails */
for (i = 0; i < event_pool->used; i++) {
if (event_pool->reg[i].fd == fd) {
ret = i;
break;
}
}
out:
return ret;
return ret;
}
static struct event_pool *
event_pool_new_poll (int count, int eventthreadcount)
event_pool_new_poll(int count, int eventthreadcount)
{
struct event_pool *event_pool = NULL;
int ret = -1;
struct event_pool *event_pool = NULL;
int ret = -1;
event_pool = GF_CALLOC (1, sizeof (*event_pool),
gf_common_mt_event_pool);
event_pool = GF_CALLOC(1, sizeof(*event_pool), gf_common_mt_event_pool);
if (!event_pool)
return NULL;
if (!event_pool)
return NULL;
event_pool->count = count;
event_pool->reg = GF_CALLOC (event_pool->count,
sizeof (*event_pool->reg),
gf_common_mt_reg);
event_pool->count = count;
event_pool->reg = GF_CALLOC(event_pool->count, sizeof(*event_pool->reg),
gf_common_mt_reg);
if (!event_pool->reg) {
GF_FREE (event_pool);
return NULL;
}
if (!event_pool->reg) {
GF_FREE(event_pool);
return NULL;
}
pthread_mutex_init (&event_pool->mutex, NULL);
pthread_mutex_init(&event_pool->mutex, NULL);
ret = pipe (event_pool->breaker);
ret = pipe(event_pool->breaker);
if (ret == -1) {
gf_msg ("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED,
"pipe creation failed");
GF_FREE (event_pool->reg);
GF_FREE (event_pool);
return NULL;
}
if (ret == -1) {
gf_msg("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED,
"pipe creation failed");
GF_FREE(event_pool->reg);
GF_FREE(event_pool);
return NULL;
}
ret = fcntl (event_pool->breaker[0], F_SETFL, O_NONBLOCK);
if (ret == -1) {
gf_msg ("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED,
"could not set pipe to non blocking mode");
sys_close (event_pool->breaker[0]);
sys_close (event_pool->breaker[1]);
event_pool->breaker[0] = event_pool->breaker[1] = -1;
ret = fcntl(event_pool->breaker[0], F_SETFL, O_NONBLOCK);
if (ret == -1) {
gf_msg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED,
"could not set pipe to non blocking mode");
sys_close(event_pool->breaker[0]);
sys_close(event_pool->breaker[1]);
event_pool->breaker[0] = event_pool->breaker[1] = -1;
GF_FREE (event_pool->reg);
GF_FREE (event_pool);
return NULL;
}
GF_FREE(event_pool->reg);
GF_FREE(event_pool);
return NULL;
}
ret = fcntl (event_pool->breaker[1], F_SETFL, O_NONBLOCK);
if (ret == -1) {
gf_msg ("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED,
"could not set pipe to non blocking mode");
ret = fcntl(event_pool->breaker[1], F_SETFL, O_NONBLOCK);
if (ret == -1) {
gf_msg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED,
"could not set pipe to non blocking mode");
sys_close (event_pool->breaker[0]);
sys_close (event_pool->breaker[1]);
event_pool->breaker[0] = event_pool->breaker[1] = -1;
sys_close(event_pool->breaker[0]);
sys_close(event_pool->breaker[1]);
event_pool->breaker[0] = event_pool->breaker[1] = -1;
GF_FREE (event_pool->reg);
GF_FREE (event_pool);
return NULL;
}
GF_FREE(event_pool->reg);
GF_FREE(event_pool);
return NULL;
}
ret = event_register_poll (event_pool, event_pool->breaker[0],
__flush_fd, NULL, 1, 0);
if (ret == -1) {
gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_REGISTER_PIPE_FAILED,
"could not register pipe fd with poll event loop");
sys_close (event_pool->breaker[0]);
sys_close (event_pool->breaker[1]);
event_pool->breaker[0] = event_pool->breaker[1] = -1;
ret = event_register_poll(event_pool, event_pool->breaker[0], __flush_fd,
NULL, 1, 0);
if (ret == -1) {
gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_REGISTER_PIPE_FAILED,
"could not register pipe fd with poll event loop");
sys_close(event_pool->breaker[0]);
sys_close(event_pool->breaker[1]);
event_pool->breaker[0] = event_pool->breaker[1] = -1;
GF_FREE (event_pool->reg);
GF_FREE (event_pool);
return NULL;
}
GF_FREE(event_pool->reg);
GF_FREE(event_pool);
return NULL;
}
if (eventthreadcount > 1) {
gf_msg ("poll", GF_LOG_INFO, 0,
LG_MSG_POLL_IGNORE_MULTIPLE_THREADS, "Currently poll "
"does not use multiple event processing threads, "
"thread count (%d) ignored", eventthreadcount);
}
if (eventthreadcount > 1) {
gf_msg("poll", GF_LOG_INFO, 0, LG_MSG_POLL_IGNORE_MULTIPLE_THREADS,
"Currently poll "
"does not use multiple event processing threads, "
"thread count (%d) ignored",
eventthreadcount);
}
/* although, eventhreadcount for poll implementation is always
* going to be 1, eventthreadcount needs to be set to 1 so that
* rpcsvc_request_handler() thread scaling works flawlessly in
* both epoll and poll models
*/
event_pool->eventthreadcount = 1;
/* although, eventhreadcount for poll implementation is always
* going to be 1, eventthreadcount needs to be set to 1 so that
* rpcsvc_request_handler() thread scaling works flawlessly in
* both epoll and poll models
*/
event_pool->eventthreadcount = 1;
return event_pool;
return event_pool;
}
static int
event_register_poll (struct event_pool *event_pool, int fd,
event_handler_t handler,
void *data, int poll_in, int poll_out)
event_register_poll(struct event_pool *event_pool, int fd,
event_handler_t handler, void *data, int poll_in,
int poll_out)
{
int idx = -1;
int idx = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
GF_VALIDATE_OR_GOTO("event", event_pool, out);
pthread_mutex_lock (&event_pool->mutex);
{
if (event_pool->count == event_pool->used)
{
event_pool->count += 256;
event_pool->reg = GF_REALLOC (event_pool->reg,
event_pool->count *
sizeof (*event_pool->reg));
if (!event_pool->reg)
goto unlock;
}
idx = event_pool->used++;
event_pool->reg[idx].fd = fd;
event_pool->reg[idx].events = POLLPRI;
event_pool->reg[idx].handler = handler;
event_pool->reg[idx].data = data;
switch (poll_in) {
case 1:
event_pool->reg[idx].events |= POLLIN;
break;
case 0:
event_pool->reg[idx].events &= ~POLLIN;
break;
case -1:
/* do nothing */
break;
default:
gf_msg ("poll", GF_LOG_ERROR, 0,
LG_MSG_INVALID_POLL_IN,
"invalid poll_in value %d", poll_in);
break;
}
switch (poll_out) {
case 1:
event_pool->reg[idx].events |= POLLOUT;
break;
case 0:
event_pool->reg[idx].events &= ~POLLOUT;
break;
case -1:
/* do nothing */
break;
default:
gf_msg ("poll", GF_LOG_ERROR, 0,
LG_MSG_INVALID_POLL_OUT,
"invalid poll_out value %d", poll_out);
break;
}
event_pool->changed = 1;
pthread_mutex_lock(&event_pool->mutex);
{
if (event_pool->count == event_pool->used) {
event_pool->count += 256;
event_pool->reg = GF_REALLOC(
event_pool->reg, event_pool->count * sizeof(*event_pool->reg));
if (!event_pool->reg)
goto unlock;
}
idx = event_pool->used++;
event_pool->reg[idx].fd = fd;
event_pool->reg[idx].events = POLLPRI;
event_pool->reg[idx].handler = handler;
event_pool->reg[idx].data = data;
switch (poll_in) {
case 1:
event_pool->reg[idx].events |= POLLIN;
break;
case 0:
event_pool->reg[idx].events &= ~POLLIN;
break;
case -1:
/* do nothing */
break;
default:
gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN,
"invalid poll_in value %d", poll_in);
break;
}
switch (poll_out) {
case 1:
event_pool->reg[idx].events |= POLLOUT;
break;
case 0:
event_pool->reg[idx].events &= ~POLLOUT;
break;
case -1:
/* do nothing */
break;
default:
gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT,
"invalid poll_out value %d", poll_out);
break;
}
event_pool->changed = 1;
}
unlock:
pthread_mutex_unlock (&event_pool->mutex);
pthread_mutex_unlock(&event_pool->mutex);
out:
return idx;
return idx;
}
static int
event_unregister_poll (struct event_pool *event_pool, int fd, int idx_hint)
event_unregister_poll(struct event_pool *event_pool, int fd, int idx_hint)
{
int idx = -1;
int idx = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
GF_VALIDATE_OR_GOTO("event", event_pool, out);
pthread_mutex_lock (&event_pool->mutex);
{
idx = __event_getindex (event_pool, fd, idx_hint);
pthread_mutex_lock(&event_pool->mutex);
{
idx = __event_getindex(event_pool, fd, idx_hint);
if (idx == -1) {
gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND,
"index not found for fd=%d (idx_hint=%d)",
fd, idx_hint);
errno = ENOENT;
goto unlock;
}
event_pool->reg[idx] = event_pool->reg[--event_pool->used];
event_pool->changed = 1;
if (idx == -1) {
gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND,
"index not found for fd=%d (idx_hint=%d)", fd, idx_hint);
errno = ENOENT;
goto unlock;
}
event_pool->reg[idx] = event_pool->reg[--event_pool->used];
event_pool->changed = 1;
}
unlock:
pthread_mutex_unlock (&event_pool->mutex);
pthread_mutex_unlock(&event_pool->mutex);
out:
return idx;
return idx;
}
static int
event_unregister_close_poll (struct event_pool *event_pool, int fd,
int idx_hint)
event_unregister_close_poll(struct event_pool *event_pool, int fd, int idx_hint)
{
int ret = -1;
int ret = -1;
ret = event_unregister_poll (event_pool, fd, idx_hint);
ret = event_unregister_poll(event_pool, fd, idx_hint);
sys_close (fd);
sys_close(fd);
return ret;
return ret;
}
static int
event_select_on_poll (struct event_pool *event_pool, int fd, int idx_hint,
int poll_in, int poll_out)
event_select_on_poll(struct event_pool *event_pool, int fd, int idx_hint,
int poll_in, int poll_out)
{
int idx = -1;
int idx = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
GF_VALIDATE_OR_GOTO("event", event_pool, out);
pthread_mutex_lock (&event_pool->mutex);
{
idx = __event_getindex (event_pool, fd, idx_hint);
pthread_mutex_lock(&event_pool->mutex);
{
idx = __event_getindex(event_pool, fd, idx_hint);
if (idx == -1) {
gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND,
"index not found for fd=%d (idx_hint=%d)",
fd, idx_hint);
errno = ENOENT;
goto unlock;
}
switch (poll_in) {
case 1:
event_pool->reg[idx].events |= POLLIN;
break;
case 0:
event_pool->reg[idx].events &= ~POLLIN;
break;
case -1:
/* do nothing */
break;
default:
/* TODO: log error */
break;
}
switch (poll_out) {
case 1:
event_pool->reg[idx].events |= POLLOUT;
break;
case 0:
event_pool->reg[idx].events &= ~POLLOUT;
break;
case -1:
/* do nothing */
break;
default:
/* TODO: log error */
break;
}
if (poll_in + poll_out > -2)
event_pool->changed = 1;
if (idx == -1) {
gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND,
"index not found for fd=%d (idx_hint=%d)", fd, idx_hint);
errno = ENOENT;
goto unlock;
}
switch (poll_in) {
case 1:
event_pool->reg[idx].events |= POLLIN;
break;
case 0:
event_pool->reg[idx].events &= ~POLLIN;
break;
case -1:
/* do nothing */
break;
default:
/* TODO: log error */
break;
}
switch (poll_out) {
case 1:
event_pool->reg[idx].events |= POLLOUT;
break;
case 0:
event_pool->reg[idx].events &= ~POLLOUT;
break;
case -1:
/* do nothing */
break;
default:
/* TODO: log error */
break;
}
if (poll_in + poll_out > -2)
event_pool->changed = 1;
}
unlock:
pthread_mutex_unlock (&event_pool->mutex);
pthread_mutex_unlock(&event_pool->mutex);
out:
return idx;
return idx;
}
static int
event_dispatch_poll_handler (struct event_pool *event_pool,
struct pollfd *ufds, int i)
event_dispatch_poll_handler(struct event_pool *event_pool, struct pollfd *ufds,
int i)
{
event_handler_t handler = NULL;
void *data = NULL;
int idx = -1;
int ret = 0;
event_handler_t handler = NULL;
void *data = NULL;
int idx = -1;
int ret = 0;
handler = NULL;
data = NULL;
handler = NULL;
data = NULL;
pthread_mutex_lock (&event_pool->mutex);
{
idx = __event_getindex (event_pool, ufds[i].fd, i);
pthread_mutex_lock(&event_pool->mutex);
{
idx = __event_getindex(event_pool, ufds[i].fd, i);
if (idx == -1) {
gf_msg ("poll", GF_LOG_ERROR, 0,
LG_MSG_INDEX_NOT_FOUND, "index not found for "
"fd=%d (idx_hint=%d)", ufds[i].fd, i);
goto unlock;
}
handler = event_pool->reg[idx].handler;
data = event_pool->reg[idx].data;
if (idx == -1) {
gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND,
"index not found for "
"fd=%d (idx_hint=%d)",
ufds[i].fd, i);
goto unlock;
}
handler = event_pool->reg[idx].handler;
data = event_pool->reg[idx].data;
}
unlock:
pthread_mutex_unlock (&event_pool->mutex);
pthread_mutex_unlock(&event_pool->mutex);
if (handler)
ret = handler (ufds[i].fd, idx, 0, data,
(ufds[i].revents & (POLLIN|POLLPRI)),
(ufds[i].revents & (POLLOUT)),
(ufds[i].revents & (POLLERR|POLLHUP|POLLNVAL)));
if (handler)
ret = handler(ufds[i].fd, idx, 0, data,
(ufds[i].revents & (POLLIN | POLLPRI)),
(ufds[i].revents & (POLLOUT)),
(ufds[i].revents & (POLLERR | POLLHUP | POLLNVAL)));
return ret;
return ret;
}
static int
event_dispatch_poll_resize (struct event_pool *event_pool,
struct pollfd *ufds, int size)
event_dispatch_poll_resize(struct event_pool *event_pool, struct pollfd *ufds,
int size)
{
int i = 0;
int i = 0;
pthread_mutex_lock (&event_pool->mutex);
{
if (event_pool->changed == 0) {
goto unlock;
}
if (event_pool->used > event_pool->evcache_size) {
GF_FREE (event_pool->evcache);
event_pool->evcache = ufds = NULL;
event_pool->evcache_size = event_pool->used;
ufds = GF_CALLOC (sizeof (struct pollfd),
event_pool->evcache_size,
gf_common_mt_pollfd);
if (!ufds)
goto unlock;
event_pool->evcache = ufds;
}
if (ufds == NULL) {
goto unlock;
}
for (i = 0; i < event_pool->used; i++) {
ufds[i].fd = event_pool->reg[i].fd;
ufds[i].events = event_pool->reg[i].events;
ufds[i].revents = 0;
}
size = i;
pthread_mutex_lock(&event_pool->mutex);
{
if (event_pool->changed == 0) {
goto unlock;
}
if (event_pool->used > event_pool->evcache_size) {
GF_FREE(event_pool->evcache);
event_pool->evcache = ufds = NULL;
event_pool->evcache_size = event_pool->used;
ufds = GF_CALLOC(sizeof(struct pollfd), event_pool->evcache_size,
gf_common_mt_pollfd);
if (!ufds)
goto unlock;
event_pool->evcache = ufds;
}
if (ufds == NULL) {
goto unlock;
}
for (i = 0; i < event_pool->used; i++) {
ufds[i].fd = event_pool->reg[i].fd;
ufds[i].events = event_pool->reg[i].events;
ufds[i].revents = 0;
}
size = i;
}
unlock:
pthread_mutex_unlock (&event_pool->mutex);
pthread_mutex_unlock(&event_pool->mutex);
return size;
return size;
}
static int
event_dispatch_poll (struct event_pool *event_pool)
event_dispatch_poll(struct event_pool *event_pool)
{
struct pollfd *ufds = NULL;
int size = 0;
int i = 0;
int ret = -1;
struct pollfd *ufds = NULL;
int size = 0;
int i = 0;
int ret = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
GF_VALIDATE_OR_GOTO("event", event_pool, out);
pthread_mutex_lock (&event_pool->mutex);
pthread_mutex_lock(&event_pool->mutex);
{
event_pool->activethreadcount = 1;
}
pthread_mutex_unlock(&event_pool->mutex);
while (1) {
pthread_mutex_lock(&event_pool->mutex);
{
event_pool->activethreadcount = 1;
if (event_pool->destroy == 1) {
event_pool->activethreadcount = 0;
pthread_cond_broadcast(&event_pool->cond);
pthread_mutex_unlock(&event_pool->mutex);
return 0;
}
}
pthread_mutex_unlock (&event_pool->mutex);
pthread_mutex_unlock(&event_pool->mutex);
while (1) {
pthread_mutex_lock (&event_pool->mutex);
{
if (event_pool->destroy == 1) {
event_pool->activethreadcount = 0;
pthread_cond_broadcast (&event_pool->cond);
pthread_mutex_unlock (&event_pool->mutex);
return 0;
}
}
pthread_mutex_unlock (&event_pool->mutex);
size = event_dispatch_poll_resize(event_pool, ufds, size);
ufds = event_pool->evcache;
size = event_dispatch_poll_resize (event_pool, ufds, size);
ufds = event_pool->evcache;
ret = poll(ufds, size, 1);
ret = poll (ufds, size, 1);
if (ret == 0)
/* timeout */
continue;
if (ret == 0)
/* timeout */
continue;
if (ret == -1 && errno == EINTR)
/* sys call */
continue;
if (ret == -1 && errno == EINTR)
/* sys call */
continue;
for (i = 0; i < size; i++) {
if (!ufds[i].revents)
continue;
for (i = 0; i < size; i++) {
if (!ufds[i].revents)
continue;
event_dispatch_poll_handler (event_pool, ufds, i);
}
event_dispatch_poll_handler(event_pool, ufds, i);
}
}
out:
return -1;
return -1;
}
int
event_reconfigure_threads_poll (struct event_pool *event_pool, int value)
event_reconfigure_threads_poll(struct event_pool *event_pool, int value)
{
/* No-op for poll */
/* No-op for poll */
return 0;
return 0;
}
/* This function is the destructor for the event_pool data structure
@ -514,33 +493,32 @@ event_reconfigure_threads_poll (struct event_pool *event_pool, int value)
* else will lead to crashes.
*/
static int
event_pool_destroy_poll (struct event_pool *event_pool)
event_pool_destroy_poll(struct event_pool *event_pool)
{
int ret = 0;
ret = sys_close (event_pool->breaker[0]);
if (ret)
return ret;
ret = sys_close (event_pool->breaker[1]);
if (ret)
return ret;
event_pool->breaker[0] = event_pool->breaker[1] = -1;
GF_FREE (event_pool->reg);
GF_FREE (event_pool);
int ret = 0;
ret = sys_close(event_pool->breaker[0]);
if (ret)
return ret;
ret = sys_close(event_pool->breaker[1]);
if (ret)
return ret;
event_pool->breaker[0] = event_pool->breaker[1] = -1;
GF_FREE(event_pool->reg);
GF_FREE(event_pool);
return ret;
}
struct event_ops event_ops_poll = {
.new = event_pool_new_poll,
.event_register = event_register_poll,
.event_select_on = event_select_on_poll,
.event_unregister = event_unregister_poll,
.event_unregister_close = event_unregister_close_poll,
.event_dispatch = event_dispatch_poll,
.event_reconfigure_threads = event_reconfigure_threads_poll,
.event_pool_destroy = event_pool_destroy_poll
};
.new = event_pool_new_poll,
.event_register = event_register_poll,
.event_select_on = event_select_on_poll,
.event_unregister = event_unregister_poll,
.event_unregister_close = event_unregister_close_poll,
.event_dispatch = event_dispatch_poll,
.event_reconfigure_threads = event_reconfigure_threads_poll,
.event_pool_destroy = event_pool_destroy_poll};

View File

@ -23,173 +23,164 @@
#include "libglusterfs-messages.h"
#include "syscall.h"
struct event_pool *
event_pool_new (int count, int eventthreadcount)
event_pool_new(int count, int eventthreadcount)
{
struct event_pool *event_pool = NULL;
extern struct event_ops event_ops_poll;
struct event_pool *event_pool = NULL;
extern struct event_ops event_ops_poll;
#ifdef HAVE_SYS_EPOLL_H
extern struct event_ops event_ops_epoll;
extern struct event_ops event_ops_epoll;
event_pool = event_ops_epoll.new (count, eventthreadcount);
event_pool = event_ops_epoll.new(count, eventthreadcount);
if (event_pool) {
event_pool->ops = &event_ops_epoll;
} else {
gf_msg ("event", GF_LOG_WARNING, 0, LG_MSG_FALLBACK_TO_POLL,
"falling back to poll based event handling");
}
if (event_pool) {
event_pool->ops = &event_ops_epoll;
} else {
gf_msg("event", GF_LOG_WARNING, 0, LG_MSG_FALLBACK_TO_POLL,
"falling back to poll based event handling");
}
#endif
if (!event_pool) {
event_pool = event_ops_poll.new (count, eventthreadcount);
if (!event_pool) {
event_pool = event_ops_poll.new(count, eventthreadcount);
if (event_pool)
event_pool->ops = &event_ops_poll;
}
if (event_pool)
event_pool->ops = &event_ops_poll;
}
return event_pool;
}
int
event_register (struct event_pool *event_pool, int fd,
event_handler_t handler,
void *data, int poll_in, int poll_out)
{
int ret = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
ret = event_pool->ops->event_register (event_pool, fd, handler, data,
poll_in, poll_out);
out:
return ret;
}
int
event_unregister (struct event_pool *event_pool, int fd, int idx)
{
int ret = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
ret = event_pool->ops->event_unregister (event_pool, fd, idx);
out:
return ret;
}
int
event_unregister_close (struct event_pool *event_pool, int fd, int idx)
{
int ret = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
ret = event_pool->ops->event_unregister_close (event_pool, fd, idx);
out:
return ret;
}
int
event_select_on (struct event_pool *event_pool, int fd, int idx_hint,
int poll_in, int poll_out)
{
int ret = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
ret = event_pool->ops->event_select_on (event_pool, fd, idx_hint,
poll_in, poll_out);
out:
return ret;
}
int
event_dispatch (struct event_pool *event_pool)
{
int ret = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
ret = event_pool->ops->event_dispatch (event_pool);
if (ret)
goto out;
out:
return ret;
return event_pool;
}
int
event_reconfigure_threads (struct event_pool *event_pool, int value)
event_register(struct event_pool *event_pool, int fd, event_handler_t handler,
void *data, int poll_in, int poll_out)
{
int ret = -1;
int ret = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
/* call event refresh function */
ret = event_pool->ops->event_reconfigure_threads (event_pool,
value);
GF_VALIDATE_OR_GOTO("event", event_pool, out);
ret = event_pool->ops->event_register(event_pool, fd, handler, data,
poll_in, poll_out);
out:
return ret;
return ret;
}
int
event_pool_destroy (struct event_pool *event_pool)
event_unregister(struct event_pool *event_pool, int fd, int idx)
{
int ret = -1;
int destroy = 0, activethreadcount = 0;
int ret = -1;
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
GF_VALIDATE_OR_GOTO("event", event_pool, out);
pthread_mutex_lock (&event_pool->mutex);
{
destroy = event_pool->destroy;
activethreadcount = event_pool->activethreadcount;
}
pthread_mutex_unlock (&event_pool->mutex);
ret = event_pool->ops->event_unregister(event_pool, fd, idx);
if (!destroy || (activethreadcount > 0)) {
goto out;
}
ret = event_pool->ops->event_pool_destroy (event_pool);
out:
return ret;
return ret;
}
int
poller_destroy_handler (int fd, int idx, int gen, void *data,
int poll_out, int poll_in, int poll_err)
event_unregister_close(struct event_pool *event_pool, int fd, int idx)
{
struct event_destroy_data *destroy = NULL;
int readfd = -1, ret = -1;
char buf = '\0';
int ret = -1;
destroy = data;
readfd = destroy->readfd;
if (readfd < 0) {
goto out;
}
GF_VALIDATE_OR_GOTO("event", event_pool, out);
while (sys_read (readfd, &buf, 1) > 0) {
}
ret = event_pool->ops->event_unregister_close(event_pool, fd, idx);
ret = 0;
out:
event_handled (destroy->pool, fd, idx, gen);
return ret;
}
return ret;
int
event_select_on(struct event_pool *event_pool, int fd, int idx_hint,
int poll_in, int poll_out)
{
int ret = -1;
GF_VALIDATE_OR_GOTO("event", event_pool, out);
ret = event_pool->ops->event_select_on(event_pool, fd, idx_hint, poll_in,
poll_out);
out:
return ret;
}
int
event_dispatch(struct event_pool *event_pool)
{
int ret = -1;
GF_VALIDATE_OR_GOTO("event", event_pool, out);
ret = event_pool->ops->event_dispatch(event_pool);
if (ret)
goto out;
out:
return ret;
}
int
event_reconfigure_threads(struct event_pool *event_pool, int value)
{
int ret = -1;
GF_VALIDATE_OR_GOTO("event", event_pool, out);
/* call event refresh function */
ret = event_pool->ops->event_reconfigure_threads(event_pool, value);
out:
return ret;
}
int
event_pool_destroy(struct event_pool *event_pool)
{
int ret = -1;
int destroy = 0, activethreadcount = 0;
GF_VALIDATE_OR_GOTO("event", event_pool, out);
pthread_mutex_lock(&event_pool->mutex);
{
destroy = event_pool->destroy;
activethreadcount = event_pool->activethreadcount;
}
pthread_mutex_unlock(&event_pool->mutex);
if (!destroy || (activethreadcount > 0)) {
goto out;
}
ret = event_pool->ops->event_pool_destroy(event_pool);
out:
return ret;
}
int
poller_destroy_handler(int fd, int idx, int gen, void *data, int poll_out,
int poll_in, int poll_err)
{
struct event_destroy_data *destroy = NULL;
int readfd = -1, ret = -1;
char buf = '\0';
destroy = data;
readfd = destroy->readfd;
if (readfd < 0) {
goto out;
}
while (sys_read(readfd, &buf, 1) > 0) {
}
ret = 0;
out:
event_handled(destroy->pool, fd, idx, gen);
return ret;
}
/* This function destroys all the poller threads.
@ -204,109 +195,111 @@ out:
* threads are destroyed)
*/
int
event_dispatch_destroy (struct event_pool *event_pool)
event_dispatch_destroy(struct event_pool *event_pool)
{
int ret = -1, threadcount = 0;
int fd[2] = {-1};
int idx = -1;
int flags = 0;
struct timespec sleep_till = {0, };
struct event_destroy_data data = {0, };
int ret = -1, threadcount = 0;
int fd[2] = {-1};
int idx = -1;
int flags = 0;
struct timespec sleep_till = {
0,
};
struct event_destroy_data data = {
0,
};
GF_VALIDATE_OR_GOTO ("event", event_pool, out);
GF_VALIDATE_OR_GOTO("event", event_pool, out);
ret = pipe (fd);
if (ret < 0)
goto out;
ret = pipe(fd);
if (ret < 0)
goto out;
/* Make the read end of the pipe nonblocking */
flags = fcntl(fd[0], F_GETFL);
flags |= O_NONBLOCK;
ret = fcntl(fd[0], F_SETFL, flags);
if (ret < 0)
goto out;
/* Make the read end of the pipe nonblocking */
flags = fcntl(fd[0], F_GETFL);
flags |= O_NONBLOCK;
ret = fcntl(fd[0], F_SETFL, flags);
if (ret < 0)
goto out;
/* Make the write end of the pipe nonblocking */
flags = fcntl(fd[1], F_GETFL);
flags |= O_NONBLOCK;
ret = fcntl(fd[1], F_SETFL, flags);
if (ret < 0)
goto out;
/* Make the write end of the pipe nonblocking */
flags = fcntl(fd[1], F_GETFL);
flags |= O_NONBLOCK;
ret = fcntl(fd[1], F_SETFL, flags);
if (ret < 0)
goto out;
data.pool = event_pool;
data.readfd = fd[1];
data.pool = event_pool;
data.readfd = fd[1];
/* From the main thread register an event on the pipe fd[0],
/* From the main thread register an event on the pipe fd[0],
*/
idx = event_register(event_pool, fd[0], poller_destroy_handler, &data, 1,
0);
if (idx < 0)
goto out;
/* Enter the destroy mode first, set this before reconfiguring to 0
* threads, to prevent further reconfigure to thread count > 0.
*/
pthread_mutex_lock(&event_pool->mutex);
{
threadcount = event_pool->eventthreadcount;
event_pool->destroy = 1;
}
pthread_mutex_unlock(&event_pool->mutex);
ret = event_reconfigure_threads(event_pool, 0);
if (ret < 0)
goto out;
/* Write something onto the write end of the pipe(fd[1]) so that
* poll wakes up and calls the handler, poller_destroy_handler()
*/
pthread_mutex_lock(&event_pool->mutex);
{
/* Write to pipe(fd[1]) and then wait for 1 second or until
* a poller thread that is dying, broadcasts. Make sure we
* do not loop forever by limiting to 10 retries
*/
idx = event_register (event_pool, fd[0], poller_destroy_handler,
&data, 1, 0);
if (idx < 0)
goto out;
int retry = 0;
/* Enter the destroy mode first, set this before reconfiguring to 0
* threads, to prevent further reconfigure to thread count > 0.
*/
pthread_mutex_lock (&event_pool->mutex);
{
threadcount = event_pool->eventthreadcount;
event_pool->destroy = 1;
while (event_pool->activethreadcount > 0 &&
(retry++ < (threadcount + 10))) {
if (sys_write(fd[1], "dummy", 6) == -1) {
break;
}
sleep_till.tv_sec = time(NULL) + 1;
ret = pthread_cond_timedwait(&event_pool->cond, &event_pool->mutex,
&sleep_till);
if (ret) {
gf_msg_debug("event", 0,
"thread cond-timedwait failed "
"active-thread-count: %d, "
"retry: %d",
event_pool->activethreadcount, retry);
}
}
pthread_mutex_unlock (&event_pool->mutex);
}
pthread_mutex_unlock(&event_pool->mutex);
ret = event_reconfigure_threads (event_pool, 0);
if (ret < 0)
goto out;
ret = event_unregister(event_pool, fd[0], idx);
/* Write something onto the write end of the pipe(fd[1]) so that
* poll wakes up and calls the handler, poller_destroy_handler()
*/
pthread_mutex_lock (&event_pool->mutex);
{
/* Write to pipe(fd[1]) and then wait for 1 second or until
* a poller thread that is dying, broadcasts. Make sure we
* do not loop forever by limiting to 10 retries
*/
int retry = 0;
out:
if (fd[0] != -1)
sys_close(fd[0]);
if (fd[1] != -1)
sys_close(fd[1]);
while (event_pool->activethreadcount > 0
&& (retry++ < (threadcount + 10))) {
if (sys_write (fd[1], "dummy", 6) == -1) {
break;
}
sleep_till.tv_sec = time (NULL) + 1;
ret = pthread_cond_timedwait (&event_pool->cond,
&event_pool->mutex,
&sleep_till);
if (ret) {
gf_msg_debug ("event", 0,
"thread cond-timedwait failed "
"active-thread-count: %d, "
"retry: %d",
event_pool->activethreadcount,
retry);
}
}
}
pthread_mutex_unlock (&event_pool->mutex);
ret = event_unregister (event_pool, fd[0], idx);
out:
if (fd[0] != -1)
sys_close (fd[0]);
if (fd[1] != -1)
sys_close (fd[1]);
return ret;
return ret;
}
int
event_handled (struct event_pool *event_pool, int fd, int idx, int gen)
event_handled(struct event_pool *event_pool, int fd, int idx, int gen)
{
int ret = 0;
int ret = 0;
if (event_pool->ops->event_handled)
ret = event_pool->ops->event_handled (event_pool, fd, idx, gen);
if (event_pool->ops->event_handled)
ret = event_pool->ops->event_handled(event_pool, fd, idx, gen);
return ret;
return ret;
}

View File

@ -25,112 +25,109 @@
#include "globals.h"
#include "events.h"
#define EVENT_HOST "127.0.0.1"
#define EVENT_PORT 24009
int
_gf_event (eventtypes_t event, const char *fmt, ...)
_gf_event(eventtypes_t event, const char *fmt, ...)
{
int ret = 0;
int sock = -1;
char *eventstr = NULL;
struct sockaddr_in server;
va_list arguments;
char *msg = NULL;
glusterfs_ctx_t *ctx = NULL;
char *host = NULL;
struct addrinfo hints;
struct addrinfo *result = NULL;
int ret = 0;
int sock = -1;
char *eventstr = NULL;
struct sockaddr_in server;
va_list arguments;
char *msg = NULL;
glusterfs_ctx_t *ctx = NULL;
char *host = NULL;
struct addrinfo hints;
struct addrinfo *result = NULL;
/* Global context */
ctx = THIS->ctx;
/* Global context */
ctx = THIS->ctx;
if (event < 0 || event >= EVENT_LAST) {
ret = EVENT_ERROR_INVALID_INPUTS;
goto out;
if (event < 0 || event >= EVENT_LAST) {
ret = EVENT_ERROR_INVALID_INPUTS;
goto out;
}
/* Initialize UDP socket */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
ret = EVENT_ERROR_SOCKET;
goto out;
}
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
/* Get Host name to send message */
if (ctx && ctx->cmd_args.volfile_server) {
/* If it is client code then volfile_server is set
use that information to push the events. */
if ((getaddrinfo(ctx->cmd_args.volfile_server, NULL, &hints,
&result)) != 0) {
ret = EVENT_ERROR_RESOLVE;
goto out;
}
/* Initialize UDP socket */
sock = socket (AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
ret = EVENT_ERROR_SOCKET;
goto out;
if (get_ip_from_addrinfo(result, &host) == NULL) {
ret = EVENT_ERROR_RESOLVE;
goto out;
}
} else {
/* Localhost, Use the defined IP for localhost */
host = gf_strdup(EVENT_HOST);
}
memset (&hints, 0, sizeof (hints));
hints.ai_family = AF_UNSPEC;
/* Socket Configurations */
server.sin_family = AF_INET;
server.sin_port = htons(EVENT_PORT);
server.sin_addr.s_addr = inet_addr(host);
memset(&server.sin_zero, '\0', sizeof(server.sin_zero));
/* Get Host name to send message */
if (ctx && ctx->cmd_args.volfile_server) {
/* If it is client code then volfile_server is set
use that information to push the events. */
if ((getaddrinfo (ctx->cmd_args.volfile_server,
NULL, &hints, &result)) != 0) {
ret = EVENT_ERROR_RESOLVE;
goto out;
}
va_start(arguments, fmt);
ret = gf_vasprintf(&msg, fmt, arguments);
va_end(arguments);
if (get_ip_from_addrinfo (result, &host) == NULL) {
ret = EVENT_ERROR_RESOLVE;
goto out;
}
} else {
/* Localhost, Use the defined IP for localhost */
host = gf_strdup (EVENT_HOST);
}
if (ret < 0) {
ret = EVENT_ERROR_INVALID_INPUTS;
goto out;
}
/* Socket Configurations */
server.sin_family = AF_INET;
server.sin_port = htons (EVENT_PORT);
server.sin_addr.s_addr = inet_addr (host);
memset (&server.sin_zero, '\0', sizeof (server.sin_zero));
ret = gf_asprintf(&eventstr, "%u %d %s", (unsigned)time(NULL), event, msg);
va_start (arguments, fmt);
ret = gf_vasprintf (&msg, fmt, arguments);
va_end (arguments);
if (ret <= 0) {
ret = EVENT_ERROR_MSG_FORMAT;
goto out;
}
if (ret < 0) {
ret = EVENT_ERROR_INVALID_INPUTS;
goto out;
}
/* Send Message */
if (sendto(sock, eventstr, strlen(eventstr), 0, (struct sockaddr *)&server,
sizeof(server)) <= 0) {
ret = EVENT_ERROR_SEND;
goto out;
}
ret = gf_asprintf (&eventstr, "%u %d %s",
(unsigned)time(NULL), event, msg);
ret = EVENT_SEND_OK;
if (ret <= 0) {
ret = EVENT_ERROR_MSG_FORMAT;
goto out;
}
out:
if (sock >= 0) {
sys_close(sock);
}
/* Send Message */
if (sendto (sock, eventstr, strlen (eventstr),
0, (struct sockaddr *)&server, sizeof (server)) <= 0) {
ret = EVENT_ERROR_SEND;
goto out;
}
/* Allocated by gf_vasprintf */
if (msg)
GF_FREE(msg);
ret = EVENT_SEND_OK;
/* Allocated by gf_asprintf */
if (eventstr)
GF_FREE(eventstr);
out:
if (sock >= 0) {
sys_close (sock);
}
if (host)
GF_FREE(host);
/* Allocated by gf_vasprintf */
if (msg)
GF_FREE (msg);
if (result)
freeaddrinfo(result);
/* Allocated by gf_asprintf */
if (eventstr)
GF_FREE (eventstr);
if (host)
GF_FREE (host);
if (result)
freeaddrinfo (result);
return ret;
return ret;
}

View File

@ -13,430 +13,421 @@
#include "libglusterfs-messages.h"
int32_t
_fd_lk_delete_lock (fd_lk_ctx_node_t *lock)
_fd_lk_delete_lock(fd_lk_ctx_node_t *lock)
{
int32_t ret = -1;
int32_t ret = -1;
GF_VALIDATE_OR_GOTO ("fd-lk", lock, out);
GF_VALIDATE_OR_GOTO("fd-lk", lock, out);
list_del_init (&lock->next);
list_del_init(&lock->next);
ret = 0;
ret = 0;
out:
return ret;
return ret;
}
int32_t
_fd_lk_destroy_lock (fd_lk_ctx_node_t *lock)
_fd_lk_destroy_lock(fd_lk_ctx_node_t *lock)
{
int32_t ret = -1;
int32_t ret = -1;
GF_VALIDATE_OR_GOTO ("fd-lk", lock, out);
GF_VALIDATE_OR_GOTO("fd-lk", lock, out);
GF_FREE (lock);
GF_FREE(lock);
ret = 0;
ret = 0;
out:
return ret;
return ret;
}
int
_fd_lk_destroy_lock_list (fd_lk_ctx_t *lk_ctx)
_fd_lk_destroy_lock_list(fd_lk_ctx_t *lk_ctx)
{
int ret = -1;
fd_lk_ctx_node_t *lk = NULL;
fd_lk_ctx_node_t *tmp = NULL;
int ret = -1;
fd_lk_ctx_node_t *lk = NULL;
fd_lk_ctx_node_t *tmp = NULL;
GF_VALIDATE_OR_GOTO ("fd-lk", lk_ctx, out);
GF_VALIDATE_OR_GOTO("fd-lk", lk_ctx, out);
list_for_each_entry_safe (lk, tmp, &lk_ctx->lk_list, next) {
_fd_lk_delete_lock (lk);
_fd_lk_destroy_lock (lk);
}
ret = 0;
list_for_each_entry_safe(lk, tmp, &lk_ctx->lk_list, next)
{
_fd_lk_delete_lock(lk);
_fd_lk_destroy_lock(lk);
}
ret = 0;
out:
return ret;
return ret;
}
int
fd_lk_ctx_unref (fd_lk_ctx_t *lk_ctx)
fd_lk_ctx_unref(fd_lk_ctx_t *lk_ctx)
{
int ref = -1;
int ref = -1;
GF_VALIDATE_OR_GOTO ("fd-lk", lk_ctx, err);
GF_VALIDATE_OR_GOTO("fd-lk", lk_ctx, err);
ref = GF_ATOMIC_DEC (lk_ctx->ref);
if (ref < 0)
GF_ASSERT (!ref);
if (ref == 0)
_fd_lk_destroy_lock_list (lk_ctx);
ref = GF_ATOMIC_DEC(lk_ctx->ref);
if (ref < 0)
GF_ASSERT(!ref);
if (ref == 0)
_fd_lk_destroy_lock_list(lk_ctx);
if (ref == 0) {
LOCK_DESTROY (&lk_ctx->lock);
GF_FREE (lk_ctx);
}
if (ref == 0) {
LOCK_DESTROY(&lk_ctx->lock);
GF_FREE(lk_ctx);
}
return 0;
return 0;
err:
return -1;
return -1;
}
fd_lk_ctx_t *
fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx)
fd_lk_ctx_ref(fd_lk_ctx_t *lk_ctx)
{
if (!lk_ctx) {
gf_msg_callingfn ("fd-lk", GF_LOG_WARNING, EINVAL,
LG_MSG_INVALID_ARG, "invalid argument");
return NULL;
}
if (!lk_ctx) {
gf_msg_callingfn("fd-lk", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
"invalid argument");
return NULL;
}
GF_ATOMIC_INC (lk_ctx->ref);
GF_ATOMIC_INC(lk_ctx->ref);
return lk_ctx;
return lk_ctx;
}
fd_lk_ctx_t *
fd_lk_ctx_create ()
fd_lk_ctx_create()
{
fd_lk_ctx_t *fd_lk_ctx = NULL;
fd_lk_ctx_t *fd_lk_ctx = NULL;
fd_lk_ctx = GF_CALLOC (1, sizeof (fd_lk_ctx_t),
gf_common_mt_fd_lk_ctx_t);
if (!fd_lk_ctx)
goto out;
fd_lk_ctx = GF_CALLOC(1, sizeof(fd_lk_ctx_t), gf_common_mt_fd_lk_ctx_t);
if (!fd_lk_ctx)
goto out;
INIT_LIST_HEAD (&fd_lk_ctx->lk_list);
INIT_LIST_HEAD(&fd_lk_ctx->lk_list);
LOCK_INIT (&fd_lk_ctx->lock);
LOCK_INIT(&fd_lk_ctx->lock);
fd_lk_ctx = fd_lk_ctx_ref (fd_lk_ctx);
fd_lk_ctx = fd_lk_ctx_ref(fd_lk_ctx);
out:
return fd_lk_ctx;
return fd_lk_ctx;
}
int
_fd_lk_insert_lock (fd_lk_ctx_t *lk_ctx,
fd_lk_ctx_node_t *lock)
_fd_lk_insert_lock(fd_lk_ctx_t *lk_ctx, fd_lk_ctx_node_t *lock)
{
list_add_tail (&lock->next, &lk_ctx->lk_list);
return 0;
list_add_tail(&lock->next, &lk_ctx->lk_list);
return 0;
}
static off_t
_fd_lk_get_lock_len (off_t start, off_t end)
_fd_lk_get_lock_len(off_t start, off_t end)
{
if (end == LLONG_MAX)
return 0;
else
return (end - start + 1);
if (end == LLONG_MAX)
return 0;
else
return (end - start + 1);
}
fd_lk_ctx_node_t *
fd_lk_ctx_node_new (int32_t cmd, struct gf_flock *flock)
fd_lk_ctx_node_new(int32_t cmd, struct gf_flock *flock)
{
fd_lk_ctx_node_t *new_lock = NULL;
fd_lk_ctx_node_t *new_lock = NULL;
/* TODO: get from mem-pool */
new_lock = GF_CALLOC (1, sizeof (fd_lk_ctx_node_t),
gf_common_mt_fd_lk_ctx_node_t);
if (!new_lock)
goto out;
/* TODO: get from mem-pool */
new_lock = GF_CALLOC(1, sizeof(fd_lk_ctx_node_t),
gf_common_mt_fd_lk_ctx_node_t);
if (!new_lock)
goto out;
new_lock->cmd = cmd;
new_lock->cmd = cmd;
if (flock) {
new_lock->fl_type = flock->l_type;
new_lock->fl_start = flock->l_start;
if (flock) {
new_lock->fl_type = flock->l_type;
new_lock->fl_start = flock->l_start;
if (flock->l_len == 0)
new_lock->fl_end = LLONG_MAX;
else
new_lock->fl_end = flock->l_start + flock->l_len - 1;
if (flock->l_len == 0)
new_lock->fl_end = LLONG_MAX;
else
new_lock->fl_end = flock->l_start + flock->l_len - 1;
memcpy (&new_lock->user_flock, flock,
sizeof (struct gf_flock));
}
memcpy(&new_lock->user_flock, flock, sizeof(struct gf_flock));
}
INIT_LIST_HEAD (&new_lock->next);
INIT_LIST_HEAD(&new_lock->next);
out:
return new_lock;
return new_lock;
}
int32_t
_fd_lk_delete_unlck_locks (fd_lk_ctx_t *lk_ctx)
_fd_lk_delete_unlck_locks(fd_lk_ctx_t *lk_ctx)
{
int32_t ret = -1;
fd_lk_ctx_node_t *tmp = NULL;
fd_lk_ctx_node_t *lk = NULL;
int32_t ret = -1;
fd_lk_ctx_node_t *tmp = NULL;
fd_lk_ctx_node_t *lk = NULL;
GF_VALIDATE_OR_GOTO ("fd-lk", lk_ctx, out);
GF_VALIDATE_OR_GOTO("fd-lk", lk_ctx, out);
list_for_each_entry_safe (lk, tmp, &lk_ctx->lk_list, next) {
if (lk->fl_type == F_UNLCK) {
_fd_lk_delete_lock (lk);
_fd_lk_destroy_lock (lk);
}
list_for_each_entry_safe(lk, tmp, &lk_ctx->lk_list, next)
{
if (lk->fl_type == F_UNLCK) {
_fd_lk_delete_lock(lk);
_fd_lk_destroy_lock(lk);
}
}
out:
return ret;
return ret;
}
int
fd_lk_overlap (fd_lk_ctx_node_t *l1,
fd_lk_ctx_node_t *l2)
fd_lk_overlap(fd_lk_ctx_node_t *l1, fd_lk_ctx_node_t *l2)
{
if (l1->fl_end >= l2->fl_start &&
l2->fl_end >= l1->fl_start)
return 1;
if (l1->fl_end >= l2->fl_start && l2->fl_end >= l1->fl_start)
return 1;
return 0;
return 0;
}
fd_lk_ctx_node_t *
_fd_lk_add_locks (fd_lk_ctx_node_t *l1,
fd_lk_ctx_node_t *l2)
_fd_lk_add_locks(fd_lk_ctx_node_t *l1, fd_lk_ctx_node_t *l2)
{
fd_lk_ctx_node_t *sum = NULL;
fd_lk_ctx_node_t *sum = NULL;
sum = fd_lk_ctx_node_new (0, NULL);
if (!sum)
goto out;
sum = fd_lk_ctx_node_new(0, NULL);
if (!sum)
goto out;
sum->fl_start = min (l1->fl_start, l2->fl_start);
sum->fl_end = max (l1->fl_end, l2->fl_end);
sum->fl_start = min(l1->fl_start, l2->fl_start);
sum->fl_end = max(l1->fl_end, l2->fl_end);
sum->user_flock.l_start = sum->fl_start;
sum->user_flock.l_len = _fd_lk_get_lock_len (sum->fl_start,
sum->fl_end);
sum->user_flock.l_start = sum->fl_start;
sum->user_flock.l_len = _fd_lk_get_lock_len(sum->fl_start, sum->fl_end);
out:
return sum;
return sum;
}
/* Subtract two locks */
struct _values {
fd_lk_ctx_node_t *locks[3];
fd_lk_ctx_node_t *locks[3];
};
int32_t
_fd_lk_sub_locks (struct _values *v,
fd_lk_ctx_node_t *big,
fd_lk_ctx_node_t *small)
_fd_lk_sub_locks(struct _values *v, fd_lk_ctx_node_t *big,
fd_lk_ctx_node_t *small)
{
int32_t ret = -1;
int32_t ret = -1;
if ((big->fl_start == small->fl_start) &&
(big->fl_end == small->fl_end)) {
/* both edges coincide with big */
v->locks[0] = fd_lk_ctx_node_new (small->cmd, NULL);
if (!v->locks[0])
goto out;
if ((big->fl_start == small->fl_start) && (big->fl_end == small->fl_end)) {
/* both edges coincide with big */
v->locks[0] = fd_lk_ctx_node_new(small->cmd, NULL);
if (!v->locks[0])
goto out;
memcpy (v->locks[0], big, sizeof (fd_lk_ctx_node_t));
memcpy(v->locks[0], big, sizeof(fd_lk_ctx_node_t));
v->locks[0]->fl_type = small->fl_type;
v->locks[0]->user_flock.l_type = small->fl_type;
} else if ((small->fl_start > big->fl_start) &&
(small->fl_end < big->fl_end)) {
/* small lock is completely inside big lock,
break it down into 3 different locks. */
v->locks[0] = fd_lk_ctx_node_new (big->cmd, NULL);
if (!v->locks[0])
goto out;
v->locks[0]->fl_type = small->fl_type;
v->locks[0]->user_flock.l_type = small->fl_type;
} else if ((small->fl_start > big->fl_start) &&
(small->fl_end < big->fl_end)) {
/* small lock is completely inside big lock,
break it down into 3 different locks. */
v->locks[0] = fd_lk_ctx_node_new(big->cmd, NULL);
if (!v->locks[0])
goto out;
v->locks[1] = fd_lk_ctx_node_new (small->cmd, NULL);
if (!v->locks[1])
goto out;
v->locks[1] = fd_lk_ctx_node_new(small->cmd, NULL);
if (!v->locks[1])
goto out;
v->locks[2] = fd_lk_ctx_node_new (big->cmd, NULL);
if (!v->locks[2])
goto out;
v->locks[2] = fd_lk_ctx_node_new(big->cmd, NULL);
if (!v->locks[2])
goto out;
memcpy (v->locks[0], big, sizeof (fd_lk_ctx_node_t));
v->locks[0]->fl_end = small->fl_start - 1;
v->locks[0]->user_flock.l_len =
_fd_lk_get_lock_len (v->locks[0]->fl_start,
v->locks[0]->fl_end);
memcpy(v->locks[0], big, sizeof(fd_lk_ctx_node_t));
v->locks[0]->fl_end = small->fl_start - 1;
v->locks[0]->user_flock.l_len = _fd_lk_get_lock_len(
v->locks[0]->fl_start, v->locks[0]->fl_end);
memcpy (v->locks[1], small, sizeof (fd_lk_ctx_node_t));
memcpy(v->locks[1], small, sizeof(fd_lk_ctx_node_t));
memcpy (v->locks[2], big, sizeof (fd_lk_ctx_node_t));
v->locks[2]->fl_start = small->fl_end + 1;
v->locks[2]->user_flock.l_len =
_fd_lk_get_lock_len (v->locks[2]->fl_start,
v->locks[2]->fl_end);
} else if (small->fl_start == big->fl_start) {
/* One of the ends co-incide, break the
locks into two separate parts */
v->locks[0] = fd_lk_ctx_node_new (small->cmd, NULL);
if (!v->locks[0])
goto out;
memcpy(v->locks[2], big, sizeof(fd_lk_ctx_node_t));
v->locks[2]->fl_start = small->fl_end + 1;
v->locks[2]->user_flock.l_len = _fd_lk_get_lock_len(
v->locks[2]->fl_start, v->locks[2]->fl_end);
} else if (small->fl_start == big->fl_start) {
/* One of the ends co-incide, break the
locks into two separate parts */
v->locks[0] = fd_lk_ctx_node_new(small->cmd, NULL);
if (!v->locks[0])
goto out;
v->locks[1] = fd_lk_ctx_node_new (big->cmd, NULL);
if (!v->locks[1])
goto out;
v->locks[1] = fd_lk_ctx_node_new(big->cmd, NULL);
if (!v->locks[1])
goto out;
memcpy (v->locks[0], small, sizeof (fd_lk_ctx_node_t));
memcpy(v->locks[0], small, sizeof(fd_lk_ctx_node_t));
memcpy (v->locks[1], big, sizeof (fd_lk_ctx_node_t));
v->locks[1]->fl_start = small->fl_end + 1;
v->locks[1]->user_flock.l_start = small->fl_end + 1;
} else if (small->fl_end == big->fl_end) {
/* One of the ends co-incide, break the
locks into two separate parts */
v->locks[0] = fd_lk_ctx_node_new (small->cmd, NULL);
if (!v->locks[0])
goto out;
memcpy(v->locks[1], big, sizeof(fd_lk_ctx_node_t));
v->locks[1]->fl_start = small->fl_end + 1;
v->locks[1]->user_flock.l_start = small->fl_end + 1;
} else if (small->fl_end == big->fl_end) {
/* One of the ends co-incide, break the
locks into two separate parts */
v->locks[0] = fd_lk_ctx_node_new(small->cmd, NULL);
if (!v->locks[0])
goto out;
v->locks[1] = fd_lk_ctx_node_new (big->cmd, NULL);
if (!v->locks[1])
goto out;
v->locks[1] = fd_lk_ctx_node_new(big->cmd, NULL);
if (!v->locks[1])
goto out;
memcpy (v->locks[0], big, sizeof (fd_lk_ctx_node_t));
v->locks[0]->fl_end = small->fl_start - 1;
v->locks[0]->user_flock.l_len =
_fd_lk_get_lock_len (v->locks[0]->fl_start,
v->locks[0]->fl_end);
memcpy(v->locks[0], big, sizeof(fd_lk_ctx_node_t));
v->locks[0]->fl_end = small->fl_start - 1;
v->locks[0]->user_flock.l_len = _fd_lk_get_lock_len(
v->locks[0]->fl_start, v->locks[0]->fl_end);
memcpy (v->locks[1], small, sizeof (fd_lk_ctx_node_t));
} else {
/* We should never come to this case */
GF_ASSERT (!"Invalid case");
}
ret = 0;
memcpy(v->locks[1], small, sizeof(fd_lk_ctx_node_t));
} else {
/* We should never come to this case */
GF_ASSERT(!"Invalid case");
}
ret = 0;
out:
return ret;
return ret;
}
static void
_fd_lk_insert_and_merge (fd_lk_ctx_t *lk_ctx,
fd_lk_ctx_node_t *lock)
_fd_lk_insert_and_merge(fd_lk_ctx_t *lk_ctx, fd_lk_ctx_node_t *lock)
{
int32_t ret = -1;
int32_t i = 0;
fd_lk_ctx_node_t *entry = NULL;
fd_lk_ctx_node_t *t = NULL;
fd_lk_ctx_node_t *sum = NULL;
struct _values v = {.locks = {0, 0, 0 }};
int32_t ret = -1;
int32_t i = 0;
fd_lk_ctx_node_t *entry = NULL;
fd_lk_ctx_node_t *t = NULL;
fd_lk_ctx_node_t *sum = NULL;
struct _values v = {.locks = {0, 0, 0}};
list_for_each_entry_safe (entry, t, &lk_ctx->lk_list, next) {
if (!fd_lk_overlap (entry, lock))
continue;
list_for_each_entry_safe(entry, t, &lk_ctx->lk_list, next)
{
if (!fd_lk_overlap(entry, lock))
continue;
if (entry->fl_type == lock->fl_type) {
sum = _fd_lk_add_locks (entry, lock);
if (!sum)
return;
sum->fl_type = entry->fl_type;
sum->user_flock.l_type = entry->fl_type;
_fd_lk_delete_lock (entry);
_fd_lk_destroy_lock (entry);
_fd_lk_destroy_lock (lock);
_fd_lk_insert_and_merge (lk_ctx, sum);
return;
} else {
sum = _fd_lk_add_locks (entry, lock);
sum->fl_type = lock->fl_type;
sum->user_flock.l_type = lock->fl_type;
ret = _fd_lk_sub_locks (&v, sum, lock);
if (ret)
return;
_fd_lk_delete_lock (entry);
_fd_lk_destroy_lock (entry);
_fd_lk_delete_lock (lock);
_fd_lk_destroy_lock (lock);
_fd_lk_destroy_lock (sum);
for (i = 0; i < 3; i++) {
if (!v.locks[i])
continue;
INIT_LIST_HEAD (&v.locks[i]->next);
_fd_lk_insert_and_merge (lk_ctx, v.locks[i]);
}
_fd_lk_delete_unlck_locks (lk_ctx);
return;
}
}
/* no conflicts, so just insert */
if (lock->fl_type != F_UNLCK) {
_fd_lk_insert_lock (lk_ctx, lock);
if (entry->fl_type == lock->fl_type) {
sum = _fd_lk_add_locks(entry, lock);
if (!sum)
return;
sum->fl_type = entry->fl_type;
sum->user_flock.l_type = entry->fl_type;
_fd_lk_delete_lock(entry);
_fd_lk_destroy_lock(entry);
_fd_lk_destroy_lock(lock);
_fd_lk_insert_and_merge(lk_ctx, sum);
return;
} else {
_fd_lk_destroy_lock (lock);
sum = _fd_lk_add_locks(entry, lock);
sum->fl_type = lock->fl_type;
sum->user_flock.l_type = lock->fl_type;
ret = _fd_lk_sub_locks(&v, sum, lock);
if (ret)
return;
_fd_lk_delete_lock(entry);
_fd_lk_destroy_lock(entry);
_fd_lk_delete_lock(lock);
_fd_lk_destroy_lock(lock);
_fd_lk_destroy_lock(sum);
for (i = 0; i < 3; i++) {
if (!v.locks[i])
continue;
INIT_LIST_HEAD(&v.locks[i]->next);
_fd_lk_insert_and_merge(lk_ctx, v.locks[i]);
}
_fd_lk_delete_unlck_locks(lk_ctx);
return;
}
}
/* no conflicts, so just insert */
if (lock->fl_type != F_UNLCK) {
_fd_lk_insert_lock(lk_ctx, lock);
} else {
_fd_lk_destroy_lock(lock);
}
}
static void
print_lock_list (fd_lk_ctx_t *lk_ctx)
print_lock_list(fd_lk_ctx_t *lk_ctx)
{
fd_lk_ctx_node_t *lk = NULL;
fd_lk_ctx_node_t *lk = NULL;
gf_msg_debug ("fd-lk", 0, "lock list:");
gf_msg_debug("fd-lk", 0, "lock list:");
list_for_each_entry (lk, &lk_ctx->lk_list, next)
gf_msg_debug ("fd-lk", 0, "owner = %s, cmd = %s fl_type = %s,"
" fs_start = %"PRId64", fs_end = %"PRId64", "
"user_flock: l_type = %s, l_start = %"PRId64", "
"l_len = %"PRId64", ",
lkowner_utoa (&lk->user_flock.l_owner),
get_lk_cmd (lk->cmd), get_lk_type (lk->fl_type),
lk->fl_start, lk->fl_end,
get_lk_type (lk->user_flock.l_type),
lk->user_flock.l_start, lk->user_flock.l_len);
list_for_each_entry(lk, &lk_ctx->lk_list, next)
gf_msg_debug("fd-lk", 0,
"owner = %s, cmd = %s fl_type = %s,"
" fs_start = %" PRId64 ", fs_end = %" PRId64
", "
"user_flock: l_type = %s, l_start = %" PRId64
", "
"l_len = %" PRId64 ", ",
lkowner_utoa(&lk->user_flock.l_owner), get_lk_cmd(lk->cmd),
get_lk_type(lk->fl_type), lk->fl_start, lk->fl_end,
get_lk_type(lk->user_flock.l_type), lk->user_flock.l_start,
lk->user_flock.l_len);
}
int
fd_lk_insert_and_merge (fd_t *fd, int32_t cmd,
struct gf_flock *flock)
fd_lk_insert_and_merge(fd_t *fd, int32_t cmd, struct gf_flock *flock)
{
int32_t ret = -1;
fd_lk_ctx_t *lk_ctx = NULL;
fd_lk_ctx_node_t *lk = NULL;
int32_t ret = -1;
fd_lk_ctx_t *lk_ctx = NULL;
fd_lk_ctx_node_t *lk = NULL;
GF_VALIDATE_OR_GOTO ("fd-lk", fd, out);
GF_VALIDATE_OR_GOTO ("fd-lk", flock, out);
GF_VALIDATE_OR_GOTO("fd-lk", fd, out);
GF_VALIDATE_OR_GOTO("fd-lk", flock, out);
lk_ctx = fd_lk_ctx_ref (fd->lk_ctx);
lk = fd_lk_ctx_node_new (cmd, flock);
lk_ctx = fd_lk_ctx_ref(fd->lk_ctx);
lk = fd_lk_ctx_node_new(cmd, flock);
gf_msg_debug ("fd-lk", 0, "new lock request: owner = %s, fl_type = %s"
", fs_start = %"PRId64", fs_end = %"PRId64", user_flock:"
" l_type = %s, l_start = %"PRId64", l_len = %"PRId64,
lkowner_utoa (&flock->l_owner),
get_lk_type (lk->fl_type), lk->fl_start, lk->fl_end,
get_lk_type (lk->user_flock.l_type),
lk->user_flock.l_start, lk->user_flock.l_len);
gf_msg_debug("fd-lk", 0,
"new lock request: owner = %s, fl_type = %s"
", fs_start = %" PRId64 ", fs_end = %" PRId64
", user_flock:"
" l_type = %s, l_start = %" PRId64 ", l_len = %" PRId64,
lkowner_utoa(&flock->l_owner), get_lk_type(lk->fl_type),
lk->fl_start, lk->fl_end, get_lk_type(lk->user_flock.l_type),
lk->user_flock.l_start, lk->user_flock.l_len);
LOCK (&lk_ctx->lock);
{
_fd_lk_insert_and_merge (lk_ctx, lk);
print_lock_list (lk_ctx);
}
UNLOCK (&lk_ctx->lock);
LOCK(&lk_ctx->lock);
{
_fd_lk_insert_and_merge(lk_ctx, lk);
print_lock_list(lk_ctx);
}
UNLOCK(&lk_ctx->lock);
fd_lk_ctx_unref (lk_ctx);
fd_lk_ctx_unref(lk_ctx);
ret = 0;
ret = 0;
out:
return ret;
return ret;
}
gf_boolean_t
fd_lk_ctx_empty (fd_lk_ctx_t *lk_ctx)
fd_lk_ctx_empty(fd_lk_ctx_t *lk_ctx)
{
gf_boolean_t verdict = _gf_true;
gf_boolean_t verdict = _gf_true;
if (!lk_ctx)
return _gf_true;
if (!lk_ctx)
return _gf_true;
LOCK (&lk_ctx->lock);
{
verdict = list_empty (&lk_ctx->lk_list);
}
UNLOCK (&lk_ctx->lock);
LOCK(&lk_ctx->lock);
{
verdict = list_empty(&lk_ctx->lk_list);
}
UNLOCK(&lk_ctx->lock);
return verdict;
return verdict;
}

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,6 @@
cases as published by the Free Software Foundation.
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
@ -22,223 +20,221 @@
#define BACKEND_D_OFF_BITS 63
#define TOP_BIT (ONE << (PRESENT_D_OFF_BITS - 1))
#define MASK (~0ULL)
#define SHIFT_BITS (max (0, (BACKEND_D_OFF_BITS - PRESENT_D_OFF_BITS + 1)))
#define SHIFT_BITS (max(0, (BACKEND_D_OFF_BITS - PRESENT_D_OFF_BITS + 1)))
#define PRESENT_MASK (MASK >> (64 - PRESENT_D_OFF_BITS))
static uint64_t
bits_for (uint64_t num)
bits_for(uint64_t num)
{
uint64_t bits = 0, ctrl = 1;
uint64_t bits = 0, ctrl = 1;
while (ctrl < num) {
ctrl *= 2;
bits++;
}
while (ctrl < num) {
ctrl *= 2;
bits++;
}
return bits;
return bits;
}
int
gf_deitransform(xlator_t *this,
uint64_t offset)
gf_deitransform(xlator_t *this, uint64_t offset)
{
int cnt = 0;
int max = 0;
int max_bits = 0;
uint64_t off_mask = 0;
uint64_t host_mask = 0;
int cnt = 0;
int max = 0;
int max_bits = 0;
uint64_t off_mask = 0;
uint64_t host_mask = 0;
max = glusterfs_get_leaf_count(this->graph);
max = glusterfs_get_leaf_count(this->graph);
if (max == 1) {
cnt = 0;
goto out;
}
if (max == 1) {
cnt = 0;
goto out;
}
if (offset & TOP_BIT) {
/* HUGE d_off */
max_bits = bits_for (max);
off_mask = (MASK << max_bits);
host_mask = ~(off_mask);
if (offset & TOP_BIT) {
/* HUGE d_off */
max_bits = bits_for(max);
off_mask = (MASK << max_bits);
host_mask = ~(off_mask);
cnt = offset & host_mask;
} else {
/* small d_off */
cnt = offset % max;
}
cnt = offset & host_mask;
} else {
/* small d_off */
cnt = offset % max;
}
out:
return cnt;
return cnt;
}
uint64_t
gf_dirent_orig_offset(xlator_t *this,
uint64_t offset)
gf_dirent_orig_offset(xlator_t *this, uint64_t offset)
{
int max = 0;
int max_bits = 0;
uint64_t off_mask = 0;
uint64_t orig_offset;
int max = 0;
int max_bits = 0;
uint64_t off_mask = 0;
uint64_t orig_offset;
max = glusterfs_get_leaf_count(this->graph);
max = glusterfs_get_leaf_count(this->graph);
if (max == 1) {
orig_offset = offset;
goto out;
}
if (max == 1) {
orig_offset = offset;
goto out;
}
if (offset & TOP_BIT) {
/* HUGE d_off */
max_bits = bits_for (max);
off_mask = (MASK << max_bits);
orig_offset = ((offset & ~TOP_BIT) & off_mask) << SHIFT_BITS;
} else {
/* small d_off */
orig_offset = offset / max;
}
if (offset & TOP_BIT) {
/* HUGE d_off */
max_bits = bits_for(max);
off_mask = (MASK << max_bits);
orig_offset = ((offset & ~TOP_BIT) & off_mask) << SHIFT_BITS;
} else {
/* small d_off */
orig_offset = offset / max;
}
out:
return orig_offset;
return orig_offset;
}
int
gf_itransform (xlator_t *this, uint64_t x, uint64_t *y_p, int client_id)
gf_itransform(xlator_t *this, uint64_t x, uint64_t *y_p, int client_id)
{
int max = 0;
uint64_t y = 0;
uint64_t hi_mask = 0;
uint64_t off_mask = 0;
int max_bits = 0;
int max = 0;
uint64_t y = 0;
uint64_t hi_mask = 0;
uint64_t off_mask = 0;
int max_bits = 0;
if (x == ((uint64_t) -1)) {
y = (uint64_t) -1;
goto out;
}
if (x == ((uint64_t)-1)) {
y = (uint64_t)-1;
goto out;
}
if (!x) {
y = 0;
goto out;
}
if (!x) {
y = 0;
goto out;
}
max = glusterfs_get_leaf_count(this->graph);
max = glusterfs_get_leaf_count(this->graph);
if (max == 1) {
y = x;
goto out;
}
if (max == 1) {
y = x;
goto out;
}
max_bits = bits_for (max);
max_bits = bits_for(max);
hi_mask = ~(PRESENT_MASK >> (max_bits + 1));
hi_mask = ~(PRESENT_MASK >> (max_bits + 1));
if (x & hi_mask) {
/* HUGE d_off */
off_mask = MASK << max_bits;
y = TOP_BIT | ((x >> SHIFT_BITS) & off_mask) | client_id;
} else {
/* small d_off */
y = ((x * max) + client_id);
}
if (x & hi_mask) {
/* HUGE d_off */
off_mask = MASK << max_bits;
y = TOP_BIT | ((x >> SHIFT_BITS) & off_mask) | client_id;
} else {
/* small d_off */
y = ((x * max) + client_id);
}
out:
if (y_p)
*y_p = y;
if (y_p)
*y_p = y;
return 0;
return 0;
}
gf_dirent_t *
gf_dirent_for_name (const char *name)
gf_dirent_for_name(const char *name)
{
gf_dirent_t *gf_dirent = NULL;
gf_dirent_t *gf_dirent = NULL;
/* TODO: use mem-pool */
gf_dirent = GF_CALLOC (gf_dirent_size (name), 1,
gf_common_mt_gf_dirent_t);
if (!gf_dirent)
return NULL;
/* TODO: use mem-pool */
gf_dirent = GF_CALLOC(gf_dirent_size(name), 1, gf_common_mt_gf_dirent_t);
if (!gf_dirent)
return NULL;
INIT_LIST_HEAD (&gf_dirent->list);
strcpy (gf_dirent->d_name, name);
INIT_LIST_HEAD(&gf_dirent->list);
strcpy(gf_dirent->d_name, name);
gf_dirent->d_off = 0;
gf_dirent->d_ino = -1;
gf_dirent->d_type = 0;
gf_dirent->d_len = strlen (name);
gf_dirent->d_off = 0;
gf_dirent->d_ino = -1;
gf_dirent->d_type = 0;
gf_dirent->d_len = strlen(name);
return gf_dirent;
return gf_dirent;
}
void
gf_dirent_entry_free (gf_dirent_t *entry)
gf_dirent_entry_free(gf_dirent_t *entry)
{
if (!entry)
return;
if (!entry)
return;
if (entry->dict)
dict_unref (entry->dict);
if (entry->inode)
inode_unref (entry->inode);
if (entry->dict)
dict_unref(entry->dict);
if (entry->inode)
inode_unref(entry->inode);
list_del_init (&entry->list);
GF_FREE (entry);
list_del_init(&entry->list);
GF_FREE(entry);
}
void
gf_dirent_free (gf_dirent_t *entries)
gf_dirent_free(gf_dirent_t *entries)
{
gf_dirent_t *entry = NULL;
gf_dirent_t *tmp = NULL;
gf_dirent_t *entry = NULL;
gf_dirent_t *tmp = NULL;
if (!entries)
return;
if (!entries)
return;
if (list_empty (&entries->list))
return;
if (list_empty(&entries->list))
return;
list_for_each_entry_safe (entry, tmp, &entries->list, list) {
gf_dirent_entry_free (entry);
}
list_for_each_entry_safe(entry, tmp, &entries->list, list)
{
gf_dirent_entry_free(entry);
}
}
gf_dirent_t *
entry_copy (gf_dirent_t *source)
entry_copy(gf_dirent_t *source)
{
gf_dirent_t *sink = NULL;
gf_dirent_t *sink = NULL;
sink = gf_dirent_for_name (source->d_name);
if (!sink)
return NULL;
sink = gf_dirent_for_name(source->d_name);
if (!sink)
return NULL;
sink->d_off = source->d_off;
sink->d_ino = source->d_ino;
sink->d_type = source->d_type;
sink->d_stat = source->d_stat;
sink->d_len = source->d_len;
sink->d_off = source->d_off;
sink->d_ino = source->d_ino;
sink->d_type = source->d_type;
sink->d_stat = source->d_stat;
sink->d_len = source->d_len;
if (source->inode)
sink->inode = inode_ref (source->inode);
if (source->inode)
sink->inode = inode_ref(source->inode);
if (source->dict)
sink->dict = dict_ref (source->dict);
return sink;
if (source->dict)
sink->dict = dict_ref(source->dict);
return sink;
}
void
gf_link_inode_from_dirent (xlator_t *this, inode_t *parent, gf_dirent_t *entry)
gf_link_inode_from_dirent(xlator_t *this, inode_t *parent, gf_dirent_t *entry)
{
inode_t *link_inode = NULL;
inode_t *tmp = NULL;
inode_t *link_inode = NULL;
inode_t *tmp = NULL;
if (!entry->inode)
return;
link_inode = inode_link (entry->inode, parent,
entry->d_name, &entry->d_stat);
if (!link_inode)
return;
if (!entry->inode)
return;
link_inode = inode_link(entry->inode, parent, entry->d_name,
&entry->d_stat);
if (!link_inode)
return;
inode_lookup (link_inode);
tmp = entry->inode;
entry->inode = link_inode;
inode_unref (tmp);
inode_lookup(link_inode);
tmp = entry->inode;
entry->inode = link_inode;
inode_unref(tmp);
}
/* TODO: Currently, with this function, we will be breaking the
@ -247,55 +243,60 @@ gf_link_inode_from_dirent (xlator_t *this, inode_t *parent, gf_dirent_t *entry)
Need more thoughts before finalizing this function
*/
int
gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent,
gf_dirent_t *entries)
gf_link_inodes_from_dirent(xlator_t *this, inode_t *parent,
gf_dirent_t *entries)
{
gf_dirent_t *entry = NULL;
gf_dirent_t *entry = NULL;
list_for_each_entry (entry, &entries->list, list) {
gf_link_inode_from_dirent (this, parent, entry);
}
list_for_each_entry(entry, &entries->list, list)
{
gf_link_inode_from_dirent(this, parent, entry);
}
return 0;
return 0;
}
int
gf_fill_iatt_for_dirent (gf_dirent_t *entry, inode_t *parent, xlator_t *subvol)
gf_fill_iatt_for_dirent(gf_dirent_t *entry, inode_t *parent, xlator_t *subvol)
{
loc_t loc = {0, };
int ret = -1;
char *path = NULL;
struct iatt iatt = {0,};
loc_t loc = {
0,
};
int ret = -1;
char *path = NULL;
struct iatt iatt = {
0,
};
loc.inode = inode_grep (parent->table, parent, entry->d_name);
if (!loc.inode) {
loc.inode = inode_new (parent->table);
gf_uuid_copy (loc.inode->gfid, entry->d_stat.ia_gfid);
}
loc.inode = inode_grep(parent->table, parent, entry->d_name);
if (!loc.inode) {
loc.inode = inode_new(parent->table);
gf_uuid_copy(loc.inode->gfid, entry->d_stat.ia_gfid);
}
gf_uuid_copy (loc.pargfid, parent->gfid);
loc.name = entry->d_name;
loc.parent = inode_ref (parent);
ret = inode_path (loc.inode, entry->d_name, &path);
loc.path = path;
if (ret < 0)
goto out;
gf_uuid_copy(loc.pargfid, parent->gfid);
loc.name = entry->d_name;
loc.parent = inode_ref(parent);
ret = inode_path(loc.inode, entry->d_name, &path);
loc.path = path;
if (ret < 0)
goto out;
ret = syncop_lookup (subvol, &loc, &iatt, NULL, NULL, NULL);
if (ret)
goto out;
ret = syncop_lookup(subvol, &loc, &iatt, NULL, NULL, NULL);
if (ret)
goto out;
entry->d_stat = iatt;
entry->inode = inode_ref (loc.inode);
/* We don't need to link inode here, because as part of readdirp_cbk
* we will link all dirents.
*
* Since we did a proper lookup, we don't need to set need_lookup
* flag.
*/
entry->d_stat = iatt;
entry->inode = inode_ref(loc.inode);
/* We don't need to link inode here, because as part of readdirp_cbk
* we will link all dirents.
*
* Since we did a proper lookup, we don't need to set need_lookup
* flag.
*/
ret = 0;
ret = 0;
out:
loc_wipe (&loc);
return ret;
loc_wipe(&loc);
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -9,151 +9,139 @@
* ****************************************************************************/
/*Create a single link info structure*/
gfdb_link_info_t*
gfdb_link_info_new ()
gfdb_link_info_t *
gfdb_link_info_new()
{
gfdb_link_info_t *link_info = NULL;
gfdb_link_info_t *link_info = NULL;
link_info = GF_CALLOC (1, sizeof(gfdb_link_info_t),
gf_mt_gfdb_link_info_t);
if (!link_info) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, ENOMEM,
LG_MSG_NO_MEMORY, "Memory allocation failed for "
"link_info ");
goto out;
}
link_info = GF_CALLOC(1, sizeof(gfdb_link_info_t), gf_mt_gfdb_link_info_t);
if (!link_info) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
"Memory allocation failed for "
"link_info ");
goto out;
}
INIT_LIST_HEAD (&link_info->list);
INIT_LIST_HEAD(&link_info->list);
out:
return link_info;
return link_info;
}
/*Destroy a link info structure*/
void
gfdb_link_info_free(gfdb_link_info_t *link_info)
{
GF_FREE (link_info);
GF_FREE(link_info);
}
/*Function to create the query_record*/
gfdb_query_record_t *
gfdb_query_record_new()
{
int ret = -1;
gfdb_query_record_t *query_record = NULL;
int ret = -1;
gfdb_query_record_t *query_record = NULL;
query_record = GF_CALLOC (1, sizeof(gfdb_query_record_t),
gf_mt_gfdb_query_record_t);
if (!query_record) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, ENOMEM,
LG_MSG_NO_MEMORY, "Memory allocation failed for "
"query_record ");
goto out;
}
query_record = GF_CALLOC(1, sizeof(gfdb_query_record_t),
gf_mt_gfdb_query_record_t);
if (!query_record) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
"Memory allocation failed for "
"query_record ");
goto out;
}
INIT_LIST_HEAD (&query_record->link_list);
INIT_LIST_HEAD(&query_record->link_list);
ret = 0;
ret = 0;
out:
if (ret == -1) {
GF_FREE (query_record);
}
return query_record;
if (ret == -1) {
GF_FREE(query_record);
}
return query_record;
}
/*Function to delete a single linkinfo from list*/
static void
gfdb_delete_linkinfo_from_list (gfdb_link_info_t **link_info)
gfdb_delete_linkinfo_from_list(gfdb_link_info_t **link_info)
{
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, link_info, out);
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, *link_info, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, link_info, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, *link_info, out);
/*Remove hard link from list*/
list_del(&(*link_info)->list);
gfdb_link_info_free (*link_info);
link_info = NULL;
/*Remove hard link from list*/
list_del(&(*link_info)->list);
gfdb_link_info_free(*link_info);
link_info = NULL;
out:
return;
return;
}
/*Function to destroy link_info list*/
void
gfdb_free_link_info_list (gfdb_query_record_t *query_record)
gfdb_free_link_info_list(gfdb_query_record_t *query_record)
{
gfdb_link_info_t *link_info = NULL;
gfdb_link_info_t *temp = NULL;
gfdb_link_info_t *link_info = NULL;
gfdb_link_info_t *temp = NULL;
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out);
list_for_each_entry_safe(link_info, temp,
&query_record->link_list, list)
{
gfdb_delete_linkinfo_from_list (&link_info);
link_info = NULL;
}
list_for_each_entry_safe(link_info, temp, &query_record->link_list, list)
{
gfdb_delete_linkinfo_from_list(&link_info);
link_info = NULL;
}
out:
return;
return;
}
/* Function to add linkinfo to the query record */
int
gfdb_add_link_to_query_record (gfdb_query_record_t *query_record,
uuid_t pgfid,
char *base_name)
gfdb_add_link_to_query_record(gfdb_query_record_t *query_record, uuid_t pgfid,
char *base_name)
{
int ret = -1;
gfdb_link_info_t *link_info = NULL;
int base_name_len = 0;
int ret = -1;
gfdb_link_info_t *link_info = NULL;
int base_name_len = 0;
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, pgfid, out);
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, base_name, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, pgfid, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, base_name, out);
link_info = gfdb_link_info_new ();
if (!link_info) {
goto out;
}
link_info = gfdb_link_info_new();
if (!link_info) {
goto out;
}
gf_uuid_copy (link_info->pargfid, pgfid);
base_name_len = strlen (base_name);
memcpy (link_info->file_name, base_name, base_name_len);
link_info->file_name[base_name_len] = '\0';
gf_uuid_copy(link_info->pargfid, pgfid);
base_name_len = strlen(base_name);
memcpy(link_info->file_name, base_name, base_name_len);
link_info->file_name[base_name_len] = '\0';
list_add_tail (&link_info->list,
&query_record->link_list);
list_add_tail(&link_info->list, &query_record->link_list);
query_record->link_count++;
query_record->link_count++;
ret = 0;
ret = 0;
out:
if (ret) {
gfdb_link_info_free (link_info);
link_info = NULL;
}
return ret;
if (ret) {
gfdb_link_info_free(link_info);
link_info = NULL;
}
return ret;
}
/*Function to destroy query record*/
void
gfdb_query_record_free(gfdb_query_record_t *query_record)
{
if (query_record) {
gfdb_free_link_info_list (query_record);
GF_FREE (query_record);
}
if (query_record) {
gfdb_free_link_info_list(query_record);
GF_FREE(query_record);
}
}
/******************************************************************************
SERIALIZATION/DE-SERIALIZATION OF QUERY RECORD
*******************************************************************************/
@ -197,40 +185,39 @@ gfdb_query_record_free(gfdb_query_record_t *query_record)
* ****************************************************************************/
#define GFDB_QUERY_RECORD_FOOTER 0xBAADF00D
#define UUID_LEN 16
#define UUID_LEN 16
/*Function to get the potential length of the serialized buffer*/
static int32_t
gfdb_query_record_serialized_length (gfdb_query_record_t *query_record)
gfdb_query_record_serialized_length(gfdb_query_record_t *query_record)
{
int32_t len = -1;
gfdb_link_info_t *link_info = NULL;
int32_t len = -1;
gfdb_link_info_t *link_info = NULL;
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out);
/* Length of GFID */
len = UUID_LEN;
/* Length of GFID */
len = UUID_LEN;
/* length of number of links*/
len += sizeof (int32_t);
/* length of number of links*/
len += sizeof(int32_t);
list_for_each_entry (link_info, &query_record->link_list, list) {
list_for_each_entry(link_info, &query_record->link_list, list)
{
/* length of PFID */
len += UUID_LEN;
/* length of PFID */
len += UUID_LEN;
/* Add size of base name length*/
len += sizeof(int32_t);
/* Add size of base name length*/
len += sizeof (int32_t);
/* Length of base_name */
len += strlen(link_info->file_name);
}
/* Length of base_name */
len += strlen (link_info->file_name);
}
/* length of footer */
len += sizeof (int32_t);
/* length of footer */
len += sizeof(int32_t);
out:
return len;
return len;
}
/* Function for serializing query record.
@ -259,211 +246,201 @@ out:
*
* */
static int
gfdb_query_record_serialize (gfdb_query_record_t *query_record,
char **in_buffer)
gfdb_query_record_serialize(gfdb_query_record_t *query_record, char **in_buffer)
{
gfdb_link_info_t *link_info = NULL;
int count = -1;
int base_name_len = 0;
int buffer_length = 0;
int footer = GFDB_QUERY_RECORD_FOOTER;
char *buffer = NULL;
char *ret_buffer = NULL;
gfdb_link_info_t *link_info = NULL;
int count = -1;
int base_name_len = 0;
int buffer_length = 0;
int footer = GFDB_QUERY_RECORD_FOOTER;
char *buffer = NULL;
char *ret_buffer = NULL;
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE,
(query_record->link_count > 0), out);
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, in_buffer, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, (query_record->link_count > 0), out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, in_buffer, out);
/* Calculate the total length of the serialized buffer */
buffer_length = gfdb_query_record_serialized_length(query_record);
if (buffer_length <= 0) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Failed to calculate the length of "
"serialized buffer");
goto out;
}
/* Calculate the total length of the serialized buffer */
buffer_length = gfdb_query_record_serialized_length (query_record);
if (buffer_length <= 0) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Failed to calculate the length of "
"serialized buffer");
goto out;
}
/* Allocate memory to the serialized buffer */
ret_buffer = GF_CALLOC(1, buffer_length, gf_common_mt_char);
if (!ret_buffer) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Memory allocation failed for "
"serialized buffer.");
goto out;
}
/* Allocate memory to the serialized buffer */
ret_buffer = GF_CALLOC (1, buffer_length, gf_common_mt_char);
if (!ret_buffer) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Memory allocation failed for "
"serialized buffer.");
goto out;
}
buffer = ret_buffer;
buffer = ret_buffer;
count = 0;
count = 0;
/* Copying the GFID */
memcpy(buffer, query_record->gfid, UUID_LEN);
buffer += UUID_LEN;
count += UUID_LEN;
/* Copying the GFID */
memcpy (buffer, query_record->gfid, UUID_LEN);
/* Copying the number of links */
memcpy(buffer, &query_record->link_count, sizeof(int32_t));
buffer += sizeof(int32_t);
count += sizeof(int32_t);
list_for_each_entry(link_info, &query_record->link_list, list)
{
/* Copying the PFID */
memcpy(buffer, link_info->pargfid, UUID_LEN);
buffer += UUID_LEN;
count += UUID_LEN;
/* Copying the number of links */
memcpy (buffer, &query_record->link_count, sizeof (int32_t));
buffer += sizeof (int32_t);
count += sizeof (int32_t);
/* Copying base name length*/
base_name_len = strlen(link_info->file_name);
memcpy(buffer, &base_name_len, sizeof(int32_t));
buffer += sizeof(int32_t);
count += sizeof(int32_t);
list_for_each_entry (link_info, &query_record->link_list, list) {
/* Length of base_name */
memcpy(buffer, link_info->file_name, base_name_len);
buffer += base_name_len;
count += base_name_len;
}
/* Copying the PFID */
memcpy(buffer, link_info->pargfid, UUID_LEN);
buffer += UUID_LEN;
count += UUID_LEN;
/* Copying base name length*/
base_name_len = strlen (link_info->file_name);
memcpy (buffer, &base_name_len, sizeof (int32_t));
buffer += sizeof (int32_t);
count += sizeof (int32_t);
/* Length of base_name */
memcpy(buffer, link_info->file_name, base_name_len);
buffer += base_name_len;
count += base_name_len;
}
/* Copying the Footer of the record */
memcpy (buffer, &footer, sizeof (int32_t));
buffer += sizeof (int32_t);
count += sizeof (int32_t);
/* Copying the Footer of the record */
memcpy(buffer, &footer, sizeof(int32_t));
buffer += sizeof(int32_t);
count += sizeof(int32_t);
out:
if (count < 0) {
GF_FREE (ret_buffer);
ret_buffer = NULL;
}
*in_buffer = ret_buffer;
return count;
if (count < 0) {
GF_FREE(ret_buffer);
ret_buffer = NULL;
}
*in_buffer = ret_buffer;
return count;
}
static gf_boolean_t
is_serialized_buffer_valid (char *in_buffer, int buffer_length) {
gf_boolean_t ret = _gf_false;
int footer = 0;
is_serialized_buffer_valid(char *in_buffer, int buffer_length)
{
gf_boolean_t ret = _gf_false;
int footer = 0;
/* Read the footer */
in_buffer += (buffer_length - sizeof (int32_t));
memcpy (&footer, in_buffer, sizeof (int32_t));
/* Read the footer */
in_buffer += (buffer_length - sizeof(int32_t));
memcpy(&footer, in_buffer, sizeof(int32_t));
/*
* if the footer is not GFDB_QUERY_RECORD_FOOTER
* then the serialized record is invalid
*
* */
if (footer != GFDB_QUERY_RECORD_FOOTER) {
goto out;
}
/*
* if the footer is not GFDB_QUERY_RECORD_FOOTER
* then the serialized record is invalid
*
* */
if (footer != GFDB_QUERY_RECORD_FOOTER) {
goto out;
}
ret = _gf_true;
ret = _gf_true;
out:
return ret;
return ret;
}
static int
gfdb_query_record_deserialize (char *in_buffer,
int buffer_length,
gfdb_query_record_t **query_record)
gfdb_query_record_deserialize(char *in_buffer, int buffer_length,
gfdb_query_record_t **query_record)
{
int ret = -1;
char *buffer = NULL;
int i = 0;
gfdb_link_info_t *link_info = NULL;
int count = 0;
int base_name_len = 0;
gfdb_query_record_t *ret_qrecord = NULL;
int ret = -1;
char *buffer = NULL;
int i = 0;
gfdb_link_info_t *link_info = NULL;
int count = 0;
int base_name_len = 0;
gfdb_query_record_t *ret_qrecord = NULL;
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, in_buffer, out);
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, (buffer_length > 0), out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, in_buffer, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, (buffer_length > 0), out);
if (!is_serialized_buffer_valid (in_buffer, buffer_length)) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Invalid serialized query record");
goto out;
if (!is_serialized_buffer_valid(in_buffer, buffer_length)) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Invalid serialized query record");
goto out;
}
buffer = in_buffer;
ret_qrecord = gfdb_query_record_new();
if (!ret_qrecord) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Failed to allocate space to "
"gfdb_query_record_t");
goto out;
}
/* READ GFID */
memcpy((ret_qrecord)->gfid, buffer, UUID_LEN);
buffer += UUID_LEN;
count += UUID_LEN;
/* Read the number of link */
memcpy(&(ret_qrecord->link_count), buffer, sizeof(int32_t));
buffer += sizeof(int32_t);
count += sizeof(int32_t);
/* Read all the links */
for (i = 0; i < ret_qrecord->link_count; i++) {
if (count >= buffer_length) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Invalid serialized "
"query record");
ret = -1;
goto out;
}
buffer = in_buffer;
ret_qrecord = gfdb_query_record_new ();
if (!ret_qrecord) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Failed to allocate space to "
"gfdb_query_record_t");
goto out;
link_info = gfdb_link_info_new();
if (!link_info) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Failed to create link_info");
goto out;
}
/* READ GFID */
memcpy ((ret_qrecord)->gfid, buffer, UUID_LEN);
/* READ PGFID */
memcpy(link_info->pargfid, buffer, UUID_LEN);
buffer += UUID_LEN;
count += UUID_LEN;
/* Read the number of link */
memcpy (&(ret_qrecord->link_count), buffer, sizeof (int32_t));
buffer += sizeof (int32_t);
count += sizeof (int32_t);
/* Read base name length */
memcpy(&base_name_len, buffer, sizeof(int32_t));
buffer += sizeof(int32_t);
count += sizeof(int32_t);
/* Read all the links */
for (i = 0; i < ret_qrecord->link_count; i++) {
if (count >= buffer_length) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Invalid serialized "
"query record");
ret = -1;
goto out;
}
/* READ basename */
memcpy(link_info->file_name, buffer, base_name_len);
buffer += base_name_len;
count += base_name_len;
link_info->file_name[base_name_len] = '\0';
link_info = gfdb_link_info_new ();
if (!link_info) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Failed to create link_info");
goto out;
}
/* Add link_info to the list */
list_add_tail(&link_info->list, &(ret_qrecord->link_list));
/* READ PGFID */
memcpy (link_info->pargfid, buffer, UUID_LEN);
buffer += UUID_LEN;
count += UUID_LEN;
/* Resetting link_info */
link_info = NULL;
}
/* Read base name length */
memcpy (&base_name_len, buffer, sizeof (int32_t));
buffer += sizeof (int32_t);
count += sizeof (int32_t);
/* READ basename */
memcpy (link_info->file_name, buffer, base_name_len);
buffer += base_name_len;
count += base_name_len;
link_info->file_name[base_name_len] = '\0';
/* Add link_info to the list */
list_add_tail (&link_info->list,
&(ret_qrecord->link_list));
/* Resetting link_info */
link_info = NULL;
}
ret = 0;
ret = 0;
out:
if (ret) {
gfdb_query_record_free (ret_qrecord);
ret_qrecord = NULL;
}
*query_record = ret_qrecord;
return ret;
if (ret) {
gfdb_query_record_free(ret_qrecord);
ret_qrecord = NULL;
}
*query_record = ret_qrecord;
return ret;
}
/* Function to write query record to file
*
* Disk format
@ -477,57 +454,54 @@ out:
*
* */
int
gfdb_write_query_record (int fd,
gfdb_query_record_t *query_record)
gfdb_write_query_record(int fd, gfdb_query_record_t *query_record)
{
int ret = -1;
int buffer_len = 0;
char *buffer = NULL;
int write_len = 0;
char *write_buffer = NULL;
int ret = -1;
int buffer_len = 0;
char *buffer = NULL;
int write_len = 0;
char *write_buffer = NULL;
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, (fd >= 0), out);
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, (fd >= 0), out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out);
buffer_len = gfdb_query_record_serialize (query_record, &buffer);
if (buffer_len < 0) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Failed to serialize query record");
goto out;
}
buffer_len = gfdb_query_record_serialize(query_record, &buffer);
if (buffer_len < 0) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Failed to serialize query record");
goto out;
}
/* Serialize the buffer length and write to file */
ret = write (fd, &buffer_len, sizeof (int32_t));
/* Serialize the buffer length and write to file */
ret = write(fd, &buffer_len, sizeof(int32_t));
if (ret < 0) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Failed to write buffer length"
" to file");
goto out;
}
/* Write the serialized query record to file */
write_len = buffer_len;
write_buffer = buffer;
while ((ret = write(fd, write_buffer, write_len)) < write_len) {
if (ret < 0) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Failed to write buffer length"
" to file");
goto out;
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, errno, LG_MSG_DB_ERROR,
"Failed to write serialized "
"query record to file");
goto out;
}
/* Write the serialized query record to file */
write_len = buffer_len;
write_buffer = buffer;
while ((ret = write (fd, write_buffer, write_len)) < write_len) {
if (ret < 0) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, errno,
LG_MSG_DB_ERROR, "Failed to write serialized "
"query record to file");
goto out;
}
write_buffer += ret;
write_len -= ret;
}
write_buffer += ret;
write_len -= ret;
}
ret = 0;
ret = 0;
out:
GF_FREE (buffer);
return ret;
GF_FREE(buffer);
return ret;
}
/* Function to read query record from file.
* Allocates memory to query record and
* returns length of serialized query record when successful
@ -535,86 +509,81 @@ out:
* Return 0 when reached EOF.
* */
int
gfdb_read_query_record (int fd,
gfdb_query_record_t **query_record)
gfdb_read_query_record(int fd, gfdb_query_record_t **query_record)
{
int ret = -1;
int buffer_len = 0;
int read_len = 0;
char *buffer = NULL;
char *read_buffer = NULL;
int ret = -1;
int buffer_len = 0;
int read_len = 0;
char *buffer = NULL;
char *read_buffer = NULL;
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, (fd >= 0), out);
GF_VALIDATE_OR_GOTO (GFDB_DATA_STORE, query_record, out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, (fd >= 0), out);
GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out);
/* Read serialized query record length from the file*/
ret = sys_read(fd, &buffer_len, sizeof(int32_t));
if (ret < 0) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Failed reading buffer length"
" from file");
goto out;
}
/* EOF */
else if (ret == 0) {
ret = 0;
goto out;
}
/* Read serialized query record length from the file*/
ret = sys_read (fd, &buffer_len, sizeof (int32_t));
/* Assumed sane range is 1B - 10MB */
if ((buffer_len <= 0) || (buffer_len > (10 * 1024 * 1024))) {
ret = -1;
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"buffer length range is out of bound %d", buffer_len);
goto out;
}
/* Allocating memory to the serialization buffer */
buffer = GF_CALLOC(1, buffer_len, gf_common_mt_char);
if (!buffer) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Failed to allocate space to "
"serialized buffer");
goto out;
}
/* Read the serialized query record from file */
read_len = buffer_len;
read_buffer = buffer;
while ((ret = sys_read(fd, read_buffer, read_len)) < read_len) {
/*Any error */
if (ret < 0) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Failed reading buffer length"
" from file");
goto out;
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, errno, LG_MSG_DB_ERROR,
"Failed to read serialized "
"query record from file");
goto out;
}
/* EOF */
else if (ret == 0) {
ret = 0;
goto out;
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Invalid query record or "
"corrupted query file");
ret = -1;
goto out;
}
/* Assumed sane range is 1B - 10MB */
if ((buffer_len <= 0) || (buffer_len > (10 * 1024 * 1024))) {
ret = -1;
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"buffer length range is out of bound %d", buffer_len);
goto out;
}
read_buffer += ret;
read_len -= ret;
}
/* Allocating memory to the serialization buffer */
buffer = GF_CALLOC (1, buffer_len, gf_common_mt_char);
if (!buffer) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Failed to allocate space to "
"serialized buffer");
goto out;
}
ret = gfdb_query_record_deserialize(buffer, buffer_len, query_record);
if (ret) {
gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
"Failed to de-serialize query record");
goto out;
}
/* Read the serialized query record from file */
read_len = buffer_len;
read_buffer = buffer;
while ((ret = sys_read (fd, read_buffer, read_len)) < read_len) {
/*Any error */
if (ret < 0) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, errno,
LG_MSG_DB_ERROR, "Failed to read serialized "
"query record from file");
goto out;
}
/* EOF */
else if (ret == 0) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Invalid query record or "
"corrupted query file");
ret = -1;
goto out;
}
read_buffer += ret;
read_len -= ret;
}
ret = gfdb_query_record_deserialize (buffer, buffer_len,
query_record);
if (ret) {
gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
LG_MSG_DB_ERROR, "Failed to de-serialize query record");
goto out;
}
ret = buffer_len;
ret = buffer_len;
out:
GF_FREE (buffer);
return ret;
GF_FREE(buffer);
return ret;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,37 +16,39 @@
* out after a configurable interval. Hardly rocket science, but lots of
* details to worry about.
*/
#define BUCKET_START(p,n) ((p) + ((n) * AUX_GID_CACHE_ASSOC))
#define BUCKET_START(p, n) ((p) + ((n)*AUX_GID_CACHE_ASSOC))
/*
* Initialize the cache.
*/
int gid_cache_init(gid_cache_t *cache, uint32_t timeout)
int
gid_cache_init(gid_cache_t *cache, uint32_t timeout)
{
if (!cache)
return -1;
if (!cache)
return -1;
LOCK_INIT(&cache->gc_lock);
cache->gc_max_age = timeout;
cache->gc_nbuckets = AUX_GID_CACHE_BUCKETS;
memset(cache->gc_cache, 0, sizeof(gid_list_t) * AUX_GID_CACHE_SIZE);
LOCK_INIT(&cache->gc_lock);
cache->gc_max_age = timeout;
cache->gc_nbuckets = AUX_GID_CACHE_BUCKETS;
memset(cache->gc_cache, 0, sizeof(gid_list_t) * AUX_GID_CACHE_SIZE);
return 0;
return 0;
}
/*
* Reconfigure the cache timeout.
*/
int gid_cache_reconf(gid_cache_t *cache, uint32_t timeout)
int
gid_cache_reconf(gid_cache_t *cache, uint32_t timeout)
{
if (!cache)
return -1;
if (!cache)
return -1;
LOCK(&cache->gc_lock);
cache->gc_max_age = timeout;
UNLOCK(&cache->gc_lock);
LOCK(&cache->gc_lock);
cache->gc_max_age = timeout;
UNLOCK(&cache->gc_lock);
return 0;
return 0;
}
/*
@ -54,153 +56,155 @@ int gid_cache_reconf(gid_cache_t *cache, uint32_t timeout)
* an additional allocation and memory copy. The caller should copy the data and
* release (unlock) the cache as soon as possible.
*/
const gid_list_t *gid_cache_lookup(gid_cache_t *cache, uint64_t id,
uint64_t uid, uint64_t gid)
const gid_list_t *
gid_cache_lookup(gid_cache_t *cache, uint64_t id, uint64_t uid, uint64_t gid)
{
int bucket;
int i;
time_t now;
const gid_list_t *agl;
int bucket;
int i;
time_t now;
const gid_list_t *agl;
LOCK(&cache->gc_lock);
now = time(NULL);
bucket = id % cache->gc_nbuckets;
agl = BUCKET_START(cache->gc_cache, bucket);
for (i = 0; i < AUX_GID_CACHE_ASSOC; i++, agl++) {
if (!agl->gl_list)
continue;
if (agl->gl_id != id)
continue;
LOCK(&cache->gc_lock);
now = time(NULL);
bucket = id % cache->gc_nbuckets;
agl = BUCKET_START(cache->gc_cache, bucket);
for (i = 0; i < AUX_GID_CACHE_ASSOC; i++, agl++) {
if (!agl->gl_list)
continue;
if (agl->gl_id != id)
continue;
/*
@uid and @gid reflect the latest UID/GID of the
process performing the syscall (taken from frame->root).
/*
@uid and @gid reflect the latest UID/GID of the
process performing the syscall (taken from frame->root).
If the UID and GID has changed for the PID since the
time we cached it, we should treat the cache as having
stale values and query them freshly.
*/
if (agl->gl_uid != uid || agl->gl_gid != gid)
break;
If the UID and GID has changed for the PID since the
time we cached it, we should treat the cache as having
stale values and query them freshly.
*/
if (agl->gl_uid != uid || agl->gl_gid != gid)
break;
/*
* We don't put new entries in the cache when expiration=0, but
* there might be entries still in there if expiration was
* changed very recently. Writing the check this way ensures
* that they're not used.
*/
if (now < agl->gl_deadline) {
return agl;
}
/*
* We don't put new entries in the cache when expiration=0, but
* there might be entries still in there if expiration was
* changed very recently. Writing the check this way ensures
* that they're not used.
*/
if (now < agl->gl_deadline) {
return agl;
}
/*
* We're not going to find any more UID matches, and reaping
* is handled further down to maintain LRU order.
*/
break;
}
UNLOCK(&cache->gc_lock);
return NULL;
/*
* We're not going to find any more UID matches, and reaping
* is handled further down to maintain LRU order.
*/
break;
}
UNLOCK(&cache->gc_lock);
return NULL;
}
/*
* Release an entry found via lookup.
*/
void gid_cache_release(gid_cache_t *cache, const gid_list_t *agl)
void
gid_cache_release(gid_cache_t *cache, const gid_list_t *agl)
{
UNLOCK(&cache->gc_lock);
UNLOCK(&cache->gc_lock);
}
/*
* Add a new list entry to the cache. If an entry for this ID already exists,
* update it.
*/
int gid_cache_add(gid_cache_t *cache, gid_list_t *gl)
int
gid_cache_add(gid_cache_t *cache, gid_list_t *gl)
{
gid_list_t *agl;
int bucket;
int i;
time_t now;
gid_list_t *agl;
int bucket;
int i;
time_t now;
if (!gl || !gl->gl_list)
return -1;
if (!gl || !gl->gl_list)
return -1;
if (!cache->gc_max_age)
return 0;
if (!cache->gc_max_age)
return 0;
LOCK(&cache->gc_lock);
now = time(NULL);
LOCK(&cache->gc_lock);
now = time(NULL);
/*
* Scan for the first free entry or one that matches this id. The id
* check is added to address a bug where the cache might contain an
* expired entry for this id. Since lookup occurs in LRU order and
* does not reclaim entries, it will always return failure on discovery
* of an expired entry. This leads to duplicate entries being added,
* which still do not satisfy lookups until the expired entry (and
* everything before it) is reclaimed.
*
* We address this through reuse of an entry already allocated to this
* id, whether expired or not, since we have obviously already received
* more recent data. The entry is repopulated with the new data and a new
* deadline and is pushed forward to reside as the last populated entry in
* the bucket.
*/
bucket = gl->gl_id % cache->gc_nbuckets;
agl = BUCKET_START(cache->gc_cache, bucket);
for (i = 0; i < AUX_GID_CACHE_ASSOC; ++i, ++agl) {
if (agl->gl_id == gl->gl_id)
break;
if (!agl->gl_list)
break;
}
/*
* Scan for the first free entry or one that matches this id. The id
* check is added to address a bug where the cache might contain an
* expired entry for this id. Since lookup occurs in LRU order and
* does not reclaim entries, it will always return failure on discovery
* of an expired entry. This leads to duplicate entries being added,
* which still do not satisfy lookups until the expired entry (and
* everything before it) is reclaimed.
*
* We address this through reuse of an entry already allocated to this
* id, whether expired or not, since we have obviously already received
* more recent data. The entry is repopulated with the new data and a new
* deadline and is pushed forward to reside as the last populated entry in
* the bucket.
*/
bucket = gl->gl_id % cache->gc_nbuckets;
agl = BUCKET_START(cache->gc_cache, bucket);
for (i = 0; i < AUX_GID_CACHE_ASSOC; ++i, ++agl) {
if (agl->gl_id == gl->gl_id)
break;
if (!agl->gl_list)
break;
}
/*
* The way we allocate free entries naturally places the newest
* ones at the highest indices, so evicting the lowest makes
* sense, but that also means we can't just replace it with the
* one that caused the eviction. That would cause us to thrash
* the first entry while others remain idle. Therefore, we
* need to slide the other entries down and add the new one at
* the end just as if the *last* slot had been free.
*
* Deadline expiration is also handled here, since the oldest
* expired entry will be in the first position. This does mean
* the bucket can stay full of expired entries if we're idle
* but, if the small amount of extra memory or scan time before
* we decide to evict someone ever become issues, we could
* easily add a reaper thread.
*/
/*
* The way we allocate free entries naturally places the newest
* ones at the highest indices, so evicting the lowest makes
* sense, but that also means we can't just replace it with the
* one that caused the eviction. That would cause us to thrash
* the first entry while others remain idle. Therefore, we
* need to slide the other entries down and add the new one at
* the end just as if the *last* slot had been free.
*
* Deadline expiration is also handled here, since the oldest
* expired entry will be in the first position. This does mean
* the bucket can stay full of expired entries if we're idle
* but, if the small amount of extra memory or scan time before
* we decide to evict someone ever become issues, we could
* easily add a reaper thread.
*/
if (i >= AUX_GID_CACHE_ASSOC) {
/* cache full, evict the first (LRU) entry */
i = 0;
agl = BUCKET_START(cache->gc_cache, bucket);
GF_FREE(agl->gl_list);
} else if (agl->gl_list) {
/* evict the old entry we plan to reuse */
GF_FREE(agl->gl_list);
}
if (i >= AUX_GID_CACHE_ASSOC) {
/* cache full, evict the first (LRU) entry */
i = 0;
agl = BUCKET_START(cache->gc_cache, bucket);
GF_FREE(agl->gl_list);
} else if (agl->gl_list) {
/* evict the old entry we plan to reuse */
GF_FREE(agl->gl_list);
}
/*
* If we have evicted an entry, slide the subsequent populated entries
* back and populate the last entry.
*/
for (; i < AUX_GID_CACHE_ASSOC - 1; i++) {
if (!agl[1].gl_list)
break;
agl[0] = agl[1];
agl++;
}
/*
* If we have evicted an entry, slide the subsequent populated entries
* back and populate the last entry.
*/
for (; i < AUX_GID_CACHE_ASSOC - 1; i++) {
if (!agl[1].gl_list)
break;
agl[0] = agl[1];
agl++;
}
agl->gl_id = gl->gl_id;
agl->gl_uid = gl->gl_uid;
agl->gl_gid = gl->gl_gid;
agl->gl_count = gl->gl_count;
agl->gl_list = gl->gl_list;
agl->gl_deadline = now + cache->gc_max_age;
agl->gl_id = gl->gl_id;
agl->gl_uid = gl->gl_uid;
agl->gl_gid = gl->gl_gid;
agl->gl_count = gl->gl_count;
agl->gl_list = gl->gl_list;
agl->gl_deadline = now + cache->gc_max_age;
UNLOCK(&cache->gc_lock);
UNLOCK(&cache->gc_lock);
return 1;
return 1;
}

View File

@ -19,75 +19,75 @@
#include "upcall-utils.h"
const char *gf_fop_list[GF_FOP_MAXVALUE] = {
[GF_FOP_NULL] = "NULL",
[GF_FOP_STAT] = "STAT",
[GF_FOP_READLINK] = "READLINK",
[GF_FOP_MKNOD] = "MKNOD",
[GF_FOP_MKDIR] = "MKDIR",
[GF_FOP_UNLINK] = "UNLINK",
[GF_FOP_RMDIR] = "RMDIR",
[GF_FOP_SYMLINK] = "SYMLINK",
[GF_FOP_RENAME] = "RENAME",
[GF_FOP_LINK] = "LINK",
[GF_FOP_TRUNCATE] = "TRUNCATE",
[GF_FOP_OPEN] = "OPEN",
[GF_FOP_READ] = "READ",
[GF_FOP_WRITE] = "WRITE",
[GF_FOP_STATFS] = "STATFS",
[GF_FOP_FLUSH] = "FLUSH",
[GF_FOP_FSYNC] = "FSYNC",
[GF_FOP_SETXATTR] = "SETXATTR",
[GF_FOP_GETXATTR] = "GETXATTR",
[GF_FOP_REMOVEXATTR] = "REMOVEXATTR",
[GF_FOP_OPENDIR] = "OPENDIR",
[GF_FOP_FSYNCDIR] = "FSYNCDIR",
[GF_FOP_ACCESS] = "ACCESS",
[GF_FOP_CREATE] = "CREATE",
[GF_FOP_FTRUNCATE] = "FTRUNCATE",
[GF_FOP_FSTAT] = "FSTAT",
[GF_FOP_LK] = "LK",
[GF_FOP_LOOKUP] = "LOOKUP",
[GF_FOP_READDIR] = "READDIR",
[GF_FOP_INODELK] = "INODELK",
[GF_FOP_FINODELK] = "FINODELK",
[GF_FOP_ENTRYLK] = "ENTRYLK",
[GF_FOP_FENTRYLK] = "FENTRYLK",
[GF_FOP_XATTROP] = "XATTROP",
[GF_FOP_FXATTROP] = "FXATTROP",
[GF_FOP_FSETXATTR] = "FSETXATTR",
[GF_FOP_FGETXATTR] = "FGETXATTR",
[GF_FOP_RCHECKSUM] = "RCHECKSUM",
[GF_FOP_SETATTR] = "SETATTR",
[GF_FOP_FSETATTR] = "FSETATTR",
[GF_FOP_READDIRP] = "READDIRP",
[GF_FOP_GETSPEC] = "GETSPEC",
[GF_FOP_FORGET] = "FORGET",
[GF_FOP_RELEASE] = "RELEASE",
[GF_FOP_RELEASEDIR] = "RELEASEDIR",
[GF_FOP_FREMOVEXATTR]= "FREMOVEXATTR",
[GF_FOP_FALLOCATE] = "FALLOCATE",
[GF_FOP_DISCARD] = "DISCARD",
[GF_FOP_ZEROFILL] = "ZEROFILL",
[GF_FOP_IPC] = "IPC",
[GF_FOP_SEEK] = "SEEK",
[GF_FOP_LEASE] = "LEASE",
[GF_FOP_COMPOUND] = "COMPOUND",
[GF_FOP_GETACTIVELK] = "GETACTIVELK",
[GF_FOP_SETACTIVELK] = "SETACTIVELK",
[GF_FOP_PUT] = "PUT",
[GF_FOP_ICREATE] = "ICREATE",
[GF_FOP_NAMELINK] = "NAMELINK",
[GF_FOP_NULL] = "NULL",
[GF_FOP_STAT] = "STAT",
[GF_FOP_READLINK] = "READLINK",
[GF_FOP_MKNOD] = "MKNOD",
[GF_FOP_MKDIR] = "MKDIR",
[GF_FOP_UNLINK] = "UNLINK",
[GF_FOP_RMDIR] = "RMDIR",
[GF_FOP_SYMLINK] = "SYMLINK",
[GF_FOP_RENAME] = "RENAME",
[GF_FOP_LINK] = "LINK",
[GF_FOP_TRUNCATE] = "TRUNCATE",
[GF_FOP_OPEN] = "OPEN",
[GF_FOP_READ] = "READ",
[GF_FOP_WRITE] = "WRITE",
[GF_FOP_STATFS] = "STATFS",
[GF_FOP_FLUSH] = "FLUSH",
[GF_FOP_FSYNC] = "FSYNC",
[GF_FOP_SETXATTR] = "SETXATTR",
[GF_FOP_GETXATTR] = "GETXATTR",
[GF_FOP_REMOVEXATTR] = "REMOVEXATTR",
[GF_FOP_OPENDIR] = "OPENDIR",
[GF_FOP_FSYNCDIR] = "FSYNCDIR",
[GF_FOP_ACCESS] = "ACCESS",
[GF_FOP_CREATE] = "CREATE",
[GF_FOP_FTRUNCATE] = "FTRUNCATE",
[GF_FOP_FSTAT] = "FSTAT",
[GF_FOP_LK] = "LK",
[GF_FOP_LOOKUP] = "LOOKUP",
[GF_FOP_READDIR] = "READDIR",
[GF_FOP_INODELK] = "INODELK",
[GF_FOP_FINODELK] = "FINODELK",
[GF_FOP_ENTRYLK] = "ENTRYLK",
[GF_FOP_FENTRYLK] = "FENTRYLK",
[GF_FOP_XATTROP] = "XATTROP",
[GF_FOP_FXATTROP] = "FXATTROP",
[GF_FOP_FSETXATTR] = "FSETXATTR",
[GF_FOP_FGETXATTR] = "FGETXATTR",
[GF_FOP_RCHECKSUM] = "RCHECKSUM",
[GF_FOP_SETATTR] = "SETATTR",
[GF_FOP_FSETATTR] = "FSETATTR",
[GF_FOP_READDIRP] = "READDIRP",
[GF_FOP_GETSPEC] = "GETSPEC",
[GF_FOP_FORGET] = "FORGET",
[GF_FOP_RELEASE] = "RELEASE",
[GF_FOP_RELEASEDIR] = "RELEASEDIR",
[GF_FOP_FREMOVEXATTR] = "FREMOVEXATTR",
[GF_FOP_FALLOCATE] = "FALLOCATE",
[GF_FOP_DISCARD] = "DISCARD",
[GF_FOP_ZEROFILL] = "ZEROFILL",
[GF_FOP_IPC] = "IPC",
[GF_FOP_SEEK] = "SEEK",
[GF_FOP_LEASE] = "LEASE",
[GF_FOP_COMPOUND] = "COMPOUND",
[GF_FOP_GETACTIVELK] = "GETACTIVELK",
[GF_FOP_SETACTIVELK] = "SETACTIVELK",
[GF_FOP_PUT] = "PUT",
[GF_FOP_ICREATE] = "ICREATE",
[GF_FOP_NAMELINK] = "NAMELINK",
};
const char *gf_upcall_list[GF_UPCALL_FLAGS_MAXVALUE] = {
[GF_UPCALL_NULL] = "NULL",
[GF_UPCALL] = "UPCALL",
[GF_UPCALL_CI_STAT] = "CI_IATT",
[GF_UPCALL_CI_XATTR] = "CI_XATTR",
[GF_UPCALL_CI_RENAME] = "CI_RENAME",
[GF_UPCALL_CI_NLINK] = "CI_UNLINK",
[GF_UPCALL_CI_FORGET] = "CI_FORGET",
[GF_UPCALL_LEASE_RECALL] = "LEASE_RECALL",
[GF_UPCALL_NULL] = "NULL",
[GF_UPCALL] = "UPCALL",
[GF_UPCALL_CI_STAT] = "CI_IATT",
[GF_UPCALL_CI_XATTR] = "CI_XATTR",
[GF_UPCALL_CI_RENAME] = "CI_RENAME",
[GF_UPCALL_CI_NLINK] = "CI_UNLINK",
[GF_UPCALL_CI_FORGET] = "CI_FORGET",
[GF_UPCALL_LEASE_RECALL] = "LEASE_RECALL",
};
/* THIS */
@ -101,461 +101,452 @@ xlator_t global_xlator;
static pthread_key_t this_xlator_key;
static pthread_key_t synctask_key;
static pthread_key_t uuid_buf_key;
static char global_uuid_buf[GF_UUID_BUF_SIZE];
static char global_uuid_buf[GF_UUID_BUF_SIZE];
static pthread_key_t lkowner_buf_key;
static char global_lkowner_buf[GF_LKOWNER_BUF_SIZE];
static char global_lkowner_buf[GF_LKOWNER_BUF_SIZE];
static pthread_key_t leaseid_buf_key;
static int gf_global_mem_acct_enable = 1;
static pthread_once_t globals_inited = PTHREAD_ONCE_INIT;
int
gf_global_mem_acct_enable_get (void)
gf_global_mem_acct_enable_get(void)
{
return gf_global_mem_acct_enable;
return gf_global_mem_acct_enable;
}
int
gf_global_mem_acct_enable_set (int val)
gf_global_mem_acct_enable_set(int val)
{
gf_global_mem_acct_enable = val;
return 0;
gf_global_mem_acct_enable = val;
return 0;
}
void
glusterfs_this_destroy (void *ptr)
glusterfs_this_destroy(void *ptr)
{
FREE (ptr);
FREE(ptr);
}
static struct xlator_cbks global_cbks = {
.forget = NULL,
.release = NULL,
.releasedir = NULL,
.invalidate = NULL,
.client_destroy = NULL,
.client_disconnect = NULL,
.ictxmerge = NULL,
.ictxsize = NULL,
.fdctxsize = NULL,
.forget = NULL,
.release = NULL,
.releasedir = NULL,
.invalidate = NULL,
.client_destroy = NULL,
.client_disconnect = NULL,
.ictxmerge = NULL,
.ictxsize = NULL,
.fdctxsize = NULL,
};
/* This is required to get through the check in graph.c */
static struct xlator_fops global_fops = {
};
static struct xlator_fops global_fops = {};
static int
global_xl_reconfigure (xlator_t *this, dict_t *options)
global_xl_reconfigure(xlator_t *this, dict_t *options)
{
int ret = -1;
gf_boolean_t bool_opt = _gf_false;
int ret = -1;
gf_boolean_t bool_opt = _gf_false;
/* This is not added in volume dump, hence adding the options in log
would be helpful for debugging later */
dict_dump_to_log (options);
/* This is not added in volume dump, hence adding the options in log
would be helpful for debugging later */
dict_dump_to_log(options);
GF_OPTION_RECONF ("measure-latency", bool_opt, options, bool, out);
this->ctx->measure_latency = bool_opt;
GF_OPTION_RECONF("measure-latency", bool_opt, options, bool, out);
this->ctx->measure_latency = bool_opt;
GF_OPTION_RECONF ("metrics-dump-path", this->ctx->config.metrics_dumppath,
options, str, out);
GF_OPTION_RECONF("metrics-dump-path", this->ctx->config.metrics_dumppath,
options, str, out);
/* TODO: add more things here */
ret = 0;
/* TODO: add more things here */
ret = 0;
out:
return ret;
return ret;
}
static int
global_xl_init (xlator_t *this)
global_xl_init(xlator_t *this)
{
int ret = -1;
gf_boolean_t bool_opt = false;
int ret = -1;
gf_boolean_t bool_opt = false;
GF_OPTION_INIT ("measure-latency", bool_opt, bool, out);
this->ctx->measure_latency = bool_opt;
GF_OPTION_INIT("measure-latency", bool_opt, bool, out);
this->ctx->measure_latency = bool_opt;
GF_OPTION_INIT ("metrics-dump-path", this->ctx->config.metrics_dumppath,
str, out);
GF_OPTION_INIT("metrics-dump-path", this->ctx->config.metrics_dumppath, str,
out);
ret = 0;
ret = 0;
out:
return ret;
return ret;
}
static void
global_xl_fini (xlator_t *this)
global_xl_fini(xlator_t *this)
{
return;
return;
}
struct volume_options global_xl_options[] = {
{ .key = {"measure-latency"},
.type = GF_OPTION_TYPE_BOOL,
.default_value = "no",
.op_version = {GD_OP_VERSION_4_0_0},
.flags = OPT_FLAG_SETTABLE,
.tags = {"global", "context"},
.description = "Use this option to toggle measuring latency"
},
{ .key = {"metrics-dump-path"},
.type = GF_OPTION_TYPE_STR,
.default_value = "{{gluster_workdir}}/metrics",
.op_version = {GD_OP_VERSION_4_0_0},
.flags = OPT_FLAG_SETTABLE,
.tags = {"global", "context"},
.description = "Use this option to set the metrics dump path"
},
{.key = {"measure-latency"},
.type = GF_OPTION_TYPE_BOOL,
.default_value = "no",
.op_version = {GD_OP_VERSION_4_0_0},
.flags = OPT_FLAG_SETTABLE,
.tags = {"global", "context"},
.description = "Use this option to toggle measuring latency"},
{.key = {"metrics-dump-path"},
.type = GF_OPTION_TYPE_STR,
.default_value = "{{gluster_workdir}}/metrics",
.op_version = {GD_OP_VERSION_4_0_0},
.flags = OPT_FLAG_SETTABLE,
.tags = {"global", "context"},
.description = "Use this option to set the metrics dump path"},
{ .key = {NULL},},
{
.key = {NULL},
},
};
static volume_opt_list_t global_xl_opt_list;
int
glusterfs_this_init ()
glusterfs_this_init()
{
int ret = 0;
ret = pthread_key_create (&this_xlator_key, glusterfs_this_destroy);
if (ret != 0) {
gf_msg ("", GF_LOG_WARNING, ret,
LG_MSG_PTHREAD_KEY_CREATE_FAILED, "failed to create "
"the pthread key");
return ret;
}
global_xlator.name = "glusterfs";
global_xlator.type = GF_GLOBAL_XLATOR_NAME;
global_xlator.cbks = &global_cbks;
global_xlator.fops = &global_fops;
global_xlator.reconfigure = global_xl_reconfigure;
global_xlator.init = global_xl_init;
global_xlator.fini = global_xl_fini;
INIT_LIST_HEAD (&global_xlator.volume_options);
INIT_LIST_HEAD (&global_xl_opt_list.list);
global_xl_opt_list.given_opt = global_xl_options;
list_add_tail (&global_xl_opt_list.list, &global_xlator.volume_options);
int ret = 0;
ret = pthread_key_create(&this_xlator_key, glusterfs_this_destroy);
if (ret != 0) {
gf_msg("", GF_LOG_WARNING, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED,
"failed to create "
"the pthread key");
return ret;
}
}
global_xlator.name = "glusterfs";
global_xlator.type = GF_GLOBAL_XLATOR_NAME;
global_xlator.cbks = &global_cbks;
global_xlator.fops = &global_fops;
global_xlator.reconfigure = global_xl_reconfigure;
global_xlator.init = global_xl_init;
global_xlator.fini = global_xl_fini;
INIT_LIST_HEAD(&global_xlator.volume_options);
INIT_LIST_HEAD(&global_xl_opt_list.list);
global_xl_opt_list.given_opt = global_xl_options;
list_add_tail(&global_xl_opt_list.list, &global_xlator.volume_options);
return ret;
}
xlator_t **
__glusterfs_this_location ()
__glusterfs_this_location()
{
xlator_t **this_location = NULL;
int ret = 0;
xlator_t **this_location = NULL;
int ret = 0;
this_location = pthread_getspecific (this_xlator_key);
this_location = pthread_getspecific(this_xlator_key);
if (!this_location) {
this_location = CALLOC (1, sizeof (*this_location));
if (!this_location)
goto out;
if (!this_location) {
this_location = CALLOC(1, sizeof(*this_location));
if (!this_location)
goto out;
ret = pthread_setspecific (this_xlator_key, this_location);
if (ret != 0) {
FREE (this_location);
this_location = NULL;
goto out;
}
ret = pthread_setspecific(this_xlator_key, this_location);
if (ret != 0) {
FREE(this_location);
this_location = NULL;
goto out;
}
}
out:
if (this_location) {
if (!*this_location)
*this_location = &global_xlator;
}
return this_location;
if (this_location) {
if (!*this_location)
*this_location = &global_xlator;
}
return this_location;
}
xlator_t *
glusterfs_this_get ()
glusterfs_this_get()
{
xlator_t **this_location = NULL;
xlator_t **this_location = NULL;
this_location = __glusterfs_this_location ();
if (!this_location)
return &global_xlator;
this_location = __glusterfs_this_location();
if (!this_location)
return &global_xlator;
return *this_location;
return *this_location;
}
int
glusterfs_this_set (xlator_t *this)
glusterfs_this_set(xlator_t *this)
{
xlator_t **this_location = NULL;
xlator_t **this_location = NULL;
this_location = __glusterfs_this_location ();
if (!this_location)
return -ENOMEM;
this_location = __glusterfs_this_location();
if (!this_location)
return -ENOMEM;
*this_location = this;
*this_location = this;
return 0;
return 0;
}
/* SYNCOPCTX */
static pthread_key_t syncopctx_key;
static void
syncopctx_key_destroy (void *ptr)
syncopctx_key_destroy(void *ptr)
{
struct syncopctx *opctx = ptr;
struct syncopctx *opctx = ptr;
if (opctx) {
if (opctx->groups)
GF_FREE (opctx->groups);
if (opctx) {
if (opctx->groups)
GF_FREE(opctx->groups);
GF_FREE (opctx);
}
GF_FREE(opctx);
}
return;
return;
}
void *
syncopctx_getctx ()
syncopctx_getctx()
{
void *opctx = NULL;
void *opctx = NULL;
opctx = pthread_getspecific (syncopctx_key);
opctx = pthread_getspecific(syncopctx_key);
return opctx;
return opctx;
}
int
syncopctx_setctx (void *ctx)
syncopctx_setctx(void *ctx)
{
int ret = 0;
int ret = 0;
ret = pthread_setspecific (syncopctx_key, ctx);
ret = pthread_setspecific(syncopctx_key, ctx);
return ret;
return ret;
}
static int
syncopctx_init (void)
syncopctx_init(void)
{
int ret;
int ret;
ret = pthread_key_create (&syncopctx_key, syncopctx_key_destroy);
ret = pthread_key_create(&syncopctx_key, syncopctx_key_destroy);
return ret;
return ret;
}
/* SYNCTASK */
int
synctask_init ()
synctask_init()
{
int ret = 0;
int ret = 0;
ret = pthread_key_create (&synctask_key, NULL);
ret = pthread_key_create(&synctask_key, NULL);
return ret;
return ret;
}
void *
synctask_get ()
synctask_get()
{
void *synctask = NULL;
void *synctask = NULL;
synctask = pthread_getspecific (synctask_key);
synctask = pthread_getspecific(synctask_key);
return synctask;
return synctask;
}
int
synctask_set (void *synctask)
synctask_set(void *synctask)
{
int ret = 0;
int ret = 0;
pthread_setspecific (synctask_key, synctask);
pthread_setspecific(synctask_key, synctask);
return ret;
return ret;
}
//UUID_BUFFER
// UUID_BUFFER
void
glusterfs_uuid_buf_destroy (void *ptr)
glusterfs_uuid_buf_destroy(void *ptr)
{
FREE (ptr);
FREE(ptr);
}
int
glusterfs_uuid_buf_init ()
glusterfs_uuid_buf_init()
{
int ret = 0;
int ret = 0;
ret = pthread_key_create (&uuid_buf_key,
glusterfs_uuid_buf_destroy);
return ret;
ret = pthread_key_create(&uuid_buf_key, glusterfs_uuid_buf_destroy);
return ret;
}
char *
glusterfs_uuid_buf_get ()
glusterfs_uuid_buf_get()
{
char *buf;
int ret = 0;
char *buf;
int ret = 0;
buf = pthread_getspecific (uuid_buf_key);
if(!buf) {
buf = MALLOC (GF_UUID_BUF_SIZE);
ret = pthread_setspecific (uuid_buf_key, (void *) buf);
if (ret)
buf = global_uuid_buf;
}
return buf;
buf = pthread_getspecific(uuid_buf_key);
if (!buf) {
buf = MALLOC(GF_UUID_BUF_SIZE);
ret = pthread_setspecific(uuid_buf_key, (void *)buf);
if (ret)
buf = global_uuid_buf;
}
return buf;
}
/* LKOWNER_BUFFER */
void
glusterfs_lkowner_buf_destroy (void *ptr)
glusterfs_lkowner_buf_destroy(void *ptr)
{
FREE (ptr);
FREE(ptr);
}
int
glusterfs_lkowner_buf_init ()
glusterfs_lkowner_buf_init()
{
int ret = 0;
int ret = 0;
ret = pthread_key_create (&lkowner_buf_key,
glusterfs_lkowner_buf_destroy);
return ret;
ret = pthread_key_create(&lkowner_buf_key, glusterfs_lkowner_buf_destroy);
return ret;
}
char *
glusterfs_lkowner_buf_get ()
glusterfs_lkowner_buf_get()
{
char *buf;
int ret = 0;
char *buf;
int ret = 0;
buf = pthread_getspecific (lkowner_buf_key);
if(!buf) {
buf = MALLOC (GF_LKOWNER_BUF_SIZE);
ret = pthread_setspecific (lkowner_buf_key, (void *) buf);
if (ret)
buf = global_lkowner_buf;
}
return buf;
buf = pthread_getspecific(lkowner_buf_key);
if (!buf) {
buf = MALLOC(GF_LKOWNER_BUF_SIZE);
ret = pthread_setspecific(lkowner_buf_key, (void *)buf);
if (ret)
buf = global_lkowner_buf;
}
return buf;
}
/* Leaseid buffer */
void
glusterfs_leaseid_buf_destroy (void *ptr)
glusterfs_leaseid_buf_destroy(void *ptr)
{
FREE (ptr);
FREE(ptr);
}
int
glusterfs_leaseid_buf_init ()
glusterfs_leaseid_buf_init()
{
int ret = 0;
int ret = 0;
ret = pthread_key_create (&leaseid_buf_key,
glusterfs_leaseid_buf_destroy);
return ret;
ret = pthread_key_create(&leaseid_buf_key, glusterfs_leaseid_buf_destroy);
return ret;
}
char *
glusterfs_leaseid_buf_get ()
glusterfs_leaseid_buf_get()
{
char *buf = NULL;
int ret = 0;
char *buf = NULL;
int ret = 0;
buf = pthread_getspecific (leaseid_buf_key);
if (!buf) {
buf = CALLOC (1, GF_LEASE_ID_BUF_SIZE);
ret = pthread_setspecific (leaseid_buf_key, (void *) buf);
if (ret) {
FREE (buf);
buf = NULL;
}
buf = pthread_getspecific(leaseid_buf_key);
if (!buf) {
buf = CALLOC(1, GF_LEASE_ID_BUF_SIZE);
ret = pthread_setspecific(leaseid_buf_key, (void *)buf);
if (ret) {
FREE(buf);
buf = NULL;
}
return buf;
}
return buf;
}
char *
glusterfs_leaseid_exist ()
glusterfs_leaseid_exist()
{
return pthread_getspecific (leaseid_buf_key);
return pthread_getspecific(leaseid_buf_key);
}
static void
gf_globals_init_once ()
gf_globals_init_once()
{
int ret = 0;
int ret = 0;
ret = glusterfs_this_init ();
if (ret) {
gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_TRANSLATOR_INIT_FAILED,
"ERROR: glusterfs-translator init failed");
goto out;
}
ret = glusterfs_this_init();
if (ret) {
gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_TRANSLATOR_INIT_FAILED,
"ERROR: glusterfs-translator init failed");
goto out;
}
ret = glusterfs_uuid_buf_init ();
if(ret) {
gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_UUID_BUF_INIT_FAILED,
"ERROR: glusterfs uuid buffer init failed");
goto out;
}
ret = glusterfs_uuid_buf_init();
if (ret) {
gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_UUID_BUF_INIT_FAILED,
"ERROR: glusterfs uuid buffer init failed");
goto out;
}
ret = glusterfs_lkowner_buf_init ();
if(ret) {
gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_LKOWNER_BUF_INIT_FAILED,
"ERROR: glusterfs lkowner buffer init failed");
goto out;
}
ret = glusterfs_lkowner_buf_init();
if (ret) {
gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_LKOWNER_BUF_INIT_FAILED,
"ERROR: glusterfs lkowner buffer init failed");
goto out;
}
ret = glusterfs_leaseid_buf_init ();
if (ret) {
gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_LEASEID_BUF_INIT_FAILED,
"ERROR: glusterfs leaseid buffer init failed");
goto out;
}
ret = glusterfs_leaseid_buf_init();
if (ret) {
gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_LEASEID_BUF_INIT_FAILED,
"ERROR: glusterfs leaseid buffer init failed");
goto out;
}
ret = synctask_init ();
if (ret) {
gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCTASK_INIT_FAILED,
"ERROR: glusterfs synctask init failed");
goto out;
}
ret = synctask_init();
if (ret) {
gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCTASK_INIT_FAILED,
"ERROR: glusterfs synctask init failed");
goto out;
}
ret = syncopctx_init ();
if (ret) {
gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCOPCTX_INIT_FAILED,
"ERROR: glusterfs syncopctx init failed");
goto out;
}
ret = syncopctx_init();
if (ret) {
gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCOPCTX_INIT_FAILED,
"ERROR: glusterfs syncopctx init failed");
goto out;
}
out:
if (ret) {
gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_GLOBAL_INIT_FAILED,
"Exiting as global initialization failed");
exit (ret);
}
if (ret) {
gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_GLOBAL_INIT_FAILED,
"Exiting as global initialization failed");
exit(ret);
}
}
int
glusterfs_globals_init (glusterfs_ctx_t *ctx)
glusterfs_globals_init(glusterfs_ctx_t *ctx)
{
int ret = 0;
int ret = 0;
gf_log_globals_init (ctx, GF_LOG_INFO);
gf_log_globals_init(ctx, GF_LOG_INFO);
ret = pthread_once (&globals_inited, gf_globals_init_once);
ret = pthread_once(&globals_inited, gf_globals_init_once);
if (ret)
gf_msg ("", GF_LOG_CRITICAL, ret, LG_MSG_PTHREAD_FAILED,
"pthread_once failed");
if (ret)
gf_msg("", GF_LOG_CRITICAL, ret, LG_MSG_PTHREAD_FAILED,
"pthread_once failed");
return ret;
return ret;
}

View File

@ -15,183 +15,180 @@
#include "graph-utils.h"
#include "libglusterfs-messages.h"
struct gf_printer {
ssize_t (*write) (struct gf_printer *gp, char *buf, size_t len);
void *priv;
int len;
ssize_t (*write)(struct gf_printer *gp, char *buf, size_t len);
void *priv;
int len;
};
static ssize_t
gp_write_file (struct gf_printer *gp, char *buf, size_t len)
gp_write_file(struct gf_printer *gp, char *buf, size_t len)
{
FILE *f = gp->priv;
FILE *f = gp->priv;
if (fwrite (buf, len, 1, f) != 1) {
gf_msg ("graph-print", GF_LOG_ERROR, errno,
LG_MSG_FWRITE_FAILED, "fwrite failed");
if (fwrite(buf, len, 1, f) != 1) {
gf_msg("graph-print", GF_LOG_ERROR, errno, LG_MSG_FWRITE_FAILED,
"fwrite failed");
return -1;
}
return -1;
}
return len;
return len;
}
static ssize_t
gp_write_buf (struct gf_printer *gp, char *buf, size_t len)
gp_write_buf(struct gf_printer *gp, char *buf, size_t len)
{
struct iovec *iov = gp->priv;
struct iovec *iov = gp->priv;
if (iov->iov_len < len) {
gf_msg ("graph-print", GF_LOG_ERROR, 0, LG_MSG_BUFFER_FULL,
"buffer full");
if (iov->iov_len < len) {
gf_msg("graph-print", GF_LOG_ERROR, 0, LG_MSG_BUFFER_FULL,
"buffer full");
return -1;
}
memcpy (iov->iov_base, buf, len);
iov->iov_base += len;
iov->iov_len -= len;
return len;
}
static int
gpprintf (struct gf_printer *gp, const char *format, ...)
{
va_list arg;
char *str = NULL;
int ret = 0;
va_start (arg, format);
ret = gf_vasprintf (&str, format, arg);
va_end (arg);
if (ret < 0)
return ret;
ret = gp->write (gp, str, ret);
GF_FREE (str);
return ret;
}
#define GPPRINTF(gp, fmt, ...) do { \
ret = gpprintf (gp, fmt, ## __VA_ARGS__); \
if (ret == -1) \
goto out; \
else \
gp->len += ret; \
} while (0)
static int
_print_volume_options (dict_t *d, char *k, data_t *v,
void *tmp)
{
struct gf_printer *gp = tmp;
int ret = 0;
GPPRINTF (gp, " option %s %s\n", k, v->data);
return 0;
out:
/* means, it is a failure */
return -1;
}
memcpy(iov->iov_base, buf, len);
iov->iov_base += len;
iov->iov_len -= len;
return len;
}
static int
glusterfs_graph_print (struct gf_printer *gp, glusterfs_graph_t *graph)
gpprintf(struct gf_printer *gp, const char *format, ...)
{
xlator_t *trav = NULL;
xlator_list_t *xch = NULL;
int ret = 0;
ssize_t len = 0;
va_list arg;
char *str = NULL;
int ret = 0;
if (!graph->first)
return 0;
va_start(arg, format);
ret = gf_vasprintf(&str, format, arg);
va_end(arg);
for (trav = graph->first; trav->next; trav = trav->next);
for (; trav; trav = trav->prev) {
GPPRINTF (gp, "volume %s\n type %s\n", trav->name,
trav->type);
if (ret < 0)
return ret;
ret = dict_foreach (trav->options, _print_volume_options, gp);
if (ret)
goto out;
ret = gp->write(gp, str, ret);
if (trav->children) {
GPPRINTF (gp, " subvolumes");
GF_FREE(str);
for (xch = trav->children; xch; xch = xch->next)
GPPRINTF (gp, " %s", xch->xlator->name);
return ret;
}
GPPRINTF (gp, "\n");
}
#define GPPRINTF(gp, fmt, ...) \
do { \
ret = gpprintf(gp, fmt, ##__VA_ARGS__); \
if (ret == -1) \
goto out; \
else \
gp->len += ret; \
} while (0)
GPPRINTF (gp, "end-volume\n");
if (trav != graph->first)
GPPRINTF (gp, "\n");
static int
_print_volume_options(dict_t *d, char *k, data_t *v, void *tmp)
{
struct gf_printer *gp = tmp;
int ret = 0;
GPPRINTF(gp, " option %s %s\n", k, v->data);
return 0;
out:
/* means, it is a failure */
return -1;
}
static int
glusterfs_graph_print(struct gf_printer *gp, glusterfs_graph_t *graph)
{
xlator_t *trav = NULL;
xlator_list_t *xch = NULL;
int ret = 0;
ssize_t len = 0;
if (!graph->first)
return 0;
for (trav = graph->first; trav->next; trav = trav->next)
;
for (; trav; trav = trav->prev) {
GPPRINTF(gp, "volume %s\n type %s\n", trav->name, trav->type);
ret = dict_foreach(trav->options, _print_volume_options, gp);
if (ret)
goto out;
if (trav->children) {
GPPRINTF(gp, " subvolumes");
for (xch = trav->children; xch; xch = xch->next)
GPPRINTF(gp, " %s", xch->xlator->name);
GPPRINTF(gp, "\n");
}
GPPRINTF(gp, "end-volume\n");
if (trav != graph->first)
GPPRINTF(gp, "\n");
}
out:
len = gp->len;
if (ret == -1) {
gf_msg ("graph-print", GF_LOG_ERROR, 0, LG_MSG_PRINT_FAILED,
"printing failed");
len = gp->len;
if (ret == -1) {
gf_msg("graph-print", GF_LOG_ERROR, 0, LG_MSG_PRINT_FAILED,
"printing failed");
return -1;
}
return -1;
}
return len;
return len;
#undef GPPRINTF
}
int
glusterfs_graph_print_file (FILE *file, glusterfs_graph_t *graph)
glusterfs_graph_print_file(FILE *file, glusterfs_graph_t *graph)
{
struct gf_printer gp = { .write = gp_write_file,
.priv = file
};
struct gf_printer gp = {.write = gp_write_file, .priv = file};
return glusterfs_graph_print (&gp, graph);
return glusterfs_graph_print(&gp, graph);
}
char *
glusterfs_graph_print_buf (glusterfs_graph_t *graph)
glusterfs_graph_print_buf(glusterfs_graph_t *graph)
{
FILE *f = NULL;
struct iovec iov = {0,};
int len = 0;
char *buf = NULL;
struct gf_printer gp = { .write = gp_write_buf,
.priv = &iov
};
FILE *f = NULL;
struct iovec iov = {
0,
};
int len = 0;
char *buf = NULL;
struct gf_printer gp = {.write = gp_write_buf, .priv = &iov};
f = fopen ("/dev/null", "a");
if (!f) {
gf_msg ("graph-print", GF_LOG_ERROR, errno,
LG_MSG_DIR_OP_FAILED, "cannot open /dev/null");
f = fopen("/dev/null", "a");
if (!f) {
gf_msg("graph-print", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
"cannot open /dev/null");
return NULL;
}
len = glusterfs_graph_print_file (f, graph);
fclose (f);
if (len == -1)
return NULL;
return NULL;
}
len = glusterfs_graph_print_file(f, graph);
fclose(f);
if (len == -1)
return NULL;
buf = GF_CALLOC (1, len + 1, gf_common_mt_graph_buf);
if (!buf) {
return NULL;
}
iov.iov_base = buf;
iov.iov_len = len;
buf = GF_CALLOC(1, len + 1, gf_common_mt_graph_buf);
if (!buf) {
return NULL;
}
iov.iov_base = buf;
iov.iov_len = len;
len = glusterfs_graph_print (&gp, graph);
if (len == -1) {
GF_FREE (buf);
len = glusterfs_graph_print(&gp, graph);
if (len == -1) {
GF_FREE(buf);
return NULL;
}
return NULL;
}
return buf;
return buf;
}

File diff suppressed because it is too large Load Diff

View File

@ -13,21 +13,20 @@
#include "hashfn.h"
#define get16bits(d) (*((const uint16_t *) (d)))
#define get16bits(d) (*((const uint16_t *)(d)))
#define DM_DELTA 0x9E3779B9
#define DM_FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
#define DM_PARTROUNDS 6 /* 6 gets complete mixing */
#define DM_FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
#define DM_PARTROUNDS 6 /* 6 gets complete mixing */
uint32_t
ReallySimpleHash (char *path, int len)
ReallySimpleHash(char *path, int len)
{
uint32_t hash = 0;
for (;len > 0; len--)
hash ^= (char)path[len];
uint32_t hash = 0;
for (; len > 0; len--)
hash ^= (char)path[len];
return hash;
return hash;
}
/*
@ -37,146 +36,145 @@ ReallySimpleHash (char *path, int len)
/* In any case make sure, you return 1 */
uint32_t SuperFastHash (const char * data, int32_t len) {
uint32_t hash = len, tmp;
int32_t rem;
uint32_t
SuperFastHash(const char *data, int32_t len)
{
uint32_t hash = len, tmp;
int32_t rem;
if (len <= 1 || data == NULL) return 1;
if (len <= 1 || data == NULL)
return 1;
rem = len & 3;
len >>= 2;
rem = len & 3;
len >>= 2;
/* Main loop */
for (;len > 0; len--) {
hash += get16bits (data);
tmp = (get16bits (data+2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2*sizeof (uint16_t);
hash += hash >> 11;
}
/* Main loop */
for (; len > 0; len--) {
hash += get16bits(data);
tmp = (get16bits(data + 2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2 * sizeof(uint16_t);
hash += hash >> 11;
}
/* Handle end cases */
switch (rem) {
case 3: hash += get16bits (data);
hash ^= hash << 16;
hash ^= data[sizeof (uint16_t)] << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits (data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
}
/* Handle end cases */
switch (rem) {
case 3:
hash += get16bits(data);
hash ^= hash << 16;
hash ^= data[sizeof(uint16_t)] << 18;
hash += hash >> 11;
break;
case 2:
hash += get16bits(data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1:
hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
return hash;
}
/* Davies-Meyer hashing function implementation
*/
static int
dm_round (int rounds, uint32_t *array, uint32_t *h0, uint32_t *h1)
dm_round(int rounds, uint32_t *array, uint32_t *h0, uint32_t *h1)
{
uint32_t sum = 0;
int n = 0;
uint32_t b0 = 0;
uint32_t b1 = 0;
uint32_t sum = 0;
int n = 0;
uint32_t b0 = 0;
uint32_t b1 = 0;
b0 = *h0;
b1 = *h1;
b0 = *h0;
b1 = *h1;
n = rounds;
n = rounds;
do {
sum += DM_DELTA;
b0 += ((b1 << 4) + array[0])
^ (b1 + sum)
^ ((b1 >> 5) + array[1]);
b1 += ((b0 << 4) + array[2])
^ (b0 + sum)
^ ((b0 >> 5) + array[3]);
} while (--n);
do {
sum += DM_DELTA;
b0 += ((b1 << 4) + array[0]) ^ (b1 + sum) ^ ((b1 >> 5) + array[1]);
b1 += ((b0 << 4) + array[2]) ^ (b0 + sum) ^ ((b0 >> 5) + array[3]);
} while (--n);
*h0 += b0;
*h1 += b1;
*h0 += b0;
*h1 += b1;
return 0;
}
uint32_t
__pad (int len)
{
uint32_t pad = 0;
pad = (uint32_t) len | ((uint32_t) len << 8);
pad |= pad << 16;
return pad;
return 0;
}
uint32_t
gf_dm_hashfn (const char *msg, int len)
__pad(int len)
{
uint32_t h0 = 0x9464a485;
uint32_t h1 = 0x542e1a94;
uint32_t array[4];
uint32_t pad = 0;
int i = 0;
int j = 0;
int full_quads = 0;
int full_words = 0;
int full_bytes = 0;
uint32_t *intmsg = NULL;
int word = 0;
uint32_t pad = 0;
pad = (uint32_t)len | ((uint32_t)len << 8);
pad |= pad << 16;
intmsg = (uint32_t *) msg;
pad = __pad (len);
return pad;
}
full_bytes = len;
full_words = len / 4;
full_quads = len / 16;
uint32_t
gf_dm_hashfn(const char *msg, int len)
{
uint32_t h0 = 0x9464a485;
uint32_t h1 = 0x542e1a94;
uint32_t array[4];
uint32_t pad = 0;
int i = 0;
int j = 0;
int full_quads = 0;
int full_words = 0;
int full_bytes = 0;
uint32_t *intmsg = NULL;
int word = 0;
for (i = 0; i < full_quads; i++) {
for (j = 0; j < 4; j++) {
word = *intmsg;
array[j] = word;
intmsg++;
full_words--;
full_bytes -= 4;
}
dm_round (DM_PARTROUNDS, &array[0], &h0, &h1);
}
intmsg = (uint32_t *)msg;
pad = __pad(len);
full_bytes = len;
full_words = len / 4;
full_quads = len / 16;
for (i = 0; i < full_quads; i++) {
for (j = 0; j < 4; j++) {
if (full_words) {
word = *intmsg;
array[j] = word;
intmsg++;
full_words--;
full_bytes -= 4;
} else {
array[j] = pad;
while (full_bytes) {
array[j] <<= 8;
array[j] |= msg[len - full_bytes];
full_bytes--;
}
}
word = *intmsg;
array[j] = word;
intmsg++;
full_words--;
full_bytes -= 4;
}
dm_round (DM_FULLROUNDS, &array[0], &h0, &h1);
dm_round(DM_PARTROUNDS, &array[0], &h0, &h1);
}
return h0 ^ h1;
for (j = 0; j < 4; j++) {
if (full_words) {
word = *intmsg;
array[j] = word;
intmsg++;
full_words--;
full_bytes -= 4;
} else {
array[j] = pad;
while (full_bytes) {
array[j] <<= 8;
array[j] |= msg[len - full_bytes];
full_bytes--;
}
}
}
dm_round(DM_FULLROUNDS, &array[0], &h0, &h1);
return h0 ^ h1;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,6 @@
cases as published by the Free Software Foundation.
*/
/*
* This file contains functions to support dumping of
* latencies of FOPs broken down by subvolumes.
@ -21,82 +20,77 @@
#include "libglusterfs-messages.h"
void
gf_update_latency (call_frame_t *frame)
gf_update_latency(call_frame_t *frame)
{
double elapsed;
struct timespec *begin, *end;
double elapsed;
struct timespec *begin, *end;
fop_latency_t *lat;
fop_latency_t *lat;
begin = &frame->begin;
end = &frame->end;
begin = &frame->begin;
end = &frame->end;
if (!(begin->tv_sec && end->tv_sec))
goto out;
if (!(begin->tv_sec && end->tv_sec))
goto out;
elapsed = (end->tv_sec - begin->tv_sec) * 1e9
+ (end->tv_nsec - begin->tv_nsec);
elapsed = (end->tv_sec - begin->tv_sec) * 1e9 +
(end->tv_nsec - begin->tv_nsec);
if (frame->op < 0 || frame->op >= GF_FOP_MAXVALUE) {
gf_log ("[core]", GF_LOG_WARNING,
"Invalid frame op value: %d",
frame->op);
return;
}
/* Can happen mostly at initiator xlator, as STACK_WIND/UNWIND macros
set it right anyways for those frames */
if (!frame->op)
frame->op = frame->root->op;
lat = &frame->this->stats.interval.latencies[frame->op];
if (lat->max < elapsed)
lat->max = elapsed;
if (lat->min > elapsed)
lat->min = elapsed;
lat->total += elapsed;
lat->count++;
out:
if (frame->op < 0 || frame->op >= GF_FOP_MAXVALUE) {
gf_log("[core]", GF_LOG_WARNING, "Invalid frame op value: %d",
frame->op);
return;
}
}
/* Can happen mostly at initiator xlator, as STACK_WIND/UNWIND macros
set it right anyways for those frames */
if (!frame->op)
frame->op = frame->root->op;
lat = &frame->this->stats.interval.latencies[frame->op];
if (lat->max < elapsed)
lat->max = elapsed;
if (lat->min > elapsed)
lat->min = elapsed;
lat->total += elapsed;
lat->count++;
out:
return;
}
void
gf_proc_dump_latency_info (xlator_t *xl)
gf_proc_dump_latency_info(xlator_t *xl)
{
char key_prefix[GF_DUMP_MAX_BUF_LEN];
char key[GF_DUMP_MAX_BUF_LEN];
int i;
char key_prefix[GF_DUMP_MAX_BUF_LEN];
char key[GF_DUMP_MAX_BUF_LEN];
int i;
snprintf (key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.latency", xl->name);
gf_proc_dump_add_section (key_prefix);
snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.latency", xl->name);
gf_proc_dump_add_section(key_prefix);
for (i = 0; i < GF_FOP_MAXVALUE; i++) {
gf_proc_dump_build_key (key, key_prefix, "%s",
(char *)gf_fop_list[i]);
for (i = 0; i < GF_FOP_MAXVALUE; i++) {
gf_proc_dump_build_key(key, key_prefix, "%s", (char *)gf_fop_list[i]);
fop_latency_t *lat = &xl->stats.interval.latencies[i];
fop_latency_t *lat = &xl->stats.interval.latencies[i];
/* Doesn't make sense to continue if there are no fops
came in the given interval */
if (!lat->count)
continue;
/* Doesn't make sense to continue if there are no fops
came in the given interval */
if (!lat->count)
continue;
gf_proc_dump_write (key, "%.03f,%"PRId64",%.03f",
(lat->total / lat->count), lat->count,
lat->total);
}
gf_proc_dump_write(key, "%.03f,%" PRId64 ",%.03f",
(lat->total / lat->count), lat->count, lat->total);
}
memset (xl->stats.interval.latencies, 0,
sizeof (xl->stats.interval.latencies));
memset(xl->stats.interval.latencies, 0,
sizeof(xl->stats.interval.latencies));
/* make sure 'min' is set to high value, so it would be
properly set later */
for (i = 0; i < GF_FOP_MAXVALUE; i++) {
xl->stats.interval.latencies[i].min = 0xffffffff;
}
/* make sure 'min' is set to high value, so it would be
properly set later */
for (i = 0; i < GF_FOP_MAXVALUE; i++) {
xl->stats.interval.latencies[i].min = 0xffffffff;
}
}

View File

@ -19,10 +19,9 @@
int use_spinlocks = 0;
static void __attribute__((constructor))
gf_lock_setup (void)
static void __attribute__((constructor)) gf_lock_setup(void)
{
//use_spinlocks = (sysconf(_SC_NPROCESSORS_ONLN) > 1);
// use_spinlocks = (sysconf(_SC_NPROCESSORS_ONLN) > 1);
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,254 +17,256 @@
static void
dump_mem_acct_details(xlator_t *xl, int fd)
{
struct mem_acct_rec *mem_rec;
int i = 0;
struct mem_acct_rec *mem_rec;
int i = 0;
if (!xl || !xl->mem_acct || (xl->ctx->active != xl->graph))
return;
if (!xl || !xl->mem_acct || (xl->ctx->active != xl->graph))
return;
dprintf (fd, "# %s.%s.total.num_types %d\n", xl->type, xl->name,
xl->mem_acct->num_types);
dprintf(fd, "# %s.%s.total.num_types %d\n", xl->type, xl->name,
xl->mem_acct->num_types);
dprintf (fd, "# type, in-use-size, in-use-units, max-size, "
"max-units, total-allocs\n");
dprintf(fd,
"# type, in-use-size, in-use-units, max-size, "
"max-units, total-allocs\n");
for (i = 0; i < xl->mem_acct->num_types; i++) {
mem_rec = &xl->mem_acct->rec[i];
if (mem_rec->num_allocs == 0)
continue;
dprintf (fd, "# %s, %"GF_PRI_SIZET", %u, %"GF_PRI_SIZET", %u,"
" %u\n", mem_rec->typestr, mem_rec->size,
mem_rec->num_allocs, mem_rec->max_size,
mem_rec->max_num_allocs, mem_rec->total_allocs);
}
for (i = 0; i < xl->mem_acct->num_types; i++) {
mem_rec = &xl->mem_acct->rec[i];
if (mem_rec->num_allocs == 0)
continue;
dprintf(fd,
"# %s, %" GF_PRI_SIZET ", %u, %" GF_PRI_SIZET
", %u,"
" %u\n",
mem_rec->typestr, mem_rec->size, mem_rec->num_allocs,
mem_rec->max_size, mem_rec->max_num_allocs,
mem_rec->total_allocs);
}
}
static void
dump_global_memory_accounting (int fd)
dump_global_memory_accounting(int fd)
{
#if MEMORY_ACCOUNTING_STATS
int i = 0;
uint64_t count = 0;
int i = 0;
uint64_t count = 0;
uint64_t tcalloc = GF_ATOMIC_GET (gf_memory_stat_counts.total_calloc);
uint64_t tmalloc = GF_ATOMIC_GET (gf_memory_stat_counts.total_malloc);
uint64_t tfree = GF_ATOMIC_GET (gf_memory_stat_counts.total_free);
uint64_t tcalloc = GF_ATOMIC_GET(gf_memory_stat_counts.total_calloc);
uint64_t tmalloc = GF_ATOMIC_GET(gf_memory_stat_counts.total_malloc);
uint64_t tfree = GF_ATOMIC_GET(gf_memory_stat_counts.total_free);
dprintf (fd, "memory.total.calloc %lu\n", tcalloc);
dprintf (fd, "memory.total.malloc %lu\n", tmalloc);
dprintf (fd, "memory.total.realloc %lu\n",
GF_ATOMIC_GET (gf_memory_stat_counts.total_realloc));
dprintf (fd, "memory.total.free %lu\n", tfree);
dprintf (fd, "memory.total.in-use %lu\n", ((tcalloc + tmalloc) - tfree));
dprintf(fd, "memory.total.calloc %lu\n", tcalloc);
dprintf(fd, "memory.total.malloc %lu\n", tmalloc);
dprintf(fd, "memory.total.realloc %lu\n",
GF_ATOMIC_GET(gf_memory_stat_counts.total_realloc));
dprintf(fd, "memory.total.free %lu\n", tfree);
dprintf(fd, "memory.total.in-use %lu\n", ((tcalloc + tmalloc) - tfree));
for (i = 0; i < GF_BLK_MAX_VALUE; i++) {
count = GF_ATOMIC_GET (gf_memory_stat_counts.blk_size[i]);
dprintf (fd, "memory.total.blk_size.%s %lu\n",
gf_mem_stats_blk[i].blk_size_str, count);
}
for (i = 0; i < GF_BLK_MAX_VALUE; i++) {
count = GF_ATOMIC_GET(gf_memory_stat_counts.blk_size[i]);
dprintf(fd, "memory.total.blk_size.%s %lu\n",
gf_mem_stats_blk[i].blk_size_str, count);
}
dprintf (fd, "#----\n");
dprintf(fd, "#----\n");
#endif
/* This is not a metric to be watched in admin guide,
but keeping it here till we resolve all leak-issues
would be great */
}
static void
dump_latency_and_count (xlator_t *xl, int fd)
{
int32_t index = 0;
uint64_t fop;
uint64_t cbk;
uint64_t count;
if (xl->winds)
dprintf (fd, "%s.total.pending-winds.count %lu\n", xl->name, xl->winds);
/* Need 'fuse' data, and don't need all the old graph info */
if ((xl != xl->ctx->master) && (xl->ctx->active != xl->graph))
return;
count = GF_ATOMIC_GET (xl->stats.total.count);
dprintf (fd, "%s.total.fop-count %lu\n", xl->name, count);
count = GF_ATOMIC_GET (xl->stats.interval.count);
dprintf (fd, "%s.interval.fop-count %lu\n", xl->name, count);
GF_ATOMIC_INIT (xl->stats.interval.count, 0);
for (index = 0; index < GF_FOP_MAXVALUE; index++) {
fop = GF_ATOMIC_GET (xl->stats.total.metrics[index].fop);
if (fop) {
dprintf (fd, "%s.total.%s.count %lu\n",
xl->name, gf_fop_list[index], fop);
}
fop = GF_ATOMIC_GET (xl->stats.interval.metrics[index].fop);
if (fop) {
dprintf (fd, "%s.interval.%s.count %lu\n",
xl->name, gf_fop_list[index], fop);
}
cbk = GF_ATOMIC_GET (xl->stats.interval.metrics[index].cbk);
if (cbk) {
dprintf (fd, "%s.interval.%s.fail_count %lu\n",
xl->name, gf_fop_list[index], cbk);
}
if (xl->stats.interval.latencies[index].count != 0.0) {
dprintf (fd, "%s.interval.%s.latency %lf\n",
xl->name, gf_fop_list[index],
(xl->stats.interval.latencies[index].total /
xl->stats.interval.latencies[index].count));
dprintf (fd, "%s.interval.%s.max %lf\n",
xl->name, gf_fop_list[index],
xl->stats.interval.latencies[index].max);
dprintf (fd, "%s.interval.%s.min %lf\n",
xl->name, gf_fop_list[index],
xl->stats.interval.latencies[index].min);
}
GF_ATOMIC_INIT (xl->stats.interval.metrics[index].cbk, 0);
GF_ATOMIC_INIT (xl->stats.interval.metrics[index].fop, 0);
}
memset (xl->stats.interval.latencies, 0,
sizeof (xl->stats.interval.latencies));
}
static inline void
dump_call_stack_details (glusterfs_ctx_t *ctx, int fd)
{
dprintf (fd, "total.stack.count %lu\n",
GF_ATOMIC_GET (ctx->pool->total_count));
dprintf (fd, "total.stack.in-flight %lu\n",
ctx->pool->cnt);
}
static inline void
dump_dict_details (glusterfs_ctx_t *ctx, int fd)
{
uint64_t total_dicts = 0;
uint64_t total_pairs = 0;
total_dicts = GF_ATOMIC_GET (ctx->stats.total_dicts_used);
total_pairs = GF_ATOMIC_GET (ctx->stats.total_pairs_used);
dprintf (fd, "total.dict.max-pairs-per %lu\n",
GF_ATOMIC_GET (ctx->stats.max_dict_pairs));
dprintf (fd, "total.dict.pairs-used %lu\n", total_pairs);
dprintf (fd, "total.dict.used %lu\n", total_dicts);
dprintf (fd, "total.dict.average-pairs %lu\n",
(total_pairs / total_dicts));
/* This is not a metric to be watched in admin guide,
but keeping it here till we resolve all leak-issues
would be great */
}
static void
dump_inode_stats (glusterfs_ctx_t *ctx, int fd)
dump_latency_and_count(xlator_t *xl, int fd)
{
}
int32_t index = 0;
uint64_t fop;
uint64_t cbk;
uint64_t count;
static void
dump_global_metrics (glusterfs_ctx_t *ctx, int fd)
{
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[64] = {0,};
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", nowtm);
/* Let every file have information on which process dumped info */
dprintf (fd, "## %s\n", ctx->cmdlinestr);
dprintf (fd, "### %s\n", tmbuf);
dprintf (fd, "### BrickName: %s\n", ctx->cmd_args.brick_name);
dprintf (fd, "### MountName: %s\n", ctx->cmd_args.mount_point);
dprintf (fd, "### VolumeName: %s\n", ctx->cmd_args.volume_name);
/* Dump memory accounting */
dump_global_memory_accounting (fd);
dprintf (fd, "# -----\n");
dump_call_stack_details (ctx, fd);
dump_dict_details (ctx, fd);
dprintf (fd, "# -----\n");
dump_inode_stats (ctx, fd);
dprintf (fd, "# -----\n");
}
static void
dump_xl_metrics (glusterfs_ctx_t *ctx, int fd)
{
xlator_t *xl;
xl = ctx->active->top;
while (xl) {
dump_latency_and_count (xl, fd);
dump_mem_acct_details (xl, fd);
if (xl->dump_metrics)
xl->dump_metrics (xl, fd);
xl = xl->next;
}
if (ctx->master) {
xl = ctx->master;
dump_latency_and_count (xl, fd);
dump_mem_acct_details (xl, fd);
if (xl->dump_metrics)
xl->dump_metrics (xl, fd);
}
if (xl->winds)
dprintf(fd, "%s.total.pending-winds.count %lu\n", xl->name, xl->winds);
/* Need 'fuse' data, and don't need all the old graph info */
if ((xl != xl->ctx->master) && (xl->ctx->active != xl->graph))
return;
count = GF_ATOMIC_GET(xl->stats.total.count);
dprintf(fd, "%s.total.fop-count %lu\n", xl->name, count);
count = GF_ATOMIC_GET(xl->stats.interval.count);
dprintf(fd, "%s.interval.fop-count %lu\n", xl->name, count);
GF_ATOMIC_INIT(xl->stats.interval.count, 0);
for (index = 0; index < GF_FOP_MAXVALUE; index++) {
fop = GF_ATOMIC_GET(xl->stats.total.metrics[index].fop);
if (fop) {
dprintf(fd, "%s.total.%s.count %lu\n", xl->name, gf_fop_list[index],
fop);
}
fop = GF_ATOMIC_GET(xl->stats.interval.metrics[index].fop);
if (fop) {
dprintf(fd, "%s.interval.%s.count %lu\n", xl->name,
gf_fop_list[index], fop);
}
cbk = GF_ATOMIC_GET(xl->stats.interval.metrics[index].cbk);
if (cbk) {
dprintf(fd, "%s.interval.%s.fail_count %lu\n", xl->name,
gf_fop_list[index], cbk);
}
if (xl->stats.interval.latencies[index].count != 0.0) {
dprintf(fd, "%s.interval.%s.latency %lf\n", xl->name,
gf_fop_list[index],
(xl->stats.interval.latencies[index].total /
xl->stats.interval.latencies[index].count));
dprintf(fd, "%s.interval.%s.max %lf\n", xl->name,
gf_fop_list[index],
xl->stats.interval.latencies[index].max);
dprintf(fd, "%s.interval.%s.min %lf\n", xl->name,
gf_fop_list[index],
xl->stats.interval.latencies[index].min);
}
GF_ATOMIC_INIT(xl->stats.interval.metrics[index].cbk, 0);
GF_ATOMIC_INIT(xl->stats.interval.metrics[index].fop, 0);
}
memset(xl->stats.interval.latencies, 0,
sizeof(xl->stats.interval.latencies));
}
static inline void
dump_call_stack_details(glusterfs_ctx_t *ctx, int fd)
{
dprintf(fd, "total.stack.count %lu\n",
GF_ATOMIC_GET(ctx->pool->total_count));
dprintf(fd, "total.stack.in-flight %lu\n", ctx->pool->cnt);
}
static inline void
dump_dict_details(glusterfs_ctx_t *ctx, int fd)
{
uint64_t total_dicts = 0;
uint64_t total_pairs = 0;
total_dicts = GF_ATOMIC_GET(ctx->stats.total_dicts_used);
total_pairs = GF_ATOMIC_GET(ctx->stats.total_pairs_used);
dprintf(fd, "total.dict.max-pairs-per %lu\n",
GF_ATOMIC_GET(ctx->stats.max_dict_pairs));
dprintf(fd, "total.dict.pairs-used %lu\n", total_pairs);
dprintf(fd, "total.dict.used %lu\n", total_dicts);
dprintf(fd, "total.dict.average-pairs %lu\n", (total_pairs / total_dicts));
}
static void
dump_inode_stats(glusterfs_ctx_t *ctx, int fd)
{
}
static void
dump_global_metrics(glusterfs_ctx_t *ctx, int fd)
{
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[64] = {
0,
};
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", nowtm);
/* Let every file have information on which process dumped info */
dprintf(fd, "## %s\n", ctx->cmdlinestr);
dprintf(fd, "### %s\n", tmbuf);
dprintf(fd, "### BrickName: %s\n", ctx->cmd_args.brick_name);
dprintf(fd, "### MountName: %s\n", ctx->cmd_args.mount_point);
dprintf(fd, "### VolumeName: %s\n", ctx->cmd_args.volume_name);
/* Dump memory accounting */
dump_global_memory_accounting(fd);
dprintf(fd, "# -----\n");
dump_call_stack_details(ctx, fd);
dump_dict_details(ctx, fd);
dprintf(fd, "# -----\n");
dump_inode_stats(ctx, fd);
dprintf(fd, "# -----\n");
}
static void
dump_xl_metrics(glusterfs_ctx_t *ctx, int fd)
{
xlator_t *xl;
xl = ctx->active->top;
while (xl) {
dump_latency_and_count(xl, fd);
dump_mem_acct_details(xl, fd);
if (xl->dump_metrics)
xl->dump_metrics(xl, fd);
xl = xl->next;
}
if (ctx->master) {
xl = ctx->master;
dump_latency_and_count(xl, fd);
dump_mem_acct_details(xl, fd);
if (xl->dump_metrics)
xl->dump_metrics(xl, fd);
}
return;
}
char *
gf_monitor_metrics (glusterfs_ctx_t *ctx)
gf_monitor_metrics(glusterfs_ctx_t *ctx)
{
int ret = -1;
int fd = 0;
char *filepath, *dumppath;
int ret = -1;
int fd = 0;
char *filepath, *dumppath;
dumppath = ctx->config.metrics_dumppath;
if (dumppath == NULL) {
dumppath = GLUSTER_METRICS_DIR;
}
dumppath = ctx->config.metrics_dumppath;
if (dumppath == NULL) {
dumppath = GLUSTER_METRICS_DIR;
}
ret = gf_asprintf(&filepath, "%s/gmetrics.XXXXXX", dumppath);
if (ret < 0) {
return NULL;
}
ret = gf_asprintf(&filepath, "%s/gmetrics.XXXXXX", dumppath);
if (ret < 0) {
return NULL;
}
/* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
fd = mkstemp (filepath);
if (fd < 0) {
gf_msg ("monitoring", GF_LOG_ERROR, 0, LG_MSG_STRDUP_ERROR,
"failed to open tmp file %s (%s)",
filepath, strerror (errno));
GF_FREE (filepath);
return NULL;
}
/* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
fd = mkstemp(filepath);
if (fd < 0) {
gf_msg("monitoring", GF_LOG_ERROR, 0, LG_MSG_STRDUP_ERROR,
"failed to open tmp file %s (%s)", filepath, strerror(errno));
GF_FREE(filepath);
return NULL;
}
dump_global_metrics (ctx, fd);
dump_global_metrics(ctx, fd);
dump_xl_metrics (ctx, fd);
dump_xl_metrics(ctx, fd);
/* This below line is used just to capture any errors with dprintf() */
ret = dprintf (fd, "\n# End of metrics\n");
if (ret < 0) {
gf_msg ("monitoring", GF_LOG_WARNING, 0, LG_MSG_STRDUP_ERROR,
"dprintf() failed: %s", strerror (errno));
}
/* This below line is used just to capture any errors with dprintf() */
ret = dprintf(fd, "\n# End of metrics\n");
if (ret < 0) {
gf_msg("monitoring", GF_LOG_WARNING, 0, LG_MSG_STRDUP_ERROR,
"dprintf() failed: %s", strerror(errno));
}
ret = sys_fsync (fd);
if (ret < 0) {
gf_msg ("monitoring", GF_LOG_WARNING, 0, LG_MSG_STRDUP_ERROR,
"fsync() failed: %s", strerror (errno));
}
sys_close (fd);
ret = sys_fsync(fd);
if (ret < 0) {
gf_msg("monitoring", GF_LOG_WARNING, 0, LG_MSG_STRDUP_ERROR,
"fsync() failed: %s", strerror(errno));
}
sys_close(fd);
/* Figure this out, not happy with returning this string */
return filepath;
/* Figure this out, not happy with returning this string */
return filepath;
}

File diff suppressed because it is too large Load Diff

View File

@ -76,8 +76,8 @@ typedef enum {
* try a solution in GD2 for this.
*/
/* typedef int (*option_validation_fn) (glusterd_volinfo_t *volinfo, dict_t
*dict, char *key, char *value, char **op_errstr);
*/
*dict, char *key, char *value, char **op_errstr);
*/
/* Each translator should define this structure */
/* XXX: This structure is in use by GD2, and SHOULD NOT be modified.

View File

@ -36,33 +36,33 @@
* : failure: NULL (on failure to compile regex or allocate memory)
*/
struct parser *
parser_init (const char *regex)
parser_init(const char *regex)
{
int rc = 0;
struct parser *parser = NULL;
int rc = 0;
struct parser *parser = NULL;
parser = GF_MALLOC (sizeof(*parser), gf_common_mt_parser_t);
if (!parser)
goto out;
parser = GF_MALLOC(sizeof(*parser), gf_common_mt_parser_t);
if (!parser)
goto out;
parser->regex = gf_strdup (regex);
if (!parser->regex) {
GF_FREE (parser);
parser = NULL;
goto out;
}
parser->regex = gf_strdup(regex);
if (!parser->regex) {
GF_FREE(parser);
parser = NULL;
goto out;
}
rc = regcomp (&parser->preg, parser->regex, REG_EXTENDED);
if (rc != 0) {
gf_msg (GF_PARSE, GF_LOG_INFO, 0, LG_MSG_REGEX_OP_FAILED,
"Failed to compile regex pattern.");
parser_deinit (parser);
parser = NULL;
goto out;
}
parser->complete_str = NULL;
rc = regcomp(&parser->preg, parser->regex, REG_EXTENDED);
if (rc != 0) {
gf_msg(GF_PARSE, GF_LOG_INFO, 0, LG_MSG_REGEX_OP_FAILED,
"Failed to compile regex pattern.");
parser_deinit(parser);
parser = NULL;
goto out;
}
parser->complete_str = NULL;
out:
return parser;
return parser;
}
/**
@ -78,22 +78,22 @@ out:
* failure: -EINVAL for NULL args, -ENOMEM for allocation errors
*/
int
parser_set_string (struct parser *parser, const char *complete_str)
parser_set_string(struct parser *parser, const char *complete_str)
{
int ret = -EINVAL;
int ret = -EINVAL;
GF_VALIDATE_OR_GOTO (GF_PARSE, parser, out);
GF_VALIDATE_OR_GOTO (GF_PARSE, complete_str, out);
GF_VALIDATE_OR_GOTO(GF_PARSE, parser, out);
GF_VALIDATE_OR_GOTO(GF_PARSE, complete_str, out);
parser->complete_str = gf_strdup (complete_str);
GF_CHECK_ALLOC_AND_LOG (GF_PARSE, parser, ret,
"Failed to duplicate string!", out);
parser->complete_str = gf_strdup(complete_str);
GF_CHECK_ALLOC_AND_LOG(GF_PARSE, parser, ret, "Failed to duplicate string!",
out);
/* Point the temp internal string to what we just dup'ed */
parser->_rstr = (char *)parser->complete_str;
ret = 0;
/* Point the temp internal string to what we just dup'ed */
parser->_rstr = (char *)parser->complete_str;
ret = 0;
out:
return ret;
return ret;
}
/**
@ -107,17 +107,17 @@ out:
* : failure: -EINVAL on NULL args
*/
int
parser_unset_string (struct parser *parser)
parser_unset_string(struct parser *parser)
{
int ret = -EINVAL;
int ret = -EINVAL;
GF_VALIDATE_OR_GOTO (GF_PARSE, parser, out);
GF_VALIDATE_OR_GOTO(GF_PARSE, parser, out);
GF_FREE (parser->complete_str);
parser->complete_str = NULL; /* Avoid double frees in parser_deinit */
ret = 0;
GF_FREE(parser->complete_str);
parser->complete_str = NULL; /* Avoid double frees in parser_deinit */
ret = 0;
out:
return ret;
return ret;
}
/**
@ -128,15 +128,15 @@ out:
* @return : nothing
*/
void
parser_deinit (struct parser *ptr)
parser_deinit(struct parser *ptr)
{
if (!ptr)
return;
if (!ptr)
return;
regfree (&ptr->preg);
GF_FREE (ptr->complete_str);
GF_FREE (ptr->regex);
GF_FREE (ptr);
regfree(&ptr->preg);
GF_FREE(ptr->complete_str);
GF_FREE(ptr->regex);
GF_FREE(ptr);
}
/**
@ -149,29 +149,28 @@ parser_deinit (struct parser *ptr)
* : failure: NULL
*/
char *
parser_get_next_match (struct parser *parser)
parser_get_next_match(struct parser *parser)
{
int rc = -EINVAL;
size_t copy_len = 0;
char *match = NULL;
int rc = -EINVAL;
size_t copy_len = 0;
char *match = NULL;
GF_VALIDATE_OR_GOTO (GF_PARSE, parser, out);
GF_VALIDATE_OR_GOTO(GF_PARSE, parser, out);
rc = regexec (&parser->preg, parser->_rstr, 1, parser->pmatch, 0);
if (rc != 0) {
gf_msg_debug (GF_PARSE, 0,
"Could not match %s with regex %s",
parser->_rstr, parser->regex);
goto out;
}
rc = regexec(&parser->preg, parser->_rstr, 1, parser->pmatch, 0);
if (rc != 0) {
gf_msg_debug(GF_PARSE, 0, "Could not match %s with regex %s",
parser->_rstr, parser->regex);
goto out;
}
copy_len = parser->pmatch[0].rm_eo - parser->pmatch[0].rm_so;
copy_len = parser->pmatch[0].rm_eo - parser->pmatch[0].rm_so;
match = gf_strndup (parser->_rstr + parser->pmatch[0].rm_so, copy_len);
GF_CHECK_ALLOC_AND_LOG (GF_PARSE, match, rc,
"Duplicating match failed!", out);
match = gf_strndup(parser->_rstr + parser->pmatch[0].rm_so, copy_len);
GF_CHECK_ALLOC_AND_LOG(GF_PARSE, match, rc, "Duplicating match failed!",
out);
parser->_rstr = &parser->_rstr[parser->pmatch[0].rm_eo];
parser->_rstr = &parser->_rstr[parser->pmatch[0].rm_eo];
out:
return match;
return match;
}

View File

@ -8,7 +8,6 @@
cases as published by the Free Software Foundation.
*/
#include "dict.h"
#include "logging.h"
#include "byte-order.h"
@ -17,227 +16,224 @@
#include "libglusterfs-messages.h"
gf_boolean_t
quota_meta_is_null (const quota_meta_t *meta)
quota_meta_is_null(const quota_meta_t *meta)
{
if (meta->size == 0 &&
meta->file_count == 0 &&
meta->dir_count == 0)
return _gf_true;
if (meta->size == 0 && meta->file_count == 0 && meta->dir_count == 0)
return _gf_true;
return _gf_false;
return _gf_false;
}
int32_t
quota_data_to_meta (data_t *data, char *key, quota_meta_t *meta)
quota_data_to_meta(data_t *data, char *key, quota_meta_t *meta)
{
int32_t ret = -1;
quota_meta_t *value = NULL;
int64_t *size = NULL;
int32_t ret = -1;
quota_meta_t *value = NULL;
int64_t *size = NULL;
if (!data || !key || !meta)
goto out;
if (!data || !key || !meta)
goto out;
if (data->len > sizeof (int64_t)) {
value = (quota_meta_t *) data->data;
meta->size = ntoh64 (value->size);
meta->file_count = ntoh64 (value->file_count);
if (data->len > (sizeof (int64_t)) * 2)
meta->dir_count = ntoh64 (value->dir_count);
else
meta->dir_count = 0;
} else {
size = (int64_t *) data->data;
meta->size = ntoh64 (*size);
meta->file_count = 0;
meta->dir_count = 0;
/* This can happen during software upgrade.
* Older version of glusterfs will not have inode count.
* Return failure, this will be healed as part of lookup
*/
gf_msg_callingfn ("quota", GF_LOG_DEBUG, 0,
LG_MSG_QUOTA_XATTRS_MISSING, "Object quota "
"xattrs missing: len = %d", data->len);
ret = -2;
goto out;
}
ret = 0;
out:
return ret;
}
int32_t
quota_dict_get_inode_meta (dict_t *dict, char *key, quota_meta_t *meta)
{
int32_t ret = -1;
data_t *data = NULL;
if (!dict || !key || !meta)
goto out;
data = dict_get (dict, key);
if (!data || !data->data)
goto out;
ret = quota_data_to_meta (data, key, meta);
out:
return ret;
}
int32_t
quota_dict_get_meta (dict_t *dict, char *key, quota_meta_t *meta)
{
int32_t ret = -1;
ret = quota_dict_get_inode_meta (dict, key, meta);
if (ret == -2)
ret = 0;
return ret;
}
int32_t
quota_dict_set_meta (dict_t *dict, char *key, const quota_meta_t *meta,
ia_type_t ia_type)
{
int32_t ret = -ENOMEM;
quota_meta_t *value = NULL;
value = GF_MALLOC (sizeof (quota_meta_t), gf_common_quota_meta_t);
if (value == NULL) {
goto out;
}
value->size = hton64 (meta->size);
value->file_count = hton64 (meta->file_count);
value->dir_count = hton64 (meta->dir_count);
if (ia_type == IA_IFDIR) {
ret = dict_set_bin (dict, key, value, sizeof (*value));
} else {
/* For a file we don't need to store dir_count in the
* quota size xattr, so we set the len of the data in the dict
* as 128bits, so when the posix xattrop reads the dict, it only
* performs operations on size and file_count
*/
ret = dict_set_bin (dict, key, value,
sizeof (*value) - sizeof (int64_t));
}
if (ret < 0) {
gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
LG_MSG_DICT_SET_FAILED, "dict set failed");
GF_FREE (value);
}
out:
return ret;
}
int32_t
quota_conf_read_header (int fd, char *buf)
{
int ret = 0;
const int header_len = SLEN (QUOTA_CONF_HEADER);
ret = gf_nread (fd, buf, header_len);
if (ret <= 0) {
goto out;
} else if (ret > 0 && ret != header_len) {
ret = -1;
goto out;
}
buf[header_len-1] = 0;
out:
if (ret < 0)
gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
LG_MSG_QUOTA_CONF_ERROR, "failed to read "
"header from a quota conf");
return ret;
}
int32_t
quota_conf_read_version (int fd, float *version)
{
int ret = 0;
char buf[PATH_MAX] = "";
char *tail = NULL;
float value = 0.0f;
ret = quota_conf_read_header (fd, buf);
if (ret == 0) {
/* quota.conf is empty */
value = GF_QUOTA_CONF_VERSION;
goto out;
} else if (ret < 0) {
goto out;
}
value = strtof ((buf + strlen(buf) - 3), &tail);
if (tail[0] != '\0') {
ret = -1;
gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
LG_MSG_QUOTA_CONF_ERROR, "invalid quota conf"
" version");
goto out;
}
ret = 0;
out:
if (ret >= 0)
*version = value;
if (data->len > sizeof(int64_t)) {
value = (quota_meta_t *)data->data;
meta->size = ntoh64(value->size);
meta->file_count = ntoh64(value->file_count);
if (data->len > (sizeof(int64_t)) * 2)
meta->dir_count = ntoh64(value->dir_count);
else
gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
LG_MSG_QUOTA_CONF_ERROR, "failed to "
"read version from a quota conf header");
meta->dir_count = 0;
} else {
size = (int64_t *)data->data;
meta->size = ntoh64(*size);
meta->file_count = 0;
meta->dir_count = 0;
/* This can happen during software upgrade.
* Older version of glusterfs will not have inode count.
* Return failure, this will be healed as part of lookup
*/
gf_msg_callingfn("quota", GF_LOG_DEBUG, 0, LG_MSG_QUOTA_XATTRS_MISSING,
"Object quota "
"xattrs missing: len = %d",
data->len);
ret = -2;
goto out;
}
return ret;
ret = 0;
out:
return ret;
}
int32_t
quota_conf_read_gfid (int fd, void *buf, char *type, float version)
quota_dict_get_inode_meta(dict_t *dict, char *key, quota_meta_t *meta)
{
int ret = 0;
int32_t ret = -1;
data_t *data = NULL;
ret = gf_nread (fd, buf, 16);
if (ret <= 0)
goto out;
if (!dict || !key || !meta)
goto out;
if (ret != 16) {
ret = -1;
goto out;
}
data = dict_get(dict, key);
if (!data || !data->data)
goto out;
if (version >= 1.2f) {
ret = gf_nread (fd, type, 1);
if (ret != 1) {
ret = -1;
goto out;
}
ret = 17;
} else {
*type = GF_QUOTA_CONF_TYPE_USAGE;
}
ret = quota_data_to_meta(data, key, meta);
out:
if (ret < 0)
gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
LG_MSG_QUOTA_CONF_ERROR, "failed to "
"read gfid from a quota conf");
return ret;
return ret;
}
int32_t
quota_conf_skip_header (int fd)
quota_dict_get_meta(dict_t *dict, char *key, quota_meta_t *meta)
{
return gf_skip_header_section (fd, strlen (QUOTA_CONF_HEADER));
int32_t ret = -1;
ret = quota_dict_get_inode_meta(dict, key, meta);
if (ret == -2)
ret = 0;
return ret;
}
int32_t
quota_dict_set_meta(dict_t *dict, char *key, const quota_meta_t *meta,
ia_type_t ia_type)
{
int32_t ret = -ENOMEM;
quota_meta_t *value = NULL;
value = GF_MALLOC(sizeof(quota_meta_t), gf_common_quota_meta_t);
if (value == NULL) {
goto out;
}
value->size = hton64(meta->size);
value->file_count = hton64(meta->file_count);
value->dir_count = hton64(meta->dir_count);
if (ia_type == IA_IFDIR) {
ret = dict_set_bin(dict, key, value, sizeof(*value));
} else {
/* For a file we don't need to store dir_count in the
* quota size xattr, so we set the len of the data in the dict
* as 128bits, so when the posix xattrop reads the dict, it only
* performs operations on size and file_count
*/
ret = dict_set_bin(dict, key, value, sizeof(*value) - sizeof(int64_t));
}
if (ret < 0) {
gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_DICT_SET_FAILED,
"dict set failed");
GF_FREE(value);
}
out:
return ret;
}
int32_t
quota_conf_read_header(int fd, char *buf)
{
int ret = 0;
const int header_len = SLEN(QUOTA_CONF_HEADER);
ret = gf_nread(fd, buf, header_len);
if (ret <= 0) {
goto out;
} else if (ret > 0 && ret != header_len) {
ret = -1;
goto out;
}
buf[header_len - 1] = 0;
out:
if (ret < 0)
gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
"failed to read "
"header from a quota conf");
return ret;
}
int32_t
quota_conf_read_version(int fd, float *version)
{
int ret = 0;
char buf[PATH_MAX] = "";
char *tail = NULL;
float value = 0.0f;
ret = quota_conf_read_header(fd, buf);
if (ret == 0) {
/* quota.conf is empty */
value = GF_QUOTA_CONF_VERSION;
goto out;
} else if (ret < 0) {
goto out;
}
value = strtof((buf + strlen(buf) - 3), &tail);
if (tail[0] != '\0') {
ret = -1;
gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
"invalid quota conf"
" version");
goto out;
}
ret = 0;
out:
if (ret >= 0)
*version = value;
else
gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
"failed to "
"read version from a quota conf header");
return ret;
}
int32_t
quota_conf_read_gfid(int fd, void *buf, char *type, float version)
{
int ret = 0;
ret = gf_nread(fd, buf, 16);
if (ret <= 0)
goto out;
if (ret != 16) {
ret = -1;
goto out;
}
if (version >= 1.2f) {
ret = gf_nread(fd, type, 1);
if (ret != 1) {
ret = -1;
goto out;
}
ret = 17;
} else {
*type = GF_QUOTA_CONF_TYPE_USAGE;
}
out:
if (ret < 0)
gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
"failed to "
"read gfid from a quota conf");
return ret;
}
int32_t
quota_conf_skip_header(int fd)
{
return gf_skip_header_section(fd, strlen(QUOTA_CONF_HEADER));
}

View File

@ -8,7 +8,6 @@
cases as published by the Free Software Foundation.
*/
#include "rbthash.h"
#include "rb.h"
#include "locking.h"
@ -19,59 +18,57 @@
#include <pthread.h>
#include <string.h>
int
rbthash_comparator (void *entry1, void *entry2, void *param)
rbthash_comparator(void *entry1, void *entry2, void *param)
{
int ret = 0;
rbthash_entry_t *e1 = NULL;
rbthash_entry_t *e2 = NULL;
int ret = 0;
rbthash_entry_t *e1 = NULL;
rbthash_entry_t *e2 = NULL;
if ((!entry1) || (!entry2) || (!param))
return -1;
if ((!entry1) || (!entry2) || (!param))
return -1;
e1 = (rbthash_entry_t *)entry1;
e2 = (rbthash_entry_t *)entry2;
e1 = (rbthash_entry_t *)entry1;
e2 = (rbthash_entry_t *)entry2;
if (e1->keylen != e2->keylen) {
if (e1->keylen < e2->keylen)
ret = -1;
else if (e1->keylen > e2->keylen)
ret = 1;
} else
ret = memcmp (e1->key, e2->key, e1->keylen);
if (e1->keylen != e2->keylen) {
if (e1->keylen < e2->keylen)
ret = -1;
else if (e1->keylen > e2->keylen)
ret = 1;
} else
ret = memcmp(e1->key, e2->key, e1->keylen);
return ret;
return ret;
}
int
__rbthash_init_buckets (rbthash_table_t *tbl, int buckets)
__rbthash_init_buckets(rbthash_table_t *tbl, int buckets)
{
int i = 0;
int ret = -1;
int i = 0;
int ret = -1;
if (!tbl)
return -1;
if (!tbl)
return -1;
for (; i < buckets; i++) {
LOCK_INIT (&tbl->buckets[i].bucketlock);
tbl->buckets[i].bucket = rb_create ((rb_comparison_func *)rbthash_comparator, tbl, NULL);
if (!tbl->buckets[i].bucket) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
LG_MSG_RB_TABLE_CREATE_FAILED, "Failed to "
"create rb table bucket");
ret = -1;
goto err;
}
for (; i < buckets; i++) {
LOCK_INIT(&tbl->buckets[i].bucketlock);
tbl->buckets[i].bucket = rb_create(
(rb_comparison_func *)rbthash_comparator, tbl, NULL);
if (!tbl->buckets[i].bucket) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RB_TABLE_CREATE_FAILED,
"Failed to "
"create rb table bucket");
ret = -1;
goto err;
}
}
ret = 0;
ret = 0;
err:
return ret;
return ret;
}
/*
* rbthash_table_init - Initialize a RBT based hash table
* @buckets - Number of buckets in the hash table
@ -83,391 +80,377 @@ err:
*/
rbthash_table_t *
rbthash_table_init (glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc,
rbt_data_destroyer_t dfunc,
unsigned long expected_entries,
struct mem_pool *entrypool)
rbthash_table_init(glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc,
rbt_data_destroyer_t dfunc, unsigned long expected_entries,
struct mem_pool *entrypool)
{
rbthash_table_t *newtab = NULL;
int ret = -1;
rbthash_table_t *newtab = NULL;
int ret = -1;
if (!hfunc) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_HASH_FUNC_ERROR,
"Hash function not given");
return NULL;
if (!hfunc) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_HASH_FUNC_ERROR,
"Hash function not given");
return NULL;
}
if (!entrypool && !expected_entries) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
"Both mem-pool and expected entries not provided");
return NULL;
}
if (entrypool && expected_entries) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
"Both mem-pool and expected entries are provided");
return NULL;
}
newtab = GF_CALLOC(1, sizeof(*newtab), gf_common_mt_rbthash_table_t);
if (!newtab)
return NULL;
newtab->buckets = GF_CALLOC(buckets, sizeof(struct rbthash_bucket),
gf_common_mt_rbthash_bucket);
if (!newtab->buckets) {
goto free_newtab;
}
if (expected_entries) {
newtab->entrypool = mem_pool_new_ctx(ctx, rbthash_entry_t,
expected_entries);
if (!newtab->entrypool) {
goto free_buckets;
}
newtab->pool_alloced = _gf_true;
} else {
newtab->entrypool = entrypool;
}
if (!entrypool && !expected_entries) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
"Both mem-pool and expected entries not provided");
return NULL;
}
LOCK_INIT(&newtab->tablelock);
INIT_LIST_HEAD(&newtab->list);
newtab->numbuckets = buckets;
ret = __rbthash_init_buckets(newtab, buckets);
if (entrypool && expected_entries) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
"Both mem-pool and expected entries are provided");
return NULL;
}
if (ret == -1) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INIT_BUCKET_FAILED,
"Failed to init buckets");
if (newtab->pool_alloced)
mem_pool_destroy(newtab->entrypool);
} else {
gf_msg_trace(GF_RBTHASH, 0,
"Inited hash table: buckets:"
" %d",
buckets);
}
newtab = GF_CALLOC (1, sizeof (*newtab),
gf_common_mt_rbthash_table_t);
if (!newtab)
return NULL;
newtab->buckets = GF_CALLOC (buckets, sizeof (struct rbthash_bucket),
gf_common_mt_rbthash_bucket);
if (!newtab->buckets) {
goto free_newtab;
}
if (expected_entries) {
newtab->entrypool =
mem_pool_new_ctx (ctx, rbthash_entry_t,
expected_entries);
if (!newtab->entrypool) {
goto free_buckets;
}
newtab->pool_alloced = _gf_true;
} else {
newtab->entrypool = entrypool;
}
LOCK_INIT (&newtab->tablelock);
INIT_LIST_HEAD (&newtab->list);
newtab->numbuckets = buckets;
ret = __rbthash_init_buckets (newtab, buckets);
if (ret == -1) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
LG_MSG_RBTHASH_INIT_BUCKET_FAILED,
"Failed to init buckets");
if (newtab->pool_alloced)
mem_pool_destroy (newtab->entrypool);
} else {
gf_msg_trace (GF_RBTHASH, 0, "Inited hash table: buckets:"
" %d", buckets);
}
newtab->hashfunc = hfunc;
newtab->dfunc = dfunc;
newtab->hashfunc = hfunc;
newtab->dfunc = dfunc;
free_buckets:
if (ret == -1)
GF_FREE (newtab->buckets);
if (ret == -1)
GF_FREE(newtab->buckets);
free_newtab:
if (ret == -1) {
GF_FREE (newtab);
newtab = NULL;
}
if (ret == -1) {
GF_FREE(newtab);
newtab = NULL;
}
return newtab;
return newtab;
}
rbthash_entry_t *
rbthash_init_entry (rbthash_table_t *tbl, void *data, void *key, int keylen)
rbthash_init_entry(rbthash_table_t *tbl, void *data, void *key, int keylen)
{
int ret = -1;
rbthash_entry_t *entry = NULL;
int ret = -1;
rbthash_entry_t *entry = NULL;
if ((!tbl) || (!data) || (!key))
return NULL;
if ((!tbl) || (!data) || (!key))
return NULL;
entry = mem_get (tbl->entrypool);
if (!entry) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
LG_MSG_RBTHASH_GET_ENTRY_FAILED,
"Failed to get entry from mem-pool");
goto ret;
}
entry = mem_get(tbl->entrypool);
if (!entry) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_ENTRY_FAILED,
"Failed to get entry from mem-pool");
goto ret;
}
entry->data = data;
entry->key = GF_MALLOC (keylen, gf_common_mt_char);
if (!entry->key) {
goto free_entry;
}
entry->data = data;
entry->key = GF_MALLOC(keylen, gf_common_mt_char);
if (!entry->key) {
goto free_entry;
}
INIT_LIST_HEAD (&entry->list);
memcpy (entry->key, key, keylen);
entry->keylen = keylen;
entry->keyhash = tbl->hashfunc (entry->key, entry->keylen);
gf_msg_trace (GF_RBTHASH, 0, "HASH: %u", entry->keyhash);
INIT_LIST_HEAD(&entry->list);
memcpy(entry->key, key, keylen);
entry->keylen = keylen;
entry->keyhash = tbl->hashfunc(entry->key, entry->keylen);
gf_msg_trace(GF_RBTHASH, 0, "HASH: %u", entry->keyhash);
ret = 0;
ret = 0;
free_entry:
if (ret == -1) {
mem_put (entry);
entry = NULL;
}
if (ret == -1) {
mem_put(entry);
entry = NULL;
}
ret:
return entry;
return entry;
}
void
rbthash_deinit_entry (rbthash_table_t *tbl, rbthash_entry_t *entry)
rbthash_deinit_entry(rbthash_table_t *tbl, rbthash_entry_t *entry)
{
if (!entry)
return;
GF_FREE (entry->key);
if (tbl) {
if ((entry->data) && (tbl->dfunc))
tbl->dfunc (entry->data);
LOCK (&tbl->tablelock);
{
list_del_init (&entry->list);
}
UNLOCK (&tbl->tablelock);
mem_put (entry);
}
if (!entry)
return;
}
GF_FREE(entry->key);
static struct rbthash_bucket *
rbthash_entry_bucket (rbthash_table_t *tbl, rbthash_entry_t * entry)
{
int nbucket = 0;
if (tbl) {
if ((entry->data) && (tbl->dfunc))
tbl->dfunc(entry->data);
nbucket = (entry->keyhash % tbl->numbuckets);
gf_msg_trace (GF_RBTHASH, 0, "BUCKET: %d", nbucket);
return &tbl->buckets[nbucket];
}
int
rbthash_insert_entry (rbthash_table_t *tbl, rbthash_entry_t *entry)
{
struct rbthash_bucket *bucket = NULL;
int ret = -1;
if ((!tbl) || (!entry))
return -1;
bucket = rbthash_entry_bucket (tbl, entry);
if (!bucket) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
LG_MSG_RBTHASH_GET_BUCKET_FAILED,
"Failed to get bucket");
goto err;
}
ret = 0;
LOCK (&bucket->bucketlock);
LOCK(&tbl->tablelock);
{
if (!rb_probe (bucket->bucket, (void *)entry)) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
LG_MSG_RBTHASH_INSERT_FAILED, "Failed to insert"
" entry");
ret = -1;
}
list_del_init(&entry->list);
}
UNLOCK (&bucket->bucketlock);
UNLOCK(&tbl->tablelock);
err:
return ret;
}
mem_put(entry);
}
int
rbthash_insert (rbthash_table_t *tbl, void *data, void *key, int keylen)
{
rbthash_entry_t *entry = NULL;
int ret = -1;
if ((!tbl) || (!data) || (!key))
return -1;
entry = rbthash_init_entry (tbl, data, key, keylen);
if (!entry) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
LG_MSG_RBTHASH_INIT_ENTRY_FAILED,
"Failed to init entry");
goto err;
}
ret = rbthash_insert_entry (tbl, entry);
if (ret == -1) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
LG_MSG_RBTHASH_INSERT_FAILED,
"Failed to insert entry");
rbthash_deinit_entry (tbl, entry);
}
LOCK (&tbl->tablelock);
{
list_add_tail (&entry->list, &tbl->list);
}
UNLOCK (&tbl->tablelock);
err:
return ret;
return;
}
static struct rbthash_bucket *
rbthash_key_bucket (rbthash_table_t *tbl, void *key, int keylen)
rbthash_entry_bucket(rbthash_table_t *tbl, rbthash_entry_t *entry)
{
uint32_t keyhash = 0;
int nbucket = 0;
int nbucket = 0;
if ((!tbl) || (!key))
return NULL;
keyhash = tbl->hashfunc (key, keylen);
gf_msg_trace (GF_RBTHASH, 0, "HASH: %u", keyhash);
nbucket = (keyhash % tbl->numbuckets);
gf_msg_trace (GF_RBTHASH, 0, "BUCKET: %u", nbucket);
return &tbl->buckets[nbucket];
nbucket = (entry->keyhash % tbl->numbuckets);
gf_msg_trace(GF_RBTHASH, 0, "BUCKET: %d", nbucket);
return &tbl->buckets[nbucket];
}
int
rbthash_insert_entry(rbthash_table_t *tbl, rbthash_entry_t *entry)
{
struct rbthash_bucket *bucket = NULL;
int ret = -1;
if ((!tbl) || (!entry))
return -1;
bucket = rbthash_entry_bucket(tbl, entry);
if (!bucket) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED,
"Failed to get bucket");
goto err;
}
ret = 0;
LOCK(&bucket->bucketlock);
{
if (!rb_probe(bucket->bucket, (void *)entry)) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED,
"Failed to insert"
" entry");
ret = -1;
}
}
UNLOCK(&bucket->bucketlock);
err:
return ret;
}
int
rbthash_insert(rbthash_table_t *tbl, void *data, void *key, int keylen)
{
rbthash_entry_t *entry = NULL;
int ret = -1;
if ((!tbl) || (!data) || (!key))
return -1;
entry = rbthash_init_entry(tbl, data, key, keylen);
if (!entry) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INIT_ENTRY_FAILED,
"Failed to init entry");
goto err;
}
ret = rbthash_insert_entry(tbl, entry);
if (ret == -1) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED,
"Failed to insert entry");
rbthash_deinit_entry(tbl, entry);
}
LOCK(&tbl->tablelock);
{
list_add_tail(&entry->list, &tbl->list);
}
UNLOCK(&tbl->tablelock);
err:
return ret;
}
static struct rbthash_bucket *
rbthash_key_bucket(rbthash_table_t *tbl, void *key, int keylen)
{
uint32_t keyhash = 0;
int nbucket = 0;
if ((!tbl) || (!key))
return NULL;
keyhash = tbl->hashfunc(key, keylen);
gf_msg_trace(GF_RBTHASH, 0, "HASH: %u", keyhash);
nbucket = (keyhash % tbl->numbuckets);
gf_msg_trace(GF_RBTHASH, 0, "BUCKET: %u", nbucket);
return &tbl->buckets[nbucket];
}
void *
rbthash_get (rbthash_table_t *tbl, void *key, int keylen)
rbthash_get(rbthash_table_t *tbl, void *key, int keylen)
{
struct rbthash_bucket *bucket = NULL;
rbthash_entry_t *entry = NULL;
rbthash_entry_t searchentry = {0, };
struct rbthash_bucket *bucket = NULL;
rbthash_entry_t *entry = NULL;
rbthash_entry_t searchentry = {
0,
};
if ((!tbl) || (!key))
return NULL;
if ((!tbl) || (!key))
return NULL;
bucket = rbthash_key_bucket (tbl, key, keylen);
if (!bucket) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_GET_BUCKET_FAILED,
"Failed to get bucket");
return NULL;
}
bucket = rbthash_key_bucket(tbl, key, keylen);
if (!bucket) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_GET_BUCKET_FAILED,
"Failed to get bucket");
return NULL;
}
searchentry.key = key;
searchentry.keylen = keylen;
LOCK (&bucket->bucketlock);
{
entry = rb_find (bucket->bucket, &searchentry);
}
UNLOCK (&bucket->bucketlock);
searchentry.key = key;
searchentry.keylen = keylen;
LOCK(&bucket->bucketlock);
{
entry = rb_find(bucket->bucket, &searchentry);
}
UNLOCK(&bucket->bucketlock);
if (!entry)
return NULL;
if (!entry)
return NULL;
return entry->data;
return entry->data;
}
void *
rbthash_remove (rbthash_table_t *tbl, void *key, int keylen)
rbthash_remove(rbthash_table_t *tbl, void *key, int keylen)
{
struct rbthash_bucket *bucket = NULL;
rbthash_entry_t *entry = NULL;
rbthash_entry_t searchentry = {0, };
void *dataref = NULL;
struct rbthash_bucket *bucket = NULL;
rbthash_entry_t *entry = NULL;
rbthash_entry_t searchentry = {
0,
};
void *dataref = NULL;
if ((!tbl) || (!key))
return NULL;
if ((!tbl) || (!key))
return NULL;
bucket = rbthash_key_bucket (tbl, key, keylen);
if (!bucket) {
gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
LG_MSG_RBTHASH_GET_BUCKET_FAILED,
"Failed to get bucket");
return NULL;
}
bucket = rbthash_key_bucket(tbl, key, keylen);
if (!bucket) {
gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED,
"Failed to get bucket");
return NULL;
}
searchentry.key = key;
searchentry.keylen = keylen;
searchentry.key = key;
searchentry.keylen = keylen;
LOCK (&bucket->bucketlock);
{
entry = rb_delete (bucket->bucket, &searchentry);
}
UNLOCK (&bucket->bucketlock);
LOCK(&bucket->bucketlock);
{
entry = rb_delete(bucket->bucket, &searchentry);
}
UNLOCK(&bucket->bucketlock);
if (!entry)
return NULL;
if (!entry)
return NULL;
GF_FREE (entry->key);
dataref = entry->data;
GF_FREE(entry->key);
dataref = entry->data;
LOCK (&tbl->tablelock);
{
list_del_init (&entry->list);
}
UNLOCK (&tbl->tablelock);
LOCK(&tbl->tablelock);
{
list_del_init(&entry->list);
}
UNLOCK(&tbl->tablelock);
mem_put (entry);
mem_put(entry);
return dataref;
return dataref;
}
void
rbthash_entry_deiniter (void *entry, void *rbparam)
rbthash_entry_deiniter(void *entry, void *rbparam)
{
if (!entry)
return;
rbthash_deinit_entry (rbparam, entry);
}
void
rbthash_table_destroy_buckets (rbthash_table_t *tbl)
{
int x = 0;
if (!tbl)
return;
for (;x < tbl->numbuckets; x++) {
LOCK_DESTROY (&tbl->buckets[x].bucketlock);
rb_destroy (tbl->buckets[x].bucket, rbthash_entry_deiniter);
}
if (!entry)
return;
rbthash_deinit_entry(rbparam, entry);
}
void
rbthash_table_destroy (rbthash_table_t *tbl)
rbthash_table_destroy_buckets(rbthash_table_t *tbl)
{
if (!tbl)
return;
int x = 0;
if (!tbl)
return;
rbthash_table_destroy_buckets (tbl);
if (tbl->pool_alloced)
mem_pool_destroy (tbl->entrypool);
for (; x < tbl->numbuckets; x++) {
LOCK_DESTROY(&tbl->buckets[x].bucketlock);
rb_destroy(tbl->buckets[x].bucket, rbthash_entry_deiniter);
}
GF_FREE (tbl->buckets);
GF_FREE (tbl);
return;
}
void
rbthash_table_destroy(rbthash_table_t *tbl)
{
if (!tbl)
return;
rbthash_table_destroy_buckets(tbl);
if (tbl->pool_alloced)
mem_pool_destroy(tbl->entrypool);
GF_FREE(tbl->buckets);
GF_FREE(tbl);
}
void
rbthash_table_traverse (rbthash_table_t *tbl, rbt_traverse_t traverse,
void *mydata)
rbthash_table_traverse(rbthash_table_t *tbl, rbt_traverse_t traverse,
void *mydata)
{
rbthash_entry_t *entry = NULL;
rbthash_entry_t *entry = NULL;
if ((tbl == NULL) || (traverse == NULL)) {
goto out;
}
if ((tbl == NULL) || (traverse == NULL)) {
goto out;
}
LOCK (&tbl->tablelock);
LOCK(&tbl->tablelock);
{
list_for_each_entry(entry, &tbl->list, list)
{
list_for_each_entry (entry, &tbl->list, list) {
traverse (entry->data, mydata);
}
traverse(entry->data, mydata);
}
UNLOCK (&tbl->tablelock);
}
UNLOCK(&tbl->tablelock);
out:
return;
return;
}

View File

@ -14,96 +14,95 @@
#ifndef REFCOUNT_NEEDS_LOCK
void *
_gf_ref_get (gf_ref_t *ref)
_gf_ref_get(gf_ref_t *ref)
{
unsigned int cnt = __sync_fetch_and_add (&ref->cnt, 1);
unsigned int cnt = __sync_fetch_and_add(&ref->cnt, 1);
/* if cnt == 0, we're in a fatal position, the object will be free'd
*
* There is a race when two threads do a _gf_ref_get(). Only one of
* them may get a 0 returned. That is acceptable, because one
* _gf_ref_get() returning 0 should be handled as a fatal problem and
* when correct usage/locking is used, it should never happen.
*/
GF_ASSERT (cnt != 0);
/* if cnt == 0, we're in a fatal position, the object will be free'd
*
* There is a race when two threads do a _gf_ref_get(). Only one of
* them may get a 0 returned. That is acceptable, because one
* _gf_ref_get() returning 0 should be handled as a fatal problem and
* when correct usage/locking is used, it should never happen.
*/
GF_ASSERT(cnt != 0);
return cnt ? ref->data : NULL;
return cnt ? ref->data : NULL;
}
unsigned int
_gf_ref_put (gf_ref_t *ref)
_gf_ref_put(gf_ref_t *ref)
{
unsigned int cnt = __sync_fetch_and_sub (&ref->cnt, 1);
unsigned int cnt = __sync_fetch_and_sub(&ref->cnt, 1);
/* if cnt == 1, the last user just did a _gf_ref_put()
*
* When cnt == 0, one _gf_ref_put() was done too much and there has
* been a thread using the refcounted structure when it was not
* supposed to.
*/
GF_ASSERT (cnt != 0);
/* if cnt == 1, the last user just did a _gf_ref_put()
*
* When cnt == 0, one _gf_ref_put() was done too much and there has
* been a thread using the refcounted structure when it was not
* supposed to.
*/
GF_ASSERT(cnt != 0);
if (cnt == 1 && ref->release)
ref->release (ref->data);
if (cnt == 1 && ref->release)
ref->release(ref->data);
return (cnt != 1);
return (cnt != 1);
}
#else
void *
_gf_ref_get (gf_ref_t *ref)
_gf_ref_get(gf_ref_t *ref)
{
unsigned int cnt = 0;
unsigned int cnt = 0;
LOCK (&ref->lk);
{
/* never can be 0, should have been free'd */
if (ref->cnt > 0)
cnt = ++ref->cnt;
else
GF_ASSERT (ref->cnt > 0);
}
UNLOCK (&ref->lk);
LOCK(&ref->lk);
{
/* never can be 0, should have been free'd */
if (ref->cnt > 0)
cnt = ++ref->cnt;
else
GF_ASSERT(ref->cnt > 0);
}
UNLOCK(&ref->lk);
return cnt ? ref->data : NULL;
return cnt ? ref->data : NULL;
}
unsigned int
_gf_ref_put (gf_ref_t *ref)
_gf_ref_put(gf_ref_t *ref)
{
unsigned int cnt = 0;
int release = 0;
unsigned int cnt = 0;
int release = 0;
LOCK (&ref->lk);
{
if (ref->cnt != 0) {
cnt = --ref->cnt;
/* call release() only when cnt == 0 */
release = (cnt == 0);
} else
GF_ASSERT (ref->cnt != 0);
}
UNLOCK (&ref->lk);
LOCK(&ref->lk);
{
if (ref->cnt != 0) {
cnt = --ref->cnt;
/* call release() only when cnt == 0 */
release = (cnt == 0);
} else
GF_ASSERT(ref->cnt != 0);
}
UNLOCK(&ref->lk);
if (release && ref->release)
ref->release (ref->data);
if (release && ref->release)
ref->release(ref->data);
return !release;
return !release;
}
#endif /* REFCOUNT_NEEDS_LOCK */
void
_gf_ref_init (gf_ref_t *ref, gf_ref_release_t release, void *data)
_gf_ref_init(gf_ref_t *ref, gf_ref_release_t release, void *data)
{
GF_ASSERT (ref);
GF_ASSERT(ref);
#ifdef REFCOUNT_NEEDS_LOCK
LOCK_INIT (&ref->lk);
LOCK_INIT(&ref->lk);
#endif
ref->cnt = 1;
ref->release = release;
ref->data = data;
ref->cnt = 1;
ref->release = release;
ref->data = data;
}

View File

@ -26,10 +26,10 @@
* TODO: do away with opaques (use arrays with indexing).
*/
#define ROT_BUFF_DEFAULT_COUNT 2
#define ROT_BUFF_ALLOC_SIZE (1 * 1024 * 1024) /* 1MB per iovec */
#define ROT_BUFF_DEFAULT_COUNT 2
#define ROT_BUFF_ALLOC_SIZE (1 * 1024 * 1024) /* 1MB per iovec */
#define RLIST_IOV_MELDED_ALLOC_SIZE (RBUF_IOVEC_SIZE + ROT_BUFF_ALLOC_SIZE)
#define RLIST_IOV_MELDED_ALLOC_SIZE (RBUF_IOVEC_SIZE + ROT_BUFF_ALLOC_SIZE)
/**
* iovec list is not shrunk (deallocated) if usage/total count
@ -37,373 +37,369 @@
* most of the workloads. for the rest shrinking iovec list is
* generous.
*/
#define RVEC_LOW_WATERMARK_COUNT 1
#define RVEC_LOW_WATERMARK_COUNT 1
#define RVEC_HIGH_WATERMARK_COUNT (1 << 4)
static inline
rbuf_list_t *rbuf_current_buffer (rbuf_t *rbuf)
static inline rbuf_list_t *
rbuf_current_buffer(rbuf_t *rbuf)
{
return rbuf->current;
return rbuf->current;
}
static void
rlist_mark_waiting (rbuf_list_t *rlist)
rlist_mark_waiting(rbuf_list_t *rlist)
{
LOCK (&rlist->c_lock);
{
rlist->awaiting = _gf_true;
}
UNLOCK (&rlist->c_lock);
LOCK(&rlist->c_lock);
{
rlist->awaiting = _gf_true;
}
UNLOCK(&rlist->c_lock);
}
static int
__rlist_has_waiter (rbuf_list_t *rlist)
__rlist_has_waiter(rbuf_list_t *rlist)
{
return (rlist->awaiting == _gf_true);
return (rlist->awaiting == _gf_true);
}
static void *
rbuf_alloc_rvec ()
rbuf_alloc_rvec()
{
return GF_CALLOC (1, RLIST_IOV_MELDED_ALLOC_SIZE, gf_common_mt_rvec_t);
return GF_CALLOC(1, RLIST_IOV_MELDED_ALLOC_SIZE, gf_common_mt_rvec_t);
}
static void
rlist_reset_vector_usage (rbuf_list_t *rlist)
rlist_reset_vector_usage(rbuf_list_t *rlist)
{
rlist->used = 1;
rlist->used = 1;
}
static void
rlist_increment_vector_usage (rbuf_list_t *rlist)
rlist_increment_vector_usage(rbuf_list_t *rlist)
{
rlist->used++;
rlist->used++;
}
static void
rlist_increment_total_usage (rbuf_list_t *rlist)
rlist_increment_total_usage(rbuf_list_t *rlist)
{
rlist->total++;
rlist->total++;
}
static int
rvec_in_watermark_range (rbuf_list_t *rlist)
rvec_in_watermark_range(rbuf_list_t *rlist)
{
return ((rlist->total >= RVEC_LOW_WATERMARK_COUNT)
&& (rlist->total <= RVEC_HIGH_WATERMARK_COUNT));
return ((rlist->total >= RVEC_LOW_WATERMARK_COUNT) &&
(rlist->total <= RVEC_HIGH_WATERMARK_COUNT));
}
static void
rbuf_reset_rvec (rbuf_iovec_t *rvec)
rbuf_reset_rvec(rbuf_iovec_t *rvec)
{
/* iov_base is _never_ modified */
rvec->iov.iov_len = 0;
/* iov_base is _never_ modified */
rvec->iov.iov_len = 0;
}
/* TODO: alloc multiple rbuf_iovec_t */
static int
rlist_add_new_vec (rbuf_list_t *rlist)
rlist_add_new_vec(rbuf_list_t *rlist)
{
rbuf_iovec_t *rvec = NULL;
rbuf_iovec_t *rvec = NULL;
rvec = (rbuf_iovec_t *) rbuf_alloc_rvec ();
if (!rvec)
return -1;
INIT_LIST_HEAD (&rvec->list);
rvec->iov.iov_base = ((char *)rvec) + RBUF_IOVEC_SIZE;
rvec->iov.iov_len = 0;
rvec = (rbuf_iovec_t *)rbuf_alloc_rvec();
if (!rvec)
return -1;
INIT_LIST_HEAD(&rvec->list);
rvec->iov.iov_base = ((char *)rvec) + RBUF_IOVEC_SIZE;
rvec->iov.iov_len = 0;
list_add_tail (&rvec->list, &rlist->veclist);
list_add_tail(&rvec->list, &rlist->veclist);
rlist->rvec = rvec; /* cache the latest */
rlist->rvec = rvec; /* cache the latest */
rlist_increment_vector_usage (rlist);
rlist_increment_total_usage (rlist);
rlist_increment_vector_usage(rlist);
rlist_increment_total_usage(rlist);
return 0;
return 0;
}
static void
rlist_free_rvec (rbuf_iovec_t *rvec)
rlist_free_rvec(rbuf_iovec_t *rvec)
{
if (!rvec)
return;
list_del (&rvec->list);
GF_FREE (rvec);
if (!rvec)
return;
list_del(&rvec->list);
GF_FREE(rvec);
}
static void
rlist_purge_all_rvec (rbuf_list_t *rlist)
rlist_purge_all_rvec(rbuf_list_t *rlist)
{
rbuf_iovec_t *rvec = NULL;
rbuf_iovec_t *rvec = NULL;
if (!rlist)
return;
while (!list_empty (&rlist->veclist)) {
rvec = list_first_entry (&rlist->veclist, rbuf_iovec_t, list);
rlist_free_rvec (rvec);
}
if (!rlist)
return;
while (!list_empty(&rlist->veclist)) {
rvec = list_first_entry(&rlist->veclist, rbuf_iovec_t, list);
rlist_free_rvec(rvec);
}
}
static void
rlist_shrink_rvec (rbuf_list_t *rlist, unsigned long long shrink)
rlist_shrink_rvec(rbuf_list_t *rlist, unsigned long long shrink)
{
rbuf_iovec_t *rvec = NULL;
rbuf_iovec_t *rvec = NULL;
while (!list_empty (&rlist->veclist) && (shrink-- > 0)) {
rvec = list_first_entry (&rlist->veclist, rbuf_iovec_t, list);
rlist_free_rvec (rvec);
}
while (!list_empty(&rlist->veclist) && (shrink-- > 0)) {
rvec = list_first_entry(&rlist->veclist, rbuf_iovec_t, list);
rlist_free_rvec(rvec);
}
}
static void
rbuf_purge_rlist (rbuf_t *rbuf)
rbuf_purge_rlist(rbuf_t *rbuf)
{
rbuf_list_t *rlist = NULL;
rbuf_list_t *rlist = NULL;
while (!list_empty (&rbuf->freelist)) {
rlist = list_first_entry (&rbuf->freelist, rbuf_list_t, list);
list_del (&rlist->list);
while (!list_empty(&rbuf->freelist)) {
rlist = list_first_entry(&rbuf->freelist, rbuf_list_t, list);
list_del(&rlist->list);
rlist_purge_all_rvec (rlist);
rlist_purge_all_rvec(rlist);
LOCK_DESTROY (&rlist->c_lock);
LOCK_DESTROY(&rlist->c_lock);
(void) pthread_mutex_destroy (&rlist->b_lock);
(void) pthread_cond_destroy (&rlist->b_cond);
(void)pthread_mutex_destroy(&rlist->b_lock);
(void)pthread_cond_destroy(&rlist->b_cond);
GF_FREE (rlist);
}
GF_FREE(rlist);
}
}
rbuf_t *
rbuf_init (int bufcount)
rbuf_init(int bufcount)
{
int j = 0;
int ret = 0;
rbuf_t *rbuf = NULL;
rbuf_list_t *rlist = NULL;
int j = 0;
int ret = 0;
rbuf_t *rbuf = NULL;
rbuf_list_t *rlist = NULL;
if (bufcount <= 0)
bufcount = ROT_BUFF_DEFAULT_COUNT;
if (bufcount <= 0)
bufcount = ROT_BUFF_DEFAULT_COUNT;
rbuf = GF_CALLOC (1, sizeof (rbuf_t), gf_common_mt_rbuf_t);
if (!rbuf)
goto error_return;
rbuf = GF_CALLOC(1, sizeof(rbuf_t), gf_common_mt_rbuf_t);
if (!rbuf)
goto error_return;
LOCK_INIT (&rbuf->lock);
INIT_LIST_HEAD (&rbuf->freelist);
LOCK_INIT(&rbuf->lock);
INIT_LIST_HEAD(&rbuf->freelist);
/* it could have been one big calloc() but this is just once.. */
for (j = 0; j < bufcount; j++) {
rlist = GF_CALLOC (1,
sizeof (rbuf_list_t), gf_common_mt_rlist_t);
if (!rlist) {
ret = -1;
break;
}
INIT_LIST_HEAD (&rlist->list);
INIT_LIST_HEAD (&rlist->veclist);
rlist->pending = rlist->completed = 0;
ret = rlist_add_new_vec (rlist);
if (ret)
break;
LOCK_INIT (&rlist->c_lock);
rlist->awaiting = _gf_false;
ret = pthread_mutex_init (&rlist->b_lock, 0);
if (ret != 0) {
GF_FREE (rlist);
break;
}
ret = pthread_cond_init (&rlist->b_cond, 0);
if (ret != 0) {
GF_FREE (rlist);
break;
}
list_add_tail (&rlist->list, &rbuf->freelist);
/* it could have been one big calloc() but this is just once.. */
for (j = 0; j < bufcount; j++) {
rlist = GF_CALLOC(1, sizeof(rbuf_list_t), gf_common_mt_rlist_t);
if (!rlist) {
ret = -1;
break;
}
if (ret != 0)
goto dealloc_rlist;
INIT_LIST_HEAD(&rlist->list);
INIT_LIST_HEAD(&rlist->veclist);
/* cache currently used buffer: first in the list */
rbuf->current = list_first_entry (&rbuf->freelist, rbuf_list_t, list);
return rbuf;
rlist->pending = rlist->completed = 0;
dealloc_rlist:
rbuf_purge_rlist (rbuf);
LOCK_DESTROY (&rbuf->lock);
GF_FREE (rbuf);
error_return:
return NULL;
ret = rlist_add_new_vec(rlist);
if (ret)
break;
LOCK_INIT(&rlist->c_lock);
rlist->awaiting = _gf_false;
ret = pthread_mutex_init(&rlist->b_lock, 0);
if (ret != 0) {
GF_FREE(rlist);
break;
}
ret = pthread_cond_init(&rlist->b_cond, 0);
if (ret != 0) {
GF_FREE(rlist);
break;
}
list_add_tail(&rlist->list, &rbuf->freelist);
}
if (ret != 0)
goto dealloc_rlist;
/* cache currently used buffer: first in the list */
rbuf->current = list_first_entry(&rbuf->freelist, rbuf_list_t, list);
return rbuf;
dealloc_rlist:
rbuf_purge_rlist(rbuf);
LOCK_DESTROY(&rbuf->lock);
GF_FREE(rbuf);
error_return:
return NULL;
}
void
rbuf_dtor (rbuf_t *rbuf)
rbuf_dtor(rbuf_t *rbuf)
{
if (!rbuf)
return;
rbuf->current = NULL;
rbuf_purge_rlist (rbuf);
LOCK_DESTROY (&rbuf->lock);
if (!rbuf)
return;
rbuf->current = NULL;
rbuf_purge_rlist(rbuf);
LOCK_DESTROY(&rbuf->lock);
GF_FREE (rbuf);
GF_FREE(rbuf);
}
static char *
rbuf_adjust_write_area (struct iovec *iov, size_t bytes)
rbuf_adjust_write_area(struct iovec *iov, size_t bytes)
{
char *wbuf = NULL;
char *wbuf = NULL;
wbuf = iov->iov_base + iov->iov_len;
iov->iov_len += bytes;
return wbuf;
wbuf = iov->iov_base + iov->iov_len;
iov->iov_len += bytes;
return wbuf;
}
static char *
rbuf_alloc_write_area (rbuf_list_t *rlist, size_t bytes)
rbuf_alloc_write_area(rbuf_list_t *rlist, size_t bytes)
{
int ret = 0;
struct iovec *iov = NULL;
int ret = 0;
struct iovec *iov = NULL;
/* check for available space in _current_ IO buffer */
iov = &rlist->rvec->iov;
if (iov->iov_len + bytes <= ROT_BUFF_ALLOC_SIZE)
return rbuf_adjust_write_area (iov, bytes); /* fast path */
/* check for available space in _current_ IO buffer */
iov = &rlist->rvec->iov;
if (iov->iov_len + bytes <= ROT_BUFF_ALLOC_SIZE)
return rbuf_adjust_write_area(iov, bytes); /* fast path */
/* not enough bytes, try next available buffers */
if (list_is_last (&rlist->rvec->list, &rlist->veclist)) {
/* OH! consumed all vector buffers */
GF_ASSERT (rlist->used == rlist->total);
ret = rlist_add_new_vec (rlist);
if (ret)
goto error_return;
} else {
/* not the end, have available rbuf_iovec's */
rlist->rvec = list_next_entry (rlist->rvec, list);
rlist->used++;
rbuf_reset_rvec (rlist->rvec);
}
/* not enough bytes, try next available buffers */
if (list_is_last(&rlist->rvec->list, &rlist->veclist)) {
/* OH! consumed all vector buffers */
GF_ASSERT(rlist->used == rlist->total);
ret = rlist_add_new_vec(rlist);
if (ret)
goto error_return;
} else {
/* not the end, have available rbuf_iovec's */
rlist->rvec = list_next_entry(rlist->rvec, list);
rlist->used++;
rbuf_reset_rvec(rlist->rvec);
}
iov = &rlist->rvec->iov;
return rbuf_adjust_write_area (iov, bytes);
iov = &rlist->rvec->iov;
return rbuf_adjust_write_area(iov, bytes);
error_return:
return NULL;
error_return:
return NULL;
}
char *
rbuf_reserve_write_area (rbuf_t *rbuf, size_t bytes, void **opaque)
rbuf_reserve_write_area(rbuf_t *rbuf, size_t bytes, void **opaque)
{
char *wbuf = NULL;
rbuf_list_t *rlist = NULL;
char *wbuf = NULL;
rbuf_list_t *rlist = NULL;
if (!rbuf || (bytes <= 0) || (bytes > ROT_BUFF_ALLOC_SIZE) || !opaque)
return NULL;
if (!rbuf || (bytes <= 0) || (bytes > ROT_BUFF_ALLOC_SIZE) || !opaque)
return NULL;
LOCK (&rbuf->lock);
{
rlist = rbuf_current_buffer (rbuf);
wbuf = rbuf_alloc_write_area (rlist, bytes);
if (!wbuf)
goto unblock;
rlist->pending++;
}
unblock:
UNLOCK (&rbuf->lock);
LOCK(&rbuf->lock);
{
rlist = rbuf_current_buffer(rbuf);
wbuf = rbuf_alloc_write_area(rlist, bytes);
if (!wbuf)
goto unblock;
rlist->pending++;
}
unblock:
UNLOCK(&rbuf->lock);
if (wbuf)
*opaque = rlist;
return wbuf;
if (wbuf)
*opaque = rlist;
return wbuf;
}
static void
rbuf_notify_waiter (rbuf_list_t *rlist)
rbuf_notify_waiter(rbuf_list_t *rlist)
{
pthread_mutex_lock (&rlist->b_lock);
{
pthread_cond_signal (&rlist->b_cond);
}
pthread_mutex_unlock (&rlist->b_lock);
pthread_mutex_lock(&rlist->b_lock);
{
pthread_cond_signal(&rlist->b_cond);
}
pthread_mutex_unlock(&rlist->b_lock);
}
int
rbuf_write_complete (void *opaque)
rbuf_write_complete(void *opaque)
{
rbuf_list_t *rlist = NULL;
gf_boolean_t notify = _gf_false;
rbuf_list_t *rlist = NULL;
gf_boolean_t notify = _gf_false;
if (!opaque)
return -1;
if (!opaque)
return -1;
rlist = opaque;
rlist = opaque;
LOCK (&rlist->c_lock);
{
rlist->completed++;
/**
* it's safe to test ->pending without rbuf->lock *only* if
* there's a waiter as there can be no new incoming writes.
*/
if (__rlist_has_waiter (rlist)
&& (rlist->completed == rlist->pending))
notify = _gf_true;
}
UNLOCK (&rlist->c_lock);
LOCK(&rlist->c_lock);
{
rlist->completed++;
/**
* it's safe to test ->pending without rbuf->lock *only* if
* there's a waiter as there can be no new incoming writes.
*/
if (__rlist_has_waiter(rlist) && (rlist->completed == rlist->pending))
notify = _gf_true;
}
UNLOCK(&rlist->c_lock);
if (notify)
rbuf_notify_waiter (rlist);
if (notify)
rbuf_notify_waiter(rlist);
return 0;
return 0;
}
int
rbuf_get_buffer (rbuf_t *rbuf,
void **opaque, sequence_fn *seqfn, void *mydata)
rbuf_get_buffer(rbuf_t *rbuf, void **opaque, sequence_fn *seqfn, void *mydata)
{
int retval = RBUF_CONSUMABLE;
rbuf_list_t *rlist = NULL;
int retval = RBUF_CONSUMABLE;
rbuf_list_t *rlist = NULL;
if (!rbuf || !opaque)
return -1;
if (!rbuf || !opaque)
return -1;
LOCK (&rbuf->lock);
{
rlist = rbuf_current_buffer (rbuf);
if (!rlist->pending) {
retval = RBUF_EMPTY;
goto unblock;
}
if (list_is_singular (&rbuf->freelist)) {
/**
* removal would lead to writer starvation, disallow
* switching.
*/
retval = RBUF_WOULD_STARVE;
goto unblock;
}
list_del_init (&rlist->list);
if (seqfn)
seqfn (rlist, mydata);
rbuf->current =
list_first_entry (&rbuf->freelist, rbuf_list_t, list);
LOCK(&rbuf->lock);
{
rlist = rbuf_current_buffer(rbuf);
if (!rlist->pending) {
retval = RBUF_EMPTY;
goto unblock;
}
unblock:
UNLOCK (&rbuf->lock);
if (retval == RBUF_CONSUMABLE)
*opaque = rlist; /* caller _owns_ the buffer */
if (list_is_singular(&rbuf->freelist)) {
/**
* removal would lead to writer starvation, disallow
* switching.
*/
retval = RBUF_WOULD_STARVE;
goto unblock;
}
return retval;
list_del_init(&rlist->list);
if (seqfn)
seqfn(rlist, mydata);
rbuf->current = list_first_entry(&rbuf->freelist, rbuf_list_t, list);
}
unblock:
UNLOCK(&rbuf->lock);
if (retval == RBUF_CONSUMABLE)
*opaque = rlist; /* caller _owns_ the buffer */
return retval;
}
/**
@ -412,10 +408,10 @@ rbuf_get_buffer (rbuf_t *rbuf,
*/
static void
__rbuf_wait_for_writers (rbuf_list_t *rlist)
__rbuf_wait_for_writers(rbuf_list_t *rlist)
{
while (rlist->completed != rlist->pending)
pthread_cond_wait (&rlist->b_cond, &rlist->b_lock);
while (rlist->completed != rlist->pending)
pthread_cond_wait(&rlist->b_cond, &rlist->b_lock);
}
#ifndef M_E
@ -423,69 +419,69 @@ __rbuf_wait_for_writers (rbuf_list_t *rlist)
#endif
static void
rlist_shrink_vector (rbuf_list_t *rlist)
rlist_shrink_vector(rbuf_list_t *rlist)
{
unsigned long long shrink = 0;
unsigned long long shrink = 0;
/**
* fast path: don't bother to deallocate if vectors are hardly
* used.
*/
if (rvec_in_watermark_range (rlist))
return;
/**
* fast path: don't bother to deallocate if vectors are hardly
* used.
*/
if (rvec_in_watermark_range(rlist))
return;
/**
* Calculate the shrink count based on total allocated vectors.
* Note that the calculation sticks to rlist->total irrespective
* of the actual usage count (rlist->used). Later, ->used could
* be used to apply slack to the calculation based on how much
* it lags from ->total. For now, let's stick to slow decay.
*/
shrink = rlist->total - (rlist->total * pow (M_E, -0.2));
/**
* Calculate the shrink count based on total allocated vectors.
* Note that the calculation sticks to rlist->total irrespective
* of the actual usage count (rlist->used). Later, ->used could
* be used to apply slack to the calculation based on how much
* it lags from ->total. For now, let's stick to slow decay.
*/
shrink = rlist->total - (rlist->total * pow(M_E, -0.2));
rlist_shrink_rvec (rlist, shrink);
rlist->total -= shrink;
rlist_shrink_rvec(rlist, shrink);
rlist->total -= shrink;
}
int
rbuf_wait_for_completion (rbuf_t *rbuf, void *opaque,
void (*fn)(rbuf_list_t *, void *), void *arg)
rbuf_wait_for_completion(rbuf_t *rbuf, void *opaque,
void (*fn)(rbuf_list_t *, void *), void *arg)
{
rbuf_list_t *rlist = NULL;
rbuf_list_t *rlist = NULL;
if (!rbuf || !opaque)
return -1;
if (!rbuf || !opaque)
return -1;
rlist = opaque;
rlist = opaque;
pthread_mutex_lock (&rlist->b_lock);
{
rlist_mark_waiting (rlist);
__rbuf_wait_for_writers (rlist);
}
pthread_mutex_unlock (&rlist->b_lock);
pthread_mutex_lock(&rlist->b_lock);
{
rlist_mark_waiting(rlist);
__rbuf_wait_for_writers(rlist);
}
pthread_mutex_unlock(&rlist->b_lock);
/**
* from here on, no need of locking until the rlist is put
* back into rotation.
*/
/**
* from here on, no need of locking until the rlist is put
* back into rotation.
*/
fn (rlist, arg); /* invoke dispatcher */
fn(rlist, arg); /* invoke dispatcher */
rlist->awaiting = _gf_false;
rlist->pending = rlist->completed = 0;
rlist->awaiting = _gf_false;
rlist->pending = rlist->completed = 0;
rlist_shrink_vector (rlist);
rlist_reset_vector_usage (rlist);
rlist_shrink_vector(rlist);
rlist_reset_vector_usage(rlist);
rlist->rvec = list_first_entry (&rlist->veclist, rbuf_iovec_t, list);
rbuf_reset_rvec (rlist->rvec);
rlist->rvec = list_first_entry(&rlist->veclist, rbuf_iovec_t, list);
rbuf_reset_rvec(rlist->rvec);
LOCK (&rbuf->lock);
{
list_add_tail (&rlist->list, &rbuf->freelist);
}
UNLOCK (&rbuf->lock);
LOCK(&rbuf->lock);
{
list_add_tail(&rlist->list, &rbuf->freelist);
}
UNLOCK(&rbuf->lock);
return 0;
return 0;
}

View File

@ -42,8 +42,9 @@
*
* $ cc -DRUN_DO_DEMO -DRUN_STANDALONE -orun run.c
*/
#if defined(RUN_STANDALONE ) || defined(RUN_DO_DEMO)
int close_fds_except (int *fdv, size_t count);
#if defined(RUN_STANDALONE) || defined(RUN_DO_DEMO)
int
close_fds_except(int *fdv, size_t count);
#define sys_read(f, b, c) read(f, b, c)
#define sys_write(f, b, c) write(f, b, c)
#define sys_close(f) close(f)
@ -54,36 +55,37 @@ int close_fds_except (int *fdv, size_t count);
#define gf_strdup(s) strdup(s)
#define gf_vasprintf(p, f, va) vasprintf(p, f, va)
#define gf_loglevel_t int
#define gf_msg_callingfn(dom, level, errnum, msgid, fmt, args...) printf("LOG: " fmt "\n", ##args)
#define gf_msg_callingfn(dom, level, errnum, msgid, fmt, args...) \
printf("LOG: " fmt "\n", ##args)
#define LOG_DEBUG 0
#ifdef RUN_STANDALONE
#include <stdbool.h>
#include <sys/resource.h>
int
close_fds_except (int *fdv, size_t count)
close_fds_except(int *fdv, size_t count)
{
int i = 0;
size_t j = 0;
bool should_close = true;
struct rlimit rl;
int ret = -1;
int i = 0;
size_t j = 0;
bool should_close = true;
struct rlimit rl;
int ret = -1;
ret = getrlimit (RLIMIT_NOFILE, &rl);
if (ret)
return ret;
ret = getrlimit(RLIMIT_NOFILE, &rl);
if (ret)
return ret;
for (i = 0; i < rl.rlim_cur; i++) {
should_close = true;
for (j = 0; j < count; j++) {
if (i == fdv[j]) {
should_close = false;
break;
}
}
if (should_close)
sys_close (i);
for (i = 0; i < rl.rlim_cur; i++) {
should_close = true;
for (j = 0; j < count; j++) {
if (i == fdv[j]) {
should_close = false;
break;
}
}
return 0;
if (should_close)
sys_close(i);
}
return 0;
}
#endif
#ifdef __linux__
@ -97,470 +99,472 @@ close_fds_except (int *fdv, size_t count)
#include "run.h"
void
runinit (runner_t *runner)
runinit(runner_t *runner)
{
int i = 0;
int i = 0;
runner->argvlen = 64;
runner->argv = GF_CALLOC (runner->argvlen,
sizeof (*runner->argv),
gf_common_mt_run_argv);
runner->runerr = runner->argv ? 0 : errno;
runner->chpid = -1;
for (i = 0; i < 3; i++) {
runner->chfd[i] = -1;
runner->chio[i] = NULL;
}
runner->argvlen = 64;
runner->argv = GF_CALLOC(runner->argvlen, sizeof(*runner->argv),
gf_common_mt_run_argv);
runner->runerr = runner->argv ? 0 : errno;
runner->chpid = -1;
for (i = 0; i < 3; i++) {
runner->chfd[i] = -1;
runner->chio[i] = NULL;
}
}
FILE *
runner_chio (runner_t *runner, int fd)
runner_chio(runner_t *runner, int fd)
{
GF_ASSERT (fd > 0 && fd < 3);
GF_ASSERT(fd > 0 && fd < 3);
if ((fd > 0) && (fd < 3))
return runner->chio[fd];
if ((fd > 0) && (fd < 3))
return runner->chio[fd];
return NULL;
return NULL;
}
static void
runner_insert_arg (runner_t *runner, char *arg)
runner_insert_arg(runner_t *runner, char *arg)
{
int i = 0;
int i = 0;
GF_ASSERT (arg);
GF_ASSERT(arg);
if (runner->runerr)
return;
if (runner->runerr)
return;
for (i = 0; i < runner->argvlen; i++) {
if (runner->argv[i] == NULL)
break;
for (i = 0; i < runner->argvlen; i++) {
if (runner->argv[i] == NULL)
break;
}
GF_ASSERT(i < runner->argvlen);
if (i == runner->argvlen - 1) {
runner->argv = GF_REALLOC(runner->argv,
runner->argvlen * 2 * sizeof(*runner->argv));
if (!runner->argv) {
runner->runerr = errno;
return;
}
GF_ASSERT (i < runner->argvlen);
memset(/* "+" is aware of the type of its left side,
* no need to multiply with type-size */
runner->argv + runner->argvlen, 0,
runner->argvlen * sizeof(*runner->argv));
runner->argvlen *= 2;
}
if (i == runner->argvlen - 1) {
runner->argv = GF_REALLOC (runner->argv,
runner->argvlen * 2 * sizeof (*runner->argv));
if (!runner->argv) {
runner->runerr = errno;
return;
}
memset (/* "+" is aware of the type of its left side,
* no need to multiply with type-size */
runner->argv + runner->argvlen,
0, runner->argvlen * sizeof (*runner->argv));
runner->argvlen *= 2;
}
runner->argv[i] = arg;
runner->argv[i] = arg;
}
void
runner_add_arg (runner_t *runner, const char *arg)
runner_add_arg(runner_t *runner, const char *arg)
{
arg = gf_strdup (arg);
if (!arg) {
runner->runerr = errno;
return;
}
arg = gf_strdup(arg);
if (!arg) {
runner->runerr = errno;
return;
}
runner_insert_arg (runner, (char *)arg);
runner_insert_arg(runner, (char *)arg);
}
static void
runner_va_add_args (runner_t *runner, va_list argp)
runner_va_add_args(runner_t *runner, va_list argp)
{
const char *arg;
const char *arg;
while ((arg = va_arg (argp, const char *)))
runner_add_arg (runner, arg);
while ((arg = va_arg(argp, const char *)))
runner_add_arg(runner, arg);
}
void
runner_add_args (runner_t *runner, ...)
runner_add_args(runner_t *runner, ...)
{
va_list argp;
va_list argp;
va_start (argp, runner);
runner_va_add_args (runner, argp);
va_end (argp);
va_start(argp, runner);
runner_va_add_args(runner, argp);
va_end(argp);
}
void
runner_argprintf (runner_t *runner, const char *format, ...)
runner_argprintf(runner_t *runner, const char *format, ...)
{
va_list argva;
char *arg = NULL;
int ret = 0;
va_list argva;
char *arg = NULL;
int ret = 0;
va_start (argva, format);
ret = gf_vasprintf (&arg, format, argva);
va_end (argva);
va_start(argva, format);
ret = gf_vasprintf(&arg, format, argva);
va_end(argva);
if (ret < 0) {
runner->runerr = errno;
return;
}
if (ret < 0) {
runner->runerr = errno;
return;
}
runner_insert_arg (runner, arg);
runner_insert_arg(runner, arg);
}
void
runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
const char *msg)
runner_log(runner_t *runner, const char *dom, gf_loglevel_t lvl,
const char *msg)
{
char *buf = NULL;
size_t len = 0;
int i = 0;
char *buf = NULL;
size_t len = 0;
int i = 0;
if (runner->runerr)
return;
if (runner->runerr)
return;
for (i = 0;; i++) {
if (runner->argv[i] == NULL)
break;
len += (strlen (runner->argv[i]) + 1);
}
for (i = 0;; i++) {
if (runner->argv[i] == NULL)
break;
len += (strlen(runner->argv[i]) + 1);
}
buf = GF_CALLOC (1, len + 1, gf_common_mt_run_logbuf);
if (!buf) {
runner->runerr = errno;
return;
}
for (i = 0;; i++) {
if (runner->argv[i] == NULL)
break;
strcat (buf, runner->argv[i]);
strcat (buf, " ");
}
if (len > 0)
buf[len - 1] = '\0';
buf = GF_CALLOC(1, len + 1, gf_common_mt_run_logbuf);
if (!buf) {
runner->runerr = errno;
return;
}
for (i = 0;; i++) {
if (runner->argv[i] == NULL)
break;
strcat(buf, runner->argv[i]);
strcat(buf, " ");
}
if (len > 0)
buf[len - 1] = '\0';
gf_msg_callingfn (dom, lvl, 0, LG_MSG_RUNNER_LOG, "%s: %s", msg, buf);
gf_msg_callingfn(dom, lvl, 0, LG_MSG_RUNNER_LOG, "%s: %s", msg, buf);
GF_FREE (buf);
GF_FREE(buf);
}
void
runner_redir (runner_t *runner, int fd, int tgt_fd)
runner_redir(runner_t *runner, int fd, int tgt_fd)
{
GF_ASSERT (fd > 0 && fd < 3);
GF_ASSERT(fd > 0 && fd < 3);
if ((fd > 0) && (fd < 3))
runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
if ((fd > 0) && (fd < 3))
runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
}
int
runner_start (runner_t *runner)
runner_start(runner_t *runner)
{
int pi[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}};
int xpi[2];
int ret = 0;
int errno_priv = 0;
int i = 0;
sigset_t set;
int pi[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}};
int xpi[2];
int ret = 0;
int errno_priv = 0;
int i = 0;
sigset_t set;
if (runner->runerr) {
errno = runner->runerr;
return -1;
}
GF_ASSERT (runner->argv[0]);
/* set up a channel to child to communicate back
* possible execve(2) failures
*/
ret = pipe(xpi);
if (ret != -1)
ret = fcntl (xpi[1], F_SETFD, FD_CLOEXEC);
for (i = 0; i < 3; i++) {
if (runner->chfd[i] != -2)
continue;
ret = pipe (pi[i]);
if (ret != -1) {
runner->chio[i] = fdopen (pi[i][i ? 0 : 1], i ? "r" : "w");
if (!runner->chio[i])
ret = -1;
}
}
if (ret != -1)
runner->chpid = fork ();
switch (runner->chpid) {
case -1:
errno_priv = errno;
sys_close (xpi[0]);
sys_close (xpi[1]);
for (i = 0; i < 3; i++) {
sys_close (pi[i][0]);
sys_close (pi[i][1]);
}
errno = errno_priv;
return -1;
case 0:
for (i = 0; i < 3; i++)
sys_close (pi[i][i ? 0 : 1]);
sys_close (xpi[0]);
ret = 0;
for (i = 0; i < 3; i++) {
if (ret == -1)
break;
switch (runner->chfd[i]) {
case -1:
/* no redir */
break;
case -2:
/* redir to pipe */
ret = dup2 (pi[i][i ? 1 : 0], i);
break;
default:
/* redir to file */
ret = dup2 (runner->chfd[i], i);
}
}
if (ret != -1 ) {
int fdv[4] = {0, 1, 2, xpi[1]};
ret = close_fds_except(fdv, sizeof (fdv) / sizeof (*fdv));
}
if (ret != -1) {
/* save child from inheriting our signal handling */
sigemptyset (&set);
sigprocmask (SIG_SETMASK, &set, NULL);
execvp (runner->argv[0], runner->argv);
}
ret = sys_write (xpi[1], &errno, sizeof (errno));
_exit (1);
}
errno_priv = errno;
for (i = 0; i < 3; i++)
sys_close (pi[i][i ? 1 : 0]);
sys_close (xpi[1]);
if (ret == -1) {
for (i = 0; i < 3; i++) {
if (runner->chio[i]) {
fclose (runner->chio[i]);
runner->chio[i] = NULL;
}
}
} else {
ret = sys_read (xpi[0], (char *)&errno_priv, sizeof (errno_priv));
sys_close (xpi[0]);
if (ret <= 0)
return 0;
GF_ASSERT (ret == sizeof (errno_priv));
}
errno = errno_priv;
if (runner->runerr) {
errno = runner->runerr;
return -1;
}
}
int
runner_end_reuse (runner_t *runner)
{
int i = 0;
int ret = 1;
int chstat = 0;
GF_ASSERT(runner->argv[0]);
if (runner->chpid > 0) {
if (waitpid (runner->chpid, &chstat, 0) == runner->chpid) {
if (WIFEXITED(chstat)) {
ret = WEXITSTATUS(chstat);
} else {
ret = chstat;
}
}
/* set up a channel to child to communicate back
* possible execve(2) failures
*/
ret = pipe(xpi);
if (ret != -1)
ret = fcntl(xpi[1], F_SETFD, FD_CLOEXEC);
for (i = 0; i < 3; i++) {
if (runner->chfd[i] != -2)
continue;
ret = pipe(pi[i]);
if (ret != -1) {
runner->chio[i] = fdopen(pi[i][i ? 0 : 1], i ? "r" : "w");
if (!runner->chio[i])
ret = -1;
}
}
if (ret != -1)
runner->chpid = fork();
switch (runner->chpid) {
case -1:
errno_priv = errno;
sys_close(xpi[0]);
sys_close(xpi[1]);
for (i = 0; i < 3; i++) {
sys_close(pi[i][0]);
sys_close(pi[i][1]);
}
errno = errno_priv;
return -1;
case 0:
for (i = 0; i < 3; i++)
sys_close(pi[i][i ? 0 : 1]);
sys_close(xpi[0]);
ret = 0;
for (i = 0; i < 3; i++) {
if (ret == -1)
break;
switch (runner->chfd[i]) {
case -1:
/* no redir */
break;
case -2:
/* redir to pipe */
ret = dup2(pi[i][i ? 1 : 0], i);
break;
default:
/* redir to file */
ret = dup2(runner->chfd[i], i);
}
}
if (ret != -1) {
int fdv[4] = {0, 1, 2, xpi[1]};
ret = close_fds_except(fdv, sizeof(fdv) / sizeof(*fdv));
}
if (ret != -1) {
/* save child from inheriting our signal handling */
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
execvp(runner->argv[0], runner->argv);
}
ret = sys_write(xpi[1], &errno, sizeof(errno));
_exit(1);
}
errno_priv = errno;
for (i = 0; i < 3; i++)
sys_close(pi[i][i ? 1 : 0]);
sys_close(xpi[1]);
if (ret == -1) {
for (i = 0; i < 3; i++) {
if (runner->chio[i]) {
fclose (runner->chio[i]);
runner->chio[i] = NULL;
}
if (runner->chio[i]) {
fclose(runner->chio[i]);
runner->chio[i] = NULL;
}
}
return -ret;
} else {
ret = sys_read(xpi[0], (char *)&errno_priv, sizeof(errno_priv));
sys_close(xpi[0]);
if (ret <= 0)
return 0;
GF_ASSERT(ret == sizeof(errno_priv));
}
errno = errno_priv;
return -1;
}
int
runner_end (runner_t *runner)
runner_end_reuse(runner_t *runner)
{
int i = 0;
int ret = -1;
char **p = NULL;
int i = 0;
int ret = 1;
int chstat = 0;
ret = runner_end_reuse (runner);
if (runner->argv) {
for (p = runner->argv; *p; p++)
GF_FREE (*p);
GF_FREE (runner->argv);
if (runner->chpid > 0) {
if (waitpid(runner->chpid, &chstat, 0) == runner->chpid) {
if (WIFEXITED(chstat)) {
ret = WEXITSTATUS(chstat);
} else {
ret = chstat;
}
}
for (i = 0; i < 3; i++)
sys_close (runner->chfd[i]);
}
return ret;
for (i = 0; i < 3; i++) {
if (runner->chio[i]) {
fclose(runner->chio[i]);
runner->chio[i] = NULL;
}
}
return -ret;
}
int
runner_end(runner_t *runner)
{
int i = 0;
int ret = -1;
char **p = NULL;
ret = runner_end_reuse(runner);
if (runner->argv) {
for (p = runner->argv; *p; p++)
GF_FREE(*p);
GF_FREE(runner->argv);
}
for (i = 0; i < 3; i++)
sys_close(runner->chfd[i]);
return ret;
}
static int
runner_run_generic (runner_t *runner, int (*rfin)(runner_t *runner))
runner_run_generic(runner_t *runner, int (*rfin)(runner_t *runner))
{
int ret = 0;
int ret = 0;
ret = runner_start (runner);
if (ret)
goto out;
ret = rfin (runner);
ret = runner_start(runner);
if (ret)
goto out;
ret = rfin(runner);
out:
return ret;
return ret;
}
int
runner_run (runner_t *runner)
runner_run(runner_t *runner)
{
return runner_run_generic (runner, runner_end);
}
int
runner_run_nowait (runner_t *runner)
{
int pid;
pid = fork ();
if (!pid) {
setsid ();
_exit (runner_start (runner));
}
if (pid > 0)
runner->chpid = pid;
return runner_end (runner);
}
int
runner_run_reuse (runner_t *runner)
{
return runner_run_generic (runner, runner_end_reuse);
return runner_run_generic(runner, runner_end);
}
int
runcmd (const char *arg, ...)
runner_run_nowait(runner_t *runner)
{
runner_t runner;
va_list argp;
int pid;
runinit (&runner);
/* ISO C requires a named argument before '...' */
runner_add_arg (&runner, arg);
pid = fork();
va_start (argp, arg);
runner_va_add_args (&runner, argp);
va_end (argp);
if (!pid) {
setsid();
_exit(runner_start(runner));
}
return runner_run (&runner);
if (pid > 0)
runner->chpid = pid;
return runner_end(runner);
}
int
runner_run_reuse(runner_t *runner)
{
return runner_run_generic(runner, runner_end_reuse);
}
int
runcmd(const char *arg, ...)
{
runner_t runner;
va_list argp;
runinit(&runner);
/* ISO C requires a named argument before '...' */
runner_add_arg(&runner, arg);
va_start(argp, arg);
runner_va_add_args(&runner, argp);
va_end(argp);
return runner_run(&runner);
}
#ifdef RUN_DO_DEMO
static void
TBANNER (const char *txt)
TBANNER(const char *txt)
{
printf("######\n### demoing %s\n", txt);
printf("######\n### demoing %s\n", txt);
}
int
main (int argc, char **argv)
main(int argc, char **argv)
{
runner_t runner;
char buf[80];
char *wdbuf;;
int ret;
int fd;
long pathmax = pathconf ("/", _PC_PATH_MAX);
struct timeval tv = {0,};
struct timeval *tvp = NULL;
char *tfile;
runner_t runner;
char buf[80];
char *wdbuf;
;
int ret;
int fd;
long pathmax = pathconf("/", _PC_PATH_MAX);
struct timeval tv = {
0,
};
struct timeval *tvp = NULL;
char *tfile;
wdbuf = malloc (pathmax);
assert (wdbuf);
getcwd (wdbuf, pathmax);
wdbuf = malloc(pathmax);
assert(wdbuf);
getcwd(wdbuf, pathmax);
TBANNER ("basic functionality: running \"echo a b\"");
runcmd ("echo", "a", "b", NULL);
TBANNER("basic functionality: running \"echo a b\"");
runcmd("echo", "a", "b", NULL);
TBANNER ("argv extension: running \"echo 1 2 ... 100\"");
runcmd ("echo", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
"21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
"31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
"41", "42", "43", "44", "45", "46", "47", "48", "49", "50",
"51", "52", "53", "54", "55", "56", "57", "58", "59", "60",
"61", "62", "63", "64", "65", "66", "67", "68", "69", "70",
"71", "72", "73", "74", "75", "76", "77", "78", "79", "80",
"81", "82", "83", "84", "85", "86", "87", "88", "89", "90",
"91", "92", "93", "94", "95", "96", "97", "98", "99", "100", NULL);
TBANNER("argv extension: running \"echo 1 2 ... 100\"");
runcmd("echo", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
"12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22",
"23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33",
"34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44",
"45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55",
"56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66",
"67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77",
"78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88",
"89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
"100", NULL);
TBANNER ("add_args, argprintf, log, and popen-style functionality:\n"
" running a multiline echo command, emit a log about it,\n"
" redirect it to a pipe, read output lines\n"
" and print them prefixed with \"got: \"");
runinit (&runner);
runner_add_args (&runner, "echo", "pid:", NULL);
runner_argprintf (&runner, "%d\n", getpid());
runner_add_arg (&runner, "wd:");
runner_add_arg (&runner, wdbuf);
runner_redir (&runner, 1, RUN_PIPE);
runner_start (&runner);
runner_log (&runner, "(x)", LOG_DEBUG, "starting program");
while (fgets (buf, sizeof(buf), runner_chio (&runner, 1)))
printf ("got: %s", buf);
runner_end (&runner);
TBANNER(
"add_args, argprintf, log, and popen-style functionality:\n"
" running a multiline echo command, emit a log about it,\n"
" redirect it to a pipe, read output lines\n"
" and print them prefixed with \"got: \"");
runinit(&runner);
runner_add_args(&runner, "echo", "pid:", NULL);
runner_argprintf(&runner, "%d\n", getpid());
runner_add_arg(&runner, "wd:");
runner_add_arg(&runner, wdbuf);
runner_redir(&runner, 1, RUN_PIPE);
runner_start(&runner);
runner_log(&runner, "(x)", LOG_DEBUG, "starting program");
while (fgets(buf, sizeof(buf), runner_chio(&runner, 1)))
printf("got: %s", buf);
runner_end(&runner);
TBANNER ("execve error reporting: running a non-existent command");
ret = runcmd ("bafflavvitty", NULL);
printf ("%d %d [%s]\n", ret, errno, strerror (errno));
TBANNER("execve error reporting: running a non-existent command");
ret = runcmd("bafflavvitty", NULL);
printf("%d %d [%s]\n", ret, errno, strerror(errno));
TBANNER ("output redirection: running \"echo foo\" redirected "
"to a temp file");
tfile = strdup ("/tmp/foofXXXXXX");
assert (tfile);
fd = mkstemp (tfile);
assert (fd != -1);
printf ("redirecting to %s\n", tfile);
runinit (&runner);
runner_add_args (&runner, "echo", "foo", NULL);
runner_redir (&runner, 1, fd);
ret = runner_run (&runner);
printf ("runner_run returned: %d", ret);
if (ret != 0)
printf (", with errno %d [%s]", errno, strerror (errno));
putchar ('\n');
TBANNER(
"output redirection: running \"echo foo\" redirected "
"to a temp file");
tfile = strdup("/tmp/foofXXXXXX");
assert(tfile);
fd = mkstemp(tfile);
assert(fd != -1);
printf("redirecting to %s\n", tfile);
runinit(&runner);
runner_add_args(&runner, "echo", "foo", NULL);
runner_redir(&runner, 1, fd);
ret = runner_run(&runner);
printf("runner_run returned: %d", ret);
if (ret != 0)
printf(", with errno %d [%s]", errno, strerror(errno));
putchar('\n');
/* sleep for seconds given as argument (0 means forever)
* to allow investigation of post-execution state to
* cbeck for resource leaks (eg. zombies).
*/
if (argc > 1) {
tv.tv_sec = strtoul (argv[1], NULL, 10);
printf ("### %s", "sleeping for");
if (tv.tv_sec > 0) {
printf (" %d seconds\n", tv.tv_sec);
tvp = &tv;
} else
printf ("%s\n", "ever");
select (0, 0, 0, 0, tvp);
}
/* sleep for seconds given as argument (0 means forever)
* to allow investigation of post-execution state to
* cbeck for resource leaks (eg. zombies).
*/
if (argc > 1) {
tv.tv_sec = strtoul(argv[1], NULL, 10);
printf("### %s", "sleeping for");
if (tv.tv_sec > 0) {
printf(" %d seconds\n", tv.tv_sec);
tvp = &tv;
} else
printf("%s\n", "ever");
select(0, 0, 0, 0, tvp);
}
return 0;
return 0;
}
#endif

View File

@ -13,433 +13,433 @@
#include "libglusterfs-messages.h"
call_frame_t *
create_frame (xlator_t *xl, call_pool_t *pool)
create_frame(xlator_t *xl, call_pool_t *pool)
{
call_stack_t *stack = NULL;
call_frame_t *frame = NULL;
call_stack_t *stack = NULL;
call_frame_t *frame = NULL;
if (!xl || !pool) {
return NULL;
}
if (!xl || !pool) {
return NULL;
}
stack = mem_get0 (pool->stack_mem_pool);
if (!stack)
return NULL;
stack = mem_get0(pool->stack_mem_pool);
if (!stack)
return NULL;
INIT_LIST_HEAD (&stack->myframes);
INIT_LIST_HEAD(&stack->myframes);
frame = mem_get0 (pool->frame_mem_pool);
if (!frame) {
mem_put (stack);
return NULL;
}
frame = mem_get0(pool->frame_mem_pool);
if (!frame) {
mem_put(stack);
return NULL;
}
frame->root = stack;
frame->this = xl;
LOCK_INIT (&frame->lock);
INIT_LIST_HEAD (&frame->frames);
list_add (&frame->frames, &stack->myframes);
frame->root = stack;
frame->this = xl;
LOCK_INIT(&frame->lock);
INIT_LIST_HEAD(&frame->frames);
list_add(&frame->frames, &stack->myframes);
stack->pool = pool;
stack->ctx = xl->ctx;
stack->pool = pool;
stack->ctx = xl->ctx;
if (frame->root->ctx->measure_latency) {
timespec_now (&stack->tv);
memcpy (&frame->begin, &stack->tv,
sizeof (stack->tv));
}
if (frame->root->ctx->measure_latency) {
timespec_now(&stack->tv);
memcpy(&frame->begin, &stack->tv, sizeof(stack->tv));
}
LOCK (&pool->lock);
{
list_add (&stack->all_frames, &pool->all_frames);
pool->cnt++;
}
UNLOCK (&pool->lock);
GF_ATOMIC_INC (pool->total_count);
LOCK(&pool->lock);
{
list_add(&stack->all_frames, &pool->all_frames);
pool->cnt++;
}
UNLOCK(&pool->lock);
GF_ATOMIC_INC(pool->total_count);
LOCK_INIT (&stack->stack_lock);
LOCK_INIT(&stack->stack_lock);
return frame;
return frame;
}
void
call_stack_set_groups (call_stack_t *stack, int ngrps, gid_t **groupbuf_p)
call_stack_set_groups(call_stack_t *stack, int ngrps, gid_t **groupbuf_p)
{
/* We take the ownership of the passed group buffer. */
/* We take the ownership of the passed group buffer. */
if (ngrps <= SMALL_GROUP_COUNT) {
memcpy (stack->groups_small, *groupbuf_p,
sizeof (gid_t) * ngrps);
stack->groups = stack->groups_small;
GF_FREE (*groupbuf_p);
} else {
stack->groups_large = *groupbuf_p;
stack->groups = stack->groups_large;
}
if (ngrps <= SMALL_GROUP_COUNT) {
memcpy(stack->groups_small, *groupbuf_p, sizeof(gid_t) * ngrps);
stack->groups = stack->groups_small;
GF_FREE(*groupbuf_p);
} else {
stack->groups_large = *groupbuf_p;
stack->groups = stack->groups_large;
}
stack->ngrps = ngrps;
/* Set a canary. */
*groupbuf_p = (void *)0xdeadf00d;
stack->ngrps = ngrps;
/* Set a canary. */
*groupbuf_p = (void *)0xdeadf00d;
}
void
gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
gf_proc_dump_call_frame(call_frame_t *call_frame, const char *key_buf, ...)
{
char prefix[GF_DUMP_MAX_BUF_LEN];
va_list ap;
call_frame_t my_frame;
int ret = -1;
char timestr[256] = {
0,
};
int len;
char prefix[GF_DUMP_MAX_BUF_LEN];
va_list ap;
call_frame_t my_frame;
int ret = -1;
char timestr[256] = {0,};
int len;
if (!call_frame)
return;
if (!call_frame)
return;
GF_ASSERT(key_buf);
GF_ASSERT (key_buf);
va_start(ap, key_buf);
vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
va_end(ap);
va_start(ap, key_buf);
vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
va_end(ap);
ret = TRY_LOCK(&call_frame->lock);
if (ret)
goto out;
ret = TRY_LOCK(&call_frame->lock);
if (ret)
goto out;
memcpy(&my_frame, call_frame, sizeof(my_frame));
UNLOCK(&call_frame->lock);
memcpy(&my_frame, call_frame, sizeof(my_frame));
UNLOCK(&call_frame->lock);
if (my_frame.root->ctx->measure_latency) {
gf_time_fmt(timestr, sizeof(timestr), my_frame.begin.tv_sec,
gf_timefmt_FT);
len = strlen(timestr);
snprintf(timestr + len, sizeof(timestr) - len, ".%" GF_PRI_SNSECONDS,
my_frame.begin.tv_nsec);
gf_proc_dump_write("frame-creation-time", "%s", timestr);
gf_proc_dump_write(
"timings", "%ld.%" GF_PRI_SNSECONDS " -> %ld.%" GF_PRI_SNSECONDS,
my_frame.begin.tv_sec, my_frame.begin.tv_nsec, my_frame.end.tv_sec,
my_frame.end.tv_nsec);
}
if (my_frame.root->ctx->measure_latency) {
gf_time_fmt (timestr, sizeof (timestr), my_frame.begin.tv_sec,
gf_timefmt_FT);
len = strlen (timestr);
snprintf (timestr + len, sizeof (timestr) - len,
".%"GF_PRI_SNSECONDS, my_frame.begin.tv_nsec);
gf_proc_dump_write("frame-creation-time", "%s", timestr);
gf_proc_dump_write("timings", "%ld.%"GF_PRI_SNSECONDS
" -> %ld.%"GF_PRI_SNSECONDS,
my_frame.begin.tv_sec,
my_frame.begin.tv_nsec,
my_frame.end.tv_sec,
my_frame.end.tv_nsec);
}
gf_proc_dump_write("frame", "%p", call_frame);
gf_proc_dump_write("ref_count", "%d", my_frame.ref_count);
gf_proc_dump_write("translator", "%s", my_frame.this->name);
gf_proc_dump_write("complete", "%d", my_frame.complete);
gf_proc_dump_write("frame", "%p", call_frame);
gf_proc_dump_write("ref_count", "%d", my_frame.ref_count);
gf_proc_dump_write("translator", "%s", my_frame.this->name);
gf_proc_dump_write("complete", "%d", my_frame.complete);
if (my_frame.parent)
gf_proc_dump_write("parent", "%s", my_frame.parent->this->name);
if (my_frame.parent)
gf_proc_dump_write("parent", "%s", my_frame.parent->this->name);
if (my_frame.wind_from)
gf_proc_dump_write("wind_from", "%s", my_frame.wind_from);
if (my_frame.wind_from)
gf_proc_dump_write("wind_from", "%s", my_frame.wind_from);
if (my_frame.wind_to)
gf_proc_dump_write("wind_to", "%s", my_frame.wind_to);
if (my_frame.wind_to)
gf_proc_dump_write("wind_to", "%s", my_frame.wind_to);
if (my_frame.unwind_from)
gf_proc_dump_write("unwind_from", "%s", my_frame.unwind_from);
if (my_frame.unwind_from)
gf_proc_dump_write("unwind_from", "%s", my_frame.unwind_from);
if (my_frame.unwind_to)
gf_proc_dump_write("unwind_to", "%s", my_frame.unwind_to);
if (my_frame.unwind_to)
gf_proc_dump_write("unwind_to", "%s", my_frame.unwind_to);
ret = 0;
ret = 0;
out:
if (ret) {
gf_proc_dump_write("Unable to dump the frame information",
"(Lock acquisition failed) %p", my_frame);
return;
}
}
void
gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
{
char prefix[GF_DUMP_MAX_BUF_LEN];
va_list ap;
call_frame_t *trav;
int32_t i = 1, cnt = 0;
char timestr[256] = {0,};
int len;
if (!call_stack)
return;
GF_ASSERT (key_buf);
va_start(ap, key_buf);
vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
va_end(ap);
cnt = call_frames_count (call_stack);
gf_time_fmt (timestr, sizeof (timestr), call_stack->tv.tv_sec,
gf_timefmt_FT);
len = strlen (timestr);
snprintf (timestr + len, sizeof (timestr) - len,
".%"GF_PRI_SNSECONDS, call_stack->tv.tv_nsec);
gf_proc_dump_write("callstack-creation-time", "%s", timestr);
gf_proc_dump_write("stack", "%p", call_stack);
gf_proc_dump_write("uid", "%d", call_stack->uid);
gf_proc_dump_write("gid", "%d", call_stack->gid);
gf_proc_dump_write("pid", "%d", call_stack->pid);
gf_proc_dump_write("unique", "%Ld", call_stack->unique);
gf_proc_dump_write("lk-owner", "%s", lkowner_utoa (&call_stack->lk_owner));
gf_proc_dump_write("ctime", "%lld.%"GF_PRI_SNSECONDS,
call_stack->tv.tv_sec, call_stack->tv.tv_nsec);
if (call_stack->type == GF_OP_TYPE_FOP)
gf_proc_dump_write("op", "%s",
(char *)gf_fop_list[call_stack->op]);
else
gf_proc_dump_write("op", "stack");
gf_proc_dump_write("type", "%d", call_stack->type);
gf_proc_dump_write("cnt", "%d", cnt);
list_for_each_entry (trav, &call_stack->myframes, frames) {
gf_proc_dump_add_section("%s.frame.%d", prefix, i);
gf_proc_dump_call_frame(trav, "%s.frame.%d", prefix, i);
i++;
}
if (ret) {
gf_proc_dump_write("Unable to dump the frame information",
"(Lock acquisition failed) %p", my_frame);
return;
}
}
void
gf_proc_dump_pending_frames (call_pool_t *call_pool)
gf_proc_dump_call_stack(call_stack_t *call_stack, const char *key_buf, ...)
{
char prefix[GF_DUMP_MAX_BUF_LEN];
va_list ap;
call_frame_t *trav;
int32_t i = 1, cnt = 0;
char timestr[256] = {
0,
};
int len;
call_stack_t *trav = NULL;
int i = 1;
int ret = -1;
gf_boolean_t section_added = _gf_false;
if (!call_stack)
return;
if (!call_pool)
return;
GF_ASSERT(key_buf);
ret = TRY_LOCK (&(call_pool->lock));
if (ret)
goto out;
va_start(ap, key_buf);
vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
va_end(ap);
cnt = call_frames_count(call_stack);
gf_time_fmt(timestr, sizeof(timestr), call_stack->tv.tv_sec, gf_timefmt_FT);
len = strlen(timestr);
snprintf(timestr + len, sizeof(timestr) - len, ".%" GF_PRI_SNSECONDS,
call_stack->tv.tv_nsec);
gf_proc_dump_write("callstack-creation-time", "%s", timestr);
gf_proc_dump_add_section("global.callpool");
section_added = _gf_true;
gf_proc_dump_write("callpool_address","%p", call_pool);
gf_proc_dump_write("callpool.cnt","%d", call_pool->cnt);
gf_proc_dump_write("stack", "%p", call_stack);
gf_proc_dump_write("uid", "%d", call_stack->uid);
gf_proc_dump_write("gid", "%d", call_stack->gid);
gf_proc_dump_write("pid", "%d", call_stack->pid);
gf_proc_dump_write("unique", "%Ld", call_stack->unique);
gf_proc_dump_write("lk-owner", "%s", lkowner_utoa(&call_stack->lk_owner));
gf_proc_dump_write("ctime", "%lld.%" GF_PRI_SNSECONDS,
call_stack->tv.tv_sec, call_stack->tv.tv_nsec);
if (call_stack->type == GF_OP_TYPE_FOP)
gf_proc_dump_write("op", "%s", (char *)gf_fop_list[call_stack->op]);
else
gf_proc_dump_write("op", "stack");
list_for_each_entry (trav, &call_pool->all_frames, all_frames) {
gf_proc_dump_add_section("global.callpool.stack.%d",i);
gf_proc_dump_call_stack(trav, "global.callpool.stack.%d", i);
i++;
}
UNLOCK (&(call_pool->lock));
gf_proc_dump_write("type", "%d", call_stack->type);
gf_proc_dump_write("cnt", "%d", cnt);
ret = 0;
list_for_each_entry(trav, &call_stack->myframes, frames)
{
gf_proc_dump_add_section("%s.frame.%d", prefix, i);
gf_proc_dump_call_frame(trav, "%s.frame.%d", prefix, i);
i++;
}
}
void
gf_proc_dump_pending_frames(call_pool_t *call_pool)
{
call_stack_t *trav = NULL;
int i = 1;
int ret = -1;
gf_boolean_t section_added = _gf_false;
if (!call_pool)
return;
ret = TRY_LOCK(&(call_pool->lock));
if (ret)
goto out;
gf_proc_dump_add_section("global.callpool");
section_added = _gf_true;
gf_proc_dump_write("callpool_address", "%p", call_pool);
gf_proc_dump_write("callpool.cnt", "%d", call_pool->cnt);
list_for_each_entry(trav, &call_pool->all_frames, all_frames)
{
gf_proc_dump_add_section("global.callpool.stack.%d", i);
gf_proc_dump_call_stack(trav, "global.callpool.stack.%d", i);
i++;
}
UNLOCK(&(call_pool->lock));
ret = 0;
out:
if (ret) {
if (_gf_false == section_added)
gf_proc_dump_add_section("global.callpool");
gf_proc_dump_write("Unable to dump the callpool",
"(Lock acquisition failed) %p",
call_pool);
}
return;
if (ret) {
if (_gf_false == section_added)
gf_proc_dump_add_section("global.callpool");
gf_proc_dump_write("Unable to dump the callpool",
"(Lock acquisition failed) %p", call_pool);
}
return;
}
void
gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
char *prefix, dict_t *dict)
gf_proc_dump_call_frame_to_dict(call_frame_t *call_frame, char *prefix,
dict_t *dict)
{
int ret = -1;
char key[GF_DUMP_MAX_BUF_LEN] = {0,};
char msg[GF_DUMP_MAX_BUF_LEN] = {0,};
call_frame_t tmp_frame = {0,};
if (!call_frame || !dict)
return;
ret = TRY_LOCK (&call_frame->lock);
if (ret)
return;
memcpy (&tmp_frame, call_frame, sizeof (tmp_frame));
UNLOCK (&call_frame->lock);
snprintf (key, sizeof (key), "%s.refcount", prefix);
ret = dict_set_int32 (dict, key, tmp_frame.ref_count);
if (ret)
return;
snprintf (key, sizeof (key), "%s.translator", prefix);
ret = dict_set_dynstr (dict, key, gf_strdup (tmp_frame.this->name));
if (ret)
return;
snprintf (key, sizeof (key), "%s.complete", prefix);
ret = dict_set_int32 (dict, key, tmp_frame.complete);
if (ret)
return;
if (tmp_frame.root->ctx->measure_latency) {
snprintf (key, sizeof (key), "%s.timings", prefix);
snprintf (msg, sizeof (msg), "%ld.%"GF_PRI_SNSECONDS
" -> %ld.%"GF_PRI_SNSECONDS,
tmp_frame.begin.tv_sec, tmp_frame.begin.tv_nsec,
tmp_frame.end.tv_sec, tmp_frame.end.tv_nsec);
ret = dict_set_str (dict, key, msg);
if (ret)
return;
}
if (tmp_frame.parent) {
snprintf (key, sizeof (key), "%s.parent", prefix);
ret = dict_set_dynstr (dict, key,
gf_strdup (tmp_frame.parent->this->name));
if (ret)
return;
}
if (tmp_frame.wind_from) {
snprintf (key, sizeof (key), "%s.windfrom", prefix);
ret = dict_set_dynstr (dict, key,
gf_strdup (tmp_frame.wind_from));
if (ret)
return;
}
if (tmp_frame.wind_to) {
snprintf (key, sizeof (key), "%s.windto", prefix);
ret = dict_set_dynstr (dict, key,
gf_strdup (tmp_frame.wind_to));
if (ret)
return;
}
if (tmp_frame.unwind_from) {
snprintf (key, sizeof (key), "%s.unwindfrom", prefix);
ret = dict_set_dynstr (dict, key,
gf_strdup (tmp_frame.unwind_from));
if (ret)
return;
}
if (tmp_frame.unwind_to) {
snprintf (key, sizeof (key), "%s.unwind_to", prefix);
ret = dict_set_dynstr (dict, key,
gf_strdup (tmp_frame.unwind_to));
}
int ret = -1;
char key[GF_DUMP_MAX_BUF_LEN] = {
0,
};
char msg[GF_DUMP_MAX_BUF_LEN] = {
0,
};
call_frame_t tmp_frame = {
0,
};
if (!call_frame || !dict)
return;
ret = TRY_LOCK(&call_frame->lock);
if (ret)
return;
memcpy(&tmp_frame, call_frame, sizeof(tmp_frame));
UNLOCK(&call_frame->lock);
snprintf(key, sizeof(key), "%s.refcount", prefix);
ret = dict_set_int32(dict, key, tmp_frame.ref_count);
if (ret)
return;
snprintf(key, sizeof(key), "%s.translator", prefix);
ret = dict_set_dynstr(dict, key, gf_strdup(tmp_frame.this->name));
if (ret)
return;
snprintf(key, sizeof(key), "%s.complete", prefix);
ret = dict_set_int32(dict, key, tmp_frame.complete);
if (ret)
return;
if (tmp_frame.root->ctx->measure_latency) {
snprintf(key, sizeof(key), "%s.timings", prefix);
snprintf(msg, sizeof(msg),
"%ld.%" GF_PRI_SNSECONDS " -> %ld.%" GF_PRI_SNSECONDS,
tmp_frame.begin.tv_sec, tmp_frame.begin.tv_nsec,
tmp_frame.end.tv_sec, tmp_frame.end.tv_nsec);
ret = dict_set_str(dict, key, msg);
if (ret)
return;
}
if (tmp_frame.parent) {
snprintf(key, sizeof(key), "%s.parent", prefix);
ret = dict_set_dynstr(dict, key,
gf_strdup(tmp_frame.parent->this->name));
if (ret)
return;
}
if (tmp_frame.wind_from) {
snprintf(key, sizeof(key), "%s.windfrom", prefix);
ret = dict_set_dynstr(dict, key, gf_strdup(tmp_frame.wind_from));
if (ret)
return;
}
if (tmp_frame.wind_to) {
snprintf(key, sizeof(key), "%s.windto", prefix);
ret = dict_set_dynstr(dict, key, gf_strdup(tmp_frame.wind_to));
if (ret)
return;
}
if (tmp_frame.unwind_from) {
snprintf(key, sizeof(key), "%s.unwindfrom", prefix);
ret = dict_set_dynstr(dict, key, gf_strdup(tmp_frame.unwind_from));
if (ret)
return;
}
if (tmp_frame.unwind_to) {
snprintf(key, sizeof(key), "%s.unwind_to", prefix);
ret = dict_set_dynstr(dict, key, gf_strdup(tmp_frame.unwind_to));
}
return;
}
void
gf_proc_dump_call_stack_to_dict (call_stack_t *call_stack,
char *prefix, dict_t *dict)
gf_proc_dump_call_stack_to_dict(call_stack_t *call_stack, char *prefix,
dict_t *dict)
{
int ret = -1;
char key[GF_DUMP_MAX_BUF_LEN] = {0,};
call_frame_t *trav = NULL;
int i = 0;
int count = 0;
if (!call_stack || !dict)
return;
count = call_frames_count (call_stack);
snprintf (key, sizeof (key), "%s.uid", prefix);
ret = dict_set_int32 (dict, key, call_stack->uid);
if (ret)
return;
snprintf (key, sizeof (key), "%s.gid", prefix);
ret = dict_set_int32 (dict, key, call_stack->gid);
if (ret)
return;
snprintf (key, sizeof (key), "%s.pid", prefix);
ret = dict_set_int32 (dict, key, call_stack->pid);
if (ret)
return;
snprintf (key, sizeof (key), "%s.unique", prefix);
ret = dict_set_uint64 (dict, key, call_stack->unique);
if (ret)
return;
snprintf (key, sizeof (key), "%s.op", prefix);
if (call_stack->type == GF_OP_TYPE_FOP)
ret = dict_set_str (dict, key,
(char *)gf_fop_list[call_stack->op]);
else
ret = dict_set_str (dict, key, "other");
if (ret)
return;
snprintf (key, sizeof (key), "%s.type", prefix);
ret = dict_set_int32 (dict, key, call_stack->type);
if (ret)
return;
snprintf (key, sizeof (key), "%s.count", prefix);
ret = dict_set_int32 (dict, key, count);
if (ret)
return;
list_for_each_entry (trav, &call_stack->myframes, frames) {
snprintf (key, sizeof (key), "%s.frame%d",
prefix, i);
gf_proc_dump_call_frame_to_dict (trav, key, dict);
i++;
}
int ret = -1;
char key[GF_DUMP_MAX_BUF_LEN] = {
0,
};
call_frame_t *trav = NULL;
int i = 0;
int count = 0;
if (!call_stack || !dict)
return;
count = call_frames_count(call_stack);
snprintf(key, sizeof(key), "%s.uid", prefix);
ret = dict_set_int32(dict, key, call_stack->uid);
if (ret)
return;
snprintf(key, sizeof(key), "%s.gid", prefix);
ret = dict_set_int32(dict, key, call_stack->gid);
if (ret)
return;
snprintf(key, sizeof(key), "%s.pid", prefix);
ret = dict_set_int32(dict, key, call_stack->pid);
if (ret)
return;
snprintf(key, sizeof(key), "%s.unique", prefix);
ret = dict_set_uint64(dict, key, call_stack->unique);
if (ret)
return;
snprintf(key, sizeof(key), "%s.op", prefix);
if (call_stack->type == GF_OP_TYPE_FOP)
ret = dict_set_str(dict, key, (char *)gf_fop_list[call_stack->op]);
else
ret = dict_set_str(dict, key, "other");
if (ret)
return;
snprintf(key, sizeof(key), "%s.type", prefix);
ret = dict_set_int32(dict, key, call_stack->type);
if (ret)
return;
snprintf(key, sizeof(key), "%s.count", prefix);
ret = dict_set_int32(dict, key, count);
if (ret)
return;
list_for_each_entry(trav, &call_stack->myframes, frames)
{
snprintf(key, sizeof(key), "%s.frame%d", prefix, i);
gf_proc_dump_call_frame_to_dict(trav, key, dict);
i++;
}
return;
}
void
gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool, dict_t *dict)
gf_proc_dump_pending_frames_to_dict(call_pool_t *call_pool, dict_t *dict)
{
int ret = -1;
call_stack_t *trav = NULL;
char key[GF_DUMP_MAX_BUF_LEN] = {0,};
int i = 0;
int ret = -1;
call_stack_t *trav = NULL;
char key[GF_DUMP_MAX_BUF_LEN] = {
0,
};
int i = 0;
if (!call_pool || !dict)
return;
if (!call_pool || !dict)
return;
ret = TRY_LOCK (&call_pool->lock);
if (ret) {
gf_msg (THIS->name, GF_LOG_WARNING, errno,
LG_MSG_LOCK_FAILURE, "Unable to dump call "
"pool to dict.");
return;
}
ret = TRY_LOCK(&call_pool->lock);
if (ret) {
gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_LOCK_FAILURE,
"Unable to dump call "
"pool to dict.");
return;
}
ret = dict_set_int32 (dict, "callpool.count", call_pool->cnt);
if (ret)
goto out;
ret = dict_set_int32(dict, "callpool.count", call_pool->cnt);
if (ret)
goto out;
list_for_each_entry (trav, &call_pool->all_frames, all_frames) {
snprintf (key, sizeof (key), "callpool.stack%d", i);
gf_proc_dump_call_stack_to_dict (trav, key, dict);
i++;
}
list_for_each_entry(trav, &call_pool->all_frames, all_frames)
{
snprintf(key, sizeof(key), "callpool.stack%d", i);
gf_proc_dump_call_stack_to_dict(trav, key, dict);
i++;
}
out:
UNLOCK (&call_pool->lock);
UNLOCK(&call_pool->lock);
return;
return;
}
gf_boolean_t
__is_fuse_call (call_frame_t *frame)
__is_fuse_call(call_frame_t *frame)
{
gf_boolean_t is_fuse_call = _gf_false;
GF_ASSERT (frame);
GF_ASSERT (frame->root);
gf_boolean_t is_fuse_call = _gf_false;
GF_ASSERT(frame);
GF_ASSERT(frame->root);
if (NFS_PID != frame->root->pid)
is_fuse_call = _gf_true;
return is_fuse_call;
if (NFS_PID != frame->root->pid)
is_fuse_call = _gf_true;
return is_fuse_call;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,77 +16,78 @@
#include "common-utils.h"
strfd_t *
strfd_open ()
strfd_open()
{
strfd_t *strfd = NULL;
strfd_t *strfd = NULL;
strfd = GF_CALLOC(1, sizeof(*strfd), gf_common_mt_strfd_t);
strfd = GF_CALLOC(1, sizeof(*strfd), gf_common_mt_strfd_t);
return strfd;
return strfd;
}
int
strvprintf (strfd_t *strfd, const char *fmt, va_list ap)
strvprintf(strfd_t *strfd, const char *fmt, va_list ap)
{
char *str = NULL;
int size = 0;
char *str = NULL;
int size = 0;
size = vasprintf (&str, fmt, ap);
if (size < 0)
return size;
if (!strfd->alloc_size) {
strfd->data = GF_CALLOC (max(size + 1, 4096), 1,
gf_common_mt_strfd_data_t);
if (!strfd->data) {
free (str); /* NOT GF_FREE */
return -1;
}
strfd->alloc_size = max(size + 1, 4096);
}
if (strfd->alloc_size <= (strfd->size + size)) {
char *tmp_ptr = NULL;
int new_size = max ((strfd->alloc_size * 2),
gf_roundup_next_power_of_two (strfd->size + size + 1));
tmp_ptr = GF_REALLOC (strfd->data, new_size);
if (!tmp_ptr) {
free (str); /* NOT GF_FREE */
return -1;
}
strfd->alloc_size = new_size;
strfd->data = tmp_ptr;
}
/* Copy the trailing '\0', but do not account for it in ->size.
This allows safe use of strfd->data as a string. */
memcpy (strfd->data + strfd->size, str, size + 1);
strfd->size += size;
free (str); /* NOT GF_FREE */
size = vasprintf(&str, fmt, ap);
if (size < 0)
return size;
if (!strfd->alloc_size) {
strfd->data = GF_CALLOC(max(size + 1, 4096), 1,
gf_common_mt_strfd_data_t);
if (!strfd->data) {
free(str); /* NOT GF_FREE */
return -1;
}
strfd->alloc_size = max(size + 1, 4096);
}
if (strfd->alloc_size <= (strfd->size + size)) {
char *tmp_ptr = NULL;
int new_size = max(
(strfd->alloc_size * 2),
gf_roundup_next_power_of_two(strfd->size + size + 1));
tmp_ptr = GF_REALLOC(strfd->data, new_size);
if (!tmp_ptr) {
free(str); /* NOT GF_FREE */
return -1;
}
strfd->alloc_size = new_size;
strfd->data = tmp_ptr;
}
/* Copy the trailing '\0', but do not account for it in ->size.
This allows safe use of strfd->data as a string. */
memcpy(strfd->data + strfd->size, str, size + 1);
strfd->size += size;
free(str); /* NOT GF_FREE */
return size;
}
int
strprintf (strfd_t *strfd, const char *fmt, ...)
strprintf(strfd_t *strfd, const char *fmt, ...)
{
int ret = 0;
va_list ap;
int ret = 0;
va_list ap;
va_start (ap, fmt);
ret = strvprintf (strfd, fmt, ap);
va_end (ap);
va_start(ap, fmt);
ret = strvprintf(strfd, fmt, ap);
va_end(ap);
return ret;
return ret;
}
int
strfd_close (strfd_t *strfd)
strfd_close(strfd_t *strfd)
{
GF_FREE (strfd->data);
GF_FREE (strfd);
GF_FREE(strfd->data);
GF_FREE(strfd);
return 0;
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -27,93 +27,93 @@
#include "throttle-tbf.h"
typedef struct tbf_throttle {
char done;
char done;
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_mutex_t mutex;
pthread_cond_t cond;
unsigned long tokens;
unsigned long tokens;
struct list_head list;
struct list_head list;
} tbf_throttle_t;
static tbf_throttle_t *
tbf_init_throttle (unsigned long tokens_required)
tbf_init_throttle(unsigned long tokens_required)
{
tbf_throttle_t *throttle = NULL;
tbf_throttle_t *throttle = NULL;
throttle = GF_CALLOC (1, sizeof (*throttle),
gf_common_mt_tbf_throttle_t);
if (!throttle)
return NULL;
throttle = GF_CALLOC(1, sizeof(*throttle), gf_common_mt_tbf_throttle_t);
if (!throttle)
return NULL;
throttle->done = 0;
throttle->tokens = tokens_required;
INIT_LIST_HEAD (&throttle->list);
throttle->done = 0;
throttle->tokens = tokens_required;
INIT_LIST_HEAD(&throttle->list);
(void) pthread_mutex_init (&throttle->mutex, NULL);
(void) pthread_cond_init (&throttle->cond, NULL);
(void)pthread_mutex_init(&throttle->mutex, NULL);
(void)pthread_cond_init(&throttle->cond, NULL);
return throttle;
return throttle;
}
void
_tbf_dispatch_queued (tbf_bucket_t *bucket)
_tbf_dispatch_queued(tbf_bucket_t *bucket)
{
gf_boolean_t xcont = _gf_false;
tbf_throttle_t *tmp = NULL;
tbf_throttle_t *throttle = NULL;
gf_boolean_t xcont = _gf_false;
tbf_throttle_t *tmp = NULL;
tbf_throttle_t *throttle = NULL;
list_for_each_entry_safe (throttle, tmp, &bucket->queued, list) {
list_for_each_entry_safe(throttle, tmp, &bucket->queued, list)
{
pthread_mutex_lock(&throttle->mutex);
{
if (bucket->tokens < throttle->tokens) {
xcont = _gf_true;
goto unblock;
}
pthread_mutex_lock (&throttle->mutex);
{
if (bucket->tokens < throttle->tokens) {
xcont = _gf_true;
goto unblock;
}
/* this request can now be serviced */
throttle->done = 1;
list_del_init(&throttle->list);
/* this request can now be serviced */
throttle->done = 1;
list_del_init (&throttle->list);
bucket->tokens -= throttle->tokens;
pthread_cond_signal (&throttle->cond);
}
unblock:
pthread_mutex_unlock (&throttle->mutex);
if (xcont)
break;
bucket->tokens -= throttle->tokens;
pthread_cond_signal(&throttle->cond);
}
unblock:
pthread_mutex_unlock(&throttle->mutex);
if (xcont)
break;
}
}
void *tbf_tokengenerator (void *arg)
void *
tbf_tokengenerator(void *arg)
{
unsigned long tokenrate = 0;
unsigned long maxtokens = 0;
unsigned long token_gen_interval = 0;
tbf_bucket_t *bucket = arg;
unsigned long tokenrate = 0;
unsigned long maxtokens = 0;
unsigned long token_gen_interval = 0;
tbf_bucket_t *bucket = arg;
tokenrate = bucket->tokenrate;
maxtokens = bucket->maxtokens;
token_gen_interval = bucket->token_gen_interval;
tokenrate = bucket->tokenrate;
maxtokens = bucket->maxtokens;
token_gen_interval = bucket->token_gen_interval;
while (1) {
usleep (token_gen_interval);
while (1) {
usleep(token_gen_interval);
LOCK (&bucket->lock);
{
bucket->tokens += tokenrate;
if (bucket->tokens > maxtokens)
bucket->tokens = maxtokens;
LOCK(&bucket->lock);
{
bucket->tokens += tokenrate;
if (bucket->tokens > maxtokens)
bucket->tokens = maxtokens;
if (!list_empty (&bucket->queued))
_tbf_dispatch_queued (bucket);
}
UNLOCK (&bucket->lock);
if (!list_empty(&bucket->queued))
_tbf_dispatch_queued(bucket);
}
UNLOCK(&bucket->lock);
}
return NULL;
return NULL;
}
/**
@ -122,170 +122,169 @@ void *tbf_tokengenerator (void *arg)
* updated _after_ all the required variables are initialized.
*/
static int32_t
tbf_init_bucket (tbf_t *tbf, tbf_opspec_t *spec)
tbf_init_bucket(tbf_t *tbf, tbf_opspec_t *spec)
{
int ret = 0;
tbf_bucket_t *curr = NULL;
tbf_bucket_t **bucket = NULL;
int ret = 0;
tbf_bucket_t *curr = NULL;
tbf_bucket_t **bucket = NULL;
GF_ASSERT (spec->op >= TBF_OP_MIN);
GF_ASSERT (spec->op <= TBF_OP_MAX);
GF_ASSERT(spec->op >= TBF_OP_MIN);
GF_ASSERT(spec->op <= TBF_OP_MAX);
/* no rate? no throttling. */
if (!spec->rate)
return 0;
bucket = tbf->bucket + spec->op;
curr = GF_CALLOC (1, sizeof (*curr), gf_common_mt_tbf_bucket_t);
if (!curr)
goto error_return;
LOCK_INIT (&curr->lock);
INIT_LIST_HEAD (&curr->queued);
curr->tokens = 0;
curr->tokenrate = spec->rate;
curr->maxtokens = spec->maxlimit;
curr->token_gen_interval = spec->token_gen_interval;
ret = gf_thread_create (&curr->tokener,
NULL, tbf_tokengenerator, curr, "tbfclock");
if (ret != 0)
goto freemem;
*bucket = curr;
/* no rate? no throttling. */
if (!spec->rate)
return 0;
freemem:
LOCK_DESTROY (&curr->lock);
GF_FREE (curr);
error_return:
return -1;
bucket = tbf->bucket + spec->op;
curr = GF_CALLOC(1, sizeof(*curr), gf_common_mt_tbf_bucket_t);
if (!curr)
goto error_return;
LOCK_INIT(&curr->lock);
INIT_LIST_HEAD(&curr->queued);
curr->tokens = 0;
curr->tokenrate = spec->rate;
curr->maxtokens = spec->maxlimit;
curr->token_gen_interval = spec->token_gen_interval;
ret = gf_thread_create(&curr->tokener, NULL, tbf_tokengenerator, curr,
"tbfclock");
if (ret != 0)
goto freemem;
*bucket = curr;
return 0;
freemem:
LOCK_DESTROY(&curr->lock);
GF_FREE(curr);
error_return:
return -1;
}
#define TBF_ALLOC_SIZE \
(sizeof (tbf_t) + (TBF_OP_MAX * sizeof (tbf_bucket_t)))
#define TBF_ALLOC_SIZE (sizeof(tbf_t) + (TBF_OP_MAX * sizeof(tbf_bucket_t)))
tbf_t *
tbf_init (tbf_opspec_t *tbfspec, unsigned int count)
tbf_init(tbf_opspec_t *tbfspec, unsigned int count)
{
int32_t i = 0;
int32_t ret = 0;
tbf_t *tbf = NULL;
tbf_opspec_t *opspec = NULL;
int32_t i = 0;
int32_t ret = 0;
tbf_t *tbf = NULL;
tbf_opspec_t *opspec = NULL;
tbf = GF_CALLOC (1, TBF_ALLOC_SIZE, gf_common_mt_tbf_t);
if (!tbf)
goto error_return;
tbf = GF_CALLOC(1, TBF_ALLOC_SIZE, gf_common_mt_tbf_t);
if (!tbf)
goto error_return;
tbf->bucket = (tbf_bucket_t **) ((char *)tbf + sizeof (*tbf));
for (i = 0; i < TBF_OP_MAX; i++) {
*(tbf->bucket + i) = NULL;
}
tbf->bucket = (tbf_bucket_t **)((char *)tbf + sizeof(*tbf));
for (i = 0; i < TBF_OP_MAX; i++) {
*(tbf->bucket + i) = NULL;
}
for (i = 0; i < count; i++) {
opspec = tbfspec + i;
ret = tbf_init_bucket (tbf, opspec);
if (ret)
break;
}
for (i = 0; i < count; i++) {
opspec = tbfspec + i;
ret = tbf_init_bucket(tbf, opspec);
if (ret)
goto error_return;
break;
}
return tbf;
if (ret)
goto error_return;
error_return:
return NULL;
return tbf;
error_return:
return NULL;
}
static void
tbf_mod_bucket (tbf_bucket_t *bucket, tbf_opspec_t *spec)
tbf_mod_bucket(tbf_bucket_t *bucket, tbf_opspec_t *spec)
{
LOCK (&bucket->lock);
{
bucket->tokens = 0;
bucket->tokenrate = spec->rate;
bucket->maxtokens = spec->maxlimit;
}
UNLOCK (&bucket->lock);
LOCK(&bucket->lock);
{
bucket->tokens = 0;
bucket->tokenrate = spec->rate;
bucket->maxtokens = spec->maxlimit;
}
UNLOCK(&bucket->lock);
/* next token tick would unqueue pending operations */
/* next token tick would unqueue pending operations */
}
int
tbf_mod (tbf_t *tbf, tbf_opspec_t *tbfspec)
tbf_mod(tbf_t *tbf, tbf_opspec_t *tbfspec)
{
int ret = 0;
tbf_bucket_t *bucket = NULL;
tbf_ops_t op = TBF_OP_MIN;
int ret = 0;
tbf_bucket_t *bucket = NULL;
tbf_ops_t op = TBF_OP_MIN;
if (!tbf || !tbfspec)
return -1;
if (!tbf || !tbfspec)
return -1;
op = tbfspec->op;
op = tbfspec->op;
GF_ASSERT (op >= TBF_OP_MIN);
GF_ASSERT (op <= TBF_OP_MAX);
GF_ASSERT(op >= TBF_OP_MIN);
GF_ASSERT(op <= TBF_OP_MAX);
bucket = *(tbf->bucket + op);
if (bucket) {
tbf_mod_bucket (bucket, tbfspec);
} else {
ret = tbf_init_bucket (tbf, tbfspec);
}
bucket = *(tbf->bucket + op);
if (bucket) {
tbf_mod_bucket(bucket, tbfspec);
} else {
ret = tbf_init_bucket(tbf, tbfspec);
}
return ret;
return ret;
}
void
tbf_throttle (tbf_t *tbf, tbf_ops_t op, unsigned long tokens_requested)
tbf_throttle(tbf_t *tbf, tbf_ops_t op, unsigned long tokens_requested)
{
char waitq = 0;
tbf_bucket_t *bucket = NULL;
tbf_throttle_t *throttle = NULL;
char waitq = 0;
tbf_bucket_t *bucket = NULL;
tbf_throttle_t *throttle = NULL;
GF_ASSERT (op >= TBF_OP_MIN);
GF_ASSERT (op <= TBF_OP_MAX);
GF_ASSERT(op >= TBF_OP_MIN);
GF_ASSERT(op <= TBF_OP_MAX);
bucket = *(tbf->bucket + op);
if (!bucket)
return;
bucket = *(tbf->bucket + op);
if (!bucket)
return;
LOCK (&bucket->lock);
{
/**
* if there are enough tokens in the bucket there is no need
* to throttle the request: therefore, consume the required
* number of tokens and continue.
*/
if (tokens_requested <= bucket->tokens) {
bucket->tokens -= tokens_requested;
} else {
throttle = tbf_init_throttle (tokens_requested);
if (!throttle) /* let it slip through for now.. */
goto unblock;
LOCK(&bucket->lock);
{
/**
* if there are enough tokens in the bucket there is no need
* to throttle the request: therefore, consume the required
* number of tokens and continue.
*/
if (tokens_requested <= bucket->tokens) {
bucket->tokens -= tokens_requested;
} else {
throttle = tbf_init_throttle(tokens_requested);
if (!throttle) /* let it slip through for now.. */
goto unblock;
waitq = 1;
pthread_mutex_lock (&throttle->mutex);
list_add_tail (&throttle->list, &bucket->queued);
}
waitq = 1;
pthread_mutex_lock(&throttle->mutex);
list_add_tail(&throttle->list, &bucket->queued);
}
unblock:
UNLOCK (&bucket->lock);
}
unblock:
UNLOCK(&bucket->lock);
if (waitq) {
while (!throttle->done) {
pthread_cond_wait (&throttle->cond, &throttle->mutex);
}
pthread_mutex_unlock (&throttle->mutex);
pthread_mutex_destroy (&throttle->mutex);
pthread_cond_destroy (&throttle->cond);
GF_FREE (throttle);
if (waitq) {
while (!throttle->done) {
pthread_cond_wait(&throttle->cond, &throttle->mutex);
}
pthread_mutex_unlock(&throttle->mutex);
pthread_mutex_destroy(&throttle->mutex);
pthread_cond_destroy(&throttle->cond);
GF_FREE(throttle);
}
}

View File

@ -17,265 +17,255 @@
/* fwd decl */
static gf_timer_registry_t *
gf_timer_registry_init (glusterfs_ctx_t *);
gf_timer_registry_init(glusterfs_ctx_t *);
gf_timer_t *
gf_timer_call_after (glusterfs_ctx_t *ctx,
struct timespec delta,
gf_timer_cbk_t callbk,
void *data)
gf_timer_call_after(glusterfs_ctx_t *ctx, struct timespec delta,
gf_timer_cbk_t callbk, void *data)
{
gf_timer_registry_t *reg = NULL;
gf_timer_t *event = NULL;
gf_timer_t *trav = NULL;
uint64_t at = 0;
gf_timer_registry_t *reg = NULL;
gf_timer_t *event = NULL;
gf_timer_t *trav = NULL;
uint64_t at = 0;
if ((ctx == NULL) || (ctx->cleanup_started))
if ((ctx == NULL) || (ctx->cleanup_started)) {
gf_msg_callingfn("timer", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
"Either ctx is NULL or"
" ctx cleanup started");
return NULL;
}
reg = gf_timer_registry_init(ctx);
if (!reg) {
gf_msg_callingfn("timer", GF_LOG_ERROR, 0, LG_MSG_TIMER_REGISTER_ERROR,
"!reg");
return NULL;
}
event = GF_CALLOC(1, sizeof(*event), gf_common_mt_gf_timer_t);
if (!event) {
return NULL;
}
timespec_now(&event->at);
timespec_adjust_delta(&event->at, delta);
at = TS(event->at);
event->callbk = callbk;
event->data = data;
event->xl = THIS;
LOCK(&reg->lock);
{
list_for_each_entry_reverse(trav, &reg->active, list)
{
gf_msg_callingfn ("timer", GF_LOG_ERROR, EINVAL,
LG_MSG_INVALID_ARG, "Either ctx is NULL or"
" ctx cleanup started");
return NULL;
if (TS(trav->at) < at)
break;
}
reg = gf_timer_registry_init (ctx);
if (!reg) {
gf_msg_callingfn ("timer", GF_LOG_ERROR, 0,
LG_MSG_TIMER_REGISTER_ERROR, "!reg");
return NULL;
}
event = GF_CALLOC (1, sizeof (*event), gf_common_mt_gf_timer_t);
if (!event) {
return NULL;
}
timespec_now (&event->at);
timespec_adjust_delta (&event->at, delta);
at = TS (event->at);
event->callbk = callbk;
event->data = data;
event->xl = THIS;
LOCK (&reg->lock);
{
list_for_each_entry_reverse (trav, &reg->active, list) {
if (TS (trav->at) < at)
break;
}
list_add (&event->list, &trav->list);
}
UNLOCK (&reg->lock);
return event;
list_add(&event->list, &trav->list);
}
UNLOCK(&reg->lock);
return event;
}
int32_t
gf_timer_call_cancel (glusterfs_ctx_t *ctx,
gf_timer_t *event)
gf_timer_call_cancel(glusterfs_ctx_t *ctx, gf_timer_t *event)
{
gf_timer_registry_t *reg = NULL;
gf_boolean_t fired = _gf_false;
gf_timer_registry_t *reg = NULL;
gf_boolean_t fired = _gf_false;
if (ctx == NULL || event == NULL)
{
gf_msg_callingfn ("timer", GF_LOG_ERROR, EINVAL,
LG_MSG_INVALID_ARG, "invalid argument");
return 0;
}
if (ctx == NULL || event == NULL) {
gf_msg_callingfn("timer", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
"invalid argument");
return 0;
}
if (ctx->cleanup_started) {
gf_msg_callingfn ("timer", GF_LOG_INFO, 0,
LG_MSG_CTX_CLEANUP_STARTED,
"ctx cleanup started");
return 0;
}
if (ctx->cleanup_started) {
gf_msg_callingfn("timer", GF_LOG_INFO, 0, LG_MSG_CTX_CLEANUP_STARTED,
"ctx cleanup started");
return 0;
}
LOCK (&ctx->lock);
{
reg = ctx->timer;
}
UNLOCK (&ctx->lock);
LOCK(&ctx->lock);
{
reg = ctx->timer;
}
UNLOCK(&ctx->lock);
if (!reg) {
/* This can happen when cleanup may have just started and
* gf_timer_registry_destroy() sets ctx->timer to NULL.
* Just bail out as success as gf_timer_proc() takes
* care of cleaning up the events.
*/
return 0;
}
if (!reg) {
/* This can happen when cleanup may have just started and
* gf_timer_registry_destroy() sets ctx->timer to NULL.
* Just bail out as success as gf_timer_proc() takes
* care of cleaning up the events.
*/
return 0;
}
LOCK (&reg->lock);
{
fired = event->fired;
if (fired)
goto unlock;
list_del (&event->list);
}
LOCK(&reg->lock);
{
fired = event->fired;
if (fired)
goto unlock;
list_del(&event->list);
}
unlock:
UNLOCK (&reg->lock);
UNLOCK(&reg->lock);
if (!fired) {
GF_FREE (event);
return 0;
}
return -1;
if (!fired) {
GF_FREE(event);
return 0;
}
return -1;
}
static void *
gf_timer_proc (void *data)
gf_timer_proc(void *data)
{
gf_timer_registry_t *reg = data;
struct timespec sleepts;
gf_timer_t *event = NULL;
gf_timer_t *tmp = NULL;
xlator_t *old_THIS = NULL;
gf_timer_registry_t *reg = data;
struct timespec sleepts;
gf_timer_t *event = NULL;
gf_timer_t *tmp = NULL;
xlator_t *old_THIS = NULL;
while (!reg->fin) {
uint64_t now;
struct timespec now_ts;
while (!reg->fin) {
uint64_t now;
struct timespec now_ts;
timespec_now (&now_ts);
now = TS (now_ts);
while (1) {
uint64_t at;
char need_cbk = 0;
timespec_now(&now_ts);
now = TS(now_ts);
while (1) {
uint64_t at;
char need_cbk = 0;
/*
* This will be overridden with a shorter interval if
* there's an event scheduled sooner. That makes the
* system more responsive in most cases, but doesn't
* include the case where a timer is added while we're
* asleep. It's tempting to use pthread_cond_timedwait,
* with the caveat that we'd be relying on system time
* instead of monotonic time. That's a mess when the
* system time is adjusted. Another alternative might
* be to use pthread_kill, but that will remain TBD for
* now.
*/
sleepts.tv_sec = 1;
sleepts.tv_nsec = 0;
/*
* This will be overridden with a shorter interval if
* there's an event scheduled sooner. That makes the
* system more responsive in most cases, but doesn't
* include the case where a timer is added while we're
* asleep. It's tempting to use pthread_cond_timedwait,
* with the caveat that we'd be relying on system time
* instead of monotonic time. That's a mess when the
* system time is adjusted. Another alternative might
* be to use pthread_kill, but that will remain TBD for
* now.
*/
sleepts.tv_sec = 1;
sleepts.tv_nsec = 0;
LOCK (&reg->lock);
{
/*
* Using list_for_each and then always breaking
* after the first iteration might seem strange,
* but (unlike alternatives) is independent of
* the underlying list implementation.
*/
list_for_each_entry_safe (event,
tmp, &reg->active, list) {
at = TS (event->at);
if (now >= at) {
need_cbk = 1;
event->fired = _gf_true;
list_del (&event->list);
} else {
uint64_t diff = now - at;
if (diff < 1000000000) {
sleepts.tv_sec = 0;
sleepts.tv_nsec = diff;
}
}
break;
}
}
UNLOCK (&reg->lock);
if (need_cbk) {
old_THIS = NULL;
if (event->xl) {
old_THIS = THIS;
THIS = event->xl;
}
event->callbk (event->data);
GF_FREE (event);
if (old_THIS) {
THIS = old_THIS;
}
} else {
break;
}
}
nanosleep (&sleepts, NULL);
}
LOCK (&reg->lock);
{
/* Do not call gf_timer_call_cancel(),
* it will lead to deadlock
LOCK(&reg->lock);
{
/*
* Using list_for_each and then always breaking
* after the first iteration might seem strange,
* but (unlike alternatives) is independent of
* the underlying list implementation.
*/
list_for_each_entry_safe (event, tmp, &reg->active, list) {
list_del (&event->list);
GF_FREE (event);
list_for_each_entry_safe(event, tmp, &reg->active, list)
{
at = TS(event->at);
if (now >= at) {
need_cbk = 1;
event->fired = _gf_true;
list_del(&event->list);
} else {
uint64_t diff = now - at;
if (diff < 1000000000) {
sleepts.tv_sec = 0;
sleepts.tv_nsec = diff;
}
}
break;
}
}
UNLOCK(&reg->lock);
if (need_cbk) {
old_THIS = NULL;
if (event->xl) {
old_THIS = THIS;
THIS = event->xl;
}
event->callbk(event->data);
GF_FREE(event);
if (old_THIS) {
THIS = old_THIS;
}
} else {
break;
}
}
UNLOCK (&reg->lock);
LOCK_DESTROY (&reg->lock);
nanosleep(&sleepts, NULL);
}
return NULL;
LOCK(&reg->lock);
{
/* Do not call gf_timer_call_cancel(),
* it will lead to deadlock
*/
list_for_each_entry_safe(event, tmp, &reg->active, list)
{
list_del(&event->list);
GF_FREE(event);
}
}
UNLOCK(&reg->lock);
LOCK_DESTROY(&reg->lock);
return NULL;
}
static gf_timer_registry_t *
gf_timer_registry_init (glusterfs_ctx_t *ctx)
gf_timer_registry_init(glusterfs_ctx_t *ctx)
{
gf_timer_registry_t *reg = NULL;
int ret = -1;
gf_timer_registry_t *reg = NULL;
int ret = -1;
LOCK (&ctx->lock);
{
reg = ctx->timer;
if (reg) {
UNLOCK (&ctx->lock);
goto out;
}
reg = GF_CALLOC (1, sizeof (*reg),
gf_common_mt_gf_timer_registry_t);
if (!reg) {
UNLOCK (&ctx->lock);
goto out;
}
ctx->timer = reg;
LOCK_INIT (&reg->lock);
INIT_LIST_HEAD (&reg->active);
LOCK(&ctx->lock);
{
reg = ctx->timer;
if (reg) {
UNLOCK(&ctx->lock);
goto out;
}
UNLOCK (&ctx->lock);
ret = gf_thread_create (&reg->th, NULL, gf_timer_proc, reg, "timer");
if (ret) {
gf_msg (THIS->name, GF_LOG_ERROR, ret,
LG_MSG_PTHREAD_FAILED,
"Thread creation failed");
reg = GF_CALLOC(1, sizeof(*reg), gf_common_mt_gf_timer_registry_t);
if (!reg) {
UNLOCK(&ctx->lock);
goto out;
}
ctx->timer = reg;
LOCK_INIT(&reg->lock);
INIT_LIST_HEAD(&reg->active);
}
UNLOCK(&ctx->lock);
ret = gf_thread_create(&reg->th, NULL, gf_timer_proc, reg, "timer");
if (ret) {
gf_msg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_FAILED,
"Thread creation failed");
}
out:
return reg;
return reg;
}
void
gf_timer_registry_destroy (glusterfs_ctx_t *ctx)
gf_timer_registry_destroy(glusterfs_ctx_t *ctx)
{
pthread_t thr_id;
gf_timer_registry_t *reg = NULL;
pthread_t thr_id;
gf_timer_registry_t *reg = NULL;
if (ctx == NULL)
return;
if (ctx == NULL)
return;
LOCK (&ctx->lock);
{
reg = ctx->timer;
ctx->timer = NULL;
}
UNLOCK (&ctx->lock);
LOCK(&ctx->lock);
{
reg = ctx->timer;
ctx->timer = NULL;
}
UNLOCK(&ctx->lock);
if (!reg)
return;
if (!reg)
return;
thr_id = reg->th;
reg->fin = 1;
pthread_join (thr_id, NULL);
GF_FREE (reg);
thr_id = reg->th;
reg->fin = 1;
pthread_join(thr_id, NULL);
GF_FREE(reg);
}

View File

@ -24,65 +24,69 @@ static mach_timebase_info_data_t gf_timebase;
#include "libglusterfs-messages.h"
#include "common-utils.h"
void timespec_now (struct timespec *ts)
void
timespec_now(struct timespec *ts)
{
#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS || defined GF_BSD_HOST_OS
if (0 == clock_gettime(CLOCK_MONOTONIC, ts)) {
/* All good */
return;
}
#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS || \
defined GF_BSD_HOST_OS
if (0 == clock_gettime(CLOCK_MONOTONIC, ts)) {
/* All good */
return;
}
/* Fall back, but there is hope in gettimeofday() syscall */
struct timeval tv;
if (0 == gettimeofday(&tv, NULL)) {
/* Again, all good */
TIMEVAL_TO_TIMESPEC(&tv, ts);
return;
}
/* Fall back, but there is hope in gettimeofday() syscall */
struct timeval tv;
if (0 == gettimeofday(&tv, NULL)) {
/* Again, all good */
TIMEVAL_TO_TIMESPEC(&tv, ts);
return;
}
/* If control hits here, there is surely a problem,
mainly because, as per man page too, these syscalls
shouldn't fail. Best way is to ABORT, because it is
not right */
GF_ABORT ("gettimeofday() failed!!");
/* If control hits here, there is surely a problem,
mainly because, as per man page too, these syscalls
shouldn't fail. Best way is to ABORT, because it is
not right */
GF_ABORT("gettimeofday() failed!!");
#elif defined GF_DARWIN_HOST_OS
uint64_t time = mach_absolute_time();
static double scaling = 0.0;
uint64_t time = mach_absolute_time();
static double scaling = 0.0;
if (mach_timebase_info(&gf_timebase) != KERN_SUCCESS) {
gf_timebase.numer = 1;
gf_timebase.denom = 1;
}
if (gf_timebase.denom == 0) {
gf_timebase.numer = 1;
gf_timebase.denom = 1;
}
if (mach_timebase_info(&gf_timebase) != KERN_SUCCESS) {
gf_timebase.numer = 1;
gf_timebase.denom = 1;
}
if (gf_timebase.denom == 0) {
gf_timebase.numer = 1;
gf_timebase.denom = 1;
}
scaling = (double) gf_timebase.numer / (double) gf_timebase.denom;
time *= scaling;
scaling = (double)gf_timebase.numer / (double)gf_timebase.denom;
time *= scaling;
ts->tv_sec = (time * NANO);
ts->tv_nsec = (time - (ts->tv_sec * GIGA));
ts->tv_sec = (time * NANO);
ts->tv_nsec = (time - (ts->tv_sec * GIGA));
#endif /* Platform verification */
}
void timespec_adjust_delta (struct timespec *ts, struct timespec delta)
void
timespec_adjust_delta(struct timespec *ts, struct timespec delta)
{
ts->tv_nsec = ((ts->tv_nsec + delta.tv_nsec) % 1000000000);
ts->tv_sec += ((ts->tv_nsec + delta.tv_nsec) / 1000000000);
ts->tv_sec += delta.tv_sec;
ts->tv_nsec = ((ts->tv_nsec + delta.tv_nsec) % 1000000000);
ts->tv_sec += ((ts->tv_nsec + delta.tv_nsec) / 1000000000);
ts->tv_sec += delta.tv_sec;
}
void timespec_sub (const struct timespec *begin, const struct timespec *end,
struct timespec *res)
void
timespec_sub(const struct timespec *begin, const struct timespec *end,
struct timespec *res)
{
if (end->tv_nsec < begin->tv_nsec) {
res->tv_sec = end->tv_sec - begin->tv_sec - 1;
res->tv_nsec = end->tv_nsec + 1000000000 - begin->tv_nsec;
} else {
res->tv_sec = end->tv_sec - begin->tv_sec;
res->tv_nsec = end->tv_nsec - begin->tv_nsec;
}
if (end->tv_nsec < begin->tv_nsec) {
res->tv_sec = end->tv_sec - begin->tv_sec - 1;
res->tv_nsec = end->tv_nsec + 1000000000 - begin->tv_nsec;
} else {
res->tv_sec = end->tv_sec - begin->tv_sec;
res->tv_nsec = end->tv_nsec - begin->tv_nsec;
}
}

View File

@ -17,371 +17,352 @@
#include "trie.h"
#define DISTANCE_EDIT 1
#define DISTANCE_INS 1
#define DISTANCE_DEL 1
#define DISTANCE_INS 1
#define DISTANCE_DEL 1
struct trienode {
char id;
char eow;
int depth;
void *data;
struct trie *trie;
struct trienode *parent;
struct trienode *subnodes[255];
char id;
char eow;
int depth;
void *data;
struct trie *trie;
struct trienode *parent;
struct trienode *subnodes[255];
};
struct trie {
struct trienode root;
int nodecnt;
size_t len;
struct trienode root;
int nodecnt;
size_t len;
};
trie_t *
trie_new ()
trie_new()
{
trie_t *trie = NULL;
trie_t *trie = NULL;
trie = GF_CALLOC (1, sizeof (*trie), gf_common_mt_trie_trie);
if (!trie)
return NULL;
trie = GF_CALLOC(1, sizeof(*trie), gf_common_mt_trie_trie);
if (!trie)
return NULL;
trie->root.trie = trie;
trie->root.trie = trie;
return trie;
return trie;
}
static trienode_t *
trie_subnode (trienode_t *node, int id)
trie_subnode(trienode_t *node, int id)
{
trienode_t *subnode = NULL;
trienode_t *subnode = NULL;
subnode = node->subnodes[id];
if (!subnode) {
subnode = GF_CALLOC (1, sizeof (*subnode),
gf_common_mt_trie_node);
if (!subnode)
return NULL;
subnode = node->subnodes[id];
if (!subnode) {
subnode = GF_CALLOC(1, sizeof(*subnode), gf_common_mt_trie_node);
if (!subnode)
return NULL;
subnode->id = id;
subnode->depth = node->depth + 1;
node->subnodes[id] = subnode;
subnode->parent = node;
subnode->trie = node->trie;
node->trie->nodecnt++;
}
subnode->id = id;
subnode->depth = node->depth + 1;
node->subnodes[id] = subnode;
subnode->parent = node;
subnode->trie = node->trie;
node->trie->nodecnt++;
}
return subnode;
return subnode;
}
int
trie_add (trie_t *trie, const char *dword)
trie_add(trie_t *trie, const char *dword)
{
trienode_t *node = NULL;
int i = 0;
char id = 0;
trienode_t *subnode = NULL;
trienode_t *node = NULL;
int i = 0;
char id = 0;
trienode_t *subnode = NULL;
node = &trie->root;
node = &trie->root;
for (i = 0; i < strlen (dword); i++) {
id = dword[i];
for (i = 0; i < strlen(dword); i++) {
id = dword[i];
subnode = trie_subnode (node, id);
if (!subnode)
return -1;
node = subnode;
}
subnode = trie_subnode(node, id);
if (!subnode)
return -1;
node = subnode;
}
node->eow = 1;
node->eow = 1;
return 0;
return 0;
}
static void
trienode_free (trienode_t *node)
trienode_free(trienode_t *node)
{
trienode_t *trav = NULL;
int i = 0;
trienode_t *trav = NULL;
int i = 0;
for (i = 0; i < 255; i++) {
trav = node->subnodes[i];
for (i = 0; i < 255; i++) {
trav = node->subnodes[i];
if (trav)
trienode_free (trav);
}
if (trav)
trienode_free(trav);
}
GF_FREE (node->data);
GF_FREE (node);
GF_FREE(node->data);
GF_FREE(node);
}
void
trie_destroy (trie_t *trie)
trie_destroy(trie_t *trie)
{
trienode_free ((trienode_t *)trie);
trienode_free((trienode_t *)trie);
}
void
trie_destroy_bynode (trienode_t *node)
trie_destroy_bynode(trienode_t *node)
{
trie_destroy (node->trie);
trie_destroy(node->trie);
}
static int
trienode_walk (trienode_t *node, int (*fn)(trienode_t *node, void *data),
void *data, int eowonly)
trienode_walk(trienode_t *node, int (*fn)(trienode_t *node, void *data),
void *data, int eowonly)
{
trienode_t *trav = NULL;
int i = 0;
int cret = 0;
int ret = 0;
trienode_t *trav = NULL;
int i = 0;
int cret = 0;
int ret = 0;
if (!eowonly || node->eow)
ret = fn (node, data);
if (!eowonly || node->eow)
ret = fn(node, data);
if (ret)
goto out;
if (ret)
goto out;
for (i = 0; i < 255; i++) {
trav = node->subnodes[i];
if (!trav)
continue;
for (i = 0; i < 255; i++) {
trav = node->subnodes[i];
if (!trav)
continue;
cret = trienode_walk (trav, fn, data, eowonly);
if (cret < 0) {
ret = cret;
goto out;
}
ret += cret;
cret = trienode_walk(trav, fn, data, eowonly);
if (cret < 0) {
ret = cret;
goto out;
}
ret += cret;
}
out:
return ret;
return ret;
}
static int
trie_walk (trie_t *trie, int (*fn)(trienode_t *node, void *data),
void *data, int eowonly)
trie_walk(trie_t *trie, int (*fn)(trienode_t *node, void *data), void *data,
int eowonly)
{
return trienode_walk (&trie->root, fn, data, eowonly);
return trienode_walk(&trie->root, fn, data, eowonly);
}
static void
print_node (trienode_t *node, char **buf)
print_node(trienode_t *node, char **buf)
{
if (!node->parent)
return;
if (!node->parent)
return;
if (node->parent) {
print_node (node->parent, buf);
*(*buf)++ = node->id;
}
if (node->parent) {
print_node(node->parent, buf);
*(*buf)++ = node->id;
}
}
int
trienode_get_word (trienode_t *node, char **bufp)
trienode_get_word(trienode_t *node, char **bufp)
{
char *buf = NULL;
char *buf = NULL;
buf = GF_CALLOC (1, node->depth + 1, gf_common_mt_trie_buf);
if (!buf)
return -1;
*bufp = buf;
buf = GF_CALLOC(1, node->depth + 1, gf_common_mt_trie_buf);
if (!buf)
return -1;
*bufp = buf;
print_node (node, &buf);
print_node(node, &buf);
return 0;
return 0;
}
static int
calc_dist (trienode_t *node, void *data)
calc_dist(trienode_t *node, void *data)
{
const char *word = NULL;
int i = 0;
int *row = NULL;
int *uprow = NULL;
int distu = 0;
int distl = 0;
int distul = 0;
const char *word = NULL;
int i = 0;
int *row = NULL;
int *uprow = NULL;
int distu = 0;
int distl = 0;
int distul = 0;
word = data;
word = data;
node->data = GF_CALLOC (node->trie->len, sizeof (int),
gf_common_mt_trie_data);
if (!node->data)
return -1;
row = node->data;
node->data = GF_CALLOC(node->trie->len, sizeof(int),
gf_common_mt_trie_data);
if (!node->data)
return -1;
row = node->data;
if (!node->parent) {
for (i = 0; i < node->trie->len; i++)
row[i] = i+1;
return 0;
}
uprow = node->parent->data;
distu = node->depth; /* up node */
distul = node->parent->depth; /* up-left node */
for (i = 0; i < node->trie->len; i++) {
distl = uprow[i]; /* left node */
if (word[i] == node->id)
row[i] = distul;
else
row[i] = min ((distul + DISTANCE_EDIT),
min ((distu + DISTANCE_DEL),
(distl + DISTANCE_INS)));
distu = row[i];
distul = distl;
}
if (!node->parent) {
for (i = 0; i < node->trie->len; i++)
row[i] = i + 1;
return 0;
}
}
uprow = node->parent->data;
distu = node->depth; /* up node */
distul = node->parent->depth; /* up-left node */
for (i = 0; i < node->trie->len; i++) {
distl = uprow[i]; /* left node */
if (word[i] == node->id)
row[i] = distul;
else
row[i] = min((distul + DISTANCE_EDIT),
min((distu + DISTANCE_DEL), (distl + DISTANCE_INS)));
distu = row[i];
distul = distl;
}
return 0;
}
int
trienode_get_dist (trienode_t *node)
trienode_get_dist(trienode_t *node)
{
int *row = NULL;
int *row = NULL;
row = node->data;
row = node->data;
return row[node->trie->len - 1];
return row[node->trie->len - 1];
}
struct trienodevec_w {
struct trienodevec *vec;
const char *word;
struct trienodevec *vec;
const char *word;
};
static void
trienodevec_clear (struct trienodevec *nodevec)
trienodevec_clear(struct trienodevec *nodevec)
{
memset(nodevec->nodes, 0, sizeof (*nodevec->nodes) * nodevec->cnt);
memset(nodevec->nodes, 0, sizeof(*nodevec->nodes) * nodevec->cnt);
}
static int
collect_closest (trienode_t *node, void *data)
collect_closest(trienode_t *node, void *data)
{
struct trienodevec_w *nodevec_w = NULL;
struct trienodevec *nodevec = NULL;
int dist = 0;
int i = 0;
struct trienodevec_w *nodevec_w = NULL;
struct trienodevec *nodevec = NULL;
int dist = 0;
int i = 0;
nodevec_w = data;
nodevec = nodevec_w->vec;
nodevec_w = data;
nodevec = nodevec_w->vec;
if (calc_dist (node, (void *)nodevec_w->word))
return -1;
if (calc_dist(node, (void *)nodevec_w->word))
return -1;
if (!node->eow || !nodevec->cnt)
return 0;
if (!node->eow || !nodevec->cnt)
return 0;
dist = trienode_get_dist (node);
dist = trienode_get_dist(node);
/*
* I thought that when descending further after some dictionary word dw,
* if we see that child's distance is bigger than it was for dw, then we
* can prune this branch, as it can contain only worse nodes.
*
* This conjecture fails, see eg:
*
* d("AB", "B") = 1;
* d("AB", "BA") = 2;
* d("AB", "BAB") = 1;
*
* -- if both "B" and "BAB" are in dict., then pruning at "BA" * would
* miss "BAB".
*
* (example courtesy of Richard Bann <richardbann at gmail.com>)
/*
* I thought that when descending further after some dictionary word dw,
* if we see that child's distance is bigger than it was for dw, then we
* can prune this branch, as it can contain only worse nodes.
*
* This conjecture fails, see eg:
*
* d("AB", "B") = 1;
* d("AB", "BA") = 2;
* d("AB", "BAB") = 1;
*
* -- if both "B" and "BAB" are in dict., then pruning at "BA" * would
* miss "BAB".
*
* (example courtesy of Richard Bann <richardbann at gmail.com>)
if (node->parent->eow && dist > trienode_get_dist (node->parent))
return 1;
if (node->parent->eow && dist > trienode_get_dist (node->parent))
return 1;
*/
*/
if (nodevec->nodes[0] &&
dist < trienode_get_dist (nodevec->nodes[0])) {
/* improving over the findings so far */
trienodevec_clear (nodevec);
nodevec->nodes[0] = node;
} else if (!nodevec->nodes[0] ||
dist == trienode_get_dist (nodevec->nodes[0])) {
/* as good as the best so far, add if there is free space */
for (i = 0; i < nodevec->cnt; i++) {
if (!nodevec->nodes[i]) {
nodevec->nodes[i] = node;
break;
}
}
if (nodevec->nodes[0] && dist < trienode_get_dist(nodevec->nodes[0])) {
/* improving over the findings so far */
trienodevec_clear(nodevec);
nodevec->nodes[0] = node;
} else if (!nodevec->nodes[0] ||
dist == trienode_get_dist(nodevec->nodes[0])) {
/* as good as the best so far, add if there is free space */
for (i = 0; i < nodevec->cnt; i++) {
if (!nodevec->nodes[i]) {
nodevec->nodes[i] = node;
break;
}
}
}
return 0;
return 0;
}
int
trie_measure (trie_t *trie, const char *word, trienode_t **nodes,
int nodecnt)
trie_measure(trie_t *trie, const char *word, trienode_t **nodes, int nodecnt)
{
struct trienodevec nodevec = {0,};
struct trienodevec nodevec = {
0,
};
nodevec.nodes = nodes;
nodevec.cnt = nodecnt;
nodevec.nodes = nodes;
nodevec.cnt = nodecnt;
return trie_measure_vec (trie, word, &nodevec);
return trie_measure_vec(trie, word, &nodevec);
}
int
trie_measure_vec (trie_t *trie, const char *word, struct trienodevec *nodevec)
trie_measure_vec(trie_t *trie, const char *word, struct trienodevec *nodevec)
{
struct trienodevec_w nodevec_w = {0,};
int ret = 0;
struct trienodevec_w nodevec_w = {
0,
};
int ret = 0;
trie->len = strlen (word);
trie->len = strlen(word);
trienodevec_clear (nodevec);
nodevec_w.vec = nodevec;
nodevec_w.word = word;
trienodevec_clear(nodevec);
nodevec_w.vec = nodevec;
nodevec_w.word = word;
ret = trie_walk (trie, collect_closest, &nodevec_w, 0);
if (ret > 0)
ret = 0;
ret = trie_walk(trie, collect_closest, &nodevec_w, 0);
if (ret > 0)
ret = 0;
return ret;
return ret;
}
static int
trienode_reset (trienode_t *node, void *data)
trienode_reset(trienode_t *node, void *data)
{
GF_FREE (node->data);
GF_FREE(node->data);
return 0;
return 0;
}
void
trie_reset_search (trie_t *trie)
trie_reset_search(trie_t *trie)
{
trie->len = 0;
trie->len = 0;
trie_walk (trie, trienode_reset, NULL, 0);
trie_walk(trie, trienode_reset, NULL, 0);
}

View File

@ -18,7 +18,8 @@
#include <cmocka.h>
xlator_t **__glusterfs_this_location ()
xlator_t **
__glusterfs_this_location()
{
return ((xlator_t **)(uintptr_t)mock());
}

View File

@ -18,33 +18,35 @@
#include <cmocka.h>
int _gf_log (const char *domain, const char *file,
const char *function, int32_t line, gf_loglevel_t level,
const char *fmt, ...)
int
_gf_log(const char *domain, const char *file, const char *function,
int32_t line, gf_loglevel_t level, const char *fmt, ...)
{
return 0;
}
int _gf_log_callingfn (const char *domain, const char *file,
const char *function, int32_t line, gf_loglevel_t level,
const char *fmt, ...)
int
_gf_log_callingfn(const char *domain, const char *file, const char *function,
int32_t line, gf_loglevel_t level, const char *fmt, ...)
{
return 0;
}
int _gf_log_nomem (const char *domain, const char *file,
const char *function, int line, gf_loglevel_t level,
size_t size)
int
_gf_log_nomem(const char *domain, const char *file, const char *function,
int line, gf_loglevel_t level, size_t size)
{
return 0;
}
int _gf_msg_nomem (const char *domain, const char *file,
const char *function, int line, gf_loglevel_t level,
size_t size)
int
_gf_msg_nomem(const char *domain, const char *file, const char *function,
int line, gf_loglevel_t level, size_t size)
{
return 0;
return 0;
}
void
gf_log_globals_init (void *data, gf_loglevel_t level) {}
gf_log_globals_init(void *data, gf_loglevel_t level)
{
}

View File

@ -21,10 +21,10 @@
#include <cmocka.h>
#ifndef assert_ptr_equal
#define assert_ptr_equal(a, b) \
_assert_int_equal(cast_ptr_to_largest_integral_type(a), \
cast_ptr_to_largest_integral_type(b), \
__FILE__, __LINE__)
#define assert_ptr_equal(a, b) \
_assert_int_equal(cast_ptr_to_largest_integral_type(a), \
cast_ptr_to_largest_integral_type(b), __FILE__, \
__LINE__)
#endif
/*
@ -42,8 +42,8 @@ typedef struct __attribute__((packed)) {
* Prototypes to private functions
*/
int
gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr, size_t size,
uint32_t type, const char *typestr);
gf_mem_set_acct_info(xlator_t *xl, char **alloc_ptr, size_t size, uint32_t type,
const char *typestr);
/*
* Helper functions
@ -59,16 +59,16 @@ helper_xlator_init(uint32_t num_types)
xl = test_calloc(1, sizeof(xlator_t));
assert_non_null(xl);
xl->mem_acct->num_types = num_types;
xl->mem_acct = test_calloc (sizeof(struct mem_acct)
+ sizeof(struct mem_acct_rec) * num_types);
xl->mem_acct = test_calloc(sizeof(struct mem_acct) +
sizeof(struct mem_acct_rec) * num_types);
assert_non_null(xl->mem_acct);
xl->ctx = test_calloc(1, sizeof(glusterfs_ctx_t));
assert_non_null(xl->ctx);
for (i = 0; i < num_types; i++) {
ret = LOCK_INIT(&(xl->mem_acct->rec[i].lock));
assert_int_equal(ret, 0);
ret = LOCK_INIT(&(xl->mem_acct->rec[i].lock));
assert_int_equal(ret, 0);
}
ENSURE(num_types == xl->mem_acct->num_types);
@ -83,8 +83,8 @@ helper_xlator_destroy(xlator_t *xl)
int i, ret;
for (i = 0; i < xl->mem_acct->num_types; i++) {
ret = LOCK_DESTROY(&(xl->mem_acct->rec[i].lock));
assert_int_equal(ret, 0);
ret = LOCK_DESTROY(&(xl->mem_acct->rec[i].lock));
assert_int_equal(ret, 0);
}
free(xl->mem_acct->rec);
@ -94,20 +94,16 @@ helper_xlator_destroy(xlator_t *xl)
}
static void
helper_check_memory_headers( char *mem,
xlator_t *xl,
size_t size,
uint32_t type)
helper_check_memory_headers(char *mem, xlator_t *xl, size_t size, uint32_t type)
{
mem_header_t *p;
p = (mem_header_t *)mem,
assert_int_equal(p->type, type);
p = (mem_header_t *)mem, assert_int_equal(p->type, type);
assert_int_equal(p->size, size);
assert_true(p->xl == xl);
assert_int_equal(p->header_magic, GF_MEM_HEADER_MAGIC);
assert_true(*(uint32_t *)(mem+sizeof(mem_header_t)+size) == GF_MEM_TRAILER_MAGIC);
assert_true(*(uint32_t *)(mem + sizeof(mem_header_t) + size) ==
GF_MEM_TRAILER_MAGIC);
}
/*
@ -116,7 +112,7 @@ helper_check_memory_headers( char *mem,
static void
test_gf_mem_acct_enable_set(void **state)
{
(void) state;
(void)state;
glusterfs_ctx_t test_ctx;
expect_assert_failure(gf_mem_acct_enable_set(NULL));
@ -143,14 +139,16 @@ test_gf_mem_set_acct_info_asserts(void **state)
size = 8196;
type = 0;
// Check xl is NULL
expect_assert_failure(gf_mem_set_acct_info(NULL, &alloc_ptr, size, type, ""));
expect_assert_failure(
gf_mem_set_acct_info(NULL, &alloc_ptr, size, type, ""));
// Check xl->mem_acct = NULL
expect_assert_failure(gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, ""));
expect_assert_failure(
gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, ""));
// Check type <= xl->mem_acct->num_types
type = 100;
expect_assert_failure(gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, ""));
expect_assert_failure(
gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, ""));
// Check alloc is NULL
assert_int_equal(-1, gf_mem_set_acct_info(&xltest, NULL, size, type, ""));
@ -189,7 +187,7 @@ test_gf_mem_set_acct_info_memory(void **state)
alloc_ptr = temp_ptr;
gf_mem_set_acct_info(xl, &alloc_ptr, size, type, typestr);
//Check values
// Check values
assert_ptr_equal(typestr, xl->mem_acct->rec[type].typestr);
assert_int_equal(xl->mem_acct->rec[type].size, size);
assert_int_equal(xl->mem_acct->rec[type].num_allocs, 1);
@ -420,10 +418,10 @@ test_gf_realloc_mem_acct_enabled(void **state)
// not to the realloc + the malloc.
// Is this a bug?
//
assert_int_equal(xl->mem_acct->rec[type].size, size+1024);
assert_int_equal(xl->mem_acct->rec[type].size, size + 1024);
assert_int_equal(xl->mem_acct->rec[type].num_allocs, 2);
assert_int_equal(xl->mem_acct->rec[type].total_allocs, 2);
assert_int_equal(xl->mem_acct->rec[type].max_size, size+1024);
assert_int_equal(xl->mem_acct->rec[type].max_size, size + 1024);
assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 2);
// Check memory
@ -465,7 +463,9 @@ test_gf_realloc_ptr(void **state)
helper_xlator_destroy(xl);
}
int main(void) {
int
main(void)
{
const struct CMUnitTest libglusterfs_mem_pool_tests[] = {
cmocka_unit_test(test_gf_mem_acct_enable_set),
cmocka_unit_test(test_gf_mem_set_acct_info_asserts),

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,6 @@
cases as published by the Free Software Foundation.
*/
#include "rpcsvc.h"
#include "list.h"
#include "dict.h"
@ -21,386 +19,369 @@
/* V1 */
ssize_t
xdr_to_glusterfs_auth (char *buf, struct auth_glusterfs_parms *req)
xdr_to_glusterfs_auth(char *buf, struct auth_glusterfs_parms *req)
{
XDR xdr;
ssize_t ret = -1;
XDR xdr;
ssize_t ret = -1;
if ((!buf) || (!req))
return -1;
if ((!buf) || (!req))
return -1;
xdrmem_create (&xdr, buf, sizeof (struct auth_glusterfs_parms),
XDR_DECODE);
if (!xdr_auth_glusterfs_parms (&xdr, req)) {
gf_log ("", GF_LOG_WARNING,
"failed to decode glusterfs parameters");
ret = -1;
goto ret;
}
xdrmem_create(&xdr, buf, sizeof(struct auth_glusterfs_parms), XDR_DECODE);
if (!xdr_auth_glusterfs_parms(&xdr, req)) {
gf_log("", GF_LOG_WARNING, "failed to decode glusterfs parameters");
ret = -1;
goto ret;
}
ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
ret:
return ret;
return ret;
}
int
auth_glusterfs_request_init (rpcsvc_request_t *req, void *priv)
auth_glusterfs_request_init(rpcsvc_request_t *req, void *priv)
{
return 0;
return 0;
}
int auth_glusterfs_authenticate (rpcsvc_request_t *req, void *priv)
int
auth_glusterfs_authenticate(rpcsvc_request_t *req, void *priv)
{
struct auth_glusterfs_parms au = {0,};
struct auth_glusterfs_parms au = {
0,
};
int ret = RPCSVC_AUTH_REJECT;
int j = 0;
int i = 0;
int gidcount = 0;
int ret = RPCSVC_AUTH_REJECT;
int j = 0;
int i = 0;
int gidcount = 0;
if (!req)
return ret;
ret = xdr_to_glusterfs_auth (req->cred.authdata, &au);
if (ret == -1) {
gf_log ("", GF_LOG_WARNING,
"failed to decode glusterfs credentials");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
req->pid = au.pid;
req->uid = au.uid;
req->gid = au.gid;
req->lk_owner.len = 8;
{
for (i = 0; i < req->lk_owner.len; i++, j += 8)
req->lk_owner.data[i] = (char)((au.lk_owner >> j) & 0xff);
}
req->auxgidcount = au.ngrps;
if (req->auxgidcount > 16) {
gf_log ("", GF_LOG_WARNING,
"more than 16 aux gids found, failing authentication");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
if (req->auxgidcount > SMALL_GROUP_COUNT) {
req->auxgidlarge = GF_CALLOC(req->auxgidcount,
sizeof(req->auxgids[0]),
gf_common_mt_auxgids);
req->auxgids = req->auxgidlarge;
} else {
req->auxgids = req->auxgidsmall;
}
if (!req->auxgids) {
gf_log ("auth-glusterfs", GF_LOG_WARNING,
"cannot allocate gid list");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
for (gidcount = 0; gidcount < au.ngrps; ++gidcount)
req->auxgids[gidcount] = au.groups[gidcount];
gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth Info: pid: %u, uid: %d"
", gid: %d, owner: %s",
req->pid, req->uid, req->gid, lkowner_utoa (&req->lk_owner));
ret = RPCSVC_AUTH_ACCEPT;
err:
if (!req)
return ret;
ret = xdr_to_glusterfs_auth(req->cred.authdata, &au);
if (ret == -1) {
gf_log("", GF_LOG_WARNING, "failed to decode glusterfs credentials");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
req->pid = au.pid;
req->uid = au.uid;
req->gid = au.gid;
req->lk_owner.len = 8;
{
for (i = 0; i < req->lk_owner.len; i++, j += 8)
req->lk_owner.data[i] = (char)((au.lk_owner >> j) & 0xff);
}
req->auxgidcount = au.ngrps;
if (req->auxgidcount > 16) {
gf_log("", GF_LOG_WARNING,
"more than 16 aux gids found, failing authentication");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
if (req->auxgidcount > SMALL_GROUP_COUNT) {
req->auxgidlarge = GF_CALLOC(req->auxgidcount, sizeof(req->auxgids[0]),
gf_common_mt_auxgids);
req->auxgids = req->auxgidlarge;
} else {
req->auxgids = req->auxgidsmall;
}
if (!req->auxgids) {
gf_log("auth-glusterfs", GF_LOG_WARNING, "cannot allocate gid list");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
for (gidcount = 0; gidcount < au.ngrps; ++gidcount)
req->auxgids[gidcount] = au.groups[gidcount];
gf_log(GF_RPCSVC, GF_LOG_TRACE,
"Auth Info: pid: %u, uid: %d"
", gid: %d, owner: %s",
req->pid, req->uid, req->gid, lkowner_utoa(&req->lk_owner));
ret = RPCSVC_AUTH_ACCEPT;
err:
return ret;
}
rpcsvc_auth_ops_t auth_glusterfs_ops = {
.transport_init = NULL,
.request_init = auth_glusterfs_request_init,
.authenticate = auth_glusterfs_authenticate
};
rpcsvc_auth_t rpcsvc_auth_glusterfs = {
.authname = "AUTH_GLUSTERFS",
.authnum = AUTH_GLUSTERFS,
.authops = &auth_glusterfs_ops,
.authprivate = NULL
};
.transport_init = NULL,
.request_init = auth_glusterfs_request_init,
.authenticate = auth_glusterfs_authenticate};
rpcsvc_auth_t rpcsvc_auth_glusterfs = {.authname = "AUTH_GLUSTERFS",
.authnum = AUTH_GLUSTERFS,
.authops = &auth_glusterfs_ops,
.authprivate = NULL};
rpcsvc_auth_t *
rpcsvc_auth_glusterfs_init (rpcsvc_t *svc, dict_t *options)
rpcsvc_auth_glusterfs_init(rpcsvc_t *svc, dict_t *options)
{
return &rpcsvc_auth_glusterfs;
return &rpcsvc_auth_glusterfs;
}
/* V2 */
ssize_t
xdr_to_glusterfs_auth_v2 (char *buf, struct auth_glusterfs_parms_v2 *req)
xdr_to_glusterfs_auth_v2(char *buf, struct auth_glusterfs_parms_v2 *req)
{
XDR xdr;
ssize_t ret = -1;
XDR xdr;
ssize_t ret = -1;
if ((!buf) || (!req))
return -1;
if ((!buf) || (!req))
return -1;
xdrmem_create (&xdr, buf, GF_MAX_AUTH_BYTES, XDR_DECODE);
if (!xdr_auth_glusterfs_parms_v2 (&xdr, req)) {
gf_log ("", GF_LOG_WARNING,
"failed to decode glusterfs v2 parameters");
ret = -1;
goto ret;
}
xdrmem_create(&xdr, buf, GF_MAX_AUTH_BYTES, XDR_DECODE);
if (!xdr_auth_glusterfs_parms_v2(&xdr, req)) {
gf_log("", GF_LOG_WARNING, "failed to decode glusterfs v2 parameters");
ret = -1;
goto ret;
}
ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
ret:
return ret;
return ret;
}
int
auth_glusterfs_v2_request_init (rpcsvc_request_t *req, void *priv)
auth_glusterfs_v2_request_init(rpcsvc_request_t *req, void *priv)
{
return 0;
return 0;
}
int auth_glusterfs_v2_authenticate (rpcsvc_request_t *req, void *priv)
int
auth_glusterfs_v2_authenticate(rpcsvc_request_t *req, void *priv)
{
struct auth_glusterfs_parms_v2 au = {0,};
int ret = RPCSVC_AUTH_REJECT;
int i = 0;
int max_groups = 0;
int max_lk_owner_len = 0;
if (!req)
return ret;
ret = xdr_to_glusterfs_auth_v2 (req->cred.authdata, &au);
if (ret == -1) {
gf_log ("", GF_LOG_WARNING,
"failed to decode glusterfs credentials");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
req->pid = au.pid;
req->uid = au.uid;
req->gid = au.gid;
req->lk_owner.len = au.lk_owner.lk_owner_len;
req->auxgidcount = au.groups.groups_len;
/* the number of groups and size of lk_owner depend on each other */
max_groups = GF_AUTH_GLUSTERFS_MAX_GROUPS (req->lk_owner.len,
AUTH_GLUSTERFS_v2);
max_lk_owner_len = GF_AUTH_GLUSTERFS_MAX_LKOWNER (req->auxgidcount,
AUTH_GLUSTERFS_v2);
if (req->auxgidcount > max_groups) {
gf_log ("", GF_LOG_WARNING,
"more than max aux gids found (%d) , truncating it "
"to %d and continuing", au.groups.groups_len,
max_groups);
req->auxgidcount = max_groups;
}
if (req->lk_owner.len > max_lk_owner_len) {
gf_log ("", GF_LOG_WARNING,
"lkowner field to big (%d), depends on the number of "
"groups (%d), failing authentication",
req->lk_owner.len, req->auxgidcount);
ret = RPCSVC_AUTH_REJECT;
goto err;
}
if (req->auxgidcount > SMALL_GROUP_COUNT) {
req->auxgidlarge = GF_CALLOC(req->auxgidcount,
sizeof(req->auxgids[0]),
gf_common_mt_auxgids);
req->auxgids = req->auxgidlarge;
} else {
req->auxgids = req->auxgidsmall;
}
if (!req->auxgids) {
gf_log ("auth-glusterfs-v2", GF_LOG_WARNING,
"cannot allocate gid list");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
for (i = 0; i < req->auxgidcount; ++i)
req->auxgids[i] = au.groups.groups_val[i];
for (i = 0; i < au.lk_owner.lk_owner_len; ++i)
req->lk_owner.data[i] = au.lk_owner.lk_owner_val[i];
gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth Info: pid: %u, uid: %d"
", gid: %d, owner: %s",
req->pid, req->uid, req->gid, lkowner_utoa (&req->lk_owner));
ret = RPCSVC_AUTH_ACCEPT;
err:
/* TODO: instead use alloca() for these variables */
free (au.groups.groups_val);
free (au.lk_owner.lk_owner_val);
struct auth_glusterfs_parms_v2 au = {
0,
};
int ret = RPCSVC_AUTH_REJECT;
int i = 0;
int max_groups = 0;
int max_lk_owner_len = 0;
if (!req)
return ret;
ret = xdr_to_glusterfs_auth_v2(req->cred.authdata, &au);
if (ret == -1) {
gf_log("", GF_LOG_WARNING, "failed to decode glusterfs credentials");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
req->pid = au.pid;
req->uid = au.uid;
req->gid = au.gid;
req->lk_owner.len = au.lk_owner.lk_owner_len;
req->auxgidcount = au.groups.groups_len;
/* the number of groups and size of lk_owner depend on each other */
max_groups = GF_AUTH_GLUSTERFS_MAX_GROUPS(req->lk_owner.len,
AUTH_GLUSTERFS_v2);
max_lk_owner_len = GF_AUTH_GLUSTERFS_MAX_LKOWNER(req->auxgidcount,
AUTH_GLUSTERFS_v2);
if (req->auxgidcount > max_groups) {
gf_log("", GF_LOG_WARNING,
"more than max aux gids found (%d) , truncating it "
"to %d and continuing",
au.groups.groups_len, max_groups);
req->auxgidcount = max_groups;
}
if (req->lk_owner.len > max_lk_owner_len) {
gf_log("", GF_LOG_WARNING,
"lkowner field to big (%d), depends on the number of "
"groups (%d), failing authentication",
req->lk_owner.len, req->auxgidcount);
ret = RPCSVC_AUTH_REJECT;
goto err;
}
if (req->auxgidcount > SMALL_GROUP_COUNT) {
req->auxgidlarge = GF_CALLOC(req->auxgidcount, sizeof(req->auxgids[0]),
gf_common_mt_auxgids);
req->auxgids = req->auxgidlarge;
} else {
req->auxgids = req->auxgidsmall;
}
if (!req->auxgids) {
gf_log("auth-glusterfs-v2", GF_LOG_WARNING, "cannot allocate gid list");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
for (i = 0; i < req->auxgidcount; ++i)
req->auxgids[i] = au.groups.groups_val[i];
for (i = 0; i < au.lk_owner.lk_owner_len; ++i)
req->lk_owner.data[i] = au.lk_owner.lk_owner_val[i];
gf_log(GF_RPCSVC, GF_LOG_TRACE,
"Auth Info: pid: %u, uid: %d"
", gid: %d, owner: %s",
req->pid, req->uid, req->gid, lkowner_utoa(&req->lk_owner));
ret = RPCSVC_AUTH_ACCEPT;
err:
/* TODO: instead use alloca() for these variables */
free(au.groups.groups_val);
free(au.lk_owner.lk_owner_val);
return ret;
}
rpcsvc_auth_ops_t auth_glusterfs_ops_v2 = {
.transport_init = NULL,
.request_init = auth_glusterfs_v2_request_init,
.authenticate = auth_glusterfs_v2_authenticate
};
rpcsvc_auth_t rpcsvc_auth_glusterfs_v2 = {
.authname = "AUTH_GLUSTERFS-v2",
.authnum = AUTH_GLUSTERFS_v2,
.authops = &auth_glusterfs_ops_v2,
.authprivate = NULL
};
.transport_init = NULL,
.request_init = auth_glusterfs_v2_request_init,
.authenticate = auth_glusterfs_v2_authenticate};
rpcsvc_auth_t rpcsvc_auth_glusterfs_v2 = {.authname = "AUTH_GLUSTERFS-v2",
.authnum = AUTH_GLUSTERFS_v2,
.authops = &auth_glusterfs_ops_v2,
.authprivate = NULL};
rpcsvc_auth_t *
rpcsvc_auth_glusterfs_v2_init (rpcsvc_t *svc, dict_t *options)
rpcsvc_auth_glusterfs_v2_init(rpcsvc_t *svc, dict_t *options)
{
return &rpcsvc_auth_glusterfs_v2;
return &rpcsvc_auth_glusterfs_v2;
}
/* V3 */
ssize_t
xdr_to_glusterfs_auth_v3 (char *buf, struct auth_glusterfs_params_v3 *req)
xdr_to_glusterfs_auth_v3(char *buf, struct auth_glusterfs_params_v3 *req)
{
XDR xdr;
ssize_t ret = -1;
XDR xdr;
ssize_t ret = -1;
if ((!buf) || (!req))
return -1;
if ((!buf) || (!req))
return -1;
xdrmem_create (&xdr, buf, GF_MAX_AUTH_BYTES, XDR_DECODE);
if (!xdr_auth_glusterfs_params_v3 (&xdr, req)) {
gf_log ("", GF_LOG_WARNING,
"failed to decode glusterfs v3 parameters");
ret = -1;
goto ret;
}
xdrmem_create(&xdr, buf, GF_MAX_AUTH_BYTES, XDR_DECODE);
if (!xdr_auth_glusterfs_params_v3(&xdr, req)) {
gf_log("", GF_LOG_WARNING, "failed to decode glusterfs v3 parameters");
ret = -1;
goto ret;
}
ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
ret:
return ret;
return ret;
}
int
auth_glusterfs_v3_request_init (rpcsvc_request_t *req, void *priv)
auth_glusterfs_v3_request_init(rpcsvc_request_t *req, void *priv)
{
return 0;
return 0;
}
int auth_glusterfs_v3_authenticate (rpcsvc_request_t *req, void *priv)
int
auth_glusterfs_v3_authenticate(rpcsvc_request_t *req, void *priv)
{
struct auth_glusterfs_params_v3 au = {0,};
int ret = RPCSVC_AUTH_REJECT;
int i = 0;
int max_groups = 0;
int max_lk_owner_len = 0;
if (!req)
return ret;
ret = xdr_to_glusterfs_auth_v3 (req->cred.authdata, &au);
if (ret == -1) {
gf_log ("", GF_LOG_WARNING,
"failed to decode glusterfs credentials");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
req->pid = au.pid;
req->uid = au.uid;
req->gid = au.gid;
req->lk_owner.len = au.lk_owner.lk_owner_len;
req->auxgidcount = au.groups.groups_len;
/* the number of groups and size of lk_owner depend on each other */
max_groups = GF_AUTH_GLUSTERFS_MAX_GROUPS (req->lk_owner.len,
AUTH_GLUSTERFS_v3);
max_lk_owner_len = GF_AUTH_GLUSTERFS_MAX_LKOWNER (req->auxgidcount,
AUTH_GLUSTERFS_v3);
if (req->auxgidcount > max_groups) {
gf_log ("", GF_LOG_WARNING,
"more than max aux gids found (%d) , truncating it "
"to %d and continuing", au.groups.groups_len,
max_groups);
req->auxgidcount = max_groups;
}
if (req->lk_owner.len > max_lk_owner_len) {
gf_log ("", GF_LOG_WARNING,
"lkowner field to big (%d), depends on the number of "
"groups (%d), failing authentication",
req->lk_owner.len, req->auxgidcount);
ret = RPCSVC_AUTH_REJECT;
goto err;
}
if (req->auxgidcount > SMALL_GROUP_COUNT) {
req->auxgidlarge = GF_CALLOC(req->auxgidcount,
sizeof(req->auxgids[0]),
gf_common_mt_auxgids);
req->auxgids = req->auxgidlarge;
} else {
req->auxgids = req->auxgidsmall;
}
if (!req->auxgids) {
gf_log ("auth-glusterfs-v2", GF_LOG_WARNING,
"cannot allocate gid list");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
for (i = 0; i < req->auxgidcount; ++i)
req->auxgids[i] = au.groups.groups_val[i];
for (i = 0; i < au.lk_owner.lk_owner_len; ++i)
req->lk_owner.data[i] = au.lk_owner.lk_owner_val[i];
/* All new things, starting glusterfs-4.0.0 */
req->flags = au.flags;
req->ctime.tv_sec = au.ctime_sec;
req->ctime.tv_nsec = au.ctime_nsec;
gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth Info: pid: %u, uid: %d"
", gid: %d, owner: %s, flags: %d",
req->pid, req->uid, req->gid, lkowner_utoa (&req->lk_owner),
req->flags);
ret = RPCSVC_AUTH_ACCEPT;
err:
/* TODO: instead use alloca() for these variables */
free (au.groups.groups_val);
free (au.lk_owner.lk_owner_val);
struct auth_glusterfs_params_v3 au = {
0,
};
int ret = RPCSVC_AUTH_REJECT;
int i = 0;
int max_groups = 0;
int max_lk_owner_len = 0;
if (!req)
return ret;
ret = xdr_to_glusterfs_auth_v3(req->cred.authdata, &au);
if (ret == -1) {
gf_log("", GF_LOG_WARNING, "failed to decode glusterfs credentials");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
req->pid = au.pid;
req->uid = au.uid;
req->gid = au.gid;
req->lk_owner.len = au.lk_owner.lk_owner_len;
req->auxgidcount = au.groups.groups_len;
/* the number of groups and size of lk_owner depend on each other */
max_groups = GF_AUTH_GLUSTERFS_MAX_GROUPS(req->lk_owner.len,
AUTH_GLUSTERFS_v3);
max_lk_owner_len = GF_AUTH_GLUSTERFS_MAX_LKOWNER(req->auxgidcount,
AUTH_GLUSTERFS_v3);
if (req->auxgidcount > max_groups) {
gf_log("", GF_LOG_WARNING,
"more than max aux gids found (%d) , truncating it "
"to %d and continuing",
au.groups.groups_len, max_groups);
req->auxgidcount = max_groups;
}
if (req->lk_owner.len > max_lk_owner_len) {
gf_log("", GF_LOG_WARNING,
"lkowner field to big (%d), depends on the number of "
"groups (%d), failing authentication",
req->lk_owner.len, req->auxgidcount);
ret = RPCSVC_AUTH_REJECT;
goto err;
}
if (req->auxgidcount > SMALL_GROUP_COUNT) {
req->auxgidlarge = GF_CALLOC(req->auxgidcount, sizeof(req->auxgids[0]),
gf_common_mt_auxgids);
req->auxgids = req->auxgidlarge;
} else {
req->auxgids = req->auxgidsmall;
}
if (!req->auxgids) {
gf_log("auth-glusterfs-v2", GF_LOG_WARNING, "cannot allocate gid list");
ret = RPCSVC_AUTH_REJECT;
goto err;
}
for (i = 0; i < req->auxgidcount; ++i)
req->auxgids[i] = au.groups.groups_val[i];
for (i = 0; i < au.lk_owner.lk_owner_len; ++i)
req->lk_owner.data[i] = au.lk_owner.lk_owner_val[i];
/* All new things, starting glusterfs-4.0.0 */
req->flags = au.flags;
req->ctime.tv_sec = au.ctime_sec;
req->ctime.tv_nsec = au.ctime_nsec;
gf_log(GF_RPCSVC, GF_LOG_TRACE,
"Auth Info: pid: %u, uid: %d"
", gid: %d, owner: %s, flags: %d",
req->pid, req->uid, req->gid, lkowner_utoa(&req->lk_owner),
req->flags);
ret = RPCSVC_AUTH_ACCEPT;
err:
/* TODO: instead use alloca() for these variables */
free(au.groups.groups_val);
free(au.lk_owner.lk_owner_val);
return ret;
}
rpcsvc_auth_ops_t auth_glusterfs_ops_v3 = {
.transport_init = NULL,
.request_init = auth_glusterfs_v3_request_init,
.authenticate = auth_glusterfs_v3_authenticate
};
rpcsvc_auth_t rpcsvc_auth_glusterfs_v3 = {
.authname = "AUTH_GLUSTERFS-v3",
.authnum = AUTH_GLUSTERFS_v3,
.authops = &auth_glusterfs_ops_v3,
.authprivate = NULL
};
.transport_init = NULL,
.request_init = auth_glusterfs_v3_request_init,
.authenticate = auth_glusterfs_v3_authenticate};
rpcsvc_auth_t rpcsvc_auth_glusterfs_v3 = {.authname = "AUTH_GLUSTERFS-v3",
.authnum = AUTH_GLUSTERFS_v3,
.authops = &auth_glusterfs_ops_v3,
.authprivate = NULL};
rpcsvc_auth_t *
rpcsvc_auth_glusterfs_v3_init (rpcsvc_t *svc, dict_t *options)
rpcsvc_auth_glusterfs_v3_init(rpcsvc_t *svc, dict_t *options)
{
return &rpcsvc_auth_glusterfs_v3;
return &rpcsvc_auth_glusterfs_v3;
}

Some files were not shown because too many files have changed in this diff Show More