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

Line 
1/*
2 * (C) 2003 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6
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
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"
25#include "pint-cached-config.h"
26#include "PINT-reqproto-encode.h"
27
28extern job_context_id pint_client_sm_context;
29
30static int root_check_comp_fn(
31    void *v_p, struct PVFS_server_resp *resp_p, int i);
32static int collect_old_values_comp_fn(
33    void *v_p, struct PVFS_server_resp *resp_p, int i);
34
35%%
36
37machine pvfs2_client_mgmt_setparam_list_sm
38{
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   
52    state setup_msgpair
53    {
54        run mgmt_setparam_list_setup_msgpair;
55        success => xfer_msgpair;
56        default => cleanup;
57    }
58
59    state xfer_msgpair
60    {
61        jump pvfs2_msgpairarray_sm;
62        default => cleanup;
63    }
64
65    state cleanup
66    {
67        run mgmt_setparam_list_cleanup;
68        default => terminate;
69    }
70}
71
72%%
73
74/** Initiate setting of a run-time server parameter on a list of servers.
75 */
76PVFS_error PVFS_imgmt_setparam_list(
77    PVFS_fs_id fs_id,
78    const PVFS_credential *credential,
79    enum PVFS_server_param param,
80    struct PVFS_mgmt_setparam_value *value,
81    PVFS_BMI_addr_t *addr_array,
82    int count,
83    PVFS_error_details *details,
84    PVFS_hint hints,
85    PVFS_mgmt_op_id *op_id,
86    void *user_ptr)
87{
88    PVFS_error ret = -PVFS_EINVAL;
89    PINT_smcb *smcb = NULL;
90    PINT_client_sm *sm_p = NULL;
91
92    gossip_debug(GOSSIP_CLIENT_DEBUG,
93                 "PVFS_imgmt_setparam_list entered\n");
94
95    if (param == PVFS_SERV_PARAM_INVALID)
96    {
97        return ret;
98    }
99
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)
106    {
107        return -PVFS_ENOMEM;
108    }
109    sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
110
111    PINT_init_msgarray_params(sm_p, fs_id);
112    PINT_init_sysint_credential(sm_p->newcred_p, credential);
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;
119
120    ret = PINT_msgpairarray_init(&sm_p->msgarray_op, count);
121    if(ret != 0)
122    {
123        PINT_smcb_free(smcb);
124        return ret;
125    }
126
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
133    return PINT_client_state_machine_post(
134        smcb,  op_id, user_ptr);
135}
136
137/** Set a run-time parameter on a list of servers.
138 */
139PVFS_error PVFS_mgmt_setparam_list(
140    PVFS_fs_id fs_id,
141    const PVFS_credential *credential,
142    enum PVFS_server_param param,
143    struct PVFS_mgmt_setparam_value *value,
144    PVFS_BMI_addr_t *addr_array,
145    int count,
146    PVFS_error_details *details,
147    PVFS_hint hints)
148{
149    PVFS_error ret = -PVFS_EINVAL, error = 0;
150    PVFS_sys_op_id op_id;
151
152    gossip_debug(GOSSIP_CLIENT_DEBUG, "%s entered\n", __func__);
153
154    ret = PVFS_imgmt_setparam_list(
155        fs_id, credential, param, value, addr_array,
156        count, details, hints, &op_id, NULL);
157
158    if (ret)
159    {
160        PVFS_perror_gossip("PVFS_imgmt_setparam_list call", ret);
161        error = ret;
162    }
163    else
164    {
165        ret = PVFS_mgmt_wait(op_id, "setparam_list", &error);
166        if (ret)
167        {
168            PVFS_perror_gossip("PVFS_mgmt_wait call", ret);
169            error = ret;
170        }
171    }
172
173    gossip_debug(GOSSIP_CLIENT_DEBUG, "%s completed\n", __func__);
174
175    PINT_mgmt_release(op_id);
176    return error;
177}
178
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
203static PINT_sm_action mgmt_setparam_list_setup_msgpair(
204        struct PINT_smcb *smcb, job_status_s *js_p)
205{
206    struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
207    int i = 0;
208    PINT_sm_msgpair_state *msg_p = NULL;
209
210    gossip_debug(GOSSIP_CLIENT_DEBUG, "setparam_list state: "
211                 "mgmt_setparam_list_setup_msgpair\n");
212
213    /* setup msgpair array */
214    foreach_msgpair(&sm_p->msgarray_op, msg_p, i)
215    {
216        PINT_SERVREQ_MGMT_SETPARAM_FILL(
217            msg_p->req,
218            sm_p->getattr.attr.capability,
219            sm_p->u.setparam_list.fs_id,
220            sm_p->u.setparam_list.param,
221            sm_p->u.setparam_list.value,
222            sm_p->hints);
223
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;
227
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;
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)));
236                break;
237
238            default:
239                msg_p->comp_fn = collect_old_values_comp_fn;
240                break;
241        }
242        msg_p->svr_addr = sm_p->u.setparam_list.addr_array[i];
243    }
244
245    /* immediate return: next state jumps to msgpairarray machine */
246    js_p->error_code = 0;
247
248    PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
249    return SM_ACTION_COMPLETE;
250}
251
252static PINT_sm_action mgmt_setparam_list_cleanup(
253        struct PINT_smcb *smcb, job_status_s *js_p)
254{
255    struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
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    {
262        sm_p->u.setparam_list.details->count_exceeded = 0;
263
264        for(i = 0; i < sm_p->u.setparam_list.count; i++)
265        {
266            int status;
267            if (sm_p->u.setparam_list.param == PVFS_SERV_PARAM_ROOT_CHECK)
268            {
269                status = sm_p->u.setparam_list.root_check_status_array[i];
270            }
271            else
272            {
273                status = sm_p->msgarray_op.msgarray[i].op_status;
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 =
280                    sm_p->msgarray_op.msgarray[i].svr_addr;
281                errct++;
282            }
283            else
284            {
285                sm_p->u.setparam_list.details->count_exceeded = 1;
286                break;
287            }
288        }
289        sm_p->u.setparam_list.details->count_used = errct;
290
291        error = -PVFS_EDETAIL;
292    }
293
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
300    PINT_msgpairarray_destroy(&sm_p->msgarray_op);
301
302    sm_p->error_code  = error;
303
304    PINT_SET_OP_COMPLETE;
305    return SM_ACTION_TERMINATE;
306}
307
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 */
315static int collect_old_values_comp_fn(
316    void *v_p, struct PVFS_server_resp *resp_p, int i)
317{
318    PINT_smcb *smcb = v_p;
319    PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
320    int j;
321
322    /* if this is the last response, check all of the status values
323     * and return error code if any requests failed
324     */
325    if (i == (sm_p->msgarray_op.count -1))
326    {
327        for (j = 0; j < sm_p->msgarray_op.count; j++)
328        {
329            if (sm_p->msgarray_op.msgarray[j].op_status != 0)
330            {
331                return sm_p->msgarray_op.msgarray[j].op_status;
332            }
333        }
334    }
335    return 0;
336}
337
338/* root_check_comp_fn()
339 *
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.
343 *
344 * returns 0 if exactly one server claims ownership of root handle,
345 * -PVFS_error on failure
346 */
347static int root_check_comp_fn(
348    void *v_p, struct PVFS_server_resp *resp_p, int i)
349{
350    int j = 0;
351    int owners = 0;
352    PINT_smcb *smcb = v_p;
353    PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
354
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] =
360        sm_p->msgarray_op.msgarray[i].op_status;
361
362    /* need to return non-zero status at the end if any of the statuses
363     * are nonzero
364     */
365    if(i == (sm_p->u.setparam_list.count - 1))
366    {
367        for(; j < sm_p->u.setparam_list.count; ++j)
368        {
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            }
378        }
379
380        if(owners != 1)
381        {
382            return -PVFS_EDETAIL;
383        }
384    }
385
386    return 0;
387}
388
389/*
390 * Local variables:
391 *  mode: c
392 *  c-indent-level: 4
393 *  c-basic-offset: 4
394 * End:
395 *
396 * vim: ft=c ts=8 sts=4 sw=4 expandtab
397 */
Note: See TracBrowser for help on using the browser.