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
242 lines (210 sloc) 6.41 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 sysint
*
* PVFS2 system interface routines for statfs.
*/
#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;
%%
machine pvfs2_client_statfs_sm
{
state run_nested
{
jump pvfs2_client_mgmt_statfs_list_nested_sm;
default => cleanup;
}
state cleanup
{
run sys_statfs_cleanup;
default => terminate;
}
}
%%
/** Initiate retrieval of file system statistics.
*/
PVFS_error PVFS_isys_statfs(
PVFS_fs_id fs_id,
const PVFS_credentials *credentials,
PVFS_sysresp_statfs *resp,
PVFS_sys_op_id *op_id,
PVFS_hint hints,
void *user_ptr)
{
PINT_smcb *smcb = NULL;
PINT_client_sm *sm_p = NULL;
int ret = -1;
gossip_debug(GOSSIP_CLIENT_DEBUG,
"PVFS_isys_statfs entered\n");
PINT_smcb_alloc(&smcb, PVFS_SYS_STATFS,
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);
/* count the number of servers */
ret = PINT_cached_config_count_servers(
fs_id, PVFS_MGMT_IO_SERVER|PVFS_MGMT_META_SERVER,
&sm_p->u.statfs_list.count);
if (ret < 0)
{
PINT_smcb_free(smcb);
return ret;
}
/* allocate storage for addresses and statfs buffers */
sm_p->u.statfs_list.addr_array = (PVFS_BMI_addr_t *)malloc(
sm_p->u.statfs_list.count*sizeof(PVFS_BMI_addr_t));
if (sm_p->u.statfs_list.addr_array == NULL)
{
PINT_smcb_free(smcb);
return -PVFS_ENOMEM;
}
sm_p->u.statfs_list.stat_array = (struct PVFS_mgmt_server_stat*)malloc(
sm_p->u.statfs_list.count*sizeof(struct PVFS_mgmt_server_stat));
if (!sm_p->u.statfs_list.stat_array)
{
free(sm_p->u.statfs_list.addr_array);
PINT_smcb_free(smcb);
return(-PVFS_ENOMEM);
}
/* generate default list of servers */
ret = PINT_cached_config_get_server_array(
fs_id, PVFS_MGMT_IO_SERVER|PVFS_MGMT_META_SERVER,
sm_p->u.statfs_list.addr_array, &sm_p->u.statfs_list.count);
if (ret < 0)
{
free(sm_p->u.statfs_list.addr_array);
free(sm_p->u.statfs_list.stat_array);
PINT_smcb_free(smcb);
return ret;
}
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.details = NULL;
sm_p->u.statfs_list.resp = resp;
memset(sm_p->u.statfs_list.stat_array, 0,
(sm_p->u.statfs_list.count * sizeof(struct PVFS_mgmt_server_stat)));
ret = PINT_msgpairarray_init(&sm_p->msgarray_op, sm_p->u.statfs_list.count);
if(ret != 0)
{
gossip_err("Failed to initialize %d msgpairs\n", sm_p->u.statfs_list.count);
return ret;
}
PVFS_hint_copy(hints, &sm_p->hints);
return PINT_client_state_machine_post(
smcb, op_id, user_ptr);
}
/** Obtain file system statistics.
*/
PVFS_error PVFS_sys_statfs(
PVFS_fs_id fs_id,
const PVFS_credentials *credentials,
PVFS_sysresp_statfs* resp,
PVFS_hint hints)
{
PVFS_error ret = -PVFS_EINVAL, error = 0;
PVFS_sys_op_id op_id;
gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_sys_statfs entered\n");
ret = PVFS_isys_statfs(
fs_id, credentials, resp, &op_id, hints, NULL);
if (ret)
{
PVFS_perror_gossip("PVFS_isys_statfs call", ret);
error = ret;
}
else
{
ret = PVFS_sys_wait(op_id, "statfs", &error);
if (ret)
{
PVFS_perror_gossip("PVFS_sys_wait call", ret);
error = ret;
}
}
gossip_debug(GOSSIP_CLIENT_DEBUG,
"PVFS_sys_statfs completed\n");
PINT_sys_release(op_id);
return error;
}
static PINT_sm_action sys_statfs_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;
int num_io_servers = 0;
PVFS_size min_bytes_available = 0;
PVFS_size min_bytes_total = 0;
sm_p->error_code = js_p->error_code;
/* aggregate statistics down into one statfs structure */
sm_p->u.statfs_list.resp->statfs_buf.fs_id = sm_p->u.statfs_list.fs_id;
sm_p->u.statfs_list.resp->statfs_buf.bytes_available = 0;
sm_p->u.statfs_list.resp->statfs_buf.bytes_total = 0;
sm_p->u.statfs_list.resp->statfs_buf.handles_available_count = 0;
sm_p->u.statfs_list.resp->statfs_buf.handles_total_count = 0;
for(i=0; i<sm_p->u.statfs_list.count; i++)
{
if(sm_p->u.statfs_list.stat_array[i].server_type & PVFS_MGMT_IO_SERVER)
{
num_io_servers++;
if(min_bytes_available == 0 ||
min_bytes_available > sm_p->u.statfs_list.stat_array[i].bytes_available)
{
min_bytes_available = sm_p->u.statfs_list.stat_array[i].bytes_available;
}
if(min_bytes_total == 0 ||
min_bytes_total > sm_p->u.statfs_list.stat_array[i].bytes_total)
{
min_bytes_total = sm_p->u.statfs_list.stat_array[i].bytes_total;
}
}
sm_p->u.statfs_list.resp->statfs_buf.handles_available_count
+= sm_p->u.statfs_list.stat_array[i].handles_available_count;
sm_p->u.statfs_list.resp->statfs_buf.handles_total_count
+= sm_p->u.statfs_list.stat_array[i].handles_total_count;
}
sm_p->u.statfs_list.resp->statfs_buf.bytes_available =
min_bytes_available*num_io_servers;
sm_p->u.statfs_list.resp->statfs_buf.bytes_total =
min_bytes_total*num_io_servers;
sm_p->u.statfs_list.resp->server_count = sm_p->u.statfs_list.count;
if(sm_p->u.statfs_list.stat_array)
{
free(sm_p->u.statfs_list.stat_array);
}
if(sm_p->u.statfs_list.addr_array)
{
free(sm_p->u.statfs_list.addr_array);
}
PINT_SET_OP_COMPLETE;
return SM_ACTION_TERMINATE;
}
/*
* Local variables:
* mode: c
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ft=c ts=8 sts=4 sw=4 expandtab
*/