Skip to content
Permalink
1139b72d5e
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
321 lines (275 sloc) 8.21 KB
/*
* (C) 2003 Clemson University and The University of Chicago
*
* Changes by Acxiom Corporation to add support for nonblocking statfs
* Copyright © Acxiom Corporation, 2006.
*
* See COPYING in top-level directory.
*/
/** \file
* \ingroup mgmtint
*
* PVFS2 management interface routines for obtaining file system
* statistics (e.g. used and free space) from a list of servers.
*/
#include <string.h>
#include <assert.h>
#include "client-state-machine.h"
#include "pvfs2-debug.h"
#include "job.h"
#include "gossip.h"
#include "str-utils.h"
#include "pvfs2-mgmt.h"
#include "pint-cached-config.h"
#include "PINT-reqproto-encode.h"
extern job_context_id pint_client_sm_context;
static int statfs_list_comp_fn(
void *v_p, struct PVFS_server_resp *resp_p, int index);
%%
nested machine pvfs2_client_mgmt_statfs_list_nested_sm
{
state setup_msgpair
{
run mgmt_statfs_list_setup_msgpair;
success => xfer_msgpair;
default => cleanup;
}
state xfer_msgpair
{
jump pvfs2_msgpairarray_sm;
default => cleanup;
}
state cleanup
{
run mgmt_statfs_list_cleanup;
default => return;
}
}
machine pvfs2_client_mgmt_statfs_list_sm
{
state run_nested
{
jump pvfs2_client_mgmt_statfs_list_nested_sm;
default => parent_cleanup;
}
state parent_cleanup
{
run mgmt_statfs_list_parent_cleanup;
default => terminate;
}
}
%%
/** Initiate retrieval of file system statistics from a list of servers.
*/
PVFS_error PVFS_imgmt_statfs_list(
PVFS_fs_id fs_id,
PVFS_credentials *credentials,
struct PVFS_mgmt_server_stat *stat_array,
PVFS_BMI_addr_t *addr_array,
int count,
PVFS_error_details *details,
PVFS_mgmt_op_id *op_id,
PVFS_hint hints,
void *user_ptr)
{
PINT_smcb *smcb = NULL;
PINT_client_sm *sm_p = NULL;
int ret;
gossip_debug(GOSSIP_CLIENT_DEBUG,
"PVFS_imgmt_statfs_list entered\n");
if ((count < 1) || !stat_array || !addr_array)
{
return -PVFS_EINVAL;
}
PINT_smcb_alloc(&smcb, PVFS_MGMT_STATFS_LIST,
sizeof(struct PINT_client_sm),
client_op_state_get_machine,
client_state_machine_terminate,
pint_client_sm_context);
if (smcb == NULL)
{
return -PVFS_ENOMEM;
}
sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
PINT_init_msgarray_params(sm_p, fs_id);
PINT_init_sysint_credentials(sm_p->cred_p, credentials);
sm_p->u.statfs_list.fs_id = fs_id;
sm_p->u.statfs_list.stat_array = stat_array;
sm_p->u.statfs_list.count = count;
sm_p->u.statfs_list.addr_array = addr_array;
sm_p->u.statfs_list.details = details;
PVFS_hint_copy(hints, &sm_p->hints);
memset(sm_p->u.statfs_list.stat_array, 0,
(count * sizeof(struct PVFS_mgmt_server_stat)));
ret = PINT_msgpairarray_init(&sm_p->msgarray_op, count);
if(ret != 0)
{
PINT_smcb_free(smcb);
return ret;
}
return PINT_client_state_machine_post(
smcb, op_id, user_ptr);
}
/** Obtain file system statistics from a list of servers.
*/
PVFS_error PVFS_mgmt_statfs_list(
PVFS_fs_id fs_id,
PVFS_credentials *credentials,
struct PVFS_mgmt_server_stat *stat_array,
PVFS_BMI_addr_t *addr_array,
int count,
PVFS_error_details *details,
PVFS_hint hints)
{
PVFS_error ret = -PVFS_EINVAL, error = 0;
PVFS_mgmt_op_id op_id;
gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_mgmt_statfs_list entered\n");
ret = PVFS_imgmt_statfs_list(
fs_id, credentials, stat_array, addr_array, count,
details, &op_id, hints, NULL);
if (ret)
{
PVFS_perror_gossip("PVFS_imgmt_statfs_list call", ret);
error = ret;
}
else
{
ret = PVFS_mgmt_wait(op_id, "statfs_list", &error);
if (ret)
{
PVFS_perror_gossip("PVFS_mgmt_wait call", ret);
error = ret;
}
}
gossip_debug(GOSSIP_CLIENT_DEBUG,
"PVFS_mgmt_statfs_list completed\n");
PINT_mgmt_release(op_id);
return error;
}
static PINT_sm_action mgmt_statfs_list_setup_msgpair(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
int i = 0;
PINT_sm_msgpair_state *msg_p = NULL;
gossip_debug(GOSSIP_CLIENT_DEBUG,
"statfs_list state: mgmt_statfs_list_setup_msgpair\n");
js_p->error_code = 0;
foreach_msgpair(&sm_p->msgarray_op, msg_p, i)
{
PINT_SERVREQ_STATFS_FILL(
msg_p->req,
*sm_p->cred_p,
sm_p->u.statfs_list.fs_id,
sm_p->hints);
msg_p->fs_id = sm_p->u.statfs_list.fs_id;
msg_p->handle = PVFS_HANDLE_NULL;
msg_p->retry_flag = PVFS_MSGPAIR_RETRY;
msg_p->comp_fn = statfs_list_comp_fn;
msg_p->svr_addr = sm_p->u.statfs_list.addr_array[i];
}
PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
return SM_ACTION_COMPLETE;
}
static PINT_sm_action mgmt_statfs_list_cleanup(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
int i = 0, errct = 0;
PVFS_error error = js_p->error_code;
/* store server-specific errors if requested and present */
if ((error != 0) && (sm_p->u.statfs_list.details != NULL))
{
sm_p->u.statfs_list.details->count_exceeded = 0;
for(i = 0; i < sm_p->u.statfs_list.count; i++)
{
if (sm_p->msgarray_op.msgarray[i].op_status != 0)
{
if (errct < sm_p->u.statfs_list.details->count_allocated)
{
sm_p->u.statfs_list.details->error[errct].error =
sm_p->msgarray_op.msgarray[i].op_status;
sm_p->u.statfs_list.details->error[errct].addr =
sm_p->msgarray_op.msgarray[i].svr_addr;
errct++;
}
else
{
sm_p->u.statfs_list.details->count_exceeded = 1;
}
}
}
sm_p->u.statfs_list.details->count_used = errct;
error = -PVFS_EDETAIL;
}
PINT_msgpairarray_destroy(&sm_p->msgarray_op);
sm_p->error_code = error;
return SM_ACTION_COMPLETE;
}
static int statfs_list_comp_fn(void *v_p,
struct PVFS_server_resp *resp_p,
int i)
{
int j = 0;
PINT_smcb *smcb = v_p;
PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
/* if this particular request was successful, then store the
* statfs information in an array to be returned to caller
*/
if (sm_p->msgarray_op.msgarray[i].op_status == 0)
{
struct PVFS_mgmt_server_stat *sm_stat =
&sm_p->u.statfs_list.stat_array[i];
PVFS_statfs *resp_stat = &resp_p->u.statfs.stat;
sm_stat->fs_id = resp_stat->fs_id;
sm_stat->bytes_available = resp_stat->bytes_available;
sm_stat->bytes_total = resp_stat->bytes_total;
sm_stat->ram_total_bytes = resp_stat->ram_total_bytes;
sm_stat->ram_free_bytes = resp_stat->ram_free_bytes;
sm_stat->load_1 = resp_stat->load_1;
sm_stat->load_5 = resp_stat->load_5;
sm_stat->load_15 = resp_stat->load_15;
sm_stat->uptime_seconds = resp_stat->uptime_seconds;
sm_stat->handles_available_count =
resp_stat->handles_available_count;
sm_stat->handles_total_count =
resp_stat->handles_total_count;
sm_stat->bmi_address = PVFS_mgmt_map_addr(
sm_p->u.statfs_list.fs_id, sm_p->cred_p,
sm_p->msgarray_op.msgarray[i].svr_addr, &sm_stat->server_type);
assert(sm_stat->bmi_address);
assert(sm_stat->handles_total_count >=
sm_stat->handles_available_count);
}
/* if this is the last response, check all of the status values
* and return error code if any requests failed
*/
if (i == (sm_p->msgarray_op.count -1))
{
for (j=0; j < sm_p->msgarray_op.count; j++)
{
if (sm_p->msgarray_op.msgarray[j].op_status != 0)
{
return(sm_p->msgarray_op.msgarray[j].op_status);
}
}
}
return 0;
}
static int mgmt_statfs_list_parent_cleanup(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
sm_p->error_code = js_p->error_code;
PINT_SET_OP_COMPLETE;
return SM_ACTION_DEFERRED;
}
/*
* Local variables:
* mode: c
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ft=c ts=8 sts=4 sw=4 expandtab
*/