root/branches/cu-security-branch/src/client/sysint/mgmt-setparam-list.sm @ 8354

Revision 8354, 10.7 KB (checked in by nlmills, 3 years ago)

moved security types into main pvfs2-types.h header

RevLine 
[2090]1/*
2 * (C) 2003 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6
[4180]7/** \file
8 *  \ingroup mgmtint
9 *
10 *  PVFS2 management interface routines for setting run-time parameters
11 *  on a list of servers.  These are currently used primarily for file
12 *  system repair purposes, specifically to put the servers in a special
13 *  administrative mode to avoid file system changes while repairs are
14 *  underway.
15 */
16
[2090]17#include <string.h>
18#include <assert.h>
19
20#include "client-state-machine.h"
21#include "pvfs2-debug.h"
22#include "job.h"
23#include "gossip.h"
24#include "str-utils.h"
[3671]25#include "pint-cached-config.h"
[2090]26#include "PINT-reqproto-encode.h"
27
28extern job_context_id pint_client_sm_context;
29
[3386]30static int root_check_comp_fn(
[3534]31    void *v_p, struct PVFS_server_resp *resp_p, int i);
[3386]32static int collect_old_values_comp_fn(
[3534]33    void *v_p, struct PVFS_server_resp *resp_p, int i);
[2090]34
35%%
36
[6103]37machine pvfs2_client_mgmt_setparam_list_sm
[2090]38{
[7361]39    state init
40    {
41        run mgmt_setparam_list_init;
42        default => setparam_list_get_capability;
43    }
44   
45    state setparam_list_get_capability
46    {
47        jump pvfs2_client_getattr_sm;
48        success => setup_msgpair;
49        default => cleanup;
50    }
51   
[3386]52    state setup_msgpair
53    {
54        run mgmt_setparam_list_setup_msgpair;
55        success => xfer_msgpair;
56        default => cleanup;
[2090]57    }
58
[3386]59    state xfer_msgpair
60    {
[3684]61        jump pvfs2_msgpairarray_sm;
[3386]62        default => cleanup;
[2090]63    }
64
[3386]65    state cleanup
66    {
67        run mgmt_setparam_list_cleanup;
68        default => terminate;
[2090]69    }
70}
71
72%%
73
[4180]74/** Initiate setting of a run-time server parameter on a list of servers.
75 */
[4098]76PVFS_error PVFS_imgmt_setparam_list(
[3534]77    PVFS_fs_id fs_id,
[7264]78    const PVFS_credential *credential,
[3534]79    enum PVFS_server_param param,
[7941]80    struct PVFS_mgmt_setparam_value *value,
[3534]81    PVFS_BMI_addr_t *addr_array,
82    int count,
83    PVFS_error_details *details,
[7941]84    PVFS_hint hints,
[3534]85    PVFS_mgmt_op_id *op_id,
86    void *user_ptr)
[2090]87{
[4098]88    PVFS_error ret = -PVFS_EINVAL;
[6212]89    PINT_smcb *smcb = NULL;
[3386]90    PINT_client_sm *sm_p = NULL;
[2090]91
[3534]92    gossip_debug(GOSSIP_CLIENT_DEBUG,
93                 "PVFS_imgmt_setparam_list entered\n");
[2090]94
[3534]95    if (param == PVFS_SERV_PARAM_INVALID)
[2090]96    {
[3534]97        return ret;
[2090]98    }
99
[6212]100    PINT_smcb_alloc(&smcb, PVFS_MGMT_SETPARAM_LIST,
101             sizeof(struct PINT_client_sm),
102             client_op_state_get_machine,
103             client_state_machine_terminate,
104             pint_client_sm_context);
105    if (smcb == NULL)
[2963]106    {
[3534]107        return -PVFS_ENOMEM;
[2963]108    }
[6212]109    sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
[2090]110
[7024]111    PINT_init_msgarray_params(sm_p, fs_id);
[7259]112    PINT_init_sysint_credential(sm_p->newcred_p, credential);
[3534]113    sm_p->u.setparam_list.fs_id = fs_id;
114    sm_p->u.setparam_list.param = param;
115    sm_p->u.setparam_list.value = value;
116    sm_p->u.setparam_list.addr_array = addr_array;
117    sm_p->u.setparam_list.count = count;
118    sm_p->u.setparam_list.details = details;
[2090]119
[7024]120    ret = PINT_msgpairarray_init(&sm_p->msgarray_op, count);
121    if(ret != 0)
[3413]122    {
[6364]123        PINT_smcb_free(smcb);
[7024]124        return ret;
[3413]125    }
126
[2974]127    if (sm_p->u.setparam_list.root_check_status_array)
128    {
129        free(sm_p->u.setparam_list.root_check_status_array);
130        sm_p->u.setparam_list.root_check_status_array = NULL;
131    }
132
[3534]133    return PINT_client_state_machine_post(
[6212]134        smcb,  op_id, user_ptr);
[3534]135}
[2090]136
[4180]137/** Set a run-time parameter on a list of servers.
138 */
[4098]139PVFS_error PVFS_mgmt_setparam_list(
[3534]140    PVFS_fs_id fs_id,
[7264]141    const PVFS_credential *credential,
[3534]142    enum PVFS_server_param param,
[7941]143    struct PVFS_mgmt_setparam_value *value,
[3534]144    PVFS_BMI_addr_t *addr_array,
145    int count,
[7941]146    PVFS_error_details *details,
147    PVFS_hint hints)
[3534]148{
[4098]149    PVFS_error ret = -PVFS_EINVAL, error = 0;
[3534]150    PVFS_sys_op_id op_id;
[2090]151
[6265]152    gossip_debug(GOSSIP_CLIENT_DEBUG, "%s entered\n", __func__);
[3386]153
[3534]154    ret = PVFS_imgmt_setparam_list(
[7941]155        fs_id, credential, param, value, addr_array,
156        count, details, hints, &op_id, NULL);
[3541]157
[3534]158    if (ret)
[2090]159    {
[3541]160        PVFS_perror_gossip("PVFS_imgmt_setparam_list call", ret);
[3534]161        error = ret;
[2090]162    }
[3541]163    else
164    {
[5190]165        ret = PVFS_mgmt_wait(op_id, "setparam_list", &error);
[3541]166        if (ret)
167        {
168            PVFS_perror_gossip("PVFS_mgmt_wait call", ret);
169            error = ret;
170        }
171    }
[2090]172
[6265]173    gossip_debug(GOSSIP_CLIENT_DEBUG, "%s completed\n", __func__);
[2090]174
[6212]175    PINT_mgmt_release(op_id);
[2090]176    return error;
177}
178
[7361]179static int mgmt_setparam_list_init(
180    struct PINT_smcb *smcb, job_status_s *js_p)
181{
182    gossip_debug(GOSSIP_CLIENT_DEBUG, "mgmt_setparam_list_init called\n");
183    struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
184    PVFS_object_ref temp_ref;
185   
186    temp_ref.fs_id = sm_p->u.setparam_list.fs_id;
187    js_p->error_code = PINT_cached_config_get_root_handle(
188                           sm_p->u.setparam_list.fs_id,
189                           &temp_ref.handle);
190       
191    assert(js_p->error_code == 0);
192
193    PINT_SM_GETATTR_STATE_FILL(
194        sm_p->getattr,
195        temp_ref,
196        PVFS_ATTR_COMMON_ALL|PVFS_ATTR_DIR_HINT|PVFS_ATTR_CAPABILITY,
197        PVFS_TYPE_NONE,
198        0);
199       
200    return SM_ACTION_COMPLETE;
201}
202
[6212]203static PINT_sm_action mgmt_setparam_list_setup_msgpair(
204        struct PINT_smcb *smcb, job_status_s *js_p)
[2090]205{
[6212]206    struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
[3386]207    int i = 0;
[3681]208    PINT_sm_msgpair_state *msg_p = NULL;
[2090]209
[2855]210    gossip_debug(GOSSIP_CLIENT_DEBUG, "setparam_list state: "
211                 "mgmt_setparam_list_setup_msgpair\n");
[2090]212
213    /* setup msgpair array */
[7024]214    foreach_msgpair(&sm_p->msgarray_op, msg_p, i)
[2090]215    {
[3926]216        PINT_SERVREQ_MGMT_SETPARAM_FILL(
[3386]217            msg_p->req,
[7361]218            sm_p->getattr.attr.capability,
[3386]219            sm_p->u.setparam_list.fs_id,
220            sm_p->u.setparam_list.param,
[7941]221            sm_p->u.setparam_list.value,
222            sm_p->hints);
[7024]223
[3926]224        msg_p->fs_id = sm_p->u.setparam_list.fs_id;
225        msg_p->handle = PVFS_HANDLE_NULL;
226        msg_p->retry_flag = PVFS_MSGPAIR_RETRY;
[2090]227
[3386]228        switch(sm_p->u.setparam_list.param)
229        {
230            case PVFS_SERV_PARAM_ROOT_CHECK:
231                msg_p->comp_fn = root_check_comp_fn;
[4948]232                sm_p->u.setparam_list.root_check_status_array = (int *)
233                    malloc(sm_p->u.setparam_list.count * sizeof(int));
234                memset(sm_p->u.setparam_list.root_check_status_array, -1,
235                       (sm_p->u.setparam_list.count * sizeof(int)));
[3386]236                break;
[4948]237
[3386]238            default:
239                msg_p->comp_fn = collect_old_values_comp_fn;
240                break;
241        }
[3926]242        msg_p->svr_addr = sm_p->u.setparam_list.addr_array[i];
[2090]243    }
244
245    /* immediate return: next state jumps to msgpairarray machine */
246    js_p->error_code = 0;
[7024]247
248    PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
[6212]249    return SM_ACTION_COMPLETE;
[2090]250}
251
[6212]252static PINT_sm_action mgmt_setparam_list_cleanup(
253        struct PINT_smcb *smcb, job_status_s *js_p)
[2090]254{
[6212]255    struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
[3534]256    int i = 0, errct = 0;
257    PVFS_error error = js_p->error_code;
258
259    /* store server-specific errors if requested and present */
260    if ((error != 0) && (sm_p->u.setparam_list.details != NULL))
261    {
[3926]262        sm_p->u.setparam_list.details->count_exceeded = 0;
[3534]263
[3926]264        for(i = 0; i < sm_p->u.setparam_list.count; i++)
[3534]265        {
[4948]266            int status;
267            if (sm_p->u.setparam_list.param == PVFS_SERV_PARAM_ROOT_CHECK)
[3926]268            {
[4948]269                status = sm_p->u.setparam_list.root_check_status_array[i];
[3926]270            }
[4948]271            else
272            {
[7024]273                status = sm_p->msgarray_op.msgarray[i].op_status;
[4948]274            }
275
276            if (errct < sm_p->u.setparam_list.details->count_allocated)
277            {
278                sm_p->u.setparam_list.details->error[errct].error = status;
279                sm_p->u.setparam_list.details->error[errct].addr =
[7024]280                    sm_p->msgarray_op.msgarray[i].svr_addr;
[4948]281                errct++;
282            }
283            else
284            {
285                sm_p->u.setparam_list.details->count_exceeded = 1;
286                break;
287            }
[3926]288        }
289        sm_p->u.setparam_list.details->count_used = errct;
[3534]290
[3926]291        error = -PVFS_EDETAIL;
[3534]292    }
293
[4948]294    if(sm_p->u.setparam_list.param == PVFS_SERV_PARAM_ROOT_CHECK)
295    {
296        free(sm_p->u.setparam_list.root_check_status_array);
297        sm_p->u.setparam_list.root_check_status_array = NULL;
298    }
299
[7024]300    PINT_msgpairarray_destroy(&sm_p->msgarray_op);
[3534]301
302    sm_p->error_code  = error;
[2090]303
[6212]304    PINT_SET_OP_COMPLETE;
305    return SM_ACTION_TERMINATE;
[2090]306}
307
[2178]308/* collect_old_values_comp_fn()
309 *
310 * completion function that assembles old values for parameters
311 * when appropriate
312 *
313 * returns 0 on success, -PVFS_error on failure
314 */
[3926]315static int collect_old_values_comp_fn(
316    void *v_p, struct PVFS_server_resp *resp_p, int i)
[2178]317{
[6212]318    PINT_smcb *smcb = v_p;
[7024]319    PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
[2178]320    int j;
321
[2855]322    /* if this is the last response, check all of the status values
323     * and return error code if any requests failed
[2178]324     */
[7024]325    if (i == (sm_p->msgarray_op.count -1))
[2178]326    {
[7024]327        for (j = 0; j < sm_p->msgarray_op.count; j++)
[3926]328        {
[7024]329            if (sm_p->msgarray_op.msgarray[j].op_status != 0)
[3926]330            {
[7024]331                return sm_p->msgarray_op.msgarray[j].op_status;
[3926]332            }
333        }
[2178]334    }
[2963]335    return 0;
[2178]336}
337
[2090]338/* root_check_comp_fn()
339 *
[2974]340 * completion function for PVFS_SERV_PARAM_ROOT_CHECK parameter; it
341 * handles this special case operation in which we want just one
342 * server to return success and all others to return -PVFS_ENOENT.
[2090]343 *
344 * returns 0 if exactly one server claims ownership of root handle,
345 * -PVFS_error on failure
346 */
[3926]347static int root_check_comp_fn(
348    void *v_p, struct PVFS_server_resp *resp_p, int i)
[2090]349{
350    int j = 0;
[4949]351    int owners = 0;
[6212]352    PINT_smcb *smcb = v_p;
[7024]353    PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
[2090]354
[2974]355    /*
356      store the op_status before it's overwritten with the return
357      value of this comp_fn by the msgpairarray code
358    */
359    sm_p->u.setparam_list.root_check_status_array[i] =
[7024]360        sm_p->msgarray_op.msgarray[i].op_status;
[2974]361
[4948]362    /* need to return non-zero status at the end if any of the statuses
363     * are nonzero
[2090]364     */
[4950]365    if(i == (sm_p->u.setparam_list.count - 1))
[2090]366    {
[4950]367        for(; j < sm_p->u.setparam_list.count; ++j)
[3926]368        {
[4950]369            if(sm_p->u.setparam_list.root_check_status_array[j] == 0)
370            {
371                owners++;
372            }
373            else if(sm_p->u.setparam_list.root_check_status_array[j] !=
374                    -PVFS_ENOENT)
375            {
376                return -PVFS_EDETAIL;
377            }
[3926]378        }
[4949]379
[4950]380        if(owners != 1)
[4949]381        {
[4950]382            return -PVFS_EDETAIL;
[4949]383        }
[2090]384    }
385
[4948]386    return 0;
[2090]387}
388
389/*
390 * Local variables:
391 *  mode: c
392 *  c-indent-level: 4
393 *  c-basic-offset: 4
394 * End:
395 *
[3784]396 * vim: ft=c ts=8 sts=4 sw=4 expandtab
[2090]397 */
Note: See TracBrowser for help on using the browser.